From: Michael Altizer (mialtize) Date: Tue, 7 Jul 2020 23:46:26 +0000 (+0000) Subject: Merge pull request #2275 in SNORT/snort3 from ~DAVMCPHE/snort3:meta-ack to master X-Git-Tag: 3.0.2-2~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1d3e74273c62604de6b1ad39f18c11543306aaa4;p=thirdparty%2Fsnort3.git Merge pull request #2275 in SNORT/snort3 from ~DAVMCPHE/snort3:meta-ack to master Squashed commit of the following: commit 96d510b820a6d46d0a6dd43de25677bc1c961d78 Author: davis mcpherson Date: Fri Jun 19 10:28:38 2020 -0400 stream_tcp: eliminate direct references to the Packet* wherevever possible within the TCP state machine context stream_tcp: implement meta-ack pseudo packet as thread local that is resued on each meta-ack TSD commit 59e6da4498451438544c50482c3a417520658841 Author: davis mcpherson Date: Thu Jun 18 07:58:58 2020 -0400 stream_tcp: eliminate use of STREAM_INSERT_OK as return code, it conveyed no useful information and was ultimately unused stream_tcp: coding style improvements commit 530dde13e8ea95613dc3f1bef471a7b58c9860f0 Author: davis mcpherson Date: Fri Jun 12 18:49:37 2020 -0400 stream_tcp: implement support for processing meta-ack information when present --- diff --git a/src/flow/flow.h b/src/flow/flow.h index f093d7978..a2b31970c 100644 --- a/src/flow/flow.h +++ b/src/flow/flow.h @@ -93,9 +93,7 @@ #define STREAM_STATE_TIMEDOUT 0x0080 #define STREAM_STATE_UNREACH 0x0100 #define STREAM_STATE_CLOSED 0x0800 -#define STREAM_STATE_IGNORE 0x1000 -#define STREAM_STATE_NO_PICKUP 0x2000 -#define STREAM_STATE_BLOCK_PENDING 0x4000 +#define STREAM_STATE_BLOCK_PENDING 0x1000 class BitOp; class Session; diff --git a/src/protocols/tcp.h b/src/protocols/tcp.h index c92bd0349..3a6bb3fe8 100644 --- a/src/protocols/tcp.h +++ b/src/protocols/tcp.h @@ -143,7 +143,7 @@ struct TCPHdr inline uint16_t raw_src_port() const { return th_sport; } - inline uint16_t raw_dst_len() const + inline uint16_t raw_dst_port() const { return th_dport; } inline uint32_t raw_seq() const diff --git a/src/stream/tcp/held_packet_queue.h b/src/stream/tcp/held_packet_queue.h index fae51114a..6a9961d1e 100644 --- a/src/stream/tcp/held_packet_queue.h +++ b/src/stream/tcp/held_packet_queue.h @@ -41,9 +41,7 @@ public: } bool has_expired() - { - return expired; - } + { return expired; } TcpStreamTracker& get_tracker() const { return tracker; } DAQ_Msg_h get_daq_msg() const { return daq_msg; } @@ -78,11 +76,10 @@ public: // Return the timeout in milliseconds. uint32_t get_timeout() const - { - return timeout.tv_sec * 1000 + timeout.tv_usec / 1000; - } + { return timeout.tv_sec * 1000 + timeout.tv_usec / 1000; } - bool empty() const { return q.empty(); } + bool empty() const + { return q.empty(); } // This must be called at reload time only, with now = reload time. // Return true if, upon exit, there are expired packets in the queue. diff --git a/src/stream/tcp/ips_stream_size.cc b/src/stream/tcp/ips_stream_size.cc index 70f684ecd..58584a773 100644 --- a/src/stream/tcp/ips_stream_size.cc +++ b/src/stream/tcp/ips_stream_size.cc @@ -219,14 +219,10 @@ bool SizeModule::set(const char*, Value& v, SnortConfig*) //------------------------------------------------------------------------- static Module* size_mod_ctor() -{ - return new SizeModule; -} +{ return new SizeModule; } static void mod_dtor(Module* m) -{ - delete m; -} +{ delete m; } static IpsOption* size_ctor(Module* p, OptTreeNode*) { @@ -235,9 +231,7 @@ static IpsOption* size_ctor(Module* p, OptTreeNode*) } static void opt_dtor(IpsOption* p) -{ - delete p; -} +{ delete p; } static const IpsApi size_api = { diff --git a/src/stream/tcp/segment_overlap_editor.cc b/src/stream/tcp/segment_overlap_editor.cc index 58d6c5ed3..dd1422138 100644 --- a/src/stream/tcp/segment_overlap_editor.cc +++ b/src/stream/tcp/segment_overlap_editor.cc @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// segment_overlap_editor.cc author davis mcpherson +// segment_overlap_editor.cc author davis mcpherson // Created on: Oct 11, 2015 #ifdef HAVE_CONFIG_H @@ -25,8 +25,8 @@ #include "segment_overlap_editor.h" +#include "detection/detection_engine.h" #include "log/messages.h" -#include "packet_tracer/packet_tracer.h" #include "tcp_module.h" #include "tcp_normalizers.h" @@ -34,21 +34,6 @@ using namespace snort; -static void set_retransmit_flag(Packet* p) -{ - if ( PacketTracer::is_active() ) - { - PacketTracer::log("Packet was retransmitted and %s from the retry queue.\n", - p->is_retry() ? "is" : "is not"); - } - - // Mark the packet as being a re-transmit if it's not from the retry - // queue. That way we can avoid adding re-transmitted packets to - // the retry queue. - if ( !p->is_retry() ) - p->packet_flags |= PKT_RETRANSMIT; -} - void SegmentOverlapState::init_sos(TcpSession* ssn, StreamPolicy pol) { session = ssn; @@ -89,17 +74,17 @@ void SegmentOverlapState::init_soe( this->left = left; this->right = right; - seq = tsd.get_seg_seq(); + seq = tsd.get_seq(); seq_end = tsd.get_end_seq(); - len = tsd.get_seg_len(); + len = tsd.get_len(); overlap = 0; slide = 0; trunc_len = 0; rdata = tsd.get_pkt()->data; - rsize = tsd.get_seg_len(); - rseq = tsd.get_seg_seq(); + rsize = tsd.get_len(); + rseq = tsd.get_seq(); keep_segment = true; } @@ -110,12 +95,12 @@ bool SegmentOverlapEditor::is_segment_retransmit( // Don't want to count retransmits as overlaps or do anything // else with them. Account for retransmits of multiple PDUs // in one segment. - bool* pb = (trs.sos.rseq == trs.sos.tsd->get_seg_seq()) ? full_retransmit : nullptr; + bool* pb = (trs.sos.rseq == trs.sos.tsd->get_seq()) ? full_retransmit : nullptr; if ( trs.sos.right->is_retransmit(trs.sos.rdata, trs.sos.rsize, trs.sos.rseq, trs.sos.right->i_len, pb) ) { - set_retransmit_flag(trs.sos.tsd->get_pkt()); + trs.sos.tsd->set_retransmit_flag(); if ( !(*full_retransmit) ) { @@ -132,7 +117,7 @@ bool SegmentOverlapEditor::is_segment_retransmit( if ( trs.sos.rsize == 0 ) { // All data was retransmitted - trs.sos.session->retransmit_process(trs.sos.tsd->get_pkt()); + snort::DetectionEngine::disable_content(trs.sos.tsd->get_pkt()); trs.sos.keep_segment = false; } @@ -142,17 +127,13 @@ bool SegmentOverlapEditor::is_segment_retransmit( return false; } -int SegmentOverlapEditor::eval_left(TcpReassemblerState& trs) +void SegmentOverlapEditor::eval_left(TcpReassemblerState& trs) { - int rc = STREAM_INSERT_OK; - if ( trs.sos.left ) - rc = insert_left_overlap(trs); - - return rc; + insert_left_overlap(trs); } -int SegmentOverlapEditor::eval_right(TcpReassemblerState& trs) +void SegmentOverlapEditor::eval_right(TcpReassemblerState& trs) { while ( trs.sos.right && SEQ_LT(trs.sos.right->i_seq, trs.sos.seq_end) ) { @@ -163,17 +144,15 @@ int SegmentOverlapEditor::eval_right(TcpReassemblerState& trs) // Treat sequence number overlap as a retransmission, // only check right side since left side happens rarely - trs.sos.session->retransmit_handle(trs.sos.tsd->get_pkt()); - + trs.sos.session->flow->call_handlers(trs.sos.tsd->get_pkt(), false); if ( trs.sos.overlap < trs.sos.right->i_len ) { if ( trs.sos.right->is_retransmit(trs.sos.rdata, trs.sos.rsize, trs.sos.rseq, trs.sos.right->i_len, nullptr) ) { - set_retransmit_flag(trs.sos.tsd->get_pkt()); - // All data was retransmitted - trs.sos.session->retransmit_process(trs.sos.tsd->get_pkt()); + trs.sos.tsd->set_retransmit_flag(); + snort::DetectionEngine::disable_content(trs.sos.tsd->get_pkt()); trs.sos.keep_segment = false; } else @@ -200,13 +179,9 @@ int SegmentOverlapEditor::eval_right(TcpReassemblerState& trs) tcpStats.overlaps++; trs.sos.overlap_count++; - int rc = insert_full_overlap(trs); - if ( rc != STREAM_INSERT_OK ) - return rc; + insert_full_overlap(trs); } } - - return STREAM_INSERT_OK; } void SegmentOverlapEditor::drop_old_segment(TcpReassemblerState& trs) @@ -216,13 +191,13 @@ void SegmentOverlapEditor::drop_old_segment(TcpReassemblerState& trs) delete_reassembly_segment(trs, drop_seg); } -int SegmentOverlapEditor::left_overlap_keep_first(TcpReassemblerState& trs) +void SegmentOverlapEditor::left_overlap_keep_first(TcpReassemblerState& trs) { // NOTE that overlap will always be less than left->size since // seq is always greater than left->seq assert(SEQ_GT(trs.sos.seq, trs.sos.left->i_seq)); - trs.sos.len = trs.sos.tsd->get_seg_len(); + trs.sos.len = trs.sos.tsd->get_len(); trs.sos.overlap = trs.sos.left->i_seq + trs.sos.left->i_len - trs.sos.seq; if ( trs.sos.len < trs.sos.overlap ) @@ -237,10 +212,8 @@ int SegmentOverlapEditor::left_overlap_keep_first(TcpReassemblerState& trs) { if (trs.sos.tcp_ips_data == NORM_MODE_ON) { - unsigned offset = trs.sos.tsd->get_seg_seq() - trs.sos.left->i_seq; - memcpy(const_cast(trs.sos.tsd->get_pkt()->data), - trs.sos.left->data + offset, trs.sos.tsd->get_seg_len()); - trs.sos.tsd->get_pkt()->packet_flags |= PKT_MODIFIED; + unsigned offset = trs.sos.tsd->get_seq() - trs.sos.left->i_seq; + trs.sos.tsd->rewrite_payload(0, trs.sos.left->data + offset); } tcp_norm_stats[PC_TCP_IPS_DATA][trs.sos.tcp_ips_data]++; } @@ -248,12 +221,10 @@ int SegmentOverlapEditor::left_overlap_keep_first(TcpReassemblerState& trs) { if ( trs.sos.tcp_ips_data == NORM_MODE_ON ) { - unsigned offset = trs.sos.tsd->get_seg_seq() - trs.sos.left->i_seq; - unsigned length = trs.sos.left->i_seq + trs.sos.left->i_len - - trs.sos.tsd->get_seg_seq(); - memcpy(const_cast(trs.sos.tsd->get_pkt()->data), - trs.sos.left->data + offset, length); - trs.sos.tsd->get_pkt()->packet_flags |= PKT_MODIFIED; + unsigned offset = trs.sos.tsd->get_seq() - trs.sos.left->i_seq; + unsigned length = + trs.sos.left->i_seq + trs.sos.left->i_len - trs.sos.tsd->get_seq(); + trs.sos.tsd->rewrite_payload(0, trs.sos.left->data + offset, length); } tcp_norm_stats[PC_TCP_IPS_DATA][trs.sos.tcp_ips_data]++; @@ -261,15 +232,13 @@ int SegmentOverlapEditor::left_overlap_keep_first(TcpReassemblerState& trs) trs.sos.seq += trs.sos.overlap; } - - return STREAM_INSERT_OK; } -int SegmentOverlapEditor::left_overlap_trim_first(TcpReassemblerState& trs) +void SegmentOverlapEditor::left_overlap_trim_first(TcpReassemblerState& trs) { assert(SEQ_GT(trs.sos.seq, trs.sos.left->i_seq)); - trs.sos.len = trs.sos.tsd->get_seg_len(); + trs.sos.len = trs.sos.tsd->get_len(); trs.sos.overlap = trs.sos.left->i_seq + trs.sos.left->i_len - trs.sos.seq; if ( trs.sos.overlap > 0 ) @@ -290,15 +259,13 @@ int SegmentOverlapEditor::left_overlap_trim_first(TcpReassemblerState& trs) trs.sos.seg_bytes_logical -= trs.sos.overlap; } } - - return STREAM_INSERT_OK; } -int SegmentOverlapEditor::left_overlap_keep_last(TcpReassemblerState& trs) +void SegmentOverlapEditor::left_overlap_keep_last(TcpReassemblerState& trs) { assert(SEQ_GT(trs.sos.seq, trs.sos.left->i_seq)); - trs.sos.len = trs.sos.tsd->get_seg_len(); + trs.sos.len = trs.sos.tsd->get_len(); trs.sos.overlap = trs.sos.left->i_seq + trs.sos.left->i_len - trs.sos.seq; if ( trs.sos.overlap > 0 ) @@ -314,17 +281,14 @@ int SegmentOverlapEditor::left_overlap_keep_last(TcpReassemblerState& trs) * Need to duplicate left. Adjust that seq by + (seq + len) and * size by - (seq + len - left->i_seq). */ - int rc = dup_reassembly_segment(trs, trs.sos.left, &trs.sos.right); - - if ( rc != STREAM_INSERT_OK ) - return rc; + dup_reassembly_segment(trs, trs.sos.left, &trs.sos.right); - trs.sos.left->c_len -= ( int16_t )trs.sos.overlap; - trs.sos.left->i_len -= ( int16_t )trs.sos.overlap; + trs.sos.left->c_len -= (int16_t)trs.sos.overlap; + trs.sos.left->i_len -= (int16_t)trs.sos.overlap; trs.sos.right->i_seq = trs.sos.seq + trs.sos.len; trs.sos.right->c_seq = trs.sos.right->i_seq; - uint16_t delta = ( int16_t )( trs.sos.right->i_seq - trs.sos.left->i_seq ); + uint16_t delta = (int16_t)(trs.sos.right->i_seq - trs.sos.left->i_seq); trs.sos.right->c_len -= delta; trs.sos.right->i_len -= delta; trs.sos.right->offset += delta; @@ -334,12 +298,10 @@ int SegmentOverlapEditor::left_overlap_keep_last(TcpReassemblerState& trs) else { trs.sos.left->c_len -= (int16_t)trs.sos.overlap; - trs.sos.left->i_len -= ( int16_t )trs.sos.overlap; + trs.sos.left->i_len -= (int16_t)trs.sos.overlap; trs.sos.seg_bytes_logical -= trs.sos.overlap; } } - - return STREAM_INSERT_OK; } void SegmentOverlapEditor::right_overlap_truncate_existing(TcpReassemblerState& trs) @@ -367,12 +329,10 @@ void SegmentOverlapEditor::right_overlap_truncate_new(TcpReassemblerState& trs) { if (trs.sos.tcp_ips_data == NORM_MODE_ON) { - unsigned offset = trs.sos.right->i_seq - trs.sos.tsd->get_seg_seq(); - unsigned length = trs.sos.tsd->get_seg_seq() + trs.sos.tsd->get_seg_len() - - trs.sos.right->i_seq; - memcpy(const_cast(trs.sos.tsd->get_pkt()->data) + offset, - trs.sos.right->data, length); - trs.sos.tsd->get_pkt()->packet_flags |= PKT_MODIFIED; + unsigned offset = trs.sos.right->i_seq - trs.sos.tsd->get_seq(); + unsigned length = + trs.sos.tsd->get_seq() + trs.sos.tsd->get_len() - trs.sos.right->i_seq; + trs.sos.tsd->rewrite_payload(offset, trs.sos.right->data, length); } tcp_norm_stats[PC_TCP_IPS_DATA][trs.sos.tcp_ips_data]++; @@ -381,14 +341,12 @@ void SegmentOverlapEditor::right_overlap_truncate_new(TcpReassemblerState& trs) // REASSEMBLY_POLICY_FIRST: // REASSEMBLY_POLICY_VISTA: -int SegmentOverlapEditor::full_right_overlap_truncate_new(TcpReassemblerState& trs) +void SegmentOverlapEditor::full_right_overlap_truncate_new(TcpReassemblerState& trs) { if ( trs.sos.tcp_ips_data == NORM_MODE_ON ) { - unsigned offset = trs.sos.right->i_seq - trs.sos.tsd->get_seg_seq(); - memcpy(const_cast(trs.sos.tsd->get_pkt()->data) + offset, - trs.sos.right->data, trs.sos.right->i_len); - trs.sos.tsd->get_pkt()->packet_flags |= PKT_MODIFIED; + unsigned offset = trs.sos.right->i_seq - trs.sos.tsd->get_seq(); + trs.sos.tsd->rewrite_payload(offset, trs.sos.right->data, trs.sos.right->i_len); } tcp_norm_stats[PC_TCP_IPS_DATA][trs.sos.tcp_ips_data]++; @@ -403,7 +361,7 @@ int SegmentOverlapEditor::full_right_overlap_truncate_new(TcpReassemblerState& t /* Adjusted seq is fully overlapped */ if ( SEQ_EQ(trs.sos.seq, trs.sos.seq_end) ) - return STREAM_INSERT_OK; + return; } else { @@ -412,11 +370,9 @@ int SegmentOverlapEditor::full_right_overlap_truncate_new(TcpReassemblerState& t /* insert this one, and see if we need to chunk it up Adjust slide so that is correct relative to orig seq */ - trs.sos.slide = trs.sos.seq - trs.sos.tsd->get_seg_seq(); - int rc = add_reassembly_segment(trs, *trs.sos.tsd, trs.sos.len, trs.sos.slide, + trs.sos.slide = trs.sos.seq - trs.sos.tsd->get_seq(); + add_reassembly_segment(trs, *trs.sos.tsd, trs.sos.len, trs.sos.slide, trs.sos.trunc_len, trs.sos.seq, trs.sos.left); - if ( rc != STREAM_INSERT_OK ) - return rc; // Set seq to end of right since overlap was greater than or equal to right->size and // inserted seq has been truncated to beginning of right and reset trunc length to 0 @@ -426,15 +382,13 @@ int SegmentOverlapEditor::full_right_overlap_truncate_new(TcpReassemblerState& t trs.sos.right = trs.sos.right->next; trs.sos.trunc_len = 0; } - - return STREAM_INSERT_OK; } // REASSEMBLY_POLICY_WINDOWS: // REASSEMBLY_POLICY_WINDOWS2K3: // REASSEMBLY_POLICY_BSD: // REASSEMBLY_POLICY_MACOS: -int SegmentOverlapEditor::full_right_overlap_os1(TcpReassemblerState& trs) +void SegmentOverlapEditor::full_right_overlap_os1(TcpReassemblerState& trs) { if ( SEQ_GEQ(trs.sos.seq_end, trs.sos.right->i_seq + trs.sos.right->i_len) and SEQ_LT(trs.sos.seq, trs.sos.right->i_seq) ) @@ -442,19 +396,13 @@ int SegmentOverlapEditor::full_right_overlap_os1(TcpReassemblerState& trs) drop_old_segment(trs); } else - { - int rc = full_right_overlap_truncate_new(trs); - if ( rc != STREAM_INSERT_OK ) - return rc; - } - - return STREAM_INSERT_OK; + full_right_overlap_truncate_new(trs); } // REASSEMBLY_POLICY_LINUX: // REASSEMBLY_POLICY_HPUX10: // REASSEMBLY_POLICY_IRIX: -int SegmentOverlapEditor::full_right_overlap_os2(TcpReassemblerState& trs) +void SegmentOverlapEditor::full_right_overlap_os2(TcpReassemblerState& trs) { if ( SEQ_GEQ(trs.sos.seq_end, trs.sos.right->i_seq + trs.sos.right->i_len) and SEQ_LT(trs.sos.seq, trs.sos.right->i_seq) ) @@ -467,18 +415,12 @@ int SegmentOverlapEditor::full_right_overlap_os2(TcpReassemblerState& trs) drop_old_segment(trs); } else - { - int rc = full_right_overlap_truncate_new(trs); - if ( rc != STREAM_INSERT_OK ) - return rc; - } - - return STREAM_INSERT_OK; + full_right_overlap_truncate_new(trs); } // REASSEMBLY_POLICY_HPUX11: // REASSEMBLY_POLICY_SOLARIS: -int SegmentOverlapEditor::full_right_overlap_os3(TcpReassemblerState& trs) +void SegmentOverlapEditor::full_right_overlap_os3(TcpReassemblerState& trs) { // If this packet is wholly overlapping and the same size as a previous one and we have not // received the one immediately preceding, we take the FIRST. @@ -495,24 +437,17 @@ int SegmentOverlapEditor::full_right_overlap_os3(TcpReassemblerState& trs) trs.sos.right = trs.sos.right->next; } else - { drop_old_segment(trs); - } - - return STREAM_INSERT_OK; } // REASSEMBLY_POLICY_OLD_LINUX: // REASSEMBLY_POLICY_LAST: -int SegmentOverlapEditor::full_right_overlap_os4(TcpReassemblerState& trs) -{ - drop_old_segment(trs); - return STREAM_INSERT_OK; -} +void SegmentOverlapEditor::full_right_overlap_os4(TcpReassemblerState& trs) +{ drop_old_segment(trs); } -int SegmentOverlapEditor::full_right_overlap_os5(TcpReassemblerState& trs) +void SegmentOverlapEditor::full_right_overlap_os5(TcpReassemblerState& trs) { - return full_right_overlap_truncate_new(trs); + full_right_overlap_truncate_new(trs); } void SegmentOverlapEditor::print(TcpReassemblerState& trs) @@ -525,4 +460,3 @@ void SegmentOverlapEditor::print(TcpReassemblerState& trs) LogMessage(" seg_bytes_total: %d\n", trs.sos.seg_bytes_total); LogMessage(" seg_bytes_logical: %d\n", trs.sos.seg_bytes_logical); } - diff --git a/src/stream/tcp/segment_overlap_editor.h b/src/stream/tcp/segment_overlap_editor.h index 813f0a94b..116151ebd 100644 --- a/src/stream/tcp/segment_overlap_editor.h +++ b/src/stream/tcp/segment_overlap_editor.h @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// segment_overlap_editor.h author davis mcpherson +// segment_overlap_editor.h author davis mcpherson // Created on: Oct 11, 2015 #ifndef SEGMENT_OVERLAP_EDITOR_H @@ -28,8 +28,6 @@ class TcpSession; class TcpStreamTracker; -#define STREAM_INSERT_OK 0 // FIXIT-RC replace with bool CRC: if useful else just delete - struct SegmentOverlapState { TcpSession* session; @@ -87,33 +85,33 @@ protected: SegmentOverlapEditor() { } virtual ~SegmentOverlapEditor() = default; - int eval_left(TcpReassemblerState&); - int eval_right(TcpReassemblerState&); + void eval_left(TcpReassemblerState&); + void eval_right(TcpReassemblerState&); virtual bool is_segment_retransmit(TcpReassemblerState&, bool*); virtual void drop_old_segment(TcpReassemblerState&); - virtual int left_overlap_keep_first(TcpReassemblerState&); - virtual int left_overlap_trim_first(TcpReassemblerState&); - virtual int left_overlap_keep_last(TcpReassemblerState&); + virtual void left_overlap_keep_first(TcpReassemblerState&); + virtual void left_overlap_trim_first(TcpReassemblerState&); + virtual void left_overlap_keep_last(TcpReassemblerState&); virtual void right_overlap_truncate_existing(TcpReassemblerState&); virtual void right_overlap_truncate_new(TcpReassemblerState&); - virtual int full_right_overlap_truncate_new(TcpReassemblerState&); - virtual int full_right_overlap_os1(TcpReassemblerState&); - virtual int full_right_overlap_os2(TcpReassemblerState&); - virtual int full_right_overlap_os3(TcpReassemblerState&); - virtual int full_right_overlap_os4(TcpReassemblerState&); - virtual int full_right_overlap_os5(TcpReassemblerState&); - - virtual int insert_left_overlap(TcpReassemblerState&) = 0; + virtual void full_right_overlap_truncate_new(TcpReassemblerState&); + virtual void full_right_overlap_os1(TcpReassemblerState&); + virtual void full_right_overlap_os2(TcpReassemblerState&); + virtual void full_right_overlap_os3(TcpReassemblerState&); + virtual void full_right_overlap_os4(TcpReassemblerState&); + virtual void full_right_overlap_os5(TcpReassemblerState&); + + virtual void insert_left_overlap(TcpReassemblerState&) = 0; virtual void insert_right_overlap(TcpReassemblerState&) = 0; - virtual int insert_full_overlap(TcpReassemblerState&) = 0; + virtual void insert_full_overlap(TcpReassemblerState&) = 0; - virtual int add_reassembly_segment( + virtual void add_reassembly_segment( TcpReassemblerState&, TcpSegmentDescriptor&, uint16_t, uint32_t, uint32_t, uint32_t, TcpSegmentNode*) = 0; - virtual int dup_reassembly_segment(TcpReassemblerState&, TcpSegmentNode*, TcpSegmentNode**) = 0; + virtual void dup_reassembly_segment(TcpReassemblerState&, TcpSegmentNode*, TcpSegmentNode**) = 0; virtual int delete_reassembly_segment(TcpReassemblerState&, TcpSegmentNode*) = 0; virtual void print(TcpReassemblerState&); }; diff --git a/src/stream/tcp/stream_tcp.cc b/src/stream/tcp/stream_tcp.cc index e149f5e7a..59a5894f6 100644 --- a/src/stream/tcp/stream_tcp.cc +++ b/src/stream/tcp/stream_tcp.cc @@ -62,9 +62,7 @@ StreamTcp::~StreamTcp() void StreamTcp::show(const SnortConfig*) const { - if ( !config ) - return; - + assert( config ); config->show(); } diff --git a/src/stream/tcp/tcp_debug_trace.h b/src/stream/tcp/tcp_debug_trace.h index 56f56d26d..bc8253825 100644 --- a/src/stream/tcp/tcp_debug_trace.h +++ b/src/stream/tcp/tcp_debug_trace.h @@ -27,10 +27,10 @@ #include "tcp_reassemblers.h" #ifndef REG_TEST -#define S5TraceTCP(pkt, flow, tsd, evt) +#define S5TraceTCP(tsd) #else -#define LCL(p, x) ((p)->x() - (p)->get_iss()) -#define RMT(p, x, q) ((p)->x - ((q) ? (q)->get_iss() : 0)) +#define LCL(p, x) ((p).x() - (p).get_iss()) +#define RMT(p, x, q) ((p).x - (q).get_iss()) static const char* const statext[] = { @@ -42,118 +42,112 @@ 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 snort::Packet* p, TcpSegmentDescriptor*, uint32_t txd, uint32_t rxd) +inline void TraceEvent(const TcpSegmentDescriptor& tsd, uint32_t txd, uint32_t rxd) { - int i; char flags[7] = "UAPRSF"; - const snort::tcp::TCPHdr* h = p->ptrs.tcph; + const snort::tcp::TCPHdr* h = tsd.get_tcph(); const char* order = ""; + const char* meta_ack_marker = tsd.is_meta_ack_packet() ? "M" : " "; if (!h) return; - for (i = 0; i < 6; i++) + for (int i = 0; i < 6; i++) if (!((1 << (5 - i)) & h->th_flags)) flags[i] = '-'; // force relative ack to zero if not conveyed if (flags[1] != 'A') - rxd = h->ack(); // FIXIT-L SYN's seen with ack > 0 and ACK flag not set... + rxd = tsd.get_ack(); // FIXIT-L SYN's seen with ack > 0 and ACK flag not set... - if (p->packet_flags & PKT_STREAM_ORDER_OK) + if ( tsd.are_packet_flags_set(PKT_STREAM_ORDER_OK) ) order = " (ins)"; - else if (p->packet_flags & PKT_STREAM_ORDER_BAD) + else if ( tsd.are_packet_flags_set(PKT_STREAM_ORDER_BAD) ) order = " (oos)"; - uint32_t rseq = ( txd ) ? h->seq() - txd : h->seq(); - uint32_t rack = ( rxd ) ? h->ack() - rxd : h->ack(); - fprintf(stdout, "\n" FMTu64("-3") " %s=0x%02x Seq=%-4u Ack=%-4u Win=%-4hu Len=%-4hu%s\n", - //"\n" FMTu64("-3") " %s=0x%02x Seq=%-4u Ack=%-4u Win=%-4u Len=%-4u End=%-4u%s\n", - p->context->packet_number, flags, h->th_flags, rseq, rack, h->win(), p->dsize, order); + 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", + 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* lws) +inline void TraceSession(const snort::Flow* flow) { - fprintf(stdout, " LWS: ST=0x%x SF=0x%x CP=%hu SP=%hu\n", (unsigned)lws->session_state, - lws->ssn_state.session_flags, lws->client_port, lws->server_port); + fprintf(stdout, " 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 TraceState(TcpStreamTracker& a, TcpStreamTracker& b, const char* s) { - 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; + 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 ", - 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()); + " %s ST=%s UA=%-4u NS=%-4u LW=%-5u RN=%-4u RW=%-4u ISS=%-4u IRS=%-4u ", + 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->splitter and a->splitter->is_paf()) ? 2 : 0; - unsigned fpt = a->flush_policy ? 192 : 0; + unsigned paf = (a.splitter and a.splitter->is_paf()) ? 2 : 0; + unsigned fpt = a.flush_policy ? 192 : 0; - fprintf(stdout, " FP=%s:%-4u SC=%-4u FL=%-4u SL=%-5u BS=%-4u", - flushxt[a->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()); + fprintf(stdout, " FP=%s:%-4u SC=%-4u FL=%-4u SL=%-5u BS=%-4u", + flushxt[a.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(); + if ( s5_trace_enabled == 2 ) + a.reassembler.trace_segments(); fprintf(stdout, "\n"); } -inline void TraceTCP( - const snort::Packet* p, const snort::Flow* lws, TcpSegmentDescriptor* tsd, int event) +inline void TraceTCP(const TcpSegmentDescriptor& tsd) { - TcpSession* ssn = (TcpSession*)lws->session; - TcpStreamTracker* srv = ssn ? &ssn->server : nullptr; - TcpStreamTracker* cli = ssn ? &ssn->client : nullptr; + TcpSession* ssn = (TcpSession*)tsd.get_flow()->session; + assert(ssn); + TcpStreamTracker& srv = ssn->server; + TcpStreamTracker& cli = ssn->client; const char* cdir = "?", * sdir = "?"; uint32_t txd = 0, rxd = 0; - if (p->is_from_server()) + if ( tsd.is_packet_from_client() ) + { + sdir = "SRV<"; + cdir = "CLI>"; + txd = cli.get_iss(); + rxd = cli.get_irs(); + } + else { sdir = "SRV>"; cdir = "CLI<"; - - txd = srv->get_iss(); - rxd = srv->get_irs(); + txd = srv.get_iss(); + rxd = srv.get_irs(); } - else if ( p->is_from_client() ) - { - sdir = "SRV<"; - cdir = "CLI>"; - txd = cli->get_iss(); - rxd = cli->get_irs(); - } - TraceEvent(p, tsd, txd, rxd); + TraceEvent(tsd, txd, rxd); - if ( lws && ssn->lws_init) - TraceSession(lws); + if ( ssn->lws_init ) + TraceSession(tsd.get_flow()); - if (lws && !event) - { - TraceState(cli, srv, cdir); - TraceState(srv, cli, sdir); - } + TraceState(cli, srv, cdir); + TraceState(srv, cli, sdir); } -inline void S5TraceTCP( - const snort::Packet* p, const snort::Flow* lws, TcpSegmentDescriptor* tsd, int event) +inline void S5TraceTCP(const TcpSegmentDescriptor& tsd) { - if (!s5_trace_enabled) + if ( !s5_trace_enabled ) return; - if (s5_trace_enabled < 0) + if ( s5_trace_enabled < 0 ) { const char* s5t = getenv("S5_TRACE"); - if (!s5t) + if ( !s5t ) { s5_trace_enabled = 0; return; @@ -163,7 +157,7 @@ inline void S5TraceTCP( s5_trace_enabled = atoi(s5t); } - TraceTCP(p, lws, tsd, event); + TraceTCP(tsd); } #endif // REG_TEST diff --git a/src/stream/tcp/tcp_event_logger.cc b/src/stream/tcp/tcp_event_logger.cc index fdeb83d7b..4f04c7007 100644 --- a/src/stream/tcp/tcp_event_logger.cc +++ b/src/stream/tcp/tcp_event_logger.cc @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_event_logger.cc author davis mcpherson +// tcp_event_logger.cc author davis mcpherson // Created on: Jul 30, 2015 #ifdef HAVE_CONFIG_H diff --git a/src/stream/tcp/tcp_event_logger.h b/src/stream/tcp/tcp_event_logger.h index ac4ab1bc6..af8ac2f58 100644 --- a/src/stream/tcp/tcp_event_logger.h +++ b/src/stream/tcp/tcp_event_logger.h @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_event_logger.h author davis mcpherson +// tcp_event_logger.h author davis mcpherson // Created on: Jul 30, 2015 #ifndef TCP_EVENT_LOGGER_H diff --git a/src/stream/tcp/tcp_module.cc b/src/stream/tcp/tcp_module.cc index eafbf1678..3cc1bac50 100644 --- a/src/stream/tcp/tcp_module.cc +++ b/src/stream/tcp/tcp_module.cc @@ -77,6 +77,7 @@ const PegInfo tcp_pegs[] = { CountType::SUM, "syn_acks", "number of syn-ack packets" }, { CountType::SUM, "resets", "number of reset packets" }, { CountType::SUM, "fins", "number of fin packets" }, + { CountType::SUM, "meta_acks", "number of meta acks processed" }, { CountType::SUM, "packets_held", "number of packets held" }, { CountType::SUM, "held_packet_rexmits", "number of retransmits of held packets" }, { CountType::SUM, "held_packets_dropped", "number of held packets dropped" }, diff --git a/src/stream/tcp/tcp_module.h b/src/stream/tcp/tcp_module.h index 96a6eb73c..489de0992 100644 --- a/src/stream/tcp/tcp_module.h +++ b/src/stream/tcp/tcp_module.h @@ -91,6 +91,7 @@ struct TcpStats PegCount syn_acks; PegCount resets; PegCount fins; + PegCount meta_acks; PegCount total_packets_held; PegCount held_packet_rexmits; PegCount held_packets_dropped; diff --git a/src/stream/tcp/tcp_normalizer.cc b/src/stream/tcp/tcp_normalizer.cc index 961981091..a269441fc 100644 --- a/src/stream/tcp/tcp_normalizer.cc +++ b/src/stream/tcp/tcp_normalizer.cc @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_normalization.cc author davis mcpherson +// tcp_normalization.cc author davis mcpherson // Created on: Jul 31, 2015 #ifdef HAVE_CONFIG_H @@ -25,8 +25,6 @@ #include "tcp_normalizer.h" -#include "packet_io/active.h" - #include "tcp_stream_session.h" #include "tcp_stream_tracker.h" @@ -64,9 +62,9 @@ void TcpNormalizer::trim_payload( { if (mode == NORM_MODE_ON) { - uint16_t fat = tsd.get_seg_len() - max; - tsd.set_seg_len(max); - tsd.get_pkt()->packet_flags |= PKT_RESIZED; + uint16_t fat = tsd.get_len() - max; + tsd.set_len(max); + tsd.set_packet_flags(PKT_RESIZED); tsd.set_end_seq(tsd.get_end_seq() - fat); } @@ -83,7 +81,7 @@ bool TcpNormalizer::strip_tcp_timestamp( { // set raw option bytes to nops memset((void*)opt, (uint32_t)tcp::TcpOptCode::NOP, tcp::TCPOLEN_TIMESTAMP); - tsd.get_pkt()->packet_flags |= PKT_MODIFIED; + tsd.set_packet_flags(PKT_MODIFIED); return true; } @@ -99,9 +97,7 @@ bool TcpNormalizer::packet_dropper( if (mode == NORM_MODE_ON) { - Packet* p = tsd.get_pkt(); - p->active->drop_packet(p); - p->active->set_drop_reason("stream"); + tsd.drop_packet(); return true; } @@ -111,28 +107,28 @@ bool TcpNormalizer::packet_dropper( void TcpNormalizer::trim_syn_payload( TcpNormalizerState& tns, TcpSegmentDescriptor& tsd, uint32_t max) { - if (tsd.get_seg_len() > max) + if (tsd.get_len() > max) trim_payload(tns, tsd, max, (NormMode)tns.trim_syn, PC_TCP_TRIM_SYN); } void TcpNormalizer::trim_rst_payload( TcpNormalizerState& tns, TcpSegmentDescriptor& tsd, uint32_t max) { - if (tsd.get_seg_len() > max) + if (tsd.get_len() > max) trim_payload(tns, tsd, max, (NormMode)tns.trim_rst, PC_TCP_TRIM_RST); } void TcpNormalizer::trim_win_payload( TcpNormalizerState& tns, TcpSegmentDescriptor& tsd, uint32_t max) { - if (tsd.get_seg_len() > max) + if (tsd.get_len() > max) trim_payload(tns, tsd, max, (NormMode)tns.trim_win, PC_TCP_TRIM_WIN); } void TcpNormalizer::trim_mss_payload( TcpNormalizerState& tns, TcpSegmentDescriptor& tsd, uint32_t max) { - if (tsd.get_seg_len() > max) + if (tsd.get_len() > max) trim_payload(tns, tsd, max, (NormMode)tns.trim_mss, PC_TCP_TRIM_MSS); } @@ -149,14 +145,15 @@ void TcpNormalizer::ecn_tracker( } void TcpNormalizer::ecn_stripper( - TcpNormalizerState& tns, Packet* p) + TcpNormalizerState& tns, TcpSegmentDescriptor& tsd) { - if (!tns.session->ecn && (p->ptrs.tcph->th_flags & (TH_ECE | TH_CWR))) + const tcp::TCPHdr* tcph = tsd.get_tcph(); + if (!tns.session->ecn && (tcph->th_flags & (TH_ECE | TH_CWR))) { if (tns.strip_ecn == NORM_MODE_ON) { - (const_cast(p->ptrs.tcph))->th_flags &= ~(TH_ECE | TH_CWR); - p->packet_flags |= PKT_MODIFIED; + (const_cast(tcph))->th_flags &= ~(TH_ECE | TH_CWR); + tsd.set_packet_flags(PKT_MODIFIED); } tcp_norm_stats[PC_TCP_ECN_SSN][tns.strip_ecn]++; @@ -190,6 +187,9 @@ uint32_t TcpNormalizer::get_stream_window( uint32_t TcpNormalizer::get_tcp_timestamp( TcpNormalizerState& tns, TcpSegmentDescriptor& tsd, bool strip) { + if ( tsd.is_meta_ack_packet() ) + return TF_NONE; + if ( tsd.get_pkt()->ptrs.decode_flags & DECODE_TCP_TS ) { tcp::TcpOptIterator iter(tsd.get_tcph(), tsd.get_pkt() ); @@ -206,13 +206,13 @@ uint32_t TcpNormalizer::get_tcp_timestamp( if (!stripped) { - tsd.set_ts(extract_32bits(opt.data) ); + tsd.set_timestamp(extract_32bits(opt.data) ); return TF_TSTAMP; } } } } - tsd.set_ts(0); + tsd.set_timestamp(0); return TF_NONE; } @@ -220,7 +220,7 @@ bool TcpNormalizer::validate_rst_seq_geq( TcpNormalizerState& tns, TcpSegmentDescriptor& tsd) { // FIXIT-M check for rcv_nxt == 0 is hack for uninitialized rcv_nxt - if ( ( tns.tracker->rcv_nxt == 0 ) || SEQ_GEQ(tsd.get_seg_seq(), tns.tracker->rcv_nxt) ) + if ( ( tns.tracker->rcv_nxt == 0 ) || SEQ_GEQ(tsd.get_seq(), tns.tracker->rcv_nxt) ) return true; return false; @@ -236,7 +236,7 @@ bool TcpNormalizer::validate_rst_end_seq_geq( if ( SEQ_GEQ(tsd.get_end_seq(), tns.tracker->r_win_base)) { // reset must be admitted when window closed - if (SEQ_LEQ(tsd.get_seg_seq(), tns.tracker->r_win_base + get_stream_window(tns, tsd))) + if (SEQ_LEQ(tsd.get_seq(), tns.tracker->r_win_base + get_stream_window(tns, tsd))) return true; } @@ -249,7 +249,7 @@ bool TcpNormalizer::validate_rst_seq_eq( uint32_t expected_seq = tns.tracker->rcv_nxt + tns.tracker->get_fin_seq_adjust(); // FIXIT-M check for rcv_nxt == 0 is hack for uninitialized rcv_nxt - if ( ( tns.tracker->rcv_nxt == 0 ) || SEQ_EQ(tsd.get_seg_seq(), expected_seq) ) + if ( ( tns.tracker->rcv_nxt == 0 ) || SEQ_EQ(tsd.get_seq(), expected_seq) ) return true; return false; @@ -269,14 +269,14 @@ int TcpNormalizer::validate_paws_timestamp( TcpNormalizerState& tns, TcpSegmentDescriptor& tsd) { const uint32_t peer_ts_last = tns.peer_tracker->get_ts_last(); - if ( peer_ts_last && ( ( (int)( ( tsd.get_ts() - peer_ts_last ) + tns.paws_ts_fudge ) ) < 0 ) ) + if ( peer_ts_last && ( ( (int)( ( tsd.get_timestamp() - peer_ts_last ) + tns.paws_ts_fudge ) ) < 0 ) ) { if ( tsd.get_pkt()->is_retry() ) { // Retry packets can legitimately have old timestamps // in TCP options (if a re-transmit comes in before // the retry) so don't consider it an error. - tsd.set_ts(tns.peer_tracker->get_ts_last()); + tsd.set_timestamp(tns.peer_tracker->get_ts_last()); return ACTION_NOTHING; } else @@ -289,7 +289,7 @@ int TcpNormalizer::validate_paws_timestamp( } } else if ( ( tns.peer_tracker->get_ts_last() != 0 ) - && ( ( uint32_t )tsd.get_pkt()->pkth->ts.tv_sec > tns.peer_tracker->get_ts_last_packet() + + && ( ( uint32_t )tsd.get_packet_timestamp() > tns.peer_tracker->get_ts_last_packet() + PAWS_24DAYS ) ) { /* this packet is from way too far into the future */ @@ -329,7 +329,7 @@ int TcpNormalizer::validate_paws( tns.session->tel.set_tcp_event(EVENT_NO_TIMESTAMP); /* Ignore the timestamp for this first packet, next one will checked. */ - if ( tns.session->config->policy == StreamPolicy::OS_SOLARIS ) + if ( tns.session->tcp_config->policy == StreamPolicy::OS_SOLARIS ) tns.tracker->clear_tf_flags(TF_TSTAMP); packet_dropper(tns, tsd, NORM_TCP_OPT); @@ -346,7 +346,7 @@ int TcpNormalizer::handle_paws_no_timestamps( if (!(tns.peer_tracker->get_tf_flags() & TF_TSTAMP)) { // SYN skipped, may have missed talker's timestamp , so set it now. - if (tsd.get_ts() == 0) + if (tsd.get_timestamp() == 0) tns.peer_tracker->set_tf_flags(TF_TSTAMP | TF_TSTAMP_ZERO); else tns.peer_tracker->set_tf_flags(TF_TSTAMP); @@ -354,7 +354,7 @@ int TcpNormalizer::handle_paws_no_timestamps( // Only valid to test this if listener is using timestamps. Otherwise, timestamp // in this packet is not used, regardless of its value. - if ( ( tns.paws_drop_zero_ts && ( tsd.get_ts() == 0 ) ) && + if ( ( tns.paws_drop_zero_ts && ( tsd.get_timestamp() == 0 ) ) && ( tns.tracker->get_tf_flags() & TF_TSTAMP ) ) { tns.session->tel.set_tcp_event(EVENT_BAD_TIMESTAMP); diff --git a/src/stream/tcp/tcp_normalizer.h b/src/stream/tcp/tcp_normalizer.h index 12b4802de..e3e26ca4e 100644 --- a/src/stream/tcp/tcp_normalizer.h +++ b/src/stream/tcp/tcp_normalizer.h @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_normalizer.h author davis mcpherson +// tcp_normalizer.h author davis mcpherson // Created on: Jul 31, 2015 #ifndef TCP_NORMALIZER_H @@ -84,7 +84,7 @@ public: virtual void trim_win_payload(State&, TcpSegmentDescriptor&, uint32_t max = 0); virtual void trim_mss_payload(State&, TcpSegmentDescriptor&, uint32_t max = 0); virtual void ecn_tracker(State&, const snort::tcp::TCPHdr*, bool req3way); - virtual void ecn_stripper(State&, snort::Packet*); + virtual void ecn_stripper(State&, TcpSegmentDescriptor&); virtual uint32_t get_stream_window(State&, TcpSegmentDescriptor&); virtual uint32_t get_tcp_timestamp(State&, TcpSegmentDescriptor&, bool strip); virtual int handle_paws(State&, TcpSegmentDescriptor&); diff --git a/src/stream/tcp/tcp_normalizers.cc b/src/stream/tcp/tcp_normalizers.cc index 3e71fe216..e6515712c 100644 --- a/src/stream/tcp/tcp_normalizers.cc +++ b/src/stream/tcp/tcp_normalizers.cc @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_normalizers.cc author davis mcpherson +// tcp_normalizers.cc author davis mcpherson // Created on: Sep 22, 2015 #ifdef HAVE_CONFIG_H @@ -186,7 +186,7 @@ static inline int handle_repeated_syn_mswin( /* Windows has some strange behavior here. If the sequence of the reset is the * next expected sequence, it Resets. Otherwise it ignores the 2nd SYN. */ - if ( SEQ_EQ(tsd.get_seg_seq(), listener->rcv_nxt) ) + if ( SEQ_EQ(tsd.get_seq(), listener->rcv_nxt) ) { session->flow->set_session_flags(SSNFLAG_RESET); talker->set_tcp_state(TcpStreamTracker::TCP_CLOSED); @@ -203,7 +203,7 @@ static inline int handle_repeated_syn_bsd( TcpStreamTracker* talker, const TcpSegmentDescriptor& tsd, TcpStreamSession* session) { /* If its not a retransmission of the actual SYN... RESET */ - if ( !SEQ_EQ(tsd.get_seg_seq(), talker->get_iss()) ) + if ( !SEQ_EQ(tsd.get_seq(), talker->get_iss()) ) { session->flow->set_session_flags(SSNFLAG_RESET); talker->set_tcp_state(TcpStreamTracker::TCP_CLOSED); @@ -241,10 +241,10 @@ static inline bool paws_3whs_zero_ts_supported( if ( talker->get_tf_flags() & TF_TSTAMP_ZERO ) { talker->clear_tf_flags(TF_TSTAMP_ZERO); - if ( SEQ_EQ(listener->rcv_nxt, tsd.get_seg_seq() ) ) + if ( SEQ_EQ(listener->rcv_nxt, tsd.get_seq() ) ) { // Ignore timestamp for this first packet, save to check on next - talker->set_ts_last(tsd.get_ts() ); + talker->set_ts_last(tsd.get_timestamp()); check_ts = false; } } @@ -370,7 +370,7 @@ bool TcpNormalizerHpux11::is_paws_ts_checked_required( { /* HPUX 11 ignores timestamps for out of order segments */ if ( (tns.tracker->get_tf_flags() & TF_MISSING_PKT) || !SEQ_EQ(tns.tracker->rcv_nxt, - tsd.get_seg_seq()) ) + tsd.get_seq()) ) return false; else return true; diff --git a/src/stream/tcp/tcp_normalizers.h b/src/stream/tcp/tcp_normalizers.h index d050ad338..97bac383b 100644 --- a/src/stream/tcp/tcp_normalizers.h +++ b/src/stream/tcp/tcp_normalizers.h @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_normalizers.h author davis mcpherson +// tcp_normalizers.h author davis mcpherson // Created on: Sep 22, 2015 #ifndef TCP_NORMALIZERS_H @@ -68,8 +68,8 @@ public: void ecn_tracker(const snort::tcp::TCPHdr* tcph, bool req3way) { norm->ecn_tracker(tns, tcph, req3way); } - void ecn_stripper(snort::Packet* p) - { norm->ecn_stripper(tns, p); } + void ecn_stripper(TcpSegmentDescriptor& tsd) + { norm->ecn_stripper(tns, tsd); } uint32_t get_stream_window(TcpSegmentDescriptor& tsd) { return norm->get_stream_window(tns, tsd); } diff --git a/src/stream/tcp/tcp_reassembler.cc b/src/stream/tcp/tcp_reassembler.cc index 65310fed3..dab3f2d56 100644 --- a/src/stream/tcp/tcp_reassembler.cc +++ b/src/stream/tcp/tcp_reassembler.cc @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_reassembler.cc author davis mcpherson +// tcp_reassembler.cc author davis mcpherson // Created on: Jul 31, 2015 #ifdef HAVE_CONFIG_H @@ -192,13 +192,13 @@ void TcpReassembler::queue_reassembly_segment( bool TcpReassembler::is_segment_fasttrack( TcpReassemblerState&, TcpSegmentNode* tail, const TcpSegmentDescriptor& tsd) { - if ( SEQ_EQ(tsd.get_seg_seq(), tail->i_seq + tail->i_len) ) + if ( SEQ_EQ(tsd.get_seq(), tail->i_seq + tail->i_len) ) return true; return false; } -int TcpReassembler::add_reassembly_segment( +void TcpReassembler::add_reassembly_segment( TcpReassemblerState& trs, TcpSegmentDescriptor& tsd, uint16_t len, uint32_t slide, uint32_t trunc_len, uint32_t seq, TcpSegmentNode* left) { @@ -210,8 +210,7 @@ int TcpReassembler::add_reassembly_segment( // Zero size data because of trimming. Don't insert it. inc_tcp_discards(); trs.tracker->normalizer.trim_win_payload(tsd); - - return STREAM_INSERT_OK; + return; } // FIXIT-L don't allocate overlapped part @@ -221,7 +220,7 @@ int TcpReassembler::add_reassembly_segment( tsn->c_len = (uint16_t)new_size; tsn->i_len = (uint16_t)new_size; tsn->i_seq = tsn->c_seq = seq; - tsn->ts = tsd.get_ts(); + tsn->ts = tsd.get_timestamp(); // FIXIT-M the urgent ptr handling is broken... urg_offset could be set here but currently // not actually referenced anywhere else. In 2.9.7 the FlushStream function did reference @@ -232,12 +231,10 @@ int TcpReassembler::add_reassembly_segment( trs.sos.seg_bytes_logical += tsn->c_len; trs.sos.total_bytes_queued += tsn->c_len; - tsd.get_pkt()->packet_flags |= PKT_STREAM_INSERT; - - return STREAM_INSERT_OK; + tsd.set_packet_flags(PKT_STREAM_INSERT); } -int TcpReassembler::dup_reassembly_segment( +void TcpReassembler::dup_reassembly_segment( TcpReassemblerState& trs, TcpSegmentNode* left, TcpSegmentNode** retSeg) { TcpSegmentNode* tsn = TcpSegmentNode::init(*left); @@ -249,7 +246,6 @@ int TcpReassembler::dup_reassembly_segment( queue_reassembly_segment(trs, left, tsn); *retSeg = tsn; - return STREAM_INSERT_OK; } void TcpReassembler::purge_alerts(TcpReassemblerState& trs) @@ -366,7 +362,7 @@ void TcpReassembler::purge_flushed_ackd(TcpReassemblerState& trs) void TcpReassembler::show_rebuilt_packet(TcpReassemblerState& trs, Packet* pkt) { - if ( trs.sos.session->config->flags & STREAM_CONFIG_SHOW_PACKETS ) + if ( trs.sos.session->tcp_config->flags & STREAM_CONFIG_SHOW_PACKETS ) { // FIXIT-L setting conf here is required because this is called before context start pkt->context->conf = SnortConfig::get_conf(); @@ -515,7 +511,7 @@ Packet* TcpReassembler::initialize_pdu( EncodeFlags enc_flags = 0; DAQ_PktHdr_t pkth; - trs.sos.session->GetPacketHeaderFoo(&pkth, pkt_flags); + trs.sos.session->get_packet_header_foo(&pkth, pkt_flags); PacketManager::format_tcp(enc_flags, p, pdu, PSEUDO_PKT_TCP, &pkth, pkth.opaque); prep_pdu(trs, trs.sos.session->flow, p, pkt_flags, pdu); assert(pdu->pkth == pdu->context->pkth); @@ -953,12 +949,12 @@ static inline void fallback(TcpStreamTracker& trk, bool server_side, uint16_t ma delete trk.splitter; trk.splitter = new AtomSplitter(!server_side, max); trk.paf_state.paf = StreamSplitter::START; - ++tcpStats.partial_fallbacks; + tcpStats.partial_fallbacks++; } void TcpReassembler::fallback(TcpStreamTracker& tracker, bool server_side) { - uint16_t max = tracker.session->config->paf_max; + uint16_t max = tracker.session->tcp_config->paf_max; ::fallback(tracker, server_side, max); Flow* flow = tracker.session->flow; @@ -970,7 +966,7 @@ void TcpReassembler::fallback(TcpStreamTracker& tracker, bool server_side) if ( flow->gadget and both_splitters_aborted(flow) ) { flow->clear_gadget(); - ++tcpStats.inspector_fallbacks; + tcpStats.inspector_fallbacks++; } } @@ -1184,16 +1180,16 @@ void TcpReassembler::insert_segment_in_empty_seglist( const tcp::TCPHdr* tcph = tsd.get_tcph(); uint32_t overlap = 0; - uint32_t seq = tsd.get_seg_seq(); + uint32_t seq = tsd.get_seq(); if ( tcph->is_syn() ) seq++; if ( SEQ_GT(trs.tracker->r_win_base, seq) ) { - overlap = trs.tracker->r_win_base - tsd.get_seg_seq(); + overlap = trs.tracker->r_win_base - tsd.get_seq(); - if ( overlap >= tsd.get_seg_len() ) + if ( overlap >= tsd.get_len() ) return; } @@ -1201,13 +1197,13 @@ void TcpReassembler::insert_segment_in_empty_seglist( { overlap = trs.sos.seglist_base_seq- seq - overlap; - if ( overlap >= tsd.get_seg_len() ) + if ( overlap >= tsd.get_len() ) return; } // BLOCK add new block to trs.sos.seglist containing data add_reassembly_segment( - trs, tsd, tsd.get_seg_len(), overlap, 0, seq + overlap, nullptr); + trs, tsd, tsd.get_len(), overlap, 0, seq + overlap, nullptr); } @@ -1219,15 +1215,15 @@ void TcpReassembler::init_overlap_editor( if ( trs.sos.seglist.head && trs.sos.seglist.tail ) { - if ( SEQ_GT(tsd.get_seg_seq(), trs.sos.seglist.head->i_seq) ) - dist_head = tsd.get_seg_seq() - trs.sos.seglist.head->i_seq; + if ( SEQ_GT(tsd.get_seq(), trs.sos.seglist.head->i_seq) ) + dist_head = tsd.get_seq() - trs.sos.seglist.head->i_seq; else - dist_head = trs.sos.seglist.head->i_seq - tsd.get_seg_seq(); + dist_head = trs.sos.seglist.head->i_seq - tsd.get_seq(); - if ( SEQ_GT(tsd.get_seg_seq(), trs.sos.seglist.tail->i_seq) ) - dist_tail = tsd.get_seg_seq() - trs.sos.seglist.tail->i_seq; + if ( SEQ_GT(tsd.get_seq(), trs.sos.seglist.tail->i_seq) ) + dist_tail = tsd.get_seq() - trs.sos.seglist.tail->i_seq; else - dist_tail = trs.sos.seglist.tail->i_seq - tsd.get_seg_seq(); + dist_tail = trs.sos.seglist.tail->i_seq - tsd.get_seq(); } if ( SEQ_LEQ(dist_head, dist_tail) ) @@ -1236,7 +1232,7 @@ void TcpReassembler::init_overlap_editor( { right = tsn; - if ( SEQ_GEQ(right->i_seq, tsd.get_seg_seq() ) ) + if ( SEQ_GEQ(right->i_seq, tsd.get_seq() ) ) break; left = right; @@ -1251,7 +1247,7 @@ void TcpReassembler::init_overlap_editor( { left = tsn; - if ( SEQ_LT(left->i_seq, tsd.get_seg_seq() ) ) + if ( SEQ_LT(left->i_seq, tsd.get_seq() ) ) break; right = left; @@ -1264,73 +1260,57 @@ void TcpReassembler::init_overlap_editor( trs.sos.init_soe(tsd, left, right); } -int TcpReassembler::insert_segment_in_seglist( +void TcpReassembler::insert_segment_in_seglist( TcpReassemblerState& trs, TcpSegmentDescriptor& tsd) { - int rc = STREAM_INSERT_OK; - // NORM fast tracks are in sequence - no norms if ( trs.sos.seglist.tail && is_segment_fasttrack(trs, trs.sos.seglist.tail, tsd) ) { /* segment fit cleanly at the end of the segment list */ - rc = add_reassembly_segment( - trs, tsd, tsd.get_seg_len(), 0, 0, tsd.get_seg_seq(), trs.sos.seglist.tail); - return rc; + add_reassembly_segment( + trs, tsd, tsd.get_len(), 0, 0, tsd.get_seq(), trs.sos.seglist.tail); + return; } init_overlap_editor(trs, tsd); - rc = eval_left(trs); - - if ( rc != STREAM_INSERT_OK ) - return rc; - - rc = eval_right(trs); - - if ( rc != STREAM_INSERT_OK ) - return rc; + eval_left(trs); + eval_right(trs); if ( trs.sos.keep_segment ) { /* Adjust slide so that is correct relative to orig seq */ - trs.sos.slide = trs.sos.seq - tsd.get_seg_seq(); + trs.sos.slide = trs.sos.seq - tsd.get_seq(); // FIXIT-L for some reason length - slide - trunc_len is sometimes negative if (trs.sos.len - trs.sos.slide - trs.sos.trunc_len < 0) - return STREAM_INSERT_OK; - rc = add_reassembly_segment( + return; + + add_reassembly_segment( trs, tsd, trs.sos.len, trs.sos.slide, trs.sos.trunc_len, trs.sos.seq, trs.sos.left); } - else - rc = STREAM_INSERT_OK; - - return rc; } -int TcpReassembler::queue_packet_for_reassembly( +void TcpReassembler::queue_packet_for_reassembly( TcpReassemblerState& trs, TcpSegmentDescriptor& tsd) { - int rc = STREAM_INSERT_OK; - if ( trs.sos.seg_count == 0 ) { insert_segment_in_empty_seglist(trs, tsd); - return STREAM_INSERT_OK; + return; } - if ( SEQ_GT(trs.tracker->r_win_base, tsd.get_seg_seq() ) ) + if ( SEQ_GT(trs.tracker->r_win_base, tsd.get_seq() ) ) { - const int32_t offset = trs.tracker->r_win_base - tsd.get_seg_seq(); + const int32_t offset = trs.tracker->r_win_base - tsd.get_seq(); - if ( offset < tsd.get_seg_len() ) + if ( offset < tsd.get_len() ) { tsd.slide_segment_in_rcv_window(offset); - rc = insert_segment_in_seglist(trs, tsd); + insert_segment_in_seglist(trs, tsd); tsd.slide_segment_in_rcv_window(-offset); } } else - rc = insert_segment_in_seglist(trs, tsd); - - return rc; + insert_segment_in_seglist(trs, tsd); } uint32_t TcpReassembler::perform_partial_flush(TcpReassemblerState& trs, Flow* flow) diff --git a/src/stream/tcp/tcp_reassembler.h b/src/stream/tcp/tcp_reassembler.h index 81ed91cf0..ba8fd5111 100644 --- a/src/stream/tcp/tcp_reassembler.h +++ b/src/stream/tcp/tcp_reassembler.h @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_reassembly.h author davis mcpherson +// tcp_reassembly.h author davis mcpherson // Created on: Jul 31, 2015 #ifndef TCP_REASSEMBLER_H @@ -28,7 +28,7 @@ class TcpReassembler : public SegmentOverlapEditor { public: - virtual int queue_packet_for_reassembly(TcpReassemblerState&, TcpSegmentDescriptor&); + virtual void queue_packet_for_reassembly(TcpReassemblerState&, TcpSegmentDescriptor&); virtual void purge_segment_list(TcpReassemblerState&); virtual void purge_flushed_ackd(TcpReassemblerState&); virtual int flush_stream( @@ -46,15 +46,15 @@ public: protected: TcpReassembler() = default; - int add_reassembly_segment( + void add_reassembly_segment( TcpReassemblerState&, TcpSegmentDescriptor&, uint16_t len, uint32_t slide, uint32_t trunc, uint32_t seq, TcpSegmentNode* left) override; - int dup_reassembly_segment( + void dup_reassembly_segment( TcpReassemblerState&, TcpSegmentNode* left, TcpSegmentNode** retSeg) override; int delete_reassembly_segment(TcpReassemblerState&, TcpSegmentNode*) override; virtual void insert_segment_in_empty_seglist(TcpReassemblerState&, TcpSegmentDescriptor&); - virtual int insert_segment_in_seglist(TcpReassemblerState&, TcpSegmentDescriptor&); + virtual void insert_segment_in_seglist(TcpReassemblerState&, TcpSegmentDescriptor&); virtual uint32_t get_pending_segment_count(TcpReassemblerState&, unsigned max); bool flush_data_ready(TcpReassemblerState&); int trim_delete_reassembly_segment(TcpReassemblerState&, TcpSegmentNode*, uint32_t flush_seq); @@ -89,7 +89,6 @@ protected: void update_next(TcpReassemblerState&, const TcpSegmentNode&); uint32_t perform_partial_flush(TcpReassemblerState&, snort::Packet*, uint32_t flushed = 0); - }; #endif diff --git a/src/stream/tcp/tcp_reassemblers.cc b/src/stream/tcp/tcp_reassemblers.cc index 9374886b0..4b720f792 100644 --- a/src/stream/tcp/tcp_reassemblers.cc +++ b/src/stream/tcp/tcp_reassemblers.cc @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_reassemblers.cc author davis mcpherson +// tcp_reassemblers.cc author davis mcpherson // Created on: Oct 9, 2015 #ifdef HAVE_CONFIG_H @@ -34,14 +34,14 @@ public: TcpReassemblerFirst() = default; private: - int insert_left_overlap(TcpReassemblerState& trs) override - { return left_overlap_keep_first(trs); } + void insert_left_overlap(TcpReassemblerState& trs) override + { left_overlap_keep_first(trs); } void insert_right_overlap(TcpReassemblerState& trs) override { right_overlap_truncate_new(trs); } - int insert_full_overlap(TcpReassemblerState& trs) override - { return full_right_overlap_os5(trs); } + void insert_full_overlap(TcpReassemblerState& trs) override + { full_right_overlap_os5(trs); } }; class TcpReassemblerLast : public TcpReassembler @@ -50,14 +50,14 @@ public: TcpReassemblerLast() = default; private: - int insert_left_overlap(TcpReassemblerState& trs) override - { return left_overlap_keep_last(trs); } + void insert_left_overlap(TcpReassemblerState& trs) override + { left_overlap_keep_last(trs); } void insert_right_overlap(TcpReassemblerState& trs) override { right_overlap_truncate_existing(trs); } - int insert_full_overlap(TcpReassemblerState& trs) override - { return full_right_overlap_os4(trs); } + void insert_full_overlap(TcpReassemblerState& trs) override + { full_right_overlap_os4(trs); } }; class TcpReassemblerLinux : public TcpReassembler @@ -66,14 +66,14 @@ public: TcpReassemblerLinux() = default; private: - int insert_left_overlap(TcpReassemblerState& trs) override - { return left_overlap_keep_first(trs); } + void insert_left_overlap(TcpReassemblerState& trs) override + { left_overlap_keep_first(trs); } void insert_right_overlap(TcpReassemblerState& trs) override { right_overlap_truncate_existing(trs); } - int insert_full_overlap(TcpReassemblerState& trs) override - { return full_right_overlap_os2(trs); } + void insert_full_overlap(TcpReassemblerState& trs) override + { full_right_overlap_os2(trs); } }; class TcpReassemblerOldLinux : public TcpReassembler @@ -82,14 +82,14 @@ public: TcpReassemblerOldLinux() = default; private: - int insert_left_overlap(TcpReassemblerState& trs) override - { return left_overlap_keep_first(trs); } + void insert_left_overlap(TcpReassemblerState& trs) override + { left_overlap_keep_first(trs); } void insert_right_overlap(TcpReassemblerState& trs) override { right_overlap_truncate_existing(trs); } - int insert_full_overlap(TcpReassemblerState& trs) override - { return full_right_overlap_os4(trs); } + void insert_full_overlap(TcpReassemblerState& trs) override + { full_right_overlap_os4(trs); } }; class TcpReassemblerBSD : public TcpReassembler @@ -98,14 +98,14 @@ public: TcpReassemblerBSD() = default; private: - int insert_left_overlap(TcpReassemblerState& trs) override - { return left_overlap_keep_first(trs); } + void insert_left_overlap(TcpReassemblerState& trs) override + { left_overlap_keep_first(trs); } void insert_right_overlap(TcpReassemblerState& trs) override { right_overlap_truncate_existing(trs); } - int insert_full_overlap(TcpReassemblerState& trs) override - { return full_right_overlap_os1(trs); } + void insert_full_overlap(TcpReassemblerState& trs) override + { full_right_overlap_os1(trs); } }; class TcpReassemblerMacOS : public TcpReassembler @@ -114,14 +114,14 @@ public: TcpReassemblerMacOS() = default; private: - int insert_left_overlap(TcpReassemblerState& trs) override - { return left_overlap_keep_first(trs); } + void insert_left_overlap(TcpReassemblerState& trs) override + { left_overlap_keep_first(trs); } void insert_right_overlap(TcpReassemblerState& trs) override { right_overlap_truncate_existing(trs); } - int insert_full_overlap(TcpReassemblerState& trs) override - { return full_right_overlap_os1(trs); } + void insert_full_overlap(TcpReassemblerState& trs) override + { full_right_overlap_os1(trs); } }; class TcpReassemblerSolaris : public TcpReassembler @@ -130,14 +130,14 @@ public: TcpReassemblerSolaris() = default; private: - int insert_left_overlap(TcpReassemblerState& trs) override - { return left_overlap_trim_first(trs); } + void insert_left_overlap(TcpReassemblerState& trs) override + { left_overlap_trim_first(trs); } void insert_right_overlap(TcpReassemblerState& trs) override { right_overlap_truncate_new(trs); } - int insert_full_overlap(TcpReassemblerState& trs) override - { return full_right_overlap_os3(trs); } + void insert_full_overlap(TcpReassemblerState& trs) override + { full_right_overlap_os3(trs); } }; class TcpReassemblerIrix : public TcpReassembler @@ -146,14 +146,14 @@ public: TcpReassemblerIrix() = default; private: - int insert_left_overlap(TcpReassemblerState& trs) override - { return left_overlap_keep_first(trs); } + void insert_left_overlap(TcpReassemblerState& trs) override + { left_overlap_keep_first(trs); } void insert_right_overlap(TcpReassemblerState& trs) override { right_overlap_truncate_existing(trs); } - int insert_full_overlap(TcpReassemblerState& trs) override - { return full_right_overlap_os2(trs); } + void insert_full_overlap(TcpReassemblerState& trs) override + { full_right_overlap_os2(trs); } }; class TcpReassemblerHpux11 : public TcpReassembler @@ -162,14 +162,14 @@ public: TcpReassemblerHpux11() = default; private: - int insert_left_overlap(TcpReassemblerState& trs) override - { return left_overlap_trim_first(trs); } + void insert_left_overlap(TcpReassemblerState& trs) override + { left_overlap_trim_first(trs); } void insert_right_overlap(TcpReassemblerState& trs) override { right_overlap_truncate_new(trs); } - int insert_full_overlap(TcpReassemblerState& trs) override - { return full_right_overlap_os3(trs); } + void insert_full_overlap(TcpReassemblerState& trs) override + { full_right_overlap_os3(trs); } }; class TcpReassemblerHpux10 : public TcpReassembler @@ -178,14 +178,14 @@ public: TcpReassemblerHpux10() = default; private: - int insert_left_overlap(TcpReassemblerState& trs) override - { return left_overlap_keep_first(trs); } + void insert_left_overlap(TcpReassemblerState& trs) override + { left_overlap_keep_first(trs); } void insert_right_overlap(TcpReassemblerState& trs) override { right_overlap_truncate_existing(trs); } - int insert_full_overlap(TcpReassemblerState& trs) override - { return full_right_overlap_os2(trs); } + void insert_full_overlap(TcpReassemblerState& trs) override + { full_right_overlap_os2(trs); } }; class TcpReassemblerWindows : public TcpReassembler @@ -194,14 +194,14 @@ public: TcpReassemblerWindows() = default; private: - int insert_left_overlap(TcpReassemblerState& trs) override - { return left_overlap_keep_first(trs); } + void insert_left_overlap(TcpReassemblerState& trs) override + { left_overlap_keep_first(trs); } void insert_right_overlap(TcpReassemblerState& trs) override { right_overlap_truncate_existing(trs); } - int insert_full_overlap(TcpReassemblerState& trs) override - { return full_right_overlap_os1(trs); } + void insert_full_overlap(TcpReassemblerState& trs) override + { full_right_overlap_os1(trs); } }; class TcpReassemblerWindows2K3 : public TcpReassembler @@ -210,14 +210,14 @@ public: TcpReassemblerWindows2K3() = default; private: - int insert_left_overlap(TcpReassemblerState& trs) override - { return left_overlap_keep_first(trs); } + void insert_left_overlap(TcpReassemblerState& trs) override + { left_overlap_keep_first(trs); } void insert_right_overlap(TcpReassemblerState& trs) override { right_overlap_truncate_existing(trs); } - int insert_full_overlap(TcpReassemblerState& trs) override - { return full_right_overlap_os1(trs); } + void insert_full_overlap(TcpReassemblerState& trs) override + { full_right_overlap_os1(trs); } }; class TcpReassemblerVista : public TcpReassembler @@ -226,14 +226,14 @@ public: TcpReassemblerVista() = default; private: - int insert_left_overlap(TcpReassemblerState& trs) override - { return left_overlap_keep_first(trs); } + void insert_left_overlap(TcpReassemblerState& trs) override + { left_overlap_keep_first(trs); } void insert_right_overlap(TcpReassemblerState& trs) override { right_overlap_truncate_new(trs); } - int insert_full_overlap(TcpReassemblerState& trs) override - { return full_right_overlap_os5 (trs); } + void insert_full_overlap(TcpReassemblerState& trs) override + { full_right_overlap_os5 (trs); } }; class TcpReassemblerProxy : public TcpReassemblerFirst @@ -242,14 +242,14 @@ public: TcpReassemblerProxy() = default; private: - int insert_left_overlap(TcpReassemblerState& trs) override - { return left_overlap_keep_first(trs); } + void insert_left_overlap(TcpReassemblerState& trs) override + { left_overlap_keep_first(trs); } void insert_right_overlap(TcpReassemblerState& trs) override { right_overlap_truncate_new(trs); } - int insert_full_overlap(TcpReassemblerState& trs) override - { return full_right_overlap_os5(trs); } + void insert_full_overlap(TcpReassemblerState& trs) override + { full_right_overlap_os5(trs); } }; void TcpReassemblerPolicy::init(TcpSession* ssn, TcpStreamTracker* trk, StreamPolicy pol, bool server) @@ -276,9 +276,7 @@ void TcpReassemblerPolicy::init(TcpSession* ssn, TcpStreamTracker* trk, StreamPo } void TcpReassemblerPolicy::reset() -{ - init(nullptr, nullptr, StreamPolicy::OS_DEFAULT, false); -} +{ init(nullptr, nullptr, StreamPolicy::OS_DEFAULT, false); } TcpReassembler* TcpReassemblerFactory::reassemblers[StreamPolicy::OS_END_OF_LIST]; diff --git a/src/stream/tcp/tcp_reassemblers.h b/src/stream/tcp/tcp_reassemblers.h index ee19d999b..c7cad8915 100644 --- a/src/stream/tcp/tcp_reassemblers.h +++ b/src/stream/tcp/tcp_reassemblers.h @@ -46,8 +46,8 @@ public: void init(TcpSession* ssn, TcpStreamTracker* trk, StreamPolicy pol, bool server); void reset(); - int queue_packet_for_reassembly(TcpSegmentDescriptor& tsd) - { return reassembler->queue_packet_for_reassembly(trs, tsd); } + void queue_packet_for_reassembly(TcpSegmentDescriptor& tsd) + { reassembler->queue_packet_for_reassembly(trs, tsd); } void purge_alerts() { reassembler->purge_alerts(trs); } diff --git a/src/stream/tcp/tcp_segment_descriptor.cc b/src/stream/tcp/tcp_segment_descriptor.cc index bcbcc755b..9cf001a47 100644 --- a/src/stream/tcp/tcp_segment_descriptor.cc +++ b/src/stream/tcp/tcp_segment_descriptor.cc @@ -26,22 +26,30 @@ #include "tcp_segment_descriptor.h" #include "detection/rules.h" +#include "packet_tracer/packet_tracer.h" #include "protocols/tcp_options.h" #include "stream/tcp/tcp_defs.h" +#include "stream/tcp/tcp_stream_tracker.h" using namespace snort; -TcpSegmentDescriptor::TcpSegmentDescriptor(Flow* flow_, Packet* pkt_, TcpEventLogger& tel) : - flow(flow_), - pkt(pkt_), - tcph(pkt->ptrs.tcph), - src_port(tcph->src_port()), - dst_port(tcph->dst_port()), - seg_seq(tcph->seq()), - seg_ack(tcph->ack()), - seg_wnd(tcph->win()), - end_seq(seg_seq + (uint32_t)pkt->dsize) +static THREAD_LOCAL Packet* ma_pseudo_packet; +static THREAD_LOCAL tcp::TCPHdr ma_pseudo_tcph; + +TcpSegmentDescriptor::TcpSegmentDescriptor(Flow* f, Packet* p, TcpEventLogger& tel) + : flow(f), pkt(p), tcph(pkt->ptrs.tcph), + packet_number(p->context->packet_number), + seq(tcph->seq()), + ack(tcph->ack()), + wnd(tcph->win()), + end_seq(seq + (uint32_t)pkt->dsize), + timestamp_option(0), + src_port(tcph->src_port()), + dst_port(tcph->dst_port()) { + packet_timestamp = p->pkth->ts.tv_sec; + packet_from_client = p->is_from_client(); + // don't bump end_seq for fin here we will bump if/when fin is processed if ( tcph->is_syn() ) { @@ -51,6 +59,46 @@ TcpSegmentDescriptor::TcpSegmentDescriptor(Flow* flow_, Packet* pkt_, TcpEventLo } } +TcpSegmentDescriptor::TcpSegmentDescriptor + (snort::Flow* f, snort::Packet* p, uint32_t meta_ack, uint16_t window) + : flow(f), pkt(ma_pseudo_packet), tcph(&ma_pseudo_tcph), + packet_number(p->context->packet_number) +{ + // init tcp header fields for meta-ack packet + ma_pseudo_tcph.th_dport = p->ptrs.tcph->raw_src_port(); + ma_pseudo_tcph.th_sport = p->ptrs.tcph->raw_dst_port(); + ma_pseudo_tcph.th_seq = p->ptrs.tcph->raw_ack(); + ma_pseudo_tcph.th_ack = htonl(meta_ack); + ma_pseudo_tcph.th_offx2 = 0; + ma_pseudo_tcph.th_flags = TH_ACK; + ma_pseudo_tcph.th_win = htons(window); + ma_pseudo_tcph.th_sum = 0; + ma_pseudo_tcph.th_urp = 0; + + // init meta-ack Packet fields stream cares about for TCP ack processing + pkt->flow = p->flow; + pkt->context = p->context; + pkt->dsize = 0; + + seq = tcph->seq(); + ack = tcph->ack(); + wnd = tcph->win(); + end_seq = seq; + timestamp_option = 0; + src_port = tcph->src_port(); + dst_port = tcph->dst_port(); + + packet_timestamp = p->pkth->ts.tv_sec; + packet_from_client = !p->is_from_client(); + meta_ack_packet = true; +} + +void TcpSegmentDescriptor::setup() +{ ma_pseudo_packet = new Packet(false); } + +void TcpSegmentDescriptor::clear() +{ delete ma_pseudo_packet; } + uint32_t TcpSegmentDescriptor::init_mss(uint16_t* value) { if ( pkt->ptrs.decode_flags & DECODE_TCP_MSS ) @@ -105,3 +153,20 @@ bool TcpSegmentDescriptor::has_wscale() return ( init_wscale(&wscale) & TF_WSCALE ) != TF_NONE; } +void TcpSegmentDescriptor::set_retransmit_flag() +{ + assert(!meta_ack_packet); + + if ( PacketTracer::is_active() ) + { + PacketTracer::log("Packet was retransmitted and %s from the retry queue.\n", + pkt->is_retry() ? "is" : "is not"); + } + + // Mark the packet as being a re-transmit if it's not from the retry + // queue. That way we can avoid adding re-transmitted packets to + // the retry queue. + if ( !pkt->is_retry() ) + pkt->packet_flags |= PKT_RETRANSMIT; +} + diff --git a/src/stream/tcp/tcp_segment_descriptor.h b/src/stream/tcp/tcp_segment_descriptor.h index 860a3c6ac..dd665649e 100644 --- a/src/stream/tcp/tcp_segment_descriptor.h +++ b/src/stream/tcp/tcp_segment_descriptor.h @@ -16,154 +16,188 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_segment_descriptor.h author davis mcpherson +// tcp_segment_descriptor.h author davis mcpherson // Created on: Jul 30, 2015 #ifndef TCP_SEGMENT_DESCRIPTOR_H #define TCP_SEGMENT_DESCRIPTOR_H +#include + +#include + #include "flow/flow.h" +#include "detection/ips_context.h" +#include "packet_io/active.h" #include "protocols/packet.h" #include "protocols/tcp.h" #include "stream/tcp/tcp_event_logger.h" +class TcpStreamTracker; + class TcpSegmentDescriptor { public: TcpSegmentDescriptor(snort::Flow*, snort::Packet*, TcpEventLogger&); + TcpSegmentDescriptor(snort::Flow*, snort::Packet*, uint32_t meta_ack, uint16_t window); + virtual ~TcpSegmentDescriptor() = default; + static void setup(); + static void clear(); + + bool is_policy_inline() + { return pkt->context->conf->inline_mode(); } + uint32_t init_mss(uint16_t* value); uint32_t init_wscale(uint16_t* value); bool has_wscale(); + void set_retransmit_flag(); snort::Flow* get_flow() const - { - return flow; - } + { return flow; } snort::Packet* get_pkt() const - { - return pkt; - } + { return pkt; } const snort::tcp::TCPHdr* get_tcph() const - { - return tcph; - } + { return tcph; } - void set_seg_seq(uint32_t seq) - { - seg_seq = seq; - } + void set_seq(uint32_t seq_num) + { seq = seq_num; } - void update_seg_seq(int32_t offset) - { - seg_seq += offset; - } + void update_seq(int32_t offset) + { seq += offset; } - uint32_t get_seg_seq() const - { - return seg_seq; - } + uint32_t get_seq() const + { return seq; } - uint32_t get_seg_ack() const - { - return seg_ack; - } + uint32_t get_ack() const + { return ack; } - void set_seg_ack(uint32_t ack) - { - this->seg_ack = ack; - } + void set_ack(uint32_t ack_num) + { ack = ack_num; } - void set_end_seq(uint32_t end_seq) - { - this->end_seq = end_seq; - } + void set_end_seq(uint32_t seq) + { end_seq = seq; } uint32_t get_end_seq() const - { - return end_seq; - } + { return end_seq; } - void set_ts(uint32_t ts) - { - this->ts = ts; - } + void set_timestamp(uint32_t timestamp) + { timestamp_option = timestamp; } - uint32_t get_ts() const - { - return ts; - } + uint32_t get_timestamp() const + { return timestamp_option; } - void scale_seg_wnd(uint16_t wscale) - { - seg_wnd <<= wscale; - } + void scale_wnd(uint16_t wscale) + { wnd <<= wscale; } - uint32_t get_seg_wnd() const - { - return seg_wnd; - } + uint32_t get_wnd() const + { return wnd; } uint16_t get_dst_port() const - { - return dst_port; - } + { return dst_port; } uint16_t get_src_port() const - { - return src_port; - } + { return src_port; } uint8_t get_direction() const + { return flow->ssn_state.direction; } + + uint16_t get_len() const + { return pkt->dsize; } + + void set_len(uint16_t seg_len) { - return flow->ssn_state.direction; + assert(!meta_ack_packet); + pkt->dsize = seg_len; } - uint16_t get_seg_len() const + void update_len(int32_t offset) { - return pkt->dsize; + assert(!meta_ack_packet); + pkt->dsize += offset; } - void set_seg_len(uint16_t seg_len) + bool is_packet_from_client() const + { return packet_from_client; } + + bool is_packet_from_server() const + { return !packet_from_client; } + + void slide_segment_in_rcv_window(int32_t offset) { - // Reset segment size to seg_len - pkt->dsize = seg_len; + assert(!meta_ack_packet); + seq += offset; + pkt->data += offset; + pkt->dsize -= offset; } - void update_seg_len(int32_t offset) + void set_packet_flags(uint32_t flags) const { - // Increase segment size by offset - pkt->dsize += offset; + assert(!meta_ack_packet); + pkt->packet_flags |= flags; } - bool is_packet_from_server() + bool are_packet_flags_set(uint32_t flags) const + { return (pkt->packet_flags & flags) == flags; } + + uint32_t get_packet_timestamp() const + { return packet_timestamp; } + + void drop_packet() const { - return pkt->is_from_server(); + pkt->active->drop_packet(pkt); + pkt->active->set_drop_reason("stream"); } - void slide_segment_in_rcv_window(int32_t offset) + bool is_meta_ack_packet() const + { return meta_ack_packet; } + + uint64_t get_packet_number() const + { return packet_number; } + + void rewrite_payload(uint16_t offset, uint8_t* from, uint16_t length) { - // This actually deletes the first offset bytes of the segment, no sliding involved - seg_seq += offset; - pkt->data += offset; - pkt->dsize -= offset; + assert(!meta_ack_packet); + memcpy(const_cast(pkt->data + offset), from, length); + set_packet_flags(PKT_MODIFIED); } + void rewrite_payload(uint16_t offset, uint8_t* from) + { rewrite_payload(offset, from, pkt->dsize); } + + TcpStreamTracker* get_listener() const + { return listener; } + + void set_listener(TcpStreamTracker& tracker) + { listener = &tracker; } + + TcpStreamTracker* get_talker() const + { return talker; } + + void set_talker(TcpStreamTracker& tracker) + { talker = &tracker; } + private: snort::Flow* const flow; snort::Packet* const pkt; - const snort::tcp::TCPHdr* const tcph; - const uint16_t src_port; - const uint16_t dst_port; - uint32_t seg_seq; - uint32_t seg_ack; - uint32_t seg_wnd; + TcpStreamTracker* talker = nullptr; + TcpStreamTracker* listener = nullptr; + + const uint64_t packet_number; + uint32_t seq; + uint32_t ack; + uint32_t wnd; uint32_t end_seq; - uint32_t ts = 0; + uint32_t timestamp_option; + uint16_t src_port; + uint16_t dst_port; + uint32_t packet_timestamp; + bool packet_from_client; + bool meta_ack_packet = false; }; #endif diff --git a/src/stream/tcp/tcp_segment_node.cc b/src/stream/tcp/tcp_segment_node.cc index 35c75acb8..2cfbc8eef 100644 --- a/src/stream/tcp/tcp_segment_node.cc +++ b/src/stream/tcp/tcp_segment_node.cc @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_segment.cc author davis mcpherson +// tcp_segment.cc author davis mcpherson // Created on: Sep 21, 2015 #ifdef HAVE_CONFIG_H @@ -104,7 +104,7 @@ TcpSegmentNode* TcpSegmentNode::create( TcpSegmentNode* TcpSegmentNode::init(const TcpSegmentDescriptor& tsd) { - return create(tsd.get_pkt()->pkth->ts, tsd.get_pkt()->data, tsd.get_seg_len()); + return create(tsd.get_pkt()->pkth->ts, tsd.get_pkt()->data, tsd.get_len()); } TcpSegmentNode* TcpSegmentNode::init(TcpSegmentNode& tns) diff --git a/src/stream/tcp/tcp_segment_node.h b/src/stream/tcp/tcp_segment_node.h index 92aa3f611..ff9fb1a7a 100644 --- a/src/stream/tcp/tcp_segment_node.h +++ b/src/stream/tcp/tcp_segment_node.h @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_segment_node.h author davis mcpherson +// tcp_segment_node.h author davis mcpherson // Created on: Sep 21, 2015 #ifndef TCP_SEGMENT_H @@ -73,7 +73,6 @@ public: uint16_t c_len; // length of data remaining for reassembly uint16_t offset; uint16_t size; // actual allocated size (overlaps cause i_len to differ) - uint8_t data[1]; }; diff --git a/src/stream/tcp/tcp_session.cc b/src/stream/tcp/tcp_session.cc index b1f18b067..9a840c4f1 100644 --- a/src/stream/tcp/tcp_session.cc +++ b/src/stream/tcp/tcp_session.cc @@ -67,10 +67,16 @@ using namespace snort; void TcpSession::sinit() -{ TcpSegmentNode::setup(); } +{ + TcpSegmentDescriptor::setup(); + TcpSegmentNode::setup(); +} void TcpSession::sterm() -{ TcpSegmentNode::clear(); } +{ + TcpSegmentDescriptor::clear(); + TcpSegmentNode::clear(); +} TcpSession::TcpSession(Flow* f) : TcpStreamSession(f) { @@ -95,8 +101,9 @@ bool TcpSession::setup(Packet* p) TcpStreamSession::setup(p); splitter_init = false; - const TcpStreamConfig* cfg = get_tcp_cfg(flow->ssn_server); - flow->set_default_session_timeout(cfg->session_timeout, false); + tcp_config = get_tcp_cfg(flow->ssn_server); + flow->set_default_session_timeout(tcp_config->session_timeout, false); + set_os_policy(); SESSION_STATS_ADD(tcpStats) tcpStats.setups++; @@ -291,36 +298,36 @@ void TcpSession::update_perf_base_state(char newState) bool TcpSession::flow_exceeds_config_thresholds(const TcpSegmentDescriptor& tsd) { + TcpStreamTracker* listener = tsd.get_listener(); + if ( listener->flush_policy == STREAM_FLPOLICY_IGNORE ) - { return true; - } // FIXIT-M any discards must be counted and in many cases alerted as well // (count all but alert at most once per flow) // three cases in this function; look for others - if ( ( config->flags & STREAM_CONFIG_NO_ASYNC_REASSEMBLY ) && !flow->two_way_traffic() ) + if ( ( tcp_config->flags & STREAM_CONFIG_NO_ASYNC_REASSEMBLY ) && !flow->two_way_traffic() ) return true; - if ( config->max_consec_small_segs ) + if ( tcp_config->max_consec_small_segs ) { - if ( tsd.get_seg_len() >= config->max_consec_small_seg_size ) + if ( tsd.get_len() >= tcp_config->max_consec_small_seg_size ) listener->small_seg_count = 0; - else if ( ++listener->small_seg_count == config->max_consec_small_segs ) + else if ( ++listener->small_seg_count == tcp_config->max_consec_small_segs ) tel.set_tcp_event(EVENT_MAX_SMALL_SEGS_EXCEEDED); } - if ( config->max_queued_bytes - && ( listener->reassembler.get_seg_bytes_total() > config->max_queued_bytes ) ) + if ( tcp_config->max_queued_bytes + && ( listener->reassembler.get_seg_bytes_total() > tcp_config->max_queued_bytes ) ) { tcpStats.exceeded_max_bytes++; // FIXIT-M add one alert per flow per above return true; } - if ( config->max_queued_segs - && ( listener->reassembler.get_seg_count() + 1 > config->max_queued_segs ) ) + if ( tcp_config->max_queued_segs + && ( listener->reassembler.get_seg_count() + 1 > tcp_config->max_queued_segs ) ) { tcpStats.exceeded_max_segs++; // FIXIT-M add one alert per flow per above @@ -332,19 +339,21 @@ bool TcpSession::flow_exceeds_config_thresholds(const TcpSegmentDescriptor& tsd) void TcpSession::process_tcp_stream(TcpSegmentDescriptor& tsd) { - if (tsd.get_pkt()->packet_flags & PKT_IGNORE) + if ( tsd.are_packet_flags_set(PKT_IGNORE) ) return; - SetPacketHeaderFoo(tsd.get_pkt()); + set_packet_header_foo(tsd); if ( flow_exceeds_config_thresholds(tsd) ) return; + TcpStreamTracker* listener = tsd.get_listener(); + listener->reassembler.queue_packet_for_reassembly(tsd); // Alert if overlap limit exceeded - if ( ( config->overlap_limit ) - && ( listener->reassembler.get_overlap_count() > config->overlap_limit ) ) + if ( (tcp_config->overlap_limit) + && (listener->reassembler.get_overlap_count() > tcp_config->overlap_limit) ) { tel.set_tcp_event(EVENT_EXCESSIVE_OVERLAP); listener->reassembler.set_overlap_count(0); @@ -353,38 +362,41 @@ void TcpSession::process_tcp_stream(TcpSegmentDescriptor& tsd) void TcpSession::update_stream_order(const TcpSegmentDescriptor& tsd, bool aligned) { + TcpStreamTracker* listener = tsd.get_listener(); + switch ( listener->order ) { case 0: if ( aligned ) - tsd.get_pkt()->packet_flags |= PKT_STREAM_ORDER_OK; + tsd.set_packet_flags(PKT_STREAM_ORDER_OK); else listener->order = 1; break; case 1: if ( aligned ) { - tsd.get_pkt()->packet_flags |= PKT_STREAM_ORDER_OK; + tsd.set_packet_flags(PKT_STREAM_ORDER_OK); listener->order = 2; } break; default: if ( aligned ) - tsd.get_pkt()->packet_flags |= PKT_STREAM_ORDER_OK; + tsd.set_packet_flags(PKT_STREAM_ORDER_OK); else { if ( !(flow->get_session_flags() & SSNFLAG_STREAM_ORDER_BAD) ) flow->set_session_flags(SSNFLAG_STREAM_ORDER_BAD); - tsd.get_pkt()->packet_flags |= PKT_STREAM_ORDER_BAD; + tsd.set_packet_flags(PKT_STREAM_ORDER_BAD); } } } int TcpSession::process_tcp_data(TcpSegmentDescriptor& tsd) { + TcpStreamTracker* listener = tsd.get_listener(); const tcp::TCPHdr* tcph = tsd.get_tcph(); - uint32_t seq = tsd.get_seg_seq(); + uint32_t seq = tsd.get_seq(); if ( tcph->is_syn() ) { @@ -401,7 +413,7 @@ int TcpSession::process_tcp_data(TcpSegmentDescriptor& tsd) if (seq == listener->rcv_nxt) { /* check if we're in the window */ - if (config->policy != StreamPolicy::OS_PROXY + if (tcp_config->policy != StreamPolicy::OS_PROXY and listener->normalizer.get_stream_window(tsd) == 0) { listener->normalizer.trim_win_payload(tsd); @@ -412,7 +424,7 @@ int TcpSession::process_tcp_data(TcpSegmentDescriptor& tsd) // FIXIT-L for ips, must move all the way to first hole or right end listener->rcv_nxt = tsd.get_end_seq(); - if (tsd.get_seg_len() != 0) + if (tsd.get_len() != 0) { update_stream_order(tsd, true); process_tcp_stream(tsd); @@ -428,13 +440,13 @@ int TcpSession::process_tcp_data(TcpSegmentDescriptor& tsd) // some cases. /* check if we're in the window */ - if (config->policy != StreamPolicy::OS_PROXY + if (tcp_config->policy != StreamPolicy::OS_PROXY and listener->normalizer.get_stream_window(tsd) == 0) { listener->normalizer.trim_win_payload(tsd); return STREAM_UNALIGNED; } - if (tsd.get_seg_len() != 0) + if (tsd.get_len() != 0) { update_stream_order(tsd, false); process_tcp_stream(tsd); @@ -447,10 +459,10 @@ int TcpSession::process_tcp_data(TcpSegmentDescriptor& tsd) void TcpSession::set_os_policy() { StreamPolicy client_os_policy = flow->ssn_policy ? - static_cast( flow->ssn_policy ) : config->policy; + static_cast( flow->ssn_policy ) : tcp_config->policy; StreamPolicy server_os_policy = flow->ssn_policy ? - static_cast( flow->ssn_policy ) : config->policy; + static_cast( flow->ssn_policy ) : tcp_config->policy; client.normalizer.init(client_os_policy, this, &client, &server); server.normalizer.init(server_os_policy, this, &server, &client); @@ -516,20 +528,26 @@ void TcpSession::init_session_on_synack(TcpSegmentDescriptor& tsd) void TcpSession::update_timestamp_tracking(TcpSegmentDescriptor& tsd) { + TcpStreamTracker* listener = tsd.get_listener(); + TcpStreamTracker* talker = tsd.get_talker(); + talker->set_tf_flags(listener->normalizer.get_timestamp_flags()); if (listener->normalizer.handling_timestamps() - && SEQ_EQ(listener->rcv_nxt, tsd.get_seg_seq())) + && SEQ_EQ(listener->rcv_nxt, tsd.get_seq())) { - talker->set_ts_last_packet(tsd.get_pkt()->pkth->ts.tv_sec); - talker->set_ts_last(tsd.get_ts()); + talker->set_ts_last_packet(tsd.get_packet_timestamp()); + talker->set_ts_last(tsd.get_timestamp()); } } bool TcpSession::handle_syn_on_reset_session(TcpSegmentDescriptor& tsd) { + TcpStreamTracker* listener = tsd.get_listener(); + TcpStreamTracker* talker = tsd.get_talker(); const tcp::TCPHdr* tcph = tsd.get_tcph(); - if ( ( listener->get_tcp_state() == TcpStreamTracker::TCP_CLOSED ) - || ( talker->get_tcp_state() == TcpStreamTracker::TCP_CLOSED ) ) + + if ( (listener->get_tcp_state() == TcpStreamTracker::TCP_CLOSED) + || (talker->get_tcp_state() == TcpStreamTracker::TCP_CLOSED) ) { // Listener previously issued a reset Talker is re-SYN-ing @@ -559,14 +577,12 @@ bool TcpSession::handle_syn_on_reset_session(TcpSegmentDescriptor& tsd) flow->set_ttl(tsd.get_pkt(), true); init_session_on_syn(tsd); tcpStats.resyns++; - listener = &server; - talker = &client; - listener->normalizer.ecn_tracker(tcph, config->require_3whs()); + listener->normalizer.ecn_tracker(tcph, tcp_config->require_3whs()); flow->update_session_flags(SSNFLAG_SEEN_CLIENT); } else if ( tcph->is_syn_ack() ) { - if (config->midstream_allowed(tsd.get_pkt())) + if ( tcp_config->midstream_allowed(tsd.get_pkt()) ) { flow->ssn_state.direction = FROM_SERVER; flow->session_state = STREAM_STATE_SYN_ACK; @@ -575,9 +591,7 @@ bool TcpSession::handle_syn_on_reset_session(TcpSegmentDescriptor& tsd) tcpStats.resyns++; } - listener = &client; - talker = &server; - listener->normalizer.ecn_tracker(tcph, config->require_3whs()); + listener->normalizer.ecn_tracker(tcph, tcp_config->require_3whs()); flow->update_session_flags(SSNFLAG_SEEN_SERVER); } } @@ -587,34 +601,43 @@ bool TcpSession::handle_syn_on_reset_session(TcpSegmentDescriptor& tsd) void TcpSession::update_ignored_session(TcpSegmentDescriptor& tsd) { + if ( tsd.is_meta_ack_packet() ) + return; + + Packet* p = tsd.get_pkt(); // FIXIT-L why flush here instead of just purge? // s5_ignored_session() may be disabling detection too soon if we really want to flush - if (Stream::ignored_flow(flow, tsd.get_pkt())) + if ( Stream::ignored_flow(flow, p) ) { + TcpStreamTracker* listener = tsd.get_listener(); + TcpStreamTracker* talker = tsd.get_talker(); + if ( talker && ( talker->get_tf_flags() & TF_FORCE_FLUSH ) ) { - flush_talker(tsd.get_pkt() ); + flush_talker(p); talker->clear_tf_flags(TF_FORCE_FLUSH); } if ( listener && ( listener->get_tf_flags() & TF_FORCE_FLUSH ) ) { - flush_listener(tsd.get_pkt()); + flush_listener(p); listener->clear_tf_flags(TF_FORCE_FLUSH); } - tsd.get_pkt()->packet_flags |= PKT_IGNORE; + tsd.set_packet_flags(PKT_IGNORE); pkt_action_mask |= ACTION_DISABLE_INSPECTION; + tcpStats.ignored++; } } void TcpSession::handle_data_on_syn(TcpSegmentDescriptor& tsd) { + TcpStreamTracker* listener = tsd.get_listener(); + TcpStreamTracker* talker = tsd.get_talker(); + /* MacOS accepts data on SYN, so don't alert if policy is MACOS */ - if (talker->normalizer.get_os_policy() == StreamPolicy::OS_MACOS) - { + if ( talker->normalizer.get_os_policy() == StreamPolicy::OS_MACOS ) handle_data_segment(tsd); - } else { listener->normalizer.trim_syn_payload(tsd); @@ -625,51 +648,53 @@ void TcpSession::handle_data_on_syn(TcpSegmentDescriptor& tsd) void TcpSession::update_session_on_rst(TcpSegmentDescriptor& tsd, bool flush) { + Packet* p = tsd.get_pkt(); + if ( flush ) { - flush_listener(tsd.get_pkt(), true); - flush_talker(tsd.get_pkt(), true); + flush_listener(p, true); + flush_talker(p, true); set_splitter(true, nullptr); set_splitter(false, nullptr); } - talker->update_on_rst_sent( ); + tsd.get_talker()->update_on_rst_sent(); } void TcpSession::update_paws_timestamps(TcpSegmentDescriptor& tsd) { - // update PAWS timestamps + TcpStreamTracker* listener = tsd.get_listener(); + TcpStreamTracker* talker = tsd.get_talker(); if ( listener->normalizer.handling_timestamps() - && SEQ_EQ(listener->r_win_base, tsd.get_seg_seq() ) ) + && SEQ_EQ(listener->r_win_base, tsd.get_seq()) ) { - if ( ( (int32_t)(tsd.get_ts() - talker->get_ts_last() ) >= 0 ) - || - ( ( uint32_t )tsd.get_pkt()->pkth->ts.tv_sec - >= talker->get_ts_last_packet() + PAWS_24DAYS ) ) + if ( ((int32_t)(tsd.get_timestamp() - talker->get_ts_last()) >= 0 ) + || (tsd.get_packet_timestamp() >= talker->get_ts_last_packet() + PAWS_24DAYS) ) { - talker->set_ts_last(tsd.get_ts()); - talker->set_ts_last_packet(tsd.get_pkt()->pkth->ts.tv_sec); + talker->set_ts_last(tsd.get_timestamp()); + talker->set_ts_last_packet(tsd.get_packet_timestamp()); } } } void TcpSession::check_for_session_hijack(TcpSegmentDescriptor& tsd) { - if (!(tsd.get_pkt()->pkth->flags & DAQ_PKT_FLAG_PRE_ROUTING)) + TcpStreamTracker* listener = tsd.get_listener(); + TcpStreamTracker* talker = tsd.get_talker(); + + Packet* p = tsd.get_pkt(); + if ( !(p->pkth->flags & DAQ_PKT_FLAG_PRE_ROUTING) ) { - if ( tsd.get_pkt()->is_eth() ) + if ( p->is_eth() ) { - // if flag is set, guaranteed to have an eth layer - Packet* p = tsd.get_pkt(); const eth::EtherHdr* eh = layer::get_eth_layer(p); bool t_hijack = !talker->compare_mac_addresses(eh->ether_src); bool l_hijack = !listener->compare_mac_addresses(eh->ether_dst); // if both seem hijacked then swap src/dst check, it that matches probably a tap - if ( ( t_hijack & l_hijack ) && - ( talker->compare_mac_addresses(eh->ether_dst) && - listener->compare_mac_addresses(eh->ether_src) ) ) + if ( (t_hijack & l_hijack) && (talker->compare_mac_addresses(eh->ether_dst) && + listener->compare_mac_addresses(eh->ether_src)) ) return; uint32_t event_code = 0; @@ -690,7 +715,7 @@ void TcpSession::check_for_session_hijack(TcpSegmentDescriptor& tsd) event_code |= EVENT_SESSION_HIJACK_CLIENT; } - if (event_code) + if ( event_code ) tel.set_tcp_event(event_code); } } @@ -698,7 +723,9 @@ void TcpSession::check_for_session_hijack(TcpSegmentDescriptor& tsd) bool TcpSession::check_for_window_slam(TcpSegmentDescriptor& tsd) { - if ( config->max_window && (tsd.get_seg_wnd() > config->max_window ) ) + TcpStreamTracker* listener = tsd.get_listener(); + + if ( tcp_config->max_window && (tsd.get_wnd() > tcp_config->max_window) ) { /* got a window too large, alert! */ tel.set_tcp_event(EVENT_WINDOW_TOO_LARGE); @@ -707,17 +734,16 @@ bool TcpSession::check_for_window_slam(TcpSegmentDescriptor& tsd) pkt_action_mask |= ACTION_BAD_PKT; return true; } - else if ((tsd.get_pkt()->is_from_client()) - && (tsd.get_seg_wnd() <= SLAM_MAX) - && (tsd.get_seg_ack() == listener->get_iss() + 1) - && !( tsd.get_tcph()->is_fin() | tsd.get_tcph()->is_rst() ) + else if ( tsd.is_packet_from_client() && (tsd.get_wnd() <= SLAM_MAX) + && (tsd.get_ack() == listener->get_iss() + 1) + && !(tsd.get_tcph()->is_fin() | tsd.get_tcph()->is_rst()) && !(flow->get_session_flags() & SSNFLAG_MIDSTREAM)) { /* got a window slam alert! */ tel.set_tcp_event(EVENT_WINDOW_SLAM); inc_tcp_discards(); - if (listener->normalizer.packet_dropper(tsd, NORM_TCP_BLOCK)) + if ( listener->normalizer.packet_dropper(tsd, NORM_TCP_BLOCK) ) { pkt_action_mask |= ACTION_BAD_PKT; return true; @@ -729,30 +755,34 @@ bool TcpSession::check_for_window_slam(TcpSegmentDescriptor& tsd) void TcpSession::mark_packet_for_drop(TcpSegmentDescriptor& tsd) { - listener->normalizer.packet_dropper(tsd, NORM_TCP_BLOCK); + + tsd.get_listener()->normalizer.packet_dropper(tsd, NORM_TCP_BLOCK); set_pkt_action_flag(ACTION_BAD_PKT); } void TcpSession::handle_data_segment(TcpSegmentDescriptor& tsd) { + TcpStreamTracker* listener = tsd.get_listener(); + TcpStreamTracker* talker = tsd.get_talker(); + if ( TcpStreamTracker::TCP_CLOSED != talker->get_tcp_state() ) { uint8_t tcp_options_len = tsd.get_tcph()->options_len(); - if (tsd.is_packet_from_server()) - server.set_tcp_options_len(tcp_options_len); - else + if ( tsd.is_packet_from_client() ) client.set_tcp_options_len(tcp_options_len); + else + server.set_tcp_options_len(tcp_options_len); // FIXIT-M move this to normalizer base class, handle OS_PROXY in derived class - if (config->policy != StreamPolicy::OS_PROXY) + if ( tcp_config->policy != StreamPolicy::OS_PROXY ) { /* check for valid sequence/retrans */ - if (!listener->is_segment_seq_valid(tsd) ) + if ( !listener->is_segment_seq_valid(tsd) ) return; // these normalizations can't be done if we missed setup. and // window is zero in one direction until we've seen both sides. - if (!(flow->get_session_flags() & SSNFLAG_MIDSTREAM) && flow->two_way_traffic()) + if ( !(flow->get_session_flags() & SSNFLAG_MIDSTREAM) && flow->two_way_traffic() ) { // sender of syn w/mss limits payloads from peer since we store mss on // sender side, use listener mss same reasoning for window size @@ -764,17 +794,17 @@ void TcpSession::handle_data_segment(TcpSegmentDescriptor& tsd) // FIXIT-H: MSS is not set on client so packets sent to client are not trimmed // use case? - if (st->get_mss()) + if ( st->get_mss() ) st->normalizer.trim_mss_payload(tsd, st->get_mss()); - st->normalizer.ecn_stripper(tsd.get_pkt()); + st->normalizer.ecn_stripper(tsd); } } // dunno if this is RFC but fragroute testing expects it for the record, // I've seen FTP data sessions that send data packets with no tcp flags set - if ((tsd.get_tcph()->th_flags != 0) or (config->policy == StreamPolicy::OS_LINUX) - or (config->policy == StreamPolicy::OS_PROXY)) + if ( (tsd.get_tcph()->th_flags != 0) or (tcp_config->policy == StreamPolicy::OS_LINUX) + or (tcp_config->policy == StreamPolicy::OS_PROXY) ) { process_tcp_data(tsd); } @@ -788,21 +818,23 @@ void TcpSession::handle_data_segment(TcpSegmentDescriptor& tsd) listener->reassembler.flush_on_data_policy(tsd.get_pkt()); } -TcpStreamTracker::TcpState TcpSession::get_talker_state() +TcpStreamTracker::TcpState TcpSession::get_talker_state(TcpSegmentDescriptor& tsd) { - return talker->get_tcp_state(); + return tsd.get_talker()->get_tcp_state(); } -TcpStreamTracker::TcpState TcpSession::get_listener_state() +TcpStreamTracker::TcpState TcpSession::get_listener_state(TcpSegmentDescriptor& tsd) { - return listener->get_tcp_state(); + return tsd.get_listener()->get_tcp_state(); } void TcpSession::check_for_repeated_syn(TcpSegmentDescriptor& tsd) { + TcpStreamTracker* listener = tsd.get_listener(); + TcpStreamTracker* talker = tsd.get_talker(); uint32_t action = ACTION_NOTHING; - if ( !SEQ_EQ(tsd.get_seg_seq(), talker->get_iss()) and + if ( !SEQ_EQ(tsd.get_seq(), talker->get_iss()) and listener->normalizer.packet_dropper(tsd, NORM_TCP_BLOCK) ) { action = ACTION_BAD_PKT; @@ -812,9 +844,9 @@ void TcpSession::check_for_repeated_syn(TcpSegmentDescriptor& tsd) { action = listener->normalizer.handle_repeated_syn(tsd); } + if (action != ACTION_NOTHING) { - /* got a bad SYN on the session, alert! */ tel.set_tcp_event(EVENT_SYN_ON_EST); pkt_action_mask |= action; } @@ -827,12 +859,9 @@ void TcpSession::flush_server(Packet* p) server.set_tf_flags(TF_FORCE_FLUSH); - // If rebuilt packet, don't flush now because we'll overwrite the packet being processed. + // don't flush if rebuilt packet, that would overwrite the packet being processed. if ( p->packet_flags & PKT_REBUILT_STREAM ) - { - // We'll check & clear the TF_FORCE_FLUSH next time through - return; - } + return; // We'll check & clear the TF_FORCE_FLUSH next time through // Need to convert the addresses to network order if ( server.reassembler.flush_stream(p, PKT_FROM_SERVER) ) @@ -850,10 +879,7 @@ void TcpSession::flush_client(Packet* p) // If rebuilt packet, don't flush now because we'll overwrite the packet being processed. if ( p->packet_flags & PKT_REBUILT_STREAM ) - { - // We'll check & clear the TF_FORCE_FLUSH next time through - return; - } + return; // TF_FORCE_FLUSH checked & cleared next time through if ( client.reassembler.flush_stream(p, PKT_FROM_CLIENT) ) client.reassembler.purge_flushed_ackd(); @@ -864,7 +890,7 @@ void TcpSession::flush_client(Packet* p) void TcpSession::flush_tracker( TcpStreamTracker& tracker, Packet* p, uint32_t dir, bool final_flush) { - if ( final_flush && ( !tracker.splitter || !tracker.splitter->finish(flow) ) ) + if ( final_flush && (!tracker.splitter || !tracker.splitter->finish(flow)) ) return; tracker.set_tf_flags(TF_FORCE_FLUSH); @@ -898,52 +924,50 @@ void TcpSession::set_extra_data(Packet* p, uint32_t xid) st.reassembler.set_xtradata_mask(st.reassembler.get_xtradata_mask() | BIT(xid)); } -static inline void set_window_scale(const TcpStreamTracker& talker, const TcpStreamTracker& listener, - TcpSegmentDescriptor& tsd) +static inline void set_window_scale(TcpSegmentDescriptor& tsd) { // scale the window. Only if BOTH client and server specified wscale option as part // of 3-way handshake. This is per RFC 1323. - if ( ( talker.get_tf_flags() & TF_WSCALE ) && ( listener.get_tf_flags() & TF_WSCALE ) ) - tsd.scale_seg_wnd(talker.get_wscale() ); + if ( (tsd.get_talker()->get_tf_flags() & TF_WSCALE) + && (tsd.get_listener()->get_tf_flags() & TF_WSCALE) ) + { + tsd.scale_wnd(tsd.get_talker()->get_wscale()); + } } -void TcpSession::do_packet_analysis_post_checks(Packet* p) +void TcpSession::check_events_and_actions(const TcpSegmentDescriptor& tsd) { + if ( tsd.is_meta_ack_packet() ) + return; + tel.log_tcp_events(); - if (!(pkt_action_mask & ACTION_LWSSN_CLOSED)) + Packet* p = tsd.get_pkt(); + if ( !(pkt_action_mask & ACTION_LWSSN_CLOSED) ) { flow->markup_packet_flags(p); - flow->set_expire(p, flow->default_session_timeout); } else - TcpHAManager::process_deletion(*p->flow); + TcpHAManager::process_deletion(*flow); - if (pkt_action_mask & ACTION_DISABLE_INSPECTION) - { + if ( pkt_action_mask & ACTION_DISABLE_INSPECTION ) DetectionEngine::disable_all(p); - } } -// FIXIT-M can flow do these checks before calling stream tcp? -bool TcpSession::is_flow_handling_packets(Packet* p) +bool TcpSession::ignore_this_packet(Packet* p) { - bool flow_ready = true; - - // FIXIT-L can't get here without protocol being set to TCP, is this really needed?? - if (flow->pkt_type != PktType::TCP) + if ( no_ack_mode_enabled() and p->is_retry() ) { - return false; + // Don't need to process a retry packet through stream again, + // just make sure the retransmit handler is called so that + // we do things like update file inspection. + flow->call_handlers(p, false); + return true; } - if(flow->session_state & STREAM_STATE_IGNORE) - { - tcpStats.ignored++; - flow_ready = false; - } - else - flow_ready = !Stream::blocked_flow(p); + if ( Stream::blocked_flow(p) ) + return true; // FIXIT-L expected flow should be checked by Stream before we get here // harmonize this with that and the checks above @@ -951,20 +975,20 @@ bool TcpSession::is_flow_handling_packets(Packet* p) { server.flush_policy = STREAM_FLPOLICY_IGNORE; client.flush_policy = STREAM_FLPOLICY_IGNORE; - flow_ready = false; + return true; } - return flow_ready; + return false; } void TcpSession::cleanup_session_if_expired(Packet* p) { // Check if the session is expired. Should be done before we do something with // the packet...Insert a packet, or handle state change SYN, FIN, RST, etc. - if (Stream::expired_flow(flow, p)) + if ( Stream::expired_flow(flow, p) ) { /* Session is timed out, if also reset then restart, otherwise clear */ - if (flow->get_session_flags() & SSNFLAG_RESET) + if ( flow->get_session_flags() & SSNFLAG_RESET ) clear_session(true, true, true, p); else clear_session(true, true, false, p); @@ -981,14 +1005,11 @@ void TcpSession::precheck(Packet* p) cleanup_session_if_expired(p); } -bool TcpSession::do_packet_analysis_pre_checks(Packet* p, TcpSegmentDescriptor& tsd) +void TcpSession::init_tcp_packet_analysis(TcpSegmentDescriptor& tsd) { - if ( !is_flow_handling_packets(p) ) - return false; - - if ( !splitter_init and tsd.get_seg_len() > 0 ) + if ( !splitter_init and tsd.get_len() > 0 ) { - if ( !(config->flags & STREAM_CONFIG_NO_REASSEMBLY) ) + if ( !(tcp_config->flags & STREAM_CONFIG_NO_REASSEMBLY) ) { client.set_splitter(tsd.get_flow()); server.set_splitter(tsd.get_flow()); @@ -996,8 +1017,9 @@ bool TcpSession::do_packet_analysis_pre_checks(Packet* p, TcpSegmentDescriptor& client.init_flush_policy(); server.init_flush_policy(); - set_no_ack(config->no_ack); + set_no_ack(tcp_config->no_ack); } + splitter_init = true; } @@ -1009,96 +1031,93 @@ bool TcpSession::do_packet_analysis_pre_checks(Packet* p, TcpSegmentDescriptor& // FIXIT-M: The snd_nxt and snd_una checks are only needed because // the snd_nxt value isn't valid for SYN/ACK packet. Can remove those // checks if that is fixed. - if ( p->is_from_client() ) + if ( tsd.is_packet_from_client() ) { update_session_on_client_packet(tsd); if ( no_ack_mode_enabled() and (server.get_snd_nxt() or server.get_snd_una()) ) - tsd.set_seg_ack(server.get_snd_nxt()); + tsd.set_ack(server.get_snd_nxt()); } else { update_session_on_server_packet(tsd); if ( no_ack_mode_enabled() and (client.get_snd_nxt() or client.get_snd_una()) ) - tsd.set_seg_ack(client.get_snd_nxt()); + tsd.set_ack(client.get_snd_nxt()); } update_ignored_session(tsd); - set_window_scale(*talker, *listener, tsd); - - if ( p->context->conf->is_address_anomaly_check_enabled() ) - check_for_session_hijack(tsd); - - return true; + set_window_scale(tsd); } bool TcpSession::validate_packet_established_session(TcpSegmentDescriptor& tsd) { + TcpStreamTracker* listener = tsd.get_listener(); + pkt_action_mask |= listener->normalizer.handle_paws(tsd); - if ( tsd.get_pkt()->context->conf->inline_mode() ) - if ( tsd.get_tcph()->is_ack() && !listener->is_ack_valid(tsd.get_seg_ack()) ) + if ( tsd.is_policy_inline() ) + if ( tsd.get_tcph()->is_ack() && !listener->is_ack_valid(tsd.get_ack()) ) pkt_action_mask |= ACTION_BAD_PKT; return ( pkt_action_mask & ACTION_BAD_PKT ) ? false : true; } -/* - * Main entry point for TCP - */ -int TcpSession::process(Packet* p) +int TcpSession::process_tcp_packet(TcpSegmentDescriptor& tsd) { - Profile profile(s5TcpPerfStats); - assert(flow->ssn_server); - - if ( no_ack_mode_enabled() and p->is_retry() ) + if ( tsm->eval(tsd) ) { - // Don't need to process a retry packet through stream again, - // just make sure the retransmit handler is called so that - // we do things like update file inspection. - flow->call_handlers(p, false); - return ACTION_NOTHING; + check_events_and_actions(tsd); + S5TraceTCP(tsd); } + else + { + if ( pkt_action_mask & ACTION_BAD_PKT ) + { + inc_tcp_discards(); + check_events_and_actions(tsd); + } - // FIXIT-M need to do something here to handle check for need to swap trackers?? - if ( !config ) - config = get_tcp_cfg(flow->ssn_server); + tel.log_tcp_events(); + S5TraceTCP(tsd); + } - if( !tcp_init ) - set_os_policy(); + return ACTION_NOTHING; +} - TcpSegmentDescriptor tsd(flow, p, tel); +int TcpSession::process(Packet* p) +{ + Profile profile(s5TcpPerfStats); + assert(flow->ssn_server && flow->pkt_type == PktType::TCP); - if ( !do_packet_analysis_pre_checks(p, tsd) ) + if ( ignore_this_packet(p) ) return ACTION_NOTHING; - if ( ( flow->get_session_flags() & SSNFLAG_RESET ) && tsd.get_tcph()->is_syn() - && !handle_syn_on_reset_session(tsd) ) - return ACTION_NOTHING; + TcpSegmentDescriptor tsd(flow, p, tel); + init_tcp_packet_analysis(tsd); - else + // if listener is in pre-ack mode, check for and process meta-ack info first if present + // the current listener is the talker for the meta-ack... + if ( tsd.get_listener()->get_flush_policy() == STREAM_FLPOLICY_ON_DATA ) { - if ( tsm->eval(tsd, *talker, *listener) ) + DAQ_PktTcpAckData_t* tcp_mack = (DAQ_PktTcpAckData_t*)p->daq_msg->meta[DAQ_PKT_META_TCP_ACK_DATA]; + if ( tcp_mack ) { - do_packet_analysis_post_checks(p); - S5TraceTCP(p, flow, &tsd, 0); + 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); + tcpStats.meta_acks++; } - else - { - if ( pkt_action_mask & ACTION_BAD_PKT ) - { - inc_tcp_discards(); + } - do_packet_analysis_post_checks(p); - } + if ( p->context->conf->is_address_anomaly_check_enabled() ) + check_for_session_hijack(tsd); - tel.log_tcp_events(); - S5TraceTCP(p, flow, &tsd, 0); - } - } + if ( ( flow->get_session_flags() & SSNFLAG_RESET ) && tsd.get_tcph()->is_syn() + && !handle_syn_on_reset_session(tsd) ) + return ACTION_NOTHING; - return ACTION_NOTHING; + return process_tcp_packet(tsd); } void TcpSession::flush() diff --git a/src/stream/tcp/tcp_session.h b/src/stream/tcp/tcp_session.h index c8cd67cb8..06f570a19 100644 --- a/src/stream/tcp/tcp_session.h +++ b/src/stream/tcp/tcp_session.h @@ -54,8 +54,8 @@ public: void clear_session(bool free_flow_data, bool flush_segments, bool restart, snort::Packet* p = nullptr) override; void set_extra_data(snort::Packet*, uint32_t /*flag*/) override; void update_perf_base_state(char new_state) override; - TcpStreamTracker::TcpState get_talker_state() override; - TcpStreamTracker::TcpState get_listener_state() override; + TcpStreamTracker::TcpState get_talker_state(TcpSegmentDescriptor& tsd) override; + TcpStreamTracker::TcpState get_listener_state(TcpSegmentDescriptor& tsd) override; void update_timestamp_tracking(TcpSegmentDescriptor&) override; void update_session_on_rst(TcpSegmentDescriptor&, bool) override; bool handle_syn_on_reset_session(TcpSegmentDescriptor&) override; @@ -69,20 +69,24 @@ public: void handle_data_segment(TcpSegmentDescriptor&) override; bool validate_packet_established_session(TcpSegmentDescriptor&) override; + bool is_midstream_allowed(const TcpSegmentDescriptor& tsd) + { return tcp_config->midstream_allowed(tsd.get_pkt()); } + private: + int process_tcp_packet(TcpSegmentDescriptor&); + void process_tcp_stream(TcpSegmentDescriptor&); + int process_tcp_data(TcpSegmentDescriptor&); void set_os_policy() override; bool flow_exceeds_config_thresholds(const TcpSegmentDescriptor&); void update_stream_order(const TcpSegmentDescriptor&, bool aligned); - void process_tcp_stream(TcpSegmentDescriptor&); - int process_tcp_data(TcpSegmentDescriptor&); void swap_trackers(); void init_session_on_syn(TcpSegmentDescriptor&); void init_session_on_synack(TcpSegmentDescriptor&); void update_on_3whs_complete(TcpSegmentDescriptor&); - bool is_flow_handling_packets(snort::Packet*); + bool ignore_this_packet(snort::Packet*); void cleanup_session_if_expired(snort::Packet*); - bool do_packet_analysis_pre_checks(snort::Packet*, TcpSegmentDescriptor&); - void do_packet_analysis_post_checks(snort::Packet*); + void init_tcp_packet_analysis(TcpSegmentDescriptor&); + void check_events_and_actions(const TcpSegmentDescriptor& tsd); void flush_tracker(TcpStreamTracker&, snort::Packet*, uint32_t dir, bool final_flush); private: diff --git a/src/stream/tcp/tcp_state_close_wait.cc b/src/stream/tcp/tcp_state_close_wait.cc index 45aba2699..acc7fb239 100644 --- a/src/stream/tcp/tcp_state_close_wait.cc +++ b/src/stream/tcp/tcp_state_close_wait.cc @@ -37,9 +37,9 @@ TcpStateCloseWait::TcpStateCloseWait(TcpStateMachine& tsm) : bool TcpStateCloseWait::syn_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs() ); + trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs() ); - if ( tsd.get_seg_len() ) + if ( tsd.get_len() ) trk.session->handle_data_on_syn(tsd); return true; @@ -83,7 +83,7 @@ bool TcpStateCloseWait::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& tr trk.update_tracker_ack_recv(tsd); - if ( SEQ_GT(tsd.get_seg_seq(), trk.get_fin_final_seq() ) ) + if ( SEQ_GT(tsd.get_seq(), trk.get_fin_final_seq() ) ) { trk.session->tel.set_tcp_event(EVENT_BAD_FIN); trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK); @@ -93,7 +93,7 @@ bool TcpStateCloseWait::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& tr { if ( !flow->two_way_traffic() ) trk.set_tf_flags(TF_FORCE_FLUSH); - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) trk.session->handle_data_segment(tsd); } return true; @@ -106,7 +106,7 @@ bool TcpStateCloseWait::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& tr trk.session->update_session_on_rst(tsd, true); trk.session->update_perf_base_state(TcpStreamTracker::TCP_CLOSING); trk.session->set_pkt_action_flag(ACTION_RST); - tsd.get_pkt()->flow->session_state |= STREAM_STATE_CLOSED; + tsd.get_flow()->session_state |= STREAM_STATE_CLOSED; } else { diff --git a/src/stream/tcp/tcp_state_close_wait.h b/src/stream/tcp/tcp_state_close_wait.h index 4b7cec6bd..601215f35 100644 --- a/src/stream/tcp/tcp_state_close_wait.h +++ b/src/stream/tcp/tcp_state_close_wait.h @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_state_close_wait.h author davis mcpherson +// tcp_state_close_wait.h author davis mcpherson // Created on: Aug 5, 2015 #ifndef TCP_STATE_CLOSE_WAIT_H diff --git a/src/stream/tcp/tcp_state_closed.cc b/src/stream/tcp/tcp_state_closed.cc index c22922469..582d593f6 100644 --- a/src/stream/tcp/tcp_state_closed.cc +++ b/src/stream/tcp/tcp_state_closed.cc @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_state_closed.cc author davis mcpherson +// tcp_state_closed.cc author davis mcpherson // Created on: Jul 30, 2015 #ifdef HAVE_CONFIG_H @@ -47,7 +47,7 @@ bool TcpStateClosed::syn_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) bool TcpStateClosed::syn_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { Flow* flow = tsd.get_flow(); - flow->set_expire(tsd.get_pkt(), trk.session->config->session_timeout); + flow->set_expire(tsd.get_pkt(), trk.session->tcp_config->session_timeout); return true; } @@ -99,7 +99,7 @@ bool TcpStateClosed::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { trk.update_tracker_ack_recv(tsd); - if( tsd.get_seg_len() > 0 ) + if( tsd.get_len() > 0 ) { if ( trk.is_rst_pkt_sent() ) trk.session->tel.set_tcp_event(EVENT_DATA_AFTER_RESET); @@ -136,7 +136,7 @@ bool TcpStateClosed::do_post_sm_packet_actions(TcpSegmentDescriptor& tsd, TcpStr if ( trk.get_tcp_event() != TcpStreamTracker::TCP_FIN_RECV_EVENT ) { - TcpStreamTracker::TcpState talker_state = trk.session->get_talker_state(); + TcpStreamTracker::TcpState talker_state = trk.session->get_talker_state(tsd); Flow* flow = tsd.get_flow(); if ( ( talker_state == TcpStreamTracker::TCP_TIME_WAIT ) || !flow->two_way_traffic() ) diff --git a/src/stream/tcp/tcp_state_closing.cc b/src/stream/tcp/tcp_state_closing.cc index 82b8b2305..132585fce 100644 --- a/src/stream/tcp/tcp_state_closing.cc +++ b/src/stream/tcp/tcp_state_closing.cc @@ -43,8 +43,8 @@ bool TcpStateClosing::syn_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) bool TcpStateClosing::syn_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs()); - if ( tsd.get_seg_len() ) + trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); + if ( tsd.get_len() ) trk.session->handle_data_on_syn(tsd); return true; } @@ -88,7 +88,7 @@ bool TcpStateClosing::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) Flow* flow = tsd.get_flow(); trk.update_tracker_ack_recv(tsd); - if ( SEQ_GT(tsd.get_seg_seq(), trk.get_fin_final_seq() ) ) + if ( SEQ_GT(tsd.get_seq(), trk.get_fin_final_seq() ) ) { trk.session->tel.set_tcp_event(EVENT_BAD_FIN); trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK); @@ -98,7 +98,7 @@ bool TcpStateClosing::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) if ( !flow->two_way_traffic() ) trk.set_tf_flags(TF_FORCE_FLUSH); - if ( SEQ_EQ(tsd.get_seg_ack(), trk.get_snd_nxt() ) ) + if ( SEQ_EQ(tsd.get_ack(), trk.get_snd_nxt() ) ) trk.set_tcp_state(TcpStreamTracker::TCP_TIME_WAIT); return true; } @@ -110,7 +110,7 @@ bool TcpStateClosing::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) trk.session->update_session_on_rst(tsd, true); trk.session->update_perf_base_state(TcpStreamTracker::TCP_CLOSING); trk.session->set_pkt_action_flag(ACTION_RST); - tsd.get_pkt()->flow->session_state |= STREAM_STATE_CLOSED; + tsd.get_flow()->session_state |= STREAM_STATE_CLOSED; } else { @@ -132,8 +132,8 @@ bool TcpStateClosing::do_post_sm_packet_actions(TcpSegmentDescriptor& tsd, TcpSt // Handle getting stuck in CLOSED/FIN_WAIT on simultaneous close (FIN FIN ACK ACK) if ( trk.get_tcp_event() != TcpStreamTracker::TCP_FIN_RECV_EVENT ) { - if ( ( trk.session->get_talker_state() == TcpStreamTracker::TCP_CLOSED ) && - ( trk.session->get_listener_state() == TcpStreamTracker::TCP_TIME_WAIT ) ) + if ( ( trk.session->get_talker_state(tsd) == TcpStreamTracker::TCP_CLOSED ) && + ( trk.session->get_listener_state(tsd) == TcpStreamTracker::TCP_TIME_WAIT ) ) { Flow* flow = tsd.get_flow(); trk.session->clear_session(false, true, false, tsd.get_pkt() ); diff --git a/src/stream/tcp/tcp_state_established.cc b/src/stream/tcp/tcp_state_established.cc index 3418d413d..a6f4e5e77 100644 --- a/src/stream/tcp/tcp_state_established.cc +++ b/src/stream/tcp/tcp_state_established.cc @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_state_established.cc author davis mcpherson +// tcp_state_established.cc author davis mcpherson // Created on: Jul 30, 2015 #ifdef HAVE_CONFIG_H @@ -42,13 +42,13 @@ bool TcpStateEstablished::syn_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& bool TcpStateEstablished::syn_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { trk.session->check_for_repeated_syn(tsd); - trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs()); + trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); return true; } bool TcpStateEstablished::syn_ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.session->config->midstream_allowed(tsd.get_pkt()) ) + if ( trk.session->tcp_config->midstream_allowed(tsd.get_pkt()) ) { // FIXIT-M there may be an issue when syn/ack from server is seen // after ack from client which causes some tracker state variables to @@ -59,7 +59,7 @@ bool TcpStateEstablished::syn_ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTrack } if ( trk.is_server_tracker() ) - trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs() ); + trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs() ); return true; } @@ -96,16 +96,15 @@ bool TcpStateEstablished::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTrac bool TcpStateEstablished::fin_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { trk.update_on_fin_sent(tsd); - trk.session->eof_handle(tsd.get_pkt()); + trk.session->flow->call_handlers(tsd.get_pkt(), true); trk.set_tcp_state(TcpStreamTracker::TCP_FIN_WAIT1); - return true; } bool TcpStateEstablished::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { trk.update_tracker_ack_recv(tsd); - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) { trk.session->handle_data_segment(tsd); trk.flush_data_on_fin_recv(tsd); @@ -134,7 +133,7 @@ bool TcpStateEstablished::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& } // FIXIT-L might be good to create alert specific to RST with data - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) trk.session->tel.set_tcp_event(EVENT_DATA_AFTER_RST_RCVD); return true; diff --git a/src/stream/tcp/tcp_state_fin_wait1.cc b/src/stream/tcp/tcp_state_fin_wait1.cc index 729aed95c..2656058ad 100644 --- a/src/stream/tcp/tcp_state_fin_wait1.cc +++ b/src/stream/tcp/tcp_state_fin_wait1.cc @@ -44,15 +44,15 @@ bool TcpStateFinWait1::syn_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk bool TcpStateFinWait1::syn_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs()); - if ( tsd.get_seg_len() ) + trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); + if ( tsd.get_len() ) trk.session->handle_data_on_syn(tsd); return true; } bool TcpStateFinWait1::syn_ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( tsd.get_seg_len() ) + if ( tsd.get_len() ) trk.session->handle_data_on_syn(tsd); return true; } @@ -81,7 +81,7 @@ bool TcpStateFinWait1::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker trk.update_tracker_ack_recv(tsd); if ( check_for_window_slam(tsd, trk) ) { - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) trk.session->handle_data_segment(tsd); } return true; @@ -103,7 +103,7 @@ bool TcpStateFinWait1::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk bool is_ack_valid = false; if ( check_for_window_slam(tsd, trk, &is_ack_valid) ) { - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) trk.session->handle_data_segment(tsd); if ( !flow->two_way_traffic() ) @@ -125,7 +125,7 @@ bool TcpStateFinWait1::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk trk.session->update_session_on_rst(tsd, true); trk.session->update_perf_base_state(TcpStreamTracker::TCP_CLOSING); trk.session->set_pkt_action_flag(ACTION_RST); - tsd.get_pkt()->flow->session_state |= STREAM_STATE_CLOSED; + tsd.get_flow()->session_state |= STREAM_STATE_CLOSED; } else { @@ -133,17 +133,17 @@ bool TcpStateFinWait1::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk } // FIXIT-L might be good to create alert specific to RST with data - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) trk.session->tel.set_tcp_event(EVENT_DATA_AFTER_RST_RCVD); return true; } bool TcpStateFinWait1::check_for_window_slam(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk, bool* is_ack_valid) { - if ( SEQ_EQ(tsd.get_seg_ack(), trk.get_snd_nxt() ) ) + if ( SEQ_EQ(tsd.get_ack(), trk.get_snd_nxt() ) ) { if ( (trk.normalizer.get_os_policy() == StreamPolicy::OS_WINDOWS) - && (tsd.get_seg_wnd() == 0)) + && (tsd.get_wnd() == 0)) { trk.session->tel.set_tcp_event(EVENT_WINDOW_SLAM); inc_tcp_discards(); diff --git a/src/stream/tcp/tcp_state_fin_wait1.h b/src/stream/tcp/tcp_state_fin_wait1.h index 6dad6be55..1bdb0879b 100644 --- a/src/stream/tcp/tcp_state_fin_wait1.h +++ b/src/stream/tcp/tcp_state_fin_wait1.h @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_state_fin_wait1.h author davis mcpherson +// tcp_state_fin_wait1.h author davis mcpherson // Created on: Aug 5, 2015 #ifndef TCP_STATE_FIN_WAIT1_H diff --git a/src/stream/tcp/tcp_state_fin_wait2.cc b/src/stream/tcp/tcp_state_fin_wait2.cc index ce70698b4..f314f147c 100644 --- a/src/stream/tcp/tcp_state_fin_wait2.cc +++ b/src/stream/tcp/tcp_state_fin_wait2.cc @@ -43,15 +43,15 @@ bool TcpStateFinWait2::syn_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk bool TcpStateFinWait2::syn_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs()); - if ( tsd.get_seg_len() ) + trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); + if ( tsd.get_len() ) trk.session->handle_data_on_syn(tsd); return true; } bool TcpStateFinWait2::syn_ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( tsd.get_seg_len() ) + if ( tsd.get_len() ) trk.session->handle_data_on_syn(tsd); return true; } @@ -64,7 +64,7 @@ bool TcpStateFinWait2::ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk bool TcpStateFinWait2::ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( SEQ_GT(tsd.get_seg_ack(), trk.get_snd_nxt() ) ) + if ( SEQ_GT(tsd.get_ack(), trk.get_snd_nxt() ) ) { trk.session->tel.set_tcp_event(EVENT_BAD_ACK); trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK); @@ -86,7 +86,7 @@ bool TcpStateFinWait2::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker bool TcpStateFinWait2::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( SEQ_GT(tsd.get_seg_ack(), trk.get_snd_nxt() ) ) + if ( SEQ_GT(tsd.get_ack(), trk.get_snd_nxt() ) ) { trk.session->tel.set_tcp_event(EVENT_BAD_ACK); trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK); @@ -95,7 +95,7 @@ bool TcpStateFinWait2::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker else { trk.update_tracker_ack_recv(tsd); - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) trk.session->handle_data_segment(tsd); } return true; @@ -108,7 +108,7 @@ bool TcpStateFinWait2::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk trk.update_tracker_ack_recv(tsd); if ( trk.update_on_fin_recv(tsd) ) { - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) trk.session->handle_data_segment(tsd); if ( !flow->two_way_traffic() ) @@ -126,7 +126,7 @@ bool TcpStateFinWait2::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk trk.session->update_session_on_rst(tsd, true); trk.session->update_perf_base_state(TcpStreamTracker::TCP_CLOSING); trk.session->set_pkt_action_flag(ACTION_RST); - tsd.get_pkt()->flow->session_state |= STREAM_STATE_CLOSED; + tsd.get_flow()->session_state |= STREAM_STATE_CLOSED; } else { diff --git a/src/stream/tcp/tcp_state_fin_wait2.h b/src/stream/tcp/tcp_state_fin_wait2.h index 353931b68..e98551a64 100644 --- a/src/stream/tcp/tcp_state_fin_wait2.h +++ b/src/stream/tcp/tcp_state_fin_wait2.h @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_state_fin_wait2.h author davis mcpherson +// tcp_state_fin_wait2.h author davis mcpherson // Created on: Aug 5, 2015 #ifndef TCP_STATE_FIN_WAIT2_H diff --git a/src/stream/tcp/tcp_state_handler.cc b/src/stream/tcp/tcp_state_handler.cc index e15dcea42..7aa331d48 100644 --- a/src/stream/tcp/tcp_state_handler.cc +++ b/src/stream/tcp/tcp_state_handler.cc @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_state_handler.cc author davis mcpherson +// tcp_state_handler.cc author davis mcpherson // Created on: Jun 24, 2015 #ifdef HAVE_CONFIG_H diff --git a/src/stream/tcp/tcp_state_handler.h b/src/stream/tcp/tcp_state_handler.h index a71061dd6..b7e014f7f 100644 --- a/src/stream/tcp/tcp_state_handler.h +++ b/src/stream/tcp/tcp_state_handler.h @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_state_handler.h author davis mcpherson +// tcp_state_handler.h author davis mcpherson // Created on: Jun 24, 2015 #ifndef TCP_STATE_HANDLER_H diff --git a/src/stream/tcp/tcp_state_last_ack.cc b/src/stream/tcp/tcp_state_last_ack.cc index 63f8c48b9..2f1f54dcb 100644 --- a/src/stream/tcp/tcp_state_last_ack.cc +++ b/src/stream/tcp/tcp_state_last_ack.cc @@ -43,8 +43,8 @@ bool TcpStateLastAck::syn_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) bool TcpStateLastAck::syn_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs()); - if ( tsd.get_seg_len() ) + trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); + if ( tsd.get_len() ) trk.session->handle_data_on_syn(tsd); return true; } @@ -58,7 +58,7 @@ bool TcpStateLastAck::ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) bool TcpStateLastAck::ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { trk.update_tracker_ack_recv(tsd); - if ( SEQ_EQ(tsd.get_seg_ack(), trk.get_snd_nxt() ) ) + if ( SEQ_EQ(tsd.get_ack(), trk.get_snd_nxt() ) ) trk.set_tcp_state(TcpStreamTracker::TCP_CLOSED); return true; } @@ -72,7 +72,7 @@ bool TcpStateLastAck::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& bool TcpStateLastAck::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { trk.update_tracker_ack_recv(tsd); - if ( SEQ_EQ(tsd.get_seg_ack(), trk.get_snd_nxt() ) ) + if ( SEQ_EQ(tsd.get_ack(), trk.get_snd_nxt() ) ) trk.set_tcp_state(TcpStreamTracker::TCP_CLOSED); return true; } @@ -88,7 +88,7 @@ bool TcpStateLastAck::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) Flow* flow = tsd.get_flow(); trk.update_tracker_ack_recv(tsd); - if ( SEQ_EQ(tsd.get_seg_ack(), trk.get_snd_nxt() ) ) + if ( SEQ_EQ(tsd.get_ack(), trk.get_snd_nxt() ) ) trk.set_tcp_state(TcpStreamTracker::TCP_CLOSED); if ( !flow->two_way_traffic() ) @@ -110,7 +110,7 @@ bool TcpStateLastAck::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) } // FIXIT-L might be good to create alert specific to RST with data - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) trk.session->tel.set_tcp_event(EVENT_DATA_AFTER_RST_RCVD); return true; } @@ -125,10 +125,10 @@ bool TcpStateLastAck::do_post_sm_packet_actions(TcpSegmentDescriptor& tsd, TcpSt trk.session->update_paws_timestamps(tsd); trk.session->check_for_window_slam(tsd); - if ( ( trk.session->get_listener_state() == TcpStreamTracker::TCP_CLOSED ) && + if ( ( trk.session->get_listener_state(tsd) == TcpStreamTracker::TCP_CLOSED ) && ( trk.get_tcp_event() != TcpStreamTracker::TCP_FIN_RECV_EVENT ) ) { - TcpStreamTracker::TcpState talker_state = trk.session->get_talker_state(); + TcpStreamTracker::TcpState talker_state = trk.session->get_talker_state(tsd); Flow* flow = tsd.get_flow(); if ( ( talker_state == TcpStreamTracker::TCP_TIME_WAIT ) diff --git a/src/stream/tcp/tcp_state_listen.cc b/src/stream/tcp/tcp_state_listen.cc index 4e45ba2ef..afdb7dc89 100644 --- a/src/stream/tcp/tcp_state_listen.cc +++ b/src/stream/tcp/tcp_state_listen.cc @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_state_listen.cc author davis mcpherson +// tcp_state_listen.cc author davis mcpherson // Created on: Jul 30, 2015 #ifdef HAVE_CONFIG_H @@ -37,10 +37,9 @@ TcpStateListen::TcpStateListen(TcpStateMachine& tsm) : bool TcpStateListen::syn_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.session->config->require_3whs() || tsd.has_wscale() || ( tsd.get_seg_len() > 0 ) ) + if ( trk.session->tcp_config->require_3whs() || tsd.has_wscale() || ( tsd.get_len() > 0 ) ) { - // FIXIT-L do we need this check? only server goes into Listen state... - if ( tsd.get_pkt()->is_from_server() ) + if ( tsd.is_packet_from_server() ) trk.session->tel.set_tcp_event(EVENT_4WHS); } return true; @@ -49,9 +48,9 @@ bool TcpStateListen::syn_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) bool TcpStateListen::syn_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { trk.init_on_syn_recv(tsd); - trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs()); + trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); trk.session->set_pkt_action_flag(trk.normalizer.handle_paws(tsd) ); - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) trk.session->handle_data_on_syn(tsd); return true; } @@ -61,13 +60,13 @@ bool TcpStateListen::syn_ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& t Flow* flow = tsd.get_flow(); flow->session_state |= ( STREAM_STATE_SYN | STREAM_STATE_SYN_ACK ); - if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) ) + if ( trk.session->is_midstream_allowed(tsd) ) { trk.init_on_synack_sent(tsd); - trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs()); + trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); trk.session->init_new_tcp_session(tsd); } - else if ( trk.session->config->require_3whs() ) + else if ( trk.session->tcp_config->require_3whs() ) { trk.session->generate_no_3whs_event(); return false; @@ -77,14 +76,13 @@ bool TcpStateListen::syn_ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& t bool TcpStateListen::syn_ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( !trk.session->config->require_3whs() or - trk.session->config->midstream_allowed(tsd.get_pkt() ) ) + if ( !trk.session->tcp_config->require_3whs() or trk.session->is_midstream_allowed(tsd) ) { trk.init_on_synack_recv(tsd); - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) trk.session->handle_data_segment(tsd); } - else if ( trk.session->config->require_3whs() ) + else if ( trk.session->tcp_config->require_3whs() ) { trk.session->generate_no_3whs_event(); return false; @@ -94,8 +92,8 @@ bool TcpStateListen::syn_ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& t bool TcpStateListen::ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) - && ( tsd.has_wscale() || ( tsd.get_seg_len() > 0 ) ) ) + if ( trk.session->tcp_config->midstream_allowed(tsd.get_pkt()) + && (tsd.has_wscale() || (tsd.get_len() > 0 )) ) { Flow* flow = tsd.get_flow(); flow->session_state |= ( STREAM_STATE_ACK | STREAM_STATE_SYN_ACK | @@ -105,7 +103,7 @@ bool TcpStateListen::ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) trk.session->init_new_tcp_session(tsd); trk.session->update_perf_base_state(TcpStreamTracker::TCP_ESTABLISHED); } - else if ( trk.session->config->require_3whs() ) + else if ( trk.session->tcp_config->require_3whs() ) { trk.session->generate_no_3whs_event(); return false; @@ -115,19 +113,18 @@ bool TcpStateListen::ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) bool TcpStateListen::ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) - && ( tsd.has_wscale() || ( tsd.get_seg_len() > 0 ) ) ) + if ( trk.session->is_midstream_allowed(tsd) && (tsd.has_wscale() || (tsd.get_len() > 0 )) ) { Flow* flow = tsd.get_flow(); - if ( !tsd.get_tcph()->is_rst() && ( flow->session_state & STREAM_STATE_SYN_ACK ) ) + if ( !tsd.get_tcph()->is_rst() && ( flow->session_state & STREAM_STATE_SYN_ACK) ) { trk.init_on_3whs_ack_recv(tsd); trk.normalizer.ecn_tracker( - tsd.get_tcph(), trk.session->config->require_3whs()); + tsd.get_tcph(), trk.session->tcp_config->require_3whs()); } } - else if ( trk.session->config->require_3whs() ) + else if ( trk.session->tcp_config->require_3whs() ) { trk.session->generate_no_3whs_event(); return false; @@ -137,7 +134,7 @@ bool TcpStateListen::ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) bool TcpStateListen::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) ) + if ( trk.session->is_midstream_allowed(tsd) ) { Flow* flow = tsd.get_flow(); @@ -154,7 +151,7 @@ bool TcpStateListen::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& if ( flow->session_state & STREAM_STATE_ESTABLISHED ) trk.session->update_perf_base_state(TcpStreamTracker::TCP_ESTABLISHED); } - else if ( trk.session->config->require_3whs() ) + else if ( trk.session->tcp_config->require_3whs() ) { trk.session->generate_no_3whs_event(); return false; @@ -164,7 +161,7 @@ bool TcpStateListen::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& bool TcpStateListen::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) ) + if ( trk.session->is_midstream_allowed(tsd) ) { Flow* flow = tsd.get_flow(); @@ -175,10 +172,10 @@ bool TcpStateListen::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& 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.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); trk.session->handle_data_segment(tsd); } - else if ( trk.session->config->require_3whs() ) + else if ( trk.session->tcp_config->require_3whs() ) { trk.session->generate_no_3whs_event(); return false; @@ -188,8 +185,7 @@ bool TcpStateListen::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& bool TcpStateListen::fin_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( !trk.session->config->midstream_allowed(tsd.get_pkt()) and - trk.session->config->require_3whs() ) + if ( !trk.session->is_midstream_allowed(tsd) and trk.session->tcp_config->require_3whs() ) { // FIXIT-L listen gets fin triggers 129:20 ?? trk.session->generate_no_3whs_event(); @@ -200,11 +196,11 @@ bool TcpStateListen::fin_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) bool TcpStateListen::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) ) + if ( trk.session->is_midstream_allowed(tsd) ) { // FIXIT-L handle FIN on midstream } - else if ( trk.session->config->require_3whs() ) + else if ( trk.session->tcp_config->require_3whs() ) { trk.session->generate_no_3whs_event(); return false; diff --git a/src/stream/tcp/tcp_state_machine.cc b/src/stream/tcp/tcp_state_machine.cc index 1d1ae2483..4e16f94c2 100644 --- a/src/stream/tcp/tcp_state_machine.cc +++ b/src/stream/tcp/tcp_state_machine.cc @@ -86,20 +86,21 @@ void TcpStateMachine::register_state_handler(TcpStreamTracker::TcpState state, tcp_state_handlers[ state ] = &handler; } -bool TcpStateMachine::eval(TcpSegmentDescriptor& tsd, TcpStreamTracker& talker, - TcpStreamTracker& listener) +bool TcpStateMachine::eval(TcpSegmentDescriptor& tsd) { - const TcpStreamTracker::TcpState talker_state = talker.get_tcp_state( ); + TcpStreamTracker* talker = tsd.get_talker(); + const TcpStreamTracker::TcpState talker_state = talker->get_tcp_state(); - talker.set_tcp_event(tsd); - if ( tcp_state_handlers[ talker_state ]->do_pre_sm_packet_actions(tsd, talker) ) + talker->set_tcp_event(tsd); + if ( tcp_state_handlers[ talker_state ]->do_pre_sm_packet_actions(tsd, *talker) ) { - if ( tcp_state_handlers[ talker_state ]->eval(tsd, talker) ) + if ( tcp_state_handlers[ talker_state ]->eval(tsd, *talker) ) { - const TcpStreamTracker::TcpState listener_state = listener.get_tcp_state( ); - listener.set_tcp_event(tsd); - tcp_state_handlers[ listener_state ]->eval(tsd, listener); - tcp_state_handlers[ listener_state ]->do_post_sm_packet_actions(tsd, listener); + TcpStreamTracker* listener = tsd.get_listener(); + const TcpStreamTracker::TcpState listener_state = listener->get_tcp_state( ); + listener->set_tcp_event(tsd); + tcp_state_handlers[ listener_state ]->eval(tsd, *listener); + tcp_state_handlers[ listener_state ]->do_post_sm_packet_actions(tsd, *listener); return true; } diff --git a/src/stream/tcp/tcp_state_machine.h b/src/stream/tcp/tcp_state_machine.h index 37d9d6e00..979530a95 100644 --- a/src/stream/tcp/tcp_state_machine.h +++ b/src/stream/tcp/tcp_state_machine.h @@ -38,7 +38,7 @@ public: { return TcpStateMachine::tsm; } virtual void register_state_handler(TcpStreamTracker::TcpState, TcpStateHandler&); - virtual bool eval(TcpSegmentDescriptor&, TcpStreamTracker&, TcpStreamTracker&); + virtual bool eval(TcpSegmentDescriptor&); protected: TcpStateMachine(); diff --git a/src/stream/tcp/tcp_state_none.cc b/src/stream/tcp/tcp_state_none.cc index c9c84f8d2..55ae09809 100644 --- a/src/stream/tcp/tcp_state_none.cc +++ b/src/stream/tcp/tcp_state_none.cc @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_state_none.cc author davis mcpherson +// tcp_state_none.cc author davis mcpherson // Created on: Jul 30, 2015 #ifdef HAVE_CONFIG_H @@ -56,15 +56,14 @@ bool TcpStateNone::syn_ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk { Flow* flow = tsd.get_flow(); - if ( !trk.session->config->require_3whs() or - trk.session->config->midstream_allowed(tsd.get_pkt() ) ) + if ( !trk.session->tcp_config->require_3whs() or trk.session->is_midstream_allowed(tsd) ) { flow->session_state |= ( STREAM_STATE_SYN | STREAM_STATE_SYN_ACK ); trk.init_on_synack_sent(tsd); trk.session->init_new_tcp_session(tsd); - trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs()); + trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); } - else if ( trk.session->config->require_3whs() ) + else if ( trk.session->tcp_config->require_3whs() ) { trk.session->generate_no_3whs_event(); return false; @@ -74,14 +73,14 @@ bool TcpStateNone::syn_ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk bool TcpStateNone::syn_ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) ) + if ( trk.session->is_midstream_allowed(tsd) ) { trk.init_on_synack_recv(tsd); - trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs()); - if ( tsd.get_seg_len() > 0 ) + trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); + if ( tsd.get_len() > 0 ) trk.session->handle_data_segment(tsd); } - else if ( trk.session->config->require_3whs() ) + else if ( trk.session->tcp_config->require_3whs() ) { trk.session->generate_no_3whs_event(); return false; @@ -91,8 +90,7 @@ bool TcpStateNone::syn_ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk bool TcpStateNone::ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) && ( tsd.has_wscale() || - ( tsd.get_seg_len() > 0 ) ) ) + if ( trk.session->is_midstream_allowed(tsd) && (tsd.has_wscale() || (tsd.get_len() > 0)) ) { Flow* flow = tsd.get_flow(); @@ -104,7 +102,7 @@ bool TcpStateNone::ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) trk.session->init_new_tcp_session(tsd); trk.session->update_perf_base_state(TcpStreamTracker::TCP_ESTABLISHED); } - else if ( trk.session->config->require_3whs() ) + else if ( trk.session->tcp_config->require_3whs() ) { trk.session->generate_no_3whs_event(); return false; @@ -114,8 +112,7 @@ bool TcpStateNone::ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) bool TcpStateNone::ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) && ( tsd.has_wscale() || - ( tsd.get_seg_len() > 0 ) ) ) + if ( trk.session->is_midstream_allowed(tsd) && (tsd.has_wscale() || (tsd.get_len() > 0)) ) { Flow* flow = tsd.get_flow(); @@ -123,10 +120,10 @@ bool TcpStateNone::ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { trk.init_on_3whs_ack_recv(tsd); trk.normalizer.ecn_tracker( - tsd.get_tcph(), trk.session->config->require_3whs()); + tsd.get_tcph(), trk.session->tcp_config->require_3whs()); } } - else if ( trk.session->config->require_3whs() ) + else if ( trk.session->tcp_config->require_3whs() ) { trk.session->generate_no_3whs_event(); return false; @@ -136,7 +133,7 @@ bool TcpStateNone::ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) bool TcpStateNone::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) ) + if ( trk.session->is_midstream_allowed(tsd) ) { Flow* flow = tsd.get_flow(); @@ -153,7 +150,7 @@ bool TcpStateNone::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& tr if ( flow->session_state & STREAM_STATE_ESTABLISHED ) trk.session->update_perf_base_state(TcpStreamTracker::TCP_ESTABLISHED); } - else if ( trk.session->config->require_3whs() ) + else if ( trk.session->tcp_config->require_3whs() ) { trk.session->generate_no_3whs_event(); return false; @@ -163,7 +160,7 @@ bool TcpStateNone::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& tr bool TcpStateNone::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) ) + if ( trk.session->is_midstream_allowed(tsd) ) { Flow* flow = tsd.get_flow(); @@ -175,10 +172,10 @@ bool TcpStateNone::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& tr } trk.init_on_data_seg_recv(tsd); - trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs()); + trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); trk.session->handle_data_segment(tsd); } - else if ( trk.session->config->require_3whs() ) + else if ( trk.session->tcp_config->require_3whs() ) { trk.session->generate_no_3whs_event(); return false; @@ -188,11 +185,11 @@ bool TcpStateNone::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& tr bool TcpStateNone::fin_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) ) + if ( trk.session->is_midstream_allowed(tsd) ) { // FIXIT-M handle FIN on midstream } - else if ( trk.session->config->require_3whs() ) + else if ( trk.session->tcp_config->require_3whs() ) { trk.session->generate_no_3whs_event(); return false; @@ -202,11 +199,11 @@ bool TcpStateNone::fin_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) bool TcpStateNone::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) ) + if ( trk.session->is_midstream_allowed(tsd) ) { // FIXIT-M handle FIN on midstream } - else if ( trk.session->config->require_3whs() ) + else if ( trk.session->tcp_config->require_3whs() ) { trk.session->generate_no_3whs_event(); return false; @@ -216,7 +213,7 @@ bool TcpStateNone::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) bool TcpStateNone::rst_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.session->config->midstream_allowed(tsd.get_pkt() ) ) + if ( trk.session->is_midstream_allowed(tsd) ) { // FIXIT-M handle RST on midstream } diff --git a/src/stream/tcp/tcp_state_syn_recv.cc b/src/stream/tcp/tcp_state_syn_recv.cc index 72356671b..1084ea9e9 100644 --- a/src/stream/tcp/tcp_state_syn_recv.cc +++ b/src/stream/tcp/tcp_state_syn_recv.cc @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_state_syn_recv.cc author davis mcpherson +// tcp_state_syn_recv.cc author davis mcpherson // Created on: Aug 5, 2015 #ifdef HAVE_CONFIG_H @@ -41,13 +41,13 @@ bool TcpStateSynRecv::syn_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) Flow* flow = tsd.get_flow(); trk.finish_server_init(tsd); - trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs()); + trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); trk.session->update_timestamp_tracking(tsd); if ( tsd.get_tcph()->are_flags_set(TH_ECE) && ( flow->get_session_flags() & SSNFLAG_ECN_CLIENT_QUERY ) ) flow->set_session_flags(SSNFLAG_ECN_SERVER_REPLY); - if ( tsd.get_pkt()->is_from_server() ) + if ( tsd.is_packet_from_server() ) { flow->set_session_flags(SSNFLAG_SEEN_SERVER); trk.session->tel.set_tcp_event(EVENT_4WHS); @@ -57,7 +57,7 @@ bool TcpStateSynRecv::syn_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) bool TcpStateSynRecv::syn_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( tsd.get_seg_len() ) + if ( tsd.get_len() ) trk.session->handle_data_on_syn(tsd); return true; } @@ -69,24 +69,24 @@ bool TcpStateSynRecv::syn_ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& // FIXIT-H verify ack being sent is valid... // norm/drop + discard trk.finish_server_init(tsd); - trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs()); + trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); flow->session_state |= STREAM_STATE_SYN_ACK; return true; } bool TcpStateSynRecv::syn_ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.is_ack_valid(tsd.get_seg_ack()) ) + if ( trk.is_ack_valid(tsd.get_ack()) ) { Flow* flow = tsd.get_flow(); trk.update_tracker_ack_recv(tsd); - trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs()); + trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); flow->set_session_flags(SSNFLAG_ESTABLISHED); flow->session_state |= ( STREAM_STATE_ACK | STREAM_STATE_ESTABLISHED ); trk.session->update_perf_base_state(TcpStreamTracker::TCP_ESTABLISHED); trk.set_tcp_state(TcpStreamTracker::TCP_ESTABLISHED); - if ( tsd.get_seg_len() ) + if ( tsd.get_len() ) trk.session->handle_data_on_syn(tsd); } return true; @@ -94,7 +94,7 @@ bool TcpStateSynRecv::syn_ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& bool TcpStateSynRecv::ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.session->config->midstream_allowed(tsd.get_pkt()) ) + if ( trk.session->tcp_config->midstream_allowed(tsd.get_pkt()) ) { trk.session->update_session_on_ack( ); } @@ -103,18 +103,18 @@ bool TcpStateSynRecv::ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) bool TcpStateSynRecv::ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.is_ack_valid(tsd.get_seg_ack()) ) + if ( trk.is_ack_valid(tsd.get_ack()) ) { Flow* flow = tsd.get_flow(); trk.update_tracker_ack_recv(tsd); trk.session->set_pkt_action_flag(trk.normalizer.handle_paws(tsd)); - tsd.get_pkt()->packet_flags |= PKT_STREAM_TWH; + tsd.set_packet_flags(PKT_STREAM_TWH); flow->set_session_flags(SSNFLAG_ESTABLISHED); flow->session_state |= ( STREAM_STATE_ACK | STREAM_STATE_ESTABLISHED ); trk.session->update_perf_base_state(TcpStreamTracker::TCP_ESTABLISHED); trk.set_tcp_state(TcpStreamTracker::TCP_ESTABLISHED); - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) trk.session->handle_data_segment(tsd); else trk.session->check_for_window_slam(tsd); @@ -132,15 +132,15 @@ bool TcpStateSynRecv::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& bool TcpStateSynRecv::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( trk.is_ack_valid(tsd.get_seg_ack()) ) + if ( trk.is_ack_valid(tsd.get_ack()) ) { trk.update_tracker_ack_recv(tsd); - tsd.get_pkt()->packet_flags |= PKT_STREAM_TWH; + tsd.set_packet_flags(PKT_STREAM_TWH); trk.session->set_pkt_action_flag(trk.normalizer.handle_paws(tsd)); trk.session->update_perf_base_state(TcpStreamTracker::TCP_ESTABLISHED); trk.set_tcp_state(TcpStreamTracker::TCP_ESTABLISHED); } - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) trk.session->handle_data_segment(tsd); return true; } @@ -154,7 +154,7 @@ bool TcpStateSynRecv::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) trk.update_tracker_ack_recv(tsd); trk.session->set_pkt_action_flag(trk.normalizer.handle_paws(tsd)); flow->session_state |= STREAM_STATE_ACK; - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) { trk.session->handle_data_segment(tsd); trk.flush_data_on_fin_recv(tsd); @@ -185,7 +185,7 @@ bool TcpStateSynRecv::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) } // FIXIT-L might be good to create alert specific to RST with data - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) trk.session->tel.set_tcp_event(EVENT_DATA_AFTER_RST_RCVD); return true; } diff --git a/src/stream/tcp/tcp_state_syn_recv.h b/src/stream/tcp/tcp_state_syn_recv.h index 8a8a77d4a..1b64bae2c 100644 --- a/src/stream/tcp/tcp_state_syn_recv.h +++ b/src/stream/tcp/tcp_state_syn_recv.h @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_syn_recv_state.h author davis mcpherson +// tcp_syn_recv_state.h author davis mcpherson // Created on: Aug 5, 2015 #ifndef TCP_STATE_SYN_RECV_H diff --git a/src/stream/tcp/tcp_state_syn_sent.cc b/src/stream/tcp/tcp_state_syn_sent.cc index 9a5ace001..c8e8c69f0 100644 --- a/src/stream/tcp/tcp_state_syn_sent.cc +++ b/src/stream/tcp/tcp_state_syn_sent.cc @@ -43,7 +43,7 @@ bool TcpStateSynSent::syn_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) bool TcpStateSynSent::syn_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { trk.finish_client_init(tsd); - if ( tsd.get_seg_len() ) + if ( tsd.get_len() ) trk.session->handle_data_on_syn(tsd); trk.set_tcp_state(TcpStreamTracker::TCP_SYN_RECV); return true; @@ -54,7 +54,7 @@ bool TcpStateSynSent::syn_ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& if ( trk.update_on_3whs_ack(tsd) ) { trk.session->update_timestamp_tracking(tsd); - if ( tsd.get_seg_len() ) + if ( tsd.get_len() ) trk.session->handle_data_on_syn(tsd); } else @@ -79,7 +79,7 @@ bool TcpStateSynSent::ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) bool TcpStateSynSent::ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) trk.session->handle_data_segment(tsd); return true; } @@ -107,7 +107,7 @@ bool TcpStateSynSent::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& bool TcpStateSynSent::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) trk.session->handle_data_segment(tsd); return true; } @@ -120,7 +120,7 @@ bool TcpStateSynSent::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) trk.set_tcp_state(TcpStreamTracker::TCP_CLOSED); trk.session->update_perf_base_state(TcpStreamTracker::TCP_CLOSED); trk.session->set_pkt_action_flag(ACTION_RST); - tsd.get_pkt()->flow->session_state |= STREAM_STATE_CLOSED; + tsd.get_flow()->session_state |= STREAM_STATE_CLOSED; } else { @@ -128,7 +128,7 @@ bool TcpStateSynSent::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) } // FIXIT-L might be good to create alert specific to RST with data - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) trk.session->tel.set_tcp_event(EVENT_DATA_AFTER_RST_RCVD); return true; } diff --git a/src/stream/tcp/tcp_state_syn_sent.h b/src/stream/tcp/tcp_state_syn_sent.h index c9b560154..1a1e48137 100644 --- a/src/stream/tcp/tcp_state_syn_sent.h +++ b/src/stream/tcp/tcp_state_syn_sent.h @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_syn_sent_state.h author davis mcpherson +// tcp_syn_sent_state.h author davis mcpherson // Created on: Aug 5, 2015 #ifndef TCP_STATE_SYN_SENT_H diff --git a/src/stream/tcp/tcp_state_time_wait.cc b/src/stream/tcp/tcp_state_time_wait.cc index 865b8ce6e..679d1153d 100644 --- a/src/stream/tcp/tcp_state_time_wait.cc +++ b/src/stream/tcp/tcp_state_time_wait.cc @@ -43,8 +43,8 @@ bool TcpStateTimeWait::syn_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk bool TcpStateTimeWait::syn_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { - trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs()); - if ( tsd.get_seg_len() ) + trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); + if ( tsd.get_len() ) trk.session->handle_data_on_syn(tsd); return true; @@ -67,13 +67,13 @@ bool TcpStateTimeWait::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker bool TcpStateTimeWait::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { trk.update_tracker_ack_recv(tsd); - if ( SEQ_GT(tsd.get_seg_seq(), trk.get_fin_final_seq() ) ) + if ( SEQ_GT(tsd.get_seq(), trk.get_fin_final_seq() ) ) { trk.session->tel.set_tcp_event(EVENT_BAD_FIN); trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK); trk.session->set_pkt_action_flag(ACTION_BAD_PKT); } - else if ( tsd.get_seg_len() > 0 ) + else if ( tsd.get_len() > 0 ) trk.session->handle_data_segment(tsd); return true; @@ -94,7 +94,7 @@ bool TcpStateTimeWait::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk // FIXIT-L might be good to create alert specific to RST with data // FIXIT-L refactoring required? seen this in many places - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) trk.session->tel.set_tcp_event(EVENT_DATA_AFTER_RST_RCVD); return true; @@ -112,7 +112,7 @@ bool TcpStateTimeWait::do_post_sm_packet_actions(TcpSegmentDescriptor& tsd, TcpS if ( trk.get_tcp_event() != TcpStreamTracker::TCP_FIN_RECV_EVENT ) { - TcpStreamTracker::TcpState talker_state = trk.session->get_talker_state(); + TcpStreamTracker::TcpState talker_state = trk.session->get_talker_state(tsd); Flow* flow = tsd.get_flow(); if ( ( talker_state == TcpStreamTracker::TCP_TIME_WAIT ) diff --git a/src/stream/tcp/tcp_state_time_wait.h b/src/stream/tcp/tcp_state_time_wait.h index bd8be5184..eb40bc3e0 100644 --- a/src/stream/tcp/tcp_state_time_wait.h +++ b/src/stream/tcp/tcp_state_time_wait.h @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_state_time_wait.h author davis mcpherson +// tcp_state_time_wait.h author davis mcpherson // Created on: Aug 5, 2015 #ifndef TCP_STATE_TIME_WAIT_H diff --git a/src/stream/tcp/tcp_stream_config.cc b/src/stream/tcp/tcp_stream_config.cc index dad8375e9..839f9cb59 100644 --- a/src/stream/tcp/tcp_stream_config.cc +++ b/src/stream/tcp/tcp_stream_config.cc @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_stream_config.cc author davis mcpherson +// tcp_stream_config.cc author davis mcpherson // Created on: Oct 22, 2015 #ifdef HAVE_CONFIG_H diff --git a/src/stream/tcp/tcp_stream_config.h b/src/stream/tcp/tcp_stream_config.h index 40595a5a3..37246229c 100644 --- a/src/stream/tcp/tcp_stream_config.h +++ b/src/stream/tcp/tcp_stream_config.h @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_stream_config.h author davis mcpherson +// tcp_stream_config.h author davis mcpherson // Created on: Oct 22, 2015 #ifndef TCP_STREAM_CONFIG_H diff --git a/src/stream/tcp/tcp_stream_session.cc b/src/stream/tcp/tcp_stream_session.cc index 9c9026bb3..dc4c9a614 100644 --- a/src/stream/tcp/tcp_stream_session.cc +++ b/src/stream/tcp/tcp_stream_session.cc @@ -39,13 +39,15 @@ TcpStreamSession::~TcpStreamSession() void TcpStreamSession::init_new_tcp_session(TcpSegmentDescriptor& tsd) { - flow->pkt_type = tsd.get_pkt()->type(); - flow->ip_proto = (uint8_t)tsd.get_pkt()->get_ip_proto_next(); + Packet* p = tsd.get_pkt(); + + flow->pkt_type = p->type(); + flow->ip_proto = (uint8_t)p->get_ip_proto_next(); /* New session, previous was marked as reset. Clear the reset flag. */ flow->clear_session_flags(SSNFLAG_RESET); - flow->set_expire(tsd.get_pkt(), flow->default_session_timeout); + flow->set_expire(p, flow->default_session_timeout); update_perf_base_state(TcpStreamTracker::TCP_SYN_SENT); @@ -83,8 +85,8 @@ void TcpStreamSession::update_session_on_ack() void TcpStreamSession::update_session_on_server_packet(TcpSegmentDescriptor& tsd) { flow->set_session_flags(SSNFLAG_SEEN_SERVER); - talker = &server; - listener = &client; + tsd.set_talker(server); + tsd.set_listener(client); /* If we picked this guy up midstream, finish the initialization */ if ( !( flow->session_state & STREAM_STATE_ESTABLISHED ) @@ -103,7 +105,7 @@ void TcpStreamSession::update_session_on_server_packet(TcpSegmentDescriptor& tsd } } - if (!flow->inner_server_ttl) + if ( !flow->inner_server_ttl && !tsd.is_meta_ack_packet() ) flow->set_ttl(tsd.get_pkt(), false); } @@ -111,8 +113,8 @@ void TcpStreamSession::update_session_on_client_packet(TcpSegmentDescriptor& tsd { /* if we got here we have seen the SYN already... */ flow->set_session_flags(SSNFLAG_SEEN_CLIENT); - talker = &client; - listener = &server; + tsd.set_talker(client); + tsd.set_listener(server); if ( !( flow->session_state & STREAM_STATE_ESTABLISHED ) && ( flow->session_state & STREAM_STATE_MIDSTREAM ) ) @@ -125,15 +127,14 @@ void TcpStreamSession::update_session_on_client_packet(TcpSegmentDescriptor& tsd } } - if (!flow->inner_client_ttl) + if (!flow->inner_client_ttl && !tsd.is_meta_ack_packet() ) flow->set_ttl(tsd.get_pkt(), true); } void TcpStreamSession::set_no_ack(bool b) { - if ( - server.get_flush_policy() == STREAM_FLPOLICY_ON_DATA and - client.get_flush_policy() == STREAM_FLPOLICY_ON_DATA ) + if ( server.get_flush_policy() == STREAM_FLPOLICY_ON_DATA and + client.get_flush_policy() == STREAM_FLPOLICY_ON_DATA ) { no_ack = b; } @@ -291,11 +292,16 @@ int TcpStreamSession::update_alert(Packet* p, uint32_t gid, uint32_t sid, bool TcpStreamSession::set_packet_action_to_hold(Packet* p) { - return listener->set_held_packet(p); + if ( p->is_from_client() ) + return server.set_held_packet(p); + else + return client.set_held_packet(p); } -void TcpStreamSession::SetPacketHeaderFoo(const Packet* p) +void TcpStreamSession::set_packet_header_foo(const TcpSegmentDescriptor& tsd) { + const Packet* p = tsd.get_pkt(); + if ( daq_flags & DAQ_PKT_FLAG_NOT_FORWARDING ) { ingress_index = p->pkth->ingress_index; @@ -304,7 +310,7 @@ void TcpStreamSession::SetPacketHeaderFoo(const Packet* p) egress_index = p->pkth->egress_index; egress_group = p->pkth->egress_group; } - else if ( p->is_from_client() ) + else if ( tsd.is_packet_from_client() ) { ingress_index = p->pkth->ingress_index; ingress_group = p->pkth->ingress_group; @@ -316,11 +322,12 @@ void TcpStreamSession::SetPacketHeaderFoo(const Packet* p) egress_index = p->pkth->ingress_index; egress_group = p->pkth->ingress_group; } + daq_flags = p->pkth->flags; address_space_id = p->pkth->address_space_id; } -void TcpStreamSession::GetPacketHeaderFoo(DAQ_PktHdr_t* pkth, uint32_t dir) +void TcpStreamSession::get_packet_header_foo(DAQ_PktHdr_t* pkth, uint32_t dir) { if ( (dir & PKT_FROM_CLIENT) || (daq_flags & DAQ_PKT_FLAG_NOT_FORWARDING) ) { @@ -358,7 +365,7 @@ bool TcpStreamSession::setup(Packet*) ingress_index = egress_index = 0; ingress_group = egress_group = 0; daq_flags = address_space_id = 0; - config = nullptr; + tcp_config = nullptr; return true; } @@ -410,6 +417,6 @@ StreamSplitter* TcpStreamSession::get_splitter(bool to_server) void TcpStreamSession::start_proxy() { - config->policy = StreamPolicy::OS_PROXY; + tcp_config->policy = StreamPolicy::OS_PROXY; } diff --git a/src/stream/tcp/tcp_stream_session.h b/src/stream/tcp/tcp_stream_session.h index aaf2d4d71..ac562c104 100644 --- a/src/stream/tcp/tcp_stream_session.h +++ b/src/stream/tcp/tcp_stream_session.h @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_stream_session.h author davis mcpherson +// tcp_stream_session.h author davis mcpherson // Created on: Feb 18, 2016 #ifndef TCP_STREAM_SESSION_H @@ -64,56 +64,34 @@ public: void reset(); void start_proxy(); - void SetPacketHeaderFoo(const snort::Packet* p); - void GetPacketHeaderFoo(DAQ_PktHdr_t* pkth, uint32_t dir); - void SwapPacketHeaderFoo(); + void set_packet_header_foo(const TcpSegmentDescriptor&); + void get_packet_header_foo(DAQ_PktHdr_t*, uint32_t dir); void set_no_ack(bool); bool no_ack_mode_enabled() { return no_ack; } - virtual void update_perf_base_state(char) { } + virtual void update_perf_base_state(char) = 0; virtual void clear_session( bool free_flow_data, bool flush_segments, bool restart, snort::Packet* p = nullptr) = 0; - // FIXIT-RC these 2 function names convey no meaning afaict... figure out - // why are they called and name appropriately... - virtual void retransmit_process(snort::Packet* p) - { - // Data has already been analyzed so don't bother looking at it again. - snort::DetectionEngine::disable_content(p); - } + virtual void flush() = 0; - virtual void retransmit_handle(snort::Packet* p) - { - flow->call_handlers(p, false); - } + virtual TcpStreamTracker::TcpState get_talker_state(TcpSegmentDescriptor&) = 0; - virtual void eof_handle(snort::Packet* p) - { - flow->call_handlers(p, true); - } - - virtual void flush() { } - - virtual TcpStreamTracker::TcpState get_talker_state() - { return TcpStreamTracker::TCP_MAX_STATES; } - - virtual TcpStreamTracker::TcpState get_listener_state() - { return TcpStreamTracker::TCP_MAX_STATES; } + virtual TcpStreamTracker::TcpState get_listener_state(TcpSegmentDescriptor&) = 0; TcpStreamTracker::TcpState get_peer_state(TcpStreamTracker* me) { return me == &client ? server.get_tcp_state() : client.get_tcp_state(); } virtual void init_new_tcp_session(TcpSegmentDescriptor&); - virtual void update_timestamp_tracking(TcpSegmentDescriptor&) { } + virtual void update_timestamp_tracking(TcpSegmentDescriptor&) = 0; virtual void update_session_on_syn_ack(); virtual void update_session_on_ack(); virtual void update_session_on_server_packet(TcpSegmentDescriptor&); virtual void update_session_on_client_packet(TcpSegmentDescriptor&); - virtual void update_session_on_rst(TcpSegmentDescriptor&, bool) { } - virtual bool handle_syn_on_reset_session(TcpSegmentDescriptor&) { return true; } - virtual void handle_data_on_syn(TcpSegmentDescriptor&) { } - virtual void update_ignored_session(TcpSegmentDescriptor&) { } - + virtual void update_session_on_rst(TcpSegmentDescriptor&, bool) = 0; + virtual bool handle_syn_on_reset_session(TcpSegmentDescriptor&) = 0; + virtual void handle_data_on_syn(TcpSegmentDescriptor&) = 0; + virtual void update_ignored_session(TcpSegmentDescriptor&) = 0; void generate_no_3whs_event() { if ( generate_3whs_alert && flow->two_way_traffic()) @@ -126,13 +104,13 @@ public: void set_pkt_action_flag(uint32_t flag) { pkt_action_mask |= flag; } - virtual void update_paws_timestamps(TcpSegmentDescriptor&) { } - virtual void check_for_repeated_syn(TcpSegmentDescriptor&) { } - virtual void check_for_session_hijack(TcpSegmentDescriptor&) { } - virtual bool check_for_window_slam(TcpSegmentDescriptor&) { return true; } - virtual void mark_packet_for_drop(TcpSegmentDescriptor&) { } - virtual void handle_data_segment(TcpSegmentDescriptor&) { } - virtual bool validate_packet_established_session(TcpSegmentDescriptor&) { return true; } + virtual void update_paws_timestamps(TcpSegmentDescriptor&) = 0; + virtual void check_for_repeated_syn(TcpSegmentDescriptor&) = 0; + virtual void check_for_session_hijack(TcpSegmentDescriptor&) = 0; + virtual bool check_for_window_slam(TcpSegmentDescriptor&) = 0; + virtual void mark_packet_for_drop(TcpSegmentDescriptor&) = 0; + virtual void handle_data_segment(TcpSegmentDescriptor&) = 0; + virtual bool validate_packet_established_session(TcpSegmentDescriptor&) = 0; TcpStreamTracker client; TcpStreamTracker server; @@ -147,7 +125,7 @@ public: uint32_t daq_flags = 0; uint16_t address_space_id = 0; bool generate_3whs_alert = true; - TcpStreamConfig* config = nullptr; + TcpStreamConfig* tcp_config = nullptr; TcpEventLogger tel; private: @@ -156,9 +134,6 @@ private: protected: TcpStreamSession(snort::Flow*); virtual void set_os_policy() = 0; - - TcpStreamTracker* talker = nullptr; - TcpStreamTracker* listener = nullptr; }; #endif diff --git a/src/stream/tcp/tcp_stream_tracker.cc b/src/stream/tcp/tcp_stream_tracker.cc index 0a07f464a..93740df2c 100644 --- a/src/stream/tcp/tcp_stream_tracker.cc +++ b/src/stream/tcp/tcp_stream_tracker.cc @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_stream_tracker.cpp author davis mcpherson +// tcp_stream_tracker.cpp author davis mcpherson // Created on: Jun 24, 2015 #ifdef HAVE_CONFIG_H @@ -76,7 +76,7 @@ TcpStreamTracker::TcpEvent TcpStreamTracker::set_tcp_event(const TcpSegmentDescr bool talker; const tcp::TCPHdr* tcph = tsd.get_tcph(); - if ( tsd.get_pkt()->is_from_client() ) + if ( tsd.is_packet_from_client() ) talker = ( client_tracker ) ? true : false; else talker = ( client_tracker ) ? false : true; @@ -95,12 +95,12 @@ TcpStreamTracker::TcpEvent TcpStreamTracker::set_tcp_event(const TcpSegmentDescr tcp_event = TCP_FIN_SENT_EVENT; else if ( tcph->is_ack() || tcph->is_psh() ) { - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) tcp_event = TCP_DATA_SEG_SENT_EVENT; else tcp_event = TCP_ACK_SENT_EVENT; } - else if ( tsd.get_seg_len() > 0 ) // FIXIT-H no flags set, how do we handle this? + else if ( tsd.get_len() > 0 ) // FIXIT-H no flags set, how do we handle this? // discard; drop if normalizing tcp_event = TCP_DATA_SEG_SENT_EVENT; else @@ -138,12 +138,12 @@ TcpStreamTracker::TcpEvent TcpStreamTracker::set_tcp_event(const TcpSegmentDescr } else if ( tcph->is_ack() || tcph->is_psh() ) { - if ( tsd.get_seg_len() > 0 ) + if ( tsd.get_len() > 0 ) tcp_event = TCP_DATA_SEG_RECV_EVENT; else tcp_event = TCP_ACK_RECV_EVENT; } - else if ( tsd.get_seg_len() > 0 ) // FIXIT-H no flags set, how do we handle this? + else if ( tsd.get_len() > 0 ) // FIXIT-H no flags set, how do we handle this? // discard; drop if normalizing tcp_event = TCP_DATA_SEG_RECV_EVENT; else @@ -268,14 +268,14 @@ void TcpStreamTracker::init_on_syn_sent(TcpSegmentDescriptor& tsd) if ( tsd.get_tcph()->are_flags_set(TH_CWR | TH_ECE) ) tsd.get_flow()->set_session_flags(SSNFLAG_ECN_CLIENT_QUERY); - iss = tsd.get_seg_seq(); + iss = tsd.get_seq(); snd_una = iss; snd_nxt = tsd.get_end_seq(); - snd_wnd = tsd.get_seg_wnd(); + snd_wnd = tsd.get_wnd(); - ts_last_packet = tsd.get_pkt()->pkth->ts.tv_sec; + ts_last_packet = tsd.get_packet_timestamp(); tf_flags |= normalizer.get_tcp_timestamp(tsd, false); - ts_last = tsd.get_ts(); + ts_last = tsd.get_timestamp(); if (ts_last == 0) tf_flags |= TF_TSTAMP_ZERO; tf_flags |= tsd.init_mss(&mss); @@ -288,11 +288,11 @@ void TcpStreamTracker::init_on_syn_sent(TcpSegmentDescriptor& tsd) void TcpStreamTracker::init_on_syn_recv(TcpSegmentDescriptor& tsd) { - irs = tsd.get_seg_seq(); + irs = tsd.get_seq(); - rcv_nxt = tsd.get_seg_seq() + 1; - r_win_base = tsd.get_seg_seq() + 1; - reassembler.set_seglist_base_seq(tsd.get_seg_seq() + 1); + rcv_nxt = tsd.get_seq() + 1; + r_win_base = tsd.get_seq() + 1; + reassembler.set_seglist_base_seq(tsd.get_seq() + 1); cache_mac_address(tsd, FROM_CLIENT); tcp_state = TcpStreamTracker::TCP_SYN_RECV; @@ -304,19 +304,19 @@ void TcpStreamTracker::init_on_synack_sent(TcpSegmentDescriptor& tsd) if (tsd.get_tcph()->are_flags_set(TH_CWR | TH_ECE)) tsd.get_flow()->set_session_flags(SSNFLAG_ECN_SERVER_REPLY); - iss = tsd.get_seg_seq(); - irs = tsd.get_seg_ack() - 1; - snd_una = tsd.get_seg_seq(); + iss = tsd.get_seq(); + irs = tsd.get_ack() - 1; + snd_una = tsd.get_seq(); snd_nxt = tsd.get_end_seq(); - snd_wnd = tsd.get_seg_wnd(); + snd_wnd = tsd.get_wnd(); - r_win_base = tsd.get_seg_ack(); - rcv_nxt = tsd.get_seg_ack(); - reassembler.set_seglist_base_seq(tsd.get_seg_ack() ); + r_win_base = tsd.get_ack(); + rcv_nxt = tsd.get_ack(); + reassembler.set_seglist_base_seq(tsd.get_ack() ); - ts_last_packet = tsd.get_pkt()->pkth->ts.tv_sec; + ts_last_packet = tsd.get_packet_timestamp(); tf_flags |= normalizer.get_tcp_timestamp(tsd, false); - ts_last = tsd.get_ts(); + ts_last = tsd.get_timestamp(); if ( ts_last == 0 ) tf_flags |= TF_TSTAMP_ZERO; tf_flags |= tsd.init_mss(&mss); @@ -329,14 +329,14 @@ void TcpStreamTracker::init_on_synack_sent(TcpSegmentDescriptor& tsd) void TcpStreamTracker::init_on_synack_recv(TcpSegmentDescriptor& tsd) { - iss = tsd.get_seg_ack() - 1; - irs = tsd.get_seg_seq(); - snd_una = tsd.get_seg_ack(); + iss = tsd.get_ack() - 1; + irs = tsd.get_seq(); + snd_una = tsd.get_ack(); snd_nxt = snd_una; - rcv_nxt = tsd.get_seg_seq() + 1; - r_win_base = tsd.get_seg_seq() + 1; - reassembler.set_seglist_base_seq(tsd.get_seg_seq() + 1); + rcv_nxt = tsd.get_seq() + 1; + r_win_base = tsd.get_seq() + 1; + reassembler.set_seglist_base_seq(tsd.get_seq() + 1); cache_mac_address(tsd, FROM_SERVER); tcp_state = TcpStreamTracker::TCP_ESTABLISHED; @@ -349,17 +349,17 @@ void TcpStreamTracker::init_on_3whs_ack_sent(TcpSegmentDescriptor& tsd) if ( tsd.get_tcph()->are_flags_set(TH_CWR | TH_ECE) ) tsd.get_flow()->set_session_flags(SSNFLAG_ECN_CLIENT_QUERY); - iss = tsd.get_seg_seq(); - snd_una = tsd.get_seg_seq(); + iss = tsd.get_seq(); + snd_una = tsd.get_seq(); snd_nxt = snd_una; - snd_wnd = tsd.get_seg_wnd(); + snd_wnd = tsd.get_wnd(); - r_win_base = tsd.get_seg_ack(); - rcv_nxt = tsd.get_seg_ack(); + r_win_base = tsd.get_ack(); + rcv_nxt = tsd.get_ack(); - ts_last_packet = tsd.get_pkt()->pkth->ts.tv_sec; + ts_last_packet = tsd.get_packet_timestamp(); tf_flags |= normalizer.get_tcp_timestamp(tsd, false); - ts_last = tsd.get_ts(); + ts_last = tsd.get_timestamp(); if (ts_last == 0) tf_flags |= TF_TSTAMP_ZERO; tf_flags |= tsd.init_mss(&mss); @@ -371,14 +371,14 @@ void TcpStreamTracker::init_on_3whs_ack_sent(TcpSegmentDescriptor& tsd) void TcpStreamTracker::init_on_3whs_ack_recv(TcpSegmentDescriptor& tsd) { - iss = tsd.get_seg_ack() - 1; - irs = tsd.get_seg_seq(); - snd_una = tsd.get_seg_ack(); + iss = tsd.get_ack() - 1; + irs = tsd.get_seq(); + snd_una = tsd.get_ack(); snd_nxt = snd_una; - rcv_nxt = tsd.get_seg_seq(); - r_win_base = tsd.get_seg_seq(); - reassembler.set_seglist_base_seq(tsd.get_seg_seq() + 1); + rcv_nxt = tsd.get_seq(); + r_win_base = tsd.get_seq(); + reassembler.set_seglist_base_seq(tsd.get_seq() + 1); cache_mac_address(tsd, FROM_CLIENT); tcp_state = TcpStreamTracker::TCP_ESTABLISHED; @@ -394,19 +394,19 @@ void TcpStreamTracker::init_on_data_seg_sent(TcpSegmentDescriptor& tsd) else flow->set_session_flags(SSNFLAG_SEEN_SERVER); - iss = tsd.get_seg_seq(); - irs = tsd.get_seg_ack(); - snd_una = tsd.get_seg_seq(); - snd_nxt = snd_una + tsd.get_seg_len(); - snd_wnd = tsd.get_seg_wnd(); + iss = tsd.get_seq(); + irs = tsd.get_ack(); + snd_una = tsd.get_seq(); + snd_nxt = snd_una + tsd.get_len(); + snd_wnd = tsd.get_wnd(); - r_win_base = tsd.get_seg_ack(); - rcv_nxt = tsd.get_seg_ack(); - reassembler.set_seglist_base_seq(tsd.get_seg_ack()); + r_win_base = tsd.get_ack(); + rcv_nxt = tsd.get_ack(); + reassembler.set_seglist_base_seq(tsd.get_ack()); - ts_last_packet = tsd.get_pkt()->pkth->ts.tv_sec; + ts_last_packet = tsd.get_packet_timestamp(); tf_flags |= normalizer.get_tcp_timestamp(tsd, false); - ts_last = tsd.get_ts(); + ts_last = tsd.get_timestamp(); if (ts_last == 0) tf_flags |= TF_TSTAMP_ZERO; tf_flags |= ( tsd.init_mss(&mss) | tsd.init_wscale(&wscale) ); @@ -417,15 +417,15 @@ void TcpStreamTracker::init_on_data_seg_sent(TcpSegmentDescriptor& tsd) void TcpStreamTracker::init_on_data_seg_recv(TcpSegmentDescriptor& tsd) { - iss = tsd.get_seg_ack(); - irs = tsd.get_seg_seq(); - snd_una = tsd.get_seg_ack(); + iss = tsd.get_ack(); + irs = tsd.get_seq(); + snd_una = tsd.get_ack(); snd_nxt = snd_una; snd_wnd = 0; /* reset later */ - rcv_nxt = tsd.get_seg_seq(); - r_win_base = tsd.get_seg_seq(); - reassembler.set_seglist_base_seq(tsd.get_seg_seq()); + rcv_nxt = tsd.get_seq(); + r_win_base = tsd.get_seq(); + reassembler.set_seglist_base_seq(tsd.get_seq()); cache_mac_address(tsd, tsd.get_direction() ); tcp_state = TcpStreamTracker::TCP_ESTABLISHED; @@ -434,19 +434,19 @@ void TcpStreamTracker::init_on_data_seg_recv(TcpSegmentDescriptor& tsd) void TcpStreamTracker::finish_server_init(TcpSegmentDescriptor& tsd) { - iss = tsd.get_seg_seq(); - snd_una = tsd.get_seg_seq(); + iss = tsd.get_seq(); + snd_una = tsd.get_seq(); snd_nxt = tsd.get_end_seq(); - snd_wnd = tsd.get_seg_wnd(); + snd_wnd = tsd.get_wnd(); // FIXIT-M move this to fin handler for syn_recv state .. //if ( tcph->is_fin() ) // server->set_snd_nxt(server->get_snd_nxt() - 1); tf_flags |= normalizer.get_tcp_timestamp(tsd, false); - ts_last = tsd.get_ts(); + ts_last = tsd.get_timestamp(); if ( ts_last != 0 ) - ts_last_packet = tsd.get_pkt()->pkth->ts.tv_sec; + ts_last_packet = tsd.get_packet_timestamp(); else tf_flags |= TF_TSTAMP_ZERO; @@ -461,21 +461,21 @@ void TcpStreamTracker::finish_client_init(TcpSegmentDescriptor& tsd) if ( !( flow->session_state & STREAM_STATE_MIDSTREAM ) ) { - reassembler.set_seglist_base_seq(tsd.get_seg_seq() + 1); + reassembler.set_seglist_base_seq(tsd.get_seq() + 1); r_win_base = tsd.get_end_seq(); } else { - reassembler.set_seglist_base_seq(tsd.get_seg_seq() ); - r_win_base = tsd.get_seg_seq(); + reassembler.set_seglist_base_seq(tsd.get_seq() ); + r_win_base = tsd.get_seq(); } } void TcpStreamTracker::update_tracker_ack_recv(TcpSegmentDescriptor& tsd) { - if ( SEQ_GT(tsd.get_seg_ack(), snd_una) ) + if ( SEQ_GT(tsd.get_ack(), snd_una) ) { - snd_una = tsd.get_seg_ack(); + snd_una = tsd.get_ack(); if ( snd_nxt < snd_una ) snd_nxt = snd_una; } @@ -505,8 +505,8 @@ void TcpStreamTracker::update_tracker_ack_sent(TcpSegmentDescriptor& tsd) if ( SEQ_GT(tsd.get_end_seq(), snd_nxt) ) snd_nxt = tsd.get_end_seq(); - if ( SEQ_GT(tsd.get_seg_ack(), r_win_base) ) - r_win_base = tsd.get_seg_ack(); + if ( SEQ_GT(tsd.get_ack(), r_win_base) ) + r_win_base = tsd.get_ack(); if ( ( fin_seq_status == TcpStreamTracker::FIN_WITH_SEQ_SEEN ) && SEQ_EQ(r_win_base, fin_final_seq) ) @@ -514,7 +514,7 @@ void TcpStreamTracker::update_tracker_ack_sent(TcpSegmentDescriptor& tsd) fin_seq_status = TcpStreamTracker::FIN_WITH_SEQ_ACKED; } - snd_wnd = tsd.get_seg_wnd(); + snd_wnd = tsd.get_wnd(); reassembler.flush_on_ack_policy(tsd.get_pkt()); } @@ -522,11 +522,11 @@ bool TcpStreamTracker::update_on_3whs_ack(TcpSegmentDescriptor& tsd) { bool good_ack = true; - if ( is_ack_valid(tsd.get_seg_ack()) ) + if ( is_ack_valid(tsd.get_ack()) ) { Flow* flow = tsd.get_flow(); - irs = tsd.get_seg_seq(); + irs = tsd.get_seq(); finish_client_init(tsd); update_tracker_ack_recv(tsd); flow->set_session_flags(SSNFLAG_ESTABLISHED); @@ -578,7 +578,7 @@ void TcpStreamTracker::flush_data_on_fin_recv(TcpSegmentDescriptor& tsd) && (flush_policy != STREAM_FLPOLICY_ON_DATA) && normalizer.is_tcp_ips_enabled()) { - tsd.get_pkt()->packet_flags |= PKT_PDU_TAIL; + tsd.set_packet_flags(PKT_PDU_TAIL); } reassembler.flush_on_data_policy(tsd.get_pkt()); @@ -603,7 +603,7 @@ bool TcpStreamTracker::update_on_fin_recv(TcpSegmentDescriptor& tsd) { fin_final_seq = tsd.get_end_seq(); fin_seq_set = true; - if( tsd.get_seg_len() == 0 ) + if( tsd.get_len() == 0 ) fin_seq_status = TcpStreamTracker::FIN_WITH_SEQ_SEEN; } @@ -629,7 +629,7 @@ bool TcpStreamTracker::is_segment_seq_valid(TcpSegmentDescriptor& tsd) else left_seq = r_win_base; - if ( tsd.get_seg_len() ) + if ( tsd.get_len() ) right_ok = SEQ_GT(tsd.get_end_seq(), left_seq); else right_ok = SEQ_GEQ(tsd.get_end_seq(), left_seq); @@ -638,7 +638,7 @@ bool TcpStreamTracker::is_segment_seq_valid(TcpSegmentDescriptor& tsd) { uint32_t win = normalizer.get_stream_window(tsd); - if ( SEQ_LEQ(tsd.get_seg_seq(), r_win_base + win) ) + if ( SEQ_LEQ(tsd.get_seq(), r_win_base + win) ) { return true; } diff --git a/src/stream/tcp/tcp_stream_tracker.h b/src/stream/tcp/tcp_stream_tracker.h index c9128c23e..4435bdc00 100644 --- a/src/stream/tcp/tcp_stream_tracker.h +++ b/src/stream/tcp/tcp_stream_tracker.h @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_stream_tracker.h author davis mcpherson +// tcp_stream_tracker.h author davis mcpherson // Created on: Jun 24, 2015 #ifndef TCP_STREAM_TRACKER_H @@ -211,7 +211,7 @@ public: // ack number must ack syn bool is_rst_valid_in_syn_sent(const TcpSegmentDescriptor& tsd) const - { return tsd.get_seg_ack() == snd_una; } + { return tsd.get_ack() == snd_una; } uint32_t get_ts_last() const { return ts_last; }