]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2278 in SNORT/snort3 from ~SELYSENK/snort3:daq_trace_filtering...
authorBhagya Tholpady (bbantwal) <bbantwal@cisco.com>
Tue, 7 Jul 2020 11:53:55 +0000 (11:53 +0000)
committerBhagya Tholpady (bbantwal) <bbantwal@cisco.com>
Tue, 7 Jul 2020 11:53:55 +0000 (11:53 +0000)
Squashed commit of the following:

commit 4d5212770eeb623de52709d2e915e7a17d0d4aff
Author: Serhii Lysenko <selysenk@cisco.com>
Date:   Wed Jun 17 07:35:46 2020 -0400

    trace: add support for DAQ trace filtering

    Skip constraints check and print trace messages when DAQ sets
    DAQ_PKT_FLAG_DEBUG_ENABLED flag on a packet.

    trace.constraints.match can be set to false to ignore traces for packets
    without DAQ_PKT_FLAG_DEBUG_ENABLED flag.

doc/trace.txt
src/framework/packet_constraints.cc
src/framework/packet_constraints.h
src/trace/dev_notes.txt
src/trace/trace_api.cc
src/trace/trace_module.cc
src/trace/trace_parser.cc
src/trace/trace_parser.h
src/trace/trace_swap.cc

index e5443d59d8fbfc5cd9c2b549b5dad10632236f29..0e6ae9b9688b9246d1f58b90561cf31ac139b3f7 100644 (file)
@@ -112,6 +112,7 @@ Available constraints options:
     src_port - match all packets with a flow that has this source port
     dst_ip - match all packets with a flow that has this server IP address (passed as a string)
     dst_port - match all packets with a flow that has this destination port
+    match - boolean flag to enable/disable whether constraints will ever match (enabled by default)
 
 The following lines placed in snort.lua will enable all trace messages for
 detection filtered by ip_proto, dst_ip, src_port and dst_port:
@@ -131,6 +132,24 @@ detection filtered by ip_proto, dst_ip, src_port and dst_port:
         }
     }
 
+To create constraints that will never successfully match, set the *match*
+parameter to 'false'. This is useful for situations where one is relying on
+external packet filtering from the DAQ module, or for preventing all trace
+messages in the context of a packet. The following is an example of such
+configuration:
+
+    trace =
+    {
+        modules =
+        {
+            snort = { all = 1 }
+        },
+        constraints =
+        {
+            match = false
+        }
+    }
+
 ==== Trace module - configuring trace output method
 
 There is a capability to configure the output method for trace messages.
index 757f60ed7af9db1cb454c439631dc091463736b7..418eb49eb6083abcb44175217e6426fd30ff2013 100644 (file)
@@ -29,8 +29,9 @@
 
 namespace {
 
-inline bool match(const snort::PacketConstraints& cs, const snort::SfIp& sip,
-    const snort::SfIp& dip, uint16_t sport, uint16_t dport)
+inline bool match_constraints(const snort::PacketConstraints& cs,
+    const snort::SfIp& sip, const snort::SfIp& dip, uint16_t sport,
+    uint16_t dport)
 {
     using SetBits = snort::PacketConstraints::SetBits;
 
@@ -56,6 +57,9 @@ bool PacketConstraints::operator==(const PacketConstraints& other) const
 
 bool PacketConstraints::packet_match(const Packet& p) const
 {
+    if ( !match )
+        return false;
+
     if ( !p.has_ip() )
         return false;
 
@@ -67,16 +71,21 @@ bool PacketConstraints::packet_match(const Packet& p) const
     const auto sp = p.ptrs.sp;
     const auto dp = p.ptrs.dp;
 
-    return match(*this, sip, dip, sp, dp) or match(*this, dip, sip, dp, sp);
+    return match_constraints(*this, sip, dip, sp, dp) or
+        match_constraints(*this, dip, sip, dp, sp);
 }
 
 bool PacketConstraints::flow_match(const Flow& f) const
 {
+    if ( !match )
+        return false;
+
     if ( (set_bits & SetBits::IP_PROTO) and
         (IpProtocol(f.ip_proto) != ip_proto) )
         return false;
 
-    return match(*this, f.client_ip, f.server_ip, f.client_port, f.server_port);
+    return match_constraints(*this, f.client_ip, f.server_ip, f.client_port,
+        f.server_port);
 }
 
 #ifdef UNIT_TEST
@@ -109,7 +118,7 @@ TEST_CASE("Packet constraints matching", "[framework]")
         cs.src_ip = sip;
         cs.dst_ip = dip;
 
-        CHECK( match(cs, sip, dip, sport, dport) );
+        CHECK( match_constraints(cs, sip, dip, sport, dport) );
     }
 
     SECTION("backwards")
@@ -126,7 +135,7 @@ TEST_CASE("Packet constraints matching", "[framework]")
         cs.src_ip = sip;
         cs.dst_ip = dip;
 
-        CHECK( !match(cs, dip, sip, dport, sport) );
+        CHECK( !match_constraints(cs, dip, sip, dport, sport) );
     }
 
     SECTION("any ip")
