14. ICMP: ping, traceroute, and Path MTU Discovery
14.1 What ICMP is for
ICMP (Internet Control Message Protocol) is IP's error-reporting and
diagnostic sidekick (IP protocol number 1; ICMPv6 is 58). It is not a
transport — no ports. An ICMP error message quotes the IP header + first 8 bytes
of the offending packet so the sender can match it to a socket.
14.2 Message types you must know
| Type/Code | Name | Triggered by | Seen as |
|---|---|---|---|
| 8 / 0 | Echo Request / Reply | ping |
reachability + RTT |
| 3 / 0 | Destination unreachable: net | no route | "Destination Net Unreachable" |
| 3 / 1 | … : host | ARP fails for final hop | "Destination Host Unreachable" |
| 3 / 3 | … : port | UDP packet to a closed port | how traceroute detects the end; "connection refused" for UDP |
| 3 / 4 | Fragmentation needed & DF set | oversize packet, DF=1 | PMTUD signal (Ch. 8) |
| 3 / 13 | Communication administratively prohibited | firewall REJECT |
!X in traceroute |
| 5 | Redirect | "use a better first-hop router" | often filtered (spoofing risk) |
| 11 / 0 | Time exceeded in transit (TTL hit 0) | traceroute |
each hop reply |
| 11 / 1 | Fragment reassembly time exceeded | lost fragment | reassembly failures |
| 12 | Parameter problem | malformed header | rare |
14.3 How ping works
Sends ICMP Echo Request; the target's kernel replies with Echo Reply (no app involved). Measures RTT and loss.
Caveats:
- Many hosts/firewalls rate-limit or drop ICMP → "ping fails" ≠ "host down."
- ICMP may be deprioritized by routers (control-plane policing) → ping latency/loss to a router's own address can look terrible while transit traffic through it is perfect. Always ping the endpoint, not an intermediate hop, for real numbers.
ping -s <size> -M dotests PMTU (don't-fragment, set payload size).ping -f(flood) and large counts need care on production links.
14.4 How traceroute works
Send packets with increasing TTL: TTL 1 → first router drops it and returns
ICMP time-exceeded (revealing hop 1's IP); TTL 2 → hop 2; and so on until a
packet reaches the destination.
- Unix traceroute: UDP to high ports by default; destination replies with
ICMP port unreachable(type 3/3) → done. - Windows
tracert: ICMP Echo. traceroute -T/tcptraceroute: TCP SYN to a real port (e.g. 443) — best for paths where UDP/ICMP is filtered but TCP/443 is open.
Reading it:
* * *at a hop = that router doesn't send time-exceeded (or rate-limits it). Not necessarily a problem if later hops respond.- Rising latency that stays high from some hop onward = real; a single hop with high latency but lower latency after it = that router just deprioritizes ICMP to itself. Ignore it.
- Different IPs per probe at the same hop = ECMP load balancing (Ch. 50). Use
tracerouteParis-mode to keep the flow tuple constant. - Asymmetry: traceroute shows the forward path only; the return path can differ and cause latency you can't see here.
14.5 mtr — the tool you should actually use
mtr runs continuous traceroute + ping, showing per-hop loss %, mean, and
jitter over time. Loss that appears at hop N and every hop after = real loss at
N. Loss at hop N only, with 0% after = cosmetic (ICMP rate limiting at N).
14.6 Do NOT block all ICMP
Blocking ICMPv4 entirely breaks PMTUD (Ch. 8 black hole). Blocking ICMPv6 breaks Neighbor Discovery (Ch. 17) — IPv6 stops working. Minimum allow-list:
- v4: echo request/reply (optional), type 3 (all), type 11.
- v6: types 1, 2, 3, 4, 128/129 (echo), and NDP types 133–137 on-link.
14.7 War story
"Traceroute shows 30% packet loss at hop 6 — the ISP has a bad router!" mtr
showed 30% at hop 6 and 0% at hops 7–15 and the destination. Hop 6 was a core
router policing ICMP-to-self at 100 pps; transit traffic was untouched. The real
user-visible issue was elsewhere (an overloaded app server). Lesson: only
trust hop loss if it persists through every subsequent hop.
Try it yourself
ping -c5 -W1 example.com
ping -M do -s 1472 -c3 example.com # PMTU probe
traceroute -n example.com
traceroute -T -p 443 -n example.com # TCP traceroute to a real port
mtr -rwzbc100 example.com
sudo tcpdump -i any -n icmp or icmp6 # watch ICMP live