/** * Evaluates whether the argument is a 6to4 address. * * <p>6to4 addresses begin with the {@code "2002::/16"} prefix. The next 32 bits are the IPv4 * address of the host to which IPv6-in-IPv4 tunneled packets should be routed. * * <p>For more on 6to4 addresses see section 2 of <a target="_parent" * href="http://tools.ietf.org/html/rfc3056#section-2">RFC 3056</a>. * * @param ip {@link Inet6Address} to be examined for 6to4 address format * @return {@code true} if the argument is a 6to4 address */ public static boolean is6to4Address(Inet6Address ip) { byte[] bytes = ip.getAddress(); return (bytes[0] == (byte) 0x20) && (bytes[1] == (byte) 0x02); }
/** * Evaluates whether the argument is a Teredo address. * * <p>Teredo addresses begin with the {@code "2001::/32"} prefix. * * @param ip {@link Inet6Address} to be examined for Teredo address format * @return {@code true} if the argument is a Teredo address */ public static boolean isTeredoAddress(Inet6Address ip) { byte[] bytes = ip.getAddress(); return (bytes[0] == (byte) 0x20) && (bytes[1] == (byte) 0x01) && (bytes[2] == 0) && (bytes[3] == 0); }
/** * Evaluates whether the argument is a 6to4 address. * * <p>6to4 addresses begin with the {@code "2002::/16"} prefix. The next 32 bits are the IPv4 * address of the host to which IPv6-in-IPv4 tunneled packets should be routed. * * <p>For more on 6to4 addresses see section 2 of <a target="_parent" * href="http://tools.ietf.org/html/rfc3056#section-2">RFC 3056</a>. * * @param ip {@link Inet6Address} to be examined for 6to4 address format * @return {@code true} if the argument is a 6to4 address */ public static boolean is6to4Address(Inet6Address ip) { byte[] bytes = ip.getAddress(); return (bytes[0] == (byte) 0x20) && (bytes[1] == (byte) 0x02); }
/** * Evaluates whether the argument is a Teredo address. * * <p>Teredo addresses begin with the {@code "2001::/32"} prefix. * * @param ip {@link Inet6Address} to be examined for Teredo address format * @return {@code true} if the argument is a Teredo address */ public static boolean isTeredoAddress(Inet6Address ip) { byte[] bytes = ip.getAddress(); return (bytes[0] == (byte) 0x20) && (bytes[1] == (byte) 0x01) && (bytes[2] == 0) && (bytes[3] == 0); }
/** * Evaluates whether the argument is a Teredo address. * * <p>Teredo addresses begin with the {@code "2001::/32"} prefix. * * @param ip {@link Inet6Address} to be examined for Teredo address format * @return {@code true} if the argument is a Teredo address */ public static boolean isTeredoAddress(Inet6Address ip) { byte[] bytes = ip.getAddress(); return (bytes[0] == (byte) 0x20) && (bytes[1] == (byte) 0x01) && (bytes[2] == 0) && (bytes[3] == 0); }
private static BigInteger ipToInt(Inet6Address ipAddress) { byte[] octets = ipAddress.getAddress(); assert octets.length == 16; return new BigInteger(octets); }
private static Inet4Address toIPv4Address(Inet6Address a6) { byte[] b6 = a6.getAddress(); byte[] b4 = { b6[12], b6[13], b6[14], b6[15] }; try { return (Inet4Address) InetAddress.getByAddress(b4); } catch (UnknownHostException e) { throw new Error(e); } } }
/** * Creates a compressed URL style representation of an Inet6Address. * * <p>This method copies and adopts code from Google's Guava library. * We re-implement this here in order to reduce dependency on Guava. * The Guava library has frequently caused dependency conflicts in the past. */ private static String getIPv6UrlRepresentation(Inet6Address address) { return getIPv6UrlRepresentation(address.getAddress()); }
/** * Evaluates whether the argument is an ISATAP address. * * <p>From RFC 5214: "ISATAP interface identifiers are constructed in Modified EUI-64 format [...] * by concatenating the 24-bit IANA OUI (00-00-5E), the 8-bit hexadecimal value 0xFE, and a 32-bit * IPv4 address in network byte order [...]" * * <p>For more on ISATAP addresses see section 6.1 of <a target="_parent" * href="http://tools.ietf.org/html/rfc5214#section-6.1">RFC 5214</a>. * * @param ip {@link Inet6Address} to be examined for ISATAP address format * @return {@code true} if the argument is an ISATAP address */ public static boolean isIsatapAddress(Inet6Address ip) { // If it's a Teredo address with the right port (41217, or 0xa101) // which would be encoded as 0x5efe then it can't be an ISATAP address. if (isTeredoAddress(ip)) { return false; } byte[] bytes = ip.getAddress(); if ((bytes[8] | (byte) 0x03) != (byte) 0x03) { // Verify that high byte of the 64 bit identifier is zero, modulo // the U/L and G bits, with which we are not concerned. return false; } return (bytes[9] == (byte) 0x00) && (bytes[10] == (byte) 0x5e) && (bytes[11] == (byte) 0xfe); }
byte[] bytes = ip.getAddress(); if ((bytes[12] == 0) && (bytes[13] == 0)
/** * Returns the IPv4 address embedded in a 6to4 address. * * @param ip {@link Inet6Address} to be examined for embedded IPv4 in 6to4 address * @return {@link Inet4Address} of embedded IPv4 in 6to4 address * @throws IllegalArgumentException if the argument is not a valid IPv6 6to4 address */ public static Inet4Address get6to4IPv4Address(Inet6Address ip) { checkArgument(is6to4Address(ip), "Address '%s' is not a 6to4 address.", toAddrString(ip)); return getInet4Address(Arrays.copyOfRange(ip.getAddress(), 2, 6)); }
/** * Returns the IPv4 address embedded in an IPv4 compatible address. * * @param ip {@link Inet6Address} to be examined for an embedded IPv4 address * @return {@link Inet4Address} of the embedded IPv4 address * @throws IllegalArgumentException if the argument is not a valid IPv4 compatible address */ public static Inet4Address getCompatIPv4Address(Inet6Address ip) { checkArgument( isCompatIPv4Address(ip), "Address '%s' is not IPv4-compatible.", toAddrString(ip)); return getInet4Address(Arrays.copyOfRange(ip.getAddress(), 12, 16)); }
/** * Returns the IPv4 address embedded in an ISATAP address. * * @param ip {@link Inet6Address} to be examined for embedded IPv4 in ISATAP address * @return {@link Inet4Address} of embedded IPv4 in an ISATAP address * @throws IllegalArgumentException if the argument is not a valid IPv6 ISATAP address */ public static Inet4Address getIsatapIPv4Address(Inet6Address ip) { checkArgument(isIsatapAddress(ip), "Address '%s' is not an ISATAP address.", toAddrString(ip)); return getInet4Address(Arrays.copyOfRange(ip.getAddress(), 12, 16)); }
/** * Returns the IPv4 address embedded in a 6to4 address. * * @param ip {@link Inet6Address} to be examined for embedded IPv4 in 6to4 address * @return {@link Inet4Address} of embedded IPv4 in 6to4 address * @throws IllegalArgumentException if the argument is not a valid IPv6 6to4 address */ public static Inet4Address get6to4IPv4Address(Inet6Address ip) { checkArgument(is6to4Address(ip), "Address '%s' is not a 6to4 address.", toAddrString(ip)); return getInet4Address(Arrays.copyOfRange(ip.getAddress(), 2, 6)); }
/** * Returns the IPv4 address embedded in an IPv4 compatible address. * * @param ip {@link Inet6Address} to be examined for an embedded IPv4 address * @return {@link Inet4Address} of the embedded IPv4 address * @throws IllegalArgumentException if the argument is not a valid IPv4 compatible address */ public static Inet4Address getCompatIPv4Address(Inet6Address ip) { checkArgument( isCompatIPv4Address(ip), "Address '%s' is not IPv4-compatible.", toAddrString(ip)); return getInet4Address(Arrays.copyOfRange(ip.getAddress(), 12, 16)); }
/** * Returns the IPv4 address embedded in an ISATAP address. * * @param ip {@link Inet6Address} to be examined for embedded IPv4 in ISATAP address * @return {@link Inet4Address} of embedded IPv4 in an ISATAP address * @throws IllegalArgumentException if the argument is not a valid IPv6 ISATAP address */ public static Inet4Address getIsatapIPv4Address(Inet6Address ip) { checkArgument(isIsatapAddress(ip), "Address '%s' is not an ISATAP address.", toAddrString(ip)); return getInet4Address(Arrays.copyOfRange(ip.getAddress(), 12, 16)); }
/** * Returns the IPv4 address embedded in a 6to4 address. * * @param ip {@link Inet6Address} to be examined for embedded IPv4 in 6to4 address * @return {@link Inet4Address} of embedded IPv4 in 6to4 address * @throws IllegalArgumentException if the argument is not a valid IPv6 6to4 address */ public static Inet4Address get6to4IPv4Address(Inet6Address ip) { checkArgument(is6to4Address(ip), "Address '%s' is not a 6to4 address.", toAddrString(ip)); return getInet4Address(Arrays.copyOfRange(ip.getAddress(), 2, 6)); }
/** * Returns the IPv4 address embedded in an ISATAP address. * * @param ip {@link Inet6Address} to be examined for embedded IPv4 in ISATAP address * @return {@link Inet4Address} of embedded IPv4 in an ISATAP address * @throws IllegalArgumentException if the argument is not a valid IPv6 ISATAP address */ public static Inet4Address getIsatapIPv4Address(Inet6Address ip) { checkArgument(isIsatapAddress(ip), "Address '%s' is not an ISATAP address.", toAddrString(ip)); return getInet4Address(Arrays.copyOfRange(ip.getAddress(), 12, 16)); }
/** * Returns the IPv4 address embedded in an IPv4 compatible address. * * @param ip {@link Inet6Address} to be examined for an embedded IPv4 address * @return {@link Inet4Address} of the embedded IPv4 address * @throws IllegalArgumentException if the argument is not a valid IPv4 compatible address */ public static Inet4Address getCompatIPv4Address(Inet6Address ip) { checkArgument( isCompatIPv4Address(ip), "Address '%s' is not IPv4-compatible.", toAddrString(ip)); return getInet4Address(Arrays.copyOfRange(ip.getAddress(), 12, 16)); }
/** * Returns the Teredo information embedded in a Teredo address. * * @param ip {@link Inet6Address} to be examined for embedded Teredo information * @return extracted {@code TeredoInfo} * @throws IllegalArgumentException if the argument is not a valid IPv6 Teredo address */ public static TeredoInfo getTeredoInfo(Inet6Address ip) { checkArgument(isTeredoAddress(ip), "Address '%s' is not a Teredo address.", toAddrString(ip)); byte[] bytes = ip.getAddress(); Inet4Address server = getInet4Address(Arrays.copyOfRange(bytes, 4, 8)); int flags = ByteStreams.newDataInput(bytes, 8).readShort() & 0xffff; // Teredo obfuscates the mapped client port, per section 4 of the RFC. int port = ~ByteStreams.newDataInput(bytes, 10).readShort() & 0xffff; byte[] clientBytes = Arrays.copyOfRange(bytes, 12, 16); for (int i = 0; i < clientBytes.length; i++) { // Teredo obfuscates the mapped client IP, per section 4 of the RFC. clientBytes[i] = (byte) ~clientBytes[i]; } Inet4Address client = getInet4Address(clientBytes); return new TeredoInfo(server, client, port, flags); }