Skip to main content

Message Formats

ICMP messages are sent using the basic IP header. The first octet of the data portion of the datagram is an ICMP type field; the value of this field determines the format of the remaining data. Any field labeled "unused" is reserved for later extensions and must be zero when sent, but receivers should not use these fields (except to include them in the checksum). Unless otherwise noted, the values of the internet header fields are as follows:

IP Header Fields for ICMP

Version

4

IHL (Internet Header Length)

Internet header length in 32-bit words.

Type of Service

0

Total Length

Length of internet header and data in octets.

Identification, Flags, Fragment Offset

Used in fragmentation, see [1].

Time to Live

Time to live in seconds; as this field is decremented at each machine in which the datagram is processed, the value in this field should be at least as great as the number of gateways which this datagram will traverse.

Protocol

ICMP = 1

Header Checksum

The 16-bit one's complement of the one's complement sum of all 16-bit words in the header. For computing the checksum, the checksum field should be zero. This checksum may be replaced in the future.

Source Address

The address of the gateway or host that composes the ICMP message. Unless otherwise noted, this can be any of a gateway's addresses.

Destination Address

The address of the gateway or host to which the message should be sent.

ICMP Message Format

 0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| Message Body |
| (Format varies by Type) |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Type Field (8 bits)

Identifies the ICMP message type. Common values:

ValueMessage Type
0Echo Reply
3Destination Unreachable
4Source Quench
5Redirect
8Echo Request
11Time Exceeded
12Parameter Problem
13Timestamp Request
14Timestamp Reply
15Information Request
16Information Reply

Code Field (8 bits)

Provides additional context for the message type. The meaning depends on the Type field.

Example - Destination Unreachable (Type 3) Codes:

  • 0 = Network unreachable
  • 1 = Host unreachable
  • 2 = Protocol unreachable
  • 3 = Port unreachable
  • 4 = Fragmentation needed but DF set
  • 5 = Source route failed

Checksum Field (16 bits)

The checksum is the 16-bit one's complement of the one's complement sum of the ICMP message starting with the ICMP Type field. When computing the checksum, the checksum field should be zero.

Checksum Calculation Algorithm:

// Pseudocode for ICMP checksum calculation
uint16_t calculate_icmp_checksum(uint8_t *data, int length) {
uint32_t sum = 0;

// Sum all 16-bit words
for (int i = 0; i < length; i += 2) {
uint16_t word = (data[i] << 8) + data[i+1];
sum += word;
}

// If length is odd, add the last byte
if (length % 2 == 1) {
sum += (data[length-1] << 8);
}

// Fold 32-bit sum to 16 bits
while (sum >> 16) {
sum = (sum & 0xFFFF) + (sum >> 16);
}

// Return one's complement
return ~sum;
}

Verification:

// Receiver verifies by computing checksum over entire message
// (including the checksum field). Result should be 0xFFFF.
bool verify_icmp_checksum(uint8_t *message, int length) {
uint16_t result = calculate_icmp_checksum(message, length);
return (result == 0xFFFF);
}

Complete ICMP Packet Structure

Ethernet Frame
┌──────────────────────────────────────────┐
│ Ethernet Header │
├──────────────────────────────────────────┤
│ IP Header │
│ - Version: 4 │
│ - IHL: 5 (20 bytes) │
│ - Protocol: 1 (ICMP) │
│ - Source IP: 192.168.1.1 │
│ - Dest IP: 10.0.0.1 │
├──────────────────────────────────────────┤
│ ICMP Message │
│ ┌────────────────────────────────────┐ │
│ │ Type (8 bits) │ │
│ ├────────────────────────────────────┤ │
│ │ Code (8 bits) │ │
│ ├────────────────────────────────────┤ │
│ │ Checksum (16 bits) │ │
│ ├────────────────────────────────────┤ │
│ │ Message-specific data │ │
│ │ (varies by Type and Code) │ │
│ └────────────────────────────────────┘ │
└──────────────────────────────────────────┘

