Core CS · Computer Networks
IP never promises delivery, so ICMP reports the failure
A router in the middle drops your packet and IP itself tells you nothing. ICMP is the one protocol whose entire job is to send that news back to you, and the two commands you already type are built out of nothing else.
Step traceroute one TTL at a time and watch the hops appear →01 The idea
A protocol that only knows how to complain
IP is best effort, which is a polite way of saying it promises nothing. There is no acknowledgement, no retransmission, no guarantee of order and no guarantee of arrival. A router that cannot forward your packet drops it, and IP has no field, no flag and no mechanism for saying so. If that were the end of the story, a host would send a packet into the network and never learn anything at all about what happened to it.
So the same document set that defines IP also defines a companion for exactly this gap. ICMP, the Internet Control Message Protocol of RFC 792, is the part of the network layer that sends the bad news back. It is carried in the payload of an ordinary IP packet, and the IP header’s Protocol field holds 1 to say so, the same field that holds 6 for TCP and 17 for UDP. That single number is the whole answer to the question interviewers open with. ICMP does not run over TCP and it does not run over UDP; it sits beside them, as a service to IP rather than a service to an application.
Now the distinction to say early, because everything else follows from it. ICMP reports, it does not repair. It never retransmits the packet that was lost. It never picks a different route. It never slows a sender down. It hands a diagnosis to whoever sent the failed packet and then it stops. What happens next is somebody else’s job: TCP may retransmit, an application may show an error, a human may run traceroute. Every candidate who describes ICMP as “the error-correcting protocol” loses the question there.
One design decision makes the diagnosis usable. An ICMP error message is not just a code; it carries a quotation of the packet that failed, specifically that packet’s IP header plus the first 8 bytes that followed it. Think about why the number is 8. A UDP header is exactly 8 bytes, and the first 8 bytes of a TCP header are the source port, the destination port and the sequence number. Either way the sender gets both port numbers back, so a host with forty packets in flight to the same destination can identify the one that died and the connection it belonged to. Without the quotation the error would say only “something to that address failed”, which is very nearly useless.
The last piece is a single byte in the IP header called TTL, and the two tools this lesson ends with are built on it. Every router that forwards a packet subtracts one from that byte. When it reaches zero the packet is destroyed and an ICMP Time Exceeded goes back to the sender. It exists to stop a packet caught in a routing loop from circulating forever. Traceroute is a clever abuse of that safety mechanism, and ping is a much simpler thing built from a request and a reply.
02 Worked example
One probe with TTL 1, and a router forced to identify itself
This is the scene for the whole lesson, including the console in section 04 and every address in the cheat sheet. One host, three routers, one server. Nothing here has been told to cooperate with a diagnostic tool, and R3 has been configured not to generate ICMP at all, which is deliberate and is the honest case you will meet on a real path.
| Device | Role | IPv4 | Note |
|---|---|---|---|
| S | the Linux host doing the diagnosing | 192.168.1.10 | sends everything below; its default initial TTL is 64 |
| R1 | the default gateway | 192.168.1.1 | first router on the path |
| R2 | the provider’s edge router | 10.20.0.6 | second router |
| R3 | a transit router | 203.0.113.9 | forwards perfectly, generates no ICMP at all |
| D | the web server being reached | 198.51.100.20 | three routers away from S |
S wants to know what is between it and 198.51.100.20. Nothing in IP offers to tell it. So it sends an ordinary packet addressed to D and sabotages one byte: it writes TTL = 1. Read left to right and watch what each device is forced to do, rather than what it chooses to.
Now do the arithmetic for all four rounds by hand, because an off-by-one here is the mistake that gets caught. A router subtracts one on forwarding, and discards if the result is zero.
| Probe | R1 | R2 | R3 | D | Who answers, and with what |
|---|---|---|---|---|---|
| TTL 1 | 1 − 1 = 0 → discard |
never sees it | never sees it | never sees it | R1, type 11 code 0 from 192.168.1.1 |
| TTL 2 | 2 − 1 = 1 → forward |
1 − 1 = 0 → discard |
never sees it | never sees it | R2, type 11 code 0 from 10.20.0.6 |
| TTL 3 | 3 − 1 = 2 → forward |
2 − 1 = 1 → forward |
1 − 1 = 0 → discard |
never sees it | nobody — R3 discards in silence, so S prints * * * |
| TTL 4 | 4 − 1 = 3 → forward |
3 − 1 = 2 → forward |
2 − 1 = 1 → forward |
arrives with TTL 1, delivered |
D, and with a different type, which is the stop signal |
Two facts fall straight out of that table and both get asked. First, a probe sent with initial TTL n dies at the nth router, so the TTL you set is the hop number you are interrogating. Second, and this is the row people get wrong, D receives a packet carrying TTL 1 and does not destroy it. The decrement-and-discard rule is a rule about forwarding. D is not forwarding this packet, it is the packet’s destination, so it hands the datagram up its own stack and answers. Three devices in that last row applied one rule and one device applied another, and what separated them was never the TTL value.
Notice also what R1 never did. It was not asked its name, it did not advertise itself, and it has no idea a diagnostic tool exists. It was handed a packet it was obliged to destroy, and the standard obliges it to send an error when it does, and an IP packet has to carry a source address. Traceroute reads the identity off that envelope. The whole tool is an exploitation of a rule written for loop prevention twenty years before anyone wanted a map.
One honesty note before the mechanics. Real traceroute sends three probes per TTL value, not one, so a single silent probe does not condemn a hop and you get three round trip times to compare. The console in section 04 sends one probe per round so the counters stay readable, and the mechanism is identical.
03 Mechanics
The message types, the TTL rule and the two tools
Start with the message classes, because every tool below is two of these rows. The type and code are what an interviewer asks you to quote; the sender column is what separates a memorised list from an understood one, and it is the half that gets skipped.
| Type / code | Name | Who generates it | What it actually means |
|---|---|---|---|
8 / 0 | Echo request | whoever is diagnosing | “Copy this data back to me.” The 4 bytes after the checksum hold a 16-bit identifier and a 16-bit sequence number, which is how the sender matches a reply to a request. |
0 / 0 | Echo reply | the host that was pinged | Same identifier, same sequence, same payload copied back. It proves the target’s IP stack is alive and that the path works in both directions. |
3 / 0 | Net unreachable | a router | No route to that network at all. The router looked in its routing table and there was nothing, not even a default. |
3 / 1 | Host unreachable | the last router on the path | The network exists and this router is attached to it, but the specific host does not answer address resolution. Only the router on the destination’s own link can know this. |
3 / 2 | Protocol unreachable | the destination host | The host is up and received your packet, but nothing in its stack handles that IP protocol number. |
3 / 3 | Port unreachable | the destination host | The host is up and nothing is bound to that UDP port. This is how Unix traceroute knows it has arrived. |
3 / 4 | Fragmentation needed and DF set | a router | Your packet is larger than the next link’s MTU and you forbade fragmenting it. Alone among the errors it carries a number the sender can act on: the next-hop MTU. Path MTU Discovery, RFC 1191, is built entirely on this one message. |
4 / 0 | Source quench (deprecated) | historically a router | “Slow down.” Deprecated by RFC 6633 in 2012: it was ineffective, unfair to whoever it happened to hit, and a denial-of-service vector. Congestion control belongs to TCP and to ECN. Name it as history and say it is dead. |
5 / x | Redirect | a router, to a host on its own link | “You sent this to me, but a better first hop for that destination is on the link we share. Use it directly next time.” It never crosses a link boundary, and it is widely disabled because nothing in it is authenticated. |
11 / 0 | Time exceeded in transit | a router | TTL hit zero here. The engine of traceroute, and the only reason a router ever tells you its address unprompted. |
11 / 1 | Fragment reassembly time exceeded | the destination host | Some fragments of one datagram arrived and the rest never did, so the host gave up holding them. Same type number as the traceroute message, nothing to do with TTL. |
12 / x | Parameter problem | any device processing the header | A field in your IP header is malformed, and the message points at the offending byte. |
What is actually inside an error, byte by byte. The ICMP header is 1 + 1 + 2 + 4 = 8 bytes: type, code, checksum, and four bytes whose meaning is type-specific. For an echo they are the identifier and sequence number; for 3/4 they hold the next-hop MTU; for most errors they are unused. Behind that 8-byte header sits the quotation: the failed packet’s IP header, at least 20 bytes, plus the first 8 bytes after it. RFC 792 fixed that at 8; RFC 1812 later told routers to return as much of the original as they can without pushing the whole ICMP packet past 576 bytes. And RFC 1122 bans three things that would otherwise cause a storm: you never send an ICMP error about an ICMP error, about a broadcast or multicast, or about anything but the first fragment of a datagram.
TTL, stated the way it should be said out loud. It is an 8-bit field, so 0 to 255. Every router that forwards the packet subtracts one, and any router receiving a packet whose TTL is already 1 must discard it and send 11/0 instead of forwarding. Its purpose is loop prevention and nothing else. Two routers with inconsistent tables can hand the same packet back and forth forever; TTL bounds that damage to 255 hops rather than to the lifetime of the network. The name is a historical accident: RFC 791 imagined a value in seconds and required a router holding a packet for a second to decrement more than once, but no router has ever held a packet for anything close to a second, so RFC 1812 defines it outright as a hop count, and IPv6 renamed the field Hop Limit. Initial values differ by operating system, which is worth knowing because you can read them: Linux and macOS send 64, Windows sends 128, and packets a Cisco router originates itself start at 255.
With that, the two tools are three rows apart. Both send something, both wait, and the difference is entirely in what they do with the TTL field.
| ping | traceroute | |
|---|---|---|
| What it sends | One ICMP echo request, type 8 code 0, with a normal TTL such as 64 | A sequence of probes with TTL deliberately set to 1, 2, 3 …, three probes per value |
| What comes back | type 0 code 0 from the destination, matched by identifier and sequence | type 11 code 0 from each router in turn, then something else from the destination |
| What it measures | Round trip time to one host, and how many of N requests were answered | Round trip time to each device along the way, one device at a time |
| What a success proves | The target’s IP stack answered and the path works both ways | Which devices are willing to admit they are on the forward path |
| What a failure proves | only that no reply came back | only that no error came back from that hop |
| Stops when | It has sent the count you asked for | A reply arrives whose type is not time exceeded, or the maximum TTL is reached |
Ping, and what a round trip time is a round trip of. The RTT is measured entirely inside the sending host: it timestamps the request going out and subtracts that from the moment the matching reply arrives. So it includes the forward path, the target’s time to turn the request around, and the return path, and the return path need not be the same route as the forward one. Packet loss is the plainer figure: send ten requests, count the replies, and any request whose reply never arrived is counted lost, whether the request died on the way out or the reply died on the way back. Ping cannot tell you which. And the caveat that matters most in practice: a failed ping does not prove a host is down. Enormous numbers of hosts, firewalls and cloud security groups drop ICMP echo on purpose, so a server can be serving a million requests a second while answering no pings at all. “It does not ping” is a statement about ICMP reachability and nothing more.
The implementation split, in one clause each. Unix traceroute sends UDP datagrams by default, aimed at high port numbers starting at 33434 that nothing is expected to be listening on, so the destination answers 3/3 port unreachable and that different type is the stop signal. Windows tracert sends ICMP echo requests, so the destination answers 0/0 echo reply instead. Linux traceroute -I does the same as Windows and traceroute -T sends TCP SYNs to port 80 to get through firewalls that drop the other two. Every one of them relies on the identical TTL trick and reads the identical 11/0 from every intermediate hop; only the last line differs.
Why hops go silent, and why that is not a fault. A star means one thing precisely: no ICMP came back within the timeout. Forwarding a packet and generating a brand new packet about a packet you just dropped are two different jobs done by two different parts of a router, and the second one is optional. A router may be configured not to generate unreachables at all. It may rate-limit them, and Cisco IOS does exactly that by default, generating at most one unreachable every 500 ms, because building an error packet is control-plane work that an operator will not let compete with forwarding. A firewall between you and it may drop the error on the way back. In every one of those cases the hop is passing traffic perfectly, and the evidence is sitting in the same output: if hop 5 answered, hop 4 forwarded the probe that reached it.
Why two consecutive probes can take different paths, and why RTTs go backwards. Routers running equal-cost multipath hash each flow across several links, and Unix traceroute increments the destination port on every probe, so consecutive probes can genuinely be hashed onto different next hops and a traceroute can show two addresses for one hop or a path that changes mid-run. Separately, every RTT in the output is a round trip to a different device, and the return leg is chosen by that device, not by you. Asymmetric routing therefore makes it entirely normal for hop 5 to report a lower time than hop 4 without any measurement being wrong. Read the column as a set of independent measurements, never as a cumulative total.
And ICMPv6 does considerably more work. It is protocol number 58, defined in RFC 4443, and the type numbers were reassigned: errors are 1 to 4, echo request is 128 and echo reply is 129. The structural change is that Neighbour Discovery replaced ARP and lives inside ICMPv6 as types 133 to 137: router solicitation, router advertisement, neighbour solicitation, neighbour advertisement and redirect. Router advertisements are also what drive stateless address autoconfiguration, and because IPv6 routers never fragment, Path MTU Discovery is compulsory rather than an optimisation, driven by the type 2 Packet Too Big message. So blocking all ICMPv6 at a firewall does not merely break ping, it breaks address resolution, autoconfiguration and any transfer larger than the 1280-byte minimum MTU. That was never true of ICMPv4, and it is the modern half of this topic.
05 Cheat sheet
Thirteen answers to have ready
Every row is something you can state in under ten seconds. The right-hand column is the specific wrong answer that gets given in interviews, not a general caution.
| What they ask | The answer | The trap |
|---|---|---|
| Where ICMP sits | directly on IP, Protocol field = 1 (ICMPv6 = 58) | saying it runs over TCP or UDP — it has no ports at all |
| What ICMP does about errors | reports them, never repairs them | calling it error correction — it retransmits nothing and reroutes nothing |
| ICMP header size | 8 bytes: 1 type + 1 code + 2 checksum + 4 type-specific | Forgetting the 4 type-specific bytes and answering 4. |
| Echo request and reply | type 8 code 0 out, type 0 code 0 back; v6 uses 128 and 129 | swapping 8 and 0 — the higher number is the question |
| Destination unreachable sub-cases | 3/0 net, 3/1 host, 3/2 protocol, 3/3 port, 3/4 frag needed + DF | Saying “unreachable” with no code. The code is the entire content. |
| Time exceeded | type 11 code 0 when TTL hits 0; code 1 when fragments never reassemble | saying the destination sends 11/0 — a router does, and the destination never sees the packet |
| What an ICMP error carries | the failed packet’s IP header + the first 8 bytes behind it | Saying the whole packet. Eight bytes is exactly a UDP header, so both ports come back. |
| What TTL is | an 8-bit hop counter, minus one per forwarding router, discarded at 0 | calling it a timer in seconds — its job is loop prevention, and IPv6 renamed it Hop Limit |
| Common initial TTLs | 64 Linux and macOS, 128 Windows, 255 Cisco-originated | Assuming the value you receive is the value that was sent. |
| What ping proves | the target’s IP stack answered, and the path works in both directions | treating a failed ping as proof the host is down — ICMP is dropped deliberately everywhere |
| The traceroute engine | TTL 1, 2, 3 …; each hop is read off the SOURCE address of its 11/0 | Thinking routers are asked for their identity. Nothing asks; the error has to carry a source. |
| How traceroute knows it arrived | the type changes: 3/3 for Unix UDP probes, 0/0 for Windows tracert | saying it stops when the TTL runs out |
| Why a hop prints * * * | no ICMP came back: filtered, rate limited, or not generated | Calling that hop broken. Forwarding and generating errors are separate jobs. |
06 Where & why
Four places this stops being theory
Every claim in this lesson is something you can type into a machine or watch fail on a real deployment. These four are where students actually meet it, and the fourth is the one that costs people a day.
ping -c 4 198.51.100.20 prints ttl= on every line, and that is the TTL remaining on arrival, set by the machine that sent the reply. Subtract it from that machine’s initial value and you have the hop count of the return path for free. ping -s sets the payload size and -M do sets the Don’t Fragment bit, which together are the manual version of Path MTU Discovery. On the receiving side, /proc/sys/net/ipv4/icmp_echo_ignore_all is the one-line switch that makes a perfectly healthy host stop answering.
ip icmp rate-limit unreachable caps generated unreachables at one every 500 ms by default, because building an error packet is control-plane work and an operator will not let it compete with forwarding. no ip unreachables on an interface switches generation off entirely, which is common on internet-facing links and is exactly how a router becomes a silent hop while forwarding every packet correctly. no ip redirects turns off type 5 for the same reason: nothing in a redirect is authenticated.
The address you ping is announced from hundreds of data centres at once, so your echo request is answered by whichever one your traffic reaches first, and somebody in another city pings the identical address and reaches a different machine. The round trip time is therefore honest about the nearest point of presence and says nothing about the origin behind it. Traceroute to an anycast address has the same limitation, and only the last line is affected: every intermediate 11/0 still comes from a real, specific router.
A new security group has no inbound rules at all, so an EC2 instance can be running, healthy and serving HTTPS to the world while every ping to it times out, until somebody adds an inbound rule for ICMP echo request. This is the demonstration that “ping failed” and “host down” are different statements, and it is worth naming in an interview because it is concrete. The same account is where blocked 3/4 bites: drop it on a VPN or a tunnel and small requests work while large transfers hang forever.
07 Interview questions
What they ask, and where the follow-up lands
This topic is asked because two of its answers are one word long and the third is a mechanism. Expect “what is ICMP”, then “so how does traceroute work”, then a scenario designed to see whether you treat a failed ping as evidence.
What is ICMP, and where does it sit?
ICMP is carried inside an IP packet. Does that make it a transport-layer protocol?
What is inside an ICMP error message, and why?
Explain TTL. Why is the name misleading?
How does traceroute work?
How does traceroute know it has reached the destination?
What does ping measure, and what does a successful ping prove?
A server does not answer ping, but its website loads fine in your browser. What do you conclude?
What is source quench, and would you bring it up today?
What is an ICMP redirect?
Give me ping and traceroute in one sentence each, and then the real difference.
What changes with ICMPv6?
08 Practice problems
Six to work out on paper
For every one, write down two things before computing anything: which device is holding the packet, and whether that device is forwarding it or receiving it. Three of these turn on that distinction and two turn on keeping header bytes and payload bytes in separate columns.