ICMP — The Internet's Error Reporting System
A deep-dive into how ICMP carries error messages and diagnostics across IP networks — covering TTL mechanics, path MTU discovery, traceroute internals, ping packet structure, ICMPv6 NDP, and the security implications of filtering ICMP.
// Chapter 01
The Protocol That Holds IP Together
That something is ICMP: the Internet Control Message Protocol. It is the out-of-band signaling system for the IP network — the mechanism by which routers and hosts report errors, announce unreachability, and provide diagnostic information. Without ICMP, a TCP connection to an unreachable host would hang silently for minutes before timing out. Without ICMP, you could not run ping or traceroute. Without ICMP Type 3 Code 4, every connection across networks with different MTUs would break.
ICMP is not optional. It is essential infrastructure, and understanding it is essential for anyone who troubleshoots networks or designs firewall policies.
ICMP (Internet Control Message Protocol) is defined in RFC 792 (ICMPv4) and RFC 4443 (ICMPv6). It rides inside IP packets with protocol number 1 (IPv4) or next header value 58 (IPv6). ICMP is not a transport protocol — it carries no application data. Its sole purpose is network-layer signaling: error reporting, reachability testing, and path discovery.
ICMP messages have a common 8-byte header: a Type field (message category), a Code field (sub-type within category), a Checksum (integrity verification over the ICMP message), and a variable rest-of-header whose fields depend on the type. Error messages also include the IP header and first 8 bytes of the original packet that triggered the error — enough to identify the causing flow.
// Chapter 02
ICMP Message Types
ICMP Message Type Explorer
Select a message type to understand its purpose, the tools that use it, and firewall considerations.
ICMP in Error Messages — The Embedded Packet
ICMP error messages (types 3, 4, 5, 11, 12) carry the IP header + first 8 bytes of the original packet that caused the error. This is enough to identify: the source and destination addresses, the protocol (TCP/UDP), and for TCP/UDP, the source and destination port numbers. This allows the receiving host to correlate the error with the specific connection that triggered it.
Eight bytes covers exactly a TCP/UDP/ICMP header — which is why 8 bytes was chosen. Applications can then deliver the error to the correct socket. This is how TCP knows to send RST when it receives ICMP Port Unreachable for a connection: the 8 bytes contain the original TCP port numbers, and the TCP stack matches them to the active socket.
# Analyze ICMP in Wireshark / tcpdump tcpdump -i eth0 icmp # Capture all ICMP tcpdump -i eth0 'icmp[icmptype]=3' # Only Destination Unreachable tcpdump -i eth0 'icmp[icmptype]=11' # Only Time Exceeded (traceroute) tcpdump -i eth0 'icmp[0]=3 and icmp[1]=4' # ICMP type 3 code 4 (PMTUD critical!) # In Wireshark filter bar: icmp.type == 3 and icmp.code == 4 # Fragmentation Needed icmp.type == 8 # Echo Request (ping outbound) icmp.type == 11 # Time Exceeded (traceroute hops)
// Chapter 03
ping — More Than Just Latency
ping is elementary. But interpreted correctly, its output is a diagnostic goldmine.
ping uses ICMP Echo Request (Type 8) and Echo Reply (Type 0) to measure round-trip time and detect packet loss. The Identifier field is typically the process ID, allowing multiple simultaneous ping processes to distinguish their own replies. The Sequence Number increments per packet, allowing detection of out-of-order replies and gaps (packet loss).
ICMP Echo Request — Packet Header Dissector
Click any field in the packet header to understand its purpose and values.
ICMP ECHO REQUEST PACKET (84 bytes total: 20 IP + 8 ICMP header + 56 data)
Type
8 bits
0x08 (8)
Code
8 bits
0x00 (0)
Checksum
16 bits
0xF7FF
Identifier
16 bits
0x1A2B
Sequence Number
16 bits
0x0001
Data (Payload)
Variable
48 bytes of padding
Advanced ping Techniques
ping is far more versatile than most users realize:
# Basic ping ping 8.8.8.8 # ICMP echo to Google DNS # Specify packet size (for MTU testing) ping -s 1472 8.8.8.8 # 1472 bytes data + 8 ICMP + 20 IP = 1500 bytes ping -s 8972 192.168.1.1 # Test jumbo frames (9000 byte MTU path) # Set DF (Don't Fragment) bit — critical for PMTUD testing ping -M do -s 1473 8.8.8.8 # Linux: force DF bit, 1501 bytes — should get ICMP type 3/4 back ping -f -l 1473 8.8.8.8 # Windows: force DF + size # Count and interval ping -c 100 -i 0.2 8.8.8.8 # 100 pings at 0.2s interval (flood-like, needs root for <0.2s) ping -i 0.01 -f 8.8.8.8 # Flood ping (root required) — stress test # TTL manipulation ping -t 3 8.8.8.8 # Windows: TTL=3, reaches only 3 hops ping -m 3 8.8.8.8 # macOS TTL limit # Record route (IPv4 option — traces path in IP header) ping -R 8.8.8.8 # Record Route option (max 9 hops due to IP header limits) # Interpret output # 64 bytes from 8.8.8.8: icmp_seq=1 ttl=117 time=20.3 ms # └─ ttl=117 means Google starts with TTL ~128 (or 255), decremented 11 times = 11 hops from Google # └─ time=20.3 ms = round-trip latency
// Chapter 04
traceroute — Mapping the Network Path
Three packets are sent per hop (hence three RTT columns in the output). This allows detection of asymmetric paths and load-balanced routes — if the three packets take different paths, the three RTTs will differ dramatically, or show three different IPs for the same hop.
Traceroute Path Simulator
Simulate traceroute 8.8.8.8 — watch each TTL hop discover a new router via ICMP Time Exceeded messages.
traceroute to 8.8.8.8 (Google DNS), 30 hops max
Reading Traceroute Output
Key patterns to recognize in traceroute output:
• * * * (all three probes timeout): the router at that hop does not send ICMP Time Exceeded, or its ICMP responses are firewall-filtered. The path may continue — stars do NOT mean a broken route, just an invisible hop.
• RTT spike at a hop, then lower RTTs after: the router at the spike is rate-limiting ICMP (prioritizing forwarded traffic over self-generated ICMP). Forwarded packet latency is actually lower. This is normal behavior for well-configured routers.
• Different IPs on the same hop line: ECMP (Equal-Cost Multi-Path) — three packets took different paths. Common in data centers and ISP cores.
• Same IP repeated on multiple hops: routing loop. Packets are cycling between two routers.
# traceroute variants traceroute 8.8.8.8 # UDP probes (Linux default), ports 33434+ traceroute -I 8.8.8.8 # ICMP Echo probes (requires root, matches ping behavior) traceroute -T -p 80 8.8.8.8 # TCP SYN probes to port 80 (bypasses ICMP filters) traceroute -T -p 443 8.8.8.8 # TCP SYN to 443 (common for testing through firewalls) tracert 8.8.8.8 # Windows: ICMP Echo by default # mtr — real-time combined ping+traceroute mtr 8.8.8.8 # Interactive, updates live mtr --report --report-cycles 100 8.8.8.8 # 100 samples per hop, great for diagnosing intermittent loss # Paris traceroute — uses consistent flow hash to avoid ECMP variation paris-traceroute 8.8.8.8 # Keeps 5-tuple constant, shows single path # Traceroute6 for IPv6 traceroute6 2001:4860:4860::8888 # IPv6 traceroute
// Chapter 05
Path MTU Discovery — ICMP's Most Critical Function
This is the TCP Black Hole problem, and ICMP Type 3 Code 4 is the only solution. What happened: somewhere on the path, a link has an MTU smaller than 1500 bytes (common in VPN tunnels, MPLS networks, or ISP links). The router at that link tries to fragment the packet, but the Don't Fragment (DF) bit is set by TCP. The router must send ICMP Fragmentation Needed back to the source — but that ICMP message is blocked by a firewall. The source never learns about the MTU constraint and keeps sending full-size packets that silently disappear.
The fix: never, under any circumstances, block ICMP Type 3 Code 4.
Path MTU Discovery (PMTUD) is the mechanism by which TCP (and other protocols) discover the smallest MTU on the entire path from source to destination. It works through the interaction of the IP DF (Don't Fragment) bit and ICMP Type 3 Code 4 messages:
1. The sender sets the DF bit on all packets (TCP does this by default).
2. A router encounters a link with MTU smaller than the packet size.
3. The router cannot fragment the packet (DF is set), so it discards it and sends ICMP Type 3 Code 4 back to the source, including the MTU of the constraining link.
4. The source receives the ICMP message, reduces its send size (lowers TCP MSS or fragments at a size below the reported MTU), and retransmits.
5. This repeats until the smallest MTU on the path is discovered.
# Test PMTUD manually # Find the PMTU to a destination: ping -M do -s 1472 8.8.8.8 # DF bit set, 1472 data + 8 ICMP + 20 IP = 1500 total ping -M do -s 1400 8.8.8.8 # If 1472 fails, try smaller # If you get ICMP Fragmentation Needed back: # PING 8.8.8.8 (8.8.8.8) 1472(1500) bytes of data. # From 10.0.0.1 icmp_seq=1 Frag needed and DF set (mtu = 1452) # ↑ PMTU to 8.8.8.8 is 1452 bytes (common with PPPoE: 1500 - 8 PPPoE header = 1492) # Diagnose TCP Black Hole: # 1. TCP handshake works (small SYN/SYN-ACK fit through) # 2. Large data packets silently disappear # 3. Capture shows ICMP Type 3 Code 4 being received but... silently dropped by firewall tcpdump -i eth0 'icmp[0]=3 and icmp[1]=4' # Watch for PMTUD ICMP # Fix on a Linux router when PMTUD is broken: # TCP MSS clamping (workaround for broken PMTUD) iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
TCP MSS (Maximum Segment Size) clamping is the production workaround when PMTUD is broken. During the TCP handshake, both sides advertise their MSS (maximum payload they can receive). A router with MSS clamping intercepts the SYN and SYN-ACK and rewrites the MSS option to a safe value (typically 1452 for PPPoE or 1436 for VPNs). This prevents large packets from being sent in the first place, bypassing the need for ICMP PMTUD messages entirely.
// Chapter 06
ICMPv6 — NDP and IPv6's Essential ICMP
If you block ICMPv6 in a firewall, your IPv6 network stops working. Not partially — completely. NDP (Neighbor Discovery Protocol) is built entirely on ICMPv6 Type 133–137. IPv6 routers send Router Advertisements via ICMPv6 Type 134. Hosts detect duplicate addresses via ICMPv6 Type 135. None of this is optional.
ICMPv6 carries all the functions of ICMPv4 plus additional roles specific to IPv6. The key ICMPv6 message types:
ICMPv6 Message Types --- Type 1: Destination Unreachable Type 2: Packet Too Big (replaces ICMPv4 Type 3 Code 4 — PMTUD) Type 3: Time Exceeded (traceroute — same as ICMPv4 Type 11) Type 4: Parameter Problem Neighbor Discovery Protocol (NDP) — replaces ARP: Type 133: Router Solicitation (RS) — host asks "any routers here?" Type 134: Router Advertisement (RA) — router announces prefix, M/O flags, MTU Type 135: Neighbor Solicitation (NS) — like ARP Request: "who has 2001:db8::1?" Type 136: Neighbor Advertisement (NA) — like ARP Reply: "I have 2001:db8::1, my MAC is X" Type 137: Redirect — router tells host of better next-hop Multicast Listener Discovery (MLD — replaces IGMP): Type 130: MLD Query Type 131: MLD Report (v1) Type 132: MLD Done Type 143: MLDv2 Report
Critically, IPv6 has no broadcast — NDP uses solicited-node multicast instead of broadcast for neighbor resolution. When a host needs to resolve 2001:db8::1234:5678, it sends a Neighbor Solicitation to the solicited-node multicast address FF02::1:FF34:5678 (last 24 bits of target). Only the host(s) with that address suffix receive the message, dramatically reducing overhead compared to ARP broadcast.
// Chapter 07
ICMP and Firewalls — What to Allow, What to Block
Blanket ICMP blocking is one of the most common network misconfigurations. A properly written firewall policy is surgical, not blanket.
The correct ICMP filtering policy for a perimeter firewall:
# Firewall ICMP policy (iptables example — apply to both IPv4 and IPv6) # ALWAYS ALLOW — critical for network operation: iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT # Type 3 all codes iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT # Type 11 (traceroute) iptables -A OUTPUT -p icmp --icmp-type destination-unreachable -j ACCEPT iptables -A OUTPUT -p icmp --icmp-type time-exceeded -j ACCEPT # Critical: PMTUD — NEVER block: iptables -A INPUT -p icmp --icmp-type fragmentation-needed -j ACCEPT # Type 3 Code 4 iptables -A OUTPUT -p icmp --icmp-type fragmentation-needed -j ACCEPT # ALLOW with rate-limiting (operational but can be abused): iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 10/s -j ACCEPT # ping in iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT # ping out replies iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT # ping out # DROP (rarely needed, potential abuse vectors): # ICMP redirect (Type 5) — should be blocked, routers should not send redirects externally iptables -A INPUT -p icmp --icmp-type redirect -j DROP # IPv6 — ALWAYS allow NDP (required for IPv6 to work): ip6tables -A INPUT -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT # Type 134 ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT # Type 135 ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT # Type 136 ip6tables -A INPUT -p icmpv6 --icmpv6-type packet-too-big -j ACCEPT # Type 2 (PMTUD)
net.ipv4.conf.all.accept_redirects=0 to ignore host-directed ICMP redirects regardless of firewall rules.// Chapter 08
ICMP in Network Diagnostics
The diagnosis: the database server NIC has jumbo frames enabled (MTU 9000). The application server NIC has standard frames (MTU 1500). The network path between them goes through a switch that supports jumbo frames, but the switch's uplink to the router does not. Large database result sets — packets over 1500 bytes — trigger PMTUD. The router sends ICMP Type 3 Code 4 back to the database server. But the database server's OS has PMTUD blackhole detection disabled. It never reduces its packet size and keeps sending 9000-byte packets that silently disappear.
MTU mismatch + PMTUD failure = one of the most frustrating networking problems to diagnose.
MTU Testing and Diagnosis
# Find MTU on a path (binary search approach) ping -M do -s 1472 10.0.0.1 # 1500 total — works if MTU >= 1500 ping -M do -s 1452 10.0.0.1 # 1480 total — PPPoE path (1492 MTU) ping -M do -s 1436 10.0.0.1 # 1464 total — IPSec/GRE path # Linux MTU detection with tracepath (auto-discovers PMTU) tracepath 8.8.8.8 # Shows MTU changes at each hop # Verify PMTUD is working on a connection ss -i dst 8.8.8.8 # Shows TCP socket info including MSS # Check system-level PMTUD settings (Linux) cat /proc/sys/net/ipv4/tcp_mtu_probing # 0=off, 1=on-error, 2=always sysctl -w net.ipv4.tcp_mtu_probing=1 # Enable PMTUD probing on MTU failures
ICMP Rate Limiting and Amplification
Routers must rate-limit ICMP generation to prevent CPU exhaustion. When thousands of packets arrive per second requiring ICMP error responses, generating a response for each would saturate the router's management plane. RFC 1812 recommends ICMP rate limiting; most routers implement token bucket rate limiters for ICMP generation.
ICMP amplification attacks use large ICMP Echo requests sent to broadcast/anycast addresses. Each request can generate many replies (one per host on the subnet). The attacker spoofs the victim's source IP, so all replies flood toward the victim. Modern routers block directed broadcast by default (no ip directed-broadcast in IOS) to prevent Smurf-style amplification.
// Chapter 09
ICMP in Security Tools
ICMP is extensively used in network security tooling for both legitimate reconnaissance and attack purposes:
Legitimate Security Uses of ICMP
• Network mapping: ICMP echo sweeps (fping, nmap -sP) discover live hosts faster than TCP port scanning. Useful for inventory and monitoring.
• Latency monitoring: continuous ping-based SLA monitoring (SmokePing, LibreNMS) detects performance degradation before users notice.
• Path analysis: mtr and Paris traceroute identify routing problems, congestion points, and asymmetric paths.
• MTU validation: ping with specific sizes and DF bit validates MTU throughout the network path.
ICMP Tunneling
ICMP tunneling encodes arbitrary data in the payload of ICMP Echo Request/Reply packets. Since ping is widely allowed through firewalls, ICMP tunnels can exfiltrate data or establish C2 channels through firewalls that block all TCP/UDP. Tools like ptunnel and icmptunnel implement this. Detection methods: look for unusually large ICMP payloads (legitimate ping is 32–56 bytes; tunneled payloads are 512+ bytes), high ICMP request rates, or ICMP traffic to unusual destinations.
# Detect ICMP tunneling with tcpdump/Wireshark # Normal ping: 64-byte packets (8 ICMP header + 56 bytes data) # Tunneled ICMP: 1500-byte packets or large data payloads # Detect in tcpdump: tcpdump -i eth0 'icmp[icmptype]=8 and len > 200' # Large ICMP Echo Requests # Detect with Snort/Suricata rule: # alert icmp any any -> any any (msg:"Possible ICMP Tunnel"; dsize:>512; sid:1000001;) # Legitimate reasons for large ICMP: # - ping with -s flag (manual size test) # - Network monitoring tools (ICMP probes with timestamp payloads) # - PMTUD testing
// Chapter 10
OS Fingerprinting via ICMP
OS fingerprinting techniques using ICMP:
• Initial TTL: Windows defaults to TTL=128, Linux/macOS to TTL=64, Cisco IOS to TTL=255. Receiving TTL=117 suggests ~11 hops from a Windows host (128-11=117).
• ICMP Error body: some OSes return more than 8 bytes of the original packet in error messages. The amount returned varies by implementation.
• ICMP Timestamp: Type 13 (Timestamp Request) / Type 14 (Timestamp Reply) can reveal system uptime from the timestamp value, and the rate at which the counter increments reveals OS clock resolution.
• Echo Request behavior: Windows sets the DF bit on ICMP Echo; Linux does not by default. The data pattern in the payload also varies by OS.
// Chapter 11
ICMP in Cloud and Virtualized Environments
Cloud environments introduce ICMP considerations that differ from traditional networking:
• AWS: Security Groups are stateful — allowing ICMP Echo outbound automatically allows Echo Reply inbound. ICMP Type 3 is allowed by default for network reachability. Jumbo frames (MTU 9001) are supported within VPCs but PMTUD handles transitions to internet (MTU 1500).
• Azure: NSG (Network Security Group) rules control ICMP per subnet/NIC. Azure allows ICMP for Azure health probes by default but blocks external pings unless explicitly allowed.
• GCP: Firewall rules are unidirectional — must explicitly allow ICMP Echo in ingress rules. GCP uses Andromeda network virtualization which handles MTU internally.
# AWS: Allow ICMP in Security Group (Terraform)
resource "aws_security_group_rule" "icmp_all" {
type = "ingress"
from_port = -1
to_port = -1
protocol = "icmp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.main.id
}
# Allow specific ICMP types (Type 3 for PMTUD — always needed):
resource "aws_security_group_rule" "icmp_unreachable" {
type = "ingress"
from_port = 3 # ICMP Type 3 (Destination Unreachable)
to_port = -1
protocol = "icmp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.main.id
}
# GCP: Allow ICMP in firewall rule
gcloud compute firewall-rules create allow-icmp --network=my-network --action=ALLOW --rules=icmp --source-ranges=0.0.0.0/0// Chapter 12
Troubleshooting with ICMP
# Connectivity diagnostic hierarchy # Step 1: Local gateway ping 192.168.1.1 # Gateway reachable? (Layer 3 local) # Step 2: Remote LAN ping 10.0.0.1 # Across router — tests routing # Step 3: Internet ping 8.8.8.8 # Internet connectivity # Step 4: DNS ping google.com # DNS resolution + internet # Step 5: Path analysis traceroute -I 8.8.8.8 # ICMP trace — find where path breaks mtr --report 8.8.8.8 # 100 samples per hop, find packet loss # Step 6: MTU ping -M do -s 1472 8.8.8.8 # Test 1500-byte path ping -M do -s 1400 8.8.8.8 # Test smaller # Step 7: IPv6 ping6 ::1 # IPv6 loopback ping6 2001:4860:4860::8888 # IPv6 internet traceroute6 2001:4860:4860::8888 # IPv6 path # Interpret results: # ping works, TCP connection hangs → PMTUD broken (check ICMP type 3/4 filtering) # ping works, SSH fails → port filtered or service down # ping fails, traceroute shows * after hop 3 → path broken at router 4 # ping RTT spikes randomly → congestion or routing instability
// Chapter 13
Common Misconceptions
// Chapter 14
Depth Check
🎯 Key Takeaways
- ✓ICMP is the error-reporting and diagnostic layer for IP networks — not optional infrastructure. IP itself provides no error feedback; ICMP fills this gap.
- ✓ICMP Type 3 Code 4 (Fragmentation Needed) must NEVER be blocked. Filtering it causes TCP Black Hole: connections establish but silently fail on data transfer when packets exceed the path MTU.
- ✓traceroute exploits TTL expiration: each probe with TTL=N discovers hop N by triggering ICMP Time Exceeded (Type 11) from that router. Stars (*) mean the hop does not send ICMP — not that the path is broken.
- ✓ICMP Redirect (Type 5) from untrusted sources can hijack traffic. Block inbound ICMP Redirect at all perimeter firewalls and disable kernel redirect acceptance on hosts.
- ✓ICMPv6 is essential for IPv6 operation — Types 133–136 (NDP) replace ARP and router discovery. Blocking ICMPv6 NDP completely breaks IPv6 neighbor resolution.
- ✓Solicited-node multicast (FF02::1:FF + last 24 bits of address) makes IPv6 neighbor discovery far more efficient than ARP broadcast — only the targeted host receives the Neighbor Solicitation.
- ✓ICMP tunneling encodes data in Echo Request/Reply payloads, bypassing firewalls that allow ICMP. Detect via payload size (> 200 bytes), rate (continuous vs. 1/second), and destination anomalies.
- ✓OS fingerprinting uses ICMP: initial TTL reveals OS family (Windows=128, Linux=64, Cisco=255), DF bit behavior, and Timestamp Request/Reply can expose system uptime.
- ✓Path MTU Discovery requires ICMP Type 3 Code 4 to flow freely. When PMTUD is broken, MSS clamping at the bottleneck device (VPN gateway, tunnel endpoint) is the production workaround.
- ✓ping RTT is not pure network latency — routers process ICMP in software (slow path), adding 1–5ms. Use transit measurements (traceroute RTT comparison) for accurate link latency assessment.
Discussion
0Have a better approach? Found something outdated? Share it — your knowledge helps everyone learning here.