feat(core): Java's IP and ICMP threads, measured with Java FILIUS

Every packet that comes in goes through its node's IP thread (UDP, TCP) or
ICMP thread (ICMP), as Java's IPThread and ICMPThread: deliver, answer an
echo request or forward, one after the other; while one waits for ARP, the
next wait behind it. A packet a node sends to itself is delivered at once,
as Java's IP.senden does. The transport send threads and these are one
mechanism now (handToProtocolThread).

ArpRun has three stories through the router (routedUdpBehind,
routedPingBesideUdp, routedPingBehindPing); the oracle writes ICMP frames
with type, code, addresses and sequence number. All seven ArpRun stories
match Java FILIUS.

Measured and not taken: Java's ARP wakes one waiter with notify, not the
one whose answer came; the core wakes all that wait for the address.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-30 18:32:48 +00:00
co-authored by Claude Opus 5.5
parent 7e0348636c
commit f5c61cdce7
13 changed files with 950 additions and 97 deletions
+35 -9
View File
@@ -9,7 +9,7 @@ import { readFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { describe, expect, it } from 'vitest';
import type { IPv4DeliveryResult, NetworkRuntimeEngine } from '../src/index.js';
import { icmpMessage, type NetworkRuntimeEngine } from '../src/index.js';
import { GAP_TOLERANCE_MILLISECONDS, gaps, javaFrames, watchedEngine, type JavaFrame } from './javaRun.js';
import type { Scenario } from './scenario.js';
@@ -21,9 +21,13 @@ interface JavaRun {
events: [number, string][];
}
/** A ping's result in Java's words: the ICMP answer's type and code, or null when none came. */
function pingResult(result: IPv4DeliveryResult, answered: boolean): string {
/** A ping from HOST in Java's words: the ICMP answer's type and code, or null when none came in time. */
function ping(engine: NetworkRuntimeEngine, target: string, sequenceNumber = 1): string {
const result = engine.sendIcmpEcho(HOST, target, { sequenceNumber });
if (result.type === 'icmpError' && result.kind === 'destinationHostUnreachable') return 'ICMP 3/1';
const answered = (engine.state.icmpObservationsByNodeId.get(HOST) ?? []).some(
(observation) => observation.message.kind === 'echoReply' && observation.message.sequenceNumber === sequenceNumber,
);
return answered ? 'ICMP 0/0' : 'null';
}
@@ -37,12 +41,8 @@ function udpSend(engine: NetworkRuntimeEngine, target: string, payload: string):
}
const STORIES: Record<string, (engine: NetworkRuntimeEngine, call: Call) => void> = {
pingLan: (engine, call) => call('sendProbe 10.0.0.9', () => pingResult(engine.sendIcmpEcho(HOST, '10.0.0.9'), false)),
pingRouted: (engine, call) =>
call('sendProbe 20.0.0.9', () => {
const result = engine.sendIcmpEcho(HOST, '20.0.0.9');
return pingResult(result, result.type === 'delivered' && result.nodeId !== HOST);
}),
pingLan: (engine, call) => call('sendProbe 10.0.0.9', () => ping(engine, '10.0.0.9')),
pingRouted: (engine, call) => call('sendProbe 20.0.0.9', () => ping(engine, '20.0.0.9')),
udpTwice: (engine, call) => {
call('senden eins', () => udpSend(engine, '10.0.0.9', 'eins'));
call('senden zwei', () => udpSend(engine, '10.0.0.9', 'zwei'));
@@ -51,6 +51,32 @@ const STORIES: Record<string, (engine: NetworkRuntimeEngine, call: Call) => void
call('senden verloren', () => udpSend(engine, '10.0.0.9', 'verloren'));
call('senden dahinter', () => udpSend(engine, '20.0.0.2', 'dahinter'));
},
routedUdpBehind: (engine, call) => {
call('senden verloren', () => udpSend(engine, '20.0.0.9', 'verloren'));
call('senden dahinter', () => udpSend(engine, '20.0.0.2', 'dahinter'));
},
routedPingBesideUdp: (engine, call) => {
call('sendProbe 20.0.0.2', () => ping(engine, '20.0.0.2'));
call('senden verloren', () => udpSend(engine, '20.0.0.9', 'verloren'));
engine.handle({ type: 'advance', toMilliseconds: engine.state.currentTimeMilliseconds + 100 });
call('sendProbe 20.0.0.2', () => ping(engine, '20.0.0.2', 2));
},
routedPingBehindPing: (engine, call) => {
// Java's sendeICMP sends in the caller's thread, which waits for ARP.
call('sendeICMP 20.0.0.9', () => {
engine.resolveMacAddress(HOST, '10.0.0.1');
engine.sendIPv4Packet(HOST, {
identity: engine.allocatePacketIdentity(),
senderIPAddress: '10.0.0.2',
receiverIPAddress: '20.0.0.9',
timeToLive: 64,
protocol: 'icmp',
payload: { kind: 'icmp', message: icmpMessage('echoRequest', { identifier: 2, sequenceNumber: 2, data: new Uint8Array() }) },
});
return '';
});
call('sendProbe 20.0.0.2', () => ping(engine, '20.0.0.2'));
},
};
/** The client's free port as "client": Java draws it at random, the engine from its seed. */
+74
View File
@@ -1783,3 +1783,77 @@ describe('ARP', () => {
expect(engine.state.packetTraces.filter((trace) => trace.layer === 'network' && trace.operation === 'sent')).toEqual([]);
});
});
describe("Java's IP and ICMP threads", () => {
const twoPcs = (prefix: string, base: number, options: { secondIsGateway?: boolean; firewall?: FirewallConfiguration } = {}) => {
const [firstId, firstPortId, secondId, secondPortId] = [base, base + 1, base + 2, base + 3].map(uuid) as [string, string, string, string];
const engine = startedEngine({
nodes: [pc(firstId, firstPortId), pc(secondId, secondPortId)],
links: [link(firstId, firstPortId, secondId, secondPortId)],
deviceConfigurations: new Map([
[firstId, device(`${prefix}.1`, options.secondIsGateway === true ? { gateway: `${prefix}.2` } : {})],
[secondId, device(`${prefix}.2`)],
]),
...(options.firewall === undefined ? {} : { firewallConfigurationsByNodeId: new Map([[secondId, options.firewall]]) }),
});
return { engine, firstId, secondId };
};
const text = (payload: Uint8Array | undefined) => new TextDecoder().decode(payload ?? new Uint8Array());
it('holds the ICMP thread while an echo reply waits for ARP: the next echo request waits behind it', () => {
const { engine, firstId } = twoPcs('10.29.0', 0x1b01);
// An echo request from .99, which no card has: the answer waits for ARP.
engine.sendIPv4Packet(firstId, {
identity: engine.allocatePacketIdentity(),
senderIPAddress: '10.29.0.99',
receiverIPAddress: '10.29.0.2',
timeToLive: 64,
protocol: 'icmp',
payload: { kind: 'icmp', message: icmpMessage('echoRequest', { identifier: 7, sequenceNumber: 7, data: new Uint8Array() }) },
});
engine.handle({ type: 'advance', toMilliseconds: 200 });
const replies = () => (engine.state.icmpObservationsByNodeId.get(firstId) ?? []).filter((observation) => observation.message.kind === 'echoReply');
engine.sendIcmpEcho(firstId, '10.29.0.2');
expect(replies()).toEqual([]);
// The request came at 165 ms after ARP there and back; ARP for .99 gives up two round trips later, then the reply takes a cable.
engine.handle({ type: 'advance', toMilliseconds: 165 + 2 * 2_750 + 55 - 1 });
expect(replies()).toEqual([]);
engine.handle({ type: 'advance', toMilliseconds: 165 + 2 * 2_750 + 55 });
expect(replies().map((observation) => observation.nodeId)).toEqual([firstId]);
});
it('frees the IP thread of a PC that drops a packet it would have to forward', () => {
const { engine, firstId, secondId } = twoPcs('10.30.1', 0x1b11, { secondIsGateway: true });
const receiver = engine.bindUdpSocket(secondId, { localPort: 9 })!;
engine.sendUdp(engine.bindUdpSocket(firstId, { remoteIPAddress: '20.0.0.5', remotePort: 9 })!, new TextEncoder().encode('elsewhere'));
engine.sendUdp(engine.bindUdpSocket(firstId, { remoteIPAddress: '10.30.1.2', remotePort: 9 })!, new TextEncoder().encode('here'));
expect(text(engine.receiveUdp(receiver, 1_000)?.datagram.payload)).toBe('here');
expect(engine.state.packetTraces.some((trace) => trace.nodeId === secondId && trace.detail === 'IPv4 forwarding disabled')).toBe(true);
});
it('frees the IP thread of a PC whose firewall drops a packet', () => {
const firewall = firewallConfiguration({ isActive: true, defaultPolicy: 'drop', rules: [firewallRule({ port: 9, protocol: 'udp', action: 'accept' })] });
const { engine, firstId, secondId } = twoPcs('10.30.2', 0x1b21, { firewall });
const receiver = engine.bindUdpSocket(secondId, { localPort: 9 })!;
engine.bindUdpSocket(secondId, { localPort: 8 });
engine.sendUdp(engine.bindUdpSocket(firstId, { remoteIPAddress: '10.30.2.2', remotePort: 8 })!, new TextEncoder().encode('blocked'));
engine.sendUdp(engine.bindUdpSocket(firstId, { remoteIPAddress: '10.30.2.2', remotePort: 9 })!, new TextEncoder().encode('let in'));
expect(text(engine.receiveUdp(receiver, 1_000)?.datagram.payload)).toBe('let in');
expect(engine.state.firewallDecisions.some((decision) => !decision.accepted)).toBe(true);
});
it('delivers what a router sends to itself at once, while its IP thread waits for ARP', () => {
const { engine, sourceNodeId, routerNodeId } = routedTopology();
// The router forwards to 20.0.0.9, which no card has: its IP thread waits two round trips.
engine.sendUdp(engine.bindUdpSocket(sourceNodeId, { remoteIPAddress: '20.0.0.9', remotePort: 9 })!, new TextEncoder().encode('nobody'));
engine.handle({ type: 'advance', toMilliseconds: 500 });
const receiver = engine.bindUdpSocket(routerNodeId, { localPort: 9 })!;
engine.sendUdp(engine.bindUdpSocket(routerNodeId, { remoteIPAddress: '10.0.0.1', remotePort: 9 })!, new TextEncoder().encode('self'));
expect(text(engine.receiveUdp(receiver)?.datagram.payload)).toBe('self');
expect(engine.state.currentTimeMilliseconds).toBe(500);
});
});
+20 -8
View File
@@ -41,6 +41,7 @@ export interface JavaFrame {
destinationPort?: number;
payload?: string | null;
icmp?: number;
icmpCode?: number;
tcpFlags?: string;
sequence?: number;
acknowledgement?: number;
@@ -54,7 +55,7 @@ export interface SeenFrame {
function javaText(frame: JavaFrame): string {
const macs = `${frame.source} > ${frame.destination}`.toUpperCase();
if (frame.arp !== undefined) return `${macs} ARP ${frame.arp === 1 ? 'request' : 'reply'} ${frame.senderIp} > ${frame.targetIp}`;
if (frame.icmp !== undefined) return `${macs} ICMP ${frame.icmp}`;
if (frame.icmp !== undefined) return icmpText(macs, frame.icmp, frame.icmpCode!, frame.sourceIp!, frame.destinationIp!, frame.sequence!);
const ends = `${frame.sourceIp}:${frame.sourcePort} > ${frame.destinationIp}:${frame.destinationPort}`;
if (frame.tcpFlags !== undefined) {
return `${macs} TCP ${ends} ${frame.tcpFlags || '-'} seq=${frame.sequence} ack=${frame.acknowledgement} length=${(frame.payload ?? '').length}`;
@@ -63,14 +64,21 @@ function javaText(frame: JavaFrame): string {
}
/** The ICMP type numbers Java logs. */
const ICMP_TYPES: Record<string, number> = {
echoReply: 0,
destinationNetworkUnreachable: 3,
destinationHostUnreachable: 3,
echoRequest: 8,
timeExceeded: 11,
/** Type and code of each ICMP message the engine knows. */
const ICMP_TYPES: Record<string, [number, number]> = {
echoReply: [0, 0],
destinationNetworkUnreachable: [3, 0],
destinationHostUnreachable: [3, 1],
echoRequest: [8, 0],
timeExceeded: [11, 0],
};
/** The sequence number only for echo messages: an error carries none of its own. */
function icmpText(macs: string, type: number, code: number, source: string, destination: string, sequence: number): string {
const echo = type === 0 || type === 8 ? ` seq=${sequence}` : '';
return `${macs} ICMP ${type}/${code} ${source} > ${destination}${echo}`;
}
const FLAG_LETTERS: [number, string][] = [
[TCP_FLAG.synchronize, 'S'],
[TCP_FLAG.acknowledgement, 'A'],
@@ -86,7 +94,11 @@ function engineText(frame: EthernetFrame): string {
return `${macs} ARP ${arp.operation} ${arp.senderIPAddress} > ${arp.targetIPAddress}`;
}
const packet = frame.payload.packet;
if (packet.payload.kind === 'icmp') return `${macs} ICMP ${ICMP_TYPES[packet.payload.message.kind]}`;
if (packet.payload.kind === 'icmp') {
const message = packet.payload.message;
const [type, code] = ICMP_TYPES[message.kind]!;
return icmpText(macs, type, code, packet.senderIPAddress, packet.receiverIPAddress, message.sequenceNumber);
}
if (packet.payload.kind === 'tcp') {
const segment = packet.payload.segment;
const flags = FLAG_LETTERS.filter(([bit]) => (segment.flags & bit) !== 0).map(([, letter]) => letter).join('');
@@ -2,7 +2,7 @@
"frames": {
"00000000-0000-0000-0000-000000000301": [
{
"time": 720,
"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": 955,
"time": 951,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"arp": 2,
@@ -18,21 +18,29 @@
"targetIp": "10.0.0.2"
},
{
"time": 959,
"time": 955,
"source": "02:00:00:00:03:11",
"destination": "02:00:00:00:03:21",
"icmp": 8
"icmp": 8,
"icmpCode": 0,
"sourceIp": "10.0.0.2",
"destinationIp": "20.0.0.9",
"sequence": 1
},
{
"time": 6685,
"time": 6681,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"icmp": 3
"icmp": 3,
"icmpCode": 1,
"sourceIp": "10.0.0.1",
"destinationIp": "10.0.0.2",
"sequence": 0
}
],
"00000000-0000-0000-0000-000000000302": [
{
"time": 841,
"time": 838,
"source": "02:00:00:00:03:11",
"destination": "FF:FF:FF:FF:FF:FF",
"arp": 1,
@@ -40,7 +48,7 @@
"targetIp": "10.0.0.1"
},
{
"time": 843,
"time": 840,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"arp": 2,
@@ -48,21 +56,29 @@
"targetIp": "10.0.0.2"
},
{
"time": 1072,
"time": 1068,
"source": "02:00:00:00:03:11",
"destination": "02:00:00:00:03:21",
"icmp": 8
"icmp": 8,
"icmpCode": 0,
"sourceIp": "10.0.0.2",
"destinationIp": "20.0.0.9",
"sequence": 1
},
{
"time": 6574,
"time": 6569,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"icmp": 3
"icmp": 3,
"icmpCode": 1,
"sourceIp": "10.0.0.1",
"destinationIp": "10.0.0.2",
"sequence": 0
}
],
"00000000-0000-0000-0000-000000000303": [
{
"time": 1128,
"time": 1124,
"source": "02:00:00:00:03:22",
"destination": "FF:FF:FF:FF:FF:FF",
"arp": 1,
@@ -70,7 +86,7 @@
"targetIp": "20.0.0.9"
},
{
"time": 3878,
"time": 3874,
"source": "02:00:00:00:03:22",
"destination": "FF:FF:FF:FF:FF:FF",
"arp": 1,
@@ -81,11 +97,11 @@
},
"events": [
[
716,
713,
"sendProbe 20.0.0.9 called"
],
[
3709,
3705,
"sendProbe 20.0.0.9 returned null"
]
]
@@ -0,0 +1,192 @@
{
"frames": {
"00000000-0000-0000-0000-000000000301": [
{
"time": 718,
"source": "02:00:00:00:03:11",
"destination": "FF:FF:FF:FF:FF:FF",
"arp": 1,
"senderIp": "10.0.0.2",
"targetIp": "10.0.0.1"
},
{
"time": 952,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"arp": 2,
"senderIp": "10.0.0.1",
"targetIp": "10.0.0.2"
},
{
"time": 955,
"source": "02:00:00:00:03:11",
"destination": "02:00:00:00:03:21",
"icmp": 8,
"icmpCode": 0,
"sourceIp": "10.0.0.2",
"destinationIp": "20.0.0.9",
"sequence": 2
},
{
"time": 1012,
"source": "02:00:00:00:03:11",
"destination": "02:00:00:00:03:21",
"icmp": 8,
"icmpCode": 0,
"sourceIp": "10.0.0.2",
"destinationIp": "20.0.0.2",
"sequence": 1
},
{
"time": 6681,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"icmp": 3,
"icmpCode": 1,
"sourceIp": "10.0.0.1",
"destinationIp": "10.0.0.2",
"sequence": 0
},
{
"time": 6904,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"icmp": 0,
"icmpCode": 0,
"sourceIp": "20.0.0.2",
"destinationIp": "10.0.0.2",
"sequence": 1
}
],
"00000000-0000-0000-0000-000000000302": [
{
"time": 838,
"source": "02:00:00:00:03:11",
"destination": "FF:FF:FF:FF:FF:FF",
"arp": 1,
"senderIp": "10.0.0.2",
"targetIp": "10.0.0.1"
},
{
"time": 840,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"arp": 2,
"senderIp": "10.0.0.1",
"targetIp": "10.0.0.2"
},
{
"time": 1068,
"source": "02:00:00:00:03:11",
"destination": "02:00:00:00:03:21",
"icmp": 8,
"icmpCode": 0,
"sourceIp": "10.0.0.2",
"destinationIp": "20.0.0.9",
"sequence": 2
},
{
"time": 1124,
"source": "02:00:00:00:03:11",
"destination": "02:00:00:00:03:21",
"icmp": 8,
"icmpCode": 0,
"sourceIp": "10.0.0.2",
"destinationIp": "20.0.0.2",
"sequence": 1
},
{
"time": 6570,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"icmp": 3,
"icmpCode": 1,
"sourceIp": "10.0.0.1",
"destinationIp": "10.0.0.2",
"sequence": 0
},
{
"time": 6793,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"icmp": 0,
"icmpCode": 0,
"sourceIp": "20.0.0.2",
"destinationIp": "10.0.0.2",
"sequence": 1
}
],
"00000000-0000-0000-0000-000000000303": [
{
"time": 1124,
"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": 3874,
"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": 6625,
"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": 6625,
"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": 6737,
"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": 6737,
"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
}
]
},
"events": [
[
713,
"sendeICMP 20.0.0.9 called"
],
[
955,
"sendeICMP 20.0.0.9 returned "
],
[
955,
"sendProbe 20.0.0.2 called"
],
[
3763,
"sendProbe 20.0.0.2 returned null"
]
]
}
@@ -0,0 +1,262 @@
{
"frames": {
"00000000-0000-0000-0000-000000000301": [
{
"time": 717,
"source": "02:00:00:00:03:11",
"destination": "FF:FF:FF:FF:FF:FF",
"arp": 1,
"senderIp": "10.0.0.2",
"targetIp": "10.0.0.1"
},
{
"time": 951,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"arp": 2,
"senderIp": "10.0.0.1",
"targetIp": "10.0.0.2"
},
{
"time": 955,
"source": "02:00:00:00:03:11",
"destination": "02:00:00:00:03:21",
"icmp": 8,
"icmpCode": 0,
"sourceIp": "10.0.0.2",
"destinationIp": "20.0.0.2",
"sequence": 1
},
{
"time": 1402,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"icmp": 0,
"icmpCode": 0,
"sourceIp": "20.0.0.2",
"destinationIp": "10.0.0.2",
"sequence": 1
},
{
"time": 1408,
"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,
"destinationPort": 9,
"payload": "verloren"
},
{
"time": 1507,
"source": "02:00:00:00:03:11",
"destination": "02:00:00:00:03:21",
"icmp": 8,
"icmpCode": 0,
"sourceIp": "10.0.0.2",
"destinationIp": "20.0.0.2",
"sequence": 2
},
{
"time": 1842,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"icmp": 0,
"icmpCode": 0,
"sourceIp": "20.0.0.2",
"destinationIp": "10.0.0.2",
"sequence": 2
},
{
"time": 7133,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"icmp": 3,
"icmpCode": 1,
"sourceIp": "10.0.0.1",
"destinationIp": "10.0.0.2",
"sequence": 0
}
],
"00000000-0000-0000-0000-000000000302": [
{
"time": 837,
"source": "02:00:00:00:03:11",
"destination": "FF:FF:FF:FF:FF:FF",
"arp": 1,
"senderIp": "10.0.0.2",
"targetIp": "10.0.0.1"
},
{
"time": 839,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"arp": 2,
"senderIp": "10.0.0.1",
"targetIp": "10.0.0.2"
},
{
"time": 1068,
"source": "02:00:00:00:03:11",
"destination": "02:00:00:00:03:21",
"icmp": 8,
"icmpCode": 0,
"sourceIp": "10.0.0.2",
"destinationIp": "20.0.0.2",
"sequence": 1
},
{
"time": 1291,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"icmp": 0,
"icmpCode": 0,
"sourceIp": "20.0.0.2",
"destinationIp": "10.0.0.2",
"sequence": 1
},
{
"time": 1521,
"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,
"destinationPort": 9,
"payload": "verloren"
},
{
"time": 1618,
"source": "02:00:00:00:03:11",
"destination": "02:00:00:00:03:21",
"icmp": 8,
"icmpCode": 0,
"sourceIp": "10.0.0.2",
"destinationIp": "20.0.0.2",
"sequence": 2
},
{
"time": 1731,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"icmp": 0,
"icmpCode": 0,
"sourceIp": "20.0.0.2",
"destinationIp": "10.0.0.2",
"sequence": 2
},
{
"time": 7022,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"icmp": 3,
"icmpCode": 1,
"sourceIp": "10.0.0.1",
"destinationIp": "10.0.0.2",
"sequence": 0
}
],
"00000000-0000-0000-0000-000000000303": [
{
"time": 1123,
"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": 1124,
"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": 1235,
"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": 1235,
"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": 1576,
"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": 1675,
"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": 1675,
"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": 4327,
"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"
}
]
},
"events": [
[
712,
"sendProbe 20.0.0.2 called"
],
[
1404,
"sendProbe 20.0.0.2 returned ICMP 0/0 from 20.0.0.2"
],
[
1404,
"senden verloren called"
],
[
1407,
"senden verloren returned "
],
[
1507,
"sendProbe 20.0.0.2 called"
],
[
1842,
"sendProbe 20.0.0.2 returned ICMP 0/0 from 20.0.0.2"
]
]
}
@@ -0,0 +1,167 @@
{
"frames": {
"00000000-0000-0000-0000-000000000301": [
{
"time": 721,
"source": "02:00:00:00:03:11",
"destination": "FF:FF:FF:FF:FF:FF",
"arp": 1,
"senderIp": "10.0.0.2",
"targetIp": "10.0.0.1"
},
{
"time": 957,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"arp": 2,
"senderIp": "10.0.0.1",
"targetIp": "10.0.0.2"
},
{
"time": 959,
"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,
"destinationPort": 9,
"payload": "verloren"
},
{
"time": 1017,
"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,
"destinationPort": 9,
"payload": "dahinter"
},
{
"time": 6689,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"icmp": 3,
"icmpCode": 1,
"sourceIp": "10.0.0.1",
"destinationIp": "10.0.0.2",
"sequence": 0
}
],
"00000000-0000-0000-0000-000000000302": [
{
"time": 844,
"source": "02:00:00:00:03:11",
"destination": "FF:FF:FF:FF:FF:FF",
"arp": 1,
"senderIp": "10.0.0.2",
"targetIp": "10.0.0.1"
},
{
"time": 846,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"arp": 2,
"senderIp": "10.0.0.1",
"targetIp": "10.0.0.2"
},
{
"time": 1073,
"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,
"destinationPort": 9,
"payload": "verloren"
},
{
"time": 1129,
"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,
"destinationPort": 9,
"payload": "dahinter"
},
{
"time": 6577,
"source": "02:00:00:00:03:21",
"destination": "02:00:00:00:03:11",
"icmp": 3,
"icmpCode": 1,
"sourceIp": "10.0.0.1",
"destinationIp": "10.0.0.2",
"sequence": 0
}
],
"00000000-0000-0000-0000-000000000303": [
{
"time": 1129,
"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": 3879,
"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": 6632,
"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": 6633,
"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": 6744,
"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,
"destinationPort": 9,
"payload": "dahinter"
}
]
},
"events": [
[
712,
"senden verloren called"
],
[
717,
"senden verloren returned "
],
[
717,
"senden dahinter called"
],
[
959,
"senden dahinter returned "
]
]
}