]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
StreamSplitter::reassemble() and Xcode fixes, etc.
authorRuss Combs <rucombs@cisco.com>
Wed, 30 Jul 2014 02:14:11 +0000 (22:14 -0400)
committerRuss Combs <rucombs@cisco.com>
Wed, 30 Jul 2014 02:14:11 +0000 (22:14 -0400)
23 files changed:
ChangeLog
src/file_api/file_mime_process.cc
src/framework/range.cc
src/main/modules.cc
src/main/snort.cc
src/main/snort_config.cc
src/managers/packet_manager.cc
src/search_engines/acsmx2.cc
src/search_engines/bnfa_search.cc
src/service_inspectors/http_inspect/hi_paf.cc
src/stream/stream_splitter.cc
src/stream/stream_splitter.h
src/stream/tcp/ips_stream_size.cc
src/stream/tcp/tcp_session.cc
src/stream/tcp/tcp_session.h
src/time/ppm.cc
src/time/ppm.h
src/time/ppm_module.cc
src/time/ppm_module.h
src/utils/stats.cc
src/utils/stats.h
src/utils/util.cc
tools/u2spewfoo/u2spewfoo.cc

index b56c8728001245233b8a4b35248dd52b99233527..d39dedc5541d0a3055df11b3ba683893a3d22fc2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+107
+-- fixed stats output
+-- deleted code that skipped over TCP urgent data when flushing
+-- added StreamSplitter::reassemble() etc for PAR
+-- updated ppm output to use stats functions for consistency
+-- fixed old HI chunk splitting
+-- changed stream tcp to use StreamSplitter::reassemble() instead of
+    direct memcpy()
+-- several new Xcode warnings cleaned up (mostly unused funcs)
+
 106
 -- converted fpdetect.cc to pull fast pattern buffers from inspector gadget
 
index c5d2b1498d5ed624e16150bd9f8aa6a5981e1d62..4b89f023f4c7da1cb459733f9e0223f3df9ffffd 100644 (file)
@@ -856,6 +856,7 @@ static void reset_mime_state(MimeState *mime_ssn)
     memset(&mime_ssn->mime_boundary, 0, sizeof(MimeBoundary));
 }
 
+#if 0
 static inline FilePosition getFilePoistion(Packet *p)
 {
     FilePosition position = SNORT_FILE_POSITION_UNKNOWN;
@@ -871,6 +872,8 @@ static inline FilePosition getFilePoistion(Packet *p)
 
     return position;
 }
+#endif
+
 /*
  * Main function for mime processing
  *
index b7899042150145ad3aab4994250ac463be498ecc..c36b1ae729bd5e6888f3a5b8edea63278c9d4aba 100644 (file)
@@ -20,7 +20,9 @@
 
 #include "range.h"
 
+#include <stdlib.h>
 #include <string.h>
+
 #include <string>
 using namespace std;
 
index 1333db7812a1bfe9634a41cd7c4ab1a57e10d638..18b35e785111245bdb1240c38d7b12e03b6c2508 100644 (file)
@@ -1396,8 +1396,8 @@ static const Parameter event_filter_params[] =
     { "track", Parameter::PT_ENUM, "by_src | by_dst", nullptr,
       "filter only matching source or destination addresses" },
 
-    { "count", Parameter::PT_INT, "0:", "0",
-      "number of events in interval before tripping" },
+    { "count", Parameter::PT_INT, "-1:", "0",
+      "number of events in interval before tripping; -1 to disable" },
 
     { "seconds", Parameter::PT_INT, "0:", "0",
       "count interval" },
index 9a5cfbffdeefce2c69a9a840e011b32dd6c469fe..c2926ae3369a937a2df8fb5920284785da9fc6fe 100644 (file)
@@ -1008,6 +1008,9 @@ void snort_thread_init(const char* intf)
 
 void snort_thread_term()
 {
+#ifdef PPM_MGR
+    ppm_sum_stats();
+#endif
     ModuleManager::accumulate(snort_conf);
     InspectorManager::thread_term(snort_conf);
     IpsManager::clear_options();
index 5ab2f7b453b9e80225aa5e88932c2c63cf3f1a98..ff73f936b16a413978b41027d8436871f93fac29 100644 (file)
@@ -121,7 +121,7 @@ static inline RuleTreeNode * protocolRuleList(RuleListNode *rule, int protocol)
     }
     return NULL;
 }
-#endif
+
 static inline const char* getProtocolName (int protocol)
 {
     static const char *protocolName[] = {"TCP", "UDP", "ICMP"};
@@ -139,6 +139,7 @@ static inline const char* getProtocolName (int protocol)
     }
     return NULL;
 }
+#endif
 
 //-------------------------------------------------------------------------
 // public methods
index 478ba0bb376fce8cd5b85efd0afe5a91696833db..df750f9770c8ac81dd9695be5fccf9f60085e849 100644 (file)
@@ -738,7 +738,7 @@ void PacketManager::dump_stats()
         pkt_names.push_back(s_protocols[i]->get_name());
 
     show_percent_stats((PegCount*) &g_stats, &pkt_names[0], (unsigned int) pkt_names.size(),
-        "codecs");
+        "codec");
 }
 
 SO_PUBLIC void PacketManager::encode_set_dst_mac(uint8_t *mac)
index 3884d15b714e3fb1cdba92e8b6731bee065cce3e..ea5ac0ab62f1f090ebb8924d3339a6da20e21b7d 100644 (file)
@@ -2666,8 +2666,10 @@ int acsmPrintDetailInfo2(ACSM_STRUCT2*)
  *   all groups use the same format, state size, etc..
  *   Combined with accrued stats, we get an average picture of things.
  */
