• No results found

Part IV: Network Layer

Chapter 14. The Internet Protocol

14.4 Internet Control Message Protocol (ICMP)

The Internet Control Message Protocol (ICMP) is the error-report mechanism for the IP layer, which also resides in the network layer. Though ICMP is based on IP, it doesn't make IP more reliable. Packets can be lost despite the use of ICMP, and IP or ICMP won't notice that packets are lost. The only purposes of this error-report mechanism are to report errors to other computers and to respond to such reports. It is mendatory for each IP implementation to implement ICMP. The ICMP

implementation is defined in the following RFC documents:

• RFC 792 [Post81b]: This is the basic definition, describing the packet types and their uses.

• RFC 1122 [Brad89]: Definition of the requirements on terminal equipment (hosts) connected to the Internet.

• RFC 1812 [Bake95]: This document describes the requirements for switching computers (routers) in the Internet.

However, RFC specifications often leave much room for flexible implementation. For some functions, it is even optional whether you implement them. For this reason, ICMP implementations and even configurations of the same implementation can differ considerably.

The most popular application of ICMP is error detection or error diagnostics. In more than ninety percent of all cases, the first information transmitted by a newly installed network adapter over an IP network will probably be that of the ping command, which is fully based on ICMP. This allows you to

check the reachability of other computers easily and without noticeable load on the network. This procedure is often done in automated form (e.g., to monitor servers). Beyond simply checking the reachability of computers, the set of different error messages allow a network administrator (or a network-analysis tool) to obtain a detailed overview of the internal state of an IP network. For example, poorly selected local routing tables or wrongly set transmit options in individual computers can be detected. And finally, it is possible to use ICMP to synchronize computer clocks within a

network, in addition to other? partly outdated? functions, which will be briefly discussed in this section.

14.4.1 Functional Principle of ICMP

ICMP sends and receives special IP packets representing error or information messages. Error messages occur whenever IP packets have not reached their destinations. All other cases create information messages, which can additionally include a request for reply. Notice that the ICMP

functionality becomes active within the network implementation of the Linux kernel only provided that a problem situation occurs during another data traffic or when ICMP packets arrive from another

computer. As mentioned earlier, ICMP transmits messages in IP packets. Figure 14-11 shows the general structure of ICMP messages (gray fields), which are transported in the payload of an IP packet. It is typical for the IP header of a packet containing an ICMP message that the Type-of-Service field is set to 0x00, which means that the packet is treated like a regular IP packet without priority.

The protocol type in the IP header for ICMP messages is set to 0x01, as specified in RFC 790

[Post81a].

Figure 14-11. Structure of an IP packet containing an ICMP message. [View full size image]

The 8-bit Type field in the ICMP part specifies the type of ICMP message. The Code field specifies the values an ICMP message can take. The original RFC 792 defines a total of eleven messages, but the current Linux implementation supports only some of them. These eleven messages are listed in Table 14-2. The 16-bit checksum extends over all fields starting from the ICMP type (i.e., over the entire part that IP treats as payload).

Table 14-2. ICMP packet types defined in RFC 792.

Type

Description

Destination Unreachable The destination address cannot be reached.

Time Exceeded A packet was discarded, because its TTL has expired. Parameter Problem Unknown or false options.

Source Quench Informs the sender that IP packets were lost to overload.

Redirect Enables path optimization.

Echo and Echo Reply The data sent to the destination address is returned in a reply. Timestamp and Timestamp

Reply

The timestamp sent to the destination address is used-to reply with the timestamp of the destination address.

Information Request und Information Reply

Request/reply used to find the network a computer connects to.

The following subsections describe the ICMP messages defined in RFC 791. Destination Unreachable

The packet for a Destination Unreachable message includes the following fields: Type-0x03 Code Checksum

unused

IP Header + 64 Bits of Original Data

• Code = 0x00 (Network Unreachable): The network of an IP packet's receiver is not

reachable. This can happen, for example, if the distance to the receiver's network is set to infinite in the routing table of a router.

• Code = 0x01 (Host Unreachable): The desired destination computer in the specified

