Ping 通道上的所有 IPv6 节点

距离以该速率开始新流程还有几天时间 “网络工程师” 来自奥图斯。 在这方面,我们想与您分享有关该主题的有用材料的翻译。

Ping 通道上的所有 IPv6 节点

有关解决 IPv6 ping 问题的提示和技巧的一系列博客文章(ICMPv6 回显请求/回显回复)

请注意,我使用的是 Linux(特别是 Fedora 31),但其他操作系统的 ping 命令语法应该非常相似。

Ping 通道上的所有 IPv6 节点

第一个也是最简单的技巧是对链路上的所有 IPv6 节点执行 ping 操作。

IPv6 使用多播地址进行所有类型的一对多通信。 没有广播(或广播)IPv6 地址。 这将 IPv6 与 IPv4 区分开来,后者有多种类型的广播地址,例如“有限广播”地址 255.255.255.255 [RFC1122]。

然而,有一个“全节点多播”IPv6 地址,因此我们将使用它来 ping 链路上的所有 IPv6 节点。 (“广播”地址实际上只是一个专门命名的多播地址,它是一个包括所有节点的多播组。注意,例如,以太网广播地址中的“组”或多播地址位在链路层打开)。

通道的全节点组播 IPv6 地址: ff02::1. ff 表示组播 IPv6 地址。 接下来的 0 是标志中未设置位的部分。

下一步 2 定义多播组的区域。 与组播 IPv4 地址不同,组播 IPv6 地址具有范围。 范围值指示允许转发多播数据包的网络部分。 一旦数据包到达指定范围的边界,无论其跳数字段是否非零,都必须丢弃该数据包。 当然,如果跳数在到达指定的多播组边界之前就达到零,也会立即重置。 以下是 IPv6 多播范围的完整列表。

最后,该 ::1 指定全节点组播组。

关于地址 ff02::1 需要注意的是,它是有歧义的。 在具有多个接口的 IPv6 主机(例如路由器或多宿主主机)上,地址 ff02::1 您无法指定向哪个接口发送 ICMPv6 回显请求,也无法期望在 ICMPv6 回显回复到达时收到它们。 ff02::1 有效并且可以在连接到多接口节点的任何接口和通道上使用。

因此,当我们 ping 链路上的所有 IPv6 节点时,我们还需要以某种方式告诉实用程序 ping 对于 IPv6,使用哪个接口。

定义接口 - 命令行选项

正如我们已经看到的,我们想要使用的全节点多播地址是 - ff02::1 - 不提供有关哪个接口发送和接收 ICMPv6 回显请求和回显应答数据包的任何信息。

那么,我们如何指定用于多播地址空间或单播链路本地地址空间的接口呢?

第一种也是最明显的方法是将其作为参数提供给我们正在使用的应用程序。

为了实用 ping 我们通过选项提供 -I.

[mark@opy ~]$ ping -w 1 -I enp3s2 ff02::1
ping: Warning: source address might be selected on device other than: enp3s2
PING ff02::1(ff02::1) from :: enp3s2: 56 data bytes
64 bytes from fe80::1d36:1fff:fefd:82be%enp3s2: icmp_seq=1 ttl=64 time=0.438 ms
64 bytes from fe80::f31c:ccff:fe26:a6d9%enp3s2: icmp_seq=1 ttl=64 time=0.589 ms (DUP!)
64 bytes from fe80::7e31:f5ff:fe1b:9fdb%enp3s2: icmp_seq=1 ttl=64 time=5.15 ms (DUP!)
64 bytes from fe80::f7f8:15ff:fe6f:be6e%enp3s2: icmp_seq=1 ttl=64 time=58.0 ms (DUP!)
64 bytes from fe80::877d:4ff:fe1a:b881%enp3s2: icmp_seq=1 ttl=64 time=62.3 ms (DUP!)
64 bytes from fe80::877d:4ff:fe1a:ad79%enp3s2: icmp_seq=1 ttl=64 time=62.8 ms (DUP!)
 
--- ff02::1 ping statistics ---
1 packets transmitted, 1 received, +5 duplicates, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.438/31.544/62.786/29.566 ms
[mark@opy ~]$

使用此全节点多播 ping,我们收到了来自 6 个 IPv6 节点的响应。 响应来自链路本地 IPv6 节点地址,以前缀开头 fe80::/10.