+#if 0
 static inline double pct(unsigned long n, unsigned long d)
 { return (100.0 * n) / d; }
+#endif
 
 int acsmPrintSummaryInfo2(void)
 {
index 247ad883de1087bd8eec8eedf88911fa6560dad3..54390050ea11f3f833cef64c2b532ac0afd5a18a 100644 (file)
@@ -1761,7 +1761,7 @@ static inline unsigned _bnfa_get_next_state_csparse_nfa_qx(bnfa_state_t * pcx, u
     int k;
     int nc;
     int index;
-    register bnfa_state_t * pcs;
+    bnfa_state_t * pcs;
 
     for(;;) {
         pcs = pcx + sindex + 1; /* skip state-id == 1st word */
@@ -1813,7 +1813,7 @@ static inline unsigned _bnfa_get_next_state_csparse_nfa(bnfa_state_t * pcx, unsi
     int k;
     int nc;
     int index;
-    register bnfa_state_t * pcs;
+    bnfa_state_t * pcs;
 
     for(;;) {
         pcs = pcx + sindex + 1; /* skip state-id == 1st word */
index ca54493d9dc417cb290069a2f28502fd81d0c5de..1537c49f4cc01852ef8f779a992b9afc4789b39a 100644 (file)
@@ -411,7 +411,7 @@ static void get_state (int s, char* buf, int max)
     snprintf(buf, max, "%s+%d", sbase, (s-nbase));
 }
 
-#if 1
+#if 0
 static inline bool dump_it (int c)
 {
     if ( !c ) return false;
@@ -703,6 +703,8 @@ static inline PAF_Status hi_exec (Hi5State* s, Action a, int c)
                 "%s: lnc=%u\n", __FUNCTION__, s->len);)
             if ( s->len )
                 return PAF_SKIP;
+            else
+                return PAF_FLUSH;
             s->flags &= ~HIF_NOF;
             s->msg = 3;
             break;
@@ -1008,7 +1010,7 @@ HttpSplitter::HttpSplitter(bool c2s) : StreamSplitter(c2s)
     if ( c2s )
         state.fsm = REQ_START_STATE;
     else
-        state.fsm = REQ_START_STATE;
+        state.fsm = RSP_START_STATE;
 }
 
 HttpSplitter::~HttpSplitter() { }
index c303f0595b7a7dbec2b36891ed3b61af539d7da9..41c2f638b353ba9f3adfb7ba61f0d05e6284051b 100644 (file)
 
 #include "stream/stream_splitter.h"
 
+#include <assert.h>
+#include <string.h>
+
+#include "protocols/packet.h"
+
+static THREAD_LOCAL uint8_t pdu_buf[65536];
+static THREAD_LOCAL StreamBuffer str_buf;
+
 uint32_t StreamSplitter::max()
 { return 16384; }  // FIXIT make default configurable
 
+const StreamBuffer* StreamSplitter::reassemble(
+    unsigned offset, const uint8_t* p, unsigned n, uint32_t flags, unsigned& copied)
+{ 
+    assert(offset + n < sizeof(pdu_buf));
+    memcpy(pdu_buf+offset, p, n);
+    copied = n;
+
+    if ( flags & PKT_PDU_TAIL )
+    {
+        str_buf.data = pdu_buf;
+        str_buf.length = offset + n;
+        return &str_buf;
+    }
+    return nullptr;
+}
+
 AtomSplitter::AtomSplitter(bool b, uint32_t sz) : StreamSplitter(b)
 {
     reset();
index de18a87abd775ad2ed11c5bdf2c0c91b147afa8f..3690aaf0259ac04c38f70039f732b6c4b8bfd84a 100644 (file)
@@ -33,9 +33,16 @@ enum PAF_Status // FIXIT move inside StreamSplitter
     PAF_START,   // internal use only
     PAF_SEARCH,  // searching for next flush point
     PAF_FLUSH,   // flush at given offset
+    PAF_BUILD,   // reassemble to given offset
     PAF_SKIP     // skip ahead to given offset
 };
 
+struct StreamBuffer
+{
+    const uint8_t* data;
+    unsigned length;
+};
+
 //-------------------------------------------------------------------------
 
 class StreamSplitter
@@ -51,6 +58,14 @@ public:
         uint32_t* fp           // flush point (offset) relative to data
     ) = 0;
 
+    virtual const StreamBuffer* reassemble(
+        unsigned offset,       // data offset from start of reassembly
+        const uint8_t* data,   // data to reassemble
+        unsigned len,          // length of data
+        uint32_t flags,        // packet flags indicating pdu head and/or tail
+        unsigned& copied       // actual data copied (1 <= copied <= len)
+    );
+
     virtual bool is_paf() { return false; };
     virtual uint32_t max();
 
index f08c16e8aa3d28124707eb41bbea6af259a91800..891c8e0160c8cbe5579e7bff2a5bd0b88fe210a0 100644 (file)
@@ -174,7 +174,7 @@ int SizeOption::eval(Cursor&, Packet* pkt)
         server_size = tcpssn->server.isn - tcpssn->server.l_nxt_seq;
     }
 
-    int result;
+    int result = DETECTION_OPTION_NO_MATCH;
 
     switch (ssod.direction)
     {
@@ -205,7 +205,6 @@ int SizeOption::eval(Cursor&, Packet* pkt)
         break;
 
     default:
-        result = DETECTION_OPTION_NO_MATCH;
         break;
     }
     MODULE_PROFILE_END(streamSizePerfStats);
