diff --git a/packages/core/test/scenarios/dhcp-conflict.java.json b/packages/core/test/scenarios/dhcp-conflict.java.json new file mode 100644 index 0000000..dc8b33e --- /dev/null +++ b/packages/core/test/scenarios/dhcp-conflict.java.json @@ -0,0 +1,489 @@ +{ + "frames": { + "00000000-0000-0000-0000-000000000101": [ + { + "time": 459, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 464, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nrouter=0.0.0.0\nsubnetmask=255.255.255.0\ndnsserver=0.0.0.0\nserverident=192.168.0.10" + }, + { + "time": 688, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "0.0.0.0", + "targetIp": "192.168.0.100" + }, + { + "time": 801, + "source": "02:00:00:00:01:13", + "destination": "ff:ff:ff:ff:ff:ff", + "arp": 2, + "senderIp": "192.168.0.100", + "targetIp": "255.255.255.255" + }, + { + "time": 912, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDECLINE\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12\nrequested=192.168.0.100\nserverident=192.168.0.10" + }, + { + "time": 968, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 3663, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 6413, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 9164, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 11914, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 11915, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nrouter=0.0.0.0\nsubnetmask=255.255.255.0\ndnsserver=0.0.0.0\nserverident=192.168.0.10" + }, + { + "time": 12138, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDECLINE\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12\nrequested=192.168.0.100\nserverident=192.168.0.10" + }, + { + "time": 12194, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 14889, + "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.191" + }, + { + "time": 17640, + "source": "02:00:00:00:01:12", + "destination": "ff:ff:ff:ff:ff:ff", + "arp": 2, + "senderIp": "169.254.1.191", + "targetIp": "255.255.255.255" + } + ], + "00000000-0000-0000-0000-000000000102": [ + { + "time": 338, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 576, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nrouter=0.0.0.0\nsubnetmask=255.255.255.0\ndnsserver=0.0.0.0\nserverident=192.168.0.10" + }, + { + "time": 577, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "0.0.0.0", + "targetIp": "192.168.0.100" + }, + { + "time": 801, + "source": "02:00:00:00:01:13", + "destination": "ff:ff:ff:ff:ff:ff", + "arp": 2, + "senderIp": "192.168.0.100", + "targetIp": "255.255.255.255" + }, + { + "time": 801, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDECLINE\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12\nrequested=192.168.0.100\nserverident=192.168.0.10" + }, + { + "time": 857, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 3552, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 6302, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 9052, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 11802, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 12026, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nrouter=0.0.0.0\nsubnetmask=255.255.255.0\ndnsserver=0.0.0.0\nserverident=192.168.0.10" + }, + { + "time": 12027, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDECLINE\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12\nrequested=192.168.0.100\nserverident=192.168.0.10" + }, + { + "time": 12082, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 14778, + "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.191" + }, + { + "time": 17528, + "source": "02:00:00:00:01:12", + "destination": "ff:ff:ff:ff:ff:ff", + "arp": 2, + "senderIp": "169.254.1.191", + "targetIp": "255.255.255.255" + } + ], + "00000000-0000-0000-0000-000000000103": [ + { + "time": 459, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 576, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nrouter=0.0.0.0\nsubnetmask=255.255.255.0\ndnsserver=0.0.0.0\nserverident=192.168.0.10" + }, + { + "time": 688, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "0.0.0.0", + "targetIp": "192.168.0.100" + }, + { + "time": 690, + "source": "02:00:00:00:01:13", + "destination": "ff:ff:ff:ff:ff:ff", + "arp": 2, + "senderIp": "192.168.0.100", + "targetIp": "255.255.255.255" + }, + { + "time": 912, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDECLINE\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12\nrequested=192.168.0.100\nserverident=192.168.0.10" + }, + { + "time": 968, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 3663, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 6413, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 9164, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 11914, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 12026, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nrouter=0.0.0.0\nsubnetmask=255.255.255.0\ndnsserver=0.0.0.0\nserverident=192.168.0.10" + }, + { + "time": 12138, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDECLINE\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12\nrequested=192.168.0.100\nserverident=192.168.0.10" + }, + { + "time": 12194, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 14889, + "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.191" + }, + { + "time": 17640, + "source": "02:00:00:00:01:12", + "destination": "ff:ff:ff:ff:ff:ff", + "arp": 2, + "senderIp": "169.254.1.191", + "targetIp": "255.255.255.255" + } + ] + }, + "devices": { + "00000000-0000-0000-0000-000000000101": [ + "192.168.0.10", + "255.255.255.0", + "", + "" + ], + "00000000-0000-0000-0000-000000000102": [ + "169.254.1.191", + "255.255.0.0", + "", + "" + ], + "00000000-0000-0000-0000-000000000103": [ + "192.168.0.100", + "255.255.255.0", + "", + "" + ] + } +} diff --git a/packages/core/test/scenarios/dhcp-lan.java.json b/packages/core/test/scenarios/dhcp-lan.java.json new file mode 100644 index 0000000..780a9df --- /dev/null +++ b/packages/core/test/scenarios/dhcp-lan.java.json @@ -0,0 +1,331 @@ +{ + "frames": { + "00000000-0000-0000-0000-000000000101": [ + { + "time": 460, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 464, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nrouter=192.168.0.1\nsubnetmask=255.255.255.0\ndnsserver=192.168.0.53\nserverident=192.168.0.10" + }, + { + "time": 516, + "source": "02:00:00:00:01:13", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:13" + }, + { + "time": 520, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.150\nchaddr=02:00:00:00:01:13\nrouter=192.168.0.1\nsubnetmask=255.255.255.0\ndnsserver=192.168.0.53\nserverident=192.168.0.10" + }, + { + "time": 688, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "0.0.0.0", + "targetIp": "192.168.0.100" + }, + { + "time": 743, + "source": "02:00:00:00:01:13", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "0.0.0.0", + "targetIp": "192.168.0.150" + }, + { + "time": 3438, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPREQUEST\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12\nrequested=192.168.0.100\nserverident=192.168.0.10" + }, + { + "time": 3438, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPACK\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nserverident=192.168.0.10" + }, + { + "time": 3493, + "source": "02:00:00:00:01:13", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPREQUEST\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:13\nrequested=192.168.0.150\nserverident=192.168.0.10" + }, + { + "time": 3494, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPACK\nyiaddr=192.168.0.150\nchaddr=02:00:00:00:01:13\nserverident=192.168.0.10" + } + ], + "00000000-0000-0000-0000-000000000102": [ + { + "time": 337, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 460, + "source": "02:00:00:00:01:13", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:13" + }, + { + "time": 575, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nrouter=192.168.0.1\nsubnetmask=255.255.255.0\ndnsserver=192.168.0.53\nserverident=192.168.0.10" + }, + { + "time": 576, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "0.0.0.0", + "targetIp": "192.168.0.100" + }, + { + "time": 631, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.150\nchaddr=02:00:00:00:01:13\nrouter=192.168.0.1\nsubnetmask=255.255.255.0\ndnsserver=192.168.0.53\nserverident=192.168.0.10" + }, + { + "time": 743, + "source": "02:00:00:00:01:13", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "0.0.0.0", + "targetIp": "192.168.0.150" + }, + { + "time": 3327, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPREQUEST\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12\nrequested=192.168.0.100\nserverident=192.168.0.10" + }, + { + "time": 3493, + "source": "02:00:00:00:01:13", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPREQUEST\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:13\nrequested=192.168.0.150\nserverident=192.168.0.10" + }, + { + "time": 3549, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPACK\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nserverident=192.168.0.10" + }, + { + "time": 3605, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPACK\nyiaddr=192.168.0.150\nchaddr=02:00:00:00:01:13\nserverident=192.168.0.10" + } + ], + "00000000-0000-0000-0000-000000000103": [ + { + "time": 460, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 575, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nrouter=192.168.0.1\nsubnetmask=255.255.255.0\ndnsserver=192.168.0.53\nserverident=192.168.0.10" + }, + { + "time": 631, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.150\nchaddr=02:00:00:00:01:13\nrouter=192.168.0.1\nsubnetmask=255.255.255.0\ndnsserver=192.168.0.53\nserverident=192.168.0.10" + }, + { + "time": 631, + "source": "02:00:00:00:01:13", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "0.0.0.0", + "targetIp": "192.168.0.150" + }, + { + "time": 688, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "0.0.0.0", + "targetIp": "192.168.0.100" + }, + { + "time": 3382, + "source": "02:00:00:00:01:13", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPREQUEST\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:13\nrequested=192.168.0.150\nserverident=192.168.0.10" + }, + { + "time": 3438, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPREQUEST\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12\nrequested=192.168.0.100\nserverident=192.168.0.10" + }, + { + "time": 3549, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPACK\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nserverident=192.168.0.10" + }, + { + "time": 3605, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPACK\nyiaddr=192.168.0.150\nchaddr=02:00:00:00:01:13\nserverident=192.168.0.10" + } + ] + }, + "devices": { + "00000000-0000-0000-0000-000000000101": [ + "192.168.0.10", + "255.255.255.0", + "", + "" + ], + "00000000-0000-0000-0000-000000000102": [ + "192.168.0.100", + "255.255.255.0", + "192.168.0.1", + "192.168.0.53" + ], + "00000000-0000-0000-0000-000000000103": [ + "192.168.0.150", + "255.255.255.0", + "192.168.0.1", + "192.168.0.53" + ] + } +} diff --git a/packages/core/test/scenarios/dhcp-no-server.java.json b/packages/core/test/scenarios/dhcp-no-server.java.json new file mode 100644 index 0000000..6c82241 --- /dev/null +++ b/packages/core/test/scenarios/dhcp-no-server.java.json @@ -0,0 +1,243 @@ +{ + "frames": { + "00000000-0000-0000-0000-000000000101": [ + { + "time": 466, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 3199, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 5949, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 8699, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 11450, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 14201, + "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" + }, + { + "time": 16951, + "source": "02:00:00:00:01:12", + "destination": "ff:ff:ff:ff:ff:ff", + "arp": 2, + "senderIp": "169.254.1.72", + "targetIp": "255.255.255.255" + } + ], + "00000000-0000-0000-0000-000000000102": [ + { + "time": 342, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 3087, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 5838, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 8588, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 11338, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 14089, + "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" + }, + { + "time": 16840, + "source": "02:00:00:00:01:12", + "destination": "ff:ff:ff:ff:ff:ff", + "arp": 2, + "senderIp": "169.254.1.72", + "targetIp": "255.255.255.255" + } + ], + "00000000-0000-0000-0000-000000000103": [ + { + "time": 466, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 3199, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 5949, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 8699, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 11450, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 14201, + "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" + }, + { + "time": 16951, + "source": "02:00:00:00:01:12", + "destination": "ff:ff:ff:ff:ff:ff", + "arp": 2, + "senderIp": "169.254.1.72", + "targetIp": "255.255.255.255" + } + ] + }, + "devices": { + "00000000-0000-0000-0000-000000000101": [ + "192.168.0.10", + "255.255.255.0", + "", + "" + ], + "00000000-0000-0000-0000-000000000102": [ + "169.254.1.72", + "255.255.0.0", + "", + "" + ], + "00000000-0000-0000-0000-000000000103": [ + "192.168.0.30", + "255.255.255.0", + "", + "" + ] + } +} diff --git a/packages/core/test/scenarios/dhcp-two-servers.java.json b/packages/core/test/scenarios/dhcp-two-servers.java.json new file mode 100644 index 0000000..51055e7 --- /dev/null +++ b/packages/core/test/scenarios/dhcp-two-servers.java.json @@ -0,0 +1,219 @@ +{ + "frames": { + "00000000-0000-0000-0000-000000000101": [ + { + "time": 455, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 460, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nrouter=192.168.0.254\nsubnetmask=255.255.255.0\ndnsserver=0.0.0.0\nserverident=192.168.0.10" + }, + { + "time": 572, + "source": "02:00:00:00:01:13", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.30", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.200\nchaddr=02:00:00:00:01:12\nrouter=192.168.0.1\nsubnetmask=255.255.255.0\ndnsserver=8.8.8.8\nserverident=192.168.0.30" + }, + { + "time": 684, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "0.0.0.0", + "targetIp": "192.168.0.100" + }, + { + "time": 3435, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPREQUEST\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12\nrequested=192.168.0.100\nserverident=192.168.0.10" + }, + { + "time": 3435, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPACK\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nserverident=192.168.0.10" + } + ], + "00000000-0000-0000-0000-000000000102": [ + { + "time": 333, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 572, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nrouter=192.168.0.254\nsubnetmask=255.255.255.0\ndnsserver=0.0.0.0\nserverident=192.168.0.10" + }, + { + "time": 572, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "0.0.0.0", + "targetIp": "192.168.0.100" + }, + { + "time": 627, + "source": "02:00:00:00:01:13", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.30", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.200\nchaddr=02:00:00:00:01:12\nrouter=192.168.0.1\nsubnetmask=255.255.255.0\ndnsserver=8.8.8.8\nserverident=192.168.0.30" + }, + { + "time": 3323, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPREQUEST\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12\nrequested=192.168.0.100\nserverident=192.168.0.10" + }, + { + "time": 3547, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPACK\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nserverident=192.168.0.10" + } + ], + "00000000-0000-0000-0000-000000000103": [ + { + "time": 455, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPDISCOVER\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12" + }, + { + "time": 460, + "source": "02:00:00:00:01:13", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.30", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.200\nchaddr=02:00:00:00:01:12\nrouter=192.168.0.1\nsubnetmask=255.255.255.0\ndnsserver=8.8.8.8\nserverident=192.168.0.30" + }, + { + "time": 572, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPOFFER\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nrouter=192.168.0.254\nsubnetmask=255.255.255.0\ndnsserver=0.0.0.0\nserverident=192.168.0.10" + }, + { + "time": 684, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "arp": 1, + "senderIp": "0.0.0.0", + "targetIp": "192.168.0.100" + }, + { + "time": 3435, + "source": "02:00:00:00:01:12", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "0.0.0.0", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 68, + "destinationPort": 67, + "payload": "DHCPREQUEST\nyiaddr=0.0.0.0\nchaddr=02:00:00:00:01:12\nrequested=192.168.0.100\nserverident=192.168.0.10" + }, + { + "time": 3547, + "source": "02:00:00:00:01:11", + "destination": "FF:FF:FF:FF:FF:FF", + "sourceIp": "192.168.0.10", + "destinationIp": "255.255.255.255", + "protocol": 17, + "sourcePort": 67, + "destinationPort": 68, + "payload": "DHCPACK\nyiaddr=192.168.0.100\nchaddr=02:00:00:00:01:12\nserverident=192.168.0.10" + } + ] + }, + "devices": { + "00000000-0000-0000-0000-000000000101": [ + "192.168.0.10", + "255.255.255.0", + "192.168.0.254", + "" + ], + "00000000-0000-0000-0000-000000000102": [ + "192.168.0.100", + "255.255.255.0", + "192.168.0.254", + "0.0.0.0" + ], + "00000000-0000-0000-0000-000000000103": [ + "192.168.0.30", + "255.255.255.0", + "", + "" + ] + } +} diff --git a/tools/java-oracle/README.md b/tools/java-oracle/README.md index da8e387..92c55c4 100644 --- a/tools/java-oracle/README.md +++ b/tools/java-oracle/README.md @@ -139,3 +139,36 @@ mit weniger als fünf Feldern lässt Java die ganze Datei verwerfen überspringt Java, statt sie zu zählen; eine Nachricht mit leerem Text geht verloren, weil `split` leere Felder am Ende abschneidet. Beim Client gewinnt die letzte Zeile, auch eine kaputte, die das Konto leert. + +## DHCP zur Laufzeit + +`DhcpRun` baut das Netz eines Kern-Szenarios (`packages/core/test/scenarios/*.scenario.json`: +Knoten, Kabel, Geräte, DHCP-Server und -Clients; die Schritte bleiben +unbeachtet) in Java-Filius nach und startet es wie der Aktionsmodus +(`starten()` jeder Systemsoftware). Nach der angegebenen Echtzeit schreibt es +nach `.java.json`, was jede Netzwerkkarte gesehen hat (Filius' eigener +Mitschnitt, der `Lauscher`: Zeit, MACs, ARP-Operation und -Adressen, +IP/UDP-Adressen und -Ports samt DHCP-Text), und die Adressen jedes Rechners +am Ende. Die MAC eines Ports ist dieselbe wie im Kern (`mac`, sonst +`stableGeneratedMacAddress`). + +* Switches und DHCP-Server starten zuerst: Javas Client wartet auf jeden + aktiven Server, findet sie aber über die Knotenliste der Oberfläche, die das + Werkzeug nicht hat. +* `GUIContainer.getGUIContainer()` wird vor dem Start einmal aufgerufen. Im + echten Filius steht das Fenster schon; ohne das legen zwei Clients den + Singleton gleichzeitig an (nicht synchronisiert), und einer von ihnen + sendet nie etwas (gemessen am Szenario `dhcp-lan`). +* Die Zeiten schwanken von Lauf zu Lauf um einige zehn Millisekunden (echte + Threads), die Link-Local-Adresse würfelt Java mit `Math.random`. Die + Reihenfolge der Nachrichten eines Clients und ihr Inhalt schwanken nicht. + +Gemessen (30.09.2026), was Swift anders macht: Je Versuch sendet Java genau +ein DISCOVER bzw. REQUEST und wartet dann bis zu einer RTT (2,5 s) auf die +Antwort; eine unpassende Antwort (etwa das Angebot des zweiten Servers) liest +es und verwirft sie. Vor dem REQUEST prüft es die angebotene Adresse per ARP +und wartet dabei eine RTT; antwortet ein anderer Rechner, lehnt es mit +DHCPDECLINE ab. Javas Server übergeht das DECLINE und hält die Adresse +weiter als Angebot fest (4 RTT). Nach dem fünften Fehlversuch (Zeitablauf) +nimmt der Client eine Link-Local-Adresse `169.254.1.x/16`: ARP-Probe, eine +RTT warten, dann ein ARP-Reply an alle. diff --git a/tools/java-oracle/run.sh b/tools/java-oracle/run.sh index 874e663..57b6e23 100755 --- a/tools/java-oracle/run.sh +++ b/tools/java-oracle/run.sh @@ -21,7 +21,7 @@ if [ ! -f "$upstream/target/filius.jar" ]; then fi classpath="$upstream/target/filius.jar:$upstream/target/lib/*" mkdir -p "$here/.build" -javac -encoding UTF-8 -d "$here/.build" -cp "$classpath" "$here/src/FlsOracle.java" "$here/src/GetterDefaults.java" "$here/src/IpCheckCases.java" "$here/src/DnsHostsCases.java" "$here/src/EmailFileCases.java" "$here/src/BeansDump.java" "$here/src/Base64Cases.java" +javac -encoding UTF-8 -d "$here/.build" -cp "$classpath" "$here/src/FlsOracle.java" "$here/src/GetterDefaults.java" "$here/src/IpCheckCases.java" "$here/src/DnsHostsCases.java" "$here/src/EmailFileCases.java" "$here/src/BeansDump.java" "$here/src/Base64Cases.java" "$here/src/DhcpRun.java" # FILIUS writes its settings below $HOME; keep them out of the real one. mkdir -p "$here/.build/home" # Removed first: a crashed run must not leave the previous result standing. @@ -106,3 +106,16 @@ for written in "$root/packages/fls/test/written" "$root/packages/fls/test/export test -s "$written.java.json" fi done + +# DHCP as Java FILIUS runs it: a core scenario's network, started as the +# action mode starts it, for the given real-time milliseconds; every frame +# each card saw and the addresses at the end (packages/core/test/dhcpJava.test.ts). +# One run after another: a busy machine stretches the times. +for run in dhcp-lan:8000 dhcp-two-servers:8000 dhcp-conflict:25000 dhcp-no-server:25000; do + name="${run%%:*}" + output="$root/packages/core/test/scenarios/$name.java.json" + rm -f "$output" + HOME="$here/.build/home" xvfb-run -a java -cp "$classpath:$here/.build" DhcpRun \ + "$root/packages/core/test/scenarios/$name.scenario.json" "${run##*:}" "$output" 2>&1 | grep -v 'logback\|^$' || true + test -s "$output" +done diff --git a/tools/java-oracle/src/DhcpRun.java b/tools/java-oracle/src/DhcpRun.java new file mode 100644 index 0000000..df756f6 --- /dev/null +++ b/tools/java-oracle/src/DhcpRun.java @@ -0,0 +1,396 @@ +// Runs a core scenario's network in Java FILIUS and records what DHCP really +// does: every frame each network card saw (FILIUS' own packet log, the +// Lauscher) and each host's address configuration at the end. +// +// DhcpRun +// +// The network is built from the scenario (nodes, links, devices, +// dhcpServers, dhcpClients; steps are ignored) the way the core reads it: a +// port's MAC is its `mac`, else the core's stableGeneratedMacAddress. The +// simulation then runs as the action mode starts it (every system software's +// starten()), in real time, for the given milliseconds. Threads make the +// times vary from run to run; the order of one client's messages does not. + +import filius.gui.GUIContainer; +import filius.hardware.Kabel; +import filius.hardware.NetzwerkInterface; +import filius.hardware.Port; +import filius.hardware.knoten.InternetKnoten; +import filius.hardware.knoten.Knoten; +import filius.hardware.knoten.LokalerKnoten; +import filius.hardware.knoten.Notebook; +import filius.hardware.knoten.Rechner; +import filius.hardware.knoten.Switch; +import filius.rahmenprogramm.nachrichten.Lauscher; +import filius.software.dhcp.DHCPServer; +import filius.software.netzzugangsschicht.EthernetFrame; +import filius.software.system.InternetKnotenBetriebssystem; +import filius.software.transportschicht.Segment; +import filius.software.vermittlungsschicht.ArpPaket; +import filius.software.vermittlungsschicht.IcmpPaket; +import filius.software.vermittlungsschicht.IpPaket; + +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.lang.reflect.Field; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +public class DhcpRun { + + public static void main(String[] args) throws Exception { + @SuppressWarnings("unchecked") + Map scenario = (Map) new JsonReader( + new String(Files.readAllBytes(Paths.get(args[0])), StandardCharsets.UTF_8)).value(); + long duration = Long.parseLong(args[1]); + + Map nodes = new LinkedHashMap<>(); + Map ports = new HashMap<>(); + Map macByNode = new LinkedHashMap<>(); + for (Object each : list(scenario.get("nodes"))) { + Map node = map(each); + String id = (String) node.get("id"); + String kind = (String) node.get("kind"); + List nodePorts = list(node.get("ports")); + Knoten knoten; + switch (kind) { + case "pc": + knoten = new Rechner(); + break; + case "notebook": + knoten = new Notebook(); + break; + case "networkSwitch": + knoten = new Switch(); + break; + default: + throw new IllegalArgumentException("node kind " + kind + " is not built by this tool"); + } + knoten.setName(id); + if (knoten instanceof InternetKnoten) { + if (nodePorts.size() != 1) throw new IllegalArgumentException("a host has one port here"); + Map port = map(nodePorts.get(0)); + NetzwerkInterface nic = ((InternetKnoten) knoten).getNetzwerkInterfaces().get(0); + String mac = port.containsKey("mac") ? (String) port.get("mac") : stableMac((String) port.get("id")); + nic.setMac(mac); + ports.put((String) port.get("id"), nic.getPort()); + macByNode.put(id, mac); + } else { + LinkedList switchPorts = ((LokalerKnoten) knoten).getAnschluesse(); + for (int index = 0; index < nodePorts.size(); index++) { + ports.put((String) map(nodePorts.get(index)).get("id"), switchPorts.get(index)); + } + } + nodes.put(id, knoten); + } + for (Map.Entry entry : map(scenario.getOrDefault("devices", new HashMap<>())).entrySet()) { + Map device = map(entry.getValue()); + NetzwerkInterface nic = ((InternetKnoten) nodes.get(entry.getKey())).getNetzwerkInterfaces().get(0); + nic.setIp((String) device.get("ip")); + nic.setSubnetzMaske((String) device.get("mask")); + nic.setGateway((String) device.getOrDefault("gateway", "")); + nic.setDns((String) device.getOrDefault("dns", "")); + } + for (Object each : list(scenario.get("links"))) { + Map link = map(each); + Kabel cable = new Kabel(); + cable.setAnschluesse(new Port[] { ports.get(link.get("sourcePort")), ports.get(link.get("targetPort")) }); + } + List servers = new ArrayList<>(); + for (Map.Entry entry : map(scenario.getOrDefault("dhcpServers", new HashMap<>())).entrySet()) { + Map config = map(entry.getValue()); + DHCPServer server = system(nodes.get(entry.getKey())).getDHCPServer(); + server.setUntergrenze((String) config.getOrDefault("lower", "0.0.0.0")); + server.setObergrenze((String) config.getOrDefault("upper", "0.0.0.0")); + server.setGatewayip((String) config.getOrDefault("gateway", "0.0.0.0")); + server.setDnsserverip((String) config.getOrDefault("dns", "0.0.0.0")); + server.setOwnSettings(Boolean.TRUE.equals(config.get("own"))); + for (Object assignment : list(config.getOrDefault("staticAssignments", new ArrayList<>()))) { + server.addStaticAssignment((String) list(assignment).get(0), (String) list(assignment).get(1)); + } + server.setAktiv(Boolean.TRUE.equals(config.get("active"))); + servers.add(entry.getKey()); + } + for (Object each : list(scenario.getOrDefault("dhcpClients", new ArrayList<>()))) { + system(nodes.get((String) each)).setDHCPKonfiguration(true); + } + + // Switches and DHCP servers first: FILIUS' client waits for every active + // server to have started (waitUntilDhcpServerStarted, through the GUI's + // node list, which this tool has not got). + // FILIUS' window exists before a simulation starts; created lazily and + // unsynchronized, the first clients to ask for it would race. + GUIContainer.getGUIContainer(); + long start = System.currentTimeMillis(); + for (Map.Entry entry : nodes.entrySet()) { + if (entry.getValue() instanceof Switch || servers.contains(entry.getKey())) entry.getValue().getSystemSoftware().starten(); + } + Thread.sleep(200); + for (Map.Entry entry : nodes.entrySet()) { + if (!(entry.getValue() instanceof Switch || servers.contains(entry.getKey()))) entry.getValue().getSystemSoftware().starten(); + } + Thread.sleep(duration); + + Field field = Lauscher.class.getDeclaredField("datenEinheiten"); + field.setAccessible(true); + @SuppressWarnings("unchecked") + Map> log = (Map>) field.get(Lauscher.getLauscher()); + + Json out = new Json(); + out.open('{'); + out.key("frames").open('{'); + for (Map.Entry entry : macByNode.entrySet()) { + out.key(entry.getKey()).open('['); + LinkedList frames = log.get(entry.getValue()); + if (frames != null) { + synchronized (frames) { + for (Object[] stamped : frames) frame(out, ((Long) stamped[0]) - start, (EthernetFrame) stamped[1]); + } + } + out.close(']'); + } + out.close('}'); + out.key("devices").open('{'); + for (Map.Entry entry : nodes.entrySet()) { + if (!(entry.getValue() instanceof InternetKnoten)) continue; + NetzwerkInterface nic = ((InternetKnoten) entry.getValue()).getNetzwerkInterfaces().get(0); + out.key(entry.getKey()).open('[').string(nic.getIp()).string(nic.getSubnetzMaske()).string(nic.getGateway()) + .string(nic.getDns()).close(']'); + } + out.close('}'); + out.close('}'); + + for (Knoten knoten : nodes.values()) { + try { + knoten.getSystemSoftware().beenden(); + } catch (Exception e) {} + } + try (Writer writer = new OutputStreamWriter(new FileOutputStream(args[2]), StandardCharsets.UTF_8)) { + writer.write(out.toString()); + writer.write('\n'); + } + System.exit(0); + } + + private static void frame(Json out, long time, EthernetFrame frame) { + out.open('{').key("time").number(time).key("source").string(frame.getQuellMacAdresse()).key("destination") + .string(frame.getZielMacAdresse()); + Object data = frame.getDaten(); + if (data instanceof ArpPaket) { + ArpPaket arp = (ArpPaket) data; + out.key("arp").number(arp.getOperation()).key("senderIp").string(arp.getSenderIP()).key("targetIp") + .string(arp.getTargetIP()); + } else if (data instanceof IcmpPaket) { + out.key("icmp").number(((IcmpPaket) data).getIcmpType()); + } else if (data instanceof IpPaket) { + IpPaket ip = (IpPaket) data; + Segment segment = ip.getSegment(); + out.key("sourceIp").string(ip.getSender()).key("destinationIp").string(ip.getEmpfaenger()).key("protocol") + .number(ip.getProtocol()).key("sourcePort").number(segment.getQuellPort()).key("destinationPort") + .number(segment.getZielPort()).key("payload").string(segment.getDaten()); + } + out.close('}'); + } + + private static InternetKnotenBetriebssystem system(Knoten knoten) { + return (InternetKnotenBetriebssystem) knoten.getSystemSoftware(); + } + + /** The core's stableGeneratedMacAddress (packages/core/src/model/node.ts). */ + static String stableMac(String portId) { + String compact = portId.toUpperCase().replace("-", ""); + String suffix = compact.substring(compact.length() - 10); + StringBuilder mac = new StringBuilder("02"); + for (int offset = 0; offset < suffix.length(); offset += 2) mac.append(':').append(suffix, offset, offset + 2); + return mac.toString(); + } + + @SuppressWarnings("unchecked") + private static Map map(Object value) { + return (Map) value; + } + + @SuppressWarnings("unchecked") + private static List list(Object value) { + return (List) value; + } + + /** Just enough JSON for a scenario: objects, arrays, strings, numbers, booleans, null. */ + static final class JsonReader { + private final String text; + private int position; + + JsonReader(String text) { + this.text = text; + } + + Object value() { + skip(); + char c = text.charAt(position); + if (c == '{') { + Map result = new TreeMap<>(); + position++; + skip(); + if (text.charAt(position) == '}') { + position++; + return result; + } + for (;;) { + skip(); + String key = (String) value(); + skip(); + expect(':'); + result.put(key, value()); + skip(); + if (text.charAt(position++) == '}') return result; + } + } + if (c == '[') { + List result = new ArrayList<>(); + position++; + skip(); + if (text.charAt(position) == ']') { + position++; + return result; + } + for (;;) { + result.add(value()); + skip(); + if (text.charAt(position++) == ']') return result; + } + } + if (c == '"') { + StringBuilder result = new StringBuilder(); + position++; + for (char each = text.charAt(position++); each != '"'; each = text.charAt(position++)) { + if (each == '\\') { + char escaped = text.charAt(position++); + switch (escaped) { + case 'n': + result.append('\n'); + break; + case 't': + result.append('\t'); + break; + case 'u': + result.append((char) Integer.parseInt(text.substring(position, position + 4), 16)); + position += 4; + break; + default: + result.append(escaped); + } + } else { + result.append(each); + } + } + return result.toString(); + } + if (text.startsWith("true", position)) { + position += 4; + return Boolean.TRUE; + } + if (text.startsWith("false", position)) { + position += 5; + return Boolean.FALSE; + } + if (text.startsWith("null", position)) { + position += 4; + return null; + } + int begin = position; + while (position < text.length() && "+-.eE0123456789".indexOf(text.charAt(position)) >= 0) position++; + return Double.parseDouble(text.substring(begin, position)); + } + + private void skip() { + while (position < text.length() && Character.isWhitespace(text.charAt(position))) position++; + } + + private void expect(char c) { + if (text.charAt(position++) != c) throw new IllegalArgumentException("expected " + c + " at " + (position - 1)); + } + } + + /** A JSON writer with commas and indentation. */ + static final class Json { + private final StringBuilder text = new StringBuilder(); + private final LinkedList first = new LinkedList<>(); + private boolean afterKey; + + private void separate() { + if (afterKey) { + afterKey = false; + return; + } + if (first.isEmpty()) return; + if (!first.peek()) text.append(','); + first.pop(); + first.push(false); + text.append('\n'); + for (int i = 0; i < first.size(); i++) text.append(" "); + } + + Json open(char bracket) { + separate(); + text.append(bracket); + first.push(true); + return this; + } + + Json close(char bracket) { + boolean empty = first.pop(); + if (!empty) { + text.append('\n'); + for (int i = 0; i < first.size(); i++) text.append(" "); + } + text.append(bracket); + return this; + } + + Json key(String key) { + separate(); + quote(key); + text.append(": "); + afterKey = true; + return this; + } + + Json string(String value) { + separate(); + if (value == null) text.append("null"); + else quote(value); + return this; + } + + Json number(long value) { + separate(); + text.append(value); + return this; + } + + private void quote(String value) { + text.append('"'); + for (char c : value.toCharArray()) { + if (c == '"' || c == '\\') text.append('\\').append(c); + else if (c == '\n') text.append("\\n"); + else if (c < 0x20) text.append(String.format("\\u%04x", (int) c)); + else text.append(c); + } + text.append('"'); + } + + @Override + public String toString() { + return text.toString(); + } + } +}