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 array but always
11 // returns 16-byte addresses.
17 // IP address lengths (bytes).
23 // An IP is a single IP address, an array of bytes.
24 // Functions in this package accept either 4-byte (IP v4)
25 // or 16-byte (IP v6) arrays as input. Unless otherwise
26 // specified, functions in this package always return
27 // IP addresses in 16-byte form using the canonical
30 // Note that in this documentation, referring to an
31 // IP address as an IPv4 address or an IPv6 address
32 // is a semantic property of the address, not just the
33 // length of the byte array: a 16-byte array can still
34 // be an IPv4 address.
37 // An IP mask is an IP address.
40 // IPv4 returns the IP address (in 16-byte form) of the
41 // IPv4 address a.b.c.d.
42 func IPv4(a
, b
, c
, d
byte) IP
{
43 p
:= make(IP
, IPv6len
)
52 var v4InV6Prefix
= []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
54 // IPv4Mask returns the IP mask (in 16-byte form) of the
56 func IPv4Mask(a
, b
, c
, d
byte) IPMask
{
57 p
:= make(IPMask
, IPv6len
)
58 for i
:= 0; i
< 12; i
++ {
68 // Well-known IPv4 addresses
70 IPv4bcast
= IPv4(255, 255, 255, 255) // broadcast
71 IPv4allsys
= IPv4(224, 0, 0, 1) // all systems
72 IPv4allrouter
= IPv4(224, 0, 0, 2) // all routers
73 IPv4zero
= IPv4(0, 0, 0, 0) // all zeros
76 // Well-known IPv6 addresses
78 IPzero
= make(IP
, IPv6len
) // all zeros
82 func isZeros(p IP
) bool {
83 for i
:= 0; i
< len(p
); i
++ {
91 // To4 converts the IPv4 address ip to a 4-byte representation.
92 // If ip is not an IPv4 address, To4 returns nil.
93 func (ip IP
) To4() IP
{
94 if len(ip
) == IPv4len
{
97 if len(ip
) == IPv6len
&&
106 // To16 converts the IP address ip to a 16-byte representation.
107 // If ip is not an IP address (it is the wrong length), To16 returns nil.
108 func (ip IP
) To16() IP
{
109 if len(ip
) == IPv4len
{
110 return IPv4(ip
[0], ip
[1], ip
[2], ip
[3])
112 if len(ip
) == IPv6len
{
118 // Default route masks for IPv4.
120 classAMask
= IPv4Mask(0xff, 0, 0, 0)
121 classBMask
= IPv4Mask(0xff, 0xff, 0, 0)
122 classCMask
= IPv4Mask(0xff, 0xff, 0xff, 0)
125 // DefaultMask returns the default IP mask for the IP address ip.
126 // Only IPv4 addresses have default masks; DefaultMask returns
127 // nil if ip is not a valid IPv4 address.
128 func (ip IP
) DefaultMask() IPMask
{
129 if ip
= ip
.To4(); ip
== nil {
140 return nil // not reached
143 func allFF(b
[]byte) bool {
144 for _
, c
:= range b
{
152 // Mask returns the result of masking the IP address ip with mask.
153 func (ip IP
) Mask(mask IPMask
) IP
{
155 if len(mask
) == 16 && len(ip
) == 4 && allFF(mask
[:12]) {
158 if len(mask
) == 4 && len(ip
) == 16 && bytesEqual(ip
[:12], v4InV6Prefix
) {
165 for i
:= 0; i
< n
; i
++ {
166 out
[i
] = ip
[i
] & mask
[i
]
171 // Convert i to decimal string.
172 func itod(i
uint) string {
177 // Assemble decimal in reverse order.
180 for ; i
> 0; i
/= 10 {
182 b
[bp
] = byte(i%10
) + '0'
185 return string(b
[bp
:])
188 // Convert i to hexadecimal string.
189 func itox(i
uint) string {
194 // Assemble hexadecimal in reverse order.
197 for ; i
> 0; i
/= 16 {
199 b
[bp
] = "0123456789abcdef"[byte(i%16
)]
202 return string(b
[bp
:])
205 // String returns the string form of the IP address ip.
206 // If the address is an IPv4 address, the string representation
207 // is dotted decimal ("74.125.19.99"). Otherwise the representation
208 // is IPv6 ("2001:4860:0:2001::68").
209 func (ip IP
) String() string {
216 // If IPv4, use dotted notation.
217 if p4
:= p
.To4(); len(p4
) == 4 {
218 return itod(uint(p4
[0])) + "." +
219 itod(uint(p4
[1])) + "." +
220 itod(uint(p4
[2])) + "." +
223 if len(p
) != IPv6len
{
227 // Find longest run of zeros.
230 for i
:= 0; i
< 16; i
+= 2 {
232 for j
< 16 && p
[j
] == 0 && p
[j
+1] == 0 {
235 if j
> i
&& j
-i
> e1
-e0
{
240 // The symbol "::" MUST NOT be used to shorten just one 16 bit 0 field.
246 // Print with possible :: in place of run of zeros
248 for i
:= 0; i
< 16; i
+= 2 {
258 s
+= itox((uint(p
[i
]) << 8) |
uint(p
[i
+1]))
263 // Equal returns true if ip and x are the same IP address.
264 // An IPv4 address and that same address in IPv6 form are
265 // considered to be equal.
266 func (ip IP
) Equal(x IP
) bool {
267 if len(ip
) == len(x
) {
268 return bytesEqual(ip
, x
)
270 if len(ip
) == 4 && len(x
) == 16 {
271 return bytesEqual(x
[0:12], v4InV6Prefix
) && bytesEqual(ip
, x
[12:])
273 if len(ip
) == 16 && len(x
) == 4 {
274 return bytesEqual(ip
[0:12], v4InV6Prefix
) && bytesEqual(ip
[12:], x
)
279 func bytesEqual(x
, y
[]byte) bool {
280 if len(x
) != len(y
) {
283 for i
, b
:= range x
{
291 // If mask is a sequence of 1 bits followed by 0 bits,
292 // return the number of 1 bits.
293 func simpleMaskLength(mask IPMask
) int {
295 for i
, v
:= range mask
{
306 // rest must be 0 bits
310 for i
++; i
< len(mask
); i
++ {
320 // String returns the string representation of mask.
321 // If the mask is in the canonical form--ones followed by zeros--the
322 // string representation is just the decimal number of ones.
323 // If the mask is in a non-canonical form, it is formatted
325 func (mask IPMask
) String() string {
328 n
:= simpleMaskLength(mask
)
330 return itod(uint(n
+ (IPv6len
-IPv4len
)*8))
333 n
:= simpleMaskLength(mask
)
335 return itod(uint(n
- 12*8))
338 return IP(mask
).String()
341 // Parse IPv4 address (d.d.d.d).
342 func parseIPv4(s
string) IP
{
345 for j
:= 0; j
< IPv4len
; j
++ {
360 n
, i
, ok
= dtoi(s
, i
)
369 return IPv4(p
[0], p
[1], p
[2], p
[3])
372 // Parse IPv6 address. Many forms.
373 // The basic form is a sequence of eight colon-separated
374 // 16-bit hex numbers separated by colons,
375 // as in 0123:4567:89ab:cdef:0123:4567:89ab:cdef.
377 // * A run of zeros can be replaced with "::".
378 // * The last 32 bits can be in IPv4 form.
379 // Thus, ::ffff:1.2.3.4 is the IPv4 address 1.2.3.4.
380 func parseIPv6(s
string) IP
{
382 ellipsis
:= -1 // position of ellipsis in p
383 i
:= 0 // index in string s
385 // Might have leading ellipsis
386 if len(s
) >= 2 && s
[0] == ':' && s
[1] == ':' {
389 // Might be only ellipsis
395 // Loop, parsing hex numbers followed by colon.
399 n
, i1
, ok
:= xtoi(s
, i
)
400 if !ok || n
> 0xFFFF {
404 // If followed by dot, might be in trailing IPv4.
405 if i1
< len(s
) && s
[i1
] == '.' {
406 if ellipsis
< 0 && j
!= IPv6len
-IPv4len
{
407 // Not the right place.
410 if j
+IPv4len
> IPv6len
{
414 p4
:= parseIPv4(s
[i
:])
427 // Save this 16-bit chunk.
432 // Stop at end of string.
438 // Otherwise must be followed by colon and more.
439 if s
[i
] != ':' && i
+1 == len(s
) {
444 // Look for ellipsis.
446 if ellipsis
>= 0 { // already have one
450 if i
++; i
== len(s
) { // can be at end
456 // Must have used entire string.
461 // If didn't parse enough, expand ellipsis.
467 for k
:= j
- 1; k
>= ellipsis
; k
-- {
470 for k
:= ellipsis
+ n
- 1; k
>= ellipsis
; k
-- {
477 // A ParseError represents a malformed text string and the type of string that was expected.
478 type ParseError
struct {
483 func (e
*ParseError
) String() string {
484 return "invalid " + e
.Type
+ ": " + e
.Text
487 func parseIP(s
string) IP
{
488 if p
:= parseIPv4(s
); p
!= nil {
491 if p
:= parseIPv6(s
); p
!= nil {
497 // ParseIP parses s as an IP address, returning the result.
498 // The string s can be in dotted decimal ("74.125.19.99")
499 // or IPv6 ("2001:4860:0:2001::68") form.
500 // If s is not a valid textual representation of an IP address,
501 // ParseIP returns nil.
502 func ParseIP(s
string) IP
{
503 if p
:= parseIPv4(s
); p
!= nil {
509 // ParseCIDR parses s as a CIDR notation IP address and mask,
510 // like "192.168.100.1/24", "2001:DB8::/48", as defined in
511 // RFC 4632 and RFC 4291.
512 func ParseCIDR(s
string) (ip IP
, mask IPMask
, err os
.Error
) {
513 i
:= byteIndex(s
, '/')
515 return nil, nil, &ParseError
{"CIDR address", s
}
517 ipstr
, maskstr
:= s
[:i
], s
[i
+1:]
519 ip
= parseIPv4(ipstr
)
522 ip
= parseIPv6(ipstr
)
524 nn
, i
, ok
:= dtoi(maskstr
, 0)
525 if ip
== nil ||
!ok || i
!= len(maskstr
) || nn
< 0 || nn
> 8*iplen
{
526 return nil, nil, &ParseError
{"CIDR address", s
}
530 v4mask
:= ^uint32(0xffffffff >> n
)
531 mask
= IPv4Mask(byte(v4mask
>>24), byte(v4mask
>>16), byte(v4mask
>>8), byte(v4mask
))
533 mask
= make(IPMask
, 16)
534 for i
:= 0; i
< 16; i
++ {
540 mask
[i
] = ^byte(0xff >> n
)
545 // address must not have any bits not in mask
547 if ip
[i
]&^mask
[i
] != 0 {
548 return nil, nil, &ParseError
{"CIDR address", s
}