ping 不会无限期地继续发送 ICMPv6 echo 请求,直到我们中断它,我们通常通过 -c 选项指定要发送的数据包数量。 但是,这也会阻止 ping 在发送多播 ICMPv6 回显请求时接受和显示多个 ICMPv6 回显回复。 相反,我们使用 -w 选项来指定 ping 应在 1 秒后完成,无论发送或接收了多少 ICMPv6 回显请求或回显回复。

另外需要注意的是(DUP!)输出第二个及后续答案。 这些数据包被识别为重复响应,因为它们与首先发送的各个 ICMPv6 回显请求具有相同的 ICMP 序列值。 它们出现是因为 ICMPv6 多播回显请求会导致多个单独的单播响应。 统计摘要中还指出了重复项的数量。

定义接口 - 区域 ID

公开接口以供使用的另一种方法是作为 IPv6 地址参数的一部分。

我们可以在 ping 输出中看到这样的示例,其中响应的 IPv6 主机的地址也具有后缀 %enp3s2例如:

64 bytes from fe80::1d36:1fff:fefd:82be%enp3s2: icmp_seq=1 ttl=64 time=0.438 ms

这种指定接口的方法在 [RFC4007]“IPv6 定义的地址架构”中正式描述。 尽管它们通常被称为操作系统接口,但它们实际上定义了更通用的东西——“区域”或“范围”。

具有更通用区域或范围区域的原因是,如 [RFC4007] 中所述,IPv6 节点可以有多个连接到同一通道的不同 IPv6 接口。 这些接口是同一区域的成员。

应该可以在操作系统下将多个接口分组到一个区域内; 目前我不知道这在 Linux 下是否可行或如何做到。

使用后缀 %<zone_id>,我们可以删除命令行选项 -I ping.

[mark@opy ~]$ ping -w 1 ff02::1%enp3s2
PING ff02::1%enp3s2(ff02::1%enp3s2) 56 data bytes
64 bytes from fe80::2392:6213:a15b:66ff%enp3s2: icmp_seq=1 ttl=64 time=0.106 ms
64 bytes from fe80::1d36:1fff:fefd:82be%enp3s2: icmp_seq=1 ttl=64 time=0.453 ms (DUP!)
64 bytes from fe80::f31c:ccff:fe26:a6d9%enp3s2: icmp_seq=1 ttl=64 time=0.606 ms (DUP!)
64 bytes from fe80::7e31:f5ff:fe1b:9fdb%enp3s2: icmp_seq=1 ttl=64 time=6.23 ms (DUP!)
64 bytes from fe80::f7f8:15ff:fe6f:be6e%enp3s2: icmp_seq=1 ttl=64 time=157 ms (DUP!)
64 bytes from fe80::877d:4ff:fe1a:ad79%enp3s2: icmp_seq=1 ttl=64 time=159 ms (DUP!)
64 bytes from fe80::877d:4ff:fe1a:b881%enp3s2: icmp_seq=1 ttl=64 time=161 ms (DUP!)
64 bytes from fe80::23d:e8ff:feec:958c%enp3s2: icmp_seq=1 ttl=64 time=179 ms (DUP!)
 
--- ff02::1%enp3s2 ping statistics ---
1 packets transmitted, 1 received, +7 duplicates, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.106/82.858/179.216/81.281 ms
 
[mark@opy ~]$

链路本地地址响应

从这个全节点多播 ping 中,我们总共收到了 6 个独特的响应。

这些响应来自单播链路本地 IPv6 主机地址。 例如,这是第一个答案:

64 bytes from fe80::2392:6213:a15b:66ff%enp3s2: icmp_seq=1 ttl=64 time=0.106 ms

所有启用 IPv6 的接口都需要单播链路本地 IPv6 地址 [RFC4291],“IP 版本 6 寻址架构”。 原因是 IPv6 节点始终自动具有单播 IPv6 地址,它至少可以使用该地址与其直接连接的链路上的其他节点进行通信。 这包括通过本地链路主机地址与其他主机上的应用程序进行通信。

这简化了 IPv6 邻居发现和 OSPFv3 等协议的设计和实现。 它还允许主机上的最终用户应用程序通过通道进行通信,而无需通道上任何其他支持 IPv6 基础设施。 连接的 IPv6 主机之间的直接通信不需要连接上的 IPv6 路由器或 DHCPv6 服务器。

