]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2477 in SNORT/snort3 from ~OKHOMIAK/snort3:update_s5_trace to...
authorBhagya Tholpady (bbantwal) <bbantwal@cisco.com>
Fri, 25 Sep 2020 17:37:39 +0000 (17:37 +0000)
committerBhagya Tholpady (bbantwal) <bbantwal@cisco.com>
Fri, 25 Sep 2020 17:37:39 +0000 (17:37 +0000)
Squashed commit of the following:

commit ec9f6a8e1b7deb16e663fac1c5f38c085f06136d
Author: Oleksii Khomiakovskyi <okhomiak@cisco.com>
Date:   Tue Sep 8 12:34:45 2020 +0300

    stream_tcp: update trace messages to use trace framework

src/stream/tcp/CMakeLists.txt
src/stream/tcp/tcp_module.cc
src/stream/tcp/tcp_module.h
src/stream/tcp/tcp_reassembler.cc
src/stream/tcp/tcp_reassembler.h
src/stream/tcp/tcp_reassemblers.h
src/stream/tcp/tcp_session.cc
src/stream/tcp/tcp_session.h
src/stream/tcp/tcp_stream_tracker.h
src/stream/tcp/tcp_trace.cc [moved from src/stream/tcp/tcp_debug_trace.h with 53% similarity]
src/stream/tcp/tcp_trace.h [new file with mode: 0644]

index 09f8e1dd3ac1a7b7499244afbde22d20876104aa..0380349e6ccc03fdd236eb5d9535c2bc1fa8602a 100644 (file)
@@ -66,6 +66,8 @@ add_library( stream_tcp OBJECT
     tcp_stream_session.h
     tcp_stream_tracker.cc
     tcp_stream_tracker.h
+    tcp_trace.cc
+    tcp_trace.h
     ${TEST_FILES}
 )
 
index cfc7712699909b723a220254932bf7339afc4ea0..d1642490cc76546592697f7fba4524ab118e293b 100644 (file)
@@ -27,6 +27,9 @@
 #include "main/snort_config.h"
 #include "profiler/profiler_defs.h"
 #include "stream/paf.h"
+#include "trace/trace.h"
+
+#include "tcp_trace.h"
 
 using namespace snort;
 
@@ -36,6 +39,16 @@ using namespace snort;
 
 THREAD_LOCAL ProfileStats s5TcpPerfStats;
 
+THREAD_LOCAL const Trace* stream_tcp_trace = nullptr;
+
+static const TraceOption stream_tcp_trace_options[] =
+{
+    { "segments", TRACE_SEGMENTS, "enable stream TCP segments trace logging" },
+    { "state",    TRACE_STATE,    "enable stream TCP state trace logging" },
+
+    { nullptr, 0, nullptr }
+};
+
 const PegInfo tcp_pegs[] =
 {
     SESSION_PEGS("tcp"),
@@ -239,6 +252,12 @@ StreamTcpModule::StreamTcpModule() :
     config = nullptr;
 }
 
+void StreamTcpModule::set_trace(const Trace* trace) const
+{ stream_tcp_trace = trace; }
+
+const TraceOption* StreamTcpModule::get_trace_options() const
+{ return stream_tcp_trace_options; }
+
 const RuleMap* StreamTcpModule::get_rules() const
 { return stream_tcp_rules; }
 
index f651e3bb62bbaf6b707fd0a7dddbdb8db862340b..9fd3d7a7d53bd8c9f6a9ed4767ae0c21d8f9d281 100644 (file)
@@ -51,6 +51,7 @@
 
 extern const PegInfo tcp_pegs[];
 
+extern THREAD_LOCAL const snort::Trace* stream_tcp_trace;
 extern THREAD_LOCAL snort::ProfileStats s5TcpPerfStats;
 
 struct TcpStats
@@ -119,11 +120,6 @@ extern THREAD_LOCAL struct TcpStats tcpStats;
 #define STREAM_TCP_MOD_NAME "stream_tcp"
 #define STREAM_TCP_MOD_HELP "stream inspector for TCP flow tracking and stream normalization and reassembly"
 
-namespace snort
-{
-struct SnortConfig;
-}
-
 class StreamTcpModule : public snort::Module
 {
 public:
@@ -149,6 +145,9 @@ public:
     bool is_bindable() const override
     { return true; }
 
+    void set_trace(const snort::Trace*) const override;
+    const snort::TraceOption* get_trace_options() const override;
+
 private:
     TcpStreamConfig* config;
 };
