]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1646 in SNORT/snort3 from ~MASHASAN/snort3:rna_pub_sub to master
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Tue, 18 Jun 2019 19:14:30 +0000 (15:14 -0400)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Tue, 18 Jun 2019 19:14:30 +0000 (15:14 -0400)
Squashed commit of the following:

commit 02d777186b7b42185154fa7d5d149ee17a2ce59a
Author: Masud Hasan <mashasan@cisco.com>
Date:   Mon Jun 17 14:41:32 2019 -0400

    rna: Renaming peg counts and adding a warning when config changes

commit d0a8a2c0fd70edf12a1e59bbd0b39bb71dffb7d3
Author: Masud Hasan <mashasan@cisco.com>
Date:   Mon Jun 17 04:09:05 2019 -0400

    rna: Implementing event-driven RNA inspections

18 files changed:
src/flow/flow_control.cc
src/flow/flow_control.h
src/framework/data_bus.h
src/main/snort_config.h
src/network_inspectors/rna/CMakeLists.txt
src/network_inspectors/rna/dev_notes.txt
src/network_inspectors/rna/rna_event_handler.cc [new file with mode: 0644]
src/network_inspectors/rna/rna_event_handler.h [new file with mode: 0644]
src/network_inspectors/rna/rna_inspector.cc
src/network_inspectors/rna/rna_inspector.h
src/network_inspectors/rna/rna_module.cc
src/network_inspectors/rna/rna_module.h
src/stream/base/stream_base.cc
src/stream/base/stream_module.cc
src/stream/base/stream_module.h
src/stream/libtcp/tcp_stream_tracker.cc
src/stream/tcp/tcp_state_listen.cc
src/stream/tcp/tcp_state_none.cc

index 42ecce4813519fd82c9fac3d2531eb4018d263a7..29d32098572abd9c17a4c0d504a78184467f9279 100644 (file)
@@ -353,7 +353,7 @@ static bool want_flow(PktType type, Packet* p)
     return false;
 }
 
-bool FlowControl::process(PktType type, Packet* p)
+bool FlowControl::process(PktType type, Packet* p, bool* new_flow)
 {
     auto& con = proto[to_utype(type)];
 
@@ -364,18 +364,24 @@ bool FlowControl::process(PktType type, Packet* p)
     set_key(&key, p);
     Flow* flow = con.cache->find(&key);
     if ( !flow )
+    {
         flow = HighAvailabilityManager::import(*p, key);
 
-    if ( !flow )
-    {
-        if ( !want_flow(type, p) )
-            return true;
+        if ( !flow )
+        {
+            if ( !want_flow(type, p) )
+                return true;
 
-        flow = con.cache->get(&key);
+            flow = con.cache->get(&key);
 
-        if ( !flow )
-            return true;
+            if ( !flow )
+                return true;
+
+            if ( new_flow )
+                *new_flow = true;
+        }
     }
+
     if ( !flow->session )
     {
         flow->init(type);
index 9c3cddd8895ab178fa58c71e755e2f04abedf0ac..4690d801cc527544f692d9e037c8f597d34b5718 100644 (file)
@@ -52,7 +52,7 @@ public:
     ~FlowControl();
 
 public:
-    bool process(PktType, snort::Packet*);
+    bool process(PktType, snort::Packet*, bool* new_flow = nullptr);
 
     snort::Flow* find_flow(const snort::FlowKey*);
     snort::Flow* new_flow(const snort::FlowKey*);
index 44eba7c95d134e13edfd8ad20a5a443acd8c0ad2..fbd2e768c2e4cc61ddba3d6bc979f6f165253e81 100644 (file)
@@ -156,6 +156,16 @@ private:
 // A flow has entered the setup state
 #define FLOW_STATE_SETUP_EVENT "flow.state_setup"
 
+// A new flow is created on this packet
+#define STREAM_ICMP_NEW_FLOW_EVENT "stream.icmp_new_flow"
+#define STREAM_IP_NEW_FLOW_EVENT "stream.ip_new_flow"
+#define STREAM_UDP_NEW_FLOW_EVENT "stream.udp_new_flow"
+
+// A TCP flow has the flag; a midstream flow may not publish other events
+#define STREAM_TCP_SYN_EVENT "stream.tcp_syn"
+#define STREAM_TCP_SYN_ACK_EVENT "stream.tcp_syn_ack"
+#define STREAM_TCP_MIDSTREAM_EVENT "stream.tcp_midstream"
+
 // A new standby flow was generated by stream high availability
 #define STREAM_HA_NEW_FLOW_EVENT "stream.ha.new_flow"
 
index 7cc5225f0b87c2ee3c2f1e7f3d2b3546bd681464..f66584968a60f563b4750bc525f9cd283b64e578 100644 (file)
@@ -73,6 +73,7 @@ enum RunFlag
 #endif
     RUN_FLAG__MEM_CHECK           = 0x02000000,
     RUN_FLAG__TRACK_ON_SYN        = 0x04000000,
+    RUN_FLAG__IP_FRAGS_ONLY       = 0x08000000,
 };
 
 enum OutputFlag
@@ -667,6 +668,12 @@ public:
     bool track_on_syn() const
     { return (run_flags & RUN_FLAG__TRACK_ON_SYN) != 0; }
 
+    bool ip_frags_only() const
+    { return (run_flags & RUN_FLAG__IP_FRAGS_ONLY) != 0; }
+
+    void clear_run_flags(RunFlag flag)
+    { run_flags &= ~flag; }
+
     void set_run_flags(RunFlag flag)
     { run_flags |= flag; }
 
index 788592ffbfdff52c487eef36195f0dabbfe6bb96..440a6c8bf122584d1aab1f83e3ab3d45738f40f0 100644 (file)
@@ -1,5 +1,7 @@
 
 set ( RNA_SOURCES
+    rna_event_handler.cc
+    rna_event_handler.h
     rna_inspector.cc
     rna_inspector.h
     rna_module.cc
@@ -14,4 +16,4 @@ add_library( rna OBJECT
 #   add_dynamic_module(rna inspectors
 #       ${RNA_SOURCES}
 #   )
-#endif (STATIC_INSPECTORS)
\ No newline at end of file
+#endif (STATIC_INSPECTORS)
index 6933d930456070662c2e327799b831d9feb61cca..bd1896d11529964ff33a4a49df6a9d02fc24729c 100644 (file)
@@ -15,3 +15,9 @@ as input so that RNA can analyze traffic.
 
 RNA discoveries will be stored globally in host_tracker objects and to be shared among
 multiple threads. RNA memory and discovery are bounded by the memcap in host_tracker.
+
+Packets from untracked sessions (e.g., non-IP) are processed via the eval method as per
+proto-bit registrations. Packets from tracked sessions (e.g., IP, TCP, UDP, and ICMP)
+are processed via events as per subscriptions. Since RNA needs to see the first packet
+of a session published from stream trackers, these modules (e.g., stream, stream_ip,
+stream_tcp, and stream_udp) should be enabled whenever RNA module is enabled.
diff --git a/src/network_inspectors/rna/rna_event_handler.cc b/src/network_inspectors/rna/rna_event_handler.cc
new file mode 100644 (file)
index 0000000..d1c317a
--- /dev/null
@@ -0,0 +1,69 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2019-2019 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+
+// rna_event_handler.cc author Masud Hasan <mashasan@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "rna_event_handler.h"
+
+using namespace snort;
+
+void RnaIcmpEventHandler::handle(snort::DataEvent&, snort::Flow*)
+{
+    Profile profile(rna_perf_stats);
+
+    ++rna_stats.icmp;
+}
+
+void RnaIpEventHandler::handle(snort::DataEvent&, snort::Flow*)
+{
+    Profile profile(rna_perf_stats);
+
+    ++rna_stats.ip;
+}
+
+void RnaUdpEventHandler::handle(snort::DataEvent&, snort::Flow*)
+{
+    Profile profile(rna_perf_stats);
+
+    ++rna_stats.udp;
+}
+
+void RnaTcpSynEventHandler::handle(snort::DataEvent&, snort::Flow*)
+{
+    Profile profile(rna_perf_stats);
+
+    ++rna_stats.tcp_syn;
+}
+
+void RnaTcpSynAckEventHandler::handle(snort::DataEvent&, snort::Flow*)
+{
+    Profile profile(rna_perf_stats);
+
+    ++rna_stats.tcp_syn_ack;
+}
+
+void RnaTcpMidstreamEventHandler::handle(snort::DataEvent&, snort::Flow*)
+{
+    Profile profile(rna_perf_stats);
+
+    ++rna_stats.tcp_midstream;
+}
diff --git a/src/network_inspectors/rna/rna_event_handler.h b/src/network_inspectors/rna/rna_event_handler.h
new file mode 100644 (file)
index 0000000..8a0f8ef
--- /dev/null
@@ -0,0 +1,70 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2019-2019 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+
+// rna_event_handler.h author Masud Hasan <mashasan@cisco.com>
+
+#ifndef RNA_EVENT_HANDLER_H
+#define RNA_EVENT_HANDLER_H
+
+#include "framework/data_bus.h"
+
+#include "rna_module.h"
+
+class RnaIcmpEventHandler : public snort::DataHandler
+{
+public:
+    RnaIcmpEventHandler() : DataHandler(RNA_NAME) { }
+    void handle(snort::DataEvent&, snort::Flow*) override;
+};
+
+class RnaIpEventHandler : public snort::DataHandler
+{
+public:
+    RnaIpEventHandler() : DataHandler(RNA_NAME) { }
+    void handle(snort::DataEvent&, snort::Flow*) override;
+};
+
+class RnaUdpEventHandler : public snort::DataHandler
+{
+public:
+    RnaUdpEventHandler() : DataHandler(RNA_NAME) { }
+    void handle(snort::DataEvent&, snort::Flow*) override;
+};
+
+class RnaTcpSynEventHandler : public snort::DataHandler
+{
+public:
+    RnaTcpSynEventHandler() : DataHandler(RNA_NAME) { }
+    void handle(snort::DataEvent&, snort::Flow*) override;
+};
+
+class RnaTcpSynAckEventHandler : public snort::DataHandler
+{
+public:
+    RnaTcpSynAckEventHandler() : DataHandler(RNA_NAME) { }
+    void handle(snort::DataEvent&, snort::Flow*) override;
+};
+
+class RnaTcpMidstreamEventHandler : public snort::DataHandler
+{
+public:
+    RnaTcpMidstreamEventHandler() : DataHandler(RNA_NAME) { }
+    void handle(snort::DataEvent&, snort::Flow*) override;
+};
+
+#endif
index 082bd6ad26c6a3b69269b3a9bdb6fd9ab16d8f4f..b3e18e23cc174ff3e63ce4f656b895d82892375d 100644 (file)
 
 #include "log/messages.h"
 #include "managers/inspector_manager.h"
-#include "profiler/profiler.h"
 #include "protocols/packet.h"
 
+#include "rna_event_handler.h"
+
 #ifdef UNIT_TEST
 #include "catch/snort_catch.h"
 #endif
@@ -41,7 +42,7 @@
 using namespace snort;
 using namespace std;
 
-THREAD_LOCAL SimpleStats rna_stats;
+THREAD_LOCAL RnaStats rna_stats;
 THREAD_LOCAL ProfileStats rna_perf_stats;
 
 //-------------------------------------------------------------------------
@@ -61,14 +62,31 @@ RnaInspector::~RnaInspector()
     delete rna_conf;
 }
 
+bool RnaInspector::configure(SnortConfig*)
+{
+    DataBus::subscribe( STREAM_ICMP_NEW_FLOW_EVENT, new RnaIcmpEventHandler() );
+    DataBus::subscribe( STREAM_IP_NEW_FLOW_EVENT, new RnaIpEventHandler() );
+    DataBus::subscribe( STREAM_UDP_NEW_FLOW_EVENT, new RnaUdpEventHandler() );
+    DataBus::subscribe( STREAM_TCP_SYN_EVENT, new RnaTcpSynEventHandler() );
+    DataBus::subscribe( STREAM_TCP_SYN_ACK_EVENT, new RnaTcpSynAckEventHandler() );
+    DataBus::subscribe( STREAM_TCP_MIDSTREAM_EVENT, new RnaTcpMidstreamEventHandler() );
+
+    return true;
+}
+
 void RnaInspector::eval(Packet* p)
 {
     Profile profile(rna_perf_stats);
 
-    if (p->packet_flags & PKT_REBUILT_STREAM)
-        return;
+    // Handling untracked sessions, e.g., non-IP packets
+    assert( !p->flow );
+    assert( !(BIT((unsigned)p->type()) & PROTO_BIT__ANY_SSN) );
 
-    ++rna_stats.total_packets;
+    ++rna_stats.other_packets;
+
+#ifdef NDEBUG
+    UNUSED(p);
+#endif
 }
 
 void RnaInspector::show(SnortConfig*)
@@ -130,7 +148,7 @@ bool RnaInspector::load_rna_conf()
     {
         string line;
         getline(in_stream, line);
-        line_num++;
+        ++line_num;
         if (line.empty() or line.front() == '#')
             continue;
 
@@ -206,7 +224,7 @@ static const InspectApi rna_inspector_api =
         rna_mod_dtor
     },
     IT_CONTROL,
-    PROTO_BIT__ANY_IP,
+    PROTO_BIT__ALL ^ PROTO_BIT__ANY_SSN,
     nullptr, // buffers
     nullptr, // service
     rna_inspector_pinit,
index 88edda724ce8b7b1688690b1a23b196906e43209..41b4e9154bfeaa0adcf3c762c519f54e19d62f1f 100644 (file)
@@ -36,6 +36,7 @@ public:
     RnaInspector(RnaModule*);
     ~RnaInspector() override;
 
+    bool configure(snort::SnortConfig*) override;
     void eval(snort::Packet*) override;
     void show(snort::SnortConfig*) override;
     void tinit() override;
index 23ee648cf9bfa9e9acd55e2993c5bb9ff1c39e6b..1bbf064e92f799f7ca1dc4377c7b7f4ed8df083f 100644 (file)
@@ -27,6 +27,7 @@
 #include <cassert>
 
 #include "log/messages.h"
+#include "main/snort_config.h"
 
 #ifdef UNIT_TEST
 #include "catch/snort_catch.h"
@@ -35,7 +36,7 @@
 using namespace snort;
 
 //-------------------------------------------------------------------------
-// rna params
+// rna params and pegs
 //-------------------------------------------------------------------------
 
 static const Parameter rna_params[] =
@@ -55,6 +56,18 @@ static const Parameter rna_params[] =
     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
 };
 
+static const PegInfo rna_pegs[] =
+{
+    { CountType::SUM, "icmp", "count of ICMP packets received" },
+    { CountType::SUM, "ip", "count of IP packets received" },
+    { CountType::SUM, "udp", "count of UDP packets received" },
+    { CountType::SUM, "tcp_syn", "count of TCP SYN packets received" },
+    { CountType::SUM, "tcp_syn_ack", "count of TCP SYN-ACK packets received" },
+    { CountType::SUM, "tcp_midstream", "count of TCP midstream packets received" },
+    { CountType::SUM, "other_packets", "count of packets received without session tracking" },
+    { CountType::END, nullptr, nullptr},
+};
+
 //-------------------------------------------------------------------------
 // rna module
 //-------------------------------------------------------------------------
@@ -69,7 +82,7 @@ RnaModule::~RnaModule()
 
 bool RnaModule::begin(const char* fqn, int, SnortConfig*)
 {
-    if (strcmp(fqn, "rna"))
+    if (strcmp(fqn, RNA_NAME))
         return false;
     else if (!mod_conf)
         mod_conf = new RnaModuleConfig;
@@ -92,11 +105,19 @@ bool RnaModule::set(const char*, Value& v, SnortConfig*)
     return true;
 }
 
-bool RnaModule::end(const char* fqn, int, SnortConfig*)
+bool RnaModule::end(const char* fqn, int, SnortConfig* sc)
 {
-    if (mod_conf == nullptr and strcmp(fqn, "rna") == 0)
+    if ( mod_conf == nullptr and strcmp(fqn, RNA_NAME) == 0 )
         return false;
 
+    sc->set_run_flags(RUN_FLAG__TRACK_ON_SYN); // Internal flag to track TCP on SYN
+
+    if ( sc->ip_frags_only() )
+    {
+        WarningMessage("RNA: Disabling stream.ip_frags_only option!\n");
+        sc->clear_run_flags(RUN_FLAG__IP_FRAGS_ONLY);
+    }
+
     return true;
 }
 
@@ -111,7 +132,7 @@ PegCount* RnaModule::get_counts() const
 { return (PegCount*)&rna_stats; }
 
 const PegInfo* RnaModule::get_pegs() const
-{ return snort::simple_pegs; }
+{ return rna_pegs; }
 
 ProfileStats* RnaModule::get_profile() const
 { return &rna_perf_stats; }
@@ -122,6 +143,7 @@ TEST_CASE("RNA module", "[rna_module]")
     SECTION("module begin, set, end")
     {
         RnaModule mod;
+        SnortConfig sc;
 
         CHECK_FALSE(mod.begin("dummy", 0, nullptr));
         CHECK(mod.end("rna", 0, nullptr) == false);
@@ -145,7 +167,7 @@ TEST_CASE("RNA module", "[rna_module]")
 
         Value v5("dummy");
         CHECK(mod.set(nullptr, v5, nullptr) == false);
-        CHECK(mod.end("rna", 0, nullptr) == true);
+        CHECK(mod.end("rna", 0, &sc) == true);
 
         RnaModuleConfig* rc = mod.get_config();
         CHECK(rc != nullptr);
@@ -156,5 +178,35 @@ TEST_CASE("RNA module", "[rna_module]")
 
         delete rc;
     }
+
+    SECTION("ip_frags_only is false")
+    {
+        RnaModule mod;
+        SnortConfig sc;
+
+        sc.set_run_flags(RUN_FLAG__IP_FRAGS_ONLY);
+        CHECK(sc.ip_frags_only() == true);
+
+        CHECK(mod.begin(RNA_NAME, 0, nullptr) == true);
+        CHECK(mod.end(RNA_NAME, 0, &sc) == true);
+        CHECK(sc.ip_frags_only() == false);
+
+        delete mod.get_config();
+    }
+
+    SECTION("track_on_syn is true")
+    {
+        RnaModule mod;
+        SnortConfig sc;
+
+        sc.clear_run_flags(RUN_FLAG__TRACK_ON_SYN);
+        CHECK(sc.track_on_syn() == false);
+
+        CHECK(mod.begin(RNA_NAME, 0, nullptr) == true);
+        CHECK(mod.end(RNA_NAME, 0, &sc) == true);
+        CHECK(sc.track_on_syn() == true);
+
+        delete mod.get_config();
+    }
 }
 #endif
index 479d98b95f2f8d63eb09e709ad5c54d408d64302..f5656380e81ac77dcc1356e44cf60baa9a156280 100644 (file)
 #define RNA_MODULE_H
 
 #include "framework/module.h"
+#include "profiler/profiler.h"
 
 #include "rna_config.h"
 
 #define RNA_NAME "rna"
 #define RNA_HELP "Real-time network awareness and OS fingerprinting (experimental)"
 
-extern THREAD_LOCAL SimpleStats rna_stats;
+struct RnaStats
+{
+    PegCount icmp;
+    PegCount ip;
+    PegCount udp;
+    PegCount tcp_syn;
+    PegCount tcp_syn_ack;
+    PegCount tcp_midstream;
+    PegCount other_packets;
+};
+
+extern THREAD_LOCAL RnaStats rna_stats;
 extern THREAD_LOCAL snort::ProfileStats rna_perf_stats;
 
 class RnaModule : public snort::Module
index f8cfe9646084b06a322d0f1473cf4b53e4674aec..837cc2c330e69376493e0ca2c6f4f1ac97bd8cc5 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "flow/flow_control.h"
 #include "flow/prune_stats.h"
+#include "framework/data_bus.h"
 #include "log/messages.h"
 #include "main/snort_config.h"
 #include "main/snort_types.h"
@@ -142,7 +143,6 @@ class StreamBase : public Inspector
 public:
     StreamBase(const StreamModuleConfig*);
 
-    bool configure(SnortConfig*) override;
     void show(SnortConfig*) override;
 
     void tinit() override;
@@ -210,12 +210,6 @@ void StreamBase::tterm()
     FlushBucket::clear();
 }
 
