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