aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/apparentlymart
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/apparentlymart')
-rw-r--r--vendor/github.com/apparentlymart/go-cidr/LICENSE19
-rw-r--r--vendor/github.com/apparentlymart/go-cidr/cidr/cidr.go112
-rw-r--r--vendor/github.com/apparentlymart/go-cidr/cidr/wrangling.go38
3 files changed, 169 insertions, 0 deletions
diff --git a/vendor/github.com/apparentlymart/go-cidr/LICENSE b/vendor/github.com/apparentlymart/go-cidr/LICENSE
new file mode 100644
index 0000000..2125378
--- /dev/null
+++ b/vendor/github.com/apparentlymart/go-cidr/LICENSE
@@ -0,0 +1,19 @@
1Copyright (c) 2015 Martin Atkins
2
3Permission is hereby granted, free of charge, to any person obtaining a copy
4of this software and associated documentation files (the "Software"), to deal
5in the Software without restriction, including without limitation the rights
6to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7copies of the Software, and to permit persons to whom the Software is
8furnished to do so, subject to the following conditions:
9
10The above copyright notice and this permission notice shall be included in
11all copies or substantial portions of the Software.
12
13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19THE SOFTWARE.
diff --git a/vendor/github.com/apparentlymart/go-cidr/cidr/cidr.go b/vendor/github.com/apparentlymart/go-cidr/cidr/cidr.go
new file mode 100644
index 0000000..a31cdec
--- /dev/null
+++ b/vendor/github.com/apparentlymart/go-cidr/cidr/cidr.go
@@ -0,0 +1,112 @@
1// Package cidr is a collection of assorted utilities for computing
2// network and host addresses within network ranges.
3//
4// It expects a CIDR-type address structure where addresses are divided into
5// some number of prefix bits representing the network and then the remaining
6// suffix bits represent the host.
7//
8// For example, it can help to calculate addresses for sub-networks of a
9// parent network, or to calculate host addresses within a particular prefix.
10//
11// At present this package is prioritizing simplicity of implementation and
12// de-prioritizing speed and memory usage. Thus caution is advised before
13// using this package in performance-critical applications or hot codepaths.
14// Patches to improve the speed and memory usage may be accepted as long as
15// they do not result in a significant increase in code complexity.
16package cidr
17
18import (
19 "fmt"
20 "math/big"
21 "net"
22)
23
24// Subnet takes a parent CIDR range and creates a subnet within it
25// with the given number of additional prefix bits and the given
26// network number.
27//
28// For example, 10.3.0.0/16, extended by 8 bits, with a network number
29// of 5, becomes 10.3.5.0/24 .
30func Subnet(base *net.IPNet, newBits int, num int) (*net.IPNet, error) {
31 ip := base.IP
32 mask := base.Mask
33
34 parentLen, addrLen := mask.Size()
35 newPrefixLen := parentLen + newBits
36
37 if newPrefixLen > addrLen {
38 return nil, fmt.Errorf("insufficient address space to extend prefix of %d by %d", parentLen, newBits)
39 }
40
41 maxNetNum := uint64(1<<uint64(newBits)) - 1
42 if uint64(num) > maxNetNum {
43 return nil, fmt.Errorf("prefix extension of %d does not accommodate a subnet numbered %d", newBits, num)
44 }
45
46 return &net.IPNet{
47 IP: insertNumIntoIP(ip, num, newPrefixLen),
48 Mask: net.CIDRMask(newPrefixLen, addrLen),
49 }, nil
50}
51
52// Host takes a parent CIDR range and turns it into a host IP address with
53// the given host number.
54//
55// For example, 10.3.0.0/16 with a host number of 2 gives 10.3.0.2.
56func Host(base *net.IPNet, num int) (net.IP, error) {
57 ip := base.IP
58 mask := base.Mask
59
60 parentLen, addrLen := mask.Size()
61 hostLen := addrLen - parentLen
62
63 maxHostNum := uint64(1<<uint64(hostLen)) - 1
64
65 numUint64 := uint64(num)
66 if num < 0 {
67 numUint64 = uint64(-num) - 1
68 num = int(maxHostNum - numUint64)
69 }
70
71 if numUint64 > maxHostNum {
72 return nil, fmt.Errorf("prefix of %d does not accommodate a host numbered %d", parentLen, num)
73 }
74
75 return insertNumIntoIP(ip, num, 32), nil
76}
77
78// AddressRange returns the first and last addresses in the given CIDR range.
79func AddressRange(network *net.IPNet) (net.IP, net.IP) {
80 // the first IP is easy
81 firstIP := network.IP
82
83 // the last IP is the network address OR NOT the mask address
84 prefixLen, bits := network.Mask.Size()
85 if prefixLen == bits {
86 // Easy!
87 // But make sure that our two slices are distinct, since they
88 // would be in all other cases.
89 lastIP := make([]byte, len(firstIP))
90 copy(lastIP, firstIP)
91 return firstIP, lastIP
92 }
93
94 firstIPInt, bits := ipToInt(firstIP)
95 hostLen := uint(bits) - uint(prefixLen)
96 lastIPInt := big.NewInt(1)
97 lastIPInt.Lsh(lastIPInt, hostLen)
98 lastIPInt.Sub(lastIPInt, big.NewInt(1))
99 lastIPInt.Or(lastIPInt, firstIPInt)
100
101 return firstIP, intToIP(lastIPInt, bits)
102}
103
104// AddressCount returns the number of distinct host addresses within the given
105// CIDR range.
106//
107// Since the result is a uint64, this function returns meaningful information
108// only for IPv4 ranges and IPv6 ranges with a prefix size of at least 65.
109func AddressCount(network *net.IPNet) uint64 {
110 prefixLen, bits := network.Mask.Size()
111 return 1 << (uint64(bits) - uint64(prefixLen))
112}
diff --git a/vendor/github.com/apparentlymart/go-cidr/cidr/wrangling.go b/vendor/github.com/apparentlymart/go-cidr/cidr/wrangling.go
new file mode 100644
index 0000000..861a5f6
--- /dev/null
+++ b/vendor/github.com/apparentlymart/go-cidr/cidr/wrangling.go
@@ -0,0 +1,38 @@
1package cidr
2
3import (
4 "fmt"
5 "math/big"
6 "net"
7)
8
9func ipToInt(ip net.IP) (*big.Int, int) {
10 val := &big.Int{}
11 val.SetBytes([]byte(ip))
12 if len(ip) == net.IPv4len {
13 return val, 32
14 } else if len(ip) == net.IPv6len {
15 return val, 128
16 } else {
17 panic(fmt.Errorf("Unsupported address length %d", len(ip)))
18 }
19}
20
21func intToIP(ipInt *big.Int, bits int) net.IP {
22 ipBytes := ipInt.Bytes()
23 ret := make([]byte, bits/8)
24 // Pack our IP bytes into the end of the return array,
25 // since big.Int.Bytes() removes front zero padding.
26 for i := 1; i <= len(ipBytes); i++ {
27 ret[len(ret)-i] = ipBytes[len(ipBytes)-i]
28 }
29 return net.IP(ret)
30}
31
32func insertNumIntoIP(ip net.IP, num int, prefixLen int) net.IP {
33 ipInt, totalBits := ipToInt(ip)
34 bigNum := big.NewInt(int64(num))
35 bigNum.Lsh(bigNum, uint(totalBits-prefixLen))
36 ipInt.Or(ipInt, bigNum)
37 return intToIP(ipInt, totalBits)
38}