github.com/zxy12/golang151_with_comment@v0.0.0-20190507085033-721809559d3c/syscall/route_bsd.go (about)

     1  // Copyright 2011 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  // +build darwin dragonfly freebsd netbsd openbsd
     6  
     7  package syscall
     8  
     9  import (
    10  	"runtime"
    11  	"unsafe"
    12  )
    13  
    14  var (
    15  	freebsdConfArch       string // "machine $arch" line in kern.conftxt on freebsd
    16  	minRoutingSockaddrLen = rsaAlignOf(0)
    17  )
    18  
    19  // Round the length of a raw sockaddr up to align it properly.
    20  func rsaAlignOf(salen int) int {
    21  	salign := sizeofPtr
    22  	if darwin64Bit {
    23  		// Darwin kernels require 32-bit aligned access to
    24  		// routing facilities.
    25  		salign = 4
    26  	} else if netbsd32Bit {
    27  		// NetBSD 6 and beyond kernels require 64-bit aligned
    28  		// access to routing facilities.
    29  		salign = 8
    30  	} else if runtime.GOOS == "freebsd" {
    31  		// In the case of kern.supported_archs="amd64 i386",
    32  		// we need to know the underlying kernel's
    33  		// architecture because the alignment for routing
    34  		// facilities are set at the build time of the kernel.
    35  		if freebsdConfArch == "amd64" {
    36  			salign = 8
    37  		}
    38  	}
    39  	if salen == 0 {
    40  		return salign
    41  	}
    42  	return (salen + salign - 1) & ^(salign - 1)
    43  }
    44  
    45  // parseSockaddrLink parses b as a datalink socket address.
    46  func parseSockaddrLink(b []byte) (*SockaddrDatalink, error) {
    47  	sa, _, err := parseLinkLayerAddr(b[4:])
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  	rsa := (*RawSockaddrDatalink)(unsafe.Pointer(&b[0]))
    52  	sa.Len = rsa.Len
    53  	sa.Family = rsa.Family
    54  	sa.Index = rsa.Index
    55  	return sa, nil
    56  }
    57  
    58  // parseLinkLayerAddr parses b as a datalink socket address in
    59  // conventional BSD kernel form.
    60  func parseLinkLayerAddr(b []byte) (*SockaddrDatalink, int, error) {
    61  	// The encoding looks like the following:
    62  	// +----------------------------+
    63  	// | Type             (1 octet) |
    64  	// +----------------------------+
    65  	// | Name length      (1 octet) |
    66  	// +----------------------------+
    67  	// | Address length   (1 octet) |
    68  	// +----------------------------+
    69  	// | Selector length  (1 octet) |
    70  	// +----------------------------+
    71  	// | Data            (variable) |
    72  	// +----------------------------+
    73  	type linkLayerAddr struct {
    74  		Type byte
    75  		Nlen byte
    76  		Alen byte
    77  		Slen byte
    78  	}
    79  	lla := (*linkLayerAddr)(unsafe.Pointer(&b[0]))
    80  	l := rsaAlignOf(int(4 + lla.Nlen + lla.Alen + lla.Slen))
    81  	if len(b) < l {
    82  		return nil, 0, EINVAL
    83  	}
    84  	b = b[4:]
    85  	sa := &SockaddrDatalink{Type: lla.Type, Nlen: lla.Nlen, Alen: lla.Alen, Slen: lla.Slen}
    86  	for i := 0; len(sa.Data) > i && i < int(lla.Nlen+lla.Alen+lla.Slen); i++ {
    87  		sa.Data[i] = int8(b[i])
    88  	}
    89  	return sa, l, nil
    90  }
    91  
    92  // parseSockaddrInet parses b as an internet socket address.
    93  func parseSockaddrInet(b []byte, family byte) (Sockaddr, error) {
    94  	switch family {
    95  	case AF_INET:
    96  		if len(b) < SizeofSockaddrInet4 {
    97  			return nil, EINVAL
    98  		}
    99  		rsa := (*RawSockaddrAny)(unsafe.Pointer(&b[0]))
   100  		return anyToSockaddr(rsa)
   101  	case AF_INET6:
   102  		if len(b) < SizeofSockaddrInet6 {
   103  			return nil, EINVAL
   104  		}
   105  		rsa := (*RawSockaddrAny)(unsafe.Pointer(&b[0]))
   106  		return anyToSockaddr(rsa)
   107  	default:
   108  		return nil, EINVAL
   109  	}
   110  }
   111  
   112  const (
   113  	offsetofInet4 = int(unsafe.Offsetof(RawSockaddrInet4{}.Addr))
   114  	offsetofInet6 = int(unsafe.Offsetof(RawSockaddrInet6{}.Addr))
   115  )
   116  
   117  // parseNetworkLayerAddr parses b as an internet socket address in
   118  // conventional BSD kernel form.
   119  func parseNetworkLayerAddr(b []byte, family byte) (Sockaddr, error) {
   120  	// The encoding looks similar to the NLRI encoding.
   121  	// +----------------------------+
   122  	// | Length           (1 octet) |
   123  	// +----------------------------+
   124  	// | Address prefix  (variable) |
   125  	// +----------------------------+
   126  	//
   127  	// The differences between the kernel form and the NLRI
   128  	// encoding are:
   129  	//
   130  	// - The length field of the kernel form indicates the prefix
   131  	//   length in bytes, not in bits
   132  	//
   133  	// - In the kernel form, zero value of the length field
   134  	//   doesn't mean 0.0.0.0/0 or ::/0
   135  	//
   136  	// - The kernel form appends leading bytes to the prefix field
   137  	//   to make the <length, prefix> tuple to be conformed with
   138  	//   the routing messeage boundary
   139  	l := int(rsaAlignOf(int(b[0])))
   140  	if len(b) < l {
   141  		return nil, EINVAL
   142  	}
   143  	// Don't reorder case expressions.
   144  	// The case expressions for IPv6 must come first.
   145  	switch {
   146  	case b[0] == SizeofSockaddrInet6:
   147  		sa := &SockaddrInet6{}
   148  		copy(sa.Addr[:], b[offsetofInet6:])
   149  		return sa, nil
   150  	case family == AF_INET6:
   151  		sa := &SockaddrInet6{}
   152  		if l-1 < offsetofInet6 {
   153  			copy(sa.Addr[:], b[1:l])
   154  		} else {
   155  			copy(sa.Addr[:], b[l-offsetofInet6:l])
   156  		}
   157  		return sa, nil
   158  	case b[0] == SizeofSockaddrInet4:
   159  		sa := &SockaddrInet4{}
   160  		copy(sa.Addr[:], b[offsetofInet4:])
   161  		return sa, nil
   162  	default: // an old fashion, AF_UNSPEC or unknown means AF_INET
   163  		sa := &SockaddrInet4{}
   164  		if l-1 < offsetofInet4 {
   165  			copy(sa.Addr[:], b[1:l])
   166  		} else {
   167  			copy(sa.Addr[:], b[l-offsetofInet4:l])
   168  		}
   169  		return sa, nil
   170  	}
   171  }
   172  
   173  // RouteRIB returns routing information base, as known as RIB,
   174  // which consists of network facility information, states and
   175  // parameters.
   176  func RouteRIB(facility, param int) ([]byte, error) {
   177  	mib := []_C_int{CTL_NET, AF_ROUTE, 0, 0, _C_int(facility), _C_int(param)}
   178  	// Find size.
   179  	n := uintptr(0)
   180  	if err := sysctl(mib, nil, &n, nil, 0); err != nil {
   181  		return nil, err
   182  	}
   183  	if n == 0 {
   184  		return nil, nil
   185  	}
   186  	tab := make([]byte, n)
   187  	if err := sysctl(mib, &tab[0], &n, nil, 0); err != nil {
   188  		return nil, err
   189  	}
   190  	return tab[:n], nil
   191  }
   192  
   193  // RoutingMessage represents a routing message.
   194  type RoutingMessage interface {
   195  	sockaddr() ([]Sockaddr, error)
   196  }
   197  
   198  const anyMessageLen = int(unsafe.Sizeof(anyMessage{}))
   199  
   200  type anyMessage struct {
   201  	Msglen  uint16
   202  	Version uint8
   203  	Type    uint8
   204  }
   205  
   206  // RouteMessage represents a routing message containing routing
   207  // entries.
   208  type RouteMessage struct {
   209  	Header RtMsghdr
   210  	Data   []byte
   211  }
   212  
   213  func (m *RouteMessage) sockaddr() ([]Sockaddr, error) {
   214  	var sas [RTAX_MAX]Sockaddr
   215  	b := m.Data[:]
   216  	family := uint8(AF_UNSPEC)
   217  	for i := uint(0); i < RTAX_MAX && len(b) >= minRoutingSockaddrLen; i++ {
   218  		if m.Header.Addrs&(1<<i) == 0 {
   219  			continue
   220  		}
   221  		rsa := (*RawSockaddr)(unsafe.Pointer(&b[0]))
   222  		switch rsa.Family {
   223  		case AF_LINK:
   224  			sa, err := parseSockaddrLink(b)
   225  			if err != nil {
   226  				return nil, err
   227  			}
   228  			sas[i] = sa
   229  			b = b[rsaAlignOf(int(rsa.Len)):]
   230  		case AF_INET, AF_INET6:
   231  			sa, err := parseSockaddrInet(b, rsa.Family)
   232  			if err != nil {
   233  				return nil, err
   234  			}
   235  			sas[i] = sa
   236  			b = b[rsaAlignOf(int(rsa.Len)):]
   237  			family = rsa.Family
   238  		default:
   239  			sa, err := parseNetworkLayerAddr(b, family)
   240  			if err != nil {
   241  				return nil, err
   242  			}
   243  			sas[i] = sa
   244  			b = b[rsaAlignOf(int(b[0])):]
   245  		}
   246  	}
   247  	return sas[:], nil
   248  }
   249  
   250  // InterfaceMessage represents a routing message containing
   251  // network interface entries.
   252  type InterfaceMessage struct {
   253  	Header IfMsghdr
   254  	Data   []byte
   255  }
   256  
   257  func (m *InterfaceMessage) sockaddr() ([]Sockaddr, error) {
   258  	var sas [RTAX_MAX]Sockaddr
   259  	if m.Header.Addrs&RTA_IFP == 0 {
   260  		return nil, nil
   261  	}
   262  	sa, err := parseSockaddrLink(m.Data[:])
   263  	if err != nil {
   264  		return nil, err
   265  	}
   266  	sas[RTAX_IFP] = sa
   267  	return sas[:], nil
   268  }
   269  
   270  // InterfaceAddrMessage represents a routing message containing
   271  // network interface address entries.
   272  type InterfaceAddrMessage struct {
   273  	Header IfaMsghdr
   274  	Data   []byte
   275  }
   276  
   277  func (m *InterfaceAddrMessage) sockaddr() ([]Sockaddr, error) {
   278  	var sas [RTAX_MAX]Sockaddr
   279  	b := m.Data[:]
   280  	family := uint8(AF_UNSPEC)
   281  	for i := uint(0); i < RTAX_MAX && len(b) >= minRoutingSockaddrLen; i++ {
   282  		if m.Header.Addrs&(1<<i) == 0 {
   283  			continue
   284  		}
   285  		rsa := (*RawSockaddr)(unsafe.Pointer(&b[0]))
   286  		switch rsa.Family {
   287  		case AF_LINK:
   288  			sa, err := parseSockaddrLink(b)
   289  			if err != nil {
   290  				return nil, err
   291  			}
   292  			sas[i] = sa
   293  			b = b[rsaAlignOf(int(rsa.Len)):]
   294  		case AF_INET, AF_INET6:
   295  			sa, err := parseSockaddrInet(b, rsa.Family)
   296  			if err != nil {
   297  				return nil, err
   298  			}
   299  			sas[i] = sa
   300  			b = b[rsaAlignOf(int(rsa.Len)):]
   301  			family = rsa.Family
   302  		default:
   303  			sa, err := parseNetworkLayerAddr(b, family)
   304  			if err != nil {
   305  				return nil, err
   306  			}
   307  			sas[i] = sa
   308  			b = b[rsaAlignOf(int(b[0])):]
   309  		}
   310  	}
   311  	return sas[:], nil
   312  }
   313  
   314  // ParseRoutingMessage parses b as routing messages and returns the
   315  // slice containing the RoutingMessage interfaces.
   316  func ParseRoutingMessage(b []byte) (msgs []RoutingMessage, err error) {
   317  	nmsgs, nskips := 0, 0
   318  	for len(b) >= anyMessageLen {
   319  		nmsgs++
   320  		any := (*anyMessage)(unsafe.Pointer(&b[0]))
   321  		if any.Version != RTM_VERSION {
   322  			b = b[any.Msglen:]
   323  			continue
   324  		}
   325  		if m := any.toRoutingMessage(b); m == nil {
   326  			nskips++
   327  		} else {
   328  			msgs = append(msgs, m)
   329  		}
   330  		b = b[any.Msglen:]
   331  	}
   332  	// We failed to parse any of the messages - version mismatch?
   333  	if nmsgs != len(msgs)+nskips {
   334  		return nil, EINVAL
   335  	}
   336  	return msgs, nil
   337  }
   338  
   339  // ParseRoutingMessage parses msg's payload as raw sockaddrs and
   340  // returns the slice containing the Sockaddr interfaces.
   341  func ParseRoutingSockaddr(msg RoutingMessage) ([]Sockaddr, error) {
   342  	sas, err := msg.sockaddr()
   343  	if err != nil {
   344  		return nil, err
   345  	}
   346  	return sas, nil
   347  }