Monday, November 2, 2015

IPv6 using ICMP6

by Craig Miller

More than just echo reply

Using ICMP6

We are all familiar with the really useful network troubleshooting application, ping. Ping uses ICMP to determine if a remote host is alive.

ICMP (Internet Control and Management Protocol RFC 4443) is used more extensively in IPv6. It is not only used for echo request and echo reply (ping), but also for MAC address resolution (think ARP, but different).

Layer 3 in the OSI model

ICMP is a part of the IP protocol suite, but is rides on top of the IPv6 address header. Prior to sending a ping packet several things must happen. Both the Layer 3 (IP address) and the Layer 2 (MAC address) must be known. This is required for both IPv4 and IPv6. However, how the Layer 2 address is discovered is quite a bit different in IPv6, since there is no ARP (Address Resolution Protocol) in IPv6.

How to get a MAC address without ARP

In the scenario where Host A will ping Host B, ICMP6 is used to resolve a destination MAC address (L2) of Host B. This leaves a conundrum, of how do you resolve a L2 or MAC address when you need to build a packet all the way up to ICMP? This is where multicast comes in. All nodes must subscribe to the all nodes address FF02::1, which has a special MAC address 33:33:00:00:00:01 (RFC 2464). And individual nodes will also subscribe to a host specific multicast address ending with the last 4 bytes of their IP address, so that Host B, which has an IPv6 address ending in feb3:0f1a, would listen to multicast address FF02::1:ffb3:f1a

IPv6 uses ICMP6 type 135, Neighbour Solicitation and type 136 Neighbour Advertisement to resolve MAC addresses (RFC 4861). A solicitation (NS) will be sent to the all nodes multicast address, and the host with the desired IPv6 address will respond with a neighbour advertisement (NA) with will include its own MAC address.

The ICMP6  Neighbour Solicitation packet sent by Host A to resolve a MAC address of Host B will be look like:
DA=33:33:00:00:00:01 | DA=FF02::1:ffb3:f1a | ICMP type 135 | Host B IP address

Link-local address saves the day

But what about the source addresses? That is where link-local addresses (those which start with FE80::/10) come in. A neighbour solicitation (NS) uses its link-local address (a Layer 3 address) as the source address. Since link-local addresses are always present in IPv6 (they are auto-generated using the MAC address), it is used as the source IPv6 address. When the Host B responds with a neighbour advertisement (NA), it is sent to the unicast link-local address of the requesting host. The NA packet (again following the destination) will look like:
DA=Host A MAC | DA=Host A link-local address | ICMP type 136 | Host B MAC address

Tying it all together

Using tcpdump, it is easy to see the ICMP6 conversation:
~$ sudo tcpdump -i eth0 -e icmp6
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes

09:50:17.799113 60:21:c0:d0:8f:0a (oui Unknown) > 33:33:ff:b3:0f:1a (oui Unknown), ethertype IPv6 (0x86dd), length 86: fe80::6221:c0ff:fed0:8f0a > ff02::1:ffb3:f1a: ICMP6, neighbor solicitation, who has fe80::211:24ff:feb3:f1a, length 32

09:50:17.803851 00:11:24:b3:0f:1a (oui Unknown) > 60:21:c0:d0:8f:0a (oui Unknown), ethertype IPv6 (0x86dd), length 86: fe80::211:24ff:feb3:f1a > fe80::6221:c0ff:fed0:8f0a: ICMP6, neighbor advertisement, tgt is fe80::211:24ff:feb3:f1a, length 32

09:50:17.803885 60:21:c0:d0:8f:0a (oui Unknown) > 00:11:24:b3:0f:1a (oui Unknown), ethertype IPv6 (0x86dd), length 118: fe80::6221:c0ff:fed0:8f0a > fe80::211:24ff:feb3:f1a: ICMP6, echo request, seq 1, length 64

09:50:17.805229 00:11:24:b3:0f:1a (oui Unknown) > 60:21:c0:d0:8f:0a (oui Unknown), ethertype IPv6 (0x86dd), length 118: fe80::211:24ff:feb3:f1a > fe80::6221:c0ff:fed0:8f0a: ICMP6, echo reply, seq 1, length 64

So where is Host B's MAC address? tcpdump is simplifying things too much, and using the -vv (for more protocol decode), the MAC address can be seen here:
10:06:29.292393 00:11:24:b3:0f:1a (oui Unknown) > 60:21:c0:d0:8f:0a (oui Unknown), ethertype IPv6 (0x86dd), length 86: (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::211:24ff:feb3:f1a > fe80::6221:c0ff:fed0:8f0a: [icmp6 sum ok] ICMP6, neighbor advertisement, length 32, tgt is fe80::211:24ff:feb3:f1a, Flags [solicited, override]
 destination link-address option (2), length 8 (1): 00:11:24:b3:0f:1a
   0x0000:  0011 24ce 0f1a

ICMP6 is more than just an echo reply

Since IPv6 does not have ARP, ICMP6 is used to resolve MAC addresses, and quite a few other things (ICMP Type numbers) which I'll cover in a later post. ICMP6 is an important part of the IPv6 protocol suite, without it, nothing would work in IPv6. Understanding how IPv6 and ICMP6 operate, will allow you to debug your network problems faster.

*ICMPv6 is used as a tcpdump or wireshark capture filter as 'ICMP6' hence I get lazy, and often drop the 'v'
**In Linux or Unix, one must use ping6 to initiate an IPv6 ping

No comments:

Post a Comment