@@ -139,7 +148,7 @@ TEST_CASE("Packet constraints matching", "[framework]")
         cs.src_port = sport;
         cs.dst_port = dport;
 
-        CHECK( match(cs, sip, dip, sport, dport) );
+        CHECK( match_constraints(cs, sip, dip, sport, dport) );
     }
 
     SECTION("any port")
@@ -152,7 +161,7 @@ TEST_CASE("Packet constraints matching", "[framework]")
         cs.src_ip = sip;
         cs.dst_ip = dip;
 
-        CHECK( match(cs, sip, dip, sport, dport) );
+        CHECK( match_constraints(cs, sip, dip, sport, dport) );
     }
 
     SECTION("any src")
@@ -165,9 +174,8 @@ TEST_CASE("Packet constraints matching", "[framework]")
         cs.dst_port = dport;
         cs.dst_ip = dip;
 
-        CHECK( match(cs, sip, dip, sport, dport) );
+        CHECK( match_constraints(cs, sip, dip, sport, dport) );
     }
-
 }
 
 #endif
index e25073b13056b7eb8f6271033477e6927b221f4b..08b16a37ddd0297cce485a8b7df369df98f274d8 100644 (file)
@@ -51,6 +51,8 @@ struct PacketConstraints
     snort::SfIp dst_ip;
 
     uint8_t set_bits = 0;
+
+    bool match = true;
 };
 
 } // namespace snort
index 97d9ffcb2544a284c9ee911694ac4275249b0355..4138096d6526025a1d473c188a1ae48459046a68 100644 (file)
@@ -87,3 +87,10 @@ This directory contains the trace logger framework.
     To create specific TraceLogger/TraceLoggerFactory pair just inherit base classes placed
     into "trace_log_base.h" and init TraceConfig with a new factory during configuration.
 
+* Disabling packet constraints matching
+
+    Constraints matching can be disabled by setting "trace.constraints.match = false" during
+    configuration. This is effectively saying all packets don't pass the trace filter. It may be
+    useful in case of using external packet filtering, such as filtering by the DAQ, or to block
+    printing for all trace messages in the context of a packet.
+
index 4cc2b8e1cf0b1f230357a457660f92a164ce22a8..4a8da6d0368fe348c2134a9b05732500d2753bfe 100644 (file)
@@ -82,14 +82,20 @@ void TraceApi::log(const char* log_msg, const char* name,
 
 void TraceApi::filter(const Packet& p)
 {
-    if ( !g_packet_constraints )
+
+    if ( p.pkth->flags & DAQ_PKT_FLAG_DEBUG_ENABLED )
         p.filtering_state.set_matched(g_constraints_generation, true);
     else
     {
-        const bool matched = p.flow
+        bool matched;
+        if ( !g_packet_constraints )
+            matched = true;
+        else
+        {
+            matched = p.flow
             ? g_packet_constraints->flow_match(*p.flow)
             : g_packet_constraints->packet_match(p);
-
+        }
         p.filtering_state.set_matched(g_constraints_generation, matched);
     }
 
index 0966b91e47d29f643a9cef181cdeff1e918d2af0..abe6feb38ba292090ca2bd1ea93cfe8a28703f5d 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <syslog.h>
 
+#include "framework/packet_constraints.h"
 #include "main/snort_config.h"
 #include "managers/module_manager.h"
 
@@ -102,6 +103,9 @@ void TraceModule::generate_params()
         { "dst_port", Parameter::PT_INT, "0:65535", nullptr,
           "destination port filter" },
 
+        { "match", Parameter::PT_BOOL, nullptr, "true",
+          "use constraints to filter traces" },
+
         { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
     };
 
@@ -191,6 +195,8 @@ bool TraceModule::end(const char* fqn, int, SnortConfig* sc)
             openlog("snort", LOG_PID | LOG_CONS, LOG_DAEMON);
         }
 
+        trace_parser->finalize_constraints();
+
         delete trace_parser;
         trace_parser = nullptr;
     }
