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