feat(core): traceroute and tcpdump after Java, measured against Java

TerminalRun adds nine stories: traceroute in the LAN, through the router,
unreachable, without a route, to no one, to the host itself, errors and
Ctrl+C; tcpdump on two hosts. traceroute counts failures across hops as
Java does and takes an error that carries its probe; tcpdump tells each
frame's highest capture row with its time of day, at once.

Departures from Java: traceroute tells its summary before the end mark
(Java after it, where its window shows no text) and calls a host at the
20th hop reached. arpsend is not built.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-02 10:46:18 +00:00
co-authored by Claude Opus 5.5
parent 495c449ef2
commit a867c33d64
16 changed files with 11983 additions and 16 deletions
+60 -2
View File
@@ -31,6 +31,16 @@
// arp arp after a ping and a lookup, -a, -d, unknown options, no address, the broadcast row removed
// netstat netstat on the client connected to the echo server, on the echo server, on the DNS server;
// the connection closed, on both again
// traceLan traceroute .31 (one hop)
// traceRouted traceroute fern.filius.de (two hops), the router's far address
// traceUnreachable traceroute 10.0.0.99 (no one behind the router)
// traceNoRoute traceroute 172.16.0.1 (no route at the router)
// traceNobody traceroute .99 (no one in the LAN)
// traceSelf traceroute its own address, localhost
// traceErrors usage, an unknown name, no DNS server
// traceInterrupt traceroute 10.0.0.99, Ctrl+C after 3.5 s
// tcpdump tcpdump on .31 and on the DNS server while the client pings .31, looks up a name
// and connects to .31's echo server; arp typed on .31 meanwhile; Ctrl+C on both
import filius.software.clientserver.ClientBaustein;
import filius.software.clientserver.ServerBaustein;
@@ -167,6 +177,46 @@ public class TerminalRun {
acts.add(new Object[] { 8000L, CLIENT, "netstat" });
acts.add(new Object[] { 8200L, ECHO, "netstat" });
break;
case "traceLan":
acts.add(new Object[] { 500L, CLIENT, "traceroute 192.168.0.31" });
break;
case "traceRouted":
acts.add(new Object[] { 500L, CLIENT, "traceroute fern.filius.de" });
acts.add(new Object[] { 3000L, CLIENT, "traceroute 10.0.0.1" });
break;
case "traceUnreachable":
acts.add(new Object[] { 500L, CLIENT, "traceroute 10.0.0.99" });
break;
case "traceNoRoute":
acts.add(new Object[] { 500L, CLIENT, "traceroute 172.16.0.1" });
break;
case "traceNobody":
acts.add(new Object[] { 500L, CLIENT, "traceroute 192.168.0.99" });
break;
case "traceSelf":
acts.add(new Object[] { 500L, CLIENT, "traceroute 192.168.0.20" });
acts.add(new Object[] { 1500L, CLIENT, "traceroute localhost" });
break;
case "traceErrors":
acts.add(new Object[] { 500L, CLIENT, "traceroute" });
acts.add(new Object[] { 700L, CLIENT, "traceroute a b" });
acts.add(new Object[] { 900L, CLIENT, "traceroute gibtsnicht.filius.de" });
acts.add(new Object[] { 3000L, FAR, "traceroute www.filius.de" });
break;
case "traceInterrupt":
acts.add(new Object[] { 500L, CLIENT, "traceroute 10.0.0.99" });
acts.add(new Object[] { 4000L, CLIENT, "^C" });
break;
case "tcpdump":
acts.add(new Object[] { 500L, ECHO, "tcpdump" });
acts.add(new Object[] { 600L, DNS, "tcpdump" });
acts.add(new Object[] { 1000L, CLIENT, "ping 192.168.0.31" });
acts.add(new Object[] { 3000L, ECHO, "arp" });
acts.add(new Object[] { 5500L, CLIENT, "host www.filius.de" });
acts.add(new Object[] { 6500L, CLIENT, "connect" });
acts.add(new Object[] { 8000L, ECHO, "^C" });
acts.add(new Object[] { 8100L, DNS, "^C" });
break;
default:
throw new IllegalArgumentException("unknown story " + story);
}
@@ -205,7 +255,7 @@ public class TerminalRun {
terminals.put(host, terminal);
}
ClientBaustein client = null;
if (story.equals("netstat")) {
if (story.equals("netstat") || story.equals("tcpdump")) {
for (String host : new String[] { ECHO, DNS }) {
network.system(host).installApp("filius.software.clientserver.ServerBaustein", false);
ServerBaustein server = (ServerBaustein) network.system(host).holeSoftware("filius.software.clientserver.ServerBaustein");
@@ -216,7 +266,7 @@ public class TerminalRun {
client = (ClientBaustein) network.system(CLIENT).holeSoftware("filius.software.clientserver.ClientBaustein");
}
network.start();
if (client != null) {
if (story.equals("netstat")) {
sleepUntil(500);
event(CLIENT, "call", "connect 192.168.0.31:55555");
client.setZielIPAdresse("192.168.0.31");
@@ -225,6 +275,14 @@ public class TerminalRun {
}
for (Object[] act : acts) {
sleepUntil((Long) act[0]);
if (act[2].equals("connect")) {
// The echo client's window: connect to the echo server (ClientBaustein.verbinden).
event(CLIENT, "call", "connect 192.168.0.31:55555");
client.setZielIPAdresse("192.168.0.31");
client.setZielPort(55555);
client.verbinden();
continue;
}
if (act[2].equals("disconnect")) {
// The echo client's window: its connection closed (ClientBaustein.trennen).
event(CLIENT, "call", "disconnect");