Ping all IPv6 hosts on the channel

A few days remain until the start of a new stream at the course "Network Engineer" from OTUS. In this regard, we want to share with you the translation of useful material on the topic.




A series of blog articles about IPv6 ping troubleshooting tips and tricks (ICMPv6 Echo Request / Echo Reply)

Please note that I use Linux (specifically Fedora 31), however the ping command syntax for other operating systems, I hope should be very similar.

Ping all IPv6 hosts on the channel


The first and easiest tip is to ping all the IPv6 hosts on the channel.

IPv6 uses multicast addresses for all types of one-to-many communications. There are no Broadcast (or Broadcast) IPv6 addresses. This distinguishes IPv6 from IPv4, where there are several types of broadcast addresses, for example, "limited broadcast" address 255.255.255.255 [RFC1122].

However, there is an “all-nodes multicast” IPv6 address, so we will use it to ping all IPv6 nodes in the channel. (A “broadcast” address is actually just a specially named multicast address, which is a multicast group that includes all nodes. Note that, for example, the “group” or multicast address bit is included in Ethernet Broadcast Addresses at the link level).

All-nodes multicast IPv6 address for the channel: ff02::1. ffdenotes a multicast IPv6 address. The next 0 is part of the flag with unset bits.

Further 2defines the area of ​​the multicast group. Unlike IPv4 multicast addresses, IPv6 multicast addresses have scope. The scope value indicates the portion of the network over which multicast packets are allowed. As soon as the packet reaches the bounds of the specified scope, the packet should be discarded, regardless of whether its Hop Count field is nonzero. Of course, if the conversion counter reaches zero before reaching the specified border of the multicast group, it is also immediately reset. Here is a complete list of multicast scope IPv6.

Finally, ::1indicates the all-nodes multicast group.

About the address ff02::1it should be noted that it is ambiguous. On an IPv6 host with multiple interfaces, such as a router or multihomed host, ff02::1there is nothing in the address where you can specify which interface to send ICMPv6 pings to or wait for ICMPv6 pings when they arrive. ff02::1valid and can be used on any of the interfaces and channels attached to the multi-interface node.

Therefore, when we ping all the IPv6 nodes on the channel, we also need to somehow tell the utility pingfor IPv6 which interface to use.

Interface Definition - Command Line Option


As we have already seen, the all-nodes multicast address that we want to use - ff02::1- does not provide any information as to which interface to send and receive ICMPv6 echo request and echo reply packets to.

So, how do we specify the interface that will be used for the multicast address space or unicast Link-Local addresses?

The first and most obvious way is to provide it as a parameter for the application we use.

For the utility, pingwe provide it through the option -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 ~]$


Using this all-nodes multicast ping, we received responses from 6 IPv6 nodes. Responses came from the host Link-Local IPv6 addresses, starting with the prefix fe80::/10.

To pingprevent ICMPv6 echo requests from continuing to endlessly until we abort it, we usually specify the number of packets to send through the -c option. However, this also prevents ping from receiving and displaying more than one ICMPv6 echo reply when sending a multicast ICMPv6 echo request. Instead, we used the -w option to indicate that ping should complete after 1 second, regardless of how many ICMPv6 pings or pings were sent or received.

Another thing to pay attention to is (DUP!) conclusion on the second and subsequent answers. These packets are identified as duplicates of the response, because they have the same ICMP sequence value as the individual ICMPv6 pings that were sent first. They appear because the ICMPv6 multicast echo request results in several individual unicast responses. The number of duplicates is also indicated in the statistics summary.

Interface Definition - Zone ID


Another way to provide an interface to use is part of the IPv6 address parameter.

We can see an example of this in the ping output, where the addresses of the responding IPv6 nodes also have a suffix %enp3s2, for example:

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


This method of specifying interfaces is formally described in [RFC4007], “Architecture with IPv6 Addresses Specified.” Although they are usually called the operating system interface, they actually define something more general - a “zone” or a “scope”.

The reason for having more general zones or scope zones is because, as mentioned in [RFC4007], an IPv6 host can have several different IPv6 interfaces connected to the same channel. These interfaces are members of the same zone.

It should be possible to group several interfaces within the zone under the operating system; Currently, I do not know if this is possible under Linux and how to do it.

Using the suffix %<zone_id>, we can remove the command line parameter -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 ~]$



Link-Local Address Responses


From this all-nodes multicast ping we received a total of 6 unique responses.

These responses came from Unicast Link-Local IPv6 host addresses. For example, here is the first answer:

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


Unicast Link-Local IPv6 Addresses Required on All IPv6-Enabled Interfaces [RFC4291], IP Version 6 Addressing Architecture. The reason for this is that the IPv6 host always automatically has a unicast IPv6 address, which it can use, at least to communicate with other hosts through its directly connected channels. This includes communication with applications of other hosts through Link-Local host addresses.

This simplifies the development and implementation of protocols such as IPv6 Neighbor Discovery and OSPFv3. It also allows end-user applications on the hosts to communicate over the channel without requiring any other supporting IPv6 infrastructure on the channel. Direct communication between connected IPv6 hosts does not require an IPv6 router or a DHCPv6 server in connection.

Link-Local addresses begin with a 10-bit prefix fe80, followed by 54 zero bits, followed by a 64-bit interface identifier (IID). In the first answer above 2392:6213:a15b:66ff, this is a 64-bit IID.

Looped multicast


By default, multicast packets are returned internally to the node that sends them. This happens for both IPv6 and IPv4 addresses.

The reason for this default behavior is that when sending multicast packets, there may also be a listening local multicast application running on the sending host itself, as well as somewhere on the network. This local application should also receive multicast packets.

We can see this multicast local loop in our ping output:

[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!)
...


The first and fastest response (0.106 ms compared to 0.453 ms) comes from the Link-Local address configured on the interface itself enp3s2.

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


The utility pingprovides a way to suppress local feedback of multicast mailing using a parameter -L. If we send an all-nodes multicast ping with this flag, then the responses are limited to the remote nodes. We do not receive a response from the Link-Local address of the sender interface.

[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 Link-Local Addresses


As you can guess, unicast Link-Local addresses themselves also do not provide enough information to indicate which interface to use to reach them. As in the case of all-nodes multicast ping, we also need to specify the interface as a command line parameter pingor zone ID with the address when ping Link-Local addresses.

This time we can use -cto limit the number of packets and responses sent and received ping, since we perform unicast 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 (all) other IPv6 addresses?


In this article, we saw how to ping all IPv6 nodes on a channel using an all-nodes multicast IPv6 address ff02::1. We also saw how to specify which interface to use with all-nodes multicast IPv6 address, since the address alone cannot provide this information. We used either a command line parameter pingor specified an interface through a suffix %<zone_id>.

Then we learned about unicast Link-Local addresses, which are addresses used to respond to all-nodes multicast ICMPv6 echo requests.

We also saw how multicast packets return to the sending host by default and how to disable this for the utility ping.

Finally, we pinged a single Link-Local address using the suffix%<zone_id>since Link-Local addresses alone do not provide information about the outgoing interface.

So what about pinging all the other nodes and retrieving their global Unicast addresses (GUAs) (i.e. their public Internet addresses) or their unique local Unicast addresses (ULAs)? We will cover this in the next blog post.

That's all.

You can find out more about our course in the open day entry .

All Articles