From 6a79516a28b58d98358ee4e817adc906eb731402 Mon Sep 17 00:00:00 2001 From: Cobra Date: Wed, 8 Apr 2026 20:31:49 -0400 Subject: [PATCH] Enrich net_alerter alerts with OUI vendor and reverse DNS hostname Parse nmap vendor name from MAC Address line (filtering out 'Unknown'). Fall back to socket.gethostbyaddr for IPs nmap didn't resolve a hostname for. Alert label is now: 'hostname (vendor)' | 'hostname' | 'vendor' | 'unknown', in that priority order. --- net_alerter/net_alerter.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/net_alerter/net_alerter.py b/net_alerter/net_alerter.py index 981a2c2..d55eaa2 100644 --- a/net_alerter/net_alerter.py +++ b/net_alerter/net_alerter.py @@ -181,9 +181,11 @@ def scan_subnet(cidr: str) -> list[dict]: else: current = {"name": "", "ip": m.group(1), "mac": ""} elif "MAC Address:" in line: - m = re.search(r"MAC Address: ([0-9A-F:]{17})", line) + m = re.search(r"MAC Address: ([0-9A-F:]{17})(?:\s+\((.+?)\))?", line) if m: current["mac"] = m.group(1).lower() + if m.group(2) and m.group(2) != "Unknown": + current["vendor"] = m.group(2) if current.get("mac"): devices.append(current) @@ -274,7 +276,21 @@ def run() -> None: # Send alerts for event, d in alerts: - label = d["name"] if d["name"] else "unknown" + name = d.get("name", "") + vendor = d.get("vendor", "") + if not name: + try: + name = socket.gethostbyaddr(d["ip"])[0] + except Exception: + pass + if name and vendor: + label = f"{name} ({vendor})" + elif name: + label = name + elif vendor: + label = vendor + else: + label = "unknown" tag = "NEW DEVICE" if event == "NEW" else "DEVICE REJOINED" msg = ( f"[{hostname}] {tag}\n"