~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/pkg/net/ip.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
// IPv4 addresses are 4 bytes; IPv6 addresses are 16 bytes.
8
8
// An IPv4 address can be converted to an IPv6 address by
9
9
// adding a canonical prefix (10 zeros, 2 0xFFs).
10
 
// This library accepts either size of byte array but always
 
10
// This library accepts either size of byte slice but always
11
11
// returns 16-byte addresses.
12
12
 
13
13
package net
18
18
        IPv6len = 16
19
19
)
20
20
 
21
 
// An IP is a single IP address, an array of bytes.
 
21
// An IP is a single IP address, a slice of bytes.
22
22
// Functions in this package accept either 4-byte (IPv4)
23
 
// or 16-byte (IPv6) arrays as input.
 
23
// or 16-byte (IPv6) slices as input.
24
24
//
25
25
// Note that in this documentation, referring to an
26
26
// IP address as an IPv4 address or an IPv6 address
27
27
// is a semantic property of the address, not just the
28
 
// length of the byte array: a 16-byte array can still
 
28
// length of the byte slice: a 16-byte slice can still
29
29
// be an IPv4 address.
30
30
type IP []byte
31
31
 
222
222
        default:
223
223
                return classCMask
224
224
        }
225
 
        return nil // not reached
226
225
}
227
226
 
228
227
func allFF(b []byte) bool {
432
431
        return true
433
432
}
434
433
 
 
434
// Network returns the address's network name, "ip+net".
 
435
func (n *IPNet) Network() string { return "ip+net" }
 
436
 
435
437
// String returns the CIDR notation of n like "192.168.100.1/24"
436
438
// or "2001:DB8::/48" as defined in RFC 4632 and RFC 4291.
437
439
// If the mask is not in the canonical form, it returns the
450
452
        return nn.String() + "/" + itod(uint(l))
451
453
}
452
454
 
453
 
// Network returns the address's network name, "ip+net".
454
 
func (n *IPNet) Network() string { return "ip+net" }
455
 
 
456
455
// Parse IPv4 address (d.d.d.d).
457
456
func parseIPv4(s string) IP {
458
457
        var p [IPv4len]byte
484
483
        return IPv4(p[0], p[1], p[2], p[3])
485
484
}
486
485
 
487
 
// Parse IPv6 address.  Many forms.
488
 
// The basic form is a sequence of eight colon-separated
489
 
// 16-bit hex numbers separated by colons,
490
 
// as in 0123:4567:89ab:cdef:0123:4567:89ab:cdef.
491
 
// Two exceptions:
492
 
//      * A run of zeros can be replaced with "::".
493
 
//      * The last 32 bits can be in IPv4 form.
494
 
// Thus, ::ffff:1.2.3.4 is the IPv4 address 1.2.3.4.
495
 
func parseIPv6(s string) IP {
496
 
        p := make(IP, IPv6len)
 
486
// parseIPv6 parses s as a literal IPv6 address described in RFC 4291
 
487
// and RFC 5952.  It can also parse a literal scoped IPv6 address with
 
488
// zone identifier which is described in RFC 4007 when zoneAllowed is
 
489
// true.
 
490
func parseIPv6(s string, zoneAllowed bool) (ip IP, zone string) {
 
491
        ip = make(IP, IPv6len)
497
492
        ellipsis := -1 // position of ellipsis in p
498
493
        i := 0         // index in string s
499
494
 
 
495
        if zoneAllowed {
 
496
                s, zone = splitHostZone(s)
 
497
        }
 
498
 
500
499
        // Might have leading ellipsis
501
500
        if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
502
501
                ellipsis = 0
503
502
                i = 2
504
503
                // Might be only ellipsis
505
504
                if i == len(s) {
506
 
                        return p
 
505
                        return ip, zone
507
506
                }
508
507
        }
509
508
 
513
512
                // Hex number.
514
513
                n, i1, ok := xtoi(s, i)
515
514
                if !ok || n > 0xFFFF {
516
 
                        return nil
 
515
                        return nil, zone
517
516
                }
518
517
 
519
518
                // If followed by dot, might be in trailing IPv4.
520
519
                if i1 < len(s) && s[i1] == '.' {
521
520
                        if ellipsis < 0 && j != IPv6len-IPv4len {
522
521
                                // Not the right place.
523
 
                                return nil
 
522
                                return nil, zone
524
523
                        }
525
524
                        if j+IPv4len > IPv6len {
526
525
                                // Not enough room.
527
 
                                return nil
528
 
                        }
529
 
                        p4 := parseIPv4(s[i:])
530
 
                        if p4 == nil {
531
 
                                return nil
532
 
                        }
533
 
                        p[j] = p4[12]
534
 
                        p[j+1] = p4[13]
535
 
                        p[j+2] = p4[14]
536
 
                        p[j+3] = p4[15]
 
526
                                return nil, zone
 
527
                        }
 
528
                        ip4 := parseIPv4(s[i:])
 
529
                        if ip4 == nil {
 
530
                                return nil, zone
 
531
                        }
 
532
                        ip[j] = ip4[12]
 
533
                        ip[j+1] = ip4[13]
 
534
                        ip[j+2] = ip4[14]
 
535
                        ip[j+3] = ip4[15]
537
536
                        i = len(s)
538
537
                        j += IPv4len
539
538
                        break
540
539
                }
