ICMPv6 ND基础
IPv6地址
目前,在IPv6体系中,将地址分为以下3类:
- 单播地址:和IPv4中单播一样,每个地址只代表一个接口,目的是该地址的数据包只能够转发到该接口(eg. 2400:da00:2000:1701::4)。
- 组播地址:和IPv4中组播一样,一个地址可以标识多个不同的接口或者节点,目的是该地址的数据报文会转发到多个节点(eg. ff02::1:ff00:4)。
- 任播地址:一个地址可以标识多个不同接口或者节点,目的是该地址的数据报文会转发到最近的 一个节点上(最近取决于单播路由计算的结果)。 原IPv4中的广播的应用被IPv6中的组播所替代。
目前IANA IPv6地址分配情况如下:
IPv6前缀 | 地址分配情况 | 所占地址比例 |
---|---|---|
::0/8 | Reserved by IETF | 1/256 |
0200::/7 | Reserved by IETF | 1/128 |
2000::/3 | Global unicast | 1/8 |
FE80::/10 | Link-local unicast | 1/1024 |
FEC0::/10 | Reserved by IETF (formely Site-local unicast) | 1/1024 |
FC00::/7 | Unique Local IPv6 address | 1/128 |
FF00::/8 | Multicast | 1/256 |
Others | Reserved by IETF |
未指定地址
0:0:0:0:0:0/128 或者 ::/128
全球单播地址
Global routing prefix:全球路由前缀
提供商指定给一个组织机构 (末端站点)的前缀应该至少是/48前缀。全球路由前缀前三位是001。
SubnetID:子网ID
站点可以进行进一步划分,通常最大分配到/64位。
InterfaceID:接口ID
在一条链路上面需要唯一的确定一个接口。
接口ID可以通过3种方式生成:通过IEEE的EUI-64格式生成
将48bit MAC地址转换位64位
将FFFE插入到MAC地址的OUI和ID之间,转换位 64bit。将第7bit改为1,代表全球唯一。 例如:
MAC地址: 00-0E-0C-82-C4-D4 转换后: 020E:0CFF:FE:82:C4D4
设备随机生成(RFC3041)
手工配置
本地链路地址
FE80::/10
本地链路地址仅限于本地链路范围内使用,该地址作为源IP或者目的IP均不可路由。
节点可以自动生成,用于相邻节点之间使用,可用于邻居发现,无状态地址配置等应用。
组播地址
预定义组播地址(仅列举3个)
Address | Description |
---|---|
FF02:0:0:0:0:0:0:1 | All-nodes address |
FF02:0:0:0:0:0:0:2 | All-routers address |
FF02:0:0:0:0:1:FFXX:XXXX | Solicited-node address |
被请求节点组播地址
被请求节点组播地址(Solicited-Node Multicast Address)通过节点的单播/任播地址生成。
当一个节点的具有了单播/任播地址,就会对应生成一个被请求节点组播地址,并且加入这个组播组。该地址用于邻居发现机制。
在IPv6中,IP解析MAC的功能通过Neighbor Solicitation报文完成。当一个节点需要解析某个IP对应MAC时候,会发送NS报文,该报文的目的IP就是需要解析IP对应的被请求节点组播地址;该报文在直连字网内广播到所有节点,只有具有该IP的节点会检查处理(该节点已经 加入到了该组播组)。
同样该地址也用来完成重复地址检测 (DAD)。
被请求节点组播地址有两部分组成:
FF02:0:0:0:0:1:FF00::/104 前缀 + 单播/任播的后24bits,
即:Solicited-Node Address: FF02:0:0:0:0:1: FFXX:XXXX
例如:
节点的单播地址: 2001:1111:2222:3333:4444:0:0:5555 对应的被请求节点组播地址是: FF02::1:FF00:5555
以太网的组播映射关系
IPv6组播对应MAC地址有两部分组成:
固定的组播MAC前缀:33:33 + 组播IP地址后32bits。
例如:
设备单播地址为:2400:da00:2000:1701::4
其组播地址为: ff02::1:ff00:4
组播IP地址 对应MAC地址: 33:33:ff:00:00:04
NS/NA 过程
NS报文格式
NS的源IP地址为一个被指定的接口地址,或者未指定地址。目的地址为目标的IP地址或者响应的被请求节点多播地址。跳数限制必为255、认证头可选、校验和为ICMP校验和,并且保留字段填充为0,所有的ND报文都遵循这几点。
ICMP部分: 类型为135,代码为0。
目标地址为请求目标的IP地址,一定不能为多播地址。也就是说, 对于一个用于地址解析目的的NS,其IP部分的目的IP为被请求节点多播地址,但是其ICMP部分的目标地址字段为被请求节点的单播地址,该字段使用单播地址保证了最终发送者最多只会收到一个期望的应答。
可能的选项为源链路层地址,表示发送者的链路层地址,源IP为未指定地址时不应使用。
NA报文格式
源IP地址为发送通告的接口的一个地址。
目的地址:如果邻居通告是作为一个邻居请求的应答,则为调用邻居请求的源地址,但如果邻居请求的源地址为未指定地址,则公告的目的地址为所有节点多播地址。
ICMP部分:
类型136,代码0。
R(Router)标志置一表示发送者是一个路由器,通常用于邻居不可达检测机制,检测路由器是否换成主机。
S(Solicited)标志公告是否是对本报文目的地址所发送的请求报文的响应,S标志用于邻居不可达检测的可达性确认,当多播发送时或者非被请求的公告中不能置位。
O(Override)标志置位标识邻居公告不考虑已有表项,并且覆盖已有的链路层地址。
虽然公告会更新没有链路层地址的表项,但是如果O比特没有置位的话,公告仍然不会更新表项。
目标地址,对于未被请求的公告,就是改变链路层地址的那个IP地址。
对于被请求的公告,同对应的请求中的目标地址字段相同。
这个目标地址填充的是发送者的地址。此字段一定不能为多播。
可能使用的选项:目标链路层地址。就是公告发送者的链路层地址。响应多播请求必须使用,响应单播请求时,可以被忽略,因为请求的发送者应该已经知道正确的链路层地址,否则不可能正确发送单播请求。
交互过程
- 发送者创建一个状态为INCOMPLETE的邻居缓存表项,并向邻居发送NS报文。NS报文的目的MAC应使用目的主机对应的被请求节点多播MAC,目的IP地址应为目的主机 的被请求节点多播地址。
请求报文必须在源链路层地址选项中包含发送者的链路层地址,目标地址字段填写请求报文的目的主机的单播IP地址。 - 目的主机收到该请求,将发送NA报文给予回复。
NA的目标地址字段从NS的目标地址字段拷贝过来,与ARP不同的是,同样是目标(target),ARP中目标通常表示的是目的,也就是报文接收者,请求报文和应答报文中目标地址不同;而ND中目标地址表达的意思更像是交互双方关心的焦点,NS关心的是NS接收者的地址,对应的NA报文关心的也是NS接收者或者说NA发送者的地址。
由于NS报文是多播发送的,作为应答的NA报文需要携带目标链路层地址选项。ICMP报文的目标地址字段和目标链路层地址选项对应的是同一主机的IP地址和MAC地址。
由于NA报文是因为NS报文请求而触发的,所以Solicited位需要置为1。 - 接收到这样的NA报文,地址解析的发起者将最初生成的INCOMPLETE表项置为REACHABLE状态并且将目标链路层地址添加到该表项中,地址解析完成。
ND的地址解析和ARP 从基本思想上没有什么明显差别,具体实现中由于 ND修改和增加了一些字段,优化了一些流程,使得 主机间能够获得的信息更多,交互过程更加合理。
- 化广播为近似于单播的精确多播,减少了邻居不必要的负担。
- 引入多种状态,对邻居细致区分,比如主机仅仅收到请求时建立的表项为STALE状态,因为可以收到请求仅仅意味着存在单向通路。
- 引入多个标志位,携带更多可用信息。
重复地址检测
ND在一个接口的单播IPv6地址生效前就开始进行重复地址检测工作。即将生效的单播地址被称为探测地址,ND通过向探测地址发送NS报文来检查网络上是否存在重复IP地址。
NS的目标地址设置为被检测的地址,IPv6报文头的源IP设置为未指定地址,目的地址设置为目标地址的被请求节点多播地址。
如果网络上已经有主机使用该IP地址,该主机会回复一个NA,由于NS的源IP地址是未指定地址,所以相应的NA应该回复给所有节点多播地址。此时NS发送者可以通过收到的NA判断网络上存在重复IP地址。如果存在重复地址,该探测地址将不能在本地接口启用。
ARP和ND在重复地址检测上的设计思想大体相同,都是向自己拥有的IP地址发送请求,如果有重复IP就能收到应答。单就这个过程而言,我们能够 看到ND与ARP相比的先进性在于:
- 使用多播代替广播,减少邻居负担。
- IP地址未被确认为网段内唯一前不被使用,这样可以避免通过人工干预的方式解决地址冲突。
邻居不可达
通往或者经过邻居的通信在任何时候都有可能失败,硬件故障、接口的热插拔更换等。当通向邻居的路径失效的时候,如果邻居是最终目的,ND将再次执行地址解析,如果邻居是路由器,则尝试切换到另一个适当的路由器。
ND定义了两种可达性的确认方式:
- 上层协议对于连接正处于转发过程的暗示。
比如在TCP中,收到一个新的确认表明之前发送的所有报文到达了对端,同样的,收到新的数据表明早先的一些确认信息已经交付给远端。
如果报文发送向远端,那么也将经过当前发送者的下一跳邻居,所以这种信息确认了远端可达的同时也确定了下一跳邻居可达。这就是第一种可达性确认。 - 收到作为对于邻居请求的响应(也就是Solicited位置1)的NA报文。
当通信双方使用的规程没有包含确认信息的定义,主机或者设备只能主动的使用单播邻居请求探测邻居以确定转发路径的可用性。
被请求主机发送回来一个Solicited位置1的NA后可以重新将表项置为REACHABLE状态。因为只有接收到被请求的公告才意味着路径是双向连通的,请求必须已经到达邻居,才能促使邻居产生公告以响应。
这个确认过程同地址解析过程大致相似,只不过NS和NA均以单播形式发送,原因很简单,相互间的确认不应影响到其他主机。
除了Solicited位置1的NA,主机收到任何其他ND报文,最多只能创建一个STALE状态的ND表项。
ND选项
所有选项都以TLV形式出现
option name | type |
---|---|
Source Link-Layer Address | 1 |
Target Link-Layer Address | 2 |
Prefix Information | 3 |
Redirected Header | 4 |
MTU | 5 |
类型:8比特,标识选项类型。
长度为8比特无符号证书,表示选项长度。单位为八字节。0是非法值,所以如果为零整个报文被丢弃。
源/目标链路层地址选项的VALUE部分即为链路层地址,仅有这一个字段。
源链路层地址选项包含报文发送者的链路层地址,用于邻居请求、路由器请求、路由器公告。
目标链路层地址 选项包含目标的链路层地址。用于邻居通告和重定向。这些选项必须被其他的邻居发现消息静静的忽略。前缀信息:类型很明显为3,长度为4(单位是8个字节,而前缀信息为32字节)。
前缀长度为8比特无符号整数,0-128。
L标志为on-link标志,置位时表示前缀可以用来判断是否on-link,也就是是否在处于直连状态。如果不置位,则通告没有根据前缀判断直连的属性。
A标志是自动地址配置位,置位表示允许自动地址配置。
保留字段1可能会被用于新的标志位,未使用,发送者将其初始化为0,接受者忽略此字段。
有效生存期32位无符号整数,单位为秒,表示前缀有效期,设置为全1表示无限长。
首选生存期32位无符号整数,单位为秒,表示首选通过该前缀无状态自动配置地址的时间,设置为全1表示无限长。
保留字段2未使用,发送者将其初始化为0,接受者忽略此字段。
前缀字段为一个IP地址或者一个IP地址的前缀,前缀长度已经包含了前缀的前导比特的个数,前缀长度后面的比特保留,发送者必须置零,接受者必须忽略。
路由器不应该发送本地链路地址的前缀,如果发送 主机应该忽略这样的前缀选项。总之,前缀选项主要功能是为主机自动地址配置提供前缀。前缀选项仅出现在路由器通告中,其他消息中出现应该被忽略。
重定向头:类型为4,长度为整个选项的长 度,保留字段未使用,发送者将其初始化为0,接受者忽略此字段。
IP头加数据字段为触发该重定向消息的IP数据包的部分或全部,但要保证重定向消息报文长度不超过1280字节。重定向头选项包含在重定向消息中,对于其他邻居发现协议报文应该予以忽略。
MTU:类型为5,长度为1。保留字段未使用,发送者将其初始化为0,接受者忽略此字段。MTU字段32为无符号整数表示链路推荐的MTU值。
MTU选项用于路由器通告消息,在一些MTU值非周知,或者不统一的链路上确保节点使用相同的MTU。