Add the range.CIDRs functions
This commit is contained in:
1 parent
6062627582
commit
2266868648
2 files changed
+56
No files matched your search
@@ -73,6 +73,40 @@ type CIDR struct {
|
||||
PrefixLen int
|
||||
}
|
||||
|
||||
// CIDRs returns a list of CIDR-aligned ranges which cover this range.
|
||||
func (r Range) CIDRs() []CIDR {
|
||||
const (
|
||||
fullMask = ^Address(0)
|
||||
cidrMaxPrefixLen = 32
|
||||
)
|
||||
var cidrs []CIDR
|
||||
|
||||
for start, end := r.Start, r.End-1; end >= start; {
|
||||
mask, prefixLen := fullMask, cidrMaxPrefixLen
|
||||
// Find the smallest mask which would cover some part of [start;end].
|
||||
// Once we found such, apply it by OR'ing
|
||||
for mask > 0 {
|
||||
tmpMask := mask << 1
|
||||
// Check whether mask neither too short nor too long
|
||||
if (start&tmpMask) != start || (start|^tmpMask) > end {
|
||||
break
|
||||
}
|
||||
mask = tmpMask
|
||||
prefixLen--
|
||||
}
|
||||
cidrs = append(cidrs, CIDR{start, prefixLen})
|
||||
// Apply mask
|
||||
start |= ^mask
|
||||
// Check for overflow
|
||||
if start+1 < start {
|
||||
break
|
||||
}
|
||||
start++
|
||||
}
|
||||
|
||||
return cidrs
|
||||
}
|
||||
|
||||
func ParseIP(s string) (Address, error) {
|
||||
if ip := net.ParseIP(s); ip != nil {
|
||||
return FromIP4(ip), nil
|
||||
|
||||
@@ -39,3 +39,25 @@ func TestBiggestPow2AlignedRange(t *testing.T) {
|
||||
}
|
||||
require.NoError(t, quick.Check(prop, &quick.Config{MaxCount: 1000000}))
|
||||
}
|
||||
|
||||
func ip(s string) Address {
|
||||
addr, _ := ParseIP(s)
|
||||
return addr
|
||||
}
|
||||
|
||||
func cidr(s string) CIDR {
|
||||
c, err := ParseCIDR(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func TestCIDRs(t *testing.T) {
|
||||
start := ip("10.0.0.1")
|
||||
end := ip("10.0.0.9")
|
||||
r := NewRange(start, Subtract(end, start))
|
||||
require.Equal(t,
|
||||
[]CIDR{cidr("10.0.0.1/32"), cidr("10.0.0.2/31"), cidr("10.0.0.4/30"), cidr("10.0.0.8/32")},
|
||||
r.CIDRs())
|
||||
}
|
||||
Reference in new issue
Block a user