Skip to content

Commit 2fd7718

Browse files
authored
Merge pull request #7 from nberlee/docs
chore: update docs
2 parents d6059be + f84be2e commit 2fd7718

File tree

2 files changed

+147
-12
lines changed

2 files changed

+147
-12
lines changed

LICENSE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
MIT License
22

33
Copyright (c) 2018 Cihangir Akturk
4+
Copyright (c) 2023 Nico Berlee
45

56
Permission is hereby granted, free of charge, to any person obtaining a copy
67
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 146 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,150 @@
1-
### Netstat implementation for Talos Linux
1+
# go-netstat
2+
go-netstat is a Golang library that provides a fast and multi-threaded implementation of the netstat utility on Linux. It is designed to be feature-complete with the net-tools netstat implementation and supports network namespaces for containers. It was written with Talos Linux in mind.
23

4+
## Installation
5+
You can install go-netstat by running the following command:
6+
```bash
7+
go get github.com/nberlee/go-netstat/netstat
38
```
4-
Usage of ./go-netstat:
5-
-4 display only IPv4 sockets
6-
-6 display only IPv6 sockets
7-
-U display udplite sockets
8-
-a display all sockets (default: connected)
9-
-l display listening server sockets
10-
-n don't resolve names (default true)
11-
-p display PID/Program name for sockets
12-
-t display tcp sockets
13-
-u display udp sockets
14-
-w display raw sockets
9+
10+
## Usage
11+
Here's an example of how to use go-netstat:
12+
13+
```go
14+
import (
15+
"context"
16+
"fmt"
17+
18+
"github.com/nberlee/go-netstat/netstat"
19+
)
20+
21+
func main() {
22+
ctx := context.Background()
23+
24+
features := netstat.EnableFeatures{
25+
TCP: true,
26+
TCP6: true,
27+
UDP: true,
28+
UDP6: true,
29+
UDPLite: true,
30+
UDPLite6: true,
31+
Raw: true,
32+
Raw6: true,
33+
PID: true,
34+
NoHostNetwork: false,
35+
AllNetNs: true,
36+
NetNsName: []string{},
37+
NetNsPids: []uint32{},
38+
}
39+
40+
fn := netstat.NoopFilter
41+
42+
netstatResp, err := netstat.Netstat(ctx, features, fn)
43+
if err != nil {
44+
panic(err)
45+
}
46+
47+
for _, entry := range netstatResp {
48+
fmt.Println(entry)
49+
}
50+
}
51+
```
52+
The `features` struct specifies which types of sockets and connections to include in the result, while the `fn` function can be used to filter the results further.
53+
54+
## Contributing
55+
We welcome contributions to go-netstat! If you have bug fixes, feature requests, or performance improvements, feel free to submit a pull request. We are especially interested in contributions that are close to the core functionality and that benefit Talos Linux netstat.
56+
57+
## Credits
58+
The initial version of go-netstat was written by Cihangir Akturk, who contributed the functions ParseAddr, ParseIpv4, and ParseIpv6. Nico Berlee later rewrote and reworked every other function to make it faster by multi-threading and to add features like network namespaces, udplite+raw support and tests.
59+
60+
## License
61+
go-netstat is released under the MIT License. See [LICENSE](https://github.com/nberlee/go-netstat/blob/main/LICENSE) for details.
62+
63+
## Types
64+
### EnableFeatures
65+
The EnableFeatures struct specifies which types of sockets and connections to include in the result.
66+
```go
67+
type EnableFeatures struct {
68+
TCP bool
69+
TCP6 bool
70+
UDP bool
71+
UDP6 bool
72+
UDPLite bool
73+
UDPLite6 bool
74+
Raw bool
75+
Raw6 bool
76+
PID bool
77+
NoHostNetwork bool
78+
AllNetNs bool
79+
NetNsName []string
80+
NetNsPids []uint32
81+
}
82+
```
83+
84+
### SockTabEntry
85+
The SockTabEntry struct represents each line of the /proc/net/[tcp|udp] file.
86+
```go
87+
type SockTabEntry struct {
88+
Transport string
89+
LocalEndpoint *SockEndpoint
90+
RemoteEndpoint *SockEndpoint
91+
State SkState
92+
TxQueue uint64
93+
RxQueue uint64
94+
Tr TimerActive
95+
TimerWhen uint64
96+
Retrnsmt uint64
97+
UID uint32
98+
Timeout uint64
99+
Inode uint64
100+
Ref uint64
101+
Process *common.Process
102+
NetNS string
103+
}
15104
```
16105

106+
### SockEndpoint
107+
108+
The `SockEndpoint` struct represents an IP address and port.
109+
110+
```go
111+
type SockEndpoint struct {
112+
IP net.IP
113+
Port uint16
114+
}
115+
```
116+
The `IP` field can be an IPv4 or IPv6 address.
117+
118+
## Filter Function
119+
The fn function is used to filter the results of the Netstat function.
120+
```go
121+
type FilterFunc func(*SockTabEntry) bool
122+
```
123+
124+
Here are some examples of filter functions:
125+
```go
126+
func NoopFilter(s *SockTabEntry) bool {
127+
return true
128+
}
129+
130+
func ConnectedFilter(s *SockTabEntry) bool {
131+
return s.State != Listen
132+
}
133+
134+
func ListeningFilter(s *SockTabEntry) bool {
135+
return s.State == Listen
136+
}
137+
```
138+
139+
## Design decisions
140+
* /proc/net/[tcp|udp|udplite|raw] are chosen over syscalls as accessing directly kernel data structures is can be faster than making syscalls with context switching overhead.
141+
* `go-netstat` does not enter an network namespace, instead it gets the process id and reads the /proc/`processid`/net/[tcp|udp|udplite|raw]. This is safer and faster.
142+
143+
### Flows
144+
145+
#### Network namespace
146+
Network Namespace Name -> Find in `/var/run/netns` -> Follow bindmount to /proc/`processid`/ns/net, get the symlink which is if for `net:[12345678]`. Search in /proc/`processid`/ns/net for the file descriptor with the same symlink.
147+
148+
#### Process ID + Name
149+
To enrich netstat entries with the process id, the inode is matched against /proc/`processid`/fd/* symlinks.
150+

0 commit comments

Comments
 (0)