index e46e88c66b6ddcacaf64819fdbd4b4e7d84374bf..8412b62c8d5cb487e6745114d70043d2a66d1bee 100644 (file)
@@ -406,9 +406,6 @@ static uint32_t Stream5GetWscale(Packet *, uint16_t *);
 static uint32_t Stream5PacketHasWscale(Packet *);
 static uint32_t Stream5GetMss(Packet *, uint16_t *);
 static uint32_t Stream5GetTcpTimestamp(Packet *, uint32_t *, int strip);
-static int FlushStream(
-    Packet*, StreamTracker *st, uint32_t toSeq, uint8_t *flushbuf,
-    const uint8_t *flushbuf_end);
 static void TcpSessionCleanup(Flow *ssn, int freeApplicationData);
 
 int s5TcpStreamSizeInit(SnortConfig* sc, char *name, char *parameters, void **dataPtr);
@@ -616,71 +613,6 @@ void Stream5UpdatePerfBaseState(SFBASE *sf_base,
 // policy translation
 //-------------------------------------------------------------------------
 
-static inline uint16_t StreamPolicyIdFromName(char *name)
-{
-    if (!name)
-    {
-        return STREAM_POLICY_DEFAULT;
-    }
-
-    if(!strcasecmp(name, "bsd"))
-    {
-        return STREAM_POLICY_BSD;
-    }
-    else if(!strcasecmp(name, "old-linux"))
-    {
-        return STREAM_POLICY_OLD_LINUX;
-    }
-    else if(!strcasecmp(name, "linux"))
-    {
-        return STREAM_POLICY_LINUX;
-    }
-    else if(!strcasecmp(name, "first"))
-    {
-        return STREAM_POLICY_FIRST;
-    }
-    else if(!strcasecmp(name, "last"))
-    {
-        return STREAM_POLICY_LAST;
-    }
-    else if(!strcasecmp(name, "windows"))
-    {
-        return STREAM_POLICY_WINDOWS;
-    }
-    else if(!strcasecmp(name, "solaris"))
-    {
-        return STREAM_POLICY_SOLARIS;
-    }
-    else if(!strcasecmp(name, "win2003") ||
-            !strcasecmp(name, "win2k3"))
-    {
-        return STREAM_POLICY_WINDOWS2K3;
-    }
-    else if(!strcasecmp(name, "vista"))
-    {
-        return STREAM_POLICY_VISTA;
-    }
-    else if(!strcasecmp(name, "hpux") ||
-            !strcasecmp(name, "hpux11"))
-    {
-        return STREAM_POLICY_HPUX11;
-    }
-    else if(!strcasecmp(name, "hpux10"))
-    {
-        return STREAM_POLICY_HPUX10;
-    }
-    else if(!strcasecmp(name, "irix"))
-    {
-        return STREAM_POLICY_IRIX;
-    }
-    else if(!strcasecmp(name, "macos") ||
-            !strcasecmp(name, "grannysmith"))
-    {
-        return STREAM_POLICY_MACOS;
-    }
-    return STREAM_POLICY_DEFAULT; /* BSD is the default */
-}
-
 static inline uint16_t GetTcpReassemblyPolicy(int os_policy)
 {
     switch (os_policy)
@@ -1969,6 +1901,134 @@ static void ShowRebuiltPacket (TcpSession* ssn, Packet* pkt)
         LogIPPkt(IPPROTO_TCP, pkt);
 }
 
+static inline unsigned int getSegmentFlushSize(
+        StreamTracker* st,
+        StreamSegment *ss,
+        uint32_t to_seq,
+        unsigned int flushBufSize
+        )
+{
+    unsigned int flushSize = ss->size;
+
+    //copy only till flush buffer gets full
+    if ( flushSize > flushBufSize )
+        flushSize = flushBufSize;
+
+    // copy only to flush point
+    if ( s5_paf_active(&st->paf_state) && SEQ_GT(ss->seq + flushSize, to_seq) )
+        flushSize = to_seq - ss->seq;
+
+    return flushSize;
+}
+
+/*
+ * flush the client seglist up to the most recently acked segment
+ */
+static int FlushStream(
+    Packet*, StreamTracker *st, uint32_t toSeq, uint8_t *flushbuf,
+    const uint8_t *flushbuf_end)
+{
+    uint16_t bytes_flushed = 0;
+    STREAM5_DEBUG_WRAP(uint32_t bytes_queued = st->seg_bytes_logical;);
+    uint32_t segs = 0;
+    uint32_t flags = PKT_PDU_HEAD;
+    PROFILE_VARS;
+
+    assert(st->seglist_next);
+    MODULE_PROFILE_START(s5TcpBuildPacketPerfStats);
+
+    while ( SEQ_LT(st->seglist_next->seq, toSeq) )
+    {
+        StreamSegment* ss = st->seglist_next, * sr;
+        unsigned flushbuf_size = flushbuf_end - flushbuf;
+        unsigned bytes_to_copy = getSegmentFlushSize(st, ss, toSeq, flushbuf_size);
+        unsigned bytes_copied = 0;
+
+        STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE,
+            "Flushing %u bytes from %X\n", bytes_to_copy, ss->seq));
+
+        if ( SEQ_EQ(ss->seq + bytes_to_copy,  toSeq) )
+            flags |= PKT_PDU_TAIL;
+
+        const StreamBuffer* sb = st->splitter->reassemble(
+            bytes_flushed, ss->payload, bytes_to_copy, flags, bytes_copied);
+
+        flags = 0;
+
+        if ( sb )
+        {
+            unsigned len = s5_pkt->max_dsize;
+            assert(sb->length <= len);
+
+            if ( sb->length < len )
+                len = sb->length;
+
+            s5_pkt->data = sb->data;
+            s5_pkt->dsize = len;
+
+            bytes_to_copy = bytes_copied;
+        }
+        else if ( !bytes_copied )
+        {
+            // FIXIT change stream splitter default reassemble 
+            // to copy into external buffer to eliminate this special case
+            memcpy(flushbuf, ss->payload, bytes_to_copy);
+        }
+        else
+            assert(bytes_to_copy == bytes_copied);
+
+        flushbuf += bytes_to_copy;
+        bytes_flushed += bytes_to_copy;
+
+        if ( bytes_to_copy < ss->size &&
+             DupStreamNode(NULL, st, ss, &sr) == STREAM_INSERT_OK )
+        {
+            ss->size = bytes_to_copy;
+            sr->seq += bytes_to_copy;
+            sr->size -= bytes_to_copy;
+            sr->payload += bytes_to_copy + (ss->payload - ss->data);
+        }
+        ss->buffered = SL_BUF_FLUSHED;
+        st->flush_count++;
+        segs++;
+
+        if ( sb )
+            break;
+
+        if ( flushbuf >= flushbuf_end )
+            break;
+
+        if ( SEQ_EQ(ss->seq + bytes_to_copy,  toSeq) )
+            break;
+
+        /* Check for a gap/missing packet */
+        // FIXIT PAF should account for missing data and resume
+        // scanning at the start of next PDU instead of aborting.
+        // FIXIT FIN may be in toSeq causing bogus gap counts.
+        if ( (ss->next && (ss->seq + ss->size != ss->next->seq)) ||
+            (!ss->next && (ss->seq + ss->size < toSeq)))
+        {
+            st->flags |= TF_MISSING_PKT;
+            st->flags |= TF_PKT_MISSED;
+            tcpStats.gaps++;
+        }
+        if ( !ss->next )
+            break;
+
+        st->seglist_next = ss->next;
+    }
+
+    STREAM5_DEBUG_WRAP(bytes_queued -= bytes_flushed;);
+
+    STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE,
+        "flushed %d bytes / %d segs on stream, "
+        "%d still queued\n",
+        bytes_flushed, segs, bytes_queued););
+
+    MODULE_PROFILE_END(s5TcpBuildPacketPerfStats);
+    return bytes_flushed;
+}
+
 static inline int _flush_to_seq (
 
     TcpSession *tcpssn, StreamTracker *st, uint32_t bytes, Packet *p,
@@ -2006,6 +2066,8 @@ static inline int _flush_to_seq (
     if ( !bytes && SEQ_GT(st->r_win_base, st->seglist_base_seq) )
         bytes = st->r_win_base - st->seglist_base_seq;
 
+    // FIXIT this should not be necessary here
+    st->seglist_base_seq = st->seglist_next->seq;
     stop_seq = st->seglist_base_seq + bytes;
 
     do
@@ -2046,30 +2108,9 @@ static inline int _flush_to_seq (
         const uint8_t* s5_pkt_end = s5_pkt->data + s5_pkt->max_dsize;
         flushed_bytes = FlushStream(p, st, stop_seq, (uint8_t *)s5_pkt->data, s5_pkt_end);
 
-        if(flushed_bytes == -1)
-        {
-            /* couldn't put a stream together for whatever reason
-             * should probably clean the seglist and bail...
-             */
-            if(st->seglist)
-            {
-                STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE,
-                            "dumping entire seglist!\n"););
-                purge_all(st);
-                st->splitter->reset();
-            }
-
-            STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE,
-                "setting st->seglist_base_seq to 0x%X\n", stop_seq););
-            st->seglist_base_seq = stop_seq;
-
-            MODULE_PROFILE_END(s5TcpFlushPerfStats);
-            return bytes_processed;
-        }
-
         if (flushed_bytes == 0)
         {
-            /* No more ACK'd data... bail */
+            /* No more data... bail */
             break;
         }
 
