Only allow a single trace file (-r) or interface (-i) option on the command-line

This commit is contained in:
Tim Wojtulewicz 2019-11-26 09:37:12 -07:00
parent 2b2121be60
commit f16f0360ff
17 changed files with 93 additions and 141 deletions

View file

@ -133,9 +133,6 @@ type PacketSource: record {
netmask: count; 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 ## A connection's transport-layer protocol. Note that Zeek uses the term
## "connection" broadly, using flow semantics for ICMP and UDP. ## "connection" broadly, using flow semantics for ICMP and UDP.
type transport_proto: enum { type transport_proto: enum {

View file

@ -145,41 +145,34 @@ void net_update_time(double new_network_time)
PLUGIN_HOOK_VOID(HOOK_UPDATE_NETWORK_TIME, HookUpdateNetworkTime(new_network_time)); PLUGIN_HOOK_VOID(HOOK_UPDATE_NETWORK_TIME, HookUpdateNetworkTime(new_network_time));
} }
void net_init(const std::vector<std::string>& interfaces, void net_init(const std::string& interface,
const std::vector<std::string>& pcap_input_files, const std::string& pcap_input_file,
const std::optional<std::string>& pcap_output_file, const std::optional<std::string>& pcap_output_file,
bool do_watchdog) bool do_watchdog)
{ {
if ( ! pcap_input_files.empty() ) if ( ! pcap_input_file.empty() )
{ {
reading_live = pseudo_realtime > 0.0; reading_live = pseudo_realtime > 0.0;
reading_traces = 1; reading_traces = 1;
for ( const auto& pif : pcap_input_files ) iosource::PktSrc* ps = iosource_mgr->OpenPktSrc(pcap_input_file, false);
{
iosource::PktSrc* ps = iosource_mgr->OpenPktSrc(pif, false);
assert(ps); assert(ps);
if ( ! ps->IsOpen() ) if ( ! ps->IsOpen() )
reporter->FatalError("problem with trace file %s (%s)", reporter->FatalError("problem with trace file %s (%s)",
pif.data(), ps->ErrorMsg()); pcap_input_file.c_str(), ps->ErrorMsg());
} }
} else if ( ! interface.empty() )
else if ( ! interfaces.empty() )
{ {
reading_live = 1; reading_live = 1;
reading_traces = 0; reading_traces = 0;
for ( const auto& iface : interfaces ) iosource::PktSrc* ps = iosource_mgr->OpenPktSrc(interface, true);
{
iosource::PktSrc* ps = iosource_mgr->OpenPktSrc(iface, true);
assert(ps); assert(ps);
if ( ! ps->IsOpen() ) if ( ! ps->IsOpen() )
reporter->FatalError("problem with interface %s (%s)", reporter->FatalError("problem with interface %s (%s)",
iface.data(), ps->ErrorMsg()); interface.c_str(), ps->ErrorMsg());
}
} }
else else
@ -377,14 +370,9 @@ void net_run()
{ {
auto have_active_packet_source = false; auto have_active_packet_source = false;
for ( auto& ps : iosource_mgr->GetPktSrcs() ) iosource::PktSrc* ps = iosource_mgr->GetPktSrc();
{ if ( ps && ps->IsOpen() )
if ( ps->IsOpen() )
{
have_active_packet_source = true; have_active_packet_source = true;
break;
}
}
if ( ! have_active_packet_source ) if ( ! have_active_packet_source )
// Can turn off pseudo realtime now // Can turn off pseudo realtime now
@ -401,14 +389,8 @@ void net_run()
void net_get_final_stats() void net_get_final_stats()
{ {
const iosource::Manager::PktSrcList& pkt_srcs(iosource_mgr->GetPktSrcs()); iosource::PktSrc* ps = iosource_mgr->GetPktSrc();
if ( ps && ps->IsLive() )
for ( iosource::Manager::PktSrcList::const_iterator i = pkt_srcs.begin();
i != pkt_srcs.end(); i++ )
{
iosource::PktSrc* ps = *i;
if ( ps->IsLive() )
{ {
iosource::PktSrc::Stats s; iosource::PktSrc::Stats s;
ps->Statistics(&s); ps->Statistics(&s);
@ -416,7 +398,6 @@ void net_get_final_stats()
s.received, ps->Path().c_str(), s.dropped); s.received, ps->Path().c_str(), s.dropped);
} }
} }
}
void net_finish(int drain_events) void net_finish(int drain_events)
{ {
@ -468,12 +449,8 @@ void net_continue_processing()
if ( _processing_suspended == 1 ) if ( _processing_suspended == 1 )
{ {
reporter->Info("processing continued"); reporter->Info("processing continued");
if ( iosource::PktSrc* ps = iosource_mgr->GetPktSrc() )
const iosource::Manager::PktSrcList& pkt_srcs(iosource_mgr->GetPktSrcs()); ps->ContinueAfterSuspend();
for ( iosource::Manager::PktSrcList::const_iterator i = pkt_srcs.begin();
i != pkt_srcs.end(); i++ )
(*i)->ContinueAfterSuspend();
} }
--_processing_suspended; --_processing_suspended;

View file

@ -14,8 +14,8 @@
#include "iosource/PktSrc.h" #include "iosource/PktSrc.h"
#include "iosource/PktDumper.h" #include "iosource/PktDumper.h"
extern void net_init(const std::vector<std::string>& interfaces, extern void net_init(const std::string& interfaces,
const std::vector<std::string>& pcap_input_files, const std::string& pcap_input_file,
const std::optional<std::string>& pcap_output_file, const std::optional<std::string>& pcap_output_file,
bool do_watchdog); bool do_watchdog);
extern void net_run(); extern void net_run();

View file

@ -16,8 +16,6 @@
void zeek::Options::filter_supervisor_options() void zeek::Options::filter_supervisor_options()
{ {
pcap_filter = {}; pcap_filter = {};
interfaces = {};
pcap_files = {};
signature_files = {}; signature_files = {};
pcap_output_file = {}; 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 // use-case-specific way. e.g. interfaces is already handled for the
// "cluster" use-case, but don't have supervised-pcap-reading // "cluster" use-case, but don't have supervised-pcap-reading
// functionality yet. // functionality yet.
/* interfaces = og.interfaces; */ /* interface = og.interface; */
/* pcap_files = og.pcap_files; */ /* pcap_file = og.pcap_file; */
pcap_output_file = og.pcap_output_file; pcap_output_file = og.pcap_output_file;
random_seed_input_file = og.random_seed_input_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 <zeek code> | augment loaded scripts by given code\n"); fprintf(stderr, " -e|--exec <zeek code> | augment loaded scripts by given code\n");
fprintf(stderr, " -f|--filter <filter> | tcpdump filter\n"); fprintf(stderr, " -f|--filter <filter> | tcpdump filter\n");
fprintf(stderr, " -h|--help | command line help\n"); fprintf(stderr, " -h|--help | command line help\n");
fprintf(stderr, " -i|--iface <interface> | read from given interface\n"); fprintf(stderr, " -i|--iface <interface> | read from given interface (only one allowed)\n");
fprintf(stderr, " -p|--prefix <prefix> | add given prefix to Zeek script file resolution\n"); fprintf(stderr, " -p|--prefix <prefix> | add given prefix to Zeek script file resolution\n");
fprintf(stderr, " -r|--readfile <readfile> | read from given tcpdump file\n"); fprintf(stderr, " -r|--readfile <readfile> | read from given tcpdump file (only one allowed, pass '-' as the filename to read from stdin)\n");
fprintf(stderr, " -s|--rulefile <rulefile> | read rules from given file\n"); fprintf(stderr, " -s|--rulefile <rulefile> | read rules from given file\n");
fprintf(stderr, " -t|--tracefile <tracefile> | activate execution tracing\n"); fprintf(stderr, " -t|--tracefile <tracefile> | activate execution tracing\n");
fprintf(stderr, " -v|--version | print version and exit\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; rval.print_usage = true;
break; break;
case 'i': 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); 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; break;
case 'j': case 'j':
rval.supervisor_mode = true; rval.supervisor_mode = true;
@ -290,12 +294,17 @@ zeek::Options zeek::parse_cmdline(int argc, char** argv)
rval.script_prefixes.emplace_back(optarg); rval.script_prefixes.emplace_back(optarg);
break; break;
case 'r': 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); 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; break;
case 's': case 's':
rval.signature_files.emplace_back(optarg); rval.signature_files.emplace_back(optarg);

View file

@ -58,8 +58,8 @@ struct Options {
std::vector<std::string> doctest_args; std::vector<std::string> doctest_args;
std::optional<std::string> pcap_filter; std::optional<std::string> pcap_filter;
std::vector<std::string> interfaces; std::string interface;
std::vector<std::string> pcap_files; std::string pcap_file;
std::vector<std::string> signature_files; std::vector<std::string> signature_files;
std::optional<std::string> pcap_output_file; std::optional<std::string> pcap_output_file;

View file

@ -207,7 +207,7 @@ void Manager::Register(IOSource* src, bool dont_count)
void Manager::Register(PktSrc* src) void Manager::Register(PktSrc* src)
{ {
pkt_srcs.push_back(src); pkt_src = src;
Register(src, false); Register(src, false);
} }

View file

@ -58,13 +58,11 @@ public:
*/ */
int Size() const { return sources.size() - dont_counts; } int Size() const { return sources.size() - dont_counts; }
typedef std::list<PktSrc *> PktSrcList;
/** /**
* Returns a list of all registered PktSrc instances. This is a * Returns the registered PktSrc. If not source is registered yet,
* subset of all registered IOSource instances. * 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 * Terminate all processing immediately by removing all sources (and
@ -136,7 +134,7 @@ private:
typedef std::list<PktDumper *> PktDumperList; typedef std::list<PktDumper *> PktDumperList;
PktSrcList pkt_srcs; PktSrc* pkt_src = nullptr;
PktDumperList pkt_dumpers; PktDumperList pkt_dumpers;
}; };

View file

@ -35,17 +35,9 @@ function precompile_pcap_filter%(id: PcapFilterID, s: string%): bool
bool success = true; bool success = true;
const iosource::Manager::PktSrcList& pkt_srcs(iosource_mgr->GetPktSrcs()); iosource::PktSrc* ps = iosource_mgr->GetPktSrc();
if ( ps && ! ps->PrecompileFilter(id->ForceAsInt(), s->CheckString()) )
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; success = false;
}
return val_mgr->GetBool(success); return val_mgr->GetBool(success);
%} %}
@ -72,16 +64,9 @@ function Pcap::install_pcap_filter%(id: PcapFilterID%): bool
%{ %{
bool success = true; bool success = true;
const iosource::Manager::PktSrcList& pkt_srcs(iosource_mgr->GetPktSrcs()); iosource::PktSrc* ps = iosource_mgr->GetPktSrc();
if ( ps && ! ps->SetFilter(id->ForceAsInt()) )
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; success = false;
}
return val_mgr->GetBool(success); return val_mgr->GetBool(success);
%} %}
@ -102,13 +87,9 @@ function Pcap::install_pcap_filter%(id: PcapFilterID%): bool
## uninstall_dst_net_filter ## uninstall_dst_net_filter
function error%(%): string function error%(%): string
%{ %{
const iosource::Manager::PktSrcList& pkt_srcs(iosource_mgr->GetPktSrcs()); iosource::PktSrc* ps = iosource_mgr->GetPktSrc();
if ( ps )
for ( iosource::Manager::PktSrcList::const_iterator i = pkt_srcs.begin();
i != pkt_srcs.end(); i++ )
{ {
iosource::PktSrc* ps = *i;
const char* err = ps->ErrorMsg(); const char* err = ps->ErrorMsg();
if ( *err ) if ( *err )
return new StringVal(err); return new StringVal(err);

View file

@ -560,8 +560,8 @@ int main(int argc, char** argv)
if ( options.plugins_to_load.empty() && options.scripts_to_load.empty() && if ( options.plugins_to_load.empty() && options.scripts_to_load.empty() &&
options.script_options_to_set.empty() && options.script_options_to_set.empty() &&
options.pcap_files.size() == 0 && options.pcap_file.empty() &&
options.interfaces.size() == 0 && options.interface.empty() &&
! options.identifier_to_print && ! options.identifier_to_print &&
! command_line_policy && ! options.print_plugins && ! command_line_policy && ! options.print_plugins &&
! options.supervisor_mode && ! zeek::Supervisor::ThisNode() ) ! options.supervisor_mode && ! zeek::Supervisor::ThisNode() )
@ -591,7 +591,7 @@ int main(int argc, char** argv)
log_mgr = new logging::Manager(); log_mgr = new logging::Manager();
input_mgr = new input::Manager(); input_mgr = new input::Manager();
file_mgr = new file_analysis::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(); plugin_mgr->InitPreScript();
analyzer_mgr->InitPreScript(); analyzer_mgr->InitPreScript();
@ -734,9 +734,7 @@ int main(int argc, char** argv)
// ### Add support for debug command file. // ### Add support for debug command file.
dbg_init_debugger(0); dbg_init_debugger(0);
auto all_interfaces = options.interfaces; if ( options.pcap_file.empty() && options.interface.empty() )
if ( options.pcap_files.empty() && options.interfaces.empty() )
{ {
Val* interfaces_val = internal_val("interfaces"); Val* interfaces_val = internal_val("interfaces");
if ( interfaces_val ) if ( interfaces_val )
@ -745,15 +743,14 @@ int main(int argc, char** argv)
interfaces_val->AsString()->Render(); interfaces_val->AsString()->Render();
if ( interfaces_str[0] != '\0' ) if ( interfaces_str[0] != '\0' )
tokenize_string(interfaces_str, " ", &all_interfaces); options.interface = interfaces_str;
delete [] interfaces_str; delete [] interfaces_str;
} }
} }
if ( dns_type != DNS_PRIME ) if ( dns_type != DNS_PRIME )
net_init(all_interfaces, options.pcap_files, net_init(options.interface, options.pcap_file, options.pcap_output_file, options.use_watchdog);
options.pcap_output_file, options.use_watchdog);
net_done = internal_handler("net_done"); net_done = internal_handler("net_done");

View file

@ -44,13 +44,8 @@ function get_net_stats%(%): NetStats
uint64_t link = 0; uint64_t link = 0;
uint64_t bytes_recv = 0; uint64_t bytes_recv = 0;
const iosource::Manager::PktSrcList& pkt_srcs(iosource_mgr->GetPktSrcs()); if ( iosource::PktSrc* ps = iosource_mgr->GetPktSrc() )
for ( iosource::Manager::PktSrcList::const_iterator i = pkt_srcs.begin();
i != pkt_srcs.end(); i++ )
{ {
iosource::PktSrc* ps = *i;
struct iosource::PktSrc::Stats stat; struct iosource::PktSrc::Stats stat;
ps->Statistics(&stat); ps->Statistics(&stat);
recv += stat.received; recv += stat.received;

View file

@ -1284,7 +1284,7 @@ void Supervisor::SupervisedNode::Init(zeek::Options* options) const
options->filter_supervised_node_options(); options->filter_supervised_node_options();
if ( config.interface ) if ( config.interface )
options->interfaces.emplace_back(*config.interface); options->interface = *config.interface;
for ( const auto& s : config.scripts ) for ( const auto& s : config.scripts )
options->scripts_to_load.emplace_back(s); options->scripts_to_load.emplace_back(s);

View file

@ -1902,11 +1902,11 @@ double current_time(bool real)
double t = double(tv.tv_sec) + double(tv.tv_usec) / 1e6; 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; return t;
// This obviously only works for a single source ... // 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() ) if ( net_is_processing_suspended() )
return src->CurrentPacketTimestamp(); return src->CurrentPacketTimestamp();

View file

@ -1905,26 +1905,24 @@ function reading_traces%(%): bool
return val_mgr->GetBool(reading_traces); 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 ## .. zeek:see:: reading_live_traffic reading_traces
function packet_sources%(%): PacketSourceList function packet_source%(%): PacketSource
%{ %{
auto ps_type = internal_type("PacketSource")->AsRecordType(); auto ps_type = internal_type("PacketSource")->AsRecordType();
auto psl_type = internal_type("PacketSourceList")->AsVectorType(); auto ps = iosource_mgr->GetPktSrc();
auto rval = make_intrusive<VectorVal>(psl_type);
for ( const auto& ps : iosource_mgr->GetPktSrcs() )
{
auto r = make_intrusive<RecordVal>(ps_type); auto r = make_intrusive<RecordVal>(ps_type);
if ( ps )
{
r->Assign(0, val_mgr->GetBool(ps->IsLive())); r->Assign(0, val_mgr->GetBool(ps->IsLive()));
r->Assign(1, new StringVal(ps->Path())); r->Assign(1, new StringVal(ps->Path()));
r->Assign(2, val_mgr->GetInt(ps->LinkType())); r->Assign(2, val_mgr->GetInt(ps->LinkType()));
r->Assign(3, val_mgr->GetCount(ps->Netmask())); 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 ## Generates a table of the size of all global variables. The table index is

View file

@ -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]

View file

@ -3,5 +3,5 @@
event zeek_init() event zeek_init()
{ {
print packet_sources(); print packet_source();
} }

View file

@ -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 # @TEST-EXEC: btest-diff out
event gtpv1_message(c: connection, hdr: gtpv1_hdr) event gtpv1_message(c: connection, hdr: gtpv1_hdr)