From e52cd355e7d890dbc6b91879b66bd717b89973c5 Mon Sep 17 00:00:00 2001 From: Robert McMahon Date: Fri, 13 Feb 2026 15:44:16 -0800 Subject: [PATCH] Change duration argument to time and add timestamps to sample packets - Change CLI argument from -d/--duration to -t/--time - Add timestamps with milliseconds to sample packets output - Update all documentation examples to use --time/-t - Format timestamps as HH:MM:SS.mmm for better readability Co-authored-by: Cursor --- wifi_monitor.py | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/wifi_monitor.py b/wifi_monitor.py index 5c517b1..8317fa3 100755 --- a/wifi_monitor.py +++ b/wifi_monitor.py @@ -5,9 +5,9 @@ Replaces the bash script with a pure Python solution. Usage: # Live capture from interface: - sudo python3 wifi_monitor.py --interface wlan0 --channel 36 --duration 10 - sudo python3 wifi_monitor.py -i wlan0 -c 36 -d 10 --keep-pcap - sudo python3 wifi_monitor.py --interface wlan0 --channel 36 --duration 10 --full-packet + sudo python3 wifi_monitor.py --interface wlan0 --channel 36 --time 10 + sudo python3 wifi_monitor.py -i wlan0 -c 36 -t 10 --keep-pcap + sudo python3 wifi_monitor.py --interface wlan0 --channel 36 --time 10 --full-packet # Read from pcap file: python3 wifi_monitor.py --pcap /tmp/capture.pcap @@ -23,6 +23,7 @@ import sys import tempfile import time from collections import Counter, defaultdict +from datetime import datetime # Third-party imports from scapy.all import RadioTap, rdpcap, sniff, wrpcap @@ -409,6 +410,14 @@ class CaptureAnalyzer: """Analyzes packet captures and generates statistics.""" def __init__(self, parser): self.parser = parser + + @staticmethod + def _format_timestamp(pkt): + """Format packet timestamp as HH:MM:SS.mmm.""" + if hasattr(pkt, 'time') and pkt.time: + dt = datetime.fromtimestamp(pkt.time) + return dt.strftime("%H:%M:%S.%f")[:-3] # Truncate to milliseconds + return "N/A" def analyze(self, packets, duration): """Analyze captured packets and generate statistics.""" @@ -464,8 +473,10 @@ class CaptureAnalyzer: duration_val = pkt[Dot11].Duration if hasattr(pkt[Dot11], 'Duration') else "N/A" plcp = "yes" if pkt.haslayer(RadioTap) else "no" + + timestamp = self._format_timestamp(pkt) - print(f" Frame {i+1}: RA={ra_str}, TA={ta_str}, type={frame_type}, {encrypted}, dur={duration_val}, PLCP={plcp}{retry}") + print(f" Frame {i+1}: time={timestamp}, RA={ra_str}, TA={ta_str}, type={frame_type}, {encrypted}, dur={duration_val}, PLCP={plcp}{retry}") print() def _print_ra_ta_pairs(self, packets): @@ -684,7 +695,7 @@ class PacketCapture: print("=== Testing Monitor Mode with scapy ===") print(f"Interface: {interface}") print(f"Channel: {channel}") - print(f"Duration: {duration} seconds") + print(f"Time: {duration} seconds") print() monitor = WiFiMonitor(interface, channel) @@ -738,7 +749,8 @@ class PacketCapture: ra_str = ra if ra else "N/A" ta_str = ta if ta else "N/A" plcp = "yes" if pkt.haslayer(RadioTap) else "no" - print(f" Frame {i+1 if i > 0 else test_count}: RA={ra_str}, TA={ta_str}, PLCP={plcp}") + timestamp = self.analyzer._format_timestamp(pkt) + print(f" Frame {i+1 if i > 0 else test_count}: time={timestamp}, RA={ra_str}, TA={ta_str}, PLCP={plcp}") print(f"\nTest capture results:") print(f" Packets captured: {test_count}") @@ -826,14 +838,14 @@ Examples: # Live capture with defaults (wlan0, channel 36, 10 seconds): sudo python3 wifi_monitor.py - # Live capture with specific interface, channel, and duration: - sudo python3 wifi_monitor.py --interface wlan0 --channel 36 --duration 10 + # Live capture with specific interface, channel, and time: + sudo python3 wifi_monitor.py --interface wlan0 --channel 36 --time 10 # Short form: - sudo python3 wifi_monitor.py -i wlan1 -c 11 -d 5 + sudo python3 wifi_monitor.py -i wlan1 -c 11 -t 5 # Save captured packets to pcap file: - sudo python3 wifi_monitor.py -i wlan0 -c 36 -d 10 --keep-pcap + sudo python3 wifi_monitor.py -i wlan0 -c 36 -t 10 --keep-pcap # Analyze existing pcap file: python3 wifi_monitor.py --pcap /tmp/capture.pcap @@ -863,11 +875,11 @@ Examples: help='WiFi channel (default: 36)' ) parser.add_argument( - '--duration', '-d', + '--time', '-t', type=int, default=10, metavar='SECONDS', - help='Capture duration in seconds (default: 10)' + help='Capture time in seconds (default: 10)' ) # Flags @@ -908,7 +920,7 @@ Examples: else: # Live capture mode self.config.wifi_interface = args.interface - return ('live', args.interface, args.channel, args.duration) + return ('live', args.interface, args.channel, args.time) def main():