-
Notifications
You must be signed in to change notification settings - Fork 51
/
autoport_nonwindows.go
149 lines (118 loc) · 3.26 KB
/
autoport_nonwindows.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// +build !windows
package nfqdatapath
import (
"fmt"
"io/ioutil"
"os"
"os/user"
"strconv"
"strings"
"go.aporeto.io/enforcerd/trireme-lib/utils/cgnetcls"
"go.uber.org/zap"
)
const (
procNetTCPFile = "/proc/net/tcp"
uidFieldOffset = 7
inodeFieldOffset = 9
procHeaderLineNum = 0
portOffset = 1
ipPortOffset = 1
sockStateOffset = 3
sockListeningState = "0A"
hexFormat = 16
integerSize = 64
minimumFields = 2
)
func getUserName(uid string) (string, error) {
u, err := user.LookupId(uid)
if err != nil {
return "", err
}
return u.Username, nil
}
func (d *defaultRead) readProcNetTCP() (inodeMap map[string]string, userMap map[string]map[string]bool, err error) {
buffer, err := ioutil.ReadFile(procNetTCPFile)
if err != nil {
return nil, nil, fmt.Errorf("Failed to read /proc/net/tcp file %s", err)
}
inodeMap = map[string]string{}
userMap = map[string]map[string]bool{}
s := string(buffer)
for cnt, line := range strings.Split(s, "\n") {
line := strings.Fields(line)
// continue if not a valid line
if len(line) < uidFieldOffset {
continue
}
/* Look at socket which are in listening state only */
if (cnt == procHeaderLineNum) || (line[sockStateOffset] != sockListeningState) {
continue
}
/* Get the UID */
uid := line[uidFieldOffset]
inode := line[inodeFieldOffset]
portString := ""
{
ipPort := strings.Split(line[ipPortOffset], ":")
if len(ipPort) < minimumFields {
zap.L().Warn("Failed to extract port")
continue
}
portNum, err := strconv.ParseInt(ipPort[portOffset], hexFormat, integerSize)
if err != nil {
zap.L().Warn("failed to parse port", zap.String("port", ipPort[portOffset]))
continue
}
portString = strconv.Itoa(int(portNum))
}
inodeMap[inode] = portString
// /proc/net/tcp file contains uid. Conversion to
// userName is required as they are keys to lookup tables.
userName, err := getUserName(uid)
if err != nil {
zap.L().Debug("Error converting to username", zap.Error(err))
continue
}
portMap := userMap[userName]
if portMap == nil {
portMap = map[string]bool{}
}
portMap[portString] = true
userMap[userName] = portMap
}
return inodeMap, userMap, nil
}
func (d *defaultRead) readOpenSockFD(pid string) []string {
var inodes []string
fdPath := "/proc/" + pid + "/fd/"
buffer, err := ioutil.ReadDir(fdPath)
if err != nil {
zap.L().Warn("Failed to read", zap.String("file", fdPath), zap.Error(err))
return nil
}
for _, f := range buffer {
link, err := os.Readlink(fdPath + f.Name())
if err != nil {
zap.L().Warn("Failed to read", zap.String("file", fdPath+f.Name()))
continue
}
if strings.Contains(link, "socket:") {
socketInode := strings.Split(link, ":")
if len(socketInode) < minimumFields {
zap.L().Warn("Failed to parse socket inodes")
continue
}
inodeString := socketInode[1]
inodeString = strings.TrimSuffix(inodeString, "]")
inodeString = strings.TrimPrefix(inodeString, "[")
inodes = append(inodes, inodeString)
}
}
return inodes
}
func (d *defaultRead) getCgroupList() []string {
return cgnetcls.GetCgroupList()
}
func (d *defaultRead) listCgroupProcesses(cgroupname string) ([]string, error) {
return cgnetcls.ListCgroupProcesses(cgroupname)
}