diff --git a/scripts/base/utils/time.zeek b/scripts/base/utils/time.zeek index c173c82878..c6f8cfe76b 100644 --- a/scripts/base/utils/time.zeek +++ b/scripts/base/utils/time.zeek @@ -1,3 +1,4 @@ +##! Time-related functions. ## Given an interval, returns a string representing the minutes and seconds ## in the interval (for example, "3m34s"). @@ -6,3 +7,22 @@ function duration_to_mins_secs(dur: interval): string local dur_count = double_to_count(interval_to_double(dur)); return fmt("%dm%ds", dur_count/60, dur_count%60); } + +## Time value representing the 0 timestamp. +const null_ts = double_to_time(0); + +## Calculate the packet lag, i.e. the difference between wall clock and the +## timestamp of the currently processed packet. If Zeek is not processing a +## packet, the function returns a 0 interval value. +function get_packet_lag(): interval + { + # We use get_current_packet_ts() instead of network_time() here, because + # network time does not immediately fall back to wall clock if there is + # no packet. Instead, network time remains set to the last seen packet's + # timestamp for ``packet_source_inactivity_timeout``. + local pkt_ts = get_current_packet_ts(); + if (pkt_ts == null_ts) + return 0 sec; + + return current_time() - pkt_ts; + } diff --git a/scripts/policy/misc/stats.zeek b/scripts/policy/misc/stats.zeek index 8449ccdb0d..cae9a3b16a 100644 --- a/scripts/policy/misc/stats.zeek +++ b/scripts/policy/misc/stats.zeek @@ -2,6 +2,7 @@ @load base/frameworks/notice @load base/frameworks/telemetry +@load base/utils/time module Stats; @@ -166,8 +167,6 @@ event zeek_init() &priority=5 Log::create_stream(Stats::LOG, [$columns=Info, $ev=log_stats, $path="stats", $policy=log_policy]); } -const null_ts = double_to_time(0); - event check_stats(then: time, last_ns: NetStats, last_cs: ConnStats, last_ps: ProcStats, last_es: EventStats, last_rs: ReassemblerStats, last_ts: TimerStats, last_fs: FileAnalysisStats, last_ds: DNSStats) { local nettime = network_time(); @@ -216,8 +215,7 @@ event check_stats(then: time, last_ns: NetStats, last_cs: ConnStats, last_ps: Pr if ( reading_live_traffic() ) { - local pkt_ts = get_current_packet_ts(); - info$pkt_lag = pkt_ts > null_ts ? current_time() - pkt_ts : 0 sec; + info$pkt_lag = get_packet_lag(); info$pkts_dropped = ns$pkts_dropped - last_ns$pkts_dropped; info$pkts_link = ns$pkts_link - last_ns$pkts_link; diff --git a/src/zeek.bif b/src/zeek.bif index d614bf27a0..84cc1e397a 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -3833,19 +3833,19 @@ function get_current_packet_header%(%) : raw_pkt_hdr return std::move(hdr); %} -## Returns the currently processed PCAP packet's timestamp. +## Returns the currently processed PCAP packet's timestamp or a 0 timestamp if +## there is no packet being processed at the moment. ## ## Returns: The currently processed packet's timestamp. ## -## .. zeek:see:: get_current_packet get_current_packet_header +## .. zeek:see:: get_current_packet get_current_packet_header network_time ## ## .. note:: ## -## For ``get_current_packet_ts()`` the same limitations as for -## :zeek:see:`get_current_packet` apply. In particular, the return value -## should be considered undefined when called within event handlers raised -## via :zeek:see:`event`, :zeek:see:`schedule` or by recipient of Broker -## messages. +## When there is no packet being processed, ``get_current_packet_ts()`` +## will return a 0 timestamp, while ``network_time()`` will return the +## timestamp of the last processed packet until it falls back to tracking +## wall clock after ``packet_source_inactivity_timeout``. function get_current_packet_ts%(%) : time %{ double ts = 0;