@@ -2117,6 +2158,11 @@ static inline int _flush_to_seq (
         }
         MODULE_PROFILE_TMPSTART(s5TcpFlushPerfStats);
 
+        st->seglist_base_seq = st->seglist_next->seq + flushed_bytes;
+
+        STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE,
+            "setting st->seglist_base_seq to 0x%X\n", st->seglist_base_seq););
+
         // TBD abort should be by PAF callback only since
         // recovery may be possible in some cases
     } while ( !(st->flags & TF_MISSING_PKT) && DataToFlush(st) );
@@ -2183,7 +2229,6 @@ static inline int flush_to_seq(
     }
 
     return _flush_to_seq(tcpssn, st, bytes, p, sip, dip, sp, dp, dir);
-
 }
 
 /*
@@ -2266,149 +2311,6 @@ static inline int flush_stream(
     return flush_ackd(tcpssn, st, p, sip, dip, sp, dp, dir);
 }
 
-static inline unsigned int getSegmentFlushSize(
-        StreamTracker* st,
-        StreamSegment *ss,
-        uint32_t to_seq,
-        unsigned int flushBufSize
-        )
-{
-    unsigned int flushSize = ss->size;
-
-    //copy only till flush buffer gets full
-    if ( flushSize > flushBufSize )
-        flushSize = flushBufSize;
-
-    // copy only to flush point
-    if ( s5_paf_active(&st->paf_state) && SEQ_GT(ss->seq + flushSize, to_seq) )
-        flushSize = to_seq - ss->seq;
-
-    return flushSize;
-}
-
-/*
- * flush the client seglist up to the most recently acked segment
- */
-static int FlushStream(
-    Packet*, StreamTracker *st, uint32_t toSeq, uint8_t *flushbuf,
-    const uint8_t *flushbuf_end)
-{
-    StreamSegment *ss = NULL, *seglist, *sr;
-    uint16_t bytes_flushed = 0;
-    uint16_t bytes_skipped = 0;
-    STREAM5_DEBUG_WRAP(uint32_t bytes_queued = st->seg_bytes_logical;);
-    uint32_t segs = 0;
-    int ret;
-    PROFILE_VARS;
-
-    if ( st->seglist == NULL || st->seglist_tail == NULL )
-        return -1;
-
-    MODULE_PROFILE_START(s5TcpBuildPacketPerfStats);
-
-    // skip over previously flushed segments
-    seglist = st->seglist_next;
-
-    for(ss = seglist; ss && SEQ_LT(ss->seq,  toSeq); ss = ss->next)
-    {
-        unsigned int flushbuf_size = flushbuf_end - flushbuf;
-        unsigned int bytes_to_copy = getSegmentFlushSize(st, ss, toSeq, flushbuf_size);
-
-        STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE,
-            "Flushing %u bytes from %X\n", bytes_to_copy, ss->seq));
-
-        if(ss->urg_offset == 1)
-        {
-            /* if urg_offset is set, seq + urg_offset is seq # of octet
-             * in stream following the last urgent octet.  all preceding
-             * octets in segment are considered urgent.  this code will
-             * skip over the urgent data when flushing.
-             */
-
-            unsigned int non_urgent_bytes =
-                ss->urg_offset < bytes_to_copy ? (bytes_to_copy - ss->urg_offset) : 0;
-
-            if ( non_urgent_bytes )
-            {
-                ret = SafeMemcpy(flushbuf, ss->payload+ss->urg_offset,
-                          non_urgent_bytes, flushbuf, flushbuf_end);
-
-                if (ret == SAFEMEM_ERROR)
-                {
-                    STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE,
-                                "ERROR writing flushbuf attempting to "
-                                "write flushbuf out of range!\n"););
-                }
-                else
-                    flushbuf += non_urgent_bytes;
-
-                bytes_skipped += ss->urg_offset;
-            }
-        }
-        else
-        {
-            ret = SafeMemcpy(flushbuf, ss->payload,
-                      bytes_to_copy, flushbuf, flushbuf_end);
-
-            if (ret == SAFEMEM_ERROR)
-            {
-                STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE,
-                            "ERROR writing flushbuf attempting to "
-                            "write flushbuf out of range!\n"););
-            }
-            else
-                flushbuf += bytes_to_copy;
-        }
-
-        if ( bytes_to_copy < ss->size &&
-             DupStreamNode(NULL, st, ss, &sr) == STREAM_INSERT_OK )
-        {
-            ss->size = bytes_to_copy;
-            sr->seq += bytes_to_copy;
-            sr->size -= bytes_to_copy;
-            sr->payload += bytes_to_copy + (ss->payload - ss->data);
-        }
-        bytes_flushed += bytes_to_copy;
-        ss->buffered = SL_BUF_FLUSHED;
-        st->flush_count++;
-        segs++;
-
-        if ( flushbuf >= flushbuf_end )
-            break;
-
-        if ( SEQ_EQ(ss->seq + bytes_to_copy,  toSeq) )
-            break;
-
-        /* Check for a gap/missing packet */
-        // FIXIT PAF should account for missing data and resume
-        // scanning at the start of next PDU instead of aborting.
-        // FIXIT FIN may be in toSeq causing bogus gap counts.
-        if ( (ss->next && (ss->seq + ss->size != ss->next->seq)) ||
-            (!ss->next && (ss->seq + ss->size < toSeq)))
-        {
-            st->flags |= TF_MISSING_PKT;
-            st->flags |= TF_PKT_MISSED;
-            tcpStats.gaps++;
-        }
-    }
-
-    st->seglist_base_seq = toSeq;
-
-    STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE,
-        "setting st->seglist_base_seq to 0x%X\n", st->seglist_base_seq););
-
-    STREAM5_DEBUG_WRAP(bytes_queued -= bytes_flushed;);
-
-    STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE,
-        "flushed %d bytes / %d segs on stream, "
-        "skipped %d bytes, %d still queued\n",
-        bytes_flushed, segs, bytes_skipped, bytes_queued););
-
-    assert(st->seglist);
-    MODULE_PROFILE_END(s5TcpBuildPacketPerfStats);
-    return bytes_flushed - bytes_skipped;
-}
-
 int Stream5FlushServer(Packet *p, Flow *lwssn)
 {
     int flushed;
@@ -2991,10 +2893,12 @@ static uint32_t Stream5PacketHasWscale(Packet *p)
     return Stream5GetWscale(p, &wscale);
 }
 
