mirror of
https://github.com/zeek/zeek.git
synced 2025-10-17 14:08:20 +00:00
A set of various fixes and smaller API tweaks, plus tests.
Also moving PCAP-related bifs to iosource/pcap.bif.
This commit is contained in:
parent
ce9f16490c
commit
5f817513d0
34 changed files with 395 additions and 164 deletions
|
@ -91,7 +91,8 @@ bool BPF_Program::Compile(pcap_t* pcap, const char* filter, uint32 netmask,
|
|||
}
|
||||
|
||||
bool BPF_Program::Compile(int snaplen, int linktype, const char* filter,
|
||||
uint32 netmask, char* errbuf, bool optimize)
|
||||
uint32 netmask, char* errbuf, unsigned int errbuf_len,
|
||||
bool optimize)
|
||||
{
|
||||
FreeCode();
|
||||
|
||||
|
@ -99,13 +100,18 @@ bool BPF_Program::Compile(int snaplen, int linktype, const char* filter,
|
|||
char my_error[PCAP_ERRBUF_SIZE];
|
||||
|
||||
int err = pcap_compile_nopcap(snaplen, linktype, &m_program,
|
||||
(char *) filter, optimize, netmask, error);
|
||||
(char *) filter, optimize, netmask, my_error);
|
||||
if ( err < 0 && errbuf )
|
||||
safe_strncpy(errbuf, my_errbuf, PCAP_ERRBUF_SIZE);
|
||||
safe_strncpy(errbuf, my_error, errbuf_len);
|
||||
*errbuf = '\0';
|
||||
#else
|
||||
int err = pcap_compile_nopcap(snaplen, linktype, &m_program,
|
||||
(char*) filter, optimize, netmask);
|
||||
|
||||
if ( err < 0 && errbuf && errbuf_len )
|
||||
*errbuf = '\0';
|
||||
#endif
|
||||
|
||||
if ( err == 0 )
|
||||
m_compiled = true;
|
||||
|
||||
|
|
|
@ -30,7 +30,8 @@ public:
|
|||
// similarly to pcap_compile_nopcap(). Parameters are
|
||||
// similar. Returns true on success.
|
||||
bool Compile(int snaplen, int linktype, const char* filter,
|
||||
uint32 netmask, char* errbuf = 0, bool optimize = true);
|
||||
uint32 netmask, char* errbuf = 0, unsigned int errbuf_len = 0,
|
||||
bool optimize = true);
|
||||
|
||||
// Returns true if this program currently contains compiled
|
||||
// code, false otherwise.
|
||||
|
|
|
@ -6,6 +6,8 @@ include_directories(BEFORE
|
|||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
add_subdirectory(pcap)
|
||||
|
||||
set(iosource_SRCS
|
||||
BPF_Program.cc
|
||||
Component.cc
|
||||
|
@ -14,6 +16,8 @@ set(iosource_SRCS
|
|||
PktSrc.cc
|
||||
)
|
||||
|
||||
bif_target(pcap.bif)
|
||||
|
||||
bro_add_subdir_library(iosource ${iosource_SRCS})
|
||||
add_dependencies(bro_iosource generate_outputs)
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace iosource {
|
|||
*/
|
||||
class IOSource {
|
||||
public:
|
||||
IOSource() { idle = closed = false; }
|
||||
IOSource() { idle = false; closed = false; }
|
||||
virtual ~IOSource() {}
|
||||
|
||||
// Returns true if source has nothing ready to process.
|
||||
|
@ -57,7 +57,6 @@ protected:
|
|||
// Derived classed are to set this to true if they have gone dry
|
||||
// temporarily.
|
||||
void SetIdle(bool is_idle) { idle = is_idle; }
|
||||
|
||||
|
||||
// Derived classed are to set this to true if they have gone dry
|
||||
// temporarily.
|
||||
|
|
|
@ -22,11 +22,19 @@ Manager::~Manager()
|
|||
{
|
||||
for ( SourceList::iterator i = sources.begin(); i != sources.end(); ++i )
|
||||
{
|
||||
(*i)->src->Done();
|
||||
// ??? (*i)->src->Done();
|
||||
delete *i;
|
||||
}
|
||||
|
||||
sources.clear();
|
||||
|
||||
for ( PktDumperList::iterator i = pkt_dumpers.begin(); i != pkt_dumpers.end(); ++i )
|
||||
{
|
||||
(*i)->Done();
|
||||
delete *i;
|
||||
}
|
||||
|
||||
pkt_dumpers.clear();
|
||||
}
|
||||
|
||||
void Manager::RemoveAll()
|
||||
|
@ -43,6 +51,7 @@ IOSource* Manager::FindSoonest(double* ts)
|
|||
i != sources.end(); ++i )
|
||||
if ( ! (*i)->src->IsOpen() )
|
||||
{
|
||||
(*i)->src->Done();
|
||||
delete *i;
|
||||
sources.erase(i);
|
||||
break;
|
||||
|
@ -246,15 +255,11 @@ PktSrc* Manager::OpenPktSrc(const std::string& path, const std::string& filter,
|
|||
// Instantiate packet source.
|
||||
|
||||
PktSrc* ps = (*component->Factory())(npath, filter, is_live);
|
||||
assert(ps);
|
||||
|
||||
if ( ! (ps && ps->IsOpen()) )
|
||||
{
|
||||
string type = (is_live ? "interface" : "trace file");
|
||||
string pserr = ps->ErrorMsg() ? (string(" - ") + ps->ErrorMsg()) : "";
|
||||
|
||||
reporter->FatalError("%s: problem with %s %s%s",
|
||||
prog, npath.c_str(), type.c_str(), pserr.c_str());
|
||||
}
|
||||
if ( ! ps->IsOpen() && ps->ErrorMsg() )
|
||||
// Set an error message if it didn't open successfully.
|
||||
ps->Error("could not open");
|
||||
|
||||
DBG_LOG(DBG_PKTIO, "Created packet source of type %s for %s", component->Name().c_str(), npath.c_str());
|
||||
|
||||
|
@ -291,16 +296,16 @@ PktDumper* Manager::OpenPktDumper(const string& path, bool append)
|
|||
// Instantiate packet dumper.
|
||||
|
||||
PktDumper* pd = (*component->Factory())(npath, append);
|
||||
assert(pd);
|
||||
|
||||
if ( ! (pd && pd->IsOpen()) )
|
||||
{
|
||||
string pderr = pd->ErrorMsg().size() ? (string(" - ") + pd->ErrorMsg()) : "";
|
||||
|
||||
reporter->FatalError("%s: can't open write file \"%s\"%s",
|
||||
prog, npath.c_str(), pderr.c_str());
|
||||
}
|
||||
if ( ! pd->IsOpen() && pd->ErrorMsg() )
|
||||
// Set an error message if it didn't open successfully.
|
||||
pd->Error("could not open");
|
||||
|
||||
DBG_LOG(DBG_PKTIO, "Created packer dumper of type %s for %s", component->Name().c_str(), npath.c_str());
|
||||
|
||||
pd->Init();
|
||||
pkt_dumpers.push_back(pd);
|
||||
|
||||
return pd;
|
||||
}
|
||||
|
|
|
@ -64,7 +64,10 @@ protected:
|
|||
typedef std::list<Source*> SourceList;
|
||||
SourceList sources;
|
||||
|
||||
typedef std::list<PktDumper *> PktDumperList;
|
||||
|
||||
PktSrcList pkt_srcs;
|
||||
PktDumperList pkt_dumpers;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,16 @@ PktDumper::~PktDumper()
|
|||
{
|
||||
}
|
||||
|
||||
void PktDumper::Init()
|
||||
{
|
||||
Open();
|
||||
}
|
||||
|
||||
void PktDumper::Done()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
const std::string& PktDumper::Path() const
|
||||
{
|
||||
return props.path;
|
||||
|
@ -40,9 +50,9 @@ bool PktDumper::IsError() const
|
|||
return errmsg.size();
|
||||
}
|
||||
|
||||
const std::string& PktDumper::ErrorMsg() const
|
||||
const char* PktDumper::ErrorMsg() const
|
||||
{
|
||||
return errmsg;
|
||||
return errmsg.size() ? errmsg.c_str() : 0;
|
||||
}
|
||||
|
||||
int PktDumper::HdrSize() const
|
||||
|
@ -60,8 +70,8 @@ void PktDumper::Opened(const Properties& arg_props)
|
|||
void PktDumper::Closed()
|
||||
{
|
||||
is_open = false;
|
||||
props.path = "";
|
||||
DBG_LOG(DBG_PKTIO, "Closed dumper %s", props.path.c_str());
|
||||
props.path = "";
|
||||
}
|
||||
|
||||
void PktDumper::Error(const std::string& msg)
|
||||
|
|
|
@ -21,16 +21,18 @@ public:
|
|||
bool IsOpen() const;
|
||||
double OpenTime() const;
|
||||
bool IsError() const;
|
||||
const std::string& ErrorMsg() const;
|
||||
const char* ErrorMsg() const;
|
||||
int HdrSize() const;
|
||||
bool Record(const Packet* pkt);
|
||||
|
||||
// PktSrc interface for derived classes to implement.
|
||||
// PktDumper interface for derived classes to implement.
|
||||
virtual void Close() = 0;
|
||||
virtual void Open() = 0;
|
||||
virtual bool Dump(const Packet* pkt) = 0;
|
||||
|
||||
protected:
|
||||
friend class Manager;
|
||||
|
||||
// Methods to use by derived classed.
|
||||
//
|
||||
struct Properties {
|
||||
|
@ -39,6 +41,9 @@ protected:
|
|||
double open_time;
|
||||
};
|
||||
|
||||
void Init();
|
||||
void Done();
|
||||
|
||||
void Opened(const Properties& props);
|
||||
void Closed();
|
||||
void Error(const std::string& msg);
|
||||
|
|
|
@ -17,6 +17,7 @@ PktSrc::PktSrc()
|
|||
{
|
||||
have_packet = false;
|
||||
errbuf = "";
|
||||
SetClosed(true);
|
||||
|
||||
next_sync_point = 0;
|
||||
first_timestamp = 0.0;
|
||||
|
@ -195,7 +196,8 @@ void PktSrc::Init()
|
|||
|
||||
void PktSrc::Done()
|
||||
{
|
||||
Close();
|
||||
if ( IsOpen() )
|
||||
Close();
|
||||
}
|
||||
|
||||
void PktSrc::GetFds(int* read, int* write, int* except)
|
||||
|
@ -433,8 +435,13 @@ int PktSrc::PrecompileBPFFilter(int index, const std::string& filter)
|
|||
|
||||
if ( ! code->Compile(SnapLen(), LinkType(), filter.c_str(), Netmask(), errbuf, sizeof(errbuf)) )
|
||||
{
|
||||
Error(fmt("cannot compile BPF filter \"%s\": %s", filter.c_str(), errbuf));
|
||||
Close();
|
||||
string msg = fmt("cannot compile BPF filter \"%s\"", filter.c_str());
|
||||
|
||||
if ( *errbuf )
|
||||
msg += ": " + string(errbuf);
|
||||
|
||||
Error(msg);
|
||||
|
||||
delete code;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -83,6 +83,8 @@ public:
|
|||
static int GetLinkHeaderSize(int link_type);
|
||||
|
||||
protected:
|
||||
friend class Manager;
|
||||
|
||||
// Methods to use by derived classes.
|
||||
|
||||
struct Properties {
|
||||
|
|
104
src/iosource/pcap.bif
Normal file
104
src/iosource/pcap.bif
Normal file
|
@ -0,0 +1,104 @@
|
|||
|
||||
## Precompiles a PCAP filter and binds it to a given identifier.
|
||||
##
|
||||
## id: The PCAP identifier to reference the filter *s* later on.
|
||||
##
|
||||
## s: The PCAP filter. See ``man tcpdump`` for valid expressions.
|
||||
##
|
||||
## Returns: True if *s* is valid and precompiles successfully.
|
||||
##
|
||||
## .. bro:see:: install_pcap_filter
|
||||
## install_src_addr_filter
|
||||
## install_src_net_filter
|
||||
## uninstall_src_addr_filter
|
||||
## uninstall_src_net_filter
|
||||
## install_dst_addr_filter
|
||||
## install_dst_net_filter
|
||||
## uninstall_dst_addr_filter
|
||||
## uninstall_dst_net_filter
|
||||
## pcap_error
|
||||
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;
|
||||
}
|
||||
|
||||
return new Val(success, TYPE_BOOL);
|
||||
%}
|
||||
|
||||
## Installs a PCAP filter that has been precompiled with
|
||||
## :bro:id:`precompile_pcap_filter`.
|
||||
##
|
||||
## id: The PCAP filter id of a precompiled filter.
|
||||
##
|
||||
## Returns: True if the filter associated with *id* has been installed
|
||||
## successfully.
|
||||
##
|
||||
## .. bro:see:: precompile_pcap_filter
|
||||
## install_src_addr_filter
|
||||
## install_src_net_filter
|
||||
## uninstall_src_addr_filter
|
||||
## uninstall_src_net_filter
|
||||
## install_dst_addr_filter
|
||||
## install_dst_net_filter
|
||||
## uninstall_dst_addr_filter
|
||||
## uninstall_dst_net_filter
|
||||
## pcap_error
|
||||
function 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;
|
||||
}
|
||||
|
||||
return new Val(success, TYPE_BOOL);
|
||||
%}
|
||||
|
||||
## Returns a string representation of the last PCAP error.
|
||||
##
|
||||
## Returns: A descriptive error message of the PCAP function that failed.
|
||||
##
|
||||
## .. bro:see:: precompile_pcap_filter
|
||||
## install_pcap_filter
|
||||
## install_src_addr_filter
|
||||
## install_src_net_filter
|
||||
## uninstall_src_addr_filter
|
||||
## uninstall_src_net_filter
|
||||
## install_dst_addr_filter
|
||||
## install_dst_net_filter
|
||||
## uninstall_dst_addr_filter
|
||||
## uninstall_dst_net_filter
|
||||
function pcap_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 = *i;
|
||||
|
||||
const char* err = ps->ErrorMsg();
|
||||
if ( *err )
|
||||
return new StringVal(err);
|
||||
}
|
||||
|
||||
return new StringVal("no error");
|
||||
%}
|
|
@ -5,9 +5,9 @@
|
|||
|
||||
#include "Dumper.h"
|
||||
#include "../PktSrc.h"
|
||||
#include "../../../Net.h"
|
||||
#include "../../Net.h"
|
||||
|
||||
using namespace iosource::pktsrc;
|
||||
using namespace iosource::pcap;
|
||||
|
||||
PcapDumper::PcapDumper(const std::string& path, bool arg_append)
|
||||
{
|
||||
|
|
|
@ -9,7 +9,7 @@ extern "C" {
|
|||
#include "../PktDumper.h"
|
||||
|
||||
namespace iosource {
|
||||
namespace pktsrc {
|
||||
namespace pcap {
|
||||
|
||||
class PcapDumper : public PktDumper {
|
||||
public:
|
||||
|
|
|
@ -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::PktSrcComponent("PcapReader", "pcap", ::iosource::PktSrcComponent::BOTH, ::iosource::pcap::PcapSource::Instantiate));
|
||||
AddComponent(new ::iosource::PktDumperComponent("PcapWriter", "pcap", ::iosource::pcap::PcapDumper::Instantiate));
|
||||
|
||||
plugin::Configuration config;
|
||||
config.name = "Bro::Pcap";
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <pcap-int.h>
|
||||
#endif
|
||||
|
||||
using namespace iosource::pktsrc;
|
||||
using namespace iosource::pcap;
|
||||
|
||||
PcapSource::~PcapSource()
|
||||
{
|
||||
|
@ -182,7 +182,7 @@ void PcapSource::DoneWithPacket(Packet* pkt)
|
|||
|
||||
int PcapSource::PrecompileFilter(int index, const std::string& filter)
|
||||
{
|
||||
return PktSrc::PrecompileBPFFilter(index, filter).
|
||||
return PktSrc::PrecompileBPFFilter(index, filter);
|
||||
}
|
||||
|
||||
int PcapSource::SetFilter(int index)
|
||||
|
@ -192,7 +192,7 @@ int PcapSource::SetFilter(int index)
|
|||
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
|
||||
BPF_Program* code = GetFilter(index);
|
||||
BPF_Program* code = GetBPFFilter(index);
|
||||
|
||||
if ( ! code )
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "../PktSrc.h"
|
||||
|
||||
namespace iosource {
|
||||
namespace pktsrc {
|
||||
namespace pcap {
|
||||
|
||||
class PcapSource : public iosource::PktSrc {
|
||||
public:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue