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

Function _pcap_wifi

network_diagnostics.py:1538–1620  ·  view source on GitHub ↗

Extract the 802.11 events that explain client drops: deauth/disassoc reason codes (per client), auth/assoc failure status codes, EAPOL 4-way handshake volume, retry rate, and SSIDs. tshark gives reason/status as hex.

(path, total_wlan_frames)

Source from the content-addressed store, hash-verified

1536 # proxy-NDP can also explain it). True NDP spoofing is ndpwatch's job, not this.
1537 v6_bindings, eui64_mismatches, seen6 = [], [], {}
1538 for ip6, mac6, _state in _neigh6_entries():
1539 m6 = _mac_norm(mac6)
1540 if not m6 or m6 in local:
1541 continue
1542 seen6.setdefault(m6, set()).add(ip6)
1543 emb = _eui64_embedded_mac(ip6)
1544 if emb and emb != m6 and _classify_mac(emb)['klass'] != 'invalid':
1545 eui64_mismatches.append({'ip': ip6, 'mac': m6, 'embedded_mac': emb})
1546 for mac6, ips6 in sorted(seen6.items()):
1547 info6 = _classify_mac(mac6)
1548 v6_bindings.append({'mac': mac6, 'ips': sorted(ips6),
1549 'prefixes': sorted({_v6_prefix64(i) for i in ips6}),
1550 'klass': info6['klass'], 'vendor': info6['vendor']})
1551 for e in eui64_mismatches[:8]:
1552 reasons.append(
1553 f"IPv6 {e['ip']} is a SLAAC EUI-64 address embedding MAC "
1554 f"{e['embedded_mac']}, but the NDP cache binds it to {e['mac']} — a "
1555 f"MAC-identity contradiction (spoof; proxy-NDP can also explain it)")
1556
1557 if spoofed or clones or hi_events or fhrp_hijacks:
1558 verdict = 'spoofed'
1559 elif tracks or randomized or fhrp_virtuals:
1560 verdict = 'suspicious' if tracks else ('fhrp' if fhrp_virtuals and not randomized
1561 else 'randomization')
1562 if eui64_mismatches and verdict in ('clean', 'randomization', 'fhrp'):
1563 verdict = 'suspicious'
1564
1565 return {
1566 'success': True, 'verdict': verdict,
1567 'summary': {
1568 'observed': len(current),
1569 'spoofed': len(spoofed),
1570 'clones': len(clones),
1571 'past_events': len(hi_events),
1572 'randomized': len(randomized),
1573 'virtual': len(virtual),
1574 'tracks': len(tracks),
1575 'fhrp_virtual': len(fhrp_virtuals),
1576 'fhrp_hijacks': len(fhrp_hijacks),
1577 'ipv6_bindings': len(v6_bindings),
1578 'eui64_mismatch': len(eui64_mismatches),
1579 },
1580 'spoofed': spoofed,
1581 'clones': clones,
1582 'fhrp': fhrp,
1583 'ipv6': {'bindings': v6_bindings, 'eui64_mismatches': eui64_mismatches},
1584 # Every MAC seen this pass, worst class first, so the UI can list them.
1585 'observed_macs': sorted(
1586 current,
1587 key=lambda c: ({'spoofed_vendor_oui': 0, 'universal': 1,
1588 'randomized': 2, 'virtual_laa': 3}.get(c['klass'], 4),
1589 c['ips'][0] if c['ips'] else '', c['mac'])),
1590 'events': [dict(e, ago=_fmt_ago(now - e['ts'])) for e in recent_events[-20:]][::-1],
1591 'randomization': randomization,
1592 'tracks': tracks,
1593 'gateway': {'ip': gw, 'mac': gw_mac},
1594 'interface': scan_iface,
1595 'scanned': scanned,

Callers 1

do_pcap_analyzeFunction · 0.85

Calls 11

collectFunction · 0.85
_tshark_fieldsFunction · 0.85
_to_intFunction · 0.85
code_tableFunction · 0.85
top_clientsFunction · 0.85
addMethod · 0.80
appendMethod · 0.80
setFunction · 0.50
getMethod · 0.45
decodeMethod · 0.45
valuesMethod · 0.45

Tested by

no test coverage detected