Source file src/net/netip/netip.go

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

View as plain text