Switch-Router

[译]理解IPv6:Ping过程与被请求节点(solicited-node)组播的联系

Published at 2018-10-17 | Last Update 2018-10-17

原文地址 https://www.networkcomputing.com/networking/understanding-ipv6-ping-solicited-node-multicast https://www.networkcomputing.com/networking/understanding-ipv6-solicited-node-multicast-action

上一篇博文,我们学习了 IPv6 的 solicited-node 组播。在下图所示的环境中, 如果我们从路由器 A ping 路由器 B。并且在连接线路上抓包,我们就会抓取到目的地址为 solicited-node 地址的报文。

IPv4 中的 Ping

我们先来看下 IPv4 中的情景。

路由器 A 需要构造 ICMP echo request 报文,将 10.10.10.2 填入报文的目的 IP 地址字段。但在发送该报文前, 路由器 A 需要确认它已经掌握了以下 4 个信息:

  • 目的 MAC 地址
  • 源 MAC 地址
  • 源 IP 地址
  • 目的 IP 地址

在这 4 个信息中,路由器 A 能轻松填上其中 3 个

我们敲的命令是 “ping 10.10.10.2” ,所以路由器 A 知道报文应该填写的目的 IP 地址为 10.10.10.2,同时,路由器 A 会选择本机上离目的地址”最近” IP 地址作为 ICMP 报文的源 IP 地址,在我们的例子中,就是 10.10.10.1 了,而源 MAC 地址自然也就填写接口的 MAC 地址 c464.130a.a280

现在唯一缺少的就是目的 MAC 地址了,站在路由器 A 的角度,它并不能知道 IP 地址 10.10.10.2 对应的 MAC 地址。

那么现在轮到 ARP 登场了。 ARP 是 IPv4 中的地址解析协议 (Address Resolution Protocol),相关标准在RFC 826,我们来看看definition of ARP中对 ARP 的叙述。

ARP 协议被用来找到一个 IP 地址对应的以太网地址。当一台设备准备向同局域网的另一台主机发送报文时,它会在这之前先发送一个 ARP request 广播报文。所有局域网内侦听该以太网广播地址的设备会收到该报文,如果设备发现报文里携带请求的 MAC 地址对应的 IP 地址是本机的,那么它会以回复 ARP response 报文单播给请求者

下图展示了报文抓包结果:

注意以下细节:

  • Line 13: 路由器 A 发送的 ARP request 报文的源 MAC 为 c464.130a.a280,目的 MAC 为广播地址
  • Line 14: 路由器 B 发送的 ARP response 报文的源 MAC 为 c4:64:13:0a:b0:00
  • Line 15: 路由器 A 现在知道要发送的 ICMP echo request (ping) 报文所需的目的 MAC 地址,因此它可以发送了

IPv6 中的 Ping

IPv6 中的 Ping 和 IPv4 非常类似,区别在于它使用的是 ICMPv6 echo request 报文。同样的,为了让报文能顺利发到目的地址 2001:DB8::AB:2, 路由器 A 同样需要以下 4 个信息:

  • 目的 MAC 地址
  • 源 MAC 地址
  • 源 IPv6 地址
  • 目的 IPv6 地址

和 IPv4 情形类似,我们可以很轻松地得到上面 4 个信息中的 3 个:

  • 源 MAC 地址 = c464.130a.a280
  • 源 IPv6 地址 = 2001:DB8::AB:1
  • 目的 IPv6 地址 = 2001:DB8::AB:2

现在我们同样只差一项了:2001:DB8::AB:2 对应的 MAC 地址。

那么现在轮到…额,等等。我们不能使用 IPv4 网络中的 ARP 了。为什么呢?因为 ARP 是广播,而 IPv6 压根没有广播,那我们应该怎么做呢?

在之前介绍 solicited-node 组播的博文中,我们知道了,如果一个接口上配置了 2001:DB8::AB:1/64 这样一个全球单播地址,根据 RFC 4291,它会计算出一个对应的组播地址 FF02::1:FFAB:1 并加入这个组播组。

现在,我们得到了下面这个对应关系

这又怎么样?看山去它并没有让我们离想要的路由器 B 上单播地址对应的 MAC 地址更近一点,它只是告诉我们路由器 B 加入的组播组。

从这篇博文中,我们了解到了 33-33-00-00-00-00 到 33-33-FF-FF-FF-FF 这个范围的 MAC 地址都是为 IPv6 组播保留使用的,并且也有一套映射规则。因此现在,我们可以得到组播地址 FF02::1:FFAB:2 对应的 MAC 地址。

还记得吗?在 IPv4 的场景中,虽然路由器 A 不知道路由器 B 上 IPv4 地址 10.10.10.2 对应的 MAC 地址,但它至少知道路由器 B 一定会侦听一个 MAC 地址:FF:FF-FF-FF-FF-FF 这个广播地址。通过这个广播地址,路由器 A 能与路由器 B 搭上话,询问 B 10.10.10.2 对应的 IP 地址是多少。

显然,路由器 B 并不是唯一一个能收到这个广播报文的设备,实际上,在广播域中的每一台设备都能收到该报文。

上面这个过程的关键之处就在于: 路由器 A 知道路由器 B 必然会侦听的一个 MAC 地址,通过往这个 MAC 地址发送报文,它就能与 B 通信,然后得到需要的单播地址对应的 MAC 地址。

尽管在 IPv6 没有广播了,但路由器 A 还是知道路由器 B 必然侦听的一个 MAC 地址:33-33-FF-AB-00-02

这下子路由器 A 就能和 B 就能通信了,它也就能获取到想要的单播地址对应的 MAC 地址了,这也被称为 IPv6 的邻居发现(Neighbor Discovery)

下面看看抓包结果:

注意以下几点:

  • 第 5 行:这是路由器 A 向 2001:DB8::AB:2 发送的邻居请求( Neighbor Solicitation )报文
  • 第 6 行:这是路由器 B 发送的邻居通告( Neighbor Advertisement )报文,它通告单播地址 2001:DB8::AB:2 对应的 MAC 地址为 c464.130a.b000
  • 第 7 行:路由器 A 现在拿到了需要的目的 MAC,现在它可以发送 ICMPv6 request 报文了

(完)