...

Source file src/net/ip.go

Documentation: net

		 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  )
		19  
		20  // IP address lengths (bytes).
		21  const (
		22  	IPv4len = 4
		23  	IPv6len = 16
		24  )
		25  
		26  // An IP is a single IP address, a slice of bytes.
		27  // Functions in this package accept either 4-byte (IPv4)
		28  // or 16-byte (IPv6) slices as input.
		29  //
		30  // Note that in this documentation, referring to an
		31  // IP address as an IPv4 address or an IPv6 address
		32  // is a semantic property of the address, not just the
		33  // length of the byte slice: a 16-byte slice can still
		34  // be an IPv4 address.
		35  type IP []byte
		36  
		37  // An IPMask is a bitmask that can be used to manipulate
		38  // IP addresses for IP addressing and routing.
		39  //
		40  // See type IPNet and func ParseCIDR for details.
		41  type IPMask []byte
		42  
		43  // An IPNet represents an IP network.
		44  type IPNet struct {
		45  	IP	 IP		 // network number
		46  	Mask IPMask // network mask
		47  }
		48  
		49  // IPv4 returns the IP address (in 16-byte form) of the
		50  // IPv4 address a.b.c.d.
		51  func IPv4(a, b, c, d byte) IP {
		52  	p := make(IP, IPv6len)
		53  	copy(p, v4InV6Prefix)
		54  	p[12] = a
		55  	p[13] = b
		56  	p[14] = c
		57  	p[15] = d
		58  	return p
		59  }
		60  
		61  var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
		62  
		63  // IPv4Mask returns the IP mask (in 4-byte form) of the
		64  // IPv4 mask a.b.c.d.
		65  func IPv4Mask(a, b, c, d byte) IPMask {
		66  	p := make(IPMask, IPv4len)
		67  	p[0] = a
		68  	p[1] = b
		69  	p[2] = c
		70  	p[3] = d
		71  	return p
		72  }
		73  
		74  // CIDRMask returns an IPMask consisting of 'ones' 1 bits
		75  // followed by 0s up to a total length of 'bits' bits.
		76  // For a mask of this form, CIDRMask is the inverse of IPMask.Size.
		77  func CIDRMask(ones, bits int) IPMask {
		78  	if bits != 8*IPv4len && bits != 8*IPv6len {
		79  		return nil
		80  	}
		81  	if ones < 0 || ones > bits {
		82  		return nil
		83  	}
		84  	l := bits / 8
		85  	m := make(IPMask, l)
		86  	n := uint(ones)
		87  	for i := 0; i < l; i++ {
		88  		if n >= 8 {
		89  			m[i] = 0xff
		90  			n -= 8
		91  			continue
		92  		}
		93  		m[i] = ^byte(0xff >> n)
		94  		n = 0
		95  	}
		96  	return m
		97  }
		98  
		99  // Well-known IPv4 addresses
	 100  var (
	 101  	IPv4bcast		 = IPv4(255, 255, 255, 255) // limited broadcast
	 102  	IPv4allsys		= IPv4(224, 0, 0, 1)			 // all systems
	 103  	IPv4allrouter = IPv4(224, 0, 0, 2)			 // all routers
	 104  	IPv4zero			= IPv4(0, 0, 0, 0)				 // all zeros
	 105  )
	 106  
	 107  // Well-known IPv6 addresses
	 108  var (
	 109  	IPv6zero									 = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
	 110  	IPv6unspecified						= IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
	 111  	IPv6loopback							 = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
	 112  	IPv6interfacelocalallnodes = IP{0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
	 113  	IPv6linklocalallnodes			= IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
	 114  	IPv6linklocalallrouters		= IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02}
	 115  )
	 116  
	 117  // IsUnspecified reports whether ip is an unspecified address, either
	 118  // the IPv4 address "0.0.0.0" or the IPv6 address "::".
	 119  func (ip IP) IsUnspecified() bool {
	 120  	return ip.Equal(IPv4zero) || ip.Equal(IPv6unspecified)
	 121  }
	 122  
	 123  // IsLoopback reports whether ip is a loopback address.
	 124  func (ip IP) IsLoopback() bool {
	 125  	if ip4 := ip.To4(); ip4 != nil {
	 126  		return ip4[0] == 127
	 127  	}
	 128  	return ip.Equal(IPv6loopback)
	 129  }
	 130  
	 131  // IsPrivate reports whether ip is a private address, according to
	 132  // RFC 1918 (IPv4 addresses) and RFC 4193 (IPv6 addresses).
	 133  func (ip IP) IsPrivate() bool {
	 134  	if ip4 := ip.To4(); ip4 != nil {
	 135  		// Following RFC 1918, Section 3. Private Address Space which says:
	 136  		//	 The Internet Assigned Numbers Authority (IANA) has reserved the
	 137  		//	 following three blocks of the IP address space for private internets:
	 138  		//		 10.0.0.0				-	 10.255.255.255	(10/8 prefix)
	 139  		//		 172.16.0.0			-	 172.31.255.255	(172.16/12 prefix)
	 140  		//		 192.168.0.0		 -	 192.168.255.255 (192.168/16 prefix)
	 141  		return ip4[0] == 10 ||
	 142  			(ip4[0] == 172 && ip4[1]&0xf0 == 16) ||
	 143  			(ip4[0] == 192 && ip4[1] == 168)
	 144  	}
	 145  	// Following RFC 4193, Section 8. IANA Considerations which says:
	 146  	//	 The IANA has assigned the FC00::/7 prefix to "Unique Local Unicast".
	 147  	return len(ip) == IPv6len && ip[0]&0xfe == 0xfc
	 148  }
	 149  
	 150  // IsMulticast reports whether ip is a multicast address.
	 151  func (ip IP) IsMulticast() bool {
	 152  	if ip4 := ip.To4(); ip4 != nil {
	 153  		return ip4[0]&0xf0 == 0xe0
	 154  	}
	 155  	return len(ip) == IPv6len && ip[0] == 0xff
	 156  }
	 157  
	 158  // IsInterfaceLocalMulticast reports whether ip is
	 159  // an interface-local multicast address.
	 160  func (ip IP) IsInterfaceLocalMulticast() bool {
	 161  	return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x01
	 162  }
	 163  
	 164  // IsLinkLocalMulticast reports whether ip is a link-local
	 165  // multicast address.
	 166  func (ip IP) IsLinkLocalMulticast() bool {
	 167  	if ip4 := ip.To4(); ip4 != nil {
	 168  		return ip4[0] == 224 && ip4[1] == 0 && ip4[2] == 0
	 169  	}
	 170  	return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x02
	 171  }
	 172  
	 173  // IsLinkLocalUnicast reports whether ip is a link-local
	 174  // unicast address.
	 175  func (ip IP) IsLinkLocalUnicast() bool {
	 176  	if ip4 := ip.To4(); ip4 != nil {
	 177  		return ip4[0] == 169 && ip4[1] == 254
	 178  	}
	 179  	return len(ip) == IPv6len && ip[0] == 0xfe && ip[1]&0xc0 == 0x80
	 180  }
	 181  
	 182  // IsGlobalUnicast reports whether ip is a global unicast
	 183  // address.
	 184  //
	 185  // The identification of global unicast addresses uses address type
	 186  // identification as defined in RFC 1122, RFC 4632 and RFC 4291 with
	 187  // the exception of IPv4 directed broadcast addresses.
	 188  // It returns true even if ip is in IPv4 private address space or
	 189  // local IPv6 unicast address space.
	 190  func (ip IP) IsGlobalUnicast() bool {
	 191  	return (len(ip) == IPv4len || len(ip) == IPv6len) &&
	 192  		!ip.Equal(IPv4bcast) &&
	 193  		!ip.IsUnspecified() &&
	 194  		!ip.IsLoopback() &&
	 195  		!ip.IsMulticast() &&
	 196  		!ip.IsLinkLocalUnicast()
	 197  }
	 198  
	 199  // Is p all zeros?
	 200  func isZeros(p IP) bool {
	 201  	for i := 0; i < len(p); i++ {
	 202  		if p[i] != 0 {
	 203  			return false
	 204  		}
	 205  	}
	 206  	return true
	 207  }
	 208  
	 209  // To4 converts the IPv4 address ip to a 4-byte representation.
	 210  // If ip is not an IPv4 address, To4 returns nil.
	 211  func (ip IP) To4() IP {
	 212  	if len(ip) == IPv4len {
	 213  		return ip
	 214  	}
	 215  	if len(ip) == IPv6len &&
	 216  		isZeros(ip[0:10]) &&
	 217  		ip[10] == 0xff &&
	 218  		ip[11] == 0xff {
	 219  		return ip[12:16]
	 220  	}
	 221  	return nil
	 222  }
	 223  
	 224  // To16 converts the IP address ip to a 16-byte representation.
	 225  // If ip is not an IP address (it is the wrong length), To16 returns nil.
	 226  func (ip IP) To16() IP {
	 227  	if len(ip) == IPv4len {
	 228  		return IPv4(ip[0], ip[1], ip[2], ip[3])
	 229  	}
	 230  	if len(ip) == IPv6len {
	 231  		return ip
	 232  	}
	 233  	return nil
	 234  }
	 235  
	 236  // Default route masks for IPv4.
	 237  var (
	 238  	classAMask = IPv4Mask(0xff, 0, 0, 0)
	 239  	classBMask = IPv4Mask(0xff, 0xff, 0, 0)
	 240  	classCMask = IPv4Mask(0xff, 0xff, 0xff, 0)
	 241  )
	 242  
	 243  // DefaultMask returns the default IP mask for the IP address ip.
	 244  // Only IPv4 addresses have default masks; DefaultMask returns
	 245  // nil if ip is not a valid IPv4 address.
	 246  func (ip IP) DefaultMask() IPMask {
	 247  	if ip = ip.To4(); ip == nil {
	 248  		return nil
	 249  	}
	 250  	switch {
	 251  	case ip[0] < 0x80:
	 252  		return classAMask
	 253  	case ip[0] < 0xC0:
	 254  		return classBMask
	 255  	default:
	 256  		return classCMask
	 257  	}
	 258  }
	 259  
	 260  func allFF(b []byte) bool {
	 261  	for _, c := range b {
	 262  		if c != 0xff {
	 263  			return false
	 264  		}
	 265  	}
	 266  	return true
	 267  }
	 268  
	 269  // Mask returns the result of masking the IP address ip with mask.
	 270  func (ip IP) Mask(mask IPMask) IP {
	 271  	if len(mask) == IPv6len && len(ip) == IPv4len && allFF(mask[:12]) {
	 272  		mask = mask[12:]
	 273  	}
	 274  	if len(mask) == IPv4len && len(ip) == IPv6len && bytealg.Equal(ip[:12], v4InV6Prefix) {
	 275  		ip = ip[12:]
	 276  	}
	 277  	n := len(ip)
	 278  	if n != len(mask) {
	 279  		return nil
	 280  	}
	 281  	out := make(IP, n)
	 282  	for i := 0; i < n; i++ {
	 283  		out[i] = ip[i] & mask[i]
	 284  	}
	 285  	return out
	 286  }
	 287  
	 288  // ubtoa encodes the string form of the integer v to dst[start:] and
	 289  // returns the number of bytes written to dst. The caller must ensure
	 290  // that dst has sufficient length.
	 291  func ubtoa(dst []byte, start int, v byte) int {
	 292  	if v < 10 {
	 293  		dst[start] = v + '0'
	 294  		return 1
	 295  	} else if v < 100 {
	 296  		dst[start+1] = v%10 + '0'
	 297  		dst[start] = v/10 + '0'
	 298  		return 2
	 299  	}
	 300  
	 301  	dst[start+2] = v%10 + '0'
	 302  	dst[start+1] = (v/10)%10 + '0'
	 303  	dst[start] = v/100 + '0'
	 304  	return 3
	 305  }
	 306  
	 307  // String returns the string form of the IP address ip.
	 308  // It returns one of 4 forms:
	 309  //	 - "<nil>", if ip has length 0
	 310  //	 - dotted decimal ("192.0.2.1"), if ip is an IPv4 or IP4-mapped IPv6 address
	 311  //	 - IPv6 ("2001:db8::1"), if ip is a valid IPv6 address
	 312  //	 - the hexadecimal form of ip, without punctuation, if no other cases apply
	 313  func (ip IP) String() string {
	 314  	p := ip
	 315  
	 316  	if len(ip) == 0 {
	 317  		return "<nil>"
	 318  	}
	 319  
	 320  	// If IPv4, use dotted notation.
	 321  	if p4 := p.To4(); len(p4) == IPv4len {
	 322  		const maxIPv4StringLen = len("255.255.255.255")
	 323  		b := make([]byte, maxIPv4StringLen)
	 324  
	 325  		n := ubtoa(b, 0, p4[0])
	 326  		b[n] = '.'
	 327  		n++
	 328  
	 329  		n += ubtoa(b, n, p4[1])
	 330  		b[n] = '.'
	 331  		n++
	 332  
	 333  		n += ubtoa(b, n, p4[2])
	 334  		b[n] = '.'
	 335  		n++
	 336  
	 337  		n += ubtoa(b, n, p4[3])
	 338  		return string(b[:n])
	 339  	}
	 340  	if len(p) != IPv6len {
	 341  		return "?" + hexString(ip)
	 342  	}
	 343  
	 344  	// Find longest run of zeros.
	 345  	e0 := -1
	 346  	e1 := -1
	 347  	for i := 0; i < IPv6len; i += 2 {
	 348  		j := i
	 349  		for j < IPv6len && p[j] == 0 && p[j+1] == 0 {
	 350  			j += 2
	 351  		}
	 352  		if j > i && j-i > e1-e0 {
	 353  			e0 = i
	 354  			e1 = j
	 355  			i = j
	 356  		}
	 357  	}
	 358  	// The symbol "::" MUST NOT be used to shorten just one 16 bit 0 field.
	 359  	if e1-e0 <= 2 {
	 360  		e0 = -1
	 361  		e1 = -1
	 362  	}
	 363  
	 364  	const maxLen = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
	 365  	b := make([]byte, 0, maxLen)
	 366  
	 367  	// Print with possible :: in place of run of zeros
	 368  	for i := 0; i < IPv6len; i += 2 {
	 369  		if i == e0 {
	 370  			b = append(b, ':', ':')
	 371  			i = e1
	 372  			if i >= IPv6len {
	 373  				break
	 374  			}
	 375  		} else if i > 0 {
	 376  			b = append(b, ':')
	 377  		}
	 378  		b = appendHex(b, (uint32(p[i])<<8)|uint32(p[i+1]))
	 379  	}
	 380  	return string(b)
	 381  }
	 382  
	 383  func hexString(b []byte) string {
	 384  	s := make([]byte, len(b)*2)
	 385  	for i, tn := range b {
	 386  		s[i*2], s[i*2+1] = hexDigit[tn>>4], hexDigit[tn&0xf]
	 387  	}
	 388  	return string(s)
	 389  }
	 390  
	 391  // ipEmptyString is like ip.String except that it returns
	 392  // an empty string when ip is unset.
	 393  func ipEmptyString(ip IP) string {
	 394  	if len(ip) == 0 {
	 395  		return ""
	 396  	}
	 397  	return ip.String()
	 398  }
	 399  
	 400  // MarshalText implements the encoding.TextMarshaler interface.
	 401  // The encoding is the same as returned by String, with one exception:
	 402  // When len(ip) is zero, it returns an empty slice.
	 403  func (ip IP) MarshalText() ([]byte, error) {
	 404  	if len(ip) == 0 {
	 405  		return []byte(""), nil
	 406  	}
	 407  	if len(ip) != IPv4len && len(ip) != IPv6len {
	 408  		return nil, &AddrError{Err: "invalid IP address", Addr: hexString(ip)}
	 409  	}
	 410  	return []byte(ip.String()), nil
	 411  }
	 412  
	 413  // UnmarshalText implements the encoding.TextUnmarshaler interface.
	 414  // The IP address is expected in a form accepted by ParseIP.
	 415  func (ip *IP) UnmarshalText(text []byte) error {
	 416  	if len(text) == 0 {
	 417  		*ip = nil
	 418  		return nil
	 419  	}
	 420  	s := string(text)
	 421  	x := ParseIP(s)
	 422  	if x == nil {
	 423  		return &ParseError{Type: "IP address", Text: s}
	 424  	}
	 425  	*ip = x
	 426  	return nil
	 427  }
	 428  
	 429  // Equal reports whether ip and x are the same IP address.
	 430  // An IPv4 address and that same address in IPv6 form are
	 431  // considered to be equal.
	 432  func (ip IP) Equal(x IP) bool {
	 433  	if len(ip) == len(x) {
	 434  		return bytealg.Equal(ip, x)
	 435  	}
	 436  	if len(ip) == IPv4len && len(x) == IPv6len {
	 437  		return bytealg.Equal(x[0:12], v4InV6Prefix) && bytealg.Equal(ip, x[12:])
	 438  	}
	 439  	if len(ip) == IPv6len && len(x) == IPv4len {
	 440  		return bytealg.Equal(ip[0:12], v4InV6Prefix) && bytealg.Equal(ip[12:], x)
	 441  	}
	 442  	return false
	 443  }
	 444  
	 445  func (ip IP) matchAddrFamily(x IP) bool {
	 446  	return ip.To4() != nil && x.To4() != nil || ip.To16() != nil && ip.To4() == nil && x.To16() != nil && x.To4() == nil
	 447  }
	 448  
	 449  // If mask is a sequence of 1 bits followed by 0 bits,
	 450  // return the number of 1 bits.
	 451  func simpleMaskLength(mask IPMask) int {
	 452  	var n int
	 453  	for i, v := range mask {
	 454  		if v == 0xff {
	 455  			n += 8
	 456  			continue
	 457  		}
	 458  		// found non-ff byte
	 459  		// count 1 bits
	 460  		for v&0x80 != 0 {
	 461  			n++
	 462  			v <<= 1
	 463  		}
	 464  		// rest must be 0 bits
	 465  		if v != 0 {
	 466  			return -1
	 467  		}
	 468  		for i++; i < len(mask); i++ {
	 469  			if mask[i] != 0 {
	 470  				return -1
	 471  			}
	 472  		}
	 473  		break
	 474  	}
	 475  	return n
	 476  }
	 477  
	 478  // Size returns the number of leading ones and total bits in the mask.
	 479  // If the mask is not in the canonical form--ones followed by zeros--then
	 480  // Size returns 0, 0.
	 481  func (m IPMask) Size() (ones, bits int) {
	 482  	ones, bits = simpleMaskLength(m), len(m)*8
	 483  	if ones == -1 {
	 484  		return 0, 0
	 485  	}
	 486  	return
	 487  }
	 488  
	 489  // String returns the hexadecimal form of m, with no punctuation.
	 490  func (m IPMask) String() string {
	 491  	if len(m) == 0 {
	 492  		return "<nil>"
	 493  	}
	 494  	return hexString(m)
	 495  }
	 496  
	 497  func networkNumberAndMask(n *IPNet) (ip IP, m IPMask) {
	 498  	if ip = n.IP.To4(); ip == nil {
	 499  		ip = n.IP
	 500  		if len(ip) != IPv6len {
	 501  			return nil, nil
	 502  		}
	 503  	}
	 504  	m = n.Mask
	 505  	switch len(m) {
	 506  	case IPv4len:
	 507  		if len(ip) != IPv4len {
	 508  			return nil, nil
	 509  		}
	 510  	case IPv6len:
	 511  		if len(ip) == IPv4len {
	 512  			m = m[12:]
	 513  		}
	 514  	default:
	 515  		return nil, nil
	 516  	}
	 517  	return
	 518  }
	 519  
	 520  // Contains reports whether the network includes ip.
	 521  func (n *IPNet) Contains(ip IP) bool {
	 522  	nn, m := networkNumberAndMask(n)
	 523  	if x := ip.To4(); x != nil {
	 524  		ip = x
	 525  	}
	 526  	l := len(ip)
	 527  	if l != len(nn) {
	 528  		return false
	 529  	}
	 530  	for i := 0; i < l; i++ {
	 531  		if nn[i]&m[i] != ip[i]&m[i] {
	 532  			return false
	 533  		}
	 534  	}
	 535  	return true
	 536  }
	 537  
	 538  // Network returns the address's network name, "ip+net".
	 539  func (n *IPNet) Network() string { return "ip+net" }
	 540  
	 541  // String returns the CIDR notation of n like "192.0.2.0/24"
	 542  // or "2001:db8::/48" as defined in RFC 4632 and RFC 4291.
	 543  // If the mask is not in the canonical form, it returns the
	 544  // string which consists of an IP address, followed by a slash
	 545  // character and a mask expressed as hexadecimal form with no
	 546  // punctuation like "198.51.100.0/c000ff00".
	 547  func (n *IPNet) String() string {
	 548  	nn, m := networkNumberAndMask(n)
	 549  	if nn == nil || m == nil {
	 550  		return "<nil>"
	 551  	}
	 552  	l := simpleMaskLength(m)
	 553  	if l == -1 {
	 554  		return nn.String() + "/" + m.String()
	 555  	}
	 556  	return nn.String() + "/" + itoa.Uitoa(uint(l))
	 557  }
	 558  
	 559  // Parse IPv4 address (d.d.d.d).
	 560  func parseIPv4(s string) IP {
	 561  	var p [IPv4len]byte
	 562  	for i := 0; i < IPv4len; i++ {
	 563  		if len(s) == 0 {
	 564  			// Missing octets.
	 565  			return nil
	 566  		}
	 567  		if i > 0 {
	 568  			if s[0] != '.' {
	 569  				return nil
	 570  			}
	 571  			s = s[1:]
	 572  		}
	 573  		n, c, ok := dtoi(s)
	 574  		if !ok || n > 0xFF {
	 575  			return nil
	 576  		}
	 577  		if c > 1 && s[0] == '0' {
	 578  			// Reject non-zero components with leading zeroes.
	 579  			return nil
	 580  		}
	 581  		s = s[c:]
	 582  		p[i] = byte(n)
	 583  	}
	 584  	if len(s) != 0 {
	 585  		return nil
	 586  	}
	 587  	return IPv4(p[0], p[1], p[2], p[3])
	 588  }
	 589  
	 590  // parseIPv6Zone parses s as a literal IPv6 address and its associated zone
	 591  // identifier which is described in RFC 4007.
	 592  func parseIPv6Zone(s string) (IP, string) {
	 593  	s, zone := splitHostZone(s)
	 594  	return parseIPv6(s), zone
	 595  }
	 596  
	 597  // parseIPv6 parses s as a literal IPv6 address described in RFC 4291
	 598  // and RFC 5952.
	 599  func parseIPv6(s string) (ip IP) {
	 600  	ip = make(IP, IPv6len)
	 601  	ellipsis := -1 // position of ellipsis in ip
	 602  
	 603  	// Might have leading ellipsis
	 604  	if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
	 605  		ellipsis = 0
	 606  		s = s[2:]
	 607  		// Might be only ellipsis
	 608  		if len(s) == 0 {
	 609  			return ip
	 610  		}
	 611  	}
	 612  
	 613  	// Loop, parsing hex numbers followed by colon.
	 614  	i := 0
	 615  	for i < IPv6len {
	 616  		// Hex number.
	 617  		n, c, ok := xtoi(s)
	 618  		if !ok || n > 0xFFFF {
	 619  			return nil
	 620  		}
	 621  
	 622  		// If followed by dot, might be in trailing IPv4.
	 623  		if c < len(s) && s[c] == '.' {
	 624  			if ellipsis < 0 && i != IPv6len-IPv4len {
	 625  				// Not the right place.
	 626  				return nil
	 627  			}
	 628  			if i+IPv4len > IPv6len {
	 629  				// Not enough room.
	 630  				return nil
	 631  			}
	 632  			ip4 := parseIPv4(s)
	 633  			if ip4 == nil {
	 634  				return nil
	 635  			}
	 636  			ip[i] = ip4[12]
	 637  			ip[i+1] = ip4[13]
	 638  			ip[i+2] = ip4[14]
	 639  			ip[i+3] = ip4[15]
	 640  			s = ""
	 641  			i += IPv4len
	 642  			break
	 643  		}
	 644  
	 645  		// Save this 16-bit chunk.
	 646  		ip[i] = byte(n >> 8)
	 647  		ip[i+1] = byte(n)
	 648  		i += 2
	 649  
	 650  		// Stop at end of string.
	 651  		s = s[c:]
	 652  		if len(s) == 0 {
	 653  			break
	 654  		}
	 655  
	 656  		// Otherwise must be followed by colon and more.
	 657  		if s[0] != ':' || len(s) == 1 {
	 658  			return nil
	 659  		}
	 660  		s = s[1:]
	 661  
	 662  		// Look for ellipsis.
	 663  		if s[0] == ':' {
	 664  			if ellipsis >= 0 { // already have one
	 665  				return nil
	 666  			}
	 667  			ellipsis = i
	 668  			s = s[1:]
	 669  			if len(s) == 0 { // can be at end
	 670  				break
	 671  			}
	 672  		}
	 673  	}
	 674  
	 675  	// Must have used entire string.
	 676  	if len(s) != 0 {
	 677  		return nil
	 678  	}
	 679  
	 680  	// If didn't parse enough, expand ellipsis.
	 681  	if i < IPv6len {
	 682  		if ellipsis < 0 {
	 683  			return nil
	 684  		}
	 685  		n := IPv6len - i
	 686  		for j := i - 1; j >= ellipsis; j-- {
	 687  			ip[j+n] = ip[j]
	 688  		}
	 689  		for j := ellipsis + n - 1; j >= ellipsis; j-- {
	 690  			ip[j] = 0
	 691  		}
	 692  	} else if ellipsis >= 0 {
	 693  		// Ellipsis must represent at least one 0 group.
	 694  		return nil
	 695  	}
	 696  	return ip
	 697  }
	 698  
	 699  // ParseIP parses s as an IP address, returning the result.
	 700  // The string s can be in IPv4 dotted decimal ("192.0.2.1"), IPv6
	 701  // ("2001:db8::68"), or IPv4-mapped IPv6 ("::ffff:192.0.2.1") form.
	 702  // If s is not a valid textual representation of an IP address,
	 703  // ParseIP returns nil.
	 704  func ParseIP(s string) IP {
	 705  	for i := 0; i < len(s); i++ {
	 706  		switch s[i] {
	 707  		case '.':
	 708  			return parseIPv4(s)
	 709  		case ':':
	 710  			return parseIPv6(s)
	 711  		}
	 712  	}
	 713  	return nil
	 714  }
	 715  
	 716  // parseIPZone parses s as an IP address, return it and its associated zone
	 717  // identifier (IPv6 only).
	 718  func parseIPZone(s string) (IP, string) {
	 719  	for i := 0; i < len(s); i++ {
	 720  		switch s[i] {
	 721  		case '.':
	 722  			return parseIPv4(s), ""
	 723  		case ':':
	 724  			return parseIPv6Zone(s)
	 725  		}
	 726  	}
	 727  	return nil, ""
	 728  }
	 729  
	 730  // ParseCIDR parses s as a CIDR notation IP address and prefix length,
	 731  // like "192.0.2.0/24" or "2001:db8::/32", as defined in
	 732  // RFC 4632 and RFC 4291.
	 733  //
	 734  // It returns the IP address and the network implied by the IP and
	 735  // prefix length.
	 736  // For example, ParseCIDR("192.0.2.1/24") returns the IP address
	 737  // 192.0.2.1 and the network 192.0.2.0/24.
	 738  func ParseCIDR(s string) (IP, *IPNet, error) {
	 739  	i := bytealg.IndexByteString(s, '/')
	 740  	if i < 0 {
	 741  		return nil, nil, &ParseError{Type: "CIDR address", Text: s}
	 742  	}
	 743  	addr, mask := s[:i], s[i+1:]
	 744  	iplen := IPv4len
	 745  	ip := parseIPv4(addr)
	 746  	if ip == nil {
	 747  		iplen = IPv6len
	 748  		ip = parseIPv6(addr)
	 749  	}
	 750  	n, i, ok := dtoi(mask)
	 751  	if ip == nil || !ok || i != len(mask) || n < 0 || n > 8*iplen {
	 752  		return nil, nil, &ParseError{Type: "CIDR address", Text: s}
	 753  	}
	 754  	m := CIDRMask(n, 8*iplen)
	 755  	return ip, &IPNet{IP: ip.Mask(m), Mask: m}, nil
	 756  }
	 757  

View as plain text