aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/apparentlymart/go-cidr/cidr/cidr.go
diff options
context:
space:
mode:
authorappilon <apilon@hashicorp.com>2019-02-27 16:43:31 -0500
committerGitHub <noreply@github.com>2019-02-27 16:43:31 -0500
commit844b5a68d8af4791755b8f0ad293cc99f5959183 (patch)
tree255c250a5c9d4801c74092d33b7337d8c14438ff /vendor/github.com/apparentlymart/go-cidr/cidr/cidr.go
parent303b299eeb6b06e939e35905e4b34cb410dd9dc3 (diff)
parent15c0b25d011f37e7c20aeca9eaf461f78285b8d9 (diff)
downloadterraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.tar.gz
terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.tar.zst
terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.zip
Merge pull request #27 from terraform-providers/go-modules-2019-02-22
[MODULES] Switch to Go Modules
Diffstat (limited to 'vendor/github.com/apparentlymart/go-cidr/cidr/cidr.go')
-rw-r--r--vendor/github.com/apparentlymart/go-cidr/cidr/cidr.go102
1 files changed, 100 insertions, 2 deletions
diff --git a/vendor/github.com/apparentlymart/go-cidr/cidr/cidr.go b/vendor/github.com/apparentlymart/go-cidr/cidr/cidr.go
index a31cdec..7534473 100644
--- a/vendor/github.com/apparentlymart/go-cidr/cidr/cidr.go
+++ b/vendor/github.com/apparentlymart/go-cidr/cidr/cidr.go
@@ -71,8 +71,13 @@ func Host(base *net.IPNet, num int) (net.IP, error) {
71 if numUint64 > maxHostNum { 71 if numUint64 > maxHostNum {
72 return nil, fmt.Errorf("prefix of %d does not accommodate a host numbered %d", parentLen, num) 72 return nil, fmt.Errorf("prefix of %d does not accommodate a host numbered %d", parentLen, num)
73 } 73 }
74 74 var bitlength int
75 return insertNumIntoIP(ip, num, 32), nil 75 if ip.To4() != nil {
76 bitlength = 32
77 } else {
78 bitlength = 128
79 }
80 return insertNumIntoIP(ip, num, bitlength), nil
76} 81}
77 82
78// AddressRange returns the first and last addresses in the given CIDR range. 83// AddressRange returns the first and last addresses in the given CIDR range.
@@ -110,3 +115,96 @@ func AddressCount(network *net.IPNet) uint64 {
110 prefixLen, bits := network.Mask.Size() 115 prefixLen, bits := network.Mask.Size()
111 return 1 << (uint64(bits) - uint64(prefixLen)) 116 return 1 << (uint64(bits) - uint64(prefixLen))
112} 117}
118
119//VerifyNoOverlap takes a list subnets and supernet (CIDRBlock) and verifies
120//none of the subnets overlap and all subnets are in the supernet
121//it returns an error if any of those conditions are not satisfied
122func VerifyNoOverlap(subnets []*net.IPNet, CIDRBlock *net.IPNet) error {
123 firstLastIP := make([][]net.IP, len(subnets))
124 for i, s := range subnets {
125 first, last := AddressRange(s)
126 firstLastIP[i] = []net.IP{first, last}
127 }
128 for i, s := range subnets {
129 if !CIDRBlock.Contains(firstLastIP[i][0]) || !CIDRBlock.Contains(firstLastIP[i][1]) {
130 return fmt.Errorf("%s does not fully contain %s", CIDRBlock.String(), s.String())
131 }
132 for j := i + 1; j < len(subnets); j++ {
133 first := firstLastIP[j][0]
134 last := firstLastIP[j][1]
135 if s.Contains(first) || s.Contains(last) {
136 return fmt.Errorf("%s overlaps with %s", subnets[j].String(), s.String())
137 }
138 }
139 }
140 return nil
141}
142
143// PreviousSubnet returns the subnet of the desired mask in the IP space
144// just lower than the start of IPNet provided. If the IP space rolls over
145// then the second return value is true
146func PreviousSubnet(network *net.IPNet, prefixLen int) (*net.IPNet, bool) {
147 startIP := checkIPv4(network.IP)
148 previousIP := make(net.IP, len(startIP))
149 copy(previousIP, startIP)
150 cMask := net.CIDRMask(prefixLen, 8*len(previousIP))
151 previousIP = Dec(previousIP)
152 previous := &net.IPNet{IP: previousIP.Mask(cMask), Mask: cMask}
153 if startIP.Equal(net.IPv4zero) || startIP.Equal(net.IPv6zero) {
154 return previous, true
155 }
156 return previous, false
157}
158
159// NextSubnet returns the next available subnet of the desired mask size
160// starting for the maximum IP of the offset subnet
161// If the IP exceeds the maxium IP then the second return value is true
162func NextSubnet(network *net.IPNet, prefixLen int) (*net.IPNet, bool) {
163 _, currentLast := AddressRange(network)
164 mask := net.CIDRMask(prefixLen, 8*len(currentLast))
165 currentSubnet := &net.IPNet{IP: currentLast.Mask(mask), Mask: mask}
166 _, last := AddressRange(currentSubnet)
167 last = Inc(last)
168 next := &net.IPNet{IP: last.Mask(mask), Mask: mask}
169 if last.Equal(net.IPv4zero) || last.Equal(net.IPv6zero) {
170 return next, true
171 }
172 return next, false
173}
174
175//Inc increases the IP by one this returns a new []byte for the IP
176func Inc(IP net.IP) net.IP {
177 IP = checkIPv4(IP)
178 incIP := make([]byte, len(IP))
179 copy(incIP, IP)
180 for j := len(incIP) - 1; j >= 0; j-- {
181 incIP[j]++
182 if incIP[j] > 0 {
183 break
184 }
185 }
186 return incIP
187}
188
189//Dec decreases the IP by one this returns a new []byte for the IP
190func Dec(IP net.IP) net.IP {
191 IP = checkIPv4(IP)
192 decIP := make([]byte, len(IP))
193 copy(decIP, IP)
194 decIP = checkIPv4(decIP)
195 for j := len(decIP) - 1; j >= 0; j-- {
196 decIP[j]--
197 if decIP[j] < 255 {
198 break
199 }
200 }
201 return decIP
202}
203
204func checkIPv4(ip net.IP) net.IP {
205 // Go for some reason allocs IPv6len for IPv4 so we have to correct it
206 if v4 := ip.To4(); v4 != nil {
207 return v4
208 }
209 return ip
210}