Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit 3e50d74

Browse files
authored
Merge pull request #3 from ecbaldwin/parse-net-utility
Add a parse net utility that doesn't allow non zero host part
2 parents ffdbb9a + c0d1cdf commit 3e50d74

File tree

3 files changed

+76
-34
lines changed

3 files changed

+76
-34
lines changed

ipset_test.go

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ var (
1313
Eights = net.ParseIP("8.8.8.8").To4()
1414
Nines = net.ParseIP("9.9.9.9").To4()
1515

16-
_, Ten24, _ = net.ParseCIDR("10.0.0.0/24")
17-
_, Ten24128, _ = net.ParseCIDR("10.0.0.128/25")
16+
Ten24, _ = ParseNet("10.0.0.0/24")
17+
Ten24128, _ = ParseNet("10.0.0.128/25")
1818
Ten24Router = net.ParseIP("10.0.0.1").To4()
1919
Ten24Broadcast = net.ParseIP("10.0.0.255").To4()
2020

21-
_, V6Net1, _ = net.ParseCIDR("2001:db8:1234:abcd::/64")
22-
_, V6Net2, _ = net.ParseCIDR("2001:db8:abcd:1234::/64")
21+
V6Net1, _ = ParseNet("2001:db8:1234:abcd::/64")
22+
V6Net2, _ = ParseNet("2001:db8:abcd:1234::/64")
2323
V6Net1Router = net.ParseIP("2001:db8:1234:abcd::1")
2424

2525
V6NetSize = big.NewInt(0).Lsh(big.NewInt(1), 64) // 2**64 or 18446744073709551616
@@ -28,17 +28,17 @@ var (
2828
func TestNetDifference(t *testing.T) {
2929
diff := netDifference(Ten24, Ten24128)
3030

31-
_, cidr, _ := net.ParseCIDR("10.0.0.0/25")
31+
cidr, _ := ParseNet("10.0.0.0/25")
3232
assert.Equal(t, []*net.IPNet{cidr}, diff)
3333

34-
_, cidr, _ = net.ParseCIDR("10.0.0.120/29")
34+
cidr, _ = ParseNet("10.0.0.120/29")
3535
diff = netDifference(Ten24, cidr)
3636

37-
_, cidr1, _ := net.ParseCIDR("10.0.0.128/25")
38-
_, cidr2, _ := net.ParseCIDR("10.0.0.0/26")
39-
_, cidr3, _ := net.ParseCIDR("10.0.0.64/27")
40-
_, cidr4, _ := net.ParseCIDR("10.0.0.96/28")
41-
_, cidr5, _ := net.ParseCIDR("10.0.0.112/29")
37+
cidr1, _ := ParseNet("10.0.0.128/25")
38+
cidr2, _ := ParseNet("10.0.0.0/26")
39+
cidr3, _ := ParseNet("10.0.0.64/27")
40+
cidr4, _ := ParseNet("10.0.0.96/28")
41+
cidr5, _ := ParseNet("10.0.0.112/29")
4242
assert.Equal(t, []*net.IPNet{cidr1, cidr2, cidr3, cidr4, cidr5}, diff)
4343
}
4444

@@ -111,30 +111,30 @@ func TestIPSetInsertSequential(t *testing.T) {
111111
assert.Equal(t, 1, set.tree.numNodes())
112112
assert.Equal(t, big.NewInt(4), set.tree.size())
113113

114-
_, cidr, _ := net.ParseCIDR("192.168.1.0/30")
114+
cidr, _ := ParseNet("192.168.1.0/30")
115115
assert.True(t, set.ContainsNet(cidr))
116116

117-
_, cidr, _ = net.ParseCIDR("192.168.1.4/31")
117+
cidr, _ = ParseNet("192.168.1.4/31")
118118
set.InsertNet(cidr)
119119
assert.Equal(t, 2, set.tree.numNodes())
120120
assert.True(t, set.ContainsNet(cidr))
121121

122-
_, cidr, _ = net.ParseCIDR("192.168.1.6/31")
122+
cidr, _ = ParseNet("192.168.1.6/31")
123123
set.InsertNet(cidr)
124124
assert.Equal(t, 1, set.tree.numNodes())
125125
assert.True(t, set.ContainsNet(cidr))
126126

127-
_, cidr, _ = net.ParseCIDR("192.168.1.6/31")
127+
cidr, _ = ParseNet("192.168.1.6/31")
128128
set.InsertNet(cidr)
129129
assert.Equal(t, 1, set.tree.numNodes())
130130
assert.True(t, set.ContainsNet(cidr))
131131

132-
_, cidr, _ = net.ParseCIDR("192.168.0.240/29")
132+
cidr, _ = ParseNet("192.168.0.240/29")
133133
set.InsertNet(cidr)
134134
assert.Equal(t, 2, set.tree.numNodes())
135135
assert.True(t, set.ContainsNet(cidr))
136136

137-
_, cidr, _ = net.ParseCIDR("192.168.0.248/29")
137+
cidr, _ = ParseNet("192.168.0.248/29")
138138
set.InsertNet(cidr)
139139
assert.Equal(t, 2, set.tree.numNodes())
140140
assert.True(t, set.ContainsNet(cidr))
@@ -150,7 +150,7 @@ func TestIPSetRemove(t *testing.T) {
150150
assert.Equal(t, big.NewInt(128), set.tree.size())
151151
assert.False(t, set.ContainsNet(Ten24))
152152
assert.False(t, set.ContainsNet(Ten24128))
153-
_, cidr, _ := net.ParseCIDR("10.0.0.0/25")
153+
cidr, _ := ParseNet("10.0.0.0/25")
154154
assert.True(t, set.ContainsNet(cidr))
155155

156156
set.Remove(Ten24Router)
@@ -172,7 +172,7 @@ func TestIPSetRemoveNetworkBroadcast(t *testing.T) {
172172
assert.False(t, set.Contains(Ten24Broadcast))
173173
assert.False(t, set.Contains(Ten24.IP))
174174

175-
_, cidr, _ := net.ParseCIDR("10.0.0.128/26")
175+
cidr, _ := ParseNet("10.0.0.128/26")
176176
assert.True(t, set.ContainsNet(cidr))
177177
assert.True(t, set.Contains(Ten24Router))
178178

@@ -185,11 +185,11 @@ func TestIPSetRemoveAll(t *testing.T) {
185185
set := IPSet{}
186186

187187
set.InsertNet(Ten24)
188-
_, cidr1, _ := net.ParseCIDR("192.168.0.0/25")
188+
cidr1, _ := ParseNet("192.168.0.0/25")
189189
set.InsertNet(cidr1)
190190
assert.Equal(t, 2, set.tree.numNodes())
191191

192-
_, cidr2, _ := net.ParseCIDR("0.0.0.0/0")
192+
cidr2, _ := ParseNet("0.0.0.0/0")
193193
set.RemoveNet(cidr2)
194194
assert.Equal(t, 0, set.tree.numNodes())
195195
assert.False(t, set.ContainsNet(Ten24))
@@ -216,7 +216,7 @@ func TestIPSetUnion(t *testing.T) {
216216
set1, set2 := &IPSet{}, &IPSet{}
217217

218218
set1.InsertNet(Ten24)
219-
_, cidr, _ := net.ParseCIDR("192.168.0.248/29")
219+
cidr, _ := ParseNet("192.168.0.248/29")
220220
set2.InsertNet(cidr)
221221

222222
set := set1.Union(set2)
@@ -228,7 +228,7 @@ func TestIPSetDifference(t *testing.T) {
228228
set1, set2 := &IPSet{}, &IPSet{}
229229

230230
set1.InsertNet(Ten24)
231-
_, cidr, _ := net.ParseCIDR("192.168.0.248/29")
231+
cidr, _ := ParseNet("192.168.0.248/29")
232232
set2.InsertNet(cidr)
233233

234234
set := set1.Difference(set2)
@@ -263,7 +263,7 @@ func TestIPSetAllocateDeallocate(t *testing.T) {
263263

264264
set := IPSet{}
265265

266-
_, bigNet, _ := net.ParseCIDR("15.1.64.0/16")
266+
bigNet, _ := ParseNet("15.1.0.0/16")
267267
set.InsertNet(bigNet)
268268

269269
ips := set.GetIPs(0)

net_utils.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package netaddr
22

33
import (
44
"bytes"
5+
"fmt"
56
"math/big"
67
"net"
78
"strings"
@@ -24,6 +25,21 @@ func ParseIP(address string) net.IP {
2425
return net.ParseIP(address).To4()
2526
}
2627

28+
// ParseNet parses an IP network from a CIDR. Unlike net.ParseCIDR, it does not
29+
// allow a CIDR where the host part is non-zero. For example, the following
30+
// CIDRs will result in an error: 203.0.113.1/24, 2001:db8::1/64, 10.0.20.0/20
31+
func ParseNet(cidr string) (parsed *net.IPNet, err error) {
32+
ip, parsed, err := net.ParseCIDR(cidr)
33+
if err != nil {
34+
return nil, err
35+
}
36+
if !ip.Equal(parsed.IP) {
37+
err = fmt.Errorf("Host part is not zero")
38+
return nil, err
39+
}
40+
return
41+
}
42+
2743
// NewIP returns a new IP with the given size. The size must be 4 for IPv4 and
2844
// 16 for IPv6.
2945
func NewIP(size int) net.IP {

net_utils_test.go

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,23 @@ import (
99
)
1010

1111
func TestExpandNet(t *testing.T) {
12-
_, n, _ := net.ParseCIDR("203.0.113.0/29")
12+
n, _ := ParseNet("203.0.113.0/29")
1313
ips := expandNet(n, 10)
1414
assert.Equal(t, 8, len(ips))
1515
assert.Equal(t, net.ParseIP("203.0.113.0").To4(), ips[0])
1616
assert.Equal(t, net.ParseIP("203.0.113.7").To4(), ips[7])
1717
}
1818

1919
func TestExpandNetLimit(t *testing.T) {
20-
_, n, _ := net.ParseCIDR("203.0.113.0/29")
20+
n, _ := ParseNet("203.0.113.0/29")
2121
ips := expandNet(n, 5)
2222
assert.Equal(t, 5, len(ips))
2323
assert.Equal(t, net.ParseIP("203.0.113.0").To4(), ips[0])
2424
assert.Equal(t, net.ParseIP("203.0.113.4").To4(), ips[4])
2525
}
2626

2727
func TestExpandNetLarge(t *testing.T) {
28-
_, n, _ := net.ParseCIDR("2001:db8::/56")
28+
n, _ := ParseNet("2001:db8::/56")
2929
ips := expandNet(n, 1000)
3030
assert.Equal(t, 1000, len(ips))
3131
assert.Equal(t, net.ParseIP("2001:db8::0"), ips[0])
@@ -34,32 +34,32 @@ func TestExpandNetLarge(t *testing.T) {
3434
}
3535

3636
func TestNetSize(t *testing.T) {
37-
_, n, _ := net.ParseCIDR("10.0.0.0/24")
37+
n, _ := ParseNet("10.0.0.0/24")
3838
assert.Equal(t, int64(256), NetSize(n).Int64())
3939
}
4040

4141
func TestNetSizeHost(t *testing.T) {
42-
_, n, _ := net.ParseCIDR("203.0.113.29/32")
42+
n, _ := ParseNet("203.0.113.29/32")
4343
assert.Equal(t, int64(1), NetSize(n).Int64())
4444
}
4545

4646
func TestNetSizeSlash8(t *testing.T) {
47-
_, n, _ := net.ParseCIDR("15.0.0.0/8")
47+
n, _ := ParseNet("15.0.0.0/8")
4848
assert.Equal(t, int64(16777216), NetSize(n).Int64())
4949
}
5050

5151
func TestNetSizeV6(t *testing.T) {
52-
_, n, _ := net.ParseCIDR("2001:db8::/64")
52+
n, _ := ParseNet("2001:db8::/64")
5353
assert.Equal(t, big.NewInt(0).Lsh(big.NewInt(1), 64), NetSize(n))
5454
}
5555

5656
func TestNetSizeV6Huge(t *testing.T) {
57-
_, n, _ := net.ParseCIDR("2001:db8::/8")
57+
n, _ := ParseNet("2000::/8")
5858
assert.Equal(t, big.NewInt(0).Lsh(big.NewInt(1), 120), NetSize(n))
5959
}
6060

6161
func TestNetSizeV6Host(t *testing.T) {
62-
_, n, _ := net.ParseCIDR("2001:db8::1/128")
62+
n, _ := ParseNet("2001:db8::1/128")
6363
assert.Equal(t, big.NewInt(1), NetSize(n))
6464
}
6565

@@ -81,7 +81,7 @@ func TestNetIP(t *testing.T) {
8181
assert.Equal(t, net.ParseIP("::"), NewIP(16))
8282
}
8383

84-
// Just a little shortcut for parsing a CIDR
84+
// Just a little shortcut for parsing a CIDR and get the net.IPNet.
8585
func parse(str string) (n *net.IPNet) {
8686
_, parsed, err := net.ParseCIDR(str)
8787
if err == nil {
@@ -90,6 +90,32 @@ func parse(str string) (n *net.IPNet) {
9090
return
9191
}
9292

93+
func TestParseNet(t *testing.T) {
94+
n, err := ParseNet("10.0.0.0/24")
95+
assert.Equal(t, parse("10.0.0.0/24"), n)
96+
assert.Nil(t, err)
97+
98+
n, err = ParseNet("2001:db8::/64")
99+
assert.Equal(t, parse("2001:db8::/64"), n)
100+
assert.Nil(t, err)
101+
}
102+
103+
func TestParseNetNonZeroHost(t *testing.T) {
104+
n, err := ParseNet("10.0.20.0/21")
105+
assert.NotNil(t, err)
106+
assert.Nil(t, n)
107+
108+
n, err = ParseNet("2001:db8::1/64")
109+
assert.NotNil(t, err)
110+
assert.Nil(t, n)
111+
}
112+
113+
func TestParseNetInvalidAddresses(t *testing.T) {
114+
n, err := ParseNet("10.0.324.0/24")
115+
assert.NotNil(t, err)
116+
assert.Nil(t, n)
117+
}
118+
93119
func TestNetworkAddr(t *testing.T) {
94120
assert.Equal(t, ParseIP("203.0.113.0"), NetworkAddr(parse("203.0.113.0/24")))
95121
assert.Equal(t, ParseIP("10.0.0.0"), NetworkAddr(parse("10.0.0.0/16")))

0 commit comments

Comments
 (0)