In this series, we have been looking at IP version 6, including the different IPv6 addresses, structures of the IPv6 header and packet, and ICMPv6. In the last article, we mentioned that ICMPv6 lays the foundation for other protocols, such as the neighbor discovery protocol for IPv6, which we will begin looking at in this article.

Introduction to the Neighbor Discovery Protocol

The word “discovery” in this protocol name may be a bit misleading, because the neighbor discovery protocol for IPv6 is more than just “discovering” neighbors. The neighbor discovery protocol, or ND for short, helps nodes on the same link perform address resolution, discover available routers, and determine nodes that are reachable. Actually, according to RFC 4861, there are nine different functions that the neighbor discovery protocol performs as highlighted below:

  1. Router discovery—This enables hosts to find routers that are available on the link.
  2. Prefix discovery—This enables hosts to determine what destinations are available on-link and which ones are available through a router.
  3. Parameter discovery—Routers can advertise parameters such as link MTU or hop limit to all attached hosts on a link.
  4. Address autoconfiguration—ND provides a way for hosts to automatically configure their interface addresses to a high degree of uniqueness.
  5. Address resolution—ND replaces ARP for resolving IP layer addresses to link-layer addresses.
  6. Next-hop determination—The way nodes determine the neighbor IP address to send the traffic for a destination through.
  7. Neighbor unreachability detection—The means by which nodes determine that a neighbor is not reachable anymore.
  8. Duplicate address detection—ND provides a node with a way to determine if the address it wants to use is already in use on the link.
  9. Redirect—Routers can advise hosts on a better next-hop to reach a particular destination.

To achieve these functions, neighbor discovery uses five ICMPv6 packet types: neighbor solicitation message, neighbor advertisement message, router solicitation message, router advertisement message and redirect message.

I figure that the best way to drive home these points is to use examples, so we will look at the functions in detail and, as we go on, we will also see how the different ICMPv6 packet types are used to achieve each function.

Address Resolution

Let’s begin with address resolution, because we are already familiar with the address resolution protocol (ARP) from IPv4. One of the reasons why ND replaces ARP for IPv6 address resolution is because of ARP’s use of broadcast, which is “noisy” compared to ND, which uses multicast.

We will use a very simple topology of two routers and a host connected to the same switch, as shown below:

R1 has a link-local address of fe80::1, while R2 has a link-local address of fe80::2. I configured these addresses manually. The host, which is running on the Windows 8 operating system, has a link-local address of fe80::240b:2ac8:47c8:8e50. This was automatically configured using a randomly generated permanent interface identifier, as discussed in the third article of this series.

The neighbor discovery protocol facilitates address resolution by making use of two of the ICMPv6 packet types we mentioned above: neighbor solicitation and neighbor advertisement. We will use Wireshark to help us see into this process.


Solicitation basically means to “request for” or “ask,” while advertisement can mean to “give.”

To initiate the address resolution, I will try to ping from R1 to R2 while capturing traffic on the Fa0/0 interface of R2.

As you can see, this ping was successful, but we will go over to Wireshark to see what happened at the backend. I have applied a filter to show only packets with IPv6 address fe80::1. Notice in the screenshot below that, before the ping packets, there were two packets, as highlighted in red – neighbor solicitation and neighbor advertisement. Ignore the router advertisement packet for now, as we will talk about it in another function.

Here’s a breakdown of what happened: R1 wanted to send traffic to R2 but, because it has never sent traffic to that address, it does not have R2’s link-layer (MAC) address. This is the same logic as in ARP. So what does R1 do? It sends a Neighbor Solicitation message for R2’s IP addresses, basically asking: “Who has IPv6 address fe80::2?”. Let’s look at this message in detail.

We will go from the upper-layer protocol to the lower-layer protocol just the way encapsulation will work, so we will look at the ICMPv6 message first.

The first thing we notice is that this is a Neighbor Solicitation message and it is carried in an ICMPv6 packet having a type field of 135. Next, we see that the Target Address is fe80::2; i.e., the IP address whose link-layer address is to be resolved. This ICMPv6 packet also contains the Source link-layer address option which is where R1 specifies its own MAC address. It is only logical that R1 should send its own MAC address in this Neighbor Solicitation message so that the responding host will know how to reply to the sender (R1). As you can see from below, the MAC address of R1’s Fa0/0 interface is c2:00:2c:fc:00:00.

