skip to content

In IPv4, how is an ICMP message carried, and what do the four parts of its 8-byte header do?

level: juniorimportance: must knowfreq 45%

answer

  1. inside IP, not beside it
  2. protocol number 1
  3. family first, then the detail
  4. checksum over the whole message
  5. second word changes by type

basics

~20 s

ICMP rides inside an IPv4 datagram with protocol number 1. Its 8-byte header holds an 8-bit type (kind of message), an 8-bit code (specific condition), a 16-bit checksum over the whole ICMP message, and a type-dependent 32-bit word.

solid answer

~50 s

ICMP is not a transport protocol beside IP: it travels inside an IPv4 datagram whose `Protocol` field is 1, and RFC 792 makes it an integral part of IP that every IP module must implement. The header opens with an 8-bit `Type`, naming the message family (3 Destination Unreachable, 11 Time Exceeded, 8 Echo), and an 8-bit `Code` that refines it: type 3 code 3 is port unreachable, type 3 code 4 is fragmentation needed and DF set. Next comes a 16-bit `Checksum`, the one's-complement sum over the entire ICMP message starting at the type field, with no pseudo-header. The second 32-bit word, the rest of the header, belongs to the type: unused in Time Exceeded, identifier and sequence number in Echo, a pointer in Parameter Problem, the next-hop MTU in fragmentation-needed. A receiver must silently discard a type it does not recognise.

go deeper

for a junior

Recall that ICMP is carried in IPv4 as protocol 1, and name the four header parts with their widths: type, code, checksum, and the type-dependent rest-of-header word.

for a middle

Explain how type and code combine to encode a condition, give two examples where the rest-of-header word carries data, and say exactly what the checksum covers.

for a senior

Show why the checksum's coverage of the quoted packet matters to middleboxes that rewrite it, and why policy must key on type and code pairs rather than on protocol 1 alone.

for a principal

Weigh ICMPv4's design debts, no class bit and no extension mechanism, against how ICMPv6 and RFC 4884 later paid them, and what that means when writing filtering policy for both families.

## Where ICMP sits The **Internet Control Message Protocol** (ICMP, RFC 792) is how IPv4 reports problems and answers simple queries. It is easy to mistake for a transport protocol like TCP or UDP, because it has its own header and travels in the IP payload, but RFC 792 calls it "an integral part of IP" that "must be implemented by every IP module". Concretely: - An ICMP message is the payload of an ordinary IPv4 datagram whose `Protocol` field is **1** (TCP is 6, UDP is 17). - The outer IPv4 source address is whoever **composed** the message: a router on the path or the destination host. - ICMP has **no ports**. Whatever identifies a conversation lives either in the type-specific word or, for errors, in the quoted packet that follows the header. ## The fixed header, field by field Every ICMPv4 message starts with the same 8 bytes: | Bytes | Field | Width | Purpose | |---|---|---|---| | 0 | `Type` | 8 bits | The message family | | 1 | `Code` | 8 bits | The specific condition inside that family | | 2-3 | `Checksum` | 16 bits | Integrity of the whole ICMP message | | 4-7 | rest of header | 32 bits | Meaning set by the type | After those 8 bytes comes the **data**: for an error message, a quotation of the datagram that caused it; for a query, whatever the query defines. ## Type and code: two levels of meaning The **type** says what kind of message this is; the **code** says which variant. Reading the pair together is what lets one small header encode many distinct conditions: | Type / code | Name | |---|---| | 3 / 0 | Destination Unreachable, net unreachable | | 3 / 3 | Destination Unreachable, port unreachable | | 3 / 4 | Destination Unreachable, fragmentation needed and DF set | | 11 / 0 | Time Exceeded, time to live exceeded in transit | | 11 / 1 | Time Exceeded, fragment reassembly time exceeded | | 8 / 0 and 0 / 0 | Echo and Echo Reply | A code means nothing on its own: code 0 is "net unreachable" under type 3 and "TTL exceeded in transit" under type 11. Software and filtering policy therefore always key on the pair, never on the code alone. RFC 1122 adds a hard rule for unknowns: **an ICMP message of unknown type MUST be silently discarded**, never answered. ## The second word, the "rest of header" The second 32-bit word is reserved per type, which is why ICMP needed no header redesign as features were added: - **Destination Unreachable and Time Exceeded** (RFC 792): unused, sent as zero. - **Fragmentation needed and DF set**: RFC 1191 places the **Next-Hop MTU** in its low-order 16 bits so a sender can learn the bottleneck size. - **Parameter Problem** (type 12): an 8-bit **Pointer** to the offending octet of the quoted header. - **Redirect** (type 5): the **Gateway Internet Address** the host should use instead. - **Echo and Echo Reply**: a 16-bit **Identifier** and a 16-bit **Sequence Number**. - **RFC 4884 extensions**: a length attribute claimed from octets that used to be zero. ## The checksum The checksum is "the 16-bit one's complement of the one's complement sum of the ICMP message starting with the ICMP Type", computed with the checksum field set to zero (RFC 792). Three consequences matter in practice: 1. It covers the **entire** message, including the quoted datagram in an error, so any device that rewrites the quote, such as a NAT translating it back, must recompute it. 2. ICMPv4 has **no pseudo-header**: the outer addresses are protected only by the IPv4 header checksum. ICMPv6 (RFC 4443) does include one, because IPv6 dropped the header checksum. 3. A message failing the check is discarded; nothing is sent back. ## Errors versus queries RFC 1122 sorts ICMPv4 messages into two classes, and the class decides what a host may do with them: - **Error messages**: Destination Unreachable, Redirect, Source Quench (now deprecated by RFC 6633), Time Exceeded, Parameter Problem. They carry a quoted datagram and must never trigger another error. - **Query messages**: Echo, Information, Timestamp, Address Mask (RFC 6918 later deprecated Information and Address Mask). They are request/response pairs. ICMPv4 has no bit that marks the class; a receiver knows it from the type value. ICMPv6 fixed that by reserving types 0-127 for errors and 128-255 for informational messages, so the high-order bit of the type says which is which.

  • How does an IPv4 receiver tell an ICMP error from an ICMP query, when the type field has no class bit?
    By the type value. RFC 1122 lists the error types (Destination Unreachable, Redirect, Source Quench, Time Exceeded, Parameter Problem) and the query types (Echo, Information, Timestamp, Address Mask). The distinction matters because errors quote a datagram and must never cause another error. ICMPv6 (RFC 4443) made the class explicit: types 0-127 are errors and 128-255 are informational, so the type's high-order bit tells them apart.
  • What does the ICMPv4 checksum protect, and how does that differ from the TCP or UDP checksum?
    It covers the whole ICMP message from the type field to the end, including the quoted datagram, computed with the checksum field zeroed. Unlike TCP and UDP it uses no pseudo-header, so the IPv4 addresses are protected only by the IPv4 header checksum. ICMPv6 adds a pseudo-header because IPv6 has no header checksum. Any middlebox rewriting the quoted datagram must recompute the ICMP checksum.

saying these in an interview costs you the question

  • ICMP runs on top of UDP like DNS or DHCP does.
  • The code field alone tells you the condition, whatever the type.
  • ICMP messages carry source and destination port numbers in their header.
  • An ICMP message of unknown type should be answered with a Parameter Problem.
  • The ICMPv4 checksum covers only the 8-byte header, not the quoted packet.