541
540
 
542
541
                // Save this 16-bit chunk.
543
 
                p[j] = byte(n >> 8)
544
 
                p[j+1] = byte(n)
 
542
                ip[j] = byte(n >> 8)
 
543
                ip[j+1] = byte(n)
545
544
                j += 2
546
545
 
547
546
                // Stop at end of string.
552
551
 
553
552
                // Otherwise must be followed by colon and more.
554
553
                if s[i] != ':' || i+1 == len(s) {
555
 
                        return nil
 
554
                        return nil, zone
556
555
                }
557
556
                i++
558
557
 
559
558
                // Look for ellipsis.
560
559
                if s[i] == ':' {
561
560
                        if ellipsis >= 0 { // already have one
562
 
                                return nil
 
561
                                return nil, zone
563
562
                        }
564
563
                        ellipsis = j
565
564
                        if i++; i == len(s) { // can be at end
570
569
 
571
570
        // Must have used entire string.
572
571
        if i != len(s) {
573
 
                return nil
 
572
                return nil, zone
574
573
        }
575
574
 
576
575
        // If didn't parse enough, expand ellipsis.
577
576
        if j < IPv6len {
578
577
                if ellipsis < 0 {
579
 
                        return nil
 
578
                        return nil, zone
580
579
                }
581
580
                n := IPv6len - j
582
581
                for k := j - 1; k >= ellipsis; k-- {
583
 
                        p[k+n] = p[k]
 
582
                        ip[k+n] = ip[k]
584
583
                }
585
584
                for k := ellipsis + n - 1; k >= ellipsis; k-- {
586
 
                        p[k] = 0
 
585
                        ip[k] = 0
587
586
                }
588
587
        }
589
 
        return p
 
588
        return ip, zone
590
589
}
591
590
 
592
591
// A ParseError represents a malformed text string and the type of string that was expected.
599
598
        return "invalid " + e.Type + ": " + e.Text
600
599
}
601
600
 
602
 
func parseIP(s string) IP {
603
 
        if p := parseIPv4(s); p != nil {
604
 
                return p
605
 
        }
606
 
        if p := parseIPv6(s); p != nil {
607
 
                return p
608
 
        }
609
 
        return nil
610
 
}
611
 
 
612
601
// ParseIP parses s as an IP address, returning the result.
613
602
// The string s can be in dotted decimal ("74.125.19.99")
614
603
// or IPv6 ("2001:4860:0:2001::68") form.
615
604
// If s is not a valid textual representation of an IP address,
616
605
// ParseIP returns nil.
617
606
func ParseIP(s string) IP {
618
 
        if p := parseIPv4(s); p != nil {
619
 
                return p
 
607
        if ip := parseIPv4(s); ip != nil {
 
608
                return ip
620
609
        }
621
 
        return parseIPv6(s)
 
610
        ip, _ := parseIPv6(s, false)
 
611
        return ip
622
612
}
623
613
 
624
614
// ParseCIDR parses s as a CIDR notation IP address and mask,
633
623
        if i < 0 {
634
624
                return nil, nil, &ParseError{"CIDR address", s}
635
625
        }
636
 
        ipstr, maskstr := s[:i], s[i+1:]
 
626
        addr, mask := s[:i], s[i+1:]
637
627
        iplen := IPv4len
638
 
        ip := parseIPv4(ipstr)
 
628
        ip := parseIPv4(addr)
639
629
        if ip == nil {
640
630
                iplen = IPv6len
641
 
                ip = parseIPv6(ipstr)
 
631
                ip, _ = parseIPv6(addr, false)
642
632
        }
643
 
        n, i, ok := dtoi(maskstr, 0)
644
 
        if ip == nil || !ok || i != len(maskstr) || n < 0 || n > 8*iplen {
 
633
        n, i, ok := dtoi(mask, 0)
 
634
        if ip == nil || !ok || i != len(mask) || n < 0 || n > 8*iplen {
645
635
                return nil, nil, &ParseError{"CIDR address", s}
646
636
        }
647
637
        m := CIDRMask(n, 8*iplen)
648
 
        return ip, &IPNet{ip.Mask(m), m}, nil
 
638
        return ip, &IPNet{IP: ip.Mask(m), Mask: m}, nil
649
639
}