Error Message Format

For error messages (Types 3, 4, 5, 11, 12), the message body includes:

 0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Unused = 0 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Internet Header + 64 bits of Original Data Datagram |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Why Include Original Data?

  • Allows receiver to identify which transmission caused the error
  • Contains source/destination ports for demultiplexing
  • Provides context for error handling

Example:

Original TCP Segment:
┌─────────────────────────────────────┐
│ IP Header (20 bytes) │
│ - Src: 192.168.1.10 │
│ - Dst: 203.0.113.50 │
│ - Protocol: 6 (TCP) │
├─────────────────────────────────────┤
│ TCP Header (20 bytes) │
│ - Src Port: 54321 │
│ - Dst Port: 80 │
│ - Seq: 1000 │
├─────────────────────────────────────┤
│ TCP Data │
└─────────────────────────────────────┘

ICMP Error Message includes:
┌─────────────────────────────────────┐
│ ICMP Header (8 bytes) │
│ - Type: 3 │
│ - Code: 1 (Host Unreachable) │
├─────────────────────────────────────┤
│ Original IP Header (20 bytes) │ ← Full IP header
├─────────────────────────────────────┤
│ First 8 bytes of TCP Header │ ← Contains ports
│ - Src Port: 54321 │
│ - Dst Port: 80 │
└─────────────────────────────────────┘

The 8 bytes of TCP header are sufficient to identify:
- Source and destination ports
- Allows demultiplexing error to correct socket

Query Message Format

For query/reply messages (Types 0, 8, 13, 14, 15, 16):

 0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identifier | Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Identifier and Sequence Number:

  • Used to match requests with replies
  • Identifier: Usually process ID of sender
  • Sequence Number: Increments with each message

Example - Ping Session:

Request 1:  ID=12345, Seq=1, Type=8
Reply 1: ID=12345, Seq=1, Type=0

Request 2: ID=12345, Seq=2, Type=8
Reply 2: ID=12345, Seq=2, Type=0

Request 3: ID=12345, Seq=3, Type=8
Reply 3: ID=12345, Seq=3, Type=0

Matching: Reply matches Request when (ID, Seq) are identical

Field Descriptions

Unused Fields

Any field labeled "unused" or "reserved":

  • Sender: MUST set to zero
  • Receiver:
    • MUST include in checksum calculation
    • SHOULD NOT interpret or use for any purpose
    • Allows for future protocol extensions

Message-Specific Fields

Different ICMP message types use additional fields. See individual message type specifications for details.

Processing Guidelines

Sender Responsibilities

  1. Construct proper IP header:

    • Set Protocol = 1 (ICMP)
    • Set appropriate TTL
    • Calculate IP header checksum
  2. Construct ICMP message:

    • Set correct Type and Code
    • Fill in message-specific fields
    • Zero out unused fields
    • Calculate ICMP checksum
  3. Include context for errors:

    • Include original IP header
    • Include first 64 bits of original data

Receiver Responsibilities

  1. Validate IP header:

    • Check IP header checksum
    • Verify destination address
  2. Validate ICMP message:

    • Verify ICMP checksum
    • Check Type and Code values
  3. Process message:

    • Extract relevant information
    • Demultiplex to appropriate handler
    • Take appropriate action
  4. Error handling:

    • Discard invalid messages silently
    • Do NOT send ICMP errors about ICMP errors

Byte Order

All multi-byte fields are transmitted in network byte order (big-endian):

  • Most significant byte first
  • Matches IP header conventions

Example:

// Checksum value: 0x1234
// Wire format: [0x12] [0x34]

uint16_t checksum = 0x1234;
uint8_t byte1 = (checksum >> 8) & 0xFF; // 0x12
uint8_t byte2 = checksum & 0xFF; // 0x34

// On wire: byte1 transmitted first, then byte2

Implementation Note: All ICMP message types share this common header structure. The interpretation of fields after the checksum varies by message type. Implementations must handle all defined message types and silently discard unrecognized types.