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
|
package main
import (
"encoding/hex"
"fmt"
"net"
"os/exec"
"strings"
"syscall"
"unsafe"
)
type router struct {
ifaces []net.Interface
addrs []net.IP
v6 routeSlice
}
type routeSlice []*rtInfo
type rtInfo struct {
// Dst net.IPNet
Gateway, PrefSrc net.IP
OutputIface uint32
Priority uint32
}
func getv6Gateway() (net.IP, error) {
rtr := &router{}
tab, err := syscall.NetlinkRIB(syscall.RTM_GETROUTE, syscall.AF_INET6)
if err != nil {
return nil, err
}
msgs, err := syscall.ParseNetlinkMessage(tab)
if err != nil {
return nil, err
}
for _, m := range msgs {
switch m.Header.Type {
case syscall.NLMSG_DONE:
break
case syscall.RTM_NEWROUTE:
// rtmsg := (*syscall.RtMsg)(unsafe.Pointer(&m.Data[0]))
attrs, err := syscall.ParseNetlinkRouteAttr(&m)
if err != nil {
return nil, err
}
routeInfo := rtInfo{}
rtr.v6 = append(rtr.v6, &routeInfo)
for _, attr := range attrs {
switch attr.Attr.Type {
// case syscall.RTA_DST:
// routeInfo.Dst.IP = net.IP(attr.Value)
// routeInfo.Dst.Mask = net.CIDRMask(int(rtmsg.Dst_len), len(attr.Value)*8)
case syscall.RTA_GATEWAY:
routeInfo.Gateway = net.IP(attr.Value)
case syscall.RTA_OIF:
routeInfo.OutputIface = *(*uint32)(unsafe.Pointer(&attr.Value[0]))
case syscall.RTA_PRIORITY:
routeInfo.Priority = *(*uint32)(unsafe.Pointer(&attr.Value[0]))
case syscall.RTA_PREFSRC:
routeInfo.PrefSrc = net.IP(attr.Value)
}
}
}
}
ips := []net.IP{}
for _, rt := range rtr.v6 {
if rt.Gateway != nil {
ips = append(ips, rt.Gateway)
}
}
return ips[0], nil
}
func getGatewayV6Mac(ifacename string, gwIP net.IP) (net.HardwareAddr, error) {
if debugOutput {
println("邻居发现--使用网卡接口为:" + ifacename)
}
out, err := exec.Command("ip", "-6", "neighbor", "show", "dev", ifacename).Output()
if err != nil {
println(err.Error())
} else {
outlines := strings.Split(string(out), "/n")
for _, line := range outlines {
linelist := strings.Split(line, " ")
// 与网关对应的MAC地址
if linelist[0] == gwIP.String() {
maclist := strings.Split(linelist[2], ":")
var macbyte []byte
for _, m := range maclist {
b, _ := hex.DecodeString(m)
macbyte = append(macbyte, b[0])
}
return net.HardwareAddr(macbyte), nil
}
}
}
return nil, fmt.Errorf("无法找到网关" + gwIP.String() + "对应的MAC地址")
}
|