/
socketscanner.go
69 lines (61 loc) · 2.03 KB
/
socketscanner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package collectors
import (
"fmt"
"github.com/otterize/go-procnet/procnet"
sharedconfig "github.com/otterize/network-mapper/src/shared/config"
"github.com/otterize/network-mapper/src/sniffer/pkg/utils"
"github.com/otterize/nilable"
"github.com/spf13/viper"
"time"
)
type SocketScanner struct {
NetworkCollector
}
func NewSocketScanner() *SocketScanner {
s := SocketScanner{
NetworkCollector{},
}
s.resetData()
return &s
}
func (s *SocketScanner) scanTcpFile(hostname string, path string) {
if !viper.GetBool(sharedconfig.EnableSocketScannerKey) {
return
}
socks, err := procnet.SocksFromPath(path)
if err != nil {
// it's likely that some files will be deleted during our iteration, so we ignore errors reading the file.
return
}
listenPorts := make(map[uint16]bool)
for _, sock := range socks {
if sock.State == procnet.Listen {
// LISTEN ports always appear first
listenPorts[sock.LocalAddr.Port] = true
continue
}
if sock.LocalAddr.IP.IsLoopback() || sock.RemoteAddr.IP.IsLoopback() {
// ignore localhost connections as they are irrelevant to the mapping
continue
}
if sock.State != procnet.Established {
// Skip sockets that are not in ESTABLISHED state, to avoid reporting stale connections (such as connections in TIME_WAIT).
continue
}
// Only report sockets from the client-side by checking if the local port for this socket is the same port as a listen socket.
if _, isServersideSocket := listenPorts[sock.LocalAddr.Port]; !isServersideSocket {
// The hostname we have here is the hostname for the client.
s.addCapturedRequest(sock.LocalAddr.IP.String(), hostname, sock.RemoteAddr.IP.String(), sock.RemoteAddr.IP.String(), time.Now(), nilable.Nilable[int]{}, nil)
}
}
}
func (s *SocketScanner) ScanProcDir() error {
return utils.ScanProcDirProcesses(func(_ int64, pDir string) {
hostname, err := utils.ExtractProcessHostname(pDir)
if err != nil {
return
}
s.scanTcpFile(hostname, fmt.Sprintf("%s/net/tcp", pDir))
s.scanTcpFile(hostname, fmt.Sprintf("%s/net/tcp6", pDir))
})
}