re-focus on TUI and core
This commit is contained in:
@@ -19,9 +19,9 @@ class FlowListPanel:
|
||||
flows_list: List[FlowStats], selected_flow: int):
|
||||
"""Draw the flow list panel"""
|
||||
|
||||
# Draw flows table header
|
||||
# Draw flows table header with adjusted column widths for better alignment
|
||||
stdscr.addstr(y_offset, x_offset, "FLOWS:", curses.A_BOLD)
|
||||
headers = f"{'Source IP':15} {'Dest IP':15} {'Pkts':5} {'Protocol':18} {'ΔT Avg':10} {'Out':4}"
|
||||
headers = f"{'Src:Port':22} {'Dst:Port':22} {'Proto':6} {'Cast':5} {'#Frames':>7} {'Bytes':>7} {'Encoding':12} {'ΔT Avg':>9}"
|
||||
stdscr.addstr(y_offset + 1, x_offset, headers[:width-1], curses.A_UNDERLINE)
|
||||
|
||||
# Calculate scrolling parameters
|
||||
@@ -40,11 +40,23 @@ class FlowListPanel:
|
||||
for flow_idx, flow in enumerate(flows_list):
|
||||
# Check if main flow line should be displayed
|
||||
if display_item >= scroll_offset and visible_items < max_rows:
|
||||
# Draw main flow line
|
||||
protocol_str = self._get_protocol_display(flow)
|
||||
# Draw main flow line with new column layout
|
||||
src_endpoint = f"{flow.src_ip}:{flow.src_port}" if flow.src_port > 0 else flow.src_ip
|
||||
dst_endpoint = f"{flow.dst_ip}:{flow.dst_port}" if flow.dst_port > 0 else flow.dst_ip
|
||||
|
||||
# Format bytes with K/M suffix
|
||||
bytes_str = self._format_bytes(flow.total_bytes)
|
||||
|
||||
# Get encoding information (primary detected protocol)
|
||||
encoding_str = self._get_encoding_display(flow)
|
||||
|
||||
# Format average time
|
||||
avg_time = f"{flow.avg_inter_arrival:.3f}s" if flow.avg_inter_arrival > 0 else "N/A"
|
||||
|
||||
line = f"{flow.src_ip:15} {flow.dst_ip:15} {flow.frame_count:5} {protocol_str:18} {avg_time:10} {'':4}"
|
||||
# Abbreviate traffic classification
|
||||
cast_abbrev = flow.traffic_classification[:4] if flow.traffic_classification != "Unknown" else "Unk"
|
||||
|
||||
line = f"{src_endpoint:22} {dst_endpoint:22} {flow.transport_protocol:6} {cast_abbrev:5} {flow.frame_count:>7} {bytes_str:>7} {encoding_str:12} {avg_time:>9}"
|
||||
|
||||
if display_item == selected_flow:
|
||||
stdscr.addstr(current_row, x_offset, line[:width-1], curses.A_REVERSE)
|
||||
@@ -66,8 +78,9 @@ class FlowListPanel:
|
||||
ft_avg = f"{ft_stats.avg_inter_arrival:.3f}s" if ft_stats.avg_inter_arrival > 0 else "N/A"
|
||||
outlier_count = len(ft_stats.outlier_details) if ft_stats.outlier_details else 0
|
||||
|
||||
# Create frame type line aligned with columns
|
||||
ft_line = f"{'':15} {'':15} {ft_stats.count:5} {frame_type:18} {ft_avg:10} {outlier_count:4}"
|
||||
# Create frame type line aligned with new column layout
|
||||
bytes_str_ft = self._format_bytes(ft_stats.total_bytes)
|
||||
ft_line = f" └─{frame_type:18} {'':22} {'':6} {'':5} {ft_stats.count:>7} {bytes_str_ft:>7} {'':12} {ft_avg:>9}"
|
||||
|
||||
if display_item == selected_flow:
|
||||
stdscr.addstr(current_row, x_offset, ft_line[:width-1], curses.A_REVERSE)
|
||||
@@ -124,4 +137,46 @@ class FlowListPanel:
|
||||
|
||||
def get_total_display_items(self, flows_list: List[FlowStats]) -> int:
|
||||
"""Public method to get total display items"""
|
||||
return self._get_total_display_items(flows_list)
|
||||
return self._get_total_display_items(flows_list)
|
||||
|
||||
def _format_bytes(self, bytes_count: int) -> str:
|
||||
"""Format byte count with K/M/G suffixes, always include magnitude indicator"""
|
||||
if bytes_count >= 1_000_000_000:
|
||||
return f"{bytes_count / 1_000_000_000:.1f}G"
|
||||
elif bytes_count >= 1_000_000:
|
||||
return f"{bytes_count / 1_000_000:.1f}M"
|
||||
elif bytes_count >= 1_000:
|
||||
return f"{bytes_count / 1_000:.1f}K"
|
||||
else:
|
||||
return f"{bytes_count}B" # Add "B" for plain bytes
|
||||
|
||||
def _get_encoding_display(self, flow: FlowStats) -> str:
|
||||
"""Get the primary encoding/application protocol for display"""
|
||||
# Prioritize specialized protocols (Chapter 10, PTP, IENA)
|
||||
if flow.detected_protocol_types:
|
||||
specialized = {'CH10', 'PTP', 'IENA', 'Chapter10', 'TMATS'}
|
||||
found_specialized = flow.detected_protocol_types.intersection(specialized)
|
||||
if found_specialized:
|
||||
return list(found_specialized)[0]
|
||||
|
||||
# Use first detected protocol type
|
||||
return list(flow.detected_protocol_types)[0]
|
||||
|
||||
# Fallback to frame types if available
|
||||
if flow.frame_types:
|
||||
frame_types = list(flow.frame_types.keys())
|
||||
# Look for interesting frame types first
|
||||
priority_types = ['TMATS', 'CH10-Data', 'PTP-Sync', 'IENA-P', 'IENA-D']
|
||||
for ptype in priority_types:
|
||||
if ptype in frame_types:
|
||||
return ptype
|
||||
return frame_types[0]
|
||||
|
||||
# Last resort - check basic protocols
|
||||
if flow.protocols:
|
||||
app_protocols = {'DNS', 'HTTP', 'HTTPS', 'NTP', 'DHCP'}
|
||||
found_app = flow.protocols.intersection(app_protocols)
|
||||
if found_app:
|
||||
return list(found_app)[0]
|
||||
|
||||
return "Unknown"
|
||||
Reference in New Issue
Block a user