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