index 222089b49783a83460c7acfda29a2c9489ae3cba..56f411bfb08caa88e0806bda1624e93743011741 100644 (file)
@@ -62,34 +62,6 @@ static void purge_alerts_callback_ips(IpsContext* c)
         session->client.reassembler.purge_alerts();
 }
 
-void TcpReassembler::trace_segments(TcpReassemblerState& trs)
-{
-    TcpSegmentNode* tsn = trs.sos.seglist.head;
-    uint32_t sx = trs.tracker->r_win_base;
-    unsigned segs = 0, bytes = 0;
-
-    while ( tsn )
-    {
-        if (SEQ_LT(sx, tsn->i_seq))
-            fprintf(stdout, " +%u", tsn->i_seq - sx);
-        else if (SEQ_GT(sx, tsn->i_seq))
-            fprintf(stdout, " -%u", sx - tsn->i_seq);
-
-        fprintf(stdout, " %hu", tsn->i_len);
-
-        if ( tsn->c_len and tsn->c_len != tsn->i_len )
-            fprintf(stdout, "(%hu|%hu|%d)",
-                tsn->offset, tsn->c_len, tsn->i_len-tsn->offset-tsn->c_len);
-
-        segs++;
-        bytes += tsn->i_len;
-        sx = tsn->i_seq + tsn->i_len;
-        tsn = tsn->next;
-    }
-    assert(trs.sos.seg_count == segs);
-    assert(trs.sos.seg_bytes_logical == bytes);
-}
-
 bool TcpReassembler::is_segment_pending_flush(TcpReassemblerState& trs)
 {
     return ( get_pending_segment_count(trs, 1) > 0 );
index ea609984c63182e3e75a740a53564c318b4f5ba2..a77d12eb71e1f18faa7662108641647684ed9967 100644 (file)
@@ -38,7 +38,6 @@ public:
     virtual bool is_segment_pending_flush(TcpReassemblerState&);
     virtual int flush_on_data_policy(TcpReassemblerState&, snort::Packet*);
     virtual int flush_on_ack_policy(TcpReassemblerState&, snort::Packet*);
-    virtual void trace_segments(TcpReassemblerState&);
     virtual bool add_alert(TcpReassemblerState&, uint32_t gid, uint32_t sid);
     virtual bool check_alerted(TcpReassemblerState&, uint32_t gid, uint32_t sid);
     virtual int update_alert(TcpReassemblerState&, uint32_t gid, uint32_t sid,
index 928a8da53f2850fb6ca993899867ed62756d8637..9e961c167b1d9176354cbe5af4ad44853deffc27 100644 (file)
@@ -82,9 +82,6 @@ public:
     int flush_on_ack_policy(snort::Packet* p)
     { return reassembler->flush_on_ack_policy(trs, p); }
 
-    void trace_segments()
-    { reassembler->trace_segments(trs); }
-
     void set_seglist_base_seq(uint32_t seglist_base_seq)
     { trs.sos.seglist_base_seq = seglist_base_seq; }
 
@@ -139,6 +136,7 @@ public:
 private:
     TcpReassembler* reassembler = nullptr;
     TcpReassemblerState trs;
+    friend inline void TraceSegments(const TcpReassemblerPolicy&, const snort::Packet* p);
 };
 #endif
 
index 3fe36e117feec129f912945b2eb8c561647bd3cc..3d1a4e0919433e1a709faceca28b238dfba02c15 100644 (file)
 #include "protocols/eth.h"
 
 #include "stream_tcp.h"
-#include "tcp_debug_trace.h"
 #include "tcp_ha.h"
 #include "tcp_module.h"
 #include "tcp_normalizers.h"
 #include "tcp_reassemblers.h"
 #include "tcp_segment_node.h"
 #include "tcp_state_machine.h"
+#include "tcp_trace.h"
 
 using namespace snort;
 
@@ -1058,12 +1058,12 @@ bool TcpSession::validate_packet_established_session(TcpSegmentDescriptor& tsd)
     return ( pkt_action_mask & ACTION_BAD_PKT ) ? false : true;
 }
 
-int TcpSession::process_tcp_packet(TcpSegmentDescriptor& tsd)
+int TcpSession::process_tcp_packet(TcpSegmentDescriptor& tsd, const Packet* p)
 {
     tsm->eval(tsd);
     check_events_and_actions(tsd);
 
-    S5TraceTCP(tsd);
+    S5TraceTCP(tsd, p);
 
     return ACTION_NOTHING;
 }
@@ -1086,7 +1086,7 @@ int TcpSession::process(Packet* p)
     {
         TcpSegmentDescriptor ma_tsd(flow, p, tcp_mack->tcp_ack_seq_num, tcp_mack->tcp_window_size);
         init_tcp_packet_analysis(ma_tsd);
-        process_tcp_packet(ma_tsd);
+        process_tcp_packet(ma_tsd, p);
         tcpStats.meta_acks++;
     }
 
@@ -1097,7 +1097,7 @@ int TcpSession::process(Packet* p)
             && !handle_syn_on_reset_session(tsd) )
         return ACTION_NOTHING;
 
-    return process_tcp_packet(tsd);
+    return process_tcp_packet(tsd, p);
 }
 
 void TcpSession::flush()
index 06f570a19b954cd7e7b7a47195138a6af9a4f4d0..42e4d40bfc89bdef3e9ba09ece0a10082711bcfc 100644 (file)
@@ -73,7 +73,7 @@ public:
     { return tcp_config->midstream_allowed(tsd.get_pkt()); }
 
 private:
-    int process_tcp_packet(TcpSegmentDescriptor&);
+    int process_tcp_packet(TcpSegmentDescriptor&, const snort::Packet*);
     void process_tcp_stream(TcpSegmentDescriptor&);
     int process_tcp_data(TcpSegmentDescriptor&);
     void set_os_policy() override;
index 490c5650fbc3769e1b7adbd85745a54c0bb31940..4da152f26c475419d30addadbaa9ed0e9291b93f 100644 (file)
@@ -247,7 +247,7 @@ public:
     void set_flush_policy(FlushPolicy policy)
     { flush_policy = policy; }
 
-    FlushPolicy get_flush_policy()
+    FlushPolicy get_flush_policy() const
     { return flush_policy; }
 
     virtual void init_tcp_state();
similarity index 53%
rename from src/stream/tcp/tcp_debug_trace.h
rename to src/stream/tcp/tcp_trace.cc
index 21c2a6b65424c4265d990bb68b47797d07def234..e9f5af14a656a3d5693b585babf2093558e79dcb 100644 (file)
 // 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //--------------------------------------------------------------------------
 
-// tcp_debug_trace.h author davis mcpherson <davmcphe@cisco.com>
-// Created on: Aug 5, 2015
+// tcp_trace.cc author Oleksii Khomiakovskyi <okhomiak@cisco.com>
+// based on work by davis mcpherson <davmcphe@cisco.com>
 
-#ifndef TCP_DEBUG_TRACE_H
-#define TCP_DEBUG_TRACE_H
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tcp_trace.h"
 
+#include "main/snort_debug.h"
 #include "utils/stats.h"
 
-#include "tcp_reassemblers.h"
+#include "tcp_module.h"
+#include "tcp_session.h"
+#include "tcp_stream_tracker.h"
 
-#ifndef REG_TEST
-#define S5TraceTCP(tsd)
+#ifndef DEBUG_MSGS
+void S5TraceTCP(const TcpSegmentDescriptor&, const snort::Packet*) { }
 #else
 #define LCL(p, x) ((p).x() - (p).get_iss())
 #define RMT(p, x, q) ((p).x - (q).get_iss())
@@ -40,24 +46,23 @@ static const char* const statext[] =
 
 static const char* const flushxt[] = { "IGN", "FPR", "PRE", "PRO", "PAF" };
 
-static THREAD_LOCAL int s5_trace_enabled = -1;  // FIXIT-L should use module trace feature
-
-inline void TraceEvent(const TcpSegmentDescriptor& tsd, uint32_t txd, uint32_t rxd)
+inline void TraceEvent(const TcpSegmentDescriptor& tsd, uint32_t txd, uint32_t rxd,
+    const snort::Packet* p)
 {
     char flags[7] = "UAPRSF";
     const snort::tcp::TCPHdr* h = tsd.get_tcph();
     const char* order = "";
     const char* meta_ack_marker = tsd.is_meta_ack_packet() ? "M" : " ";
 
-    if (!h)
+    if ( !h )
         return;
 
     for (int i = 0; i < 6; i++)
-        if (!((1 << (5 - i)) & h->th_flags))
+        if ( !((1 << (5 - i)) & h->th_flags) )
             flags[i] = '-';
 
     // force relative ack to zero if not conveyed
-    if (flags[1] != 'A')
+    if ( flags[1] != 'A' )
         rxd = tsd.get_ack();   // FIXIT-L SYN's seen with ack > 0 and ACK flag not set...
 
     if ( tsd.are_packet_flags_set(PKT_STREAM_ORDER_OK) )
@@ -65,54 +70,96 @@ inline void TraceEvent(const TcpSegmentDescriptor& tsd, uint32_t txd, uint32_t r
     else if ( tsd.are_packet_flags_set(PKT_STREAM_ORDER_BAD) )
         order = " (oos)";
 
-    uint32_t rseq = ( txd ) ? tsd.get_seq() - txd : tsd.get_seq();
-    uint32_t rack = ( rxd ) ? tsd.get_ack() - rxd : tsd.get_ack();
-    fprintf(stdout, "\n" FMTu64("-3") " %s %s=0x%02x Seq=%-4u Ack=%-4u Win=%-4u Len=%-4hu%s\n",
+    uint32_t rseq = txd ? tsd.get_seq() - txd : tsd.get_seq();
+    uint32_t rack = rxd ? tsd.get_ack() - rxd : tsd.get_ack();
+
+    debug_logf(stream_tcp_trace, TRACE_STATE, p,
+        FMTu64("-3") " %s %s=0x%02x Seq=%-4u Ack=%-4u Win=%-4u Len=%-4hu%s\n",
         tsd.get_packet_number(), meta_ack_marker, flags, h->th_flags, rseq, rack, tsd.get_wnd(),
         tsd.get_len(), order);
 }
 
-inline void TraceSession(const snort::Flow* flow)
+inline void TraceSession(const snort::Flow* flow, const snort::Packet* p)
 {
-    fprintf(stdout, "      LWS: ST=0x%x SF=0x%x CP=%hu SP=%hu\n", (unsigned)flow->session_state,
+    debug_logf(stream_tcp_trace, TRACE_STATE, p,
+        "      LWS: ST=0x%x SF=0x%x CP=%hu SP=%hu\n", (unsigned)flow->session_state,
         flow->ssn_state.session_flags, flow->client_port, flow->server_port);
 }
 
-inline void TraceState(TcpStreamTracker& a, TcpStreamTracker& b, const char* s)
+inline void TraceSegments(const TcpReassemblerPolicy& trp, const snort::Packet* p)
+{
+    const TcpSegmentNode* tsn = trp.trs.sos.seglist.head;
+    uint32_t sx = trp.trs.tracker->r_win_base;
+    unsigned segs = 0;
+    unsigned bytes = 0;
+    std::stringstream ss;
+
+    if ( !trace_enabled(stream_tcp_trace, TRACE_SEGMENTS) )
+        return;
+
+    while ( tsn )
+    {
+        if ( SEQ_LT(sx, tsn->i_seq) )
+            ss << " +" << tsn->i_seq - sx;
+        else if ( SEQ_GT(sx, tsn->i_seq) )
+            ss << " -" << sx - tsn->i_seq;
+
+        ss << " " << tsn->i_len;
+
+        if ( tsn->c_len and tsn->c_len != tsn->i_len )
+        {
+            ss << "(" << tsn->offset << "|" << tsn->c_len;
+            ss << "|" << tsn->i_len-tsn->offset-tsn->c_len << ")";
+        }
+
+        segs++;
+        bytes += tsn->i_len;
+        sx = tsn->i_seq + tsn->i_len;
+        tsn = tsn->next;
+    }
+
+    if ( !ss.str().empty() )
+        debug_logf(stream_tcp_trace, TRACE_SEGMENTS, p, "       %s\n", ss.str().c_str());
+
+    assert(trp.trs.sos.seg_count == segs);
+    assert(trp.trs.sos.seg_bytes_logical == bytes);
+}
+
+inline void TraceState(const TcpStreamTracker& a, const TcpStreamTracker& b, const char* s,
+    const snort::Packet* p)
 {
     uint32_t ua = a.get_snd_una() ? LCL(a, get_snd_una) : 0;
     uint32_t ns = a.get_snd_nxt() ? LCL(a, get_snd_nxt) : 0;
 
-    fprintf(stdout,
-        "      %s ST=%s      UA=%-4u NS=%-4u LW=%-5u RN=%-4u RW=%-4u ISS=%-4u IRS=%-4u ",
+    debug_logf(stream_tcp_trace, TRACE_STATE, p,
+        "      %s ST=%s      UA=%-4u NS=%-4u LW=%-5u RN=%-4u RW=%-4u ISS=%-4u IRS=%-4u\n",
         s, statext[a.get_tcp_state()], ua, ns, a.get_snd_wnd( ),
         RMT(a, rcv_nxt, b), RMT(a, r_win_base, b), a.get_iss(), a.get_irs());
 
-    fprintf(stdout, "\n");
-    unsigned paf = ( a.is_splitter_paf() ) ? 2 : 0;
+    unsigned paf = a.is_splitter_paf() ? 2 : 0;
     unsigned fpt = a.get_flush_policy() ? 192 : 0;
 
-    fprintf(stdout, "           FP=%s:%-4u SC=%-4u FL=%-4u SL=%-5u BS=%-4u",
+    debug_logf(stream_tcp_trace, TRACE_STATE, p,
+        "           FP=%s:%-4u SC=%-4u FL=%-4u SL=%-5u BS=%-4u\n",
         flushxt[a.get_flush_policy() + paf], fpt,
         a.reassembler.get_seg_count(), a.reassembler.get_flush_count(),
         a.reassembler.get_seg_bytes_logical(),
         a.reassembler.get_seglist_base_seq() - b.get_iss());
 
-    if ( s5_trace_enabled == 2 )
-        a.reassembler.trace_segments();
-
-    fprintf(stdout, "\n");
+    TraceSegments(a.reassembler, p);
 }
 
-inline void TraceTCP(const TcpSegmentDescriptor& tsd)
+void S5TraceTCP(const TcpSegmentDescriptor& tsd, const snort::Packet* p)
 {
     TcpSession* ssn = (TcpSession*)tsd.get_flow()->session;
     assert(ssn);
-    TcpStreamTracker& srv = ssn->server;
-    TcpStreamTracker& cli = ssn->client;
+    const TcpStreamTracker& srv = ssn->server;
+    const TcpStreamTracker& cli = ssn->client;
 
-    const char* cdir = "?", * sdir = "?";
-    uint32_t txd = 0, rxd = 0;
+    const char* cdir = "?";
+    const char* sdir = "?";
+    uint32_t txd = 0;
+    uint32_t rxd = 0;
 
     if ( tsd.is_packet_from_client() )
     {
@@ -129,37 +176,14 @@ inline void TraceTCP(const TcpSegmentDescriptor& tsd)
         rxd = srv.get_irs();
     }
 
-    TraceEvent(tsd, txd, rxd);
+    TraceEvent(tsd, txd, rxd, p);
 
     if ( ssn->lws_init )
-        TraceSession(tsd.get_flow());
-
-    TraceState(cli, srv, cdir);
-    TraceState(srv, cli, sdir);
-}
-
-inline void S5TraceTCP(const TcpSegmentDescriptor& tsd)
-{
-    if ( !s5_trace_enabled )
-        return;
+        TraceSession(tsd.get_flow(), p);
 
-    if ( s5_trace_enabled < 0 )
-    {
-        const char* s5t = getenv("S5_TRACE");
-
-        if ( !s5t )
-        {
-            s5_trace_enabled = 0;
-            return;
-        }
-
-        // no error checking required - atoi() is sufficient
-        s5_trace_enabled = atoi(s5t);
-    }
-
-    TraceTCP(tsd);
+    TraceState(cli, srv, cdir, p);
+    TraceState(srv, cli, sdir, p);
 }
-#endif  // REG_TEST
 
-#endif
+#endif // DEBUG_MSGS
 
diff --git a/src/stream/tcp/tcp_trace.h b/src/stream/tcp/tcp_trace.h
new file mode 100644 (file)
index 0000000..d035b62
--- /dev/null
@@ -0,0 +1,42 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 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.
+//--------------------------------------------------------------------------
+
+// tcp_trace.h author Oleksii Khomiakovskyi <okhomiak@cisco.com>
+
+#ifndef TCP_TRACE_H
+#define TCP_TRACE_H
+
+#include "main/thread.h"
+
+namespace snort
+{
+struct Packet;
+}
+
+class TcpSegmentDescriptor;
+
+enum
+{
+    TRACE_SEGMENTS = 0,
+    TRACE_STATE,
+};
+
+void S5TraceTCP(const TcpSegmentDescriptor&, const snort::Packet*);
+
+#endif
+