diff --git a/listener.py b/listener.py index 908bf5f..5d3b4d4 100755 --- a/listener.py +++ b/listener.py @@ -33,6 +33,15 @@ bssid_channels = {} CHANNEL_LIST = [1, 6, 11, 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165] # Channels to hop CHANNEL_HOP_INTERVAL = 5 # Seconds per channel +def get_channel_from_freq(freq): + if 2412 <= freq <= 2472: + return (freq - 2407) // 5 + elif freq == 2484: + return 14 + elif 5180 <= freq <= 5825: + return (freq - 5000) // 5 + return None + # === Signal handling === def stop_sniff(signum, frame): global running @@ -87,6 +96,12 @@ def handle_packet(pkt): a1 = dot11.addr1.lower() if dot11.addr1 else None a2 = dot11.addr2.lower() if dot11.addr2 else None + try: + freq = pkt[RadioTap].ChannelFrequency + packet_channel = get_channel_from_freq(freq) + except: + packet_channel = current_channel or "?" + # === Detect APs via beacon (and optionally probe response) frames === if dot11.type == 0 and dot11.subtype in ([8, 5] if include_probes else [8]): if a2 and is_unicast(a2): @@ -150,7 +165,7 @@ def write_csv(outfile): "NumberofBSSIDsOnSSID": "N/A", "NumberofChannelsOnSSID": "N/A", "UnlinkedDevices": len(unlinked_candidates), - "Deadpoints": len([ap for ap in deadpoint_candidates if not ap_clients.get(ap)]) + "Deadpoints": len([ap for ap in deadpoint_candidates if is_deadpoint(ap)]) } new_file = not os.path.exists(outfile) @@ -195,7 +210,7 @@ def print_suspect_aps(): flags = [] if any(kw in ssid.lower() for kw in keywords): flags.append("Suspicious SSID") - if bssid in deadpoint_candidates and not ap_clients.get(bssid): + if is_deadpoint(bssid): flags.append("Deadpoint") if flags: suspects.append((bssid, ssid, flags)) @@ -216,6 +231,9 @@ def channel_hopper(interface): i += 1 time.sleep(CHANNEL_HOP_INTERVAL) +def is_deadpoint(ap_bssid): + return sum(ap_clients[ap_bssid].values()) < 2 # No meaningful client interaction + # === Main === def main(): parser = ArgumentParser()