Lesson 06 / 13
Reachability Tests
Reading echo and path-test tools correctly: no response from a remote address fits four separate candidate causes, three reachability tests plus a connection attempt together still cannot split two candidate pairs, and what splits them is reading the configuration.
Contents
The previous lesson measured the diagnosis order and showed that two tests in the layered order’s first steps looked weak: echo to the gateway eliminated only 2 candidates, echo to the remote address 4. These tests are diagnosis’s most commonly used tools, and their weakness is not the real problem. The real problem is that they are misread.
The misreading runs in two directions. In the first direction, silence is assumed to say too much: when no response arrives, the conclusion “the machine is down” or “there is no network” is reached, even though more than one cause produces the same silence. In the second direction, a response is assumed to say too much: when a response arrives, “reach is fine” is said, even though the layer that responded is not the layer being reached. This lesson meets both misreadings with numbers.
The Echo Test’s Two-Valued Response
An echo test sends a small request to an address and waits for a response in return. The mock
setup reduces this to a two-valued response: response or no-response (SG6). Latency,
loss rate, and response order are not measured in this lesson; what is measured is how many
candidate causes the silence fits.
There are two separate echo tests, and they look at different distances. Gateway echo asks whether we can reach the local network at all; for a response, the interface being up and the address being assigned is enough. Remote echo asks about the path all the way to the target; for a response, the gateway also has to be correct and the route has to exist. The second test requires everything the first one requires, plus two more conditions. This nesting directly explains why the silence fits more than one cause.
Name resolution is kept out of these tests: echo is done with the address, not the name. An echo done by name mixes two mechanisms into a single response and blurs the cause of the silence by one more candidate. The protocol itself is the subject of the Computer Networks curriculum and is not built here.
Path Test: The Same Test Repeated at Increasing Distance
Traceroute-style path testing is the common name for tools that show the path to a target along with its intermediate stops. What it does is repeat the same reachability question at increasing distances: first one hop out, then two hops out. In the mock setup this corresponds to running gateway echo and remote echo back to back (SG7); the intermediate stops’ individual behavior is not modeled separately.
A third reachability test is a large-packet attempt that is not allowed to fragment (SG8). A path where small packets get through but large ones get lost looks sound to an echo test. This split comes from echo sending a small request: the packet size a test uses determines the fault it cannot see.
A fourth boundary needs to be written up front too: an echo response being deliberately withheld is not in the candidate-cause set (SG9). A target can be configured not to respond to echo at all, and in that case the silence corresponds to no fault on the list. This is the price of the closed-world assumption: a cause outside the list gives the same response as a cause inside it.
The most commonly misread part of path-test output is an intermediate stop’s silence. No response from a stop does not show that stop is broken; intermediate stops are not obligated to respond to requests not addressed to them, and most treat it as low-priority work. The only meaningful line in a path test is the last one: at what distance the path goes completely silent. Empty lines in the middle eliminate no candidate, they only add to the line count. The same mistake runs in reverse too: every stop responding while the target stays silent suggests the path is sound and the fault sits at the target, but the return direction is a separate path, and the outbound direction being sound does not prove the return is.
The mock setup’s reduction to a two-valued response is not a convenience, it is a deliberate boundary. A real echo test also says how many of three requests came back, and “3 lost out of 3” is not the same thing, diagnostically, as “1 lost out of 3”: the first points to a persistent fault, the second to an intermittent one. The mock setup does not cover this second case; intermittent faults are the fourth lesson’s subject. The point to hold onto here is this: every reading that drops the loss rate and reduces the response to two values shows an intermittent fault as either fully sound or fully broken.
# example dump , has not been run $ ping -c 3 <gateway> # one hop out $ ping -c 3 <target-address> # all the way to the target $ tracepath <target-address> # repetition at increasing distance $ ping -c 3 -M do -s 1400 <target-address> # attempt that disallows fragmentation
HEALTHY = {"interface_up": True, "address_set": True, "gateway_correct": True, "route_present": True, "resolver_responds": True, "service_listening": True, "firewall_passes": True, "path_ok": True} FAULT = { "interface-down": {"interface_up": False, "address_set": False}, "no-address": {"address_set": False}, "wrong-gateway": {"gateway_correct": False}, "missing-route": {"route_present": False}, "resolver-silent": {"resolver_responds": False}, "service-not-listening": {"service_listening": False}, "firewall-dropping": {"firewall_passes": False}, "large-packet-lost": {"path_ok": False}, } CANDIDATES = tuple(FAULT) def state(a=None): d = dict(HEALTHY) if a: d.update(FAULT[a]) return d def path(d): return (d["interface_up"] and d["address_set"] and d["gateway_correct"] and d["route_present"]) TEST = { # five of the common definition's eight used in this lesson "gateway-echo": lambda d: ("response" if d["interface_up"] and d["address_set"] else "no-response"), "remote-echo": lambda d: "response" if path(d) else "no-response", "large-packet": lambda d: ("passes" if path(d) and d["path_ok"] else "blocked"), "connection": lambda d: ("unreachable" if not path(d) else "timeout" if not d["firewall_passes"] else "refused" if not d["service_listening"] else "established"), "route": lambda d: ("table-empty" if not d["address_set"] else "complete" if d["route_present"] else "no-default"), } ECHO = ["gateway-echo", "remote-echo", "large-packet"] # SG7: traceroute-style def groups(kit, candidates=CANDIDATES): o = {} for a in candidates: o.setdefault(tuple(TEST[s](state(a)) for s in kit), []).append(a) return o print("how many candidate causes a response fits") for s in ECHO + ["connection"]: for response, fits in sorted(groups([s]).items()): print(f" {s:14s} {response[0]:12s} {len(fits)} {', '.join(sorted(fits))}") print() ORACLE = "wrong-gateway" print("oracle:", ORACLE, "| tests applied in order") remaining = CANDIDATES for s in ECHO + ["connection", "route"]: response = TEST[s](state(ORACLE)) new = tuple(a for a in remaining if TEST[s](state(a)) == response) print(f" {s:14s} {response:12s} eliminated {len(remaining) - len(new)} left {len(new)}" f" {', '.join(sorted(new))}") remaining = new print() print("test kit groups unsplit largest group") for kit in (["gateway-echo"], ["remote-echo"], ["gateway-echo", "remote-echo"], ECHO, ["connection"], ECHO + ["connection"]): o = groups(kit) split = [v for v in o.values() if len(v) > 1] print(f" {'+'.join(kit):45s} {len(o):4d} {len(split):12d}" f" {max(len(v) for v in o.values()):14d}") print() print("candidate set sweep: how many candidates 'remote-echo = no-response' fits") kit = ["interface-down"] for a in CANDIDATES: if a not in kit: kit.append(a) fits = [x for x in kit if TEST["remote-echo"](state(x)) == "no-response"] print(f" candidate {len(kit)} added {a:26s} fits {len(fits)}")
how many candidate causes a response fits gateway-echo no-response 2 interface-down, no-address gateway-echo response 6 firewall-dropping, large-packet-lost, missing-route, resolver-silent, service-not-listening, wrong-gateway remote-echo no-response 4 interface-down, missing-route, no-address, wrong-gateway remote-echo response 4 firewall-dropping, large-packet-lost, resolver-silent, service-not-listening large-packet blocked 5 interface-down, large-packet-lost, missing-route, no-address, wrong-gateway large-packet passes 3 firewall-dropping, resolver-silent, service-not-listening connection established 2 large-packet-lost, resolver-silent connection refused 1 service-not-listening connection timeout 1 firewall-dropping connection unreachable 4 interface-down, missing-route, no-address, wrong-gateway oracle: wrong-gateway | tests applied in order gateway-echo response eliminated 2 left 6 firewall-dropping, large-packet-lost, missing-route, resolver-silent, service-not-listening, wrong-gateway remote-echo no-response eliminated 4 left 2 missing-route, wrong-gateway large-packet blocked eliminated 0 left 2 missing-route, wrong-gateway connection unreachable eliminated 0 left 2 missing-route, wrong-gateway route complete eliminated 1 left 1 wrong-gateway test kit groups unsplit largest group gateway-echo 2 2 6 remote-echo 2 2 4 gateway-echo+remote-echo 3 3 4 gateway-echo+remote-echo+large-packet 4 3 3 connection 4 2 4 gateway-echo+remote-echo+large-packet+connection 6 2 2 candidate set sweep: how many candidates 'remote-echo = no-response' fits candidate 2 added no-address fits 2 candidate 3 added wrong-gateway fits 3 candidate 4 added missing-route fits 4 candidate 5 added resolver-silent fits 4 candidate 6 added service-not-listening fits 4 candidate 7 added firewall-dropping fits 4 candidate 8 added large-packet-lost fits 4
Oracle, Test, Eliminated Candidate
Three numbers sit side by side. Oracle: the real fault is wrong-gateway, that is, the
default gateway is set wrong. Test: remote echo returns no-response. Eliminated
candidate: this response eliminates 4 of eight candidates and leaves 4 behind.
The silence fitting four candidates is this lesson’s first number. The sentence “no response
from the remote address” is on its own consistent with all of interface-down,
no-address, wrong-gateway, and missing-route. Reading the silence as “network’s down”
lumps these four together as if they were one cause; fixing each of the four is different, and
picking the wrong fix does not work.
When gateway echo stays silent, the picture is narrower: only 2 candidates fit
(interface-down, no-address). A practical reading follows from this. Nearby silence is
more informative than distant silence, because it depends on fewer conditions. This is exactly
the path test’s real function too: finding at what distance silence begins, to narrow the
number of candidates that fit.
What a Response Does Not Say
The second misreading is sneakier. Echo returning a response eliminates four candidates but
leaves 4 behind: resolver-silent, service-not-listening, firewall-dropping, and
large-packet-lost. That is, the sentence “the machine is responding” does not mean the
service is reachable, and four separate faults are entirely consistent with that sentence.
What makes the difference is that silence and being refused are not the same thing. Two of
the connection test’s four responses each pin down a single candidate: refused fits only
service-not-listening, timeout only firewall-dropping. Being refused is a response, and
the responding side also proves the path is sound; silence is ambiguous about the state of both
the path and the target. So what diagnosis looks for is a test that can turn silence into a
response.
The large-packet attempt splits off one of these four: in the large-packet-lost scenario, a
small echo gets through, a large packet does not. This is diagnosis’s most commonly overlooked
signature, because it is the one place two tests contradict each other — one says sound, the
other broken, and both are correct.
The step-by-step table shows how this order runs. With the oracle at wrong-gateway, gateway
echo eliminates 2 candidates, remote echo eliminates 4; after that, the large-packet attempt
eliminates 0, and so does the connection attempt. A test being powerful is not enough:
re-eliminating an already-eliminated candidate is not elimination. The connection attempt
eliminated seven candidates in the previous lesson; here it eliminates zero, because the tests
that ran before it had already made the same split.
The Wall Reachability Tests Hit
The last table is the lesson’s harshest result. Gateway echo alone splits the eight candidates into 2 groups, and the largest group holds 6. Remote echo alone gives 2 groups, largest 4. Together they produce 3 groups, and all three groups hold more than one candidate: these two tests cannot pin down even a single candidate on their own.
Adding the large-packet attempt brings the group count to 4 and the largest group down to 3;
the number of unsplit groups is still 3. Adding the connection attempt too produces 6
groups, and 2 unsplit pairs remain: interface-down with no-address, and wrong-gateway
with missing-route.
These two pairs stay unsplit no matter how many reachability tests are run. The reason is
structural: both members of each pair cut the same path at the same place, so every test
that looks at the path gives the same response. What splits them is not looking at the path, it
is reading the configuration. The table’s last row does this: the routing-table test returns
complete, eliminates the last candidate between wrong-gateway and missing-route, and the
diagnosis drops to one candidate.
This is where the course’s second claim shows its first face: adding more tests does not add elimination power. Three reachability tests do not do what a single configuration reading does. What is needed is not multiplying tests but changing their kind.
The reason these tools get used this much is hidden in the same table: they are cheap. An echo test takes seconds, is a one-line command, changes nothing on the target, and its failure is harmless. Cheapness makes a tool the first choice; elimination power is what makes it the tool that finishes the diagnosis, and the two are not the same measure. The measurement counted every test as one step (SG5), that is, decisions were counted, not seconds. Measured in seconds, echo tests would look even more favorable, and it is exactly this appearance that leads to dozens of repeated echo tests once diagnosis stalls. Repeating the same test eliminates no new candidate; the information gained after the first run is fixed.
Candidate Set Sweep
The sweep shows how much the number of candidates the silence fits depends on the set. As the
set grows from interface-down up to eight, the number of candidates fitting remote-echo = no-response climbs 1, 2, 3, 4, and stops at four: the four candidates added after that sit
in an upper layer and produce a response to remote echo.
The table can also be read backward. Removing a candidate from the list is the same as reading
the rows upward: with missing-route removed, the candidates fitting the silence drop from 4
to 3; with wrong-gateway also removed, to 2. Removing always looks like a gain, because the
silence narrows; but if the removed candidate is the real fault, the diagnosis ends with zero
candidates, and this shows up nowhere in the table.
The result cuts both ways. If the candidate list is short, silence looks more informative — in a three-candidate list, “no response” fits two candidates — but that information is bought at the cost of causes left outside the list. As the candidate list grows, silence’s discriminating power neither grows nor shrinks past a certain point: as long as added candidates give a different response, silence’s meaning stays fixed. What determines a test’s power is not the candidate count, it is which response the candidates fall into.
Summary
- No response from a remote address fits 4 separate candidate causes; no response from the gateway fits 2. Nearby silence is more informative because it depends on fewer conditions.
- Echo returning a response also leaves 4 candidates standing; “the machine is responding” does not say the service is reachable.
- A path test is the same reachability question repeated at increasing distance; the large-packet attempt splits off the one fault a small echo cannot see.
- Three reachability tests together cannot pin down even a single candidate; adding the connection attempt leaves 2 unsplit pairs, and only reading the configuration splits them.
- Re-eliminating an already-eliminated candidate is not elimination: the connection attempt eliminates 0 candidates in this order; repeating the same test eliminates no new one either.
- Being refused is a response and pins down a single candidate; silence is ambiguous about both the path and the target.
Next Step
When reachability tests hit a wall, the next step that comes to mind is usually the same one: looking at the traffic itself. Packet capture does not show a summary of responses, it shows every frame crossing the wire, and for that reason it is counted the “most detailed” tool. The next lesson measures that expectation: it sets the number of lines a capture produces against the number of candidate causes it eliminates, and compares elimination power per line against the connection attempt’s. That packet capture is a diagnosis tool, not a procedure for seizing someone else’s traffic, is also written there, along with its boundary.
To keep your progress and take notes, Log in
My notes
Log in to take notes.