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  }