From f16f0360ff064c31bb330f4006c1fab512afd2d3 Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Tue, 26 Nov 2019 09:37:12 -0700 Subject: [PATCH] Only allow a single trace file (-r) or interface (-i) option on the command-line --- scripts/base/init-bare.zeek | 3 - src/Net.cc | 73 ++++++------------ src/Net.h | 4 +- src/Options.cc | 33 +++++--- src/Options.h | 4 +- src/iosource/Manager.cc | 2 +- src/iosource/Manager.h | 10 +-- src/iosource/pcap/pcap.bif | 35 ++------- src/main.cc | 35 ++++----- src/stats.bif | 9 +-- src/supervisor/Supervisor.cc | 2 +- src/util.cc | 4 +- src/zeek.bif | 14 ++-- .../btest/Baseline/bifs.packet_sources/out | 2 +- .../Traces/tunnels/gtp/pdp_ctx_messages.trace | Bin 0 -> 2360 bytes testing/btest/bifs/packet_sources.zeek | 2 +- .../core/tunnels/gtp/pdp_ctx_messages.test | 2 +- 17 files changed, 93 insertions(+), 141 deletions(-) create mode 100644 testing/btest/Traces/tunnels/gtp/pdp_ctx_messages.trace diff --git a/scripts/base/init-bare.zeek b/scripts/base/init-bare.zeek index 7360a5bd23..d810c500a0 100644 --- a/scripts/base/init-bare.zeek +++ b/scripts/base/init-bare.zeek @@ -133,9 +133,6 @@ type PacketSource: record { netmask: count; }; -## A list of packet sources being read by Zeek. -type PacketSourceList: vector of PacketSource; - ## A connection's transport-layer protocol. Note that Zeek uses the term ## "connection" broadly, using flow semantics for ICMP and UDP. type transport_proto: enum { diff --git a/src/Net.cc b/src/Net.cc index ac38eb846d..856fc75ae0 100644 --- a/src/Net.cc +++ b/src/Net.cc @@ -145,41 +145,34 @@ void net_update_time(double new_network_time) PLUGIN_HOOK_VOID(HOOK_UPDATE_NETWORK_TIME, HookUpdateNetworkTime(new_network_time)); } -void net_init(const std::vector& interfaces, - const std::vector& pcap_input_files, +void net_init(const std::string& interface, + const std::string& pcap_input_file, const std::optional& pcap_output_file, bool do_watchdog) { - if ( ! pcap_input_files.empty() ) + if ( ! pcap_input_file.empty() ) { reading_live = pseudo_realtime > 0.0; reading_traces = 1; - for ( const auto& pif : pcap_input_files ) - { - iosource::PktSrc* ps = iosource_mgr->OpenPktSrc(pif, false); - assert(ps); + iosource::PktSrc* ps = iosource_mgr->OpenPktSrc(pcap_input_file, false); + assert(ps); - if ( ! ps->IsOpen() ) - reporter->FatalError("problem with trace file %s (%s)", - pif.data(), ps->ErrorMsg()); - } + if ( ! ps->IsOpen() ) + reporter->FatalError("problem with trace file %s (%s)", + pcap_input_file.c_str(), ps->ErrorMsg()); } - - else if ( ! interfaces.empty() ) + else if ( ! interface.empty() ) { reading_live = 1; reading_traces = 0; - for ( const auto& iface : interfaces ) - { - iosource::PktSrc* ps = iosource_mgr->OpenPktSrc(iface, true); - assert(ps); + iosource::PktSrc* ps = iosource_mgr->OpenPktSrc(interface, true); + assert(ps); - if ( ! ps->IsOpen() ) - reporter->FatalError("problem with interface %s (%s)", - iface.data(), ps->ErrorMsg()); - } + if ( ! ps->IsOpen() ) + reporter->FatalError("problem with interface %s (%s)", + interface.c_str(), ps->ErrorMsg()); } else @@ -377,14 +370,9 @@ void net_run() { auto have_active_packet_source = false; - for ( auto& ps : iosource_mgr->GetPktSrcs() ) - { - if ( ps->IsOpen() ) - { - have_active_packet_source = true; - break; - } - } + iosource::PktSrc* ps = iosource_mgr->GetPktSrc(); + if ( ps && ps->IsOpen() ) + have_active_packet_source = true; if ( ! have_active_packet_source ) // Can turn off pseudo realtime now @@ -401,20 +389,13 @@ void net_run() void net_get_final_stats() { - const iosource::Manager::PktSrcList& pkt_srcs(iosource_mgr->GetPktSrcs()); - - for ( iosource::Manager::PktSrcList::const_iterator i = pkt_srcs.begin(); - i != pkt_srcs.end(); i++ ) + iosource::PktSrc* ps = iosource_mgr->GetPktSrc(); + if ( ps && ps->IsLive() ) { - iosource::PktSrc* ps = *i; - - if ( ps->IsLive() ) - { - iosource::PktSrc::Stats s; - ps->Statistics(&s); - reporter->Info("%" PRIu64 " packets received on interface %s, %" PRIu64 " dropped", - s.received, ps->Path().c_str(), s.dropped); - } + iosource::PktSrc::Stats s; + ps->Statistics(&s); + reporter->Info("%" PRIu64 " packets received on interface %s, %" PRIu64 " dropped", + s.received, ps->Path().c_str(), s.dropped); } } @@ -468,12 +449,8 @@ void net_continue_processing() if ( _processing_suspended == 1 ) { reporter->Info("processing continued"); - - const iosource::Manager::PktSrcList& pkt_srcs(iosource_mgr->GetPktSrcs()); - - for ( iosource::Manager::PktSrcList::const_iterator i = pkt_srcs.begin(); - i != pkt_srcs.end(); i++ ) - (*i)->ContinueAfterSuspend(); + if ( iosource::PktSrc* ps = iosource_mgr->GetPktSrc() ) + ps->ContinueAfterSuspend(); } --_processing_suspended; diff --git a/src/Net.h b/src/Net.h index dab0014dd5..a5d330141b 100644 --- a/src/Net.h +++ b/src/Net.h @@ -14,8 +14,8 @@ #include "iosource/PktSrc.h" #include "iosource/PktDumper.h" -extern void net_init(const std::vector& interfaces, - const std::vector& pcap_input_files, +extern void net_init(const std::string& interfaces, + const std::string& pcap_input_file, const std::optional& pcap_output_file, bool do_watchdog); extern void net_run(); diff --git a/src/Options.cc b/src/Options.cc index 6143657967..2468675c24 100644 --- a/src/Options.cc +++ b/src/Options.cc @@ -16,8 +16,6 @@ void zeek::Options::filter_supervisor_options() { pcap_filter = {}; - interfaces = {}; - pcap_files = {}; signature_files = {}; pcap_output_file = {}; } @@ -49,8 +47,8 @@ void zeek::Options::filter_supervised_node_options() // use-case-specific way. e.g. interfaces is already handled for the // "cluster" use-case, but don't have supervised-pcap-reading // functionality yet. - /* interfaces = og.interfaces; */ - /* pcap_files = og.pcap_files; */ + /* interface = og.interface; */ + /* pcap_file = og.pcap_file; */ pcap_output_file = og.pcap_output_file; random_seed_input_file = og.random_seed_input_file; @@ -82,9 +80,9 @@ void zeek::usage(const char* prog, int code) fprintf(stderr, " -e|--exec | augment loaded scripts by given code\n"); fprintf(stderr, " -f|--filter | tcpdump filter\n"); fprintf(stderr, " -h|--help | command line help\n"); - fprintf(stderr, " -i|--iface | read from given interface\n"); + fprintf(stderr, " -i|--iface | read from given interface (only one allowed)\n"); fprintf(stderr, " -p|--prefix | add given prefix to Zeek script file resolution\n"); - fprintf(stderr, " -r|--readfile | read from given tcpdump file\n"); + fprintf(stderr, " -r|--readfile | read from given tcpdump file (only one allowed, pass '-' as the filename to read from stdin)\n"); fprintf(stderr, " -s|--rulefile | read rules from given file\n"); fprintf(stderr, " -t|--tracefile | activate execution tracing\n"); fprintf(stderr, " -v|--version | print version and exit\n"); @@ -270,12 +268,18 @@ zeek::Options zeek::parse_cmdline(int argc, char** argv) rval.print_usage = true; break; case 'i': - if ( ! rval.pcap_files.empty() ) + if ( ! rval.interface.empty() ) { - fprintf(stderr, "Using -i is not allowed when reading pcap files"); + fprintf(stderr, "ERROR: Only a single interface option (-i) is allowed.\n"); exit(1); } - rval.interfaces.emplace_back(optarg); + else if ( ! rval.pcap_file.empty() ) + { + fprintf(stderr, "ERROR: Using -i is not allow when reading a pcap file.\n"); + exit(1); + } + + rval.interface = optarg; break; case 'j': rval.supervisor_mode = true; @@ -290,12 +294,17 @@ zeek::Options zeek::parse_cmdline(int argc, char** argv) rval.script_prefixes.emplace_back(optarg); break; case 'r': - if ( ! rval.interfaces.empty() ) + if ( ! rval.pcap_file.empty() ) { - fprintf(stderr, "Using -r is not allowed when reading a live interface"); + fprintf(stderr, "ERROR: Only a single readfile option (-r) is allowed.\n"); exit(1); } - rval.pcap_files.emplace_back(optarg); + else if ( ! rval.interface.empty() ) + { + fprintf(stderr, "Using -r is not allowed when reading a live interface.\n"); + exit(1); + } + rval.pcap_file = optarg; break; case 's': rval.signature_files.emplace_back(optarg); diff --git a/src/Options.h b/src/Options.h index 01711481d9..ca61493cb0 100644 --- a/src/Options.h +++ b/src/Options.h @@ -58,8 +58,8 @@ struct Options { std::vector doctest_args; std::optional pcap_filter; - std::vector interfaces; - std::vector pcap_files; + std::string interface; + std::string pcap_file; std::vector signature_files; std::optional pcap_output_file; diff --git a/src/iosource/Manager.cc b/src/iosource/Manager.cc index 390449da81..c76e7786bc 100644 --- a/src/iosource/Manager.cc +++ b/src/iosource/Manager.cc @@ -207,7 +207,7 @@ void Manager::Register(IOSource* src, bool dont_count) void Manager::Register(PktSrc* src) { - pkt_srcs.push_back(src); + pkt_src = src; Register(src, false); } diff --git a/src/iosource/Manager.h b/src/iosource/Manager.h index a02401a0f1..cdb8757540 100644 --- a/src/iosource/Manager.h +++ b/src/iosource/Manager.h @@ -58,13 +58,11 @@ public: */ int Size() const { return sources.size() - dont_counts; } - typedef std::list PktSrcList; - /** - * Returns a list of all registered PktSrc instances. This is a - * subset of all registered IOSource instances. + * Returns the registered PktSrc. If not source is registered yet, + * returns a nullptr. */ - const PktSrcList& GetPktSrcs() const { return pkt_srcs; } + PktSrc* GetPktSrc() const { return pkt_src; } /** * Terminate all processing immediately by removing all sources (and @@ -136,7 +134,7 @@ private: typedef std::list PktDumperList; - PktSrcList pkt_srcs; + PktSrc* pkt_src = nullptr; PktDumperList pkt_dumpers; }; diff --git a/src/iosource/pcap/pcap.bif b/src/iosource/pcap/pcap.bif index 9e6e0238ba..e7b97cf4dd 100644 --- a/src/iosource/pcap/pcap.bif +++ b/src/iosource/pcap/pcap.bif @@ -35,17 +35,9 @@ function precompile_pcap_filter%(id: PcapFilterID, s: string%): bool bool success = true; - const iosource::Manager::PktSrcList& pkt_srcs(iosource_mgr->GetPktSrcs()); - - for ( iosource::Manager::PktSrcList::const_iterator i = pkt_srcs.begin(); - i != pkt_srcs.end(); i++ ) - { - iosource::PktSrc* ps = *i; - - if ( ! ps->PrecompileFilter(id->ForceAsInt(), - s->CheckString()) ) - success = false; - } + iosource::PktSrc* ps = iosource_mgr->GetPktSrc(); + if ( ps && ! ps->PrecompileFilter(id->ForceAsInt(), s->CheckString()) ) + success = false; return val_mgr->GetBool(success); %} @@ -72,16 +64,9 @@ function Pcap::install_pcap_filter%(id: PcapFilterID%): bool %{ bool success = true; - const iosource::Manager::PktSrcList& pkt_srcs(iosource_mgr->GetPktSrcs()); - - for ( iosource::Manager::PktSrcList::const_iterator i = pkt_srcs.begin(); - i != pkt_srcs.end(); i++ ) - { - iosource::PktSrc* ps = *i; - - if ( ! ps->SetFilter(id->ForceAsInt()) ) - success = false; - } + iosource::PktSrc* ps = iosource_mgr->GetPktSrc(); + if ( ps && ! ps->SetFilter(id->ForceAsInt()) ) + success = false; return val_mgr->GetBool(success); %} @@ -102,13 +87,9 @@ function Pcap::install_pcap_filter%(id: PcapFilterID%): bool ## uninstall_dst_net_filter function error%(%): string %{ - const iosource::Manager::PktSrcList& pkt_srcs(iosource_mgr->GetPktSrcs()); - - for ( iosource::Manager::PktSrcList::const_iterator i = pkt_srcs.begin(); - i != pkt_srcs.end(); i++ ) + iosource::PktSrc* ps = iosource_mgr->GetPktSrc(); + if ( ps ) { - iosource::PktSrc* ps = *i; - const char* err = ps->ErrorMsg(); if ( *err ) return new StringVal(err); diff --git a/src/main.cc b/src/main.cc index 9847aa2df2..5e47fa6089 100644 --- a/src/main.cc +++ b/src/main.cc @@ -234,17 +234,17 @@ void done_with_network() #ifdef USE_PERFTOOLS_DEBUG - if ( perftools_profile ) - { - HeapProfilerDump("post net_run"); - HeapProfilerStop(); - } + if ( perftools_profile ) + { + HeapProfilerDump("post net_run"); + HeapProfilerStop(); + } - if ( heap_checker && ! heap_checker->NoLeaks() ) - { - fprintf(stderr, "Memory leaks - aborting.\n"); - abort(); - } + if ( heap_checker && ! heap_checker->NoLeaks() ) + { + fprintf(stderr, "Memory leaks - aborting.\n"); + abort(); + } #endif ZEEK_LSAN_DISABLE(); @@ -560,8 +560,8 @@ int main(int argc, char** argv) if ( options.plugins_to_load.empty() && options.scripts_to_load.empty() && options.script_options_to_set.empty() && - options.pcap_files.size() == 0 && - options.interfaces.size() == 0 && + options.pcap_file.empty() && + options.interface.empty() && ! options.identifier_to_print && ! command_line_policy && ! options.print_plugins && ! options.supervisor_mode && ! zeek::Supervisor::ThisNode() ) @@ -591,7 +591,7 @@ int main(int argc, char** argv) log_mgr = new logging::Manager(); input_mgr = new input::Manager(); file_mgr = new file_analysis::Manager(); - broker_mgr = new bro_broker::Manager(! options.pcap_files.empty()); + broker_mgr = new bro_broker::Manager(! options.pcap_file.empty()); plugin_mgr->InitPreScript(); analyzer_mgr->InitPreScript(); @@ -734,9 +734,7 @@ int main(int argc, char** argv) // ### Add support for debug command file. dbg_init_debugger(0); - auto all_interfaces = options.interfaces; - - if ( options.pcap_files.empty() && options.interfaces.empty() ) + if ( options.pcap_file.empty() && options.interface.empty() ) { Val* interfaces_val = internal_val("interfaces"); if ( interfaces_val ) @@ -745,15 +743,14 @@ int main(int argc, char** argv) interfaces_val->AsString()->Render(); if ( interfaces_str[0] != '\0' ) - tokenize_string(interfaces_str, " ", &all_interfaces); + options.interface = interfaces_str; delete [] interfaces_str; } } if ( dns_type != DNS_PRIME ) - net_init(all_interfaces, options.pcap_files, - options.pcap_output_file, options.use_watchdog); + net_init(options.interface, options.pcap_file, options.pcap_output_file, options.use_watchdog); net_done = internal_handler("net_done"); diff --git a/src/stats.bif b/src/stats.bif index 8166021d4e..cf94ebb985 100644 --- a/src/stats.bif +++ b/src/stats.bif @@ -44,13 +44,8 @@ function get_net_stats%(%): NetStats uint64_t link = 0; uint64_t bytes_recv = 0; - const iosource::Manager::PktSrcList& pkt_srcs(iosource_mgr->GetPktSrcs()); - - for ( iosource::Manager::PktSrcList::const_iterator i = pkt_srcs.begin(); - i != pkt_srcs.end(); i++ ) + if ( iosource::PktSrc* ps = iosource_mgr->GetPktSrc() ) { - iosource::PktSrc* ps = *i; - struct iosource::PktSrc::Stats stat; ps->Statistics(&stat); recv += stat.received; @@ -440,7 +435,7 @@ function get_broker_stats%(%): BrokerStats %{ RecordVal* r = new RecordVal(BrokerStats); int n = 0; - + auto cs = broker_mgr->GetStatistics(); r->Assign(n++, val_mgr->GetCount(static_cast(cs.num_peers))); r->Assign(n++, val_mgr->GetCount(static_cast(cs.num_stores))); diff --git a/src/supervisor/Supervisor.cc b/src/supervisor/Supervisor.cc index 4d41383a85..b6e157c1a3 100644 --- a/src/supervisor/Supervisor.cc +++ b/src/supervisor/Supervisor.cc @@ -1284,7 +1284,7 @@ void Supervisor::SupervisedNode::Init(zeek::Options* options) const options->filter_supervised_node_options(); if ( config.interface ) - options->interfaces.emplace_back(*config.interface); + options->interface = *config.interface; for ( const auto& s : config.scripts ) options->scripts_to_load.emplace_back(s); diff --git a/src/util.cc b/src/util.cc index a9b1707297..87cb6250d8 100644 --- a/src/util.cc +++ b/src/util.cc @@ -1902,11 +1902,11 @@ double current_time(bool real) double t = double(tv.tv_sec) + double(tv.tv_usec) / 1e6; - if ( ! pseudo_realtime || real || ! iosource_mgr || iosource_mgr->GetPktSrcs().empty() ) + if ( ! pseudo_realtime || real || ! iosource_mgr || ! iosource_mgr->GetPktSrc() ) return t; // This obviously only works for a single source ... - iosource::PktSrc* src = iosource_mgr->GetPktSrcs().front(); + iosource::PktSrc* src = iosource_mgr->GetPktSrc(); if ( net_is_processing_suspended() ) return src->CurrentPacketTimestamp(); diff --git a/src/zeek.bif b/src/zeek.bif index c357c3ce5f..e491909034 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -1905,26 +1905,24 @@ function reading_traces%(%): bool return val_mgr->GetBool(reading_traces); %} -## Returns: a list of packet sources being read by Zeek. +## Returns: the packet source being read by Zeek. ## ## .. zeek:see:: reading_live_traffic reading_traces -function packet_sources%(%): PacketSourceList +function packet_source%(%): PacketSource %{ auto ps_type = internal_type("PacketSource")->AsRecordType(); - auto psl_type = internal_type("PacketSourceList")->AsVectorType(); - auto rval = make_intrusive(psl_type); + auto ps = iosource_mgr->GetPktSrc(); + auto r = make_intrusive(ps_type); - for ( const auto& ps : iosource_mgr->GetPktSrcs() ) + if ( ps ) { - auto r = make_intrusive(ps_type); r->Assign(0, val_mgr->GetBool(ps->IsLive())); r->Assign(1, new StringVal(ps->Path())); r->Assign(2, val_mgr->GetInt(ps->LinkType())); r->Assign(3, val_mgr->GetCount(ps->Netmask())); - rval->Assign(rval->Size(), r.detach()); } - return rval.detach(); + return r.detach(); %} ## Generates a table of the size of all global variables. The table index is diff --git a/testing/btest/Baseline/bifs.packet_sources/out b/testing/btest/Baseline/bifs.packet_sources/out index ce47345d99..0fa2ce4c2a 100644 --- a/testing/btest/Baseline/bifs.packet_sources/out +++ b/testing/btest/Baseline/bifs.packet_sources/out @@ -1 +1 @@ -[[live=F, path=/Users/jsiwek/pro/zeek/zeek/testing/btest/Traces/http/get.trace, link_type=1, netmask=4294967295]] +[live=F, path=/Users/tim/Desktop/projects/zeek/testing/btest/Traces/http/get.trace, link_type=1, netmask=4294967295] diff --git a/testing/btest/Traces/tunnels/gtp/pdp_ctx_messages.trace b/testing/btest/Traces/tunnels/gtp/pdp_ctx_messages.trace new file mode 100644 index 0000000000000000000000000000000000000000..2124ee4c51974a5dcf170c57b9abef9b44c854b4 GIT binary patch literal 2360 zcmb`Ie@t6d6vxkfuPu)UE$t{jWUREH@@s{*lns{&9n3!*fz61KzgU4jX~Q6-bZ&_; zdz7DZKg{;W2uqBFsIVEAMO?BUMyrX_W&g-DGchKPEc`+I2V&GLnXBjAKEf-1s4<@8 zynF8Lz2EyeC+EG&X0tp60Bw7#ix`ec%|viRTX(PX;LFZVr`J>Ct*`O!boLyL90@tS z&owtRI4kydM~_7YaaQB0@l@hj1JpvB675rZyN8?=uSTNEaJW0#U+JvF9bRX}>wI*3 z+tKNDyvk6Jhzh%gMhisen)xHrBdtoG8~;B z@Yz5ia>|XV(i2Oe)e10f!-r}&o-mco-%-J|?n*2?j*o#0Yi>0#u zeRIf}9~U}vPx-%&SE)Vwzke_?CC4SvJoTc9dKS|eMGear`x1F?HH%rgx{B2%#uF?5 z=e$}9@1sfro%lP^$!<*;!2j;t%r1<{^~UR70T6(IZSR*SuyxR}?$}fI#d0451MSY{ zM@Vn0?kUu5z;$xHaos9SH$j@D&2{tNFYyUni0fL|hVG}D0Pz~<=4LM9oLp~Q_q3+l zmBxGgY$Lt{VcMOI%`Y?qbG0awk1S#i!$tvSqlX=eBv4cRpD9HKV@h;TiH$*?nkcj3 zi)s@GB7IU=85mHGMEbBp=nid|fQ)mYjBUP--zTvyS?5ath?#0Ki%v%D&B(4|Os+T1 z9@W^7qwZ!+x?-!?@)_9Lm(!|Vp4~H!d8?+!V)AKTwh*PyCV%)!3 zSMguf6;BWwF$U4eh;ejre5Da%a=mdzkH&a2t)|7-o_An9=^u+2H%|pI+^T=~+Qdo# z*U9z9^?jQDb=2Rifn&bjA%L(|-@<|@K>D9(Ld3tjU~=U=&dK%0^~W^**V6chZhY)W zLI>_nt1{XTdqAXzo77` zqV2^y93@UyY1z}yJX>B-SyjE$T~q7v`s)1kyLP8oiTPWSK_g~w)8xt(jLG%JnP)ZT t18FrmeWMGRhj4c~a{`7g&EW~wejk|`af|Zf-$->MpC)$uf6RyS_zMr1%~k*a literal 0 HcmV?d00001 diff --git a/testing/btest/bifs/packet_sources.zeek b/testing/btest/bifs/packet_sources.zeek index f6ae5aac5a..893f840bd2 100644 --- a/testing/btest/bifs/packet_sources.zeek +++ b/testing/btest/bifs/packet_sources.zeek @@ -3,5 +3,5 @@ event zeek_init() { - print packet_sources(); + print packet_source(); } diff --git a/testing/btest/core/tunnels/gtp/pdp_ctx_messages.test b/testing/btest/core/tunnels/gtp/pdp_ctx_messages.test index 06912c1f9d..4f145252b3 100644 --- a/testing/btest/core/tunnels/gtp/pdp_ctx_messages.test +++ b/testing/btest/core/tunnels/gtp/pdp_ctx_messages.test @@ -1,4 +1,4 @@ -# @TEST-EXEC: zeek -r $TRACES/tunnels/gtp/gtp_control_prime.pcap -r $TRACES/tunnels/gtp/gtp_create_pdp_ctx.pcap %INPUT >out +# @TEST-EXEC: zeek -r $TRACES/tunnels/gtp/pdp_ctx_messages.trace %INPUT >out # @TEST-EXEC: btest-diff out event gtpv1_message(c: connection, hdr: gtpv1_hdr)