-bool StreamBase::configure(SnortConfig* sc)
-{
-    config.track_on_syn = sc->track_on_syn();
-    return true;
-}
-
 void StreamBase::show(SnortConfig*)
 {
     LogMessage("Stream Base config:\n");
@@ -240,8 +234,14 @@ void StreamBase::eval(Packet* p)
         break;
 
     case PktType::IP:
-        if ( p->has_ip() and ((p->ptrs.decode_flags & DECODE_FRAG) or !config.ip_frags_only) )
-            flow_con->process(PktType::IP, p);
+        if ( p->has_ip() and ((p->ptrs.decode_flags & DECODE_FRAG) or
+            !SnortConfig::get_conf()->ip_frags_only()) )
+        {
+            bool new_flow = false;
+            flow_con->process(PktType::IP, p, &new_flow);
+            if ( new_flow )
+                DataBus::publish(STREAM_IP_NEW_FLOW_EVENT, p);
+        }
         break;
 
     case PktType::TCP:
@@ -254,14 +254,22 @@ void StreamBase::eval(Packet* p)
             flow_con->process(PktType::IP, p);
 
         if ( p->ptrs.udph )
-            flow_con->process(PktType::UDP, p);
+        {
+            bool new_flow = false;
+            flow_con->process(PktType::UDP, p, &new_flow);
+            if ( new_flow )
+                DataBus::publish(STREAM_UDP_NEW_FLOW_EVENT, p);
+        }
         break;
 
     case PktType::ICMP:
         if ( p->ptrs.icmph )
         {
-            if ( !flow_con->process(PktType::ICMP, p) )
-                flow_con->process(PktType::IP, p);
+            bool new_flow = false;
+            if ( !flow_con->process(PktType::ICMP, p, &new_flow) )
+                flow_con->process(PktType::IP, p, &new_flow);
+            if ( new_flow )
+                DataBus::publish(STREAM_ICMP_NEW_FLOW_EVENT, p);
         }
         break;
 
index e3f3a2fdeb2da76feabc0b80dc109ca7d13bb28e..afdcd6d65d3c1e1444337455398aa17e7495249b 100644 (file)
@@ -27,6 +27,7 @@
 #include "detection/rules.h"
 #include "log/messages.h"
 #include "main/snort.h"
+#include "main/snort_config.h"
 #include "main/snort_debug.h"
 
 using namespace snort;
@@ -137,7 +138,8 @@ bool StreamModule::set(const char* fqn, Value& v, SnortConfig* c)
     }
     else if ( v.is("ip_frags_only") )
     {
-        config.ip_frags_only = v.get_bool();
+        if ( v.get_bool() )
+            c->set_run_flags(RUN_FLAG__IP_FRAGS_ONLY);
         return true;
     }
     else if ( strstr(fqn, "ip_cache") )
