From b448b41fa8225057421b734d630822b6fdee90c9 Mon Sep 17 00:00:00 2001 From: Yaro Kasear Date: Thu, 10 Apr 2025 09:18:24 -0500 Subject: [PATCH] Fix querying Kismet log. --- kismet_enrich_csv.py | 65 +++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/kismet_enrich_csv.py b/kismet_enrich_csv.py index 69740ed..40b0e0a 100755 --- a/kismet_enrich_csv.py +++ b/kismet_enrich_csv.py @@ -20,31 +20,64 @@ def convert_timestamp_to_epoch(ts_string): def get_rf_metrics(cursor, bssid, channel, start_time, end_time): cursor.execute(""" - SELECT COUNT(*) FROM devicelink - WHERE type = 'Wi-Fi Client' AND mac = ? AND last_time BETWEEN ? AND ? - """, (bssid.lower(), start_time, end_time)) + SELECT COUNT(*) FROM devices + WHERE type = 'Wi-Fi Client' + AND last_time BETWEEN ? AND ? + AND LOWER(json_extract(device, '$.kismet.device.base.bssid')) = ? + """, (start_time, end_time, bssid.lower())) clients_on_ap = cursor.fetchone()[0] cursor.execute(""" - SELECT COUNT(DISTINCT devicelink.remote_mac) - FROM devicelink - JOIN devices ON devicelink.mac = devices.base_mac - WHERE devicelink.type = 'Wi-Fi Client' - AND devices.channel = ? - AND devicelink.last_time BETWEEN ? AND ? - """, (channel, start_time, end_time)) + SELECT COUNT(*) FROM devices + WHERE type = 'Wi-Fi Client' + AND last_time BETWEEN ? AND ? + AND ( + json_extract(device, '$.kismet.device.base.channel') = ? OR + json_type(json_extract(device, '$.kismet.device.base.freq_khz_map')) = 'object' + ) + AND json_extract(device, '$.kismet.device.base.packets.total') > 0 + """, (start_time, end_time, channel)) clients_on_channel = cursor.fetchone()[0] cursor.execute(""" SELECT COUNT(*) FROM devices - WHERE type = 'Wi-Fi AP' AND channel = ? - AND last_time BETWEEN ? AND ? - """, (channel, start_time, end_time)) + WHERE type = 'Wi-Fi AP' + AND last_time BETWEEN ? AND ? + AND ( + json_extract(device, '$.kismet.device.base.channel') = ? OR + json_type(json_extract(device, '$.kismet.device.base.freq_khz_map')) = 'object' + ) + AND strongest_signal < 0 + """, (start_time, end_time, channel)) aps_on_channel = cursor.fetchone()[0] - congestion_score = round(clients_on_channel / aps_on_channel, 2) if aps_on_channel else 0.0 + cursor.execute(""" + SELECT strongest_signal FROM devices + WHERE type = 'Wi-Fi AP' + AND last_time BETWEEN ? AND ? + AND ( + json_extract(device, '$.kismet.device.base.channel') = ? OR + json_type(json_extract(device, '$.kismet.device.base.freq_khz_map')) = 'object' + ) + AND strongest_signal < 0 + """, (start_time, end_time, channel)) + signals = cursor.fetchall() + avg_signal = sum([s[0] for s in signals]) / len(signals) if signals else None + strongest_signal = max([s[0] for s in signals]) if signals else None - return clients_on_ap, clients_on_channel, aps_on_channel, congestion_score + cursor.execute(""" + SELECT COUNT(*) FROM devices + WHERE type = 'Wi-Fi Client' + AND last_time BETWEEN ? AND ? + AND json_extract(device, '$.kismet.device.base.channel') IS NULL + AND json_type(json_extract(device, '$.kismet.device.base.freq_khz_map')) != 'object' + AND json_extract(device, '$.kismet.device.base.packets.total') = 0 + """, (start_time, end_time)) + unlinked_devices = cursor.fetchone()[0] + + congestion_score = round(clients_on_channel / aps_on_channel, 2) if aps_on_channel else None + + return clients_on_ap, clients_on_channel, aps_on_channel, congestion_score, avg_signal, strongest_signal, unlinked_devices def main(): args = parse_args() @@ -70,7 +103,7 @@ def main(): writer.writerow(row) continue - if ts is None: + if tstart is None or tend is None: writer.writerow(row) continue