1

所以有几个网站会为你计算你的本地链接 ipv6 地址,就像这里的这个。

然而,对于如何计算这个地址以及输入参数是什么,它没有给出任何有用的信息。那么,如果知道 ipv4 地址、子网掩码和网关地址,那么计算链路本地 ipv6 地址的过程(或算法)是什么?我正在做一个使用 ISATAP 网络隧道的 SCTP 套接字项目,并且 LL ipv6 地址用于构建 ISATAP 地址。

4

3 回答 3

4

RFC 4291 的附录 A描述了从 MAC 地址计算修改后的 EUI-64 的方法。一旦你有了修改后的 EUI-64,你只需把它放在地址的低 64 位,然后把fe80::放在高 64 位。

基本上你翻转 MAC 地址的第 7 位,并打包它的前 24 位(包括翻转的位),然后是 fffe,然后是 MAC 地址的低 24 位,总共 64 位。

话虽如此,您的问题是如何从 IPv4 地址和子网掩码派生链接本地地址。那,你做不到。IPv4 地址和子网掩码(如果确实有一个 - IPv6 根本不需要 IPv4 在同一接口上运行)与 IPv6 地址无关,并且两者没有任何关系。IPv4 网关地址(同样,如果有的话)甚至更不相关。

于 2013-05-26T20:19:06.433 回答
3

链路本地地址可以基于RFC 4862的 MAC 地址,也可以根据RFC 4941随机生成。

通常这应该限制在全局范围内,但一些系统将此隐私扩展实现扩展到链接本地范围。 按照这个关于 serverfault 的问题来讨论这个话题

于 2013-05-27T00:14:46.383 回答
0

The previous answers failed to note that there is a defined procedure for generating a link local IPv6 address from an IPv4 address when using ISATAP, and there is a different process for generating a link local IPv6 address from a MAC address. The two things are unrelated.

For ISATAP, the 32-bit IPv4 address is prepended wit the 96 bits of either fe80::200:5efe or fe80::200:5efe to get the 128-bit IPv6 link-local address.

For MAC to IPv6, the 48-bit MAC address is split in half, 16 bits are inserted in the middle, those bits being ff:fe, then it is prepended by the 64-bit link-local prefix fe80::, and finally the 7th bit in the 5th IPv6 segment is flipped, to get the 128-bit IPv6 link-local address.

The following code provides examples showing how to use the The IPAddress library to do the conversions in either Java or Go. Disclaimer: I am the project manager of those libraries.

These examples also help to visualize the conversions described above.

Go:

func convertToIsatap(ipv4Str string, isGlobal bool) string {
    ipv4Address := ipaddr.NewIPAddressString(ipv4Str).GetAddress().ToIPv4()
    zero := &ipaddr.IPv6AddressSegment{}
    segments := make([]*ipaddr.IPv6AddressSegment, ipaddr.IPv6SegmentCount)
    segments[1], segments[2], segments[3], segments[4] = zero, zero, zero, zero
    segments[0] = ipaddr.NewIPv6Segment(0xfe80)
    segments[5] = ipaddr.NewIPv6Segment(0x5efe)
    if isGlobal {
        segments[4] = ipaddr.NewIPv6Segment(0x200)
    }
    ipv6Address, _ := ipv4Address.GetIPv6Address(ipaddr.NewIPv6Section(segments))
    return ipv6Address.String()
}

func convertToLinkLocalIPv6(macAddr string) string {
    macAddress := ipaddr.NewMACAddressString(macAddr).GetAddress()
    ipv6LinkLocal, _ := macAddress.ToLinkLocalIPv6()
    return ipv6LinkLocal.String()
}

fmt.Println("1.2.3.4 becomes ISATAP " + 
    convertToIsatap("1.2.3.4", true))
fmt.Println("aa:bb:cc:11:22:33 becomes " + 
    convertToLinkLocalIPv6("aa:bb:cc:11:22:33"))

Java:

static String convertToIsatap(String ipv4Str, boolean isGlobal) {
    IPv4Address ipv4Address = new IPAddressString(ipv4Str).getAddress().toIPv4();
    IPv6AddressSegment zeroSeg = new IPv6AddressSegment(0);
    IPv6AddressSegment segments[] = 
        new IPv6AddressSegment[IPv6Address.SEGMENT_COUNT - 2];
    segments[1] = segments[2] = segments[3] = segments[4] = zeroSeg;
    segments[0] = new IPv6AddressSegment(0xfe80);
    segments[5] = new IPv6AddressSegment(0x5efe);
    if(isGlobal) {
        segments[4] = new IPv6AddressSegment(0x200);
    }
    return ipv4Address.getIPv6Address(
        new IPv6AddressSection(segments)).toString();
}

static String convertToLinkLocalIPv6(String  macStr) {
    MACAddress macAddress = new MACAddressString(macStr).getAddress();
    return macAddress.toLinkLocalIPv6().toString();
}

System.out.println("1.2.3.4 becomes ISATAP " +
    convertToIsatap("1.2.3.4", true));
System.out.println("aa:bb:cc:11:22:33 becomes " +
    convertToLinkLocalIPv6("aa:bb:cc:11:22:33"));

The output is the same for both examples:

1.2.3.4 becomes ISATAP fe80::200:5efe:102:304
aa:bb:cc:11:22:33 becomes fe80::a8bb:ccff:fe11:2233
于 2022-03-02T22:24:07.467 回答