Search code examples
javaipipv6ipv4

Why does Java interpret some IPv6 addresses as IPv4?


Why are certain IPv6 addresses converted to IPv4 addresses when using InetAddress.getByName?

For example, I expect both of these addresses ::f:f:f, ::ffff:f:f to be converted to Inet6Address

However, this one ::ffff:f:f becomes Inet4Address

import java.net.InetAddress;
class Main {
  public static void main(String[] args) throws Exception {
    // Interpreted as IPv6
    var address = InetAddress.getByName("::f:f:f");
    System.out.println(address); // /0:0:0:0:0:f:f:f
    System.out.println(address.getClass()); // class java.net.Inet6Address
    
    // Interpreted as IPv4
    address = InetAddress.getByName("::ffff:f:f");
    System.out.println(address); // /103.30.217.152
    System.out.println(address.getClass()); // class java.net.Inet4Address
  }
}

Solution

  • IPv6 addresses in the ::ffff:0:0/96 range are IPv4-Mapped IPv6 addresses. This is a special range to represent IPv4 addresses in the IPv6 addressing format, so those actually are IPv4 addresses, not IPv6 addresses. This is explained in RFC 4291, IP Version 6 Addressing Architecture:

    2.5.5.2. IPv4-Mapped IPv6 Address

    A second type of IPv6 address that holds an embedded IPv4 address is defined. This address type is used to represent the addresses of IPv4 nodes as IPv6 addresses. The format of the "IPv4-mapped IPv6 address" is as follows:

       |                80 bits               | 16 |      32 bits        |
       +--------------------------------------+--------------------------+
       |0000..............................0000|FFFF|    IPv4 address     |
       +--------------------------------------+----+---------------------+
    

    See [RFC4038] for background on the usage of the "IPv4-mapped IPv6 address".