diff --git a/templates/index.html b/templates/index.html index f226205..47b2475 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1272,6 +1272,13 @@ + +
+
πŸ“‹ Selected Device
+
+
Click a network or client to view details
+
+

πŸ•ΈοΈ Network Topology

@@ -3731,6 +3738,8 @@ let activeCapture = null; // {bssid, channel, file, startTime, pollInterval} let watchMacs = JSON.parse(localStorage.getItem('watchMacs') || '[]'); let alertedMacs = new Set(); // Prevent duplicate alerts per session + let selectedWifiDevice = null; // Selected network or client for details view + let selectedWifiType = null; // 'network' or 'client' // 5GHz channel mapping for the graph const channels5g = ['36', '40', '44', '48', '52', '56', '60', '64', '100', '149', '153', '157', '161', '165']; @@ -4686,6 +4695,9 @@ updateChannelGraph(); updateChannel5gGraph(); + // Update selected device panel + updateWifiSelectedDevice(); + // Update probe analysis (throttled) if (clientsToProcess.length > 0) { scheduleProbeAnalysisUpdate(); @@ -4878,7 +4890,7 @@ }).join(' '); html += ` -
+
${escapeHtml(client.mac)} ${vendorBadge} @@ -4895,6 +4907,116 @@ list.innerHTML = html; } + // Select a WiFi network or client for detailed view + function selectWifiDevice(id, type) { + selectedWifiDevice = id; + selectedWifiType = type; + updateWifiSelectedDevice(); + } + + // Update the selected WiFi device panel + function updateWifiSelectedDevice() { + const panel = document.getElementById('wifiSelectedDevice'); + if (!panel) return; + + if (!selectedWifiDevice) { + panel.innerHTML = '
Click a network or client to view details
'; + return; + } + + if (selectedWifiType === 'network') { + const net = wifiNetworks[selectedWifiDevice]; + if (!net) { + panel.innerHTML = '
Network no longer visible
'; + return; + } + + const power = parseInt(net.power) || -100; + const signalPercent = Math.max(0, Math.min(100, (power + 100) * 2)); + const signalColor = power >= -50 ? 'var(--accent-green)' : power >= -70 ? 'var(--accent-orange)' : 'var(--accent-red)'; + + panel.innerHTML = ` +
+
+
${escapeHtml(net.essid || '[Hidden]')}
+
${escapeHtml(net.bssid)}
+
+
+
SIGNAL
+
${power} dBm
+
+
+
+
+
+
CHANNEL
+
${net.channel}
+
+
+
SECURITY
+
${escapeHtml(net.privacy || 'Unknown')}
+
+
+
BEACONS
+
${net.beacons || 0}
+
+
+ + +
+
+ `; + } else if (selectedWifiType === 'client') { + const client = wifiClients[selectedWifiDevice]; + if (!client) { + panel.innerHTML = '
Client no longer visible
'; + return; + } + + const power = parseInt(client.power) || -100; + const signalPercent = Math.max(0, Math.min(100, (power + 100) * 2)); + const signalColor = power >= -50 ? 'var(--accent-green)' : power >= -70 ? 'var(--accent-orange)' : 'var(--accent-red)'; + const probes = (client.probes || '').split(',').map(p => p.trim()).filter(p => p); + const associatedNet = client.bssid && wifiNetworks[client.bssid]; + + panel.innerHTML = ` +
+
+
CLIENT DEVICE
+
${escapeHtml(client.mac)}
+ ${client.vendor ? `
${escapeHtml(client.vendor)}
` : ''} +
+
+
SIGNAL
+
${power} dBm
+
+
+
+
+
+
PACKETS
+
${client.packets || 0}
+
+ ${associatedNet ? ` +
+
CONNECTED TO
+
${escapeHtml(associatedNet.essid || associatedNet.bssid)}
+
+ ` : ''} + ${probes.length > 0 ? ` +
+
PROBING FOR
+
+ ${probes.slice(0, 5).map(p => `${escapeHtml(p)}`).join('')} + ${probes.length > 5 ? `+${probes.length - 5} more` : ''} +
+
+ ` : ''} +
+ `; + } + } + // Add WiFi network card to output function addWifiNetworkCard(net, isNew) { const output = document.getElementById('output'); @@ -4911,11 +5033,18 @@ card.style.borderLeftColor = net.privacy.includes('WPA') ? 'var(--accent-orange)' : net.privacy.includes('WEP') ? 'var(--accent-red)' : 'var(--accent-green)'; + card.style.cursor = 'pointer'; + card.onclick = () => selectWifiDevice(net.bssid, 'network'); output.insertBefore(card, output.firstChild); } - const signalStrength = parseInt(net.power) || -100; - const signalBars = Math.max(0, Math.min(5, Math.floor((signalStrength + 100) / 15))); + // Handle signal strength - airodump returns -1 when not measured + let signalStrength = parseInt(net.power); + if (isNaN(signalStrength) || signalStrength === -1) { + signalStrength = null; // No reading available + } + const signalBars = signalStrength !== null ? Math.max(0, Math.min(5, Math.floor((signalStrength + 100) / 15))) : 0; + const signalDisplay = signalStrength !== null ? `${signalStrength} dBm` : 'N/A'; const wpsEnabled = net.wps === '1' || net.wps === 'Yes' || (net.privacy || '').includes('WPS'); const wpsHtml = wpsEnabled ? 'WPS' : ''; @@ -4936,7 +5065,7 @@
Signal
-
${net.power} dBm ${'β–ˆ'.repeat(signalBars)}${'β–‘'.repeat(5-signalBars)}
+
${signalDisplay} ${'β–ˆ'.repeat(signalBars)}${'β–‘'.repeat(5-signalBars)}
Beacons