-
Notifications
You must be signed in to change notification settings - Fork 7
/
state_linux.go
74 lines (61 loc) · 1.69 KB
/
state_linux.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
package main
import (
"bufio"
"fmt"
"log"
"os"
"strconv"
"strings"
)
func getStateFile() string {
homedir, _ := os.UserHomeDir()
gateways := findGateways()
if len(gateways) == 1 {
mac := findMacFromIPInArpTable(gateways[0])
return fmt.Sprintf("%s/.pnmap/state-%s-%s.json", homedir, mac, gateways[0])
}
// If we have multiple - or zero - gateways, we fall-back to a generic state file.
return fmt.Sprintf("%s/.pnmap/state.json", homedir)
}
// find gateways
func findGateways() []string {
file, err := os.Open("/proc/net/route")
if err != nil {
log.Fatalf("Failed to open /proc/net/route")
}
defer file.Close()
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines)
var gateways []string
scanner.Scan() // skip first line as it's a header
for scanner.Scan() {
s := strings.Fields(scanner.Text())
if s[1] == "00000000" && s[7] == "00000000" {
octet0, _ := strconv.ParseInt(s[2][6:8], 16, 64)
octet1, _ := strconv.ParseInt(s[2][4:6], 16, 64)
octet2, _ := strconv.ParseInt(s[2][2:4], 16, 64)
octet3, _ := strconv.ParseInt(s[2][0:2], 16, 64)
gateway := fmt.Sprintf("%d.%d.%d.%d", octet0, octet1, octet2, octet3)
gateways = append(gateways, gateway)
}
}
return gateways
}
// find the gateway in the arp table
func findMacFromIPInArpTable(ip string) string {
file, err := os.Open("/proc/net/arp")
if err != nil {
log.Fatalf("Failed to open /proc/net/route")
}
defer file.Close()
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines)
scanner.Scan() // skip first line as it's a header
for scanner.Scan() {
s := strings.Fields(scanner.Text())
if s[0] == ip {
return string(s[3]) // we don't expect to find more than one
}
}
return ""
}