2011-04-11 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / libgo / go / net / ip.go
blob12bb6f351a1e914a4f76faecf37cc98c9afdf307
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
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 array but always
11 // returns 16-byte addresses.
13 package net
15 import "os"
17 // IP address lengths (bytes).
18 const (
19 IPv4len = 4
20 IPv6len = 16
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
28 // embedding.
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.
35 type IP []byte
37 // An IP mask is an IP address.
38 type IPMask []byte
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)
44 copy(p, v4InV6Prefix)
45 p[12] = a
46 p[13] = b
47 p[14] = c
48 p[15] = d
49 return p
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
55 // IPv4 mask a.b.c.d.
56 func IPv4Mask(a, b, c, d byte) IPMask {
57 p := make(IPMask, IPv6len)
58 for i := 0; i < 12; i++ {
59 p[i] = 0xff
61 p[12] = a
62 p[13] = b
63 p[14] = c
64 p[15] = d
65 return p
68 // Well-known IPv4 addresses
69 var (
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
77 var (
78 IPzero = make(IP, IPv6len) // all zeros
81 // Is p all zeros?
82 func isZeros(p IP) bool {
83 for i := 0; i < len(p); i++ {
84 if p[i] != 0 {
85 return false
88 return true
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 {
95 return ip
97 if len(ip) == IPv6len &&
98 isZeros(ip[0:10]) &&
99 ip[10] == 0xff &&
100 ip[11] == 0xff {
101 return ip[12:16]
103 return nil
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 {
113 return ip
115 return nil
118 // Default route masks for IPv4.
119 var (
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 {
130 return nil
132 switch true {
133 case ip[0] < 0x80:
134 return classAMask
135 case ip[0] < 0xC0:
136 return classBMask
137 default:
138 return classCMask
140 return nil // not reached
143 func allFF(b []byte) bool {
144 for _, c := range b {
145 if c != 0xff {
146 return false
149 return true
152 // Mask returns the result of masking the IP address ip with mask.
153 func (ip IP) Mask(mask IPMask) IP {
154 n := len(ip)
155 if len(mask) == 16 && len(ip) == 4 && allFF(mask[:12]) {
156 mask = mask[12:]
158 if len(mask) == 4 && len(ip) == 16 && bytesEqual(ip[:12], v4InV6Prefix) {
159 ip = ip[12:]
161 if n != len(mask) {
162 return nil
164 out := make(IP, n)
165 for i := 0; i < n; i++ {
166 out[i] = ip[i] & mask[i]
168 return out
171 // Convert i to decimal string.
172 func itod(i uint) string {
173 if i == 0 {
174 return "0"
177 // Assemble decimal in reverse order.
178 var b [32]byte
179 bp := len(b)
180 for ; i > 0; i /= 10 {
181 bp--
182 b[bp] = byte(i%10) + '0'
185 return string(b[bp:])
188 // Convert i to hexadecimal string.
189 func itox(i uint) string {
190 if i == 0 {
191 return "0"
194 // Assemble hexadecimal in reverse order.
195 var b [32]byte
196 bp := len(b)
197 for ; i > 0; i /= 16 {
198 bp--
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 {
210 p := ip
212 if len(ip) == 0 {
213 return ""
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])) + "." +
221 itod(uint(p4[3]))
223 if len(p) != IPv6len {
224 return "?"
227 // Find longest run of zeros.
228 e0 := -1
229 e1 := -1
230 for i := 0; i < 16; i += 2 {
231 j := i
232 for j < 16 && p[j] == 0 && p[j+1] == 0 {
233 j += 2
235 if j > i && j-i > e1-e0 {
236 e0 = i
237 e1 = j
240 // The symbol "::" MUST NOT be used to shorten just one 16 bit 0 field.
241 if e1-e0 <= 2 {
242 e0 = -1
243 e1 = -1
246 // Print with possible :: in place of run of zeros
247 var s string
248 for i := 0; i < 16; i += 2 {
249 if i == e0 {
250 s += "::"
251 i = e1
252 if i >= 16 {
253 break
255 } else if i > 0 {
256 s += ":"
258 s += itox((uint(p[i]) << 8) | uint(p[i+1]))
260 return s
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)
276 return false
279 func bytesEqual(x, y []byte) bool {
280 if len(x) != len(y) {
281 return false
283 for i, b := range x {
284 if y[i] != b {
285 return false
288 return true
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 {
294 var n int
295 for i, v := range mask {
296 if v == 0xff {
297 n += 8
298 continue
300 // found non-ff byte
301 // count 1 bits
302 for v&0x80 != 0 {
304 v <<= 1
306 // rest must be 0 bits
307 if v != 0 {
308 return -1
310 for i++; i < len(mask); i++ {
311 if mask[i] != 0 {
312 return -1
315 break
317 return n
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
324 // as an IP address.
325 func (mask IPMask) String() string {
326 switch len(mask) {
327 case 4:
328 n := simpleMaskLength(mask)
329 if n >= 0 {
330 return itod(uint(n + (IPv6len-IPv4len)*8))
332 case 16:
333 n := simpleMaskLength(mask)
334 if n >= 12*8 {
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 {
343 var p [IPv4len]byte
344 i := 0
345 for j := 0; j < IPv4len; j++ {
346 if i >= len(s) {
347 // Missing octets.
348 return nil
350 if j > 0 {
351 if s[i] != '.' {
352 return nil
356 var (
357 n int
358 ok bool
360 n, i, ok = dtoi(s, i)
361 if !ok || n > 0xFF {
362 return nil
364 p[j] = byte(n)
366 if i != len(s) {
367 return nil
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.
376 // Two exceptions:
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 {
381 p := make(IP, 16)
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] == ':' {
387 ellipsis = 0
388 i = 2
389 // Might be only ellipsis
390 if i == len(s) {
391 return p
395 // Loop, parsing hex numbers followed by colon.
396 j := 0
397 for j < IPv6len {
398 // Hex number.
399 n, i1, ok := xtoi(s, i)
400 if !ok || n > 0xFFFF {
401 return nil
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.
408 return nil
410 if j+IPv4len > IPv6len {
411 // Not enough room.
412 return nil
414 p4 := parseIPv4(s[i:])
415 if p4 == nil {
416 return nil
418 p[j] = p4[12]
419 p[j+1] = p4[13]
420 p[j+2] = p4[14]
421 p[j+3] = p4[15]
422 i = len(s)
423 j += 4
424 break
427 // Save this 16-bit chunk.
428 p[j] = byte(n >> 8)
429 p[j+1] = byte(n)
430 j += 2
432 // Stop at end of string.
433 i = i1
434 if i == len(s) {
435 break
438 // Otherwise must be followed by colon and more.
439 if s[i] != ':' && i+1 == len(s) {
440 return nil
444 // Look for ellipsis.
445 if s[i] == ':' {
446 if ellipsis >= 0 { // already have one
447 return nil
449 ellipsis = j
450 if i++; i == len(s) { // can be at end
451 break
456 // Must have used entire string.
457 if i != len(s) {
458 return nil
461 // If didn't parse enough, expand ellipsis.
462 if j < IPv6len {
463 if ellipsis < 0 {
464 return nil
466 n := IPv6len - j
467 for k := j - 1; k >= ellipsis; k-- {
468 p[k+n] = p[k]
470 for k := ellipsis + n - 1; k >= ellipsis; k-- {
471 p[k] = 0
474 return p
477 // A ParseError represents a malformed text string and the type of string that was expected.
478 type ParseError struct {
479 Type string
480 Text string
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 {
489 return p
491 if p := parseIPv6(s); p != nil {
492 return p
494 return 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 {
504 return p
506 return parseIPv6(s)
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, '/')
514 if i < 0 {
515 return nil, nil, &ParseError{"CIDR address", s}
517 ipstr, maskstr := s[:i], s[i+1:]
518 iplen := 4
519 ip = parseIPv4(ipstr)
520 if ip == nil {
521 iplen = 16
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}
528 n := uint(nn)
529 if iplen == 4 {
530 v4mask := ^uint32(0xffffffff >> n)
531 mask = IPv4Mask(byte(v4mask>>24), byte(v4mask>>16), byte(v4mask>>8), byte(v4mask))
532 } else {
533 mask = make(IPMask, 16)
534 for i := 0; i < 16; i++ {
535 if n >= 8 {
536 mask[i] = 0xff
537 n -= 8
538 continue
540 mask[i] = ^byte(0xff >> n)
541 n = 0
545 // address must not have any bits not in mask
546 for i := range ip {
547 if ip[i]&^mask[i] != 0 {
548 return nil, nil, &ParseError{"CIDR address", s}
551 return ip, mask, nil