A series of updates and tweaks to the new PktSrc interface.

This commit is contained in:
Robin Sommer 2014-01-27 15:19:32 -08:00
parent 191b63e334
commit 9a9451af00
11 changed files with 169 additions and 118 deletions

4
configure vendored
View file

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

View file

@ -167,91 +167,34 @@ 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);
}
#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);
iosource::PktSrc* ps = iosource_mgr->OpenPktSrc(readfiles[i], filter, false);
assert(ps);
if ( ! ps->IsOpen() )
if ( ps->ErrorMsg() )
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);
iosource::PktSrc* ps = iosource_mgr->OpenPktSrc(interfaces[i], filter, true);
assert(ps);
if ( ! ps->IsOpen() )
reporter->Error("%s: problem with interface %s - %s\n",
if ( ps->ErrorMsg() )
reporter->FatalError("%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]);
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);
}
#endif
else
// have_pending_timers = 1, possibly. We don't set
// that here, though, because at this point we don't know

View file

@ -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<pktsrc::DumperComponent*>::const_iterator i = all_components.begin();
i != all_components.end(); i++ )
{
if ( (*i)->Prefix() == prefix )
if ( (*i)->HandlesPrefix(prefix) )
{
component = (*i);
break;

View file

@ -1,2 +1,3 @@
add_subdirectory(pcap)
add_subdirectory(netmap)

View file

@ -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<std::string>& SourceComponent::Prefixes() const
{
return prefix;
return prefixes;
}
bool SourceComponent::HandlesPrefix(const string& prefix) const
{
for ( std::vector<std::string>::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<std::string>::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<std::string>& DumperComponent::Prefixes() const
{
return prefix;
return prefixes;
}
bool DumperComponent::HandlesPrefix(const string& prefix) const
{
for ( std::vector<std::string>::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<std::string>::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(")");
}

View file

@ -3,6 +3,8 @@
#ifndef IOSOURCE_PKTSRC_PLUGIN_COMPONENT_H
#define IOSOURCE_PKTSRC_PLUGIN_COMPONENT_H
#include <vector>
#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<std::string>& 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<std::string> 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<std::string>& 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<std::string> prefixes;
factory_callback factory;
};

View file

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

View file

@ -3,9 +3,11 @@
#ifndef IOSOURCE_PKTSRC_PKTSRC_H
#define IOSOURCE_PKTSRC_PKTSRC_H
#include "../IOSource.h"
extern "C" {
#include <pcap.h>
}
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);

View file

@ -1,4 +1,6 @@
#include <assert.h>
#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, &current_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);
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);

View file

@ -3,10 +3,6 @@
#ifndef IOSOURCE_PKTSRC_PCAP_SOURCE_H
#define IOSOURCE_PKTSRC_PCAP_SOURCE_H
extern "C" {
#include <pcap.h>
}
#include "../PktSrc.h"
#include "BPF_Program.h"
#include "Dict.h"