network cannot be reached.

• Code = 0x02 (Protocol Unreachable): This message can be generated if another protocol

listens to the destination port specified in the TCP packet header. The message can be sent both by a router and by a router and by an end system.

• Code = 0x03 (Port Unreachable): The port address of the receiver specified in the TCP

packet header is not reachable. The end system is "reachable" in this case, too, so both a router and an end system can generate this message.

• Code = 0x04 (Fragmentation Needed): This ICMP packet can be sent if an IP packet has to

be fragmented in a router, but the Don't-Fragment flag is set in the packet header, so that the packet may not be fragmented. In this case, the router has to discard the IP packet.

• Code = 0x05 (Source Route Failed): If the IP packet option Source Routing is set and an

error occurs, then this ICMP message is returned to the sender.

The IP header of the packet that caused the ICMP message, plus the first 64 data bits, are specified in the payload part of the ICMP message Destination Unreachable.

Source Quench

The packet of a Source Quench message is structured as follows: Type-0x04 Code-0x00 Checksum

unused

IP Header + 64 Bits of Original Data

When the network load is high, it can happen that a router (or the receiver) discards IP packets because of a lack of resources (e.g., memory space or computing capacity). If this happens, then a Source Quench message can be transmitted to the sender. RFC 792 specifies that an ICMP

implementation can generate such an ICMP message for each discarded packet. The sender should then respond by slowing down its transmission rate until no more Source Quench messages arrive. Subsequently, the sender can gradually increase its rate.

Instead of responding to discarded packets, routers, or end systems can send ICMP messages of the Source Quench type before they reach their capacity limits, to prevent the consequences of lost packets.

The only value defined for the Code field of a Source Quench message is 0x00. The payload part

includes the IP header of the triggering IP packet and the first 64 bits of that packet's payload. Redirect

The packet of a Redirect message is structured as follows: Type-0x05 Code Checksum

Router IP Address

IP Header + 64 Bits of Original Data

This ICMP message type is designed to optimize routing through the Internet. Assume that a router, R1, receives an IP packet of a sending end system, S, with receiver E. Based on a corresponding entry in the routing table of R1, this packet is forwarded to router R2. However, if R2 and S are in the same network (which can be determined based on the sender address), this route can be optimized by sending packets from S to receiver E directly to router R2 over R1, without detour. In this case, router R2 would send a Redirect message to end system S to announce that packets to receiver E will be sent directly to R2 in the future. Consequently, the field Router IP Address would contain the IP

address of R2. The Code field would take either of the following values:

• Code = 0x00: Redirect IP packets that should be sent to the network that connects the

receiver of these IP packets.

• Code = 0x01: Redirect all IP packets that should be sent to the specified receiver.

• Code = 0x02: Redirect all IP packets that should be sent to the receiver's network and have

the same value in the TOS field as the IP packet that triggers the ICMP message.

• Code = 0x03: Redirect all IP packets that have the same receiver and the same TOS field

as the IP packet that triggers the ICMP message.

Notice that no Redirect message is sent if the Source Route option is set in the IP packet options, even if there would be a shorter path to the receiver. The last field specifies the IP header and the first 64 data bits of the initiating packet.

Echo and Echo Reply

The packet of an Echo or Echo Reply message is structured as follows: Type Code-0x00 Checksum

Identifier Sequence Number Data...

Echo and Echo Reply messages are normally used to verify the existence of an end system or intermediate system. To this end, an Echo message is sent to the desired system. The ICMP

implementation in the receiver has to respond to this Echo request by sending an Echo Reply message. Echo and Echo Reply messages differ only in the Type field: 0x08 specifies an Echo message and

0x00 specifies an Echo Reply message. The Code value has to be set to 0x00 for both types. RFC 792

does not define explicit values for the other fields (i.e., Identifier, Sequence Number, and Data); therefore, the application can set these fields arbitrarily. The only thing the ICMP

implementation has to ensure is that these three fields are copied from an Echo message to the Echo Reply message. The Data field can have an arbitrary length. For example, an ICMP application could

