github.com/lovishpuri/go-40569/src@v0.0.0-20230519171745-f8623e7c56cf/net/netip/netip.go (about)

     1  // Copyright 2020 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 netip defines an IP address type that's a small value type.
     6  // Building on that [Addr] type, the package also defines [AddrPort] (an
     7  // IP address and a port) and [Prefix] (an IP address and a bit length
     8  // prefix).
     9  //
    10  // Compared to the [net.IP] type, [Addr] type takes less memory, is immutable,
    11  // and is comparable (supports == and being a map key).
    12  package netip
    13  
    14  import (
    15  	"errors"
    16  	"math"
    17  	"strconv"
    18  
    19  	"internal/bytealg"
    20  	"internal/intern"
    21  	"internal/itoa"
    22  )
    23  
    24  // Sizes: (64-bit)
    25  //   net.IP:     24 byte slice header + {4, 16} = 28 to 40 bytes
    26  //   net.IPAddr: 40 byte slice header + {4, 16} = 44 to 56 bytes + zone length
    27  //   netip.Addr: 24 bytes (zone is per-name singleton, shared across all users)
    28  
    29  // Addr represents an IPv4 or IPv6 address (with or without a scoped
    30  // addressing zone), similar to [net.IP] or [net.IPAddr].
    31  //
    32  // Unlike [net.IP] or [net.IPAddr], Addr is a comparable value
    33  // type (it supports == and can be a map key) and is immutable.
    34  //
    35  // The zero Addr is not a valid IP address.
    36  // Addr{} is distinct from both 0.0.0.0 and ::.
    37  type Addr struct {
    38  	// addr is the hi and lo bits of an IPv6 address. If z==z4,
    39  	// hi and lo contain the IPv4-mapped IPv6 address.
    40  	//
    41  	// hi and lo are constructed by interpreting a 16-byte IPv6
    42  	// address as a big-endian 128-bit number. The most significant
    43  	// bits of that number go into hi, the rest into lo.
    44  	//
    45  	// For example, 0011:2233:4455:6677:8899:aabb:ccdd:eeff is stored as:
    46  	//  addr.hi = 0x0011223344556677
    47  	//  addr.lo = 0x8899aabbccddeeff
    48  	//
    49  	// We store IPs like this, rather than as [16]byte, because it
    50  	// turns most operations on IPs into arithmetic and bit-twiddling
    51  	// operations on 64-bit registers, which is much faster than
    52  	// bytewise processing.
    53  	addr uint128
    54  
    55  	// z is a combination of the address family and the IPv6 zone.
    56  	//
    57  	// nil means invalid IP address (for a zero Addr).
    58  	// z4 means an IPv4 address.
    59  	// z6noz means an IPv6 address without a zone.
    60  	//
    61  	// Otherwise it's the interned zone name string.
    62  	z *intern.Value
    63  }
    64  
    65  // z0, z4, and z6noz are sentinel Addr.z values.
    66  // See the Addr type's field docs.
    67  var (
    68  	z0    = (*intern.Value)(nil)
    69  	z4    = new(intern.Value)
    70  	z6noz = new(intern.Value)
    71  )
    72  
    73  // IPv6LinkLocalAllNodes returns the IPv6 link-local all nodes multicast
    74  // address ff02::1.
    75  func IPv6LinkLocalAllNodes() Addr { return AddrFrom16([16]byte{0: 0xff, 1: 0x02, 15: 0x01}) }
    76  
    77  // IPv6LinkLocalAllRouters returns the IPv6 link-local all routers multicast
    78  // address ff02::2.
    79  func IPv6LinkLocalAllRouters() Addr { return AddrFrom16([16]byte{0: 0xff, 1: 0x02, 15: 0x02}) }
    80  
    81  // IPv6Loopback returns the IPv6 loopback address ::1.
    82  func IPv6Loopback() Addr { return AddrFrom16([16]byte{15: 0x01}) }
    83  
    84  // IPv6Unspecified returns the IPv6 unspecified address "::".
    85  func IPv6Unspecified() Addr { return Addr{z: z6noz} }
    86  
    87  // IPv4Unspecified returns the IPv4 unspecified address "0.0.0.0".
    88  func IPv4Unspecified() Addr { return AddrFrom4([4]byte{}) }
    89  
    90  // AddrFrom4 returns the address of the IPv4 address given by the bytes in addr.
    91  func AddrFrom4(addr [4]byte) Addr {
    92  	return Addr{
    93  		addr: uint128{0, 0xffff00000000 | uint64(addr[0])<<24 | uint64(addr[1])<<16 | uint64(addr[2])<<8 | uint64(addr[3])},
    94  		z:    z4,
    95  	}
    96  }
    97  
    98  // AddrFrom16 returns the IPv6 address given by the bytes in addr.
    99  // An IPv4-mapped IPv6 address is left as an IPv6 address.
   100  // (Use Unmap to convert them if needed.)
   101  func AddrFrom16(addr [16]byte) Addr {
   102  	return Addr{
   103  		addr: uint128{
   104  			beUint64(addr[:8]),
   105  			beUint64(addr[8:]),
   106  		},
   107  		z: z6noz,
   108  	}
   109  }
   110  
   111  // ParseAddr parses s as an IP address, returning the result. The string
   112  // s can be in dotted decimal ("192.0.2.1"), IPv6 ("2001:db8::68"),
   113  // or IPv6 with a scoped addressing zone ("fe80::1cc0:3e8c:119f:c2e1%ens18").
   114  func ParseAddr(s string) (Addr, error) {
   115  	for i := 0; i < len(s); i++ {
   116  		switch s[i] {
   117  		case '.':
   118  			return parseIPv4(s)
   119  		case ':':
   120  			return parseIPv6(s)
   121  		case '%':
   122  			// Assume that this was trying to be an IPv6 address with
   123  			// a zone specifier, but the address is missing.
   124  			return Addr{}, parseAddrError{in: s, msg: "missing IPv6 address"}
   125  		}
   126  	}
   127  	return Addr{}, parseAddrError{in: s, msg: "unable to parse IP"}
   128  }
   129  
   130  // MustParseAddr calls ParseAddr(s) and panics on error.
   131  // It is intended for use in tests with hard-coded strings.
   132  func MustParseAddr(s string) Addr {
   133  	ip, err := ParseAddr(s)
   134  	if err != nil {
   135  		panic(err)
   136  	}
   137  	return ip
   138  }
   139  
   140  type parseAddrError struct {
   141  	in  string // the string given to ParseAddr
   142  	msg string // an explanation of the parse failure
   143  	at  string // optionally, the unparsed portion of in at which the error occurred.
   144  }
   145  
   146  func (err parseAddrError) Error() string {
   147  	q := strconv.Quote
   148  	if err.at != "" {
   149  		return "ParseAddr(" + q(err.in) + "): " + err.msg + " (at " + q(err.at) + ")"
   150  	}
   151  	return "ParseAddr(" + q(err.in) + "): " + err.msg
   152  }
   153  
   154  // parseIPv4 parses s as an IPv4 address (in form "192.168.0.1").
   155  func parseIPv4(s string) (ip Addr, err error) {
   156  	var fields [4]uint8
   157  	var val, pos int
   158  	var digLen int // number of digits in current octet
   159  	for i := 0; i < len(s); i++ {
   160  		if s[i] >= '0' && s[i] <= '9' {
   161  			if digLen == 1 && val == 0 {
   162  				return Addr{}, parseAddrError{in: s, msg: "IPv4 field has octet with leading zero"}
   163  			}
   164  			val = val*10 + int(s[i]) - '0'
   165  			digLen++
   166  			if val > 255 {
   167  				return Addr{}, parseAddrError{in: s, msg: "IPv4 field has value >255"}
   168  			}
   169  		} else if s[i] == '.' {
   170  			// .1.2.3
   171  			// 1.2.3.
   172  			// 1..2.3
   173  			if i == 0 || i == len(s)-1 || s[i-1] == '.' {
   174  				return Addr{}, parseAddrError{in: s, msg: "IPv4 field must have at least one digit", at: s[i:]}
   175  			}
   176  			// 1.2.3.4.5
   177  			if pos == 3 {
   178  				return Addr{}, parseAddrError{in: s, msg: "IPv4 address too long"}
   179  			}
   180  			fields[pos] = uint8(val)
   181  			pos++
   182  			val = 0
   183  			digLen = 0
   184  		} else {
   185  			return Addr{}, parseAddrError{in: s, msg: "unexpected character", at: s[i:]}
   186  		}
   187  	}
   188  	if pos < 3 {
   189  		return Addr{}, parseAddrError{in: s, msg: "IPv4 address too short"}
   190  	}
   191  	fields[3] = uint8(val)
   192  	return AddrFrom4(fields), nil
   193  }
   194  
   195  // parseIPv6 parses s as an IPv6 address (in form "2001:db8::68").
   196  func parseIPv6(in string) (Addr, error) {
   197  	s := in
   198  
   199  	// Split off the zone right from the start. Yes it's a second scan
   200  	// of the string, but trying to handle it inline makes a bunch of
   201  	// other inner loop conditionals more expensive, and it ends up
   202  	// being slower.
   203  	zone := ""
   204  	i := bytealg.IndexByteString(s, '%')
   205  	if i != -1 {
   206  		s, zone = s[:i], s[i+1:]
   207  		if zone == "" {
   208  			// Not allowed to have an empty zone if explicitly specified.
   209  			return Addr{}, parseAddrError{in: in, msg: "zone must be a non-empty string"}
   210  		}
   211  	}
   212  
   213  	var ip [16]byte
   214  	ellipsis := -1 // position of ellipsis in ip
   215  
   216  	// Might have leading ellipsis
   217  	if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
   218  		ellipsis = 0
   219  		s = s[2:]
   220  		// Might be only ellipsis
   221  		if len(s) == 0 {
   222  			return IPv6Unspecified().WithZone(zone), nil
   223  		}
   224  	}
   225  
   226  	// Loop, parsing hex numbers followed by colon.
   227  	i = 0
   228  	for i < 16 {
   229  		// Hex number. Similar to parseIPv4, inlining the hex number
   230  		// parsing yields a significant performance increase.
   231  		off := 0
   232  		acc := uint32(0)
   233  		for ; off < len(s); off++ {
   234  			c := s[off]
   235  			if c >= '0' && c <= '9' {
   236  				acc = (acc << 4) + uint32(c-'0')
   237  			} else if c >= 'a' && c <= 'f' {
   238  				acc = (acc << 4) + uint32(c-'a'+10)
   239  			} else if c >= 'A' && c <= 'F' {
   240  				acc = (acc << 4) + uint32(c-'A'+10)
   241  			} else {
   242  				break
   243  			}
   244  			if acc > math.MaxUint16 {
   245  				// Overflow, fail.
   246  				return Addr{}, parseAddrError{in: in, msg: "IPv6 field has value >=2^16", at: s}
   247  			}
   248  		}
   249  		if off == 0 {
   250  			// No digits found, fail.
   251  			return Addr{}, parseAddrError{in: in, msg: "each colon-separated field must have at least one digit", at: s}
   252  		}
   253  
   254  		// If followed by dot, might be in trailing IPv4.
   255  		if off < len(s) && s[off] == '.' {
   256  			if ellipsis < 0 && i != 12 {
   257  				// Not the right place.
   258  				return Addr{}, parseAddrError{in: in, msg: "embedded IPv4 address must replace the final 2 fields of the address", at: s}
   259  			}
   260  			if i+4 > 16 {
   261  				// Not enough room.
   262  				return Addr{}, parseAddrError{in: in, msg: "too many hex fields to fit an embedded IPv4 at the end of the address", at: s}
   263  			}
   264  			// TODO: could make this a bit faster by having a helper
   265  			// that parses to a [4]byte, and have both parseIPv4 and
   266  			// parseIPv6 use it.
   267  			ip4, err := parseIPv4(s)
   268  			if err != nil {
   269  				return Addr{}, parseAddrError{in: in, msg: err.Error(), at: s}
   270  			}
   271  			ip[i] = ip4.v4(0)
   272  			ip[i+1] = ip4.v4(1)
   273  			ip[i+2] = ip4.v4(2)
   274  			ip[i+3] = ip4.v4(3)
   275  			s = ""
   276  			i += 4
   277  			break
   278  		}
   279  
   280  		// Save this 16-bit chunk.
   281  		ip[i] = byte(acc >> 8)
   282  		ip[i+1] = byte(acc)
   283  		i += 2
   284  
   285  		// Stop at end of string.
   286  		s = s[off:]
   287  		if len(s) == 0 {
   288  			break
   289  		}
   290  
   291  		// Otherwise must be followed by colon and more.
   292  		if s[0] != ':' {
   293  			return Addr{}, parseAddrError{in: in, msg: "unexpected character, want colon", at: s}
   294  		} else if len(s) == 1 {
   295  			return Addr{}, parseAddrError{in: in, msg: "colon must be followed by more characters", at: s}
   296  		}
   297  		s = s[1:]
   298  
   299  		// Look for ellipsis.
   300  		if s[0] == ':' {
   301  			if ellipsis >= 0 { // already have one
   302  				return Addr{}, parseAddrError{in: in, msg: "multiple :: in address", at: s}
   303  			}
   304  			ellipsis = i
   305  			s = s[1:]
   306  			if len(s) == 0 { // can be at end
   307  				break
   308  			}
   309  		}
   310  	}
   311  
   312  	// Must have used entire string.
   313  	if len(s) != 0 {
   314  		return Addr{}, parseAddrError{in: in, msg: "trailing garbage after address", at: s}
   315  	}
   316  
   317  	// If didn't parse enough, expand ellipsis.
   318  	if i < 16 {
   319  		if ellipsis < 0 {
   320  			return Addr{}, parseAddrError{in: in, msg: "address string too short"}
   321  		}
   322  		n := 16 - i
   323  		for j := i - 1; j >= ellipsis; j-- {
   324  			ip[j+n] = ip[j]
   325  		}
   326  		for j := ellipsis + n - 1; j >= ellipsis; j-- {
   327  			ip[j] = 0
   328  		}
   329  	} else if ellipsis >= 0 {
   330  		// Ellipsis must represent at least one 0 group.
   331  		return Addr{}, parseAddrError{in: in, msg: "the :: must expand to at least one field of zeros"}
   332  	}
   333  	return AddrFrom16(ip).WithZone(zone), nil
   334  }
   335  
   336  // AddrFromSlice parses the 4- or 16-byte byte slice as an IPv4 or IPv6 address.
   337  // Note that a net.IP can be passed directly as the []byte argument.
   338  // If slice's length is not 4 or 16, AddrFromSlice returns Addr{}, false.
   339  func AddrFromSlice(slice []byte) (ip Addr, ok bool) {
   340  	switch len(slice) {
   341  	case 4:
   342  		return AddrFrom4([4]byte(slice)), true
   343  	case 16:
   344  		return AddrFrom16([16]byte(slice)), true
   345  	}
   346  	return Addr{}, false
   347  }
   348  
   349  // v4 returns the i'th byte of ip. If ip is not an IPv4, v4 returns
   350  // unspecified garbage.
   351  func (ip Addr) v4(i uint8) uint8 {
   352  	return uint8(ip.addr.lo >> ((3 - i) * 8))
   353  }
   354  
   355  // v6 returns the i'th byte of ip. If ip is an IPv4 address, this
   356  // accesses the IPv4-mapped IPv6 address form of the IP.
   357  func (ip Addr) v6(i uint8) uint8 {
   358  	return uint8(*(ip.addr.halves()[(i/8)%2]) >> ((7 - i%8) * 8))
   359  }
   360  
   361  // v6u16 returns the i'th 16-bit word of ip. If ip is an IPv4 address,
   362  // this accesses the IPv4-mapped IPv6 address form of the IP.
   363  func (ip Addr) v6u16(i uint8) uint16 {
   364  	return uint16(*(ip.addr.halves()[(i/4)%2]) >> ((3 - i%4) * 16))
   365  }
   366  
   367  // isZero reports whether ip is the zero value of the IP type.
   368  // The zero value is not a valid IP address of any type.
   369  //
   370  // Note that "0.0.0.0" and "::" are not the zero value. Use IsUnspecified to
   371  // check for these values instead.
   372  func (ip Addr) isZero() bool {
   373  	// Faster than comparing ip == Addr{}, but effectively equivalent,
   374  	// as there's no way to make an IP with a nil z from this package.
   375  	return ip.z == z0
   376  }
   377  
   378  // IsValid reports whether the Addr is an initialized address (not the zero Addr).
   379  //
   380  // Note that "0.0.0.0" and "::" are both valid values.
   381  func (ip Addr) IsValid() bool { return ip.z != z0 }
   382  
   383  // BitLen returns the number of bits in the IP address:
   384  // 128 for IPv6, 32 for IPv4, and 0 for the zero Addr.
   385  //
   386  // Note that IPv4-mapped IPv6 addresses are considered IPv6 addresses
   387  // and therefore have bit length 128.
   388  func (ip Addr) BitLen() int {
   389  	switch ip.z {
   390  	case z0:
   391  		return 0
   392  	case z4:
   393  		return 32
   394  	}
   395  	return 128
   396  }
   397  
   398  // Zone returns ip's IPv6 scoped addressing zone, if any.
   399  func (ip Addr) Zone() string {
   400  	if ip.z == nil {
   401  		return ""
   402  	}
   403  	zone, _ := ip.z.Get().(string)
   404  	return zone
   405  }
   406  
   407  // Compare returns an integer comparing two IPs.
   408  // The result will be 0 if ip == ip2, -1 if ip < ip2, and +1 if ip > ip2.
   409  // The definition of "less than" is the same as the Less method.
   410  func (ip Addr) Compare(ip2 Addr) int {
   411  	f1, f2 := ip.BitLen(), ip2.BitLen()
   412  	if f1 < f2 {
   413  		return -1
   414  	}
   415  	if f1 > f2 {
   416  		return 1
   417  	}
   418  	hi1, hi2 := ip.addr.hi, ip2.addr.hi
   419  	if hi1 < hi2 {
   420  		return -1
   421  	}
   422  	if hi1 > hi2 {
   423  		return 1
   424  	}
   425  	lo1, lo2 := ip.addr.lo, ip2.addr.lo
   426  	if lo1 < lo2 {
   427  		return -1
   428  	}
   429  	if lo1 > lo2 {
   430  		return 1
   431  	}
   432  	if ip.Is6() {
   433  		za, zb := ip.Zone(), ip2.Zone()
   434  		if za < zb {
   435  			return -1
   436  		}
   437  		if za > zb {
   438  			return 1
   439  		}
   440  	}
   441  	return 0
   442  }
   443  
   444  // Less reports whether ip sorts before ip2.
   445  // IP addresses sort first by length, then their address.
   446  // IPv6 addresses with zones sort just after the same address without a zone.
   447  func (ip Addr) Less(ip2 Addr) bool { return ip.Compare(ip2) == -1 }
   448  
   449  // Is4 reports whether ip is an IPv4 address.
   450  //
   451  // It returns false for IPv4-mapped IPv6 addresses. See Addr.Unmap.
   452  func (ip Addr) Is4() bool {
   453  	return ip.z == z4
   454  }
   455  
   456  // Is4In6 reports whether ip is an IPv4-mapped IPv6 address.
   457  func (ip Addr) Is4In6() bool {
   458  	return ip.Is6() && ip.addr.hi == 0 && ip.addr.lo>>32 == 0xffff
   459  }
   460  
   461  // Is6 reports whether ip is an IPv6 address, including IPv4-mapped
   462  // IPv6 addresses.
   463  func (ip Addr) Is6() bool {
   464  	return ip.z != z0 && ip.z != z4
   465  }
   466  
   467  // Unmap returns ip with any IPv4-mapped IPv6 address prefix removed.
   468  //
   469  // That is, if ip is an IPv6 address wrapping an IPv4 address, it
   470  // returns the wrapped IPv4 address. Otherwise it returns ip unmodified.
   471  func (ip Addr) Unmap() Addr {
   472  	if ip.Is4In6() {
   473  		ip.z = z4
   474  	}
   475  	return ip
   476  }
   477  
   478  // WithZone returns an IP that's the same as ip but with the provided
   479  // zone. If zone is empty, the zone is removed. If ip is an IPv4
   480  // address, WithZone is a no-op and returns ip unchanged.
   481  func (ip Addr) WithZone(zone string) Addr {
   482  	if !ip.Is6() {
   483  		return ip
   484  	}
   485  	if zone == "" {
   486  		ip.z = z6noz
   487  		return ip
   488  	}
   489  	ip.z = intern.GetByString(zone)
   490  	return ip
   491  }
   492  
   493  // withoutZone unconditionally strips the zone from ip.
   494  // It's similar to WithZone, but small enough to be inlinable.
   495  func (ip Addr) withoutZone() Addr {
   496  	if !ip.Is6() {
   497  		return ip
   498  	}
   499  	ip.z = z6noz
   500  	return ip
   501  }
   502  
   503  // hasZone reports whether ip has an IPv6 zone.
   504  func (ip Addr) hasZone() bool {
   505  	return ip.z != z0 && ip.z != z4 && ip.z != z6noz
   506  }
   507  
   508  // IsLinkLocalUnicast reports whether ip is a link-local unicast address.
   509  func (ip Addr) IsLinkLocalUnicast() bool {
   510  	// Dynamic Configuration of IPv4 Link-Local Addresses
   511  	// https://datatracker.ietf.org/doc/html/rfc3927#section-2.1
   512  	if ip.Is4() {
   513  		return ip.v4(0) == 169 && ip.v4(1) == 254
   514  	}
   515  	// IP Version 6 Addressing Architecture (2.4 Address Type Identification)
   516  	// https://datatracker.ietf.org/doc/html/rfc4291#section-2.4
   517  	if ip.Is6() {
   518  		return ip.v6u16(0)&0xffc0 == 0xfe80
   519  	}
   520  	return false // zero value
   521  }
   522  
   523  // IsLoopback reports whether ip is a loopback address.
   524  func (ip Addr) IsLoopback() bool {
   525  	// Requirements for Internet Hosts -- Communication Layers (3.2.1.3 Addressing)
   526  	// https://datatracker.ietf.org/doc/html/rfc1122#section-3.2.1.3
   527  	if ip.Is4() {
   528  		return ip.v4(0) == 127
   529  	}
   530  	// IP Version 6 Addressing Architecture (2.4 Address Type Identification)
   531  	// https://datatracker.ietf.org/doc/html/rfc4291#section-2.4
   532  	if ip.Is6() {
   533  		return ip.addr.hi == 0 && ip.addr.lo == 1
   534  	}
   535  	return false // zero value
   536  }
   537  
   538  // IsMulticast reports whether ip is a multicast address.
   539  func (ip Addr) IsMulticast() bool {
   540  	// Host Extensions for IP Multicasting (4. HOST GROUP ADDRESSES)
   541  	// https://datatracker.ietf.org/doc/html/rfc1112#section-4
   542  	if ip.Is4() {
   543  		return ip.v4(0)&0xf0 == 0xe0
   544  	}
   545  	// IP Version 6 Addressing Architecture (2.4 Address Type Identification)
   546  	// https://datatracker.ietf.org/doc/html/rfc4291#section-2.4
   547  	if ip.Is6() {
   548  		return ip.addr.hi>>(64-8) == 0xff // ip.v6(0) == 0xff
   549  	}
   550  	return false // zero value
   551  }
   552  
   553  // IsInterfaceLocalMulticast reports whether ip is an IPv6 interface-local
   554  // multicast address.
   555  func (ip Addr) IsInterfaceLocalMulticast() bool {
   556  	// IPv6 Addressing Architecture (2.7.1. Pre-Defined Multicast Addresses)
   557  	// https://datatracker.ietf.org/doc/html/rfc4291#section-2.7.1
   558  	if ip.Is6() {
   559  		return ip.v6u16(0)&0xff0f == 0xff01
   560  	}
   561  	return false // zero value
   562  }
   563  
   564  // IsLinkLocalMulticast reports whether ip is a link-local multicast address.
   565  func (ip Addr) IsLinkLocalMulticast() bool {
   566  	// IPv4 Multicast Guidelines (4. Local Network Control Block (224.0.0/24))
   567  	// https://datatracker.ietf.org/doc/html/rfc5771#section-4
   568  	if ip.Is4() {
   569  		return ip.v4(0) == 224 && ip.v4(1) == 0 && ip.v4(2) == 0
   570  	}
   571  	// IPv6 Addressing Architecture (2.7.1. Pre-Defined Multicast Addresses)
   572  	// https://datatracker.ietf.org/doc/html/rfc4291#section-2.7.1
   573  	if ip.Is6() {
   574  		return ip.v6u16(0)&0xff0f == 0xff02
   575  	}
   576  	return false // zero value
   577  }
   578  
   579  // IsGlobalUnicast reports whether ip is a global unicast address.
   580  //
   581  // It returns true for IPv6 addresses which fall outside of the current
   582  // IANA-allocated 2000::/3 global unicast space, with the exception of the
   583  // link-local address space. It also returns true even if ip is in the IPv4
   584  // private address space or IPv6 unique local address space.
   585  // It returns false for the zero Addr.
   586  //
   587  // For reference, see RFC 1122, RFC 4291, and RFC 4632.
   588  func (ip Addr) IsGlobalUnicast() bool {
   589  	if ip.z == z0 {
   590  		// Invalid or zero-value.
   591  		return false
   592  	}
   593  
   594  	// Match package net's IsGlobalUnicast logic. Notably private IPv4 addresses
   595  	// and ULA IPv6 addresses are still considered "global unicast".
   596  	if ip.Is4() && (ip == IPv4Unspecified() || ip == AddrFrom4([4]byte{255, 255, 255, 255})) {
   597  		return false
   598  	}
   599  
   600  	return ip != IPv6Unspecified() &&
   601  		!ip.IsLoopback() &&
   602  		!ip.IsMulticast() &&
   603  		!ip.IsLinkLocalUnicast()
   604  }
   605  
   606  // IsPrivate reports whether ip is a private address, according to RFC 1918
   607  // (IPv4 addresses) and RFC 4193 (IPv6 addresses). That is, it reports whether
   608  // ip is in 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, or fc00::/7. This is the
   609  // same as net.IP.IsPrivate.
   610  func (ip Addr) IsPrivate() bool {
   611  	// Match the stdlib's IsPrivate logic.
   612  	if ip.Is4() {
   613  		// RFC 1918 allocates 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16 as
   614  		// private IPv4 address subnets.
   615  		return ip.v4(0) == 10 ||
   616  			(ip.v4(0) == 172 && ip.v4(1)&0xf0 == 16) ||
   617  			(ip.v4(0) == 192 && ip.v4(1) == 168)
   618  	}
   619  
   620  	if ip.Is6() {
   621  		// RFC 4193 allocates fc00::/7 as the unique local unicast IPv6 address
   622  		// subnet.
   623  		return ip.v6(0)&0xfe == 0xfc
   624  	}
   625  
   626  	return false // zero value
   627  }
   628  
   629  // IsUnspecified reports whether ip is an unspecified address, either the IPv4
   630  // address "0.0.0.0" or the IPv6 address "::".
   631  //
   632  // Note that the zero Addr is not an unspecified address.
   633  func (ip Addr) IsUnspecified() bool {
   634  	return ip == IPv4Unspecified() || ip == IPv6Unspecified()
   635  }
   636  
   637  // Prefix keeps only the top b bits of IP, producing a Prefix
   638  // of the specified length.
   639  // If ip is a zero Addr, Prefix always returns a zero Prefix and a nil error.
   640  // Otherwise, if bits is less than zero or greater than ip.BitLen(),
   641  // Prefix returns an error.
   642  func (ip Addr) Prefix(b int) (Prefix, error) {
   643  	if b < 0 {
   644  		return Prefix{}, errors.New("negative Prefix bits")
   645  	}
   646  	effectiveBits := b
   647  	switch ip.z {
   648  	case z0:
   649  		return Prefix{}, nil
   650  	case z4:
   651  		if b > 32 {
   652  			return Prefix{}, errors.New("prefix length " + itoa.Itoa(b) + " too large for IPv4")
   653  		}
   654  		effectiveBits += 96
   655  	default:
   656  		if b > 128 {
   657  			return Prefix{}, errors.New("prefix length " + itoa.Itoa(b) + " too large for IPv6")
   658  		}
   659  	}
   660  	ip.addr = ip.addr.and(mask6(effectiveBits))
   661  	return PrefixFrom(ip, b), nil
   662  }
   663  
   664  const (
   665  	netIPv4len = 4
   666  	netIPv6len = 16
   667  )
   668  
   669  // As16 returns the IP address in its 16-byte representation.
   670  // IPv4 addresses are returned as IPv4-mapped IPv6 addresses.
   671  // IPv6 addresses with zones are returned without their zone (use the
   672  // Zone method to get it).
   673  // The ip zero value returns all zeroes.
   674  func (ip Addr) As16() (a16 [16]byte) {
   675  	bePutUint64(a16[:8], ip.addr.hi)
   676  	bePutUint64(a16[8:], ip.addr.lo)
   677  	return a16
   678  }
   679  
   680  // As4 returns an IPv4 or IPv4-in-IPv6 address in its 4-byte representation.
   681  // If ip is the zero Addr or an IPv6 address, As4 panics.
   682  // Note that 0.0.0.0 is not the zero Addr.
   683  func (ip Addr) As4() (a4 [4]byte) {
   684  	if ip.z == z4 || ip.Is4In6() {
   685  		bePutUint32(a4[:], uint32(ip.addr.lo))
   686  		return a4
   687  	}
   688  	if ip.z == z0 {
   689  		panic("As4 called on IP zero value")
   690  	}
   691  	panic("As4 called on IPv6 address")
   692  }
   693  
   694  // AsSlice returns an IPv4 or IPv6 address in its respective 4-byte or 16-byte representation.
   695  func (ip Addr) AsSlice() []byte {
   696  	switch ip.z {
   697  	case z0:
   698  		return nil
   699  	case z4:
   700  		var ret [4]byte
   701  		bePutUint32(ret[:], uint32(ip.addr.lo))
   702  		return ret[:]
   703  	default:
   704  		var ret [16]byte
   705  		bePutUint64(ret[:8], ip.addr.hi)
   706  		bePutUint64(ret[8:], ip.addr.lo)
   707  		return ret[:]
   708  	}
   709  }
   710  
   711  // Next returns the address following ip.
   712  // If there is none, it returns the zero Addr.
   713  func (ip Addr) Next() Addr {
   714  	ip.addr = ip.addr.addOne()
   715  	if ip.Is4() {
   716  		if uint32(ip.addr.lo) == 0 {
   717  			// Overflowed.
   718  			return Addr{}
   719  		}
   720  	} else {
   721  		if ip.addr.isZero() {
   722  			// Overflowed
   723  			return Addr{}
   724  		}
   725  	}
   726  	return ip
   727  }
   728  
   729  // Prev returns the IP before ip.
   730  // If there is none, it returns the IP zero value.
   731  func (ip Addr) Prev() Addr {
   732  	if ip.Is4() {
   733  		if uint32(ip.addr.lo) == 0 {
   734  			return Addr{}
   735  		}
   736  	} else if ip.addr.isZero() {
   737  		return Addr{}
   738  	}
   739  	ip.addr = ip.addr.subOne()
   740  	return ip
   741  }
   742  
   743  // String returns the string form of the IP address ip.
   744  // It returns one of 5 forms:
   745  //
   746  //   - "invalid IP", if ip is the zero Addr
   747  //   - IPv4 dotted decimal ("192.0.2.1")
   748  //   - IPv6 ("2001:db8::1")
   749  //   - "::ffff:1.2.3.4" (if Is4In6)
   750  //   - IPv6 with zone ("fe80:db8::1%eth0")
   751  //
   752  // Note that unlike package net's IP.String method,
   753  // IPv4-mapped IPv6 addresses format with a "::ffff:"
   754  // prefix before the dotted quad.
   755  func (ip Addr) String() string {
   756  	switch ip.z {
   757  	case z0:
   758  		return "invalid IP"
   759  	case z4:
   760  		return ip.string4()
   761  	default:
   762  		if ip.Is4In6() {
   763  			if z := ip.Zone(); z != "" {
   764  				return "::ffff:" + ip.Unmap().string4() + "%" + z
   765  			} else {
   766  				return "::ffff:" + ip.Unmap().string4()
   767  			}
   768  		}
   769  		return ip.string6()
   770  	}
   771  }
   772  
   773  // AppendTo appends a text encoding of ip,
   774  // as generated by MarshalText,
   775  // to b and returns the extended buffer.
   776  func (ip Addr) AppendTo(b []byte) []byte {
   777  	switch ip.z {
   778  	case z0:
   779  		return b
   780  	case z4:
   781  		return ip.appendTo4(b)
   782  	default:
   783  		if ip.Is4In6() {
   784  			b = append(b, "::ffff:"...)
   785  			b = ip.Unmap().appendTo4(b)
   786  			if z := ip.Zone(); z != "" {
   787  				b = append(b, '%')
   788  				b = append(b, z...)
   789  			}
   790  			return b
   791  		}
   792  		return ip.appendTo6(b)
   793  	}
   794  }
   795  
   796  // digits is a string of the hex digits from 0 to f. It's used in
   797  // appendDecimal and appendHex to format IP addresses.
   798  const digits = "0123456789abcdef"
   799  
   800  // appendDecimal appends the decimal string representation of x to b.
   801  func appendDecimal(b []byte, x uint8) []byte {
   802  	// Using this function rather than strconv.AppendUint makes IPv4
   803  	// string building 2x faster.
   804  
   805  	if x >= 100 {
   806  		b = append(b, digits[x/100])
   807  	}
   808  	if x >= 10 {
   809  		b = append(b, digits[x/10%10])
   810  	}
   811  	return append(b, digits[x%10])
   812  }
   813  
   814  // appendHex appends the hex string representation of x to b.
   815  func appendHex(b []byte, x uint16) []byte {
   816  	// Using this function rather than strconv.AppendUint makes IPv6
   817  	// string building 2x faster.
   818  
   819  	if x >= 0x1000 {
   820  		b = append(b, digits[x>>12])
   821  	}
   822  	if x >= 0x100 {
   823  		b = append(b, digits[x>>8&0xf])
   824  	}
   825  	if x >= 0x10 {
   826  		b = append(b, digits[x>>4&0xf])
   827  	}
   828  	return append(b, digits[x&0xf])
   829  }
   830  
   831  // appendHexPad appends the fully padded hex string representation of x to b.
   832  func appendHexPad(b []byte, x uint16) []byte {
   833  	return append(b, digits[x>>12], digits[x>>8&0xf], digits[x>>4&0xf], digits[x&0xf])
   834  }
   835  
   836  func (ip Addr) string4() string {
   837  	const max = len("255.255.255.255")
   838  	ret := make([]byte, 0, max)
   839  	ret = ip.appendTo4(ret)
   840  	return string(ret)
   841  }
   842  
   843  func (ip Addr) appendTo4(ret []byte) []byte {
   844  	ret = appendDecimal(ret, ip.v4(0))
   845  	ret = append(ret, '.')
   846  	ret = appendDecimal(ret, ip.v4(1))
   847  	ret = append(ret, '.')
   848  	ret = appendDecimal(ret, ip.v4(2))
   849  	ret = append(ret, '.')
   850  	ret = appendDecimal(ret, ip.v4(3))
   851  	return ret
   852  }
   853  
   854  // string6 formats ip in IPv6 textual representation. It follows the
   855  // guidelines in section 4 of RFC 5952
   856  // (https://tools.ietf.org/html/rfc5952#section-4): no unnecessary
   857  // zeros, use :: to elide the longest run of zeros, and don't use ::
   858  // to compact a single zero field.
   859  func (ip Addr) string6() string {
   860  	// Use a zone with a "plausibly long" name, so that most zone-ful
   861  	// IP addresses won't require additional allocation.
   862  	//
   863  	// The compiler does a cool optimization here, where ret ends up
   864  	// stack-allocated and so the only allocation this function does
   865  	// is to construct the returned string. As such, it's okay to be a
   866  	// bit greedy here, size-wise.
   867  	const max = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0")
   868  	ret := make([]byte, 0, max)
   869  	ret = ip.appendTo6(ret)
   870  	return string(ret)
   871  }
   872  
   873  func (ip Addr) appendTo6(ret []byte) []byte {
   874  	zeroStart, zeroEnd := uint8(255), uint8(255)
   875  	for i := uint8(0); i < 8; i++ {
   876  		j := i
   877  		for j < 8 && ip.v6u16(j) == 0 {
   878  			j++
   879  		}
   880  		if l := j - i; l >= 2 && l > zeroEnd-zeroStart {
   881  			zeroStart, zeroEnd = i, j
   882  		}
   883  	}
   884  
   885  	for i := uint8(0); i < 8; i++ {
   886  		if i == zeroStart {
   887  			ret = append(ret, ':', ':')
   888  			i = zeroEnd
   889  			if i >= 8 {
   890  				break
   891  			}
   892  		} else if i > 0 {
   893  			ret = append(ret, ':')
   894  		}
   895  
   896  		ret = appendHex(ret, ip.v6u16(i))
   897  	}
   898  
   899  	if ip.z != z6noz {
   900  		ret = append(ret, '%')
   901  		ret = append(ret, ip.Zone()...)
   902  	}
   903  	return ret
   904  }
   905  
   906  // StringExpanded is like String but IPv6 addresses are expanded with leading
   907  // zeroes and no "::" compression. For example, "2001:db8::1" becomes
   908  // "2001:0db8:0000:0000:0000:0000:0000:0001".
   909  func (ip Addr) StringExpanded() string {
   910  	switch ip.z {
   911  	case z0, z4:
   912  		return ip.String()
   913  	}
   914  
   915  	const size = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
   916  	ret := make([]byte, 0, size)
   917  	for i := uint8(0); i < 8; i++ {
   918  		if i > 0 {
   919  			ret = append(ret, ':')
   920  		}
   921  
   922  		ret = appendHexPad(ret, ip.v6u16(i))
   923  	}
   924  
   925  	if ip.z != z6noz {
   926  		// The addition of a zone will cause a second allocation, but when there
   927  		// is no zone the ret slice will be stack allocated.
   928  		ret = append(ret, '%')
   929  		ret = append(ret, ip.Zone()...)
   930  	}
   931  	return string(ret)
   932  }
   933  
   934  // MarshalText implements the encoding.TextMarshaler interface,
   935  // The encoding is the same as returned by String, with one exception:
   936  // If ip is the zero Addr, the encoding is the empty string.
   937  func (ip Addr) MarshalText() ([]byte, error) {
   938  	switch ip.z {
   939  	case z0:
   940  		return []byte(""), nil
   941  	case z4:
   942  		max := len("255.255.255.255")
   943  		b := make([]byte, 0, max)
   944  		return ip.appendTo4(b), nil
   945  	default:
   946  		max := len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0")
   947  		b := make([]byte, 0, max)
   948  		if ip.Is4In6() {
   949  			b = append(b, "::ffff:"...)
   950  			b = ip.Unmap().appendTo4(b)
   951  			if z := ip.Zone(); z != "" {
   952  				b = append(b, '%')
   953  				b = append(b, z...)
   954  			}
   955  			return b, nil
   956  		}
   957  		return ip.appendTo6(b), nil
   958  	}
   959  
   960  }
   961  
   962  // UnmarshalText implements the encoding.TextUnmarshaler interface.
   963  // The IP address is expected in a form accepted by ParseAddr.
   964  //
   965  // If text is empty, UnmarshalText sets *ip to the zero Addr and
   966  // returns no error.
   967  func (ip *Addr) UnmarshalText(text []byte) error {
   968  	if len(text) == 0 {
   969  		*ip = Addr{}
   970  		return nil
   971  	}
   972  	var err error
   973  	*ip, err = ParseAddr(string(text))
   974  	return err
   975  }
   976  
   977  func (ip Addr) marshalBinaryWithTrailingBytes(trailingBytes int) []byte {
   978  	var b []byte
   979  	switch ip.z {
   980  	case z0:
   981  		b = make([]byte, trailingBytes)
   982  	case z4:
   983  		b = make([]byte, 4+trailingBytes)
   984  		bePutUint32(b, uint32(ip.addr.lo))
   985  	default:
   986  		z := ip.Zone()
   987  		b = make([]byte, 16+len(z)+trailingBytes)
   988  		bePutUint64(b[:8], ip.addr.hi)
   989  		bePutUint64(b[8:], ip.addr.lo)
   990  		copy(b[16:], z)
   991  	}
   992  	return b
   993  }
   994  
   995  // MarshalBinary implements the encoding.BinaryMarshaler interface.
   996  // It returns a zero-length slice for the zero Addr,
   997  // the 4-byte form for an IPv4 address,
   998  // and the 16-byte form with zone appended for an IPv6 address.
   999  func (ip Addr) MarshalBinary() ([]byte, error) {
  1000  	return ip.marshalBinaryWithTrailingBytes(0), nil
  1001  }
  1002  
  1003  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
  1004  // It expects data in the form generated by MarshalBinary.
  1005  func (ip *Addr) UnmarshalBinary(b []byte) error {
  1006  	n := len(b)
  1007  	switch {
  1008  	case n == 0:
  1009  		*ip = Addr{}
  1010  		return nil
  1011  	case n == 4:
  1012  		*ip = AddrFrom4([4]byte(b))
  1013  		return nil
  1014  	case n == 16:
  1015  		*ip = AddrFrom16([16]byte(b))
  1016  		return nil
  1017  	case n > 16:
  1018  		*ip = AddrFrom16([16]byte(b[:16])).WithZone(string(b[16:]))
  1019  		return nil
  1020  	}
  1021  	return errors.New("unexpected slice size")
  1022  }
  1023  
  1024  // AddrPort is an IP and a port number.
  1025  type AddrPort struct {
  1026  	ip   Addr
  1027  	port uint16
  1028  }
  1029  
  1030  // AddrPortFrom returns an AddrPort with the provided IP and port.
  1031  // It does not allocate.
  1032  func AddrPortFrom(ip Addr, port uint16) AddrPort { return AddrPort{ip: ip, port: port} }
  1033  
  1034  // Addr returns p's IP address.
  1035  func (p AddrPort) Addr() Addr { return p.ip }
  1036  
  1037  // Port returns p's port.
  1038  func (p AddrPort) Port() uint16 { return p.port }
  1039  
  1040  // splitAddrPort splits s into an IP address string and a port
  1041  // string. It splits strings shaped like "foo:bar" or "[foo]:bar",
  1042  // without further validating the substrings. v6 indicates whether the
  1043  // ip string should parse as an IPv6 address or an IPv4 address, in
  1044  // order for s to be a valid ip:port string.
  1045  func splitAddrPort(s string) (ip, port string, v6 bool, err error) {
  1046  	i := stringsLastIndexByte(s, ':')
  1047  	if i == -1 {
  1048  		return "", "", false, errors.New("not an ip:port")
  1049  	}
  1050  
  1051  	ip, port = s[:i], s[i+1:]
  1052  	if len(ip) == 0 {
  1053  		return "", "", false, errors.New("no IP")
  1054  	}
  1055  	if len(port) == 0 {
  1056  		return "", "", false, errors.New("no port")
  1057  	}
  1058  	if ip[0] == '[' {
  1059  		if len(ip) < 2 || ip[len(ip)-1] != ']' {
  1060  			return "", "", false, errors.New("missing ]")
  1061  		}
  1062  		ip = ip[1 : len(ip)-1]
  1063  		v6 = true
  1064  	}
  1065  
  1066  	return ip, port, v6, nil
  1067  }
  1068  
  1069  // ParseAddrPort parses s as an AddrPort.
  1070  //
  1071  // It doesn't do any name resolution: both the address and the port
  1072  // must be numeric.
  1073  func ParseAddrPort(s string) (AddrPort, error) {
  1074  	var ipp AddrPort
  1075  	ip, port, v6, err := splitAddrPort(s)
  1076  	if err != nil {
  1077  		return ipp, err
  1078  	}
  1079  	port16, err := strconv.ParseUint(port, 10, 16)
  1080  	if err != nil {
  1081  		return ipp, errors.New("invalid port " + strconv.Quote(port) + " parsing " + strconv.Quote(s))
  1082  	}
  1083  	ipp.port = uint16(port16)
  1084  	ipp.ip, err = ParseAddr(ip)
  1085  	if err != nil {
  1086  		return AddrPort{}, err
  1087  	}
  1088  	if v6 && ipp.ip.Is4() {
  1089  		return AddrPort{}, errors.New("invalid ip:port " + strconv.Quote(s) + ", square brackets can only be used with IPv6 addresses")
  1090  	} else if !v6 && ipp.ip.Is6() {
  1091  		return AddrPort{}, errors.New("invalid ip:port " + strconv.Quote(s) + ", IPv6 addresses must be surrounded by square brackets")
  1092  	}
  1093  	return ipp, nil
  1094  }
  1095  
  1096  // MustParseAddrPort calls ParseAddrPort(s) and panics on error.
  1097  // It is intended for use in tests with hard-coded strings.
  1098  func MustParseAddrPort(s string) AddrPort {
  1099  	ip, err := ParseAddrPort(s)
  1100  	if err != nil {
  1101  		panic(err)
  1102  	}
  1103  	return ip
  1104  }
  1105  
  1106  // IsValid reports whether p.Addr() is valid.
  1107  // All ports are valid, including zero.
  1108  func (p AddrPort) IsValid() bool { return p.ip.IsValid() }
  1109  
  1110  func (p AddrPort) String() string {
  1111  	switch p.ip.z {
  1112  	case z0:
  1113  		return "invalid AddrPort"
  1114  	case z4:
  1115  		a := p.ip.As4()
  1116  		buf := make([]byte, 0, 21)
  1117  		for i := range a {
  1118  			buf = strconv.AppendUint(buf, uint64(a[i]), 10)
  1119  			buf = append(buf, "...:"[i])
  1120  		}
  1121  		buf = strconv.AppendUint(buf, uint64(p.port), 10)
  1122  		return string(buf)
  1123  	default:
  1124  		// TODO: this could be more efficient allocation-wise:
  1125  		return joinHostPort(p.ip.String(), itoa.Itoa(int(p.port)))
  1126  	}
  1127  }
  1128  
  1129  func joinHostPort(host, port string) string {
  1130  	// We assume that host is a literal IPv6 address if host has
  1131  	// colons.
  1132  	if bytealg.IndexByteString(host, ':') >= 0 {
  1133  		return "[" + host + "]:" + port
  1134  	}
  1135  	return host + ":" + port
  1136  }
  1137  
  1138  // AppendTo appends a text encoding of p,
  1139  // as generated by MarshalText,
  1140  // to b and returns the extended buffer.
  1141  func (p AddrPort) AppendTo(b []byte) []byte {
  1142  	switch p.ip.z {
  1143  	case z0:
  1144  		return b
  1145  	case z4:
  1146  		b = p.ip.appendTo4(b)
  1147  	default:
  1148  		if p.ip.Is4In6() {
  1149  			b = append(b, "[::ffff:"...)
  1150  			b = p.ip.Unmap().appendTo4(b)
  1151  			if z := p.ip.Zone(); z != "" {
  1152  				b = append(b, '%')
  1153  				b = append(b, z...)
  1154  			}
  1155  		} else {
  1156  			b = append(b, '[')
  1157  			b = p.ip.appendTo6(b)
  1158  		}
  1159  		b = append(b, ']')
  1160  	}
  1161  	b = append(b, ':')
  1162  	b = strconv.AppendUint(b, uint64(p.port), 10)
  1163  	return b
  1164  }
  1165  
  1166  // MarshalText implements the encoding.TextMarshaler interface. The
  1167  // encoding is the same as returned by String, with one exception: if
  1168  // p.Addr() is the zero Addr, the encoding is the empty string.
  1169  func (p AddrPort) MarshalText() ([]byte, error) {
  1170  	var max int
  1171  	switch p.ip.z {
  1172  	case z0:
  1173  	case z4:
  1174  		max = len("255.255.255.255:65535")
  1175  	default:
  1176  		max = len("[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0]:65535")
  1177  	}
  1178  	b := make([]byte, 0, max)
  1179  	b = p.AppendTo(b)
  1180  	return b, nil
  1181  }
  1182  
  1183  // UnmarshalText implements the encoding.TextUnmarshaler
  1184  // interface. The AddrPort is expected in a form
  1185  // generated by MarshalText or accepted by ParseAddrPort.
  1186  func (p *AddrPort) UnmarshalText(text []byte) error {
  1187  	if len(text) == 0 {
  1188  		*p = AddrPort{}
  1189  		return nil
  1190  	}
  1191  	var err error
  1192  	*p, err = ParseAddrPort(string(text))
  1193  	return err
  1194  }
  1195  
  1196  // MarshalBinary implements the encoding.BinaryMarshaler interface.
  1197  // It returns Addr.MarshalBinary with an additional two bytes appended
  1198  // containing the port in little-endian.
  1199  func (p AddrPort) MarshalBinary() ([]byte, error) {
  1200  	b := p.Addr().marshalBinaryWithTrailingBytes(2)
  1201  	lePutUint16(b[len(b)-2:], p.Port())
  1202  	return b, nil
  1203  }
  1204  
  1205  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
  1206  // It expects data in the form generated by MarshalBinary.
  1207  func (p *AddrPort) UnmarshalBinary(b []byte) error {
  1208  	if len(b) < 2 {
  1209  		return errors.New("unexpected slice size")
  1210  	}
  1211  	var addr Addr
  1212  	err := addr.UnmarshalBinary(b[:len(b)-2])
  1213  	if err != nil {
  1214  		return err
  1215  	}
  1216  	*p = AddrPortFrom(addr, leUint16(b[len(b)-2:]))
  1217  	return nil
  1218  }
  1219  
  1220  // Prefix is an IP address prefix (CIDR) representing an IP network.
  1221  //
  1222  // The first Bits() of Addr() are specified. The remaining bits match any address.
  1223  // The range of Bits() is [0,32] for IPv4 or [0,128] for IPv6.
  1224  type Prefix struct {
  1225  	ip Addr
  1226  
  1227  	// bitsPlusOne stores the prefix bit length plus one.
  1228  	// A Prefix is valid if and only if bitsPlusOne is non-zero.
  1229  	bitsPlusOne uint8
  1230  }
  1231  
  1232  // PrefixFrom returns a Prefix with the provided IP address and bit
  1233  // prefix length.
  1234  //
  1235  // It does not allocate. Unlike Addr.Prefix, PrefixFrom does not mask
  1236  // off the host bits of ip.
  1237  //
  1238  // If bits is less than zero or greater than ip.BitLen, Prefix.Bits
  1239  // will return an invalid value -1.
  1240  func PrefixFrom(ip Addr, bits int) Prefix {
  1241  	var bitsPlusOne uint8
  1242  	if !ip.isZero() && bits >= 0 && bits <= ip.BitLen() {
  1243  		bitsPlusOne = uint8(bits) + 1
  1244  	}
  1245  	return Prefix{
  1246  		ip:          ip.withoutZone(),
  1247  		bitsPlusOne: bitsPlusOne,
  1248  	}
  1249  }
  1250  
  1251  // Addr returns p's IP address.
  1252  func (p Prefix) Addr() Addr { return p.ip }
  1253  
  1254  // Bits returns p's prefix length.
  1255  //
  1256  // It reports -1 if invalid.
  1257  func (p Prefix) Bits() int { return int(p.bitsPlusOne) - 1 }
  1258  
  1259  // IsValid reports whether p.Bits() has a valid range for p.Addr().
  1260  // If p.Addr() is the zero Addr, IsValid returns false.
  1261  // Note that if p is the zero Prefix, then p.IsValid() == false.
  1262  func (p Prefix) IsValid() bool { return p.bitsPlusOne > 0 }
  1263  
  1264  func (p Prefix) isZero() bool { return p == Prefix{} }
  1265  
  1266  // IsSingleIP reports whether p contains exactly one IP.
  1267  func (p Prefix) IsSingleIP() bool { return p.IsValid() && p.Bits() == p.ip.BitLen() }
  1268  
  1269  // ParsePrefix parses s as an IP address prefix.
  1270  // The string can be in the form "192.168.1.0/24" or "2001:db8::/32",
  1271  // the CIDR notation defined in RFC 4632 and RFC 4291.
  1272  // IPv6 zones are not permitted in prefixes, and an error will be returned if a
  1273  // zone is present.
  1274  //
  1275  // Note that masked address bits are not zeroed. Use Masked for that.
  1276  func ParsePrefix(s string) (Prefix, error) {
  1277  	i := stringsLastIndexByte(s, '/')
  1278  	if i < 0 {
  1279  		return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): no '/'")
  1280  	}
  1281  	ip, err := ParseAddr(s[:i])
  1282  	if err != nil {
  1283  		return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): " + err.Error())
  1284  	}
  1285  	// IPv6 zones are not allowed: https://go.dev/issue/51899
  1286  	if ip.Is6() && ip.z != z6noz {
  1287  		return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): IPv6 zones cannot be present in a prefix")
  1288  	}
  1289  
  1290  	bitsStr := s[i+1:]
  1291  	bits, err := strconv.Atoi(bitsStr)
  1292  	if err != nil {
  1293  		return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): bad bits after slash: " + strconv.Quote(bitsStr))
  1294  	}
  1295  	maxBits := 32
  1296  	if ip.Is6() {
  1297  		maxBits = 128
  1298  	}
  1299  	if bits < 0 || bits > maxBits {
  1300  		return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): prefix length out of range")
  1301  	}
  1302  	return PrefixFrom(ip, bits), nil
  1303  }
  1304  
  1305  // MustParsePrefix calls ParsePrefix(s) and panics on error.
  1306  // It is intended for use in tests with hard-coded strings.
  1307  func MustParsePrefix(s string) Prefix {
  1308  	ip, err := ParsePrefix(s)
  1309  	if err != nil {
  1310  		panic(err)
  1311  	}
  1312  	return ip
  1313  }
  1314  
  1315  // Masked returns p in its canonical form, with all but the high
  1316  // p.Bits() bits of p.Addr() masked off.
  1317  //
  1318  // If p is zero or otherwise invalid, Masked returns the zero Prefix.
  1319  func (p Prefix) Masked() Prefix {
  1320  	m, _ := p.ip.Prefix(p.Bits())
  1321  	return m
  1322  }
  1323  
  1324  // Contains reports whether the network p includes ip.
  1325  //
  1326  // An IPv4 address will not match an IPv6 prefix.
  1327  // An IPv4-mapped IPv6 address will not match an IPv4 prefix.
  1328  // A zero-value IP will not match any prefix.
  1329  // If ip has an IPv6 zone, Contains returns false,
  1330  // because Prefixes strip zones.
  1331  func (p Prefix) Contains(ip Addr) bool {
  1332  	if !p.IsValid() || ip.hasZone() {
  1333  		return false
  1334  	}
  1335  	if f1, f2 := p.ip.BitLen(), ip.BitLen(); f1 == 0 || f2 == 0 || f1 != f2 {
  1336  		return false
  1337  	}
  1338  	if ip.Is4() {
  1339  		// xor the IP addresses together; mismatched bits are now ones.
  1340  		// Shift away the number of bits we don't care about.
  1341  		// Shifts in Go are more efficient if the compiler can prove
  1342  		// that the shift amount is smaller than the width of the shifted type (64 here).
  1343  		// We know that p.bits is in the range 0..32 because p is Valid;
  1344  		// the compiler doesn't know that, so mask with 63 to help it.
  1345  		// Now truncate to 32 bits, because this is IPv4.
  1346  		// If all the bits we care about are equal, the result will be zero.
  1347  		return uint32((ip.addr.lo^p.ip.addr.lo)>>((32-p.Bits())&63)) == 0
  1348  	} else {
  1349  		// xor the IP addresses together.
  1350  		// Mask away the bits we don't care about.
  1351  		// If all the bits we care about are equal, the result will be zero.
  1352  		return ip.addr.xor(p.ip.addr).and(mask6(p.Bits())).isZero()
  1353  	}
  1354  }
  1355  
  1356  // Overlaps reports whether p and o contain any IP addresses in common.
  1357  //
  1358  // If p and o are of different address families or either have a zero
  1359  // IP, it reports false. Like the Contains method, a prefix with an
  1360  // IPv4-mapped IPv6 address is still treated as an IPv6 mask.
  1361  func (p Prefix) Overlaps(o Prefix) bool {
  1362  	if !p.IsValid() || !o.IsValid() {
  1363  		return false
  1364  	}
  1365  	if p == o {
  1366  		return true
  1367  	}
  1368  	if p.ip.Is4() != o.ip.Is4() {
  1369  		return false
  1370  	}
  1371  	var minBits int
  1372  	if pb, ob := p.Bits(), o.Bits(); pb < ob {
  1373  		minBits = pb
  1374  	} else {
  1375  		minBits = ob
  1376  	}
  1377  	if minBits == 0 {
  1378  		return true
  1379  	}
  1380  	// One of these Prefix calls might look redundant, but we don't require
  1381  	// that p and o values are normalized (via Prefix.Masked) first,
  1382  	// so the Prefix call on the one that's already minBits serves to zero
  1383  	// out any remaining bits in IP.
  1384  	var err error
  1385  	if p, err = p.ip.Prefix(minBits); err != nil {
  1386  		return false
  1387  	}
  1388  	if o, err = o.ip.Prefix(minBits); err != nil {
  1389  		return false
  1390  	}
  1391  	return p.ip == o.ip
  1392  }
  1393  
  1394  // AppendTo appends a text encoding of p,
  1395  // as generated by MarshalText,
  1396  // to b and returns the extended buffer.
  1397  func (p Prefix) AppendTo(b []byte) []byte {
  1398  	if p.isZero() {
  1399  		return b
  1400  	}
  1401  	if !p.IsValid() {
  1402  		return append(b, "invalid Prefix"...)
  1403  	}
  1404  
  1405  	// p.ip is non-nil, because p is valid.
  1406  	if p.ip.z == z4 {
  1407  		b = p.ip.appendTo4(b)
  1408  	} else {
  1409  		if p.ip.Is4In6() {
  1410  			b = append(b, "::ffff:"...)
  1411  			b = p.ip.Unmap().appendTo4(b)
  1412  		} else {
  1413  			b = p.ip.appendTo6(b)
  1414  		}
  1415  	}
  1416  
  1417  	b = append(b, '/')
  1418  	b = appendDecimal(b, uint8(p.Bits()))
  1419  	return b
  1420  }
  1421  
  1422  // MarshalText implements the encoding.TextMarshaler interface,
  1423  // The encoding is the same as returned by String, with one exception:
  1424  // If p is the zero value, the encoding is the empty string.
  1425  func (p Prefix) MarshalText() ([]byte, error) {
  1426  	var max int
  1427  	switch p.ip.z {
  1428  	case z0:
  1429  	case z4:
  1430  		max = len("255.255.255.255/32")
  1431  	default:
  1432  		max = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0/128")
  1433  	}
  1434  	b := make([]byte, 0, max)
  1435  	b = p.AppendTo(b)
  1436  	return b, nil
  1437  }
  1438  
  1439  // UnmarshalText implements the encoding.TextUnmarshaler interface.
  1440  // The IP address is expected in a form accepted by ParsePrefix
  1441  // or generated by MarshalText.
  1442  func (p *Prefix) UnmarshalText(text []byte) error {
  1443  	if len(text) == 0 {
  1444  		*p = Prefix{}
  1445  		return nil
  1446  	}
  1447  	var err error
  1448  	*p, err = ParsePrefix(string(text))
  1449  	return err
  1450  }
  1451  
  1452  // MarshalBinary implements the encoding.BinaryMarshaler interface.
  1453  // It returns Addr.MarshalBinary with an additional byte appended
  1454  // containing the prefix bits.
  1455  func (p Prefix) MarshalBinary() ([]byte, error) {
  1456  	b := p.Addr().withoutZone().marshalBinaryWithTrailingBytes(1)
  1457  	b[len(b)-1] = uint8(p.Bits())
  1458  	return b, nil
  1459  }
  1460  
  1461  // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
  1462  // It expects data in the form generated by MarshalBinary.
  1463  func (p *Prefix) UnmarshalBinary(b []byte) error {
  1464  	if len(b) < 1 {
  1465  		return errors.New("unexpected slice size")
  1466  	}
  1467  	var addr Addr
  1468  	err := addr.UnmarshalBinary(b[:len(b)-1])
  1469  	if err != nil {
  1470  		return err
  1471  	}
  1472  	*p = PrefixFrom(addr, int(b[len(b)-1]))
  1473  	return nil
  1474  }
  1475  
  1476  // String returns the CIDR notation of p: "<ip>/<bits>".
  1477  func (p Prefix) String() string {
  1478  	if !p.IsValid() {
  1479  		return "invalid Prefix"
  1480  	}
  1481  	return p.ip.String() + "/" + itoa.Itoa(p.Bits())
  1482  }