Like most others that start tinkering with IPv6, I quickly learned that there was no such thing as broadcasts on v6 networks. Since I thought that was a pretty revolutionary concept, I started thinking about all the protocols that until now have relied upon the ability to send via broadcast. The first that came to mind was ARP, which resolves known IP addresses to unknown MAC addresses by sending to the Layer 2 broadcast address of FF:FF:FF:FF:FF:FF. It wasn’t thought of as a big deal when TCP/IP was first invented, but now it’s rather pesky, as each broadcast, ARP included, must be processed by every device on the segment.
I concluded, and quickly confirmed that there’s no such thing as ARP in IPv6 – so how do hosts find each other on a network? During the course of my studies, I learned that many functions like this were wrapped under the umbrella of IPv6 Neighbor Discovery, which runs on ICMPv6. The function of ARP is replaced in IPv6 by Neighbor Solicitation messages. I’d like to deep dive for a minute or two and explain exactly how this works.
Today’s example carries a simple network topology – remember that we’re focusing on the ability of one router to find the other using IPv6 Neighbor Solicitation. Both devices are Cisco 2691 routers.
I enable the FastEthernet interfaces on both routers and configure IP addresses as shown per the diagram. I’m running this lab in GNS3, so I’m able to handily capture packets on R1′s Fa0/0 interface before issuing a “no shut” command on it.
Once the capture started, I opened the interfaces on both routers and issued a ping from R1 to R2:
R1#ping 2001:db2::1F5C:7A92 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 2001:DB2::1F5C:7A92, timeout is 2 seconds: !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 16/23/44 ms
The purpose of the ping was to initiate some form of communication between the routers, forcing the IPv6 neighbor solicitation to occur, just like an ARP would occur between two hsots on an IPv4 network. I was able to instantly identify the solicitation message in the packet capture, immediately before the 5 ping request/response messages:
I’d like to compare and contrast this a bit with what an ARP message would look like. First, at the very bottom of the packet, you’ll see the IPv6 address that R1 is looking for. R1 has no ARP entry for 2001:DB2::1F5C:7A92, and therefore must ask who has this address. This is much the same as ARP, this just says “Hey guys, this is the IP address I’m looking for, now who has it?”
Now, point your attention to the destination IPv6 address. It starts with “FF02″, so we know it’s multicast. We know already that this is a new thing for us, because ARP never even had an IP header. Taking a closer look at the address, you’ll notice a prefix that you’ll see frequently in these messages:
Forget about the remaining 24 bits of the address for now. This prefix is the beginning of a special type of IPv6 Multicast Address called a “Solicited Node Address”. The “FF” indicates that the address is a multicast address. The “02″ indicates it is a link-local address. The remaining portions of the prefix shown above indicate that this address is a solicited-node address. These are used to send traffic to the host being searched for.
However, as stated before, the idea behind limiting broadcasts is so that not every device on the segment needs to process the packet, so there needs to be a way to send the packet to the host device being searched for, without first knowing the device’s Ethernet address.
This is accomplished by taking the 104 bit prefix shown above and appending the last 24 bits of the known IP address to it. Since the known IP address of R2 is 2001:db2::1F5C:7A92, our solicited-node address becomes:
So, we have our solicited-node addresses, but how does this limit the amount of devices unnecessarily bothered by the traffic? Multicast is built upon the idea that devices join “multicast groups”, designated by their own special addresses, and if the device is in that particular group, it processes the frame. If not, it is immediately discarded.
Starting to get it? This is super cool – let’s look at the interface details for Fa0/0 on R1:
R1#show ipv6 interface Fa0/0 FastEthernet0/0 is up, line protocol is up IPv6 is enabled, link-local address is FE80::C200:1BFF:FEA0:0 Global unicast address(es): 2001:DB2::7729:C0AD, subnet is 2001:DB2::/64 Joined group address(es): FF02::1 FF02::2 FF02::1:FF29:C0AD FF02::1:FFA0:0 MTU is 1500 bytes ICMP error messages limited to one every 100 milliseconds ICMP redirects are enabled ND DAD is enabled, number of DAD attempts: 1 ND reachable time is 30000 milliseconds R1#
According to the output, we have joined an IPv6 multicast group address that is equivalent to the solicited-node address that we saw earlier. The router derived this address from an assigned IP address on its Fa0/0 interface, and joined the multicast group for that address. As a result, it will receive frames that are sent to that address, and since no other host has that IP address, it is the only host that will receive these frames. It’s still a multicast, but it’s acting like a unicast – a very efficient way of sending messages like this.
Look back at the packet capture for the solicitation message, and you’ll notice a similar trait in the destination Ethernet address:
Wireshark tells us that the first 24 bits, “33:33:FF” is the prefix to indicate the encapsulated packet is an IPv6 multicast. However, you’ll notice that the last 24 bits is the same last 24 bits as both the IPv6 address on R1′s Fa0/0 interface, and the resulting solicited-node address.
Now that we’ve identified the mechanism used to limit broadcast frames, which is pretty cool in my opinion, we can finally see the response from R2 in the form of a Neighbor Advertisement message:
Note that, much like ARP, the advertisement includes the actual unicast Ethernet address of the host we’re trying to reach, and we can now send traffic to it normally. As opposed to an ARP table, we have an IPv6 Neighbors Table, which can be viewed on a Cisco router as follows:
R1#show ipv6 neighbors IPv6 Address Age Link-layer Addr State Interface 2001:DB2::1F5C:7A92 0 c001.1ba0.0000 REACH Fa0/0 FE80::C201:1BFF:FEA0:0 0 c001.1ba0.0000 STALE Fa0/0 R1#
As a result of this feature, we’ve successfully discovered the host we intend to send traffic to, and we’ve done so without bothering every other device on the network.