【问题标题】:Why does Java interpret some IPv6 addresses as IPv4?为什么 Java 将某些 IPv6 地址解释为 IPv4?
【发布时间】:2021-07-30 00:36:54
【问题描述】:

为什么在使用InetAddress.getByName 时某些 IPv6 地址会转换为 IPv4 地址?

例如,我希望::f:f:f::ffff:f:f 这两个地址都转换为Inet6Address

但是,这个::ffff:f:f 变成了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
  }
}

【问题讨论】:

  • 您可以参考 IANA IPv6 Special-Purpose Address Registry 了解特殊 IPv6 地址范围。这不包括 IPv6 多播范围(ff00::/8 具有范围和标志,以及单独的 IANA 页面)和当前的全球 IPv6 地址范围 (2000::/3)。

标签: java ip ipv6 ipv4


【解决方案1】:

::ffff:0:0/96 范围内的 IPv6 地址是 IPv4 映射的 IPv6 地址。这是一个以 IPv6 寻址格式表示 IPv4 地址的特殊范围,因此它们实际上是 IPv4 地址,而不是 IPv6 地址。这在 RFC 4291, IP Version 6 Addressing Architecture 中有解释:

2.5.5.2。 IPv4 映射的 IPv6 地址

另一种包含嵌入式 IPv4 地址的 IPv6 地址是 定义。此地址类型用于表示 IPv4 的地址 节点作为 IPv6 地址。 “IPv4 映射的 IPv6 地址”的格式 如下:

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

有关背景信息,请参阅 [RFC4038] “IPv4映射的IPv6地址”的使用。

【讨论】: