]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2017 in SNORT/snort3 from ~SUNIMUKH/snort3:drop_servicability...
authorCynthia Leonard (cyleonar) <cyleonar@cisco.com>
Fri, 5 Jun 2020 14:05:18 +0000 (14:05 +0000)
committerCynthia Leonard (cyleonar) <cyleonar@cisco.com>
Fri, 5 Jun 2020 14:05:18 +0000 (14:05 +0000)
Squashed commit of the following:

commit 38e5c894583a168c71633f6fd427a9b349775b01
Author: Sunirmal Mukherjee <sunimukh@cisco.com>
Date:   Fri May 29 05:06:55 2020 -0400

    active: add drop reason and ability to publish mapped drop reason ID to
     the DAQ layer

        Drop/verdict reason handling has been moved from PacketTracer to Active.
        Many modules have been changed to update the drop reason when deciding
        to drop. The Active API has been extended to allow external modules to
        map reason strings to verdict reason IDs to be sent to the DAQ layer.

24 files changed:
src/actions/actions.cc
src/file_api/file_cache.cc
src/file_api/file_lib.cc
src/flow/flow_control.cc
src/flow/test/flow_cache_test.cc
src/flow/test/flow_control_test.cc
src/main/CMakeLists.txt
src/main/analyzer.cc
src/main/test/distill_verdict_test.cc
src/main/test/stubs.h
src/network_inspectors/packet_tracer/packet_tracer.cc
src/network_inspectors/packet_tracer/packet_tracer.h
src/network_inspectors/reputation/reputation_inspect.cc
src/packet_io/active.cc
src/packet_io/active.h
src/packet_io/sfdaq_instance.cc
src/packet_io/sfdaq_instance.h
src/service_inspectors/dce_rpc/dce_smb_utils.cc
src/service_inspectors/ftp_telnet/ftp_data.cc
src/stream/stream.cc
src/stream/tcp/tcp_event_logger.cc
src/stream/tcp/tcp_normalizer.cc
src/stream/tcp/tcp_state_fin_wait2.cc
src/stream/tcp/tcp_state_syn_recv.cc

