MCPcopy Create free account
hub / github.com/PierreGode/Ragnar / renderWifiInterfaceSwitch

Function renderWifiInterfaceSwitch

web/scripts/ragnar_modern.js:8921–8969  ·  view source on GitHub ↗
(interfaces = [])

Source from the content-addressed store, hash-verified

8919 html += `<p class="text-xs uppercase text-gray-400 mt-4 mb-1">All MACs observed (${obs.length})</p>` +
8920 '<table class="min-w-full text-xs text-gray-300 whitespace-nowrap"><thead>' +
8921 '<tr class="text-left text-gray-500"><th class="px-2 py-1">MAC</th><th class="px-2 py-1">Type</th><th class="px-2 py-1">Vendor</th><th class="px-2 py-1">IP(s)</th></tr>' +
8922 '</thead><tbody>' +
8923 obs.map(c => {
8924 const [lbl, cls] = KLASS[c.klass] || [c.klass, 'text-gray-400'];
8925 const ips = (c.ips || []);
8926 return `<tr class="border-t border-slate-800">
8927 <td class="px-2 py-1 font-mono ${c.klass === 'spoofed_vendor_oui' ? 'text-red-300' : ''}">${escapeHtml(c.mac)}</td>
8928 <td class="px-2 py-1 ${cls}">${escapeHtml(lbl)}</td>
8929 <td class="px-2 py-1 text-gray-400">${escapeHtml(c.vendor || '—')}</td>
8930 <td class="px-2 py-1 font-mono">${escapeHtml(ips.slice(0, 4).join(', ')) || '—'}${ips.length > 4 ? '…' : ''}</td>
8931 </tr>`;
8932 }).join('') +
8933 '</tbody></table>';
8934 }
8935 // Reasons narrative
8936 if (d.reasons && d.reasons.length) {
8937 html += '<ul class="text-xs text-gray-400 mt-3 list-disc pl-5">' +
8938 d.reasons.map(x => '<li>' + escapeHtml(x) + '</li>').join('') + '</ul>';
8939 }
8940 if (!d.oui_db) {
8941 html += '<p class="text-xs text-gray-600 mt-2">OUI vendor database not installed — spoof detection uses the built-in seed only. Install arp-scan for full vendor coverage.</p>';
8942 }
8943 out.innerHTML = html;
8944 } catch (e) {
8945 out.innerHTML = '<p class="text-sm text-red-400">Failed: ' + escapeHtml(e.message) + '</p>';
8946 } finally {
8947 _ndBusy(btn, false);
8948 }
8949}
8950async function macWatchReset() {
8951 try {
8952 await postAPI('/api/net/mac-watch-reset', {});
8953 addConsoleMessage('MAC Watch history cleared', 'info');
8954 const out = document.getElementById('macwatch-results');
8955 if (out) { out.classList.remove('hidden'); out.innerHTML = '<p class="text-sm text-gray-400">History cleared — run a scan to rebuild it.</p>'; }
8956 } catch (e) {
8957 addConsoleMessage('Failed to reset MAC Watch history: ' + e.message, 'error');
8958 }
8959}
8960function exportMacWatchCsv() {
8961 const d = _ndLastMacWatch;
8962 const TYPE = { spoofed_vendor_oui: 'Spoofed', universal: 'Vendor',
8963 randomized: 'Randomized', virtual_laa: 'Virtual/VM' };
8964 _ndDownloadCsv('mac_watch' + (d && d.interface ? '_' + d.interface : ''),
8965 ['MAC', 'Type', 'Vendor', 'IPs', 'Flag', 'Note'],
8966 ((d && d.observed_macs) || []).map(c => {
8967 const ips = c.ips || [];
8968 const flag = c.klass === 'spoofed_vendor_oui' ? 'SPOOFED'
8969 : (ips.length > 1 ? 'CLONE (multiple IPs)' : '');
8970 return [c.mac, TYPE[c.klass] || c.klass, c.vendor || '',
8971 ips.join(' '), flag, c.note || ''];
8972 }));

Callers 2

refreshWifiStatusFunction · 0.70
loadWifiInterfacesFunction · 0.70

Calls 5

filterMethod · 0.80
setWifiInterfaceMetadataFunction · 0.70
getActiveWifiInterfaceFunction · 0.70
setSelectedWifiInterfaceFunction · 0.70

Tested by

no test coverage detected