前阵子在Android下调试一个只有IPv6地址的网络设备时,发现通过ping6
来测试网络连通时提示错误:
1 |
|
stackoverflow上有人说这是一个link-local address
本地链路地址,
1 |
|
所以在ping
时需要加上端口,或者像这样<亲测,Android设备不支持如下指令>:
1 |
|
那么,什么是本地链路地址(link-local address
)? 其跟IPv4中的局域网地址有什么不同的地方了? 这里就来看下IPv6地址的一些细节。
什么是link-local 地址
按照维基百科的解释, 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的地址类型有单播(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
link-local address是如何生成的
对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