2.8. ICMPThe Internet Control Message Protocol (ICMP) is used to carry error and control messages. For example, if a router decrements an IP datagram's TTL to 0, it will send an ICMP error message back to the sending host, informing it that the datagram was dropped due to an exceeded lifetime. Another common example is the ICMP echo request and echo reply control messages, which are used by the ping utility to test connectivity between hosts. Although ICMP is usually considered to be a network-layer protocol, ICMP messages are carried in IP datagrams and have their own encapsulation, as shown in Figure 2.21. The specification for ICMP is RFC 777 [Postel 1981]. Figure 2.21. ICMP Message Encapsulation in an IP DatagramICMP Message FormatsFigure 2.22 shows the format of an ICMP message. Figure 2.22. The General ICMP Header
The type and code fields indicate the ICMP message type and subtype. Figure 2.24 lists the values for these fields. The checksum field contains a normal IP checksum of the entire ICMP message. Recall that the IP checksum covers only the IP header, so ICMP must provide its own. We will use the ping utility in many of our examples, so it is worthwhile taking a look at the ICMP echo request and reply messages in greater detail. Figure 2.23 shows an ICMP echo request or reply message. Under UNIX, the identification field is usually the pid of the ping process sending the echo requests. This identification field is used to tie the echo replies back to the process that sent the echo request. As we have seen, the upper-layer protocols use ports to route data to the appropriate process, but because ICMP runs in the network-layer and doesn't have ports, it must use the identification field. Figure 2.23. A ping Packet
Here is a tcpdump of a single ping to host linux: 1 17:07:49.959527 laptop > linux: icmp: echo request 1.1 4500 0054 B0f60 0000 4001 12fd ac1e 000c E..T.'..@....... 1.2 ac1e 0004 0800 c237 2308 0000 a504 1b3f .......7#......? 1.3 5979 0e00 0809 0a0b 0c0d 0e0f 1011 1213 Yy.............. 1.4 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 .............!"# 1.5 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 $%&'()*+,-./0123 1.6 3435 3637 4567 2 17:07:49.995696 linux > laptop: icmp: echo reply 2.1 4500 0054 2778 0000 4001 fae4 ac1e 0004 E..T'x..@....... 2.2 ac1e 000c 0000 ca37 2308 0000 a504 1b3f .......7#......? 2.3 5979 0e00 0809 0a0b 0c0d 0e0f 1011 1213 Yy.............. 2.4 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 .............!"# 2.5 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 $%&'()*+,-./0123 2.6 3435 3637 4567 The first 20 bytes in each datagram are the IP header. The ICMP messages follow the IP headers and are set in boldface. Notice that the echo request has a type of 0 and that the echo reply has a type of 8, as expected. The data portion of the message depends on what operating system the ping was run under and what options were specified for the ping invocation. In this case, the first 8 bytes are a timestamp, and each byte of the remaining data is the offset from the beginning of the data. ICMP Error MessagesAs we saw in Figure 2.24, ICMP messages can either be informational, such as the echo request/reply messages, or they can be error messages. The error messages follow the format shown in Figure 2.25: The type and code fields indicate the error, and the message-specific data is a copy of the IP header, including options, and at least the first 8 bytes of the upper-layer protocol header. Figure 2.25. An ICMP Error MessageWe can see an example of an ICMP error message by sending a UDP datagram to a port with no application listening. The destination host will respond with a port-unreachable message as shown next. On laptop, we use netcat to send a datagram to port 6666 on bsd. Once the datagram is sent, netcat terminates: laptop:~
$ nc -u bsd 6666
hello
laptop:~We capture the result by running tcpdump on laptop: 1 06:28:53.089078 laptop.iad2 > bsd.6666: udp 6 1.1 4500 0022 003f 0000 4011 2243 ac1e 000c E..".?..@."C.... 1.2 ac1e 0001 0407 1a0a 000e 459b 6865 6c6c ..........E.hell 1.3 6f0a o. 2 06:28:53.091639 bsd > laptop: icmp: bsd udp port 6666 unreachable 2.1 4500 0038 0538 0000 4001 1d44 ac1e 0001 E..8.8..@..D.... 2.2 ac1e 000c 0303 dedd 0000 0000 4500 0022 ............E.." 2.3 003f 0000 4011 2243 ac1e 000c ac1e 0001 .?..@."C........ 2.4 0407 1a0a 000e 0000 ........ We see the UDP datagram on lines 1.2 and 1.3 with its payload of hello\n. The ICMP error message is on line 2, with the ICMP header on line 2.2 set in boldface. Notice that the type and code are both 3. From Figure 2.24 we see that this is a port unreachable message. As shown on line 2, this message informs laptop that it sent a message to bsd on port 6666 but that no application was listening on that porthence the port was "unreachable." In lines 2.2 and 2.3, we see a copy of the IP header from lines 1.1 and 1.2: 2.2 ac1e 000c 0303 dedd 0000 0000 4500 0022 ............E.." 2.3 003f 0000 4011 2243 ac1e 000c ac1e 0001 .?..@."C........ Notice that this header is an exact copy of the IP header from the UDP datagram. Finally, on line 2.4, we see the 8 bytes of the UDP header: 2.4 0407 1a0a 000e 0000 ........ These bytes are how laptop knows that it was port 6666 (0x1a0a) that was unreachable, and that the source port of the sending application was 1031 (0x407).
|