1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.net.util;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertThrows;
23 import static org.junit.jupiter.api.Assertions.assertTrue;
24
25 import java.math.BigInteger;
26 import java.net.Inet6Address;
27 import java.net.InetAddress;
28 import java.net.UnknownHostException;
29
30 import org.apache.commons.net.util.SubnetUtils6.SubnetInfo;
31 import org.junit.jupiter.api.Test;
32
33
34
35
36 class SubnetUtils6Test {
37
38 private static final BigInteger TWO = BigInteger.valueOf(2);
39
40 private static void assertEquivalentSubnets(final String... cidrs) {
41 final SubnetInfo reference = new SubnetUtils6(cidrs[0]).getInfo();
42 for (int i = 1; i < cidrs.length; i++) {
43 final SubnetInfo other = new SubnetUtils6(cidrs[i]).getInfo();
44 assertEquals(reference.getNetworkAddress(), other.getNetworkAddress(),
45 cidrs[0] + " vs " + cidrs[i] + " network");
46 assertEquals(reference.getHighAddress(), other.getHighAddress(),
47 cidrs[0] + " vs " + cidrs[i] + " high");
48 assertEquals(reference.getAddress(), other.getAddress(),
49 cidrs[0] + " vs " + cidrs[i] + " address");
50 }
51 }
52
53 @Test
54 void testBasicCidr128() {
55 final SubnetUtils6 utils = new SubnetUtils6("2001:db8::1/128");
56 final SubnetInfo info = utils.getInfo();
57
58 assertEquals(128, info.getPrefixLength());
59 assertEquals("2001:db8:0:0:0:0:0:1", info.getNetworkAddress());
60 assertEquals("2001:db8:0:0:0:0:0:1", info.getHighAddress());
61 assertEquals(BigInteger.ONE, info.getAddressCount());
62 }
63
64 @Test
65 void testBasicCidr64() {
66 final SubnetUtils6 utils = new SubnetUtils6("2001:db8::1/64");
67 final SubnetInfo info = utils.getInfo();
68
69 assertEquals(64, info.getPrefixLength());
70 assertEquals("2001:db8:0:0:0:0:0:1", info.getAddress());
71 assertEquals("2001:db8:0:0:0:0:0:0", info.getNetworkAddress());
72 assertEquals("2001:db8:0:0:ffff:ffff:ffff:ffff", info.getHighAddress());
73
74 assertEquals(TWO.pow(64), info.getAddressCount());
75 }
76
77 @Test
78 void testCidr0() {
79 final SubnetUtils6 utils = new SubnetUtils6("::/0");
80 final SubnetInfo info = utils.getInfo();
81
82 assertEquals(0, info.getPrefixLength());
83 assertEquals("0:0:0:0:0:0:0:0", info.getNetworkAddress());
84
85 assertEquals(TWO.pow(128), info.getAddressCount());
86 }
87
88 @Test
89 void testCidr48() {
90 final SubnetUtils6 utils = new SubnetUtils6("2001:db8:abcd::/48");
91 final SubnetInfo info = utils.getInfo();
92
93 assertEquals(48, info.getPrefixLength());
94 assertEquals("2001:db8:abcd:0:0:0:0:0", info.getNetworkAddress());
95 assertEquals("2001:db8:abcd:ffff:ffff:ffff:ffff:ffff", info.getHighAddress());
96 }
97
98 @Test
99 void testCompressedAddress() {
100 final SubnetUtils6 utils = new SubnetUtils6("fe80::1/10");
101 final SubnetInfo info = utils.getInfo();
102
103 assertEquals(10, info.getPrefixLength());
104 assertTrue(info.isInRange("fe80::1"));
105 assertTrue(info.isInRange("fe80::ffff"));
106 assertTrue(info.isInRange("febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
107 assertFalse(info.isInRange("fec0::1"));
108 }
109
110 @Test
111 void testConstructorWithSeparateArgs() {
112 final SubnetUtils6 utils = new SubnetUtils6("2001:db8::1", 64);
113 final SubnetInfo info = utils.getInfo();
114
115 assertEquals(64, info.getPrefixLength());
116 assertEquals("2001:db8:0:0:0:0:0:0", info.getNetworkAddress());
117 }
118
119 @Test
120 void testFullAddress() {
121 final SubnetUtils6 utils = new SubnetUtils6("2001:0db8:0000:0000:0000:0000:0000:0001/64");
122 final SubnetInfo info = utils.getInfo();
123
124 assertEquals(64, info.getPrefixLength());
125 assertEquals("2001:db8:0:0:0:0:0:0", info.getNetworkAddress());
126 }
127
128 @Test
129 void testGetCidrSignature() {
130 final SubnetUtils6 utils = new SubnetUtils6("2001:db8::1/64");
131 final SubnetInfo info = utils.getInfo();
132
133 assertEquals("2001:db8:0:0:0:0:0:1/64", info.getCidrSignature());
134 }
135
136 @Test
137 void testGetLowAddress() {
138 final SubnetUtils6 utils = new SubnetUtils6("2001:db8::100/120");
139 final SubnetInfo info = utils.getInfo();
140
141
142 assertEquals(info.getNetworkAddress(), info.getLowAddress());
143 assertEquals("2001:db8:0:0:0:0:0:100", info.getLowAddress());
144 }
145
146 @Test
147 void testHighBitAddress() {
148 final SubnetUtils6 utils = new SubnetUtils6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
149 final SubnetInfo info = utils.getInfo();
150
151 assertEquals("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", info.getAddress());
152 assertEquals("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", info.getNetworkAddress());
153 assertEquals("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", info.getHighAddress());
154 assertEquals(BigInteger.ONE, info.getAddressCount());
155 }
156
157 @Test
158 void testInvalidCidr() {
159 assertThrows(IllegalArgumentException.class, () -> new SubnetUtils6(null));
160 assertThrows(IllegalArgumentException.class, () -> new SubnetUtils6("2001:db8::1"));
161 assertThrows(IllegalArgumentException.class, () -> new SubnetUtils6("2001:db8::1/"));
162 assertThrows(IllegalArgumentException.class, () -> new SubnetUtils6("2001:db8::1/129"));
163 assertThrows(IllegalArgumentException.class, () -> new SubnetUtils6("2001:db8::1/-1"));
164 assertThrows(IllegalArgumentException.class, () -> new SubnetUtils6("2001:db8::1/abc"));
165 assertThrows(IllegalArgumentException.class, () -> new SubnetUtils6("not-an-address/64"));
166 }
167
168 @Test
169 void testInvalidIPv4Address() {
170
171 assertThrows(IllegalArgumentException.class, () -> new SubnetUtils6("192.168.1.1/24"));
172 }
173
174 @Test
175 void testInvalidTwoArgConstructor() {
176 assertThrows(IllegalArgumentException.class, () -> new SubnetUtils6("2001:db8::1", 129));
177 assertThrows(IllegalArgumentException.class, () -> new SubnetUtils6("2001:db8::1", -1));
178 assertThrows(IllegalArgumentException.class, () -> new SubnetUtils6("not-an-address", 64));
179 }
180
181 @Test
182 void testIsInRange() {
183 final SubnetUtils6 utils = new SubnetUtils6("2001:db8::/32");
184 final SubnetInfo info = utils.getInfo();
185
186
187 assertTrue(info.isInRange("2001:db8::1"));
188 assertTrue(info.isInRange("2001:db8::"));
189 assertTrue(info.isInRange("2001:db8:ffff:ffff:ffff:ffff:ffff:ffff"));
190 assertTrue(info.isInRange("2001:db8:1234:5678:9abc:def0:1234:5678"));
191
192
193 assertFalse(info.isInRange("2001:db9::1"));
194 assertFalse(info.isInRange("2001:db7::1"));
195 assertFalse(info.isInRange("2002:db8::1"));
196 assertFalse(info.isInRange("::1"));
197 }
198
199 @Test
200 void testIsInRangeWithBigInteger() throws UnknownHostException {
201 final SubnetUtils6 utils = new SubnetUtils6("2001:db8::/32");
202 final SubnetInfo info = utils.getInfo();
203
204
205 assertFalse(info.isInRange((BigInteger) null));
206
207 final BigInteger inRange = new BigInteger(1, InetAddress.getByName("2001:db8::1").getAddress());
208 assertTrue(info.isInRange(inRange));
209 final BigInteger outOfRange = new BigInteger(1, InetAddress.getByName("2001:db9::1").getAddress());
210 assertFalse(info.isInRange(outOfRange));
211 }
212
213 @Test
214 void testIsInRangeWithByteArray() throws UnknownHostException {
215 final SubnetUtils6 utils = new SubnetUtils6("2001:db8::/32");
216 final SubnetInfo info = utils.getInfo();
217
218
219 assertFalse(info.isInRange((byte[]) null));
220
221
222 assertFalse(info.isInRange(new byte[4]));
223 assertFalse(info.isInRange(new byte[15]));
224 assertFalse(info.isInRange(new byte[17]));
225
226 assertTrue(info.isInRange(InetAddress.getByName("2001:db8::1").getAddress()));
227 assertFalse(info.isInRange(InetAddress.getByName("2001:db9::1").getAddress()));
228 }
229
230 @Test
231 void testIsInRangeWithInet6Address() throws UnknownHostException {
232 final SubnetUtils6 utils = new SubnetUtils6("2001:db8::/32");
233 final SubnetInfo info = utils.getInfo();
234
235
236 final Inet6Address addr = (Inet6Address) InetAddress.getByName("2001:db8::1");
237 assertTrue(info.isInRange(addr));
238
239 final Inet6Address addrOutside = (Inet6Address) InetAddress.getByName("2001:db9::1");
240 assertFalse(info.isInRange(addrOutside));
241
242
243 assertFalse(info.isInRange((Inet6Address) null));
244 }
245
246 @Test
247 void testIsInRangeWithInvalidString() {
248 final SubnetUtils6 utils = new SubnetUtils6("2001:db8::/32");
249 final SubnetInfo info = utils.getInfo();
250
251 assertThrows(IllegalArgumentException.class, () -> info.isInRange("not-an-address"));
252 assertThrows(IllegalArgumentException.class, () -> info.isInRange("192.168.1.1"));
253 }
254
255 @Test
256 void testLinkLocalAddress() {
257 final SubnetUtils6 utils = new SubnetUtils6("fe80::/10");
258 final SubnetInfo info = utils.getInfo();
259
260 assertTrue(info.isInRange("fe80::1"));
261 assertTrue(info.isInRange("fe80::1:2:3:4"));
262 assertFalse(info.isInRange("::1"));
263 }
264
265 @Test
266 void testLoopbackAddress() {
267 final SubnetUtils6 utils = new SubnetUtils6("::1/128");
268 final SubnetInfo info = utils.getInfo();
269
270 assertEquals(128, info.getPrefixLength());
271 assertTrue(info.isInRange("::1"));
272 assertFalse(info.isInRange("::2"));
273 }
274
275
276
277
278
279 @Test
280 void testRfc5952Section1EquivalentRepresentations() {
281 assertEquivalentSubnets(
282 "2001:db8:0:0:1:0:0:1/128",
283 "2001:0db8:0:0:1:0:0:1/128",
284 "2001:db8::1:0:0:1/128",
285 "2001:db8::0:1:0:0:1/128",
286 "2001:0db8::1:0:0:1/128",
287 "2001:db8:0:0:1::1/128",
288 "2001:db8:0000:0:1::1/128",
289 "2001:DB8:0:0:1::1/128"
290 );
291 }
292
293
294
295
296 @Test
297 void testRfc5952Section21LeadingZeros() {
298 assertEquivalentSubnets(
299 "2001:db8:aaaa:bbbb:cccc:dddd:eeee:0001/128",
300 "2001:db8:aaaa:bbbb:cccc:dddd:eeee:001/128",
301 "2001:db8:aaaa:bbbb:cccc:dddd:eeee:01/128",
302 "2001:db8:aaaa:bbbb:cccc:dddd:eeee:1/128"
303 );
304 }
305
306
307
308
309 @Test
310 void testRfc5952Section22ZeroCompression() {
311 assertEquivalentSubnets(
312 "2001:db8:0:0:0:0:0:1/128",
313 "2001:db8:0:0:0::1/128",
314 "2001:db8:0:0::1/128",
315 "2001:db8:0::1/128",
316 "2001:db8::1/128"
317 );
318 }
319
320
321
322
323 @Test
324 void testRfc5952Section23CaseInsensitivity() {
325 assertEquivalentSubnets(
326 "2001:db8:aaaa:bbbb:cccc:dddd:eeee:aaaa/128",
327 "2001:db8:aaaa:bbbb:cccc:dddd:eeee:AAAA/128",
328 "2001:db8:aaaa:bbbb:cccc:dddd:eeee:AaAa/128",
329 "2001:DB8:AAAA:BBBB:CCCC:DDDD:EEEE:AAAA/128"
330 );
331 }
332
333
334
335
336
337 @Test
338 void testRfc5952Section41CanonicalLeadingZeros() {
339 final SubnetInfo a = new SubnetUtils6("2001:0db8::0001/128").getInfo();
340 final SubnetInfo b = new SubnetUtils6("2001:db8::1/128").getInfo();
341 assertEquals(a.getAddress(), b.getAddress());
342 }
343
344
345
346
347
348 @Test
349 void testRfc5952Section421MaximumShortening() {
350 final SubnetInfo a = new SubnetUtils6("2001:db8::0:1/128").getInfo();
351 final SubnetInfo b = new SubnetUtils6("2001:db8::1/128").getInfo();
352 assertEquals(a.getAddress(), b.getAddress());
353 }
354
355
356
357
358
359 @Test
360 void testRfc5952Section423FirstLongestRunCompressed() {
361 assertEquivalentSubnets(
362 "2001:db8:0:0:1:0:0:1/128",
363 "2001:db8::1:0:0:1/128",
364 "2001:db8:0:0:1::1/128"
365 );
366 }
367
368 @Test
369 void testRfc5952Section5SpecialAddresses() {
370 final SubnetInfo loopback = new SubnetUtils6("::1/128").getInfo();
371 assertEquals("0:0:0:0:0:0:0:1", loopback.getAddress());
372
373 final SubnetInfo unspecified = new SubnetUtils6("::/128").getInfo();
374 assertEquals("0:0:0:0:0:0:0:0", unspecified.getAddress());
375 }
376
377 @Test
378 void testToString() {
379 final SubnetUtils6 utils = new SubnetUtils6("2001:db8::1/64");
380 final SubnetInfo info = utils.getInfo();
381 final String str = utils.toString();
382
383 assertNotNull(str);
384 assertTrue(str.contains("CIDR Signature"));
385 assertTrue(str.contains("Network"));
386 assertTrue(str.contains("First address"));
387 assertTrue(str.contains("Last address"));
388 assertTrue(str.contains("Address Count"));
389
390
391 final String cidr = info.getCidrSignature();
392 final SubnetUtils6 roundTrip = new SubnetUtils6(cidr);
393 final SubnetInfo roundTripInfo = roundTrip.getInfo();
394 assertEquals(info.getPrefixLength(), roundTripInfo.getPrefixLength());
395 assertEquals(info.getNetworkAddress(), roundTripInfo.getNetworkAddress());
396 assertEquals(info.getHighAddress(), roundTripInfo.getHighAddress());
397 assertEquals(info.getAddressCount(), roundTripInfo.getAddressCount());
398 assertEquals(info.getCidrSignature(), roundTripInfo.getCidrSignature());
399 }
400
401 @Test
402 void testUniqueLocalAddress() {
403
404 final SubnetUtils6 utils = new SubnetUtils6("fd00::/8");
405 final SubnetInfo info = utils.getInfo();
406
407 assertTrue(info.isInRange("fd00::1"));
408 assertTrue(info.isInRange("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
409 assertFalse(info.isInRange("fc00::1"));
410 }
411 }