forked from weaveworks/procspy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
spy_darwin.go
62 lines (56 loc) · 1.39 KB
/
spy_darwin.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
package procspy
import (
"net"
"os/exec"
"strconv"
)
const (
netstatBinary = "netstat"
lsofBinary = "lsof"
)
// Connections returns all established (TCP) connections. No need to be root
// to run this. If processes is true it also tries to fill in the process
// fields of the connection. You need to be root to find all processes.
var cbConnections = func(processes bool) (ConnIter, error) {
out, err := exec.Command(
netstatBinary,
"-n", // no number resolving
"-W", // Wide output
// "-l", // full IPv6 addresses // What does this do?
"-p", "tcp", // only TCP
).CombinedOutput()
if err != nil {
// log.Printf("lsof error: %s", err)
return nil, err
}
connections := parseDarwinNetstat(string(out))
if processes {
out, err := exec.Command(
lsofBinary,
"-i", // only Internet files
"-n", "-P", // no number resolving
"-w", // no warnings
"-F", lsofFields, // \n based output of only the fields we want.
).CombinedOutput()
if err != nil {
return nil, err
}
procs, err := parseLSOF(string(out))
if err != nil {
return nil, err
}
for local, proc := range procs {
for i, c := range connections {
localAddr := net.JoinHostPort(
c.LocalAddress.String(),
strconv.Itoa(int(c.LocalPort)),
)
if localAddr == local {
connections[i].Proc = proc
}
}
}
}
f := fixedConnIter(connections)
return &f, nil
}