From 5505e8e8afb74bf5f9d1132b45d25f68b4955bcc Mon Sep 17 00:00:00 2001 From: Julian Kiedaisch Date: Wed, 30 Sep 2026 19:50:08 +0000 Subject: [PATCH] test(java-oracle): NatRun records the home router's NAT as Java FILIUS runs it ScenarioNetwork builds home routers (their first card the WAN port) and their port forwarding (portForwarding, through GatewayFirmware.setStaticNAT). NatRun plays six stories on nat-home's network and writes the frames, the calls and the router's NAT table: a ping, a UDP exchange, the same socket to a second server (whose answer never reaches the LAN: Java keeps one entry per LAN endpoint, for the first remote only), a TCP connection out, a forwarded one in, and pings at the WAN address and past it. Co-Authored-By: Claude Opus 5.5 --- .../test/scenarios/nat-home.scenario.json | 142 +++++ .../test/scenarios/nat-java-forward.java.json | 591 ++++++++++++++++++ .../test/scenarios/nat-java-pingOut.java.json | 141 +++++ .../test/scenarios/nat-java-pingWan.java.json | 130 ++++ .../test/scenarios/nat-java-tcpOut.java.json | 591 ++++++++++++++++++ .../test/scenarios/nat-java-udpOut.java.json | 159 +++++ .../nat-java-udpTwoRemotes.java.json | 274 ++++++++ tools/java-oracle/README.md | 36 ++ tools/java-oracle/run.sh | 13 +- tools/java-oracle/src/NatRun.java | 230 +++++++ tools/java-oracle/src/ScenarioNetwork.java | 12 + 11 files changed, 2318 insertions(+), 1 deletion(-) create mode 100644 packages/core/test/scenarios/nat-home.scenario.json create mode 100644 packages/core/test/scenarios/nat-java-forward.java.json create mode 100644 packages/core/test/scenarios/nat-java-pingOut.java.json create mode 100644 packages/core/test/scenarios/nat-java-pingWan.java.json create mode 100644 packages/core/test/scenarios/nat-java-tcpOut.java.json create mode 100644 packages/core/test/scenarios/nat-java-udpOut.java.json create mode 100644 packages/core/test/scenarios/nat-java-udpTwoRemotes.java.json create mode 100644 tools/java-oracle/src/NatRun.java diff --git a/packages/core/test/scenarios/nat-home.scenario.json b/packages/core/test/scenarios/nat-home.scenario.json new file mode 100644 index 0000000..4fcb233 --- /dev/null +++ b/packages/core/test/scenarios/nat-home.scenario.json @@ -0,0 +1,142 @@ +{ + "seed": 81, + "nodes": [ + { + "id": "00000000-0000-0000-0000-000000000501", + "kind": "pc", + "ports": [ + { + "id": "00000000-0000-0000-0000-000000000511", + "label": "eth0" + } + ] + }, + { + "id": "00000000-0000-0000-0000-000000000502", + "kind": "gateway", + "ports": [ + { + "id": "00000000-0000-0000-0000-000000000521", + "label": "wan0" + }, + { + "id": "00000000-0000-0000-0000-000000000522", + "label": "lan0" + } + ] + }, + { + "id": "00000000-0000-0000-0000-000000000503", + "kind": "networkSwitch", + "ports": [ + { + "id": "00000000-0000-0000-0000-000000000531", + "label": "sw1" + }, + { + "id": "00000000-0000-0000-0000-000000000532", + "label": "sw2" + }, + { + "id": "00000000-0000-0000-0000-000000000533", + "label": "sw3" + } + ] + }, + { + "id": "00000000-0000-0000-0000-000000000504", + "kind": "pc", + "ports": [ + { + "id": "00000000-0000-0000-0000-000000000541", + "label": "eth0" + } + ] + }, + { + "id": "00000000-0000-0000-0000-000000000505", + "kind": "pc", + "ports": [ + { + "id": "00000000-0000-0000-0000-000000000551", + "label": "eth0" + } + ] + } + ], + "links": [ + { + "id": "00000000-0000-0000-0000-00000000F501", + "sourceNode": "00000000-0000-0000-0000-000000000501", + "sourcePort": "00000000-0000-0000-0000-000000000511", + "targetNode": "00000000-0000-0000-0000-000000000502", + "targetPort": "00000000-0000-0000-0000-000000000522" + }, + { + "id": "00000000-0000-0000-0000-00000000F502", + "sourceNode": "00000000-0000-0000-0000-000000000502", + "sourcePort": "00000000-0000-0000-0000-000000000521", + "targetNode": "00000000-0000-0000-0000-000000000503", + "targetPort": "00000000-0000-0000-0000-000000000531" + }, + { + "id": "00000000-0000-0000-0000-00000000F503", + "sourceNode": "00000000-0000-0000-0000-000000000504", + "sourcePort": "00000000-0000-0000-0000-000000000541", + "targetNode": "00000000-0000-0000-0000-000000000503", + "targetPort": "00000000-0000-0000-0000-000000000532" + }, + { + "id": "00000000-0000-0000-0000-00000000F504", + "sourceNode": "00000000-0000-0000-0000-000000000505", + "sourcePort": "00000000-0000-0000-0000-000000000551", + "targetNode": "00000000-0000-0000-0000-000000000503", + "targetPort": "00000000-0000-0000-0000-000000000533" + } + ], + "devices": { + "00000000-0000-0000-0000-000000000501": { + "ip": "192.168.0.10", + "mask": "255.255.255.0", + "gateway": "192.168.0.1" + }, + "00000000-0000-0000-0000-000000000502": { + "ip": "42.0.0.10", + "mask": "255.0.0.0" + }, + "00000000-0000-0000-0000-000000000504": { + "ip": "42.0.0.20", + "mask": "255.0.0.0", + "gateway": "42.0.0.10" + }, + "00000000-0000-0000-0000-000000000505": { + "ip": "42.0.0.30", + "mask": "255.0.0.0" + } + }, + "interfaces": [ + { + "node": "00000000-0000-0000-0000-000000000502", + "port": "00000000-0000-0000-0000-000000000521", + "ip": "42.0.0.10", + "mask": "255.0.0.0" + }, + { + "node": "00000000-0000-0000-0000-000000000502", + "port": "00000000-0000-0000-0000-000000000522", + "ip": "192.168.0.1", + "mask": "255.255.255.0" + } + ], + "portForwarding": { + "00000000-0000-0000-0000-000000000502": [ + [ + "TCP", + "8080", + "192.168.0.10", + "80" + ] + ] + }, + "steps": [] +} diff --git a/packages/core/test/scenarios/nat-java-forward.java.json b/packages/core/test/scenarios/nat-java-forward.java.json new file mode 100644 index 0000000..f110e5b --- /dev/null +++ b/packages/core/test/scenarios/nat-java-forward.java.json @@ -0,0 +1,591 @@ +{ + "frames": { + "00000000-0000-0000-0000-000000000501": [ + { + "time": 1389, + "source": "02:00:00:00:05:22", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.1", + "targetIp": "192.168.0.10" + }, + { + "time": 1389, + "source": "02:00:00:00:05:11", + "destination": "02:00:00:00:05:22", + "arp": 2, + "senderIp": "192.168.0.10", + "targetIp": "192.168.0.1" + }, + { + "time": 1501, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "sourceIp": "42.0.0.20", + "destinationIp": "192.168.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 80, + "payload": null, + "tcpFlags": "S", + "sequence": 2000000, + "acknowledgement": 0 + }, + { + "time": 1503, + "source": "02:00:00:00:05:11", + "destination": "02:00:00:00:05:22", + "sourceIp": "192.168.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 61267, + "payload": null, + "tcpFlags": "SA", + "sequence": 1000000, + "acknowledgement": 2000001 + }, + { + "time": 1839, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "sourceIp": "42.0.0.20", + "destinationIp": "192.168.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 2000001, + "acknowledgement": 1000001 + }, + { + "time": 1913, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "sourceIp": "42.0.0.20", + "destinationIp": "192.168.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 80, + "payload": "hello", + "tcpFlags": "P", + "sequence": 2000001, + "acknowledgement": 0 + }, + { + "time": 1914, + "source": "02:00:00:00:05:11", + "destination": "02:00:00:00:05:22", + "sourceIp": "192.168.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 61267, + "payload": null, + "tcpFlags": "A", + "sequence": 1000001, + "acknowledgement": 2000006 + }, + { + "time": 1969, + "source": "02:00:00:00:05:11", + "destination": "02:00:00:00:05:22", + "sourceIp": "192.168.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 61267, + "payload": "reply hello", + "tcpFlags": "P", + "sequence": 1000001, + "acknowledgement": 0 + }, + { + "time": 2303, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "sourceIp": "42.0.0.20", + "destinationIp": "192.168.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 2000006, + "acknowledgement": 1000012 + }, + { + "time": 2359, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "sourceIp": "42.0.0.20", + "destinationIp": "192.168.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 80, + "payload": null, + "tcpFlags": "F", + "sequence": 2000006, + "acknowledgement": 0 + }, + { + "time": 2359, + "source": "02:00:00:00:05:11", + "destination": "02:00:00:00:05:22", + "sourceIp": "192.168.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 61267, + "payload": null, + "tcpFlags": "A", + "sequence": 1000012, + "acknowledgement": 2000007 + }, + { + "time": 2415, + "source": "02:00:00:00:05:11", + "destination": "02:00:00:00:05:22", + "sourceIp": "192.168.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 61267, + "payload": null, + "tcpFlags": "F", + "sequence": 1000012, + "acknowledgement": 0 + }, + { + "time": 2749, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "sourceIp": "42.0.0.20", + "destinationIp": "192.168.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 2000007, + "acknowledgement": 1000013 + } + ], + "00000000-0000-0000-0000-000000000502": [ + { + "time": 1101, + "source": "02:00:00:00:05:41", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.20", + "targetIp": "42.0.0.10" + }, + { + "time": 1104, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "arp": 2, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.20" + }, + { + "time": 1333, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 8080, + "payload": null, + "tcpFlags": "S", + "sequence": 2000000, + "acknowledgement": 0 + }, + { + "time": 1560, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 8080, + "destinationPort": 61267, + "payload": null, + "tcpFlags": "SA", + "sequence": 1000000, + "acknowledgement": 2000001 + }, + { + "time": 1783, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 8080, + "payload": null, + "tcpFlags": "A", + "sequence": 2000001, + "acknowledgement": 1000001 + }, + { + "time": 1857, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 8080, + "payload": "hello", + "tcpFlags": "P", + "sequence": 2000001, + "acknowledgement": 0 + }, + { + "time": 1969, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 8080, + "destinationPort": 61267, + "payload": null, + "tcpFlags": "A", + "sequence": 1000001, + "acknowledgement": 2000006 + }, + { + "time": 2025, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 8080, + "destinationPort": 61267, + "payload": "reply hello", + "tcpFlags": "P", + "sequence": 1000001, + "acknowledgement": 0 + }, + { + "time": 2248, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 8080, + "payload": null, + "tcpFlags": "A", + "sequence": 2000006, + "acknowledgement": 1000012 + }, + { + "time": 2303, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 8080, + "payload": null, + "tcpFlags": "F", + "sequence": 2000006, + "acknowledgement": 0 + }, + { + "time": 2415, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 8080, + "destinationPort": 61267, + "payload": null, + "tcpFlags": "A", + "sequence": 1000012, + "acknowledgement": 2000007 + }, + { + "time": 2471, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 8080, + "destinationPort": 61267, + "payload": null, + "tcpFlags": "F", + "sequence": 1000012, + "acknowledgement": 0 + }, + { + "time": 2693, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 8080, + "payload": null, + "tcpFlags": "A", + "sequence": 2000007, + "acknowledgement": 1000013 + } + ], + "00000000-0000-0000-0000-000000000504": [ + { + "time": 965, + "source": "02:00:00:00:05:41", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.20", + "targetIp": "42.0.0.10" + }, + { + "time": 1215, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "arp": 2, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.20" + }, + { + "time": 1219, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 8080, + "payload": null, + "tcpFlags": "S", + "sequence": 2000000, + "acknowledgement": 0 + }, + { + "time": 1671, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 8080, + "destinationPort": 61267, + "payload": null, + "tcpFlags": "SA", + "sequence": 1000000, + "acknowledgement": 2000001 + }, + { + "time": 1671, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 8080, + "payload": null, + "tcpFlags": "A", + "sequence": 2000001, + "acknowledgement": 1000001 + }, + { + "time": 1746, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 8080, + "payload": "hello", + "tcpFlags": "P", + "sequence": 2000001, + "acknowledgement": 0 + }, + { + "time": 2081, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 8080, + "destinationPort": 61267, + "payload": null, + "tcpFlags": "A", + "sequence": 1000001, + "acknowledgement": 2000006 + }, + { + "time": 2136, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 8080, + "destinationPort": 61267, + "payload": "reply hello", + "tcpFlags": "P", + "sequence": 1000001, + "acknowledgement": 0 + }, + { + "time": 2136, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 8080, + "payload": null, + "tcpFlags": "A", + "sequence": 2000006, + "acknowledgement": 1000012 + }, + { + "time": 2192, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 8080, + "payload": null, + "tcpFlags": "F", + "sequence": 2000006, + "acknowledgement": 0 + }, + { + "time": 2526, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 8080, + "destinationPort": 61267, + "payload": null, + "tcpFlags": "A", + "sequence": 1000012, + "acknowledgement": 2000007 + }, + { + "time": 2582, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 8080, + "destinationPort": 61267, + "payload": null, + "tcpFlags": "F", + "sequence": 1000012, + "acknowledgement": 0 + }, + { + "time": 2582, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 61267, + "destinationPort": 8080, + "payload": null, + "tcpFlags": "A", + "sequence": 2000007, + "acknowledgement": 1000013 + } + ], + "00000000-0000-0000-0000-000000000505": [ + { + "time": 1104, + "source": "02:00:00:00:05:41", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.20", + "targetIp": "42.0.0.10" + } + ] + }, + "events": [ + [ + 745, + "server oeffnen called" + ], + [ + 945, + "client verbinden called" + ], + [ + 1746, + "client verbinden returned " + ], + [ + 1746, + "client senden called" + ], + [ + 1848, + "server oeffnen returned filius.software.transportschicht.TCPSocket@641fefcc" + ], + [ + 1849, + "server empfangen called" + ], + [ + 1913, + "server empfangen returned hello" + ], + [ + 1914, + "server senden called" + ], + [ + 2081, + "client senden returned " + ], + [ + 2081, + "client empfangen called" + ], + [ + 2136, + "client empfangen returned reply hello" + ], + [ + 2136, + "client schliessen called" + ], + [ + 2137, + "client schliessen returned " + ], + [ + 2303, + "server senden returned " + ] + ], + "nat": [ + "6 42.0.0.20:8080 -> 192.168.0.10:80 DynamicEnryFromStatic" + ] +} diff --git a/packages/core/test/scenarios/nat-java-pingOut.java.json b/packages/core/test/scenarios/nat-java-pingOut.java.json new file mode 100644 index 0000000..1e4bc8b --- /dev/null +++ b/packages/core/test/scenarios/nat-java-pingOut.java.json @@ -0,0 +1,141 @@ +{ + "frames": { + "00000000-0000-0000-0000-000000000501": [ + { + "time": 735, + "source": "02:00:00:00:05:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.10", + "targetIp": "192.168.0.1" + }, + { + "time": 860, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "arp": 2, + "senderIp": "192.168.0.1", + "targetIp": "192.168.0.10" + }, + { + "time": 866, + "source": "02:00:00:00:05:11", + "destination": "02:00:00:00:05:22", + "icmp": 8, + "icmpCode": 0, + "sourceIp": "192.168.0.10", + "destinationIp": "42.0.0.20", + "sequence": 1 + }, + { + "time": 1444, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "icmp": 0, + "icmpCode": 0, + "sourceIp": "42.0.0.20", + "destinationIp": "192.168.0.10", + "sequence": 1 + } + ], + "00000000-0000-0000-0000-000000000502": [ + { + "time": 932, + "source": "02:00:00:00:05:21", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.20" + }, + { + "time": 1164, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "arp": 2, + "senderIp": "42.0.0.20", + "targetIp": "42.0.0.10" + }, + { + "time": 1165, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "icmp": 8, + "icmpCode": 0, + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "sequence": 1 + }, + { + "time": 1388, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "icmp": 0, + "icmpCode": 0, + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "sequence": 1 + } + ], + "00000000-0000-0000-0000-000000000504": [ + { + "time": 1052, + "source": "02:00:00:00:05:21", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.20" + }, + { + "time": 1052, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "arp": 2, + "senderIp": "42.0.0.20", + "targetIp": "42.0.0.10" + }, + { + "time": 1276, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "icmp": 8, + "icmpCode": 0, + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "sequence": 1 + }, + { + "time": 1276, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "icmp": 0, + "icmpCode": 0, + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "sequence": 1 + } + ], + "00000000-0000-0000-0000-000000000505": [ + { + "time": 1052, + "source": "02:00:00:00:05:21", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.20" + } + ] + }, + "events": [ + [ + 730, + "sendProbe 42.0.0.20 called" + ], + [ + 1445, + "sendProbe 42.0.0.20 returned ICMP 0/0 from 42.0.0.20" + ] + ], + "nat": [ + "1 42.0.0.20:1 -> 192.168.0.10:1 DynamicEntry" + ] +} diff --git a/packages/core/test/scenarios/nat-java-pingWan.java.json b/packages/core/test/scenarios/nat-java-pingWan.java.json new file mode 100644 index 0000000..045169f --- /dev/null +++ b/packages/core/test/scenarios/nat-java-pingWan.java.json @@ -0,0 +1,130 @@ +{ + "frames": { + "00000000-0000-0000-0000-000000000501": [], + "00000000-0000-0000-0000-000000000502": [ + { + "time": 849, + "source": "02:00:00:00:05:41", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.20", + "targetIp": "42.0.0.10" + }, + { + "time": 851, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "arp": 2, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.20" + }, + { + "time": 1089, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "icmp": 8, + "icmpCode": 0, + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "sequence": 1 + }, + { + "time": 1089, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "icmp": 0, + "icmpCode": 0, + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "sequence": 1 + }, + { + "time": 1315, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "icmp": 8, + "icmpCode": 0, + "sourceIp": "42.0.0.20", + "destinationIp": "192.168.0.10", + "sequence": 2 + } + ], + "00000000-0000-0000-0000-000000000504": [ + { + "time": 727, + "source": "02:00:00:00:05:41", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.20", + "targetIp": "42.0.0.10" + }, + { + "time": 965, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "arp": 2, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.20" + }, + { + "time": 970, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "icmp": 8, + "icmpCode": 0, + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "sequence": 1 + }, + { + "time": 1201, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "icmp": 0, + "icmpCode": 0, + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "sequence": 1 + }, + { + "time": 1204, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "icmp": 8, + "icmpCode": 0, + "sourceIp": "42.0.0.20", + "destinationIp": "192.168.0.10", + "sequence": 2 + } + ], + "00000000-0000-0000-0000-000000000505": [ + { + "time": 849, + "source": "02:00:00:00:05:41", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.20", + "targetIp": "42.0.0.10" + } + ] + }, + "events": [ + [ + 720, + "sendProbe 42.0.0.10 called" + ], + [ + 1203, + "sendProbe 42.0.0.10 returned ICMP 0/0 from 42.0.0.10" + ], + [ + 1204, + "sendProbe 192.168.0.10 called" + ], + [ + 3954, + "sendProbe 192.168.0.10 returned null" + ] + ], + "nat": [] +} diff --git a/packages/core/test/scenarios/nat-java-tcpOut.java.json b/packages/core/test/scenarios/nat-java-tcpOut.java.json new file mode 100644 index 0000000..c644fe3 --- /dev/null +++ b/packages/core/test/scenarios/nat-java-tcpOut.java.json @@ -0,0 +1,591 @@ +{ + "frames": { + "00000000-0000-0000-0000-000000000501": [ + { + "time": 935, + "source": "02:00:00:00:05:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.10", + "targetIp": "192.168.0.1" + }, + { + "time": 1054, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "arp": 2, + "senderIp": "192.168.0.1", + "targetIp": "192.168.0.10" + }, + { + "time": 1056, + "source": "02:00:00:00:05:11", + "destination": "02:00:00:00:05:22", + "sourceIp": "192.168.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 64470, + "destinationPort": 80, + "payload": null, + "tcpFlags": "S", + "sequence": 3000000, + "acknowledgement": 0 + }, + { + "time": 1622, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "sourceIp": "42.0.0.20", + "destinationIp": "192.168.0.10", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 64470, + "payload": null, + "tcpFlags": "SA", + "sequence": 2000000, + "acknowledgement": 3000001 + }, + { + "time": 1622, + "source": "02:00:00:00:05:11", + "destination": "02:00:00:00:05:22", + "sourceIp": "192.168.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 64470, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 3000001, + "acknowledgement": 2000001 + }, + { + "time": 1678, + "source": "02:00:00:00:05:11", + "destination": "02:00:00:00:05:22", + "sourceIp": "192.168.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 64470, + "destinationPort": 80, + "payload": "hello", + "tcpFlags": "P", + "sequence": 3000001, + "acknowledgement": 0 + }, + { + "time": 2012, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "sourceIp": "42.0.0.20", + "destinationIp": "192.168.0.10", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 64470, + "payload": null, + "tcpFlags": "A", + "sequence": 2000001, + "acknowledgement": 3000006 + }, + { + "time": 2067, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "sourceIp": "42.0.0.20", + "destinationIp": "192.168.0.10", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 64470, + "payload": "reply hello", + "tcpFlags": "P", + "sequence": 2000001, + "acknowledgement": 0 + }, + { + "time": 2068, + "source": "02:00:00:00:05:11", + "destination": "02:00:00:00:05:22", + "sourceIp": "192.168.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 64470, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 3000006, + "acknowledgement": 2000012 + }, + { + "time": 2123, + "source": "02:00:00:00:05:11", + "destination": "02:00:00:00:05:22", + "sourceIp": "192.168.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 64470, + "destinationPort": 80, + "payload": null, + "tcpFlags": "F", + "sequence": 3000006, + "acknowledgement": 0 + }, + { + "time": 2457, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "sourceIp": "42.0.0.20", + "destinationIp": "192.168.0.10", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 64470, + "payload": null, + "tcpFlags": "A", + "sequence": 2000012, + "acknowledgement": 3000007 + }, + { + "time": 2513, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "sourceIp": "42.0.0.20", + "destinationIp": "192.168.0.10", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 64470, + "payload": null, + "tcpFlags": "F", + "sequence": 2000012, + "acknowledgement": 0 + }, + { + "time": 2513, + "source": "02:00:00:00:05:11", + "destination": "02:00:00:00:05:22", + "sourceIp": "192.168.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 64470, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 3000007, + "acknowledgement": 2000013 + } + ], + "00000000-0000-0000-0000-000000000502": [ + { + "time": 1115, + "source": "02:00:00:00:05:21", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.20" + }, + { + "time": 1341, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "arp": 2, + "senderIp": "42.0.0.20", + "targetIp": "42.0.0.10" + }, + { + "time": 1341, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 58632, + "destinationPort": 80, + "payload": null, + "tcpFlags": "S", + "sequence": 3000000, + "acknowledgement": 0 + }, + { + "time": 1566, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 58632, + "payload": null, + "tcpFlags": "SA", + "sequence": 2000000, + "acknowledgement": 3000001 + }, + { + "time": 1678, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 58632, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 3000001, + "acknowledgement": 2000001 + }, + { + "time": 1734, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 58632, + "destinationPort": 80, + "payload": "hello", + "tcpFlags": "P", + "sequence": 3000001, + "acknowledgement": 0 + }, + { + "time": 1956, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 58632, + "payload": null, + "tcpFlags": "A", + "sequence": 2000001, + "acknowledgement": 3000006 + }, + { + "time": 2012, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 58632, + "payload": "reply hello", + "tcpFlags": "P", + "sequence": 2000001, + "acknowledgement": 0 + }, + { + "time": 2124, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 58632, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 3000006, + "acknowledgement": 2000012 + }, + { + "time": 2179, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 58632, + "destinationPort": 80, + "payload": null, + "tcpFlags": "F", + "sequence": 3000006, + "acknowledgement": 0 + }, + { + "time": 2402, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 58632, + "payload": null, + "tcpFlags": "A", + "sequence": 2000012, + "acknowledgement": 3000007 + }, + { + "time": 2457, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 58632, + "payload": null, + "tcpFlags": "F", + "sequence": 2000012, + "acknowledgement": 0 + }, + { + "time": 2569, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 58632, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 3000007, + "acknowledgement": 2000013 + } + ], + "00000000-0000-0000-0000-000000000504": [ + { + "time": 1230, + "source": "02:00:00:00:05:21", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.20" + }, + { + "time": 1230, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "arp": 2, + "senderIp": "42.0.0.20", + "targetIp": "42.0.0.10" + }, + { + "time": 1453, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 58632, + "destinationPort": 80, + "payload": null, + "tcpFlags": "S", + "sequence": 3000000, + "acknowledgement": 0 + }, + { + "time": 1455, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 58632, + "payload": null, + "tcpFlags": "SA", + "sequence": 2000000, + "acknowledgement": 3000001 + }, + { + "time": 1789, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 58632, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 3000001, + "acknowledgement": 2000001 + }, + { + "time": 1845, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 58632, + "destinationPort": 80, + "payload": "hello", + "tcpFlags": "P", + "sequence": 3000001, + "acknowledgement": 0 + }, + { + "time": 1845, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 58632, + "payload": null, + "tcpFlags": "A", + "sequence": 2000001, + "acknowledgement": 3000006 + }, + { + "time": 1901, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 58632, + "payload": "reply hello", + "tcpFlags": "P", + "sequence": 2000001, + "acknowledgement": 0 + }, + { + "time": 2235, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 58632, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 3000006, + "acknowledgement": 2000012 + }, + { + "time": 2290, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 58632, + "destinationPort": 80, + "payload": null, + "tcpFlags": "F", + "sequence": 3000006, + "acknowledgement": 0 + }, + { + "time": 2291, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 58632, + "payload": null, + "tcpFlags": "A", + "sequence": 2000012, + "acknowledgement": 3000007 + }, + { + "time": 2346, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 6, + "sourcePort": 80, + "destinationPort": 58632, + "payload": null, + "tcpFlags": "F", + "sequence": 2000012, + "acknowledgement": 0 + }, + { + "time": 2680, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 6, + "sourcePort": 58632, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 3000007, + "acknowledgement": 2000013 + } + ], + "00000000-0000-0000-0000-000000000505": [ + { + "time": 1230, + "source": "02:00:00:00:05:21", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.20" + } + ] + }, + "events": [ + [ + 719, + "server oeffnen called" + ], + [ + 921, + "client verbinden called" + ], + [ + 1623, + "client verbinden returned " + ], + [ + 1623, + "client senden called" + ], + [ + 1820, + "server oeffnen returned filius.software.transportschicht.TCPSocket@452d1e97" + ], + [ + 1820, + "server empfangen called" + ], + [ + 1845, + "server empfangen returned hello" + ], + [ + 1845, + "server senden called" + ], + [ + 2012, + "client senden returned " + ], + [ + 2012, + "client empfangen called" + ], + [ + 2068, + "client empfangen returned reply hello" + ], + [ + 2068, + "client schliessen called" + ], + [ + 2068, + "client schliessen returned " + ], + [ + 2235, + "server senden returned " + ] + ], + "nat": [ + "6 42.0.0.20:58632 -> 192.168.0.10:64470 DynamicEntry" + ] +} diff --git a/packages/core/test/scenarios/nat-java-udpOut.java.json b/packages/core/test/scenarios/nat-java-udpOut.java.json new file mode 100644 index 0000000..0920bc9 --- /dev/null +++ b/packages/core/test/scenarios/nat-java-udpOut.java.json @@ -0,0 +1,159 @@ +{ + "frames": { + "00000000-0000-0000-0000-000000000501": [ + { + "time": 923, + "source": "02:00:00:00:05:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.10", + "targetIp": "192.168.0.1" + }, + { + "time": 1042, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "arp": 2, + "senderIp": "192.168.0.1", + "targetIp": "192.168.0.10" + }, + { + "time": 1045, + "source": "02:00:00:00:05:11", + "destination": "02:00:00:00:05:22", + "sourceIp": "192.168.0.10", + "destinationIp": "42.0.0.20", + "protocol": 17, + "sourcePort": 62293, + "destinationPort": 7, + "payload": "one" + }, + { + "time": 1614, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "sourceIp": "42.0.0.20", + "destinationIp": "192.168.0.10", + "protocol": 17, + "sourcePort": 7, + "destinationPort": 62293, + "payload": "pong one" + } + ], + "00000000-0000-0000-0000-000000000502": [ + { + "time": 1107, + "source": "02:00:00:00:05:21", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.20" + }, + { + "time": 1333, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "arp": 2, + "senderIp": "42.0.0.20", + "targetIp": "42.0.0.10" + }, + { + "time": 1333, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 17, + "sourcePort": 50801, + "destinationPort": 7, + "payload": "one" + }, + { + "time": 1558, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 17, + "sourcePort": 7, + "destinationPort": 50801, + "payload": "pong one" + } + ], + "00000000-0000-0000-0000-000000000504": [ + { + "time": 1221, + "source": "02:00:00:00:05:21", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.20" + }, + { + "time": 1221, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "arp": 2, + "senderIp": "42.0.0.20", + "targetIp": "42.0.0.10" + }, + { + "time": 1445, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 17, + "sourcePort": 50801, + "destinationPort": 7, + "payload": "one" + }, + { + "time": 1447, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 17, + "sourcePort": 7, + "destinationPort": 50801, + "payload": "pong one" + } + ], + "00000000-0000-0000-0000-000000000505": [ + { + "time": 1221, + "source": "02:00:00:00:05:21", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.20" + } + ] + }, + "events": [ + [ + 917, + "senden 42.0.0.20 called" + ], + [ + 919, + "senden 42.0.0.20 returned " + ], + [ + 919, + "empfangen called" + ], + [ + 1447, + "server received one" + ], + [ + 1615, + "empfangen returned pong one" + ] + ], + "nat": [ + "17 42.0.0.20:50801 -> 192.168.0.10:62293 DynamicEntry" + ] +} diff --git a/packages/core/test/scenarios/nat-java-udpTwoRemotes.java.json b/packages/core/test/scenarios/nat-java-udpTwoRemotes.java.json new file mode 100644 index 0000000..ca64414 --- /dev/null +++ b/packages/core/test/scenarios/nat-java-udpTwoRemotes.java.json @@ -0,0 +1,274 @@ +{ + "frames": { + "00000000-0000-0000-0000-000000000501": [ + { + "time": 921, + "source": "02:00:00:00:05:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.10", + "targetIp": "192.168.0.1" + }, + { + "time": 1041, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "arp": 2, + "senderIp": "192.168.0.1", + "targetIp": "192.168.0.10" + }, + { + "time": 1044, + "source": "02:00:00:00:05:11", + "destination": "02:00:00:00:05:22", + "sourceIp": "192.168.0.10", + "destinationIp": "42.0.0.20", + "protocol": 17, + "sourcePort": 53169, + "destinationPort": 7, + "payload": "one" + }, + { + "time": 1612, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", + "sourceIp": "42.0.0.20", + "destinationIp": "192.168.0.10", + "protocol": 17, + "sourcePort": 7, + "destinationPort": 53169, + "payload": "pong one" + }, + { + "time": 1613, + "source": "02:00:00:00:05:11", + "destination": "02:00:00:00:05:22", + "sourceIp": "192.168.0.10", + "destinationIp": "42.0.0.30", + "protocol": 17, + "sourcePort": 53169, + "destinationPort": 7, + "payload": "two" + } + ], + "00000000-0000-0000-0000-000000000502": [ + { + "time": 1105, + "source": "02:00:00:00:05:21", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.20" + }, + { + "time": 1331, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "arp": 2, + "senderIp": "42.0.0.20", + "targetIp": "42.0.0.10" + }, + { + "time": 1331, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 17, + "sourcePort": 58343, + "destinationPort": 7, + "payload": "one" + }, + { + "time": 1556, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 17, + "sourcePort": 7, + "destinationPort": 58343, + "payload": "pong one" + }, + { + "time": 1669, + "source": "02:00:00:00:05:21", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.30" + }, + { + "time": 1892, + "source": "02:00:00:00:05:51", + "destination": "02:00:00:00:05:21", + "arp": 2, + "senderIp": "42.0.0.30", + "targetIp": "42.0.0.10" + }, + { + "time": 1892, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:51", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.30", + "protocol": 17, + "sourcePort": 58343, + "destinationPort": 7, + "payload": "two" + }, + { + "time": 2115, + "source": "02:00:00:00:05:51", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.30", + "destinationIp": "42.0.0.10", + "protocol": 17, + "sourcePort": 7, + "destinationPort": 58343, + "payload": "pong two" + } + ], + "00000000-0000-0000-0000-000000000504": [ + { + "time": 1220, + "source": "02:00:00:00:05:21", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.20" + }, + { + "time": 1220, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "arp": 2, + "senderIp": "42.0.0.20", + "targetIp": "42.0.0.10" + }, + { + "time": 1443, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:41", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.20", + "protocol": 17, + "sourcePort": 58343, + "destinationPort": 7, + "payload": "one" + }, + { + "time": 1445, + "source": "02:00:00:00:05:41", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.20", + "destinationIp": "42.0.0.10", + "protocol": 17, + "sourcePort": 7, + "destinationPort": 58343, + "payload": "pong one" + }, + { + "time": 1780, + "source": "02:00:00:00:05:21", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.30" + } + ], + "00000000-0000-0000-0000-000000000505": [ + { + "time": 1220, + "source": "02:00:00:00:05:21", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.20" + }, + { + "time": 1780, + "source": "02:00:00:00:05:21", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "42.0.0.10", + "targetIp": "42.0.0.30" + }, + { + "time": 1781, + "source": "02:00:00:00:05:51", + "destination": "02:00:00:00:05:21", + "arp": 2, + "senderIp": "42.0.0.30", + "targetIp": "42.0.0.10" + }, + { + "time": 2003, + "source": "02:00:00:00:05:21", + "destination": "02:00:00:00:05:51", + "sourceIp": "42.0.0.10", + "destinationIp": "42.0.0.30", + "protocol": 17, + "sourcePort": 58343, + "destinationPort": 7, + "payload": "two" + }, + { + "time": 2003, + "source": "02:00:00:00:05:51", + "destination": "02:00:00:00:05:21", + "sourceIp": "42.0.0.30", + "destinationIp": "42.0.0.10", + "protocol": 17, + "sourcePort": 7, + "destinationPort": 58343, + "payload": "pong two" + } + ] + }, + "events": [ + [ + 916, + "senden 42.0.0.20 called" + ], + [ + 918, + "senden 42.0.0.20 returned " + ], + [ + 918, + "empfangen called" + ], + [ + 1445, + "server received one" + ], + [ + 1613, + "empfangen returned pong one" + ], + [ + 1613, + "senden 42.0.0.30 called" + ], + [ + 1613, + "senden 42.0.0.30 returned " + ], + [ + 1613, + "empfangen called" + ], + [ + 2003, + "other server received two" + ], + [ + 15363, + "empfangen returned null" + ] + ], + "nat": [ + "17 42.0.0.20:58343 -> 192.168.0.10:53169 DynamicEntry" + ] +} diff --git a/tools/java-oracle/README.md b/tools/java-oracle/README.md index f3f20c0..2a2db27 100644 --- a/tools/java-oracle/README.md +++ b/tools/java-oracle/README.md @@ -375,3 +375,39 @@ Gemessen (30.09.2026, dazu die Pausenformel am JDK): Nachbarn vor seinem ersten Beacon hört, sendet die gelernte Route gleich mit. Senden mehrere zugleich, fehlt im Lauscher mancher eigene Frame. +## NAT zur Laufzeit + +`NatRun` startet das Netz von `nat-home` (PC 192.168.0.10 am LAN-Port des +Heimrouters 192.168.0.1; sein WAN-Port 42.0.0.10/8 an einem Switch mit +42.0.0.20 und 42.0.0.30; Portweiterleitung TCP 8080 an 192.168.0.10:80; +`ScenarioNetwork` baut Heimrouter und das Feld `portForwarding` über +`GatewayFirmware.setStaticNAT`) und schreibt nach `nat-java-.java.json` +die Frames, die Aufrufe und am Ende die NAT-Tabelle des Heimrouters. Abläufe: +`pingOut`, `udpOut` (Antwort vom Server), `udpTwoRemotes` (danach vom selben +Port an 42.0.0.30), `tcpOut`, `forward` (von 42.0.0.20 an 42.0.0.10:8080), +`pingWan` (42.0.0.20 pingt die WAN-Adresse, dann 192.168.0.10). + +Ein UDP-Server im Werkzeug ist ein aktiver Socket auf Port 7: ein passiver +trägt seinen Port erst ein, wenn Daten da sind, die vorher nicht ankommen. + +Gemessen (30.09.2026), was der Heimrouter tut (`NatGateway`, dessen +Threads zwischen Karte und Ethernet-Schicht sitzen): + +* Ausgehend (Ziel außerhalb des LAN, nicht die WAN-Adresse) wird die + Absenderadresse zur WAN-Adresse, der Port zu einem freien Port des + Heimrouters (nach Javas Zufall); ICMP behält seine Kennung, die als Port + des Eintrags dient. Einen Eintrag legt ein TCP-SYN, jedes UDP-Datagramm + und jedes ICMP-Paket an, aber nur, wenn der LAN-Endpunkt noch keinen hat. +* Eingehend an die WAN-Adresse sucht der Heimrouter den Eintrag nach + Gegenstelle, WAN-Port und Protokoll, sonst nach der Portweiterleitung, die + dann einen dynamischen Eintrag für die Gegenstelle anlegt + (`DynamicEnryFromStatic`). +* Ein zweiter Server, an den derselbe LAN-Endpunkt sendet, bekommt das + Datagramm mit demselben WAN-Port, seine Antwort aber findet keinen Eintrag + (der gilt nur für die erste Gegenstelle) und kommt nicht ins LAN. +* Ein Ping an die WAN-Adresse beantwortet der Heimrouter, einer an eine + LAN-Adresse von außen verschwindet. +* Dynamische Einträge verfallen nach 300 s mal Javas Verzögerungsfaktor + (bei 90 % 55 Minuten), geprüft jede Sekunde, aufgefrischt nur von + eingehenden Paketen (aus dem Code, nicht gemessen). + diff --git a/tools/java-oracle/run.sh b/tools/java-oracle/run.sh index 0908f7d..0bc9dee 100755 --- a/tools/java-oracle/run.sh +++ b/tools/java-oracle/run.sh @@ -21,7 +21,7 @@ if [ ! -f "$upstream/target/filius.jar" ]; then fi classpath="$upstream/target/filius.jar:$upstream/target/lib/*" mkdir -p "$here/.build" -javac -encoding UTF-8 -d "$here/.build" -cp "$classpath" "$here/src/FlsOracle.java" "$here/src/GetterDefaults.java" "$here/src/IpCheckCases.java" "$here/src/DnsHostsCases.java" "$here/src/EmailFileCases.java" "$here/src/BeansDump.java" "$here/src/Base64Cases.java" "$here/src/ScenarioNetwork.java" "$here/src/DhcpRun.java" "$here/src/TcpRun.java" "$here/src/DnsRun.java" "$here/src/ArpRun.java" "$here/src/RipRun.java" +javac -encoding UTF-8 -d "$here/.build" -cp "$classpath" "$here/src/FlsOracle.java" "$here/src/GetterDefaults.java" "$here/src/IpCheckCases.java" "$here/src/DnsHostsCases.java" "$here/src/EmailFileCases.java" "$here/src/BeansDump.java" "$here/src/Base64Cases.java" "$here/src/ScenarioNetwork.java" "$here/src/DhcpRun.java" "$here/src/TcpRun.java" "$here/src/DnsRun.java" "$here/src/ArpRun.java" "$here/src/RipRun.java" "$here/src/NatRun.java" # FILIUS writes its settings below $HOME; keep them out of the real one. mkdir -p "$here/.build/home" # Removed first: a crashed run must not leave the previous result standing. @@ -152,6 +152,17 @@ for run in address:5000 referral:5000 unknown:5000 unknownInZone:5000 unknownInO test -s "$output" done +# NAT as Java FILIUS runs it: nat-home's home router between a LAN PC and two +# WAN hosts (NatRun); frames, calls and the router's NAT table at the end. +for run in pingOut:10000 udpOut:10000 udpTwoRemotes:25000 tcpOut:20000 forward:20000 pingWan:15000; do + story="${run%%:*}" + output="$root/packages/core/test/scenarios/nat-java-$story.java.json" + rm -f "$output" + HOME="$here/.build/home" xvfb-run -a java -cp "$classpath:$here/.build" NatRun \ + "$root/packages/core/test/scenarios/nat-home.scenario.json" "$story" "${run##*:}" "$output" 2>&1 | grep -v 'logback\|^$' || true + test -s "$output" +done + # RIP as Java FILIUS runs it: rip-chain's routers, each with the core's seed # for its pauses (RipRun); frames, table changes and the ping. Real time. for run in converge:60000 expire:135000; do diff --git a/tools/java-oracle/src/NatRun.java b/tools/java-oracle/src/NatRun.java new file mode 100644 index 0000000..6ca8be4 --- /dev/null +++ b/tools/java-oracle/src/NatRun.java @@ -0,0 +1,230 @@ +// Runs nat-home's network in Java FILIUS (ScenarioNetwork) and records what +// the home router's NAT really does: every frame each card saw, the story's +// calls and, at the end, the router's NAT table. +// +// NatRun +// +// PC 192.168.0.10 on the home router's LAN port (192.168.0.1); its WAN port +// (42.0.0.10/8) on a switch with 42.0.0.20 (gateway 42.0.0.10) and +// 42.0.0.30. Port forwarding: TCP 8080 to 192.168.0.10:80. The stories: +// pingOut 192.168.0.10 pings 42.0.0.20 +// udpOut 192.168.0.10 sends a datagram to 42.0.0.20:7, which answers +// udpTwoRemotes the same, then from the same local port to 42.0.0.30:7, +// which answers too +// tcpOut 192.168.0.10 connects to 42.0.0.20:80, sends, receives, closes +// forward 42.0.0.20 connects to 42.0.0.10:8080, forwarded to +// 192.168.0.10:80; sends, receives, closes +// pingWan 42.0.0.20 pings 42.0.0.10, then 192.168.0.10 + +import filius.software.nat.NatEntry; +import filius.software.nat.NatGateway; +import filius.software.nat.PortProtocolPair; +import filius.software.system.GatewayFirmware; +import filius.software.system.InternetKnotenBetriebssystem; +import filius.software.transportschicht.ServerSocket; +import filius.software.transportschicht.Socket; +import filius.software.transportschicht.TCPSocket; +import filius.software.transportschicht.UDPSocket; +import filius.software.vermittlungsschicht.IcmpPaket; +import filius.software.vermittlungsschicht.IpPaket; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeSet; + +public class NatRun { + static final String LAN_PC = "00000000-0000-0000-0000-000000000501"; + static final String GATEWAY = "00000000-0000-0000-0000-000000000502"; + static final String SERVER = "00000000-0000-0000-0000-000000000504"; + static final String OTHER_SERVER = "00000000-0000-0000-0000-000000000505"; + + static ScenarioNetwork network; + static final List events = new ArrayList<>(); + + static synchronized void event(String what) { + events.add(new Object[] { System.currentTimeMillis() - network.start, what }); + } + + interface Call { + Object run() throws Exception; + } + + static Object call(String label, Call call) { + event(label + " called"); + try { + Object result = call.run(); + event(label + " returned" + (result == null ? " null" : " " + result)); + return result; + } catch (Exception e) { + event(label + " failed " + e.getClass().getSimpleName()); + return null; + } + } + + static void inThread(Call body) { + Thread thread = new Thread(() -> { + try { + body.run(); + } catch (Exception e) { + event("thread failed " + e.getClass().getSimpleName()); + } + }); + thread.setDaemon(true); + thread.start(); + } + + static InternetKnotenBetriebssystem os(String node) { + return network.system(node); + } + + static String icmp(IcmpPaket packet) { + return packet == null ? "null" : "ICMP " + packet.getIcmpType() + "/" + packet.getIcmpCode() + " from " + packet.getSender(); + } + + /** + * A UDP server on the node's port 7: answers the first datagram with + * "pong ". An active socket (a passive one registers its port only + * after data came, which cannot come before); it answers to where the + * datagram came from. + */ + static void udpEcho(String node, String label) { + inThread(() -> { + UDPSocket socket = new UDPSocket(os(node), "0.0.0.0", 1, 7); + socket.verbinden(); + String message = socket.empfangen(); + event(label + " received " + message); + socket.senden("pong " + message); + return null; + }); + } + + /** A TCP server on the node's port 80: receives one message, answers "reply ", and closes when the client does. */ + static void tcpServer(String node) { + inThread(() -> { + ServerSocket listener = new ServerSocket(os(node), 80, IpPaket.TCP, new ArrayList<>()); + Socket accepted = (Socket) call("server oeffnen", listener::oeffnen); + String message = (String) call("server empfangen", accepted::empfangen); + call("server senden", () -> { + accepted.senden("reply " + message); + return ""; + }); + return null; + }); + } + + static void tcpClient(String node, String target, int port) throws Exception { + TCPSocket client = new TCPSocket(os(node), target, port); + call("client verbinden", () -> { + client.verbinden(); + return ""; + }); + call("client senden", () -> { + client.senden("hello"); + return ""; + }); + call("client empfangen", client::empfangen); + call("client schliessen", () -> { + client.schliessen(); + return ""; + }); + } + + static long rtt() { + return filius.hardware.Verbindung.holeRTT(); + } + + static void sleepUntil(long milliseconds) throws InterruptedException { + long rest = network.start + milliseconds - System.currentTimeMillis(); + if (rest > 0) Thread.sleep(rest); + } + + public static void main(String[] args) throws Exception { + network = ScenarioNetwork.read(args[0]); + String story = args[1]; + long end = Long.parseLong(args[2]); + network.start(); + Thread.sleep(500); + + switch (story) { + case "pingOut": + call("sendProbe 42.0.0.20", () -> icmp(os(LAN_PC).holeICMP().sendProbe("42.0.0.20", 64, 1, 1))); + break; + case "udpOut": { + udpEcho(SERVER, "server"); + Thread.sleep(200); + UDPSocket socket = new UDPSocket(os(LAN_PC), "42.0.0.20", 7); + socket.verbinden(); + call("senden 42.0.0.20", () -> { + socket.senden("one"); + return ""; + }); + call("empfangen", () -> socket.empfangen(5 * rtt())); + break; + } + case "udpTwoRemotes": { + udpEcho(SERVER, "server"); + udpEcho(OTHER_SERVER, "other server"); + Thread.sleep(200); + UDPSocket first = new UDPSocket(os(LAN_PC), "42.0.0.20", 7); + first.verbinden(); + call("senden 42.0.0.20", () -> { + first.senden("one"); + return ""; + }); + call("empfangen", () -> first.empfangen(5 * rtt())); + int port = first.holeLokalenPort(); + first.schliessen(); + UDPSocket second = new UDPSocket(os(LAN_PC), "42.0.0.30", 7, port); + second.verbinden(); + call("senden 42.0.0.30", () -> { + second.senden("two"); + return ""; + }); + call("empfangen", () -> second.empfangen(5 * rtt())); + break; + } + case "tcpOut": + tcpServer(SERVER); + Thread.sleep(200); + tcpClient(LAN_PC, "42.0.0.20", 80); + break; + case "forward": + tcpServer(LAN_PC); + Thread.sleep(200); + tcpClient(SERVER, "42.0.0.10", 8080); + break; + case "pingWan": + call("sendProbe 42.0.0.10", () -> icmp(os(SERVER).holeICMP().sendProbe("42.0.0.10", 64, 1, 1))); + call("sendProbe 192.168.0.10", () -> icmp(os(SERVER).holeICMP().sendProbe("192.168.0.10", 64, 1, 2))); + break; + default: + throw new IllegalArgumentException("unknown story " + story); + } + sleepUntil(end); + + // The NAT table: `protocol address:port -> lan address:port type`, sorted. + TreeSet table = new TreeSet<>(); + NatGateway nat = (NatGateway) ((GatewayFirmware) os(GATEWAY)).holeFirewall(); + for (Map.Entry entry : nat.getNATTable().getDynamicNATTable().entrySet()) { + table.add(entry.getKey().getProtocol() + " " + entry.getKey().getAddress() + ":" + entry.getKey().getPort() + " -> " + + entry.getValue().getInetAddress() + " " + entry.getValue().getNatType()); + } + + ScenarioNetwork.Json out = new ScenarioNetwork.Json(); + out.open('{'); + network.writeFrames(out); + synchronized (NatRun.class) { + out.key("events").open('['); + for (Object[] each : events) out.open('[').number((Long) each[0]).string((String) each[1]).close(']'); + out.close(']'); + } + out.key("nat").open('['); + for (String each : table) out.string(each); + out.close(']'); + out.close('}'); + network.stop(); + ScenarioNetwork.write(args[3], out); + System.exit(0); + } +} diff --git a/tools/java-oracle/src/ScenarioNetwork.java b/tools/java-oracle/src/ScenarioNetwork.java index badd9bd..51e4d3e 100644 --- a/tools/java-oracle/src/ScenarioNetwork.java +++ b/tools/java-oracle/src/ScenarioNetwork.java @@ -10,6 +10,7 @@ import filius.gui.GUIContainer; import filius.hardware.Kabel; import filius.hardware.NetzwerkInterface; import filius.hardware.Port; +import filius.hardware.knoten.Gateway; import filius.hardware.knoten.InternetKnoten; import filius.hardware.knoten.Knoten; import filius.hardware.knoten.LokalerKnoten; @@ -21,6 +22,7 @@ import filius.rahmenprogramm.nachrichten.Lauscher; import filius.software.dhcp.DHCPServer; import filius.software.dns.DNSServer; import filius.software.netzzugangsschicht.EthernetFrame; +import filius.software.system.GatewayFirmware; import filius.software.system.InternetKnotenBetriebssystem; import filius.software.system.VermittlungsrechnerBetriebssystem; import filius.software.transportschicht.Segment; @@ -90,6 +92,10 @@ public class ScenarioNetwork { knoten = new Vermittlungsrechner(); ((InternetKnoten) knoten).setzeAnzahlAnschluesse(nodePorts.size()); break; + case "gateway": + // Its first card is the WAN port, its second the LAN port. + knoten = new Gateway(); + break; default: throw new IllegalArgumentException("node kind " + kind + " is not built by this tool"); } @@ -165,6 +171,12 @@ public class ScenarioNetwork { for (Object each : list(scenario.getOrDefault("dhcpClients", new ArrayList<>()))) { system(nodes.get((String) each)).setDHCPKonfiguration(true); } + // A home router's port forwarding: rows of protocol, public port, LAN address, LAN port. + for (Map.Entry entry : map(scenario.getOrDefault("portForwarding", new HashMap<>())).entrySet()) { + LinkedList rows = new LinkedList<>(); + for (Object row : list(entry.getValue())) rows.add(list(row).stream().map(String::valueOf).toArray(String[]::new)); + ((GatewayFirmware) system(nodes.get(entry.getKey()))).setStaticNAT(rows); + } for (Object each : list(scenario.getOrDefault("rip", new ArrayList<>()))) { ((VermittlungsrechnerBetriebssystem) system(nodes.get((String) each))).setRipEnabled(true); }