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