ICMP Explained: ping, traceroute, and Message Types thumbnail

ICMP Explained: ping, traceroute, and Message Types

⏱ approx. 14 min views 75 likes 0 LOG_DATE:2026-05-09
TOC

Internet Control Message Protocol (ICMP) #

Conceptual diagram of ICMP carrying error and diagnostic messages across an IP network

Internet Control Message Protocol (ICMP) is the control protocol used to report errors and route conditions on IP networks. It doesn't carry application data — instead, it tells the sender "didn't reach", "TTL expired", "port is closed" so hosts and routers can react to what's actually happening. ping and traceroute are both built on top of it. Defined by RFC 792 (IPv4); IPv6 uses the redesigned ICMPv6 (RFC 4443).

1. Reading ICMP messages #

ICMP runs as an upper-layer protocol on top of IP (Protocol Number 1 for IPv4, 58 for IPv6). Unlike TCP/UDP, it has no port numbers, so it doesn't appear in the connection list of ss or netstat.

Diagram showing an ICMP packet composed of Ethernet, IP, and ICMP headers plus payload

The header is intentionally simple.

Field Size Purpose
Type 1 byte Message kind (Echo Request, Destination Unreachable, etc.)
Code 1 byte Sub-kind for the Type (e.g. Type 3 Code 1 = Host Unreachable)
Checksum 2 bytes Verifies the entire ICMP message
Rest of Header 4 bytes Type-specific (Echo's Identifier+Sequence, etc.)
Data variable For error messages, contains the failing IP packet's IP header plus its first 8 bytes

The key is that last field. Because error messages echo back part of the original packet, the sender can identify which packet failed and how. When reading ICMP in tcpdump, look at the inner IP header (Source / Dest IP, TCP port) along with Type/Code — that's usually what tells you what went wrong.

2. What ping and traceroute are really doing #

2.1 ping = Echo Request (Type 8) / Echo Reply (Type 0) #

ping sends Type 8 and times how long Type 0 takes to come back. The Identifier + Sequence Number let you distinguish concurrent pings, so multiple pings from the same host coexist correctly.

When no reply comes, the triage paths are:

  • Nothing returns → something on the path (or the destination firewall) is dropping ICMP
  • Destination Unreachable (Type 3) returns → something on the path is explicitly telling you why it couldn't deliver. The Code says which reason (§3)
  • TTL exceeded (Type 11) returns → routing loop, or you sent with an unusually low TTL

"ping doesn't reach == host is dead" is not a safe inference. Plenty of web servers block ICMP while serving traffic fine.

2.2 traceroute increments TTL and collects Time Exceeded #

traceroute sends probes with TTL = 1, 2, 3, ... and stitches the path together from the Time Exceeded (Type 11) messages each hop returns. The final host doesn't return Type 11, so traceroute needs another signal to know it arrived:

  • UDP high port (Linux/macOS default): if the final host returns Port Unreachable (Type 3 Code 3), it's arrival
  • ICMP Echo (Windows tracert, Linux traceroute -I): final host returns Echo Reply (Type 0)
  • TCP SYN (traceroute -T / tcptraceroute): probe on 80/443 to trace through firewalls that drop UDP/ICMP

What about the * * * rows? They mean that hop's router didn't return Time Exceeded (or is rate-limiting ICMP generation). Many routers rate-limit ICMP, so hops disappearing is not unusual.

3. Messages you read in the field #

3.1 Destination Unreachable (Type 3) — read by Code #

Code Meaning What it means on the ground
0 Network Unreachable No route to that network in the routing table
1 Host Unreachable The last-hop router can't ARP-resolve the host's MAC
3 Port Unreachable UDP port is closed, or it's the UDP-traceroute "arrived" signal
4 Fragmentation Needed and DF Set Essential for PMTUD (§4)
9 Network Administratively Prohibited ACL deny at network scope
10 Host Administratively Prohibited ACL deny at host scope
13 Communication Administratively Prohibited Firewall block

Code 3 (Port Unreachable) is what you'll typically see as a reply to a UDP probe — also a common reason dig resolution fails. Code 13 is an explicit firewall reject, so the network owner is the one to ask.

3.2 Time Exceeded (Type 11) #

Code Meaning
0 TTL Exceeded in Transit (TTL hit 0 mid-route)
1 Fragment Reassembly Time Exceeded

Code 0 is also the traceroute signal — but if you see lots of it in production, suspect a routing loop.

3.3 Redirect (Type 5) #

A router telling a host "there's a better route." Spoofable into a MITM, so modern OSes don't accept it by default (see §6).

3.4 Deprecated / safe-to-ignore #

  • Source Quench (Type 4): deprecated by RFC 6633 (2012). Leave congestion control to TCP ECN.
  • Timestamp (Type 13/14): replaced by NTP. Abused for uptime fingerprinting, so dropping outbound is the norm.
  • Address Mask Request (Type 17/18): DHCP replaced it.

4. PMTUD black hole — the canonical "ICMP fully blocked breaks things" story #

When the path has a smaller MTU somewhere, a router that drops a DF (Don't Fragment) packet returns Destination Unreachable Code 4 (Fragmentation Needed). The sender uses this to lower the TCP MSS — that's Path MTU Discovery (PMTUD).

If a firewall "blocks all ICMP", Code 4 doesn't get back to the sender — and large TCP segments just silently disappear:

  • Small HTTP requests work
  • Large POSTs or responses suddenly hang
  • A standard small ping still works, so the network looks healthy

This is the PMTUD black hole, and it's the textbook cause of "this VPN only stalls on some traffic" or "this one API response always times out" — the most reproducibility-resistant kind of outage. Always allow Type 3 Code 4 through.

A workaround is TCP MSS Clamping, where the router rewrites the MSS field of TCP SYNs to a safe value. Essentially mandatory in VPN and PPPoE deployments.

5. ICMPv6 — blocking it breaks IPv6 #

In IPv6, ICMP's role expanded dramatically and is now indispensable to IPv6 itself. ARP, IGMP, Router Discovery, and so on are all folded into ICMPv6.

Function Type Role
Neighbor Solicitation 135 IPv4 ARP equivalent — resolve a neighbor's MAC
Neighbor Advertisement 136 Reply to NS
Router Solicitation 133 Host asks "any routers here?"
Router Advertisement 134 Router announces itself + prefix (core of SLAAC)
MLD 130-132, 143 IPv4 IGMP equivalent for multicast group management

If you block all ICMPv6, NDP and RA stop working — IPv6 simply doesn't function. Read RFC 4890 before designing IPv6 filtering — it specifies which Types are safe to drop and which absolutely must pass.

6. Security points worth knowing now #

Smurf and Ping of Death made historical headlines but are mitigated in modern OSes and routers. What's still worth caring about today:

6.1 ICMP Redirect spoofing #

An attacker on the local segment sends a forged ICMP Redirect to lure traffic through themselves — a classic MITM. On Linux, lock it down with:

sysctl -w net.ipv4.conf.all.accept_redirects=0
sysctl -w net.ipv4.conf.all.send_redirects=0
sysctl -w net.ipv6.conf.all.accept_redirects=0

6.2 ICMP tunneling (covert channel) #

Stuff arbitrary data into Echo Request/Reply payloads to disguise TCP/UDP traffic as ICMP and slip through firewalls. icmpsh and ptunnel are the well-known examples; APT campaigns have used the technique for C2.

Detection clues:

  • Unusually large or sustained Echo packets (normal pings are ~64 bytes)
  • One-way Echo traffic with no replies (high volume internal → external)
  • ICMP egress from servers monitored at the perimeter firewall

6.3 OS fingerprinting #

Quirks in ICMP replies (initial TTL, choice of Codes, what gets answered) feed nmap -O and similar tools. For internet-facing hosts, dropping Timestamp (Type 13/14) is a low-cost reduction in recon signal.

6.4 Ping flood / rate limiting #

A simple DoS — just blast Echo Requests. Standard mitigation: kernel-level icmp_ratelimit on Linux / routers, plus firewall rules that gate Echo Request through a limit module (§7).

7. Filtering strategy — neither "allow all" nor "block all" #

"Block all ICMP for safety" is wrong. PMTUD breaks and diagnostics die. Selective allow is the right model.

7.1 What to allow / what to drop #

# Allow (inbound and outbound)
- Destination Unreachable (Type 3) Code 4: mandatory (PMTUD)
- Destination Unreachable (Type 3) other codes: allowing makes ops far easier
- Time Exceeded (Type 11): for traceroute / diagnostics
- Echo Request (Type 8): rate-limit and allow (full deny kills diagnostics)
- Echo Reply (Type 0): for replies to your own pings

# Safe to drop
- Redirect (Type 5): MITM risk
- Timestamp (Type 13/14): recon abuse
- Address Mask Request (Type 17/18): no use case
- Source Quench (Type 4): deprecated

7.2 iptables example #

# Rate-limit Echo Request to 5/sec
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 5/sec -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-request -j DROP

# Allow Destination Unreachable and Time Exceeded
iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT

# Drop Redirect and Timestamp
iptables -A INPUT -p icmp --icmp-type redirect -j DROP
iptables -A INPUT -p icmp --icmp-type timestamp-request -j DROP

7.3 For ICMPv6, follow RFC 4890 #

Because NDP, RA, MLD, and PMTUDv6 all ride on ICMPv6, run a blacklist model (explicit drops only). A blanket ip6tables drop will immediately kill connectivity.


ICMP is unglamorous, but it's the protocol that brings you the first signal when something breaks. When you reach for ping / traceroute / mtr during triage, looking at "is the reply Type 3 or Type 11, and what's the Code?" cuts the distance to the root cause sharply. Stop reflexively blocking all ICMP — keep at minimum Code 4 (PMTUD) and Time Exceeded allowed, and you've taken the first real step toward reconciling operations and security.