IPV6地址的那些事儿

前阵子在Android下调试一个只有IPv6地址的网络设备时,发现通过ping6来测试网络连通时提示错误:

1
2
3

ping6 fe80::47af:e871:3c63:a272
connect: Invalid argument

stackoverflow上有人说这是一个link-local address本地链路地址,

1
2
3
4
5
6

use the following syntax on Android:

ping6 fe80::405a:e0a5:e054:cbde%wlan0

You must add %wlan0 since it is a link-local address, and your android device has multiple interfaces (Wi-Fi and mobile at least), so you need to tell your device the interface/link you want to use with this link-local address.

所以在ping时需要加上端口,或者像这样<亲测,Android设备不支持如下指令>:

1
2

ping6 -I wlan0 fe80::47af:e871:3c63:a272

那么,什么是本地链路地址(link-local address)? 其跟IPv4中的局域网地址有什么不同的地方了? 这里就来看下IPv6地址的一些细节。

按照维基百科的解释, link-local地址是一个只有在主机当前网段或者广播域才有效的地址。由于本地链路地址一般都是系统自动配置的,因此也被称为自动私有IP寻址(automatic private IP addressing)或者自动IP(auto IP):

  • 对IPv4来说,本地链路地址范围为: 169.254.0.0/16
  • IPv6的本地链路地址一般为: `fe80::/10

在弄清楚IPv6link-local地址是如何自动分配之前,先来看下IPv6地址的格式以及分类。

IPv6地址格式

相比IPv4地址的32位,IPv6地址扩到了128位,一般有两部分组成:

  • Network Prefix(网络前缀): 占n位,跟IPV4的网络ID类似
  • Interface ID(网口ID): 占余下的(128 - n)位, 类似于IPV4的主机ID

IPV6 address format

IPv6的地址类型有单播(unicast), 组播(anycast), 多播(multicast)三种,而广播地址(broadcast)的功能则由多播地址替代:

  • unicast address: 单播地址对应唯一的一个网口,发送给单播地址的数据包都只会发送到对应的网口上,根据不同的功能需要,单播地址又可以分为如下几个:
单播地址类型 二进制前缀 IPV6缩写
link-local unicast addresss 1111111010 FE80::/10
unique local unicast address 1111110 FC00::/7
loopback address 00…1(128bits) ::1/128
unspecified address 00..0(128bits) ::/128
Global unicast adress 其他
  • anycast address: 用于标识一组网口(通常属于不同的网络节点),发送给组播地址的数据会发送到该组网络节点中的一个

  • multicast address: 与anycast address类似,只是发送到该地址的数据会发送给该组所有的网络节点

有关IPv6地址的具体描述,可以参考RFC4291

对IPv6来说,link-local地址一般通过NDP(Neighbour Discovery Protocol)协议来实现自动配置:IPv6地址在设置之前,系统会先通过NDP协议发送消息确保要配置的IPv6地址在当前链路上具有唯一性,不与其他节点的IP地址发生冲突。

NDP协议类似与IPv4的ARP(Address Resolution Protocol),不同的是NDP是基于ICMPv6, 更多关于NDP细节可以参考RFC4862; Linux的实现可以参考源码:/net/ipv6/ndisc.c

参考文献

0%