Skip to content

Commit f6b1469

Browse files
authored
Merge pull request #384 from lduchosal/feat/v4-nullable
feat!: complete IANA reserved block coverage (#376)
2 parents 63025f9 + 794fd20 commit f6b1469

File tree

2 files changed

+399
-38
lines changed

2 files changed

+399
-38
lines changed

src/System.Net.IPNetwork/IPNetwork2IANAblock.cs

Lines changed: 215 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,75 +4,187 @@
44

55
namespace System.Net;
66

7+
using System.Net.Sockets;
8+
79
/// <summary>
810
/// IANA Blocks.
911
/// </summary>
1012
public sealed partial class IPNetwork2
1113
{
14+
// IPv4 RFC 1918 Private Address Blocks
1215
private static readonly Lazy<IPNetwork2> IanaAblockReserved = new (() => Parse("10.0.0.0/8"));
1316
private static readonly Lazy<IPNetwork2> IanaBblockReserved = new (() => Parse("172.16.0.0/12"));
1417
private static readonly Lazy<IPNetwork2> IanaCblockReserved = new (() => Parse("192.168.0.0/16"));
1518

19+
// IPv4 Additional IANA Reserved Blocks
20+
private static readonly Lazy<IPNetwork2> IanaThisNetwork = new (() => Parse("0.0.0.0/8"));
21+
private static readonly Lazy<IPNetwork2> IanaLoopback = new (() => Parse("127.0.0.0/8"));
22+
private static readonly Lazy<IPNetwork2> IanaLinkLocal = new (() => Parse("169.254.0.0/16"));
23+
private static readonly Lazy<IPNetwork2> IanaIetfProtocol = new (() => Parse("192.0.0.0/24"));
24+
private static readonly Lazy<IPNetwork2> IanaTestNet1 = new (() => Parse("192.0.2.0/24"));
25+
private static readonly Lazy<IPNetwork2> IanaBenchmark = new (() => Parse("198.18.0.0/15"));
26+
private static readonly Lazy<IPNetwork2> IanaTestNet2 = new (() => Parse("198.51.100.0/24"));
27+
private static readonly Lazy<IPNetwork2> IanaTestNet3 = new (() => Parse("203.0.113.0/24"));
28+
private static readonly Lazy<IPNetwork2> IanaMulticast = new (() => Parse("224.0.0.0/4"));
29+
private static readonly Lazy<IPNetwork2> IanaReserved = new (() => Parse("240.0.0.0/4"));
30+
private static readonly Lazy<IPNetwork2> IanaBroadcast = new (() => Parse("255.255.255.255/32"));
31+
32+
// IPv6 IANA Reserved Blocks
33+
private static readonly Lazy<IPNetwork2> Iana6Unspecified = new (() => Parse("::/128"));
34+
private static readonly Lazy<IPNetwork2> Iana6Loopback = new (() => Parse("::1/128"));
35+
private static readonly Lazy<IPNetwork2> Iana6Ipv4Mapped = new (() => Parse("::ffff:0:0/96"));
36+
private static readonly Lazy<IPNetwork2> Iana6Ipv4Translation = new (() => Parse("64:ff9b::/96"));
37+
private static readonly Lazy<IPNetwork2> Iana6Teredo = new (() => Parse("2001::/32"));
38+
private static readonly Lazy<IPNetwork2> Iana6Documentation = new (() => Parse("2001:db8::/32"));
39+
private static readonly Lazy<IPNetwork2> Iana6UniqueLocal = new (() => Parse("fc00::/7"));
40+
private static readonly Lazy<IPNetwork2> Iana6LinkLocal = new (() => Parse("fe80::/10"));
41+
private static readonly Lazy<IPNetwork2> Iana6Multicast = new (() => Parse("ff00::/8"));
42+
1643
/// <summary>
1744
/// Gets 10.0.0.0/8.
1845
/// </summary>
1946
/// <returns>The IANA reserved IPNetwork 10.0.0.0/8.</returns>
20-
public static IPNetwork2 IANA_ABLK_RESERVED1
21-
{
22-
get
23-
{
24-
return IanaAblockReserved.Value;
25-
}
26-
}
47+
public static IPNetwork2 IANA_ABLK_RESERVED1 => IanaAblockReserved.Value;
2748

2849
/// <summary>
29-
/// Gets 172.12.0.0/12.
50+
/// Gets 172.16.0.0/12.
3051
/// </summary>
31-
/// <returns>The IANA reserved IPNetwork 172.12.0.0/12.</returns>
32-
public static IPNetwork2 IANA_BBLK_RESERVED1
33-
{
34-
get
35-
{
36-
return IanaBblockReserved.Value;
37-
}
38-
}
52+
/// <returns>The IANA reserved IPNetwork 172.16.0.0/12.</returns>
53+
public static IPNetwork2 IANA_BBLK_RESERVED1 => IanaBblockReserved.Value;
3954

4055
/// <summary>
4156
/// Gets 192.168.0.0/16.
4257
/// </summary>
4358
/// <returns>The IANA reserved IPNetwork 192.168.0.0/16.</returns>
44-
public static IPNetwork2 IANA_CBLK_RESERVED1
45-
{
46-
get
47-
{
48-
return IanaCblockReserved.Value;
49-
}
50-
}
59+
public static IPNetwork2 IANA_CBLK_RESERVED1 => IanaCblockReserved.Value;
60+
61+
/// <summary>
62+
/// Gets 0.0.0.0/8 (This network).
63+
/// </summary>
64+
public static IPNetwork2 IANA_THIS_NETWORK => IanaThisNetwork.Value;
65+
66+
/// <summary>
67+
/// Gets 127.0.0.0/8 (Loopback).
68+
/// </summary>
69+
public static IPNetwork2 IANA_LOOPBACK => IanaLoopback.Value;
70+
71+
/// <summary>
72+
/// Gets 169.254.0.0/16 (Link-local).
73+
/// </summary>
74+
public static IPNetwork2 IANA_LINK_LOCAL => IanaLinkLocal.Value;
75+
76+
/// <summary>
77+
/// Gets 192.0.0.0/24 (IETF Protocol Assignments).
78+
/// </summary>
79+
public static IPNetwork2 IANA_IETF_PROTOCOL => IanaIetfProtocol.Value;
80+
81+
/// <summary>
82+
/// Gets 192.0.2.0/24 (Documentation TEST-NET-1).
83+
/// </summary>
84+
public static IPNetwork2 IANA_TEST_NET1 => IanaTestNet1.Value;
85+
86+
/// <summary>
87+
/// Gets 198.18.0.0/15 (Benchmarking).
88+
/// </summary>
89+
public static IPNetwork2 IANA_BENCHMARK => IanaBenchmark.Value;
90+
91+
/// <summary>
92+
/// Gets 198.51.100.0/24 (Documentation TEST-NET-2).
93+
/// </summary>
94+
public static IPNetwork2 IANA_TEST_NET2 => IanaTestNet2.Value;
95+
96+
/// <summary>
97+
/// Gets 203.0.113.0/24 (Documentation TEST-NET-3).
98+
/// </summary>
99+
public static IPNetwork2 IANA_TEST_NET3 => IanaTestNet3.Value;
100+
101+
/// <summary>
102+
/// Gets 224.0.0.0/4 (Multicast).
103+
/// </summary>
104+
public static IPNetwork2 IANA_MULTICAST => IanaMulticast.Value;
105+
106+
/// <summary>
107+
/// Gets 240.0.0.0/4 (Reserved).
108+
/// </summary>
109+
public static IPNetwork2 IANA_RESERVED => IanaReserved.Value;
110+
111+
/// <summary>
112+
/// Gets 255.255.255.255/32 (Broadcast).
113+
/// </summary>
114+
public static IPNetwork2 IANA_BROADCAST => IanaBroadcast.Value;
115+
116+
/// <summary>
117+
/// Gets ::/128 (Unspecified).
118+
/// </summary>
119+
public static IPNetwork2 IANA6_UNSPECIFIED => Iana6Unspecified.Value;
120+
121+
/// <summary>
122+
/// Gets ::1/128 (Loopback).
123+
/// </summary>
124+
public static IPNetwork2 IANA6_LOOPBACK => Iana6Loopback.Value;
125+
126+
/// <summary>
127+
/// Gets ::ffff:0:0/96 (IPv4-mapped).
128+
/// </summary>
129+
public static IPNetwork2 IANA6_IPV4_MAPPED => Iana6Ipv4Mapped.Value;
130+
131+
/// <summary>
132+
/// Gets 64:ff9b::/96 (IPv4/IPv6 translation).
133+
/// </summary>
134+
public static IPNetwork2 IANA6_IPV4_TRANSLATION => Iana6Ipv4Translation.Value;
135+
136+
/// <summary>
137+
/// Gets 2001::/32 (TEREDO).
138+
/// </summary>
139+
public static IPNetwork2 IANA6_TEREDO => Iana6Teredo.Value;
140+
141+
/// <summary>
142+
/// Gets 2001:db8::/32 (Documentation).
143+
/// </summary>
144+
public static IPNetwork2 IANA6_DOCUMENTATION => Iana6Documentation.Value;
145+
146+
/// <summary>
147+
/// Gets fc00::/7 (Unique local).
148+
/// </summary>
149+
public static IPNetwork2 IANA6_UNIQUE_LOCAL => Iana6UniqueLocal.Value;
150+
151+
/// <summary>
152+
/// Gets fe80::/10 (Link-local).
153+
/// </summary>
154+
public static IPNetwork2 IANA6_LINK_LOCAL => Iana6LinkLocal.Value;
155+
156+
/// <summary>
157+
/// Gets ff00::/8 (Multicast).
158+
/// </summary>
159+
public static IPNetwork2 IANA6_MULTICAST => Iana6Multicast.Value;
51160

52161
/// <summary>
53162
/// return true if ipaddress is contained in
54-
/// IANA_ABLK_RESERVED1, IANA_BBLK_RESERVED1, IANA_CBLK_RESERVED1.
163+
/// any IANA reserved block (IPv4 or IPv6).
55164
/// </summary>
56-
/// <param name="ipaddress">A string containing an ip address to convert.</param>
57-
/// <returns>true if ipaddress is a IANA reserverd IP Netowkr ; otherwise, false.</returns>
165+
/// <param name="ipaddress">An IP address to check.</param>
166+
/// <returns>true if ipaddress is in an IANA reserved block; otherwise, false.</returns>
58167
public static bool IsIANAReserved(IPAddress ipaddress)
59168
{
60169
if (ipaddress == null)
61170
{
62171
throw new ArgumentNullException(nameof(ipaddress));
63172
}
64173

65-
return IANA_ABLK_RESERVED1.Contains(ipaddress)
66-
|| IANA_BBLK_RESERVED1.Contains(ipaddress)
67-
|| IANA_CBLK_RESERVED1.Contains(ipaddress);
174+
if (ipaddress.AddressFamily == AddressFamily.InterNetworkV6)
175+
{
176+
return IsIANAReservedIPv6(ipaddress);
177+
}
178+
179+
return IsIANAReservedIPv4(ipaddress);
68180
}
69181

70182
/// <summary>
71183
/// return true if ipnetwork is contained in
72-
/// IANA_ABLK_RESERVED1, IANA_BBLK_RESERVED1, IANA_CBLK_RESERVED1.
184+
/// any IANA reserved block (IPv4 or IPv6).
73185
/// </summary>
74186
/// <param name="ipnetwork">The IPNetwork to test.</param>
75-
/// <returns>true if the ipnetwork is a IANA reserverd IP Netowkr ; otherwise, false.</returns>
187+
/// <returns>true if the ipnetwork is in an IANA reserved block; otherwise, false.</returns>
76188
public static bool IsIANAReserved(IPNetwork2 ipnetwork)
77189
{
78190
if (ipnetwork == null)
@@ -84,14 +196,79 @@ public static bool IsIANAReserved(IPNetwork2 ipnetwork)
84196
}
85197

86198
/// <summary>
87-
/// return true if ipnetwork is contained in
88-
/// IANA_ABLK_RESERVED1, IANA_BBLK_RESERVED1, IANA_CBLK_RESERVED1.
199+
/// return true if this ipnetwork is contained in
200+
/// any IANA reserved block (IPv4 or IPv6).
89201
/// </summary>
90-
/// <returns>true if the ipnetwork is a IANA reserverd IP Netowkr ; otherwise, false.</returns>
202+
/// <returns>true if the ipnetwork is in an IANA reserved block; otherwise, false.</returns>
91203
public bool IsIANAReserved()
92204
{
93-
return IANA_ABLK_RESERVED1.Contains(this)
94-
|| IANA_BBLK_RESERVED1.Contains(this)
95-
|| IANA_CBLK_RESERVED1.Contains(this);
205+
if (this.family == AddressFamily.InterNetworkV6)
206+
{
207+
return IsIANAReservedIPv6(this);
208+
}
209+
210+
return IsIANAReservedIPv4(this);
211+
}
212+
213+
private static bool IsIANAReservedIPv4(IPAddress ipaddress)
214+
{
215+
return IANA_THIS_NETWORK.Contains(ipaddress)
216+
|| IANA_LOOPBACK.Contains(ipaddress)
217+
|| IANA_ABLK_RESERVED1.Contains(ipaddress)
218+
|| IANA_LINK_LOCAL.Contains(ipaddress)
219+
|| IANA_BBLK_RESERVED1.Contains(ipaddress)
220+
|| IANA_IETF_PROTOCOL.Contains(ipaddress)
221+
|| IANA_TEST_NET1.Contains(ipaddress)
222+
|| IANA_CBLK_RESERVED1.Contains(ipaddress)
223+
|| IANA_BENCHMARK.Contains(ipaddress)
224+
|| IANA_TEST_NET2.Contains(ipaddress)
225+
|| IANA_TEST_NET3.Contains(ipaddress)
226+
|| IANA_MULTICAST.Contains(ipaddress)
227+
|| IANA_RESERVED.Contains(ipaddress)
228+
|| IANA_BROADCAST.Contains(ipaddress);
229+
}
230+
231+
private static bool IsIANAReservedIPv4(IPNetwork2 ipnetwork)
232+
{
233+
return IANA_THIS_NETWORK.Contains(ipnetwork)
234+
|| IANA_LOOPBACK.Contains(ipnetwork)
235+
|| IANA_ABLK_RESERVED1.Contains(ipnetwork)
236+
|| IANA_LINK_LOCAL.Contains(ipnetwork)
237+
|| IANA_BBLK_RESERVED1.Contains(ipnetwork)
238+
|| IANA_IETF_PROTOCOL.Contains(ipnetwork)
239+
|| IANA_TEST_NET1.Contains(ipnetwork)
240+
|| IANA_CBLK_RESERVED1.Contains(ipnetwork)
241+
|| IANA_BENCHMARK.Contains(ipnetwork)
242+
|| IANA_TEST_NET2.Contains(ipnetwork)
243+
|| IANA_TEST_NET3.Contains(ipnetwork)
244+
|| IANA_MULTICAST.Contains(ipnetwork)
245+
|| IANA_RESERVED.Contains(ipnetwork)
246+
|| IANA_BROADCAST.Contains(ipnetwork);
247+
}
248+
249+
private static bool IsIANAReservedIPv6(IPAddress ipaddress)
250+
{
251+
return IANA6_UNSPECIFIED.Contains(ipaddress)
252+
|| IANA6_LOOPBACK.Contains(ipaddress)
253+
|| IANA6_IPV4_MAPPED.Contains(ipaddress)
254+
|| IANA6_IPV4_TRANSLATION.Contains(ipaddress)
255+
|| IANA6_TEREDO.Contains(ipaddress)
256+
|| IANA6_DOCUMENTATION.Contains(ipaddress)
257+
|| IANA6_UNIQUE_LOCAL.Contains(ipaddress)
258+
|| IANA6_LINK_LOCAL.Contains(ipaddress)
259+
|| IANA6_MULTICAST.Contains(ipaddress);
260+
}
261+
262+
private static bool IsIANAReservedIPv6(IPNetwork2 ipnetwork)
263+
{
264+
return IANA6_UNSPECIFIED.Contains(ipnetwork)
265+
|| IANA6_LOOPBACK.Contains(ipnetwork)
266+
|| IANA6_IPV4_MAPPED.Contains(ipnetwork)
267+
|| IANA6_IPV4_TRANSLATION.Contains(ipnetwork)
268+
|| IANA6_TEREDO.Contains(ipnetwork)
269+
|| IANA6_DOCUMENTATION.Contains(ipnetwork)
270+
|| IANA6_UNIQUE_LOCAL.Contains(ipnetwork)
271+
|| IANA6_LINK_LOCAL.Contains(ipnetwork)
272+
|| IANA6_MULTICAST.Contains(ipnetwork);
96273
}
97-
}
274+
}

0 commit comments

Comments
 (0)