Store error message from BPF compilation

This commit is contained in:
Tim Wojtulewicz 2022-08-12 09:13:41 -07:00
parent 767c83ede8
commit 82adecb2ad
8 changed files with 100 additions and 49 deletions

View file

@ -263,25 +263,19 @@ void PcapSource::DoneWithPacket()
// Nothing to do.
}
bool PcapSource::PrecompileFilter(int index, const std::string& filter)
{
return PktSrc::PrecompileBPFFilter(index, filter);
}
detail::BPF_Program* PcapSource::CompileFilter(const std::string& filter)
{
std::string errbuf;
auto code = std::make_unique<detail::BPF_Program>();
if ( ! code->Compile(pd, filter.c_str(), Netmask(), errbuf) )
if ( ! code->Compile(pd, filter.c_str(), Netmask()) )
{
std::string msg = util::fmt("cannot compile BPF filter \"%s\"", filter.c_str());
if ( ! errbuf.empty() )
msg += ": " + errbuf;
std::string state_msg = code->GetStateMessage();
if ( ! state_msg.empty() )
msg += ": " + state_msg;
Error(msg);
return nullptr;
}
return code.release();
@ -310,14 +304,16 @@ bool PcapSource::SetFilter(int index)
// since the default scripts will always attempt to compile
// and install a default filter
}
else
else if ( auto program = code->GetProgram() )
{
if ( pcap_setfilter(pd, code->GetProgram()) < 0 )
if ( pcap_setfilter(pd, program) < 0 )
{
PcapError();
return false;
}
}
else if ( code->GetState() != FilterState::OK )
return false;
#ifndef HAVE_LINUX
// Linux doesn't clear counters when resetting filter.

View file

@ -28,9 +28,9 @@ protected:
void Close() override;
bool ExtractNextPacket(Packet* pkt) override;
void DoneWithPacket() override;
bool PrecompileFilter(int index, const std::string& filter) override;
bool SetFilter(int index) override;
void Statistics(Stats* stats) override;
detail::BPF_Program* CompileFilter(const std::string& filter) override;
private:

View file

@ -8,6 +8,7 @@ const bufsize: count;
%%{
#include <pcap.h>
#include "zeek/iosource/BPF_Program.h"
#include "zeek/iosource/Manager.h"
%%}
@ -44,8 +45,13 @@ function precompile_pcap_filter%(id: PcapFilterID, s: string%): bool
bool success = true;
zeek::iosource::PktSrc* ps = zeek::iosource_mgr->GetPktSrc();
if ( ps && ! ps->PrecompileFilter(id->AsInt(), s->CheckString()) )
success = false;
if ( ps )
{
bool compiled = ps->PrecompileFilter(id->AsInt(), s->CheckString());
auto filter = ps->GetBPFFilter(id->AsInt());
if ( ! compiled || ( filter && filter->GetState() != zeek::iosource::FilterState::OK ) )
success = false;
}
return zeek::val_mgr->Bool(success);
%}
@ -99,7 +105,7 @@ function error%(%): string
if ( ps )
{
const char* err = ps->ErrorMsg();
if ( *err )
if ( err && *err )
return zeek::make_intrusive<zeek::StringVal>(err);
}