index 3578908907ef0ef7d483ef596174f90f9e0bece9..2f28c9aea087dc83f21f8a520d06bfe8ef34e514 100644 (file)
@@ -121,12 +121,14 @@ void Actions::execute(Actions::Type action, Packet* p, const OptTreeNode* otn,
 
     case Actions::DROP:
         p->active->drop_packet(p);
+        p->active->set_drop_reason("ips");
         alert(p, otn);
         SetTags(p, otn, event_id);
         break;
 
     case Actions::BLOCK:
         p->active->block_session(p);
+        p->active->set_drop_reason("ips");
         alert(p, otn);
         SetTags(p, otn, event_id);
         break;
index 675472761f1b9103b6b3460d444beaa52096c4ea..a64397b750444ab9e1e4948dac1f1d4bd6f09502 100644 (file)
@@ -274,11 +274,13 @@ bool FileCache::apply_verdict(Packet* p, FileContext* file_ctx, FileVerdict verd
     case FILE_VERDICT_BLOCK:
         // can't block session inside a session
         act->set_delayed_action(Active::ACT_BLOCK, true);
+        act->set_drop_reason("file");
         break;
 
     case FILE_VERDICT_REJECT:
         // can't reset session inside a session
         act->set_delayed_action(Active::ACT_RESET, true);
+        act->set_drop_reason("file");
         break;
     case FILE_VERDICT_STOP_CAPTURE:
         file_ctx->stop_file_capture();
index 4b85144278df46086d2d20f5ef5a752ade0537b3..54ddaefd98fa3291ce3bfb1cc6e421c5e5bd1455 100644 (file)
@@ -349,6 +349,13 @@ void FileContext::finish_signature_lookup(Packet* p, bool final_lookup, FilePoli
             FileCache* file_cache = FileService::get_file_cache();
             if (file_cache)
                 file_cache->apply_verdict(p, this, verdict, false, policy);
+
+            if ( PacketTracer::is_active() and ( verdict == FILE_VERDICT_BLOCK
+                    or verdict == FILE_VERDICT_REJECT ))
+            {
+                PacketTracer::log("File: signature lookup verdict %s\n",
+                    verdict == FILE_VERDICT_BLOCK ? "block" : "reject");
+            }
             log_file_event(flow, policy);
             config_file_signature(false);
             file_stats->signatures_processed[get_file_type()][get_file_direction()]++;
@@ -450,6 +457,13 @@ bool FileContext::process(Packet* p, const uint8_t* file_data, int data_size,
                 FileCache* file_cache = FileService::get_file_cache();
                 if (file_cache)
                     file_cache->apply_verdict(p, this, v, false, policy);
+
+                if ( PacketTracer::is_active() and ( v == FILE_VERDICT_BLOCK
+                        or v == FILE_VERDICT_REJECT ))
+                {
+                    PacketTracer::log("File: file type verdict %s\n",
+                        v == FILE_VERDICT_BLOCK ? "block" : "reject");
+                }
             }
 
             log_file_event(flow, policy);
index 3735a7519480b94bace450b828841d543e49cd82..31bddb9e89821566217ef3e0016bc1c12ee823fa 100644 (file)
@@ -470,7 +470,10 @@ unsigned FlowControl::process(Flow* flow, Packet* p)
         else
             p->active->block_again();
 
+        p->active->set_drop_reason("session");
         DetectionEngine::disable_all(p);
+        if ( PacketTracer::is_active() )
+            PacketTracer::log("Session: session has been blocked, drop\n");
         break;
 
     case Flow::FlowState::RESET:
@@ -480,7 +483,10 @@ unsigned FlowControl::process(Flow* flow, Packet* p)
             p->active->reset_again();
 
         Stream::blocked_flow(p);
+        p->active->set_drop_reason("session");
         DetectionEngine::disable_all(p);
+        if ( PacketTracer::is_active() )
+            PacketTracer::log("Session: session has been reset\n");
         break;
     }
 
index db8f0a1d2347089ffe48f6ab1a41979d12b4075d..7b1005c62888b3c1a103c86b0bcc16de0fd97ea9 100644 (file)
@@ -54,12 +54,12 @@ THREAD_LOCAL bool Active::s_suspend = false;
 THREAD_LOCAL PacketTracer* snort::s_pkt_trace = nullptr;
 
 void Active::drop_packet(snort::Packet const*, bool) { }
-PacketTracer::PacketTracer() { }
 PacketTracer::~PacketTracer() { }
 void PacketTracer::log(const char*, ...) { }
 void PacketTracer::open_file() { }
 void PacketTracer::dump_to_daq(Packet*) { }
 void PacketTracer::reset() { }
+void Active::set_drop_reason(char const*) { }
 Packet::Packet(bool) { }
 Packet::~Packet() { }
 Flow::Flow() { memset(this, 0, sizeof(*this)); }
index da1fc84bbe5d135de12cfe8f4ad3a51d5a68a63f..5cc2d97f2744761c024339a0f55eec76e9a232ec 100644 (file)
@@ -54,12 +54,12 @@ THREAD_LOCAL bool Active::s_suspend = false;
 THREAD_LOCAL PacketTracer* snort::s_pkt_trace = nullptr;
 
 void Active::drop_packet(snort::Packet const*, bool) { }
-PacketTracer::PacketTracer() = default;
 PacketTracer::~PacketTracer() = default;
 void PacketTracer::log(const char*, ...) { }
 void PacketTracer::open_file() { }
 void PacketTracer::dump_to_daq(Packet*) { }
 void PacketTracer::reset() { }
+void Active::set_drop_reason(char const*) { }
 Packet::Packet(bool) { }
 Packet::~Packet() = default;
 FlowCache::FlowCache(const FlowCacheConfig& cfg) : config(cfg) { }
index d1d61cd96f9517c73f64e6bad6f5b181f77ecc57..c5eaed25eb9f9f0563b831e662a88ee7e46fd59c 100644 (file)
@@ -2,6 +2,7 @@
 set (INCLUDES
     analyzer_command.h
     policy.h
+    snort.h
     snort_config.h
     snort_debug.h
     snort_types.h
index 37105a1ece5d2987bb66e4973b2c06c3e7f224ba..dcc89bf67a2ee163382627dce49245dfc4c98ad2 100644 (file)
@@ -392,6 +392,9 @@ void Analyzer::post_process_daq_pkt_msg(Packet* p)
             DataBus::publish(FINALIZE_PACKET_EVENT, event);
         }
 
+        if (verdict == DAQ_VERDICT_BLOCK or verdict == DAQ_VERDICT_BLACKLIST)
+            p->active->send_reason_to_daq(*p);
+        
         p->pkth = nullptr;  // No longer avail after finalize_message.
 
         {
index 3e16dad4933e787b976c3b23b03eefaf09934eed..f4d106df28deb6ae63d3fc56578bce266bd1f056 100644 (file)
@@ -26,6 +26,7 @@
 #include "stubs.h"
 
 #include "main/analyzer.h"
+#include "packet_io/sfdaq_instance.h"
 
 #include <CppUTest/CommandLineTestRunner.h>
 #include <CppUTest/TestHarness.h>
index 75f564d42651ae018ece5a31a2f99a7ec9d58a5b..7c3581a7603faf149ea61e26c65f467c9c6a9f3f 100644 (file)
@@ -152,6 +152,7 @@ bool SFDAQ::forwarding_packet(const DAQ_PktHdr_t*) { return false; }
 int SFDAQ::inject(DAQ_Msg_h, int, const uint8_t*, uint32_t) { return -1; }
 bool SFDAQ::can_inject() { return false; }
 bool SFDAQ::can_inject_raw() { return false; }
+int SFDAQInstance::set_packet_verdict_reason(DAQ_Msg_h, uint8_t) { return 0; }
 DetectionEngine::DetectionEngine() { }
 DetectionEngine::~DetectionEngine() { }
 void DetectionEngine::onload() { }
index a027f90bb49b4556da4b605c90e97b0ba9dab3e3..59e51dc973f64b0ab75faed4030d3cb4dcb52b8c 100644 (file)
@@ -31,6 +31,7 @@
 #include "detection/ips_context.h"
 #include "log/log.h"
 #include "log/messages.h"
+#include "packet_io/active.h"
 #include "packet_io/sfdaq_instance.h"
 #include "protocols/eth.h"
 #include "protocols/icmp4.h"
@@ -49,11 +50,6 @@ using namespace snort;
 // static variables
 // -----------------------------------------------------------------------------
 
-static const uint8_t VERDICT_REASON_NO_BLOCK = 2; /* Not blocking packet; all enum defined after this indicates blocking */
-
-// FIXIT-M currently non-thread-safe accesses being done in packet threads against this
-static std::unordered_map<uint8_t, uint8_t> reasons = { {VERDICT_REASON_NO_BLOCK, PacketTracer::PRIORITY_UNSET} };
-
 // FIXIT-M refactor the way this is used so all methods are members called against this pointer
 THREAD_LOCAL PacketTracer* snort::s_pkt_trace = nullptr;
 
@@ -67,12 +63,6 @@ static bool config_status = false;
 // static functions
 // -----------------------------------------------------------------------------
 
-void PacketTracer::register_verdict_reason(uint8_t reason_code, uint8_t priority)
-{
-    assert(reasons.find(reason_code) == reasons.end());
-    reasons[reason_code] = priority;
-}
-
 void PacketTracer::set_log_file(const std::string& file)
 { log_file = file; }
 
@@ -120,18 +110,18 @@ void PacketTracer::dump(Packet* p)
     if (s_pkt_trace->daq_activated)
         s_pkt_trace->dump_to_daq(p);
 
-    if (s_pkt_trace->user_enabled or s_pkt_trace->shell_enabled)
+    if ((s_pkt_trace->buff_len > 0)
+        and (s_pkt_trace->user_enabled or s_pkt_trace->shell_enabled))
+    {
+        const char* drop_reason = p->active->get_drop_reason();
+        if (drop_reason)
+            PacketTracer::log("Verdict Reason: %s\n", drop_reason);
         LogMessage(s_pkt_trace->log_fh, "%s\n", s_pkt_trace->buffer);
+    }
 
     s_pkt_trace->reset();
 }
 
-void PacketTracer::set_reason(uint8_t reason)
-{
-    if ( reasons[reason] > reasons[s_pkt_trace->reason] )
-        s_pkt_trace->reason = reason;
-}
-
 void PacketTracer::log(const char* format, ...)
 {
     if (is_paused())
@@ -240,10 +230,6 @@ void PacketTracer::activate(const Packet& p)
 // non-static functions
 // -----------------------------------------------------------------------------
 
-// constructor
-PacketTracer::PacketTracer()
-{ reason = VERDICT_REASON_NO_BLOCK; }
-
 // destructor
 PacketTracer::~PacketTracer()
 {
@@ -405,7 +391,7 @@ void PacketTracer::open_file()
 void PacketTracer::dump_to_daq(Packet* p)
 {
     assert(p);
-    p->daq_instance->modify_flow_pkt_trace(p->daq_msg, reason,
+    p->daq_instance->set_packet_trace_data(p->daq_msg, 
         (uint8_t *)buffer, buff_len + 1);
 }
 
@@ -413,12 +399,10 @@ void PacketTracer::reset()
 {
     buff_len = 0;
     buffer[0] = '\0';
-    reason = VERDICT_REASON_NO_BLOCK;
 
     for ( unsigned i = 0; i < mutes.size(); i++ )
         mutes[i] = false;
 }
-
 // --------------------------------------------------------------------------
 // unit tests
 // --------------------------------------------------------------------------
@@ -430,8 +414,6 @@ void PacketTracer::reset()
 class TestPacketTracer : public PacketTracer
 {
 public:
-    uint8_t dump_reason = VERDICT_REASON_NO_BLOCK;
-
     static void thread_init()
     { PacketTracer::_thread_init<TestPacketTracer>(); }
 
@@ -456,14 +438,8 @@ public:
     static bool is_paused()
     { return ((TestPacketTracer*)s_pkt_trace)->pause_count; }
 
-    static uint8_t get_reason()
-    { return ((TestPacketTracer*)s_pkt_trace)->reason; }
-
-    static uint8_t get_dump_reason()
-    { return ((TestPacketTracer*)s_pkt_trace)->dump_reason; }
-
     void dump_to_daq(Packet*) override
-    { dump_reason = reason; }
+    { }
 
     static std::vector<bool> get_mutes()
     { return ((TestPacketTracer*)s_pkt_trace)->mutes; }
@@ -595,42 +571,6 @@ TEST_CASE("pause", "[PacketTracer]")
     TestPacketTracer::thread_term();
 }
 
-TEST_CASE("reasons", "[PacketTracer]")
-{
-    TestPacketTracer::thread_init();
-    TestPacketTracer::set_daq_enable(true);
-    uint8_t low1 = 100, low2 = 101, high = 102;
-    TestPacketTracer::register_verdict_reason(low1, PacketTracer::PRIORITY_LOW);
-    TestPacketTracer::register_verdict_reason(low2, PacketTracer::PRIORITY_LOW);
-    TestPacketTracer::register_verdict_reason(high, PacketTracer::PRIORITY_HIGH);
-
-    // Init
-    CHECK((TestPacketTracer::get_reason() == VERDICT_REASON_NO_BLOCK));
-
-    // Update
-    TestPacketTracer::set_reason(low1);
-    CHECK((TestPacketTracer::get_reason() == low1));
-
-    // Don't update if already set
-    TestPacketTracer::set_reason(VERDICT_REASON_NO_BLOCK);
-    CHECK((TestPacketTracer::get_reason() == low1));
-    TestPacketTracer::set_reason(low2);
-    CHECK((TestPacketTracer::get_reason() == low1));
-
-    // Always update for high priority
-    TestPacketTracer::set_reason(high);
-    CHECK((TestPacketTracer::get_reason() == high));
-
-    // Dump resets reason
-    TestPacketTracer::dump(nullptr);
-    CHECK((TestPacketTracer::get_reason() == VERDICT_REASON_NO_BLOCK));
-
-    // Dump delivers reason to daq
-    CHECK((TestPacketTracer::get_dump_reason() == high));
-
-    TestPacketTracer::thread_term();
-}
-
 TEST_CASE("verbosity", "[PacketTracer]")
 {
     TestPacketTracer::thread_init();
index 16fef4ff40fd0b0f4de5b22b5314d0f879d72443..413cb3514590d1e2316f7d04182fd8c3ebf05fce 100644 (file)
@@ -44,14 +44,7 @@ struct Packet;
 class PacketTracer
 {
 public:
-    enum VerdictPriority : uint8_t
-    {
-        PRIORITY_UNSET = 0,
-        PRIORITY_LOW = 1,
-        PRIORITY_HIGH = 2
-    };
-
-    PacketTracer();
+    PacketTracer() = default;
     virtual ~PacketTracer();
 
     typedef uint8_t TracerMute;
@@ -76,8 +69,6 @@ public:
 
     static SO_PUBLIC TracerMute get_mute();
 
-    static SO_PUBLIC void register_verdict_reason(uint8_t reason_code, uint8_t priority);
-    static SO_PUBLIC void set_reason(uint8_t);
     static SO_PUBLIC void log(const char* format, ...) __attribute__((format (printf, 1, 2)));
     static SO_PUBLIC void log(TracerMute, const char* format, ...) __attribute__((format (printf, 2, 3)));
 
@@ -89,7 +80,6 @@ protected:
     std::vector<bool> mutes;
     char buffer[max_buff_size];
     unsigned buff_len = 0;
-    uint8_t reason;
 
     unsigned pause_count = 0;
     bool user_enabled = false;
index d8f9e31c538846c4d44f959033dcd8ceaf306bb4..3fe290b12992beaaa2989ad5f2266cc50ee94e20 100644 (file)
@@ -37,8 +37,6 @@
 
 #include "reputation_parse.h"
 
-#define VERDICT_REASON_REPUTATION 19
-
 using namespace snort;
 
 THREAD_LOCAL ProfileStats reputation_perf_stats;
@@ -277,12 +275,10 @@ static void snort_reputation(ReputationConfig* config, Packet* p)
         // disable all preproc analysis and detection for this packet
         DetectionEngine::disable_all(p);
         act->block_session(p, true);
+        act->set_drop_reason("reputation");
         reputationstats.blacklisted++;
         if (PacketTracer::is_active())
-        {
-            PacketTracer::set_reason(VERDICT_REASON_REPUTATION);
             PacketTracer::log("Reputation: packet blacklisted, drop\n");
-        }
     }
 
     else if (MONITORED_SRC == decision or MONITORED_DST == decision)
@@ -453,10 +449,6 @@ static Module* mod_ctor()
 static void mod_dtor(Module* m)
 { delete m; }
 
-static void reputation_init()
-{
-    PacketTracer::register_verdict_reason(VERDICT_REASON_REPUTATION, PacketTracer::PRIORITY_LOW);
-}
 
 static Inspector* reputation_ctor(Module* m)
 {
@@ -488,7 +480,7 @@ const InspectApi reputation_api =
     PROTO_BIT__ANY_IP,
     nullptr, // buffers
     nullptr, // service
-    reputation_init, // pinit
+    nullptr, // pinit
     nullptr, // pterm
     nullptr, // tinit
     nullptr, // tterm
index 2b7cfa257b876acd26c2f88b5eabd307ea769935..a98f6d751105e8f5d06aa74a3d13da2bb2660a55 100644 (file)
@@ -79,6 +79,9 @@ static THREAD_LOCAL ip_t* s_ipnet = nullptr;
 static THREAD_LOCAL send_t s_send = SFDAQ::inject;
 
 static ResetAction default_reset;
+static int default_drop_reason_id = -1;
+
+static std::unordered_map<std::string, uint8_t> drop_reason_id_map;
 
 //--------------------------------------------------------------------
 // helpers
@@ -775,6 +778,7 @@ void Active::reset()
     active_action = ACT_ALLOW;
     delayed_active_action = ACT_ALLOW;
     delayed_reject = nullptr;
+    drop_reason = nullptr;
 }
 
 void Active::clear_queue(Packet* p)
@@ -792,3 +796,37 @@ void Active::execute(Packet* p)
     }
 }
 
+void Active::set_default_drop_reason(uint8_t reason_id)
+{
+    default_drop_reason_id = reason_id;
+}
+
+void Active::map_drop_reason_id(const char* verdict_reason, uint8_t id)
+{
+    drop_reason_id_map[verdict_reason] = id;
+}
+
+void Active::set_drop_reason(const char* reason)
+{
+    if ( drop_reason == nullptr )
+        drop_reason = reason;
+}
+
+int Active::get_drop_reason_id()
+{
+    const auto iter = drop_reason_id_map.find(drop_reason);
+    if ( iter != drop_reason_id_map.end() )
+        return iter->second;
+            
+    return default_drop_reason_id;
+}
+
+void Active::send_reason_to_daq(Packet& p)
+{
+    if ( drop_reason == nullptr )
+        return;
+
+    int reason = get_drop_reason_id();
+    if ( reason != -1 )
+        p.daq_instance->set_packet_verdict_reason(p.daq_msg, reason);
+}
index cc8e97e409fb807ca5a5c41a99d1ccda2ae39e4d..5c9ccc7fa2a7112d5810be65b9119387d5f6fedb 100644 (file)
@@ -156,6 +156,14 @@ public:
 
     void reset();
 
+    static void set_default_drop_reason(uint8_t reason_id);
+    static void map_drop_reason_id(const char* verdict_reason, uint8_t id);
+    void set_drop_reason(const char*);
+    void send_reason_to_daq(Packet&);
+
+    const char* get_drop_reason() 
+    { return drop_reason; }
+
 private:
     static bool open(const char*);
     static void close();
@@ -169,6 +177,8 @@ private:
 
     void cant_drop();
 
+    int get_drop_reason_id();
+
 private:
     static const char* act_str[ACT_MAX][AST_MAX];
     static bool enabled;
@@ -176,6 +186,7 @@ private:
     static THREAD_LOCAL bool s_suspend;
 
     int active_tunnel_bypass;
+    const char* drop_reason;
 
     bool prevent_trust_action;
 
index 561dbaac3a7392ec344752d648cdcadad35e7e03..38735fc126e4a69cb7264ec8ee03ef8be2e84398 100644 (file)
@@ -317,12 +317,21 @@ int SFDAQInstance::modify_flow_opaque(DAQ_Msg_h msg, uint32_t opaque)
     return daq_instance_ioctl(instance, DIOCTL_SET_FLOW_OPAQUE, &d_sfo, sizeof(d_sfo));
 }
 
-int SFDAQInstance::modify_flow_pkt_trace(DAQ_Msg_h msg, uint8_t verdict_reason, uint8_t* buff, uint32_t buff_len)
+int SFDAQInstance::set_packet_verdict_reason(DAQ_Msg_h msg, uint8_t verdict_reason)
+{
+    DIOCTL_SetPacketVerdictReason d_spvr;
+
+    d_spvr.msg = msg;
+    d_spvr.verdict_reason = verdict_reason;
+
+    return daq_instance_ioctl(instance, DIOCTL_SET_PACKET_VERDICT_REASON, &d_spvr, sizeof(d_spvr));
+}
+
+int SFDAQInstance::set_packet_trace_data(DAQ_Msg_h msg, uint8_t* buff, uint32_t buff_len)
 {
     DIOCTL_SetPacketTraceData d_sptd;
 
     d_sptd.msg = msg;
-    d_sptd.verdict_reason = verdict_reason;
     d_sptd.trace_data_len = buff_len;
     d_sptd.trace_data = buff;
 
index 19027cbbe7e739a91162d99f2a75b519679aa710..d8b2249fa806ead83be16f7bca78f0f88634d7ed 100644 (file)
@@ -76,8 +76,8 @@ public:
 
     SO_PUBLIC int ioctl(DAQ_IoctlCmd cmd, void *arg, size_t arglen);
     SO_PUBLIC int modify_flow_opaque(DAQ_Msg_h, uint32_t opaque);
-    int modify_flow_pkt_trace(DAQ_Msg_h, uint8_t verdict_reason,
-        uint8_t* buff, uint32_t buff_len);
+    int set_packet_verdict_reason(DAQ_Msg_h msg, uint8_t verdict_reason);
+    int set_packet_trace_data(DAQ_Msg_h, 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 */);
index bcaf0bd5a1939a605bc3408a804a3a89ab465c99..7586b650f2086e35be5657c633df503199b74e79 100644 (file)
@@ -30,6 +30,7 @@
 #include "file_api/file_api.h"
 #include "main/snort.h"
 #include "main/snort_debug.h"
+#include "network_inspectors/packet_tracer/packet_tracer.h"
 #include "packet_io/active.h"
 #include "utils/util.h"
 
@@ -1444,6 +1445,7 @@ static void DCE2_SmbFinishFileBlockVerdict(DCE2_SmbSsnData* ssd)
     if ((verdict == FILE_VERDICT_BLOCK) || (verdict == FILE_VERDICT_REJECT))
     {
         DCE2_SmbInjectDeletePdu(ssd->fb_ftracker);
+        DetectionEngine::get_current_packet()->active->set_drop_reason("smb");
     }
 
     ssd->fb_ftracker = nullptr;
@@ -1475,7 +1477,12 @@ static void DCE2_SmbFinishFileAPI(DCE2_SmbSsnData* ssd)
                     FileVerdict verdict = DCE2_get_file_verdict();
 
                     if ((verdict == FILE_VERDICT_BLOCK) || (verdict == FILE_VERDICT_REJECT))
+                    {
                         ssd->fb_ftracker = ftracker;
+                        if (PacketTracer::is_active())
+                            PacketTracer::log("Dce2_smb: smb file verdict %s\n",
+                                verdict == FILE_VERDICT_BLOCK ? "block" : "reject");
+                    }
                 }
             }
             dce2_smb_stats.smb_files_processed++;
@@ -1558,6 +1565,11 @@ static DCE2_Ret DCE2_SmbFileAPIProcess(DCE2_SmbSsnData* ssd,
                     || (verdict == FILE_VERDICT_PENDING))
                 {
                     ssd->fb_ftracker = ftracker;
+                    if (verdict != FILE_VERDICT_PENDING and PacketTracer::is_active())
+                    {
+                        PacketTracer::log("Dce2_smb: smb file verdict %s\n",
+                            verdict == FILE_VERDICT_BLOCK ? "block" : "reject");
+                    }
                 }
             }
             ftracker->ff_sequential_only = false;
index 45388297ad945d0a32a9b8a4811dc41eb04e204d..a70fa93f127b2e556902c99e104ef005ac438d9d 100644 (file)
@@ -62,6 +62,9 @@ static void FTPDataProcess(
     if (data_ssn->packet_flags & FTPDATA_FLG_REST)
     {
         p->active->block_again();
+        p->active->set_drop_reason("ftp");
+        if (PacketTracer::is_active())
+            PacketTracer::log("FTP: session reset, drop\n");
         return;
     }
 
index 430fd31002e317fd277a1281f740afe9c28c85c5..f9e2284de6c4a6d6978ade8b5fc37224785f5365 100644 (file)
@@ -33,6 +33,7 @@
 #include "main/snort.h"
 #include "main/snort_config.h"
 #include "main/snort_debug.h"
+#include "network_inspectors/packet_tracer/packet_tracer.h"
 #include "packet_io/active.h"
 #include "protocols/vlan.h"
 #include "stream/base/stream_module.h"
@@ -180,7 +181,12 @@ void Stream::check_flow_closed(Packet* p)
         flow->set_state(Flow::FlowState::BLOCK);
 
         if ( !(p->packet_flags & PKT_STATELESS) )
+        {
             drop_traffic(p, SSN_DIR_BOTH);
+            p->active->set_drop_reason("stream");
+            if (PacketTracer::is_active())
+                PacketTracer::log("Stream: pending block, drop\n");
+        }
         flow->session_state &= ~STREAM_STATE_BLOCK_PENDING;
     }
 }
@@ -319,6 +325,10 @@ void Stream::drop_flow(const Packet* p)
 
     if ( !(p->packet_flags & PKT_STATELESS) )
         drop_traffic(p, SSN_DIR_BOTH);
+
+    p->active->set_drop_reason("stream");
+    if (PacketTracer::is_active())
+        PacketTracer::log("Stream: session has been dropped\n");
 }
 
 //-------------------------------------------------------------------------
@@ -600,6 +610,9 @@ bool Stream::blocked_flow(Packet* p)
         DetectionEngine::disable_content(p);
         p->active->drop_packet(p);
         active_response(p, flow);
+        p->active->set_drop_reason("stream");
+        if (PacketTracer::is_active())
+            PacketTracer::log("Stream: session was already blocked\n");
         return true;
     }
     return false;
index bbbab52ccad40c42744101d1e9bd601cf39b7839..fdeb83d7bbab07aea0676d15e47b3c70593588fd 100644 (file)
@@ -29,6 +29,7 @@
 #include "detection/rules.h"
 #include "filters/sfrf.h"
 #include "main/snort_config.h"
+#include "packet_tracer/packet_tracer.h"
 
 #include "tcp_module.h"
 
@@ -38,35 +39,37 @@ struct tcp_event_sid
 {
     uint32_t event_id;
     uint32_t sid;
+    const char* event_description;
 };
 
 // ffs returns 1 as bit position of lsb so event id array
 // has dummy entry for index 0
 struct tcp_event_sid tcp_event_sids[] =
 {
-    { 0, 0 },
-    { EVENT_SYN_ON_EST, STREAM_TCP_SYN_ON_EST },
-    { EVENT_DATA_ON_SYN, STREAM_TCP_DATA_ON_SYN },
-    { EVENT_DATA_ON_CLOSED, STREAM_TCP_DATA_ON_CLOSED },
-    { EVENT_BAD_TIMESTAMP, STREAM_TCP_BAD_TIMESTAMP },
-    { EVENT_WINDOW_TOO_LARGE, STREAM_TCP_WINDOW_TOO_LARGE },
-    { EVENT_DATA_AFTER_RESET, STREAM_TCP_DATA_AFTER_RESET },
-    { EVENT_SESSION_HIJACK_CLIENT, STREAM_TCP_SESSION_HIJACKED_CLIENT },
-    { EVENT_SESSION_HIJACK_SERVER, STREAM_TCP_SESSION_HIJACKED_SERVER },
-    { EVENT_DATA_WITHOUT_FLAGS, STREAM_TCP_DATA_WITHOUT_FLAGS },
-    { EVENT_4WHS, STREAM_TCP_4WAY_HANDSHAKE },
-    { EVENT_NO_TIMESTAMP, STREAM_TCP_NO_TIMESTAMP },
-    { EVENT_BAD_RST, STREAM_TCP_BAD_RST },
-    { EVENT_BAD_FIN, STREAM_TCP_BAD_FIN },
-    { EVENT_BAD_ACK, STREAM_TCP_BAD_ACK },
-    { EVENT_DATA_AFTER_RST_RCVD, STREAM_TCP_DATA_AFTER_RST_RCVD },
-    { EVENT_WINDOW_SLAM, STREAM_TCP_WINDOW_SLAM },
-    { EVENT_NO_3WHS, STREAM_TCP_NO_3WHS },
-    { EVENT_BAD_SEGMENT, STREAM_TCP_BAD_SEGMENT },
-    { EVENT_EXCESSIVE_OVERLAP, STREAM_TCP_EXCESSIVE_TCP_OVERLAPS },
-    { EVENT_MAX_SMALL_SEGS_EXCEEDED, STREAM_TCP_SMALL_SEGMENT },
-    { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
-    { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }
+    { 0, 0, nullptr },
+    { EVENT_SYN_ON_EST, STREAM_TCP_SYN_ON_EST, "SYN_ON_EST" },
+    { EVENT_DATA_ON_SYN, STREAM_TCP_DATA_ON_SYN, "DATA_ON_SYN" },
+    { EVENT_DATA_ON_CLOSED, STREAM_TCP_DATA_ON_CLOSED, "DATA_ON_CLOSED" },
+    { EVENT_BAD_TIMESTAMP, STREAM_TCP_BAD_TIMESTAMP, "BAD_TIMESTAMP" },
+    { EVENT_WINDOW_TOO_LARGE, STREAM_TCP_WINDOW_TOO_LARGE, "WINDOW_TOO_LARGE" },
+    { EVENT_DATA_AFTER_RESET, STREAM_TCP_DATA_AFTER_RESET, "DATA_AFTER_RESET" },
+    { EVENT_SESSION_HIJACK_CLIENT, STREAM_TCP_SESSION_HIJACKED_CLIENT, "SESSION_HIJACK_CLIENT" },
+    { EVENT_SESSION_HIJACK_SERVER, STREAM_TCP_SESSION_HIJACKED_SERVER, "SESSION_HIJACK_SERVER" },
+    { EVENT_DATA_WITHOUT_FLAGS, STREAM_TCP_DATA_WITHOUT_FLAGS, "DATA_WITHOUT_FLAGS" },
+    { EVENT_4WHS, STREAM_TCP_4WAY_HANDSHAKE, "4WHS" },
+    { EVENT_NO_TIMESTAMP, STREAM_TCP_NO_TIMESTAMP, "NO_TIMESTAMP" },
+    { EVENT_BAD_RST, STREAM_TCP_BAD_RST, "BAD_RST" },
+    { EVENT_BAD_FIN, STREAM_TCP_BAD_FIN, "BAD_FIN" },
+    { EVENT_BAD_ACK, STREAM_TCP_BAD_ACK, "BAD_ACK" },
+    { EVENT_DATA_AFTER_RST_RCVD, STREAM_TCP_DATA_AFTER_RST_RCVD, "DATA_AFTER_RST_RCVD" },
+    { EVENT_WINDOW_SLAM, STREAM_TCP_WINDOW_SLAM, "WINDOW_SLAM" },
+    { EVENT_NO_3WHS, STREAM_TCP_NO_3WHS, "NO_3WHS" },
+    { EVENT_BAD_SEGMENT, STREAM_TCP_BAD_SEGMENT, "BAD_SEGMENT" },
+    { EVENT_EXCESSIVE_OVERLAP, STREAM_TCP_EXCESSIVE_TCP_OVERLAPS, "EXCESSIVE_OVERLAP" },
+    { EVENT_MAX_SMALL_SEGS_EXCEEDED, STREAM_TCP_SMALL_SEGMENT, "MAX_SMALL_SEGS_EXCEEDED" },
+    { 0, 0, nullptr }, { 0, 0, nullptr }, { 0, 0, nullptr }, { 0, 0, nullptr },
+    { 0, 0, nullptr }, { 0, 0, nullptr }, { 0, 0, nullptr }, { 0, 0, nullptr },
+    { 0, 0, nullptr }, { 0, 0, nullptr }, { 0, 0, nullptr }, { 0, 0, nullptr }
 };
 
 void TcpEventLogger::log_internal_event(uint32_t eventSid)
@@ -85,8 +88,11 @@ void TcpEventLogger::log_tcp_events()
         uint32_t idx = ffs(tcp_events);
         if ( idx )
         {
-            DetectionEngine::queue_event(GID_STREAM_TCP, tcp_event_sids[ idx ].sid);
-            tcp_events ^= tcp_event_sids[ idx ].event_id;
+            DetectionEngine::queue_event(GID_STREAM_TCP, tcp_event_sids[idx].sid);
+            if ( PacketTracer::is_active() )
+                PacketTracer::log("Stream: TCP normalization error in %s\n",
+                    tcp_event_sids[idx].event_description);
+            tcp_events ^= tcp_event_sids[idx].event_id;
             tcpStats.events++;
         }
     }
