@@ -2078,12 +2078,57 @@ function formatTimestamp(timestamp) {
20782078}
20792079
20802080function createTooltipHTML ( data ) {
2081+ // Helper to decode protocol numbers to names; falls back to TCP for legacy datasets.
2082+ const PROTOCOL_MAP = {
2083+ 1 : 'ICMP' ,
2084+ 2 : 'IGMP' ,
2085+ 6 : 'TCP' ,
2086+ 17 : 'UDP' ,
2087+ 41 : 'IPv6' ,
2088+ 47 : 'GRE' ,
2089+ 50 : 'ESP' ,
2090+ 51 : 'AH' ,
2091+ 58 : 'ICMPv6' ,
2092+ 89 : 'OSPF' ,
2093+ 132 : 'SCTP'
2094+ } ;
2095+ function normalizeProtocolValue ( raw ) {
2096+ if ( raw === undefined || raw === null || raw === '' ) return 'TCP' ;
2097+ if ( Array . isArray ( raw ) ) raw = raw [ 0 ] ;
2098+ // If already a recognizable string, return upper-cased canonical form
2099+ if ( typeof raw === 'string' ) {
2100+ const upper = raw . trim ( ) . toUpperCase ( ) ;
2101+ // If it's a numeric string try decoding
2102+ if ( / ^ \d + $ / . test ( upper ) ) {
2103+ const num = parseInt ( upper , 10 ) ;
2104+ return PROTOCOL_MAP [ num ] ? `${ PROTOCOL_MAP [ num ] } (${ num } )` : `Unknown (${ num } )` ;
2105+ }
2106+ // Already a protocol token
2107+ return upper || 'TCP' ;
2108+ }
2109+ if ( typeof raw === 'number' ) {
2110+ return PROTOCOL_MAP [ raw ] ? `${ PROTOCOL_MAP [ raw ] } (${ raw } )` : `Unknown (${ raw } )` ;
2111+ }
2112+ return 'TCP' ;
2113+ }
2114+ function extractProtocol ( p ) {
2115+ if ( ! p ) return 'TCP' ;
2116+ const raw = p . protocol ?? p . ip_proto ?? p . ipProtocol ?? p . proto ?? p . ipProtocolNumber ;
2117+ return normalizeProtocolValue ( raw ) ;
2118+ }
20812119 if ( data . binned && data . count > 1 ) {
20822120 // Binned data tooltip
20832121 const { utcTime, timestampSec } = formatTimestamp ( data . timestamp ) ;
20842122 let tooltipContent = `<b>${ data . flagType } (Binned)</b><br>` ;
20852123 tooltipContent += `Count: ${ data . count } packets<br>` ;
20862124 tooltipContent += `From: ${ data . src_ip } <br>To: ${ data . dst_ip } <br>` ;
2125+ // Aggregate protocols in the bin (in case of mixed, though unlikely)
2126+ if ( data . originalPackets && data . originalPackets . length ) {
2127+ const protocols = Array . from ( new Set ( data . originalPackets . map ( extractProtocol ) ) ) ;
2128+ tooltipContent += `Protocol: ${ protocols . join ( ', ' ) } <br>` ;
2129+ } else {
2130+ tooltipContent += `Protocol: ${ extractProtocol ( data ) } <br>` ;
2131+ }
20872132 tooltipContent += `Time Bin: ${ utcTime } <br>` ;
20882133 tooltipContent += `Total Bytes: ${ formatBytes ( data . totalBytes ) } ` ;
20892134
@@ -2100,7 +2145,7 @@ function createTooltipHTML(data) {
21002145 // Single packet tooltip
21012146 const packet = data . originalPackets ? data . originalPackets [ 0 ] : data ;
21022147 const { utcTime, timestampSec } = formatTimestamp ( packet . timestamp ) ;
2103- let tooltipContent = `<b>${ classifyFlags ( packet . flags ) } </b><br>From: ${ packet . src_ip } <br>To: ${ packet . dst_ip } <br>Time: ${ utcTime } ` ;
2148+ let tooltipContent = `<b>${ classifyFlags ( packet . flags ) } </b><br>From: ${ packet . src_ip } <br>To: ${ packet . dst_ip } <br>Protocol: ${ extractProtocol ( packet ) } <br> Time: ${ utcTime } ` ;
21042149
21052150 // Add sequence and acknowledgment numbers if available
21062151 if ( packet . seq_num !== undefined && packet . seq_num !== null ) {
0 commit comments