...

Source file src/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	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	}
   164	

View as plain text