mirror of
https://github.com/zeek/zeek.git
synced 2025-10-17 05:58:20 +00:00
Merge branch 'master' of https://github.com/knielander/bro
I reworked this a bit: - Moved the globals into a new Pcap::* namespace, and renamed them slightly. - Moved the definitions of the globals into pcap/const.bif. - Also moved the existing 'snaplen' into Pcap::* and removed SnapLen() from the PktSrc API (it's really a pcap thing). - Likewise moved the existing functions precompile_pcap_filter, install_pcap_filter, and pcap_error, into Pcap::*. - Did some more refactoring for the pcap code. * 'master' of https://github.com/knielander/bro: Refactored patch (removed options, less ambiguous name) Allow Bro to run in fanout mode. Allow libpcap buffer size to be set manually. Allow Bro to run in fanout mode. Allowed libpcap buffer size to be set via configuration.
This commit is contained in:
commit
36b5a4db08
24 changed files with 208 additions and 76 deletions
|
@ -17,8 +17,6 @@ set(iosource_SRCS
|
|||
PktSrc.cc
|
||||
)
|
||||
|
||||
bif_target(pcap.bif)
|
||||
|
||||
bro_add_subdir_library(iosource ${iosource_SRCS})
|
||||
add_dependencies(bro_iosource generate_outputs)
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "Net.h"
|
||||
#include "Sessions.h"
|
||||
|
||||
#include "pcap/const.bif.h"
|
||||
|
||||
using namespace iosource;
|
||||
|
||||
PktSrc::Properties::Properties()
|
||||
|
@ -66,11 +68,6 @@ bool PktSrc::IsError() const
|
|||
return ErrorMsg();
|
||||
}
|
||||
|
||||
int PktSrc::SnapLen() const
|
||||
{
|
||||
return snaplen; // That's a global. Change?
|
||||
}
|
||||
|
||||
bool PktSrc::IsLive() const
|
||||
{
|
||||
return props.is_live;
|
||||
|
@ -112,7 +109,7 @@ void PktSrc::Opened(const Properties& arg_props)
|
|||
}
|
||||
|
||||
if ( props.is_live )
|
||||
Info(fmt("listening on %s, capture length %d bytes\n", props.path.c_str(), SnapLen()));
|
||||
Info(fmt("listening on %s\n", props.path.c_str()));
|
||||
|
||||
DBG_LOG(DBG_PKTIO, "Opened source %s", props.path.c_str());
|
||||
}
|
||||
|
@ -325,7 +322,7 @@ bool PktSrc::PrecompileBPFFilter(int index, const std::string& filter)
|
|||
// Compile filter.
|
||||
BPF_Program* code = new BPF_Program();
|
||||
|
||||
if ( ! code->Compile(SnapLen(), LinkType(), filter.c_str(), Netmask(), errbuf, sizeof(errbuf)) )
|
||||
if ( ! code->Compile(BifConst::Pcap::snaplen, LinkType(), filter.c_str(), Netmask(), errbuf, sizeof(errbuf)) )
|
||||
{
|
||||
string msg = fmt("cannot compile BPF filter \"%s\"", filter.c_str());
|
||||
|
||||
|
|
|
@ -95,11 +95,6 @@ public:
|
|||
*/
|
||||
int HdrSize() const;
|
||||
|
||||
/**
|
||||
* Returns the snap length for this source.
|
||||
*/
|
||||
int SnapLen() const;
|
||||
|
||||
/**
|
||||
* In pseudo-realtime mode, returns the logical timestamp of the
|
||||
* current packet. Undefined if not running pseudo-realtime mode.
|
||||
|
|
|
@ -5,4 +5,6 @@ include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DI
|
|||
|
||||
bro_plugin_begin(Bro Pcap)
|
||||
bro_plugin_cc(Source.cc Dumper.cc Plugin.cc)
|
||||
bif_target(functions.bif)
|
||||
bif_target(const.bif)
|
||||
bro_plugin_end()
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "../PktSrc.h"
|
||||
#include "../../Net.h"
|
||||
|
||||
#include "const.bif.h"
|
||||
|
||||
using namespace iosource::pcap;
|
||||
|
||||
PcapDumper::PcapDumper(const std::string& path, bool arg_append)
|
||||
|
@ -25,7 +27,8 @@ void PcapDumper::Open()
|
|||
{
|
||||
int linktype = -1;
|
||||
|
||||
pd = pcap_open_dead(DLT_EN10MB, snaplen);
|
||||
pd = pcap_open_dead(DLT_EN10MB, BifConst::Pcap::snaplen);
|
||||
|
||||
if ( ! pd )
|
||||
{
|
||||
Error("error for pcap_open_dead");
|
||||
|
|
|
@ -7,10 +7,16 @@
|
|||
#include "Source.h"
|
||||
#include "iosource/Packet.h"
|
||||
|
||||
#include "const.bif.h"
|
||||
|
||||
#ifdef HAVE_PCAP_INT_H
|
||||
#include <pcap-int.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PACKET_FANOUT
|
||||
#include <linux/if_packet.h>
|
||||
#endif
|
||||
|
||||
using namespace iosource::pcap;
|
||||
|
||||
PcapSource::~PcapSource()
|
||||
|
@ -84,32 +90,64 @@ void PcapSource::OpenLive()
|
|||
props.netmask = PktSrc::NETMASK_UNKNOWN;
|
||||
#endif
|
||||
|
||||
// We use the smallest time-out possible to return almost immediately if
|
||||
// no packets are available. (We can't use set_nonblocking() as it's
|
||||
// broken on FreeBSD: even when select() indicates that we can read
|
||||
// something, we may get nothing if the store buffer hasn't filled up
|
||||
// yet.)
|
||||
pd = pcap_open_live(props.path.c_str(), SnapLen(), 1, 1, tmp_errbuf);
|
||||
pd = pcap_create(props.path.c_str(), errbuf);
|
||||
|
||||
if ( ! pd )
|
||||
{
|
||||
Error(tmp_errbuf);
|
||||
PcapError("pcap_create");
|
||||
return;
|
||||
}
|
||||
|
||||
// ### This needs autoconf'ing.
|
||||
#ifdef HAVE_PCAP_INT_H
|
||||
Info(fmt("pcap bufsize = %d\n", ((struct pcap *) pd)->bufsize));
|
||||
#endif
|
||||
if ( pcap_set_snaplen(pd, BifConst::Pcap::snaplen) )
|
||||
{
|
||||
PcapError("pcap_set_snaplen");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pcap_set_promisc(pd, 1) )
|
||||
{
|
||||
PcapError("pcap_set_promisc");
|
||||
return;
|
||||
}
|
||||
|
||||
// We use the smallest time-out possible to return almost immediately
|
||||
// if no packets are available. (We can't use set_nonblocking() as
|
||||
// it's broken on FreeBSD: even when select() indicates that we can
|
||||
// read something, we may get nothing if the store buffer hasn't
|
||||
// filled up yet.)
|
||||
//
|
||||
// TODO: The comment about FreeBSD is pretty old and may not apply
|
||||
// anymore these days.
|
||||
if ( pcap_set_timeout(pd, 1) )
|
||||
{
|
||||
PcapError("pcap_set_timeout");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pcap_set_buffer_size(pd, BifConst::Pcap::bufsize * 1024 * 1024) )
|
||||
{
|
||||
PcapError("pcap_set_buffer_size");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( pcap_activate(pd) )
|
||||
{
|
||||
PcapError("pcap_activate");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LINUX
|
||||
if ( pcap_setnonblock(pd, 1, tmp_errbuf) < 0 )
|
||||
{
|
||||
PcapError();
|
||||
PcapError("pcap_setnonblock");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PCAP_INT_H
|
||||
Info(fmt("pcap bufsize = %d\n", ((struct pcap *) pd)->bufsize));
|
||||
#endif
|
||||
|
||||
props.selectable_fd = pcap_fileno(pd);
|
||||
|
||||
SetHdrSize();
|
||||
|
@ -118,6 +156,24 @@ void PcapSource::OpenLive()
|
|||
// Was closed, couldn't get header size.
|
||||
return;
|
||||
|
||||
#ifdef HAVE_PACKET_FANOUT
|
||||
// Turn on cluster mode for the device.
|
||||
if ( BifConst::Pcap::packet_fanout_enable )
|
||||
{
|
||||
uint32_t packet_fanout_arg = (PACKET_FANOUT_HASH << 16)
|
||||
| (BifConst::Pcap::packet_fanout_id & 0xffff);
|
||||
|
||||
if ( BifConst::Pcap::packet_fanout_defrag )
|
||||
packet_fanout_arg |= (PACKET_FANOUT_FLAG_DEFRAG << 16);
|
||||
|
||||
if ( setsockopt(props.selectable_fd, SOL_PACKET, PACKET_FANOUT, &packet_fanout_arg, sizeof(packet_fanout_arg)) == -1 )
|
||||
{
|
||||
Error(fmt("packet fanout: %s", strerror(errno)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
props.is_live = true;
|
||||
|
||||
Opened(props);
|
||||
|
@ -257,12 +313,17 @@ void PcapSource::Statistics(Stats* s)
|
|||
s->dropped = 0;
|
||||
}
|
||||
|
||||
void PcapSource::PcapError()
|
||||
void PcapSource::PcapError(const char* where)
|
||||
{
|
||||
string location;
|
||||
|
||||
if ( where )
|
||||
location = fmt(" (%s)", where);
|
||||
|
||||
if ( pd )
|
||||
Error(fmt("pcap_error: %s", pcap_geterr(pd)));
|
||||
Error(fmt("pcap_error: %s%s", pcap_geterr(pd), location.c_str()));
|
||||
else
|
||||
Error("pcap_error: not open");
|
||||
Error(fmt("pcap_error: not open%s", location.c_str()));
|
||||
|
||||
Close();
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ protected:
|
|||
private:
|
||||
void OpenLive();
|
||||
void OpenOffline();
|
||||
void PcapError();
|
||||
void PcapError(const char* where = 0);
|
||||
void SetHdrSize();
|
||||
|
||||
Properties props;
|
||||
|
|
9
src/iosource/pcap/const.bif
Normal file
9
src/iosource/pcap/const.bif
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
|
||||
const Pcap::snaplen: count;
|
||||
const Pcap::bufsize: count;
|
||||
|
||||
const Pcap::packet_fanout_enable: bool;
|
||||
const Pcap::packet_fanout_id: count;
|
||||
const Pcap::packet_fanout_defrag: bool;
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
module Pcap;
|
||||
|
||||
## Precompiles a PCAP filter and binds it to a given identifier.
|
||||
##
|
||||
## id: The PCAP identifier to reference the filter *s* later on.
|
||||
|
@ -86,7 +88,7 @@ function install_pcap_filter%(id: PcapFilterID%): bool
|
|||
## install_dst_net_filter
|
||||
## uninstall_dst_addr_filter
|
||||
## uninstall_dst_net_filter
|
||||
function pcap_error%(%): string
|
||||
function error%(%): string
|
||||
%{
|
||||
const iosource::Manager::PktSrcList& pkt_srcs(iosource_mgr->GetPktSrcs());
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue