00001 //--------------------------------------------------------------------------
00002 // Copyright (C) 2015-2017 Cisco and/or its affiliates. All rights reserved.
00003 //
00004 // This program is free software; you can redistribute it and/or modify it
00005 // under the terms of the GNU General Public License Version 2 as published
00006 // by the Free Software Foundation. You may not use, modify or distribute
00007 // this program under any other version of the GNU General Public License.
00008 //
00009 // This program is distributed in the hope that it will be useful, but
00010 // WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License along
00015 // with this program; if not, write to the Free Software Foundation, Inc.,
00016 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017 //--------------------------------------------------------------------------
00018
00019 // tcp_state_syn_recv.cc author davis mcpherson <davmcphe@@cisco.com>
00020 // Created on: Aug 5, 2015
00021
00022 #ifdef HAVE_CONFIG_H
00023 #include "config.h"
00024 #endif
00025
00026 #include "tcp_state_syn_recv.h"
00027
00028 #include "tcp_module.h"
00029 #include "tcp_normalizer.h"
00030 #include "tcp_session.h"
00031
00032 using namespace std;
00033
00034 TcpStateSynRecv::TcpStateSynRecv(TcpStateMachine& tsm) :
00035 TcpStateHandler(TcpStreamTracker::TCP_SYN_RECV, tsm)
00036 {
00037 }
00038
00039
00040 bool TcpStateSynRecv::syn_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00041 {
00042 Flow* flow = tsd.get_flow();
00043
00044 trk.finish_server_init(tsd);
00045 trk.normalizer->ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs() );
00046 trk.session->update_timestamp_tracking(tsd);
00047 if ( tsd.get_tcph()->are_flags_set(TH_ECE) &&
00048 ( flow->get_session_flags() & SSNFLAG_ECN_CLIENT_QUERY ) )
00049 flow->set_session_flags(SSNFLAG_ECN_SERVER_REPLY);
00050
00051 if ( tsd.get_pkt()->is_from_server() )
00052 {
00053 flow->set_session_flags(SSNFLAG_SEEN_SERVER);
00054 trk.session->tel.set_tcp_event(EVENT_4WHS);
00055 }
00056
00057 return default_state_action(tsd, trk);
00058 }
00059
00060 bool TcpStateSynRecv::syn_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00061 {
00062 if ( tsd.get_seg_len() )
00063 trk.session->handle_data_on_syn(tsd);
00064
00065 return default_state_action(tsd, trk);
00066 }
00067
00068 bool TcpStateSynRecv::syn_ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00069 {
00070 Flow* flow = tsd.get_flow();
00071
00072 // FIXIT-H verify ack being sent is valid...
00073 trk.finish_server_init(tsd);
00074 trk.normalizer->ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs() );
00075 flow->session_state |= STREAM_STATE_SYN_ACK;
00076
00077 return default_state_action(tsd, trk);
00078 }
00079
00080 bool TcpStateSynRecv::syn_ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00081 {
00082 if ( trk.is_ack_valid(tsd.get_seg_ack() ) )
00083 {
00084 Flow* flow = tsd.get_flow();
00085
00086 trk.update_tracker_ack_recv(tsd);
00087 trk.normalizer->ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs() );
00088 flow->set_session_flags(SSNFLAG_ESTABLISHED);
00089 flow->session_state |= ( STREAM_STATE_ACK | STREAM_STATE_ESTABLISHED );
00090 trk.session->update_perf_base_state(TcpStreamTracker::TCP_ESTABLISHED);
00091 trk.set_tcp_state(TcpStreamTracker::TCP_ESTABLISHED);
00092 if ( tsd.get_seg_len() )
00093 trk.session->handle_data_on_syn(tsd);
00094 }
00095
00096 return default_state_action(tsd, trk);
00097 }
00098
00099 bool TcpStateSynRecv::ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00100 {
00101 if ( trk.session->config->midstream_allowed(tsd.get_pkt()) )
00102 {
00103 trk.session->update_session_on_ack( );
00104 }
00105
00106 return default_state_action(tsd, trk);
00107 }
00108
00109 bool TcpStateSynRecv::ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00110 {
00111 if ( trk.is_ack_valid(tsd.get_seg_ack() ) )
00112 {
00113 Flow* flow = tsd.get_flow();
00114
00115 trk.update_tracker_ack_recv(tsd);
00116 trk.session->set_pkt_action_flag(trk.normalizer->handle_paws(tsd) );
00117 tsd.get_pkt()->packet_flags |= PKT_STREAM_TWH;
00118 flow->set_session_flags(SSNFLAG_ESTABLISHED);
00119 flow->session_state |= ( STREAM_STATE_ACK | STREAM_STATE_ESTABLISHED );
00120 trk.session->update_perf_base_state(TcpStreamTracker::TCP_ESTABLISHED);
00121 trk.set_tcp_state(TcpStreamTracker::TCP_ESTABLISHED);
00122 if ( tsd.get_seg_len() > 0 )
00123 trk.session->handle_data_segment(tsd);
00124 else
00125 trk.session->check_for_window_slam(tsd);
00126 }
00127
00128 return default_state_action(tsd, trk);
00129 }
00130
00131 bool TcpStateSynRecv::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00132 {
00133 return default_state_action(tsd, trk);
00134 }
00135
00136 bool TcpStateSynRecv::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00137 {
00138 if ( trk.is_ack_valid(tsd.get_seg_ack() ) )
00139 {
00140 trk.update_tracker_ack_recv(tsd);
00141 tsd.get_pkt()->packet_flags |= PKT_STREAM_TWH;
00142 trk.session->set_pkt_action_flag(trk.normalizer->handle_paws(tsd) );
00143 trk.session->update_perf_base_state(TcpStreamTracker::TCP_ESTABLISHED);
00144 trk.set_tcp_state(TcpStreamTracker::TCP_ESTABLISHED);
00145 if ( tsd.get_seg_len() > 0 )
00146 trk.session->handle_data_segment(tsd);
00147 }
00148
00149 return default_state_action(tsd, trk);
00150 }
00151
00152 bool TcpStateSynRecv::fin_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00153 {
00154 return default_state_action(tsd, trk);
00155 }
00156
00157 bool TcpStateSynRecv::fin_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00158 {
00159 if ( tsd.get_tcph()->is_ack() )
00160 {
00161 Flow* flow = tsd.get_flow();
00162
00163 trk.update_tracker_ack_recv(tsd);
00164 trk.session->set_pkt_action_flag(trk.normalizer->handle_paws(tsd) );
00165 flow->session_state |= STREAM_STATE_ACK;
00166 if ( tsd.get_seg_len() > 0 )
00167 {
00168 trk.session->handle_data_segment(tsd);
00169 trk.flush_data_on_fin_recv(tsd);
00170 }
00171
00172 if ( trk.update_on_fin_recv(tsd) )
00173 {
00174 trk.session->update_perf_base_state(TcpStreamTracker::TCP_CLOSING);
00175 trk.set_tcp_state(TcpStreamTracker::TCP_CLOSE_WAIT);
00176 }
00177 }
00178
00179 return default_state_action(tsd, trk);
00180 }
00181
00182 bool TcpStateSynRecv::rst_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00183 {
00184 return default_state_action(tsd, trk);
00185 }
00186
00187 bool TcpStateSynRecv::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00188 {
00189 trk.normalizer->trim_rst_payload(tsd);
00190 if ( trk.normalizer->validate_rst(tsd) )
00191 {
00192 Flow* flow = tsd.get_flow();
00193
00194 flow->set_session_flags(SSNFLAG_RESET);
00195 if ( trk.normalizer->is_tcp_ips_enabled() )
00196 tcp_state = TcpStreamTracker::TCP_LISTEN;
00197 }
00198 else
00199 {
00200 DebugMessage(DEBUG_STREAM_STATE, "Received RST with bad sequence number\n");
00201 inc_tcp_discards();
00202 trk.normalizer->packet_dropper(tsd, NORM_TCP_BLOCK);
00203 trk.session->tel.set_tcp_event(EVENT_BAD_RST);
00204 }
00205
00206 // FIXIT-L might be good to create alert specific to RST with data
00207 if ( tsd.get_seg_len() > 0 )
00208 trk.session->tel.set_tcp_event(EVENT_DATA_AFTER_RST_RCVD);
00209
00210 return default_state_action(tsd, trk);
00211 }
00212
00213 bool TcpStateSynRecv::do_post_sm_packet_actions(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
00214 {
00215 trk.session->check_for_window_slam(tsd);
00216
00217 return true;
00218 }
00219
END OF CODE