diff --git a/backend/src/utilities/database.py b/backend/src/utilities/database.py index 99e55e3..7fa1fa8 100644 --- a/backend/src/utilities/database.py +++ b/backend/src/utilities/database.py @@ -28,6 +28,25 @@ def _db_text(value: Any) -> Any: return str(value) +def _analysis_protocol_name(app_protocol: Any, ip_proto_raw: Any, eth_type_raw: Any) -> str: + if app_protocol not in (None, ""): + return str(app_protocol) + + if ip_proto_raw is not None: + try: + return str(protocol_from_number(int(ip_proto_raw))) + except Exception: + return f"IP_PROTO_{ip_proto_raw}" + + if eth_type_raw is not None: + try: + return str(ethertype_from_int(int(eth_type_raw))) + except Exception: + return f"ETH_TYPE_{eth_type_raw}" + + return "UNKNOWN" + + def _serialize_row_for_broadcast(row: Dict[str, Any]) -> Dict[str, Any]: serialized = dict(row) _normalize_json_fields(serialized) @@ -757,7 +776,9 @@ class DatabasePool: ingress_if AS iface, src_ip::text AS ip_address, src_mac::text AS mac_address, - COALESCE(NULLIF(app_protocol::text, ''), NULLIF(ip_proto::text, ''), NULLIF(eth_type::text, ''), 'UNKNOWN') AS protocol_name, + NULLIF(app_protocol::text, '') AS app_protocol_name, + ip_proto_raw, + eth_type_raw, COALESCE(NULLIF(verdict::text, ''), 'unknown') AS verdict_name, timestamp, 'source_on_ingress' AS evidence @@ -772,7 +793,9 @@ class DatabasePool: egress_if AS iface, dst_ip::text AS ip_address, dst_mac::text AS mac_address, - COALESCE(NULLIF(app_protocol::text, ''), NULLIF(ip_proto::text, ''), NULLIF(eth_type::text, ''), 'UNKNOWN') AS protocol_name, + NULLIF(app_protocol::text, '') AS app_protocol_name, + ip_proto_raw, + eth_type_raw, COALESCE(NULLIF(verdict::text, ''), 'unknown') AS verdict_name, timestamp, 'destination_on_egress' AS evidence @@ -821,7 +844,9 @@ class DatabasePool: filtered.iface, filtered.ip_address, filtered.mac_address, - filtered.protocol_name, + filtered.app_protocol_name, + filtered.ip_proto_raw, + filtered.eth_type_raw, COUNT(*) AS packet_count, MAX(filtered.timestamp) AS last_seen, SUM(CASE WHEN filtered.verdict_name = 'accept' THEN 1 ELSE 0 END) AS accept_count, @@ -833,7 +858,13 @@ class DatabasePool: ON selected_hosts.iface = filtered.iface AND selected_hosts.ip_address IS NOT DISTINCT FROM filtered.ip_address AND selected_hosts.mac_address IS NOT DISTINCT FROM filtered.mac_address - GROUP BY filtered.iface, filtered.ip_address, filtered.mac_address, filtered.protocol_name + GROUP BY + filtered.iface, + filtered.ip_address, + filtered.mac_address, + filtered.app_protocol_name, + filtered.ip_proto_raw, + filtered.eth_type_raw ), ranked_protocols AS ( SELECT * @@ -842,7 +873,12 @@ class DatabasePool: *, ROW_NUMBER() OVER ( PARTITION BY iface, ip_address, mac_address - ORDER BY packet_count DESC, last_seen DESC, protocol_name + ORDER BY + packet_count DESC, + last_seen DESC, + app_protocol_name NULLS LAST, + ip_proto_raw NULLS LAST, + eth_type_raw NULLS LAST ) AS row_num FROM protocol_aggregated ) ranked @@ -856,7 +892,9 @@ class DatabasePool: selected_hosts.last_seen AS host_last_seen, selected_hosts.source_on_ingress_count, selected_hosts.destination_on_egress_count, - ranked_protocols.protocol_name, + ranked_protocols.app_protocol_name, + ranked_protocols.ip_proto_raw, + ranked_protocols.eth_type_raw, ranked_protocols.packet_count AS protocol_packet_count, ranked_protocols.last_seen AS protocol_last_seen, ranked_protocols.accept_count, @@ -876,7 +914,9 @@ class DatabasePool: selected_hosts.mac_address, ranked_protocols.packet_count DESC NULLS LAST, ranked_protocols.last_seen DESC NULLS LAST, - ranked_protocols.protocol_name + ranked_protocols.app_protocol_name NULLS LAST, + ranked_protocols.ip_proto_raw NULLS LAST, + ranked_protocols.eth_type_raw NULLS LAST """, since, limit_per_interface, @@ -906,7 +946,11 @@ class DatabasePool: } iface_hosts[host_key] = host_record - protocol_name = record.get("protocol_name") + protocol_name = _analysis_protocol_name( + record.get("app_protocol_name"), + record.get("ip_proto_raw"), + record.get("eth_type_raw"), + ) if protocol_name not in (None, ""): host_record["protocols"].append( {