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.
5 // IP address manipulations
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.
15 import _
"unsafe" // for go:linkname
17 // IP address lengths (bytes).
23 // An IP is a single IP address, a slice of bytes.
24 // Functions in this package accept either 4-byte (IPv4)
25 // or 16-byte (IPv6) slices as input.
27 // Note that in this documentation, referring to an
28 // IP address as an IPv4 address or an IPv6 address
29 // is a semantic property of the address, not just the
30 // length of the byte slice: a 16-byte slice can still
31 // be an IPv4 address.
34 // An IP mask is an IP address.
37 // An IPNet represents an IP network.
39 IP IP
// network number
40 Mask IPMask
// network mask
43 // IPv4 returns the IP address (in 16-byte form) of the
44 // IPv4 address a.b.c.d.
45 func IPv4(a
, b
, c
, d
byte) IP
{
46 p
:= make(IP
, IPv6len
)
55 var v4InV6Prefix
= []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
57 // IPv4Mask returns the IP mask (in 4-byte form) of the
59 func IPv4Mask(a
, b
, c
, d
byte) IPMask
{
60 p
:= make(IPMask
, IPv4len
)
68 // CIDRMask returns an IPMask consisting of `ones' 1 bits
69 // followed by 0s up to a total length of `bits' bits.
70 // For a mask of this form, CIDRMask is the inverse of IPMask.Size.
71 func CIDRMask(ones
, bits
int) IPMask
{
72 if bits
!= 8*IPv4len
&& bits
!= 8*IPv6len
{
75 if ones
< 0 || ones
> bits
{
81 for i
:= 0; i
< l
; i
++ {
87 m
[i
] = ^byte(0xff >> n
)
93 // Well-known IPv4 addresses
95 IPv4bcast
= IPv4(255, 255, 255, 255) // limited broadcast
96 IPv4allsys
= IPv4(224, 0, 0, 1) // all systems
97 IPv4allrouter
= IPv4(224, 0, 0, 2) // all routers
98 IPv4zero
= IPv4(0, 0, 0, 0) // all zeros
101 // Well-known IPv6 addresses
103 IPv6zero
= IP
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
104 IPv6unspecified
= IP
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
105 IPv6loopback
= IP
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
106 IPv6interfacelocalallnodes
= IP
{0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
107 IPv6linklocalallnodes
= IP
{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
108 IPv6linklocalallrouters
= IP
{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02}
111 // IsUnspecified reports whether ip is an unspecified address, either
112 // the IPv4 address "0.0.0.0" or the IPv6 address "::".
113 func (ip IP
) IsUnspecified() bool {
114 return ip
.Equal(IPv4zero
) || ip
.Equal(IPv6unspecified
)
117 // IsLoopback reports whether ip is a loopback address.
118 func (ip IP
) IsLoopback() bool {
119 if ip4
:= ip
.To4(); ip4
!= nil {
122 return ip
.Equal(IPv6loopback
)
125 // IsMulticast reports whether ip is a multicast address.
126 func (ip IP
) IsMulticast() bool {
127 if ip4
:= ip
.To4(); ip4
!= nil {
128 return ip4
[0]&0xf0 == 0xe0
130 return len(ip
) == IPv6len
&& ip
[0] == 0xff
133 // IsInterfaceLocalMulticast reports whether ip is
134 // an interface-local multicast address.
135 func (ip IP
) IsInterfaceLocalMulticast() bool {
136 return len(ip
) == IPv6len
&& ip
[0] == 0xff && ip
[1]&0x0f == 0x01
139 // IsLinkLocalMulticast reports whether ip is a link-local
140 // multicast address.
141 func (ip IP
) IsLinkLocalMulticast() bool {
142 if ip4
:= ip
.To4(); ip4
!= nil {
143 return ip4
[0] == 224 && ip4
[1] == 0 && ip4
[2] == 0
145 return len(ip
) == IPv6len
&& ip
[0] == 0xff && ip
[1]&0x0f == 0x02
148 // IsLinkLocalUnicast reports whether ip is a link-local
150 func (ip IP
) IsLinkLocalUnicast() bool {
151 if ip4
:= ip
.To4(); ip4
!= nil {
152 return ip4
[0] == 169 && ip4
[1] == 254
154 return len(ip
) == IPv6len
&& ip
[0] == 0xfe && ip
[1]&0xc0 == 0x80
157 // IsGlobalUnicast reports whether ip is a global unicast
160 // The identification of global unicast addresses uses address type
161 // identification as defined in RFC 1122, RFC 4632 and RFC 4291 with
162 // the exception of IPv4 directed broadcast addresses.
163 // It returns true even if ip is in IPv4 private address space or
164 // local IPv6 unicast address space.
165 func (ip IP
) IsGlobalUnicast() bool {
166 return (len(ip
) == IPv4len ||
len(ip
) == IPv6len
) &&
167 !ip
.Equal(IPv4bcast
) &&
168 !ip
.IsUnspecified() &&
171 !ip
.IsLinkLocalUnicast()
175 func isZeros(p IP
) bool {
176 for i
:= 0; i
< len(p
); i
++ {
184 // To4 converts the IPv4 address ip to a 4-byte representation.
185 // If ip is not an IPv4 address, To4 returns nil.
186 func (ip IP
) To4() IP
{
187 if len(ip
) == IPv4len
{
190 if len(ip
) == IPv6len
&&
199 // To16 converts the IP address ip to a 16-byte representation.
200 // If ip is not an IP address (it is the wrong length), To16 returns nil.
201 func (ip IP
) To16() IP
{
202 if len(ip
) == IPv4len
{
203 return IPv4(ip
[0], ip
[1], ip
[2], ip
[3])
205 if len(ip
) == IPv6len
{
211 // Default route masks for IPv4.
213 classAMask
= IPv4Mask(0xff, 0, 0, 0)
214 classBMask
= IPv4Mask(0xff, 0xff, 0, 0)
215 classCMask
= IPv4Mask(0xff, 0xff, 0xff, 0)
218 // DefaultMask returns the default IP mask for the IP address ip.
219 // Only IPv4 addresses have default masks; DefaultMask returns
220 // nil if ip is not a valid IPv4 address.
221 func (ip IP
) DefaultMask() IPMask
{
222 if ip
= ip
.To4(); ip
== nil {
235 func allFF(b
[]byte) bool {
236 for _
, c
:= range b
{
244 // Mask returns the result of masking the IP address ip with mask.
245 func (ip IP
) Mask(mask IPMask
) IP
{
246 if len(mask
) == IPv6len
&& len(ip
) == IPv4len
&& allFF(mask
[:12]) {
249 if len(mask
) == IPv4len
&& len(ip
) == IPv6len
&& bytesEqual(ip
[:12], v4InV6Prefix
) {
257 for i
:= 0; i
< n
; i
++ {
258 out
[i
] = ip
[i
] & mask
[i
]
263 // ubtoa encodes the string form of the integer v to dst[start:] and
264 // returns the number of bytes written to dst. The caller must ensure
265 // that dst has sufficient length.
266 func ubtoa(dst
[]byte, start
int, v
byte) int {
271 dst
[start
+1] = v%10
+ '0'
272 dst
[start
] = v
/10 + '0'
276 dst
[start
+2] = v%10
+ '0'
277 dst
[start
+1] = (v
/10)%10
+ '0'
278 dst
[start
] = v
/100 + '0'
282 // String returns the string form of the IP address ip.
283 // It returns one of 4 forms:
284 // - "<nil>", if ip has length 0
285 // - dotted decimal ("192.0.2.1"), if ip is an IPv4 or IP4-mapped IPv6 address
286 // - IPv6 ("2001:db8::1"), if ip is a valid IPv6 address
287 // - the hexadecimal form of ip, without punctuation, if no other cases apply
288 func (ip IP
) String() string {
295 // If IPv4, use dotted notation.
296 if p4
:= p
.To4(); len(p4
) == IPv4len
{
297 const maxIPv4StringLen
= len("255.255.255.255")
298 b
:= make([]byte, maxIPv4StringLen
)
300 n
:= ubtoa(b
, 0, p4
[0])
304 n
+= ubtoa(b
, n
, p4
[1])
308 n
+= ubtoa(b
, n
, p4
[2])
312 n
+= ubtoa(b
, n
, p4
[3])
315 if len(p
) != IPv6len
{
316 return "?" + hexString(ip
)
319 // Find longest run of zeros.
322 for i
:= 0; i
< IPv6len
; i
+= 2 {
324 for j
< IPv6len
&& p
[j
] == 0 && p
[j
+1] == 0 {
327 if j
> i
&& j
-i
> e1
-e0
{
333 // The symbol "::" MUST NOT be used to shorten just one 16 bit 0 field.
339 const maxLen
= len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
340 b
:= make([]byte, 0, maxLen
)
342 // Print with possible :: in place of run of zeros
343 for i
:= 0; i
< IPv6len
; i
+= 2 {
345 b
= append(b
, ':', ':')
353 b
= appendHex(b
, (uint32(p
[i
])<<8)|
uint32(p
[i
+1]))
358 func hexString(b
[]byte) string {
359 s
:= make([]byte, len(b
)*2)
360 for i
, tn
:= range b
{
361 s
[i
*2], s
[i
*2+1] = hexDigit
[tn
>>4], hexDigit
[tn
&0xf]
366 // ipEmptyString is like ip.String except that it returns
367 // an empty string when ip is unset.
368 func ipEmptyString(ip IP
) string {
375 // MarshalText implements the encoding.TextMarshaler interface.
376 // The encoding is the same as returned by String, with one exception:
377 // When len(ip) is zero, it returns an empty slice.
378 func (ip IP
) MarshalText() ([]byte, error
) {
380 return []byte(""), nil
382 if len(ip
) != IPv4len
&& len(ip
) != IPv6len
{
383 return nil, &AddrError
{Err
: "invalid IP address", Addr
: hexString(ip
)}
385 return []byte(ip
.String()), nil
388 // UnmarshalText implements the encoding.TextUnmarshaler interface.
389 // The IP address is expected in a form accepted by ParseIP.
390 func (ip
*IP
) UnmarshalText(text
[]byte) error
{
398 return &ParseError
{Type
: "IP address", Text
: s
}
404 // Equal reports whether ip and x are the same IP address.
405 // An IPv4 address and that same address in IPv6 form are
406 // considered to be equal.
407 func (ip IP
) Equal(x IP
) bool {
408 if len(ip
) == len(x
) {
409 return bytesEqual(ip
, x
)
411 if len(ip
) == IPv4len
&& len(x
) == IPv6len
{
412 return bytesEqual(x
[0:12], v4InV6Prefix
) && bytesEqual(ip
, x
[12:])
414 if len(ip
) == IPv6len
&& len(x
) == IPv4len
{
415 return bytesEqual(ip
[0:12], v4InV6Prefix
) && bytesEqual(ip
[12:], x
)
420 // bytes.Equal is implemented in runtime/asm_$goarch.s
421 //go:linkname bytesEqual bytes.Equal
422 func bytesEqual(x
, y
[]byte) bool
424 func (ip IP
) matchAddrFamily(x IP
) bool {
425 return ip
.To4() != nil && x
.To4() != nil || ip
.To16() != nil && ip
.To4() == nil && x
.To16() != nil && x
.To4() == nil
428 // If mask is a sequence of 1 bits followed by 0 bits,
429 // return the number of 1 bits.
430 func simpleMaskLength(mask IPMask
) int {
432 for i
, v
:= range mask
{
443 // rest must be 0 bits
447 for i
++; i
< len(mask
); i
++ {
457 // Size returns the number of leading ones and total bits in the mask.
458 // If the mask is not in the canonical form--ones followed by zeros--then
459 // Size returns 0, 0.
460 func (m IPMask
) Size() (ones
, bits
int) {
461 ones
, bits
= simpleMaskLength(m
), len(m
)*8
468 // String returns the hexadecimal form of m, with no punctuation.
469 func (m IPMask
) String() string {
476 func networkNumberAndMask(n
*IPNet
) (ip IP
, m IPMask
) {
477 if ip
= n
.IP
.To4(); ip
== nil {
479 if len(ip
) != IPv6len
{
486 if len(ip
) != IPv4len
{
490 if len(ip
) == IPv4len
{
499 // Contains reports whether the network includes ip.
500 func (n
*IPNet
) Contains(ip IP
) bool {
501 nn
, m
:= networkNumberAndMask(n
)
502 if x
:= ip
.To4(); x
!= nil {
509 for i
:= 0; i
< l
; i
++ {
510 if nn
[i
]&m
[i
] != ip
[i
]&m
[i
] {
517 // Network returns the address's network name, "ip+net".
518 func (n
*IPNet
) Network() string { return "ip+net" }
520 // String returns the CIDR notation of n like "192.0.2.1/24"
521 // or "2001:db8::/48" as defined in RFC 4632 and RFC 4291.
522 // If the mask is not in the canonical form, it returns the
523 // string which consists of an IP address, followed by a slash
524 // character and a mask expressed as hexadecimal form with no
525 // punctuation like "198.51.100.1/c000ff00".
526 func (n
*IPNet
) String() string {
527 nn
, m
:= networkNumberAndMask(n
)
528 if nn
== nil || m
== nil {
531 l
:= simpleMaskLength(m
)
533 return nn
.String() + "/" + m
.String()
535 return nn
.String() + "/" + uitoa(uint(l
))
538 // Parse IPv4 address (d.d.d.d).
539 func parseIPv4(s
string) IP
{
541 for i
:= 0; i
< IPv4len
; i
++ {
562 return IPv4(p
[0], p
[1], p
[2], p
[3])
565 // parseIPv6Zone parses s as a literal IPv6 address and its associated zone
566 // identifier which is described in RFC 4007.
567 func parseIPv6Zone(s
string) (IP
, string) {
568 s
, zone
:= splitHostZone(s
)
569 return parseIPv6(s
), zone
572 // parseIPv6Zone parses s as a literal IPv6 address described in RFC 4291
574 func parseIPv6(s
string) (ip IP
) {
575 ip
= make(IP
, IPv6len
)
576 ellipsis
:= -1 // position of ellipsis in ip
578 // Might have leading ellipsis
579 if len(s
) >= 2 && s
[0] == ':' && s
[1] == ':' {
582 // Might be only ellipsis
588 // Loop, parsing hex numbers followed by colon.
593 if !ok || n
> 0xFFFF {
597 // If followed by dot, might be in trailing IPv4.
598 if c
< len(s
) && s
[c
] == '.' {
599 if ellipsis
< 0 && i
!= IPv6len
-IPv4len
{
600 // Not the right place.
603 if i
+IPv4len
> IPv6len
{
620 // Save this 16-bit chunk.
625 // Stop at end of string.
631 // Otherwise must be followed by colon and more.
632 if s
[0] != ':' ||
len(s
) == 1 {
637 // Look for ellipsis.
639 if ellipsis
>= 0 { // already have one
644 if len(s
) == 0 { // can be at end
650 // Must have used entire string.
655 // If didn't parse enough, expand ellipsis.
661 for j
:= i
- 1; j
>= ellipsis
; j
-- {
664 for j
:= ellipsis
+ n
- 1; j
>= ellipsis
; j
-- {
667 } else if ellipsis
>= 0 {
668 // Ellipsis must represent at least one 0 group.
674 // ParseIP parses s as an IP address, returning the result.
675 // The string s can be in dotted decimal ("192.0.2.1")
676 // or IPv6 ("2001:db8::68") form.
677 // If s is not a valid textual representation of an IP address,
678 // ParseIP returns nil.
679 func ParseIP(s
string) IP
{
680 for i
:= 0; i
< len(s
); i
++ {
691 // parseIPZone parses s as an IP address, return it and its associated zone
692 // identifier (IPv6 only).
693 func parseIPZone(s
string) (IP
, string) {
694 for i
:= 0; i
< len(s
); i
++ {
697 return parseIPv4(s
), ""
699 return parseIPv6Zone(s
)
705 // ParseCIDR parses s as a CIDR notation IP address and prefix length,
706 // like "192.0.2.0/24" or "2001:db8::/32", as defined in
707 // RFC 4632 and RFC 4291.
709 // It returns the IP address and the network implied by the IP and
711 // For example, ParseCIDR("192.0.2.1/24") returns the IP address
712 // 192.0.2.1 and the network 192.0.2.0/24.
713 func ParseCIDR(s
string) (IP
, *IPNet
, error
) {
714 i
:= byteIndex(s
, '/')
716 return nil, nil, &ParseError
{Type
: "CIDR address", Text
: s
}
718 addr
, mask
:= s
[:i
], s
[i
+1:]
720 ip
:= parseIPv4(addr
)
725 n
, i
, ok
:= dtoi(mask
)
726 if ip
== nil ||
!ok || i
!= len(mask
) || n
< 0 || n
> 8*iplen
{
727 return nil, nil, &ParseError
{Type
: "CIDR address", Text
: s
}
729 m
:= CIDRMask(n
, 8*iplen
)
730 return ip
, &IPNet
{IP
: ip
.Mask(m
), Mask
: m
}, nil