From ae3d6a4df03622fc10085f54628f6c2559ad9b14 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Fri, 31 Mar 2023 13:35:10 -0700 Subject: [PATCH] Add optional packet filtered statistics for packet sources --- scripts/base/init-bare.zeek | 1 + scripts/policy/misc/stats.zeek | 8 ++++++ src/RunState.cc | 25 ++++++++++++++----- src/iosource/PktSrc.h | 14 +++++++---- src/stats.bif | 23 ++++++----------- .../Baseline/bifs.net_stats_trace/output | 2 +- 6 files changed, 46 insertions(+), 27 deletions(-) diff --git a/scripts/base/init-bare.zeek b/scripts/base/init-bare.zeek index ca1cf8052d..f9633aeabd 100644 --- a/scripts/base/init-bare.zeek +++ b/scripts/base/init-bare.zeek @@ -678,6 +678,7 @@ type NetStats: record { ## be always set to zero. pkts_link: count &default=0; bytes_recvd: count &default=0; ##< Bytes received by Zeek. + filtered: count &optional; ##< Packets filtered by the packet source. }; type ConnStats: record { diff --git a/scripts/policy/misc/stats.zeek b/scripts/policy/misc/stats.zeek index 86b31b19dd..d9b9ce0d7d 100644 --- a/scripts/policy/misc/stats.zeek +++ b/scripts/policy/misc/stats.zeek @@ -34,6 +34,9 @@ export { ## Lag between the wall clock and packet timestamps if reading ## live traffic. pkt_lag: interval &log &optional; + ## Number of packets filtered from the link since the last + ## stats interval if reading live traffic. + pkts_filtered: count &log &optional; ## Number of events processed since the last stats interval. events_proc: count &log; @@ -140,6 +143,11 @@ event check_stats(then: time, last_ns: NetStats, last_cs: ConnStats, last_ps: Pr info$pkt_lag = current_time() - nettime; info$pkts_dropped = ns$pkts_dropped - last_ns$pkts_dropped; info$pkts_link = ns$pkts_link - last_ns$pkts_link; + + # This makes the assumption that if pkts_filtered is valid, it's been valid in + # all of the previous calls. + if ( ns?$pkts_filtered ) + info$pkts_filtered = ns$pkts_filtered - last_ns$pkts_filtered; } Log::write(Stats::LOG, info); diff --git a/src/RunState.cc b/src/RunState.cc index 19cc97c0de..4791759bf2 100644 --- a/src/RunState.cc +++ b/src/RunState.cc @@ -414,20 +414,33 @@ void get_final_stats() { iosource::PktSrc::Stats s; ps->Statistics(&s); - double dropped_pct = s.dropped > 0.0 - ? ((double)s.dropped / ((double)s.received + (double)s.dropped)) * - 100.0 - : 0.0; + + auto pct = [](uint64_t v, uint64_t received) + { + return (static_cast(v) / + (static_cast(v) + static_cast(received))) * + 100; + }; + + double dropped_pct = s.dropped > 0 ? pct(s.dropped, s.received) : 0.0; uint64_t not_processed = packet_mgr->GetUnprocessedCount(); double unprocessed_pct = not_processed > 0 ? ((double)not_processed / (double)s.received) * 100.0 : 0.0; + std::string filtered = ""; + if ( s.filtered ) + { + double filtered_pct = s.filtered ? pct(s.filtered.value(), s.received) : 0.0; + filtered = zeek::util::fmt(" %" PRIu64 " (%.2f%%) filtered", s.filtered.value(), + filtered_pct); + } + reporter->Info("%" PRIu64 " packets received on interface %s, %" PRIu64 - " (%.2f%%) dropped, %" PRIu64 " (%.2f%%) not processed", + " (%.2f%%) dropped, %" PRIu64 " (%.2f%%) not processed%s", s.received, ps->Path().c_str(), s.dropped, dropped_pct, not_processed, - unprocessed_pct); + unprocessed_pct, filtered.c_str()); } } diff --git a/src/iosource/PktSrc.h b/src/iosource/PktSrc.h index 6b2a007039..b4c6fa0dc0 100644 --- a/src/iosource/PktSrc.h +++ b/src/iosource/PktSrc.h @@ -3,6 +3,7 @@ #pragma once #include // for u_char +#include #include #include "zeek/iosource/BPF_Program.h" @@ -30,25 +31,28 @@ public: /** * Packets received by source after filtering (w/o drops). */ - uint64_t received; + uint64_t received = 0; /** * Packets dropped by source. */ - uint64_t dropped; // pkts dropped + uint64_t dropped = 0; // pkts dropped /** * Total number of packets on link before filtering. * Optional, can be left unset if not available. */ - uint64_t link; + uint64_t link = 0; /** * Bytes received by source after filtering (w/o drops). */ - uint64_t bytes_received; + uint64_t bytes_received = 0; - Stats() { received = dropped = link = bytes_received = 0; } + /** + * Packets filtered by the packet source. + */ + std::optional filtered; }; /** diff --git a/src/stats.bif b/src/stats.bif index 3dc7a5d567..6eee809f1c 100644 --- a/src/stats.bif +++ b/src/stats.bif @@ -39,28 +39,21 @@ zeek::RecordTypePtr ReporterStats; ## get_reporter_stats function get_net_stats%(%): NetStats %{ - uint64_t recv = 0; - uint64_t drop = 0; - uint64_t link = 0; - uint64_t bytes_recv = 0; + struct zeek::iosource::PktSrc::Stats stat; if ( zeek::iosource::PktSrc* ps = zeek::iosource_mgr->GetPktSrc() ) - { - struct zeek::iosource::PktSrc::Stats stat; ps->Statistics(&stat); - recv += stat.received; - drop += stat.dropped; - link += stat.link; - bytes_recv += stat.bytes_received; - } auto r = zeek::make_intrusive(NetStats); int n = 0; - r->Assign(n++, recv); - r->Assign(n++, drop); - r->Assign(n++, link); - r->Assign(n++, bytes_recv); + r->Assign(n++, stat.received); + r->Assign(n++, stat.dropped); + r->Assign(n++, stat.link); + r->Assign(n++, stat.bytes_received); + + if ( stat.filtered ) + r->Assign(n++, stat.filtered.value()); return r; %} diff --git a/testing/btest/Baseline/bifs.net_stats_trace/output b/testing/btest/Baseline/bifs.net_stats_trace/output index 89c44d658a..a501e46e65 100644 --- a/testing/btest/Baseline/bifs.net_stats_trace/output +++ b/testing/btest/Baseline/bifs.net_stats_trace/output @@ -1,2 +1,2 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -[pkts_recvd=136, pkts_dropped=0, pkts_link=0, bytes_recvd=25260] +[pkts_recvd=136, pkts_dropped=0, pkts_link=0, bytes_recvd=25260, pkts_filtered=]