Skip to content

Commit 18cd5a9

Browse files
authored
Fix: usable count according to CIDR reference (#360)
* Fix: usable count according to CIDR reference
1 parent ac2717f commit 18cd5a9

File tree

5 files changed

+31
-83
lines changed

5 files changed

+31
-83
lines changed

src/System.Net.IPNetwork/IPNetwork2Members.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public IPAddress FirstUsable
103103
{
104104
BigInteger first = this.family == AddressFamily.InterNetworkV6
105105
? this.InternalNetwork
106-
: (this.Usable <= 0)
106+
: (this.Usable <= 1)
107107
? this.InternalNetwork
108108
: this.InternalNetwork + 1;
109109
return ToIPAddress(first, this.family);
@@ -119,7 +119,7 @@ public IPAddress LastUsable
119119
{
120120
BigInteger last = this.family == AddressFamily.InterNetworkV6
121121
? this.InternalBroadcast
122-
: (this.Usable <= 0)
122+
: (this.Usable <= 1)
123123
? this.InternalNetwork
124124
: this.InternalBroadcast - 1;
125125
return ToIPAddress(last, this.family);
@@ -128,6 +128,12 @@ public IPAddress LastUsable
128128

129129
/// <summary>
130130
/// Gets number of usable IPAddress in Network.
131+
///
132+
/// According to : https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#IPv4_CIDR_blocks
133+
/// Address Mask Total Usable Network Broadcast FirstUsable LastUsable Typical use
134+
/// 1.0.0.1/32 255.255.255.255 1 **1** 1.0.0.1 1.0.0.1 1.0.0.1 1.0.0.1 Host route
135+
/// 1.0.0.1/31 255.255.255.254 2 **2** 1.0.0.1 1.0.0.2 1.0.0.1 1.0.0.2 Point-to-point links (RFC 3021)
136+
/// ...
131137
/// </summary>
132138
public BigInteger Usable
133139
{
@@ -140,7 +146,9 @@ public BigInteger Usable
140146

141147
byte[] mask = [0xff, 0xff, 0xff, 0xff, 0x00];
142148
var bmask = new BigInteger(mask);
143-
BigInteger usableIps = (this.cidr > 30) ? 0 : ((bmask >> this.cidr) - 1);
149+
BigInteger usableIps = (this.cidr == 32)? 1
150+
: (this.cidr == 31)? 2
151+
: ((bmask >> this.cidr)- 1);
144152
return usableIps;
145153
}
146154
}

src/TestProject/IPNetworkTest/IPNetworkParseTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ public void TestParseString4()
239239
string firstUsable = "0.0.0.0";
240240
string lastUsable = "0.0.0.0";
241241
byte cidr = 32;
242-
uint usable = 0;
242+
uint usable = 1;
243243

244244
var ipnetwork = IPNetwork2.Parse(ipaddress);
245245
Assert.AreEqual(network, ipnetwork.Network.ToString(), "Network");
@@ -266,7 +266,7 @@ public void TestParseString5()
266266
string firstUsable = "255.255.255.255";
267267
string lastUsable = "255.255.255.255";
268268
byte cidr = 32;
269-
uint usable = 0;
269+
uint usable = 1;
270270

271271
var ipnetwork = IPNetwork2.Parse(ipaddress);
272272
Assert.AreEqual(network, ipnetwork.Network.ToString(), "Network");
@@ -484,7 +484,7 @@ public void TestParseIPAddressNoNetmask1_ClassLess()
484484
string firstUsable = "10.0.0.0";
485485
string lastUsable = "10.0.0.0";
486486
byte cidr = 32;
487-
uint usable = 0;
487+
uint usable = 1;
488488

489489
Assert.AreEqual(network, ipnetwork.Network.ToString(), "Network");
490490
Assert.AreEqual(netmask, ipnetwork.Netmask.ToString(), "Netmask");
@@ -512,7 +512,7 @@ public void TestParseIPAddressNoNetmask2_ClassLess()
512512
string firstUsable = "172.0.0.0";
513513
string lastUsable = "172.0.0.0";
514514
byte cidr = 32;
515-
uint usable = 0;
515+
uint usable = 1;
516516

517517
Assert.AreEqual(network, ipnetwork.Network.ToString(), "Network");
518518
Assert.AreEqual(netmask, ipnetwork.Netmask.ToString(), "Netmask");
@@ -540,7 +540,7 @@ public void TestParseIPAddressNoNetmask3_ClassLess()
540540
string firstUsable = "192.0.0.0";
541541
string lastUsable = "192.0.0.0";
542542
byte cidr = 32;
543-
uint usable = 0;
543+
uint usable = 1;
544544

545545
Assert.AreEqual(network, ipnetwork.Network.ToString(), "Network");
546546
Assert.AreEqual(netmask, ipnetwork.Netmask.ToString(), "Netmask");

src/TestProject/IPNetworkTest/IPNetworkTryParseTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ public void TestTryParseString4()
253253
string firstUsable = "0.0.0.0";
254254
string lastUsable = "0.0.0.0";
255255
byte cidr = 32;
256-
uint usable = 0;
256+
uint usable = 1;
257257

258258
bool parsed = IPNetwork2.TryParse(ipaddress, out IPNetwork2 ipnetwork);
259259
Assert.IsTrue(parsed, "parsed");
@@ -280,7 +280,7 @@ public void TestTryParseString5()
280280
string firstUsable = "255.255.255.255";
281281
string lastUsable = "255.255.255.255";
282282
byte cidr = 32;
283-
uint usable = 0;
283+
uint usable = 1;
284284

285285
bool parsed = IPNetwork2.TryParse(ipaddress, out IPNetwork2 ipnetwork);
286286
Assert.IsTrue(parsed, "parsed");

src/TestProject/IPNetworkTest/IPNetworkUsableTests.cs

Lines changed: 11 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -14,76 +14,16 @@ public class IPNetworkUsableTests
1414
/// Tests Usable functionality with a /32 network.
1515
/// </summary>
1616
[TestMethod]
17-
public void Usable32()
17+
[DataRow("0.0.0.0/32", (uint)1)]
18+
[DataRow("0.0.0.0/31", (uint)2)]
19+
[DataRow("0.0.0.0/30", (uint)2)]
20+
[DataRow("0.0.0.0/24", (uint)254)]
21+
[DataRow("0.0.0.0/8", (uint)16777214)]
22+
[DataRow("0.0.0.0/16", (uint)65534)]
23+
[DataRow("0.0.0.0/0", 4294967294)]
24+
public void TestUsable(string ipnetwork, uint usable)
1825
{
19-
var network = IPNetwork2.Parse("0.0.0.0/32");
20-
uint usable = 0;
21-
Assert.AreEqual(usable, network.Usable, "Usable");
22-
}
23-
24-
/// <summary>
25-
/// Tests Usable functionality with a /31 network.
26-
/// </summary>
27-
[TestMethod]
28-
public void Usable31()
29-
{
30-
var network = IPNetwork2.Parse("0.0.0.0/31");
31-
uint usable = 0;
32-
Assert.AreEqual(usable, network.Usable, "Usable");
33-
}
34-
35-
/// <summary>
36-
/// Tests Usable functionality with a /30 network.
37-
/// </summary>
38-
[TestMethod]
39-
public void Usable30()
40-
{
41-
var network = IPNetwork2.Parse("0.0.0.0/30");
42-
uint usable = 2;
43-
Assert.AreEqual(usable, network.Usable, "Usable");
44-
}
45-
46-
/// <summary>
47-
/// Tests Usable functionality with a /24 network.
48-
/// </summary>
49-
[TestMethod]
50-
public void Usable24()
51-
{
52-
var network = IPNetwork2.Parse("0.0.0.0/24");
53-
uint usable = 254;
54-
Assert.AreEqual(usable, network.Usable, "Usable");
55-
}
56-
57-
/// <summary>
58-
/// Tests Usable functionality with a /16 network.
59-
/// </summary>
60-
[TestMethod]
61-
public void Usable16()
62-
{
63-
var network = IPNetwork2.Parse("0.0.0.0/16");
64-
uint usable = 65534;
65-
Assert.AreEqual(usable, network.Usable, "Usable");
66-
}
67-
68-
/// <summary>
69-
/// Tests Usable functionality with a /8 network.
70-
/// </summary>
71-
[TestMethod]
72-
public void Usable8()
73-
{
74-
var network = IPNetwork2.Parse("0.0.0.0/8");
75-
uint usable = 16777214;
76-
Assert.AreEqual(usable, network.Usable, "Usable");
77-
}
78-
79-
/// <summary>
80-
/// Tests Usable functionality with a /0 network.
81-
/// </summary>
82-
[TestMethod]
83-
public void Usable0()
84-
{
85-
var network = IPNetwork2.Parse("0.0.0.0/0");
86-
uint usable = 4294967294;
87-
Assert.AreEqual(usable, network.Usable, "Usable");
88-
}
26+
var network = IPNetwork2.Parse(ipnetwork);
27+
Assert.AreEqual(usable, network.Usable, "Usable");
28+
}
8929
}

src/TestProject/TryParseUnitTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ public void TestTryParseString4()
269269
string firstUsable = "0.0.0.0";
270270
string lastUsable = "0.0.0.0";
271271
byte cidr = 32;
272-
uint usable = 0;
272+
uint usable = 1;
273273

274274
bool parsed = IPNetwork2.TryParse(ipaddress, out IPNetwork2 ipnetwork);
275275

@@ -297,7 +297,7 @@ public void TestTryParseString5()
297297
string firstUsable = "255.255.255.255";
298298
string lastUsable = "255.255.255.255";
299299
byte cidr = 32;
300-
uint usable = 0;
300+
uint usable = 1;
301301

302302
bool parsed = IPNetwork2.TryParse(ipaddress, out IPNetwork2 ipnetwork);
303303

0 commit comments

Comments
 (0)