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