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

Function detectAndApplyHardware

web/scripts/ragnar_modern.js:7352–7396  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

7350 o.value = i.name;
7351 const tag = i.type === 'wifi' ? ' (WiFi)' : i.type === 'ethernet' ? ' (LAN)' : (i.type ? ' (' + i.type + ')' : '');
7352 o.textContent = i.name + tag;
7353 sel.appendChild(o);
7354 });
7355 sel.dataset.filled = '1';
7356 }).catch(() => {});
7357}
7358async function runNdpWatch() {
7359 const out = document.getElementById('ndp-results');
7360 if (!out) return;
7361 const btn = (typeof event !== 'undefined' && event && event.target) ? event.target : null;
7362 const ifaceSel = document.getElementById('ndp-iface');
7363 const iface = ifaceSel && ifaceSel.value ? ifaceSel.value : '';
7364 const secsEl = document.getElementById('ndp-secs');
7365 const secs = secsEl && secsEl.value ? secsEl.value : '12';
7366 _ndBusy(btn, true, 'Listening…');
7367 out.classList.remove('hidden');
7368 out.innerHTML = '<p class="text-sm text-gray-400">Passively capturing Neighbor Solicitation / Advertisement on the segment…</p>';
7369 try {
7370 _ndpFillIfaces();
7371 const qs = '?seconds=' + encodeURIComponent(secs) + (iface ? '&interface=' + encodeURIComponent(iface) : '');
7372 const d = await fetchAPI('/api/net/ndp-watch' + qs);
7373 if (!d || d.success === false) {
7374 const msg = (d && d.error) || 'failed';
7375 let extra = '';
7376 if (d && d.missing_tool) extra = ' <button onclick="installNetTool(\'tcpdump\', this, runNdpWatch)" class="ml-2 underline text-cyan-400">Install tcpdump</button>';
7377 out.innerHTML = '<p class="text-sm text-red-400">Error: ' + escapeHtml(msg) + extra + '</p>';
7378 return;
7379 }
7380 const [cls, label] = _NDP_VERDICT_STYLE[d.verdict] || _NDP_VERDICT_STYLE.unknown;
7381 let html = `<div class="mb-2 px-3 py-2 rounded border ${cls} text-sm">${label}</div>`;
7382 html += `<p class="text-xs text-gray-500 mb-2">Interface: ${escapeHtml(d.interface || '—')} · ${d.na_count} NA (${d.rate}/s) · ${d.ns_count} NS${d.dad_count ? ' · ' + d.dad_count + ' DAD' : ''}${d.learned ? ' · <span class="text-gray-400">baseline learned now</span>' : ''}</p>`;
7383 const hosts = d.hosts || [];
7384 if (hosts.length) {
7385 html += '<p class="text-xs uppercase text-gray-400 mt-2 mb-1">Advertised neighbours (' + hosts.length + ')</p>' +
7386 '<table class="min-w-full text-xs text-gray-300 whitespace-nowrap"><thead>' +
7387 '<tr class="text-left text-gray-500"><th class="px-2 py-1">IPv6 target</th><th class="px-2 py-1">Claimed by MAC(s)</th><th class="px-2 py-1">Trusted MAC</th><th class="px-2 py-1">State</th></tr>' +
7388 '</thead><tbody>' +
7389 hosts.map(h => {
7390 const bad = h.conflict || (h.baseline && h.macs.length === 1 && h.macs[0] !== h.baseline);
7391 return `<tr class="border-t border-slate-800">
7392 <td class="px-2 py-1 font-mono ${bad ? 'text-red-300' : 'text-gray-200'}">${escapeHtml(h.ip)}</td>
7393 <td class="px-2 py-1 font-mono ${bad ? 'text-red-300' : 'text-gray-400'}">${escapeHtml((h.macs || []).join(', '))}</td>
7394 <td class="px-2 py-1 font-mono text-gray-500">${escapeHtml(h.baseline || '—')}</td>
7395 <td class="px-2 py-1">${h.conflict ? '<span class="text-red-300">CONFLICT</span>' : bad ? '<span class="text-red-300">CHANGED</span>' : '<span class="text-gray-500">ok</span>'}</td>
7396 </tr>`;
7397 }).join('') + '</tbody></table>';
7398 }
7399 if (d.reasons && d.reasons.length) {

Callers

nothing calls this directly

Calls 4

errorMethod · 0.80
addConsoleMessageFunction · 0.70
fetchAPIFunction · 0.70
applyHardwareProfileFunction · 0.70

Tested by

no test coverage detected