diff --git a/packages/core/test/oracle.test.ts b/packages/core/test/oracle.test.ts index face4a9..a95ff83 100644 --- a/packages/core/test/oracle.test.ts +++ b/packages/core/test/oracle.test.ts @@ -3,7 +3,7 @@ // same file (.swift.json, written by tools/swift-oracle/run.sh). // Every trace event must match: identity, time, node, headers, detail. -import { readdirSync, readFileSync } from 'node:fs'; +import { existsSync, readdirSync, readFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; import { describe, expect, it } from 'vitest'; @@ -272,8 +272,9 @@ function run(scenario: Scenario): Record { }; } +// Scenarios with a Swift result (the Java comparisons have scenarios of their own). const scenarioNames = readdirSync(scenarioDirectory) - .filter((name) => name.endsWith('.scenario.json')) + .filter((name) => name.endsWith('.scenario.json') && existsSync(join(scenarioDirectory, name.replace('.scenario.json', '.swift.json')))) .map((name) => name.replace('.scenario.json', '')) .sort(); diff --git a/packages/core/test/scenarios/dns-java-address.java.json b/packages/core/test/scenarios/dns-java-address.java.json new file mode 100644 index 0000000..ad23a2b --- /dev/null +++ b/packages/core/test/scenarios/dns-java-address.java.json @@ -0,0 +1,114 @@ +{ + "frames": { + "00000000-0000-0000-0000-000000000101": [ + { + "time": 723, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.10" + }, + { + "time": 956, + "source": "02:00:00:00:01:12", + "destination": "02:00:00:00:01:11", + "arp": 2, + "senderIp": "192.168.0.10", + "targetIp": "192.168.0.20" + }, + { + "time": 959, + "source": "02:00:00:00:01:11", + "destination": "02:00:00:00:01:12", + "sourceIp": "192.168.0.20", + "destinationIp": "192.168.0.10", + "protocol": 17, + "sourcePort": 57362, + "destinationPort": 53, + "payload": "ID=38187 QR=0 RCODE=0 QDCOUNT=1 ANCOUNT=0 NSCOUNT=0 ARCOUNT=0 \nweb.filius.de. A IN\n" + }, + { + "time": 1188, + "source": "02:00:00:00:01:12", + "destination": "02:00:00:00:01:11", + "sourceIp": "192.168.0.10", + "destinationIp": "192.168.0.20", + "protocol": 17, + "sourcePort": 53, + "destinationPort": 57362, + "payload": "ID=38187 QR=1 RCODE=0 QDCOUNT=0 ANCOUNT=1 NSCOUNT=0 ARCOUNT=0 \nweb.filius.de. A 3600 192.168.0.30\n" + } + ], + "00000000-0000-0000-0000-000000000102": [ + { + "time": 844, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.10" + }, + { + "time": 845, + "source": "02:00:00:00:01:12", + "destination": "02:00:00:00:01:11", + "arp": 2, + "senderIp": "192.168.0.10", + "targetIp": "192.168.0.20" + }, + { + "time": 1072, + "source": "02:00:00:00:01:11", + "destination": "02:00:00:00:01:12", + "sourceIp": "192.168.0.20", + "destinationIp": "192.168.0.10", + "protocol": 17, + "sourcePort": 57362, + "destinationPort": 53, + "payload": "ID=38187 QR=0 RCODE=0 QDCOUNT=1 ANCOUNT=0 NSCOUNT=0 ARCOUNT=0 \nweb.filius.de. A IN\n" + }, + { + "time": 1077, + "source": "02:00:00:00:01:12", + "destination": "02:00:00:00:01:11", + "sourceIp": "192.168.0.10", + "destinationIp": "192.168.0.20", + "protocol": 17, + "sourcePort": 53, + "destinationPort": 57362, + "payload": "ID=38187 QR=1 RCODE=0 QDCOUNT=0 ANCOUNT=1 NSCOUNT=0 ARCOUNT=0 \nweb.filius.de. A 3600 192.168.0.30\n" + } + ], + "00000000-0000-0000-0000-000000000103": [ + { + "time": 844, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.10" + } + ], + "00000000-0000-0000-0000-000000000104": [ + { + "time": 844, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.10" + } + ] + }, + "events": [ + [ + 712, + "holeIPAdresse web.filius.de called" + ], + [ + 1189, + "holeIPAdresse web.filius.de returned 192.168.0.30" + ] + ] +} diff --git a/packages/core/test/scenarios/dns-java-mail.java.json b/packages/core/test/scenarios/dns-java-mail.java.json new file mode 100644 index 0000000..59a8807 --- /dev/null +++ b/packages/core/test/scenarios/dns-java-mail.java.json @@ -0,0 +1,114 @@ +{ + "frames": { + "00000000-0000-0000-0000-000000000101": [ + { + "time": 725, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.10" + }, + { + "time": 958, + "source": "02:00:00:00:01:12", + "destination": "02:00:00:00:01:11", + "arp": 2, + "senderIp": "192.168.0.10", + "targetIp": "192.168.0.20" + }, + { + "time": 961, + "source": "02:00:00:00:01:11", + "destination": "02:00:00:00:01:12", + "sourceIp": "192.168.0.20", + "destinationIp": "192.168.0.10", + "protocol": 17, + "sourcePort": 55842, + "destinationPort": 53, + "payload": "ID=4405 QR=0 RCODE=0 QDCOUNT=1 ANCOUNT=0 NSCOUNT=0 ARCOUNT=0 \nfilius.de. MX IN\n" + }, + { + "time": 1191, + "source": "02:00:00:00:01:12", + "destination": "02:00:00:00:01:11", + "sourceIp": "192.168.0.10", + "destinationIp": "192.168.0.20", + "protocol": 17, + "sourcePort": 53, + "destinationPort": 55842, + "payload": "ID=4405 QR=1 RCODE=0 QDCOUNT=0 ANCOUNT=2 NSCOUNT=0 ARCOUNT=0 \nfilius.de. MX 3600 mail.filius.de.\nmail.filius.de. A 3600 192.168.0.31\n" + } + ], + "00000000-0000-0000-0000-000000000102": [ + { + "time": 846, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.10" + }, + { + "time": 847, + "source": "02:00:00:00:01:12", + "destination": "02:00:00:00:01:11", + "arp": 2, + "senderIp": "192.168.0.10", + "targetIp": "192.168.0.20" + }, + { + "time": 1074, + "source": "02:00:00:00:01:11", + "destination": "02:00:00:00:01:12", + "sourceIp": "192.168.0.20", + "destinationIp": "192.168.0.10", + "protocol": 17, + "sourcePort": 55842, + "destinationPort": 53, + "payload": "ID=4405 QR=0 RCODE=0 QDCOUNT=1 ANCOUNT=0 NSCOUNT=0 ARCOUNT=0 \nfilius.de. MX IN\n" + }, + { + "time": 1079, + "source": "02:00:00:00:01:12", + "destination": "02:00:00:00:01:11", + "sourceIp": "192.168.0.10", + "destinationIp": "192.168.0.20", + "protocol": 17, + "sourcePort": 53, + "destinationPort": 55842, + "payload": "ID=4405 QR=1 RCODE=0 QDCOUNT=0 ANCOUNT=2 NSCOUNT=0 ARCOUNT=0 \nfilius.de. MX 3600 mail.filius.de.\nmail.filius.de. A 3600 192.168.0.31\n" + } + ], + "00000000-0000-0000-0000-000000000103": [ + { + "time": 845, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.10" + } + ], + "00000000-0000-0000-0000-000000000104": [ + { + "time": 845, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.10" + } + ] + }, + "events": [ + [ + 714, + "holeIPAdresseMailServer filius.de called" + ], + [ + 1191, + "holeIPAdresseMailServer filius.de returned 192.168.0.31" + ] + ] +} diff --git a/packages/core/test/scenarios/dns-java-noServer.java.json b/packages/core/test/scenarios/dns-java-noServer.java.json new file mode 100644 index 0000000..cda42e2 --- /dev/null +++ b/packages/core/test/scenarios/dns-java-noServer.java.json @@ -0,0 +1,86 @@ +{ + "frames": { + "00000000-0000-0000-0000-000000000101": [ + { + "time": 844, + "source": "02:00:00:00:01:14", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.21", + "targetIp": "192.168.0.99" + }, + { + "time": 3585, + "source": "02:00:00:00:01:14", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.21", + "targetIp": "192.168.0.99" + } + ], + "00000000-0000-0000-0000-000000000102": [ + { + "time": 844, + "source": "02:00:00:00:01:14", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.21", + "targetIp": "192.168.0.99" + }, + { + "time": 3585, + "source": "02:00:00:00:01:14", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.21", + "targetIp": "192.168.0.99" + } + ], + "00000000-0000-0000-0000-000000000103": [ + { + "time": 844, + "source": "02:00:00:00:01:14", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.21", + "targetIp": "192.168.0.99" + }, + { + "time": 3585, + "source": "02:00:00:00:01:14", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.21", + "targetIp": "192.168.0.99" + } + ], + "00000000-0000-0000-0000-000000000104": [ + { + "time": 723, + "source": "02:00:00:00:01:14", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.21", + "targetIp": "192.168.0.99" + }, + { + "time": 3473, + "source": "02:00:00:00:01:14", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.21", + "targetIp": "192.168.0.99" + } + ] + }, + "events": [ + [ + 713, + "holeIPAdresse web.filius.de called" + ], + [ + 14470, + "holeIPAdresse web.filius.de failed TimeOutException" + ] + ] +} diff --git a/packages/core/test/scenarios/dns-java-referral.java.json b/packages/core/test/scenarios/dns-java-referral.java.json new file mode 100644 index 0000000..204500d --- /dev/null +++ b/packages/core/test/scenarios/dns-java-referral.java.json @@ -0,0 +1,206 @@ +{ + "frames": { + "00000000-0000-0000-0000-000000000101": [ + { + "time": 725, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.10" + }, + { + "time": 959, + "source": "02:00:00:00:01:12", + "destination": "02:00:00:00:01:11", + "arp": 2, + "senderIp": "192.168.0.10", + "targetIp": "192.168.0.20" + }, + { + "time": 962, + "source": "02:00:00:00:01:11", + "destination": "02:00:00:00:01:12", + "sourceIp": "192.168.0.20", + "destinationIp": "192.168.0.10", + "protocol": 17, + "sourcePort": 49846, + "destinationPort": 53, + "payload": "ID=27710 QR=0 RCODE=0 QDCOUNT=1 ANCOUNT=0 NSCOUNT=0 ARCOUNT=0 \nwww.schule.de. A IN\n" + }, + { + "time": 1191, + "source": "02:00:00:00:01:12", + "destination": "02:00:00:00:01:11", + "sourceIp": "192.168.0.10", + "destinationIp": "192.168.0.20", + "protocol": 17, + "sourcePort": 53, + "destinationPort": 49846, + "payload": "ID=27710 QR=1 RCODE=0 QDCOUNT=0 ANCOUNT=2 NSCOUNT=0 ARCOUNT=0 \nschule.de. NS 3600 ns.schule.de.\nns.schule.de. A 3600 192.168.0.11\n" + }, + { + "time": 1192, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.11" + }, + { + "time": 1414, + "source": "02:00:00:00:01:13", + "destination": "02:00:00:00:01:11", + "arp": 2, + "senderIp": "192.168.0.11", + "targetIp": "192.168.0.20" + }, + { + "time": 1415, + "source": "02:00:00:00:01:11", + "destination": "02:00:00:00:01:13", + "sourceIp": "192.168.0.20", + "destinationIp": "192.168.0.11", + "protocol": 17, + "sourcePort": 61850, + "destinationPort": 53, + "payload": "ID=14830 QR=0 RCODE=0 QDCOUNT=1 ANCOUNT=0 NSCOUNT=0 ARCOUNT=0 \nwww.schule.de. A IN\n" + }, + { + "time": 1638, + "source": "02:00:00:00:01:13", + "destination": "02:00:00:00:01:11", + "sourceIp": "192.168.0.11", + "destinationIp": "192.168.0.20", + "protocol": 17, + "sourcePort": 53, + "destinationPort": 61850, + "payload": "ID=14830 QR=1 RCODE=0 QDCOUNT=0 ANCOUNT=1 NSCOUNT=0 ARCOUNT=0 \nwww.schule.de. A 3600 192.168.0.40\n" + } + ], + "00000000-0000-0000-0000-000000000102": [ + { + "time": 846, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.10" + }, + { + "time": 848, + "source": "02:00:00:00:01:12", + "destination": "02:00:00:00:01:11", + "arp": 2, + "senderIp": "192.168.0.10", + "targetIp": "192.168.0.20" + }, + { + "time": 1075, + "source": "02:00:00:00:01:11", + "destination": "02:00:00:00:01:12", + "sourceIp": "192.168.0.20", + "destinationIp": "192.168.0.10", + "protocol": 17, + "sourcePort": 49846, + "destinationPort": 53, + "payload": "ID=27710 QR=0 RCODE=0 QDCOUNT=1 ANCOUNT=0 NSCOUNT=0 ARCOUNT=0 \nwww.schule.de. A IN\n" + }, + { + "time": 1080, + "source": "02:00:00:00:01:12", + "destination": "02:00:00:00:01:11", + "sourceIp": "192.168.0.10", + "destinationIp": "192.168.0.20", + "protocol": 17, + "sourcePort": 53, + "destinationPort": 49846, + "payload": "ID=27710 QR=1 RCODE=0 QDCOUNT=0 ANCOUNT=2 NSCOUNT=0 ARCOUNT=0 \nschule.de. NS 3600 ns.schule.de.\nns.schule.de. A 3600 192.168.0.11\n" + }, + { + "time": 1303, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.11" + } + ], + "00000000-0000-0000-0000-000000000103": [ + { + "time": 846, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.10" + }, + { + "time": 1303, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.11" + }, + { + "time": 1303, + "source": "02:00:00:00:01:13", + "destination": "02:00:00:00:01:11", + "arp": 2, + "senderIp": "192.168.0.11", + "targetIp": "192.168.0.20" + }, + { + "time": 1526, + "source": "02:00:00:00:01:11", + "destination": "02:00:00:00:01:13", + "sourceIp": "192.168.0.20", + "destinationIp": "192.168.0.11", + "protocol": 17, + "sourcePort": 61850, + "destinationPort": 53, + "payload": "ID=14830 QR=0 RCODE=0 QDCOUNT=1 ANCOUNT=0 NSCOUNT=0 ARCOUNT=0 \nwww.schule.de. A IN\n" + }, + { + "time": 1527, + "source": "02:00:00:00:01:13", + "destination": "02:00:00:00:01:11", + "sourceIp": "192.168.0.11", + "destinationIp": "192.168.0.20", + "protocol": 17, + "sourcePort": 53, + "destinationPort": 61850, + "payload": "ID=14830 QR=1 RCODE=0 QDCOUNT=0 ANCOUNT=1 NSCOUNT=0 ARCOUNT=0 \nwww.schule.de. A 3600 192.168.0.40\n" + } + ], + "00000000-0000-0000-0000-000000000104": [ + { + "time": 846, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.10" + }, + { + "time": 1303, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.11" + } + ] + }, + "events": [ + [ + 715, + "holeIPAdresse www.schule.de called" + ], + [ + 1639, + "holeIPAdresse www.schule.de returned 192.168.0.40" + ] + ] +} diff --git a/packages/core/test/scenarios/dns-java-unknown.java.json b/packages/core/test/scenarios/dns-java-unknown.java.json new file mode 100644 index 0000000..bebe8b1 --- /dev/null +++ b/packages/core/test/scenarios/dns-java-unknown.java.json @@ -0,0 +1,114 @@ +{ + "frames": { + "00000000-0000-0000-0000-000000000101": [ + { + "time": 726, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.10" + }, + { + "time": 960, + "source": "02:00:00:00:01:12", + "destination": "02:00:00:00:01:11", + "arp": 2, + "senderIp": "192.168.0.10", + "targetIp": "192.168.0.20" + }, + { + "time": 963, + "source": "02:00:00:00:01:11", + "destination": "02:00:00:00:01:12", + "sourceIp": "192.168.0.20", + "destinationIp": "192.168.0.10", + "protocol": 17, + "sourcePort": 56964, + "destinationPort": 53, + "payload": "ID=54840 QR=0 RCODE=0 QDCOUNT=1 ANCOUNT=0 NSCOUNT=0 ARCOUNT=0 \nx.unbekannt.org. A IN\n" + }, + { + "time": 1192, + "source": "02:00:00:00:01:12", + "destination": "02:00:00:00:01:11", + "sourceIp": "192.168.0.10", + "destinationIp": "192.168.0.20", + "protocol": 17, + "sourcePort": 53, + "destinationPort": 56964, + "payload": "ID=54840 QR=1 RCODE=0 QDCOUNT=0 ANCOUNT=0 NSCOUNT=0 ARCOUNT=0 \n" + } + ], + "00000000-0000-0000-0000-000000000102": [ + { + "time": 848, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.10" + }, + { + "time": 849, + "source": "02:00:00:00:01:12", + "destination": "02:00:00:00:01:11", + "arp": 2, + "senderIp": "192.168.0.10", + "targetIp": "192.168.0.20" + }, + { + "time": 1076, + "source": "02:00:00:00:01:11", + "destination": "02:00:00:00:01:12", + "sourceIp": "192.168.0.20", + "destinationIp": "192.168.0.10", + "protocol": 17, + "sourcePort": 56964, + "destinationPort": 53, + "payload": "ID=54840 QR=0 RCODE=0 QDCOUNT=1 ANCOUNT=0 NSCOUNT=0 ARCOUNT=0 \nx.unbekannt.org. A IN\n" + }, + { + "time": 1081, + "source": "02:00:00:00:01:12", + "destination": "02:00:00:00:01:11", + "sourceIp": "192.168.0.10", + "destinationIp": "192.168.0.20", + "protocol": 17, + "sourcePort": 53, + "destinationPort": 56964, + "payload": "ID=54840 QR=1 RCODE=0 QDCOUNT=0 ANCOUNT=0 NSCOUNT=0 ARCOUNT=0 \n" + } + ], + "00000000-0000-0000-0000-000000000103": [ + { + "time": 848, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.10" + } + ], + "00000000-0000-0000-0000-000000000104": [ + { + "time": 848, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "192.168.0.20", + "targetIp": "192.168.0.10" + } + ] + }, + "events": [ + [ + 716, + "holeIPAdresse x.unbekannt.org called" + ], + [ + 1192, + "holeIPAdresse x.unbekannt.org returned null" + ] + ] +} diff --git a/packages/core/test/scenarios/dns-lan.scenario.json b/packages/core/test/scenarios/dns-lan.scenario.json new file mode 100644 index 0000000..ca09354 --- /dev/null +++ b/packages/core/test/scenarios/dns-lan.scenario.json @@ -0,0 +1,138 @@ +{ + "seed": 51, + "nodes": [ + { + "id": "00000000-0000-0000-0000-000000000101", + "kind": "pc", + "ports": [ + { + "id": "00000000-0000-0000-0000-000000000111", + "label": "eth0" + } + ] + }, + { + "id": "00000000-0000-0000-0000-000000000102", + "kind": "pc", + "ports": [ + { + "id": "00000000-0000-0000-0000-000000000112", + "label": "eth0" + } + ] + }, + { + "id": "00000000-0000-0000-0000-000000000103", + "kind": "pc", + "ports": [ + { + "id": "00000000-0000-0000-0000-000000000113", + "label": "eth0" + } + ] + }, + { + "id": "00000000-0000-0000-0000-000000000104", + "kind": "pc", + "ports": [ + { + "id": "00000000-0000-0000-0000-000000000114", + "label": "eth0" + } + ] + }, + { + "id": "00000000-0000-0000-0000-000000000105", + "kind": "networkSwitch", + "ports": [ + { + "id": "00000000-0000-0000-0000-000000000121", + "label": "sw1" + }, + { + "id": "00000000-0000-0000-0000-000000000122", + "label": "sw2" + }, + { + "id": "00000000-0000-0000-0000-000000000123", + "label": "sw3" + }, + { + "id": "00000000-0000-0000-0000-000000000124", + "label": "sw4" + }, + { + "id": "00000000-0000-0000-0000-000000000125", + "label": "sw5" + } + ] + } + ], + "links": [ + { + "id": "00000000-0000-0000-0000-00000000F001", + "sourceNode": "00000000-0000-0000-0000-000000000101", + "sourcePort": "00000000-0000-0000-0000-000000000111", + "targetNode": "00000000-0000-0000-0000-000000000105", + "targetPort": "00000000-0000-0000-0000-000000000121" + }, + { + "id": "00000000-0000-0000-0000-00000000F002", + "sourceNode": "00000000-0000-0000-0000-000000000102", + "sourcePort": "00000000-0000-0000-0000-000000000112", + "targetNode": "00000000-0000-0000-0000-000000000105", + "targetPort": "00000000-0000-0000-0000-000000000122" + }, + { + "id": "00000000-0000-0000-0000-00000000F003", + "sourceNode": "00000000-0000-0000-0000-000000000103", + "sourcePort": "00000000-0000-0000-0000-000000000113", + "targetNode": "00000000-0000-0000-0000-000000000105", + "targetPort": "00000000-0000-0000-0000-000000000123" + }, + { + "id": "00000000-0000-0000-0000-00000000F004", + "sourceNode": "00000000-0000-0000-0000-000000000104", + "sourcePort": "00000000-0000-0000-0000-000000000114", + "targetNode": "00000000-0000-0000-0000-000000000105", + "targetPort": "00000000-0000-0000-0000-000000000124" + } + ], + "devices": { + "00000000-0000-0000-0000-000000000101": { + "ip": "192.168.0.20", + "mask": "255.255.255.0", + "dns": "192.168.0.10" + }, + "00000000-0000-0000-0000-000000000102": { + "ip": "192.168.0.10", + "mask": "255.255.255.0" + }, + "00000000-0000-0000-0000-000000000103": { + "ip": "192.168.0.11", + "mask": "255.255.255.0" + }, + "00000000-0000-0000-0000-000000000104": { + "ip": "192.168.0.21", + "mask": "255.255.255.0", + "dns": "192.168.0.99" + } + }, + "dnsServers": { + "00000000-0000-0000-0000-000000000102": { + "records": [ + "web.filius.de A 192.168.0.30", + "filius.de MX mail.filius.de", + "mail.filius.de A 192.168.0.31", + "schule.de NS ns.schule.de", + "ns.schule.de A 192.168.0.11" + ] + }, + "00000000-0000-0000-0000-000000000103": { + "records": [ + "www.schule.de A 192.168.0.40" + ] + } + }, + "steps": [] +} \ No newline at end of file diff --git a/tools/java-oracle/README.md b/tools/java-oracle/README.md index 173192b..9544c76 100644 --- a/tools/java-oracle/README.md +++ b/tools/java-oracle/README.md @@ -222,3 +222,28 @@ Gemessen (30.09.2026, 90 %, RTT 2750 ms), was Swift anders macht: SYN+ACK nie. * Startnummern aus einem Zähler über alle TCP-Sockets (1000000, 2000000, …), wie im Kern; der freie Port ist zufällig. + +## DNS zur Laufzeit + +`DnsRun` ruft auf dem Netz von `dns-lan` den Resolver eines Clients auf, wie +Filius' Programme es tun, und schreibt nach `dns-java-.java.json` die +Frames jeder Karte und das Ergebnis des Aufrufs. `ScenarioNetwork` richtet +dazu die `dnsServers` des Szenarios ein: installiert, Einträge über +`hinzuRecord` in `/dns/hosts` (Zeilen `name TYP ziel`, TTL 3600), +eingeschaltet. Server 192.168.0.10 kennt `web.filius.de`, den Mailserver +von `filius.de` und verweist `schule.de` an 192.168.0.11, der +`www.schule.de` kennt. + +* `address`, `mail`, `referral`, `unknown`: A, MX (samt A des Mailservers), + Verweis per NS, unbekannter Name. +* `noServer`: der DNS-Server des Clients (192.168.0.99) fehlt. + +Gemessen (30.09.2026), Javas Format, das Swift durch ein eigenes ersetzt: +Jede Nachricht ist Text, `ID=… QR=… RCODE=… QDCOUNT=… ANCOUNT=… NSCOUNT=… +ARCOUNT=… ` und dann je Zeile eine Frage `name. TYP IN` oder ein Eintrag +`name. TYP ttl ziel`. Die ID würfelt Java (`Math.random`). Die Antwort +wiederholt die Frage nicht (`QDCOUNT=0`), RCODE ist immer 0, auch für einen +unbekannten Namen (leere Antwort), und ein Verweis steht mit NS und A des +Nameservers im Antwortteil. Der Resolver folgt dem Verweis selbst +(iterativ) und wartet je Anfrage 5 RTT (13750 ms bei 90 %); ohne Server +fragt ARP zweimal im Abstand einer RTT, dann scheitert der Aufruf. diff --git a/tools/java-oracle/run.sh b/tools/java-oracle/run.sh index 1a13d53..3068f16 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" +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" # 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. @@ -130,3 +130,14 @@ for run in exchange:30000 closedPort:30000 lostData:45000; do "$root/packages/core/test/scenarios/tcp-lan.scenario.json" "$story" "${run##*:}" "$output" 2>&1 | grep -v 'logback\|^$' || true test -s "$output" done + +# DNS as Java FILIUS runs it: a resolver's lookup on dns-lan's network +# (DnsRun); frames and the call's result, for the core's DNS comparison. +for run in address:5000 mail:5000 referral:5000 unknown:5000 noServer:22000; do + story="${run%%:*}" + output="$root/packages/core/test/scenarios/dns-java-$story.java.json" + rm -f "$output" + HOME="$here/.build/home" xvfb-run -a java -cp "$classpath:$here/.build" DnsRun \ + "$root/packages/core/test/scenarios/dns-lan.scenario.json" "$story" "${run##*:}" "$output" 2>&1 | grep -v 'logback\|^$' || true + test -s "$output" +done diff --git a/tools/java-oracle/src/DnsRun.java b/tools/java-oracle/src/DnsRun.java new file mode 100644 index 0000000..84611b0 --- /dev/null +++ b/tools/java-oracle/src/DnsRun.java @@ -0,0 +1,86 @@ +// Runs a DNS lookup on dns-lan's network in Java FILIUS (ScenarioNetwork) +// and records what really happens: every frame each card saw, and when the +// resolver's call started and what it returned (or that it failed). +// +// DnsRun +// +// Server 192.168.0.10 knows web.filius.de, filius.de's mail exchange and +// refers schule.de to 192.168.0.11, which knows www.schule.de. The stories, +// each the resolver of a client (Resolver, as FILIUS' programs call it): +// address 192.168.0.20 asks for web.filius.de (A) +// mail 192.168.0.20 asks for filius.de's mail server (MX, then its A) +// referral 192.168.0.20 asks for www.schule.de (A), referred to .11 +// unknown 192.168.0.20 asks for x.unbekannt.org, which no one knows +// noServer 192.168.0.21 asks its DNS server 192.168.0.99, which is not there + +import filius.software.dns.Resolver; + +import java.util.ArrayList; +import java.util.List; + +public class DnsRun { + static final String CLIENT = "00000000-0000-0000-0000-000000000101"; + static final String LOST_CLIENT = "00000000-0000-0000-0000-000000000104"; + + static ScenarioNetwork network; + static final List events = new ArrayList<>(); + + interface Call { + String run() throws Exception; + } + + static void event(String what) { + events.add(new Object[] { System.currentTimeMillis() - network.start, what }); + } + + static void call(String label, Call call) { + event(label + " called"); + try { + event(label + " returned " + call.run()); + } catch (Exception e) { + event(label + " failed " + e.getClass().getSimpleName()); + } + } + + 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); + Resolver client = network.system(CLIENT).holeDNSClient(); + switch (story) { + case "address": + call("holeIPAdresse web.filius.de", () -> client.holeIPAdresse("web.filius.de")); + break; + case "mail": + call("holeIPAdresseMailServer filius.de", () -> client.holeIPAdresseMailServer("filius.de")); + break; + case "referral": + call("holeIPAdresse www.schule.de", () -> client.holeIPAdresse("www.schule.de")); + break; + case "unknown": + call("holeIPAdresse x.unbekannt.org", () -> client.holeIPAdresse("x.unbekannt.org")); + break; + case "noServer": + Resolver lost = network.system(LOST_CLIENT).holeDNSClient(); + call("holeIPAdresse web.filius.de", () -> lost.holeIPAdresse("web.filius.de")); + break; + default: + throw new IllegalArgumentException("unknown story " + story); + } + long rest = network.start + end - System.currentTimeMillis(); + if (rest > 0) Thread.sleep(rest); + + ScenarioNetwork.Json out = new ScenarioNetwork.Json(); + out.open('{'); + network.writeFrames(out); + out.key("events").open('['); + for (Object[] each : events) out.open('[').number((Long) each[0]).string((String) each[1]).close(']'); + 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 46b27be..cea3126 100644 --- a/tools/java-oracle/src/ScenarioNetwork.java +++ b/tools/java-oracle/src/ScenarioNetwork.java @@ -18,6 +18,7 @@ import filius.hardware.knoten.Rechner; import filius.hardware.knoten.Switch; import filius.rahmenprogramm.nachrichten.Lauscher; import filius.software.dhcp.DHCPServer; +import filius.software.dns.DNSServer; import filius.software.netzzugangsschicht.EthernetFrame; import filius.software.system.InternetKnotenBetriebssystem; import filius.software.transportschicht.Segment; @@ -121,6 +122,21 @@ public class ScenarioNetwork { server.setAktiv(Boolean.TRUE.equals(config.get("active"))); servers.add(entry.getKey()); } + // A DNS server: installed, its records written to /dns/hosts (TTL 3600), switched on. + for (Map.Entry entry : map(scenario.getOrDefault("dnsServers", new HashMap<>())).entrySet()) { + Map config = map(entry.getValue()); + InternetKnotenBetriebssystem os = system(nodes.get(entry.getKey())); + DNSServer dns = new DNSServer(); + dns.setSystemSoftware(os); + os.getInstallierteAnwendungen().put("filius.software.dns.DNSServer", dns); + for (Object line : list(config.getOrDefault("records", new ArrayList<>()))) { + String[] parts = ((String) line).split(" "); + dns.hinzuRecord(parts[0], parts[1], parts[2]); + } + dns.setRecursiveResolutionEnabled(Boolean.TRUE.equals(config.get("recursive"))); + dns.setAktiv(true); + servers.add(entry.getKey()); + } for (Object each : list(scenario.getOrDefault("dhcpClients", new ArrayList<>()))) { system(nodes.get((String) each)).setDHCPKonfiguration(true); }