feat(core): packet capture per card after Java's Lauscher, measured card by card

The engine keeps Java's packet capture (capture.ts): per network card
every frame it sent (when it leaves on the cable) or received (also one
for another card), once, with time and number; switches log nothing;
frames the packet loss dropped are kept apart; the capture outlives a
stop and a new start, as in Java, until clearCapture. Per port instead
of per MAC, at most 10,000 frames a card.

expectSameCaptures compares each card's capture with Java's list of that
card in the ARP, WLAN, DNS, TCP, NAT, RIP and single-client DHCP runs.
It found that ScenarioNetwork ignored a switch's learning time (Java ran
300 s, the core the scenarios' 5 s); the oracle sets it now, and the TCP
and DHCP runs are recorded again. A core test found that a new start
numbers frames from 1 again and the capture took them as seen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-01 08:53:37 +00:00
co-authored by Claude Opus 5.5
parent 65ccd9ddd7
commit 088b62469f
24 changed files with 796 additions and 344 deletions
@@ -2,7 +2,7 @@
"frames": {
"00000000-0000-0000-0000-000000000101": [
{
"time": 854,
"time": 853,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"arp": 1,
@@ -24,7 +24,7 @@
"sourceIp": "192.168.0.20",
"destinationIp": "192.168.0.10",
"protocol": 6,
"sourcePort": 61897,
"sourcePort": 51723,
"destinationPort": 80,
"payload": null,
"tcpFlags": "S",
@@ -32,27 +32,27 @@
"acknowledgement": 0
},
{
"time": 1084,
"time": 1085,
"source": "02:00:00:00:01:11",
"destination": "02:00:00:00:01:12",
"sourceIp": "192.168.0.10",
"destinationIp": "192.168.0.20",
"protocol": 6,
"sourcePort": 80,
"destinationPort": 61897,
"destinationPort": 51723,
"payload": null,
"tcpFlags": "SA",
"sequence": 1000000,
"acknowledgement": 2000001
},
{
"time": 1307,
"time": 1308,
"source": "02:00:00:00:01:12",
"destination": "02:00:00:00:01:11",
"sourceIp": "192.168.0.20",
"destinationIp": "192.168.0.10",
"protocol": 6,
"sourcePort": 61897,
"sourcePort": 51723,
"destinationPort": 80,
"payload": null,
"tcpFlags": "A",
@@ -60,13 +60,13 @@
"acknowledgement": 1000001
},
{
"time": 26579,
"time": 26578,
"source": "02:00:00:00:01:12",
"destination": "02:00:00:00:01:11",
"sourceIp": "192.168.0.20",
"destinationIp": "192.168.0.10",
"protocol": 6,
"sourcePort": 61897,
"sourcePort": 51723,
"destinationPort": 80,
"payload": null,
"tcpFlags": "F",
@@ -74,41 +74,41 @@
"acknowledgement": 0
},
{
"time": 26579,
"time": 26578,
"source": "02:00:00:00:01:11",
"destination": "02:00:00:00:01:12",
"sourceIp": "192.168.0.10",
"destinationIp": "192.168.0.20",
"protocol": 6,
"sourcePort": 80,
"destinationPort": 61897,
"destinationPort": 51723,
"payload": null,
"tcpFlags": "A",
"sequence": 1000001,
"acknowledgement": 2000010
},
{
"time": 26635,
"time": 26634,
"source": "02:00:00:00:01:11",
"destination": "02:00:00:00:01:12",
"sourceIp": "192.168.0.10",
"destinationIp": "192.168.0.20",
"protocol": 6,
"sourcePort": 80,
"destinationPort": 61897,
"destinationPort": 51723,
"payload": null,
"tcpFlags": "F",
"sequence": 1000001,
"acknowledgement": 0
},
{
"time": 26858,
"time": 26856,
"source": "02:00:00:00:01:12",
"destination": "02:00:00:00:01:11",
"sourceIp": "192.168.0.20",
"destinationIp": "192.168.0.10",
"protocol": 6,
"sourcePort": 61897,
"sourcePort": 51723,
"destinationPort": 80,
"payload": null,
"tcpFlags": "A",
@@ -118,7 +118,7 @@
],
"00000000-0000-0000-0000-000000000102": [
{
"time": 731,
"time": 729,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"arp": 1,
@@ -126,7 +126,7 @@
"targetIp": "192.168.0.10"
},
{
"time": 967,
"time": 966,
"source": "02:00:00:00:01:11",
"destination": "02:00:00:00:01:12",
"arp": 2,
@@ -140,7 +140,7 @@
"sourceIp": "192.168.0.20",
"destinationIp": "192.168.0.10",
"protocol": 6,
"sourcePort": 61897,
"sourcePort": 51723,
"destinationPort": 80,
"payload": null,
"tcpFlags": "S",
@@ -155,20 +155,20 @@
"destinationIp": "192.168.0.20",
"protocol": 6,
"sourcePort": 80,
"destinationPort": 61897,
"destinationPort": 51723,
"payload": null,
"tcpFlags": "SA",
"sequence": 1000000,
"acknowledgement": 2000001
},
{
"time": 1196,
"time": 1197,
"source": "02:00:00:00:01:12",
"destination": "02:00:00:00:01:11",
"sourceIp": "192.168.0.20",
"destinationIp": "192.168.0.10",
"protocol": 6,
"sourcePort": 61897,
"sourcePort": 51723,
"destinationPort": 80,
"payload": null,
"tcpFlags": "A",
@@ -176,13 +176,13 @@
"acknowledgement": 1000001
},
{
"time": 1717,
"time": 1716,
"source": "02:00:00:00:01:12",
"destination": "02:00:00:00:01:11",
"sourceIp": "192.168.0.20",
"destinationIp": "192.168.0.10",
"protocol": 6,
"sourcePort": 61897,
"sourcePort": 51723,
"destinationPort": 80,
"payload": "verloren",
"tcpFlags": "P",
@@ -190,13 +190,13 @@
"acknowledgement": 0
},
{
"time": 9967,
"time": 9966,
"source": "02:00:00:00:01:12",
"destination": "02:00:00:00:01:11",
"sourceIp": "192.168.0.20",
"destinationIp": "192.168.0.10",
"protocol": 6,
"sourcePort": 61897,
"sourcePort": 51723,
"destinationPort": 80,
"payload": "verloren",
"tcpFlags": "P",
@@ -204,13 +204,13 @@
"acknowledgement": 0
},
{
"time": 18217,
"time": 18216,
"source": "02:00:00:00:01:12",
"destination": "02:00:00:00:01:11",
"sourceIp": "192.168.0.20",
"destinationIp": "192.168.0.10",
"protocol": 6,
"sourcePort": 61897,
"sourcePort": 51723,
"destinationPort": 80,
"payload": "verloren",
"tcpFlags": "P",
@@ -224,7 +224,7 @@
"sourceIp": "192.168.0.20",
"destinationIp": "192.168.0.10",
"protocol": 6,
"sourcePort": 61897,
"sourcePort": 51723,
"destinationPort": 80,
"payload": null,
"tcpFlags": "F",
@@ -232,41 +232,41 @@
"acknowledgement": 0
},
{
"time": 26691,
"time": 26690,
"source": "02:00:00:00:01:11",
"destination": "02:00:00:00:01:12",
"sourceIp": "192.168.0.10",
"destinationIp": "192.168.0.20",
"protocol": 6,
"sourcePort": 80,
"destinationPort": 61897,
"destinationPort": 51723,
"payload": null,
"tcpFlags": "A",
"sequence": 1000001,
"acknowledgement": 2000010
},
{
"time": 26746,
"time": 26745,
"source": "02:00:00:00:01:11",
"destination": "02:00:00:00:01:12",
"sourceIp": "192.168.0.10",
"destinationIp": "192.168.0.20",
"protocol": 6,
"sourcePort": 80,
"destinationPort": 61897,
"destinationPort": 51723,
"payload": null,
"tcpFlags": "F",
"sequence": 1000001,
"acknowledgement": 0
},
{
"time": 26747,
"time": 26745,
"source": "02:00:00:00:01:12",
"destination": "02:00:00:00:01:11",
"sourceIp": "192.168.0.20",
"destinationIp": "192.168.0.10",
"protocol": 6,
"sourcePort": 61897,
"sourcePort": 51723,
"destinationPort": 80,
"payload": null,
"tcpFlags": "A",
@@ -276,18 +276,32 @@
],
"00000000-0000-0000-0000-000000000103": [
{
"time": 854,
"time": 853,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"arp": 1,
"senderIp": "192.168.0.20",
"targetIp": "192.168.0.10"
},
{
"time": 26578,
"source": "02:00:00:00:01:12",
"destination": "02:00:00:00:01:11",
"sourceIp": "192.168.0.20",
"destinationIp": "192.168.0.10",
"protocol": 6,
"sourcePort": 51723,
"destinationPort": 80,
"payload": null,
"tcpFlags": "F",
"sequence": 2000009,
"acknowledgement": 0
}
]
},
"events": [
[
215,
214,
"server oeffnen called"
],
[
@@ -295,15 +309,15 @@
"client verbinden called"
],
[
1216,
1215,
"client verbinden returned"
],
[
1317,
1316,
"server oeffnen returned"
],
[
1716,
1715,
"loss on"
],
[
@@ -322,19 +336,19 @@
"states": {
"client": [
[
715,
714,
"CLOSED"
],
[
727,
725,
"SYN_SENT"
],
[
1197,
1198,
"ESTABLISHED"
],
[
26469,
26467,
"FIN_WAIT_1"
],
[
@@ -352,9 +366,13 @@
],
"server": [
[
1317,
1316,
"ESTABLISHED"
],
[
26578,
"CLOSE_WAIT"
],
[
26580,
"LAST_ACK"