From: Steve Chew (stechew) Date: Mon, 5 Apr 2021 22:34:23 +0000 (+0000) Subject: Merge pull request #2825 in SNORT/snort3 from ~DERAMADA/snort3:held_pkt_reset to... X-Git-Tag: 3.1.4.0~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bf6af7f4edda1c2f7ec5dea411d553a1cb5a8220;p=thirdparty%2Fsnort3.git Merge pull request #2825 in SNORT/snort3 from ~DERAMADA/snort3:held_pkt_reset to master Squashed commit of the following: commit 5480871c0d14c8487fc7a2044f8ce002fc65d2c5 Author: Deepak Ramadass Date: Mon Mar 29 21:14:30 2021 -0400 stream: store held packet SYN commit 14116e12388e618b28aef80f90e3364b22655f88 Author: Deepak Ramadass Date: Mon Mar 29 21:13:48 2021 -0400 stream: fetch held packet SYN commit b38b8d4d69bd0bd09bd2ffcfe69faa470f62b5d7 Author: Deepak Ramadass Date: Mon Mar 29 21:12:00 2021 -0400 codecs: use held packet SYN in Tcp header creation --- diff --git a/src/codecs/ip/cd_tcp.cc b/src/codecs/ip/cd_tcp.cc index 05fd8f7ba..cd4bf555b 100644 --- a/src/codecs/ip/cd_tcp.cc +++ b/src/codecs/ip/cd_tcp.cc @@ -33,6 +33,7 @@ #include "protocols/tcp.h" #include "protocols/tcp_options.h" #include "sfip/sf_ipvar.h" +#include "stream/stream.h" #include "utils/util.h" #include "checksum.h" @@ -607,7 +608,7 @@ void TcpCodec::log(TextLog* const text_log, const uint8_t* raw_pkt, //------------------------------------------------------------------------- bool TcpCodec::encode(const uint8_t* const raw_in, const uint16_t /*raw_len*/, - EncState& enc, Buffer& buf, Flow*) + EncState& enc, Buffer& buf, Flow* flow) { const tcp::TCPHdr* const hi = reinterpret_cast(raw_in); @@ -624,7 +625,14 @@ bool TcpCodec::encode(const uint8_t* const raw_in, const uint16_t /*raw_len*/, // th_seq depends on whether the data passes or drops if (enc.flags & ENC_FLAG_INLINE) - tcph_out->th_seq = hi->th_seq; + { + uint32_t seq = 0; + + if(Stream::get_held_pkt_seq(flow, seq)) + tcph_out->th_seq = htonl(seq); + else + tcph_out->th_seq = hi->th_seq; + } else tcph_out->th_seq = htonl(ntohl(hi->th_seq) + enc.dsize + ctl); diff --git a/src/service_inspectors/ftp_telnet/ftpp_si.cc b/src/service_inspectors/ftp_telnet/ftpp_si.cc index c21cad44e..d7fd395ea 100644 --- a/src/service_inspectors/ftp_telnet/ftpp_si.cc +++ b/src/service_inspectors/ftp_telnet/ftpp_si.cc @@ -359,15 +359,30 @@ void FTPFreesession(FTP_SESSION* ssn) */ bool FTPDataDirection(Packet* p, FTP_DATA_SESSION* ftpdata) { - uint32_t direction; - uint32_t pktdir = Stream::get_packet_direction(p); + Stream::get_packet_direction(p); if (ftpdata->mode == FTPP_XFER_ACTIVE) - direction = ftpdata->direction ? PKT_FROM_SERVER : PKT_FROM_CLIENT; + { + // download + if (!p->is_from_application_client() && p->is_from_client()) + return true; + + // upload + if (p->is_from_application_client() && !p->is_from_client()) + return true; + } else - direction = ftpdata->direction ? PKT_FROM_CLIENT : PKT_FROM_SERVER; + { + // download + if (!p->is_from_client() && !p->is_from_application_client()) + return true; + + // upload + if (p->is_from_client() && p->is_from_application_client()) + return true; + } - return (pktdir == direction); + return false; } /* diff --git a/src/stream/stream.cc b/src/stream/stream.cc index 9bf827f89..3b28f9d60 100644 --- a/src/stream/stream.cc +++ b/src/stream/stream.cc @@ -818,6 +818,33 @@ void Stream::partial_flush(Flow* flow, bool to_server) } } +bool Stream::get_held_pkt_seq(Flow* flow, uint32_t& seq) +{ + if (!flow or !flow->session or !(flow->pkt_type == PktType::TCP)) + return false; + + TcpStreamSession* tcp_session = (TcpStreamSession*)flow->session; + + if (tcp_session->held_packet_dir == SSN_DIR_NONE) + return false; + + if (tcp_session->held_packet_dir == SSN_DIR_FROM_CLIENT) + { + seq = tcp_session->server.held_pkt_seq; + tcp_session->held_packet_dir = SSN_DIR_NONE; + return true; + } + + if (tcp_session->held_packet_dir == SSN_DIR_FROM_SERVER) + { + seq = tcp_session->client.held_pkt_seq; + tcp_session->held_packet_dir = SSN_DIR_NONE; + return true; + } + + return false; +} + #ifdef UNIT_TEST #include "catch/snort_catch.h" diff --git a/src/stream/stream.h b/src/stream/stream.h index 372852e5d..402ce2b95 100644 --- a/src/stream/stream.h +++ b/src/stream/stream.h @@ -243,6 +243,8 @@ public: static void set_no_ack_mode(Flow*, bool); static void partial_flush(Flow*, bool to_server); + static bool get_held_pkt_seq(Flow*, uint32_t&); + private: static void set_ip_protocol(Flow*); }; diff --git a/src/stream/tcp/tcp_stream_session.cc b/src/stream/tcp/tcp_stream_session.cc index 1675b666f..0a37dabe4 100644 --- a/src/stream/tcp/tcp_stream_session.cc +++ b/src/stream/tcp/tcp_stream_session.cc @@ -261,9 +261,15 @@ int TcpStreamSession::update_alert(Packet* p, uint32_t gid, uint32_t sid, bool TcpStreamSession::set_packet_action_to_hold(Packet* p) { if ( p->is_from_client() ) + { + held_packet_dir = SSN_DIR_FROM_CLIENT; return server.set_held_packet(p); + } else + { + held_packet_dir = SSN_DIR_FROM_SERVER; return client.set_held_packet(p); + } } void TcpStreamSession::set_packet_header_foo(const TcpSegmentDescriptor& tsd) diff --git a/src/stream/tcp/tcp_stream_session.h b/src/stream/tcp/tcp_stream_session.h index 1acfcd6d6..f3f33c4ed 100644 --- a/src/stream/tcp/tcp_stream_session.h +++ b/src/stream/tcp/tcp_stream_session.h @@ -121,6 +121,7 @@ public: TcpStreamConfig* tcp_config = nullptr; TcpEventLogger tel; bool cleaning = false; + uint8_t held_packet_dir = SSN_DIR_NONE; private: bool no_ack = false; diff --git a/src/stream/tcp/tcp_stream_tracker.cc b/src/stream/tcp/tcp_stream_tracker.cc index de21ed73d..db4c45ea3 100644 --- a/src/stream/tcp/tcp_stream_tracker.cc +++ b/src/stream/tcp/tcp_stream_tracker.cc @@ -635,6 +635,7 @@ bool TcpStreamTracker::set_held_packet(Packet* p) memory::MemoryCap::update_allocations(daq_msg_get_data_len(p->daq_msg)); held_packet = hpq->append(p->daq_msg, p->ptrs.tcph->seq(), *this); + held_pkt_seq = p->ptrs.tcph->seq(); tcpStats.total_packets_held++; if ( ++tcpStats.current_packets_held > tcpStats.max_packets_held ) @@ -699,6 +700,9 @@ void TcpStreamTracker::finalize_held_packet(Packet* cp) Analyzer::get_local_analyzer()->finalize_daq_message(msg, DAQ_VERDICT_PASS); tcpStats.held_packets_passed++; } + + TcpStreamSession* tcp_session = (TcpStreamSession*)cp->flow->session; + tcp_session->held_packet_dir = SSN_DIR_NONE; } memory::MemoryCap::update_deallocations(msglen); @@ -728,6 +732,8 @@ void TcpStreamTracker::finalize_held_packet(Flow* flow) } else { + TcpStreamSession* tcp_session = (TcpStreamSession*)flow->session; + tcp_session->held_packet_dir = SSN_DIR_NONE; Analyzer::get_local_analyzer()->finalize_daq_message(msg, DAQ_VERDICT_PASS); tcpStats.held_packets_passed++; } diff --git a/src/stream/tcp/tcp_stream_tracker.h b/src/stream/tcp/tcp_stream_tracker.h index 7a3a25f57..0945f2ea8 100644 --- a/src/stream/tcp/tcp_stream_tracker.h +++ b/src/stream/tcp/tcp_stream_tracker.h @@ -316,6 +316,7 @@ public: uint16_t snd_up = 0; // SND.UP - send urgent pointer uint16_t rcv_up = 0; // RCV.UP - receive urgent pointer + uint32_t held_pkt_seq = 0; TcpState tcp_state; TcpEvent tcp_event = TCP_MAX_EVENTS;