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;
};
## 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 {

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));
}
void net_init(const std::vector<std::string>& interfaces,
const std::vector<std::string>& pcap_input_files,
void net_init(const std::string& interface,
const std::string& pcap_input_file,
const std::optional<std::string>& 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;

View file

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

View file

@ -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 <zeek code> | augment loaded scripts by given code\n");
fprintf(stderr, " -f|--filter <filter> | tcpdump filter\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, " -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, " -t|--tracefile <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);

View file

@ -58,8 +58,8 @@ struct Options {
std::vector<std::string> doctest_args;
std::optional<std::string> pcap_filter;
std::vector<std::string> interfaces;
std::vector<std::string> pcap_files;
std::string interface;
std::string pcap_file;
std::vector<std::string> signature_files;
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)
{
pkt_srcs.push_back(src);
pkt_src = src;
Register(src, false);
}

View file

@ -58,13 +58,11 @@ public:
*/
int Size() const { return sources.size() - dont_counts; }
typedef std::list<PktSrc *> 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<PktDumper *> PktDumperList;
PktSrcList pkt_srcs;
PktSrc* pkt_src = nullptr;
PktDumperList pkt_dumpers;
};

View file

@ -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);

View file

@ -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");

View file

@ -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<uint64_t>(cs.num_peers)));
r->Assign(n++, val_mgr->GetCount(static_cast<uint64_t>(cs.num_stores)));

View file

@ -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);

View file

@ -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();

View file

@ -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<VectorVal>(psl_type);
auto ps = iosource_mgr->GetPktSrc();
auto r = make_intrusive<RecordVal>(ps_type);
for ( const auto& ps : iosource_mgr->GetPktSrcs() )
if ( ps )
{
auto r = make_intrusive<RecordVal>(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

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()
{
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
event gtpv1_message(c: connection, hdr: gtpv1_hdr)