index 696ecd43ceae7571ab900e30e596848d590679d1..8d7593f3a826667c2068e430874f6a1af6bf81bb 100644 (file)
@@ -24,7 +24,6 @@
 #include "trace_parser.h"
 
 #include "framework/module.h"
-#include "framework/packet_constraints.h"
 #include "managers/module_manager.h"
 
 #include "trace_config.h"
@@ -71,48 +70,51 @@ bool TraceParser::set_traces(const std::string& module_name, const Value& val)
 
 bool TraceParser::set_constraints(const Value& val)
 {
-    if ( !trace_config->constraints )
-        trace_config->constraints = new PacketConstraints;
-
-    auto& cs = *trace_config->constraints;
-
     if ( val.is("ip_proto") )
     {
-        cs.ip_proto = static_cast<IpProtocol>(val.get_uint8());
-        cs.set_bits |= PacketConstraints::SetBits::IP_PROTO;
+        parsed_constraints.ip_proto = static_cast<IpProtocol>(val.get_uint8());
+        parsed_constraints.set_bits |= PacketConstraints::SetBits::IP_PROTO;
     }
     else if ( val.is("src_port") )
     {
-        cs.src_port = val.get_uint16();
-        cs.set_bits |= PacketConstraints::SetBits::SRC_PORT;
+        parsed_constraints.src_port = val.get_uint16();
+        parsed_constraints.set_bits |= PacketConstraints::SetBits::SRC_PORT;
     }
     else if ( val.is("dst_port") )
     {
-        cs.dst_port = val.get_uint16();
-        cs.set_bits |= PacketConstraints::SetBits::DST_PORT;
+        parsed_constraints.dst_port = val.get_uint16();
+        parsed_constraints.set_bits |= PacketConstraints::SetBits::DST_PORT;
     }
     else if ( val.is("src_ip") )
     {
         const char* str = val.get_string();
-        if ( cs.src_ip.set(str) != SFIP_SUCCESS )
+        if ( parsed_constraints.src_ip.set(str) != SFIP_SUCCESS )
             return false;
 
-        cs.set_bits |= PacketConstraints::SetBits::SRC_IP;
+        parsed_constraints.set_bits |= PacketConstraints::SetBits::SRC_IP;
     }
     else if ( val.is("dst_ip") )
     {
         const char* str = val.get_string();
-        if ( cs.dst_ip.set(str) != SFIP_SUCCESS )
+        if ( parsed_constraints.dst_ip.set(str) != SFIP_SUCCESS )
             return false;
 
-        cs.set_bits |= PacketConstraints::SetBits::DST_IP;
+        parsed_constraints.set_bits |= PacketConstraints::SetBits::DST_IP;
     }
+    else if ( val.is("match") )
+        parsed_constraints.match = val.get_bool();
     else
         return false;
 
     return true;
 }
 
+void TraceParser::finalize_constraints()
+{
+    if ( !parsed_constraints.match or parsed_constraints.set_bits )
+        trace_config->constraints = new PacketConstraints(parsed_constraints);
+}
+
 void TraceParser::clear_traces()
 { trace_config->clear_traces(); }
 
index e9a26a9f780496f3eec85a0f231d66254f482d41..f96a5c1d5807b401e6061ddcce5247114cd98335 100644 (file)
@@ -23,6 +23,8 @@
 #include <map>
 #include <string>
 
+#include "framework/packet_constraints.h"
+
 namespace snort
 {
 class Module;
@@ -39,6 +41,7 @@ public:
     bool set_traces(const std::string& module_name, const snort::Value& val);
     bool set_constraints(const snort::Value& val);
 
+    void finalize_constraints();
     void clear_traces();
     void clear_constraints();
 
@@ -52,6 +55,7 @@ private:
 
 private:
     TraceConfig* trace_config = nullptr;
+    snort::PacketConstraints parsed_constraints;
     static std::map<std::string, std::map<std::string, bool>> s_configured_trace_options;
 };
 
index bc2eb778a80bf07b240c44700224dd726930501c..cc9341485a056189be4a3f8ffefefb207cd30e62 100644 (file)
@@ -26,6 +26,7 @@
 #include <lua.hpp>
 
 #include "framework/module.h"
