-
Notifications
You must be signed in to change notification settings - Fork 6
/
hostinfo.go
95 lines (83 loc) · 2.14 KB
/
hostinfo.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
package main
import (
"net"
"net/netip"
"os/exec"
"time"
"github.com/vishvananda/netlink"
"go.uber.org/zap"
"golang.org/x/sys/unix"
)
// HostInfo contains address information of the host machine.
type HostInfo struct {
HostMAC net.HardwareAddr
GatewayIP netip.Addr
}
func gatherHostInfo() (hi HostInfo, e error) {
logEntry := logger.Named("HostInfo")
hi.HostMAC = netif.HardwareAddr
logEntry.Info("found MAC", zap.Stringer("mac", hi.HostMAC))
nl, e := netlink.NewHandle()
if e != nil {
logEntry.Error("netlink.NewHandle error", zap.Error(e))
return hi, nil
}
defer nl.Close()
link, e := nl.LinkByIndex(netif.Index)
if e != nil {
logEntry.Error("netlink.LinkByIndex error", zap.Error(e))
return hi, nil
}
routes, e := nl.RouteList(link, unix.AF_INET6)
if e != nil {
logEntry.Error("netlink.RouteList error", zap.Error(e))
return hi, nil
}
for _, route := range routes {
maskLen := 0
if route.Dst != nil {
maskLen, _ = route.Dst.Mask.Size()
}
if maskLen == 0 {
hi.GatewayIP, _ = netip.AddrFromSlice(route.Gw)
}
}
if !hi.GatewayIP.IsValid() {
logEntry.Warn("no default gateway")
return hi, nil
}
logEntry.Info("found gateway", zap.Stringer("gateway", hi.GatewayIP))
var gatewayNeigh *netlink.Neigh
for {
neighs, e := nl.NeighList(netif.Index, unix.AF_INET6)
if e != nil {
logEntry.Error("netlink.NeighList error", zap.Error(e))
return hi, nil
}
for _, neigh := range neighs {
ip, _ := netip.AddrFromSlice(neigh.IP)
if ip != hi.GatewayIP || len(neigh.HardwareAddr) != 6 {
continue
}
switch neigh.State {
case unix.NUD_REACHABLE, unix.NUD_NOARP:
gatewayNeigh = &neigh
goto NEIGH_SET
case unix.NUD_PERMANENT:
goto NEIGH_SKIP
}
}
exec.Command("/usr/bin/ping", "-c", "1", hi.GatewayIP.String()).Run()
logEntry.Debug("waiting for gateway neigh entry")
time.Sleep(time.Second)
}
NEIGH_SET:
gatewayNeigh.State = unix.NUD_NOARP
if e = nl.NeighSet(gatewayNeigh); e != nil {
logEntry.Error("netlink.NeighSet error", zap.Error(e))
} else {
logEntry.Info("netlink.NeighSet OK", zap.Stringer("lladdr", gatewayNeigh.HardwareAddr))
}
NEIGH_SKIP:
return hi, nil
}