ICMP — The Internet's Control Channel

ping, traceroute, destination-unreachable, time-exceeded, redirect — how the network tells you what went wrong.

Building Block Foundational
8 min read
icmp network-layer diagnostics ping

What it is#

ICMP (Internet Control Message Protocol) is the diagnostic and signalling sibling of IP. It rides directly on top of IP — protocol number 1 for ICMPv4, 58 for ICMPv6 — and carries messages that the network sends to itself: “your packet got dropped because the TTL expired”, “this destination is unreachable”, “fragmentation was needed but you set Don’t-Fragment”, “this is a better route”.

Unlike TCP or UDP, ICMP is not used by applications for data transfer. Its job is to report problems back to whoever sent the offending packet, and to enable a handful of diagnostic tools (ping, traceroute, Path MTU Discovery). The protocol is intentionally minimal: a one-byte Type, a one-byte Code, a 16-bit Checksum, and a payload that varies by message.

ICMPv6 (RFC 4443) extends the ICMPv4 idea and absorbs the responsibilities of ARP (Neighbor Discovery) and IGMP (Multicast Listener Discovery). Where ICMPv4 is optional infrastructure, ICMPv6 is load-bearing — drop it and IPv6 stops working.

When to use it#

You almost never write code that emits ICMP directly. The OS does it on your behalf. You consume ICMP through:

  • ping — sends ICMP Echo Request (Type 8 in v4, 128 in v6), expects Echo Reply (Type 0 / 129). The simplest reachability test.
  • traceroute / tracert — sends UDP or ICMP probes with increasing TTL, reads Time Exceeded (Type 11 / 3) from each intermediate router. The map-the-path tool.
  • Path MTU Discovery — sends IP packets with DF set, listens for Fragmentation Needed (Type 3 Code 4 in v4) or Packet Too Big (Type 2 in v6), shrinks segments.
  • Connection-error feedback — UDP applications get Destination Unreachable Code 3 (port unreachable) when the peer port is closed. TCP folds the same information into RST.
  • Network monitoring — observability stacks ping continuously and graph loss / latency. Smokeping is the canonical example.

Avoid relying on ICMP for anything time-critical or security-critical. It is unreliable (best-effort, like the IP it rides on), often rate-limited by routers, and frequently filtered by overzealous firewalls.

How it works#

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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Rest of header (varies) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data — typically the IP header + first 64 bits |
| of the offending datagram |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The Type identifies the category of message; the Code narrows it. The Data field carries enough of the original datagram for the source to map the message back to a socket — the IP header plus the first 8 bytes (which contain TCP/UDP source and destination ports).

The Types you actually meet (ICMPv4)#

Type Code Meaning
0 0 Echo Reply (ping response)
3 0 Net Unreachable
3 1 Host Unreachable
3 3 Port Unreachable (UDP to closed port)
3 4 Fragmentation Needed and DF Set (PMTUD signal)
3 13 Communication Administratively Prohibited (firewall drop)
5 0/1 Redirect (router says "use this gateway instead")
8 0 Echo Request (ping probe)
11 0 TTL Exceeded in Transit (traceroute signal)
11 1 Fragment Reassembly Time Exceeded
12 0 Parameter Problem

ICMPv6 renumbers (Echo Request is 128, Echo Reply is 129, Time Exceeded is 3, Packet Too Big is 2) and adds the Neighbor Discovery family (133-137).

How traceroute uses TTL#

traceroute exploits a side effect: every router decrements TTL, and when TTL hits zero the router drops the packet and sends ICMP Time Exceeded to the source.

Send TTL=1 → first hop drops, ICMP Time Exceeded → record router 1
Send TTL=2 → second hop drops, ICMP Time Exceeded → record router 2
Send TTL=3 → third hop drops, ICMP Time Exceeded → record router 3
...
Send TTL=N → reaches destination, ICMP Echo Reply or UDP Port Unreachable

Each probe carries a different destination port (UDP traceroute) or sequence number (ICMP traceroute) so replies can be matched up. Modern implementations send three probes per hop and report min / avg / max RTT.

Path MTU Discovery#

The sender sets DF (Don’t Fragment) on every datagram. If a downstream link is too small, the offending router drops the datagram and emits ICMP Type 3 Code 4 carrying the link’s MTU in the “rest of header” field (RFC 1191). The sender updates its per-destination PMTU cache and resends with smaller segments.

When ICMP Fragmentation Needed is filtered (a common firewall misconfiguration), the sender never learns. Small flows work; large transfers stall. This is the “VPN works for SSH but breaks file transfer” failure mode.

