(subtypes_filter)
| 1544 | continue |
| 1545 | seen6.setdefault(m6, set()).add(ip6) |
| 1546 | emb = _eui64_embedded_mac(ip6) |
| 1547 | if emb and emb != m6 and _classify_mac(emb)['klass'] != 'invalid': |
| 1548 | eui64_mismatches.append({'ip': ip6, 'mac': m6, 'embedded_mac': emb}) |
| 1549 | for mac6, ips6 in sorted(seen6.items()): |
| 1550 | info6 = _classify_mac(mac6) |
| 1551 | v6_bindings.append({'mac': mac6, 'ips': sorted(ips6), |
| 1552 | 'prefixes': sorted({_v6_prefix64(i) for i in ips6}), |
| 1553 | 'klass': info6['klass'], 'vendor': info6['vendor']}) |
| 1554 | for e in eui64_mismatches[:8]: |
| 1555 | reasons.append( |
| 1556 | f"IPv6 {e['ip']} is a SLAAC EUI-64 address embedding MAC " |
| 1557 | f"{e['embedded_mac']}, but the NDP cache binds it to {e['mac']} — a " |
| 1558 | f"MAC-identity contradiction (spoof; proxy-NDP can also explain it)") |
| 1559 | |
| 1560 | if spoofed or clones or hi_events or fhrp_hijacks: |
| 1561 | verdict = 'spoofed' |
no test coverage detected