+#if 0
 static inline int IsWellFormed(Packet *p, StreamTracker *ts)
 {
     return ( !ts->mss || (p->dsize <= ts->mss) );
 }
+#endif
 
 static void FinishServerInit(Packet *p, TcpDataBlock *tdb, TcpSession *ssn)
 {
@@ -3092,45 +2996,6 @@ static void NewQueue(
     return;
 }
 
-static inline StreamSegment *FindSegment(StreamTracker *st, uint32_t pkt_seq)
-{
-    int32_t dist_head;
-    int32_t dist_tail;
-    StreamSegment *ss;
-
-    if (!st->seglist)
-        return NULL;
-
-    dist_head = pkt_seq - st->seglist->seq;
-    dist_tail = pkt_seq - st->seglist_tail->seq;
-
-    if (dist_head <= dist_tail)
-    {
-        /* Start iterating at the head (left) */
-        for (ss = st->seglist; ss; ss = ss->next)
-        {
-            if (SEQ_EQ(ss->seq, pkt_seq))
-                return ss;
-
-            if (SEQ_GEQ(ss->seq, pkt_seq))
-                break;
-        }
-    }
-    else
-    {
-        /* Start iterating at the tail (right) */
-        for (ss = st->seglist_tail; ss; ss = ss->prev)
-        {
-            if (SEQ_EQ(ss->seq, pkt_seq))
-                return ss;
-
-            if (SEQ_LT(ss->seq, pkt_seq))
-                break;
-        }
-    }
-    return NULL;
-}
-
 static inline int SegmentFastTrack(StreamSegment *tail, TcpDataBlock *tdb)
 {
     STREAM5_DEBUG_WRAP(DebugMessage(DEBUG_STREAM_STATE,
@@ -6088,6 +5953,8 @@ static inline int CheckFlushPolicyOnData(
 
             while ( flush_amt > 0 )
             {
+#if 0
+                // FIXIT can't do this with new HI - copy is inevitable
                 // if this payload is exactly one pdu, don't
                 // actually flush, just use the raw packet
                 if ( (tdb->seq == listener->seglist->seq) &&
@@ -6101,6 +5968,7 @@ static inline int CheckFlushPolicyOnData(
                     ShowRebuiltPacket(tcpssn, p);
                 }
                 else
+#endif
                 {
                     this_flush = flush_to_seq(
                         tcpssn, listener, flush_amt, p,
index 7f4fb97332f4d7a35da9578440580bb75b265473..73073548be4c56ad6c6c87c6f640cba630287110 100644 (file)
@@ -136,8 +136,11 @@ struct StreamTracker
     StreamSegment *seglist;       /* first queued segment */
     StreamSegment *seglist_tail;  /* last queued segment */
 
-    // TBD move out of here since only used per packet?
-    StreamSegment* seglist_next;  /* next queued segment to flush */
+    // FIXIT seglist_base_seq is the sequence number to flush from
+    // and is valid even when seglist is empty.  seglist_next is
+    // the segment to flush from and is set per packet.  should keep
+    // up to date.
+    StreamSegment* seglist_next;
 
 #ifdef DEBUG
     int segment_ordinal;
index 97698afb7130bf9a4ed5f360a8e9e5009141aced..414529bc87e8b9fd471c71bb1530ad7c59c55213 100644 (file)
@@ -74,6 +74,7 @@
 #include "detection/fpdetect.h"
 #include "actions/actions.h"
 #include "protocols/packet.h"
+#include "utils/stats.h"
 
 #ifdef PPM_MGR
 
@@ -87,6 +88,8 @@
 
 PPM_TICKS ppm_tpu = 0; /* ticks per usec */
 
+static ppm_stats_t g_ppm_stats;
+
 THREAD_LOCAL ppm_stats_t       ppm_stats;
 THREAD_LOCAL ppm_pkt_timer_t   ppm_pkt_times[PPM_MAX_TIMERS];
 THREAD_LOCAL ppm_pkt_timer_t  *ppm_pt = NULL;
@@ -224,8 +227,7 @@ void ppm_print_cfg(ppm_cfg_t *ppm_cfg)
     }
 }
 
-static
-int print_rule( int, RuleTreeNode*, OptTreeNode * o )
+static int print_rule( int, RuleTreeNode*, OptTreeNode * o )
 {
     if( !o->enabled )
     {
@@ -236,6 +238,23 @@ int print_rule( int, RuleTreeNode*, OptTreeNode * o )
     return 0;
 }
 
+// FIXIT ppm_stats should be rolled into ppm module
+// (need module support)
+
+void ppm_sum_stats()
+{
+    g_ppm_stats.pkt_event_cnt += ppm_stats.pkt_event_cnt;
+    g_ppm_stats.rule_event_cnt += ppm_stats.rule_event_cnt;
+    g_ppm_stats.tot_pkt_time += ppm_stats.tot_pkt_time;
+    g_ppm_stats.tot_pkts += ppm_stats.tot_pkts;
+    g_ppm_stats.tot_rule_time += ppm_stats.tot_rule_time;
+    g_ppm_stats.tot_rules += ppm_stats.tot_pkts;
+    g_ppm_stats.tot_nc_rule_time += ppm_stats.tot_nc_rule_time;
+    g_ppm_stats.tot_nc_rules += ppm_stats.tot_nc_rules;
+    g_ppm_stats.tot_pcre_rule_time += ppm_stats.tot_pcre_rule_time;
+    g_ppm_stats.tot_pcre_rules += ppm_stats.tot_pcre_rules;
+}
+
 void ppm_print_summary(ppm_cfg_t *ppm_cfg)
 {
     if (ppm_cfg == NULL)
@@ -244,47 +263,46 @@ void ppm_print_summary(ppm_cfg_t *ppm_cfg)
     if (!ppm_cfg->enabled)
         return;
 
-    LogMessage("===============================================================================\n");
     if(ppm_cfg->max_pkt_ticks)
     {
-        LogMessage("Packet Performance Summary:\n");
+        LogLabel("packet performance");
 
-        LogMessage("   max packet time       : %g usecs\n",
+        LogStat("max packet time (usecs)",
             ppm_ticks_to_usecs(ppm_cfg->max_pkt_ticks));
 
-        LogMessage("   packet events         : %u\n",
-            (unsigned int)ppm_stats.pkt_event_cnt);
+        LogCount("packet events",
+            (unsigned int)g_ppm_stats.pkt_event_cnt);
 
-        if( ppm_stats.tot_pkts )
-            LogMessage("   avg pkt time          : %g usecs\n",
-                ppm_ticks_to_usecs((PPM_TICKS)(ppm_stats.tot_pkt_time/
-                    ppm_stats.tot_pkts)));
+        if( g_ppm_stats.tot_pkts )
+            LogStat("avg pkt time (usecs)",
+                ppm_ticks_to_usecs((PPM_TICKS)(g_ppm_stats.tot_pkt_time/
+                    g_ppm_stats.tot_pkts)));
     }
 
     if(ppm_cfg->max_rule_ticks)
     {
-        LogMessage("Rule Performance Summary:\n");
+        LogLabel("rule performance");
 
-        LogMessage("   max rule time         : %lu usecs\n",
+        LogCount("max rule time (usecs)",
             (unsigned long)(ppm_cfg->max_rule_ticks/ppm_tpu));
 
-        LogMessage("   rule events           : %u\n",
-            (unsigned int)ppm_stats.rule_event_cnt);
+        LogCount("rule events",
+            (unsigned int)g_ppm_stats.rule_event_cnt);
 
-        if( ppm_stats.tot_rules )
-            LogMessage("   avg rule time         : %g usecs\n",
-                ppm_ticks_to_usecs((PPM_TICKS)(ppm_stats.tot_rule_time/
-                    ppm_stats.tot_rules)));
+        if( g_ppm_stats.tot_rules )
+            LogStat("avg rule time (usecs)", 
+                ppm_ticks_to_usecs((PPM_TICKS)(g_ppm_stats.tot_rule_time/
+                    g_ppm_stats.tot_rules)));
 
-        if( ppm_stats.tot_nc_rules )
-            LogMessage("   avg nc-rule time      : %g usecs\n",
-                ppm_ticks_to_usecs((PPM_TICKS)(ppm_stats.tot_nc_rule_time/
-                    ppm_stats.tot_nc_rules)));
+        if( g_ppm_stats.tot_nc_rules )
+            LogStat("avg nc-rule time (usecs)",
+                ppm_ticks_to_usecs((PPM_TICKS)(g_ppm_stats.tot_nc_rule_time/
+                    g_ppm_stats.tot_nc_rules)));
 
-        if( ppm_stats.tot_pcre_rules )
-            LogMessage("   avg nc-pcre-rule time : %g usecs\n",
-                ppm_ticks_to_usecs((PPM_TICKS)(ppm_stats.tot_pcre_rule_time/
-                    ppm_stats.tot_pcre_rules)));
+        if( g_ppm_stats.tot_pcre_rules )
+            LogStat("avg nc-pcre-rule time (usecs)",
+                ppm_ticks_to_usecs((PPM_TICKS)(g_ppm_stats.tot_pcre_rule_time/
+                    g_ppm_stats.tot_pcre_rules)));
 
         fpWalkOtns( 0, print_rule );
     }
index 80277c11b8b452a0615fc754fd23ab62cbdd72a1..f9de165a392d002125675bbd22f3c6d2b83f0cef 100644 (file)
@@ -324,8 +324,9 @@ void ppm_set_max_pkt_time(ppm_cfg_t *, PPM_USECS);
 void ppm_set_max_rule_time(ppm_cfg_t *, PPM_USECS);
 void ppm_set_max_suspend_time(ppm_cfg_t *, PPM_SECS);
 
-void   ppm_print_cfg(ppm_cfg_t *);
-void   ppm_print_summary(ppm_cfg_t *);
+void ppm_print_cfg(ppm_cfg_t *);
+void ppm_print_summary(ppm_cfg_t *);
+void ppm_sum_stats();
 double ppm_ticks_to_usecs( PPM_TICKS );
 
 void ppm_pkt_log(ppm_cfg_t*, Packet*);
@@ -336,7 +337,7 @@ void ppm_set_rule_event (ppm_cfg_t *, detection_option_tree_root_t *);
 void ppm_clear_rule_event (ppm_cfg_t *, detection_option_tree_root_t *);
 void ppm_set_rule(detection_option_tree_root_t *, PPM_TICKS);
 
-#define PPM_INIT()            ppm_init()
+#define PPM_INIT(x)           ppm_init(x)
 #define PPM_PRINT_CFG(x)      ppm_print_cfg(x)
 #define PPM_PRINT_SUMMARY(x)  ppm_print_summary(x)
 
index b4e7bec0841dc49cb41c02fb3a26ec18172c9b07..29134212dbc3c443c2788479ac0c4c6620b0dd73 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "ppm.h"
 #include "main/snort_config.h"
+#include "main/snort.h"
 
 //-------------------------------------------------------------------------
 // ppm attributes
@@ -92,6 +93,14 @@ PpmModule::PpmModule() : Module("ppm", ppm_params) { }
 const RuleMap* PpmModule::get_rules() const
 { return ppm_rules; }
 
+bool PpmModule::begin(const char*, int, SnortConfig* sc)
+{
+    if ( !PPM_ENABLED() )
+        PPM_INIT(&sc->ppm_cfg);
+
+    return true;
+}
+
 bool PpmModule::set(const char*, Value& v, SnortConfig* sc)
 {
     if ( v.is("max_pkt_time") )
index 92148b73a84685ce010922498effcdd9531682ca..fd5c1be1ec8a544c2605f894742ee697b428ab65 100644 (file)
@@ -39,6 +39,8 @@ class PpmModule : public Module
 {
 public:
     PpmModule();
+
+    bool begin(const char*, int, SnortConfig*);
     bool set(const char*, Value&, SnortConfig*);
 
     const RuleMap* get_rules() const;
index 00bb909e906c25b9e22274ada345750bc09c3802..808fccb173eb6133d71ade3fdf40e8b0022a8665 100644 (file)
@@ -70,7 +70,7 @@ static inline void LogSeparator()
     LogMessage("%s\n", STATS_SEPARATOR);
 }
 
-static inline void LogLabel(const char* s)
+void LogLabel(const char* s)
 {
     if ( *s == ' ' )
     {
@@ -83,12 +83,12 @@ static inline void LogLabel(const char* s)
     }
 }
 
-static inline void LogCount (const char* s, uint64_t c)
+void LogCount (const char* s, uint64_t c)
 {
     LogMessage("%25.25s: " STDu64 "\n", s, c);
 }
 
-static inline void LogStat (const char* s, uint64_t n, uint64_t tot)
+void LogStat (const char* s, uint64_t n, uint64_t tot)
 {
 #ifdef VALGRIND_TESTING
     LogMessage("%25.25s: " FMTu64("-12") "\n", s, n);
@@ -97,6 +97,11 @@ static inline void LogStat (const char* s, uint64_t n, uint64_t tot)
 #endif
 }
 
+void LogStat (const char* s, double d)
+{
+    LogMessage("%25.25s: %g\n", s, d);
+}
+
 //-------------------------------------------------------------------------
 
 static struct timeval starttime, endtime;
@@ -246,9 +251,7 @@ void DropStats()
 {
     const DAQ_Stats_t* pkt_stats = &g_daq_stats;
 
-#ifdef PPM_MGR
-    PPM_PRINT_SUMMARY(&snort_conf->ppm_cfg);
-#endif
+    LogLabel("Basic");
 
     {
         uint64_t pkts_out, pkts_inj;
@@ -297,6 +300,7 @@ void DropStats()
     PacketManager::dump_stats();
     //mpse_print_qinfo();
 
+    LogLabel("Modules");
     ModuleManager::dump_stats(snort_conf);
 
     // ensure proper counting of log_limit
@@ -306,8 +310,12 @@ void DropStats()
     if ( gpc.total_alert_pkts == gpc.alert_pkts )
         gpc.total_alert_pkts = 0;
 
+    LogLabel("Summary");
     show_stats((PegCount*)&gpc, pc_names, array_size(pc_names), "detection");
 
+#ifdef PPM_MGR
+    PPM_PRINT_SUMMARY(&snort_conf->ppm_cfg);
+#endif
     proc_stats.attribute_table_hosts = SFAT_NumberOfHosts();
     show_stats((PegCount*)&proc_stats, proc_names, array_size(proc_names), "process");
 }
index 5c31f2b067a0c613344a1ff86b3d3a4ed2f3de21..27decde79895365657fb8837a497722708dca656 100644 (file)
@@ -70,6 +70,11 @@ struct ProcessCount
 extern ProcessCount proc_stats;
 extern THREAD_LOCAL PacketCount pc; 
 
+void LogLabel(const char*);
+void LogCount(const char*, uint64_t);
+void LogStat(const char*, uint64_t n, uint64_t tot);
+void LogStat(const char*, double);
+
 void sum_stats(PegCount* sums, PegCount* counts, unsigned n);
 void show_stats(PegCount*, const char* names[], unsigned n,
     const char* module_name = nullptr);
index 6a42e059c8c12f7adce8bac4981eb980cdab9bbe..88dad42dcf28a01bdb8fbabe24005ab586e30255 100644 (file)
@@ -134,7 +134,7 @@ int DisplayBanner(void)
 
 /****************************************************************************
  *
- * Function: ts_print(register const struct, char *)
+ * Function: ts_print(const struct, char *)
  *
  * Purpose: Generate a time stamp and stuff it in a buffer.  This one has
  *          millisecond precision.  Oh yeah, I ripped this code off from
@@ -146,9 +146,9 @@ int DisplayBanner(void)
  * Returns: void function
  *
  ****************************************************************************/
-void ts_print(register const struct timeval *tvp, char *timebuf)
+void ts_print(const struct timeval *tvp, char *timebuf)
 {
-    register int s;
+    int s;
     int    localzone;
     time_t Time;
     struct timeval tv;
@@ -511,8 +511,8 @@ void CleanupProtoNames(void)
  ****************************************************************************/
 char *read_infile(char *fname)
 {
-    register int fd, cc;
-    register char *cp, *cmt;
+    int fd, cc;
+    char *cp, *cmt;
     struct stat buf;
 
     fd = open(fname, O_RDONLY);
index f8b1998635dd0b722382b47d4c4dd6afc3dec5a1..c53b4e4a4ea5f61d03578dfb4f179078ef8645d4 100644 (file)
@@ -474,17 +474,6 @@ static void event2_6_dump(u2record *record) {
 
 }
 
-static inline void print_uuid (const char* label, uint8_t* data)
-{
-#ifdef HAVE_LIBUUID
-    char buf[37];
-    uuid_unparse(data, buf);
-    printf("%s: %s\n", label, buf);
-#else
-    printf("%s: %.*s\n", label, 16, data);
-#endif
-}
-
 #define LOG_CHARS 16
 
 static void LogBuffer (const uint8_t* p, unsigned n)