diff --git a/kismet_enrich_from_pcap.py b/kismet_enrich_from_pcap.py new file mode 100644 index 0000000..1d6bf35 --- /dev/null +++ b/kismet_enrich_from_pcap.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +import argparse +import csv +from datetime import datetime +import pyshark + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--csv', required=True, help='Input speedtest CSV') + parser.add_argument('--pcapng', required=True, help='Kismet-generated .pcapng file') + parser.add_argument('--output', required=True, help='Output enriched CSV') + return parser.parse_args() + +def convert_timestamp_to_epoch(ts_string): + try: + return int(datetime.fromisoformat(ts_string.replace("Z", "+00:00")).timestamp()) + except Exception as e: + print(f"[!] Failed to parse timestamp: {ts_string}") + return None + +def analyze_pcap(pcapng_path, start_ts, end_ts): + # Placeholder: Logic will be added for: + # - ClientsOnAP + # - ClientsOnChannel + # - APsOnChannel + # - CongestionScore + # - AvgAPSignal + # - StrongestAPSignal + # - UnlinkedDevices + return 0, 0, 0, None, None, None, 0 + +def main(): + args = parse_args() + with open(args.csv, newline='') as infile, open(args.output, 'w', newline='', encoding='utf-8') as outfile: + reader = csv.DictReader(infile) + fieldnames = reader.fieldnames + [ + 'ClientsOnAP', 'ClientsOnChannel', 'APsOnChannel', 'CongestionScore', + 'AvgAPSignal', 'StrongestAPSignal', 'UnlinkedDevices' + ] + writer = csv.DictWriter(outfile, fieldnames=fieldnames) + writer.writeheader() + + for row in reader: + tstart = convert_timestamp_to_epoch(row.get("StartTimestamp")) + tend = convert_timestamp_to_epoch(row.get("EndTimestamp")) + + if not tstart or not tend: + writer.writerow(row) + continue + + clients_ap, clients_chan, aps_chan, congestion, avg_signal, strongest_signal, unlinked = analyze_pcap(args.pcapng, tstart, tend) + + row.update({ + 'ClientsOnAP': clients_ap, + 'ClientsOnChannel': clients_chan, + 'APsOnChannel': aps_chan, + 'CongestionScore': congestion, + 'AvgAPSignal': avg_signal, + 'StrongestAPSignal': strongest_signal, + 'UnlinkedDevices': unlinked + }) + + writer.writerow(row) + + print(f"[+] Enrichment complete: {args.output}") + +if __name__ == "__main__": + main() diff --git a/runtest.sh b/runtest.sh index 8c920d9..722be3c 100755 --- a/runtest.sh +++ b/runtest.sh @@ -11,9 +11,12 @@ TEST_FILE="/home/yaro/${BOOT_ID}-speedtest.csv" PING_COUNT=25 PING_TARGET=1.1.1.1 KISMET_LOG_DIR="/home/yaro/kismet_logs" +LEAD_TIME=90s ENRICHED_FILE="${TEST_FILE%}+rf.csv" +sleep $LEAD_TIME + # Function to get current TX failed count get_tx_failed() { iw dev $INTERFACE station dump | awk '/tx failed/ {print $3}'