+#include "framework/packet_constraints.h"
 #include "log/messages.h"
 #include "main/analyzer_command.h"
 #include "main/snort_config.h"
@@ -162,24 +163,24 @@ static int set(lua_State* L)
     lua_pushnil(L);
     while ( lua_next(L, 1) )
     {
-        const char* root_tbl_name = luaL_checkstring(L, -2);
-        const Parameter* root_tbl_param = Parameter::find(params_tree, root_tbl_name);
+        const char* root_element_key = luaL_checkstring(L, -2);
+        const Parameter* root_parameter = Parameter::find(params_tree, root_element_key);
 
-        if ( !lua_istable(L, -1) or !root_tbl_param )
+        if ( !lua_istable(L, -1) or !root_parameter )
         {
-            LogMessage("== invalid table is provided: %s\n", root_tbl_name);
+            LogMessage("== invalid table is provided: %s\n", root_element_key);
             parse_err = true;
             lua_pop(L, 1);
             continue;
         }
 
         // "modules" table traversal
-        if ( !strcmp(root_tbl_name, params_tree[0].name) )
+        else if ( !strcmp(root_element_key, params_tree[0].name) )
         {
             set_traces = true;
             trace_parser.clear_traces();
 
-            const Parameter* modules_param = (const Parameter*)root_tbl_param->range;
+            const Parameter* modules_param = (const Parameter*)root_parameter->range;
 
             int modules_tbl_idx = lua_gettop(L);
             lua_pushnil(L);
@@ -190,7 +191,7 @@ static int set(lua_State* L)
 
                 if ( !lua_istable(L, -1) or !module_param )
                 {
-                    LogMessage("== invalid table is provided: %s.%s\n", root_tbl_name,
+                    LogMessage("== invalid table is provided: %s.%s\n", root_element_key,
                         module_name);
 
                     parse_err = true;
@@ -219,7 +220,7 @@ static int set(lua_State* L)
                          !trace_parser.set_traces(module_name, val) )
                     {
                         LogMessage("== invalid trace value is provided: %s.%s.%s = %s\n",
-                            root_tbl_name, module_name, val_name, val.get_as_string());
+                            root_element_key, module_name, val_name, val.get_as_string());
 
                         parse_err = true;
                     }
@@ -231,12 +232,12 @@ static int set(lua_State* L)
             }
         }
         // "constraints" table traversal
-        else if ( !strcmp(root_tbl_name, params_tree[1].name) )
+        else if ( !strcmp(root_element_key, params_tree[1].name) )
         {
             set_constraints = true;
             trace_parser.clear_constraints();
 
-            const Parameter* constraints_param = (const Parameter*)root_tbl_param->range;
+            const Parameter* constraints_param = (const Parameter*)root_parameter->range;
 
             int constraints_tbl_idx = lua_gettop(L);
             lua_pushnil(L);
@@ -249,6 +250,8 @@ static int set(lua_State* L)
 
                 if ( lua_isnumber(L, -1) )
                     val.set((double)lua_tointeger(L, -1));
+                else if ( lua_isboolean(L, -1) )
+                    val.set(bool(lua_toboolean(L, -1)));
                 else
                     val.set(luaL_checkstring(L, -1));
 
@@ -256,7 +259,7 @@ static int set(lua_State* L)
                      !trace_parser.set_constraints(val) )
                 {
                     LogMessage("== invalid constraints value is provided: %s.%s = %s\n",
-                        root_tbl_name, val_name, val.get_as_string());
+                        root_element_key, val_name, val.get_as_string());
 
                     parse_err = true;
                 }
@@ -276,6 +279,9 @@ static int set(lua_State* L)
             trace_parser.clear_constraints();
         }
 
+        if ( set_constraints )
+            trace_parser.finalize_constraints();
+
         main_broadcast_command(new TraceSwap(
             trace_parser.get_trace_config(), set_traces, set_constraints),
             true);
@@ -290,7 +296,7 @@ static int clear(lua_State*)
 {
     // Create an empty overlay TraceConfig
     // It will be set in a SnortConfig during TraceSwap execution and owned by it after
-    main_broadcast_command(new TraceSwap(new TraceConfig()), true);
+    main_broadcast_command(new TraceSwap(new TraceConfig), true);
     return 0;
 }