1
2
3
4
5 package route
6
7 import (
8 "syscall"
9 "unsafe"
10 )
11
12 func (typ RIBType) parseable() bool { return true }
13
14
15 type RouteMetrics struct {
16 PathMTU int
17 }
18
19
20 func (rmx *RouteMetrics) SysType() SysType { return SysMetrics }
21
22
23 func (m *RouteMessage) Sys() []Sys {
24 if kernelAlign == 8 {
25 return []Sys{
26 &RouteMetrics{
27 PathMTU: int(nativeEndian.Uint64(m.raw[m.extOff+8 : m.extOff+16])),
28 },
29 }
30 }
31 return []Sys{
32 &RouteMetrics{
33 PathMTU: int(nativeEndian.Uint32(m.raw[m.extOff+4 : m.extOff+8])),
34 },
35 }
36 }
37
38
39 type InterfaceMetrics struct {
40 Type int
41 MTU int
42 }
43
44
45 func (imx *InterfaceMetrics) SysType() SysType { return SysMetrics }
46
47
48 func (m *InterfaceMessage) Sys() []Sys {
49 return []Sys{
50 &InterfaceMetrics{
51 Type: int(m.raw[m.extOff]),
52 MTU: int(nativeEndian.Uint32(m.raw[m.extOff+8 : m.extOff+12])),
53 },
54 }
55 }
56
57 var compatFreeBSD32 bool
58
59 func probeRoutingStack() (int, map[int]*wireFormat) {
60 var p uintptr
61 wordSize := int(unsafe.Sizeof(p))
62 align := wordSize
63
64
65
66
67 conf, _ := syscall.Sysctl("kern.conftxt")
68 for i, j := 0, 0; j < len(conf); j++ {
69 if conf[j] != '\n' {
70 continue
71 }
72 s := conf[i:j]
73 i = j + 1
74 if len(s) > len("machine") && s[:len("machine")] == "machine" {
75 s = s[len("machine"):]
76 for k := 0; k < len(s); k++ {
77 if s[k] == ' ' || s[k] == '\t' {
78 s = s[1:]
79 }
80 break
81 }
82 if s == "amd64" {
83 align = 8
84 }
85 break
86 }
87 }
88 if align != wordSize {
89 compatFreeBSD32 = true
90 }
91 var rtm, ifm, ifam, ifmam, ifanm *wireFormat
92 if compatFreeBSD32 {
93 rtm = &wireFormat{extOff: sizeofRtMsghdrFreeBSD10Emu - sizeofRtMetricsFreeBSD10Emu, bodyOff: sizeofRtMsghdrFreeBSD10Emu}
94 ifm = &wireFormat{extOff: 16}
95 ifam = &wireFormat{extOff: sizeofIfaMsghdrFreeBSD10Emu, bodyOff: sizeofIfaMsghdrFreeBSD10Emu}
96 ifmam = &wireFormat{extOff: sizeofIfmaMsghdrFreeBSD10Emu, bodyOff: sizeofIfmaMsghdrFreeBSD10Emu}
97 ifanm = &wireFormat{extOff: sizeofIfAnnouncemsghdrFreeBSD10Emu, bodyOff: sizeofIfAnnouncemsghdrFreeBSD10Emu}
98 } else {
99 rtm = &wireFormat{extOff: sizeofRtMsghdrFreeBSD10 - sizeofRtMetricsFreeBSD10, bodyOff: sizeofRtMsghdrFreeBSD10}
100 ifm = &wireFormat{extOff: 16}
101 ifam = &wireFormat{extOff: sizeofIfaMsghdrFreeBSD10, bodyOff: sizeofIfaMsghdrFreeBSD10}
102 ifmam = &wireFormat{extOff: sizeofIfmaMsghdrFreeBSD10, bodyOff: sizeofIfmaMsghdrFreeBSD10}
103 ifanm = &wireFormat{extOff: sizeofIfAnnouncemsghdrFreeBSD10, bodyOff: sizeofIfAnnouncemsghdrFreeBSD10}
104 }
105 rel, _ := syscall.SysctlUint32("kern.osreldate")
106 switch {
107 case rel < 800000:
108 if compatFreeBSD32 {
109 ifm.bodyOff = sizeofIfMsghdrFreeBSD7Emu
110 } else {
111 ifm.bodyOff = sizeofIfMsghdrFreeBSD7
112 }
113 case 800000 <= rel && rel < 900000:
114 if compatFreeBSD32 {
115 ifm.bodyOff = sizeofIfMsghdrFreeBSD8Emu
116 } else {
117 ifm.bodyOff = sizeofIfMsghdrFreeBSD8
118 }
119 case 900000 <= rel && rel < 1000000:
120 if compatFreeBSD32 {
121 ifm.bodyOff = sizeofIfMsghdrFreeBSD9Emu
122 } else {
123 ifm.bodyOff = sizeofIfMsghdrFreeBSD9
124 }
125 case 1000000 <= rel && rel < 1100000:
126 if compatFreeBSD32 {
127 ifm.bodyOff = sizeofIfMsghdrFreeBSD10Emu
128 } else {
129 ifm.bodyOff = sizeofIfMsghdrFreeBSD10
130 }
131 default:
132 if compatFreeBSD32 {
133 ifm.bodyOff = sizeofIfMsghdrFreeBSD11Emu
134 } else {
135 ifm.bodyOff = sizeofIfMsghdrFreeBSD11
136 }
137 }
138 rtm.parse = rtm.parseRouteMessage
139 ifm.parse = ifm.parseInterfaceMessage
140 ifam.parse = ifam.parseInterfaceAddrMessage
141 ifmam.parse = ifmam.parseInterfaceMulticastAddrMessage
142 ifanm.parse = ifanm.parseInterfaceAnnounceMessage
143 return align, map[int]*wireFormat{
144 syscall.RTM_ADD: rtm,
145 syscall.RTM_DELETE: rtm,
146 syscall.RTM_CHANGE: rtm,
147 syscall.RTM_GET: rtm,
148 syscall.RTM_LOSING: rtm,
149 syscall.RTM_REDIRECT: rtm,
150 syscall.RTM_MISS: rtm,
151 syscall.RTM_LOCK: rtm,
152 syscall.RTM_RESOLVE: rtm,
153 syscall.RTM_NEWADDR: ifam,
154 syscall.RTM_DELADDR: ifam,
155 syscall.RTM_IFINFO: ifm,
156 syscall.RTM_NEWMADDR: ifmam,
157 syscall.RTM_DELMADDR: ifmam,
158 syscall.RTM_IFANNOUNCE: ifanm,
159 }
160 }
161
View as plain text