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