This commit is contained in:
2025-07-25 21:45:07 -04:00
parent f75c757b12
commit d77dd386f3
19 changed files with 2131 additions and 38 deletions

View File

@@ -7,6 +7,7 @@ from typing import TYPE_CHECKING
from .navigation import NavigationHandler
from .panels import FlowListPanel, DetailPanel, TimelinePanel
from ..utils.signal_visualizer import signal_visualizer
if TYPE_CHECKING:
from ..analysis.core import EthernetAnalyzer
@@ -61,6 +62,8 @@ class TUIInterface:
if self.analyzer.is_live:
self.analyzer.stop_capture = True
break
elif action == 'visualize':
self._handle_visualization()
def _draw_main_view(self, stdscr):
"""Draw three-panel main view: flows list, details, and timeline"""
@@ -183,4 +186,55 @@ class TUIInterface:
self.analyzer.statistics_engine.get_max_sigma_deviation(x),
x.frame_count
), reverse=True)
return flows_list
return flows_list
def _handle_visualization(self):
"""Handle Chapter 10 signal visualization for selected flow"""
flows_list = self._get_flows_list()
if not flows_list or self.navigation.selected_flow >= len(flows_list):
return
selected_flow = flows_list[self.navigation.selected_flow]
flow_key = f"{selected_flow.src_ip}->{selected_flow.dst_ip}"
# Check if this flow has Chapter 10 data
if not self.navigation.has_chapter10_data(selected_flow):
return
# Get packets for this flow
flow_packets = self._get_flow_packets(selected_flow)
if not flow_packets:
return
# Launch visualization in TUI mode (will save plots to files)
try:
# Set TUI context to avoid GUI windows
signal_visualizer._in_tui_context = True
# Temporarily show status (will be overwritten by next TUI refresh)
print(f"Generating signal visualization for flow {flow_key}...")
signal_visualizer.visualize_flow_signals(selected_flow, flow_packets, gui_mode=False)
except Exception as e:
# Log error but don't disrupt TUI
print(f"Visualization error: {e}")
pass
def _get_flow_packets(self, flow):
"""Get all packets belonging to a specific flow"""
flow_packets = []
# Iterate through all packets and filter by source/destination
for packet in self.analyzer.all_packets:
try:
# Check if packet matches this flow
if hasattr(packet, 'haslayer'):
from scapy.all import IP
if packet.haslayer(IP):
ip_layer = packet[IP]
if ip_layer.src == flow.src_ip and ip_layer.dst == flow.dst_ip:
flow_packets.append(packet)
except:
continue
return flow_packets