index 3c59f85311bfe680919625d70e6b8c5ca0ad6774..961981091b5f76ee24b1be1028c7c36624062d7b 100644 (file)
@@ -30,7 +30,6 @@
 #include "tcp_stream_session.h"
 #include "tcp_stream_tracker.h"
 
-
 using namespace snort;
 
 THREAD_LOCAL PegCount tcp_norm_stats[PC_TCP_MAX][NORM_MODE_MAX];
@@ -102,6 +101,7 @@ bool TcpNormalizer::packet_dropper(
     {
         Packet* p = tsd.get_pkt();
         p->active->drop_packet(p);
+        p->active->set_drop_reason("stream");
         return true;
     }
 
index 3e1f42aeecbbbf5a8752e85f0608b9d5aa8dfa7b..ce70698b465f81ae71a565e0874ec711271ead42 100644 (file)
@@ -66,8 +66,8 @@ bool TcpStateFinWait2::ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk
 {
     if ( SEQ_GT(tsd.get_seg_ack(), trk.get_snd_nxt() ) )
     {
-        trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK);
         trk.session->tel.set_tcp_event(EVENT_BAD_ACK);
+        trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK);
         trk.session->set_pkt_action_flag(ACTION_BAD_PKT);
     }
     else
@@ -88,8 +88,8 @@ bool TcpStateFinWait2::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker
 {
     if ( SEQ_GT(tsd.get_seg_ack(), trk.get_snd_nxt() ) )
     {
-        trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK);
         trk.session->tel.set_tcp_event(EVENT_BAD_ACK);
+        trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK);
         trk.session->set_pkt_action_flag(ACTION_BAD_PKT);
     }
     else
index 0f1806e1c6f4719e90b81849b2baf250e5100290..72356671b0b71ae616e3e25e1510893fa0be116b 100644 (file)
@@ -180,8 +180,8 @@ bool TcpStateSynRecv::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
     else
     {
         inc_tcp_discards();
-        trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK);
         trk.session->tel.set_tcp_event(EVENT_BAD_RST);
+        trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK);
     }
 
     // FIXIT-L might be good to create alert specific to RST with data