OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / net / route / sys_freebsd.go
1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package route
6
7 import (
8         "syscall"
9         "unsafe"
10 )
11
12 func (typ RIBType) parseable() bool { return true }
13
14 // RouteMetrics represents route metrics.
15 type RouteMetrics struct {
16         PathMTU int // path maximum transmission unit
17 }
18
19 // SysType implements the SysType method of Sys interface.
20 func (rmx *RouteMetrics) SysType() SysType { return SysMetrics }
21
22 // Sys implements the Sys method of Message interface.
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 // InterfaceMetrics represents interface metrics.
39 type InterfaceMetrics struct {
40         Type int // interface type
41         MTU  int // maximum transmission unit
42 }
43
44 // SysType implements the SysType method of Sys interface.
45 func (imx *InterfaceMetrics) SysType() SysType { return SysMetrics }
46
47 // Sys implements the Sys method of Message interface.
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 func probeRoutingStack() (int, map[int]*wireFormat) {
58         var p uintptr
59         wordSize := int(unsafe.Sizeof(p))
60         align := int(unsafe.Sizeof(p))
61         // In the case of kern.supported_archs="amd64 i386", we need
62         // to know the underlying kernel's architecture because the
63         // alignment for routing facilities are set at the build time
64         // of the kernel.
65         conf, _ := syscall.Sysctl("kern.conftxt")
66         for i, j := 0, 0; j < len(conf); j++ {
67                 if conf[j] != '\n' {
68                         continue
69                 }
70                 s := conf[i:j]
71                 i = j + 1
72                 if len(s) > len("machine") && s[:len("machine")] == "machine" {
73                         s = s[len("machine"):]
74                         for k := 0; k < len(s); k++ {
75                                 if s[k] == ' ' || s[k] == '\t' {
76                                         s = s[1:]
77                                 }
78                                 break
79                         }
80                         if s == "amd64" {
81                                 align = 8
82                         }
83                         break
84                 }
85         }
86         var rtm, ifm, ifam, ifmam, ifanm *wireFormat
87         if align != wordSize { // 386 emulation on amd64
88                 rtm = &wireFormat{extOff: sizeofRtMsghdrFreeBSD10Emu - sizeofRtMetricsFreeBSD10Emu, bodyOff: sizeofRtMsghdrFreeBSD10Emu}
89                 ifm = &wireFormat{extOff: 16}
90                 ifam = &wireFormat{extOff: sizeofIfaMsghdrFreeBSD10Emu, bodyOff: sizeofIfaMsghdrFreeBSD10Emu}
91                 ifmam = &wireFormat{extOff: sizeofIfmaMsghdrFreeBSD10Emu, bodyOff: sizeofIfmaMsghdrFreeBSD10Emu}
92                 ifanm = &wireFormat{extOff: sizeofIfAnnouncemsghdrFreeBSD10Emu, bodyOff: sizeofIfAnnouncemsghdrFreeBSD10Emu}
93         } else {
94                 rtm = &wireFormat{extOff: sizeofRtMsghdrFreeBSD10 - sizeofRtMetricsFreeBSD10, bodyOff: sizeofRtMsghdrFreeBSD10}
95                 ifm = &wireFormat{extOff: 16}
96                 ifam = &wireFormat{extOff: sizeofIfaMsghdrFreeBSD10, bodyOff: sizeofIfaMsghdrFreeBSD10}
97                 ifmam = &wireFormat{extOff: sizeofIfmaMsghdrFreeBSD10, bodyOff: sizeofIfmaMsghdrFreeBSD10}
98                 ifanm = &wireFormat{extOff: sizeofIfAnnouncemsghdrFreeBSD10, bodyOff: sizeofIfAnnouncemsghdrFreeBSD10}
99         }
100         rel, _ := syscall.SysctlUint32("kern.osreldate")
101         switch {
102         case rel < 800000:
103                 if align != wordSize { // 386 emulation on amd64
104                         ifm.bodyOff = sizeofIfMsghdrFreeBSD7Emu
105                 } else {
106                         ifm.bodyOff = sizeofIfMsghdrFreeBSD7
107                 }
108         case 800000 <= rel && rel < 900000:
109                 if align != wordSize { // 386 emulation on amd64
110                         ifm.bodyOff = sizeofIfMsghdrFreeBSD8Emu
111                 } else {
112                         ifm.bodyOff = sizeofIfMsghdrFreeBSD8
113                 }
114         case 900000 <= rel && rel < 1000000:
115                 if align != wordSize { // 386 emulation on amd64
116                         ifm.bodyOff = sizeofIfMsghdrFreeBSD9Emu
117                 } else {
118                         ifm.bodyOff = sizeofIfMsghdrFreeBSD9
119                 }
120         case 1000000 <= rel && rel < 1100000:
121                 if align != wordSize { // 386 emulation on amd64
122                         ifm.bodyOff = sizeofIfMsghdrFreeBSD10Emu
123                 } else {
124                         ifm.bodyOff = sizeofIfMsghdrFreeBSD10
125                 }
126         default:
127                 if align != wordSize { // 386 emulation on amd64
128                         ifm.bodyOff = sizeofIfMsghdrFreeBSD11Emu
129                 } else {
130                         ifm.bodyOff = sizeofIfMsghdrFreeBSD11
131                 }
132         }
133         rtm.parse = rtm.parseRouteMessage
134         ifm.parse = ifm.parseInterfaceMessage
135         ifam.parse = ifam.parseInterfaceAddrMessage
136         ifmam.parse = ifmam.parseInterfaceMulticastAddrMessage
137         ifanm.parse = ifanm.parseInterfaceAnnounceMessage
138         return align, map[int]*wireFormat{
139                 sysRTM_ADD:        rtm,
140                 sysRTM_DELETE:     rtm,
141                 sysRTM_CHANGE:     rtm,
142                 sysRTM_GET:        rtm,
143                 sysRTM_LOSING:     rtm,
144                 sysRTM_REDIRECT:   rtm,
145                 sysRTM_MISS:       rtm,
146                 sysRTM_LOCK:       rtm,
147                 sysRTM_RESOLVE:    rtm,
148                 sysRTM_NEWADDR:    ifam,
149                 sysRTM_DELADDR:    ifam,
150                 sysRTM_IFINFO:     ifm,
151                 sysRTM_NEWMADDR:   ifmam,
152                 sysRTM_DELMADDR:   ifmam,
153                 sysRTM_IFANNOUNCE: ifanm,
154         }
155 }