diff --git a/src/iosource/PktSrc.cc b/src/iosource/PktSrc.cc index e4cbfe31e9..8db9db6ef1 100644 --- a/src/iosource/PktSrc.cc +++ b/src/iosource/PktSrc.cc @@ -36,9 +36,7 @@ PktSrc::PktSrc() PktSrc::~PktSrc() { - BPF_Program* code; - IterCookie* cookie = filters.InitForIteration(); - while ( (code = filters.NextEntry(cookie)) ) + for ( auto code : filters ) delete code; } @@ -335,16 +333,16 @@ bool PktSrc::PrecompileBPFFilter(int index, const std::string& filter) return 0; } - // Store it in hash. - HashKey* hash = new HashKey(HashKey(bro_int_t(index))); - BPF_Program* oldcode = filters.Lookup(hash); - if ( oldcode ) - delete oldcode; + // Store it in vector. + if ( index >= static_cast(filters.size()) ) + filters.resize(index + 1); - filters.Insert(hash, code); - delete hash; + if ( auto old = filters[index] ) + delete old; - return 1; + filters[index] = code; + + return true; } BPF_Program* PktSrc::GetBPFFilter(int index) @@ -352,10 +350,7 @@ BPF_Program* PktSrc::GetBPFFilter(int index) if ( index < 0 ) return 0; - HashKey* hash = new HashKey(HashKey(bro_int_t(index))); - BPF_Program* code = filters.Lookup(hash); - delete hash; - return code; + return (static_cast(filters.size()) > index ? filters[index] : 0); } bool PktSrc::ApplyBPFFilter(int index, const struct pcap_pkthdr *hdr, const u_char *pkt) diff --git a/src/iosource/PktSrc.h b/src/iosource/PktSrc.h index 7d05a5583f..25a743dc53 100644 --- a/src/iosource/PktSrc.h +++ b/src/iosource/PktSrc.h @@ -3,6 +3,8 @@ #ifndef IOSOURCE_PKTSRC_PKTSRC_H #define IOSOURCE_PKTSRC_PKTSRC_H +#include + #include "IOSource.h" #include "BPF_Program.h" #include "Dict.h" @@ -362,7 +364,7 @@ private: Packet current_packet; // For BPF filtering support. - PDict(BPF_Program) filters; + std::vector filters; // Only set in pseudo-realtime mode. double first_timestamp; diff --git a/src/iosource/pcap/functions.bif b/src/iosource/pcap/functions.bif index e36c374a3c..6ba880c3b1 100644 --- a/src/iosource/pcap/functions.bif +++ b/src/iosource/pcap/functions.bif @@ -21,6 +21,15 @@ module Pcap; ## pcap_error function precompile_pcap_filter%(id: PcapFilterID, s: string%): bool %{ + if ( id->AsEnum() >= 100 ) + { + // We use a vector as underlying data structure for fast + // lookups and limit the ID space so that that doesn't grow too + // large. + builtin_error(fmt("PCAP filter ids must remain below 100 (is %ld)", id->AsInt())); + return new Val(false, TYPE_BOOL); + } + bool success = true; const iosource::Manager::PktSrcList& pkt_srcs(iosource_mgr->GetPktSrcs());