]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #979 in SNORT/snort3 from pkt_tracer_p2 to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Tue, 8 Aug 2017 20:01:51 +0000 (16:01 -0400)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Tue, 8 Aug 2017 20:01:51 +0000 (16:01 -0400)
Squashed commit of the following:

commit c171b98fe8535d65293d2ea0694d09cbe6a42c9a
Author: Steven Baigal <sbaigal@cisco.com>
Date:   Thu Jul 27 16:24:39 2017 -0400

    add support of writing packet trace to DAQ

extra/src/daqs/daq_regtest/daq_regtest.c
src/log/packet_tracer.cc
src/log/packet_tracer.h
src/main/snort.cc
src/network_inspectors/appid/appid_inspector.cc
src/packet_io/sfdaq.cc
src/packet_io/sfdaq.h

index 57f9160ebae97032b83fccf25a7f6bb0b3cefe54..637372e46d69a85dbb1e4169f309332d191fa2bc 100644 (file)
@@ -49,8 +49,36 @@ typedef struct
     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;
@@ -102,7 +130,6 @@ static int daq_regtest_parse_config(DAQRegTestContext *context, DAQRegTestConfig
 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)
@@ -171,6 +198,8 @@ static int daq_regtest_initialize (
         return rval;
     }
 
+    daq_regtest_get_vars(context, cfg);
+
     context->module = daq_find_module("dump");
 
     if (!context->module)
@@ -218,12 +247,33 @@ static int daq_regtest_inject (
 }
 
 //-------------------------------------------------------------------------
+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);
 }
 
 //-------------------------------------------------------------------------
@@ -288,6 +338,25 @@ static int daq_regtest_get_device_index(void* handle, const char* device)
     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;
@@ -362,7 +431,7 @@ DAQ_SO_PUBLIC DAQ_Module_t DAQ_MODULE_DATA =
     .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,
index 6680f0dd53f2d9c7a39448f9c80b655532949069..97fea0c6264517949cf918e6c6755fdb5aabf723 100644 (file)
@@ -27,6 +27,7 @@
 #include <cstdarg>
 
 #include "log.h"
+#include "packet_io/sfdaq.h"
 #include "protocols/eth.h"
 #include "protocols/ip.h"
 #include "protocols/packet.h"
@@ -36,6 +37,9 @@
 #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()
@@ -55,16 +59,59 @@ void PacketTracer::thread_term()
     }
 }
 
-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;
@@ -73,7 +120,7 @@ void PacketTracer::dump(char* output_buff, unsigned int len)
 
 void PacketTracer::log(const char* format, ...)
 {
-    if (!s_pkt_trace)
+    if (!get_enable())
         return;
 
     va_list ap;
@@ -96,13 +143,13 @@ void PacketTracer::log(const char* format, ...)
 
 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],
@@ -119,7 +166,7 @@ void PacketTracer::add_header_info(Packet* p)
         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)
@@ -134,15 +181,14 @@ void PacketTracer::add_header_info(Packet* p)
 }
 
 #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
@@ -152,17 +198,17 @@ TEST_CASE("basic log", "[PacketTracer]")
     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));
@@ -174,7 +220,7 @@ TEST_CASE("corner cases", "[PacketTracer]")
 {
     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
@@ -200,7 +246,7 @@ TEST_CASE("dump", "[PacketTracer]")
     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));
@@ -213,4 +259,29 @@ TEST_CASE("dump", "[PacketTracer]")
 
     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
index 25c4d7036bbae15d2e06125512ca628bb4e05115..1a59218654e886de8452152e53b81adb55c6456f 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef PACKET_TRACER_H
 #define PACKET_TRACER_H
 
+#include <daq_common.h>
+
 struct Packet;
 
 class PacketTracer
@@ -29,13 +31,19 @@ public:
     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;
index f1cfb9fb60f5c56e94c1a49681eee3af5637238a..485a07eb26757c980e04df8c91a47c8d50b10777 100644 (file)
@@ -757,8 +757,9 @@ void Snort::thread_init_unprivileged()
     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();
@@ -916,6 +917,11 @@ static DAQ_Verdict update_verdict(DAQ_Verdict verdict, int& inject)
 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);
 
@@ -942,10 +948,8 @@ DAQ_Verdict Snort::packet_callback(
         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();
index 93a09c5bee337a67093362d769efa6b076d69013..22fb6801c19cbe7bff51f963c76dcb13107c285c 100644 (file)
@@ -198,7 +198,7 @@ void AppIdInspector::eval(Packet* p)
     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
index d814e7f4b8b6b8ba93aec97da2683e16f68020d4..6f9956488f0b2221a62f40dd544d545c50b5430e 100644 (file)
@@ -565,6 +565,20 @@ int SFDAQInstance::modify_flow_opaque(const DAQ_PktHdr_t* hdr, uint32_t opaque)
     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,
index 2633e5bd472864d30a4525c174d039d5ae91f3c2..b7a63c113ff10a7425101ecf1e98695e581d86bb 100644 (file)
@@ -64,6 +64,8 @@ public:
 
     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 */);