From: Russ Combs Date: Wed, 30 Jul 2014 02:14:11 +0000 (-0400) Subject: StreamSplitter::reassemble() and Xcode fixes, etc. X-Git-Tag: 3.0.0-233~1434^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=af8e971caae6e2a9fe86b4f78b46178140afd23d;p=thirdparty%2Fsnort3.git StreamSplitter::reassemble() and Xcode fixes, etc. --- diff --git a/ChangeLog b/ChangeLog index b56c87280..d39dedc55 100644 --- 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 diff --git a/src/file_api/file_mime_process.cc b/src/file_api/file_mime_process.cc index c5d2b1498..4b89f023f 100644 --- a/src/file_api/file_mime_process.cc +++ b/src/file_api/file_mime_process.cc @@ -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 * diff --git a/src/framework/range.cc b/src/framework/range.cc index b78990421..c36b1ae72 100644 --- a/src/framework/range.cc +++ b/src/framework/range.cc @@ -20,7 +20,9 @@ #include "range.h" +#include #include + #include using namespace std; diff --git a/src/main/modules.cc b/src/main/modules.cc index 1333db781..18b35e785 100644 --- a/src/main/modules.cc +++ b/src/main/modules.cc @@ -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" }, diff --git a/src/main/snort.cc b/src/main/snort.cc index 9a5cfbffd..c2926ae33 100644 --- a/src/main/snort.cc +++ b/src/main/snort.cc @@ -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(); diff --git a/src/main/snort_config.cc b/src/main/snort_config.cc index 5ab2f7b45..ff73f936b 100644 --- a/src/main/snort_config.cc +++ b/src/main/snort_config.cc @@ -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 diff --git a/src/managers/packet_manager.cc b/src/managers/packet_manager.cc index 478ba0bb3..df750f977 100644 --- a/src/managers/packet_manager.cc +++ b/src/managers/packet_manager.cc @@ -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) diff --git a/src/search_engines/acsmx2.cc b/src/search_engines/acsmx2.cc index 3884d15b7..ea5ac0ab6 100644 --- a/src/search_engines/acsmx2.cc +++ b/src/search_engines/acsmx2.cc @@ -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) { diff --git a/src/search_engines/bnfa_search.cc b/src/search_engines/bnfa_search.cc index 247ad883d..54390050e 100644 --- a/src/search_engines/bnfa_search.cc +++ b/src/search_engines/bnfa_search.cc @@ -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 */ diff --git a/src/service_inspectors/http_inspect/hi_paf.cc b/src/service_inspectors/http_inspect/hi_paf.cc index ca54493d9..1537c49f4 100644 --- a/src/service_inspectors/http_inspect/hi_paf.cc +++ b/src/service_inspectors/http_inspect/hi_paf.cc @@ -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() { } diff --git a/src/stream/stream_splitter.cc b/src/stream/stream_splitter.cc index c303f0595..41c2f638b 100644 --- a/src/stream/stream_splitter.cc +++ b/src/stream/stream_splitter.cc @@ -20,9 +20,33 @@ #include "stream/stream_splitter.h" +#include +#include + +#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(); diff --git a/src/stream/stream_splitter.h b/src/stream/stream_splitter.h index de18a87ab..3690aaf02 100644 --- a/src/stream/stream_splitter.h +++ b/src/stream/stream_splitter.h @@ -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(); diff --git a/src/stream/tcp/ips_stream_size.cc b/src/stream/tcp/ips_stream_size.cc index f08c16e8a..891c8e016 100644 --- a/src/stream/tcp/ips_stream_size.cc +++ b/src/stream/tcp/ips_stream_size.cc @@ -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); diff --git a/src/stream/tcp/tcp_session.cc b/src/stream/tcp/tcp_session.cc index e46e88c66..8412b62c8 100644 --- a/src/stream/tcp/tcp_session.cc +++ b/src/stream/tcp/tcp_session.cc @@ -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, diff --git a/src/stream/tcp/tcp_session.h b/src/stream/tcp/tcp_session.h index 7f4fb9733..73073548b 100644 --- a/src/stream/tcp/tcp_session.h +++ b/src/stream/tcp/tcp_session.h @@ -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; diff --git a/src/time/ppm.cc b/src/time/ppm.cc index 97698afb7..414529bc8 100644 --- a/src/time/ppm.cc +++ b/src/time/ppm.cc @@ -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 ); } diff --git a/src/time/ppm.h b/src/time/ppm.h index 80277c11b..f9de165a3 100644 --- a/src/time/ppm.h +++ b/src/time/ppm.h @@ -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) diff --git a/src/time/ppm_module.cc b/src/time/ppm_module.cc index b4e7bec08..29134212d 100644 --- a/src/time/ppm_module.cc +++ b/src/time/ppm_module.cc @@ -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") ) diff --git a/src/time/ppm_module.h b/src/time/ppm_module.h index 92148b73a..fd5c1be1e 100644 --- a/src/time/ppm_module.h +++ b/src/time/ppm_module.h @@ -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; diff --git a/src/utils/stats.cc b/src/utils/stats.cc index 00bb909e9..808fccb17 100644 --- a/src/utils/stats.cc +++ b/src/utils/stats.cc @@ -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"); } diff --git a/src/utils/stats.h b/src/utils/stats.h index 5c31f2b06..27decde79 100644 --- a/src/utils/stats.h +++ b/src/utils/stats.h @@ -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); diff --git a/src/utils/util.cc b/src/utils/util.cc index 6a42e059c..88dad42dc 100644 --- a/src/utils/util.cc +++ b/src/utils/util.cc @@ -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); diff --git a/tools/u2spewfoo/u2spewfoo.cc b/tools/u2spewfoo/u2spewfoo.cc index f8b199863..c53b4e4a4 100644 --- a/tools/u2spewfoo/u2spewfoo.cc +++ b/tools/u2spewfoo/u2spewfoo.cc @@ -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)