链路本地地址以 10 位前缀开头 fe80,后跟 54 个零位,然后是 64 位接口标识符 (IID)。 在上面第一个答案中 2392:6213:a15b:66ff 是 64 位 IID。

循环组播

默认情况下,多播数据包在内部返回到发送它们的节点。 IPv6 和 IPv4 寻址都会发生这种情况。

这种默认行为的原因是,当发送多播数据包时,发送主机本身以及网络上的某个位置也可能有一个侦听本地多播应用程序正在运行。 该本地应用程序还必须接收多播数据包。

我们可以在 ping 输出中看到这个多播本地循环:

[mark@opy ~]$ ping -w 1 ff02::1%enp3s2
PING ff02::1%enp3s2(ff02::1%enp3s2) 56 data bytes
64 bytes from fe80::2392:6213:a15b:66ff%enp3s2: icmp_seq=1 ttl=64 time=0.106 ms
64 bytes from fe80::1d36:1fff:fefd:82be%enp3s2: icmp_seq=1 ttl=64 time=0.453 ms (DUP!)
...

第一个也是最快的响应(0,106 毫秒与 0,453 毫秒相比)来自接口本身配置的链路本地地址 enp3s2.

[mark@opy ~]$ ip addr show dev enp3s2 | grep fe80
    inet6 fe80::2392:6213:a15b:66ff/64 scope link noprefixroute 
[mark@opy ~]$

效用 ping 提供了一种使用参数抑制本地多播反馈的方法 -L。 如果我们发送带有此标志的所有节点多播 ping,则响应仅限于远程节点。 我们没有收到来自发送接口的链路本地地址的响应。

[mark@opy ~]$ ping -L -w 1 ff02::1%enp3s2
PING ff02::1%enp3s2(ff02::1%enp3s2) 56 data bytes
64 bytes from fe80::1d36:1fff:fefd:82be%enp3s2: icmp_seq=1 ttl=64 time=0.383 ms
 
64 bytes from fe80::f31c:ccff:fe26:a6d9%enp3s2: icmp_seq=1 ttl=64 time=0.467 ms (DUP!)
...

Ping 链路本地地址

正如您可能猜到的那样,单播链路本地地址本身也没有提供足够的信息来指示使用哪个接口来访问它们。 与全节点多播 ping 一样,我们还需要将接口指定为命令行参数 ping 或在 ping 链路本地地址时带有地址的区域 ID。

这次我们可以使用 -c限制发送和接收的数据包和响应的数量 ping,因为我们正在执行单播 ping。

[mark@opy ~]$ ping -c 1 fe80::f31c:ccff:fe26:a6d9%enp3s2
 
PING fe80::f31c:ccff:fe26:a6d9%enp3s2(fe80::fad1:11ff:feb7:3704%enp3s2) 56 data bytes
64 bytes from fe80::f31c:ccff:fe26:a6d9%enp3s2: icmp_seq=1 ttl=64 time=0.395 ms
 
--- fe80::f31c:ccff:fe26:a6d9%enp3s2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.395/0.395/0.395/0.000 ms
[mark@opy ~]$

Ping(所有)其他 IPv6 地址?

在本文中,我们了解了如何使用全节点多播 IPv6 地址 ping 通道上的所有 IPv6 节点 ff02::1。 我们还了解了如何指定与全节点多播 IPv6 地址一起使用的接口,因为该地址本身无法提供此信息。 我们使用命令行选项 ping,或使用后缀指定接口 %<zone_id>.

然后我们了解了单播链路本地地址,它是用于响应全节点多播ICMPv6 echo请求的地址。

我们还了解了默认情况下多播数据包如何返回到发送节点以及如何为该实用程序禁用此功能 ping.

最后,我们使用后缀 ping 单个链路本地地址 %<zone_id>,因为本地链路地址本身也不提供有关传出接口的信息。

那么,如何 ping 所有其他节点并获取它们的全局单播地址 (GUA)(即它们在 Internet 上的公共地址)或其唯一的本地单播地址 (ULA)? 我们将在下一篇博客文章中讨论这一点。

就是这样。

您可以在以下位置找到有关我们课程的更多信息 开放日笔记.

来源: habr.com

添加评论