1 //-------------------------------------------------------------------------- 2 // Copyright (C) 2015-2021 Cisco and/or its affiliates. All rights reserved. 3 // 4 // This program is free software; you can redistribute it and/or modify it 5 // under the terms of the GNU General Public License Version 2 as published 6 // by the Free Software Foundation. You may not use, modify or distribute 7 // this program under any other version of the GNU General Public License. 8 // 9 // This program is distributed in the hope that it will be useful, but 10 // WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 // General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License along 15 // with this program; if not, write to the Free Software Foundation, Inc., 16 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 //-------------------------------------------------------------------------- 18 19 // tcp_stream_tracker.h author davis mcpherson <davmcphe@cisco.com> 20 // Created on: Jun 24, 2015 21 22 #ifndef TCP_STREAM_TRACKER_H 23 #define TCP_STREAM_TRACKER_H 24 25 #include <list> 26 27 #include "stream/paf.h" 28 29 #include "segment_overlap_editor.h" 30 #include "tcp_defs.h" 31 #include "tcp_module.h" 32 #include "tcp_normalizers.h" 33 #include "tcp_reassemblers.h" 34 #include "tcp_segment_descriptor.h" 35 36 extern const char* tcp_state_names[]; 37 extern const char* tcp_event_names[]; 38 39 namespace snort 40 { 41 struct Packet; 42 } 43 44 class HeldPacket; 45 class TcpReassembler; 46 class TcpSession; 47 48 class TcpStreamTracker 49 { 50 public: 51 enum TcpState : uint8_t 52 { 53 TCP_LISTEN, 54 TCP_SYN_SENT, 55 TCP_SYN_RECV, 56 TCP_ESTABLISHED, 57 TCP_FIN_WAIT1, 58 TCP_FIN_WAIT2, 59 TCP_CLOSE_WAIT, 60 TCP_CLOSING, 61 TCP_LAST_ACK, 62 TCP_TIME_WAIT, 63 TCP_CLOSED, 64 TCP_STATE_NONE, 65 TCP_MAX_STATES 66 }; 67 68 enum TcpEvent : uint8_t 69 { 70 TCP_SYN_SENT_EVENT, 71 TCP_SYN_RECV_EVENT, 72 TCP_SYN_ACK_SENT_EVENT, 73 TCP_SYN_ACK_RECV_EVENT, 74 TCP_ACK_SENT_EVENT, 75 TCP_ACK_RECV_EVENT, 76 TCP_DATA_SEG_SENT_EVENT, 77 TCP_DATA_SEG_RECV_EVENT, 78 TCP_FIN_SENT_EVENT, 79 TCP_FIN_RECV_EVENT, 80 TCP_RST_SENT_EVENT, 81 TCP_RST_RECV_EVENT, 82 TCP_NO_FLAGS_EVENT, 83 TCP_MAX_EVENTS 84 }; 85 86 enum FinSeqNumStatus : uint8_t { FIN_NOT_SEEN, FIN_WITH_SEQ_SEEN, FIN_WITH_SEQ_ACKED }; 87 88 TcpStreamTracker(bool client); 89 virtual ~TcpStreamTracker(); 90 is_client_tracker()91 bool is_client_tracker() const 92 { return client_tracker; } 93 is_server_tracker()94 bool is_server_tracker() const 95 { return !client_tracker; } 96 get_tcp_state()97 TcpState get_tcp_state() const 98 { return tcp_state; } 99 set_tcp_state(TcpState tcp_state)100 void set_tcp_state(TcpState tcp_state) 101 { this->tcp_state = tcp_state; } 102 get_tcp_event()103 TcpEvent get_tcp_event() const 104 { return tcp_event; } 105 106 TcpEvent set_tcp_event(const TcpSegmentDescriptor&); 107 set_tcp_event(TcpEvent tcp_event)108 void set_tcp_event(TcpEvent tcp_event) 109 { this->tcp_event = tcp_event; } 110 get_rcv_nxt()111 uint32_t get_rcv_nxt() const 112 { return rcv_nxt; } 113 set_rcv_nxt(uint32_t rcv_nxt)114 void set_rcv_nxt(uint32_t rcv_nxt) 115 { this->rcv_nxt = rcv_nxt; } 116 get_rcv_wnd()117 uint32_t get_rcv_wnd() const 118 { return rcv_wnd; } 119 set_rcv_wnd(uint32_t rcv_wnd)120 void set_rcv_wnd(uint32_t rcv_wnd) 121 { this->rcv_wnd = rcv_wnd; } 122 get_rcv_up()123 uint16_t get_rcv_up() const 124 { return rcv_up; } 125 set_rcv_up(uint16_t rcv_up)126 void set_rcv_up(uint16_t rcv_up) 127 { this->rcv_up = rcv_up; } 128 get_irs()129 uint32_t get_irs() const 130 { return irs; } 131 set_irs(uint32_t irs)132 void set_irs(uint32_t irs) 133 { this->irs = irs; } 134 get_snd_una()135 uint32_t get_snd_una() const 136 { return snd_una; } 137 set_snd_una(uint32_t snd_una)138 void set_snd_una(uint32_t snd_una) 139 { this->snd_una = snd_una; } 140 get_snd_nxt()141 uint32_t get_snd_nxt() const 142 { return snd_nxt; } 143 set_snd_nxt(uint32_t snd_nxt)144 void set_snd_nxt(uint32_t snd_nxt) 145 { this->snd_nxt = snd_nxt; } 146 get_snd_up()147 uint16_t get_snd_up() const 148 { return snd_up; } 149 set_snd_up(uint16_t snd_up)150 void set_snd_up(uint16_t snd_up) 151 { this->snd_up = snd_up; } 152 get_snd_wl1()153 uint32_t get_snd_wl1() const 154 { return snd_wl1; } 155 set_snd_wl1(uint32_t snd_wl1)156 void set_snd_wl1(uint32_t snd_wl1) 157 { this->snd_wl1 = snd_wl1; } 158 get_snd_wl2()159 uint32_t get_snd_wl2() const 160 { return snd_wl2; } 161 set_snd_wl2(uint32_t snd_wl2)162 void set_snd_wl2(uint32_t snd_wl2) 163 { this->snd_wl2 = snd_wl2; } 164 get_snd_wnd()165 uint32_t get_snd_wnd() const 166 { return snd_wnd; } 167 set_snd_wnd(uint32_t snd_wnd)168 void set_snd_wnd(uint32_t snd_wnd) 169 { this->snd_wnd = snd_wnd; } 170 get_iss()171 uint32_t get_iss() const 172 { return iss; } 173 set_iss(uint32_t iss)174 void set_iss(uint32_t iss) 175 { this->iss = iss; } 176 get_fin_final_seq()177 uint32_t get_fin_final_seq() const 178 { return fin_final_seq + fin_seq_adjust; } 179 get_fin_seq_adjust()180 uint32_t get_fin_seq_adjust() 181 { return fin_seq_adjust; } 182 is_fin_seq_set()183 bool is_fin_seq_set() const 184 { return fin_seq_set; } 185 get_ts_last_packet()186 uint32_t get_ts_last_packet() const 187 { return ts_last_packet; } 188 set_ts_last_packet(uint32_t ts_last_packet)189 void set_ts_last_packet(uint32_t ts_last_packet) 190 { this->ts_last_packet = ts_last_packet; } 191 is_ack_valid(uint32_t cur)192 bool is_ack_valid(uint32_t cur) 193 { 194 if ( ( snd_una == 0 ) && ( snd_nxt == 0 ) ) 195 return true; 196 197 bool valid = SEQ_LEQ(cur, snd_nxt); 198 if ( !valid ) 199 tcpStats.invalid_ack++; 200 201 return valid; 202 } 203 204 // ack number must ack syn is_rst_valid_in_syn_sent(const TcpSegmentDescriptor & tsd)205 bool is_rst_valid_in_syn_sent(const TcpSegmentDescriptor& tsd) const 206 { return tsd.get_ack() == snd_una; } 207 get_ts_last()208 uint32_t get_ts_last() const 209 { return ts_last; } 210 set_ts_last(uint32_t ts_last)211 void set_ts_last(uint32_t ts_last) 212 { this->ts_last = ts_last; } 213 get_tf_flags()214 uint16_t get_tf_flags() const 215 { return tf_flags; } 216 set_tf_flags(uint16_t flags)217 void set_tf_flags(uint16_t flags) 218 { this->tf_flags |= flags; } 219 clear_tf_flags(uint16_t flags)220 void clear_tf_flags(uint16_t flags) 221 { this->tf_flags &= ~flags; } 222 get_wscale()223 uint16_t get_wscale() const 224 { return wscale; } 225 set_wscale(uint16_t wscale)226 void set_wscale(uint16_t wscale) 227 { this->wscale = wscale; } 228 get_mss()229 uint16_t get_mss() const 230 { return mss; } 231 set_mss(uint16_t mss)232 void set_mss(uint16_t mss) 233 { this->mss = mss; } 234 get_tcp_options_len()235 uint8_t get_tcp_options_len() const 236 { return tcp_options_len; } 237 set_tcp_options_len(uint8_t tcp_options_len)238 void set_tcp_options_len(uint8_t tcp_options_len) 239 { this->tcp_options_len = tcp_options_len; } 240 241 void cache_mac_address(const TcpSegmentDescriptor&, uint8_t direction); 242 bool compare_mac_addresses(const uint8_t eth_addr[]); 243 is_rst_pkt_sent()244 bool is_rst_pkt_sent() const 245 { return rst_pkt_sent; } 246 set_flush_policy(FlushPolicy policy)247 void set_flush_policy(FlushPolicy policy) 248 { flush_policy = policy; } 249 get_flush_policy()250 FlushPolicy get_flush_policy() const 251 { return flush_policy; } 252 253 virtual void init_tcp_state(); 254 virtual void init_flush_policy(); 255 virtual void set_splitter(snort::StreamSplitter* ss); 256 virtual void set_splitter(const snort::Flow* flow); 257 get_splitter()258 snort::StreamSplitter* get_splitter() 259 { return splitter; } 260 is_splitter_paf()261 bool is_splitter_paf() const 262 { return splitter && splitter->is_paf(); } 263 is_reassembly_enabled()264 bool is_reassembly_enabled() const 265 { return ( splitter and (flush_policy != STREAM_FLPOLICY_IGNORE) ); } 266 267 virtual void init_on_syn_sent(TcpSegmentDescriptor&); 268 virtual void init_on_syn_recv(TcpSegmentDescriptor&); 269 virtual void init_on_synack_sent(TcpSegmentDescriptor&); 270 virtual void init_on_synack_recv(TcpSegmentDescriptor&); 271 virtual void init_on_3whs_ack_sent(TcpSegmentDescriptor&); 272 virtual void init_on_3whs_ack_recv(TcpSegmentDescriptor&); 273 virtual void init_on_data_seg_sent(TcpSegmentDescriptor&); 274 virtual void init_on_data_seg_recv(TcpSegmentDescriptor&); 275 virtual void finish_server_init(TcpSegmentDescriptor&); 276 virtual void finish_client_init(TcpSegmentDescriptor&); 277 278 virtual void update_tracker_ack_recv(TcpSegmentDescriptor&); 279 virtual void update_tracker_ack_sent(TcpSegmentDescriptor&); 280 virtual void update_tracker_no_ack_recv(TcpSegmentDescriptor&); 281 virtual void update_tracker_no_ack_sent(TcpSegmentDescriptor&); 282 virtual bool update_on_3whs_ack(TcpSegmentDescriptor&); 283 virtual bool update_on_rst_recv(TcpSegmentDescriptor&); 284 virtual void update_on_rst_sent(); 285 virtual bool update_on_fin_recv(TcpSegmentDescriptor&); 286 virtual bool update_on_fin_sent(TcpSegmentDescriptor&); 287 virtual bool is_segment_seq_valid(TcpSegmentDescriptor&); 288 bool set_held_packet(snort::Packet*); 289 bool is_retransmit_of_held_packet(snort::Packet*); 290 void finalize_held_packet(snort::Packet*); 291 void finalize_held_packet(snort::Flow*); 292 void perform_fin_recv_flush(TcpSegmentDescriptor&); 293 uint32_t perform_partial_flush(); is_holding_packet()294 bool is_holding_packet() const { return held_packet != null_iterator; } 295 296 // max_remove < 0 means time out all eligible packets. 297 // Return whether there are more packets that need to be released. 298 static bool release_held_packets(const timeval& cur_time, int max_remove); 299 static void set_held_packet_timeout(const uint32_t ms); 300 static bool adjust_expiration(uint32_t new_timeout_ms, const timeval& now); 301 static void thread_init(); 302 static void thread_term(); 303 304 public: 305 uint32_t snd_una = 0; // SND.UNA - send unacknowledged 306 uint32_t snd_nxt = 0; // SND.NXT - send next 307 uint32_t snd_wnd = 0; // SND.WND - send window 308 uint32_t snd_wl1 = 0; // SND.WL1 - segment sequence number used for last window update 309 uint32_t snd_wl2 = 0; // SND.WL2 - segment acknowledgment number used for last window update 310 uint32_t iss = 0; // ISS - initial send sequence number 311 312 uint32_t rcv_nxt = 0; // RCV.NXT - receive next 313 uint32_t rcv_wnd = 0; // RCV.WND - receive window 314 uint32_t irs = 0; // IRS - initial receive sequence number 315 316 uint16_t snd_up = 0; // SND.UP - send urgent pointer 317 uint16_t rcv_up = 0; // RCV.UP - receive urgent pointer 318 319 uint32_t held_pkt_seq = 0; 320 TcpState tcp_state; 321 TcpEvent tcp_event = TCP_MAX_EVENTS; 322 323 bool client_tracker; 324 bool require_3whs = false; 325 bool rst_pkt_sent = false; 326 327 // FIXIT-L make these non-public 328 public: 329 TcpNormalizerPolicy normalizer; 330 TcpReassemblerPolicy reassembler; 331 TcpSession* session = nullptr; 332 333 uint32_t r_win_base = 0; // remote side window base sequence number (the last ack we got) 334 uint32_t small_seg_count = 0; 335 uint32_t max_queue_seq_nxt; // next expected sequence once queue limit is exceeded 336 uint8_t max_queue_exceeded = MQ_NONE; 337 uint8_t order = 0; 338 FinSeqNumStatus fin_seq_status = TcpStreamTracker::FIN_NOT_SEEN; 339 bool reinit_seg_base = false; 340 341 protected: 342 static const std::list<HeldPacket>::iterator null_iterator; 343 std::list<HeldPacket>::iterator held_packet; 344 snort::StreamSplitter* splitter = nullptr; 345 uint32_t ts_last_packet = 0; 346 uint32_t ts_last = 0; // last timestamp (for PAWS) 347 uint32_t fin_final_seq = 0; 348 uint32_t fin_seq_adjust = 0; 349 uint16_t mss = 0; // max segment size 350 uint16_t wscale = 0; // window scale setting 351 uint16_t tf_flags = 0; 352 uint8_t mac_addr[6] = { }; 353 uint8_t tcp_options_len = 0; 354 FlushPolicy flush_policy = STREAM_FLPOLICY_IGNORE; 355 bool mac_addr_valid = false; 356 bool fin_seq_set = false; // FIXIT-M should be obviated by tcp state 357 }; 358 359 // <--- note -- the 'state' parameter must be a reference 360 inline TcpStreamTracker::TcpState& operator++(TcpStreamTracker::TcpState& state, int) 361 { 362 if ( state < TcpStreamTracker::TCP_MAX_STATES ) 363 state = static_cast<TcpStreamTracker::TcpState>( static_cast<int>(state) + 1 ); 364 else 365 state = TcpStreamTracker::TCP_MAX_STATES; 366 367 return state; 368 } 369 370 #endif 371 372