use session numbers for the Identifier field and increment the sequence number for each Echo

message it sends. Time Exceeded

The packet of a Time Exceeded message is structured as follows: Type-0x0B Code Checksum

unused

IP Header + 64 Bits of Original Data

An ICMP message of the type Time Exceeded is generated and returned to the sender if the lifetime of the IP packet has expired (i.e., its TTL value is 0) and the packet was discarded. There could occur either of the following two cases:

• Code = 0x00: A router sends this message if it discarded a packet because its TTL had

expired.

• Code = 0x01: An end system sends a message with this code if it was unable to

reassemble a fragmented IP message correctly within a certain time, because fragments were missing.

As in the Destination Unreachable message, the payload part in the Time Exceeded message includes the IP header of the packet that caused the ICMP message, plus the first 64 data bits from that packet. Parameter Problem

The packet of a Parameter Problem message is structured as follows: Type-0x0C Code-0x00 Checksum

Pointer unused

IP Header + 64 Bits of Original Data

If an error due to an invalid parameter in the IP header occurs while an IP packet is being handled in an intermediate node or end system, then this IP packet is discarded. For example, this can happen if there is a wrong argument in the IP packet options. In this case, the router or end system can

generate an ICMP message of the type Parameter Problem and return it to the sender of the discarded IP packet. The Code field has to be set to 0x00 in all cases, which means that the Pointer field

shows an error. More specifically, the pointer points to the octet in the original IP packet header where the problem occurred while the packet was being processed. For example, the value Pointer=0x01

means that the version number (i.e., the first field in the IP packet header; see Figure 14-11) is faulty. The IP packet header of the discarded packet and the first 64 bits of its payload are attached to the ICMP message.

Timestamp and Timestamp Reply

The packet of an Timestamp or Timestamp Reply message is structured as follows: Type Code-0x00 Checksum

Identifier Sequence Number Originate Timestamp

Receive Timestamp Transmit Timestamp

These two ICMP message types are used to poll the current time from an intermediate or end system. The exchange is similar to the two previous message types, Echo and Echo Reply. The Type field is

used to distinguish between Timestamp and Timestamp Reply: A value of 0x00 specifies a Timestamp

message, and 0x0E denotes a Timestamp Reply message. The exclusive value for the Code field is 0x00. As for Echo and Echo Reply, the fields Identifier and Sequence Number are required by

the sender to be able to allocate a Timestamp Echo message to a Timestamp message properly. The payload part of these two ICMP messages consists of 32-bit timestamps. A timestamp is the time in milliseconds that has passed since midnight (GMT). The Originate Timestamp field defines the

time when the transmitted ICMP message was last "touched" by the sender. Similarly, there is a

Receive Timestamp specifying the time that the message arrived in the receiver. Transmit Timestamp stores the time at which the Timestamp Reply message was sent.

Information Request and Information Reply

The packet of an Information Request or Information Reply message is structured as follows: Type Code-0x00 Checksum

Identifier Sequence Number

The way these two ICMP message types operate is similar to the Echo and Echo Request messages, except that they don't have a payload field. This message pair allows you to additionally identify the network that connects a computer. For this purpose, the value 0.0.0.0 is used as receiver address,

which means that all computers in the local area network are addressed. The ICMP modules of these computers react to an Information Request by sending an Information Reply, where they state the LAN identifier instead of 0.0.0.0.

The Identifier and Sequence Number fields are used to allocate Information Request and

Information Reply pairs, similarly to an Echo and Echo Reply pair. The Type field is defined as follows:

• Type = 0x0F: The message is an Information Request.

• Type = 0x10: The message is an Information Reply.

14.4.2 Configuring ICMP

The specified RFCs allow the local system administrator to control the behavior of some ICMP functions. The Linux implementation includes three cases where the sysctl() function can be used to control behavior at runtime:

• Echo Replies: The system manager can decide whether Echo Replies may be sent at all, for security reasons. This option is activated by default.

• Echo Replies to broadcast packets: The system manager can decide whether a reply should be sent to an Echo Request packet addressed to all computers in a LAN (i.e., destination address 0.0.0.0). This option is deactivated by default.

