diff --git a/db.py b/db.py index 040fb12..17cdecb 100644 --- a/db.py +++ b/db.py @@ -82,21 +82,35 @@ def init_db(): conn.close() -def upsert_switch(chassis_id, hostname, mgmt_ip, description, firmware='', vendor='', serial=''): +def upsert_switch(chassis_id, hostname, mgmt_ip, description, firmware='', vendor='', serial='', trusted=False): + """ + trusted=True means mgmt_ip came from directly scanning this switch (its own + SSH session / local LLDP info) — always authoritative. trusted=False means + it came from another switch's LLDP neighbor report about this one: some + switches (e.g. HP/Aruba ProCurve) advertise a per-port Management Address + TLV that reflects whatever VLAN happens to be routable out that specific + link, not the switch's real management IP — so an untrusted mgmt_ip is + only used to fill in a still-unknown value, never to overwrite one already + established by a trusted (direct) scan. + """ conn = get_conn() conn.execute(""" INSERT INTO switches (chassis_id, hostname, mgmt_ip, description, firmware, vendor, serial, last_seen) VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now')) ON CONFLICT(chassis_id) DO UPDATE SET hostname = excluded.hostname, - mgmt_ip = CASE WHEN excluded.mgmt_ip != '' AND excluded.mgmt_ip LIKE '%.%.%.%' - THEN excluded.mgmt_ip ELSE mgmt_ip END, + mgmt_ip = CASE + WHEN excluded.mgmt_ip = '' OR excluded.mgmt_ip NOT LIKE '%.%.%.%' THEN mgmt_ip + WHEN ? THEN excluded.mgmt_ip + WHEN mgmt_ip = '' OR mgmt_ip IS NULL THEN excluded.mgmt_ip + ELSE mgmt_ip + END, description = CASE WHEN excluded.description != '' THEN excluded.description ELSE description END, firmware = CASE WHEN excluded.firmware != '' THEN excluded.firmware ELSE firmware END, vendor = CASE WHEN excluded.vendor != '' THEN excluded.vendor ELSE vendor END, serial = CASE WHEN excluded.serial != '' THEN excluded.serial ELSE serial END, last_seen = excluded.last_seen - """, (chassis_id, hostname, mgmt_ip, description, firmware, vendor, serial)) + """, (chassis_id, hostname, mgmt_ip, description, firmware, vendor, serial, bool(trusted))) conn.commit() conn.close() diff --git a/scanner.py b/scanner.py index 821ad6f..40e6107 100644 --- a/scanner.py +++ b/scanner.py @@ -105,6 +105,7 @@ def run_scan(dept: str = None, workers: int = 5, login_delay: int = 3): firmware=result.get("firmware", ""), vendor=result.get("vendor", ""), serial=result.get("serial", ""), + trusted=True, ) for neighbor in result["neighbors"]: