Source file src/net/ip.go

     1  // Copyright 2009 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  // IP address manipulations
     6  //
     7  // IPv4 addresses are 4 bytes; IPv6 addresses are 16 bytes.
     8  // An IPv4 address can be converted to an IPv6 address by
     9  // adding a canonical prefix (10 zeros, 2 0xFFs).
    10  // This library accepts either size of byte slice but always
    11  // returns 16-byte addresses.
    12  
    13  package net
    14  
    15  import (
    16  	"internal/bytealg"
    17  	"internal/itoa"
    18  	"net/netip"
    19  )
    20  
    21  // IP address lengths (bytes).
    22  const (
    23  	IPv4len = 4
    24  	IPv6len = 16
    25  )
    26  
    27  // An IP is a single IP address, a slice of bytes.
    28  // Functions in this package accept either 4-byte (IPv4)
    29  // or 16-byte (IPv6) slices as input.
    30  //
    31  // Note that in this documentation, referring to an
    32  // IP address as an IPv4 address or an IPv6 address
    33  // is a semantic property of the address, not just the
    34  // length of the byte slice: a 16-byte slice can still
    35  // be an IPv4 address.
    36  type IP []byte
    37  
    38  // An IPMask is a bitmask that can be used to manipulate
    39  // IP addresses for IP addressing and routing.
    40  //
    41  // See type [IPNet] and func [ParseCIDR] for details.
    42  type IPMask []byte
    43  
    44  // An IPNet represents an IP network.
    45  type IPNet struct {
    46  	IP   IP     // network number
    47  	Mask IPMask // network mask
    48  }
    49  
    50  // IPv4 returns the IP address (in 16-byte form) of the
    51  // IPv4 address a.b.c.d.
    52  func IPv4(a, b, c, d byte) IP {
    53  	p := make(IP, IPv6len)
    54  	copy(p, v4InV6Prefix)
    55  	p[12] = a
    56  	p[13] = b
    57  	p[14] = c
    58  	p[15] = d
    59  	return p
    60  }
    61  
    62  var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
    63  
    64  // IPv4Mask returns the IP mask (in 4-byte form) of the
    65  // IPv4 mask a.b.c.d.
    66  func IPv4Mask(a, b, c, d byte) IPMask {
    67  	p := make(IPMask, IPv4len)
    68  	p[0] = a
    69  	p[1] = b
    70  	p[2] = c
    71  	p[3] = d
    72  	return p
    73  }
    74  
    75  // CIDRMask returns an [IPMask] consisting of 'ones' 1 bits
    76  // followed by 0s up to a total length of 'bits' bits.
    77  // For a mask of this form, CIDRMask is the inverse of [IPMask.Size].
    78  func CIDRMask(ones, bits int) IPMask {
    79  	if bits != 8*IPv4len && bits != 8*IPv6len {
    80  		return nil
    81  	}
    82  	if ones < 0 || ones > bits {
    83  		return nil
    84  	}
    85  	l := bits / 8
    86  	m := make(IPMask, l)
    87  	n := uint(ones)
    88  	for i := 0; i < l; i++ {
    89  		if n >= 8 {
    90  			m[i] = 0xff
    91  			n -= 8
    92  			continue
    93  		}
    94  		m[i] = ^byte(0xff >> n)
    95  		n = 0
    96  	}
    97  	return m
    98  }
    99  
   100  // Well-known IPv4 addresses
   101  var (
   102  	IPv4bcast     = IPv4(255, 255, 255, 255) // limited broadcast
   103  	IPv4allsys    = IPv4(224, 0, 0, 1)       // all systems
   104  	IPv4allrouter = IPv4(224, 0, 0, 2)       // all routers
   105  	IPv4zero      = IPv4(0, 0, 0, 0)         // all zeros
   106  )
   107  
   108  // Well-known IPv6 addresses
   109  var (
   110  	IPv6zero                   = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
   111  	IPv6unspecified            = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
   112  	IPv6loopback               = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
   113  	IPv6interfacelocalallnodes = IP{0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
   114  	IPv6linklocalallnodes      = IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
   115  	IPv6linklocalallrouters    = IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02}
   116  )
   117  
   118  // IsUnspecified reports whether ip is an unspecified address, either
   119  // the IPv4 address "0.0.0.0" or the IPv6 address "::".
   120  func (ip IP) IsUnspecified() bool {
   121  	return ip.Equal(IPv4zero) || ip.Equal(IPv6unspecified)
   122  }
   123  
   124  // IsLoopback reports whether ip is a loopback address.
   125  func (ip IP) IsLoopback() bool {
   126  	if ip4 := ip.To4(); ip4 != nil {
   127  		return ip4[0] == 127
   128  	}
   129  	return ip.Equal(IPv6loopback)
   130  }
   131  
   132  // IsPrivate reports whether ip is a private address, according to
   133  // RFC 1918 (IPv4 addresses) and RFC 4193 (IPv6 addresses).
   134  func (ip IP) IsPrivate() bool {
   135  	if ip4 := ip.To4(); ip4 != nil {
   136  		// Following RFC 1918, Section 3. Private Address Space which says:
   137  		//   The Internet Assigned Numbers Authority (IANA) has reserved the
   138  		//   following three blocks of the IP address space for private internets:
   139  		//     10.0.0.0        -   10.255.255.255  (10/8 prefix)
   140  		//     172.16.0.0      -   172.31.255.255  (172.16/12 prefix)
   141  		//     192.168.0.0     -   192.168.255.255 (192.168/16 prefix)
   142  		return ip4[0] == 10 ||
   143  			(ip4[0] == 172 && ip4[1]&0xf0 == 16) ||
   144  			(ip4[0] == 192 && ip4[1] == 168)
   145  	}
   146  	// Following RFC 4193, Section 8. IANA Considerations which says:
   147  	//   The IANA has assigned the FC00::/7 prefix to "Unique Local Unicast".
   148  	return len(ip) == IPv6len && ip[0]&0xfe == 0xfc
   149  }
   150  
   151  // IsMulticast reports whether ip is a multicast address.
   152  func (ip IP) IsMulticast() bool {
   153  	if ip4 := ip.To4(); ip4 != nil {
   154  		return ip4[0]&0xf0 == 0xe0
   155  	}
   156  	return len(ip) == IPv6len && ip[0] == 0xff
   157  }
   158  
   159  // IsInterfaceLocalMulticast reports whether ip is
   160  // an interface-local multicast address.
   161  func (ip IP) IsInterfaceLocalMulticast() bool {
   162  	return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x01
   163  }
   164  
   165  // IsLinkLocalMulticast reports whether ip is a link-local
   166  // multicast address.
   167  func (ip IP) IsLinkLocalMulticast() bool {
   168  	if ip4 := ip.To4(); ip4 != nil {
   169  		return ip4[0] == 224 && ip4[1] == 0 && ip4[2] == 0
   170  	}
   171  	return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x02
   172  }
   173  
   174  // IsLinkLocalUnicast reports whether ip is a link-local
   175  // unicast address.
   176  func (ip IP) IsLinkLocalUnicast() bool {
   177  	if ip4 := ip.To4(); ip4 != nil {
   178  		return ip4[0] == 169 && ip4[1] == 254
   179  	}
   180  	return len(ip) == IPv6len && ip[0] == 0xfe && ip[1]&0xc0 == 0x80
   181  }
   182  
   183  // IsGlobalUnicast reports whether ip is a global unicast
   184  // address.
   185  //
   186  // The identification of global unicast addresses uses address type
   187  // identification as defined in RFC 1122, RFC 4632 and RFC 4291 with
   188  // the exception of IPv4 directed broadcast addresses.
   189  // It returns true even if ip is in IPv4 private address space or
   190  // local IPv6 unicast address space.
   191  func (ip IP) IsGlobalUnicast() bool {
   192  	return (len(ip) == IPv4len || len(ip) == IPv6len) &&
   193  		!ip.Equal(IPv4bcast) &&
   194  		!ip.IsUnspecified() &&
   195  		!ip.IsLoopback() &&
   196  		!ip.IsMulticast() &&
   197  		!ip.IsLinkLocalUnicast()
   198  }
   199  
   200  // Is p all zeros?
   201  func isZeros(p IP) bool {
   202  	for i := 0; i < len(p); i++ {
   203  		if p[i] != 0 {
   204  			return false
   205  		}
   206  	}
   207  	return true
   208  }
   209  
   210  // To4 converts the IPv4 address ip to a 4-byte representation.
   211  // If ip is not an IPv4 address, To4 returns nil.
   212  func (ip IP) To4() IP {
   213  	if len(ip) == IPv4len {
   214  		return ip
   215  	}
   216  	if len(ip) == IPv6len &&
   217  		isZeros(ip[0:10]) &&
   218  		ip[10] == 0xff &&
   219  		ip[11] == 0xff {
   220  		return ip[12:16]
   221  	}
   222  	return nil
   223  }
   224  
   225  // To16 converts the IP address ip to a 16-byte representation.
   226  // If ip is not an IP address (it is the wrong length), To16 returns nil.
   227  func (ip IP) To16() IP {
   228  	if len(ip) == IPv4len {
   229  		return IPv4(ip[0], ip[1], ip[2], ip[3])
   230  	}
   231  	if len(ip) == IPv6len {
   232  		return ip
   233  	}
   234  	return nil
   235  }
   236  
   237  // Default route masks for IPv4.
   238  var (
   239  	classAMask = IPv4Mask(0xff, 0, 0, 0)
   240  	classBMask = IPv4Mask(0xff, 0xff, 0, 0)
   241  	classCMask = IPv4Mask(0xff, 0xff, 0xff, 0)
   242  )
   243  
   244  // DefaultMask returns the default IP mask for the IP address ip.
   245  // Only IPv4 addresses have default masks; DefaultMask returns
   246  // nil if ip is not a valid IPv4 address.
   247  func (ip IP) DefaultMask() IPMask {
   248  	if ip = ip.To4(); ip == nil {
   249  		return nil
   250  	}
   251  	switch {
   252  	case ip[0] < 0x80:
   253  		return classAMask
   254  	case ip[0] < 0xC0:
   255  		return classBMask
   256  	default:
   257  		return classCMask
   258  	}
   259  }
   260  
   261  func allFF(b []byte) bool {
   262  	for _, c := range b {
   263  		if c != 0xff {
   264  			return false
   265  		}
   266  	}
   267  	return true
   268  }
   269  
   270  // Mask returns the result of masking the IP address ip with mask.
   271  func (ip IP) Mask(mask IPMask) IP {
   272  	if len(mask) == IPv6len && len(ip) == IPv4len && allFF(mask[:12]) {
   273  		mask = mask[12:]
   274  	}
   275  	if len(mask) == IPv4len && len(ip) == IPv6len && bytealg.Equal(ip[:12], v4InV6Prefix) {
   276  		ip = ip[12:]
   277  	}
   278  	n := len(ip)
   279  	if n != len(mask) {
   280  		return nil
   281  	}
   282  	out := make(IP, n)
   283  	for i := 0; i < n; i++ {
   284  		out[i] = ip[i] & mask[i]
   285  	}
   286  	return out
   287  }
   288  
   289  // String returns the string form of the IP address ip.
   290  // It returns one of 4 forms:
   291  //   - "<nil>", if ip has length 0
   292  //   - dotted decimal ("192.0.2.1"), if ip is an IPv4 or IP4-mapped IPv6 address
   293  //   - IPv6 conforming to RFC 5952 ("2001:db8::1"), if ip is a valid IPv6 address
   294  //   - the hexadecimal form of ip, without punctuation, if no other cases apply
   295  func (ip IP) String() string {
   296  	if len(ip) == 0 {
   297  		return "<nil>"
   298  	}
   299  
   300  	if len(ip) != IPv4len && len(ip) != IPv6len {
   301  		return "?" + hexString(ip)
   302  	}
   303  	// If IPv4, use dotted notation.
   304  	if p4 := ip.To4(); len(p4) == IPv4len {
   305  		return netip.AddrFrom4([4]byte(p4)).String()
   306  	}
   307  	return netip.AddrFrom16([16]byte(ip)).String()
   308  }
   309  
   310  func hexString(b []byte) string {
   311  	s := make([]byte, len(b)*2)
   312  	for i, tn := range b {
   313  		s[i*2], s[i*2+1] = hexDigit[tn>>4], hexDigit[tn&0xf]
   314  	}
   315  	return string(s)
   316  }
   317  
   318  // ipEmptyString is like ip.String except that it returns
   319  // an empty string when ip is unset.
   320  func ipEmptyString(ip IP) string {
   321  	if len(ip) == 0 {
   322  		return ""
   323  	}
   324  	return ip.String()
   325  }
   326  
   327  // MarshalText implements the [encoding.TextMarshaler] interface.
   328  // The encoding is the same as returned by [IP.String], with one exception:
   329  // When len(ip) is zero, it returns an empty slice.
   330  func (ip IP) MarshalText() ([]byte, error) {
   331  	if len(ip) == 0 {
   332  		return []byte(""), nil
   333  	}
   334  	if len(ip) != IPv4len && len(ip) != IPv6len {
   335  		return nil, &AddrError{Err: "invalid IP address", Addr: hexString(ip)}
   336  	}
   337  	return []byte(ip.String()), nil
   338  }
   339  
   340  // UnmarshalText implements the [encoding.TextUnmarshaler] interface.
   341  // The IP address is expected in a form accepted by [ParseIP].
   342  func (ip *IP) UnmarshalText(text []byte) error {
   343  	if len(text) == 0 {
   344  		*ip = nil
   345  		return nil
   346  	}
   347  	s := string(text)
   348  	x := ParseIP(s)
   349  	if x == nil {
   350  		return &ParseError{Type: "IP address", Text: s}
   351  	}
   352  	*ip = x
   353  	return nil
   354  }
   355  
   356  // Equal reports whether ip and x are the same IP address.
   357  // An IPv4 address and that same address in IPv6 form are
   358  // considered to be equal.
   359  func (ip IP) Equal(x IP) bool {
   360  	if len(ip) == len(x) {
   361  		return bytealg.Equal(ip, x)
   362  	}
   363  	if len(ip) == IPv4len && len(x) == IPv6len {
   364  		return bytealg.Equal(x[0:12], v4InV6Prefix) && bytealg.Equal(ip, x[12:])
   365  	}
   366  	if len(ip) == IPv6len && len(x) == IPv4len {
   367  		return bytealg.Equal(ip[0:12], v4InV6Prefix) && bytealg.Equal(ip[12:], x)
   368  	}
   369  	return false
   370  }
   371  
   372  func (ip IP) matchAddrFamily(x IP) bool {
   373  	return ip.To4() != nil && x.To4() != nil || ip.To16() != nil && ip.To4() == nil && x.To16() != nil && x.To4() == nil
   374  }
   375  
   376  // If mask is a sequence of 1 bits followed by 0 bits,
   377  // return the number of 1 bits.
   378  func simpleMaskLength(mask IPMask) int {
   379  	var n int
   380  	for i, v := range mask {
   381  		if v == 0xff {
   382  			n += 8
   383  			continue
   384  		}
   385  		// found non-ff byte
   386  		// count 1 bits
   387  		for v&0x80 != 0 {
   388  			n++
   389  			v <<= 1
   390  		}
   391  		// rest must be 0 bits
   392  		if v != 0 {
   393  			return -1
   394  		}
   395  		for i++; i < len(mask); i++ {
   396  			if mask[i] != 0 {
   397  				return -1
   398  			}
   399  		}
   400  		break
   401  	}
   402  	return n
   403  }
   404  
   405  // Size returns the number of leading ones and total bits in the mask.
   406  // If the mask is not in the canonical form--ones followed by zeros--then
   407  // Size returns 0, 0.
   408  func (m IPMask) Size() (ones, bits int) {
   409  	ones, bits = simpleMaskLength(m), len(m)*8
   410  	if ones == -1 {
   411  		return 0, 0
   412  	}
   413  	return
   414  }
   415  
   416  // String returns the hexadecimal form of m, with no punctuation.
   417  func (m IPMask) String() string {
   418  	if len(m) == 0 {
   419  		return "<nil>"
   420  	}
   421  	return hexString(m)
   422  }
   423  
   424  func networkNumberAndMask(n *IPNet) (ip IP, m IPMask) {
   425  	if ip = n.IP.To4(); ip == nil {
   426  		ip = n.IP
   427  		if len(ip) != IPv6len {
   428  			return nil, nil
   429  		}
   430  	}
   431  	m = n.Mask
   432  	switch len(m) {
   433  	case IPv4len:
   434  		if len(ip) != IPv4len {
   435  			return nil, nil
   436  		}
   437  	case IPv6len:
   438  		if len(ip) == IPv4len {
   439  			m = m[12:]
   440  		}
   441  	default:
   442  		return nil, nil
   443  	}
   444  	return
   445  }
   446  
   447  // Contains reports whether the network includes ip.
   448  func (n *IPNet) Contains(ip IP) bool {
   449  	nn, m := networkNumberAndMask(n)
   450  	if x := ip.To4(); x != nil {
   451  		ip = x
   452  	}
   453  	l := len(ip)
   454  	if l != len(nn) {
   455  		return false
   456  	}
   457  	for i := 0; i < l; i++ {
   458  		if nn[i]&m[i] != ip[i]&m[i] {
   459  			return false
   460  		}
   461  	}
   462  	return true
   463  }
   464  
   465  // Network returns the address's network name, "ip+net".
   466  func (n *IPNet) Network() string { return "ip+net" }
   467  
   468  // String returns the CIDR notation of n like "192.0.2.0/24"
   469  // or "2001:db8::/48" as defined in RFC 4632 and RFC 4291.
   470  // If the mask is not in the canonical form, it returns the
   471  // string which consists of an IP address, followed by a slash
   472  // character and a mask expressed as hexadecimal form with no
   473  // punctuation like "198.51.100.0/c000ff00".
   474  func (n *IPNet) String() string {
   475  	if n == nil {
   476  		return "<nil>"
   477  	}
   478  	nn, m := networkNumberAndMask(n)
   479  	if nn == nil || m == nil {
   480  		return "<nil>"
   481  	}
   482  	l := simpleMaskLength(m)
   483  	if l == -1 {
   484  		return nn.String() + "/" + m.String()
   485  	}
   486  	return nn.String() + "/" + itoa.Uitoa(uint(l))
   487  }
   488  
   489  // ParseIP parses s as an IP address, returning the result.
   490  // The string s can be in IPv4 dotted decimal ("192.0.2.1"), IPv6
   491  // ("2001:db8::68"), or IPv4-mapped IPv6 ("::ffff:192.0.2.1") form.
   492  // If s is not a valid textual representation of an IP address,
   493  // ParseIP returns nil.
   494  func ParseIP(s string) IP {
   495  	if addr, valid := parseIP(s); valid {
   496  		return IP(addr[:])
   497  	}
   498  	return nil
   499  }
   500  
   501  func parseIP(s string) ([16]byte, bool) {
   502  	ip, err := netip.ParseAddr(s)
   503  	if err != nil || ip.Zone() != "" {
   504  		return [16]byte{}, false
   505  	}
   506  	return ip.As16(), true
   507  }
   508  
   509  // ParseCIDR parses s as a CIDR notation IP address and prefix length,
   510  // like "192.0.2.0/24" or "2001:db8::/32", as defined in
   511  // RFC 4632 and RFC 4291.
   512  //
   513  // It returns the IP address and the network implied by the IP and
   514  // prefix length.
   515  // For example, ParseCIDR("192.0.2.1/24") returns the IP address
   516  // 192.0.2.1 and the network 192.0.2.0/24.
   517  func ParseCIDR(s string) (IP, *IPNet, error) {
   518  	i := bytealg.IndexByteString(s, '/')
   519  	if i < 0 {
   520  		return nil, nil, &ParseError{Type: "CIDR address", Text: s}
   521  	}
   522  	addr, mask := s[:i], s[i+1:]
   523  
   524  	ipAddr, err := netip.ParseAddr(addr)
   525  	if err != nil || ipAddr.Zone() != "" {
   526  		return nil, nil, &ParseError{Type: "CIDR address", Text: s}
   527  	}
   528  
   529  	n, i, ok := dtoi(mask)
   530  	if !ok || i != len(mask) || n < 0 || n > ipAddr.BitLen() {
   531  		return nil, nil, &ParseError{Type: "CIDR address", Text: s}
   532  	}
   533  	m := CIDRMask(n, ipAddr.BitLen())
   534  	addr16 := ipAddr.As16()
   535  	return IP(addr16[:]), &IPNet{IP: IP(addr16[:]).Mask(m), Mask: m}, nil
   536  }
   537  
   538  func copyIP(x IP) IP {
   539  	y := make(IP, len(x))
   540  	copy(y, x)
   541  	return y
   542  }
   543  

View as plain text