What ICMP is
ICMP (Internet Control Message Protocol, RFC 792) is a layer on top of IP for control messages: notifications about delivery errors, diagnostics, MTU discovery. It is not a transport for application data (TCP/UDP handle that).
An ICMP packet is an IP packet with protocol number 1. The payload holds the ICMP header (type + code + checksum) and type-specific data.
The most important types
| type | code | name | purpose |
|---|---|---|---|
| 0 | 0 | echo-reply | reply to ping |
| 3 | 0 | destination-unreachable: net | network unreachable |
| 3 | 1 | destination-unreachable: host | host unreachable (ARP did not resolve) |
| 3 | 3 | destination-unreachable: port | port closed (UDP trick) |
| 3 | 4 | fragmentation-needed | packet > MTU + DF (PMTU discovery) |
| 5 | 0 | redirect | router reports "your route is bad, use Y" |
| 8 | 0 | echo-request | ping request |
| 11 | 0 | time-exceeded: TTL=0 | the basis of traceroute |
| 11 | 1 | time-exceeded: frag-reassembly | fragment reassembly timeout |
ping = ICMP echo
The ping command sends type=8 (echo-request) and receives type=0 (echo-reply).
The payload carries an increasing seq and a timestamp; comparing them lets you measure
RTT and loss.
Fields that help with diagnostics:
64 bytes from 8.8.8.8: icmp_seq=1 ttl=119 time=8.45 ms
icmp_seqis the packet number (missing = loss)ttlis how many hops the reply has left; different ttl values = ECMP load balancingtimeis the RTT (full round trip)
traceroute via time-exceeded
A classic traceroute:
- Sends a UDP packet (or ICMP echo, or TCP SYN) with TTL=1
- The first router decrements TTL to 0, drops the packet, sends ICMP type=11 (time-exceeded). The source sees the IP of the first hop
- Sends again with TTL=2 → you see the second hop, and so on
When ICMP is blocked
Paranoid firewalls like to drop ICMP. This is an antipattern:
- Without ICMP, PMTU discovery does not work → packets larger than the MTU are dropped silently → the application "hangs" on large responses
- Without traceroute, network problems are harder to diagnose
- Without ping, it is harder to check whether a host is alive
At worst, drop only echo and keep type=3 and type=11.