int daq_config_reads;
const DAQ_Module_t* module;
void *handle;
+ struct
+ {
+ int skip;
+ int trace;
+ void* user;
+ DAQ_Analysis_Func_t orig_daq_packet_callback;
+ } packt_tracer_cfg;
}DAQRegTestContext;
+// packet tracer configuration from command line daq-var skip and trace
+// --daq-var skip=10 --daq-var trace=5 would trace packets 11 through 15 only
+static void daq_regtest_get_vars(DAQRegTestContext* context, const DAQ_Config_t* cfg)
+{
+ DAQ_Dict* entry;
+
+ context->packt_tracer_cfg.skip = 0;
+ context->packt_tracer_cfg.trace = 0;
+ for ( entry = cfg->values; entry; entry = entry->next)
+ {
+ if ( !strcmp(entry->key, "skip") )
+ {
+ context->packt_tracer_cfg.skip = atoi(entry->value);
+ }
+ else if ( !strcmp(entry->key, "trace") )
+ {
+ context->packt_tracer_cfg.trace = atoi(entry->value);
+ }
+ }
+}
+
static int daq_regtest_parse_config(DAQRegTestContext *context, DAQRegTestConfig** new_config, char* errBuf, size_t errMax)
{
long size = 0;
static int daq_regtest_init_context(DAQRegTestContext* context, char* errBuf, size_t errMax)
{
context->debug_fh = NULL;
-
return daq_regtest_parse_config(context, &(context->daq_regtest_cfg), errBuf, errMax);
}
static void daq_regtest_cleanup(DAQRegTestContext* context)
return rval;
}
+ daq_regtest_get_vars(context, cfg);
+
context->module = daq_find_module("dump");
if (!context->module)
}
//-------------------------------------------------------------------------
+static DAQ_Verdict daq_regtest_packet_callback(void* user, const DAQ_PktHdr_t* hdr,
+ const uint8_t* data)
+{
+ DAQRegTestContext* context = (DAQRegTestContext*)user;
+
+ if (context->packt_tracer_cfg.skip == 0 && context->packt_tracer_cfg.trace >0)
+ {
+ DAQ_PktHdr_t* pkthdr = (DAQ_PktHdr_t*)hdr;
+ pkthdr->flags |= DAQ_PKT_FLAG_TRACE_ENABLED;
+ }
+
+ if (context->packt_tracer_cfg.skip > 0)
+ context->packt_tracer_cfg.skip--;
+ else if (context->packt_tracer_cfg.trace > 0)
+ context->packt_tracer_cfg.trace--;
+
+ return context->packt_tracer_cfg.orig_daq_packet_callback(context->packt_tracer_cfg.user,
+ hdr, data);
+}
static int daq_regtest_acquire (
void* handle, int cnt, DAQ_Analysis_Func_t callback, DAQ_Meta_Func_t meta, void* user)
{
DAQRegTestContext* context = (DAQRegTestContext*)handle;
- return context->module->acquire(context->handle, cnt, callback, meta, user);
+ context->packt_tracer_cfg.orig_daq_packet_callback = callback;
+ context->packt_tracer_cfg.user = user;
+ return context->module->acquire(context->handle, cnt, daq_regtest_packet_callback, meta, handle);
}
//-------------------------------------------------------------------------
return context->module->get_device_index(context->handle, device);
}
+static int daq_regtest_modify_flow(void *handle, const DAQ_PktHdr_t *hdr, const DAQ_ModFlow_t *modify)
+{
+ DAQRegTestContext* context = (DAQRegTestContext*)handle;
+
+ if (modify->type == DAQ_MODFLOW_TYPE_PKT_TRACE)
+ {
+ if (modify->length != sizeof(DAQ_ModFlowPktTrace_t))
+ return DAQ_ERROR_INVAL;
+
+ DAQ_ModFlowPktTrace_t* mod_tr = (DAQ_ModFlowPktTrace_t *) modify->value;
+ printf("DAQ_REGTEST_PKT_TRACE (%d)\n%s\n", mod_tr->pkt_trace_data_len,
+ mod_tr->pkt_trace_data);
+ }
+ if (context->module->modify_flow)
+ return context->module->modify_flow(context->handle, hdr, modify);
+ else
+ return DAQ_SUCCESS;
+}
+
static int daq_regtest_set_filter (void* handle, const char* filter)
{
DAQRegTestContext* context = (DAQRegTestContext*)handle;
.get_errbuf = daq_regtest_get_errbuf,
.set_errbuf = daq_regtest_set_errbuf,
.get_device_index = daq_regtest_get_device_index,
- .modify_flow = NULL,
+ .modify_flow = daq_regtest_modify_flow,
.hup_prep = daq_regtest_hup_prep,
.hup_apply = daq_regtest_hup_apply,
.hup_post = daq_regtest_hup_post,
#include <cstdarg>
#include "log.h"
+#include "packet_io/sfdaq.h"
#include "protocols/eth.h"
#include "protocols/ip.h"
#include "protocols/packet.h"
#include "catch/catch.hpp"
#endif
+#define PACKET_TRACER_USER_ENABLED 0x00000001
+#define PACKET_TRACER_DAQ_ENABLED 0x00000002
+
static THREAD_LOCAL PacketTracer* s_pkt_trace = nullptr;
void PacketTracer::thread_init()
}
}
-void PacketTracer::dump(char* output_buff, unsigned int len)
+bool PacketTracer::get_enable(const uint32_t mask)
{
if (!s_pkt_trace)
+ return false;
+ if (mask)
+ return (s_pkt_trace->enable_flags & mask);
+ else
+ return (s_pkt_trace->enable_flags != 0);
+}
+
+void PacketTracer::enable_user_trace()
+{
+ assert(s_pkt_trace);
+ s_pkt_trace->enable_flags |= PACKET_TRACER_USER_ENABLED;
+}
+
+void PacketTracer::enable_daq_trace()
+{
+ assert(s_pkt_trace);
+ s_pkt_trace->enable_flags |= PACKET_TRACER_DAQ_ENABLED;
+}
+
+void PacketTracer::disable_daq_trace()
+{
+ assert(s_pkt_trace);
+ s_pkt_trace->enable_flags &= ~PACKET_TRACER_DAQ_ENABLED;
+}
+
+void PacketTracer::dump(char* output_buff, unsigned int len)
+{
+ if (!get_enable())
return;
+
if (output_buff)
- {
memcpy(output_buff, s_pkt_trace->buffer,
(len < s_pkt_trace->buff_len + 1 ? len : s_pkt_trace->buff_len + 1));
+
+ s_pkt_trace->buff_len = 0;
+ s_pkt_trace->buffer[0] = '\0';
+}
+
+void PacketTracer::dump(const DAQ_PktHdr_t* pkthdr, DAQ_Verdict verdict)
+{
+ if (!get_enable())
+ return;
+
+ if (get_enable(PACKET_TRACER_DAQ_ENABLED))
+ {
+ SFDAQ::get_local_instance()->modify_flow_pkt_trace(pkthdr, verdict,
+ (uint8_t *)s_pkt_trace->buffer, s_pkt_trace->buff_len + 1);
}
- else
+
+ if (get_enable(PACKET_TRACER_USER_ENABLED))
printf("%s\n", s_pkt_trace->buffer);
s_pkt_trace->buff_len = 0;
void PacketTracer::log(const char* format, ...)
{
- if (!s_pkt_trace)
+ if (!get_enable())
return;
va_list ap;
void PacketTracer::add_header_info(Packet* p)
{
- if (!s_pkt_trace)
+ if (!get_enable())
return;
if ( auto eh = layer::get_eth_layer(p) )
{
// MAC layer
- log("%02X:%02X:%02X:%02X:%02X:%02X - ", eh->ether_src[0],
+ log("%02X:%02X:%02X:%02X:%02X:%02X -> ", eh->ether_src[0],
eh->ether_src[1], eh->ether_src[2], eh->ether_src[3],
eh->ether_src[4], eh->ether_src[5]);
log("%02X:%02X:%02X:%02X:%02X:%02X ", eh->ether_dst[0],
p->ptrs.ip_api.get_src()->ntop(sipstr, sizeof(sipstr));
p->ptrs.ip_api.get_dst()->ntop(dipstr, sizeof(dipstr));
- log("%s-%u - %s-%u %u\n",
+ log("%s:%u -> %s:%u proto %u\n",
sipstr, p->ptrs.sp, dipstr, p->ptrs.dp, (unsigned)p->ptrs.ip_api.proto());
log("Packet: %s", p->get_type());
if (p->type() == PktType::TCP)
}
#ifdef UNIT_TEST
-
char* PacketTracer::get_buff()
{
- return this->buffer;
+ return buffer;
}
-int PacketTracer::get_buff_len()
+unsigned int PacketTracer::get_buff_len()
{
- return this->buff_len;
+ return buff_len;
}
#define MAX_PKT_TRACE_BUFF_SIZE 2048
char test_str[] = "1234567890";
// instantiate a packet tracer
PacketTracer::thread_init();
-
+ PacketTracer::enable_user_trace();
// basic logging
PacketTracer::log("%s", test_str);
- CHECK((memcmp(s_pkt_trace->get_buff(), test_str, 10) == 0));
+ CHECK(!(strcmp(s_pkt_trace->get_buff(), test_str)));
CHECK((s_pkt_trace->get_buff_len() == 10));
// continue log will add message to the buffer
PacketTracer::log("%s", "ABCDEFG");
CHECK((strcmp(s_pkt_trace->get_buff(), "1234567890ABCDEFG") == 0));
- CHECK((s_pkt_trace->get_buff_len() == (int)strlen(s_pkt_trace->get_buff())));
+ CHECK((s_pkt_trace->get_buff_len() == strlen(s_pkt_trace->get_buff())));
// log empty string won't change existed buffer
- int curr_len = s_pkt_trace->get_buff_len();
+ unsigned int curr_len = s_pkt_trace->get_buff_len();
char empty_str[] = "";
PacketTracer::log("%s", empty_str);
CHECK((s_pkt_trace->get_buff_len() == curr_len));
{
char test_str[] = "1234567890", empty_str[] = "";
PacketTracer::thread_init();
-
+ PacketTracer::enable_user_trace();
// init length check
CHECK((s_pkt_trace->get_buff_len() == 0));
// logging empty string to start with
char test_str[] = "ABCD", results[] = "ABCD3=400";
PacketTracer::thread_init();
-
+ PacketTracer::enable_user_trace();
PacketTracer::log("%s%d=%d", test_str, 3, 400);
PacketTracer::dump(test_string, MAX_PKT_TRACE_BUFF_SIZE);
CHECK(!strcmp(test_string, results));
PacketTracer::thread_term();
}
+
+TEST_CASE("enable", "[PacketTracer]")
+{
+ PacketTracer::thread_init();
+ // packet tracer is disabled by default
+ CHECK(!PacketTracer::get_enable());
+ // enabled from user
+ PacketTracer::enable_user_trace();
+ CHECK(PacketTracer::get_enable());
+ CHECK(PacketTracer::get_enable(PACKET_TRACER_USER_ENABLED));
+ CHECK(!PacketTracer::get_enable(PACKET_TRACER_DAQ_ENABLED));
+ // enabled from DAQ
+ PacketTracer::enable_daq_trace();
+ CHECK(PacketTracer::get_enable());
+ CHECK(PacketTracer::get_enable(PACKET_TRACER_DAQ_ENABLED));
+ // disable DAQ enable
+ PacketTracer::disable_daq_trace();
+ CHECK(!PacketTracer::get_enable(PACKET_TRACER_DAQ_ENABLED));
+ // user configuration remain enabled
+ CHECK(PacketTracer::get_enable());
+ CHECK(PacketTracer::get_enable(PACKET_TRACER_USER_ENABLED));
+
+ PacketTracer::thread_term();
+}
+
#endif
#ifndef PACKET_TRACER_H
#define PACKET_TRACER_H
+#include <daq_common.h>
+
struct Packet;
class PacketTracer
static void thread_init();
static void thread_term();
static void log(const char* format, ...) __attribute__((format (printf, 1, 2)));
- static void dump(char* output_buff=nullptr, unsigned int len=0);
+ static void dump(char* output_buff, unsigned int len);
+ static void dump(const DAQ_PktHdr_t* pkthdr, DAQ_Verdict verdict);
static void add_header_info(Packet* p);
+ static bool get_enable(const uint32_t mask=0);
+ static void enable_user_trace();
+ static void enable_daq_trace();
+ static void disable_daq_trace();
#ifdef UNIT_TEST
char* get_buff();
- int get_buff_len();
+ unsigned int get_buff_len();
#endif
private:
+ uint32_t enable_flags = 0;
static const int max_buff_size = 2048;
char buffer[max_buff_size];
unsigned int buff_len = 0;
SideChannelManager::thread_init();
HighAvailabilityManager::thread_init(); // must be before InspectorManager::thread_init();
InspectorManager::thread_init(snort_conf);
+ PacketTracer::thread_init();
if (SnortConfig::packet_trace_enabled())
- PacketTracer::thread_init();
+ PacketTracer::enable_user_trace();
// in case there are HA messages waiting, process them first
HighAvailabilityManager::process_receive();
DAQ_Verdict Snort::packet_callback(
void*, const DAQ_PktHdr_t* pkthdr, const uint8_t* pkt)
{
+ if (pkthdr->flags & DAQ_PKT_FLAG_TRACE_ENABLED)
+ PacketTracer::enable_daq_trace();
+ else
+ PacketTracer::disable_daq_trace();
+
set_default_policy();
Profile profile(totalPerfStats);
get_network_policy()->policy_id, get_ips_policy()->policy_id,
SFDAQ::verdict_to_string(verdict));
- PacketTracer::dump();
+ PacketTracer::dump(pkthdr, verdict);
- // FIXIT-H move this to the appropriate struct
- //perfBase->UpdateWireStats(pkthdr->caplen, Active::packet_was_dropped(), inject);
HighAvailabilityManager::process_update(s_packet->flow, pkthdr);
Active::reset();
if (p->flow)
{
AppIdDiscovery::do_application_discovery(p);
- if (SnortConfig::packet_trace_enabled())
+ if (PacketTracer::get_enable())
add_appid_to_packet_trace(p->flow);
}
else
return daq_modify_flow(daq_mod, daq_hand, hdr, &mod);
}
+int SFDAQInstance::modify_flow_pkt_trace(const DAQ_PktHdr_t* hdr, DAQ_Verdict verdict,
+ uint8_t* buff, uint32_t buff_len)
+{
+ DAQ_ModFlow_t mod;
+ DAQ_ModFlowPktTrace_t mod_tr;
+ mod_tr.vreason = (uint8_t)verdict;
+ mod_tr.pkt_trace_data_len = buff_len;
+ mod_tr.pkt_trace_data = buff;
+ mod.type = DAQ_MODFLOW_TYPE_PKT_TRACE;
+ mod.length = sizeof(DAQ_ModFlowPktTrace_t);
+ mod.value = (void*)&mod_tr;
+ return daq_modify_flow(daq_mod, daq_hand, hdr, &mod);
+}
+
// FIXIT-L X Add Snort flag definitions for callers to use and translate/pass them through to
// the DAQ module
int SFDAQInstance::add_expected(const Packet* ctrlPkt, const SfIp* cliIP, uint16_t cliPort,
SO_PUBLIC int query_flow(const DAQ_PktHdr_t*, DAQ_QueryFlow_t*);
int modify_flow_opaque(const DAQ_PktHdr_t*, uint32_t opaque);
+ int modify_flow_pkt_trace(const DAQ_PktHdr_t*, DAQ_Verdict,
+ uint8_t* buff, uint32_t buff_len);
int add_expected(const Packet* ctrlPkt, const SfIp* cliIP, uint16_t cliPort,
const SfIp* srvIP, uint16_t srvPort, IpProtocol, unsigned timeout_ms,
unsigned /* flags */);