From 7a77bc1b43d6ca2644445f54c53dbc30a1c0fd34 Mon Sep 17 00:00:00 2001 From: Julian Kiedaisch Date: Wed, 30 Sep 2026 20:06:04 +0000 Subject: [PATCH] feat(core): home router NAT after Java, measured with Java FILIUS The core translates before the IP thread, as Java's NAT threads sit between card and Ethernet: out, the WAN address and the entry's port (ICMP keeps its identifier); in, by remote end, port and protocol, else by the port forwarding, which then makes a dynamic entry; a ping at the WAN address is answered by the router, packets from outside for the LAN are dropped, both sides pass the router's firewall, TTL 1 going out gets time exceeded. Dynamic entries expire at Java's check each second, 300 s times the delay factor old (55 minutes at 90 %), refreshed only by what comes in. The home router forwards as a router does. Measured and not taken: when a LAN endpoint sends to a second remote end, Java gives it the entry's WAN port but no entry, and the answer stays at the router; the core adds an entry for each new remote end on that port. The oracle now records every card of a node (the second card of routers was missing); the ARP and RIP runs are recorded anew and still match. Co-Authored-By: Claude Opus 5.5 --- CHANGES.md | 3 +- packages/core/src/runtime/engine.ts | 342 +++++++++- packages/core/src/runtime/snapshot.ts | 5 + packages/core/test/engine.test.ts | 238 +++++++ packages/core/test/natJava.test.ts | 257 +++++++ packages/core/test/scenario.ts | 8 + .../test/scenarios/arp-java-pingLan.java.json | 13 +- .../scenarios/arp-java-pingRouted.java.json | 44 +- .../arp-java-routedPingBehindPing.java.json | 68 +- .../arp-java-routedPingBesideUdp.java.json | 140 +++- .../arp-java-routedUdpBehind.java.json | 95 ++- .../scenarios/arp-java-udpBehind.java.json | 71 +- .../scenarios/arp-java-udpTwice.java.json | 13 +- .../test/scenarios/nat-java-forward.java.json | 632 +++++++++++------- .../test/scenarios/nat-java-pingOut.java.json | 68 +- .../test/scenarios/nat-java-pingWan.java.json | 29 +- .../test/scenarios/nat-java-tcpOut.java.json | 586 ++++++++++------ .../test/scenarios/nat-java-udpOut.java.json | 90 ++- .../nat-java-udpTwoRemotes.java.json | 135 ++-- .../scenarios/rip-java-converge.java.json | 470 +++++++++++-- .../test/scenarios/rip-java-expire.java.json | 347 +++++++++- tools/java-oracle/README.md | 6 + tools/java-oracle/src/ScenarioNetwork.java | 3 +- 23 files changed, 2915 insertions(+), 748 deletions(-) create mode 100644 packages/core/test/natJava.test.ts diff --git a/CHANGES.md b/CHANGES.md index 7e64cec..81cb9a9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,7 +13,7 @@ Swift-Pfade relativ zu `filius-ipad/ios/FiliusPad/TopologyEditor/` (Stand | `src/model/link.ts`, `src/model/graph.ts` | `Model/TopologyLink.swift`, `Model/TopologyGraph.swift` | übertragen, bisher nur die Daten (Abfragen folgen mit dem Editor) | | `src/model/documentation.ts` | `Model/TopologyDocumentation.swift` | übertragen; FNV-Kennung mit BigInt, gegen die IDs aus dem Swift-Import geprüft | | `src/runtime/config.ts` | `State/TopologyEditorState.swift` (Laufzeit-Konfigurationen, WLAN eines Rechners, DHCP, Portweiterleitung, Remote Link ohne LAN-Transport, Programme und ihre Konfiguration, Firewall, DNS-Einträge aus `State/TopologyDNSResolver.swift`, E-Mail-Konten und -Nachrichten aus `State/TopologyEmail.swift`); dazu Echo-Server- und Client-Konfiguration, die Swift nicht speichert | übertragen; Java-Beschriftungen der Oberfläche weggelassen | -| `src/runtime/engine.ts` | `State/TopologyNetworkRuntimeEngine.swift` Z. ~313–3585, ~4472–5187 (UDP), ~4753–4850 | übertragen: Warteschlange, Uhr, Ethernet, Switch, ARP, IPv4, ICMP, Routing, Firewall, UDP-Sockets (binden, freie Ports nach Javas Zufall, senden samt Broadcast, zustellen, empfangen mit Wartezeit, schließen), TCP (Z. ~5187–5913: Server- und Client-Sockets, Handschlag mit Ergebnis, Segmente zu 1460 Byte bis zum PSH, höchstens drei Versuche, Abbau über alle Java-Zustände samt `TIME_WAIT`; seit F2.3c nach Javas `TCPSocket` an Java-Filius gemessen: je Versuch und für `TIME_WAIT` 3 RTT nach der Geschwindigkeit (8250 ms bei 90 %, Swift fest 7500 bzw. 2500 ms), der Zeitablauf zählt ab der Übergabe des Segments, vor ARP; ein Segment beendet `TIME_WAIT`; die Gegenseite schließt beim FIN von selbst; nicht bestätigte Daten schließen mit FIN statt sofort; der angenommene Socket hat die Startnummer des Listeners, der Listener eine neue. seit F2.3e wie Java: SYN+ACK und FIN gehen nie ein zweites Mal hinaus; der Server gibt einen Handschlag nach 3 RTT auf und schließt mit FIN; nach dem FIN wartet ein Socket höchstens fünfmal 3 RTT, jedes Segment beendet eine Wartezeit, dann CLOSED (Java lässt den Zustand stehen). Abweichend von Java: drei SYN statt einem, weil Javas Wiederholungsschleife nach dem ersten Zeitablauf abbricht, und ein wiederholtes SYN in `SYN_RCVD` bekommt das SYN+ACK noch einmal, statt den Socket zu schließen), DHCP (Z. ~5913–6694: Server mit festen Zuordnungen, Adressbereich, Angeboten, Leases und Sperrliste; Client seit F2.3b nach Javas `DHCPClient` neu gebaut und an Java-Filius gemessen: je Versuch eine Nachricht, eine Antwort, die nicht passt, wird gelesen und verworfen; die ARP-Prüfung wartet eine RTT, eine Antwort für die Adresse beendet sie sofort, dann DECLINE; nach einem Zeitablauf wiederholt der Zustand seine Nachricht, nach dem fünften nimmt der Client eine Link-Local-Adresse `169.254.1.x/16` (ARP-Probe, ARP-Reply an alle) und gibt keine alte Adresse zurück; Swift sendete doppelt, wartete nicht auf ARP und kehrte nach zehn Versuchen zur alten Adresse zurück. Abweichend von Java: Nach fünf belegten Link-Local-Adressen gibt der Client auf (Java sucht endlos), und ein ARP-Paket für eine andere Adresse beendet die Prüfung nicht. Seit F2.3d befördert ein Kabel einen Frame nach dem anderen wie Javas `SimplexVerbindung` (ein Frame wartet im Ausgangspuffer, bis der vorige angekommen ist, und erscheint im Protokoll, wenn er losgeht); Swift schickt alle zugleich, die Option `swiftCables` behält das für den Swift-Vergleich. Die RTT der DHCP-Zeiten (Warten, Angebote, Sperrliste) folgt wie in Java der Geschwindigkeit (50 Kabel, 2750 ms bei 90 %); Swift rechnet fest mit 2500 ms. ARP seit F2.4b nach Javas `holeARPTabellenEintrag`, an Java-Filius gemessen: eine Auflösung fragt, wartet eine RTT, fragt ein zweites Mal und gibt nach einer weiteren RTT auf; dann „Host unreachable" beim Absender selbst oder vom Router zurück (bei ICMP nur für Echo-Anfragen); ein wartender Absender wacht nach den übrigen Ereignissen desselben Zeitpunkts auf; der Ping wartet danach eine RTT auf die Antwort. Swift schickt in der Ereignisverarbeitung beide Anfragen zugleich und lässt das Paket ohne Ende warten, wenn die Adresse irgendwo im Netz vorkommt (Wissen, das kein Knoten hat), und blockiert direkte Aufrufe ohne Wartezeit; die Option `swiftArp` behält das für den Swift-Vergleich. Seit F2.4b-2 kehrt ein Senden wie in Java sofort zurück, die Frames reisen, während die Uhr läuft (Swift: der Aufruf kehrt erst zurück, wenn alle Frames angekommen sind; die Option `swiftSends` behält das für den Swift-Vergleich), und UDP und TCP senden über Javas Transport-Thread je Knoten und Protokoll: ein Segment nach dem anderen; solange IP auf ARP wartet, blockiert das nächste `senden`. Wartende Absender kommen in der Reihenfolge an die Reihe, in der sie kamen (Javas Sperre überlässt das dem Zufall). Seit F2.4b-3 geht jedes ankommende Paket wie in Java durch den IP-Thread (UDP, TCP) oder den ICMP-Thread (ICMP) seines Knotens: zustellen, Echo-Reply, weiterleiten, eins nach dem anderen; solange ARP wartet, warten die folgenden. Abweichend von Java weckt eine ARP-Antwort alle, die auf die Adresse warten (Javas `notify` weckt einen beliebigen). DNS seit F2.4a nach Javas `DNSServer`/`Resolver`, an Java-Filius gemessen: Server auf Port 53 mit Einträgen aus dem Modell (die Antwort wiederholt die Frage nicht, RCODE immer 0, ein Verweis mit NS und A im Antwortteil), iterativer Resolver mit 5 RTT je Anfrage, der nur die Server behält, an die er verwiesen wurde; seit F2.4c auf den Ereignissen statt blockierend und mit rekursivem Server nach `DNSServer.answerWithRemoteData` (Nameserver der Zone, dann der eigene DNS-Server, sonst Verweis), abweichend von Java fragt er sich nie selbst (Java endlos). RIP seit F2.5a (Z. ~4700–5090) nach Javas `filius.software.rip`, seit F2.5b an Java-Filius gemessen (die Pause in Javas `float`-Rechnung): eine Route mit 0 Hops je eigenem Netz, die nie verfällt; der erste Beacon nach einer Sekunde, dann alle 25,2–35,2 s aus einem Zufall je Router (Java: ein ungesetzter `Random` je Router; der Kern setzt ihn aus Szenario und Router-ID, `ripSeed`; Swift: ein Zufall für alle); eine Nachricht je Schnittstelle ohne die Routen über sie (Split Horizon); eine neue Route oder mehr Hops vom selben Router senden sofort; eine gelernte Route wird erst beim nächsten eigenen Beacon auf 16 gesetzt, wenn sie verfallen ist (Swift: bei jedem Ereignis); Nachrichten von jedem Quellport (Swift: nur 521); ein RIP-Router leitet nur nach seiner Tabelle weiter, wenige Hops vor langer Maske. `receiveUdp` kehrt wie Javas `empfangen` zurück, sobald ein Datagramm da ist. Klasse statt Werttyp. Noch nicht übertragen (wirft `NotPortedError`): Gateway-NAT, Remote Link, WLAN | +| `src/runtime/engine.ts` | `State/TopologyNetworkRuntimeEngine.swift` Z. ~313–3585, ~4472–5187 (UDP), ~4753–4850 | übertragen: Warteschlange, Uhr, Ethernet, Switch, ARP, IPv4, ICMP, Routing, Firewall, UDP-Sockets (binden, freie Ports nach Javas Zufall, senden samt Broadcast, zustellen, empfangen mit Wartezeit, schließen), TCP (Z. ~5187–5913: Server- und Client-Sockets, Handschlag mit Ergebnis, Segmente zu 1460 Byte bis zum PSH, höchstens drei Versuche, Abbau über alle Java-Zustände samt `TIME_WAIT`; seit F2.3c nach Javas `TCPSocket` an Java-Filius gemessen: je Versuch und für `TIME_WAIT` 3 RTT nach der Geschwindigkeit (8250 ms bei 90 %, Swift fest 7500 bzw. 2500 ms), der Zeitablauf zählt ab der Übergabe des Segments, vor ARP; ein Segment beendet `TIME_WAIT`; die Gegenseite schließt beim FIN von selbst; nicht bestätigte Daten schließen mit FIN statt sofort; der angenommene Socket hat die Startnummer des Listeners, der Listener eine neue. seit F2.3e wie Java: SYN+ACK und FIN gehen nie ein zweites Mal hinaus; der Server gibt einen Handschlag nach 3 RTT auf und schließt mit FIN; nach dem FIN wartet ein Socket höchstens fünfmal 3 RTT, jedes Segment beendet eine Wartezeit, dann CLOSED (Java lässt den Zustand stehen). Abweichend von Java: drei SYN statt einem, weil Javas Wiederholungsschleife nach dem ersten Zeitablauf abbricht, und ein wiederholtes SYN in `SYN_RCVD` bekommt das SYN+ACK noch einmal, statt den Socket zu schließen), DHCP (Z. ~5913–6694: Server mit festen Zuordnungen, Adressbereich, Angeboten, Leases und Sperrliste; Client seit F2.3b nach Javas `DHCPClient` neu gebaut und an Java-Filius gemessen: je Versuch eine Nachricht, eine Antwort, die nicht passt, wird gelesen und verworfen; die ARP-Prüfung wartet eine RTT, eine Antwort für die Adresse beendet sie sofort, dann DECLINE; nach einem Zeitablauf wiederholt der Zustand seine Nachricht, nach dem fünften nimmt der Client eine Link-Local-Adresse `169.254.1.x/16` (ARP-Probe, ARP-Reply an alle) und gibt keine alte Adresse zurück; Swift sendete doppelt, wartete nicht auf ARP und kehrte nach zehn Versuchen zur alten Adresse zurück. Abweichend von Java: Nach fünf belegten Link-Local-Adressen gibt der Client auf (Java sucht endlos), und ein ARP-Paket für eine andere Adresse beendet die Prüfung nicht. Seit F2.3d befördert ein Kabel einen Frame nach dem anderen wie Javas `SimplexVerbindung` (ein Frame wartet im Ausgangspuffer, bis der vorige angekommen ist, und erscheint im Protokoll, wenn er losgeht); Swift schickt alle zugleich, die Option `swiftCables` behält das für den Swift-Vergleich. Die RTT der DHCP-Zeiten (Warten, Angebote, Sperrliste) folgt wie in Java der Geschwindigkeit (50 Kabel, 2750 ms bei 90 %); Swift rechnet fest mit 2500 ms. ARP seit F2.4b nach Javas `holeARPTabellenEintrag`, an Java-Filius gemessen: eine Auflösung fragt, wartet eine RTT, fragt ein zweites Mal und gibt nach einer weiteren RTT auf; dann „Host unreachable" beim Absender selbst oder vom Router zurück (bei ICMP nur für Echo-Anfragen); ein wartender Absender wacht nach den übrigen Ereignissen desselben Zeitpunkts auf; der Ping wartet danach eine RTT auf die Antwort. Swift schickt in der Ereignisverarbeitung beide Anfragen zugleich und lässt das Paket ohne Ende warten, wenn die Adresse irgendwo im Netz vorkommt (Wissen, das kein Knoten hat), und blockiert direkte Aufrufe ohne Wartezeit; die Option `swiftArp` behält das für den Swift-Vergleich. Seit F2.4b-2 kehrt ein Senden wie in Java sofort zurück, die Frames reisen, während die Uhr läuft (Swift: der Aufruf kehrt erst zurück, wenn alle Frames angekommen sind; die Option `swiftSends` behält das für den Swift-Vergleich), und UDP und TCP senden über Javas Transport-Thread je Knoten und Protokoll: ein Segment nach dem anderen; solange IP auf ARP wartet, blockiert das nächste `senden`. Wartende Absender kommen in der Reihenfolge an die Reihe, in der sie kamen (Javas Sperre überlässt das dem Zufall). Seit F2.4b-3 geht jedes ankommende Paket wie in Java durch den IP-Thread (UDP, TCP) oder den ICMP-Thread (ICMP) seines Knotens: zustellen, Echo-Reply, weiterleiten, eins nach dem anderen; solange ARP wartet, warten die folgenden. Abweichend von Java weckt eine ARP-Antwort alle, die auf die Adresse warten (Javas `notify` weckt einen beliebigen). DNS seit F2.4a nach Javas `DNSServer`/`Resolver`, an Java-Filius gemessen: Server auf Port 53 mit Einträgen aus dem Modell (die Antwort wiederholt die Frage nicht, RCODE immer 0, ein Verweis mit NS und A im Antwortteil), iterativer Resolver mit 5 RTT je Anfrage, der nur die Server behält, an die er verwiesen wurde; seit F2.4c auf den Ereignissen statt blockierend und mit rekursivem Server nach `DNSServer.answerWithRemoteData` (Nameserver der Zone, dann der eigene DNS-Server, sonst Verweis), abweichend von Java fragt er sich nie selbst (Java endlos). Gateway-NAT seit F2.6 (Z. ~3585–3900) nach Javas `filius.software.nat`, an Java-Filius gemessen: die Übersetzung vor dem IP-Thread (wie Javas NAT-Threads zwischen Karte und Ethernet), ausgehend WAN-Adresse und der Port des Eintrags (ICMP behält die Kennung), eingehend nach Gegenstelle, Port und Protokoll, sonst nach der Portweiterleitung (legt einen dynamischen Eintrag an), ein Ping an die WAN-Adresse beantwortet der Heimrouter, Pakete von außen an das LAN verschwinden, beide Seiten durch die Firewall des Heimrouters, ausgehend TTL 1 bekommt „Zeit überschritten“; dynamische Einträge verfallen nach 300 s mal Javas Verzögerungsfaktor (Swift fest 300 s) bei Javas sekündlicher Prüfung, aufgefrischt nur eingehend; der Heimrouter leitet weiter wie ein Router. Abweichend von Java: ein LAN-Endpunkt bekommt für jede neue Gegenstelle einen Eintrag auf demselben WAN-Port (Java behält nur den für die erste, die Antworten weiterer bleiben am Heimrouter hängen). RIP seit F2.5a (Z. ~4700–5090) nach Javas `filius.software.rip`, seit F2.5b an Java-Filius gemessen (die Pause in Javas `float`-Rechnung): eine Route mit 0 Hops je eigenem Netz, die nie verfällt; der erste Beacon nach einer Sekunde, dann alle 25,2–35,2 s aus einem Zufall je Router (Java: ein ungesetzter `Random` je Router; der Kern setzt ihn aus Szenario und Router-ID, `ripSeed`; Swift: ein Zufall für alle); eine Nachricht je Schnittstelle ohne die Routen über sie (Split Horizon); eine neue Route oder mehr Hops vom selben Router senden sofort; eine gelernte Route wird erst beim nächsten eigenen Beacon auf 16 gesetzt, wenn sie verfallen ist (Swift: bei jedem Ereignis); Nachrichten von jedem Quellport (Swift: nur 521); ein RIP-Router leitet nur nach seiner Tabelle weiter, wenige Hops vor langer Maske. `receiveUdp` kehrt wie Javas `empfangen` zurück, sobald ein Datagramm da ist. Klasse statt Werttyp. Noch nicht übertragen (wirft `NotPortedError`): Remote Link, WLAN | | `src/runtime/dns.ts` | Java `filius.software.dns.DNSNachricht`, `Query`, `ResourceRecord` | neu nach Java statt nach Swift (Swift ersetzt Javas Textnachrichten durch `FILIUS-DNS-TYPED/1`): Kopfzeile `ID=… QR=… RCODE=… QDCOUNT=… …`, Frage- und Eintragszeilen, Suche nach Namen ohne Rücksicht auf Groß- und Kleinschreibung, NS der längsten Zone, sonst der Wurzel | | `src/runtime/ipv4.ts` | Engine `parseIPv4`/`sameSubnet` | übertragen | | `src/runtime/packets.ts` | Engine, Paketmodelle | übertragen; `Data` → `Uint8Array` | @@ -31,6 +31,7 @@ Swift-Pfade relativ zu `filius-ipad/ios/FiliusPad/TopologyEditor/` (Stand | `test/oracle.test.ts`, `test/scenarios/` | — | neu: 14 Szenarien (davon 2 UDP, 3 TCP, 4 DHCP), Ergebnis mit dem Swift-Kern abgeglichen (`tools/swift-oracle`); Schritte für UDP, TCP und DHCP; die vier DHCP-Szenarien folgen seit F2.3b Java, die drei TCP-Szenarien seit F2.3c; sie müssen von Swift abweichen; drei weitere (`firewall-and-loss`, `routed-two-networks`, `switch-lan`) folgen seit F2.4b ab der Spur, an der ARP scheitert oder ein Ping unbeantwortet bleibt, Java und stimmen bis dahin mit Swift | | `test/dhcpJava.test.ts`, `test/scenarios/*.java.json`, `test/scenario.ts`, `test/javaRun.ts` | — | neu: die DHCP-Szenarien gegen Java-Filius (`tools/java-oracle`, `DhcpRun`): je Client dieselben Frames in derselben Reihenfolge, Abstände auf 200 ms, dieselben Adressen am Ende | | `test/arpJava.test.ts`, `test/scenarios/arp-routed.scenario.json`, `test/scenarios/arp-java-*.java.json` | — | neu: vier ARP-Abläufe gegen Java-Filius (`ArpRun`): Frames, Abstände und wann jeder Aufruf zurückkehrt; die zwei Pings stimmen seit F2.4b-1, die zwei UDP-Abläufe seit F2.4b-2 (Javas Transport-Thread), drei Abläufe durch den Router seit F2.4b-3 (IP- und ICMP-Thread) | +| `test/natJava.test.ts`, `test/scenarios/nat-home.scenario.json`, `test/scenarios/nat-java-*.java.json` | — | neu: sechs NAT-Abläufe gegen Java-Filius (`NatRun`): je Absenderkarte dieselben Frames in derselben Folge zur selben Zeit, dieselben Aufrufe, dieselbe NAT-Tabelle; freie Ports und TCP-Startnummern als Platzhalter; ein benannter Java-Fehler (`JAVA_BUGS`: die Antwort der zweiten Gegenstelle) | | `test/ripJava.test.ts`, `test/scenarios/rip-chain.scenario.json`, `test/scenarios/rip-java-*.java.json` | — | neu: zwei RIP-Abläufe gegen Java-Filius (`RipRun`, der Zufall jedes Routers auf `ripSeed` gesetzt): je Absenderkarte dieselben Nachrichten zur selben Zeit, jede Tabelle durch dieselben Zustände, derselbe Ping; die ersten 5 s (Javas gestaffelter Start) nur über den erreichten Zustand | | `test/dnsJava.test.ts`, `test/scenarios/dns-lan.scenario.json`, `test/scenarios/dns-java-*.java.json` | — | neu: fünf DNS-Abfragen gegen Java-Filius (`DnsRun`): Frames, Ergebnis und Dauer; seit F2.4b-1 alle wie Java; seit F2.4c dazu fünf mit rekursivem Server (`dns-recursive.scenario.json`, `dns-recursive-java-*.java.json`), einer nur bis zur Anfrage des Clients verglichen (`JAVA_UNTIL`: Javas Server fragt sich selbst ohne Ende) | | `test/tcpJava.test.ts`, `test/scenarios/tcp-java-*.java.json` | — | neu: sechs TCP-Abläufe gegen Java-Filius (`TcpRun`, drei davon mit genau einem verlorenen Frame, `loseFirst`): Frames mit Flags und Nummern, Socket-Zustände; benannte Java-Fehler (`JAVA_BUGS`: nur ein SYN, der Zustand bleibt nach dem Schließen stehen), `lostSynAck` nur bis zum zweiten SYN verglichen (`JAVA_UNTIL`) | diff --git a/packages/core/src/runtime/engine.ts b/packages/core/src/runtime/engine.ts index 70ec240..9863ed6 100644 --- a/packages/core/src/runtime/engine.ts +++ b/packages/core/src/runtime/engine.ts @@ -17,6 +17,9 @@ // one message per attempt, an ARP check that waits a round trip, // link-local after five failures; round trip times follow the speed) // processScheduledRuntimeEvent, dropForGlobalPacketLoss (lines ~4753–4850) +// "Gateway NAT/PAT" (lines ~3585–3900; after Java's filius.software.nat, +// measured with Java FILIUS: one entry per LAN endpoint, the expiry of +// Java's GatewayFirmware.checkNAT) // A cable carries one frame after the other, as Java's SimplexVerbindung // (Swift: all at once; the option swiftCables keeps that for the comparison). // ARP after Java's holeARPTabellenEintrag: a lookup asks twice, a round trip @@ -43,7 +46,7 @@ // advance the virtual clock inside the call, exactly as the Swift port does. // // Not ported yet — each place throws NotPortedError instead of guessing: -// gateway NAT, remote links. +// remote links. import { compareIds, type Id } from '../ids.js'; import { isPcClassEndpoint, stableGeneratedMacAddress } from '../model/node.js'; @@ -51,6 +54,7 @@ import type { DeviceConfiguration, DhcpServerConfiguration, FirewallConfiguration, + GatewayPortForwardingRow, FirewallRule, InterfaceConfiguration, InterfaceKey, @@ -172,8 +176,7 @@ export type ScheduledEventKind = readonly pairIdentifier: string; readonly latencyMilliseconds: number; readonly frame: EthernetFrame; - } - | { readonly kind: 'natExpirySweep' }; + }; export interface ScheduledEvent { readonly id: number; @@ -456,6 +459,117 @@ export const RIP_INFINITY = 16; export const RIP_TIMEOUT_MILLISECONDS = 75_000; export const RIP_FIRST_BEACON_DELAY_MILLISECONDS = 1_000; +/** GatewayFirmware.retentionTime: a dynamic NAT entry lasts 300 s, times Java's delay factor. */ +export const NAT_RETENTION_MILLISECONDS = 300_000; + +export type NatProtocol = 'tcp' | 'udp' | 'icmp'; + +export interface NatEndpoint { + readonly ipAddress: string; + /** A port; for ICMP, the identifier. */ + readonly port: number; +} + +/** + * An entry of a home router's NAT table (Java NatEntry under its + * PortProtocolPair): the WAN port and the remote end (empty for a static + * entry of the port forwarding) lead to the LAN endpoint. + */ +export interface NatEntry { + readonly protocol: NatProtocol; + readonly remoteIPAddress: string; + readonly port: number; + readonly lan: NatEndpoint; + /** Java NatType: StaticEntry, DynamicEntry, DynamicEnryFromStatic. */ + readonly type: 'static' | 'dynamic' | 'dynamicFromStatic'; + readonly updatedAtMilliseconds: number; +} + +/** + * A port forwarding row as Java's GatewayFirmware.validateData takes it: + * TCP or UDP in any case, or 6 or 17; ports 1…65535 without leading zeros; + * an IPv4 address (EingabenUeberpruefung). + */ +function parsePortForwardingRow( + row: GatewayPortForwardingRow, +): { protocol: 'tcp' | 'udp'; publicPort: number; lanIPAddress: string; lanPort: number } | undefined { + const protocolValue = row.protocolValue.toUpperCase(); + const protocol = protocolValue === 'TCP' || protocolValue === '6' ? 'tcp' : protocolValue === 'UDP' || protocolValue === '17' ? 'udp' : undefined; + const port = (value: string) => (/^[1-9][0-9]{0,4}$/.test(value) && Number(value) <= 65_535 ? Number(value) : undefined); + const address = + /^(0*([1-9]?[0-9]?|1[0-9]{1,2}|2[0-4]?[0-9]|25[0-5]))\.((0*(1?[0-9]{1,2}|2[0-4]?[0-9]|25[0-5]))\.){2}(0*(1?[0-9]{1,2}|2[0-4]?[0-9]|25[0-5]))$/; + const publicPort = port(row.publicPortValue); + const lanPort = port(row.lanPortValue); + if (protocol === undefined || publicPort === undefined || lanPort === undefined || !address.test(row.lanIPAddress)) return undefined; + return { protocol, publicPort, lanIPAddress: row.lanIPAddress, lanPort }; +} + +/** The endpoint a packet from the LAN leaves from, and whether it opens an entry (a TCP SYN, any UDP datagram, any ICMP packet). */ +function natOutboundEndpoint(packet: IPv4Packet): { protocol: NatProtocol; port: number; opens: boolean } { + const payload = packet.payload; + switch (payload.kind) { + case 'tcp': { + const flags = payload.segment.flags; + return { protocol: 'tcp', port: payload.segment.sourcePort, opens: (flags & TCP_FLAG.synchronize) !== 0 && (flags & TCP_FLAG.acknowledgement) === 0 }; + } + case 'udp': + return { protocol: 'udp', port: payload.datagram.sourcePort, opens: true }; + case 'icmp': + return { protocol: 'icmp', port: payload.message.identifier, opens: true }; + } +} + +/** + * NatGateway.replaceDestination's key: the remote end, the WAN port and the + * protocol; for an ICMP error, those of the packet it carries (whose + * receiver was the remote end and whose source port, or identifier, the WAN + * port); for other ICMP, the sender and the identifier. + */ +function natInboundLookup(packet: IPv4Packet): { remoteIPAddress: string; port: number; protocol: NatProtocol } | undefined { + const payload = packet.payload; + switch (payload.kind) { + case 'tcp': + return { remoteIPAddress: packet.senderIPAddress, port: payload.segment.destinationPort, protocol: 'tcp' }; + case 'udp': + return { remoteIPAddress: packet.senderIPAddress, port: payload.datagram.destinationPort, protocol: 'udp' }; + case 'icmp': { + const embedded = payload.message.embeddedOriginalPacket; + if (embedded === undefined) return { remoteIPAddress: packet.senderIPAddress, port: payload.message.identifier, protocol: 'icmp' }; + const inner = embedded.payload; + const port = inner.kind === 'icmp' ? inner.message.identifier : inner.kind === 'tcp' ? inner.segment.sourcePort : inner.datagram.sourcePort; + return { remoteIPAddress: embedded.receiverIPAddress, port, protocol: inner.kind }; + } + } +} + +/** NatGateway.replaceSource: the WAN address; TCP and UDP the entry's port (ICMP keeps its identifier). */ +function natWithSource(packet: IPv4Packet, ipAddress: string, port: number | undefined): IPv4Packet { + const payload = packet.payload; + if (port === undefined || payload.kind === 'icmp') return { ...packet, senderIPAddress: ipAddress }; + return payload.kind === 'tcp' + ? { ...packet, senderIPAddress: ipAddress, payload: { kind: 'tcp', segment: { ...payload.segment, sourcePort: port } } } + : { ...packet, senderIPAddress: ipAddress, payload: { kind: 'udp', datagram: { ...payload.datagram, sourcePort: port } } }; +} + +/** NatGateway.replaceDestination: the LAN endpoint's address; TCP and UDP its port. */ +function natWithDestination(packet: IPv4Packet, endpoint: NatEndpoint): IPv4Packet { + const payload = packet.payload; + if (payload.kind === 'icmp') return { ...packet, receiverIPAddress: endpoint.ipAddress }; + return payload.kind === 'tcp' + ? { ...packet, receiverIPAddress: endpoint.ipAddress, payload: { kind: 'tcp', segment: { ...payload.segment, destinationPort: endpoint.port } } } + : { ...packet, receiverIPAddress: endpoint.ipAddress, payload: { kind: 'udp', datagram: { ...payload.datagram, destinationPort: endpoint.port } } }; +} + +/** VermittlungsProtokoll.isBroadcast: the limited broadcast, or the broadcast address of the sender's network. */ +function isBroadcastFrom(receiverIPAddress: string, senderIPAddress: string, subnetMask: string): boolean { + if (receiverIPAddress === LIMITED_BROADCAST_IP_ADDRESS) return true; + const receiver = parseIPv4(receiverIPAddress); + const sender = parseIPv4(senderIPAddress); + const mask = parseIPv4(subnetMask); + if (receiver === undefined || sender === undefined || mask === undefined) return false; + return maskAddress(receiver, mask) === maskAddress(sender, mask) && (receiver | mask) >>> 0 === 0xffff_ffff; +} + /** RIPMessage: the sender's interface address, its first address, infinity, the timeout, its routes. */ interface RipMessage { readonly ipAddress: string; @@ -564,6 +678,8 @@ export interface RuntimeState { dnsServerSocketIdsByNodeId: Map; /** Each RIP router's table (RIPTable.routes): its networks, then what it learned. */ ripTablesByNodeId: Map; + /** Each home router's NAT table (Java NetworkAddressTranslationTable): static and dynamic entries. */ + natTablesByNodeId: Map; dhcpClientStatusesByNodeId: Map; dhcpClientContextsByNodeId: Map; nextSocketSequenceNumber: number; @@ -603,6 +719,7 @@ function initialState(seed: bigint): RuntimeState { dhcpServerSocketIdsByNodeId: new Map(), dnsServerSocketIdsByNodeId: new Map(), ripTablesByNodeId: new Map(), + natTablesByNodeId: new Map(), dhcpClientStatusesByNodeId: new Map(), dhcpClientContextsByNodeId: new Map(), nextSocketSequenceNumber: 1, @@ -713,6 +830,8 @@ export class NetworkRuntimeEngine { private nextArpLookupId = 1; /** Per RIP router: its random for the beacon's pauses and its sockets (RIPBeacon, RIPServer). */ private ripRoutersByNodeId = new Map(); + /** When the NAT tables started: Java's expiry timer ticks every second from then. */ + private natStartedAtMilliseconds = 0; /** DNS queries waiting for their answer, by the socket they were sent from. */ private dnsQueriesBySocketId = new Map void>(); /** Per node and kind (`nodeId/udp`, `nodeId/icmp`, …). */ @@ -819,6 +938,7 @@ export class NetworkRuntimeEngine { state.dnsServerSocketIdsByNodeId.clear(); state.ripTablesByNodeId.clear(); this.ripRoutersByNodeId.clear(); + state.natTablesByNodeId.clear(); state.firewallDecisions = []; return [this.output({ type: 'stopped' })]; } @@ -1008,8 +1128,6 @@ export class NetworkRuntimeEngine { case 'remoteLinkDelivery': case 'lanRemoteLinkTransmission': throw new NotPortedError('remote links'); - case 'natExpirySweep': - throw new NotPortedError('gateway NAT'); } } @@ -1080,7 +1198,7 @@ export class NetworkRuntimeEngine { } private isUdpPortReserved(nodeId: Id, port: number): boolean { - // Swift also counts a gateway's NAT mappings; gateways do not run here yet. + if (this.isNatPort(nodeId, 'udp', port)) return true; for (const socket of this.stateValue.socketsById.values()) { if (socket.nodeId === nodeId && socket.protocol === 'udp' && socket.localPort === port) return true; } @@ -1643,6 +1761,7 @@ export class NetworkRuntimeEngine { /** A port held by an open (not closed) TCP socket that is no listener's child. */ isTcpPortReserved(nodeId: Id, port: number): boolean { + if (this.isNatPort(nodeId, 'tcp', port)) return true; for (const socket of this.stateValue.socketsById.values()) { if ( socket.nodeId === nodeId && @@ -3177,13 +3296,208 @@ export class NetworkRuntimeEngine { this.stateValue.topologySnapshot = withSnapshot(this.stateValue.topologySnapshot, { deviceConfigurations, interfaceConfigurations }); } + /** + * Java's GatewayFirmware.starten: each home router's port forwarding + * becomes its static entries (rows Java's input check rejects are left + * out). Dynamic entries expire as Java's timer finds them, checked every + * second from the start (natEntryExpired). + */ private initializeNatState(): void { - // Gateway NAT (F2): schedules the expiry sweep when a gateway exists. - if (this.stateValue.topologySnapshot.nodes.some((node) => node.kind === 'gateway')) { - throw new NotPortedError('gateway NAT'); + const state = this.stateValue; + state.natTablesByNodeId.clear(); + this.natStartedAtMilliseconds = state.currentTimeMilliseconds; + for (const node of state.topologySnapshot.nodes) { + if (node.kind !== 'gateway') continue; + const entries: NatEntry[] = []; + for (const row of state.topologySnapshot.portForwardingRowsByNodeId.get(node.id) ?? []) { + const forwarding = parsePortForwardingRow(row); + if (forwarding === undefined) continue; + // Java's HashMap: a second row for the same port and protocol replaces the first. + const index = entries.findIndex((entry) => entry.protocol === forwarding.protocol && entry.port === forwarding.publicPort); + const entry: NatEntry = { + protocol: forwarding.protocol, + remoteIPAddress: '', + port: forwarding.publicPort, + lan: { ipAddress: forwarding.lanIPAddress, port: forwarding.lanPort }, + type: 'static', + updatedAtMilliseconds: state.currentTimeMilliseconds, + }; + if (index >= 0) entries[index] = entry; + else entries.push(entry); + } + state.natTablesByNodeId.set(node.id, entries); } } + /** The home router's NAT table as it stands: static entries, then the dynamic ones that have not expired. */ + natEntries(nodeId: Id): readonly NatEntry[] { + this.expireNatEntries(nodeId); + return this.stateValue.natTablesByNodeId.get(nodeId) ?? []; + } + + /** + * GatewayFirmware.checkNAT: every second from a second after the start, + * dynamic entries whose last update is 300 s (times Java's delay factor) + * old are removed — at the first such check. + */ + private natEntryExpired(entry: NatEntry, nowMilliseconds: number): boolean { + if (entry.type === 'static') return false; + const start = this.natStartedAtMilliseconds; + const retention = NAT_RETENTION_MILLISECONDS * this.runtimeSpeed.javaDelayFactor; + const firstCheck = start + Math.max(1, Math.ceil((entry.updatedAtMilliseconds + retention - start) / 1_000)) * 1_000; + return nowMilliseconds >= firstCheck; + } + + private expireNatEntries(nodeId: Id): void { + const table = this.stateValue.natTablesByNodeId.get(nodeId); + if (table === undefined) return; + const now = this.stateValue.currentTimeMilliseconds; + if (table.some((entry) => this.natEntryExpired(entry, now))) { + this.stateValue.natTablesByNodeId.set( + nodeId, + table.filter((entry) => !this.natEntryExpired(entry, now)), + ); + } + } + + /** A port a dynamic entry of the home router holds (Java reserves it at the transport layer). */ + private isNatPort(nodeId: Id, protocol: 'tcp' | 'udp', port: number): boolean { + return this.natEntries(nodeId).some((entry) => entry.type !== 'static' && entry.protocol === protocol && entry.port === port); + } + + /** + * NetworkAddressTranslationTable.find: the dynamic entry for the remote end, + * port and protocol (updated), else the static one for the port, which + * then gets a dynamic entry for the remote end. + */ + private findNatEntry(nodeId: Id, port: number, remoteIPAddress: string, protocol: NatProtocol): NatEndpoint | undefined { + const table = [...this.natEntries(nodeId)]; + const now = this.stateValue.currentTimeMilliseconds; + const index = table.findIndex((entry) => entry.type !== 'static' && entry.protocol === protocol && entry.port === port && entry.remoteIPAddress === remoteIPAddress); + if (index >= 0) { + table[index] = { ...table[index]!, updatedAtMilliseconds: now }; + this.stateValue.natTablesByNodeId.set(nodeId, table); + return table[index]!.lan; + } + const forwarding = table.find((entry) => entry.type === 'static' && entry.protocol === protocol && entry.port === port); + if (forwarding === undefined) return undefined; + this.putDynamicNatEntry(nodeId, { protocol, remoteIPAddress, port, lan: forwarding.lan, type: 'dynamicFromStatic', updatedAtMilliseconds: now }); + return forwarding.lan; + } + + /** Java's ConcurrentHashMap.put: an entry for the same remote end, port and protocol is replaced. */ + private putDynamicNatEntry(nodeId: Id, entry: NatEntry): void { + const table = [...this.natEntries(nodeId)]; + const index = table.findIndex( + (each) => each.type !== 'static' && each.protocol === entry.protocol && each.port === entry.port && each.remoteIPAddress === entry.remoteIPAddress, + ); + if (index >= 0) table[index] = entry; + else table.push(entry); + this.stateValue.natTablesByNodeId.set(nodeId, table); + } + + /** + * NetworkAddressTranslationTable.findPort: the WAN port of the LAN + * endpoint's entries, 0 without one. (Java looks at the dynamic entries + * first; an endpoint's entries all have the same port.) + */ + private natPortOf(nodeId: Id, lan: NatEndpoint, protocol: NatProtocol): number { + return ( + this.natEntries(nodeId).find((entry) => entry.protocol === protocol && entry.lan.ipAddress === lan.ipAddress && entry.lan.port === lan.port)?.port ?? 0 + ); + } + + /** + * NatGateway.insertNewConnection: a LAN endpoint without an entry gets one + * for the remote end, on a free port of the home router (ICMP: its + * identifier). + * + * Java keeps that one entry for the endpoint's later remote ends too: they + * get its WAN port, but their answers find no entry and never reach the LAN + * (measured: udpTwoRemotes). The core adds an entry for each new remote end + * on the same WAN port — unless a port forwarding serves the endpoint, + * whose answers find their way already. + */ + private insertNatConnection(nodeId: Id, protocol: NatProtocol, lan: NatEndpoint, remoteIPAddress: string): void { + const table = this.natEntries(nodeId); + const now = this.stateValue.currentTimeMilliseconds; + const ofEndpoint = table.filter((entry) => entry.protocol === protocol && entry.lan.ipAddress === lan.ipAddress && entry.lan.port === lan.port); + if (ofEndpoint.length === 0) { + const port = protocol === 'tcp' ? this.reserveFreeTcpPort(nodeId) : protocol === 'udp' ? this.reserveFreeUdpPort(nodeId) : lan.port; + if (port === undefined) return; + this.putDynamicNatEntry(nodeId, { protocol, remoteIPAddress, port, lan, type: 'dynamic', updatedAtMilliseconds: now }); + return; + } + if (ofEndpoint.some((entry) => entry.type === 'static' || entry.remoteIPAddress === remoteIPAddress)) return; + this.putDynamicNatEntry(nodeId, { protocol, remoteIPAddress, port: this.natPortOf(nodeId, lan, protocol), lan, type: 'dynamic', updatedAtMilliseconds: now }); + } + + /** + * What Java's NatGatewayLANThread and NatGatewayWANThread do to a packet + * before the home router's IP layer sees it: from the LAN, a packet to + * elsewhere (not the LAN, not a broadcast, not the WAN address) gets the + * WAN address and the entry's port; from the WAN, a packet to the WAN + * address with an entry goes to its LAN endpoint, one to the LAN's + * addresses is dropped, and an echo request to the WAN address is answered + * by the router itself. Both sides pass the router's firewall first. + * Undefined when the packet goes no further. + */ + private translateAtGateway(packet: IPv4Packet, frameIdentity: number | undefined, nodeId: Id, networkInterface: NetworkInterface): IPv4Packet | undefined { + const interfaces = this.networkInterfaces(nodeId); + const wan = interfaces.find((each) => each.index === 0); + const lan = interfaces.find((each) => each.index === 1); + if (wan === undefined || lan === undefined) return packet; + const payload = packet.payload; + const trace = (operation: TraceOperation, detail: string, after?: IPv4Packet) => + this.recordTrace({ + frameIdentity, + packetIdentity: packet.identity, + nodeId, + interfaceId: networkInterface.portId, + direction: networkInterface.portId === wan.portId ? 'inbound' : 'outbound', + layer: 'network', + operation, + beforeHeaders: ipv4Headers(packet), + ...(after === undefined ? {} : { afterHeaders: ipv4Headers(after) }), + detail, + }); + + if (networkInterface.portId === wan.portId) { + if (payload.kind === 'icmp' && payload.message.kind === 'echoRequest' && packet.receiverIPAddress === wan.ipAddress) return packet; + if (sameSubnet(packet.receiverIPAddress, lan.ipAddress, lan.subnetMask)) { + trace('dropped', 'WAN packet addressed to the LAN'); + return undefined; + } + if (!this.evaluateFirewall(packet, nodeId, networkInterface.portId, frameIdentity).accepted) return undefined; + if (packet.receiverIPAddress !== wan.ipAddress) return packet; + const lookup = natInboundLookup(packet); + if (lookup === undefined) return packet; + const endpoint = this.findNatEntry(nodeId, lookup.port, lookup.remoteIPAddress, lookup.protocol); + if (endpoint === undefined) return packet; + const translated = natWithDestination(packet, endpoint); + trace('rewritten', 'NAT WAN to LAN', translated); + return translated; + } + + if (networkInterface.portId !== lan.portId) return packet; + if (!this.evaluateFirewall(packet, nodeId, networkInterface.portId, frameIdentity).accepted) return undefined; + const outgoing = + !sameSubnet(packet.receiverIPAddress, lan.ipAddress, lan.subnetMask) && + !isBroadcastFrom(packet.receiverIPAddress, packet.senderIPAddress, lan.subnetMask) && + packet.receiverIPAddress !== wan.ipAddress; + if (!outgoing) return packet; + if (packet.timeToLive <= 1) { + this.emitIcmpError(nodeId, networkInterface, 'timeExceeded', packet); + return undefined; + } + const endpoint = natOutboundEndpoint(packet); + if (endpoint.opens) this.insertNatConnection(nodeId, endpoint.protocol, { ipAddress: packet.senderIPAddress, port: endpoint.port }, packet.receiverIPAddress); + const port = endpoint.protocol === 'icmp' ? undefined : this.natPortOf(nodeId, { ipAddress: packet.senderIPAddress, port: endpoint.port }, endpoint.protocol); + const translated = natWithSource(packet, wan.ipAddress, port); + trace('rewritten', 'NAT LAN to WAN', translated); + return translated; + } + private isRipEnabledRouter(nodeId: Id): boolean { return ( this.nodeSnapshot(nodeId)?.kind === 'router' && @@ -4064,8 +4378,11 @@ export class NetworkRuntimeEngine { const node = this.nodeSnapshot(nodeId); if (node === undefined) return; - // Swift: the gateway branch (WAN/LAN, firewall, NAT rewrite) comes here. - if (node.kind === 'gateway') throw new NotPortedError('gateway NAT'); + if (node.kind === 'gateway' && throughThread) { + const translated = this.translateAtGateway(packet, frameIdentity, nodeId, networkInterface); + if (translated === undefined) return; + packet = translated; + } if (node.kind === 'router') { const decision = this.evaluateFirewall(packet, nodeId, networkInterface.portId, frameIdentity); if (!decision.accepted) return; @@ -4113,7 +4430,8 @@ export class NetworkRuntimeEngine { if (!this.deliverIPv4Locally(packetForProcessing, nodeId, networkInterface, finished)) finished(); return; } - if (node.kind !== 'router') { + // Java: routers and home routers forward (IpForwardingEnabled), nothing else. + if (node.kind !== 'router' && node.kind !== 'gateway') { this.recordTrace({ frameIdentity, packetIdentity: packetForProcessing.identity, diff --git a/packages/core/src/runtime/snapshot.ts b/packages/core/src/runtime/snapshot.ts index 6490068..d7ca79c 100644 --- a/packages/core/src/runtime/snapshot.ts +++ b/packages/core/src/runtime/snapshot.ts @@ -13,6 +13,7 @@ import type { DhcpServerConfiguration, DnsServerConfiguration, FirewallConfiguration, + GatewayPortForwardingRow, InterfaceConfiguration, InterfaceKey, ManualRoute, @@ -59,6 +60,8 @@ export interface TopologySnapshot { /** The DNS servers switched on (Java: aktiv), by node. */ readonly dnsServerConfigurationsByNodeId: ReadonlyMap; readonly firewallConfigurationsByNodeId: ReadonlyMap; + /** A home router's port forwarding (Java GatewayFirmware.staticNAT), by node. */ + readonly portForwardingRowsByNodeId: ReadonlyMap; readonly switchConfigurationsByNodeId: ReadonlyMap; } @@ -73,6 +76,7 @@ export interface TopologySnapshotInput { dhcpServerConfigurationsByNodeId?: ReadonlyMap; dnsServerConfigurationsByNodeId?: ReadonlyMap; firewallConfigurationsByNodeId?: ReadonlyMap; + portForwardingRowsByNodeId?: ReadonlyMap; switchConfigurationsByNodeId?: ReadonlyMap; } @@ -88,6 +92,7 @@ export function topologySnapshot(input: TopologySnapshotInput): TopologySnapshot dhcpServerConfigurationsByNodeId: input.dhcpServerConfigurationsByNodeId ?? new Map(), dnsServerConfigurationsByNodeId: input.dnsServerConfigurationsByNodeId ?? new Map(), firewallConfigurationsByNodeId: input.firewallConfigurationsByNodeId ?? new Map(), + portForwardingRowsByNodeId: input.portForwardingRowsByNodeId ?? new Map(), switchConfigurationsByNodeId: input.switchConfigurationsByNodeId ?? new Map(), }; } diff --git a/packages/core/test/engine.test.ts b/packages/core/test/engine.test.ts index 16d04cc..b175c79 100644 --- a/packages/core/test/engine.test.ts +++ b/packages/core/test/engine.test.ts @@ -39,6 +39,7 @@ import { type EthernetFrame, type EthernetPayload, type FirewallConfiguration, + type NatEntry, type IPv4Packet, type NodeSnapshot, type RuntimeOutput, @@ -2147,3 +2148,240 @@ describe('RIP', () => { expect(engine.state.ripTablesByNodeId.size).toBe(0); }); }); + +describe('Home router NAT', () => { + const [lanPcId, lanPcPort, gatewayId, wanPort, lanPort, wanPcId, wanPcPort] = [0x1c01, 0x1c02, 0x1c03, 0x1c04, 0x1c05, 0x1c06, 0x1c07].map(uuid) as [ + string, + string, + string, + string, + string, + string, + string, + ]; + /** PC 192.168.0.10 — home router (WAN 42.0.0.10/8, LAN 192.168.0.1/24) — PC 42.0.0.20, each on its own cable. */ + const home = (options: { forwarding?: [string, string, string, string][]; firewall?: FirewallConfiguration; speed?: number } = {}) => { + const engine = new NetworkRuntimeEngine(14); + if (options.speed !== undefined) engine.setSimulationSpeed(options.speed); + engine.handle({ + type: 'start', + snapshot: topologySnapshot({ + nodes: [ + pc(lanPcId, lanPcPort), + { id: gatewayId, kind: 'gateway', ports: [portSnapshot(wanPort, 'wan0'), portSnapshot(lanPort, 'lan0')] }, + pc(wanPcId, wanPcPort), + ], + links: [link(lanPcId, lanPcPort, gatewayId, lanPort), link(gatewayId, wanPort, wanPcId, wanPcPort)], + deviceConfigurations: new Map([ + [lanPcId, device('192.168.0.10', { gateway: '192.168.0.1' })], + [wanPcId, device('42.0.0.20', { mask: '255.0.0.0', gateway: '42.0.0.10' })], + ]), + interfaceConfigurations: new Map([ + [interfaceKey(gatewayId, wanPort), { ipAddress: '42.0.0.10', subnetMask: '255.0.0.0' }], + [interfaceKey(gatewayId, lanPort), { ipAddress: '192.168.0.1', subnetMask: '255.255.255.0' }], + ]), + portForwardingRowsByNodeId: new Map([ + [gatewayId, (options.forwarding ?? []).map(([protocolValue, publicPortValue, lanIPAddress, lanPortValue]) => ({ protocolValue, publicPortValue, lanIPAddress, lanPortValue }))], + ]), + ...(options.firewall === undefined ? {} : { firewallConfigurationsByNodeId: new Map([[gatewayId, options.firewall]]) }), + }), + seed: 14, + initialTimeMilliseconds: 0, + }); + return engine; + }; + const udpOut = (engine: NetworkRuntimeEngine, localPort = 5000) => { + engine.sendUdp(engine.bindUdpSocket(lanPcId, { localPort, remoteIPAddress: '42.0.0.20', remotePort: 7 })!, new TextEncoder().encode('out')); + letFramesArrive(engine); + }; + + it("takes the port forwarding rows Java's input check takes, a later row for the same port replacing an earlier one", () => { + const engine = home({ + forwarding: [ + ['tcp', '8080', '192.168.0.10', '80'], + ['17', '53', '192.168.0.10', '53'], + ['6', '8080', '192.168.0.11', '81'], + ['ICMP', '1', '192.168.0.10', '1'], + ['TCP', '080', '192.168.0.10', '80'], + ['TCP', '65536', '192.168.0.10', '80'], + ['UDP', '9', '192.168.0.300', '9'], + ], + }); + expect(engine.natEntries(gatewayId).map((entry) => `${entry.protocol} ${entry.port} ${entry.lan.ipAddress}:${entry.lan.port} ${entry.type}`)).toEqual([ + 'tcp 8080 192.168.0.11:81 static', + 'udp 53 192.168.0.10:53 static', + ]); + }); + + it('holds the WAN port of an entry against the router’s own sockets', () => { + const engine = home(); + udpOut(engine); + const [entry] = engine.natEntries(gatewayId) as [NatEntry]; + expect(engine.bindUdpSocket(gatewayId, { localPort: entry.port })).toBeUndefined(); + }); + + it("drops an entry at the first of Java's checks, each second from the start, when it is 300 s times the delay factor old; answers refresh it", () => { + const engine = home({ speed: 100 }); + udpOut(engine); + // At 100 %, the factor is 1: 300 s. The entry came at 15 ms (three cables of 5 ms); it is gone at the check at 301 s. + const [entry] = engine.natEntries(gatewayId) as [NatEntry]; + expect(entry.updatedAtMilliseconds).toBe(15); + engine.handle({ type: 'advance', toMilliseconds: 300_999 }); + expect(engine.natEntries(gatewayId)).toHaveLength(1); + engine.handle({ type: 'advance', toMilliseconds: 301_000 }); + expect(engine.natEntries(gatewayId)).toHaveLength(0); + + // Another, now refreshed by an answer, and not by what goes out. + udpOut(engine, 5001); + const [fresh] = engine.natEntries(gatewayId) as [NatEntry]; + engine.handle({ type: 'advance', toMilliseconds: 400_000 }); + udpOut(engine, 5001); + expect(engine.natEntries(gatewayId)[0]?.updatedAtMilliseconds).toBe(fresh.updatedAtMilliseconds); + const answer = engine.bindUdpSocket(wanPcId, { localPort: 7, remoteIPAddress: '42.0.0.10', remotePort: fresh.port })!; + engine.sendUdp(answer, new TextEncoder().encode('back')); + letFramesArrive(engine); + expect(engine.natEntries(gatewayId)[0]!.updatedAtMilliseconds).toBeGreaterThan(400_000); + }); + + it('passes both sides through the router’s firewall', () => { + const engine = home({ firewall: firewallConfiguration({ isActive: true, defaultPolicy: 'drop' }) }); + udpOut(engine); + expect(engine.natEntries(gatewayId)).toEqual([]); + expect(engine.state.firewallDecisions.some((decision) => !decision.accepted && decision.nodeId === gatewayId)).toBe(true); + }); + + it('answers a packet going out with TTL 1 with time exceeded, and drops what comes from the WAN for the LAN', () => { + const engine = home(); + engine.sendIPv4Packet(lanPcId, { + identity: engine.allocatePacketIdentity(), + senderIPAddress: '192.168.0.10', + receiverIPAddress: '42.0.0.20', + timeToLive: 1, + protocol: 'udp', + payload: { kind: 'udp', datagram: { sourcePort: 5000, destinationPort: 7, payload: new Uint8Array() } }, + }); + letFramesArrive(engine); + expect((engine.state.icmpObservationsByNodeId.get(lanPcId) ?? []).map((observation) => observation.message.kind)).toEqual(['timeExceeded']); + expect(engine.natEntries(gatewayId)).toEqual([]); + + engine.sendIPv4Packet(wanPcId, { + identity: engine.allocatePacketIdentity(), + senderIPAddress: '42.0.0.20', + receiverIPAddress: '192.168.0.10', + timeToLive: 64, + protocol: 'udp', + payload: { kind: 'udp', datagram: { sourcePort: 7, destinationPort: 5000, payload: new Uint8Array() } }, + }); + letFramesArrive(engine); + expect(engine.state.packetTraces.some((trace) => trace.nodeId === gatewayId && trace.detail === 'WAN packet addressed to the LAN')).toBe(true); + expect((engine.state.deliveredIPv4PacketsByNodeId.get(lanPcId) ?? []).filter((delivered) => delivered.packet.protocol === 'udp')).toEqual([]); + }); + + const raw = (engine: NetworkRuntimeEngine, from: string, packet: Omit) => { + const identity = engine.allocatePacketIdentity(); + engine.sendIPv4Packet(from, { identity, timeToLive: 64, ...packet }); + letFramesArrive(engine); + return identity; + }; + const echo = (identifier: number) => ({ kind: 'icmp' as const, message: icmpMessage('echoRequest', { identifier, sequenceNumber: 1 }) }); + + it('keeps static entries, and dynamic ones for 300 s times the delay factor (55 minutes at 90 %)', () => { + const engine = home({ forwarding: [['UDP', '53', '192.168.0.10', '53']] }); + udpOut(engine); + engine.handle({ type: 'advance', toMilliseconds: 3_300_000 }); + expect(engine.natEntries(gatewayId).map((entry) => entry.type)).toEqual(['static', 'dynamic']); + engine.handle({ type: 'advance', toMilliseconds: 3_302_000 }); + expect(engine.natEntries(gatewayId).map((entry) => entry.type)).toEqual(['static']); + }); + + it('opens an entry with a SYN, not with other TCP segments; they leave with port 0', () => { + const engine = home(); + raw(engine, lanPcId, { + senderIPAddress: '192.168.0.10', + receiverIPAddress: '42.0.0.20', + protocol: 'tcp', + payload: { kind: 'tcp', segment: { sourcePort: 5000, destinationPort: 80, sequenceNumber: 1, acknowledgementNumber: 1, flags: TCP_FLAG.acknowledgement, payload: new Uint8Array() } }, + }); + expect(engine.natEntries(gatewayId)).toEqual([]); + const arrived = engine.state.packetTraces.find((trace) => trace.nodeId === wanPcId && trace.detail === 'TCP destination port closed')!; + expect(arrived.beforeHeaders.find((header) => header.name === 'sourcePort')?.value).toBe('0'); + }); + + it('lets broadcasts from the LAN be', () => { + const engine = home(); + engine.sendUdp(engine.bindUdpSocket(lanPcId, { localPort: 5000 })!, new TextEncoder().encode('all'), { ipAddress: '255.255.255.255', port: 7 }); + letFramesArrive(engine); + expect(engine.natEntries(gatewayId)).toEqual([]); + expect(engine.state.icmpObservationsByNodeId.get(lanPcId) ?? []).toEqual([]); + }); + + it('replaces an entry for the same remote end, port and protocol (Java: a map), as two hosts pinging with one identifier do', () => { + const engine = home(); + raw(engine, lanPcId, { senderIPAddress: '192.168.0.10', receiverIPAddress: '42.0.0.20', protocol: 'icmp', payload: echo(1) }); + raw(engine, lanPcId, { senderIPAddress: '192.168.0.11', receiverIPAddress: '42.0.0.20', protocol: 'icmp', payload: echo(1) }); + expect(engine.natEntries(gatewayId).map((entry) => `${entry.remoteIPAddress}:${entry.port} ${entry.lan.ipAddress}:${entry.lan.port}`)).toEqual([ + '42.0.0.20:1 192.168.0.11:1', + ]); + }); + + it('answers a ping at its WAN address itself, even when an entry would fit', () => { + const engine = home(); + raw(engine, lanPcId, { senderIPAddress: '192.168.0.10', receiverIPAddress: '42.0.0.20', protocol: 'icmp', payload: echo(1) }); + raw(engine, wanPcId, { senderIPAddress: '42.0.0.20', receiverIPAddress: '42.0.0.10', protocol: 'icmp', payload: echo(1) }); + const replies = (engine.state.icmpObservationsByNodeId.get(wanPcId) ?? []).filter((observation) => observation.message.kind === 'echoReply'); + expect(replies.map((observation) => observation.packet.senderIPAddress)).toContain('42.0.0.10'); + expect(engine.state.packetTraces.filter((trace) => trace.nodeId === lanPcId && trace.detail === 'ICMP echo reply')).toHaveLength(0); + }); + + it('sends an ICMP error for a packet it translated to the LAN endpoint, found by the packet it carries', () => { + const engine = home(); + udpOut(engine); + const [entry] = engine.natEntries(gatewayId) as [NatEntry]; + raw(engine, wanPcId, { + senderIPAddress: '42.0.0.20', + receiverIPAddress: '42.0.0.10', + protocol: 'icmp', + payload: { + kind: 'icmp', + message: icmpMessage('destinationHostUnreachable', { + embeddedOriginalPacket: { + identity: 1, + senderIPAddress: '42.0.0.10', + receiverIPAddress: '42.0.0.20', + timeToLive: 63, + protocol: 'udp', + payload: { kind: 'udp', datagram: { sourcePort: entry.port, destinationPort: 7, payload: new Uint8Array() } }, + }, + }), + }, + }); + expect((engine.state.icmpObservationsByNodeId.get(lanPcId) ?? []).map((observation) => observation.message.kind)).toEqual(['destinationHostUnreachable']); + }); + + it('lets a forwarded endpoint reach a new remote end through its forwarding, whose answer makes the entry', () => { + const engine = home({ forwarding: [['UDP', '53', '192.168.0.10', '53']] }); + udpOut(engine, 53); + const answer = engine.bindUdpSocket(wanPcId, { localPort: 7, remoteIPAddress: '42.0.0.10', remotePort: 53 })!; + engine.sendUdp(answer, new TextEncoder().encode('back')); + letFramesArrive(engine); + expect(engine.natEntries(gatewayId).map((entry) => `${entry.type} ${entry.remoteIPAddress}:${entry.port}`)).toEqual(['static :53', 'dynamicFromStatic 42.0.0.20:53']); + }); + + it('drops at its WAN side what its firewall drops', () => { + const engine = home({ firewall: firewallConfiguration({ isActive: true, defaultPolicy: 'drop' }) }); + const identity = raw(engine, wanPcId, { + senderIPAddress: '42.0.0.20', + receiverIPAddress: '42.0.0.10', + protocol: 'udp', + payload: { kind: 'udp', datagram: { sourcePort: 7, destinationPort: 9, payload: new Uint8Array() } }, + }); + expect(engine.state.packetTraces.some((trace) => trace.nodeId === gatewayId && trace.packetIdentity === identity && trace.layer === 'transport')).toBe(false); + }); + + it('forgets its tables on stop', () => { + const engine = home(); + udpOut(engine); + engine.handle({ type: 'stop' }); + expect(engine.state.natTablesByNodeId.size).toBe(0); + }); +}); diff --git a/packages/core/test/natJava.test.ts b/packages/core/test/natJava.test.ts new file mode 100644 index 0000000..1185343 --- /dev/null +++ b/packages/core/test/natJava.test.ts @@ -0,0 +1,257 @@ +// NAT as Java FILIUS runs it. tools/java-oracle's NatRun ran stories on +// nat-home's network (a PC behind a home router, two hosts on its WAN side) +// in Java FILIUS and wrote every frame each card saw, the story's calls and +// the router's NAT table (nat-java-.java.json). The engine plays the +// same story: each card must send the same frames in the same order, each at +// about the same time from the first frame; the calls must return the same; +// the NAT table must hold the same entries. +// +// Java's servers answer in threads of their own, and its client sends its +// next segment some 90 ms after the last (thread latency); the engine's story +// plays the servers between the client's calls. The order between cards +// follows those threads, so it is not compared. Free ports — a client's, and the WAN port +// the router draws for an entry — are Java's random and the engine's seed: +// both are compared as "port". Java numbers the TCP sockets' initial +// sequence numbers over all sockets, and its home router's web server (not +// in the engine yet) takes the first: each is compared by the order it first +// shows in. Frames that show within TIE_MILLISECONDS of each other Java's +// packet log writes in any order; they are compared sorted by their text. + +import { readFileSync } from 'node:fs'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { describe, expect, it } from 'vitest'; +import type { Id, IPv4DeliveryResult, NetworkRuntimeEngine } from '../src/index.js'; +import { GAP_TOLERANCE_MILLISECONDS, javaFrames, watchedEngine, type JavaFrame, type SeenFrame } from './javaRun.js'; +import type { Scenario } from './scenario.js'; + +const scenarioDirectory = join(dirname(fileURLToPath(import.meta.url)), 'scenarios'); +const LAN_PC = '00000000-0000-0000-0000-000000000501'; +const GATEWAY = '00000000-0000-0000-0000-000000000502'; +const SERVER = '00000000-0000-0000-0000-000000000504'; +const OTHER_SERVER = '00000000-0000-0000-0000-000000000505'; +const RTT = 2_750; +const TIE_MILLISECONDS = 1; +// As in tcpJava.test.ts: the engine's calls block one after the other, so +// the server answers when the client's send returns, and the client closes +// when the server's send returns — up to two cables' delay each later. +const TCP_TOLERANCE_MILLISECONDS = 250; +const TCP_STORIES = new Set(['tcpOut', 'forward']); + +/** The frames by the card that sent them (the source MAC address), in order, times from the first frame. */ +function bySender(frames: readonly SeenFrame[]): Map { + const start = Math.min(...frames.map((frame) => frame.time)); + const result = new Map(); + for (const frame of frames) { + const sender = frame.text.slice(0, 17); + result.set(sender, [...(result.get(sender) ?? []), { time: frame.time - start, text: frame.text }]); + } + return result; +} + +interface JavaRun { + frames: Record; + events: [number, string][]; + nat: string[]; +} + +type Call = (label: string, run: () => string) => void; + +const text = (value: string) => new TextEncoder().encode(value); +const decode = (value: Uint8Array | undefined) => (value === undefined ? 'null' : new TextDecoder().decode(value)); + +/** A ping in Java's words: the answer's type and code and its sender, or null. */ +function ping(engine: NetworkRuntimeEngine, from: Id, target: string, sequenceNumber: number): string { + const result: IPv4DeliveryResult = engine.sendIcmpEcho(from, target, { sequenceNumber }); + if (result.type === 'icmpError') return `ICMP ${result.kind}`; + const reply = (engine.state.icmpObservationsByNodeId.get(from) ?? []).find( + (observation) => observation.message.kind === 'echoReply' && observation.message.sequenceNumber === sequenceNumber, + ); + return reply === undefined ? 'null' : `ICMP 0/0 from ${reply.packet.senderIPAddress}`; +} + +/** The server's socket on port 7 answers the first datagram with "pong ", as NatRun's echo thread. */ +function udpEcho(engine: NetworkRuntimeEngine, socket: Id): void { + const received = engine.receiveUdp(socket, 10 * RTT); + if (received !== undefined) engine.sendUdp(socket, text(`pong ${decode(received.datagram.payload)}`)); +} + +/** NatRun's TCP exchange: the server listens on 80; the client connects, sends "hello", receives, closes. */ +function tcpExchange(engine: NetworkRuntimeEngine, call: Call, server: Id, client: Id, target: string, port: number): void { + const listener = engine.openTcpServerSocket(server, 80)!; + const socket = engine.openTcpClientSocket(client, target, port)!; + call('client verbinden', () => (engine.connectTcpWithResult(socket) === 'connected' ? '' : 'failed')); + const accepted = () => engine.state.tcpAcceptedSocketIdsByListenerId.get(listener)![0]!; + call('client senden', () => (engine.sendTcp(socket, text('hello')) ? '' : 'failed')); + engine.sendTcp(accepted(), text(`reply ${decode(engine.receiveTcp(accepted()))}`)); + call('client empfangen', () => decode(engine.receiveTcp(socket))); + call('client schliessen', () => { + engine.closeTcpSocket(socket); + return ''; + }); +} + +const STORIES: Record void> = { + pingOut: (engine, call) => call('sendProbe 42.0.0.20', () => ping(engine, LAN_PC, '42.0.0.20', 1)), + udpOut: (engine, call) => { + const server = engine.bindUdpSocket(SERVER, { localPort: 7 })!; + const client = engine.bindUdpSocket(LAN_PC, { remoteIPAddress: '42.0.0.20', remotePort: 7 })!; + call('senden 42.0.0.20', () => { + engine.sendUdp(client, text('one')); + return ''; + }); + call('empfangen', () => { + udpEcho(engine, server); + return decode(engine.receiveUdp(client, 5 * RTT)?.datagram.payload); + }); + }, + udpTwoRemotes: (engine, call) => { + const server = engine.bindUdpSocket(SERVER, { localPort: 7 })!; + const otherServer = engine.bindUdpSocket(OTHER_SERVER, { localPort: 7 })!; + const first = engine.bindUdpSocket(LAN_PC, { remoteIPAddress: '42.0.0.20', remotePort: 7 })!; + call('senden 42.0.0.20', () => { + engine.sendUdp(first, text('one')); + return ''; + }); + call('empfangen', () => { + udpEcho(engine, server); + return decode(engine.receiveUdp(first, 5 * RTT)?.datagram.payload); + }); + const port = engine.state.socketsById.get(first)!.localPort; + engine.closeSocket(first); + const second = engine.bindUdpSocket(LAN_PC, { localPort: port, remoteIPAddress: '42.0.0.30', remotePort: 7 })!; + call('senden 42.0.0.30', () => { + engine.sendUdp(second, text('two')); + return ''; + }); + call('empfangen', () => { + udpEcho(engine, otherServer); + return decode(engine.receiveUdp(second, 5 * RTT)?.datagram.payload); + }); + }, + tcpOut: (engine, call) => tcpExchange(engine, call, SERVER, LAN_PC, '42.0.0.20', 80), + forward: (engine, call) => tcpExchange(engine, call, LAN_PC, SERVER, '42.0.0.10', 8080), + pingWan: (engine, call) => { + call('sendProbe 42.0.0.10', () => ping(engine, SERVER, '42.0.0.10', 1)); + call('sendProbe 192.168.0.10', () => ping(engine, SERVER, '192.168.0.10', 2)); + }, +}; + +/** + * Where Java errs, per story: its run corrected, as Java means it. + * + * udpTwoRemotes: Java keeps one entry per LAN endpoint, for the first remote + * end; the second server gets the datagram from the entry's WAN port, but its + * answer finds no entry and stays at the router. The engine adds an entry for + * the second remote end: its answer goes on to the PC, a cable later. + */ +const JAVA_BUGS: Record JavaRun> = { + udpTwoRemotes: (java) => { + const answer = Object.values(java.frames) + .flat() + .find((frame) => frame.payload === 'pong two' && frame.destinationIp === '42.0.0.10')!; + const [lanPort] = java.nat[0]!.match(/192\.168\.0\.10:(\d+)/)!.slice(1); + const onLan: JavaFrame = { + ...answer, + time: answer.time + 56, + source: '02:00:00:00:05:22', + destination: '02:00:00:00:05:11', + destinationIp: '192.168.0.10', + destinationPort: Number(lanPort), + }; + const wanPort = java.nat[0]!.match(/42\.0\.0\.20:(\d+)/)![1]; + const received = java.events.find(([, event]) => event === 'other server received two')!; + return { + frames: { ...java.frames, [LAN_PC]: [...java.frames[LAN_PC]!, onLan] }, + events: java.events.map(([time, event], index) => + index === java.events.length - 1 && event === 'empfangen returned null' ? [received[0] + 168, 'empfangen returned pong two'] : [time, event], + ), + nat: [...java.nat, `17 42.0.0.30:${wanPort} -> 192.168.0.10:${lanPort} DynamicEntry`].sort(), + }; + }, +}; + +/** Free ports as "port", initial sequence numbers by their order, ties sorted. */ +function normalized(frames: readonly SeenFrame[]): SeenFrame[] { + const bases = new Map(); + const sequence = (value: string) => { + const number = Number(value); + const base = Math.floor(number / 1_000_000); + if (!bases.has(base)) bases.set(base, bases.size + 1); + return `isn${bases.get(base)}+${number % 1_000_000}`; + }; + const texts = frames.map((frame) => ({ + time: frame.time, + text: withPorts(frame.text).replace(/(seq|ack)=(\d+)/g, (whole, name: string, value: string) => (value === '0' ? whole : `${name}=${sequence(value)}`)), + })); + const result: SeenFrame[] = []; + for (let start = 0; start < texts.length; ) { + let end = start + 1; + while (end < texts.length && texts[end]!.time - texts[start]!.time <= TIE_MILLISECONDS) end += 1; + const tie = texts.slice(start, end); + const sortedTexts = tie.map((frame) => frame.text).sort(); + result.push(...tie.map((frame, index) => ({ time: frame.time, text: sortedTexts[index]! }))); + start = end; + } + return result; +} + +function withPorts(value: string): string { + return value.replace(/:(\d{5})\b/g, (whole, port: string) => (Number(port) >= 49_152 ? ':port' : whole)); +} + +/** The router's dynamic entries as NatRun writes them. */ +function natTable(engine: NetworkRuntimeEngine): string[] { + const protocols = { tcp: 6, udp: 17, icmp: 1 } as const; + const types = { dynamic: 'DynamicEntry', dynamicFromStatic: 'DynamicEnryFromStatic' } as const; + return engine + .natEntries(GATEWAY) + .filter((entry) => entry.type !== 'static') + .map((entry) => `${protocols[entry.protocol]} ${entry.remoteIPAddress}:${entry.port} -> ${entry.lan.ipAddress}:${entry.lan.port} ${types[entry.type as 'dynamic']}`) + .sort(); +} + +describe('NAT as Java FILIUS runs it', () => { + it('corrects Java only where it errs', () => { + for (const [name, correct] of Object.entries(JAVA_BUGS)) { + const java = JSON.parse(readFileSync(join(scenarioDirectory, `nat-java-${name}.java.json`), 'utf8')) as JavaRun; + expect(JSON.stringify(correct(java)), name).not.toBe(JSON.stringify(java)); + } + }); + + const scenario = JSON.parse(readFileSync(join(scenarioDirectory, 'nat-home.scenario.json'), 'utf8')) as Scenario; + + for (const [name, story] of Object.entries(STORIES)) { + it(name, () => { + const measured = JSON.parse(readFileSync(join(scenarioDirectory, `nat-java-${name}.java.json`), 'utf8')) as JavaRun; + const java = JAVA_BUGS[name]?.(measured) ?? measured; + const { engine, frames } = watchedEngine(scenario); + engine.handle({ type: 'advance', toMilliseconds: 500 }); + const events: [number, string][] = []; + story(engine, (label, run) => { + events.push([engine.state.currentTimeMilliseconds, `${label} called`]); + const result = run(); + events.push([engine.state.currentTimeMilliseconds, `${label} returned${result === '' ? ' ' : ` ${result}`}`]); + }); + engine.handle({ type: 'advance', toMilliseconds: engine.state.currentTimeMilliseconds + 10_000 }); + + const expected = bySender(normalized(javaFrames(java.frames))); + const actual = bySender(normalized(frames())); + expect([...actual.keys()].sort()).toEqual([...expected.keys()].sort()); + for (const [sender, javaList] of expected) { + const engineList = actual.get(sender)!; + for (let index = 0; index < Math.max(javaList.length, engineList.length); index += 1) { + expect(engineList[index]?.text, `${sender} frame #${index + 1}`).toBe(javaList[index]?.text); + expect(Math.abs(engineList[index]!.time - javaList[index]!.time), `${sender} time of frame #${index + 1}`).toBeLessThanOrEqual( + TCP_STORIES.has(name) ? TCP_TOLERANCE_MILLISECONDS : GAP_TOLERANCE_MILLISECONDS, + ); + } + } + + // The client's calls: Java's server threads write events of their own, which the engine's story has not. + const javaCalls = java.events.filter(([, event]) => !event.startsWith('server') && !event.startsWith('other server')); + expect(events.map(([, event]) => event)).toEqual(javaCalls.map(([, event]) => event)); + expect(natTable(engine).map(withPorts)).toEqual(java.nat.map(withPorts)); + }); + } +}); diff --git a/packages/core/test/scenario.ts b/packages/core/test/scenario.ts index 38cd255..9e63ff5 100644 --- a/packages/core/test/scenario.ts +++ b/packages/core/test/scenario.ts @@ -51,6 +51,8 @@ export interface Scenario { { active?: boolean; lower?: string; upper?: string; gateway?: string; dns?: string; own?: boolean; staticAssignments?: [string, string][] } >; dhcpClients?: string[]; + /** Home routers' port forwarding: rows of protocol, public port, LAN address, LAN port. */ + portForwarding?: Record; /** Routers with RIP switched on. */ rip?: string[]; /** Records as `name TYPE target` (Java's hinzuRecord: TTL 3600). */ @@ -164,6 +166,12 @@ export function snapshotOf(scenario: Scenario): TopologySnapshot { ), dhcpClientConfigurationsByNodeId: new Map((scenario.dhcpClients ?? []).map((node) => [node, { isEnabled: true }])), ripEnabledByNodeId: new Map((scenario.rip ?? []).map((node) => [node, true])), + portForwardingRowsByNodeId: new Map( + Object.entries(scenario.portForwarding ?? {}).map(([node, rows]) => [ + node, + rows.map(([protocolValue, publicPortValue, lanIPAddress, lanPortValue]) => ({ protocolValue, publicPortValue, lanIPAddress, lanPortValue })), + ]), + ), switchConfigurationsByNodeId: new Map( Object.entries(scenario.switches ?? {}).map(([node, config]) => [ node, diff --git a/packages/core/test/scenarios/arp-java-pingLan.java.json b/packages/core/test/scenarios/arp-java-pingLan.java.json index 33c4e9a..d464078 100644 --- a/packages/core/test/scenarios/arp-java-pingLan.java.json +++ b/packages/core/test/scenarios/arp-java-pingLan.java.json @@ -2,7 +2,7 @@ "frames": { "00000000-0000-0000-0000-000000000301": [ { - "time": 716, + "time": 747, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -10,7 +10,7 @@ "targetIp": "10.0.0.9" }, { - "time": 3467, + "time": 3497, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -20,7 +20,7 @@ ], "00000000-0000-0000-0000-000000000302": [ { - "time": 837, + "time": 869, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -28,7 +28,7 @@ "targetIp": "10.0.0.9" }, { - "time": 3578, + "time": 3609, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -36,15 +36,16 @@ "targetIp": "10.0.0.9" } ], + "00000000-0000-0000-0000-000000000302#1": [], "00000000-0000-0000-0000-000000000303": [] }, "events": [ [ - 712, + 743, "sendProbe 10.0.0.9 called" ], [ - 6222, + 6253, "sendProbe 10.0.0.9 returned ICMP 3/1 from 127.0.0.1" ] ] diff --git a/packages/core/test/scenarios/arp-java-pingRouted.java.json b/packages/core/test/scenarios/arp-java-pingRouted.java.json index fa3160f..d05ed82 100644 --- a/packages/core/test/scenarios/arp-java-pingRouted.java.json +++ b/packages/core/test/scenarios/arp-java-pingRouted.java.json @@ -2,7 +2,7 @@ "frames": { "00000000-0000-0000-0000-000000000301": [ { - "time": 718, + "time": 716, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -10,7 +10,7 @@ "targetIp": "10.0.0.1" }, { - "time": 951, + "time": 953, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "arp": 2, @@ -18,7 +18,7 @@ "targetIp": "10.0.0.2" }, { - "time": 955, + "time": 957, "source": "02:00:00:00:03:11", "destination": "02:00:00:00:03:21", "icmp": 8, @@ -28,7 +28,7 @@ "sequence": 1 }, { - "time": 6681, + "time": 6682, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "icmp": 3, @@ -40,7 +40,7 @@ ], "00000000-0000-0000-0000-000000000302": [ { - "time": 838, + "time": 839, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -48,7 +48,7 @@ "targetIp": "10.0.0.1" }, { - "time": 840, + "time": 841, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "arp": 2, @@ -56,7 +56,7 @@ "targetIp": "10.0.0.2" }, { - "time": 1068, + "time": 1069, "source": "02:00:00:00:03:11", "destination": "02:00:00:00:03:21", "icmp": 8, @@ -66,7 +66,7 @@ "sequence": 1 }, { - "time": 6569, + "time": 6571, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "icmp": 3, @@ -76,9 +76,9 @@ "sequence": 0 } ], - "00000000-0000-0000-0000-000000000303": [ + "00000000-0000-0000-0000-000000000302#1": [ { - "time": 1124, + "time": 1070, "source": "02:00:00:00:03:22", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -86,7 +86,25 @@ "targetIp": "20.0.0.9" }, { - "time": 3874, + "time": 3820, + "source": "02:00:00:00:03:22", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "20.0.0.1", + "targetIp": "20.0.0.9" + } + ], + "00000000-0000-0000-0000-000000000303": [ + { + "time": 1125, + "source": "02:00:00:00:03:22", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "20.0.0.1", + "targetIp": "20.0.0.9" + }, + { + "time": 3876, "source": "02:00:00:00:03:22", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -97,11 +115,11 @@ }, "events": [ [ - 713, + 711, "sendProbe 20.0.0.9 called" ], [ - 3705, + 3707, "sendProbe 20.0.0.9 returned null" ] ] diff --git a/packages/core/test/scenarios/arp-java-routedPingBehindPing.java.json b/packages/core/test/scenarios/arp-java-routedPingBehindPing.java.json index 65671ac..1beabf4 100644 --- a/packages/core/test/scenarios/arp-java-routedPingBehindPing.java.json +++ b/packages/core/test/scenarios/arp-java-routedPingBehindPing.java.json @@ -2,7 +2,7 @@ "frames": { "00000000-0000-0000-0000-000000000301": [ { - "time": 718, + "time": 717, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -10,7 +10,7 @@ "targetIp": "10.0.0.1" }, { - "time": 952, + "time": 950, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "arp": 2, @@ -60,7 +60,7 @@ ], "00000000-0000-0000-0000-000000000302": [ { - "time": 838, + "time": 837, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -68,7 +68,7 @@ "targetIp": "10.0.0.1" }, { - "time": 840, + "time": 839, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "arp": 2, @@ -86,7 +86,7 @@ "sequence": 2 }, { - "time": 1124, + "time": 1123, "source": "02:00:00:00:03:11", "destination": "02:00:00:00:03:21", "icmp": 8, @@ -96,7 +96,7 @@ "sequence": 1 }, { - "time": 6570, + "time": 6569, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "icmp": 3, @@ -116,6 +116,60 @@ "sequence": 1 } ], + "00000000-0000-0000-0000-000000000302#1": [ + { + "time": 1068, + "source": "02:00:00:00:03:22", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "20.0.0.1", + "targetIp": "20.0.0.9" + }, + { + "time": 3818, + "source": "02:00:00:00:03:22", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "20.0.0.1", + "targetIp": "20.0.0.9" + }, + { + "time": 6570, + "source": "02:00:00:00:03:22", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "20.0.0.1", + "targetIp": "20.0.0.2" + }, + { + "time": 6681, + "source": "02:00:00:00:03:13", + "destination": "02:00:00:00:03:22", + "arp": 2, + "senderIp": "20.0.0.2", + "targetIp": "20.0.0.1" + }, + { + "time": 6681, + "source": "02:00:00:00:03:22", + "destination": "02:00:00:00:03:13", + "icmp": 8, + "icmpCode": 0, + "sourceIp": "10.0.0.2", + "destinationIp": "20.0.0.2", + "sequence": 1 + }, + { + "time": 6792, + "source": "02:00:00:00:03:13", + "destination": "02:00:00:00:03:22", + "icmp": 0, + "icmpCode": 0, + "sourceIp": "20.0.0.2", + "destinationIp": "10.0.0.2", + "sequence": 1 + } + ], "00000000-0000-0000-0000-000000000303": [ { "time": 1124, @@ -185,7 +239,7 @@ "sendProbe 20.0.0.2 called" ], [ - 3763, + 3762, "sendProbe 20.0.0.2 returned null" ] ] diff --git a/packages/core/test/scenarios/arp-java-routedPingBesideUdp.java.json b/packages/core/test/scenarios/arp-java-routedPingBesideUdp.java.json index fa72b4a..4f58b09 100644 --- a/packages/core/test/scenarios/arp-java-routedPingBesideUdp.java.json +++ b/packages/core/test/scenarios/arp-java-routedPingBesideUdp.java.json @@ -2,7 +2,7 @@ "frames": { "00000000-0000-0000-0000-000000000301": [ { - "time": 717, + "time": 718, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -10,7 +10,7 @@ "targetIp": "10.0.0.1" }, { - "time": 951, + "time": 954, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "arp": 2, @@ -18,7 +18,7 @@ "targetIp": "10.0.0.2" }, { - "time": 955, + "time": 958, "source": "02:00:00:00:03:11", "destination": "02:00:00:00:03:21", "icmp": 8, @@ -28,7 +28,7 @@ "sequence": 1 }, { - "time": 1402, + "time": 1406, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "icmp": 0, @@ -38,18 +38,18 @@ "sequence": 1 }, { - "time": 1408, + "time": 1412, "source": "02:00:00:00:03:11", "destination": "02:00:00:00:03:21", "sourceIp": "10.0.0.2", "destinationIp": "20.0.0.9", "protocol": 17, - "sourcePort": 59998, + "sourcePort": 55220, "destinationPort": 9, "payload": "verloren" }, { - "time": 1507, + "time": 1511, "source": "02:00:00:00:03:11", "destination": "02:00:00:00:03:21", "icmp": 8, @@ -59,7 +59,7 @@ "sequence": 2 }, { - "time": 1842, + "time": 1846, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "icmp": 0, @@ -69,7 +69,7 @@ "sequence": 2 }, { - "time": 7133, + "time": 7137, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "icmp": 3, @@ -81,7 +81,7 @@ ], "00000000-0000-0000-0000-000000000302": [ { - "time": 837, + "time": 840, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -89,7 +89,7 @@ "targetIp": "10.0.0.1" }, { - "time": 839, + "time": 842, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "arp": 2, @@ -97,7 +97,7 @@ "targetIp": "10.0.0.2" }, { - "time": 1068, + "time": 1071, "source": "02:00:00:00:03:11", "destination": "02:00:00:00:03:21", "icmp": 8, @@ -107,7 +107,7 @@ "sequence": 1 }, { - "time": 1291, + "time": 1295, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "icmp": 0, @@ -117,18 +117,18 @@ "sequence": 1 }, { - "time": 1521, + "time": 1525, "source": "02:00:00:00:03:11", "destination": "02:00:00:00:03:21", "sourceIp": "10.0.0.2", "destinationIp": "20.0.0.9", "protocol": 17, - "sourcePort": 59998, + "sourcePort": 55220, "destinationPort": 9, "payload": "verloren" }, { - "time": 1618, + "time": 1623, "source": "02:00:00:00:03:11", "destination": "02:00:00:00:03:21", "icmp": 8, @@ -138,7 +138,7 @@ "sequence": 2 }, { - "time": 1731, + "time": 1735, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "icmp": 0, @@ -148,7 +148,7 @@ "sequence": 2 }, { - "time": 7022, + "time": 7026, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "icmp": 3, @@ -158,9 +158,9 @@ "sequence": 0 } ], - "00000000-0000-0000-0000-000000000303": [ + "00000000-0000-0000-0000-000000000302#1": [ { - "time": 1123, + "time": 1071, "source": "02:00:00:00:03:22", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -168,7 +168,7 @@ "targetIp": "20.0.0.2" }, { - "time": 1124, + "time": 1183, "source": "02:00:00:00:03:13", "destination": "02:00:00:00:03:22", "arp": 2, @@ -176,7 +176,7 @@ "targetIp": "20.0.0.1" }, { - "time": 1235, + "time": 1183, "source": "02:00:00:00:03:22", "destination": "02:00:00:00:03:13", "icmp": 8, @@ -186,7 +186,7 @@ "sequence": 1 }, { - "time": 1235, + "time": 1295, "source": "02:00:00:00:03:13", "destination": "02:00:00:00:03:22", "icmp": 0, @@ -196,7 +196,7 @@ "sequence": 1 }, { - "time": 1576, + "time": 1525, "source": "02:00:00:00:03:22", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -204,7 +204,7 @@ "targetIp": "20.0.0.9" }, { - "time": 1675, + "time": 1623, "source": "02:00:00:00:03:22", "destination": "02:00:00:00:03:13", "icmp": 8, @@ -214,7 +214,7 @@ "sequence": 2 }, { - "time": 1675, + "time": 1735, "source": "02:00:00:00:03:13", "destination": "02:00:00:00:03:22", "icmp": 0, @@ -224,7 +224,81 @@ "sequence": 2 }, { - "time": 4327, + "time": 4275, + "source": "02:00:00:00:03:22", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "20.0.0.1", + "targetIp": "20.0.0.9" + } + ], + "00000000-0000-0000-0000-000000000303": [ + { + "time": 1127, + "source": "02:00:00:00:03:22", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "20.0.0.1", + "targetIp": "20.0.0.2" + }, + { + "time": 1127, + "source": "02:00:00:00:03:13", + "destination": "02:00:00:00:03:22", + "arp": 2, + "senderIp": "20.0.0.2", + "targetIp": "20.0.0.1" + }, + { + "time": 1239, + "source": "02:00:00:00:03:22", + "destination": "02:00:00:00:03:13", + "icmp": 8, + "icmpCode": 0, + "sourceIp": "10.0.0.2", + "destinationIp": "20.0.0.2", + "sequence": 1 + }, + { + "time": 1239, + "source": "02:00:00:00:03:13", + "destination": "02:00:00:00:03:22", + "icmp": 0, + "icmpCode": 0, + "sourceIp": "20.0.0.2", + "destinationIp": "10.0.0.2", + "sequence": 1 + }, + { + "time": 1580, + "source": "02:00:00:00:03:22", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "20.0.0.1", + "targetIp": "20.0.0.9" + }, + { + "time": 1679, + "source": "02:00:00:00:03:22", + "destination": "02:00:00:00:03:13", + "icmp": 8, + "icmpCode": 0, + "sourceIp": "10.0.0.2", + "destinationIp": "20.0.0.2", + "sequence": 2 + }, + { + "time": 1679, + "source": "02:00:00:00:03:13", + "destination": "02:00:00:00:03:22", + "icmp": 0, + "icmpCode": 0, + "sourceIp": "20.0.0.2", + "destinationIp": "10.0.0.2", + "sequence": 2 + }, + { + "time": 4331, "source": "02:00:00:00:03:22", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -235,27 +309,27 @@ }, "events": [ [ - 712, + 713, "sendProbe 20.0.0.2 called" ], [ - 1404, + 1408, "sendProbe 20.0.0.2 returned ICMP 0/0 from 20.0.0.2" ], [ - 1404, + 1408, "senden verloren called" ], [ - 1407, + 1411, "senden verloren returned " ], [ - 1507, + 1511, "sendProbe 20.0.0.2 called" ], [ - 1842, + 1846, "sendProbe 20.0.0.2 returned ICMP 0/0 from 20.0.0.2" ] ] diff --git a/packages/core/test/scenarios/arp-java-routedUdpBehind.java.json b/packages/core/test/scenarios/arp-java-routedUdpBehind.java.json index e3adf09..60c69e2 100644 --- a/packages/core/test/scenarios/arp-java-routedUdpBehind.java.json +++ b/packages/core/test/scenarios/arp-java-routedUdpBehind.java.json @@ -2,7 +2,7 @@ "frames": { "00000000-0000-0000-0000-000000000301": [ { - "time": 721, + "time": 725, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -10,7 +10,7 @@ "targetIp": "10.0.0.1" }, { - "time": 957, + "time": 960, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "arp": 2, @@ -18,29 +18,29 @@ "targetIp": "10.0.0.2" }, { - "time": 959, + "time": 962, "source": "02:00:00:00:03:11", "destination": "02:00:00:00:03:21", "sourceIp": "10.0.0.2", "destinationIp": "20.0.0.9", "protocol": 17, - "sourcePort": 49345, + "sourcePort": 62662, "destinationPort": 9, "payload": "verloren" }, { - "time": 1017, + "time": 1020, "source": "02:00:00:00:03:11", "destination": "02:00:00:00:03:21", "sourceIp": "10.0.0.2", "destinationIp": "20.0.0.2", "protocol": 17, - "sourcePort": 58689, + "sourcePort": 57980, "destinationPort": 9, "payload": "dahinter" }, { - "time": 6689, + "time": 6692, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "icmp": 3, @@ -52,7 +52,7 @@ ], "00000000-0000-0000-0000-000000000302": [ { - "time": 844, + "time": 847, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -60,7 +60,7 @@ "targetIp": "10.0.0.1" }, { - "time": 846, + "time": 848, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "arp": 2, @@ -68,29 +68,29 @@ "targetIp": "10.0.0.2" }, { - "time": 1073, + "time": 1075, "source": "02:00:00:00:03:11", "destination": "02:00:00:00:03:21", "sourceIp": "10.0.0.2", "destinationIp": "20.0.0.9", "protocol": 17, - "sourcePort": 49345, + "sourcePort": 62662, "destinationPort": 9, "payload": "verloren" }, { - "time": 1129, + "time": 1131, "source": "02:00:00:00:03:11", "destination": "02:00:00:00:03:21", "sourceIp": "10.0.0.2", "destinationIp": "20.0.0.2", "protocol": 17, - "sourcePort": 58689, + "sourcePort": 57980, "destinationPort": 9, "payload": "dahinter" }, { - "time": 6577, + "time": 6580, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "icmp": 3, @@ -100,9 +100,9 @@ "sequence": 0 } ], - "00000000-0000-0000-0000-000000000303": [ + "00000000-0000-0000-0000-000000000302#1": [ { - "time": 1129, + "time": 1076, "source": "02:00:00:00:03:22", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -110,7 +110,7 @@ "targetIp": "20.0.0.9" }, { - "time": 3879, + "time": 3826, "source": "02:00:00:00:03:22", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -118,7 +118,7 @@ "targetIp": "20.0.0.9" }, { - "time": 6632, + "time": 6580, "source": "02:00:00:00:03:22", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -126,7 +126,7 @@ "targetIp": "20.0.0.2" }, { - "time": 6633, + "time": 6691, "source": "02:00:00:00:03:13", "destination": "02:00:00:00:03:22", "arp": 2, @@ -134,13 +134,58 @@ "targetIp": "20.0.0.1" }, { - "time": 6744, + "time": 6691, "source": "02:00:00:00:03:22", "destination": "02:00:00:00:03:13", "sourceIp": "10.0.0.2", "destinationIp": "20.0.0.2", "protocol": 17, - "sourcePort": 58689, + "sourcePort": 57980, + "destinationPort": 9, + "payload": "dahinter" + } + ], + "00000000-0000-0000-0000-000000000303": [ + { + "time": 1131, + "source": "02:00:00:00:03:22", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "20.0.0.1", + "targetIp": "20.0.0.9" + }, + { + "time": 3882, + "source": "02:00:00:00:03:22", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "20.0.0.1", + "targetIp": "20.0.0.9" + }, + { + "time": 6635, + "source": "02:00:00:00:03:22", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "20.0.0.1", + "targetIp": "20.0.0.2" + }, + { + "time": 6636, + "source": "02:00:00:00:03:13", + "destination": "02:00:00:00:03:22", + "arp": 2, + "senderIp": "20.0.0.2", + "targetIp": "20.0.0.1" + }, + { + "time": 6747, + "source": "02:00:00:00:03:22", + "destination": "02:00:00:00:03:13", + "sourceIp": "10.0.0.2", + "destinationIp": "20.0.0.2", + "protocol": 17, + "sourcePort": 57980, "destinationPort": 9, "payload": "dahinter" } @@ -148,19 +193,19 @@ }, "events": [ [ - 712, + 717, "senden verloren called" ], [ - 717, + 721, "senden verloren returned " ], [ - 717, + 721, "senden dahinter called" ], [ - 959, + 962, "senden dahinter returned " ] ] diff --git a/packages/core/test/scenarios/arp-java-udpBehind.java.json b/packages/core/test/scenarios/arp-java-udpBehind.java.json index 2fd517f..b741160 100644 --- a/packages/core/test/scenarios/arp-java-udpBehind.java.json +++ b/packages/core/test/scenarios/arp-java-udpBehind.java.json @@ -2,7 +2,7 @@ "frames": { "00000000-0000-0000-0000-000000000301": [ { - "time": 724, + "time": 731, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -10,7 +10,7 @@ "targetIp": "10.0.0.9" }, { - "time": 3475, + "time": 3481, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -18,7 +18,7 @@ "targetIp": "10.0.0.9" }, { - "time": 6230, + "time": 6237, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -26,7 +26,7 @@ "targetIp": "10.0.0.1" }, { - "time": 6453, + "time": 6460, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "arp": 2, @@ -34,20 +34,20 @@ "targetIp": "10.0.0.2" }, { - "time": 6453, + "time": 6460, "source": "02:00:00:00:03:11", "destination": "02:00:00:00:03:21", "sourceIp": "10.0.0.2", "destinationIp": "20.0.0.2", "protocol": 17, - "sourcePort": 64055, + "sourcePort": 55273, "destinationPort": 9, "payload": "dahinter" } ], "00000000-0000-0000-0000-000000000302": [ { - "time": 846, + "time": 852, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -55,7 +55,7 @@ "targetIp": "10.0.0.9" }, { - "time": 3586, + "time": 3593, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -63,7 +63,7 @@ "targetIp": "10.0.0.9" }, { - "time": 6341, + "time": 6348, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -71,7 +71,7 @@ "targetIp": "10.0.0.1" }, { - "time": 6342, + "time": 6349, "source": "02:00:00:00:03:21", "destination": "02:00:00:00:03:11", "arp": 2, @@ -79,20 +79,20 @@ "targetIp": "10.0.0.2" }, { - "time": 6566, + "time": 6574, "source": "02:00:00:00:03:11", "destination": "02:00:00:00:03:21", "sourceIp": "10.0.0.2", "destinationIp": "20.0.0.2", "protocol": 17, - "sourcePort": 64055, + "sourcePort": 55273, "destinationPort": 9, "payload": "dahinter" } ], - "00000000-0000-0000-0000-000000000303": [ + "00000000-0000-0000-0000-000000000302#1": [ { - "time": 6622, + "time": 6574, "source": "02:00:00:00:03:22", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -100,7 +100,7 @@ "targetIp": "20.0.0.2" }, { - "time": 6622, + "time": 6685, "source": "02:00:00:00:03:13", "destination": "02:00:00:00:03:22", "arp": 2, @@ -108,13 +108,42 @@ "targetIp": "20.0.0.1" }, { - "time": 6733, + "time": 6685, "source": "02:00:00:00:03:22", "destination": "02:00:00:00:03:13", "sourceIp": "10.0.0.2", "destinationIp": "20.0.0.2", "protocol": 17, - "sourcePort": 64055, + "sourcePort": 55273, + "destinationPort": 9, + "payload": "dahinter" + } + ], + "00000000-0000-0000-0000-000000000303": [ + { + "time": 6629, + "source": "02:00:00:00:03:22", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "20.0.0.1", + "targetIp": "20.0.0.2" + }, + { + "time": 6629, + "source": "02:00:00:00:03:13", + "destination": "02:00:00:00:03:22", + "arp": 2, + "senderIp": "20.0.0.2", + "targetIp": "20.0.0.1" + }, + { + "time": 6741, + "source": "02:00:00:00:03:22", + "destination": "02:00:00:00:03:13", + "sourceIp": "10.0.0.2", + "destinationIp": "20.0.0.2", + "protocol": 17, + "sourcePort": 55273, "destinationPort": 9, "payload": "dahinter" } @@ -122,19 +151,19 @@ }, "events": [ [ - 716, + 723, "senden verloren called" ], [ - 720, + 727, "senden verloren returned " ], [ - 720, + 727, "senden dahinter called" ], [ - 6230, + 6237, "senden dahinter returned " ] ] diff --git a/packages/core/test/scenarios/arp-java-udpTwice.java.json b/packages/core/test/scenarios/arp-java-udpTwice.java.json index fe1e6c3..924786a 100644 --- a/packages/core/test/scenarios/arp-java-udpTwice.java.json +++ b/packages/core/test/scenarios/arp-java-udpTwice.java.json @@ -2,7 +2,7 @@ "frames": { "00000000-0000-0000-0000-000000000301": [ { - "time": 722, + "time": 723, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -18,7 +18,7 @@ "targetIp": "10.0.0.9" }, { - "time": 6228, + "time": 6229, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -26,7 +26,7 @@ "targetIp": "10.0.0.9" }, { - "time": 8978, + "time": 8979, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -36,7 +36,7 @@ ], "00000000-0000-0000-0000-000000000302": [ { - "time": 844, + "time": 843, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -52,7 +52,7 @@ "targetIp": "10.0.0.9" }, { - "time": 6339, + "time": 6340, "source": "02:00:00:00:03:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -68,6 +68,7 @@ "targetIp": "10.0.0.9" } ], + "00000000-0000-0000-0000-000000000302#1": [], "00000000-0000-0000-0000-000000000303": [] }, "events": [ @@ -84,7 +85,7 @@ "senden zwei called" ], [ - 6228, + 6229, "senden zwei returned " ] ] diff --git a/packages/core/test/scenarios/nat-java-forward.java.json b/packages/core/test/scenarios/nat-java-forward.java.json index f110e5b..f1d2d2f 100644 --- a/packages/core/test/scenarios/nat-java-forward.java.json +++ b/packages/core/test/scenarios/nat-java-forward.java.json @@ -2,7 +2,7 @@ "frames": { "00000000-0000-0000-0000-000000000501": [ { - "time": 1389, + "time": 1342, "source": "02:00:00:00:05:22", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -10,7 +10,7 @@ "targetIp": "192.168.0.10" }, { - "time": 1389, + "time": 1343, "source": "02:00:00:00:05:11", "destination": "02:00:00:00:05:22", "arp": 2, @@ -18,163 +18,163 @@ "targetIp": "192.168.0.1" }, { - "time": 1501, + "time": 1454, "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, + "sourcePort": 49255, "destinationPort": 80, "payload": null, "tcpFlags": "S", - "sequence": 2000000, + "sequence": 3000000, "acknowledgement": 0 }, { - "time": 1503, + "time": 1456, "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, + "destinationPort": 49255, "payload": null, "tcpFlags": "SA", - "sequence": 1000000, + "sequence": 2000000, + "acknowledgement": 3000001 + }, + { + "time": 1791, + "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": 49255, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 3000001, "acknowledgement": 2000001 }, { - "time": 1839, + "time": 1890, "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, + "sourcePort": 49255, "destinationPort": 80, "payload": "hello", "tcpFlags": "P", + "sequence": 3000001, + "acknowledgement": 0 + }, + { + "time": 1890, + "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": 49255, + "payload": null, + "tcpFlags": "A", + "sequence": 2000001, + "acknowledgement": 3000006 + }, + { + "time": 1946, + "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": 49255, + "payload": "reply 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, + "time": 2281, "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, + "sourcePort": 49255, "destinationPort": 80, "payload": null, "tcpFlags": "A", - "sequence": 2000006, - "acknowledgement": 1000012 + "sequence": 3000006, + "acknowledgement": 2000012 }, { - "time": 2359, + "time": 2337, "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, + "sourcePort": 49255, "destinationPort": 80, "payload": null, "tcpFlags": "F", - "sequence": 2000006, + "sequence": 3000006, "acknowledgement": 0 }, { - "time": 2359, + "time": 2337, "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, + "destinationPort": 49255, "payload": null, "tcpFlags": "A", - "sequence": 1000012, - "acknowledgement": 2000007 + "sequence": 2000012, + "acknowledgement": 3000007 }, { - "time": 2415, + "time": 2392, "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, + "destinationPort": 49255, "payload": null, "tcpFlags": "F", - "sequence": 1000012, + "sequence": 2000012, "acknowledgement": 0 }, { - "time": 2749, + "time": 2727, "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, + "sourcePort": 49255, "destinationPort": 80, "payload": null, "tcpFlags": "A", - "sequence": 2000007, - "acknowledgement": 1000013 + "sequence": 3000007, + "acknowledgement": 2000013 } ], "00000000-0000-0000-0000-000000000502": [ { - "time": 1101, + "time": 1057, "source": "02:00:00:00:05:41", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -182,7 +182,7 @@ "targetIp": "42.0.0.10" }, { - "time": 1104, + "time": 1058, "source": "02:00:00:00:05:21", "destination": "02:00:00:00:05:41", "arp": 2, @@ -190,163 +190,335 @@ "targetIp": "42.0.0.20" }, { - "time": 1333, + "time": 1286, "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, + "sourcePort": 49255, "destinationPort": 8080, "payload": null, "tcpFlags": "S", - "sequence": 2000000, + "sequence": 3000000, "acknowledgement": 0 }, { - "time": 1560, + "time": 1512, "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, + "destinationPort": 49255, "payload": null, "tcpFlags": "SA", - "sequence": 1000000, + "sequence": 2000000, + "acknowledgement": 3000001 + }, + { + "time": 1735, + "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": 49255, + "destinationPort": 8080, + "payload": null, + "tcpFlags": "A", + "sequence": 3000001, "acknowledgement": 2000001 }, { - "time": 1783, + "time": 1834, "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, + "sourcePort": 49255, "destinationPort": 8080, "payload": "hello", "tcpFlags": "P", + "sequence": 3000001, + "acknowledgement": 0 + }, + { + "time": 1946, + "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": 49255, + "payload": null, + "tcpFlags": "A", + "sequence": 2000001, + "acknowledgement": 3000006 + }, + { + "time": 2002, + "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": 49255, + "payload": "reply 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", + "time": 2225, + "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": 8080, - "destinationPort": 61267, + "sourcePort": 49255, + "destinationPort": 8080, "payload": null, "tcpFlags": "A", - "sequence": 1000001, - "acknowledgement": 2000006 + "sequence": 3000006, + "acknowledgement": 2000012 }, { - "time": 2025, + "time": 2281, + "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": 49255, + "destinationPort": 8080, + "payload": null, + "tcpFlags": "F", + "sequence": 3000006, + "acknowledgement": 0 + }, + { + "time": 2393, "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, + "destinationPort": 49255, + "payload": null, + "tcpFlags": "A", + "sequence": 2000012, + "acknowledgement": 3000007 + }, + { + "time": 2448, + "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": 49255, + "payload": null, + "tcpFlags": "F", + "sequence": 2000012, + "acknowledgement": 0 + }, + { + "time": 2671, + "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": 49255, + "destinationPort": 8080, + "payload": null, + "tcpFlags": "A", + "sequence": 3000007, + "acknowledgement": 2000013 + } + ], + "00000000-0000-0000-0000-000000000502#1": [ + { + "time": 1287, + "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": 1398, + "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": 1399, + "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": 49255, + "destinationPort": 80, + "payload": null, + "tcpFlags": "S", + "sequence": 3000000, + "acknowledgement": 0 + }, + { + "time": 1512, + "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": 49255, + "payload": null, + "tcpFlags": "SA", + "sequence": 2000000, + "acknowledgement": 3000001 + }, + { + "time": 1736, + "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": 49255, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 3000001, + "acknowledgement": 2000001 + }, + { + "time": 1834, + "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": 49255, + "destinationPort": 80, + "payload": "hello", + "tcpFlags": "P", + "sequence": 3000001, + "acknowledgement": 0 + }, + { + "time": 1946, + "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": 49255, + "payload": null, + "tcpFlags": "A", + "sequence": 2000001, + "acknowledgement": 3000006 + }, + { + "time": 2002, + "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": 49255, "payload": "reply hello", "tcpFlags": "P", - "sequence": 1000001, + "sequence": 2000001, "acknowledgement": 0 }, { - "time": 2248, - "source": "02:00:00:00:05:41", - "destination": "02:00:00:00:05:21", + "time": 2225, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", "sourceIp": "42.0.0.20", - "destinationIp": "42.0.0.10", + "destinationIp": "192.168.0.10", "protocol": 6, - "sourcePort": 61267, - "destinationPort": 8080, + "sourcePort": 49255, + "destinationPort": 80, "payload": null, "tcpFlags": "A", - "sequence": 2000006, - "acknowledgement": 1000012 + "sequence": 3000006, + "acknowledgement": 2000012 }, { - "time": 2303, - "source": "02:00:00:00:05:41", - "destination": "02:00:00:00:05:21", + "time": 2281, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", "sourceIp": "42.0.0.20", - "destinationIp": "42.0.0.10", + "destinationIp": "192.168.0.10", "protocol": 6, - "sourcePort": 61267, - "destinationPort": 8080, + "sourcePort": 49255, + "destinationPort": 80, "payload": null, "tcpFlags": "F", - "sequence": 2000006, + "sequence": 3000006, "acknowledgement": 0 }, { - "time": 2415, - "source": "02:00:00:00:05:21", - "destination": "02:00:00:00:05:41", - "sourceIp": "42.0.0.10", + "time": 2392, + "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": 8080, - "destinationPort": 61267, + "sourcePort": 80, + "destinationPort": 49255, "payload": null, "tcpFlags": "A", - "sequence": 1000012, - "acknowledgement": 2000007 + "sequence": 2000012, + "acknowledgement": 3000007 }, { - "time": 2471, - "source": "02:00:00:00:05:21", - "destination": "02:00:00:00:05:41", - "sourceIp": "42.0.0.10", + "time": 2448, + "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": 8080, - "destinationPort": 61267, + "sourcePort": 80, + "destinationPort": 49255, "payload": null, "tcpFlags": "F", - "sequence": 1000012, + "sequence": 2000012, "acknowledgement": 0 }, { - "time": 2693, - "source": "02:00:00:00:05:41", - "destination": "02:00:00:00:05:21", + "time": 2671, + "source": "02:00:00:00:05:22", + "destination": "02:00:00:00:05:11", "sourceIp": "42.0.0.20", - "destinationIp": "42.0.0.10", + "destinationIp": "192.168.0.10", "protocol": 6, - "sourcePort": 61267, - "destinationPort": 8080, + "sourcePort": 49255, + "destinationPort": 80, "payload": null, "tcpFlags": "A", - "sequence": 2000007, - "acknowledgement": 1000013 + "sequence": 3000007, + "acknowledgement": 2000013 } ], "00000000-0000-0000-0000-000000000504": [ { - "time": 965, + "time": 935, "source": "02:00:00:00:05:41", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -354,7 +526,7 @@ "targetIp": "42.0.0.10" }, { - "time": 1215, + "time": 1170, "source": "02:00:00:00:05:21", "destination": "02:00:00:00:05:41", "arp": 2, @@ -362,163 +534,163 @@ "targetIp": "42.0.0.20" }, { - "time": 1219, + "time": 1172, "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, + "sourcePort": 49255, "destinationPort": 8080, "payload": null, "tcpFlags": "S", - "sequence": 2000000, + "sequence": 3000000, "acknowledgement": 0 }, { - "time": 1671, + "time": 1624, "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, + "destinationPort": 49255, "payload": null, "tcpFlags": "SA", - "sequence": 1000000, + "sequence": 2000000, + "acknowledgement": 3000001 + }, + { + "time": 1624, + "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": 49255, + "destinationPort": 8080, + "payload": null, + "tcpFlags": "A", + "sequence": 3000001, "acknowledgement": 2000001 }, { - "time": 1671, + "time": 1723, "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, + "sourcePort": 49255, "destinationPort": 8080, "payload": "hello", "tcpFlags": "P", + "sequence": 3000001, + "acknowledgement": 0 + }, + { + "time": 2057, + "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": 49255, + "payload": null, + "tcpFlags": "A", + "sequence": 2000001, + "acknowledgement": 3000006 + }, + { + "time": 2113, + "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": 49255, + "payload": "reply 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, + "time": 2114, "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, + "sourcePort": 49255, "destinationPort": 8080, "payload": null, "tcpFlags": "A", - "sequence": 2000006, - "acknowledgement": 1000012 + "sequence": 3000006, + "acknowledgement": 2000012 }, { - "time": 2192, + "time": 2169, "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, + "sourcePort": 49255, "destinationPort": 8080, "payload": null, "tcpFlags": "F", - "sequence": 2000006, + "sequence": 3000006, "acknowledgement": 0 }, { - "time": 2526, + "time": 2504, "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, + "destinationPort": 49255, "payload": null, "tcpFlags": "A", - "sequence": 1000012, - "acknowledgement": 2000007 + "sequence": 2000012, + "acknowledgement": 3000007 }, { - "time": 2582, + "time": 2560, "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, + "destinationPort": 49255, "payload": null, "tcpFlags": "F", - "sequence": 1000012, + "sequence": 2000012, "acknowledgement": 0 }, { - "time": 2582, + "time": 2560, "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, + "sourcePort": 49255, "destinationPort": 8080, "payload": null, "tcpFlags": "A", - "sequence": 2000007, - "acknowledgement": 1000013 + "sequence": 3000007, + "acknowledgement": 2000013 } ], "00000000-0000-0000-0000-000000000505": [ { - "time": 1104, + "time": 1057, "source": "02:00:00:00:05:41", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -529,59 +701,59 @@ }, "events": [ [ - 745, + 719, "server oeffnen called" ], [ - 945, + 921, "client verbinden called" ], [ - 1746, + 1722, "client verbinden returned " ], [ - 1746, + 1722, "client senden called" ], [ - 1848, - "server oeffnen returned filius.software.transportschicht.TCPSocket@641fefcc" + 1820, + "server oeffnen returned filius.software.transportschicht.TCPSocket@290a67fb" ], [ - 1849, + 1820, "server empfangen called" ], [ - 1913, + 1890, "server empfangen returned hello" ], [ - 1914, + 1891, "server senden called" ], [ - 2081, + 2058, "client senden returned " ], [ - 2081, + 2058, "client empfangen called" ], [ - 2136, + 2114, "client empfangen returned reply hello" ], [ - 2136, + 2114, "client schliessen called" ], [ - 2137, + 2114, "client schliessen returned " ], [ - 2303, + 2281, "server senden returned " ] ], diff --git a/packages/core/test/scenarios/nat-java-pingOut.java.json b/packages/core/test/scenarios/nat-java-pingOut.java.json index 1e4bc8b..ea671e4 100644 --- a/packages/core/test/scenarios/nat-java-pingOut.java.json +++ b/packages/core/test/scenarios/nat-java-pingOut.java.json @@ -2,7 +2,7 @@ "frames": { "00000000-0000-0000-0000-000000000501": [ { - "time": 735, + "time": 717, "source": "02:00:00:00:05:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -10,7 +10,7 @@ "targetIp": "192.168.0.1" }, { - "time": 860, + "time": 837, "source": "02:00:00:00:05:22", "destination": "02:00:00:00:05:11", "arp": 2, @@ -18,7 +18,7 @@ "targetIp": "192.168.0.10" }, { - "time": 866, + "time": 841, "source": "02:00:00:00:05:11", "destination": "02:00:00:00:05:22", "icmp": 8, @@ -28,7 +28,7 @@ "sequence": 1 }, { - "time": 1444, + "time": 1409, "source": "02:00:00:00:05:22", "destination": "02:00:00:00:05:11", "icmp": 0, @@ -40,7 +40,7 @@ ], "00000000-0000-0000-0000-000000000502": [ { - "time": 932, + "time": 903, "source": "02:00:00:00:05:21", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -48,7 +48,7 @@ "targetIp": "42.0.0.20" }, { - "time": 1164, + "time": 1130, "source": "02:00:00:00:05:41", "destination": "02:00:00:00:05:21", "arp": 2, @@ -56,7 +56,7 @@ "targetIp": "42.0.0.10" }, { - "time": 1165, + "time": 1130, "source": "02:00:00:00:05:21", "destination": "02:00:00:00:05:41", "icmp": 8, @@ -66,7 +66,7 @@ "sequence": 1 }, { - "time": 1388, + "time": 1352, "source": "02:00:00:00:05:41", "destination": "02:00:00:00:05:21", "icmp": 0, @@ -76,9 +76,47 @@ "sequence": 1 } ], + "00000000-0000-0000-0000-000000000502#1": [ + { + "time": 780, + "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": 782, + "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": 898, + "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": 1353, + "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-000000000504": [ { - "time": 1052, + "time": 1018, "source": "02:00:00:00:05:21", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -86,7 +124,7 @@ "targetIp": "42.0.0.20" }, { - "time": 1052, + "time": 1018, "source": "02:00:00:00:05:41", "destination": "02:00:00:00:05:21", "arp": 2, @@ -94,7 +132,7 @@ "targetIp": "42.0.0.10" }, { - "time": 1276, + "time": 1241, "source": "02:00:00:00:05:21", "destination": "02:00:00:00:05:41", "icmp": 8, @@ -104,7 +142,7 @@ "sequence": 1 }, { - "time": 1276, + "time": 1241, "source": "02:00:00:00:05:41", "destination": "02:00:00:00:05:21", "icmp": 0, @@ -116,7 +154,7 @@ ], "00000000-0000-0000-0000-000000000505": [ { - "time": 1052, + "time": 1018, "source": "02:00:00:00:05:21", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -127,11 +165,11 @@ }, "events": [ [ - 730, + 713, "sendProbe 42.0.0.20 called" ], [ - 1445, + 1410, "sendProbe 42.0.0.20 returned ICMP 0/0 from 42.0.0.20" ] ], diff --git a/packages/core/test/scenarios/nat-java-pingWan.java.json b/packages/core/test/scenarios/nat-java-pingWan.java.json index 045169f..99fa067 100644 --- a/packages/core/test/scenarios/nat-java-pingWan.java.json +++ b/packages/core/test/scenarios/nat-java-pingWan.java.json @@ -3,7 +3,7 @@ "00000000-0000-0000-0000-000000000501": [], "00000000-0000-0000-0000-000000000502": [ { - "time": 849, + "time": 851, "source": "02:00:00:00:05:41", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -11,7 +11,7 @@ "targetIp": "42.0.0.10" }, { - "time": 851, + "time": 853, "source": "02:00:00:00:05:21", "destination": "02:00:00:00:05:41", "arp": 2, @@ -19,7 +19,7 @@ "targetIp": "42.0.0.20" }, { - "time": 1089, + "time": 1083, "source": "02:00:00:00:05:41", "destination": "02:00:00:00:05:21", "icmp": 8, @@ -29,7 +29,7 @@ "sequence": 1 }, { - "time": 1089, + "time": 1083, "source": "02:00:00:00:05:21", "destination": "02:00:00:00:05:41", "icmp": 0, @@ -39,7 +39,7 @@ "sequence": 1 }, { - "time": 1315, + "time": 1308, "source": "02:00:00:00:05:41", "destination": "02:00:00:00:05:21", "icmp": 8, @@ -49,9 +49,10 @@ "sequence": 2 } ], + "00000000-0000-0000-0000-000000000502#1": [], "00000000-0000-0000-0000-000000000504": [ { - "time": 727, + "time": 729, "source": "02:00:00:00:05:41", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -67,7 +68,7 @@ "targetIp": "42.0.0.20" }, { - "time": 970, + "time": 969, "source": "02:00:00:00:05:41", "destination": "02:00:00:00:05:21", "icmp": 8, @@ -77,7 +78,7 @@ "sequence": 1 }, { - "time": 1201, + "time": 1194, "source": "02:00:00:00:05:21", "destination": "02:00:00:00:05:41", "icmp": 0, @@ -87,7 +88,7 @@ "sequence": 1 }, { - "time": 1204, + "time": 1196, "source": "02:00:00:00:05:41", "destination": "02:00:00:00:05:21", "icmp": 8, @@ -99,7 +100,7 @@ ], "00000000-0000-0000-0000-000000000505": [ { - "time": 849, + "time": 851, "source": "02:00:00:00:05:41", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -110,19 +111,19 @@ }, "events": [ [ - 720, + 725, "sendProbe 42.0.0.10 called" ], [ - 1203, + 1196, "sendProbe 42.0.0.10 returned ICMP 0/0 from 42.0.0.10" ], [ - 1204, + 1196, "sendProbe 192.168.0.10 called" ], [ - 3954, + 3946, "sendProbe 192.168.0.10 returned null" ] ], diff --git a/packages/core/test/scenarios/nat-java-tcpOut.java.json b/packages/core/test/scenarios/nat-java-tcpOut.java.json index c644fe3..eb9a7e4 100644 --- a/packages/core/test/scenarios/nat-java-tcpOut.java.json +++ b/packages/core/test/scenarios/nat-java-tcpOut.java.json @@ -2,7 +2,7 @@ "frames": { "00000000-0000-0000-0000-000000000501": [ { - "time": 935, + "time": 943, "source": "02:00:00:00:05:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -10,7 +10,7 @@ "targetIp": "192.168.0.1" }, { - "time": 1054, + "time": 1063, "source": "02:00:00:00:05:22", "destination": "02:00:00:00:05:11", "arp": 2, @@ -18,163 +18,163 @@ "targetIp": "192.168.0.10" }, { - "time": 1056, + "time": 1066, "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, + "sourcePort": 49413, "destinationPort": 80, "payload": null, "tcpFlags": "S", - "sequence": 3000000, + "sequence": 2000000, "acknowledgement": 0 }, { - "time": 1622, + "time": 1633, "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, + "destinationPort": 49413, "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, + "sequence": 1000000, "acknowledgement": 2000001 }, { - "time": 1678, + "time": 1633, "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, + "sourcePort": 49413, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 2000001, + "acknowledgement": 1000001 + }, + { + "time": 1726, + "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": 49413, "destinationPort": 80, "payload": "hello", "tcpFlags": "P", - "sequence": 3000001, + "sequence": 2000001, "acknowledgement": 0 }, { - "time": 2012, + "time": 2061, "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, + "destinationPort": 49413, "payload": null, "tcpFlags": "A", - "sequence": 2000001, - "acknowledgement": 3000006 + "sequence": 1000001, + "acknowledgement": 2000006 }, { - "time": 2067, + "time": 2117, "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, + "destinationPort": 49413, "payload": "reply hello", "tcpFlags": "P", - "sequence": 2000001, + "sequence": 1000001, "acknowledgement": 0 }, { - "time": 2068, + "time": 2117, "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, + "sourcePort": 49413, "destinationPort": 80, "payload": null, "tcpFlags": "A", - "sequence": 3000006, - "acknowledgement": 2000012 + "sequence": 2000006, + "acknowledgement": 1000012 }, { - "time": 2123, + "time": 2173, "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, + "sourcePort": 49413, "destinationPort": 80, "payload": null, "tcpFlags": "F", - "sequence": 3000006, + "sequence": 2000006, "acknowledgement": 0 }, { - "time": 2457, + "time": 2507, "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, + "destinationPort": 49413, "payload": null, "tcpFlags": "A", - "sequence": 2000012, - "acknowledgement": 3000007 + "sequence": 1000012, + "acknowledgement": 2000007 }, { - "time": 2513, + "time": 2562, "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, + "destinationPort": 49413, "payload": null, "tcpFlags": "F", - "sequence": 2000012, + "sequence": 1000012, "acknowledgement": 0 }, { - "time": 2513, + "time": 2563, "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, + "sourcePort": 49413, "destinationPort": 80, "payload": null, "tcpFlags": "A", - "sequence": 3000007, - "acknowledgement": 2000013 + "sequence": 2000007, + "acknowledgement": 1000013 } ], "00000000-0000-0000-0000-000000000502": [ { - "time": 1115, + "time": 1124, "source": "02:00:00:00:05:21", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -182,7 +182,7 @@ "targetIp": "42.0.0.20" }, { - "time": 1341, + "time": 1352, "source": "02:00:00:00:05:41", "destination": "02:00:00:00:05:21", "arp": 2, @@ -190,163 +190,335 @@ "targetIp": "42.0.0.10" }, { - "time": 1341, + "time": 1352, "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, + "sourcePort": 65308, "destinationPort": 80, "payload": null, "tcpFlags": "S", - "sequence": 3000000, + "sequence": 2000000, "acknowledgement": 0 }, { - "time": 1566, + "time": 1577, "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, + "destinationPort": 65308, "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, + "sequence": 1000000, "acknowledgement": 2000001 }, { - "time": 1734, + "time": 1689, "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, + "sourcePort": 65308, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 2000001, + "acknowledgement": 1000001 + }, + { + "time": 1782, + "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": 65308, "destinationPort": 80, "payload": "hello", "tcpFlags": "P", - "sequence": 3000001, + "sequence": 2000001, "acknowledgement": 0 }, { - "time": 1956, + "time": 2005, "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, + "destinationPort": 65308, + "payload": null, + "tcpFlags": "A", + "sequence": 1000001, + "acknowledgement": 2000006 + }, + { + "time": 2061, + "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": 65308, + "payload": "reply hello", + "tcpFlags": "P", + "sequence": 1000001, + "acknowledgement": 0 + }, + { + "time": 2173, + "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": 65308, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 2000006, + "acknowledgement": 1000012 + }, + { + "time": 2229, + "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": 65308, + "destinationPort": 80, + "payload": null, + "tcpFlags": "F", + "sequence": 2000006, + "acknowledgement": 0 + }, + { + "time": 2451, + "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": 65308, + "payload": null, + "tcpFlags": "A", + "sequence": 1000012, + "acknowledgement": 2000007 + }, + { + "time": 2507, + "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": 65308, + "payload": null, + "tcpFlags": "F", + "sequence": 1000012, + "acknowledgement": 0 + }, + { + "time": 2619, + "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": 65308, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 2000007, + "acknowledgement": 1000013 + } + ], + "00000000-0000-0000-0000-000000000502#1": [ + { + "time": 1006, + "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": 1007, + "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": 1123, + "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": 49413, + "destinationPort": 80, + "payload": null, + "tcpFlags": "S", + "sequence": 2000000, + "acknowledgement": 0 + }, + { + "time": 1577, + "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": 49413, + "payload": null, + "tcpFlags": "SA", + "sequence": 1000000, + "acknowledgement": 2000001 + }, + { + "time": 1689, + "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": 49413, + "destinationPort": 80, "payload": null, "tcpFlags": "A", "sequence": 2000001, - "acknowledgement": 3000006 + "acknowledgement": 1000001 }, { - "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", + "time": 1782, + "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": 58632, - "payload": "reply hello", + "sourcePort": 49413, + "destinationPort": 80, + "payload": "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", + "time": 2005, + "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": 58632, - "destinationPort": 80, + "sourcePort": 80, + "destinationPort": 49413, "payload": null, "tcpFlags": "A", - "sequence": 3000006, - "acknowledgement": 2000012 + "sequence": 1000001, + "acknowledgement": 2000006 }, { - "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", + "time": 2061, + "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": 58632, - "destinationPort": 80, - "payload": null, - "tcpFlags": "F", - "sequence": 3000006, + "sourcePort": 80, + "destinationPort": 49413, + "payload": "reply hello", + "tcpFlags": "P", + "sequence": 1000001, "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", + "time": 2172, + "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": 58632, + "sourcePort": 49413, "destinationPort": 80, "payload": null, "tcpFlags": "A", - "sequence": 3000007, - "acknowledgement": 2000013 + "sequence": 2000006, + "acknowledgement": 1000012 + }, + { + "time": 2228, + "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": 49413, + "destinationPort": 80, + "payload": null, + "tcpFlags": "F", + "sequence": 2000006, + "acknowledgement": 0 + }, + { + "time": 2452, + "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": 49413, + "payload": null, + "tcpFlags": "A", + "sequence": 1000012, + "acknowledgement": 2000007 + }, + { + "time": 2507, + "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": 49413, + "payload": null, + "tcpFlags": "F", + "sequence": 1000012, + "acknowledgement": 0 + }, + { + "time": 2618, + "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": 49413, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 2000007, + "acknowledgement": 1000013 } ], "00000000-0000-0000-0000-000000000504": [ { - "time": 1230, + "time": 1240, "source": "02:00:00:00:05:21", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -354,7 +526,7 @@ "targetIp": "42.0.0.20" }, { - "time": 1230, + "time": 1240, "source": "02:00:00:00:05:41", "destination": "02:00:00:00:05:21", "arp": 2, @@ -362,163 +534,163 @@ "targetIp": "42.0.0.10" }, { - "time": 1453, + "time": 1464, "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, + "sourcePort": 65308, "destinationPort": 80, "payload": null, "tcpFlags": "S", - "sequence": 3000000, + "sequence": 2000000, "acknowledgement": 0 }, { - "time": 1455, + "time": 1466, "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, + "destinationPort": 65308, "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, + "sequence": 1000000, "acknowledgement": 2000001 }, { - "time": 1845, + "time": 1800, "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, + "sourcePort": 65308, + "destinationPort": 80, + "payload": null, + "tcpFlags": "A", + "sequence": 2000001, + "acknowledgement": 1000001 + }, + { + "time": 1894, + "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": 65308, "destinationPort": 80, "payload": "hello", "tcpFlags": "P", - "sequence": 3000001, + "sequence": 2000001, "acknowledgement": 0 }, { - "time": 1845, + "time": 1894, "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, + "destinationPort": 65308, "payload": null, "tcpFlags": "A", - "sequence": 2000001, - "acknowledgement": 3000006 + "sequence": 1000001, + "acknowledgement": 2000006 }, { - "time": 1901, + "time": 1949, "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, + "destinationPort": 65308, "payload": "reply hello", "tcpFlags": "P", - "sequence": 2000001, + "sequence": 1000001, "acknowledgement": 0 }, { - "time": 2235, + "time": 2284, "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, + "sourcePort": 65308, "destinationPort": 80, "payload": null, "tcpFlags": "A", - "sequence": 3000006, - "acknowledgement": 2000012 + "sequence": 2000006, + "acknowledgement": 1000012 }, { - "time": 2290, + "time": 2340, "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, + "sourcePort": 65308, "destinationPort": 80, "payload": null, "tcpFlags": "F", - "sequence": 3000006, + "sequence": 2000006, "acknowledgement": 0 }, { - "time": 2291, + "time": 2340, "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, + "destinationPort": 65308, "payload": null, "tcpFlags": "A", - "sequence": 2000012, - "acknowledgement": 3000007 + "sequence": 1000012, + "acknowledgement": 2000007 }, { - "time": 2346, + "time": 2396, "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, + "destinationPort": 65308, "payload": null, "tcpFlags": "F", - "sequence": 2000012, + "sequence": 1000012, "acknowledgement": 0 }, { - "time": 2680, + "time": 2730, "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, + "sourcePort": 65308, "destinationPort": 80, "payload": null, "tcpFlags": "A", - "sequence": 3000007, - "acknowledgement": 2000013 + "sequence": 2000007, + "acknowledgement": 1000013 } ], "00000000-0000-0000-0000-000000000505": [ { - "time": 1230, + "time": 1240, "source": "02:00:00:00:05:21", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -529,63 +701,63 @@ }, "events": [ [ - 719, + 725, "server oeffnen called" ], [ - 921, + 925, "client verbinden called" ], [ - 1623, + 1726, "client verbinden returned " ], [ - 1623, + 1726, "client senden called" ], [ - 1820, - "server oeffnen returned filius.software.transportschicht.TCPSocket@452d1e97" + 1829, + "server oeffnen returned filius.software.transportschicht.TCPSocket@678eb1ba" ], [ - 1820, + 1829, "server empfangen called" ], [ - 1845, + 1894, "server empfangen returned hello" ], [ - 1845, + 1894, "server senden called" ], [ - 2012, + 2061, "client senden returned " ], [ - 2012, + 2061, "client empfangen called" ], [ - 2068, + 2117, "client empfangen returned reply hello" ], [ - 2068, + 2117, "client schliessen called" ], [ - 2068, + 2117, "client schliessen returned " ], [ - 2235, + 2284, "server senden returned " ] ], "nat": [ - "6 42.0.0.20:58632 -> 192.168.0.10:64470 DynamicEntry" + "6 42.0.0.20:65308 -> 192.168.0.10:49413 DynamicEntry" ] } diff --git a/packages/core/test/scenarios/nat-java-udpOut.java.json b/packages/core/test/scenarios/nat-java-udpOut.java.json index 0920bc9..a2e3f47 100644 --- a/packages/core/test/scenarios/nat-java-udpOut.java.json +++ b/packages/core/test/scenarios/nat-java-udpOut.java.json @@ -2,7 +2,7 @@ "frames": { "00000000-0000-0000-0000-000000000501": [ { - "time": 923, + "time": 927, "source": "02:00:00:00:05:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -10,7 +10,7 @@ "targetIp": "192.168.0.1" }, { - "time": 1042, + "time": 1048, "source": "02:00:00:00:05:22", "destination": "02:00:00:00:05:11", "arp": 2, @@ -18,31 +18,31 @@ "targetIp": "192.168.0.10" }, { - "time": 1045, + "time": 1051, "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, + "sourcePort": 50152, "destinationPort": 7, "payload": "one" }, { - "time": 1614, + "time": 1620, "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, + "destinationPort": 50152, "payload": "pong one" } ], "00000000-0000-0000-0000-000000000502": [ { - "time": 1107, + "time": 1112, "source": "02:00:00:00:05:21", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -50,7 +50,7 @@ "targetIp": "42.0.0.20" }, { - "time": 1333, + "time": 1339, "source": "02:00:00:00:05:41", "destination": "02:00:00:00:05:21", "arp": 2, @@ -58,31 +58,71 @@ "targetIp": "42.0.0.10" }, { - "time": 1333, + "time": 1339, "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, + "sourcePort": 63618, "destinationPort": 7, "payload": "one" }, { - "time": 1558, + "time": 1564, "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, + "destinationPort": 63618, + "payload": "pong one" + } + ], + "00000000-0000-0000-0000-000000000502#1": [ + { + "time": 991, + "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": 992, + "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": 1108, + "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": 50152, + "destinationPort": 7, + "payload": "one" + }, + { + "time": 1564, + "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": 50152, "payload": "pong one" } ], "00000000-0000-0000-0000-000000000504": [ { - "time": 1221, + "time": 1227, "source": "02:00:00:00:05:21", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -90,7 +130,7 @@ "targetIp": "42.0.0.20" }, { - "time": 1221, + "time": 1227, "source": "02:00:00:00:05:41", "destination": "02:00:00:00:05:21", "arp": 2, @@ -98,31 +138,31 @@ "targetIp": "42.0.0.10" }, { - "time": 1445, + "time": 1450, "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, + "sourcePort": 63618, "destinationPort": 7, "payload": "one" }, { - "time": 1447, + "time": 1452, "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, + "destinationPort": 63618, "payload": "pong one" } ], "00000000-0000-0000-0000-000000000505": [ { - "time": 1221, + "time": 1227, "source": "02:00:00:00:05:21", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -133,27 +173,27 @@ }, "events": [ [ - 917, + 920, "senden 42.0.0.20 called" ], [ - 919, + 922, "senden 42.0.0.20 returned " ], [ - 919, + 922, "empfangen called" ], [ - 1447, + 1452, "server received one" ], [ - 1615, + 1620, "empfangen returned pong one" ] ], "nat": [ - "17 42.0.0.20:50801 -> 192.168.0.10:62293 DynamicEntry" + "17 42.0.0.20:63618 -> 192.168.0.10:50152 DynamicEntry" ] } diff --git a/packages/core/test/scenarios/nat-java-udpTwoRemotes.java.json b/packages/core/test/scenarios/nat-java-udpTwoRemotes.java.json index ca64414..2de16f8 100644 --- a/packages/core/test/scenarios/nat-java-udpTwoRemotes.java.json +++ b/packages/core/test/scenarios/nat-java-udpTwoRemotes.java.json @@ -24,36 +24,36 @@ "sourceIp": "192.168.0.10", "destinationIp": "42.0.0.20", "protocol": 17, - "sourcePort": 53169, + "sourcePort": 51562, "destinationPort": 7, "payload": "one" }, { - "time": 1612, + "time": 1615, "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, + "destinationPort": 51562, "payload": "pong one" }, { - "time": 1613, + "time": 1616, "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, + "sourcePort": 51562, "destinationPort": 7, "payload": "two" } ], "00000000-0000-0000-0000-000000000502": [ { - "time": 1105, + "time": 1106, "source": "02:00:00:00:05:21", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -61,7 +61,7 @@ "targetIp": "42.0.0.20" }, { - "time": 1331, + "time": 1334, "source": "02:00:00:00:05:41", "destination": "02:00:00:00:05:21", "arp": 2, @@ -69,29 +69,29 @@ "targetIp": "42.0.0.10" }, { - "time": 1331, + "time": 1334, "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, + "sourcePort": 60310, "destinationPort": 7, "payload": "one" }, { - "time": 1556, + "time": 1559, "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, + "destinationPort": 60310, "payload": "pong one" }, { - "time": 1669, + "time": 1672, "source": "02:00:00:00:05:21", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -99,7 +99,7 @@ "targetIp": "42.0.0.30" }, { - "time": 1892, + "time": 1895, "source": "02:00:00:00:05:51", "destination": "02:00:00:00:05:21", "arp": 2, @@ -107,31 +107,82 @@ "targetIp": "42.0.0.10" }, { - "time": 1892, + "time": 1896, "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, + "sourcePort": 60310, "destinationPort": 7, "payload": "two" }, { - "time": 2115, + "time": 2119, "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, + "destinationPort": 60310, "payload": "pong two" } ], + "00000000-0000-0000-0000-000000000502#1": [ + { + "time": 984, + "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": 985, + "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": 1101, + "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": 51562, + "destinationPort": 7, + "payload": "one" + }, + { + "time": 1560, + "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": 51562, + "payload": "pong one" + }, + { + "time": 1672, + "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": 51562, + "destinationPort": 7, + "payload": "two" + } + ], "00000000-0000-0000-0000-000000000504": [ { - "time": 1220, + "time": 1222, "source": "02:00:00:00:05:21", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -139,7 +190,7 @@ "targetIp": "42.0.0.20" }, { - "time": 1220, + "time": 1222, "source": "02:00:00:00:05:41", "destination": "02:00:00:00:05:21", "arp": 2, @@ -147,29 +198,29 @@ "targetIp": "42.0.0.10" }, { - "time": 1443, + "time": 1446, "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, + "sourcePort": 60310, "destinationPort": 7, "payload": "one" }, { - "time": 1445, + "time": 1448, "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, + "destinationPort": 60310, "payload": "pong one" }, { - "time": 1780, + "time": 1784, "source": "02:00:00:00:05:21", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -179,7 +230,7 @@ ], "00000000-0000-0000-0000-000000000505": [ { - "time": 1220, + "time": 1222, "source": "02:00:00:00:05:21", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -187,7 +238,7 @@ "targetIp": "42.0.0.20" }, { - "time": 1780, + "time": 1784, "source": "02:00:00:00:05:21", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -195,7 +246,7 @@ "targetIp": "42.0.0.30" }, { - "time": 1781, + "time": 1784, "source": "02:00:00:00:05:51", "destination": "02:00:00:00:05:21", "arp": 2, @@ -203,72 +254,72 @@ "targetIp": "42.0.0.10" }, { - "time": 2003, + "time": 2007, "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, + "sourcePort": 60310, "destinationPort": 7, "payload": "two" }, { - "time": 2003, + "time": 2007, "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, + "destinationPort": 60310, "payload": "pong two" } ] }, "events": [ [ - 916, + 915, "senden 42.0.0.20 called" ], [ - 918, + 917, "senden 42.0.0.20 returned " ], [ - 918, + 917, "empfangen called" ], [ - 1445, + 1448, "server received one" ], [ - 1613, + 1616, "empfangen returned pong one" ], [ - 1613, + 1616, "senden 42.0.0.30 called" ], [ - 1613, + 1616, "senden 42.0.0.30 returned " ], [ - 1613, + 1616, "empfangen called" ], [ - 2003, + 2007, "other server received two" ], [ - 15363, + 15366, "empfangen returned null" ] ], "nat": [ - "17 42.0.0.20:58343 -> 192.168.0.10:53169 DynamicEntry" + "17 42.0.0.20:60310 -> 192.168.0.10:51562 DynamicEntry" ] } diff --git a/packages/core/test/scenarios/rip-java-converge.java.json b/packages/core/test/scenarios/rip-java-converge.java.json index 2a370a9..b0bc4a4 100644 --- a/packages/core/test/scenarios/rip-java-converge.java.json +++ b/packages/core/test/scenarios/rip-java-converge.java.json @@ -2,7 +2,7 @@ "frames": { "00000000-0000-0000-0000-000000000401": [ { - "time": 1292, + "time": 1295, "source": "02:00:00:00:04:21", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.1.1", @@ -24,7 +24,7 @@ "payload": "10.0.1.1\n10.0.1.1\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.23.0 255.255.255.0 1" }, { - "time": 1411, + "time": 1412, "source": "02:00:00:00:04:21", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.1.1", @@ -72,7 +72,7 @@ "sequence": 1 }, { - "time": 45896, + "time": 45895, "source": "02:00:00:00:04:21", "destination": "02:00:00:00:04:11", "icmp": 0, @@ -82,7 +82,7 @@ "sequence": 1 }, { - "time": 58186, + "time": 58188, "source": "02:00:00:00:04:21", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.1.1", @@ -95,7 +95,7 @@ ], "00000000-0000-0000-0000-000000000402": [ { - "time": 1296, + "time": 1299, "source": "02:00:00:00:04:21", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.1.1", @@ -106,7 +106,7 @@ "payload": "10.0.1.1\n10.0.1.1\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.23.0 255.255.255.0 1" }, { - "time": 1355, + "time": 1356, "source": "02:00:00:00:04:21", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.1.1", @@ -117,7 +117,7 @@ "payload": "10.0.1.1\n10.0.1.1\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.23.0 255.255.255.0 1\n10.0.3.0 255.255.255.0 2" }, { - "time": 27345, + "time": 27346, "source": "02:00:00:00:04:21", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.1.1", @@ -128,7 +128,7 @@ "payload": "10.0.1.1\n10.0.1.1\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.23.0 255.255.255.0 1\n10.0.3.0 255.255.255.0 2" }, { - "time": 45058, + "time": 45057, "source": "02:00:00:00:04:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -136,7 +136,7 @@ "targetIp": "10.0.1.1" }, { - "time": 45059, + "time": 45058, "source": "02:00:00:00:04:21", "destination": "02:00:00:00:04:11", "arp": 2, @@ -144,7 +144,7 @@ "targetIp": "10.0.1.2" }, { - "time": 45173, + "time": 45172, "source": "02:00:00:00:04:11", "destination": "02:00:00:00:04:21", "icmp": 8, @@ -164,7 +164,7 @@ "sequence": 1 }, { - "time": 58130, + "time": 58132, "source": "02:00:00:00:04:21", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.1.1", @@ -175,9 +175,9 @@ "payload": "10.0.1.1\n10.0.1.1\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.23.0 255.255.255.0 1\n10.0.3.0 255.255.255.0 2" } ], - "00000000-0000-0000-0000-000000000403": [ + "00000000-0000-0000-0000-000000000402#1": [ { - "time": 1292, + "time": 1220, "source": "02:00:00:00:04:22", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.12.1", @@ -188,7 +188,144 @@ "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" }, { - "time": 1296, + "time": 1295, + "source": "02:00:00:00:04:31", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.2\n10.0.12.2\n16\n75000\n10.0.23.0 255.255.255.0 0" + }, + { + "time": 1300, + "source": "02:00:00:00:04:22", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" + }, + { + "time": 1356, + "source": "02:00:00:00:04:31", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.2\n10.0.12.2\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.3.0 255.255.255.0 1" + }, + { + "time": 1356, + "source": "02:00:00:00:04:22", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" + }, + { + "time": 27346, + "source": "02:00:00:00:04:22", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" + }, + { + "time": 29281, + "source": "02:00:00:00:04:31", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.2\n10.0.12.2\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.3.0 255.255.255.0 1" + }, + { + "time": 45172, + "source": "02:00:00:00:04:22", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "10.0.12.1", + "targetIp": "10.0.12.2" + }, + { + "time": 45283, + "source": "02:00:00:00:04:31", + "destination": "02:00:00:00:04:22", + "arp": 2, + "senderIp": "10.0.12.2", + "targetIp": "10.0.12.1" + }, + { + "time": 45284, + "source": "02:00:00:00:04:22", + "destination": "02:00:00:00:04:31", + "icmp": 8, + "icmpCode": 0, + "sourceIp": "10.0.1.2", + "destinationIp": "10.0.3.2", + "sequence": 1 + }, + { + "time": 45839, + "source": "02:00:00:00:04:31", + "destination": "02:00:00:00:04:22", + "icmp": 0, + "icmpCode": 0, + "sourceIp": "10.0.3.2", + "destinationIp": "10.0.1.2", + "sequence": 1 + }, + { + "time": 58132, + "source": "02:00:00:00:04:22", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" + } + ], + "00000000-0000-0000-0000-000000000403": [ + { + "time": 1220, + "source": "02:00:00:00:04:31", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.2\n10.0.12.2\n16\n75000\n10.0.23.0 255.255.255.0 0" + }, + { + "time": 1295, + "source": "02:00:00:00:04:22", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" + }, + { + "time": 1300, "source": "02:00:00:00:04:31", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.12.2", @@ -210,7 +347,7 @@ "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" }, { - "time": 1411, + "time": 1412, "source": "02:00:00:00:04:22", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.12.1", @@ -232,7 +369,7 @@ "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" }, { - "time": 29222, + "time": 29225, "source": "02:00:00:00:04:31", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.12.2", @@ -269,7 +406,7 @@ "sequence": 1 }, { - "time": 45785, + "time": 45784, "source": "02:00:00:00:04:31", "destination": "02:00:00:00:04:22", "icmp": 0, @@ -279,7 +416,7 @@ "sequence": 1 }, { - "time": 58186, + "time": 58188, "source": "02:00:00:00:04:22", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.12.1", @@ -290,20 +427,9 @@ "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" } ], - "00000000-0000-0000-0000-000000000404": [ + "00000000-0000-0000-0000-000000000403#1": [ { - "time": 1217, - "source": "02:00:00:00:04:41", - "destination": "FF:FF:FF:FF:FF:FF", - "sourceIp": "10.0.23.3", - "destinationIp": "255.255.255.255", - "protocol": 17, - "sourcePort": 521, - "destinationPort": 520, - "payload": "10.0.23.3\n10.0.23.3\n16\n75000\n10.0.3.0 255.255.255.0 0" - }, - { - "time": 1292, + "time": 1220, "source": "02:00:00:00:04:32", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.23.2", @@ -314,7 +440,7 @@ "payload": "10.0.23.2\n10.0.12.2\n16\n75000\n10.0.12.0 255.255.255.0 0" }, { - "time": 1296, + "time": 1295, "source": "02:00:00:00:04:41", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.23.3", @@ -325,7 +451,7 @@ "payload": "10.0.23.3\n10.0.23.3\n16\n75000\n10.0.3.0 255.255.255.0 0" }, { - "time": 1355, + "time": 1300, "source": "02:00:00:00:04:32", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.23.2", @@ -336,7 +462,7 @@ "payload": "10.0.23.2\n10.0.12.2\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.1.0 255.255.255.0 1" }, { - "time": 1355, + "time": 1356, "source": "02:00:00:00:04:41", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.23.3", @@ -347,7 +473,18 @@ "payload": "10.0.23.3\n10.0.23.3\n16\n75000\n10.0.3.0 255.255.255.0 0" }, { - "time": 29277, + "time": 1412, + "source": "02:00:00:00:04:41", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.3", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.3\n10.0.23.3\n16\n75000\n10.0.3.0 255.255.255.0 0" + }, + { + "time": 29225, "source": "02:00:00:00:04:32", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.23.2", @@ -358,7 +495,133 @@ "payload": "10.0.23.2\n10.0.12.2\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.1.0 255.255.255.0 1" }, { - "time": 31606, + "time": 31663, + "source": "02:00:00:00:04:41", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.3", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.3\n10.0.23.3\n16\n75000\n10.0.3.0 255.255.255.0 0" + }, + { + "time": 45339, + "source": "02:00:00:00:04:32", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "10.0.23.2", + "targetIp": "10.0.23.3" + }, + { + "time": 45450, + "source": "02:00:00:00:04:41", + "destination": "02:00:00:00:04:32", + "arp": 2, + "senderIp": "10.0.23.3", + "targetIp": "10.0.23.2" + }, + { + "time": 45450, + "source": "02:00:00:00:04:32", + "destination": "02:00:00:00:04:41", + "icmp": 8, + "icmpCode": 0, + "sourceIp": "10.0.1.2", + "destinationIp": "10.0.3.2", + "sequence": 1 + }, + { + "time": 45784, + "source": "02:00:00:00:04:41", + "destination": "02:00:00:00:04:32", + "icmp": 0, + "icmpCode": 0, + "sourceIp": "10.0.3.2", + "destinationIp": "10.0.1.2", + "sequence": 1 + }, + { + "time": 57852, + "source": "02:00:00:00:04:41", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.3", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.3\n10.0.23.3\n16\n75000\n10.0.3.0 255.255.255.0 0" + } + ], + "00000000-0000-0000-0000-000000000404": [ + { + "time": 1221, + "source": "02:00:00:00:04:41", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.3", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.3\n10.0.23.3\n16\n75000\n10.0.3.0 255.255.255.0 0" + }, + { + "time": 1295, + "source": "02:00:00:00:04:32", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.2\n10.0.12.2\n16\n75000\n10.0.12.0 255.255.255.0 0" + }, + { + "time": 1300, + "source": "02:00:00:00:04:41", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.3", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.3\n10.0.23.3\n16\n75000\n10.0.3.0 255.255.255.0 0" + }, + { + "time": 1356, + "source": "02:00:00:00:04:32", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.2\n10.0.12.2\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.1.0 255.255.255.0 1" + }, + { + "time": 1356, + "source": "02:00:00:00:04:41", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.3", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.3\n10.0.23.3\n16\n75000\n10.0.3.0 255.255.255.0 0" + }, + { + "time": 29281, + "source": "02:00:00:00:04:32", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.2\n10.0.12.2\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.1.0 255.255.255.0 1" + }, + { + "time": 31608, "source": "02:00:00:00:04:41", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.23.3", @@ -395,7 +658,7 @@ "sequence": 1 }, { - "time": 45729, + "time": 45728, "source": "02:00:00:00:04:41", "destination": "02:00:00:00:04:32", "icmp": 0, @@ -405,7 +668,7 @@ "sequence": 1 }, { - "time": 57795, + "time": 57796, "source": "02:00:00:00:04:41", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.23.3", @@ -416,9 +679,9 @@ "payload": "10.0.23.3\n10.0.23.3\n16\n75000\n10.0.3.0 255.255.255.0 0" } ], - "00000000-0000-0000-0000-000000000405": [ + "00000000-0000-0000-0000-000000000404#1": [ { - "time": 1292, + "time": 1221, "source": "02:00:00:00:04:42", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.3.1", @@ -429,7 +692,7 @@ "payload": "10.0.3.1\n10.0.23.3\n16\n75000\n10.0.23.0 255.255.255.0 0" }, { - "time": 1352, + "time": 1300, "source": "02:00:00:00:04:42", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.3.1", @@ -440,7 +703,7 @@ "payload": "10.0.3.1\n10.0.23.3\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.12.0 255.255.255.0 1" }, { - "time": 1411, + "time": 1356, "source": "02:00:00:00:04:42", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.3.1", @@ -451,7 +714,7 @@ "payload": "10.0.3.1\n10.0.23.3\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.12.0 255.255.255.0 1\n10.0.1.0 255.255.255.0 2" }, { - "time": 31662, + "time": 31608, "source": "02:00:00:00:04:42", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.3.1", @@ -462,7 +725,100 @@ "payload": "10.0.3.1\n10.0.23.3\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.12.0 255.255.255.0 1\n10.0.1.0 255.255.255.0 2" }, { - "time": 45562, + "time": 45506, + "source": "02:00:00:00:04:42", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "10.0.3.1", + "targetIp": "10.0.3.2" + }, + { + "time": 45617, + "source": "02:00:00:00:04:51", + "destination": "02:00:00:00:04:42", + "arp": 2, + "senderIp": "10.0.3.2", + "targetIp": "10.0.3.1" + }, + { + "time": 45617, + "source": "02:00:00:00:04:42", + "destination": "02:00:00:00:04:51", + "icmp": 8, + "icmpCode": 0, + "sourceIp": "10.0.1.2", + "destinationIp": "10.0.3.2", + "sequence": 1 + }, + { + "time": 45728, + "source": "02:00:00:00:04:51", + "destination": "02:00:00:00:04:42", + "icmp": 0, + "icmpCode": 0, + "sourceIp": "10.0.3.2", + "destinationIp": "10.0.1.2", + "sequence": 1 + }, + { + "time": 57797, + "source": "02:00:00:00:04:42", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.3.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.3.1\n10.0.23.3\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.12.0 255.255.255.0 1\n10.0.1.0 255.255.255.0 2" + } + ], + "00000000-0000-0000-0000-000000000405": [ + { + "time": 1295, + "source": "02:00:00:00:04:42", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.3.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.3.1\n10.0.23.3\n16\n75000\n10.0.23.0 255.255.255.0 0" + }, + { + "time": 1356, + "source": "02:00:00:00:04:42", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.3.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.3.1\n10.0.23.3\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.12.0 255.255.255.0 1" + }, + { + "time": 1412, + "source": "02:00:00:00:04:42", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.3.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.3.1\n10.0.23.3\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.12.0 255.255.255.0 1\n10.0.1.0 255.255.255.0 2" + }, + { + "time": 31664, + "source": "02:00:00:00:04:42", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.3.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.3.1\n10.0.23.3\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.12.0 255.255.255.0 1\n10.0.1.0 255.255.255.0 2" + }, + { + "time": 45561, "source": "02:00:00:00:04:42", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -478,7 +834,7 @@ "targetIp": "10.0.3.1" }, { - "time": 45673, + "time": 45672, "source": "02:00:00:00:04:42", "destination": "02:00:00:00:04:51", "icmp": 8, @@ -498,7 +854,7 @@ "sequence": 1 }, { - "time": 57850, + "time": 57854, "source": "02:00:00:00:04:42", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.3.1", @@ -512,56 +868,56 @@ }, "events": [ [ - 213, + 223, "seeded" ], [ - 45001, + 45000, "sendProbe 10.0.3.2 called" ], [ - 45897, + 45898, "sendProbe 10.0.3.2 returned ICMP 0/0 from 10.0.3.2" ] ], "tables": [ [ - 213, + 223, "00000000-0000-0000-0000-000000000402", "10.0.1.0/255.255.255.0 10.0.1.1 10.0.1.1 0; 10.0.12.0/255.255.255.0 10.0.12.1 10.0.12.1 0" ], [ - 213, + 223, "00000000-0000-0000-0000-000000000403", "10.0.12.0/255.255.255.0 10.0.12.2 10.0.12.2 0; 10.0.23.0/255.255.255.0 10.0.23.2 10.0.23.2 0" ], [ - 213, + 223, "00000000-0000-0000-0000-000000000404", "10.0.23.0/255.255.255.0 10.0.23.3 10.0.23.3 0; 10.0.3.0/255.255.255.0 10.0.3.1 10.0.3.1 0" ], [ - 1297, + 1300, "00000000-0000-0000-0000-000000000402", "10.0.1.0/255.255.255.0 10.0.1.1 10.0.1.1 0; 10.0.12.0/255.255.255.0 10.0.12.1 10.0.12.1 0; 10.0.23.0/255.255.255.0 10.0.12.2 10.0.12.1 1" ], [ - 1297, + 1300, "00000000-0000-0000-0000-000000000403", "10.0.12.0/255.255.255.0 10.0.12.2 10.0.12.2 0; 10.0.23.0/255.255.255.0 10.0.23.2 10.0.23.2 0; 10.0.1.0/255.255.255.0 10.0.12.1 10.0.12.2 1; 10.0.3.0/255.255.255.0 10.0.23.3 10.0.23.2 1" ], [ - 1297, + 1300, "00000000-0000-0000-0000-000000000404", "10.0.23.0/255.255.255.0 10.0.23.3 10.0.23.3 0; 10.0.3.0/255.255.255.0 10.0.3.1 10.0.3.1 0; 10.0.12.0/255.255.255.0 10.0.23.2 10.0.23.3 1" ], [ - 1357, + 1358, "00000000-0000-0000-0000-000000000402", "10.0.1.0/255.255.255.0 10.0.1.1 10.0.1.1 0; 10.0.12.0/255.255.255.0 10.0.12.1 10.0.12.1 0; 10.0.23.0/255.255.255.0 10.0.12.2 10.0.12.1 1; 10.0.3.0/255.255.255.0 10.0.12.2 10.0.12.1 2" ], [ - 1357, + 1358, "00000000-0000-0000-0000-000000000404", "10.0.23.0/255.255.255.0 10.0.23.3 10.0.23.3 0; 10.0.3.0/255.255.255.0 10.0.3.1 10.0.3.1 0; 10.0.12.0/255.255.255.0 10.0.23.2 10.0.23.3 1; 10.0.1.0/255.255.255.0 10.0.23.2 10.0.23.3 2" ] diff --git a/packages/core/test/scenarios/rip-java-expire.java.json b/packages/core/test/scenarios/rip-java-expire.java.json index 7f36140..6add250 100644 --- a/packages/core/test/scenarios/rip-java-expire.java.json +++ b/packages/core/test/scenarios/rip-java-expire.java.json @@ -24,7 +24,7 @@ "payload": "10.0.1.1\n10.0.1.1\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.23.0 255.255.255.0 1" }, { - "time": 1409, + "time": 1412, "source": "02:00:00:00:04:21", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.1.1", @@ -35,7 +35,7 @@ "payload": "10.0.1.1\n10.0.1.1\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.23.0 255.255.255.0 1\n10.0.3.0 255.255.255.0 2" }, { - "time": 27398, + "time": 27402, "source": "02:00:00:00:04:21", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.1.1", @@ -46,7 +46,7 @@ "payload": "10.0.1.1\n10.0.1.1\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.23.0 255.255.255.0 1\n10.0.3.0 255.255.255.0 2" }, { - "time": 58184, + "time": 58188, "source": "02:00:00:00:04:21", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.1.1", @@ -116,6 +116,17 @@ } ], "00000000-0000-0000-0000-000000000402": [ + { + "time": 1217, + "source": "02:00:00:00:04:21", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.1.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.1.1\n10.0.1.1\n16\n75000\n10.0.12.0 255.255.255.0 0" + }, { "time": 1297, "source": "02:00:00:00:04:21", @@ -128,7 +139,7 @@ "payload": "10.0.1.1\n10.0.1.1\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.23.0 255.255.255.0 1" }, { - "time": 1353, + "time": 1356, "source": "02:00:00:00:04:21", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.1.1", @@ -139,7 +150,7 @@ "payload": "10.0.1.1\n10.0.1.1\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.23.0 255.255.255.0 1\n10.0.3.0 255.255.255.0 2" }, { - "time": 27343, + "time": 27346, "source": "02:00:00:00:04:21", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.1.1", @@ -150,7 +161,7 @@ "payload": "10.0.1.1\n10.0.1.1\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.23.0 255.255.255.0 1\n10.0.3.0 255.255.255.0 2" }, { - "time": 58129, + "time": 58132, "source": "02:00:00:00:04:21", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.1.1", @@ -183,7 +194,7 @@ "payload": "10.0.1.1\n10.0.1.1\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.23.0 255.255.255.0 1\n10.0.3.0 255.255.255.0 16" }, { - "time": 125058, + "time": 125057, "source": "02:00:00:00:04:11", "destination": "FF:FF:FF:FF:FF:FF", "arp": 1, @@ -191,7 +202,7 @@ "targetIp": "10.0.1.1" }, { - "time": 125059, + "time": 125058, "source": "02:00:00:00:04:21", "destination": "02:00:00:00:04:11", "arp": 2, @@ -199,7 +210,7 @@ "targetIp": "10.0.1.2" }, { - "time": 125173, + "time": 125172, "source": "02:00:00:00:04:11", "destination": "02:00:00:00:04:21", "icmp": 8, @@ -209,7 +220,7 @@ "sequence": 1 }, { - "time": 125173, + "time": 125172, "source": "02:00:00:00:04:21", "destination": "02:00:00:00:04:11", "icmp": 3, @@ -219,9 +230,20 @@ "sequence": 0 } ], - "00000000-0000-0000-0000-000000000403": [ + "00000000-0000-0000-0000-000000000402#1": [ { - "time": 1218, + "time": 1217, + "source": "02:00:00:00:04:22", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" + }, + { + "time": 1293, "source": "02:00:00:00:04:31", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.12.2", @@ -231,6 +253,129 @@ "destinationPort": 520, "payload": "10.0.12.2\n10.0.12.2\n16\n75000\n10.0.23.0 255.255.255.0 0" }, + { + "time": 1297, + "source": "02:00:00:00:04:22", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" + }, + { + "time": 1356, + "source": "02:00:00:00:04:31", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.2\n10.0.12.2\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.3.0 255.255.255.0 1" + }, + { + "time": 1357, + "source": "02:00:00:00:04:22", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" + }, + { + "time": 27346, + "source": "02:00:00:00:04:22", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" + }, + { + "time": 29278, + "source": "02:00:00:00:04:31", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.2\n10.0.12.2\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.3.0 255.255.255.0 1" + }, + { + "time": 58132, + "source": "02:00:00:00:04:22", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" + }, + { + "time": 61329, + "source": "02:00:00:00:04:31", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.2\n10.0.12.2\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.3.0 255.255.255.0 1" + }, + { + "time": 86748, + "source": "02:00:00:00:04:31", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.2\n10.0.12.2\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.3.0 255.255.255.0 16" + }, + { + "time": 86749, + "source": "02:00:00:00:04:22", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" + }, + { + "time": 113405, + "source": "02:00:00:00:04:22", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" + }, + { + "time": 114396, + "source": "02:00:00:00:04:31", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.12.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.12.2\n10.0.12.2\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.3.0 255.255.255.0 16" + } + ], + "00000000-0000-0000-0000-000000000403": [ { "time": 1293, "source": "02:00:00:00:04:22", @@ -254,7 +399,7 @@ "payload": "10.0.12.2\n10.0.12.2\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.3.0 255.255.255.0 1" }, { - "time": 1353, + "time": 1356, "source": "02:00:00:00:04:22", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.12.1", @@ -265,7 +410,7 @@ "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" }, { - "time": 1409, + "time": 1412, "source": "02:00:00:00:04:22", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.12.1", @@ -276,7 +421,7 @@ "payload": "10.0.12.1\n10.0.1.1\n16\n75000\n10.0.1.0 255.255.255.0 0" }, { - "time": 27398, + "time": 27402, "source": "02:00:00:00:04:22", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.12.1", @@ -298,7 +443,7 @@ "payload": "10.0.12.2\n10.0.12.2\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.3.0 255.255.255.0 1" }, { - "time": 58184, + "time": 58188, "source": "02:00:00:00:04:22", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.12.1", @@ -320,7 +465,7 @@ "payload": "10.0.12.2\n10.0.12.2\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.3.0 255.255.255.0 1" }, { - "time": 86692, + "time": 86693, "source": "02:00:00:00:04:31", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.12.2", @@ -364,6 +509,107 @@ "payload": "10.0.12.2\n10.0.12.2\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.3.0 255.255.255.0 16" } ], + "00000000-0000-0000-0000-000000000403#1": [ + { + "time": 1217, + "source": "02:00:00:00:04:32", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.2\n10.0.12.2\n16\n75000\n10.0.12.0 255.255.255.0 0" + }, + { + "time": 1293, + "source": "02:00:00:00:04:41", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.3", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.3\n10.0.23.3\n16\n75000\n10.0.3.0 255.255.255.0 0" + }, + { + "time": 1298, + "source": "02:00:00:00:04:32", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.2\n10.0.12.2\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.1.0 255.255.255.0 1" + }, + { + "time": 1356, + "source": "02:00:00:00:04:41", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.3", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.3\n10.0.23.3\n16\n75000\n10.0.3.0 255.255.255.0 0" + }, + { + "time": 1412, + "source": "02:00:00:00:04:41", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.3", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.3\n10.0.23.3\n16\n75000\n10.0.3.0 255.255.255.0 0" + }, + { + "time": 29222, + "source": "02:00:00:00:04:32", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.2\n10.0.12.2\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.1.0 255.255.255.0 1" + }, + { + "time": 61273, + "source": "02:00:00:00:04:32", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.2\n10.0.12.2\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.1.0 255.255.255.0 1" + }, + { + "time": 86693, + "source": "02:00:00:00:04:32", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.2\n10.0.12.2\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.1.0 255.255.255.0 1" + }, + { + "time": 114340, + "source": "02:00:00:00:04:32", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.23.2", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.23.2\n10.0.12.2\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.1.0 255.255.255.0 1" + } + ], "00000000-0000-0000-0000-000000000404": [ { "time": 1293, @@ -388,7 +634,7 @@ "payload": "10.0.23.3\n10.0.23.3\n16\n75000\n10.0.3.0 255.255.255.0 0" }, { - "time": 1353, + "time": 1356, "source": "02:00:00:00:04:32", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.23.2", @@ -399,7 +645,7 @@ "payload": "10.0.23.2\n10.0.12.2\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.1.0 255.255.255.0 1" }, { - "time": 1354, + "time": 1356, "source": "02:00:00:00:04:41", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.23.3", @@ -454,6 +700,41 @@ "payload": "10.0.23.2\n10.0.12.2\n16\n75000\n10.0.12.0 255.255.255.0 0\n10.0.1.0 255.255.255.0 1" } ], + "00000000-0000-0000-0000-000000000404#1": [ + { + "time": 1217, + "source": "02:00:00:00:04:42", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.3.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.3.1\n10.0.23.3\n16\n75000\n10.0.23.0 255.255.255.0 0" + }, + { + "time": 1297, + "source": "02:00:00:00:04:42", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.3.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.3.1\n10.0.23.3\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.12.0 255.255.255.0 1" + }, + { + "time": 1357, + "source": "02:00:00:00:04:42", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "10.0.3.1", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 521, + "destinationPort": 520, + "payload": "10.0.3.1\n10.0.23.3\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.12.0 255.255.255.0 1\n10.0.1.0 255.255.255.0 2" + } + ], "00000000-0000-0000-0000-000000000405": [ { "time": 1293, @@ -467,7 +748,7 @@ "payload": "10.0.3.1\n10.0.23.3\n16\n75000\n10.0.23.0 255.255.255.0 0" }, { - "time": 1353, + "time": 1356, "source": "02:00:00:00:04:42", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.3.1", @@ -478,7 +759,7 @@ "payload": "10.0.3.1\n10.0.23.3\n16\n75000\n10.0.23.0 255.255.255.0 0\n10.0.12.0 255.255.255.0 1" }, { - "time": 1409, + "time": 1412, "source": "02:00:00:00:04:42", "destination": "FF:FF:FF:FF:FF:FF", "sourceIp": "10.0.3.1", @@ -492,11 +773,11 @@ }, "events": [ [ - 216, + 212, "seeded" ], [ - 10000, + 10001, "R3 silent" ], [ @@ -504,53 +785,53 @@ "sendProbe 10.0.3.2 called" ], [ - 125233, + 125229, "sendProbe 10.0.3.2 returned ICMP 3/0 from 10.0.1.1" ] ], "tables": [ [ - 218, + 213, "00000000-0000-0000-0000-000000000402", "10.0.1.0/255.255.255.0 10.0.1.1 10.0.1.1 0; 10.0.12.0/255.255.255.0 10.0.12.1 10.0.12.1 0" ], [ - 218, + 213, "00000000-0000-0000-0000-000000000403", "10.0.12.0/255.255.255.0 10.0.12.2 10.0.12.2 0; 10.0.23.0/255.255.255.0 10.0.23.2 10.0.23.2 0" ], [ - 218, + 213, "00000000-0000-0000-0000-000000000404", "10.0.23.0/255.255.255.0 10.0.23.3 10.0.23.3 0; 10.0.3.0/255.255.255.0 10.0.3.1 10.0.3.1 0" ], [ - 1299, + 1298, "00000000-0000-0000-0000-000000000402", "10.0.1.0/255.255.255.0 10.0.1.1 10.0.1.1 0; 10.0.12.0/255.255.255.0 10.0.12.1 10.0.12.1 0; 10.0.23.0/255.255.255.0 10.0.12.2 10.0.12.1 1" ], [ - 1299, + 1298, "00000000-0000-0000-0000-000000000403", "10.0.12.0/255.255.255.0 10.0.12.2 10.0.12.2 0; 10.0.23.0/255.255.255.0 10.0.23.2 10.0.23.2 0; 10.0.1.0/255.255.255.0 10.0.12.1 10.0.12.2 1; 10.0.3.0/255.255.255.0 10.0.23.3 10.0.23.2 1" ], [ - 1299, + 1298, "00000000-0000-0000-0000-000000000404", "10.0.23.0/255.255.255.0 10.0.23.3 10.0.23.3 0; 10.0.3.0/255.255.255.0 10.0.3.1 10.0.3.1 0; 10.0.12.0/255.255.255.0 10.0.23.2 10.0.23.3 1" ], [ - 1354, + 1358, "00000000-0000-0000-0000-000000000402", "10.0.1.0/255.255.255.0 10.0.1.1 10.0.1.1 0; 10.0.12.0/255.255.255.0 10.0.12.1 10.0.12.1 0; 10.0.23.0/255.255.255.0 10.0.12.2 10.0.12.1 1; 10.0.3.0/255.255.255.0 10.0.12.2 10.0.12.1 2" ], [ - 1354, + 1358, "00000000-0000-0000-0000-000000000404", "10.0.23.0/255.255.255.0 10.0.23.3 10.0.23.3 0; 10.0.3.0/255.255.255.0 10.0.3.1 10.0.3.1 0; 10.0.12.0/255.255.255.0 10.0.23.2 10.0.23.3 1; 10.0.1.0/255.255.255.0 10.0.23.2 10.0.23.3 2" ], [ - 86694, + 86693, "00000000-0000-0000-0000-000000000403", "10.0.12.0/255.255.255.0 10.0.12.2 10.0.12.2 0; 10.0.23.0/255.255.255.0 10.0.23.2 10.0.23.2 0; 10.0.1.0/255.255.255.0 10.0.12.1 10.0.12.2 1; 10.0.3.0/255.255.255.0 10.0.23.3 10.0.23.2 16" ], diff --git a/tools/java-oracle/README.md b/tools/java-oracle/README.md index 2a2db27..3a928c4 100644 --- a/tools/java-oracle/README.md +++ b/tools/java-oracle/README.md @@ -390,6 +390,12 @@ Port an 42.0.0.30), `tcpOut`, `forward` (von 42.0.0.20 an 42.0.0.10:8080), 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. +`ScenarioNetwork` schreibt seit F2.6 die Frames **jeder** Karte eines Knotens +(die erste unter der Knoten-ID, weitere unter `id#index`); vorher nur die +erste, so dass bei Routern und Heimroutern die zweite Karte fehlte. Die +ARP-, RIP- und NAT-Läufe sind damit neu aufgenommen; die übrigen Knoten haben +nur eine Karte. + Gemessen (30.09.2026), was der Heimrouter tut (`NatGateway`, dessen Threads zwischen Karte und Ethernet-Schicht sitzen): diff --git a/tools/java-oracle/src/ScenarioNetwork.java b/tools/java-oracle/src/ScenarioNetwork.java index 51e4d3e..b4c6956 100644 --- a/tools/java-oracle/src/ScenarioNetwork.java +++ b/tools/java-oracle/src/ScenarioNetwork.java @@ -48,6 +48,7 @@ import java.util.TreeMap; public class ScenarioNetwork { final Map nodes = new LinkedHashMap<>(); + /** Each card's MAC address, under its node's id (the first card) or `id#index` (the others). */ final Map macByNode = new LinkedHashMap<>(); final List servers = new ArrayList<>(); long start; @@ -109,7 +110,7 @@ public class ScenarioNetwork { nic.setMac(mac); ports.put((String) port.get("id"), nic.getPort()); nicsByPort.put((String) port.get("id"), nic); - if (index == 0) macByNode.put(id, mac); + macByNode.put(index == 0 ? id : id + "#" + index, mac); } } else { LinkedList switchPorts = ((LokalerKnoten) knoten).getAnschluesse();