diff --git a/listener.py b/listener.py index b770f6b..241fd72 100755 --- a/listener.py +++ b/listener.py @@ -13,12 +13,12 @@ from argparse import ArgumentParser # === Globals === running = True packet_count = 0 -clients = set() +clients = defaultdict(int) aps = set() ap_signals = defaultdict(list) # BSSID -> list of dBm ssid_map = {} # BSSID -> SSID ssid_signals = defaultdict(list) # SSID -> list of dBm -ap_clients = defaultdict(set) +ap_clients = defaultdict(int) target_ap_bssid = None # === Signal handling === @@ -72,11 +72,8 @@ def handle_packet(pkt): return dot11 = pkt[Dot11] - a1 = dot11.addr1.lower() - try: - a2 = dot11.addr2.lower() - except: - a2 = None + a1 = dot11.addr1.lower() if dot11.addr1 else None + a2 = dot11.addr2.lower() if dot11.addr2 else None # === Detect APs via beacons/probe responses === if dot11.type == 0 and dot11.subtype in (5, 8): # Probe Response or Beacon @@ -88,10 +85,9 @@ def handle_packet(pkt): # === Track all seen clients === if is_unicast(a1) and a1 not in aps: - clients.add(a1) - + clients[a1] += 1 if is_unicast(a2) and a2 not in aps: - clients.add(a2) + clients[a2] += 1 # === Guess client <-> AP relationships === if a1 in aps and a2: @@ -105,7 +101,7 @@ def handle_packet(pkt): if target_ap_bssid in (a1.lower(), a2.lower()): peer = a2 if a1 == target_ap_bssid else a1 if is_unicast(peer) and peer not in aps: - ap_clients[target_ap_bssid].add(peer) + ap_clients[target_ap_bssid][peer] += 1 # === Signal strength tracking === try: @@ -123,14 +119,14 @@ def write_csv(outfile): timestamp = datetime.utcnow().isoformat() row = { "Timestamp": timestamp, - "ClientsOnChannel": len(clients), + "ClientsOnChannel": len([mac for mac, count in clients.items() if count > 3]), "APsOnChannel": len(aps), "PacketCount": packet_count, "AvgAPSignal": round(sum([sum(v)/len(v) for v in ap_signals.values() if v]) / len(ap_signals) if ap_signals else 0, 2), "StrongestAPSignal": max([max(v) for v in ap_signals.values() if v], default=0), "AvgSSIDSignal": round(sum([sum(v)/len(v) for v in ssid_signals.values() if v]) / len(ssid_signals) if ssid_signals else 0, 2), "MaxSSIDSignal": max([max(v) for v in ssid_signals.values() if v], default=0), - "ClientsOnAP": sum(len(s) for s in ap_clients.values()), + "ClientsOnAP": len([mac for mac, count in ap_clients[target_ap_bssid].items() if count > 3]), "CiscoAvgReportedClients": "N/A", "CiscoMaxReportedClients": "N/A", "NumberofBSSIDsOnSSID": "N/A",