Previous Page
Next Page

2.8. ICMP

The 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 Datagram


ICMP Message Formats

Figure 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


Figure 2.24. ICMP Message Types

Type

Code

Description

0

0

echo reply

3

 

destination unreachable

 

0

network unreachable

 

1

host unreachable

 

2

protocol unreachable

 

3

port unreachable

 

4

fragmentation required but DF bit set

 

5

source route failed

 

6

destination network unknown

 

7

destination host unknown

 

8

source host isolated

 

9

communication with destination network administratively prohibited

 

10

communication with destination host administratively prohibited

 

11

network unreachable for TOS

 

12

host unreachable for TOS

 

13

communication administratively prohibited

 

14

host precedence violation

 

15

precedence cutoff in effect

4

0

source quench

5

 

redirect

 

0

redirect for network

 

1

redirect for host

 

2

redirect for TOS and network

 

3

redirect for TOS and host

6

0

alternate host address

8

0

echo request

9

0

router advertisement

10

0

router solicitation

11

 

time exceeded

 

0

TTL is 0 during transit

 

1

TTL is 0 during reassembly

12

 

parameter problem

 

0

IP header bad

 

1

required option missing

13

0

timestamp request

14

0

timestamp reply

15

0

information request

16

0

information reply

17

0

address mask request

18

0

address mask reply


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 Messages

As 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 Message


We 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).

Notice that bsd has set the UDP checksum field to 0 in the ICMP error message. This behavior is incorrect. If we run this experiment again but send the UDP datagram to solaris or linux instead of to bsd, the checksum field is correct. Indeed, both solaris and linux return the entire UDP datagram, showing that exactly what gets returned in an ICMP error message depends very much on the implementation.


Previous Page
Next Page