mirror of
https://github.com/zeek/zeek.git
synced 2025-10-08 17:48:21 +00:00
Prototype of a netmap packet source.
TODO: Add userland BPF filtering so that our filters work.
This commit is contained in:
parent
9a9451af00
commit
462fd68931
6 changed files with 247 additions and 1 deletions
|
@ -35,7 +35,7 @@ const std::string& PktSrc::Path() const
|
|||
|
||||
const char* PktSrc::ErrorMsg() const
|
||||
{
|
||||
return errbuf.c_str();
|
||||
return errbuf.size() ? errbuf.c_str() : 0;
|
||||
}
|
||||
|
||||
int PktSrc::LinkType() const
|
||||
|
|
12
src/iosource/pktsrc/netmap/CMakeLists.txt
Normal file
12
src/iosource/pktsrc/netmap/CMakeLists.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
find_package(Netmap)
|
||||
|
||||
if ( NETMAP_FOUND )
|
||||
include(BroPlugin)
|
||||
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${NETMAP_INCLUDE_DIR}/sys)
|
||||
bro_plugin_begin(Bro Netmap)
|
||||
bro_plugin_cc(Source.cc Plugin.cc)
|
||||
bro_plugin_end()
|
||||
endif ()
|
33
src/iosource/pktsrc/netmap/FindNetmap.cmake
Normal file
33
src/iosource/pktsrc/netmap/FindNetmap.cmake
Normal file
|
@ -0,0 +1,33 @@
|
|||
# - Try to find netmap includes.
|
||||
#
|
||||
#
|
||||
# Variables used by this module, they can change the default behaviour and need
|
||||
# to be set before calling find_package:
|
||||
#
|
||||
# NETMAP_ROOT_DIR Set this variable to the root installation of
|
||||
# netmap if the module has problems finding the
|
||||
# proper installation path.
|
||||
#
|
||||
# Variables defined by this module:
|
||||
#
|
||||
# NETMAP_FOUND System has netmap API files.
|
||||
# NETMAP_INCLUDE_DIR The netmap include directory.
|
||||
|
||||
find_path(NETMAP_ROOT_DIR
|
||||
NAMES sys/net/netmap_user.h
|
||||
)
|
||||
|
||||
find_path(NETMAP_INCLUDE_DIR
|
||||
NAMES sys/net/netmap_user.h
|
||||
HINTS ${NETMAP_ROOT_DIR}
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Netmap DEFAULT_MSG
|
||||
NETMAP_INCLUDE_DIR
|
||||
)
|
||||
|
||||
mark_as_advanced(
|
||||
NETMAP_ROOT_DIR
|
||||
NETMAP_INCLUDE_DIR
|
||||
)
|
26
src/iosource/pktsrc/netmap/Plugin.cc
Normal file
26
src/iosource/pktsrc/netmap/Plugin.cc
Normal file
|
@ -0,0 +1,26 @@
|
|||
// See the file in the main distribution directory for copyright.
|
||||
|
||||
#include "plugin/Plugin.h"
|
||||
|
||||
#include "Source.h"
|
||||
|
||||
namespace plugin {
|
||||
namespace Bro_Netmap {
|
||||
|
||||
class Plugin : public plugin::Plugin {
|
||||
public:
|
||||
plugin::Configuration Configure()
|
||||
{
|
||||
AddComponent(new ::iosource::pktsrc::SourceComponent("NetmapReader", "netmap", ::iosource::pktsrc::SourceComponent::LIVE, ::iosource::pktsrc::NetmapSource::InstantiateNetmap));
|
||||
AddComponent(new ::iosource::pktsrc::SourceComponent("NetmapReader", "vale", ::iosource::pktsrc::SourceComponent::LIVE, ::iosource::pktsrc::NetmapSource::InstantiateVale));
|
||||
|
||||
plugin::Configuration config;
|
||||
config.name = "Bro::Netmap";
|
||||
config.description = "Packet aquisition via netmap";
|
||||
return config;
|
||||
}
|
||||
} plugin;
|
||||
|
||||
}
|
||||
}
|
||||
|
127
src/iosource/pktsrc/netmap/Source.cc
Normal file
127
src/iosource/pktsrc/netmap/Source.cc
Normal file
|
@ -0,0 +1,127 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "Source.h"
|
||||
|
||||
using namespace iosource::pktsrc;
|
||||
|
||||
NetmapSource::~NetmapSource()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
NetmapSource::NetmapSource(const std::string& path, const std::string& filter, bool is_live, const std::string& arg_kind)
|
||||
{
|
||||
if ( ! is_live )
|
||||
Error("netmap source does not support offline input");
|
||||
|
||||
kind = arg_kind;
|
||||
props.path = path;
|
||||
props.filter = filter;
|
||||
last_data = 0;
|
||||
}
|
||||
|
||||
void NetmapSource::Close()
|
||||
{
|
||||
if ( ! nd )
|
||||
return;
|
||||
|
||||
nm_close(nd);
|
||||
nd = 0;
|
||||
last_data = 0;
|
||||
|
||||
Closed();
|
||||
}
|
||||
|
||||
void NetmapSource::Open()
|
||||
{
|
||||
std::string iface = kind + ":" + props.path;
|
||||
nd = nm_open(iface.c_str(), getenv("NETMAP_RING_ID"), 0, 0);
|
||||
|
||||
if ( ! nd )
|
||||
{
|
||||
Error(errno ? strerror(errno) : "invalid interface");
|
||||
return;
|
||||
}
|
||||
|
||||
props.selectable_fd = NETMAP_FD(nd);
|
||||
props.is_live = true;
|
||||
props.link_type = DLT_EN10MB;
|
||||
props.hdr_size = GetLinkHeaderSize(props.link_type);
|
||||
assert(props.hdr_size >= 0);
|
||||
|
||||
Info(fmt("netmap listening on %s\n", props.path.c_str()));
|
||||
|
||||
Opened(props);
|
||||
}
|
||||
|
||||
int NetmapSource::ExtractNextPacket(Packet* pkt)
|
||||
{
|
||||
nm_hdr_t hdr;
|
||||
const u_char* data = nm_nextpkt(nd, &hdr);
|
||||
|
||||
if ( ! data )
|
||||
// Source has gone dry.
|
||||
return 0;
|
||||
|
||||
current_hdr.ts = hdr.ts;
|
||||
current_hdr.caplen = hdr.caplen;
|
||||
current_hdr.len = hdr.len;
|
||||
|
||||
pkt->ts = current_hdr.ts.tv_sec + double(current_hdr.ts.tv_usec) / 1e6;
|
||||
pkt->hdr = ¤t_hdr;
|
||||
pkt->data = last_data = data;
|
||||
|
||||
if ( current_hdr.len == 0 || current_hdr.caplen == 0 )
|
||||
{
|
||||
Weird("empty_netmap_header", pkt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
last_hdr = current_hdr;
|
||||
last_data = data;
|
||||
++stats.received;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void NetmapSource::DoneWithPacket(Packet* pkt)
|
||||
{
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
void NetmapSource::Statistics(Stats* s)
|
||||
{
|
||||
if ( ! nd )
|
||||
{
|
||||
s->received = s->link = s->dropped = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
s->received = stats.received;
|
||||
|
||||
// TODO: Seems these counter's aren't actually set?
|
||||
s->link = nd->st.ps_recv;
|
||||
s->dropped = nd->st.ps_drop + nd->st.ps_ifdrop;
|
||||
}
|
||||
|
||||
bool NetmapSource::GetCurrentPacket(const pcap_pkthdr** hdr, const u_char** pkt)
|
||||
{
|
||||
if ( ! last_data )
|
||||
return false;
|
||||
|
||||
*hdr = &last_hdr;
|
||||
*pkt = last_data;
|
||||
return true;
|
||||
}
|
||||
|
||||
iosource::PktSrc* NetmapSource::InstantiateNetmap(const std::string& path, const std::string& filter, bool is_live)
|
||||
{
|
||||
return new NetmapSource(path, filter, is_live, "netmap");
|
||||
}
|
||||
|
||||
iosource::PktSrc* NetmapSource::InstantiateVale(const std::string& path, const std::string& filter, bool is_live)
|
||||
{
|
||||
return new NetmapSource(path, filter, is_live, "value");
|
||||
}
|
48
src/iosource/pktsrc/netmap/Source.h
Normal file
48
src/iosource/pktsrc/netmap/Source.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#ifndef IOSOURCE_PKTSRC_NETMAP_SOURCE_H
|
||||
#define IOSOURCE_PKTSRC_NETMAP_SOURCE_H
|
||||
|
||||
extern "C" {
|
||||
#define NETMAP_WITH_LIBS
|
||||
#include <net/netmap_user.h>
|
||||
}
|
||||
|
||||
#include "../PktSrc.h"
|
||||
|
||||
namespace iosource {
|
||||
namespace pktsrc {
|
||||
|
||||
class NetmapSource : public iosource::PktSrc {
|
||||
public:
|
||||
// XXX
|
||||
NetmapSource(const std::string& path, const std::string& filter, bool is_live, const std::string& kind);
|
||||
virtual ~NetmapSource();
|
||||
|
||||
static PktSrc* InstantiateNetmap(const std::string& path, const std::string& filter, bool is_live);
|
||||
static PktSrc* InstantiateVale(const std::string& path, const std::string& filter, bool is_live);
|
||||
|
||||
protected:
|
||||
// PktSrc interface.
|
||||
virtual void Open();
|
||||
virtual void Close();
|
||||
virtual int ExtractNextPacket(Packet* pkt);
|
||||
virtual void DoneWithPacket(Packet* pkt);
|
||||
virtual void Statistics(Stats* stats);
|
||||
virtual bool GetCurrentPacket(const pcap_pkthdr** hdr, const u_char** pkt);
|
||||
|
||||
private:
|
||||
std::string kind;
|
||||
Properties props;
|
||||
Stats stats;
|
||||
|
||||
nm_desc_t *nd;
|
||||
pcap_pkthdr current_hdr;
|
||||
pcap_pkthdr last_hdr;
|
||||
const u_char* last_data;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue