...

Source file src/golang.org/x/net/route/address.go

Documentation: golang.org/x/net/route

     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  //go:build darwin || dragonfly || freebsd || netbsd || openbsd
     6  
     7  package route
     8  
     9  import (
    10  	"runtime"
    11  	"syscall"
    12  )
    13  
    14  // An Addr represents an address associated with packet routing.
    15  type Addr interface {
    16  	// Family returns an address family.
    17  	Family() int
    18  }
    19  
    20  // A LinkAddr represents a link-layer address.
    21  type LinkAddr struct {
    22  	Index int    // interface index when attached
    23  	Name  string // interface name when attached
    24  	Addr  []byte // link-layer address when attached
    25  }
    26  
    27  // Family implements the Family method of Addr interface.
    28  func (a *LinkAddr) Family() int { return syscall.AF_LINK }
    29  
    30  func (a *LinkAddr) lenAndSpace() (int, int) {
    31  	l := 8 + len(a.Name) + len(a.Addr)
    32  	return l, roundup(l)
    33  }
    34  
    35  func (a *LinkAddr) marshal(b []byte) (int, error) {
    36  	l, ll := a.lenAndSpace()
    37  	if len(b) < ll {
    38  		return 0, errShortBuffer
    39  	}
    40  	nlen, alen := len(a.Name), len(a.Addr)
    41  	if nlen > 255 || alen > 255 {
    42  		return 0, errInvalidAddr
    43  	}
    44  	b[0] = byte(l)
    45  	b[1] = syscall.AF_LINK
    46  	if a.Index > 0 {
    47  		nativeEndian.PutUint16(b[2:4], uint16(a.Index))
    48  	}
    49  	data := b[8:]
    50  	if nlen > 0 {
    51  		b[5] = byte(nlen)
    52  		copy(data[:nlen], a.Name)
    53  		data = data[nlen:]
    54  	}
    55  	if alen > 0 {
    56  		b[6] = byte(alen)
    57  		copy(data[:alen], a.Addr)
    58  		data = data[alen:]
    59  	}
    60  	return ll, nil
    61  }
    62  
    63  func parseLinkAddr(b []byte) (Addr, error) {
    64  	if len(b) < 8 {
    65  		return nil, errInvalidAddr
    66  	}
    67  	_, a, err := parseKernelLinkAddr(syscall.AF_LINK, b[4:])
    68  	if err != nil {
    69  		return nil, err
    70  	}
    71  	a.(*LinkAddr).Index = int(nativeEndian.Uint16(b[2:4]))
    72  	return a, nil
    73  }
    74  
    75  // parseKernelLinkAddr parses b as a link-layer address in
    76  // conventional BSD kernel form.
    77  func parseKernelLinkAddr(_ int, b []byte) (int, Addr, error) {
    78  	// The encoding looks like the following:
    79  	// +----------------------------+
    80  	// | Type             (1 octet) |
    81  	// +----------------------------+
    82  	// | Name length      (1 octet) |
    83  	// +----------------------------+
    84  	// | Address length   (1 octet) |
    85  	// +----------------------------+
    86  	// | Selector length  (1 octet) |
    87  	// +----------------------------+
    88  	// | Data            (variable) |
    89  	// +----------------------------+
    90  	//
    91  	// On some platforms, all-bit-one of length field means "don't
    92  	// care".
    93  	nlen, alen, slen := int(b[1]), int(b[2]), int(b[3])
    94  	if nlen == 0xff {
    95  		nlen = 0
    96  	}
    97  	if alen == 0xff {
    98  		alen = 0
    99  	}
   100  	if slen == 0xff {
   101  		slen = 0
   102  	}
   103  	l := 4 + nlen + alen + slen
   104  	if len(b) < l {
   105  		return 0, nil, errInvalidAddr
   106  	}
   107  	data := b[4:]
   108  	var name string
   109  	var addr []byte
   110  	if nlen > 0 {
   111  		name = string(data[:nlen])
   112  		data = data[nlen:]
   113  	}
   114  	if alen > 0 {
   115  		addr = data[:alen]
   116  		data = data[alen:]
   117  	}
   118  	return l, &LinkAddr{Name: name, Addr: addr}, nil
   119  }
   120  
   121  // An Inet4Addr represents an internet address for IPv4.
   122  type Inet4Addr struct {
   123  	IP [4]byte // IP address
   124  }
   125  
   126  // Family implements the Family method of Addr interface.
   127  func (a *Inet4Addr) Family() int { return syscall.AF_INET }
   128  
   129  func (a *Inet4Addr) lenAndSpace() (int, int) {
   130  	return sizeofSockaddrInet, roundup(sizeofSockaddrInet)
   131  }
   132  
   133  func (a *Inet4Addr) marshal(b []byte) (int, error) {
   134  	l, ll := a.lenAndSpace()
   135  	if len(b) < ll {
   136  		return 0, errShortBuffer
   137  	}
   138  	b[0] = byte(l)
   139  	b[1] = syscall.AF_INET
   140  	copy(b[4:8], a.IP[:])
   141  	return ll, nil
   142  }
   143  
   144  // An Inet6Addr represents an internet address for IPv6.
   145  type Inet6Addr struct {
   146  	IP     [16]byte // IP address
   147  	ZoneID int      // zone identifier
   148  }
   149  
   150  // Family implements the Family method of Addr interface.
   151  func (a *Inet6Addr) Family() int { return syscall.AF_INET6 }
   152  
   153  func (a *Inet6Addr) lenAndSpace() (int, int) {
   154  	return sizeofSockaddrInet6, roundup(sizeofSockaddrInet6)
   155  }
   156  
   157  func (a *Inet6Addr) marshal(b []byte) (int, error) {
   158  	l, ll := a.lenAndSpace()
   159  	if len(b) < ll {
   160  		return 0, errShortBuffer
   161  	}
   162  	b[0] = byte(l)
   163  	b[1] = syscall.AF_INET6
   164  	copy(b[8:24], a.IP[:])
   165  	if a.ZoneID > 0 {
   166  		nativeEndian.PutUint32(b[24:28], uint32(a.ZoneID))
   167  	}
   168  	return ll, nil
   169  }
   170  
   171  // parseInetAddr parses b as an internet address for IPv4 or IPv6.
   172  func parseInetAddr(af int, b []byte) (Addr, error) {
   173  	const (
   174  		off4 = 4 // offset of in_addr
   175  		off6 = 8 // offset of in6_addr
   176  	)
   177  	switch af {
   178  	case syscall.AF_INET:
   179  		if len(b) < (off4+1) || len(b) < int(b[0]) || b[0] == 0 {
   180  			return nil, errInvalidAddr
   181  		}
   182  		sockAddrLen := int(b[0])
   183  		a := &Inet4Addr{}
   184  		n := off4 + 4
   185  		if sockAddrLen < n {
   186  			n = sockAddrLen
   187  		}
   188  		copy(a.IP[:], b[off4:n])
   189  		return a, nil
   190  	case syscall.AF_INET6:
   191  		if len(b) < (off6+1) || len(b) < int(b[0]) || b[0] == 0 {
   192  			return nil, errInvalidAddr
   193  		}
   194  		sockAddrLen := int(b[0])
   195  		n := off6 + 16
   196  		if sockAddrLen < n {
   197  			n = sockAddrLen
   198  		}
   199  		a := &Inet6Addr{}
   200  		if sockAddrLen == sizeofSockaddrInet6 {
   201  			a.ZoneID = int(nativeEndian.Uint32(b[24:28]))
   202  		}
   203  		copy(a.IP[:], b[off6:n])
   204  		if a.IP[0] == 0xfe && a.IP[1]&0xc0 == 0x80 || a.IP[0] == 0xff && (a.IP[1]&0x0f == 0x01 || a.IP[1]&0x0f == 0x02) {
   205  			// KAME based IPv6 protocol stack usually
   206  			// embeds the interface index in the
   207  			// interface-local or link-local address as
   208  			// the kernel-internal form.
   209  			id := int(bigEndian.Uint16(a.IP[2:4]))
   210  			if id != 0 {
   211  				a.ZoneID = id
   212  				a.IP[2], a.IP[3] = 0, 0
   213  			}
   214  		}
   215  		return a, nil
   216  	default:
   217  		return nil, errInvalidAddr
   218  	}
   219  }
   220  
   221  // parseKernelInetAddr parses b as an internet address in conventional
   222  // BSD kernel form.
   223  func parseKernelInetAddr(af int, b []byte) (int, Addr, error) {
   224  	// The encoding looks similar to the NLRI encoding.
   225  	// +----------------------------+
   226  	// | Length           (1 octet) |
   227  	// +----------------------------+
   228  	// | Address prefix  (variable) |
   229  	// +----------------------------+
   230  	//
   231  	// The differences between the kernel form and the NLRI
   232  	// encoding are:
   233  	//
   234  	// - The length field of the kernel form indicates the prefix
   235  	//   length in bytes, not in bits
   236  	//
   237  	// - In the kernel form, zero value of the length field
   238  	//   doesn't mean 0.0.0.0/0 or ::/0
   239  	//
   240  	// - The kernel form appends leading bytes to the prefix field
   241  	//   to make the <length, prefix> tuple to be conformed with
   242  	//   the routing message boundary
   243  	l := int(b[0])
   244  	if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
   245  		// On Darwin, an address in the kernel form is also
   246  		// used as a message filler.
   247  		if l == 0 || len(b) > roundup(l) {
   248  			l = roundup(l)
   249  		}
   250  	} else {
   251  		l = roundup(l)
   252  	}
   253  	if len(b) < l {
   254  		return 0, nil, errInvalidAddr
   255  	}
   256  	// Don't reorder case expressions.
   257  	// The case expressions for IPv6 must come first.
   258  	const (
   259  		off4 = 4 // offset of in_addr
   260  		off6 = 8 // offset of in6_addr
   261  	)
   262  	switch {
   263  	case b[0] == sizeofSockaddrInet6:
   264  		a := &Inet6Addr{}
   265  		copy(a.IP[:], b[off6:off6+16])
   266  		return int(b[0]), a, nil
   267  	case af == syscall.AF_INET6:
   268  		a := &Inet6Addr{}
   269  		if l-1 < off6 {
   270  			copy(a.IP[:], b[1:l])
   271  		} else {
   272  			copy(a.IP[:], b[l-off6:l])
   273  		}
   274  		return int(b[0]), a, nil
   275  	case b[0] == sizeofSockaddrInet:
   276  		a := &Inet4Addr{}
   277  		copy(a.IP[:], b[off4:off4+4])
   278  		return int(b[0]), a, nil
   279  	default: // an old fashion, AF_UNSPEC or unknown means AF_INET
   280  		a := &Inet4Addr{}
   281  		if l-1 < off4 {
   282  			copy(a.IP[:], b[1:l])
   283  		} else {
   284  			copy(a.IP[:], b[l-off4:l])
   285  		}
   286  		return int(b[0]), a, nil
   287  	}
   288  }
   289  
   290  // A DefaultAddr represents an address of various operating
   291  // system-specific features.
   292  type DefaultAddr struct {
   293  	af  int
   294  	Raw []byte // raw format of address
   295  }
   296  
   297  // Family implements the Family method of Addr interface.
   298  func (a *DefaultAddr) Family() int { return a.af }
   299  
   300  func (a *DefaultAddr) lenAndSpace() (int, int) {
   301  	l := len(a.Raw)
   302  	return l, roundup(l)
   303  }
   304  
   305  func (a *DefaultAddr) marshal(b []byte) (int, error) {
   306  	l, ll := a.lenAndSpace()
   307  	if len(b) < ll {
   308  		return 0, errShortBuffer
   309  	}
   310  	if l > 255 {
   311  		return 0, errInvalidAddr
   312  	}
   313  	b[1] = byte(l)
   314  	copy(b[:l], a.Raw)
   315  	return ll, nil
   316  }
   317  
   318  func parseDefaultAddr(b []byte) (Addr, error) {
   319  	if len(b) < 2 || len(b) < int(b[0]) {
   320  		return nil, errInvalidAddr
   321  	}
   322  	a := &DefaultAddr{af: int(b[1]), Raw: b[:b[0]]}
   323  	return a, nil
   324  }
   325  
   326  func addrsSpace(as []Addr) int {
   327  	var l int
   328  	for _, a := range as {
   329  		switch a := a.(type) {
   330  		case *LinkAddr:
   331  			_, ll := a.lenAndSpace()
   332  			l += ll
   333  		case *Inet4Addr:
   334  			_, ll := a.lenAndSpace()
   335  			l += ll
   336  		case *Inet6Addr:
   337  			_, ll := a.lenAndSpace()
   338  			l += ll
   339  		case *DefaultAddr:
   340  			_, ll := a.lenAndSpace()
   341  			l += ll
   342  		}
   343  	}
   344  	return l
   345  }
   346  
   347  // marshalAddrs marshals as and returns a bitmap indicating which
   348  // address is stored in b.
   349  func marshalAddrs(b []byte, as []Addr) (uint, error) {
   350  	var attrs uint
   351  	for i, a := range as {
   352  		switch a := a.(type) {
   353  		case *LinkAddr:
   354  			l, err := a.marshal(b)
   355  			if err != nil {
   356  				return 0, err
   357  			}
   358  			b = b[l:]
   359  			attrs |= 1 << uint(i)
   360  		case *Inet4Addr:
   361  			l, err := a.marshal(b)
   362  			if err != nil {
   363  				return 0, err
   364  			}
   365  			b = b[l:]
   366  			attrs |= 1 << uint(i)
   367  		case *Inet6Addr:
   368  			l, err := a.marshal(b)
   369  			if err != nil {
   370  				return 0, err
   371  			}
   372  			b = b[l:]
   373  			attrs |= 1 << uint(i)
   374  		case *DefaultAddr:
   375  			l, err := a.marshal(b)
   376  			if err != nil {
   377  				return 0, err
   378  			}
   379  			b = b[l:]
   380  			attrs |= 1 << uint(i)
   381  		}
   382  	}
   383  	return attrs, nil
   384  }
   385  
   386  func parseAddrs(attrs uint, fn func(int, []byte) (int, Addr, error), b []byte) ([]Addr, error) {
   387  	var as [syscall.RTAX_MAX]Addr
   388  	af := int(syscall.AF_UNSPEC)
   389  	for i := uint(0); i < syscall.RTAX_MAX && len(b) >= roundup(0); i++ {
   390  		if attrs&(1<<i) == 0 {
   391  			continue
   392  		}
   393  		if i <= syscall.RTAX_BRD {
   394  			switch b[1] {
   395  			case syscall.AF_LINK:
   396  				a, err := parseLinkAddr(b)
   397  				if err != nil {
   398  					return nil, err
   399  				}
   400  				as[i] = a
   401  				l := roundup(int(b[0]))
   402  				if len(b) < l {
   403  					return nil, errMessageTooShort
   404  				}
   405  				b = b[l:]
   406  			case syscall.AF_INET, syscall.AF_INET6:
   407  				// #70528: if the sockaddrlen is 0, no address to parse inside,
   408  				// skip over the record.
   409  				if b[0] > 0 {
   410  					af = int(b[1])
   411  					a, err := parseInetAddr(af, b)
   412  					if err != nil {
   413  						return nil, err
   414  					}
   415  					as[i] = a
   416  				}
   417  				l := roundup(int(b[0]))
   418  				if len(b) < l {
   419  					return nil, errMessageTooShort
   420  				}
   421  				b = b[l:]
   422  			default:
   423  				l, a, err := fn(af, b)
   424  				if err != nil {
   425  					return nil, err
   426  				}
   427  				as[i] = a
   428  				ll := roundup(l)
   429  				if len(b) < ll {
   430  					b = b[l:]
   431  				} else {
   432  					b = b[ll:]
   433  				}
   434  			}
   435  		} else {
   436  			a, err := parseDefaultAddr(b)
   437  			if err != nil {
   438  				return nil, err
   439  			}
   440  			as[i] = a
   441  			l := roundup(int(b[0]))
   442  			if len(b) < l {
   443  				return nil, errMessageTooShort
   444  			}
   445  			b = b[l:]
   446  		}
   447  	}
   448  	// The only remaining bytes in b should be alignment.
   449  	// However, under some circumstances DragonFly BSD appears to put
   450  	// more addresses in the message than are indicated in the address
   451  	// bitmask, so don't check for this.
   452  	return as[:], nil
   453  }
   454  

View as plain text