index bbff1a671c80d2f08883b2e9e52a2e59b5c6a429..1710fe4779da2b406fece741fa5e4e0f741e34c2 100644 (file)
@@ -73,8 +73,6 @@ struct StreamModuleConfig
     FlowConfig file_cfg;
 
     unsigned footprint;
-    bool ip_frags_only;
-    bool track_on_syn;
 };
 
 class StreamModule : public snort::Module
index b58cf98e2fb796a86554e6f34fd19a3beb928050..e784b9776ef097b8be74dbc227cfa393b4a1f3c4 100644 (file)
@@ -105,11 +105,18 @@ TcpStreamTracker::TcpEvent TcpStreamTracker::set_tcp_event(TcpSegmentDescriptor&
         {
             tcp_event = TCP_SYN_RECV_EVENT;
             tcpStats.syns++;
+            if ( tcp_state == TcpStreamTracker::TCP_LISTEN )
+                DataBus::publish(STREAM_TCP_SYN_EVENT, tsd.get_pkt());
         }
         else if ( tcph->is_syn_ack() )
         {
             tcp_event = TCP_SYN_ACK_RECV_EVENT;
             tcpStats.syn_acks++;
+            if ( tcp_state == TcpStreamTracker::TCP_SYN_SENT or
+                (!Stream::is_midstream(tsd.get_flow()) and
+                (tcp_state == TcpStreamTracker::TCP_LISTEN or
+                tcp_state == TcpStreamTracker::TCP_STATE_NONE)) )
+                DataBus::publish(STREAM_TCP_SYN_ACK_EVENT, tsd.get_pkt());
         }
         else if ( tcph->is_rst() )
         {
index c2a4d9d64e7a0502ff26ddd8c2780e476992ece7..8ffc8894783fae4d9632b69f52e1e73c5323bf40 100644 (file)
@@ -144,7 +144,11 @@ bool TcpStateListen::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker&
         Flow* flow = tsd.get_flow();
 
         flow->session_state |= STREAM_STATE_MIDSTREAM;
-        flow->set_session_flags(SSNFLAG_MIDSTREAM);
+        if ( !Stream::is_midstream(flow) )
+        {
+            flow->set_session_flags(SSNFLAG_MIDSTREAM);
+            DataBus::publish(STREAM_TCP_MIDSTREAM_EVENT, tsd.get_pkt());
+        }
 
         trk.init_on_data_seg_sent(tsd);
         trk.session->init_new_tcp_session(tsd);
@@ -167,7 +171,11 @@ bool TcpStateListen::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker&
         Flow* flow = tsd.get_flow();
 
         flow->session_state |= STREAM_STATE_MIDSTREAM;
-        flow->set_session_flags(SSNFLAG_MIDSTREAM);
+        if ( !Stream::is_midstream(flow) )
+        {
+            flow->set_session_flags(SSNFLAG_MIDSTREAM);
+            DataBus::publish(STREAM_TCP_MIDSTREAM_EVENT, tsd.get_pkt());
+        }
         trk.init_on_data_seg_recv(tsd);
         trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs());
         trk.session->handle_data_segment(tsd);
index 8bdef30fe5597825d754f761d128953d6f6d38f7..45e83ea11b8cbfa6700d144dbe50c3177b466a55 100644 (file)
@@ -141,7 +141,11 @@ bool TcpStateNone::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& tr
         Flow* flow = tsd.get_flow();
 
         flow->session_state |= STREAM_STATE_MIDSTREAM;
-        flow->set_session_flags(SSNFLAG_MIDSTREAM);
+        if ( !Stream::is_midstream(flow) )
+        {
+            flow->set_session_flags(SSNFLAG_MIDSTREAM);
+            DataBus::publish(STREAM_TCP_MIDSTREAM_EVENT, tsd.get_pkt());
+        }
 
         trk.init_on_data_seg_sent(tsd);
         trk.session->init_new_tcp_session(tsd);
@@ -164,7 +168,11 @@ bool TcpStateNone::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& tr
         Flow* flow = tsd.get_flow();
 
         flow->session_state |= STREAM_STATE_MIDSTREAM;
-        flow->set_session_flags(SSNFLAG_MIDSTREAM);
+        if ( !Stream::is_midstream(flow) )
+        {
+            flow->set_session_flags(SSNFLAG_MIDSTREAM);
+            DataBus::publish(STREAM_TCP_MIDSTREAM_EVENT, tsd.get_pkt());
+        }
 
         trk.init_on_data_seg_recv(tsd);
         trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs());