Compare commits
2 Commits
fc9b8c7f00
...
77fb5c69d4
| Author | SHA1 | Date |
|---|---|---|
|
|
77fb5c69d4 | |
|
|
1ef363f644 |
|
|
@ -427,14 +427,18 @@ class CaptureAnalyzer:
|
||||||
total_count = len(packets)
|
total_count = len(packets)
|
||||||
print(f"Total packets captured (scapy): {total_count}")
|
print(f"Total packets captured (scapy): {total_count}")
|
||||||
|
|
||||||
|
scapy_data_count = sum(1 for pkt in packets if pkt.haslayer(Dot11) and pkt[Dot11].type == 2)
|
||||||
|
|
||||||
if tcpdump_data_count is not None:
|
if tcpdump_data_count is not None:
|
||||||
|
print(f"Data frames captured (scapy): {scapy_data_count}")
|
||||||
print(f"Data frames captured (tcpdump): {tcpdump_data_count}")
|
print(f"Data frames captured (tcpdump): {tcpdump_data_count}")
|
||||||
if total_count > 0:
|
if tcpdump_data_count > 0:
|
||||||
scapy_data_count = sum(1 for pkt in packets if pkt.haslayer(Dot11) and pkt[Dot11].type == 2)
|
ratio = scapy_data_count / tcpdump_data_count
|
||||||
print(f"Data frames captured (scapy): {scapy_data_count}")
|
print(f"Scapy capture ratio: {ratio:.1%} ({scapy_data_count}/{tcpdump_data_count})")
|
||||||
if tcpdump_data_count > 0:
|
elif scapy_data_count > 0:
|
||||||
ratio = scapy_data_count / tcpdump_data_count
|
print(f"Note: tcpdump found 0 data frames while scapy found {scapy_data_count}")
|
||||||
print(f"Scapy capture ratio: {ratio:.1%} ({scapy_data_count}/{tcpdump_data_count})")
|
else:
|
||||||
|
print("Note: tcpdump counter unavailable (tcpdump not found or failed)")
|
||||||
|
|
||||||
if total_count == 0:
|
if total_count == 0:
|
||||||
self._print_no_packets_message()
|
self._print_no_packets_message()
|
||||||
|
|
@ -786,11 +790,14 @@ class PacketCapture:
|
||||||
)
|
)
|
||||||
await check_proc.wait()
|
await check_proc.wait()
|
||||||
if check_proc.returncode != 0:
|
if check_proc.returncode != 0:
|
||||||
|
print("Warning: tcpdump not found, skipping concurrent count")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Use tcpdump with BPF filter for data frames
|
# Use tcpdump with BPF filter for data frames
|
||||||
# wlan[0] & 0x0C extracts the type field (bits 2-3)
|
# For 802.11 frames: wlan[0] contains Frame Control field
|
||||||
# Type 2 (data) = 0x08, so we check wlan[0] & 0x0C == 0x08
|
# Bits 2-3 are the type field: 00=Management, 01=Control, 10=Data
|
||||||
|
# Type 2 (Data) = 0x08 when masked with 0x0C
|
||||||
|
# BPF syntax: use == for equality comparison
|
||||||
proc = await asyncio.create_subprocess_exec(
|
proc = await asyncio.create_subprocess_exec(
|
||||||
"tcpdump",
|
"tcpdump",
|
||||||
"-i", interface,
|
"-i", interface,
|
||||||
|
|
@ -817,6 +824,18 @@ class PacketCapture:
|
||||||
_, stderr = await proc.communicate()
|
_, stderr = await proc.communicate()
|
||||||
stderr_text = stderr.decode() if stderr else ""
|
stderr_text = stderr.decode() if stderr else ""
|
||||||
|
|
||||||
|
# Check return code
|
||||||
|
if proc.returncode != 0 and proc.returncode != -15: # -15 is SIGTERM, which is expected
|
||||||
|
print(f"Warning: tcpdump exited with code {proc.returncode}")
|
||||||
|
if stderr_text:
|
||||||
|
print(f"tcpdump stderr: {stderr_text[:300]}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Debug: print stderr if no count found
|
||||||
|
if not stderr_text.strip():
|
||||||
|
print("Warning: tcpdump produced no output")
|
||||||
|
return None
|
||||||
|
|
||||||
# Parse tcpdump output for packet count
|
# Parse tcpdump output for packet count
|
||||||
# Format: "X packets captured" or "X packets received by filter"
|
# Format: "X packets captured" or "X packets received by filter"
|
||||||
data_frame_count = 0
|
data_frame_count = 0
|
||||||
|
|
@ -834,11 +853,19 @@ class PacketCapture:
|
||||||
if potential_count > data_frame_count:
|
if potential_count > data_frame_count:
|
||||||
data_frame_count = potential_count
|
data_frame_count = potential_count
|
||||||
|
|
||||||
return data_frame_count if data_frame_count > 0 else None
|
if data_frame_count == 0:
|
||||||
|
# Debug output - but still return 0 so we can show it
|
||||||
|
print(f"Warning: tcpdump found 0 data frames. tcpdump stderr: {stderr_text[:200]}")
|
||||||
|
|
||||||
|
# Return the count even if 0, so we can display it
|
||||||
|
return data_frame_count
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
|
print("Warning: tcpdump not found, skipping concurrent count")
|
||||||
return None
|
return None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Warning: tcpdump counter failed: {e}")
|
print(f"Warning: tcpdump counter failed: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def _main_capture_async(self, interface, duration):
|
async def _main_capture_async(self, interface, duration):
|
||||||
|
|
@ -860,9 +887,23 @@ class PacketCapture:
|
||||||
pcap_file.close()
|
pcap_file.close()
|
||||||
print(f"Capturing to file: {pcap_path}")
|
print(f"Capturing to file: {pcap_path}")
|
||||||
|
|
||||||
# Start tcpdump counter concurrently
|
# Start tcpdump counter concurrently (only if available)
|
||||||
print("Starting concurrent tcpdump counter for data frames...")
|
tcpdump_task = None
|
||||||
tcpdump_task = asyncio.create_task(self._run_tcpdump_counter(interface, duration))
|
try:
|
||||||
|
# Check if tcpdump is available before starting
|
||||||
|
check_proc = await asyncio.create_subprocess_exec(
|
||||||
|
"which", "tcpdump",
|
||||||
|
stdout=asyncio.subprocess.DEVNULL,
|
||||||
|
stderr=asyncio.subprocess.DEVNULL
|
||||||
|
)
|
||||||
|
await check_proc.wait()
|
||||||
|
if check_proc.returncode == 0:
|
||||||
|
print("Starting concurrent tcpdump counter for data frames...")
|
||||||
|
tcpdump_task = asyncio.create_task(self._run_tcpdump_counter(interface, duration))
|
||||||
|
else:
|
||||||
|
print("Note: tcpdump not found, skipping concurrent count")
|
||||||
|
except Exception:
|
||||||
|
print("Note: tcpdump not found, skipping concurrent count")
|
||||||
|
|
||||||
capture_error = None
|
capture_error = None
|
||||||
try:
|
try:
|
||||||
|
|
@ -901,8 +942,10 @@ class PacketCapture:
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
# Get tcpdump count
|
# Get tcpdump count (if task was started)
|
||||||
tcpdump_data_count = await tcpdump_task
|
tcpdump_data_count = None
|
||||||
|
if tcpdump_task is not None:
|
||||||
|
tcpdump_data_count = await tcpdump_task
|
||||||
|
|
||||||
self.analyzer.analyze(packets, duration, tcpdump_data_count)
|
self.analyzer.analyze(packets, duration, tcpdump_data_count)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue