github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/net/ip.go (about) 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 }