working well, good docs. TUI.

This commit is contained in:
2025-07-25 19:42:33 -04:00
parent 4c6e23bff8
commit f75c757b12
5 changed files with 549 additions and 5 deletions

View File

@@ -237,4 +237,23 @@ class StatisticsEngine:
'tracked_flows': total_flows,
'total_outliers': total_outliers,
'update_frequency': 'per_packet'
}
}
def get_max_sigma_deviation(self, flow: FlowStats) -> float:
"""Get the maximum sigma deviation for any outlier in this flow"""
max_sigma = 0.0
# Check flow-level outliers
if flow.outlier_details and flow.std_inter_arrival > 0:
for frame_num, inter_arrival_time in flow.outlier_details:
sigma_deviation = (inter_arrival_time - flow.avg_inter_arrival) / flow.std_inter_arrival
max_sigma = max(max_sigma, sigma_deviation)
# Check frame-type-level outliers
for frame_type, ft_stats in flow.frame_types.items():
if ft_stats.outlier_details and ft_stats.std_inter_arrival > 0:
for frame_num, inter_arrival_time in ft_stats.outlier_details:
sigma_deviation = (inter_arrival_time - ft_stats.avg_inter_arrival) / ft_stats.std_inter_arrival
max_sigma = max(max_sigma, sigma_deviation)
return max_sigma

View File

@@ -157,12 +157,17 @@ def print_console_results(analyzer: EthernetAnalyzer):
print(f"Update Frequency: {rt_stats.get('update_frequency', 'N/A')}")
print(f"\n=== FLOW STATISTICS ===")
flows_sorted = sorted(summary['flows'].values(), key=lambda x: x.frame_count, reverse=True)
flows_sorted = sorted(summary['flows'].values(), key=lambda x: (
analyzer.statistics_engine.get_max_sigma_deviation(x),
x.frame_count
), reverse=True)
for flow in flows_sorted:
max_sigma = analyzer.statistics_engine.get_max_sigma_deviation(flow)
print(f"\nFlow: {flow.src_ip} -> {flow.dst_ip}")
print(f" Packets: {flow.frame_count}")
print(f" Total Bytes: {flow.total_bytes:,}")
print(f" Max Sigma Deviation: {max_sigma:.2f}σ")
print(f" Protocols: {', '.join(flow.protocols)}")
if flow.detected_protocol_types:
print(f" Enhanced Protocols: {', '.join(flow.detected_protocol_types)}")
@@ -217,15 +222,20 @@ def generate_outlier_report(analyzer: EthernetAnalyzer, threshold_sigma: float):
print("DETAILED FLOW ANALYSIS")
print("=" * 80)
flows_sorted = sorted(summary['flows'].values(), key=lambda x: x.frame_count, reverse=True)
flows_sorted = sorted(summary['flows'].values(), key=lambda x: (
analyzer.statistics_engine.get_max_sigma_deviation(x),
x.frame_count
), reverse=True)
for flow_idx, flow in enumerate(flows_sorted, 1):
max_sigma = analyzer.statistics_engine.get_max_sigma_deviation(flow)
print(f"\n[FLOW {flow_idx}] {flow.src_ip} -> {flow.dst_ip}")
print("-" * 60)
# Flow summary
print(f"Total Packets: {flow.frame_count:,}")
print(f"Total Bytes: {flow.total_bytes:,}")
print(f"Max Sigma Deviation: {max_sigma:.2f}σ")
print(f"Protocols: {', '.join(flow.protocols)}")
if flow.detected_protocol_types:
print(f"Enhanced Protocols: {', '.join(flow.detected_protocol_types)}")

View File

@@ -176,7 +176,11 @@ class TUIInterface:
stdscr.addstr(status_y, 0, status[:width-1], curses.A_REVERSE)
def _get_flows_list(self):
"""Get sorted list of flows"""
"""Get sorted list of flows - prioritize by largest sigma outlier"""
flows_list = list(self.analyzer.flows.values())
flows_list.sort(key=lambda x: x.frame_count, reverse=True)
# Sort by maximum sigma deviation first, then by frame count as secondary criterion
flows_list.sort(key=lambda x: (
self.analyzer.statistics_engine.get_max_sigma_deviation(x),
x.frame_count
), reverse=True)
return flows_list