From 3ffcebb4824b5ae2a482a1ff9947275947d3410a Mon Sep 17 00:00:00 2001 From: Travis Hegner Date: Tue, 13 Feb 2018 11:32:07 -0500 Subject: [PATCH] fix some bugs in new random address with exclusions... added some tests --- iputil.go | 43 ++++++++++++++++++- iputil6_test.go | 102 ++++++++++++++++++++++++++++++++++++++++++++ iputil_test.go | 109 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 253 insertions(+), 1 deletion(-) diff --git a/iputil.go b/iputil.go index 2ff604e..d4c3c4b 100644 --- a/iputil.go +++ b/iputil.go @@ -104,12 +104,18 @@ func RandAddr(n *net.IPNet) net.IP { func RandAddrWithExclude(n *net.IPNet, xf, xl int) net.IP { f := IPAdd(FirstAddr(n), xf) l := IPAdd(LastAddr(n), -xl) - d := IPDiff(f, l) + d := IPDiff(l, f) + if d <= 0 { + return nil + } return IPAdd(f, rand.Intn(d)) } //IPDiff returns the difference between ip and ip2 +//nil is treated as the zero address func IPDiff(ip, ip2 net.IP) int { + ip, ip2 = makeNilZero(ip, ip2) + ip, ip2 = makeSameLength(ip, ip2) o := 1 if IPBefore(ip, ip2) { ip, ip2 = ip2, ip @@ -126,6 +132,8 @@ func IPDiff(ip, ip2 net.IP) int { //IPDiff returns true if ip < ip2 func IPBefore(ip, ip2 net.IP) bool { + ip, ip2 = makeNilZero(ip, ip2) + ip, ip2 = makeSameLength(ip, ip2) for i := range ip { if int(ip[i]) < int(ip2[i]) { return true @@ -134,6 +142,39 @@ func IPBefore(ip, ip2 net.IP) bool { return false } +func makeNilZero(ip, ip2 net.IP) (net.IP, net.IP) { + if ip == nil { + ip = net.IP{0, 0, 0, 0} + } + if ip2 == nil { + ip2 = net.IP{0, 0, 0, 0} + } + + return ip, ip2 +} + +func makeSameLength(ip, ip2 net.IP) (net.IP, net.IP) { + var ph1 []byte + var ph2 []byte + + if len(ip) < len(ip2) { + ph1 = append(ph1, ip2[:len(ip2)-len(ip)]...) + ph1 = append(ph1, ip[:]...) + ph2 = ip2 + } + if len(ip2) < len(ip) { + ph2 = append(ph2, ip[:len(ip)-len(ip2)]...) + ph2 = append(ph2, ip2...) + ph1 = ip + } + if len(ip) == len(ip2) { + ph1 = ip + ph2 = ip2 + } + + return ph1, ph2 +} + //IPAdd adds an offset to an IP func IPAdd(ip net.IP, offset int) net.IP { rip := make([]byte, len(ip)) // return ip diff --git a/iputil6_test.go b/iputil6_test.go index 28e330b..3648bac 100644 --- a/iputil6_test.go +++ b/iputil6_test.go @@ -219,3 +219,105 @@ func TestIPSubCarryover26(t *testing.T) { t.Errorf("%v should equal %v", rip.String(), r.String()) } } + +func TestIPBefore6(t *testing.T) { + ip := net.ParseIP("fe80::1") + ip2 := net.ParseIP("fe80::2") + ret := IPBefore(ip, ip2) + if !ret { + t.Errorf("%v should be before %v", ip.String(), ip2.String()) + } +} + +func TestIPNotBefore6(t *testing.T) { + ip := net.ParseIP("fe80::2") + ip2 := net.ParseIP("fe80::1") + ret := IPBefore(ip, ip2) + if ret { + t.Errorf("%v should not be before %v", ip.String(), ip2.String()) + } +} + +func TestIPBeforeEqual6(t *testing.T) { + ip := net.ParseIP("fe80::1") + ip2 := net.ParseIP("fe80::1") + ret := IPBefore(ip, ip2) + if ret { + t.Errorf("%v should not be before %v", ip.String(), ip2.String()) + } +} + +func TestIPBeforeNilFirst6(t *testing.T) { + ip2 := net.ParseIP("fe80::1") + ret := IPBefore(nil, ip2) + if !ret { + t.Errorf("nil should be before %v", ip2.String()) + } +} + +func TestIPBeforeNilSecond6(t *testing.T) { + ip := net.ParseIP("fe80::1") + ret := IPBefore(ip, nil) + if ret { + t.Errorf("%v should not be before nil", ip.String()) + } +} + +func TestIPDiffNeg6(t *testing.T) { + ip := net.ParseIP("fe80::1") + ip2 := net.ParseIP("fe80::2") + ret := IPDiff(ip, ip2) + if ret != -1 { + t.Errorf("%v minus %v should be -1", ip, ip2) + } +} + +func TestIPDiffPos6(t *testing.T) { + ip := net.ParseIP("fe80::2") + ip2 := net.ParseIP("fe80::1") + ret := IPDiff(ip, ip2) + if ret != 1 { + t.Errorf("%v minus %v should be 1", ip, ip2) + } +} + +func TestIPDiffEq6(t *testing.T) { + ip := net.ParseIP("fe80::1") + ip2 := net.ParseIP("fe80::1") + ret := IPDiff(ip, ip2) + if ret != 0 { + t.Errorf("%v minus %v should be 0", ip, ip2) + } +} + +func TestRandomAddrWithExclude6(t *testing.T) { + _, sn, _ := net.ParseCIDR("fe80::/120") + ip := RandAddrWithExclude(sn, 0, 0) + if !sn.Contains(ip) { + t.Errorf("%v should be an IP in %v", ip.String(), sn.String()) + } +} + +func TestRandomAddrWithBadExcludeFirst6(t *testing.T) { + _, sn, _ := net.ParseCIDR("fe80::/120") + ip := RandAddrWithExclude(sn, 300, 0) + if ip != nil { + t.Errorf("exclusions that land outside the subnet's range should return a nil IP") + } +} + +func TestRandomAddrWithBadExcludeSecond6(t *testing.T) { + _, sn, _ := net.ParseCIDR("fe80::/120") + ip := RandAddrWithExclude(sn, 0, 300) + if ip != nil { + t.Errorf("exclusions that land outside the subnet's range should return a nil IP") + } +} + +func TestRandomAddrWithBadExcludeBoth6(t *testing.T) { + _, sn, _ := net.ParseCIDR("fe80::/120") + ip := RandAddrWithExclude(sn, 150, 150) + if ip != nil { + t.Errorf("exclusions that land outside the subnet's range should return a nil IP") + } +} diff --git a/iputil_test.go b/iputil_test.go index f5b3190..929027f 100644 --- a/iputil_test.go +++ b/iputil_test.go @@ -258,3 +258,112 @@ func TestIPSubCarryover2(t *testing.T) { t.Errorf("%v should equal %v", rip.String(), r.String()) } } + +func TestIPBefore(t *testing.T) { + ip := net.ParseIP("10.1.0.1") + ip2 := net.ParseIP("10.1.0.2") + ret := IPBefore(ip, ip2) + if !ret { + t.Errorf("%v should be before %v", ip.String(), ip2.String()) + } +} + +func TestIPNotBefore(t *testing.T) { + ip := net.ParseIP("10.1.0.2") + ip2 := net.ParseIP("10.1.0.1") + ret := IPBefore(ip, ip2) + if ret { + t.Errorf("%v should not be before %v", ip.String(), ip2.String()) + } +} + +func TestIPBeforeEqual(t *testing.T) { + ip := net.ParseIP("10.1.0.1") + ip2 := net.ParseIP("10.1.0.1") + ret := IPBefore(ip, ip2) + if ret { + t.Errorf("%v should not be before %v", ip.String(), ip2.String()) + } +} + +func TestIPBeforeNilFirst(t *testing.T) { + ip2 := net.ParseIP("10.1.0.1") + ret := IPBefore(nil, ip2) + if !ret { + t.Errorf("nil should be before %v", ip2.String()) + } +} + +func TestIPBeforeNilSecond(t *testing.T) { + ip := net.ParseIP("10.1.0.1") + ret := IPBefore(ip, nil) + if ret { + t.Errorf("%v should not be before nil", ip.String()) + } +} + +func TestIPBeforeNilBoth(t *testing.T) { + ret := IPBefore(nil, nil) + if ret { + t.Errorf("nil should not be before nil") + } +} + +func TestIPDiffNeg(t *testing.T) { + ip := net.ParseIP("10.1.0.1") + ip2 := net.ParseIP("10.1.0.2") + ret := IPDiff(ip, ip2) + if ret != -1 { + t.Errorf("%v minus %v should be -1", ip, ip2) + } +} + +func TestIPDiffPos(t *testing.T) { + ip := net.ParseIP("10.1.0.2") + ip2 := net.ParseIP("10.1.0.1") + ret := IPDiff(ip, ip2) + if ret != 1 { + t.Errorf("%v minus %v should be 1", ip, ip2) + } +} + +func TestIPDiffEq(t *testing.T) { + ip := net.ParseIP("10.1.0.1") + ip2 := net.ParseIP("10.1.0.1") + ret := IPDiff(ip, ip2) + if ret != 0 { + t.Errorf("%v minus %v should be 0", ip, ip2) + } +} + +func TestRandomAddrWithExclude(t *testing.T) { + _, sn, _ := net.ParseCIDR("10.1.0.0/24") + ip := RandAddrWithExclude(sn, 0, 0) + if !sn.Contains(ip) { + t.Errorf("%v should be an IP in %v", ip.String(), sn.String()) + } +} + +func TestRandomAddrWithBadExcludeFirst(t *testing.T) { + _, sn, _ := net.ParseCIDR("10.1.0.0/24") + ip := RandAddrWithExclude(sn, 300, 0) + if ip != nil { + t.Errorf("exclusions that land outside the subnet's range should return a nil IP") + } +} + +func TestRandomAddrWithBadExcludeSecond(t *testing.T) { + _, sn, _ := net.ParseCIDR("10.1.0.0/24") + ip := RandAddrWithExclude(sn, 0, 300) + if ip != nil { + t.Errorf("exclusions that land outside the subnet's range should return a nil IP") + } +} + +func TestRandomAddrWithBadExcludeBoth(t *testing.T) { + _, sn, _ := net.ParseCIDR("10.1.0.0/24") + ip := RandAddrWithExclude(sn, 150, 150) + if ip != nil { + t.Errorf("exclusions that land outside the subnet's range should return a nil IP") + } +}