Source file
src/net/ip.go
Documentation: net
1
2
3
4
5
6
7
8
9
10
11
12
13 package net
14
15 import _ "unsafe"
16
17
18 const (
19 IPv4len = 4
20 IPv6len = 16
21 )
22
23
24
25
26
27
28
29
30
31
32 type IP []byte
33
34
35 type IPMask []byte
36
37
38 type IPNet struct {
39 IP IP
40 Mask IPMask
41 }
42
43
44
45 func IPv4(a, b, c, d byte) IP {
46 p := make(IP, IPv6len)
47 copy(p, v4InV6Prefix)
48 p[12] = a
49 p[13] = b
50 p[14] = c
51 p[15] = d
52 return p
53 }
54
55 var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
56
57
58
59 func IPv4Mask(a, b, c, d byte) IPMask {
60 p := make(IPMask, IPv4len)
61 p[0] = a
62 p[1] = b
63 p[2] = c
64 p[3] = d
65 return p
66 }
67
68
69
70
71 func CIDRMask(ones, bits int) IPMask {
72 if bits != 8*IPv4len && bits != 8*IPv6len {
73 return nil
74 }
75 if ones < 0 || ones > bits {
76 return nil
77 }
78 l := bits / 8
79 m := make(IPMask, l)
80 n := uint(ones)
81 for i := 0; i < l; i++ {
82 if n >= 8 {
83 m[i] = 0xff
84 n -= 8
85 continue
86 }
87 m[i] = ^byte(0xff >> n)
88 n = 0
89 }
90 return m
91 }
92
93
94 var (
95 IPv4bcast = IPv4(255, 255, 255, 255)
96 IPv4allsys = IPv4(224, 0, 0, 1)
97 IPv4allrouter = IPv4(224, 0, 0, 2)
98 IPv4zero = IPv4(0, 0, 0, 0)
99 )
100
101
102 var (
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}
109 )
110
111
112
113 func (ip IP) IsUnspecified() bool {
114 return ip.Equal(IPv4zero) || ip.Equal(IPv6unspecified)
115 }
116
117
118 func (ip IP) IsLoopback() bool {
119 if ip4 := ip.To4(); ip4 != nil {
120 return ip4[0] == 127
121 }
122 return ip.Equal(IPv6loopback)
123 }
124
125
126 func (ip IP) IsMulticast() bool {
127 if ip4 := ip.To4(); ip4 != nil {
128 return ip4[0]&0xf0 == 0xe0
129 }
130 return len(ip) == IPv6len && ip[0] == 0xff
131 }
132
133
134
135 func (ip IP) IsInterfaceLocalMulticast() bool {
136 return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x01
137 }
138
139
140
141 func (ip IP) IsLinkLocalMulticast() bool {
142 if ip4 := ip.To4(); ip4 != nil {
143 return ip4[0] == 224 && ip4[1] == 0 && ip4[2] == 0
144 }
145 return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x02
146 }
147
148
149
150 func (ip IP) IsLinkLocalUnicast() bool {
151 if ip4 := ip.To4(); ip4 != nil {
152 return ip4[0] == 169 && ip4[1] == 254
153 }
154 return len(ip) == IPv6len && ip[0] == 0xfe && ip[1]&0xc0 == 0x80
155 }
156
157
158
159
160
161
162
163
164
165 func (ip IP) IsGlobalUnicast() bool {
166 return (len(ip) == IPv4len || len(ip) == IPv6len) &&
167 !ip.Equal(IPv4bcast) &&
168 !ip.IsUnspecified() &&
169 !ip.IsLoopback() &&
170 !ip.IsMulticast() &&
171 !ip.IsLinkLocalUnicast()
172 }
173
174
175 func isZeros(p IP) bool {
176 for i := 0; i < len(p); i++ {
177 if p[i] != 0 {
178 return false
179 }
180 }
181 return true
182 }
183
184
185
186 func (ip IP) To4() IP {
187 if len(ip) == IPv4len {
188 return ip
189 }
190 if len(ip) == IPv6len &&
191 isZeros(ip[0:10]) &&
192 ip[10] == 0xff &&
193 ip[11] == 0xff {
194 return ip[12:16]
195 }
196 return nil
197 }
198
199
200
201 func (ip IP) To16() IP {
202 if len(ip) == IPv4len {
203 return IPv4(ip[0], ip[1], ip[2], ip[3])
204 }
205 if len(ip) == IPv6len {
206 return ip
207 }
208 return nil
209 }
210
211
212 var (
213 classAMask = IPv4Mask(0xff, 0, 0, 0)
214 classBMask = IPv4Mask(0xff, 0xff, 0, 0)
215 classCMask = IPv4Mask(0xff, 0xff, 0xff, 0)
216 )
217
218
219
220
221 func (ip IP) DefaultMask() IPMask {
222 if ip = ip.To4(); ip == nil {
223 return nil
224 }
225 switch true {
226 case ip[0] < 0x80:
227 return classAMask
228 case ip[0] < 0xC0:
229 return classBMask
230 default:
231 return classCMask
232 }
233 }
234
235 func allFF(b []byte) bool {
236 for _, c := range b {
237 if c != 0xff {
238 return false
239 }
240 }
241 return true
242 }
243
244
245 func (ip IP) Mask(mask IPMask) IP {
246 if len(mask) == IPv6len && len(ip) == IPv4len && allFF(mask[:12]) {
247 mask = mask[12:]
248 }
249 if len(mask) == IPv4len && len(ip) == IPv6len && bytesEqual(ip[:12], v4InV6Prefix) {
250 ip = ip[12:]
251 }
252 n := len(ip)
253 if n != len(mask) {
254 return nil
255 }
256 out := make(IP, n)
257 for i := 0; i < n; i++ {
258 out[i] = ip[i] & mask[i]
259 }
260 return out
261 }
262
263
264
265
266
267
268
269 func (ip IP) String() string {
270 p := ip
271
272 if len(ip) == 0 {
273 return "<nil>"
274 }
275
276
277 if p4 := p.To4(); len(p4) == IPv4len {
278 return uitoa(uint(p4[0])) + "." +
279 uitoa(uint(p4[1])) + "." +
280 uitoa(uint(p4[2])) + "." +
281 uitoa(uint(p4[3]))
282 }
283 if len(p) != IPv6len {
284 return "?" + hexString(ip)
285 }
286
287
288 e0 := -1
289 e1 := -1
290 for i := 0; i < IPv6len; i += 2 {
291 j := i
292 for j < IPv6len && p[j] == 0 && p[j+1] == 0 {
293 j += 2
294 }
295 if j > i && j-i > e1-e0 {
296 e0 = i
297 e1 = j
298 i = j
299 }
300 }
301
302 if e1-e0 <= 2 {
303 e0 = -1
304 e1 = -1
305 }
306
307 const maxLen = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
308 b := make([]byte, 0, maxLen)
309
310
311 for i := 0; i < IPv6len; i += 2 {
312 if i == e0 {
313 b = append(b, ':', ':')
314 i = e1
315 if i >= IPv6len {
316 break
317 }
318 } else if i > 0 {
319 b = append(b, ':')
320 }
321 b = appendHex(b, (uint32(p[i])<<8)|uint32(p[i+1]))
322 }
323 return string(b)
324 }
325
326 func hexString(b []byte) string {
327 s := make([]byte, len(b)*2)
328 for i, tn := range b {
329 s[i*2], s[i*2+1] = hexDigit[tn>>4], hexDigit[tn&0xf]
330 }
331 return string(s)
332 }
333
334
335
336 func ipEmptyString(ip IP) string {
337 if len(ip) == 0 {
338 return ""
339 }
340 return ip.String()
341 }
342
343
344
345
346 func (ip IP) MarshalText() ([]byte, error) {
347 if len(ip) == 0 {
348 return []byte(""), nil
349 }
350 if len(ip) != IPv4len && len(ip) != IPv6len {
351 return nil, &AddrError{Err: "invalid IP address", Addr: hexString(ip)}
352 }
353 return []byte(ip.String()), nil
354 }
355
356
357
358 func (ip *IP) UnmarshalText(text []byte) error {
359 if len(text) == 0 {
360 *ip = nil
361 return nil
362 }
363 s := string(text)
364 x := ParseIP(s)
365 if x == nil {
366 return &ParseError{Type: "IP address", Text: s}
367 }
368 *ip = x
369 return nil
370 }
371
372
373
374
375 func (ip IP) Equal(x IP) bool {
376 if len(ip) == len(x) {
377 return bytesEqual(ip, x)
378 }
379 if len(ip) == IPv4len && len(x) == IPv6len {
380 return bytesEqual(x[0:12], v4InV6Prefix) && bytesEqual(ip, x[12:])
381 }
382 if len(ip) == IPv6len && len(x) == IPv4len {
383 return bytesEqual(ip[0:12], v4InV6Prefix) && bytesEqual(ip[12:], x)
384 }
385 return false
386 }
387
388
389
390 func bytesEqual(x, y []byte) bool
391
392 func (ip IP) matchAddrFamily(x IP) bool {
393 return ip.To4() != nil && x.To4() != nil || ip.To16() != nil && ip.To4() == nil && x.To16() != nil && x.To4() == nil
394 }
395
396
397
398 func simpleMaskLength(mask IPMask) int {
399 var n int
400 for i, v := range mask {
401 if v == 0xff {
402 n += 8
403 continue
404 }
405
406
407 for v&0x80 != 0 {
408 n++
409 v <<= 1
410 }
411
412 if v != 0 {
413 return -1
414 }
415 for i++; i < len(mask); i++ {
416 if mask[i] != 0 {
417 return -1
418 }
419 }
420 break
421 }
422 return n
423 }
424
425
426
427
428 func (m IPMask) Size() (ones, bits int) {
429 ones, bits = simpleMaskLength(m), len(m)*8
430 if ones == -1 {
431 return 0, 0
432 }
433 return
434 }
435
436
437 func (m IPMask) String() string {
438 if len(m) == 0 {
439 return "<nil>"
440 }
441 return hexString(m)
442 }
443
444 func networkNumberAndMask(n *IPNet) (ip IP, m IPMask) {
445 if ip = n.IP.To4(); ip == nil {
446 ip = n.IP
447 if len(ip) != IPv6len {
448 return nil, nil
449 }
450 }
451 m = n.Mask
452 switch len(m) {
453 case IPv4len:
454 if len(ip) != IPv4len {
455 return nil, nil
456 }
457 case IPv6len:
458 if len(ip) == IPv4len {
459 m = m[12:]
460 }
461 default:
462 return nil, nil
463 }
464 return
465 }
466
467
468 func (n *IPNet) Contains(ip IP) bool {
469 nn, m := networkNumberAndMask(n)
470 if x := ip.To4(); x != nil {
471 ip = x
472 }
473 l := len(ip)
474 if l != len(nn) {
475 return false
476 }
477 for i := 0; i < l; i++ {
478 if nn[i]&m[i] != ip[i]&m[i] {
479 return false
480 }
481 }
482 return true
483 }
484
485
486 func (n *IPNet) Network() string { return "ip+net" }
487
488
489
490
491
492
493
494 func (n *IPNet) String() string {
495 nn, m := networkNumberAndMask(n)
496 if nn == nil || m == nil {
497 return "<nil>"
498 }
499 l := simpleMaskLength(m)
500 if l == -1 {
501 return nn.String() + "/" + m.String()
502 }
503 return nn.String() + "/" + uitoa(uint(l))
504 }
505
506
507 func parseIPv4(s string) IP {
508 var p [IPv4len]byte
509 for i := 0; i < IPv4len; i++ {
510 if len(s) == 0 {
511
512 return nil
513 }
514 if i > 0 {
515 if s[0] != '.' {
516 return nil
517 }
518 s = s[1:]
519 }
520 n, c, ok := dtoi(s)
521 if !ok || n > 0xFF {
522 return nil
523 }
524 s = s[c:]
525 p[i] = byte(n)
526 }
527 if len(s) != 0 {
528 return nil
529 }
530 return IPv4(p[0], p[1], p[2], p[3])
531 }
532
533
534
535
536
537 func parseIPv6(s string, zoneAllowed bool) (ip IP, zone string) {
538 ip = make(IP, IPv6len)
539 ellipsis := -1
540
541 if zoneAllowed {
542 s, zone = splitHostZone(s)
543 }
544
545
546 if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
547 ellipsis = 0
548 s = s[2:]
549
550 if len(s) == 0 {
551 return ip, zone
552 }
553 }
554
555
556 i := 0
557 for i < IPv6len {
558
559 n, c, ok := xtoi(s)
560 if !ok || n > 0xFFFF {
561 return nil, zone
562 }
563
564
565 if c < len(s) && s[c] == '.' {
566 if ellipsis < 0 && i != IPv6len-IPv4len {
567
568 return nil, zone
569 }
570 if i+IPv4len > IPv6len {
571
572 return nil, zone
573 }
574 ip4 := parseIPv4(s)
575 if ip4 == nil {
576 return nil, zone
577 }
578 ip[i] = ip4[12]
579 ip[i+1] = ip4[13]
580 ip[i+2] = ip4[14]
581 ip[i+3] = ip4[15]
582 s = ""
583 i += IPv4len
584 break
585 }
586
587
588 ip[i] = byte(n >> 8)
589 ip[i+1] = byte(n)
590 i += 2
591
592
593 s = s[c:]
594 if len(s) == 0 {
595 break
596 }
597
598
599 if s[0] != ':' || len(s) == 1 {
600 return nil, zone
601 }
602 s = s[1:]
603
604
605 if s[0] == ':' {
606 if ellipsis >= 0 {
607 return nil, zone
608 }
609 ellipsis = i
610 s = s[1:]
611 if len(s) == 0 {
612 break
613 }
614 }
615 }
616
617
618 if len(s) != 0 {
619 return nil, zone
620 }
621
622
623 if i < IPv6len {
624 if ellipsis < 0 {
625 return nil, zone
626 }
627 n := IPv6len - i
628 for j := i - 1; j >= ellipsis; j-- {
629 ip[j+n] = ip[j]
630 }
631 for j := ellipsis + n - 1; j >= ellipsis; j-- {
632 ip[j] = 0
633 }
634 } else if ellipsis >= 0 {
635
636 return nil, zone
637 }
638 return ip, zone
639 }
640
641
642
643
644
645
646 func ParseIP(s string) IP {
647 for i := 0; i < len(s); i++ {
648 switch s[i] {
649 case '.':
650 return parseIPv4(s)
651 case ':':
652 ip, _ := parseIPv6(s, false)
653 return ip
654 }
655 }
656 return nil
657 }
658
659
660
661
662
663
664
665
666
667 func ParseCIDR(s string) (IP, *IPNet, error) {
668 i := byteIndex(s, '/')
669 if i < 0 {
670 return nil, nil, &ParseError{Type: "CIDR address", Text: s}
671 }
672 addr, mask := s[:i], s[i+1:]
673 iplen := IPv4len
674 ip := parseIPv4(addr)
675 if ip == nil {
676 iplen = IPv6len
677 ip, _ = parseIPv6(addr, false)
678 }
679 n, i, ok := dtoi(mask)
680 if ip == nil || !ok || i != len(mask) || n < 0 || n > 8*iplen {
681 return nil, nil, &ParseError{Type: "CIDR address", Text: s}
682 }
683 m := CIDRMask(n, 8*iplen)
684 return ip, &IPNet{IP: ip.Mask(m), Mask: m}, nil
685 }
686
View as plain text