1 /* 2 * Copyright (C) 2008 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.net; 18 19 import static com.google.common.truth.Truth.assertThat; 20 import static org.junit.Assert.assertThrows; 21 22 import com.google.common.collect.ImmutableSet; 23 import com.google.common.testing.NullPointerTester; 24 import java.math.BigInteger; 25 import java.net.Inet4Address; 26 import java.net.Inet6Address; 27 import java.net.InetAddress; 28 import java.net.UnknownHostException; 29 import junit.framework.TestCase; 30 31 /** 32 * Tests for {@link InetAddresses}. 33 * 34 * @author Erik Kline 35 */ 36 public class InetAddressesTest extends TestCase { 37 testNulls()38 public void testNulls() { 39 NullPointerTester tester = new NullPointerTester(); 40 41 tester.testAllPublicStaticMethods(InetAddresses.class); 42 } 43 testForStringBogusInput()44 public void testForStringBogusInput() { 45 ImmutableSet<String> bogusInputs = 46 ImmutableSet.of( 47 "", 48 "016.016.016.016", 49 "016.016.016", 50 "016.016", 51 "016", 52 "000.000.000.000", 53 "000", 54 "0x0a.0x0a.0x0a.0x0a", 55 "0x0a.0x0a.0x0a", 56 "0x0a.0x0a", 57 "0x0a", 58 "42.42.42.42.42", 59 "42.42.42", 60 "42.42", 61 "42", 62 "42..42.42", 63 "42..42.42.42", 64 "42.42.42.42.", 65 "42.42.42.42...", 66 ".42.42.42.42", 67 ".42.42.42", 68 "...42.42.42.42", 69 "42.42.42.-0", 70 "42.42.42.+0", 71 ".", 72 "...", 73 "bogus", 74 "bogus.com", 75 "192.168.0.1.com", 76 "12345.67899.-54321.-98765", 77 "257.0.0.0", 78 "42.42.42.-42", 79 "42.42.42.ab", 80 "3ffe::1.net", 81 "3ffe::1::1", 82 "1::2::3::4:5", 83 "::7:6:5:4:3:2:", // should end with ":0" 84 ":6:5:4:3:2:1::", // should begin with "0:" 85 "2001::db:::1", 86 "FEDC:9878", 87 "+1.+2.+3.4", 88 "1.2.3.4e0", 89 "6:5:4:3:2:1:0", // too few parts 90 "::7:6:5:4:3:2:1:0", // too many parts 91 "7:6:5:4:3:2:1:0::", // too many parts 92 "9:8:7:6:5:4:3::2:1", // too many parts 93 "0:1:2:3::4:5:6:7", // :: must remove at least one 0. 94 "3ffe:0:0:0:0:0:0:0:1", // too many parts (9 instead of 8) 95 "3ffe::10000", // hextet exceeds 16 bits 96 "3ffe::goog", 97 "3ffe::-0", 98 "3ffe::+0", 99 "3ffe::-1", 100 ":", 101 ":::", 102 "::1.2.3", 103 "::1.2.3.4.5", 104 "::1.2.3.4:", 105 "1.2.3.4::", 106 "2001:db8::1:", 107 ":2001:db8::1", 108 ":1:2:3:4:5:6:7", 109 "1:2:3:4:5:6:7:", 110 ":1:2:3:4:5:6:"); 111 112 for (String bogusInput : bogusInputs) { 113 assertThrows( 114 "IllegalArgumentException expected for '" + bogusInput + "'", 115 IllegalArgumentException.class, 116 () -> InetAddresses.forString(bogusInput)); 117 assertFalse(InetAddresses.isInetAddress(bogusInput)); 118 } 119 } 120 test3ff31()121 public void test3ff31() { 122 assertThrows(IllegalArgumentException.class, () -> InetAddresses.forString("3ffe:::1")); 123 assertFalse(InetAddresses.isInetAddress("016.016.016.016")); 124 } 125 testForStringIPv4Input()126 public void testForStringIPv4Input() throws UnknownHostException { 127 String ipStr = "192.168.0.1"; 128 // Shouldn't hit DNS, because it's an IP string literal. 129 InetAddress ipv4Addr = InetAddress.getByName(ipStr); 130 assertEquals(ipv4Addr, InetAddresses.forString(ipStr)); 131 assertTrue(InetAddresses.isInetAddress(ipStr)); 132 } 133 testForStringIPv4NonAsciiInput()134 public void testForStringIPv4NonAsciiInput() throws UnknownHostException { 135 String ipStr = "૧૯૨.૧૬૮.૦.૧"; // 192.168.0.1 in Gujarati digits 136 // Shouldn't hit DNS, because it's an IP string literal. 137 InetAddress ipv4Addr; 138 try { 139 ipv4Addr = InetAddress.getByName(ipStr); 140 } catch (UnknownHostException e) { 141 // OK: this is probably Android, which is stricter. 142 return; 143 } 144 assertEquals(ipv4Addr, InetAddresses.forString(ipStr)); 145 assertTrue(InetAddresses.isInetAddress(ipStr)); 146 } 147 testForStringIPv6Input()148 public void testForStringIPv6Input() throws UnknownHostException { 149 String ipStr = "3ffe::1"; 150 // Shouldn't hit DNS, because it's an IP string literal. 151 InetAddress ipv6Addr = InetAddress.getByName(ipStr); 152 assertEquals(ipv6Addr, InetAddresses.forString(ipStr)); 153 assertTrue(InetAddresses.isInetAddress(ipStr)); 154 } 155 testForStringIPv6NonAsciiInput()156 public void testForStringIPv6NonAsciiInput() throws UnknownHostException { 157 String ipStr = "૩ffe::૧"; // 3ffe::1 with Gujarati digits for 3 and 1 158 // Shouldn't hit DNS, because it's an IP string literal. 159 InetAddress ipv6Addr; 160 try { 161 ipv6Addr = InetAddress.getByName(ipStr); 162 } catch (UnknownHostException e) { 163 // OK: this is probably Android, which is stricter. 164 return; 165 } 166 assertEquals(ipv6Addr, InetAddresses.forString(ipStr)); 167 assertTrue(InetAddresses.isInetAddress(ipStr)); 168 } 169 testForStringIPv6EightColons()170 public void testForStringIPv6EightColons() throws UnknownHostException { 171 ImmutableSet<String> eightColons = 172 ImmutableSet.of("::7:6:5:4:3:2:1", "::7:6:5:4:3:2:0", "7:6:5:4:3:2:1::", "0:6:5:4:3:2:1::"); 173 174 for (String ipString : eightColons) { 175 // Shouldn't hit DNS, because it's an IP string literal. 176 InetAddress ipv6Addr = InetAddress.getByName(ipString); 177 assertEquals(ipv6Addr, InetAddresses.forString(ipString)); 178 assertTrue(InetAddresses.isInetAddress(ipString)); 179 } 180 } 181 testConvertDottedQuadToHex()182 public void testConvertDottedQuadToHex() throws UnknownHostException { 183 ImmutableSet<String> ipStrings = 184 ImmutableSet.of("7::0.128.0.127", "7::0.128.0.128", "7::128.128.0.127", "7::0.128.128.127"); 185 186 for (String ipString : ipStrings) { 187 // Shouldn't hit DNS, because it's an IP string literal. 188 InetAddress ipv6Addr = InetAddress.getByName(ipString); 189 assertEquals(ipv6Addr, InetAddresses.forString(ipString)); 190 assertTrue(InetAddresses.isInetAddress(ipString)); 191 } 192 } 193 194 // see https://github.com/google/guava/issues/2587 195 private static final ImmutableSet<String> SCOPE_IDS = 196 ImmutableSet.of("eno1", "en1", "eth0", "X", "1", "2", "14", "20"); 197 testIPv4AddressWithScopeId()198 public void testIPv4AddressWithScopeId() { 199 ImmutableSet<String> ipStrings = ImmutableSet.of("1.2.3.4", "192.168.0.1"); 200 for (String ipString : ipStrings) { 201 for (String scopeId : SCOPE_IDS) { 202 String withScopeId = ipString + "%" + scopeId; 203 assertFalse( 204 "InetAddresses.isInetAddress(" + withScopeId + ") should be false but was true", 205 InetAddresses.isInetAddress(withScopeId)); 206 } 207 } 208 } 209 testDottedQuadAddressWithScopeId()210 public void testDottedQuadAddressWithScopeId() { 211 ImmutableSet<String> ipStrings = 212 ImmutableSet.of("7::0.128.0.127", "7::0.128.0.128", "7::128.128.0.127", "7::0.128.128.127"); 213 for (String ipString : ipStrings) { 214 for (String scopeId : SCOPE_IDS) { 215 String withScopeId = ipString + "%" + scopeId; 216 assertFalse( 217 "InetAddresses.isInetAddress(" + withScopeId + ") should be false but was true", 218 InetAddresses.isInetAddress(withScopeId)); 219 } 220 } 221 } 222 testIPv6AddressWithScopeId()223 public void testIPv6AddressWithScopeId() { 224 ImmutableSet<String> ipStrings = 225 ImmutableSet.of( 226 "0:0:0:0:0:0:0:1", 227 "fe80::a", 228 "fe80::1", 229 "fe80::2", 230 "fe80::42", 231 "fe80::3dd0:7f8e:57b7:34d5", 232 "fe80::71a3:2b00:ddd3:753f", 233 "fe80::8b2:d61e:e5c:b333", 234 "fe80::b059:65f4:e877:c40"); 235 for (String ipString : ipStrings) { 236 for (String scopeId : SCOPE_IDS) { 237 String withScopeId = ipString + "%" + scopeId; 238 assertTrue( 239 "InetAddresses.isInetAddress(" + withScopeId + ") should be true but was false", 240 InetAddresses.isInetAddress(withScopeId)); 241 assertEquals(InetAddresses.forString(withScopeId), InetAddresses.forString(ipString)); 242 } 243 } 244 } 245 testToAddrStringIPv4()246 public void testToAddrStringIPv4() { 247 // Don't need to test IPv4 much; it just calls getHostAddress(). 248 assertEquals("1.2.3.4", InetAddresses.toAddrString(InetAddresses.forString("1.2.3.4"))); 249 } 250 testToAddrStringIPv6()251 public void testToAddrStringIPv6() { 252 assertEquals( 253 "1:2:3:4:5:6:7:8", InetAddresses.toAddrString(InetAddresses.forString("1:2:3:4:5:6:7:8"))); 254 assertEquals( 255 "2001:0:0:4::8", InetAddresses.toAddrString(InetAddresses.forString("2001:0:0:4:0:0:0:8"))); 256 assertEquals( 257 "2001::4:5:6:7:8", 258 InetAddresses.toAddrString(InetAddresses.forString("2001:0:0:4:5:6:7:8"))); 259 assertEquals( 260 "2001:0:3:4:5:6:7:8", 261 InetAddresses.toAddrString(InetAddresses.forString("2001:0:3:4:5:6:7:8"))); 262 assertEquals( 263 "0:0:3::ffff", InetAddresses.toAddrString(InetAddresses.forString("0:0:3:0:0:0:0:ffff"))); 264 assertEquals( 265 "::4:0:0:0:ffff", 266 InetAddresses.toAddrString(InetAddresses.forString("0:0:0:4:0:0:0:ffff"))); 267 assertEquals( 268 "::5:0:0:ffff", InetAddresses.toAddrString(InetAddresses.forString("0:0:0:0:5:0:0:ffff"))); 269 assertEquals( 270 "1::4:0:0:7:8", InetAddresses.toAddrString(InetAddresses.forString("1:0:0:4:0:0:7:8"))); 271 assertEquals("::", InetAddresses.toAddrString(InetAddresses.forString("0:0:0:0:0:0:0:0"))); 272 assertEquals("::1", InetAddresses.toAddrString(InetAddresses.forString("0:0:0:0:0:0:0:1"))); 273 assertEquals( 274 "2001:658:22a:cafe::", 275 InetAddresses.toAddrString(InetAddresses.forString("2001:0658:022a:cafe::"))); 276 assertEquals("::102:304", InetAddresses.toAddrString(InetAddresses.forString("::1.2.3.4"))); 277 } 278 testToUriStringIPv4()279 public void testToUriStringIPv4() { 280 String ipStr = "1.2.3.4"; 281 InetAddress ip = InetAddresses.forString(ipStr); 282 assertEquals("1.2.3.4", InetAddresses.toUriString(ip)); 283 } 284 testToUriStringIPv6()285 public void testToUriStringIPv6() { 286 // Unfortunately the InetAddress.toString() method for IPv6 addresses 287 // does not collapse contiguous shorts of zeroes with the :: abbreviation. 288 String ipStr = "3ffe::1"; 289 InetAddress ip = InetAddresses.forString(ipStr); 290 assertEquals("[3ffe::1]", InetAddresses.toUriString(ip)); 291 } 292 testForUriStringIPv4()293 public void testForUriStringIPv4() { 294 Inet4Address expected = (Inet4Address) InetAddresses.forString("192.168.1.1"); 295 assertEquals(expected, InetAddresses.forUriString("192.168.1.1")); 296 } 297 testForUriStringIPv6()298 public void testForUriStringIPv6() { 299 Inet6Address expected = (Inet6Address) InetAddresses.forString("3ffe:0:0:0:0:0:0:1"); 300 assertEquals(expected, InetAddresses.forUriString("[3ffe:0:0:0:0:0:0:1]")); 301 } 302 testForUriStringIPv4Mapped()303 public void testForUriStringIPv4Mapped() { 304 Inet4Address expected = (Inet4Address) InetAddresses.forString("192.0.2.1"); 305 assertEquals(expected, InetAddresses.forUriString("[::ffff:192.0.2.1]")); 306 } 307 testIsUriInetAddress()308 public void testIsUriInetAddress() { 309 assertTrue(InetAddresses.isUriInetAddress("192.168.1.1")); 310 assertTrue(InetAddresses.isUriInetAddress("[3ffe:0:0:0:0:0:0:1]")); 311 assertTrue(InetAddresses.isUriInetAddress("[::ffff:192.0.2.1]")); 312 313 assertFalse(InetAddresses.isUriInetAddress("[192.168.1.1")); 314 assertFalse(InetAddresses.isUriInetAddress("192.168.1.1]")); 315 assertFalse(InetAddresses.isUriInetAddress("")); 316 assertFalse(InetAddresses.isUriInetAddress("192.168.999.888")); 317 assertFalse(InetAddresses.isUriInetAddress("www.google.com")); 318 assertFalse(InetAddresses.isUriInetAddress("1:2e")); 319 assertFalse(InetAddresses.isUriInetAddress("[3ffe:0:0:0:0:0:0:1")); 320 assertFalse(InetAddresses.isUriInetAddress("3ffe:0:0:0:0:0:0:1]")); 321 assertFalse(InetAddresses.isUriInetAddress("3ffe:0:0:0:0:0:0:1")); 322 assertFalse(InetAddresses.isUriInetAddress("::ffff:192.0.2.1")); 323 } 324 testForUriStringBad()325 public void testForUriStringBad() { 326 assertThrows(IllegalArgumentException.class, () -> InetAddresses.forUriString("")); 327 328 assertThrows( 329 IllegalArgumentException.class, () -> InetAddresses.forUriString("192.168.999.888")); 330 331 assertThrows( 332 IllegalArgumentException.class, () -> InetAddresses.forUriString("www.google.com")); 333 334 assertThrows(IllegalArgumentException.class, () -> InetAddresses.forUriString("[1:2e]")); 335 336 assertThrows(IllegalArgumentException.class, () -> InetAddresses.forUriString("[192.168.1.1]")); 337 338 assertThrows(IllegalArgumentException.class, () -> InetAddresses.forUriString("192.168.1.1]")); 339 340 assertThrows(IllegalArgumentException.class, () -> InetAddresses.forUriString("[192.168.1.1")); 341 342 assertThrows( 343 IllegalArgumentException.class, () -> InetAddresses.forUriString("[3ffe:0:0:0:0:0:0:1")); 344 345 assertThrows( 346 IllegalArgumentException.class, () -> InetAddresses.forUriString("3ffe:0:0:0:0:0:0:1]")); 347 348 assertThrows( 349 IllegalArgumentException.class, () -> InetAddresses.forUriString("3ffe:0:0:0:0:0:0:1")); 350 351 assertThrows( 352 IllegalArgumentException.class, () -> InetAddresses.forUriString("::ffff:192.0.2.1")); 353 } 354 testCompatIPv4Addresses()355 public void testCompatIPv4Addresses() { 356 ImmutableSet<String> nonCompatAddresses = ImmutableSet.of("3ffe::1", "::", "::1"); 357 358 for (String nonCompatAddress : nonCompatAddresses) { 359 InetAddress ip = InetAddresses.forString(nonCompatAddress); 360 assertFalse(InetAddresses.isCompatIPv4Address((Inet6Address) ip)); 361 assertThrows( 362 "IllegalArgumentException expected for '" + nonCompatAddress + "'", 363 IllegalArgumentException.class, 364 () -> InetAddresses.getCompatIPv4Address((Inet6Address) ip)); 365 } 366 367 ImmutableSet<String> validCompatAddresses = ImmutableSet.of("::1.2.3.4", "::102:304"); 368 String compatStr = "1.2.3.4"; 369 InetAddress compat = InetAddresses.forString(compatStr); 370 371 for (String validCompatAddress : validCompatAddresses) { 372 InetAddress ip = InetAddresses.forString(validCompatAddress); 373 assertTrue("checking '" + validCompatAddress + "'", ip instanceof Inet6Address); 374 assertTrue( 375 "checking '" + validCompatAddress + "'", 376 InetAddresses.isCompatIPv4Address((Inet6Address) ip)); 377 assertEquals( 378 "checking '" + validCompatAddress + "'", 379 compat, 380 InetAddresses.getCompatIPv4Address((Inet6Address) ip)); 381 } 382 } 383 testMappedIPv4Addresses()384 public void testMappedIPv4Addresses() throws UnknownHostException { 385 /* 386 * Verify that it is not possible to instantiate an Inet6Address 387 * from an "IPv4 mapped" IPv6 address. Our String-based method can 388 * at least identify them, however. 389 */ 390 String mappedStr = "::ffff:192.168.0.1"; 391 assertTrue(InetAddresses.isMappedIPv4Address(mappedStr)); 392 InetAddress mapped = InetAddresses.forString(mappedStr); 393 assertThat(mapped).isNotInstanceOf(Inet6Address.class); 394 assertEquals(InetAddress.getByName("192.168.0.1"), mapped); 395 396 // check upper case 397 mappedStr = "::FFFF:192.168.0.1"; 398 assertTrue(InetAddresses.isMappedIPv4Address(mappedStr)); 399 mapped = InetAddresses.forString(mappedStr); 400 assertThat(mapped).isNotInstanceOf(Inet6Address.class); 401 assertEquals(InetAddress.getByName("192.168.0.1"), mapped); 402 403 mappedStr = "0:00:000:0000:0:ffff:1.2.3.4"; 404 assertTrue(InetAddresses.isMappedIPv4Address(mappedStr)); 405 mapped = InetAddresses.forString(mappedStr); 406 assertThat(mapped).isNotInstanceOf(Inet6Address.class); 407 assertEquals(InetAddress.getByName("1.2.3.4"), mapped); 408 409 mappedStr = "::ffff:0102:0304"; 410 assertTrue(InetAddresses.isMappedIPv4Address(mappedStr)); 411 mapped = InetAddresses.forString(mappedStr); 412 assertThat(mapped).isNotInstanceOf(Inet6Address.class); 413 assertEquals(InetAddress.getByName("1.2.3.4"), mapped); 414 415 assertFalse(InetAddresses.isMappedIPv4Address("::")); 416 assertFalse(InetAddresses.isMappedIPv4Address("::ffff")); 417 assertFalse(InetAddresses.isMappedIPv4Address("::ffff:0")); 418 assertFalse(InetAddresses.isMappedIPv4Address("::fffe:0:0")); 419 assertFalse(InetAddresses.isMappedIPv4Address("::1:ffff:0:0")); 420 assertFalse(InetAddresses.isMappedIPv4Address("foo")); 421 assertFalse(InetAddresses.isMappedIPv4Address("192.0.2.1")); 422 } 423 test6to4Addresses()424 public void test6to4Addresses() { 425 ImmutableSet<String> non6to4Addresses = ImmutableSet.of("::1.2.3.4", "3ffe::1", "::", "::1"); 426 427 for (String non6to4Address : non6to4Addresses) { 428 InetAddress ip = InetAddresses.forString(non6to4Address); 429 assertFalse(InetAddresses.is6to4Address((Inet6Address) ip)); 430 assertThrows( 431 "IllegalArgumentException expected for '" + non6to4Address + "'", 432 IllegalArgumentException.class, 433 () -> InetAddresses.get6to4IPv4Address((Inet6Address) ip)); 434 } 435 436 String valid6to4Address = "2002:0102:0304::1"; 437 String ipv4Str = "1.2.3.4"; 438 439 InetAddress ipv4 = InetAddresses.forString(ipv4Str); 440 InetAddress ip = InetAddresses.forString(valid6to4Address); 441 assertTrue(InetAddresses.is6to4Address((Inet6Address) ip)); 442 assertEquals(ipv4, InetAddresses.get6to4IPv4Address((Inet6Address) ip)); 443 } 444 testTeredoAddresses()445 public void testTeredoAddresses() { 446 ImmutableSet<String> nonTeredoAddresses = ImmutableSet.of("::1.2.3.4", "3ffe::1", "::", "::1"); 447 448 for (String nonTeredoAddress : nonTeredoAddresses) { 449 InetAddress ip = InetAddresses.forString(nonTeredoAddress); 450 assertFalse(InetAddresses.isTeredoAddress((Inet6Address) ip)); 451 assertThrows( 452 "IllegalArgumentException expected for '" + nonTeredoAddress + "'", 453 IllegalArgumentException.class, 454 () -> InetAddresses.getTeredoInfo((Inet6Address) ip)); 455 } 456 457 String validTeredoAddress = "2001:0000:4136:e378:8000:63bf:3fff:fdd2"; 458 String serverStr = "65.54.227.120"; 459 String clientStr = "192.0.2.45"; 460 int port = 40000; 461 int flags = 0x8000; 462 463 InetAddress ip = InetAddresses.forString(validTeredoAddress); 464 assertTrue(InetAddresses.isTeredoAddress((Inet6Address) ip)); 465 InetAddresses.TeredoInfo teredo = InetAddresses.getTeredoInfo((Inet6Address) ip); 466 467 InetAddress server = InetAddresses.forString(serverStr); 468 assertEquals(server, teredo.getServer()); 469 470 InetAddress client = InetAddresses.forString(clientStr); 471 assertEquals(client, teredo.getClient()); 472 473 assertEquals(port, teredo.getPort()); 474 assertEquals(flags, teredo.getFlags()); 475 } 476 testTeredoAddress_nullServer()477 public void testTeredoAddress_nullServer() { 478 InetAddresses.TeredoInfo info = new InetAddresses.TeredoInfo(null, null, 80, 1000); 479 assertEquals(InetAddresses.forString("0.0.0.0"), info.getServer()); 480 assertEquals(InetAddresses.forString("0.0.0.0"), info.getClient()); 481 assertEquals(80, info.getPort()); 482 assertEquals(1000, info.getFlags()); 483 } 484 testIsatapAddresses()485 public void testIsatapAddresses() { 486 InetAddress ipv4 = InetAddresses.forString("1.2.3.4"); 487 ImmutableSet<String> validIsatapAddresses = 488 ImmutableSet.of( 489 "2001:db8::5efe:102:304", 490 "2001:db8::100:5efe:102:304", // Private Multicast? Not likely. 491 "2001:db8::200:5efe:102:304", 492 "2001:db8::300:5efe:102:304" // Public Multicast? Also unlikely. 493 ); 494 ImmutableSet<String> nonIsatapAddresses = 495 ImmutableSet.of( 496 "::1.2.3.4", 497 "3ffe::1", 498 "::", 499 "::1", 500 "2001:db8::0040:5efe:102:304", 501 "2001:db8::5ffe:102:304", 502 "2001:db8::5eff:102:304", 503 "2001:0:102:203:200:5efe:506:708" // Teredo address; not ISATAP 504 ); 505 506 for (String validIsatapAddress : validIsatapAddresses) { 507 InetAddress ip = InetAddresses.forString(validIsatapAddress); 508 assertTrue(InetAddresses.isIsatapAddress((Inet6Address) ip)); 509 assertEquals( 510 "checking '" + validIsatapAddress + "'", 511 ipv4, 512 InetAddresses.getIsatapIPv4Address((Inet6Address) ip)); 513 } 514 for (String nonIsatapAddress : nonIsatapAddresses) { 515 InetAddress ip = InetAddresses.forString(nonIsatapAddress); 516 assertFalse(InetAddresses.isIsatapAddress((Inet6Address) ip)); 517 assertThrows( 518 "IllegalArgumentException expected for '" + nonIsatapAddress + "'", 519 IllegalArgumentException.class, 520 () -> InetAddresses.getIsatapIPv4Address((Inet6Address) ip)); 521 } 522 } 523 testGetEmbeddedIPv4ClientAddress()524 public void testGetEmbeddedIPv4ClientAddress() { 525 Inet6Address testIp; 526 527 // Test regular global unicast address. 528 testIp = (Inet6Address) InetAddresses.forString("2001:db8::1"); 529 assertFalse(InetAddresses.hasEmbeddedIPv4ClientAddress(testIp)); 530 531 // Test ISATAP address. 532 testIp = (Inet6Address) InetAddresses.forString("2001:db8::5efe:102:304"); 533 assertFalse(InetAddresses.hasEmbeddedIPv4ClientAddress(testIp)); 534 535 // Test compat address. 536 testIp = (Inet6Address) InetAddresses.forString("::1.2.3.4"); 537 assertTrue(InetAddresses.hasEmbeddedIPv4ClientAddress(testIp)); 538 InetAddress ipv4 = InetAddresses.forString("1.2.3.4"); 539 assertEquals(ipv4, InetAddresses.getEmbeddedIPv4ClientAddress(testIp)); 540 541 // Test 6to4 address. 542 testIp = (Inet6Address) InetAddresses.forString("2002:0102:0304::1"); 543 assertTrue(InetAddresses.hasEmbeddedIPv4ClientAddress(testIp)); 544 ipv4 = InetAddresses.forString("1.2.3.4"); 545 assertEquals(ipv4, InetAddresses.getEmbeddedIPv4ClientAddress(testIp)); 546 547 // Test Teredo address. 548 testIp = (Inet6Address) InetAddresses.forString("2001:0000:4136:e378:8000:63bf:3fff:fdd2"); 549 assertTrue(InetAddresses.hasEmbeddedIPv4ClientAddress(testIp)); 550 ipv4 = InetAddresses.forString("192.0.2.45"); 551 assertEquals(ipv4, InetAddresses.getEmbeddedIPv4ClientAddress(testIp)); 552 } 553 testGetCoercedIPv4Address()554 public void testGetCoercedIPv4Address() { 555 // Check that a coerced IPv4 address is unaltered. 556 assertThat(InetAddresses.getCoercedIPv4Address(InetAddresses.forString("127.0.0.1"))) 557 .isEqualTo(InetAddresses.forString("127.0.0.1")); 558 559 // ::1 special case 560 assertThat(InetAddresses.getCoercedIPv4Address(InetAddresses.forString("::1"))) 561 .isEqualTo(InetAddresses.forString("127.0.0.1")); 562 563 // :: special case 564 assertThat(InetAddresses.getCoercedIPv4Address(InetAddresses.forString("::"))) 565 .isEqualTo(InetAddresses.forString("0.0.0.0")); 566 567 // test compat address (should be hashed) 568 assertThat(InetAddresses.getCoercedIPv4Address(InetAddresses.forString("::1.2.3.4"))) 569 .isNotEqualTo(InetAddresses.forString("1.2.3.4")); 570 571 // test 6to4 address (should be hashed) 572 assertThat(InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2002:0102:0304::1"))) 573 .isNotEqualTo(InetAddresses.forString("1.2.3.4")); 574 575 // 2 6to4 addresses differing in the embedded IPv4 address should 576 // hash to the different values. 577 assertThat(InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2002:0102:0304::1"))) 578 .isNotEqualTo( 579 InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2002:0506:0708::1"))); 580 581 // 2 6to4 addresses NOT differing in the embedded IPv4 address should 582 // hash to the same value. 583 assertThat(InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2002:0102:0304::1"))) 584 .isEqualTo( 585 InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2002:0102:0304::2"))); 586 587 // test Teredo address (should be hashed) 588 assertThat( 589 InetAddresses.getCoercedIPv4Address( 590 InetAddresses.forString("2001:0000:4136:e378:8000:63bf:3fff:fdd2"))) 591 .isNotEqualTo(InetAddresses.forString("192.0.2.45")); 592 593 // 2 Teredo addresses differing in their embedded IPv4 addresses should hash to different 594 // values. 595 assertThat( 596 InetAddresses.getCoercedIPv4Address( 597 InetAddresses.forString("2001:0000:4136:e378:8000:63bf:3fff:fdd2"))) 598 .isNotEqualTo( 599 InetAddresses.getCoercedIPv4Address( 600 InetAddresses.forString("2001:0000:4136:e378:8000:63bf:3fff:fdd3"))); 601 602 // 2 Teredo addresses NOT differing in their embedded IPv4 addresses should hash to the same 603 // value. 604 assertThat( 605 InetAddresses.getCoercedIPv4Address( 606 InetAddresses.forString("2001:0000:4136:e378:8000:63bf:3fff:fdd2"))) 607 .isEqualTo( 608 InetAddresses.getCoercedIPv4Address( 609 InetAddresses.forString("2001:0000:5136:f378:9000:73bf:3fff:fdd2"))); 610 611 // Test that an address hashes in to the 224.0.0.0/3 number-space. 612 int coercedInt = 613 InetAddresses.coerceToInteger( 614 InetAddresses.getCoercedIPv4Address(InetAddresses.forString("2001:4860::1"))); 615 assertThat(coercedInt).isAtLeast(0xe0000000); 616 assertThat(coercedInt).isAtMost(0xfffffffe); 617 } 618 testCoerceToInteger()619 public void testCoerceToInteger() { 620 assertThat(InetAddresses.coerceToInteger(InetAddresses.forString("127.0.0.1"))) 621 .isEqualTo(0x7f000001); 622 } 623 testFromInteger()624 public void testFromInteger() { 625 assertThat(InetAddresses.fromInteger(0x7f000001)) 626 .isEqualTo(InetAddresses.forString("127.0.0.1")); 627 } 628 testFromLittleEndianByteArray()629 public void testFromLittleEndianByteArray() throws UnknownHostException { 630 assertEquals( 631 InetAddresses.fromLittleEndianByteArray(new byte[] {1, 2, 3, 4}), 632 InetAddress.getByAddress(new byte[] {4, 3, 2, 1})); 633 634 assertEquals( 635 InetAddresses.fromLittleEndianByteArray( 636 new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}), 637 InetAddress.getByAddress( 638 new byte[] {16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1})); 639 640 assertThrows( 641 UnknownHostException.class, () -> InetAddresses.fromLittleEndianByteArray(new byte[3])); 642 } 643 testIsMaximum()644 public void testIsMaximum() throws UnknownHostException { 645 InetAddress address = InetAddress.getByName("255.255.255.254"); 646 assertFalse(InetAddresses.isMaximum(address)); 647 648 address = InetAddress.getByName("255.255.255.255"); 649 assertTrue(InetAddresses.isMaximum(address)); 650 651 address = InetAddress.getByName("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe"); 652 assertFalse(InetAddresses.isMaximum(address)); 653 654 address = InetAddress.getByName("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); 655 assertTrue(InetAddresses.isMaximum(address)); 656 } 657 testIncrementIPv4()658 public void testIncrementIPv4() throws UnknownHostException { 659 InetAddress address_66_0 = InetAddress.getByName("172.24.66.0"); 660 InetAddress address_66_255 = InetAddress.getByName("172.24.66.255"); 661 InetAddress address_67_0 = InetAddress.getByName("172.24.67.0"); 662 663 InetAddress address = address_66_0; 664 for (int i = 0; i < 255; i++) { 665 address = InetAddresses.increment(address); 666 } 667 assertEquals(address_66_255, address); 668 669 address = InetAddresses.increment(address); 670 assertEquals(address_67_0, address); 671 672 InetAddress address_ffffff = InetAddress.getByName("255.255.255.255"); 673 assertThrows(IllegalArgumentException.class, () -> InetAddresses.increment(address_ffffff)); 674 } 675 testIncrementIPv6()676 public void testIncrementIPv6() throws UnknownHostException { 677 InetAddress addressV6_66_0 = InetAddress.getByName("2001:db8::6600"); 678 InetAddress addressV6_66_ff = InetAddress.getByName("2001:db8::66ff"); 679 InetAddress addressV6_67_0 = InetAddress.getByName("2001:db8::6700"); 680 681 InetAddress address = addressV6_66_0; 682 for (int i = 0; i < 255; i++) { 683 address = InetAddresses.increment(address); 684 } 685 assertEquals(addressV6_66_ff, address); 686 687 address = InetAddresses.increment(address); 688 assertEquals(addressV6_67_0, address); 689 690 InetAddress addressV6_ffffff = InetAddress.getByName("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); 691 assertThrows(IllegalArgumentException.class, () -> InetAddresses.increment(addressV6_ffffff)); 692 } 693 testDecrementIPv4()694 public void testDecrementIPv4() throws UnknownHostException { 695 InetAddress address660 = InetAddress.getByName("172.24.66.0"); 696 InetAddress address66255 = InetAddress.getByName("172.24.66.255"); 697 InetAddress address670 = InetAddress.getByName("172.24.67.0"); 698 699 InetAddress address = address670; 700 address = InetAddresses.decrement(address); 701 702 assertEquals(address66255, address); 703 704 for (int i = 0; i < 255; i++) { 705 address = InetAddresses.decrement(address); 706 } 707 assertEquals(address660, address); 708 709 InetAddress address0000 = InetAddress.getByName("0.0.0.0"); 710 assertThrows(IllegalArgumentException.class, () -> InetAddresses.decrement(address0000)); 711 } 712 testDecrementIPv6()713 public void testDecrementIPv6() throws UnknownHostException { 714 InetAddress addressV6660 = InetAddress.getByName("2001:db8::6600"); 715 InetAddress addressV666ff = InetAddress.getByName("2001:db8::66ff"); 716 InetAddress addressV6670 = InetAddress.getByName("2001:db8::6700"); 717 718 InetAddress address = addressV6670; 719 address = InetAddresses.decrement(address); 720 721 assertEquals(addressV666ff, address); 722 723 for (int i = 0; i < 255; i++) { 724 address = InetAddresses.decrement(address); 725 } 726 assertEquals(addressV6660, address); 727 728 InetAddress addressV6000000 = InetAddress.getByName("0:0:0:0:0:0:0:0"); 729 assertThrows(IllegalArgumentException.class, () -> InetAddresses.decrement(addressV6000000)); 730 } 731 testFromIpv4BigIntegerThrowsLessThanZero()732 public void testFromIpv4BigIntegerThrowsLessThanZero() { 733 IllegalArgumentException expected = 734 assertThrows( 735 IllegalArgumentException.class, 736 () -> InetAddresses.fromIPv4BigInteger(BigInteger.valueOf(-1L))); 737 assertEquals("BigInteger must be greater than or equal to 0", expected.getMessage()); 738 } 739 testFromIpv6BigIntegerThrowsLessThanZero()740 public void testFromIpv6BigIntegerThrowsLessThanZero() { 741 IllegalArgumentException expected = 742 assertThrows( 743 IllegalArgumentException.class, 744 () -> InetAddresses.fromIPv6BigInteger(BigInteger.valueOf(-1L))); 745 assertEquals("BigInteger must be greater than or equal to 0", expected.getMessage()); 746 } 747 testFromIpv4BigIntegerValid()748 public void testFromIpv4BigIntegerValid() { 749 checkBigIntegerConversion("0.0.0.0", BigInteger.ZERO); 750 checkBigIntegerConversion("0.0.0.1", BigInteger.ONE); 751 checkBigIntegerConversion("127.255.255.255", BigInteger.valueOf(Integer.MAX_VALUE)); 752 checkBigIntegerConversion( 753 "255.255.255.254", BigInteger.valueOf(Integer.MAX_VALUE).multiply(BigInteger.valueOf(2))); 754 checkBigIntegerConversion( 755 "255.255.255.255", BigInteger.ONE.shiftLeft(32).subtract(BigInteger.ONE)); 756 } 757 testFromIpv6BigIntegerValid()758 public void testFromIpv6BigIntegerValid() { 759 checkBigIntegerConversion("::", BigInteger.ZERO); 760 checkBigIntegerConversion("::1", BigInteger.ONE); 761 checkBigIntegerConversion("::7fff:ffff", BigInteger.valueOf(Integer.MAX_VALUE)); 762 checkBigIntegerConversion("::7fff:ffff:ffff:ffff", BigInteger.valueOf(Long.MAX_VALUE)); 763 checkBigIntegerConversion( 764 "::ffff:ffff:ffff:ffff", BigInteger.ONE.shiftLeft(64).subtract(BigInteger.ONE)); 765 checkBigIntegerConversion( 766 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 767 BigInteger.ONE.shiftLeft(128).subtract(BigInteger.ONE)); 768 } 769 testFromIpv4BigIntegerInputTooLarge()770 public void testFromIpv4BigIntegerInputTooLarge() { 771 IllegalArgumentException expected = 772 assertThrows( 773 IllegalArgumentException.class, 774 () -> 775 InetAddresses.fromIPv4BigInteger(BigInteger.ONE.shiftLeft(32).add(BigInteger.ONE))); 776 assertEquals( 777 "BigInteger cannot be converted to InetAddress because it has more than 4 bytes:" 778 + " 4294967297", 779 expected.getMessage()); 780 } 781 testFromIpv6BigIntegerInputTooLarge()782 public void testFromIpv6BigIntegerInputTooLarge() { 783 IllegalArgumentException expected = 784 assertThrows( 785 IllegalArgumentException.class, 786 () -> 787 InetAddresses.fromIPv6BigInteger( 788 BigInteger.ONE.shiftLeft(128).add(BigInteger.ONE))); 789 assertEquals( 790 "BigInteger cannot be converted to InetAddress because it has more than 16 bytes:" 791 + " 340282366920938463463374607431768211457", 792 expected.getMessage()); 793 } 794 795 /** Checks that the IP converts to the big integer and the big integer converts to the IP. */ checkBigIntegerConversion(String ip, BigInteger bigIntegerIp)796 private static void checkBigIntegerConversion(String ip, BigInteger bigIntegerIp) { 797 InetAddress address = InetAddresses.forString(ip); 798 boolean isIpv6 = address instanceof Inet6Address; 799 assertEquals(bigIntegerIp, InetAddresses.toBigInteger(address)); 800 assertEquals( 801 address, 802 isIpv6 803 ? InetAddresses.fromIPv6BigInteger(bigIntegerIp) 804 : InetAddresses.fromIPv4BigInteger(bigIntegerIp)); 805 } 806 } 807