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 <cursoragent@cursor.com>
This commit is contained in:
Robert McMahon 2026-02-13 15:44:16 -08:00
parent 12c57df2a2
commit e52cd355e7
1 changed files with 25 additions and 13 deletions

View File

@ -5,9 +5,9 @@ Replaces the bash script with a pure Python solution.
Usage: Usage:
# Live capture from interface: # Live capture from interface:
sudo python3 wifi_monitor.py --interface wlan0 --channel 36 --duration 10 sudo python3 wifi_monitor.py --interface wlan0 --channel 36 --time 10
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
sudo python3 wifi_monitor.py --interface wlan0 --channel 36 --duration 10 --full-packet sudo python3 wifi_monitor.py --interface wlan0 --channel 36 --time 10 --full-packet
# Read from pcap file: # Read from pcap file:
python3 wifi_monitor.py --pcap /tmp/capture.pcap python3 wifi_monitor.py --pcap /tmp/capture.pcap
@ -23,6 +23,7 @@ import sys
import tempfile import tempfile
import time import time
from collections import Counter, defaultdict from collections import Counter, defaultdict
from datetime import datetime
# Third-party imports # Third-party imports
from scapy.all import RadioTap, rdpcap, sniff, wrpcap from scapy.all import RadioTap, rdpcap, sniff, wrpcap
@ -409,6 +410,14 @@ class CaptureAnalyzer:
"""Analyzes packet captures and generates statistics.""" """Analyzes packet captures and generates statistics."""
def __init__(self, parser): def __init__(self, parser):
self.parser = 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): def analyze(self, packets, duration):
"""Analyze captured packets and generate statistics.""" """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" duration_val = pkt[Dot11].Duration if hasattr(pkt[Dot11], 'Duration') else "N/A"
plcp = "yes" if pkt.haslayer(RadioTap) else "no" 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() print()
def _print_ra_ta_pairs(self, packets): def _print_ra_ta_pairs(self, packets):
@ -684,7 +695,7 @@ class PacketCapture:
print("=== Testing Monitor Mode with scapy ===") print("=== Testing Monitor Mode with scapy ===")
print(f"Interface: {interface}") print(f"Interface: {interface}")
print(f"Channel: {channel}") print(f"Channel: {channel}")
print(f"Duration: {duration} seconds") print(f"Time: {duration} seconds")
print() print()
monitor = WiFiMonitor(interface, channel) monitor = WiFiMonitor(interface, channel)
@ -738,7 +749,8 @@ class PacketCapture:
ra_str = ra if ra else "N/A" ra_str = ra if ra else "N/A"
ta_str = ta if ta else "N/A" ta_str = ta if ta else "N/A"
plcp = "yes" if pkt.haslayer(RadioTap) else "no" 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"\nTest capture results:")
print(f" Packets captured: {test_count}") print(f" Packets captured: {test_count}")
@ -826,14 +838,14 @@ Examples:
# Live capture with defaults (wlan0, channel 36, 10 seconds): # Live capture with defaults (wlan0, channel 36, 10 seconds):
sudo python3 wifi_monitor.py sudo python3 wifi_monitor.py
# Live capture with specific interface, channel, and duration: # Live capture with specific interface, channel, and time:
sudo python3 wifi_monitor.py --interface wlan0 --channel 36 --duration 10 sudo python3 wifi_monitor.py --interface wlan0 --channel 36 --time 10
# Short form: # 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: # 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: # Analyze existing pcap file:
python3 wifi_monitor.py --pcap /tmp/capture.pcap python3 wifi_monitor.py --pcap /tmp/capture.pcap
@ -863,11 +875,11 @@ Examples:
help='WiFi channel (default: 36)' help='WiFi channel (default: 36)'
) )
parser.add_argument( parser.add_argument(
'--duration', '-d', '--time', '-t',
type=int, type=int,
default=10, default=10,
metavar='SECONDS', metavar='SECONDS',
help='Capture duration in seconds (default: 10)' help='Capture time in seconds (default: 10)'
) )
# Flags # Flags
@ -908,7 +920,7 @@ Examples:
else: else:
# Live capture mode # Live capture mode
self.config.wifi_interface = args.interface self.config.wifi_interface = args.interface
return ('live', args.interface, args.channel, args.duration) return ('live', args.interface, args.channel, args.time)
def main(): def main():