• Monitoring illegal ICMP broadcast replies: Faulty ICMP messages sent as a response to an IP broadcast can be ignored. (See RFC 1122 [Brad89].) This is not the case by default.

In addition, RFC 1812 [Bake95] specifies that the transmission rate of ICMP messages should be limited and that this limit should be configurable. The transmit function icmp_send() is limited

accordingly, but the rate can be set only in the source code (in the xrlim_allow() function, XRLIM_BURST_FACTOR constant), which means that you have to recompile the Linux kernel.

14.4.3 ICMP in the Linux Kernel

The Linux implementation is done mainly in the file net/ipv4/icmp.c and in the associated header

file include/linux/icmp.h. Each ICMP message type is defined as a constant with the type fields

specified in RFC 792: ICMP_ECHOREPLY = 0 ICMP_DEST_UNREACH = 3 ICMP_SOURCE_QUENCH = 4 ICMP_REDIRECT = 5 ICMP_ECHO = 8 ICMP_TIME_EXCEEDED = 11 ICMP_PARAMETERPROB = 12 ICMP_TIMESTAMP = 13 ICMP_TIMESTAMPREPLY = 14 ICMP_INFO_REQUEST = 15 ICMP_INFO_REPLY = 16 ICMP_ADDRESS = 17 ICMP_ADDRESSREPLY = 18

Almost all IP modules use the ICMP implementation to send ICMP messages.

icmp_unit() include/linux/icmp.h

From the local perspective, the ICMP layer is stateless, except for a few internal statistics, but messages exchanged between two computers can include states. The ICMP socket is the only central structure included in the implementation. This socket can be reached exclusively with root privileges.

This is the reason why, for example, the ping command requires root privileges. The initialization

function icmp_unit() creates this socket.

The statistical information mentioned in the previous section is maintained in the data structure

icmp_statistics. It includes the number of packets sent and received in total, the number of

errors incurred, and the accumulated number of ICMP types.

The current contents from this statistics variable can be output from the pseudo file /proc/net/snmp

. This file includes the meaning of the individual entries in the form of abbreviated ICMP types with leading "In" or "Out" for each packet and an additional row with values from the statistics array. The fol lowing listing is an example to show you what the contents of the /proc/net/snmp can look like: > cat /proc/net/snmp

Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams

InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails

FragCreates

IP: 2 64 900 0 0 0 0 0 64 963 0 0 0 0 0 0 0 0 0

Icmp: InMsgs InErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds

OutParmProbs

OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps

Icmp: 35 0 15 0 0 0 0 11 9 0 0 0 0 26 0 15 0 0 0 0 0 11 0 0 0 0 Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts

Tcp: 0 0 0 0 4 0 0 0 0 816 888 0 0 0

Udp: InDatagrams NoPorts InErrors OutDatagrams Udp: 25 6 0 31

Sending ICMP Packets

You can send ICMP packets from outside of the ICMP implementation in the Linux kernel? for example, from within the ping program. This case is independent of the functions discussed below and will not be further discussed here.

icmp_send() include/linux/icmp.h

Within the Linux kernel, an ICMP message is sent by the function icmp_send() in all cases where

the message is not a reply to an ICMP message. This function gets all data from an ICMP message as call parameters, which means that it can send any ICMP type. In addition, to generate an ICMP packet correctly, this function is responsible for limiting the transmission rate of ICMP messages (see also the configuration options discussed in Section 14.4.2) and for catching cases where no ICMP messages may be sent. In this respect, two cases are possible:

• If the IP packet that initiated an ICMP message was an ICMP error message, then a reply to this error message could cause an infinite cycle of ICMP messages.

• If an IP packet was fragmented, then an ICMP message is sent for the first fragment only to avoid loading the network unnecessarily with redundant packets.

Table 14-3 shows the cases where Linux kernel modules send ICMP messages.

Table 14-3. Generating ICMP messages from within the kernel modules.

Type

Module

Reason

Time Exceeded Forward and defragment packets A packet was discarded because it's