working to analyze timing issues

This commit is contained in:
2025-07-25 15:52:16 -04:00
parent 70c2a1b9d3
commit 4c6e23bff8
31 changed files with 3197 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
"""
Utility modules for the Ethernet Traffic Analyzer
"""
from .pcap_loader import PCAPLoader
from .live_capture import LiveCapture
__all__ = ['PCAPLoader', 'LiveCapture']

View File

@@ -0,0 +1,129 @@
"""
Live network capture utilities
"""
import sys
import threading
import time
from typing import Callable, Optional, List
try:
from scapy.all import sniff, Packet, get_if_list
except ImportError:
print("Error: scapy library required. Install with: pip install scapy")
sys.exit(1)
class LiveCapture:
"""Utility class for live network capture"""
def __init__(self, interface: Optional[str] = None, filter_str: Optional[str] = None):
self.interface = interface
self.filter_str = filter_str
self.is_capturing = False
self.stop_requested = False
self.packet_count = 0
self.capture_thread: Optional[threading.Thread] = None
self.packet_handlers: List[Callable[[Packet, int], None]] = []
def add_packet_handler(self, handler: Callable[[Packet, int], None]) -> None:
"""Add a packet handler function"""
self.packet_handlers.append(handler)
def remove_packet_handler(self, handler: Callable[[Packet, int], None]) -> None:
"""Remove a packet handler function"""
if handler in self.packet_handlers:
self.packet_handlers.remove(handler)
def start_capture(self, threaded: bool = True) -> None:
"""Start packet capture"""
if self.is_capturing:
raise RuntimeError("Capture is already running")
self.stop_requested = False
self.packet_count = 0
if threaded:
self.capture_thread = threading.Thread(target=self._capture_loop, daemon=True)
self.capture_thread.start()
else:
self._capture_loop()
def stop_capture(self) -> None:
"""Stop packet capture"""
self.stop_requested = True
if self.capture_thread and self.capture_thread.is_alive():
self.capture_thread.join(timeout=5.0)
if self.capture_thread.is_alive():
print("Warning: Capture thread did not stop gracefully")
def _capture_loop(self) -> None:
"""Main capture loop"""
self.is_capturing = True
try:
def packet_handler(packet: Packet) -> None:
if self.stop_requested:
return
self.packet_count += 1
# Call all registered handlers
for handler in self.packet_handlers:
try:
handler(packet, self.packet_count)
except Exception as e:
print(f"Error in packet handler: {e}")
sniff(
iface=self.interface,
filter=self.filter_str,
prn=packet_handler,
stop_filter=lambda x: self.stop_requested
)
except Exception as e:
print(f"Error during live capture: {e}")
finally:
self.is_capturing = False
def get_capture_stats(self) -> dict:
"""Get capture statistics"""
return {
'is_capturing': self.is_capturing,
'packet_count': self.packet_count,
'interface': self.interface,
'filter': self.filter_str
}
@staticmethod
def list_interfaces() -> List[str]:
"""List available network interfaces"""
try:
return get_if_list()
except Exception as e:
print(f"Error listing interfaces: {e}")
return []
@staticmethod
def validate_interface(interface: str) -> bool:
"""Validate that an interface exists"""
try:
available_interfaces = LiveCapture.list_interfaces()
return interface in available_interfaces
except Exception:
return False
@staticmethod
def test_capture_permissions() -> bool:
"""Test if we have permissions for packet capture"""
try:
# Try a very short capture to test permissions
def dummy_handler(packet):
pass
sniff(count=1, timeout=1, prn=dummy_handler)
return True
except Exception:
return False

View File

@@ -0,0 +1,96 @@
"""
PCAP file loading utilities
"""
import sys
from typing import List, Iterator, Optional
try:
from scapy.all import rdpcap, PcapReader, Packet
except ImportError:
print("Error: scapy library required. Install with: pip install scapy")
sys.exit(1)
class PCAPLoader:
"""Utility class for loading PCAP files"""
def __init__(self, file_path: str):
self.file_path = file_path
self._packet_count: Optional[int] = None
def load_all(self) -> List[Packet]:
"""Load all packets from the PCAP file"""
try:
packets = rdpcap(self.file_path)
self._packet_count = len(packets)
return packets
except Exception as e:
raise IOError(f"Error loading PCAP file {self.file_path}: {e}")
def load_streaming(self, chunk_size: int = 1000) -> Iterator[List[Packet]]:
"""Load packets in chunks for memory efficiency"""
try:
with PcapReader(self.file_path) as pcap_reader:
chunk = []
for packet in pcap_reader:
chunk.append(packet)
if len(chunk) >= chunk_size:
yield chunk
chunk = []
# Yield remaining packets
if chunk:
yield chunk
except Exception as e:
raise IOError(f"Error streaming PCAP file {self.file_path}: {e}")
def get_packet_count(self) -> Optional[int]:
"""Get the total number of packets (if loaded)"""
return self._packet_count
def validate_file(self) -> bool:
"""Validate that the file exists and is a valid PCAP"""
try:
with PcapReader(self.file_path) as pcap_reader:
# Try to read first packet
next(iter(pcap_reader))
return True
except (IOError, StopIteration):
return False
except Exception:
return False
@staticmethod
def get_file_info(file_path: str) -> dict:
"""Get basic information about a PCAP file"""
try:
packet_count = 0
first_timestamp = None
last_timestamp = None
total_bytes = 0
with PcapReader(file_path) as pcap_reader:
for packet in pcap_reader:
packet_count += 1
total_bytes += len(packet)
if first_timestamp is None:
first_timestamp = float(packet.time)
last_timestamp = float(packet.time)
duration = (last_timestamp - first_timestamp) if first_timestamp and last_timestamp else 0
return {
'file_path': file_path,
'packet_count': packet_count,
'total_bytes': total_bytes,
'duration_seconds': duration,
'first_timestamp': first_timestamp,
'last_timestamp': last_timestamp,
'avg_packet_rate': packet_count / duration if duration > 0 else 0
}
except Exception as e:
return {'error': str(e)}