Rate-limiting#

Routers cap ICMP generation aggressively — typically a few hundred Time Exceeded per second per router — because generating ICMP for every dropped packet during a DDoS would amplify the attack. Linux default net.ipv4.icmp_ratelimit is 1 token per millisecond.

Variants#

  • ICMPv4 (RFC 792, 1981). The original. Carried over IPv4 with protocol number 1. Optional infrastructure — IPv4 mostly works without it, except for PMTUD.
  • ICMPv6 (RFC 4443, 2006). Mandatory in IPv6. Carries Neighbor Discovery, Router Advertisement, Multicast Listener Discovery, in addition to the diagnostic types.
  • ICMP Echo with payload. ping -s 1400 lets you exercise specific MTU paths; ping -f flood-pings for stress testing (root only). Payload can be arbitrary up to MTU.
  • ICMP Timestamp (Type 13/14). Pre-NTP latency-and-clock probe. Mostly disabled today (information leak — host clock).
  • ICMP Redirect (Type 5). A router on the same LAN telling a host “use this other router for that destination”. Disabled by default on modern hosts due to abuse — an attacker on the LAN could MITM by injecting Redirects.
  • Smurf attack. Historical amplification — spoofed ICMP Echo Request to a network’s broadcast address, every host replied to the spoofed source. RFC 2644 mandated directed-broadcast disable; the attack is mostly extinct.

Trade-offs#

ICMP enabled — diagnostics work (ping, traceroute), PMTUD works, hosts get useful feedback on unreachable destinations, monitoring is straightforward. ICMP can be used for reconnaissance (host enumeration) and was historically an amplification vector (Smurf).
ICMP blocked — the network goes quiet for attackers but also for legitimate operators. PMTUD breaks (black-hole symptoms on large transfers), troubleshooting is harder, IPv6 stops working entirely if ICMPv6 is filtered.

Other tensions:

  • Diagnostic value vs information leak. Echo and Timestamp leak host existence and clock skew. Defenders sometimes drop them outright; operators sometimes need them.
  • Best-effort. ICMP errors are themselves IP datagrams — they can be dropped, reordered, or rate-limited. Never treat absence of an ICMP error as proof of success.
  • No ICMP-on-ICMP. RFC 792 forbids generating ICMP errors in response to ICMP errors — prevents loops.
  • Filtering granularity. “Block ICMP” is too coarse. RFC 4890 enumerates the ICMPv6 types that must pass; equivalent IPv4 guidance is RFC 4949 / vendor docs. Allow Echo, Time Exceeded, Fragmentation Needed at minimum.
Why does Linux let unprivileged users send ICMP Echo without root?

Historically ping was setuid root because raw sockets required root. Modern Linux ships net.ipv4.ping_group_range — a kernel mechanism that lets non-root processes send Echo Requests via the IPPROTO_ICMP socket type if their GID falls in the allowed range. The kernel restricts the socket to Echo / Echo Reply only (no other types), so the attack surface is narrow. macOS and BSD have analogous mechanisms.

Common pitfalls#

  • Blanket-blocking ICMP at the firewall. Breaks PMTUD silently; the symptom is “small requests work, large responses hang”. Allow Type 3 Code 4 at a minimum.
  • Treating ping failure as proof of host death. Many hosts (Windows by default, many cloud VMs) drop ICMP Echo. The host is alive; ICMP is the wrong probe. Use TCP-syn-ping on a known port instead.
  • Assuming traceroute paths are symmetric. Internet routes are routinely asymmetric; the path your probes take outbound is not the path the replies take inbound. The latency you see is round-trip.
  • Trusting ICMP source addresses. ICMP can be spoofed end-to-end. Never authenticate based on an ICMP source.
  • Filtering ICMPv6 the way you filter ICMPv4. ICMPv6 is mandatory; filtering Neighbor Solicitation breaks the LAN and filtering Packet Too Big breaks PMTUD.
  • Reading the “Code” without the “Type”. Code is only meaningful within a Type. Type 3 Code 4 (Fragmentation Needed) is unrelated to Type 11 Code 4 (which does not exist).
  • Using ICMP Redirect. Modern hosts ignore Redirects by default (net.ipv4.conf.all.accept_redirects=0). Do not design networks that rely on them.
  • Confusing ICMP rate-limit with link congestion. A traceroute hop showing 80% loss is usually router rate-limit, not a broken link — TCP flowing through that hop is fine.
Search ESC

Keyboard shortcuts

Shortcuts are disabled while typing in inputs.