]> Cypherpunks.ru repositories - gostls13.git/blob - src/net/netip/netip.go
99cb754fae87762b22c42b2014d6989558ee8019
[gostls13.git] / src / net / netip / netip.go
1 // Copyright 2020 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 // Package netip defines an IP address type that's a small value type.
6 // Building on that [Addr] type, the package also defines [AddrPort] (an
7 // IP address and a port) and [Prefix] (an IP address and a bit length
8 // prefix).
9 //
10 // Compared to the [net.IP] type, [Addr] type takes less memory, is immutable,
11 // and is comparable (supports == and being a map key).
12 package netip
13
14 import (
15         "cmp"
16         "errors"
17         "math"
18         "strconv"
19
20         "internal/bytealg"
21         "internal/intern"
22         "internal/itoa"
23 )
24
25 // Sizes: (64-bit)
26 //   net.IP:     24 byte slice header + {4, 16} = 28 to 40 bytes
27 //   net.IPAddr: 40 byte slice header + {4, 16} = 44 to 56 bytes + zone length
28 //   netip.Addr: 24 bytes (zone is per-name singleton, shared across all users)
29
30 // Addr represents an IPv4 or IPv6 address (with or without a scoped
31 // addressing zone), similar to [net.IP] or [net.IPAddr].
32 //
33 // Unlike [net.IP] or [net.IPAddr], Addr is a comparable value
34 // type (it supports == and can be a map key) and is immutable.
35 //
36 // The zero Addr is not a valid IP address.
37 // Addr{} is distinct from both 0.0.0.0 and ::.
38 type Addr struct {
39         // addr is the hi and lo bits of an IPv6 address. If z==z4,
40         // hi and lo contain the IPv4-mapped IPv6 address.
41         //
42         // hi and lo are constructed by interpreting a 16-byte IPv6
43         // address as a big-endian 128-bit number. The most significant
44         // bits of that number go into hi, the rest into lo.
45         //
46         // For example, 0011:2233:4455:6677:8899:aabb:ccdd:eeff is stored as:
47         //  addr.hi = 0x0011223344556677
48         //  addr.lo = 0x8899aabbccddeeff
49         //
50         // We store IPs like this, rather than as [16]byte, because it
51         // turns most operations on IPs into arithmetic and bit-twiddling
52         // operations on 64-bit registers, which is much faster than
53         // bytewise processing.
54         addr uint128
55
56         // z is a combination of the address family and the IPv6 zone.
57         //
58         // nil means invalid IP address (for a zero Addr).
59         // z4 means an IPv4 address.
60         // z6noz means an IPv6 address without a zone.
61         //
62         // Otherwise it's the interned zone name string.
63         z *intern.Value
64 }
65
66 // z0, z4, and z6noz are sentinel Addr.z values.
67 // See the Addr type's field docs.
68 var (
69         z0    = (*intern.Value)(nil)
70         z4    = new(intern.Value)
71         z6noz = new(intern.Value)
72 )
73
74 // IPv6LinkLocalAllNodes returns the IPv6 link-local all nodes multicast
75 // address ff02::1.
76 func IPv6LinkLocalAllNodes() Addr { return AddrFrom16([16]byte{0: 0xff, 1: 0x02, 15: 0x01}) }
77
78 // IPv6LinkLocalAllRouters returns the IPv6 link-local all routers multicast
79 // address ff02::2.
80 func IPv6LinkLocalAllRouters() Addr { return AddrFrom16([16]byte{0: 0xff, 1: 0x02, 15: 0x02}) }
81
82 // IPv6Loopback returns the IPv6 loopback address ::1.
83 func IPv6Loopback() Addr { return AddrFrom16([16]byte{15: 0x01}) }
84
85 // IPv6Unspecified returns the IPv6 unspecified address "::".
86 func IPv6Unspecified() Addr { return Addr{z: z6noz} }
87
88 // IPv4Unspecified returns the IPv4 unspecified address "0.0.0.0".
89 func IPv4Unspecified() Addr { return AddrFrom4([4]byte{}) }
90
91 // AddrFrom4 returns the address of the IPv4 address given by the bytes in addr.
92 func AddrFrom4(addr [4]byte) Addr {
93         return Addr{
94                 addr: uint128{0, 0xffff00000000 | uint64(addr[0])<<24 | uint64(addr[1])<<16 | uint64(addr[2])<<8 | uint64(addr[3])},
95                 z:    z4,
96         }
97 }
98
99 // AddrFrom16 returns the IPv6 address given by the bytes in addr.
100 // An IPv4-mapped IPv6 address is left as an IPv6 address.
101 // (Use Unmap to convert them if needed.)
102 func AddrFrom16(addr [16]byte) Addr {
103         return Addr{
104                 addr: uint128{
105                         beUint64(addr[:8]),
106                         beUint64(addr[8:]),
107                 },
108                 z: z6noz,
109         }
110 }
111
112 // ParseAddr parses s as an IP address, returning the result. The string
113 // s can be in dotted decimal ("192.0.2.1"), IPv6 ("2001:db8::68"),
114 // or IPv6 with a scoped addressing zone ("fe80::1cc0:3e8c:119f:c2e1%ens18").
115 func ParseAddr(s string) (Addr, error) {
116         for i := 0; i < len(s); i++ {
117                 switch s[i] {
118                 case '.':
119                         return parseIPv4(s)
120                 case ':':
121                         return parseIPv6(s)
122                 case '%':
123                         // Assume that this was trying to be an IPv6 address with
124                         // a zone specifier, but the address is missing.
125                         return Addr{}, parseAddrError{in: s, msg: "missing IPv6 address"}
126                 }
127         }
128         return Addr{}, parseAddrError{in: s, msg: "unable to parse IP"}
129 }
130
131 // MustParseAddr calls ParseAddr(s) and panics on error.
132 // It is intended for use in tests with hard-coded strings.
133 func MustParseAddr(s string) Addr {
134         ip, err := ParseAddr(s)
135         if err != nil {
136                 panic(err)
137         }
138         return ip
139 }
140
141 type parseAddrError struct {
142         in  string // the string given to ParseAddr
143         msg string // an explanation of the parse failure
144         at  string // optionally, the unparsed portion of in at which the error occurred.
145 }
146
147 func (err parseAddrError) Error() string {
148         q := strconv.Quote
149         if err.at != "" {
150                 return "ParseAddr(" + q(err.in) + "): " + err.msg + " (at " + q(err.at) + ")"
151         }
152         return "ParseAddr(" + q(err.in) + "): " + err.msg
153 }
154
155 // parseIPv4 parses s as an IPv4 address (in form "192.168.0.1").
156 func parseIPv4(s string) (ip Addr, err error) {
157         var fields [4]uint8
158         var val, pos int
159         var digLen int // number of digits in current octet
160         for i := 0; i < len(s); i++ {
161                 if s[i] >= '0' && s[i] <= '9' {
162                         if digLen == 1 && val == 0 {
163                                 return Addr{}, parseAddrError{in: s, msg: "IPv4 field has octet with leading zero"}
164                         }
165                         val = val*10 + int(s[i]) - '0'
166                         digLen++
167                         if val > 255 {
168                                 return Addr{}, parseAddrError{in: s, msg: "IPv4 field has value >255"}
169                         }
170                 } else if s[i] == '.' {
171                         // .1.2.3
172                         // 1.2.3.
173                         // 1..2.3
174                         if i == 0 || i == len(s)-1 || s[i-1] == '.' {
175                                 return Addr{}, parseAddrError{in: s, msg: "IPv4 field must have at least one digit", at: s[i:]}
176                         }
177                         // 1.2.3.4.5
178                         if pos == 3 {
179                                 return Addr{}, parseAddrError{in: s, msg: "IPv4 address too long"}
180                         }
181                         fields[pos] = uint8(val)
182                         pos++
183                         val = 0
184                         digLen = 0
185                 } else {
186                         return Addr{}, parseAddrError{in: s, msg: "unexpected character", at: s[i:]}
187                 }
188         }
189         if pos < 3 {
190                 return Addr{}, parseAddrError{in: s, msg: "IPv4 address too short"}
191         }
192         fields[3] = uint8(val)
193         return AddrFrom4(fields), nil
194 }
195
196 // parseIPv6 parses s as an IPv6 address (in form "2001:db8::68").
197 func parseIPv6(in string) (Addr, error) {
198         s := in
199
200         // Split off the zone right from the start. Yes it's a second scan
201         // of the string, but trying to handle it inline makes a bunch of
202         // other inner loop conditionals more expensive, and it ends up
203         // being slower.
204         zone := ""
205         i := bytealg.IndexByteString(s, '%')
206         if i != -1 {
207                 s, zone = s[:i], s[i+1:]
208                 if zone == "" {
209                         // Not allowed to have an empty zone if explicitly specified.
210                         return Addr{}, parseAddrError{in: in, msg: "zone must be a non-empty string"}
211                 }
212         }
213
214         var ip [16]byte
215         ellipsis := -1 // position of ellipsis in ip
216
217         // Might have leading ellipsis
218         if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
219                 ellipsis = 0
220                 s = s[2:]
221                 // Might be only ellipsis
222                 if len(s) == 0 {
223                         return IPv6Unspecified().WithZone(zone), nil
224                 }
225         }
226
227         // Loop, parsing hex numbers followed by colon.
228         i = 0
229         for i < 16 {
230                 // Hex number. Similar to parseIPv4, inlining the hex number
231                 // parsing yields a significant performance increase.
232                 off := 0
233                 acc := uint32(0)
234                 for ; off < len(s); off++ {
235                         c := s[off]
236                         if c >= '0' && c <= '9' {
237                                 acc = (acc << 4) + uint32(c-'0')
238                         } else if c >= 'a' && c <= 'f' {
239                                 acc = (acc << 4) + uint32(c-'a'+10)
240                         } else if c >= 'A' && c <= 'F' {
241                                 acc = (acc << 4) + uint32(c-'A'+10)
242                         } else {
243                                 break
244                         }
245                         if acc > math.MaxUint16 {
246                                 // Overflow, fail.
247                                 return Addr{}, parseAddrError{in: in, msg: "IPv6 field has value >=2^16", at: s}
248                         }
249                 }
250                 if off == 0 {
251                         // No digits found, fail.
252                         return Addr{}, parseAddrError{in: in, msg: "each colon-separated field must have at least one digit", at: s}
253                 }
254
255                 // If followed by dot, might be in trailing IPv4.
256                 if off < len(s) && s[off] == '.' {
257                         if ellipsis < 0 && i != 12 {
258                                 // Not the right place.
259                                 return Addr{}, parseAddrError{in: in, msg: "embedded IPv4 address must replace the final 2 fields of the address", at: s}
260                         }
261                         if i+4 > 16 {
262                                 // Not enough room.
263                                 return Addr{}, parseAddrError{in: in, msg: "too many hex fields to fit an embedded IPv4 at the end of the address", at: s}
264                         }
265                         // TODO: could make this a bit faster by having a helper
266                         // that parses to a [4]byte, and have both parseIPv4 and
267                         // parseIPv6 use it.
268                         ip4, err := parseIPv4(s)
269                         if err != nil {
270                                 return Addr{}, parseAddrError{in: in, msg: err.Error(), at: s}
271                         }
272                         ip[i] = ip4.v4(0)
273                         ip[i+1] = ip4.v4(1)
274                         ip[i+2] = ip4.v4(2)
275                         ip[i+3] = ip4.v4(3)
276                         s = ""
277                         i += 4
278                         break
279                 }
280
281                 // Save this 16-bit chunk.
282                 ip[i] = byte(acc >> 8)
283                 ip[i+1] = byte(acc)
284                 i += 2
285
286                 // Stop at end of string.
287                 s = s[off:]
288                 if len(s) == 0 {
289                         break
290                 }
291
292                 // Otherwise must be followed by colon and more.
293                 if s[0] != ':' {
294                         return Addr{}, parseAddrError{in: in, msg: "unexpected character, want colon", at: s}
295                 } else if len(s) == 1 {
296                         return Addr{}, parseAddrError{in: in, msg: "colon must be followed by more characters", at: s}
297                 }
298                 s = s[1:]
299
300                 // Look for ellipsis.
301                 if s[0] == ':' {
302                         if ellipsis >= 0 { // already have one
303                                 return Addr{}, parseAddrError{in: in, msg: "multiple :: in address", at: s}
304                         }
305                         ellipsis = i
306                         s = s[1:]
307                         if len(s) == 0 { // can be at end
308                                 break
309                         }
310                 }
311         }
312
313         // Must have used entire string.
314         if len(s) != 0 {
315                 return Addr{}, parseAddrError{in: in, msg: "trailing garbage after address", at: s}
316         }
317
318         // If didn't parse enough, expand ellipsis.
319         if i < 16 {
320                 if ellipsis < 0 {
321                         return Addr{}, parseAddrError{in: in, msg: "address string too short"}
322                 }
323                 n := 16 - i
324                 for j := i - 1; j >= ellipsis; j-- {
325                         ip[j+n] = ip[j]
326                 }
327                 for j := ellipsis + n - 1; j >= ellipsis; j-- {
328                         ip[j] = 0
329                 }
330         } else if ellipsis >= 0 {
331                 // Ellipsis must represent at least one 0 group.
332                 return Addr{}, parseAddrError{in: in, msg: "the :: must expand to at least one field of zeros"}
333         }
334         return AddrFrom16(ip).WithZone(zone), nil
335 }
336
337 // AddrFromSlice parses the 4- or 16-byte byte slice as an IPv4 or IPv6 address.
338 // Note that a net.IP can be passed directly as the []byte argument.
339 // If slice's length is not 4 or 16, AddrFromSlice returns Addr{}, false.
340 func AddrFromSlice(slice []byte) (ip Addr, ok bool) {
341         switch len(slice) {
342         case 4:
343                 return AddrFrom4([4]byte(slice)), true
344         case 16:
345                 return AddrFrom16([16]byte(slice)), true
346         }
347         return Addr{}, false
348 }
349
350 // v4 returns the i'th byte of ip. If ip is not an IPv4, v4 returns
351 // unspecified garbage.
352 func (ip Addr) v4(i uint8) uint8 {
353         return uint8(ip.addr.lo >> ((3 - i) * 8))
354 }
355
356 // v6 returns the i'th byte of ip. If ip is an IPv4 address, this
357 // accesses the IPv4-mapped IPv6 address form of the IP.
358 func (ip Addr) v6(i uint8) uint8 {
359         return uint8(*(ip.addr.halves()[(i/8)%2]) >> ((7 - i%8) * 8))
360 }
361
362 // v6u16 returns the i'th 16-bit word of ip. If ip is an IPv4 address,
363 // this accesses the IPv4-mapped IPv6 address form of the IP.
364 func (ip Addr) v6u16(i uint8) uint16 {
365         return uint16(*(ip.addr.halves()[(i/4)%2]) >> ((3 - i%4) * 16))
366 }
367
368 // isZero reports whether ip is the zero value of the IP type.
369 // The zero value is not a valid IP address of any type.
370 //
371 // Note that "0.0.0.0" and "::" are not the zero value. Use IsUnspecified to
372 // check for these values instead.
373 func (ip Addr) isZero() bool {
374         // Faster than comparing ip == Addr{}, but effectively equivalent,
375         // as there's no way to make an IP with a nil z from this package.
376         return ip.z == z0
377 }
378
379 // IsValid reports whether the Addr is an initialized address (not the zero Addr).
380 //
381 // Note that "0.0.0.0" and "::" are both valid values.
382 func (ip Addr) IsValid() bool { return ip.z != z0 }
383
384 // BitLen returns the number of bits in the IP address:
385 // 128 for IPv6, 32 for IPv4, and 0 for the zero Addr.
386 //
387 // Note that IPv4-mapped IPv6 addresses are considered IPv6 addresses
388 // and therefore have bit length 128.
389 func (ip Addr) BitLen() int {
390         switch ip.z {
391         case z0:
392                 return 0
393         case z4:
394                 return 32
395         }
396         return 128
397 }
398
399 // Zone returns ip's IPv6 scoped addressing zone, if any.
400 func (ip Addr) Zone() string {
401         if ip.z == nil {
402                 return ""
403         }
404         zone, _ := ip.z.Get().(string)
405         return zone
406 }
407
408 // Compare returns an integer comparing two IPs.
409 // The result will be 0 if ip == ip2, -1 if ip < ip2, and +1 if ip > ip2.
410 // The definition of "less than" is the same as the Less method.
411 func (ip Addr) Compare(ip2 Addr) int {
412         f1, f2 := ip.BitLen(), ip2.BitLen()
413         if f1 < f2 {
414                 return -1
415         }
416         if f1 > f2 {
417                 return 1
418         }
419         hi1, hi2 := ip.addr.hi, ip2.addr.hi
420         if hi1 < hi2 {
421                 return -1
422         }
423         if hi1 > hi2 {
424                 return 1
425         }
426         lo1, lo2 := ip.addr.lo, ip2.addr.lo
427         if lo1 < lo2 {
428                 return -1
429         }
430         if lo1 > lo2 {
431                 return 1
432         }
433         if ip.Is6() {
434                 za, zb := ip.Zone(), ip2.Zone()
435                 if za < zb {
436                         return -1
437                 }
438                 if za > zb {
439                         return 1
440                 }
441         }
442         return 0
443 }
444
445 // Less reports whether ip sorts before ip2.
446 // IP addresses sort first by length, then their address.
447 // IPv6 addresses with zones sort just after the same address without a zone.
448 func (ip Addr) Less(ip2 Addr) bool { return ip.Compare(ip2) == -1 }
449
450 // Is4 reports whether ip is an IPv4 address.
451 //
452 // It returns false for IPv4-mapped IPv6 addresses. See Addr.Unmap.
453 func (ip Addr) Is4() bool {
454         return ip.z == z4
455 }
456
457 // Is4In6 reports whether ip is an IPv4-mapped IPv6 address.
458 func (ip Addr) Is4In6() bool {
459         return ip.Is6() && ip.addr.hi == 0 && ip.addr.lo>>32 == 0xffff
460 }
461
462 // Is6 reports whether ip is an IPv6 address, including IPv4-mapped
463 // IPv6 addresses.
464 func (ip Addr) Is6() bool {
465         return ip.z != z0 && ip.z != z4
466 }
467
468 // Unmap returns ip with any IPv4-mapped IPv6 address prefix removed.
469 //
470 // That is, if ip is an IPv6 address wrapping an IPv4 address, it
471 // returns the wrapped IPv4 address. Otherwise it returns ip unmodified.
472 func (ip Addr) Unmap() Addr {
473         if ip.Is4In6() {
474                 ip.z = z4
475         }
476         return ip
477 }
478
479 // WithZone returns an IP that's the same as ip but with the provided
480 // zone. If zone is empty, the zone is removed. If ip is an IPv4
481 // address, WithZone is a no-op and returns ip unchanged.
482 func (ip Addr) WithZone(zone string) Addr {
483         if !ip.Is6() {
484                 return ip
485         }
486         if zone == "" {
487                 ip.z = z6noz
488                 return ip
489         }
490         ip.z = intern.GetByString(zone)
491         return ip
492 }
493
494 // withoutZone unconditionally strips the zone from ip.
495 // It's similar to WithZone, but small enough to be inlinable.
496 func (ip Addr) withoutZone() Addr {
497         if !ip.Is6() {
498                 return ip
499         }
500         ip.z = z6noz
501         return ip
502 }
503
504 // hasZone reports whether ip has an IPv6 zone.
505 func (ip Addr) hasZone() bool {
506         return ip.z != z0 && ip.z != z4 && ip.z != z6noz
507 }
508
509 // IsLinkLocalUnicast reports whether ip is a link-local unicast address.
510 func (ip Addr) IsLinkLocalUnicast() bool {
511         // Dynamic Configuration of IPv4 Link-Local Addresses
512         // https://datatracker.ietf.org/doc/html/rfc3927#section-2.1
513         if ip.Is4() {
514                 return ip.v4(0) == 169 && ip.v4(1) == 254
515         }
516         // IP Version 6 Addressing Architecture (2.4 Address Type Identification)
517         // https://datatracker.ietf.org/doc/html/rfc4291#section-2.4
518         if ip.Is6() {
519                 return ip.v6u16(0)&0xffc0 == 0xfe80
520         }
521         return false // zero value
522 }
523
524 // IsLoopback reports whether ip is a loopback address.
525 func (ip Addr) IsLoopback() bool {
526         // Requirements for Internet Hosts -- Communication Layers (3.2.1.3 Addressing)
527         // https://datatracker.ietf.org/doc/html/rfc1122#section-3.2.1.3
528         if ip.Is4() {
529                 return ip.v4(0) == 127
530         }
531         // IP Version 6 Addressing Architecture (2.4 Address Type Identification)
532         // https://datatracker.ietf.org/doc/html/rfc4291#section-2.4
533         if ip.Is6() {
534                 return ip.addr.hi == 0 && ip.addr.lo == 1
535         }
536         return false // zero value
537 }
538
539 // IsMulticast reports whether ip is a multicast address.
540 func (ip Addr) IsMulticast() bool {
541         // Host Extensions for IP Multicasting (4. HOST GROUP ADDRESSES)
542         // https://datatracker.ietf.org/doc/html/rfc1112#section-4
543         if ip.Is4() {
544                 return ip.v4(0)&0xf0 == 0xe0
545         }
546         // IP Version 6 Addressing Architecture (2.4 Address Type Identification)
547         // https://datatracker.ietf.org/doc/html/rfc4291#section-2.4
548         if ip.Is6() {
549                 return ip.addr.hi>>(64-8) == 0xff // ip.v6(0) == 0xff
550         }
551         return false // zero value
552 }
553
554 // IsInterfaceLocalMulticast reports whether ip is an IPv6 interface-local
555 // multicast address.
556 func (ip Addr) IsInterfaceLocalMulticast() bool {
557         // IPv6 Addressing Architecture (2.7.1. Pre-Defined Multicast Addresses)
558         // https://datatracker.ietf.org/doc/html/rfc4291#section-2.7.1
559         if ip.Is6() {
560                 return ip.v6u16(0)&0xff0f == 0xff01
561         }
562         return false // zero value
563 }
564
565 // IsLinkLocalMulticast reports whether ip is a link-local multicast address.
566 func (ip Addr) IsLinkLocalMulticast() bool {
567         // IPv4 Multicast Guidelines (4. Local Network Control Block (224.0.0/24))
568         // https://datatracker.ietf.org/doc/html/rfc5771#section-4
569         if ip.Is4() {
570                 return ip.v4(0) == 224 && ip.v4(1) == 0 && ip.v4(2) == 0
571         }
572         // IPv6 Addressing Architecture (2.7.1. Pre-Defined Multicast Addresses)
573         // https://datatracker.ietf.org/doc/html/rfc4291#section-2.7.1
574         if ip.Is6() {
575                 return ip.v6u16(0)&0xff0f == 0xff02
576         }
577         return false // zero value
578 }
579
580 // IsGlobalUnicast reports whether ip is a global unicast address.
581 //
582 // It returns true for IPv6 addresses which fall outside of the current
583 // IANA-allocated 2000::/3 global unicast space, with the exception of the
584 // link-local address space. It also returns true even if ip is in the IPv4
585 // private address space or IPv6 unique local address space.
586 // It returns false for the zero Addr.
587 //
588 // For reference, see RFC 1122, RFC 4291, and RFC 4632.
589 func (ip Addr) IsGlobalUnicast() bool {
590         if ip.z == z0 {
591                 // Invalid or zero-value.
592                 return false
593         }
594
595         // Match package net's IsGlobalUnicast logic. Notably private IPv4 addresses
596         // and ULA IPv6 addresses are still considered "global unicast".
597         if ip.Is4() && (ip == IPv4Unspecified() || ip == AddrFrom4([4]byte{255, 255, 255, 255})) {
598                 return false
599         }
600
601         return ip != IPv6Unspecified() &&
602                 !ip.IsLoopback() &&
603                 !ip.IsMulticast() &&
604                 !ip.IsLinkLocalUnicast()
605 }
606
607 // IsPrivate reports whether ip is a private address, according to RFC 1918
608 // (IPv4 addresses) and RFC 4193 (IPv6 addresses). That is, it reports whether
609 // ip is in 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, or fc00::/7. This is the
610 // same as net.IP.IsPrivate.
611 func (ip Addr) IsPrivate() bool {
612         // Match the stdlib's IsPrivate logic.
613         if ip.Is4() {
614                 // RFC 1918 allocates 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16 as
615                 // private IPv4 address subnets.
616                 return ip.v4(0) == 10 ||
617                         (ip.v4(0) == 172 && ip.v4(1)&0xf0 == 16) ||
618                         (ip.v4(0) == 192 && ip.v4(1) == 168)
619         }
620
621         if ip.Is6() {
622                 // RFC 4193 allocates fc00::/7 as the unique local unicast IPv6 address
623                 // subnet.
624                 return ip.v6(0)&0xfe == 0xfc
625         }
626
627         return false // zero value
628 }
629
630 // IsUnspecified reports whether ip is an unspecified address, either the IPv4
631 // address "0.0.0.0" or the IPv6 address "::".
632 //
633 // Note that the zero Addr is not an unspecified address.
634 func (ip Addr) IsUnspecified() bool {
635         return ip == IPv4Unspecified() || ip == IPv6Unspecified()
636 }
637
638 // Prefix keeps only the top b bits of IP, producing a Prefix
639 // of the specified length.
640 // If ip is a zero Addr, Prefix always returns a zero Prefix and a nil error.
641 // Otherwise, if bits is less than zero or greater than ip.BitLen(),
642 // Prefix returns an error.
643 func (ip Addr) Prefix(b int) (Prefix, error) {
644         if b < 0 {
645                 return Prefix{}, errors.New("negative Prefix bits")
646         }
647         effectiveBits := b
648         switch ip.z {
649         case z0:
650                 return Prefix{}, nil
651         case z4:
652                 if b > 32 {
653                         return Prefix{}, errors.New("prefix length " + itoa.Itoa(b) + " too large for IPv4")
654                 }
655                 effectiveBits += 96
656         default:
657                 if b > 128 {
658                         return Prefix{}, errors.New("prefix length " + itoa.Itoa(b) + " too large for IPv6")
659                 }
660         }
661         ip.addr = ip.addr.and(mask6(effectiveBits))
662         return PrefixFrom(ip, b), nil
663 }
664
665 // As16 returns the IP address in its 16-byte representation.
666 // IPv4 addresses are returned as IPv4-mapped IPv6 addresses.
667 // IPv6 addresses with zones are returned without their zone (use the
668 // Zone method to get it).
669 // The ip zero value returns all zeroes.
670 func (ip Addr) As16() (a16 [16]byte) {
671         bePutUint64(a16[:8], ip.addr.hi)
672         bePutUint64(a16[8:], ip.addr.lo)
673         return a16
674 }
675
676 // As4 returns an IPv4 or IPv4-in-IPv6 address in its 4-byte representation.
677 // If ip is the zero Addr or an IPv6 address, As4 panics.
678 // Note that 0.0.0.0 is not the zero Addr.
679 func (ip Addr) As4() (a4 [4]byte) {
680         if ip.z == z4 || ip.Is4In6() {
681                 bePutUint32(a4[:], uint32(ip.addr.lo))
682                 return a4
683         }
684         if ip.z == z0 {
685                 panic("As4 called on IP zero value")
686         }
687         panic("As4 called on IPv6 address")
688 }
689
690 // AsSlice returns an IPv4 or IPv6 address in its respective 4-byte or 16-byte representation.
691 func (ip Addr) AsSlice() []byte {
692         switch ip.z {
693         case z0:
694                 return nil
695         case z4:
696                 var ret [4]byte
697                 bePutUint32(ret[:], uint32(ip.addr.lo))
698                 return ret[:]
699         default:
700                 var ret [16]byte
701                 bePutUint64(ret[:8], ip.addr.hi)
702                 bePutUint64(ret[8:], ip.addr.lo)
703                 return ret[:]
704         }
705 }
706
707 // Next returns the address following ip.
708 // If there is none, it returns the zero Addr.
709 func (ip Addr) Next() Addr {
710         ip.addr = ip.addr.addOne()
711         if ip.Is4() {
712                 if uint32(ip.addr.lo) == 0 {
713                         // Overflowed.
714                         return Addr{}
715                 }
716         } else {
717                 if ip.addr.isZero() {
718                         // Overflowed
719                         return Addr{}
720                 }
721         }
722         return ip
723 }
724
725 // Prev returns the IP before ip.
726 // If there is none, it returns the IP zero value.
727 func (ip Addr) Prev() Addr {
728         if ip.Is4() {
729                 if uint32(ip.addr.lo) == 0 {
730                         return Addr{}
731                 }
732         } else if ip.addr.isZero() {
733                 return Addr{}
734         }
735         ip.addr = ip.addr.subOne()
736         return ip
737 }
738
739 // String returns the string form of the IP address ip.
740 // It returns one of 5 forms:
741 //
742 //   - "invalid IP", if ip is the zero Addr
743 //   - IPv4 dotted decimal ("192.0.2.1")
744 //   - IPv6 ("2001:db8::1")
745 //   - "::ffff:1.2.3.4" (if Is4In6)
746 //   - IPv6 with zone ("fe80:db8::1%eth0")
747 //
748 // Note that unlike package net's IP.String method,
749 // IPv4-mapped IPv6 addresses format with a "::ffff:"
750 // prefix before the dotted quad.
751 func (ip Addr) String() string {
752         switch ip.z {
753         case z0:
754                 return "invalid IP"
755         case z4:
756                 return ip.string4()
757         default:
758                 if ip.Is4In6() {
759                         if z := ip.Zone(); z != "" {
760                                 return "::ffff:" + ip.Unmap().string4() + "%" + z
761                         } else {
762                                 return "::ffff:" + ip.Unmap().string4()
763                         }
764                 }
765                 return ip.string6()
766         }
767 }
768
769 // AppendTo appends a text encoding of ip,
770 // as generated by MarshalText,
771 // to b and returns the extended buffer.
772 func (ip Addr) AppendTo(b []byte) []byte {
773         switch ip.z {
774         case z0:
775                 return b
776         case z4:
777                 return ip.appendTo4(b)
778         default:
779                 if ip.Is4In6() {
780                         b = append(b, "::ffff:"...)
781                         b = ip.Unmap().appendTo4(b)
782                         if z := ip.Zone(); z != "" {
783                                 b = append(b, '%')
784                                 b = append(b, z...)
785                         }
786                         return b
787                 }
788                 return ip.appendTo6(b)
789         }
790 }
791
792 // digits is a string of the hex digits from 0 to f. It's used in
793 // appendDecimal and appendHex to format IP addresses.
794 const digits = "0123456789abcdef"
795
796 // appendDecimal appends the decimal string representation of x to b.
797 func appendDecimal(b []byte, x uint8) []byte {
798         // Using this function rather than strconv.AppendUint makes IPv4
799         // string building 2x faster.
800
801         if x >= 100 {
802                 b = append(b, digits[x/100])
803         }
804         if x >= 10 {
805                 b = append(b, digits[x/10%10])
806         }
807         return append(b, digits[x%10])
808 }
809
810 // appendHex appends the hex string representation of x to b.
811 func appendHex(b []byte, x uint16) []byte {
812         // Using this function rather than strconv.AppendUint makes IPv6
813         // string building 2x faster.
814
815         if x >= 0x1000 {
816                 b = append(b, digits[x>>12])
817         }
818         if x >= 0x100 {
819                 b = append(b, digits[x>>8&0xf])
820         }
821         if x >= 0x10 {
822                 b = append(b, digits[x>>4&0xf])
823         }
824         return append(b, digits[x&0xf])
825 }
826
827 // appendHexPad appends the fully padded hex string representation of x to b.
828 func appendHexPad(b []byte, x uint16) []byte {
829         return append(b, digits[x>>12], digits[x>>8&0xf], digits[x>>4&0xf], digits[x&0xf])
830 }
831
832 func (ip Addr) string4() string {
833         const max = len("255.255.255.255")
834         ret := make([]byte, 0, max)
835         ret = ip.appendTo4(ret)
836         return string(ret)
837 }
838
839 func (ip Addr) appendTo4(ret []byte) []byte {
840         ret = appendDecimal(ret, ip.v4(0))
841         ret = append(ret, '.')
842         ret = appendDecimal(ret, ip.v4(1))
843         ret = append(ret, '.')
844         ret = appendDecimal(ret, ip.v4(2))
845         ret = append(ret, '.')
846         ret = appendDecimal(ret, ip.v4(3))
847         return ret
848 }
849
850 // string6 formats ip in IPv6 textual representation. It follows the
851 // guidelines in section 4 of RFC 5952
852 // (https://tools.ietf.org/html/rfc5952#section-4): no unnecessary
853 // zeros, use :: to elide the longest run of zeros, and don't use ::
854 // to compact a single zero field.
855 func (ip Addr) string6() string {
856         // Use a zone with a "plausibly long" name, so that most zone-ful
857         // IP addresses won't require additional allocation.
858         //
859         // The compiler does a cool optimization here, where ret ends up
860         // stack-allocated and so the only allocation this function does
861         // is to construct the returned string. As such, it's okay to be a
862         // bit greedy here, size-wise.
863         const max = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0")
864         ret := make([]byte, 0, max)
865         ret = ip.appendTo6(ret)
866         return string(ret)
867 }
868
869 func (ip Addr) appendTo6(ret []byte) []byte {
870         zeroStart, zeroEnd := uint8(255), uint8(255)
871         for i := uint8(0); i < 8; i++ {
872                 j := i
873                 for j < 8 && ip.v6u16(j) == 0 {
874                         j++
875                 }
876                 if l := j - i; l >= 2 && l > zeroEnd-zeroStart {
877                         zeroStart, zeroEnd = i, j
878                 }
879         }
880
881         for i := uint8(0); i < 8; i++ {
882                 if i == zeroStart {
883                         ret = append(ret, ':', ':')
884                         i = zeroEnd
885                         if i >= 8 {
886                                 break
887                         }
888                 } else if i > 0 {
889                         ret = append(ret, ':')
890                 }
891
892                 ret = appendHex(ret, ip.v6u16(i))
893         }
894
895         if ip.z != z6noz {
896                 ret = append(ret, '%')
897                 ret = append(ret, ip.Zone()...)
898         }
899         return ret
900 }
901
902 // StringExpanded is like String but IPv6 addresses are expanded with leading
903 // zeroes and no "::" compression. For example, "2001:db8::1" becomes
904 // "2001:0db8:0000:0000:0000:0000:0000:0001".
905 func (ip Addr) StringExpanded() string {
906         switch ip.z {
907         case z0, z4:
908                 return ip.String()
909         }
910
911         const size = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
912         ret := make([]byte, 0, size)
913         for i := uint8(0); i < 8; i++ {
914                 if i > 0 {
915                         ret = append(ret, ':')
916                 }
917
918                 ret = appendHexPad(ret, ip.v6u16(i))
919         }
920
921         if ip.z != z6noz {
922                 // The addition of a zone will cause a second allocation, but when there
923                 // is no zone the ret slice will be stack allocated.
924                 ret = append(ret, '%')
925                 ret = append(ret, ip.Zone()...)
926         }
927         return string(ret)
928 }
929
930 // MarshalText implements the encoding.TextMarshaler interface,
931 // The encoding is the same as returned by String, with one exception:
932 // If ip is the zero Addr, the encoding is the empty string.
933 func (ip Addr) MarshalText() ([]byte, error) {
934         switch ip.z {
935         case z0:
936                 return []byte(""), nil
937         case z4:
938                 max := len("255.255.255.255")
939                 b := make([]byte, 0, max)
940                 return ip.appendTo4(b), nil
941         default:
942                 max := len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0")
943                 b := make([]byte, 0, max)
944                 if ip.Is4In6() {
945                         b = append(b, "::ffff:"...)
946                         b = ip.Unmap().appendTo4(b)
947                         if z := ip.Zone(); z != "" {
948                                 b = append(b, '%')
949                                 b = append(b, z...)
950                         }
951                         return b, nil
952                 }
953                 return ip.appendTo6(b), nil
954         }
955
956 }
957
958 // UnmarshalText implements the encoding.TextUnmarshaler interface.
959 // The IP address is expected in a form accepted by ParseAddr.
960 //
961 // If text is empty, UnmarshalText sets *ip to the zero Addr and
962 // returns no error.
963 func (ip *Addr) UnmarshalText(text []byte) error {
964         if len(text) == 0 {
965                 *ip = Addr{}
966                 return nil
967         }
968         var err error
969         *ip, err = ParseAddr(string(text))
970         return err
971 }
972
973 func (ip Addr) marshalBinaryWithTrailingBytes(trailingBytes int) []byte {
974         var b []byte
975         switch ip.z {
976         case z0:
977                 b = make([]byte, trailingBytes)
978         case z4:
979                 b = make([]byte, 4+trailingBytes)
980                 bePutUint32(b, uint32(ip.addr.lo))
981         default:
982                 z := ip.Zone()
983                 b = make([]byte, 16+len(z)+trailingBytes)
984                 bePutUint64(b[:8], ip.addr.hi)
985                 bePutUint64(b[8:], ip.addr.lo)
986                 copy(b[16:], z)
987         }
988         return b
989 }
990
991 // MarshalBinary implements the encoding.BinaryMarshaler interface.
992 // It returns a zero-length slice for the zero Addr,
993 // the 4-byte form for an IPv4 address,
994 // and the 16-byte form with zone appended for an IPv6 address.
995 func (ip Addr) MarshalBinary() ([]byte, error) {
996         return ip.marshalBinaryWithTrailingBytes(0), nil
997 }
998
999 // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
1000 // It expects data in the form generated by MarshalBinary.
1001 func (ip *Addr) UnmarshalBinary(b []byte) error {
1002         n := len(b)
1003         switch {
1004         case n == 0:
1005                 *ip = Addr{}
1006                 return nil
1007         case n == 4:
1008                 *ip = AddrFrom4([4]byte(b))
1009                 return nil
1010         case n == 16:
1011                 *ip = AddrFrom16([16]byte(b))
1012                 return nil
1013         case n > 16:
1014                 *ip = AddrFrom16([16]byte(b[:16])).WithZone(string(b[16:]))
1015                 return nil
1016         }
1017         return errors.New("unexpected slice size")
1018 }
1019
1020 // AddrPort is an IP and a port number.
1021 type AddrPort struct {
1022         ip   Addr
1023         port uint16
1024 }
1025
1026 // AddrPortFrom returns an AddrPort with the provided IP and port.
1027 // It does not allocate.
1028 func AddrPortFrom(ip Addr, port uint16) AddrPort { return AddrPort{ip: ip, port: port} }
1029
1030 // Addr returns p's IP address.
1031 func (p AddrPort) Addr() Addr { return p.ip }
1032
1033 // Port returns p's port.
1034 func (p AddrPort) Port() uint16 { return p.port }
1035
1036 // splitAddrPort splits s into an IP address string and a port
1037 // string. It splits strings shaped like "foo:bar" or "[foo]:bar",
1038 // without further validating the substrings. v6 indicates whether the
1039 // ip string should parse as an IPv6 address or an IPv4 address, in
1040 // order for s to be a valid ip:port string.
1041 func splitAddrPort(s string) (ip, port string, v6 bool, err error) {
1042         i := bytealg.LastIndexByteString(s, ':')
1043         if i == -1 {
1044                 return "", "", false, errors.New("not an ip:port")
1045         }
1046
1047         ip, port = s[:i], s[i+1:]
1048         if len(ip) == 0 {
1049                 return "", "", false, errors.New("no IP")
1050         }
1051         if len(port) == 0 {
1052                 return "", "", false, errors.New("no port")
1053         }
1054         if ip[0] == '[' {
1055                 if len(ip) < 2 || ip[len(ip)-1] != ']' {
1056                         return "", "", false, errors.New("missing ]")
1057                 }
1058                 ip = ip[1 : len(ip)-1]
1059                 v6 = true
1060         }
1061
1062         return ip, port, v6, nil
1063 }
1064
1065 // ParseAddrPort parses s as an AddrPort.
1066 //
1067 // It doesn't do any name resolution: both the address and the port
1068 // must be numeric.
1069 func ParseAddrPort(s string) (AddrPort, error) {
1070         var ipp AddrPort
1071         ip, port, v6, err := splitAddrPort(s)
1072         if err != nil {
1073                 return ipp, err
1074         }
1075         port16, err := strconv.ParseUint(port, 10, 16)
1076         if err != nil {
1077                 return ipp, errors.New("invalid port " + strconv.Quote(port) + " parsing " + strconv.Quote(s))
1078         }
1079         ipp.port = uint16(port16)
1080         ipp.ip, err = ParseAddr(ip)
1081         if err != nil {
1082                 return AddrPort{}, err
1083         }
1084         if v6 && ipp.ip.Is4() {
1085                 return AddrPort{}, errors.New("invalid ip:port " + strconv.Quote(s) + ", square brackets can only be used with IPv6 addresses")
1086         } else if !v6 && ipp.ip.Is6() {
1087                 return AddrPort{}, errors.New("invalid ip:port " + strconv.Quote(s) + ", IPv6 addresses must be surrounded by square brackets")
1088         }
1089         return ipp, nil
1090 }
1091
1092 // MustParseAddrPort calls ParseAddrPort(s) and panics on error.
1093 // It is intended for use in tests with hard-coded strings.
1094 func MustParseAddrPort(s string) AddrPort {
1095         ip, err := ParseAddrPort(s)
1096         if err != nil {
1097                 panic(err)
1098         }
1099         return ip
1100 }
1101
1102 // IsValid reports whether p.Addr() is valid.
1103 // All ports are valid, including zero.
1104 func (p AddrPort) IsValid() bool { return p.ip.IsValid() }
1105
1106 // Compare returns an integer comparing two AddrPorts.
1107 // The result will be 0 if p == p2, -1 if p < p2, and +1 if p > p2.
1108 // AddrPorts sort first by IP address, then port.
1109 func (p AddrPort) Compare(p2 AddrPort) int {
1110         if c := p.Addr().Compare(p2.Addr()); c != 0 {
1111                 return c
1112         }
1113         return cmp.Compare(p.Port(), p2.Port())
1114 }
1115
1116 func (p AddrPort) String() string {
1117         switch p.ip.z {
1118         case z0:
1119                 return "invalid AddrPort"
1120         case z4:
1121                 a := p.ip.As4()
1122                 buf := make([]byte, 0, 21)
1123                 for i := range a {
1124                         buf = strconv.AppendUint(buf, uint64(a[i]), 10)
1125                         buf = append(buf, "...:"[i])
1126                 }
1127                 buf = strconv.AppendUint(buf, uint64(p.port), 10)
1128                 return string(buf)
1129         default:
1130                 // TODO: this could be more efficient allocation-wise:
1131                 return joinHostPort(p.ip.String(), itoa.Itoa(int(p.port)))
1132         }
1133 }
1134
1135 func joinHostPort(host, port string) string {
1136         // We assume that host is a literal IPv6 address if host has
1137         // colons.
1138         if bytealg.IndexByteString(host, ':') >= 0 {
1139                 return "[" + host + "]:" + port
1140         }
1141         return host + ":" + port
1142 }
1143
1144 // AppendTo appends a text encoding of p,
1145 // as generated by MarshalText,
1146 // to b and returns the extended buffer.
1147 func (p AddrPort) AppendTo(b []byte) []byte {
1148         switch p.ip.z {
1149         case z0:
1150                 return b
1151         case z4:
1152                 b = p.ip.appendTo4(b)
1153         default:
1154                 if p.ip.Is4In6() {
1155                         b = append(b, "[::ffff:"...)
1156                         b = p.ip.Unmap().appendTo4(b)
1157                         if z := p.ip.Zone(); z != "" {
1158                                 b = append(b, '%')
1159                                 b = append(b, z...)
1160                         }
1161                 } else {
1162                         b = append(b, '[')
1163                         b = p.ip.appendTo6(b)
1164                 }
1165                 b = append(b, ']')
1166         }
1167         b = append(b, ':')
1168         b = strconv.AppendUint(b, uint64(p.port), 10)
1169         return b
1170 }
1171
1172 // MarshalText implements the encoding.TextMarshaler interface. The
1173 // encoding is the same as returned by String, with one exception: if
1174 // p.Addr() is the zero Addr, the encoding is the empty string.
1175 func (p AddrPort) MarshalText() ([]byte, error) {
1176         var max int
1177         switch p.ip.z {
1178         case z0:
1179         case z4:
1180                 max = len("255.255.255.255:65535")
1181         default:
1182                 max = len("[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0]:65535")
1183         }
1184         b := make([]byte, 0, max)
1185         b = p.AppendTo(b)
1186         return b, nil
1187 }
1188
1189 // UnmarshalText implements the encoding.TextUnmarshaler
1190 // interface. The AddrPort is expected in a form
1191 // generated by MarshalText or accepted by ParseAddrPort.
1192 func (p *AddrPort) UnmarshalText(text []byte) error {
1193         if len(text) == 0 {
1194                 *p = AddrPort{}
1195                 return nil
1196         }
1197         var err error
1198         *p, err = ParseAddrPort(string(text))
1199         return err
1200 }
1201
1202 // MarshalBinary implements the encoding.BinaryMarshaler interface.
1203 // It returns Addr.MarshalBinary with an additional two bytes appended
1204 // containing the port in little-endian.
1205 func (p AddrPort) MarshalBinary() ([]byte, error) {
1206         b := p.Addr().marshalBinaryWithTrailingBytes(2)
1207         lePutUint16(b[len(b)-2:], p.Port())
1208         return b, nil
1209 }
1210
1211 // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
1212 // It expects data in the form generated by MarshalBinary.
1213 func (p *AddrPort) UnmarshalBinary(b []byte) error {
1214         if len(b) < 2 {
1215                 return errors.New("unexpected slice size")
1216         }
1217         var addr Addr
1218         err := addr.UnmarshalBinary(b[:len(b)-2])
1219         if err != nil {
1220                 return err
1221         }
1222         *p = AddrPortFrom(addr, leUint16(b[len(b)-2:]))
1223         return nil
1224 }
1225
1226 // Prefix is an IP address prefix (CIDR) representing an IP network.
1227 //
1228 // The first Bits() of Addr() are specified. The remaining bits match any address.
1229 // The range of Bits() is [0,32] for IPv4 or [0,128] for IPv6.
1230 type Prefix struct {
1231         ip Addr
1232
1233         // bitsPlusOne stores the prefix bit length plus one.
1234         // A Prefix is valid if and only if bitsPlusOne is non-zero.
1235         bitsPlusOne uint8
1236 }
1237
1238 // PrefixFrom returns a Prefix with the provided IP address and bit
1239 // prefix length.
1240 //
1241 // It does not allocate. Unlike Addr.Prefix, PrefixFrom does not mask
1242 // off the host bits of ip.
1243 //
1244 // If bits is less than zero or greater than ip.BitLen, Prefix.Bits
1245 // will return an invalid value -1.
1246 func PrefixFrom(ip Addr, bits int) Prefix {
1247         var bitsPlusOne uint8
1248         if !ip.isZero() && bits >= 0 && bits <= ip.BitLen() {
1249                 bitsPlusOne = uint8(bits) + 1
1250         }
1251         return Prefix{
1252                 ip:          ip.withoutZone(),
1253                 bitsPlusOne: bitsPlusOne,
1254         }
1255 }
1256
1257 // Addr returns p's IP address.
1258 func (p Prefix) Addr() Addr { return p.ip }
1259
1260 // Bits returns p's prefix length.
1261 //
1262 // It reports -1 if invalid.
1263 func (p Prefix) Bits() int { return int(p.bitsPlusOne) - 1 }
1264
1265 // IsValid reports whether p.Bits() has a valid range for p.Addr().
1266 // If p.Addr() is the zero Addr, IsValid returns false.
1267 // Note that if p is the zero Prefix, then p.IsValid() == false.
1268 func (p Prefix) IsValid() bool { return p.bitsPlusOne > 0 }
1269
1270 func (p Prefix) isZero() bool { return p == Prefix{} }
1271
1272 // IsSingleIP reports whether p contains exactly one IP.
1273 func (p Prefix) IsSingleIP() bool { return p.IsValid() && p.Bits() == p.ip.BitLen() }
1274
1275 // Compare returns an integer comparing two prefixes.
1276 // The result will be 0 if p == p2, -1 if p < p2, and +1 if p > p2.
1277 // Prefixes sort first by validity (invalid before valid), then
1278 // address family (IPv4 before IPv6), then prefix length, then
1279 // address.
1280 func (p Prefix) Compare(p2 Prefix) int {
1281         if c := cmp.Compare(p.Addr().BitLen(), p2.Addr().BitLen()); c != 0 {
1282                 return c
1283         }
1284         if c := cmp.Compare(p.Bits(), p2.Bits()); c != 0 {
1285                 return c
1286         }
1287         return p.Addr().Compare(p2.Addr())
1288 }
1289
1290 // ParsePrefix parses s as an IP address prefix.
1291 // The string can be in the form "192.168.1.0/24" or "2001:db8::/32",
1292 // the CIDR notation defined in RFC 4632 and RFC 4291.
1293 // IPv6 zones are not permitted in prefixes, and an error will be returned if a
1294 // zone is present.
1295 //
1296 // Note that masked address bits are not zeroed. Use Masked for that.
1297 func ParsePrefix(s string) (Prefix, error) {
1298         i := bytealg.LastIndexByteString(s, '/')
1299         if i < 0 {
1300                 return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): no '/'")
1301         }
1302         ip, err := ParseAddr(s[:i])
1303         if err != nil {
1304                 return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): " + err.Error())
1305         }
1306         // IPv6 zones are not allowed: https://go.dev/issue/51899
1307         if ip.Is6() && ip.z != z6noz {
1308                 return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): IPv6 zones cannot be present in a prefix")
1309         }
1310
1311         bitsStr := s[i+1:]
1312         bits, err := strconv.Atoi(bitsStr)
1313         if err != nil {
1314                 return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): bad bits after slash: " + strconv.Quote(bitsStr))
1315         }
1316         maxBits := 32
1317         if ip.Is6() {
1318                 maxBits = 128
1319         }
1320         if bits < 0 || bits > maxBits {
1321                 return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): prefix length out of range")
1322         }
1323         return PrefixFrom(ip, bits), nil
1324 }
1325
1326 // MustParsePrefix calls ParsePrefix(s) and panics on error.
1327 // It is intended for use in tests with hard-coded strings.
1328 func MustParsePrefix(s string) Prefix {
1329         ip, err := ParsePrefix(s)
1330         if err != nil {
1331                 panic(err)
1332         }
1333         return ip
1334 }
1335
1336 // Masked returns p in its canonical form, with all but the high
1337 // p.Bits() bits of p.Addr() masked off.
1338 //
1339 // If p is zero or otherwise invalid, Masked returns the zero Prefix.
1340 func (p Prefix) Masked() Prefix {
1341         m, _ := p.ip.Prefix(p.Bits())
1342         return m
1343 }
1344
1345 // Contains reports whether the network p includes ip.
1346 //
1347 // An IPv4 address will not match an IPv6 prefix.
1348 // An IPv4-mapped IPv6 address will not match an IPv4 prefix.
1349 // A zero-value IP will not match any prefix.
1350 // If ip has an IPv6 zone, Contains returns false,
1351 // because Prefixes strip zones.
1352 func (p Prefix) Contains(ip Addr) bool {
1353         if !p.IsValid() || ip.hasZone() {
1354                 return false
1355         }
1356         if f1, f2 := p.ip.BitLen(), ip.BitLen(); f1 == 0 || f2 == 0 || f1 != f2 {
1357                 return false
1358         }
1359         if ip.Is4() {
1360                 // xor the IP addresses together; mismatched bits are now ones.
1361                 // Shift away the number of bits we don't care about.
1362                 // Shifts in Go are more efficient if the compiler can prove
1363                 // that the shift amount is smaller than the width of the shifted type (64 here).
1364                 // We know that p.bits is in the range 0..32 because p is Valid;
1365                 // the compiler doesn't know that, so mask with 63 to help it.
1366                 // Now truncate to 32 bits, because this is IPv4.
1367                 // If all the bits we care about are equal, the result will be zero.
1368                 return uint32((ip.addr.lo^p.ip.addr.lo)>>((32-p.Bits())&63)) == 0
1369         } else {
1370                 // xor the IP addresses together.
1371                 // Mask away the bits we don't care about.
1372                 // If all the bits we care about are equal, the result will be zero.
1373                 return ip.addr.xor(p.ip.addr).and(mask6(p.Bits())).isZero()
1374         }
1375 }
1376
1377 // Overlaps reports whether p and o contain any IP addresses in common.
1378 //
1379 // If p and o are of different address families or either have a zero
1380 // IP, it reports false. Like the Contains method, a prefix with an
1381 // IPv4-mapped IPv6 address is still treated as an IPv6 mask.
1382 func (p Prefix) Overlaps(o Prefix) bool {
1383         if !p.IsValid() || !o.IsValid() {
1384                 return false
1385         }
1386         if p == o {
1387                 return true
1388         }
1389         if p.ip.Is4() != o.ip.Is4() {
1390                 return false
1391         }
1392         var minBits int
1393         if pb, ob := p.Bits(), o.Bits(); pb < ob {
1394                 minBits = pb
1395         } else {
1396                 minBits = ob
1397         }
1398         if minBits == 0 {
1399                 return true
1400         }
1401         // One of these Prefix calls might look redundant, but we don't require
1402         // that p and o values are normalized (via Prefix.Masked) first,
1403         // so the Prefix call on the one that's already minBits serves to zero
1404         // out any remaining bits in IP.
1405         var err error
1406         if p, err = p.ip.Prefix(minBits); err != nil {
1407                 return false
1408         }
1409         if o, err = o.ip.Prefix(minBits); err != nil {
1410                 return false
1411         }
1412         return p.ip == o.ip
1413 }
1414
1415 // AppendTo appends a text encoding of p,
1416 // as generated by MarshalText,
1417 // to b and returns the extended buffer.
1418 func (p Prefix) AppendTo(b []byte) []byte {
1419         if p.isZero() {
1420                 return b
1421         }
1422         if !p.IsValid() {
1423                 return append(b, "invalid Prefix"...)
1424         }
1425
1426         // p.ip is non-nil, because p is valid.
1427         if p.ip.z == z4 {
1428                 b = p.ip.appendTo4(b)
1429         } else {
1430                 if p.ip.Is4In6() {
1431                         b = append(b, "::ffff:"...)
1432                         b = p.ip.Unmap().appendTo4(b)
1433                 } else {
1434                         b = p.ip.appendTo6(b)
1435                 }
1436         }
1437
1438         b = append(b, '/')
1439         b = appendDecimal(b, uint8(p.Bits()))
1440         return b
1441 }
1442
1443 // MarshalText implements the encoding.TextMarshaler interface,
1444 // The encoding is the same as returned by String, with one exception:
1445 // If p is the zero value, the encoding is the empty string.
1446 func (p Prefix) MarshalText() ([]byte, error) {
1447         var max int
1448         switch p.ip.z {
1449         case z0:
1450         case z4:
1451                 max = len("255.255.255.255/32")
1452         default:
1453                 max = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0/128")
1454         }
1455         b := make([]byte, 0, max)
1456         b = p.AppendTo(b)
1457         return b, nil
1458 }
1459
1460 // UnmarshalText implements the encoding.TextUnmarshaler interface.
1461 // The IP address is expected in a form accepted by ParsePrefix
1462 // or generated by MarshalText.
1463 func (p *Prefix) UnmarshalText(text []byte) error {
1464         if len(text) == 0 {
1465                 *p = Prefix{}
1466                 return nil
1467         }
1468         var err error
1469         *p, err = ParsePrefix(string(text))
1470         return err
1471 }
1472
1473 // MarshalBinary implements the encoding.BinaryMarshaler interface.
1474 // It returns Addr.MarshalBinary with an additional byte appended
1475 // containing the prefix bits.
1476 func (p Prefix) MarshalBinary() ([]byte, error) {
1477         b := p.Addr().withoutZone().marshalBinaryWithTrailingBytes(1)
1478         b[len(b)-1] = uint8(p.Bits())
1479         return b, nil
1480 }
1481
1482 // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
1483 // It expects data in the form generated by MarshalBinary.
1484 func (p *Prefix) UnmarshalBinary(b []byte) error {
1485         if len(b) < 1 {
1486                 return errors.New("unexpected slice size")
1487         }
1488         var addr Addr
1489         err := addr.UnmarshalBinary(b[:len(b)-1])
1490         if err != nil {
1491                 return err
1492         }
1493         *p = PrefixFrom(addr, int(b[len(b)-1]))
1494         return nil
1495 }
1496
1497 // String returns the CIDR notation of p: "<ip>/<bits>".
1498 func (p Prefix) String() string {
1499         if !p.IsValid() {
1500                 return "invalid Prefix"
1501         }
1502         return p.ip.String() + "/" + itoa.Itoa(p.Bits())
1503 }