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": 466,
"time": 457,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"sourceIp": "0.0.0.0",
@@ -13,7 +13,7 @@
"payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12"
},
{
"time": 3199,
"time": 3189,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"sourceIp": "0.0.0.0",
@@ -24,7 +24,7 @@
"payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12"
},
{
"time": 5949,
"time": 5943,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"sourceIp": "0.0.0.0",
@@ -35,7 +35,7 @@
"payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12"
},
{
"time": 8699,
"time": 8690,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"sourceIp": "0.0.0.0",
@@ -46,7 +46,7 @@
"payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12"
},
{
"time": 11450,
"time": 11440,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"sourceIp": "0.0.0.0",
@@ -57,25 +57,25 @@
"payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12"
},
{
"time": 14201,
"time": 14191,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"arp": 1,
"senderIp": "0.0.0.0",
"targetIp": "169.254.1.72"
"targetIp": "169.254.1.174"
},
{
"time": 16951,
"time": 16941,
"source": "02:00:00:00:01:12",
"destination": "ff:ff:ff:ff:ff:ff",
"arp": 2,
"senderIp": "169.254.1.72",
"senderIp": "169.254.1.174",
"targetIp": "255.255.255.255"
}
],
"00000000-0000-0000-0000-000000000102": [
{
"time": 342,
"time": 333,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"sourceIp": "0.0.0.0",
@@ -86,7 +86,7 @@
"payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12"
},
{
"time": 3087,
"time": 3078,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"sourceIp": "0.0.0.0",
@@ -97,7 +97,7 @@
"payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12"
},
{
"time": 5838,
"time": 5828,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"sourceIp": "0.0.0.0",
@@ -108,7 +108,7 @@
"payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12"
},
{
"time": 8588,
"time": 8578,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"sourceIp": "0.0.0.0",
@@ -119,7 +119,7 @@
"payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12"
},
{
"time": 11338,
"time": 11329,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"sourceIp": "0.0.0.0",
@@ -130,25 +130,25 @@
"payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12"
},
{
"time": 14089,
"time": 14080,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"arp": 1,
"senderIp": "0.0.0.0",
"targetIp": "169.254.1.72"
"targetIp": "169.254.1.174"
},
{
"time": 16840,
"time": 16830,
"source": "02:00:00:00:01:12",
"destination": "ff:ff:ff:ff:ff:ff",
"arp": 2,
"senderIp": "169.254.1.72",
"senderIp": "169.254.1.174",
"targetIp": "255.255.255.255"
}
],
"00000000-0000-0000-0000-000000000103": [
{
"time": 466,
"time": 457,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"sourceIp": "0.0.0.0",
@@ -159,7 +159,7 @@
"payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12"
},
{
"time": 3199,
"time": 3189,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"sourceIp": "0.0.0.0",
@@ -170,7 +170,7 @@
"payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12"
},
{
"time": 5949,
"time": 5943,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"sourceIp": "0.0.0.0",
@@ -181,7 +181,7 @@
"payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12"
},
{
"time": 8699,
"time": 8690,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"sourceIp": "0.0.0.0",
@@ -192,7 +192,7 @@
"payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12"
},
{
"time": 11450,
"time": 11440,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"sourceIp": "0.0.0.0",
@@ -203,19 +203,19 @@
"payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12"
},
{
"time": 14201,
"time": 14191,
"source": "02:00:00:00:01:12",
"destination": "FF:FF:FF:FF:FF:FF",
"arp": 1,
"senderIp": "0.0.0.0",
"targetIp": "169.254.1.72"
"targetIp": "169.254.1.174"
},
{
"time": 16951,
"time": 16941,
"source": "02:00:00:00:01:12",
"destination": "ff:ff:ff:ff:ff:ff",
"arp": 2,
"senderIp": "169.254.1.72",
"senderIp": "169.254.1.174",
"targetIp": "255.255.255.255"
}
]
@@ -228,7 +228,7 @@
""
],
"00000000-0000-0000-0000-000000000102": [
"169.254.1.72",
"169.254.1.174",
"255.255.0.0",
"",
""