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
}
}
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".