github.com/lianghucheng/zrddz@v0.0.0-20200923083010-c71f680932e2/src/golang.org/x/net/route/sys_freebsd.go (about) 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 var compatFreeBSD32 bool // 386 emulation on amd64 58 59 func probeRoutingStack() (int, map[int]*wireFormat) { 60 var p uintptr 61 wordSize := int(unsafe.Sizeof(p)) 62 align := wordSize 63 // In the case of kern.supported_archs="amd64 i386", we need 64 // to know the underlying kernel's architecture because the 65 // alignment for routing facilities are set at the build time 66 // of the kernel. 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 // 386 emulation on amd64 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 if rel >= 1102000 { // see https://github.com/freebsd/freebsd/commit/027c7f4d66ff8d8c4a46c3665a5ee7d6d8462034#diff-ad4e5b7f1449ea3fc87bc97280de145b 138 align = wordSize 139 } 140 } 141 rtm.parse = rtm.parseRouteMessage 142 ifm.parse = ifm.parseInterfaceMessage 143 ifam.parse = ifam.parseInterfaceAddrMessage 144 ifmam.parse = ifmam.parseInterfaceMulticastAddrMessage 145 ifanm.parse = ifanm.parseInterfaceAnnounceMessage 146 return align, map[int]*wireFormat{ 147 sysRTM_ADD: rtm, 148 sysRTM_DELETE: rtm, 149 sysRTM_CHANGE: rtm, 150 sysRTM_GET: rtm, 151 sysRTM_LOSING: rtm, 152 sysRTM_REDIRECT: rtm, 153 sysRTM_MISS: rtm, 154 sysRTM_LOCK: rtm, 155 sysRTM_RESOLVE: rtm, 156 sysRTM_NEWADDR: ifam, 157 sysRTM_DELADDR: ifam, 158 sysRTM_IFINFO: ifm, 159 sysRTM_NEWMADDR: ifmam, 160 sysRTM_DELMADDR: ifmam, 161 sysRTM_IFANNOUNCE: ifanm, 162 } 163 }