diff --git a/configure b/configure index ba9bf58301..5a4596328c 100755 --- a/configure +++ b/configure @@ -64,6 +64,7 @@ Usage: $0 [OPTION]... [VAR=VALUE]... --with-dataseries=PATH path to DataSeries and Lintel libraries --with-xml2=PATH path to libxml2 installation (for DataSeries) --with-curl=PATH path to libcurl install root (for ElasticSearch) + --with-netmap=PATH path to netmap distribution Packaging Options (for developers): --binary-package toggle special logic for binary packaging @@ -247,6 +248,9 @@ while [ $# -ne 0 ]; do --with-curl=*) append_cache_entry LibCURL_ROOT_DIR PATH $optarg ;; + --with-netmap=*) + append_cache_entry NETMAP_ROOT_DIR PATH $optarg + ;; --binary-package) append_cache_entry BINARY_PACKAGING_MODE BOOL true ;; diff --git a/src/Net.cc b/src/Net.cc index 629f2398d0..a1278c709b 100644 --- a/src/Net.cc +++ b/src/Net.cc @@ -167,90 +167,33 @@ void net_init(name_list& interfaces, name_list& readfiles, reading_traces = 1; for ( int i = 0; i < readfiles.length(); ++i ) - iosource_mgr->OpenPktSrc(readfiles[i], filter, false); + { + iosource::PktSrc* ps = iosource_mgr->OpenPktSrc(readfiles[i], filter, false); + assert(ps); + + if ( ps->ErrorMsg() ) + reporter->FatalError("%s: problem with trace file %s - %s\n", + prog, readfiles[i], + ps->ErrorMsg()); + } } -#if 0 - if ( secondary_filter ) - { - // We use a second PktFileSrc for the - // secondary path. - PktFileSrc* ps = new PktFileSrc(readfiles[i], - secondary_filter, - TYPE_FILTER_SECONDARY); - - if ( ! ps->IsOpen() ) - reporter->FatalError("%s: problem with trace file %s - %s\n", - prog, readfiles[i], - ps->ErrorMsg()); - else - { - pkt_srcs.append(ps); - io_sources.Register(ps); - } - - ps->AddSecondaryTablePrograms(); - } - - for ( int i = 0; i < flowfiles.length(); ++i ) - { - FlowFileSrc* fs = new FlowFileSrc(flowfiles[i]); - - if ( ! fs->IsOpen() ) - reporter->FatalError("%s: problem with netflow file %s - %s\n", - prog, flowfiles[i], fs->ErrorMsg()); - else - { - io_sources.Register(fs); - } - } -#endif - - else if ((interfaces.length() > 0 || netflows.length() > 0)) + else if ( interfaces.length() > 0 ) { reading_live = 1; reading_traces = 0; for ( int i = 0; i < interfaces.length(); ++i ) - iosource_mgr->OpenPktSrc(interfaces[i], filter, true); - } -#if 0 - - if ( secondary_filter ) - { - iosource::PktSrc* ps; - ps = new PktInterfaceSrc(interfaces[i], - filter, TYPE_FILTER_SECONDARY); - - if ( ! ps->IsOpen() ) - reporter->Error("%s: problem with interface %s - %s\n", - prog, interfaces[i], - ps->ErrorMsg()); - else - { - pkt_srcs.append(ps); - io_sources.Register(ps); - } - - ps->AddSecondaryTablePrograms(); - } - } - - for ( int i = 0; i < netflows.length(); ++i ) { - FlowSocketSrc* fs = new FlowSocketSrc(netflows[i]); + iosource::PktSrc* ps = iosource_mgr->OpenPktSrc(interfaces[i], filter, true); + assert(ps); - if ( ! fs->IsOpen() ) - { - reporter->Error("%s: problem with netflow socket %s - %s\n", - prog, netflows[i], fs->ErrorMsg()); - delete fs; - } - - else - io_sources.Register(fs); + if ( ps->ErrorMsg() ) + reporter->FatalError("%s: problem with interface %s - %s\n", + prog, interfaces[i], + ps->ErrorMsg()); } -#endif + } else // have_pending_timers = 1, possibly. We don't set diff --git a/src/iosource/Manager.cc b/src/iosource/Manager.cc index 06608c7afd..6c01e5e57b 100644 --- a/src/iosource/Manager.cc +++ b/src/iosource/Manager.cc @@ -231,7 +231,7 @@ PktSrc* Manager::OpenPktSrc(const std::string& path, const std::string& filter, { pktsrc::SourceComponent* c = *i; - if ( c->Prefix() == prefix && + if ( c->HandlesPrefix(prefix) && (( is_live && c->DoesLive() ) || (! is_live && c->DoesTrace())) ) { @@ -242,7 +242,7 @@ PktSrc* Manager::OpenPktSrc(const std::string& path, const std::string& filter, if ( ! component ) - reporter->FatalError("type of packet source '%s' not recognized", prefix.c_str()); + reporter->FatalError("type of packet source '%s' not recognized, or mode not supported", prefix.c_str()); // Instantiate packet source. @@ -279,7 +279,7 @@ PktDumper* Manager::OpenPktDumper(const string& path, bool append) for ( std::list::const_iterator i = all_components.begin(); i != all_components.end(); i++ ) { - if ( (*i)->Prefix() == prefix ) + if ( (*i)->HandlesPrefix(prefix) ) { component = (*i); break; diff --git a/src/iosource/pktsrc/CMakeLists.txt b/src/iosource/pktsrc/CMakeLists.txt index 07303b46a3..9c8a458c54 100644 --- a/src/iosource/pktsrc/CMakeLists.txt +++ b/src/iosource/pktsrc/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(pcap) +add_subdirectory(netmap) diff --git a/src/iosource/pktsrc/Component.cc b/src/iosource/pktsrc/Component.cc index 7597e1aaa5..6caf743ff9 100644 --- a/src/iosource/pktsrc/Component.cc +++ b/src/iosource/pktsrc/Component.cc @@ -3,13 +3,14 @@ #include "Component.h" #include "../Desc.h" +#include "../Reporter.h" using namespace iosource::pktsrc; SourceComponent::SourceComponent(const std::string& arg_name, const std::string& arg_prefix, InputType arg_type, factory_callback arg_factory) : iosource::Component(plugin::component::PKTSRC, arg_name) { - prefix = arg_prefix; + tokenize_string(arg_prefix, ":", &prefixes); type = arg_type; factory = arg_factory; } @@ -18,9 +19,21 @@ SourceComponent::~SourceComponent() { } -const std::string& SourceComponent::Prefix() const +const std::vector& SourceComponent::Prefixes() const { - return prefix; + return prefixes; + } + +bool SourceComponent::HandlesPrefix(const string& prefix) const + { + for ( std::vector::const_iterator i = prefixes.begin(); + i != prefixes.end(); i++ ) + { + if ( *i == prefix ) + return true; + } + + return false; } bool SourceComponent::DoesLive() const @@ -43,16 +56,50 @@ void SourceComponent::Describe(ODesc* d) const { iosource::Component::Describe(d); - d->Add(" (interface prefix: "); - d->Add(prefix); + string prefs; + + for ( std::vector::const_iterator i = prefixes.begin(); + i != prefixes.end(); i++ ) + { + if ( prefs.size() ) + prefs += ", "; + + prefs += *i; + } + + d->Add(" (interface prefix"); + if ( prefixes.size() > 1 ) + d->Add("es"); + + d->Add(": "); + d->Add(prefs); + d->Add("; "); + + switch ( type ) { + case LIVE: + d->Add("live input"); + break; + + case TRACE: + d->Add("trace input"); + break; + + case BOTH: + d->Add("live and trace input"); + break; + + default: + reporter->InternalError("unknown PkrSrc type"); + } + d->Add(")"); } DumperComponent::DumperComponent(const std::string& name, const std::string& arg_prefix, factory_callback arg_factory) : plugin::Component(plugin::component::PKTDUMPER, name) { + tokenize_string(arg_prefix, ":", &prefixes); factory = arg_factory; - prefix = arg_prefix; } DumperComponent::~DumperComponent() @@ -64,17 +111,45 @@ DumperComponent::factory_callback DumperComponent::Factory() const return factory; } -const std::string& DumperComponent::Prefix() const +const std::vector& DumperComponent::Prefixes() const { - return prefix; + return prefixes; + } + +bool DumperComponent::HandlesPrefix(const string& prefix) const + { + for ( std::vector::const_iterator i = prefixes.begin(); + i != prefixes.end(); i++ ) + { + if ( *i == prefix ) + return true; + } + + return false; } void DumperComponent::Describe(ODesc* d) const { plugin::Component::Describe(d); - d->Add(" (dumper prefix: "); - d->Add(prefix); + string prefs; + + for ( std::vector::const_iterator i = prefixes.begin(); + i != prefixes.end(); i++ ) + { + if ( prefs.size() ) + prefs += ", "; + + prefs += *i; + } + + d->Add(" (dumper prefix"); + + if ( prefixes.size() > 1 ) + d->Add("es"); + + d->Add(": "); + d->Add(prefs); d->Add(")"); } diff --git a/src/iosource/pktsrc/Component.h b/src/iosource/pktsrc/Component.h index 31ed8a7180..0e4755d7b8 100644 --- a/src/iosource/pktsrc/Component.h +++ b/src/iosource/pktsrc/Component.h @@ -3,6 +3,8 @@ #ifndef IOSOURCE_PKTSRC_PLUGIN_COMPONENT_H #define IOSOURCE_PKTSRC_PLUGIN_COMPONENT_H +#include + #include "../Component.h" namespace iosource { @@ -24,7 +26,7 @@ public: /** * XXX */ - SourceComponent(const std::string& name, const std::string& prefix, InputType type, factory_callback factory); + SourceComponent(const std::string& name, const std::string& prefixes, InputType type, factory_callback factory); /** * Destructor. @@ -32,9 +34,14 @@ public: virtual ~SourceComponent(); /** - * Returns the prefix passes to the constructor. + * Returns the prefix(es) passed to the constructor. */ - const std::string& Prefix() const; + const std::vector& Prefixes() const; + + /** + * Returns true if the given prefix is among the one specified for the component. + */ + bool HandlesPrefix(const std::string& prefix) const; /** * Returns true if packet source instantiated by the component handle @@ -60,7 +67,7 @@ public: virtual void Describe(ODesc* d) const; private: - std::string prefix; + std::vector prefixes; InputType type; factory_callback factory; }; @@ -78,7 +85,7 @@ public: /** * XXX */ - DumperComponent(const std::string& name, const std::string& prefix, factory_callback factory); + DumperComponent(const std::string& name, const std::string& prefixes, factory_callback factory); /** * Destructor. @@ -86,9 +93,14 @@ public: ~DumperComponent(); /** - * Returns the prefix passes to the constructor. + * Returns the prefix(es) passed to the constructor. */ - const std::string& Prefix() const; + const std::vector& Prefixes() const; + + /** + * Returns true if the given prefix is among the one specified for the component. + */ + bool HandlesPrefix(const std::string& prefix) const; /** * Returns the source's factory function. @@ -102,7 +114,7 @@ public: virtual void Describe(ODesc* d) const; private: - std::string prefix; + std::vector prefixes; factory_callback factory; }; diff --git a/src/iosource/pktsrc/PktSrc.cc b/src/iosource/pktsrc/PktSrc.cc index 703a2d634b..c608f5267f 100644 --- a/src/iosource/pktsrc/PktSrc.cc +++ b/src/iosource/pktsrc/PktSrc.cc @@ -409,3 +409,12 @@ int PktSrc::ExtractNextPacketInternal() return 0; } +int PktSrc::PrecompileFilter(int index, const std::string& filter) + { + return 1; + } + +int PktSrc::SetFilter(int index) + { + return 1; + } diff --git a/src/iosource/pktsrc/PktSrc.h b/src/iosource/pktsrc/PktSrc.h index 3c3436bb19..edeecfe6cf 100644 --- a/src/iosource/pktsrc/PktSrc.h +++ b/src/iosource/pktsrc/PktSrc.h @@ -3,9 +3,11 @@ #ifndef IOSOURCE_PKTSRC_PKTSRC_H #define IOSOURCE_PKTSRC_PKTSRC_H -#include "../IOSource.h" +extern "C" { +#include +} -struct pcap_pkthdr; +#include "../IOSource.h" namespace iosource { @@ -48,12 +50,12 @@ public: // Precompiles a filter and associates the given index with it. // Returns true on success, 0 if a problem occurred or filtering is // not supported. - virtual int PrecompileFilter(int index, const std::string& filter) = 0; + virtual int PrecompileFilter(int index, const std::string& filter); // Activates the filter with the given index. Returns true on // success, 0 if a problem occurred or the filtering is not // supported. - virtual int SetFilter(int index) = 0; + virtual int SetFilter(int index); static int GetLinkHeaderSize(int link_type); diff --git a/src/iosource/pktsrc/pcap/Plugin.cc b/src/iosource/pktsrc/pcap/Plugin.cc index 884b5b2bfd..a412e4f650 100644 --- a/src/iosource/pktsrc/pcap/Plugin.cc +++ b/src/iosource/pktsrc/pcap/Plugin.cc @@ -12,8 +12,8 @@ class Plugin : public plugin::Plugin { public: plugin::Configuration Configure() { - AddComponent(new ::iosource::pktsrc::SourceComponent("PcapReader", "pcap", ::iosource::pktsrc::SourceComponent::BOTH, ::iosource::pktsrc::PcapSource::Instantiate)); - AddComponent(new ::iosource::pktsrc::DumperComponent("PcapWriter", "pcap", ::iosource::pktsrc::PcapDumper::Instantiate)); + AddComponent(new ::iosource::pktsrc::SourceComponent("PcapReader", "pcap", ::iosource::pktsrc::SourceComponent::BOTH, ::iosource::pktsrc::PcapSource::Instantiate)); + AddComponent(new ::iosource::pktsrc::DumperComponent("PcapWriter", "pcap", ::iosource::pktsrc::PcapDumper::Instantiate)); plugin::Configuration config; config.name = "Bro::Pcap"; diff --git a/src/iosource/pktsrc/pcap/Source.cc b/src/iosource/pktsrc/pcap/Source.cc index 86c0273adf..8165724871 100644 --- a/src/iosource/pktsrc/pcap/Source.cc +++ b/src/iosource/pktsrc/pcap/Source.cc @@ -1,4 +1,6 @@ +#include + #include "config.h" #include "Source.h" @@ -92,9 +94,7 @@ void PcapSource::OpenLive() if ( ! pd ) { - safe_snprintf(errbuf, sizeof(errbuf), - "pcap_open_live: %s", tmp_errbuf); - Error(errbuf); + Error(tmp_errbuf); return; } @@ -106,10 +106,7 @@ void PcapSource::OpenLive() #ifdef HAVE_LINUX if ( pcap_setnonblock(pd, 1, tmp_errbuf) < 0 ) { - safe_snprintf(errbuf, sizeof(errbuf), - "pcap_setnonblock: %s", tmp_errbuf); - Error(errbuf); - pcap_close(pd); + PcapError(); return; } #endif @@ -136,7 +133,6 @@ void PcapSource::OpenLive() void PcapSource::OpenOffline() { char errbuf[PCAP_ERRBUF_SIZE]; - char tmp_errbuf[PCAP_ERRBUF_SIZE]; #if 0 filter_type = ft; @@ -146,8 +142,6 @@ void PcapSource::OpenOffline() if ( ! pd ) { - safe_snprintf(errbuf, sizeof(errbuf), - "pcap_open_offline: %s", tmp_errbuf); Error(errbuf); return; } @@ -178,6 +172,9 @@ void PcapSource::OpenOffline() int PcapSource::ExtractNextPacket(Packet* pkt) { + if ( ! pd ) + return 0; + const u_char* data = pcap_next(pd, ¤t_hdr); if ( ! data ) @@ -214,6 +211,9 @@ void PcapSource::DoneWithPacket(Packet* pkt) int PcapSource::PrecompileFilter(int index, const std::string& filter) { + if ( ! pd ) + return 1; // Prevent error message. + char errbuf[PCAP_ERRBUF_SIZE]; // Compile filter. @@ -240,6 +240,9 @@ int PcapSource::PrecompileFilter(int index, const std::string& filter) int PcapSource::SetFilter(int index) { + if ( ! pd ) + return 1; // Prevent error message + char errbuf[PCAP_ERRBUF_SIZE]; #if 0 @@ -279,7 +282,7 @@ void PcapSource::Statistics(Stats* s) { char errbuf[PCAP_ERRBUF_SIZE]; - if ( ! props.is_live ) + if ( ! (props.is_live && pd) ) s->received = s->dropped = s->link = 0; else @@ -316,13 +319,19 @@ bool PcapSource::GetCurrentPacket(const pcap_pkthdr** hdr, const u_char** pkt) void PcapSource::PcapError() { - assert(pd); - Error(fmt("pcap_error: %s", pcap_geterr(pd))); + if ( pd ) + Error(fmt("pcap_error: %s", pcap_geterr(pd))); + else + Error("pcap_error: not open"); + Close(); } void PcapSource::SetHdrSize() { + if ( ! pd ) + return; + char errbuf[PCAP_ERRBUF_SIZE]; props.link_type = pcap_datalink(pd); diff --git a/src/iosource/pktsrc/pcap/Source.h b/src/iosource/pktsrc/pcap/Source.h index 9f1d7c7eb8..03b75c1ca7 100644 --- a/src/iosource/pktsrc/pcap/Source.h +++ b/src/iosource/pktsrc/pcap/Source.h @@ -3,10 +3,6 @@ #ifndef IOSOURCE_PKTSRC_PCAP_SOURCE_H #define IOSOURCE_PKTSRC_PCAP_SOURCE_H -extern "C" { -#include -} - #include "../PktSrc.h" #include "BPF_Program.h" #include "Dict.h"