尝试从给定的IPv4映射IPv6地址派生IPv4地址

时间:2014-11-19 13:43:39

标签: java ip-address ipv6 ipv4

我的问题陈述说我可以接收IPv4地址或v4映射的v6地址作为InetSocketAddress实例。如果它是v4映射的v6地址,我将导出v4地址并使用它。

我正在阅读InetAddresses的javadoc,这就是它所说的:

 `Technically one can create a 128bit IPv6 address with the wire format of a
  "mapped" address, as shown above, and transmit it in an IPv6 packet header. 
  However, Java's InetAddress creation methods appear to adhere doggedly to the 
  original intent of the "mapped" address: all "mapped" addresses return 
  Inet4Address objects.`

我可以使用此库中的方法确定收到的地址是否是v4映射的v6地址,如下所示:

  // Input is InetSocketAddress socketAddress

  if (InetAddresses.isMappedIPv4Address(socketAddress.getAddress().getHostAddress())) {
        System.out.println("This is a v4 mapped v6 address");
  }

根据文档,没有一个库(InetSocketAddress,InetAddress或InetAddresses)提供了从这种映射输入中导出IPv4地址的方法。那么这是否意味着将从InetSocketAddress收到的InetAddress类型转换为Inet4Address就足够了?

 Inet4Address inetAddress = (Inet4Address) socketAddress.getAddress();

如果是这样,我甚至需要使用InetAddresses.isMappedIPv4Address吗?如何判断转换是否失败,或者给定的地址既不是有效的IPv4地址,也不是v4映射的v6地址,因此我可以抛出适当的异常?

1 个答案:

答案 0 :(得分:0)

The IPAddress Java library以多态方式支持IPv4和IPv6。它可以完成你在这里描述的内容。

首先,使用该库,使用您的InetSocketAddress,您可以获得IPAddress:

InetSocketAddress inetSocketAddress = ...;
IPAddress addr = IPAddress.from(inetSocketAddress.getAddress());

从那里,您可以检查IPv4或IPv6:

boolean isIpv4 = addr.isIpv4();
boolean isIpv6 = addr.isIpv6();

然后,如果是ipv6或ipv6,则可以使用关联的子类。如果是Ipv6,那么您可以检查地址是IPv4映射,IPv4兼容等。如果是这样,您可以获取派生的IPv4地址。之后,您可以转换回java.net类型实例。

if(isIpv4) {
    IPv4Address ipv4Address = addr.toIPv4();
    Inet4Address addr = ipv4Address.toInetAddress();
    ...
} else if(isIpv6) {
    IPv6Address ipv6Address = addr.toIPv6();
    if(ipv6Address.isIPv4Compatible() || ipv6Address.isIPv4Mapped()) {
        IPv4Address derivedIpv4Address = ipv6Address.getLowerIPv4Address();
        Inet4Address addr = ipv4Address.toInetAddress();
        ...
    }
}

链接上提供了javadoc。