Compare commits

..

3 commits

View file

@ -3,6 +3,7 @@ import argparse
import csv
from datetime import datetime
import pyshark
from statistics import mean
# United States regulatory domain channel lookup table
@ -183,9 +184,6 @@ def get_aps_on_channel(capture, ap_channel):
if ts_hex is None:
continue
# For debugging purposes, display the type_subtype value with some sarcasm
print(f"Type/Subtype Hex: {ts_hex}")
ts = int(ts_hex, 16)
if ts not in (5, 8): # Probe Response or Beacon
continue
@ -201,6 +199,54 @@ def get_aps_on_channel(capture, ap_channel):
return len(aps)
def calculate_signal_strength_stats(capture, ap_channel):
try:
ap_channel = int(ap_channel)
except ValueError:
print(f"[!] Could not parse channel number: {ap_channel}")
return 0
ap_signals = []
for packet in capture:
try:
if 'radiotap' not in packet or 'wlan' not in packet:
continue
radio = packet.radiotap
wlan = packet.wlan
if not hasattr(radio, 'channel') or not hasattr(radio.channel, 'freq'):
continue
packet_freq = int(radio.channel.freq)
packet_channel = get_channel_from_freq(packet_freq)
if packet_channel != ap_channel:
continue
# Check for beacon or probe response
ts_hex = getattr(wlan, 'type_subtype', None)
if ts_hex is None:
continue
ts = int(ts_hex, 16)
if ts not in (5, 8): # Probe Response or Beacon
continue
# Get signal strength
signal_strength = getattr(radio, 'dbm_antsignal', None)
if signal_strength is not None:
ap_signals.append(int(signal_strength))
except Exception as e:
print(f"[DEBUG] Signal strength parse error: {e}")
continue
if ap_signals:
return mean(ap_signals), max(ap_signals)
else:
return 0, 0
def analyze_pcap(pcapng_path, start_ts, end_ts, ap_bssid, ap_channel):
cap = pyshark.FileCapture(
pcapng_path,
@ -212,6 +258,9 @@ def analyze_pcap(pcapng_path, start_ts, end_ts, ap_bssid, ap_channel):
clients_on_ap = 0
clients_on_channel = 0
aps_on_channel = 0
avg_ap_signal = 0
max_ap_signal = 0
try:
# Filter packets manually by timestamp
@ -231,13 +280,16 @@ def analyze_pcap(pcapng_path, start_ts, end_ts, ap_bssid, ap_channel):
# Placeholder: Logic will be added for:
# - CongestionScore
# - AvgAPSignal
avg_ap_signal, max_ap_signal = calculate_signal_strength_stats(filtered_packets, ap_channel)
# - StrongestAPSignal
# - UnlinkedDevices
finally:
cap.close()
return clients_on_ap, clients_on_channel, aps_on_channel, None, None, None, 0
return clients_on_ap, clients_on_channel, aps_on_channel, avg_ap_signal, max_ap_signal, None, 0
def main():