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