From 8c3df643d0e0f3b161a539735b0a3b4b1da1ea20 Mon Sep 17 00:00:00 2001 From: bloqaudio Date: Thu, 13 Aug 2026 17:18:04 -0500 Subject: [PATCH] ports: show the devices connected behind each port Adds a Connected devices column to the Port Configuration table, fed by the shared walkL2() helper. A port with a single MAC behind it shows the MAC directly; several are shown as a count with the full list in the cell tooltip, since picking one of many to display would suggest it was "the" device. The walk restarts 15 seconds after each completion and starts 3 seconds after page load to stay clear of the initial status and MTU requests. A walk that ends without ok keeps the previous cells, since an incomplete table would blank ports that have devices behind them. Translations for the three languages included. --- html/i18n.js | 6 ++++++ html/ports.html | 2 +- html/ports.js | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/html/i18n.js b/html/i18n.js index 850d9ac..de87476 100644 --- a/html/i18n.js +++ b/html/i18n.js @@ -37,6 +37,8 @@ var LANG = { port_col_speed: 'Current Link Speed', port_col_set_speed: 'Set Speed', port_col_disabled: 'Disabled', + port_col_devices: 'Connected devices', + port_devices: 'devices', port_col_apply: 'Apply', port_mtu_heading: 'Configure Maximum Frame Size (MTU) forwarded at Port', port_auto: 'Auto', @@ -224,6 +226,8 @@ var LANG = { port_col_speed: '現在のリンク速度', port_col_set_speed: '速度設定', port_col_disabled: '無効', + port_col_devices: '接続デバイス', + port_devices: 'デバイス', port_col_apply: '適用', port_mtu_heading: 'ポートの最大フレームサイズ (MTU) 設定', port_auto: '自動', @@ -411,6 +415,8 @@ var LANG = { port_col_speed: '当前链路速率', port_col_set_speed: '设置速率', port_col_disabled: '禁用', + port_col_devices: '已连接设备', + port_devices: '台设备', port_col_apply: '应用', port_mtu_heading: '配置端口转发的最大帧大小 (MTU)', port_auto: '自动', diff --git a/html/ports.html b/html/ports.html index 8d9409f..986921e 100644 --- a/html/ports.html +++ b/html/ports.html @@ -12,7 +12,7 @@

Port Configuration

- +
Port Name Current Link SpeedSet SpeedDisabledApply
Port Name Current Link SpeedConnected devicesSet SpeedDisabledApply

Configure Maximum Frame Size (MTU) forwarded at Port

diff --git a/html/ports.js b/html/ports.js index 9079ca1..cf99d47 100644 --- a/html/ports.js +++ b/html/ports.js @@ -22,6 +22,7 @@ function createPortTable() { let portName = portNames[physToLogPort[i-1]] || ''; td = tr.insertCell(); td.appendChild(document.createTextNode(portName)); td = tr.insertCell(); td.innerHTML = linkText(pState[i] + 1); + tr.insertCell(); // filled by devRender() td = tr.insertCell(); td.innerHTML = sSelect.replaceAll("speed_sel", "speed_sel_" + i); td = tr.insertCell(); td.innerHTML = dSwitch.replaceAll("disable_port", "disable_port_" + i) .replace("portOnOff()", "portOnOff(" + i + ")"); @@ -117,6 +118,46 @@ async function applyMTU(port) { } } +function devRender(entries) { + var tbl = document.getElementById('speedtable'); + if (tbl.rows.length <= 2 || !numPorts) + return; + var perPort = {}; + for (var i = 0; i < entries.length; i++) { + var e = entries[i]; + if (e.port == 'CPU') + continue; + if (!perPort[e.port]) + perPort[e.port] = []; + if (perPort[e.port].indexOf(e.mac) < 0) + perPort[e.port].push(e.mac); + } + for (let i = 1; i <= numPorts; i++) { + if (pIsSFP[i-1]) + continue; + var cell = tbl.rows[i].cells[3]; + var macs = perPort[i] || []; + if (macs.length == 1) { + cell.textContent = macs[0]; + cell.title = ''; + } else if (macs.length > 1) { + cell.textContent = macs.length + ' ' + t('port_devices'); + cell.title = macs.join('\n'); + } else { + cell.textContent = ''; + cell.title = ''; + } + } +} + +function devWalk() { + walkL2(function(entries, ok) { + if (ok) + devRender(entries); + setTimeout(devWalk, 15000); + }); +} + function getMTUs() { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { @@ -143,6 +184,7 @@ window.addEventListener("load", function() { createPortTable(); updatePortTable(); getMTUs() + setTimeout(devWalk, 3000); const interval = setInterval(update, 2000); const updatePortTableInterval = setInterval(updatePortTable, 1000); });