The general format of a Neighbor Solicitation message is as shown below:

As we have seen above, the type field has a value of 135. The code field is 0. The Target Address field contains the IP address to be resolved to link-layer address. The only option that can be contained in a Neighbor Solicitation message is the Source link-layer address, as we saw above.

Now, let’s move down to the IP layer.

There are three things of importance here:

  1. The hop limit is set to 255. This is actually a security feature because, when this message is received at the other end, the receiver knows that the message was generated by a node on the link. If it wasn’t generated by a node on the link, i.e., the packet passed through a router, then the router would have decreased the hop limit by 1 when forwarding that packet thus making the Hop limit 254. ND messages should be between nodes on the same link and not across boundaries.
  2. The source address is fe80::1. This is the IP address of the sender, i.e., R1
  3. The destination address is ff02::1:ff00:2. This address is called the “solicited-node multicast address” of the IPv6 address fe80::2. We need to take a detour to explain what this address is.

Solicited-Node Multicast Address

We mentioned that one of the reasons ARP was dropped in IPv6 was because it was too noisy due to its use of broadcast packets. By using the broadcast address, all nodes received the ARP message, whether those nodes are using IPv4 or not. ND reduces noise by sending Neighbor Solicitation messages to a smaller multicast address called the “solicited-node multicast address.”

The solicited-node multicast address is formed by appending the last-order 24 bits of an address (unicast or anycast) to the prefix ff02::1:ff00:0/104. Therefore, the format for this address is ff02:0:0:0:0:1:ffxx:xxxx, where “xx:xxxx” is the last-order 24-bit portion of the target address. For example, the solicited-node multicast address for the link-local address fe80::240b:2ac8:47c8:8e50 is ff02::1:ffc8:8e50.

For the solicited-node address to be useful in address resolution, it means that when a node’s interface is configured with an IPv6 address, that node must join the solicited-node multicast address group for that interface so that it can receive solicitation messages.

Note: A node (host or router) must also join the all-nodes multicast addresses (ff01::1 and ff02:1) and other multicast addresses of all groups the host belongs to. In addition, routers must also join the all-routers multicast addresses (ff01:2, ff02:2, and ff05:2).

By sending Neighbor Solicitation messages to the solicited-node multicast address, only a few hosts (those with interface addresses that have the same low-order 24-bit interface ID) will receive those messages, thereby reducing network disturbance, unlike ARP. Going back to our scenario therefore, we can see why the solicited-node multicast address for fe80::2 (fe80:0000:0000:0000:0000:0000:0000:0002) is ff02::1:ff00:2 (ff02::1:ff00:0002).

Finally, we move to the data-link layer.

The source address is the MAC address of R1’s Fa0/0 interface. However, the destination address is 33:33:ff:00:00:02. This is the Ethernet multicast MAC address of the destination address—in this case, the destination address is the solicited-node multicast address.

The Ethernet multicast MAC address is formed by appending the low-order 32 bits of the destination address to “33:33:”. Therefore, the Ethernet multicast MAC address for ff02::1:ff00:0002 is 33:33:ff:00:00:02.

Let’s stop here for now because we have already spoken about so many new concepts. We will recap the things we have talked about on address resolution:

  1. It uses two messages: Neighbor solicitation and neighbor advertisement messages.
  2. The target address in the neighbor solicitation message is the IP address to be resolved.
  3. The destination IP address in the IPv6 header for a neighbor solicitation message (during address resolution) is the solicited-node multicast address of the target address.
  4. The solicited-node multicast address is derived by appending the low-order 24 bits of a unicast/anycast address to the prefix ff02::1:ff00:0/104.
  5. The destination MAC address of the Ethernet frame is formed by appending the low-order 32 bits of the destination IP address to “33:33:”.


This brings us to the end of this article, where we have been introduced to the neighbor discovery protocol. We have highlighted the nine functions performed by this protocol and we have also mentioned the five ICMP packet types it uses. We then went on to look at the address resolution function of ND where we discussed the Neighbor Solicitation message in detail.

In the next article, we will conclude with our discussion on address resolution. I hope you have found this article insightful.

References and Further reading

  1. RFC 4861: Neighbor Discovery for IP version 6 (IPv6):
  2. RFC 4291: IP Version 6 Addressing Architecture: