Add SQLite OUI database lookup to net_alerter
- lookup_oui() now tries SQLite first (/opt/net_alerter/oui.db) - Falls back to inline OUI_DICT if DB missing or query fails - No network calls, local SQLite reads only - Debug-level logging for failures (no output noise)
This commit is contained in:
@@ -20,6 +20,7 @@ import threading
|
|||||||
import time
|
import time
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import urllib.request
|
import urllib.request
|
||||||
|
import sqlite3
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
# --- Config (from .env or env vars) ---
|
# --- Config (from .env or env vars) ---
|
||||||
@@ -27,6 +28,7 @@ MATRIX_HOMESERVER = ""
|
|||||||
MATRIX_ACCESS_TOKEN = ""
|
MATRIX_ACCESS_TOKEN = ""
|
||||||
MATRIX_ROOM_ID = ""
|
MATRIX_ROOM_ID = ""
|
||||||
LOG_FILE = "/opt/net_alerter/net_alerter.log"
|
LOG_FILE = "/opt/net_alerter/net_alerter.log"
|
||||||
|
OUI_DB_PATH = "/opt/net_alerter/oui.db"
|
||||||
|
|
||||||
known_devices = {} # {mac: {ip, hostname, vendor, first_seen, last_seen, infrastructure (opt)}}
|
known_devices = {} # {mac: {ip, hostname, vendor, first_seen, last_seen, infrastructure (opt)}}
|
||||||
known_lock = threading.Lock()
|
known_lock = threading.Lock()
|
||||||
@@ -279,14 +281,29 @@ def load_env():
|
|||||||
def lookup_oui(mac: str) -> str:
|
def lookup_oui(mac: str) -> str:
|
||||||
"""
|
"""
|
||||||
Look up OUI vendor from MAC address (first 3 octets).
|
Look up OUI vendor from MAC address (first 3 octets).
|
||||||
Uses inline dictionary of top 200 common vendors.
|
Tries SQLite database first, falls back to inline dictionary.
|
||||||
Returns vendor name or 'unknown' if not found.
|
Returns vendor name or 'unknown' if not found.
|
||||||
"""
|
"""
|
||||||
if not mac or mac == "00:00:00:00:00:00":
|
if not mac or mac == "00:00:00:00:00:00":
|
||||||
return "unknown"
|
return "unknown"
|
||||||
|
|
||||||
oui_prefix = mac[:8].replace(":", "").upper()
|
# Try database first
|
||||||
return OUI_DICT.get(oui_prefix, "unknown")
|
oui_prefix = mac[:8].lower()
|
||||||
|
try:
|
||||||
|
conn = sqlite3.connect(OUI_DB_PATH, timeout=1)
|
||||||
|
conn.row_factory = sqlite3.Row
|
||||||
|
cursor = conn.cursor()
|
||||||
|
result = cursor.execute("SELECT vendor FROM oui WHERE prefix = ?", (oui_prefix,)).fetchone()
|
||||||
|
conn.close()
|
||||||
|
if result:
|
||||||
|
return result['vendor']
|
||||||
|
except Exception:
|
||||||
|
# Log at DEBUG only, no output noise
|
||||||
|
logging.debug(f"OUI database lookup failed for {oui_prefix}", exc_info=False)
|
||||||
|
|
||||||
|
# Fall back to inline dictionary
|
||||||
|
oui_prefix_upper = oui_prefix.replace(":", "").upper()
|
||||||
|
return OUI_DICT.get(oui_prefix_upper, "unknown")
|
||||||
|
|
||||||
|
|
||||||
def seed_from_arp_cache():
|
def seed_from_arp_cache():
|
||||||
|
|||||||
Reference in New Issue
Block a user