001 /* 002 * Copyright (C) 2008 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 package com.google.common.net; 018 019 import com.google.common.annotations.Beta; 020 import com.google.common.base.Objects; 021 import com.google.common.base.Preconditions; 022 import com.google.common.hash.Hashing; 023 import com.google.common.io.ByteStreams; 024 import com.google.common.primitives.Ints; 025 026 import java.net.Inet4Address; 027 import java.net.Inet6Address; 028 import java.net.InetAddress; 029 import java.net.UnknownHostException; 030 import java.nio.ByteBuffer; 031 import java.util.Arrays; 032 033 import javax.annotation.Nullable; 034 035 /** 036 * Static utility methods pertaining to {@link InetAddress} instances. 037 * 038 * <p><b>Important note:</b> Unlike {@code InetAddress.getByName()}, the 039 * methods of this class never cause DNS services to be accessed. For 040 * this reason, you should prefer these methods as much as possible over 041 * their JDK equivalents whenever you are expecting to handle only 042 * IP address string literals -- there is no blocking DNS penalty for a 043 * malformed string. 044 * 045 * <p>This class hooks into the {@code sun.net.util.IPAddressUtil} class 046 * to make use of the {@code textToNumericFormatV4} and 047 * {@code textToNumericFormatV6} methods directly as a means to avoid 048 * accidentally traversing all nameservices (it can be vitally important 049 * to avoid, say, blocking on DNS at times). 050 * 051 * <p>When dealing with {@link Inet4Address} and {@link Inet6Address} 052 * objects as byte arrays (vis. {@code InetAddress.getAddress()}) they 053 * are 4 and 16 bytes in length, respectively, and represent the address 054 * in network byte order. 055 * 056 * <p>Examples of IP addresses and their byte representations: 057 * <ul> 058 * <li>The IPv4 loopback address, {@code "127.0.0.1"}.<br/> 059 * {@code 7f 00 00 01} 060 * 061 * <li>The IPv6 loopback address, {@code "::1"}.<br/> 062 * {@code 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01} 063 * 064 * <li>From the IPv6 reserved documentation prefix ({@code 2001:db8::/32}), 065 * {@code "2001:db8::1"}.<br/> 066 * {@code 20 01 0d b8 00 00 00 00 00 00 00 00 00 00 00 01} 067 * 068 * <li>An IPv6 "IPv4 compatible" (or "compat") address, 069 * {@code "::192.168.0.1"}.<br/> 070 * {@code 00 00 00 00 00 00 00 00 00 00 00 00 c0 a8 00 01} 071 * 072 * <li>An IPv6 "IPv4 mapped" address, {@code "::ffff:192.168.0.1"}.<br/> 073 * {@code 00 00 00 00 00 00 00 00 00 00 ff ff c0 a8 00 01} 074 * </ul> 075 * 076 * <p>A few notes about IPv6 "IPv4 mapped" addresses and their observed 077 * use in Java. 078 * <br><br> 079 * "IPv4 mapped" addresses were originally a representation of IPv4 080 * addresses for use on an IPv6 socket that could receive both IPv4 081 * and IPv6 connections (by disabling the {@code IPV6_V6ONLY} socket 082 * option on an IPv6 socket). Yes, it's confusing. Nevertheless, 083 * these "mapped" addresses were never supposed to be seen on the 084 * wire. That assumption was dropped, some say mistakenly, in later 085 * RFCs with the apparent aim of making IPv4-to-IPv6 transition simpler. 086 * 087 * <p>Technically one <i>can</i> create a 128bit IPv6 address with the wire 088 * format of a "mapped" address, as shown above, and transmit it in an 089 * IPv6 packet header. However, Java's InetAddress creation methods 090 * appear to adhere doggedly to the original intent of the "mapped" 091 * address: all "mapped" addresses return {@link Inet4Address} objects. 092 * 093 * <p>For added safety, it is common for IPv6 network operators to filter 094 * all packets where either the source or destination address appears to 095 * be a "compat" or "mapped" address. Filtering suggestions usually 096 * recommend discarding any packets with source or destination addresses 097 * in the invalid range {@code ::/3}, which includes both of these bizarre 098 * address formats. For more information on "bogons", including lists 099 * of IPv6 bogon space, see: 100 * 101 * <ul> 102 * <li><a target="_parent" 103 * href="http://en.wikipedia.org/wiki/Bogon_filtering" 104 * >http://en.wikipedia.org/wiki/Bogon_filtering</a> 105 * <li><a target="_parent" 106 * href="http://www.cymru.com/Bogons/ipv6.txt" 107 * >http://www.cymru.com/Bogons/ipv6.txt</a> 108 * <li><a target="_parent" 109 * href="http://www.cymru.com/Bogons/v6bogon.html" 110 * >http://www.cymru.com/Bogons/v6bogon.html</a> 111 * <li><a target="_parent" 112 * href="http://www.space.net/~gert/RIPE/ipv6-filters.html" 113 * >http://www.space.net/~gert/RIPE/ipv6-filters.html</a> 114 * </ul> 115 * 116 * @author Erik Kline 117 * @since 5.0 118 */ 119 @Beta 120 public final class InetAddresses { 121 private static final int IPV4_PART_COUNT = 4; 122 private static final int IPV6_PART_COUNT = 8; 123 private static final Inet4Address LOOPBACK4 = (Inet4Address) forString("127.0.0.1"); 124 private static final Inet4Address ANY4 = (Inet4Address) forString("0.0.0.0"); 125 126 private InetAddresses() {} 127 128 /** 129 * Returns an {@link Inet4Address}, given a byte array representation of the IPv4 address. 130 * 131 * @param bytes byte array representing an IPv4 address (should be of length 4) 132 * @return {@link Inet4Address} corresponding to the supplied byte array 133 * @throws IllegalArgumentException if a valid {@link Inet4Address} can not be created 134 */ 135 private static Inet4Address getInet4Address(byte[] bytes) { 136 Preconditions.checkArgument(bytes.length == 4, 137 "Byte array has invalid length for an IPv4 address: %s != 4.", 138 bytes.length); 139 140 // Given a 4-byte array, this cast should always succeed. 141 return (Inet4Address) bytesToInetAddress(bytes); 142 } 143 144 /** 145 * Returns the {@link InetAddress} having the given string representation. 146 * 147 * <p>This deliberately avoids all nameservice lookups (e.g. no DNS). 148 * 149 * @param ipString {@code String} containing an IPv4 or IPv6 string literal, e.g. 150 * {@code "192.168.0.1"} or {@code "2001:db8::1"} 151 * @return {@link InetAddress} representing the argument 152 * @throws IllegalArgumentException if the argument is not a valid IP string literal 153 */ 154 public static InetAddress forString(String ipString) { 155 byte[] addr = ipStringToBytes(ipString); 156 157 // The argument was malformed, i.e. not an IP string literal. 158 if (addr == null) { 159 throw new IllegalArgumentException( 160 String.format("'%s' is not an IP string literal.", ipString)); 161 } 162 163 return bytesToInetAddress(addr); 164 } 165 166 /** 167 * Returns {@code true} if the supplied string is a valid IP string 168 * literal, {@code false} otherwise. 169 * 170 * @param ipString {@code String} to evaluated as an IP string literal 171 * @return {@code true} if the argument is a valid IP string literal 172 */ 173 public static boolean isInetAddress(String ipString) { 174 return ipStringToBytes(ipString) != null; 175 } 176 177 private static byte[] ipStringToBytes(String ipString) { 178 // Make a first pass to categorize the characters in this string. 179 boolean hasColon = false; 180 boolean hasDot = false; 181 for (int i = 0; i < ipString.length(); i++) { 182 char c = ipString.charAt(i); 183 if (c == '.') { 184 hasDot = true; 185 } else if (c == ':') { 186 if (hasDot) { 187 return null; // Colons must not appear after dots. 188 } 189 hasColon = true; 190 } else if (Character.digit(c, 16) == -1) { 191 return null; // Everything else must be a decimal or hex digit. 192 } 193 } 194 195 // Now decide which address family to parse. 196 if (hasColon) { 197 if (hasDot) { 198 ipString = convertDottedQuadToHex(ipString); 199 if (ipString == null) { 200 return null; 201 } 202 } 203 return textToNumericFormatV6(ipString); 204 } else if (hasDot) { 205 return textToNumericFormatV4(ipString); 206 } 207 return null; 208 } 209 210 private static byte[] textToNumericFormatV4(String ipString) { 211 String[] address = ipString.split("\\.", IPV4_PART_COUNT + 1); 212 if (address.length != IPV4_PART_COUNT) { 213 return null; 214 } 215 216 byte[] bytes = new byte[IPV4_PART_COUNT]; 217 try { 218 for (int i = 0; i < bytes.length; i++) { 219 bytes[i] = parseOctet(address[i]); 220 } 221 } catch (NumberFormatException ex) { 222 return null; 223 } 224 225 return bytes; 226 } 227 228 private static byte[] textToNumericFormatV6(String ipString) { 229 // An address can have [2..8] colons, and N colons make N+1 parts. 230 String[] parts = ipString.split(":", IPV6_PART_COUNT + 2); 231 if (parts.length < 3 || parts.length > IPV6_PART_COUNT + 1) { 232 return null; 233 } 234 235 // Disregarding the endpoints, find "::" with nothing in between. 236 // This indicates that a run of zeroes has been skipped. 237 int skipIndex = -1; 238 for (int i = 1; i < parts.length - 1; i++) { 239 if (parts[i].length() == 0) { 240 if (skipIndex >= 0) { 241 return null; // Can't have more than one :: 242 } 243 skipIndex = i; 244 } 245 } 246 247 int partsHi; // Number of parts to copy from above/before the "::" 248 int partsLo; // Number of parts to copy from below/after the "::" 249 if (skipIndex >= 0) { 250 // If we found a "::", then check if it also covers the endpoints. 251 partsHi = skipIndex; 252 partsLo = parts.length - skipIndex - 1; 253 if (parts[0].length() == 0 && --partsHi != 0) { 254 return null; // ^: requires ^:: 255 } 256 if (parts[parts.length - 1].length() == 0 && --partsLo != 0) { 257 return null; // :$ requires ::$ 258 } 259 } else { 260 // Otherwise, allocate the entire address to partsHi. The endpoints 261 // could still be empty, but parseHextet() will check for that. 262 partsHi = parts.length; 263 partsLo = 0; 264 } 265 266 // If we found a ::, then we must have skipped at least one part. 267 // Otherwise, we must have exactly the right number of parts. 268 int partsSkipped = IPV6_PART_COUNT - (partsHi + partsLo); 269 if (!(skipIndex >= 0 ? partsSkipped >= 1 : partsSkipped == 0)) { 270 return null; 271 } 272 273 // Now parse the hextets into a byte array. 274 ByteBuffer rawBytes = ByteBuffer.allocate(2 * IPV6_PART_COUNT); 275 try { 276 for (int i = 0; i < partsHi; i++) { 277 rawBytes.putShort(parseHextet(parts[i])); 278 } 279 for (int i = 0; i < partsSkipped; i++) { 280 rawBytes.putShort((short) 0); 281 } 282 for (int i = partsLo; i > 0; i--) { 283 rawBytes.putShort(parseHextet(parts[parts.length - i])); 284 } 285 } catch (NumberFormatException ex) { 286 return null; 287 } 288 return rawBytes.array(); 289 } 290 291 private static String convertDottedQuadToHex(String ipString) { 292 int lastColon = ipString.lastIndexOf(':'); 293 String initialPart = ipString.substring(0, lastColon + 1); 294 String dottedQuad = ipString.substring(lastColon + 1); 295 byte[] quad = textToNumericFormatV4(dottedQuad); 296 if (quad == null) { 297 return null; 298 } 299 String penultimate = Integer.toHexString(((quad[0] & 0xff) << 8) | (quad[1] & 0xff)); 300 String ultimate = Integer.toHexString(((quad[2] & 0xff) << 8) | (quad[3] & 0xff)); 301 return initialPart + penultimate + ":" + ultimate; 302 } 303 304 private static byte parseOctet(String ipPart) { 305 // Note: we already verified that this string contains only hex digits. 306 int octet = Integer.parseInt(ipPart); 307 // Disallow leading zeroes, because no clear standard exists on 308 // whether these should be interpreted as decimal or octal. 309 if (octet > 255 || (ipPart.startsWith("0") && ipPart.length() > 1)) { 310 throw new NumberFormatException(); 311 } 312 return (byte) octet; 313 } 314 315 private static short parseHextet(String ipPart) { 316 // Note: we already verified that this string contains only hex digits. 317 int hextet = Integer.parseInt(ipPart, 16); 318 if (hextet > 0xffff) { 319 throw new NumberFormatException(); 320 } 321 return (short) hextet; 322 } 323 324 /** 325 * Convert a byte array into an InetAddress. 326 * 327 * {@link InetAddress#getByAddress} is documented as throwing a checked 328 * exception "if IP address if of illegal length." We replace it with 329 * an unchecked exception, for use by callers who already know that addr 330 * is an array of length 4 or 16. 331 * 332 * @param addr the raw 4-byte or 16-byte IP address in big-endian order 333 * @return an InetAddress object created from the raw IP address 334 */ 335 private static InetAddress bytesToInetAddress(byte[] addr) { 336 try { 337 return InetAddress.getByAddress(addr); 338 } catch (UnknownHostException e) { 339 throw new AssertionError(e); 340 } 341 } 342 343 /** 344 * Returns the string representation of an {@link InetAddress}. 345 * 346 * <p>For IPv4 addresses, this is identical to 347 * {@link InetAddress#getHostAddress()}, but for IPv6 addresses, the output 348 * follows <a href="http://tools.ietf.org/html/rfc5952">RFC 5952</a> 349 * section 4. The main difference is that this method uses "::" for zero 350 * compression, while Java's version uses the uncompressed form. 351 * 352 * <p>This method uses hexadecimal for all IPv6 addresses, including 353 * IPv4-mapped IPv6 addresses such as "::c000:201". The output does not 354 * include a Scope ID. 355 * 356 * @param ip {@link InetAddress} to be converted to an address string 357 * @return {@code String} containing the text-formatted IP address 358 * @since 10.0 359 */ 360 public static String toAddrString(InetAddress ip) { 361 Preconditions.checkNotNull(ip); 362 if (ip instanceof Inet4Address) { 363 // For IPv4, Java's formatting is good enough. 364 return ip.getHostAddress(); 365 } 366 Preconditions.checkArgument(ip instanceof Inet6Address); 367 byte[] bytes = ip.getAddress(); 368 int[] hextets = new int[IPV6_PART_COUNT]; 369 for (int i = 0; i < hextets.length; i++) { 370 hextets[i] = Ints.fromBytes( 371 (byte) 0, (byte) 0, bytes[2 * i], bytes[2 * i + 1]); 372 } 373 compressLongestRunOfZeroes(hextets); 374 return hextetsToIPv6String(hextets); 375 } 376 377 /** 378 * Identify and mark the longest run of zeroes in an IPv6 address. 379 * 380 * <p>Only runs of two or more hextets are considered. In case of a tie, the 381 * leftmost run wins. If a qualifying run is found, its hextets are replaced 382 * by the sentinel value -1. 383 * 384 * @param hextets {@code int[]} mutable array of eight 16-bit hextets 385 */ 386 private static void compressLongestRunOfZeroes(int[] hextets) { 387 int bestRunStart = -1; 388 int bestRunLength = -1; 389 int runStart = -1; 390 for (int i = 0; i < hextets.length + 1; i++) { 391 if (i < hextets.length && hextets[i] == 0) { 392 if (runStart < 0) { 393 runStart = i; 394 } 395 } else if (runStart >= 0) { 396 int runLength = i - runStart; 397 if (runLength > bestRunLength) { 398 bestRunStart = runStart; 399 bestRunLength = runLength; 400 } 401 runStart = -1; 402 } 403 } 404 if (bestRunLength >= 2) { 405 Arrays.fill(hextets, bestRunStart, bestRunStart + bestRunLength, -1); 406 } 407 } 408 409 /** 410 * Convert a list of hextets into a human-readable IPv6 address. 411 * 412 * <p>In order for "::" compression to work, the input should contain negative 413 * sentinel values in place of the elided zeroes. 414 * 415 * @param hextets {@code int[]} array of eight 16-bit hextets, or -1s 416 */ 417 private static String hextetsToIPv6String(int[] hextets) { 418 /* 419 * While scanning the array, handle these state transitions: 420 * start->num => "num" start->gap => "::" 421 * num->num => ":num" num->gap => "::" 422 * gap->num => "num" gap->gap => "" 423 */ 424 StringBuilder buf = new StringBuilder(39); 425 boolean lastWasNumber = false; 426 for (int i = 0; i < hextets.length; i++) { 427 boolean thisIsNumber = hextets[i] >= 0; 428 if (thisIsNumber) { 429 if (lastWasNumber) { 430 buf.append(':'); 431 } 432 buf.append(Integer.toHexString(hextets[i])); 433 } else { 434 if (i == 0 || lastWasNumber) { 435 buf.append("::"); 436 } 437 } 438 lastWasNumber = thisIsNumber; 439 } 440 return buf.toString(); 441 } 442 443 /** 444 * Returns the string representation of an {@link InetAddress} suitable 445 * for inclusion in a URI. 446 * 447 * <p>For IPv4 addresses, this is identical to 448 * {@link InetAddress#getHostAddress()}, but for IPv6 addresses it 449 * compresses zeroes and surrounds the text with square brackets; for example 450 * {@code "[2001:db8::1]"}. 451 * 452 * <p>Per section 3.2.2 of 453 * <a target="_parent" 454 * href="http://tools.ietf.org/html/rfc3986#section-3.2.2" 455 * >http://tools.ietf.org/html/rfc3986</a>, 456 * a URI containing an IPv6 string literal is of the form 457 * {@code "http://[2001:db8::1]:8888/index.html"}. 458 * 459 * <p>Use of either {@link InetAddresses#toAddrString}, 460 * {@link InetAddress#getHostAddress()}, or this method is recommended over 461 * {@link InetAddress#toString()} when an IP address string literal is 462 * desired. This is because {@link InetAddress#toString()} prints the 463 * hostname and the IP address string joined by a "/". 464 * 465 * @param ip {@link InetAddress} to be converted to URI string literal 466 * @return {@code String} containing URI-safe string literal 467 */ 468 public static String toUriString(InetAddress ip) { 469 if (ip instanceof Inet6Address) { 470 return "[" + toAddrString(ip) + "]"; 471 } 472 return toAddrString(ip); 473 } 474 475 /** 476 * Returns an InetAddress representing the literal IPv4 or IPv6 host 477 * portion of a URL, encoded in the format specified by RFC 3986 section 3.2.2. 478 * 479 * <p>This function is similar to {@link InetAddresses#forString(String)}, 480 * however, it requires that IPv6 addresses are surrounded by square brackets. 481 * 482 * <p>This function is the inverse of 483 * {@link InetAddresses#toUriString(java.net.InetAddress)}. 484 * 485 * @param hostAddr A RFC 3986 section 3.2.2 encoded IPv4 or IPv6 address 486 * @return an InetAddress representing the address in {@code hostAddr} 487 * @throws IllegalArgumentException if {@code hostAddr} is not a valid 488 * IPv4 address, or IPv6 address surrounded by square brackets 489 */ 490 public static InetAddress forUriString(String hostAddr) { 491 Preconditions.checkNotNull(hostAddr); 492 493 // Decide if this should be an IPv6 or IPv4 address. 494 String ipString; 495 int expectBytes; 496 if (hostAddr.startsWith("[") && hostAddr.endsWith("]")) { 497 ipString = hostAddr.substring(1, hostAddr.length() - 1); 498 expectBytes = 16; 499 } else { 500 ipString = hostAddr; 501 expectBytes = 4; 502 } 503 504 // Parse the address, and make sure the length/version is correct. 505 byte[] addr = ipStringToBytes(ipString); 506 if (addr == null || addr.length != expectBytes) { 507 throw new IllegalArgumentException( 508 String.format("Not a valid URI IP literal: '%s'", hostAddr)); 509 } 510 511 return bytesToInetAddress(addr); 512 } 513 514 /** 515 * Returns {@code true} if the supplied string is a valid URI IP string 516 * literal, {@code false} otherwise. 517 * 518 * @param ipString {@code String} to evaluated as an IP URI host string literal 519 * @return {@code true} if the argument is a valid IP URI host 520 */ 521 public static boolean isUriInetAddress(String ipString) { 522 try { 523 forUriString(ipString); 524 return true; 525 } catch (IllegalArgumentException e) { 526 return false; 527 } 528 } 529 530 /** 531 * Evaluates whether the argument is an IPv6 "compat" address. 532 * 533 * <p>An "IPv4 compatible", or "compat", address is one with 96 leading 534 * bits of zero, with the remaining 32 bits interpreted as an 535 * IPv4 address. These are conventionally represented in string 536 * literals as {@code "::192.168.0.1"}, though {@code "::c0a8:1"} is 537 * also considered an IPv4 compatible address (and equivalent to 538 * {@code "::192.168.0.1"}). 539 * 540 * <p>For more on IPv4 compatible addresses see section 2.5.5.1 of 541 * <a target="_parent" 542 * href="http://tools.ietf.org/html/rfc4291#section-2.5.5.1" 543 * >http://tools.ietf.org/html/rfc4291</a> 544 * 545 * <p>NOTE: This method is different from 546 * {@link Inet6Address#isIPv4CompatibleAddress} in that it more 547 * correctly classifies {@code "::"} and {@code "::1"} as 548 * proper IPv6 addresses (which they are), NOT IPv4 compatible 549 * addresses (which they are generally NOT considered to be). 550 * 551 * @param ip {@link Inet6Address} to be examined for embedded IPv4 compatible address format 552 * @return {@code true} if the argument is a valid "compat" address 553 */ 554 public static boolean isCompatIPv4Address(Inet6Address ip) { 555 if (!ip.isIPv4CompatibleAddress()) { 556 return false; 557 } 558 559 byte[] bytes = ip.getAddress(); 560 if ((bytes[12] == 0) && (bytes[13] == 0) && (bytes[14] == 0) 561 && ((bytes[15] == 0) || (bytes[15] == 1))) { 562 return false; 563 } 564 565 return true; 566 } 567 568 /** 569 * Returns the IPv4 address embedded in an IPv4 compatible address. 570 * 571 * @param ip {@link Inet6Address} to be examined for an embedded IPv4 address 572 * @return {@link Inet4Address} of the embedded IPv4 address 573 * @throws IllegalArgumentException if the argument is not a valid IPv4 compatible address 574 */ 575 public static Inet4Address getCompatIPv4Address(Inet6Address ip) { 576 Preconditions.checkArgument(isCompatIPv4Address(ip), 577 "Address '%s' is not IPv4-compatible.", toAddrString(ip)); 578 579 return getInet4Address(Arrays.copyOfRange(ip.getAddress(), 12, 16)); 580 } 581 582 /** 583 * Evaluates whether the argument is a 6to4 address. 584 * 585 * <p>6to4 addresses begin with the {@code "2002::/16"} prefix. 586 * The next 32 bits are the IPv4 address of the host to which 587 * IPv6-in-IPv4 tunneled packets should be routed. 588 * 589 * <p>For more on 6to4 addresses see section 2 of 590 * <a target="_parent" href="http://tools.ietf.org/html/rfc3056#section-2" 591 * >http://tools.ietf.org/html/rfc3056</a> 592 * 593 * @param ip {@link Inet6Address} to be examined for 6to4 address format 594 * @return {@code true} if the argument is a 6to4 address 595 */ 596 public static boolean is6to4Address(Inet6Address ip) { 597 byte[] bytes = ip.getAddress(); 598 return (bytes[0] == (byte) 0x20) && (bytes[1] == (byte) 0x02); 599 } 600 601 /** 602 * Returns the IPv4 address embedded in a 6to4 address. 603 * 604 * @param ip {@link Inet6Address} to be examined for embedded IPv4 in 6to4 address 605 * @return {@link Inet4Address} of embedded IPv4 in 6to4 address 606 * @throws IllegalArgumentException if the argument is not a valid IPv6 6to4 address 607 */ 608 public static Inet4Address get6to4IPv4Address(Inet6Address ip) { 609 Preconditions.checkArgument(is6to4Address(ip), 610 "Address '%s' is not a 6to4 address.", toAddrString(ip)); 611 612 return getInet4Address(Arrays.copyOfRange(ip.getAddress(), 2, 6)); 613 } 614 615 /** 616 * A simple immutable data class to encapsulate the information to be found in a 617 * Teredo address. 618 * 619 * <p>All of the fields in this class are encoded in various portions 620 * of the IPv6 address as part of the protocol. More protocols details 621 * can be found at: 622 * <a target="_parent" href="http://en.wikipedia.org/wiki/Teredo_tunneling" 623 * >http://en.wikipedia.org/wiki/Teredo_tunneling</a>. 624 * 625 * <p>The RFC can be found here: 626 * <a target="_parent" href="http://tools.ietf.org/html/rfc4380" 627 * >http://tools.ietf.org/html/rfc4380</a>. 628 * 629 * @since 5.0 630 */ 631 @Beta 632 public static final class TeredoInfo { 633 private final Inet4Address server; 634 private final Inet4Address client; 635 private final int port; 636 private final int flags; 637 638 /** 639 * Constructs a TeredoInfo instance. 640 * 641 * <p>Both server and client can be {@code null}, in which case the 642 * value {@code "0.0.0.0"} will be assumed. 643 * 644 * @throws IllegalArgumentException if either of the {@code port} or the {@code flags} 645 * arguments are out of range of an unsigned short 646 */ 647 // TODO: why is this public? 648 public TeredoInfo( 649 @Nullable Inet4Address server, @Nullable Inet4Address client, int port, int flags) { 650 Preconditions.checkArgument((port >= 0) && (port <= 0xffff), 651 "port '%s' is out of range (0 <= port <= 0xffff)", port); 652 Preconditions.checkArgument((flags >= 0) && (flags <= 0xffff), 653 "flags '%s' is out of range (0 <= flags <= 0xffff)", flags); 654 655 this.server = Objects.firstNonNull(server, ANY4); 656 this.client = Objects.firstNonNull(client, ANY4); 657 this.port = port; 658 this.flags = flags; 659 } 660 661 public Inet4Address getServer() { 662 return server; 663 } 664 665 public Inet4Address getClient() { 666 return client; 667 } 668 669 public int getPort() { 670 return port; 671 } 672 673 public int getFlags() { 674 return flags; 675 } 676 } 677 678 /** 679 * Evaluates whether the argument is a Teredo address. 680 * 681 * <p>Teredo addresses begin with the {@code "2001::/32"} prefix. 682 * 683 * @param ip {@link Inet6Address} to be examined for Teredo address format 684 * @return {@code true} if the argument is a Teredo address 685 */ 686 public static boolean isTeredoAddress(Inet6Address ip) { 687 byte[] bytes = ip.getAddress(); 688 return (bytes[0] == (byte) 0x20) && (bytes[1] == (byte) 0x01) 689 && (bytes[2] == 0) && (bytes[3] == 0); 690 } 691 692 /** 693 * Returns the Teredo information embedded in a Teredo address. 694 * 695 * @param ip {@link Inet6Address} to be examined for embedded Teredo information 696 * @return extracted {@code TeredoInfo} 697 * @throws IllegalArgumentException if the argument is not a valid IPv6 Teredo address 698 */ 699 public static TeredoInfo getTeredoInfo(Inet6Address ip) { 700 Preconditions.checkArgument(isTeredoAddress(ip), 701 "Address '%s' is not a Teredo address.", toAddrString(ip)); 702 703 byte[] bytes = ip.getAddress(); 704 Inet4Address server = getInet4Address(Arrays.copyOfRange(bytes, 4, 8)); 705 706 int flags = ByteStreams.newDataInput(bytes, 8).readShort() & 0xffff; 707 708 // Teredo obfuscates the mapped client port, per section 4 of the RFC. 709 int port = ~ByteStreams.newDataInput(bytes, 10).readShort() & 0xffff; 710 711 byte[] clientBytes = Arrays.copyOfRange(bytes, 12, 16); 712 for (int i = 0; i < clientBytes.length; i++) { 713 // Teredo obfuscates the mapped client IP, per section 4 of the RFC. 714 clientBytes[i] = (byte) ~clientBytes[i]; 715 } 716 Inet4Address client = getInet4Address(clientBytes); 717 718 return new TeredoInfo(server, client, port, flags); 719 } 720 721 /** 722 * Evaluates whether the argument is an ISATAP address. 723 * 724 * <p>From RFC 5214: "ISATAP interface identifiers are constructed in 725 * Modified EUI-64 format [...] by concatenating the 24-bit IANA OUI 726 * (00-00-5E), the 8-bit hexadecimal value 0xFE, and a 32-bit IPv4 727 * address in network byte order [...]" 728 * 729 * <p>For more on ISATAP addresses see section 6.1 of 730 * <a target="_parent" href="http://tools.ietf.org/html/rfc5214#section-6.1" 731 * >http://tools.ietf.org/html/rfc5214</a> 732 * 733 * @param ip {@link Inet6Address} to be examined for ISATAP address format 734 * @return {@code true} if the argument is an ISATAP address 735 */ 736 public static boolean isIsatapAddress(Inet6Address ip) { 737 738 // If it's a Teredo address with the right port (41217, or 0xa101) 739 // which would be encoded as 0x5efe then it can't be an ISATAP address. 740 if (isTeredoAddress(ip)) { 741 return false; 742 } 743 744 byte[] bytes = ip.getAddress(); 745 746 if ((bytes[8] | (byte) 0x03) != (byte) 0x03) { 747 748 // Verify that high byte of the 64 bit identifier is zero, modulo 749 // the U/L and G bits, with which we are not concerned. 750 return false; 751 } 752 753 return (bytes[9] == (byte) 0x00) && (bytes[10] == (byte) 0x5e) 754 && (bytes[11] == (byte) 0xfe); 755 } 756 757 /** 758 * Returns the IPv4 address embedded in an ISATAP address. 759 * 760 * @param ip {@link Inet6Address} to be examined for embedded IPv4 in ISATAP address 761 * @return {@link Inet4Address} of embedded IPv4 in an ISATAP address 762 * @throws IllegalArgumentException if the argument is not a valid IPv6 ISATAP address 763 */ 764 public static Inet4Address getIsatapIPv4Address(Inet6Address ip) { 765 Preconditions.checkArgument(isIsatapAddress(ip), 766 "Address '%s' is not an ISATAP address.", toAddrString(ip)); 767 768 return getInet4Address(Arrays.copyOfRange(ip.getAddress(), 12, 16)); 769 } 770 771 /** 772 * Examines the Inet6Address to determine if it is an IPv6 address of one 773 * of the specified address types that contain an embedded IPv4 address. 774 * 775 * <p>NOTE: ISATAP addresses are explicitly excluded from this method 776 * due to their trivial spoofability. With other transition addresses 777 * spoofing involves (at least) infection of one's BGP routing table. 778 * 779 * @param ip {@link Inet6Address} to be examined for embedded IPv4 client address 780 * @return {@code true} if there is an embedded IPv4 client address 781 * @since 7.0 782 */ 783 public static boolean hasEmbeddedIPv4ClientAddress(Inet6Address ip) { 784 return isCompatIPv4Address(ip) || is6to4Address(ip) || isTeredoAddress(ip); 785 } 786 787 /** 788 * Examines the Inet6Address to extract the embedded IPv4 client address 789 * if the InetAddress is an IPv6 address of one of the specified address 790 * types that contain an embedded IPv4 address. 791 * 792 * <p>NOTE: ISATAP addresses are explicitly excluded from this method 793 * due to their trivial spoofability. With other transition addresses 794 * spoofing involves (at least) infection of one's BGP routing table. 795 * 796 * @param ip {@link Inet6Address} to be examined for embedded IPv4 client address 797 * @return {@link Inet4Address} of embedded IPv4 client address 798 * @throws IllegalArgumentException if the argument does not have a valid embedded IPv4 address 799 */ 800 public static Inet4Address getEmbeddedIPv4ClientAddress(Inet6Address ip) { 801 if (isCompatIPv4Address(ip)) { 802 return getCompatIPv4Address(ip); 803 } 804 805 if (is6to4Address(ip)) { 806 return get6to4IPv4Address(ip); 807 } 808 809 if (isTeredoAddress(ip)) { 810 return getTeredoInfo(ip).getClient(); 811 } 812 813 throw new IllegalArgumentException( 814 String.format("'%s' has no embedded IPv4 address.", toAddrString(ip))); 815 } 816 817 /** 818 * Evaluates whether the argument is an "IPv4 mapped" IPv6 address. 819 * 820 * <p>An "IPv4 mapped" address is anything in the range ::ffff:0:0/96 821 * (sometimes written as ::ffff:0.0.0.0/96), with the last 32 bits 822 * interpreted as an IPv4 address. 823 * 824 * <p>For more on IPv4 mapped addresses see section 2.5.5.2 of 825 * <a target="_parent" 826 * href="http://tools.ietf.org/html/rfc4291#section-2.5.5.2" 827 * >http://tools.ietf.org/html/rfc4291</a> 828 * 829 * <p>Note: This method takes a {@code String} argument because 830 * {@link InetAddress} automatically collapses mapped addresses to IPv4. 831 * (It is actually possible to avoid this using one of the obscure 832 * {@link Inet6Address} methods, but it would be unwise to depend on such 833 * a poorly-documented feature.) 834 * 835 * @param ipString {@code String} to be examined for embedded IPv4-mapped IPv6 address format 836 * @return {@code true} if the argument is a valid "mapped" address 837 * @since 10.0 838 */ 839 public static boolean isMappedIPv4Address(String ipString) { 840 byte[] bytes = ipStringToBytes(ipString); 841 if (bytes != null && bytes.length == 16) { 842 for (int i = 0; i < 10; i++) { 843 if (bytes[i] != 0) { 844 return false; 845 } 846 } 847 for (int i = 10; i < 12; i++) { 848 if (bytes[i] != (byte) 0xff) { 849 return false; 850 } 851 } 852 return true; 853 } 854 return false; 855 } 856 857 /** 858 * Coerces an IPv6 address into an IPv4 address. 859 * 860 * <p>HACK: As long as applications continue to use IPv4 addresses for 861 * indexing into tables, accounting, et cetera, it may be necessary to 862 * <b>coerce</b> IPv6 addresses into IPv4 addresses. This function does 863 * so by hashing the upper 64 bits into {@code 224.0.0.0/3} 864 * (64 bits into 29 bits). 865 * 866 * <p>A "coerced" IPv4 address is equivalent to itself. 867 * 868 * <p>NOTE: This function is failsafe for security purposes: ALL IPv6 869 * addresses (except localhost (::1)) are hashed to avoid the security 870 * risk associated with extracting an embedded IPv4 address that might 871 * permit elevated privileges. 872 * 873 * @param ip {@link InetAddress} to "coerce" 874 * @return {@link Inet4Address} represented "coerced" address 875 * @since 7.0 876 */ 877 public static Inet4Address getCoercedIPv4Address(InetAddress ip) { 878 if (ip instanceof Inet4Address) { 879 return (Inet4Address) ip; 880 } 881 882 // Special cases: 883 byte[] bytes = ip.getAddress(); 884 boolean leadingBytesOfZero = true; 885 for (int i = 0; i < 15; ++i) { 886 if (bytes[i] != 0) { 887 leadingBytesOfZero = false; 888 break; 889 } 890 } 891 if (leadingBytesOfZero && (bytes[15] == 1)) { 892 return LOOPBACK4; // ::1 893 } else if (leadingBytesOfZero && (bytes[15] == 0)) { 894 return ANY4; // ::0 895 } 896 897 Inet6Address ip6 = (Inet6Address) ip; 898 long addressAsLong = 0; 899 if (hasEmbeddedIPv4ClientAddress(ip6)) { 900 addressAsLong = getEmbeddedIPv4ClientAddress(ip6).hashCode(); 901 } else { 902 903 // Just extract the high 64 bits (assuming the rest is user-modifiable). 904 addressAsLong = ByteBuffer.wrap(ip6.getAddress(), 0, 8).getLong(); 905 } 906 907 // Many strategies for hashing are possible. This might suffice for now. 908 int coercedHash = Hashing.murmur3_32().hashLong(addressAsLong).asInt(); 909 910 // Squash into 224/4 Multicast and 240/4 Reserved space (i.e. 224/3). 911 coercedHash |= 0xe0000000; 912 913 // Fixup to avoid some "illegal" values. Currently the only potential 914 // illegal value is 255.255.255.255. 915 if (coercedHash == 0xffffffff) { 916 coercedHash = 0xfffffffe; 917 } 918 919 return getInet4Address(Ints.toByteArray(coercedHash)); 920 } 921 922 /** 923 * Returns an integer representing an IPv4 address regardless of 924 * whether the supplied argument is an IPv4 address or not. 925 * 926 * <p>IPv6 addresses are <b>coerced</b> to IPv4 addresses before being 927 * converted to integers. 928 * 929 * <p>As long as there are applications that assume that all IP addresses 930 * are IPv4 addresses and can therefore be converted safely to integers 931 * (for whatever purpose) this function can be used to handle IPv6 932 * addresses as well until the application is suitably fixed. 933 * 934 * <p>NOTE: an IPv6 address coerced to an IPv4 address can only be used 935 * for such purposes as rudimentary identification or indexing into a 936 * collection of real {@link InetAddress}es. They cannot be used as 937 * real addresses for the purposes of network communication. 938 * 939 * @param ip {@link InetAddress} to convert 940 * @return {@code int}, "coerced" if ip is not an IPv4 address 941 * @since 7.0 942 */ 943 public static int coerceToInteger(InetAddress ip) { 944 return ByteStreams.newDataInput(getCoercedIPv4Address(ip).getAddress()).readInt(); 945 } 946 947 /** 948 * Returns an Inet4Address having the integer value specified by 949 * the argument. 950 * 951 * @param address {@code int}, the 32bit integer address to be converted 952 * @return {@link Inet4Address} equivalent of the argument 953 */ 954 public static Inet4Address fromInteger(int address) { 955 return getInet4Address(Ints.toByteArray(address)); 956 } 957 958 /** 959 * Returns an address from a <b>little-endian ordered</b> byte array 960 * (the opposite of what {@link InetAddress#getByAddress} expects). 961 * 962 * <p>IPv4 address byte array must be 4 bytes long and IPv6 byte array 963 * must be 16 bytes long. 964 * 965 * @param addr the raw IP address in little-endian byte order 966 * @return an InetAddress object created from the raw IP address 967 * @throws UnknownHostException if IP address is of illegal length 968 */ 969 public static InetAddress fromLittleEndianByteArray(byte[] addr) throws UnknownHostException { 970 byte[] reversed = new byte[addr.length]; 971 for (int i = 0; i < addr.length; i++) { 972 reversed[i] = addr[addr.length - i - 1]; 973 } 974 return InetAddress.getByAddress(reversed); 975 } 976 977 /** 978 * Returns a new InetAddress that is one more than the passed in address. 979 * This method works for both IPv4 and IPv6 addresses. 980 * 981 * @param address the InetAddress to increment 982 * @return a new InetAddress that is one more than the passed in address 983 * @throws IllegalArgumentException if InetAddress is at the end of its range 984 * @since 10.0 985 */ 986 public static InetAddress increment(InetAddress address) { 987 byte[] addr = address.getAddress(); 988 int i = addr.length - 1; 989 while (i >= 0 && addr[i] == (byte) 0xff) { 990 addr[i] = 0; 991 i--; 992 } 993 994 Preconditions.checkArgument(i >= 0, "Incrementing %s would wrap.", address); 995 996 addr[i]++; 997 return bytesToInetAddress(addr); 998 } 999 1000 /** 1001 * Returns true if the InetAddress is either 255.255.255.255 for IPv4 or 1002 * ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff for IPv6. 1003 * 1004 * @return true if the InetAddress is either 255.255.255.255 for IPv4 or 1005 * ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff for IPv6 1006 * @since 10.0 1007 */ 1008 public static boolean isMaximum(InetAddress address) { 1009 byte[] addr = address.getAddress(); 1010 for (int i = 0; i < addr.length; i++) { 1011 if (addr[i] != (byte) 0xff) { 1012 return false; 1013 } 1014 } 1015 return true; 1016 } 1017 }