From 02ba3fb57366247de3cc1655f186f7c0450d71fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Gr=C3=BCner?= <47506558+MegaRedHand@users.noreply.github.com> Date: Sat, 21 Jun 2025 16:57:27 -0300 Subject: [PATCH 1/2] feat: allow changing interface IPs --- src/graphics/renderables/device_info.ts | 36 ++++++++++++++----------- src/styles/parameter_editor.css | 2 +- src/types/view-devices/vDevice.ts | 17 ++++++++++++ src/types/view-devices/vRouter.ts | 1 + 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/graphics/renderables/device_info.ts b/src/graphics/renderables/device_info.ts index 73811545..1fa530be 100644 --- a/src/graphics/renderables/device_info.ts +++ b/src/graphics/renderables/device_info.ts @@ -19,9 +19,11 @@ import { Layer } from "../../types/layer"; import { DataNetworkDevice, DataSwitch } from "../../types/data-devices"; import { ForwardingTable } from "./forwarding_table"; import { getRoutingTable } from "../../types/network-modules/tables/routing_table"; -import { ToggleInfo } from "../components/toggle_info"; import { getArpTable } from "../../types/network-modules/tables/arp_table"; import { getForwardingTable } from "../../types/network-modules/tables/forwarding_table"; +import { EditableParameter } from "../basic_components/parameter_editor"; +import { IpAddress } from "../../packets/ip"; +import { MacAddress } from "../../packets/ethernet"; export class DeviceInfo extends BaseInfo { readonly device: ViewDevice; @@ -90,35 +92,38 @@ export class DeviceInfo extends BaseInfo { const showIp = this.device.getType() !== DeviceType.Switch; const showMac = layer === Layer.Link; - const fields: { key: string; value: string; tooltip: string }[] = []; + const fields: EditableParameter[] = []; if (showIp) { this.device.interfaces.forEach((iface) => { fields.push({ - key: TOOLTIP_KEYS.IP_ADDRESS + (iface.name ? ` (${iface.name})` : ""), - value: iface.ip.toString(), - tooltip: TOOLTIP_KEYS.IP_ADDRESS, + label: + TOOLTIP_KEYS.IP_ADDRESS + (iface.name ? ` (${iface.name})` : ""), + initialValue: iface.ip.toString(), + onChange: (newValue: string) => { + const ip = IpAddress.parse(newValue); + iface.ip = ip; + this.device.setInterface(iface); + }, }); }); } if (showMac) { this.device.interfaces.forEach((iface) => { fields.push({ - key: + label: TOOLTIP_KEYS.MAC_ADDRESS + (iface.name ? ` (${iface.name})` : ""), - value: iface.mac.toString(), - tooltip: TOOLTIP_KEYS.MAC_ADDRESS, + initialValue: iface.mac.toString(), + onChange: (newValue: string) => { + const mac = MacAddress.parse(newValue); + iface.mac = mac; + this.device.setInterface(iface); + }, }); }); } - const toggleInfo = new ToggleInfo({ - title: "Interfaces", - fields, - toggleButtonText: { on: "Hide Interfaces", off: "Show Interfaces" }, - }); - - this.inputFields.push(toggleInfo.toHTML()); + this.addParameterGroup("Interfaces", "Show/Hide interfaces", fields); } addProgramRunner(runner: ProgramRunner, programs: ProgramInfo[]): void { @@ -164,7 +169,6 @@ export class DeviceInfo extends BaseInfo { parameters, ); this.inputFields.push(parameterEditor.toHTML()); - this.addDivider(); } /** diff --git a/src/styles/parameter_editor.css b/src/styles/parameter_editor.css index 9b3b14a8..2a59389c 100644 --- a/src/styles/parameter_editor.css +++ b/src/styles/parameter_editor.css @@ -31,7 +31,7 @@ text-align: center; font-size: 0.9rem; /* Smaller font size */ border-radius: 0.5rem; - width: 80px; /* Fixed width for the input */ + width: 120px; /* Fixed width for the input */ box-sizing: border-box; transition: background-color 0.3s ease, diff --git a/src/types/view-devices/vDevice.ts b/src/types/view-devices/vDevice.ts index bfa42a8b..1883057b 100644 --- a/src/types/view-devices/vDevice.ts +++ b/src/types/view-devices/vDevice.ts @@ -304,6 +304,23 @@ export abstract class ViewDevice extends Container { return { x: this.x, y: this.y }; } + setInterface(setIface: NetworkInterface) { + this.viewgraph.getDataGraph().modifyDevice(this.id, (device) => { + if (device) { + device.interfaces = device.interfaces.map((iface) => { + if (iface.name === setIface.name) { + return { + ...iface, + mac: setIface.mac, + ip: setIface.ip ? setIface.ip : iface.ip, + }; + } + return iface; + }); + } + }); + } + delete(): RemovedNodeData { const deviceData = this.viewgraph.removeDevice(this.id); console.log(`Device ${this.id} deleted`); diff --git a/src/types/view-devices/vRouter.ts b/src/types/view-devices/vRouter.ts index 1d891d91..ed793bab 100644 --- a/src/types/view-devices/vRouter.ts +++ b/src/types/view-devices/vRouter.ts @@ -97,6 +97,7 @@ export class ViewRouter extends ViewNetworkDevice { }, ], ); + info.addDivider(); info.addRoutingTable(this.viewgraph, this.id); From 46be9a23d2de7052334e652867fd0eac12d99ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Gr=C3=BCner?= <47506558+MegaRedHand@users.noreply.github.com> Date: Sat, 21 Jun 2025 17:01:06 -0300 Subject: [PATCH 2/2] feat: show compressed MAC addresses --- src/graphics/renderables/device_info.ts | 2 +- src/packets/ethernet.ts | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/graphics/renderables/device_info.ts b/src/graphics/renderables/device_info.ts index 1fa530be..0c616dac 100644 --- a/src/graphics/renderables/device_info.ts +++ b/src/graphics/renderables/device_info.ts @@ -113,7 +113,7 @@ export class DeviceInfo extends BaseInfo { fields.push({ label: TOOLTIP_KEYS.MAC_ADDRESS + (iface.name ? ` (${iface.name})` : ""), - initialValue: iface.mac.toString(), + initialValue: iface.mac.toCompressedString(), onChange: (newValue: string) => { const mac = MacAddress.parse(newValue); iface.mac = mac; diff --git a/src/packets/ethernet.ts b/src/packets/ethernet.ts index f9bbc37a..87ff842f 100644 --- a/src/packets/ethernet.ts +++ b/src/packets/ethernet.ts @@ -37,6 +37,10 @@ export class MacAddress { static parse(addrString: string): MacAddress { const octets = new Uint8Array(6); addrString.split(":").forEach((octet, i) => { + if (octet === "") { + octets[i] = 0; + return; + } const octetInt = parseInt(octet, 16); if (isNaN(octetInt) || octetInt < 0 || octetInt > 255) { throw new Error(`Invalid MAC address: ${addrString}`);