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_tracker.cc author davis mcpherson <davmcphe@@cisco.com>
00020 // Created on: Dec 1, 2015
00021
00022 #ifdef HAVE_CONFIG_H
00023 #include "config.h"
00024 #endif
00025
00026 #include "tcp_tracker.h"
00027
00028 #include "log/messages.h"
00029 #include "profiler/profiler_defs.h"
00030
00031 #include "tcp_module.h"
00032 #include "tcp_normalizer.h"
00033 #include "tcp_reassembler.h"
00034
00035 TcpTracker::TcpTracker(bool client, TcpSession* ssn) :
00036 TcpStreamTracker(client)
00037 {
00038 session = ssn;
00039 }
00040
00041 TcpTracker::~TcpTracker()
00042 {
00043 delete splitter;
00044 delete normalizer;
00045 delete reassembler;
00046 }
00047
00048 void TcpTracker::init_tcp_state( )
00049 {
00050 tcp_state = ( client_tracker ) ?
00051 TcpStreamTracker::TCP_STATE_NONE : TcpStreamTracker::TCP_LISTEN;
00052 flush_policy = STREAM_FLPOLICY_IGNORE;
00053 memset(&paf_state, 0, sizeof(paf_state));
00054 snd_una = snd_nxt = snd_wnd = 0;
00055 r_nxt_ack = r_win_base = iss = ts_last = ts_last_packet = 0;
00056 small_seg_count = wscale = mss = 0;
00057 tf_flags = 0;
00058 alert_count = 0;
00059 memset(&alerts, 0, sizeof(alerts));
00060 memset(&mac_addr, 0, sizeof(mac_addr));
00061 mac_addr_valid = false;
00062 fin_final_seq = 0;
00063 fin_seq_status = TcpStreamTracker::FIN_NOT_SEEN;
00064 fin_seq_set = false;
00065 rst_pkt_sent = false;
00066 }
00067
00068 void TcpTracker::init_toolbox()
00069 {
00070 delete splitter;
00071 splitter = nullptr;
00072 delete normalizer;
00073 normalizer = nullptr;
00074 delete reassembler;
00075 reassembler = nullptr;
00076 }
00077
00078 //-------------------------------------------------------------------------
00079 // flush policy stuff
00080 //-------------------------------------------------------------------------
00081
00082 void TcpTracker::init_flush_policy()
00083 {
00084 if ( splitter == nullptr )
00085 flush_policy = STREAM_FLPOLICY_IGNORE;
00086 else if ( normalizer->is_tcp_ips_enabled() )
00087 flush_policy = STREAM_FLPOLICY_ON_DATA;
00088 else
00089 flush_policy = STREAM_FLPOLICY_ON_ACK;
00090 }
00091
00092 void TcpTracker::set_splitter(StreamSplitter* ss)
00093 {
00094 if ( splitter )
00095 delete splitter;
00096
00097 splitter = ss;
00098
00099 if ( ss )
00100 paf_setup(&paf_state);
00101 else
00102 flush_policy = STREAM_FLPOLICY_IGNORE;
00103 }
00104
00105 void TcpTracker::set_splitter(const Flow* flow)
00106 {
00107 Inspector* ins = flow->gadget;
00108
00109 if ( !ins )
00110 ins = flow->clouseau;
00111
00112 if ( ins )
00113 set_splitter(ins->get_splitter(!client_tracker) );
00114 else
00115 set_splitter(new AtomSplitter(!client_tracker) );
00116 }
00117
00118 void TcpTracker::reset_splitter( )
00119 {
00120 if ( splitter )
00121 splitter->reset();
00122 }
00123
00124 void TcpTracker::init_on_syn_sent(TcpSegmentDescriptor& tsd)
00125 {
00126 Profile profile(s5TcpNewSessPerfStats);
00127
00128 tsd.get_flow()->set_session_flags(SSNFLAG_SEEN_CLIENT);
00129 if ( tsd.get_tcph()->are_flags_set(TH_CWR | TH_ECE) )
00130 tsd.get_flow()->set_session_flags(SSNFLAG_ECN_CLIENT_QUERY);
00131
00132 iss = tsd.get_seg_seq();
00133 snd_una = iss;
00134 snd_nxt = tsd.get_end_seq();
00135 snd_wnd = tsd.get_seg_wnd();
00136
00137 ts_last_packet = tsd.get_pkt()->pkth->ts.tv_sec;
00138 tf_flags |= normalizer->get_tcp_timestamp(tsd, false);
00139 ts_last = tsd.get_ts();
00140 if (ts_last == 0)
00141 tf_flags |= TF_TSTAMP_ZERO;
00142 tf_flags |= tsd.init_mss(&mss);
00143 tf_flags |= tsd.init_wscale(&wscale);
00144
00145 cache_mac_address(tsd, FROM_CLIENT);
00146 set_splitter(tsd.get_flow() );
00147 init_flush_policy( );
00148
00149 tcpStats.sessions_on_syn++;
00150 tcp_state = TcpStreamTracker::TCP_SYN_SENT;
00151 }
00152
00153 void TcpTracker::init_on_syn_recv(TcpSegmentDescriptor& tsd)
00154 {
00155 Profile profile(s5TcpNewSessPerfStats);
00156
00157 irs = tsd.get_seg_seq();
00158 // FIXIT-H can we really set the vars below now?
00159 r_nxt_ack = tsd.get_seg_seq() + 1;
00160 r_win_base = tsd.get_seg_seq() + 1;
00161 reassembler->set_seglist_base_seq(tsd.get_seg_seq() + 1);
00162
00163 cache_mac_address(tsd, FROM_CLIENT);
00164 set_splitter(tsd.get_flow() );
00165 init_flush_policy( );
00166
00167 tcp_state = TcpStreamTracker::TCP_SYN_RECV;
00168 }
00169
00170 void TcpTracker::init_on_synack_sent(TcpSegmentDescriptor& tsd)
00171 {
00172 Profile profile(s5TcpNewSessPerfStats);
00173
00174 DebugMessage(DEBUG_STREAM_STATE, "Creating new session tracker on SYN_ACK!\n");
00175
00176 tsd.get_flow()->set_session_flags(SSNFLAG_SEEN_SERVER);
00177 if (tsd.get_tcph()->are_flags_set(TH_CWR | TH_ECE))
00178 tsd.get_flow()->set_session_flags(SSNFLAG_ECN_SERVER_REPLY);
00179
00180 iss = tsd.get_seg_seq();
00181 irs = tsd.get_seg_ack() - 1;
00182 snd_una = tsd.get_seg_seq();
00183 snd_nxt = tsd.get_end_seq();
00184 snd_wnd = tsd.get_seg_wnd();
00185
00186 r_win_base = tsd.get_seg_ack();
00187 r_nxt_ack = tsd.get_seg_ack();
00188 reassembler->set_seglist_base_seq(tsd.get_seg_ack() );
00189
00190 ts_last_packet = tsd.get_pkt()->pkth->ts.tv_sec;
00191 tf_flags |= normalizer->get_tcp_timestamp(tsd, false);
00192 ts_last = tsd.get_ts();
00193 if ( ts_last == 0 )
00194 tf_flags |= TF_TSTAMP_ZERO;
00195 tf_flags |= tsd.init_mss(&mss);
00196 tf_flags |= tsd.init_wscale(&wscale);
00197
00198 cache_mac_address(tsd, FROM_SERVER);
00199 set_splitter(tsd.get_flow() );
00200 init_flush_policy();
00201
00202 tcpStats.sessions_on_syn_ack++;
00203 tcp_state = TcpStreamTracker::TCP_SYN_RECV;
00204 }
00205
00206 void TcpTracker::init_on_synack_recv(TcpSegmentDescriptor& tsd)
00207 {
00208 Profile profile(s5TcpNewSessPerfStats);
00209
00210 iss = tsd.get_seg_ack() - 1;
00211 irs = tsd.get_seg_seq();
00212 snd_una = tsd.get_seg_ack();
00213 snd_nxt = snd_una;
00214
00215 r_nxt_ack = tsd.get_seg_seq() + 1;
00216 r_win_base = tsd.get_seg_seq() + 1;
00217 reassembler->set_seglist_base_seq(tsd.get_seg_seq() + 1);
00218
00219 cache_mac_address(tsd, FROM_SERVER);
00220 set_splitter(tsd.get_flow() );
00221 init_flush_policy();
00222
00223 tcp_state = TcpStreamTracker::TCP_ESTABLISHED;
00224 }
00225
00226 void TcpTracker::init_on_3whs_ack_sent(TcpSegmentDescriptor& tsd)
00227 {
00228 Profile profile(s5TcpNewSessPerfStats);
00229
00230 tsd.get_flow()->set_session_flags(SSNFLAG_SEEN_CLIENT);
00231
00232 if ( tsd.get_tcph()->are_flags_set(TH_CWR | TH_ECE) )
00233 tsd.get_flow()->set_session_flags(SSNFLAG_ECN_CLIENT_QUERY);
00234
00235 iss = tsd.get_seg_seq();
00236 snd_una = tsd.get_seg_seq();
00237 snd_nxt = snd_una;
00238 snd_wnd = tsd.get_seg_wnd();
00239
00240 r_win_base = tsd.get_seg_ack();
00241 r_nxt_ack = tsd.get_seg_ack();
00242
00243 ts_last_packet = tsd.get_pkt()->pkth->ts.tv_sec;
00244 tf_flags |= normalizer->get_tcp_timestamp(tsd, false);
00245 ts_last = tsd.get_ts();
00246 if (ts_last == 0)
00247 tf_flags |= TF_TSTAMP_ZERO;
00248 tf_flags |= tsd.init_mss(&mss);
00249 tf_flags |= tsd.init_wscale(&wscale);
00250
00251 cache_mac_address(tsd, FROM_CLIENT);
00252 set_splitter(tsd.get_flow() );
00253 init_flush_policy();
00254 tcp_state = TcpStreamTracker::TCP_ESTABLISHED;
00255 }
00256
00257 void TcpTracker::init_on_3whs_ack_recv(TcpSegmentDescriptor& tsd)
00258 {
00259 Profile profile(s5TcpNewSessPerfStats);
00260
00261 iss = tsd.get_seg_ack() - 1;
00262 irs = tsd.get_seg_seq();
00263 snd_una = tsd.get_seg_ack();
00264 snd_nxt = snd_una;
00265
00266 r_nxt_ack = tsd.get_seg_seq();
00267 r_win_base = tsd.get_seg_seq();
00268 reassembler->set_seglist_base_seq(tsd.get_seg_seq() + 1);
00269
00270 cache_mac_address(tsd, FROM_CLIENT);
00271 set_splitter(tsd.get_flow() );
00272 init_flush_policy();
00273
00274 tcpStats.sessions_on_3way++;
00275 tcp_state = TcpStreamTracker::TCP_ESTABLISHED;
00276 }
00277
00278 void TcpTracker::init_on_data_seg_sent(TcpSegmentDescriptor& tsd)
00279 {
00280 Profile profile(s5TcpNewSessPerfStats);
00281
00282 Flow* flow = tsd.get_flow();
00283
00284 if ( flow->ssn_state.direction == FROM_CLIENT )
00285 flow->set_session_flags(SSNFLAG_SEEN_CLIENT);
00286 else
00287 flow->set_session_flags(SSNFLAG_SEEN_SERVER);
00288
00289 // FIXIT-H should we init these?
00290 iss = tsd.get_seg_seq();
00291 irs = tsd.get_seg_ack();
00292 snd_una = tsd.get_seg_seq();
00293 snd_nxt = snd_una + tsd.get_seg_len();
00294 snd_wnd = tsd.get_seg_wnd();
00295
00296 r_win_base = tsd.get_seg_ack();
00297 r_nxt_ack = tsd.get_seg_ack();
00298 reassembler->set_seglist_base_seq(tsd.get_seg_ack());
00299
00300 ts_last_packet = tsd.get_pkt()->pkth->ts.tv_sec;
00301 tf_flags |= normalizer->get_tcp_timestamp(tsd, false);
00302 ts_last = tsd.get_ts();
00303 if (ts_last == 0)
00304 tf_flags |= TF_TSTAMP_ZERO;
00305 tf_flags |= ( tsd.init_mss(&mss) | tsd.init_wscale(&wscale) );
00306
00307 cache_mac_address(tsd, tsd.get_direction() );
00308 set_splitter(tsd.get_flow() );
00309 init_flush_policy();
00310 tcp_state = TcpStreamTracker::TCP_ESTABLISHED;
00311 }
00312
00313 void TcpTracker::init_on_data_seg_recv(TcpSegmentDescriptor& tsd)
00314 {
00315 Profile profile(s5TcpNewSessPerfStats);
00316
00317 iss = tsd.get_seg_ack();
00318 irs = tsd.get_seg_seq();
00319 snd_una = tsd.get_seg_ack();
00320 snd_nxt = snd_una;
00321 snd_wnd = 0; /* reset later */
00322
00323 r_nxt_ack = tsd.get_seg_seq();
00324 r_win_base = tsd.get_seg_seq();
00325 reassembler->set_seglist_base_seq(tsd.get_seg_seq());
00326
00327 cache_mac_address(tsd, tsd.get_direction() );
00328 set_splitter(tsd.get_flow() );
00329 init_flush_policy();
00330
00331 tcpStats.sessions_on_data++;
00332 tcp_state = TcpStreamTracker::TCP_ESTABLISHED;
00333 }
00334
00335 void TcpTracker::finish_server_init(TcpSegmentDescriptor& tsd)
00336 {
00337 iss = tsd.get_seg_seq();
00338 snd_una = tsd.get_seg_seq();
00339 snd_nxt = tsd.get_end_seq();
00340 snd_wnd = tsd.get_seg_wnd();
00341
00342 // FIXIT-H move this to fin handler for syn_recv state ..
00343 //if ( tcph->is_fin() )
00344 // server->set_snd_nxt(server->get_snd_nxt() - 1);
00345
00346 tf_flags |= normalizer->get_tcp_timestamp(tsd, false);
00347 ts_last = tsd.get_ts();
00348 if ( ts_last != 0 )
00349 ts_last_packet = tsd.get_pkt()->pkth->ts.tv_sec;
00350 else
00351 tf_flags |= TF_TSTAMP_ZERO;
00352
00353 tf_flags |= ( tsd.init_mss(&mss) | tsd.init_wscale(&wscale) );
00354 }
00355
00356 void TcpTracker::finish_client_init(TcpSegmentDescriptor& tsd)
00357 {
00358 Flow* flow = tsd.get_flow();
00359
00360 r_nxt_ack = tsd.get_end_seq();
00361
00362 if ( !( flow->session_state & STREAM_STATE_MIDSTREAM ) )
00363 {
00364 reassembler->set_seglist_base_seq(tsd.get_seg_seq() + 1);
00365 r_win_base = tsd.get_end_seq();
00366 }
00367 else
00368 {
00369 reassembler->set_seglist_base_seq(tsd.get_seg_seq() );
00370 r_win_base = tsd.get_seg_seq();
00371 }
00372 }
00373
00374 void TcpTracker::update_tracker_ack_recv(TcpSegmentDescriptor& tsd)
00375 {
00376 if ( SEQ_GT(tsd.get_seg_ack(), snd_una) )
00377 {
00378 snd_una = tsd.get_seg_ack();
00379 if ( snd_nxt < snd_una )
00380 snd_nxt = snd_una;
00381 }
00382 }
00383
00384 void TcpTracker::update_tracker_ack_sent(TcpSegmentDescriptor& tsd)
00385 {
00386 // ** this is how we track the last seq number sent
00387 // as is l_unackd is the "last left" seq recvd
00388 //snd_una = tsd.get_seg_seq();
00389
00390 // FIXIT-H add check to validate ack...
00391
00392 if ( SEQ_GT(tsd.get_end_seq(), snd_nxt) )
00393 snd_nxt = tsd.get_end_seq();
00394
00395 if ( !SEQ_EQ(r_win_base, tsd.get_seg_ack() ) )
00396 small_seg_count = 0;
00397
00398 #ifdef S5_PEDANTIC
00399 if ( SEQ_GT(tsd.get_seg_ack(), r_win_base) &&
00400 SEQ_LEQ(tsd.get_seg_ack(), r_nxt_ack) )
00401 #else
00402 if ( SEQ_GT(tsd.get_seg_ack(), r_win_base) )
00403 #endif
00404 r_win_base = tsd.get_seg_ack();
00405
00406 if ( ( fin_seq_status == TcpStreamTracker::FIN_WITH_SEQ_SEEN )
00407 && SEQ_EQ(r_win_base, fin_final_seq) )
00408 {
00409 fin_seq_status = TcpStreamTracker::FIN_WITH_SEQ_ACKED;
00410 }
00411
00412 snd_wnd = tsd.get_seg_wnd();
00413 reassembler->flush_on_ack_policy(tsd.get_pkt() );
00414 }
00415
00416 bool TcpTracker::update_on_3whs_ack(TcpSegmentDescriptor& tsd)
00417 {
00418 bool good_ack = true;
00419
00420 if ( is_ack_valid(tsd.get_seg_ack()) )
00421 {
00422 Flow* flow = tsd.get_flow();
00423
00424 irs = tsd.get_seg_seq();
00425 finish_client_init(tsd);
00426 update_tracker_ack_recv(tsd);
00427 flow->set_session_flags(SSNFLAG_ESTABLISHED);
00428 flow->session_state |= ( STREAM_STATE_ACK | STREAM_STATE_ESTABLISHED );
00429
00430 /* Indicate this packet completes 3-way handshake */
00431 tsd.get_pkt()->packet_flags |= PKT_STREAM_TWH;
00432 tcp_state = TcpStreamTracker::TCP_ESTABLISHED;
00433 }
00434 else
00435 {
00436 DebugFormat(DEBUG_STREAM_STATE,
00437 "Pkt Ack is Out of Bounds (%X, %X, %X) = (snd_una, snd_nxt, cur)\n",
00438 snd_una, snd_nxt, tsd.get_seg_ack());
00439 inc_tcp_discards();
00440 normalizer->trim_win_payload(tsd);
00441 good_ack = false;
00442 }
00443
00444 return good_ack;
00445 }
00446
00447 bool TcpTracker::update_on_rst_recv(TcpSegmentDescriptor& tsd)
00448 {
00449 bool good_rst = true;
00450
00451 normalizer->trim_rst_payload(tsd);
00452 if ( normalizer->validate_rst(tsd) )
00453 {
00454 Flow* flow = tsd.get_flow();
00455
00456 DebugMessage(DEBUG_STREAM_STATE, "Received Valid RST, bailing\n");
00457 flow->set_session_flags(SSNFLAG_RESET);
00458 if ( normalizer->is_tcp_ips_enabled() )
00459 tcp_state = TcpStreamTracker::TCP_CLOSED;
00460 }
00461 else
00462 {
00463 DebugMessage(DEBUG_STREAM_STATE, "Received RST with bad sequence number, bailing\n");
00464 inc_tcp_discards();
00465 normalizer->packet_dropper(tsd, NORM_TCP_BLOCK);
00466 good_rst = false;
00467 }
00468
00469 return good_rst;
00470 }
00471
00472 void TcpTracker::update_on_rst_sent()
00473 {
00474 tcp_state = TcpStreamTracker::TCP_CLOSED;
00475 rst_pkt_sent = true;
00476 }
00477
00478 void TcpTracker::flush_data_on_fin_recv(TcpSegmentDescriptor& tsd)
00479 {
00480 if ( (flush_policy != STREAM_FLPOLICY_ON_ACK)
00481 && (flush_policy != STREAM_FLPOLICY_ON_DATA)
00482 && normalizer->is_tcp_ips_enabled())
00483 {
00484 tsd.get_pkt()->packet_flags |= PKT_PDU_TAIL;
00485 }
00486
00487 reassembler->flush_on_data_policy(tsd.get_pkt());
00488 }
00489
00490 bool TcpTracker::update_on_fin_recv(TcpSegmentDescriptor& tsd)
00491 {
00492 if ( SEQ_LT(tsd.get_end_seq(), r_win_base) )
00493 {
00494 DebugMessage(DEBUG_STREAM_STATE, "FIN inside r_win_base, bailing\n");
00495 return false;
00496 }
00497
00498 //--------------------------------------------------
00499 // FIXIT-L don't bump r_nxt_ack unless FIN is in seq
00500 // because it causes bogus 129:5 cases
00501 // but doing so causes extra gaps
00502 //if ( SEQ_EQ(tsd.end_seq, r_nxt_ack) )
00503 r_nxt_ack++;
00504
00505 // set final seq # any packet rx'ed with seq > is bad
00506 if ( !fin_seq_set )
00507 {
00508 fin_final_seq = tsd.get_end_seq();
00509 fin_seq_set = true;
00510 if( tsd.get_seg_len() == 0 )
00511 fin_seq_status = TcpStreamTracker::FIN_WITH_SEQ_SEEN;
00512 }
00513
00514 return true;
00515 }
00516
00517 bool TcpTracker::update_on_fin_sent(TcpSegmentDescriptor& tsd)
00518 {
00519 update_tracker_ack_sent(tsd);
00520 snd_nxt++;
00521 return true;
00522 }
00523
00524 #ifdef S5_PEDANTIC
00525 // From RFC 793:
00526 //
00527 // Segment Receive Test
00528 // Length Window
00529 // ------- ------- -------------------------------------------
00530 //
00531 // 0 0 SEG.SEQ = RCV.NXT
00532 //
00533 // 0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
00534 //
00535 // >0 0 not acceptable
00536 //
00537 // >0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
00538 // or RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND
00539 //
00540 bool ValidSeq(const Packet* p, Flow* flow, TcpTracker* st, TcpSegmentDescriptor& tsd)
00541 {
00542 uint32_t win = normalizer->get_stream_window(flow, st, tsd);
00543
00544 if ( !p->dsize )
00545 {
00546 if ( !win )
00547 {
00548 return ( tsd.get_seg_seq() == r_win_base );
00549 }
00550 return SEQ_LEQ(r_win_base, tsd.get_seg_seq()) &&
00551 SEQ_LT(tsd.get_seg_seq(), r_win_base+win);
00552 }
00553 if ( !win )
00554 return 0;
00555
00556 if ( SEQ_LEQ(r_win_base, tsd.get_seg_seq()) &&
00557 SEQ_LT(tsd.get_seg_seq(), r_win_base+win) )
00558 return 1;
00559
00560 return SEQ_LEQ(r_win_base, tsd.get_end_seq()) &&
00561 SEQ_LT(tsd.get_end_seq(), r_win_base+win);
00562 }
00563
00564 #endif
00565
00566 bool TcpTracker::is_segment_seq_valid(TcpSegmentDescriptor& tsd)
00567 {
00568 bool valid_seq = true;
00569
00570 int right_ok;
00571 uint32_t left_seq;
00572
00573 DebugFormat(DEBUG_STREAM_STATE,
00574 "Checking end_seq (%X) > r_win_base (%X) && seq (%X) < r_nxt_ack(%X)\n",
00575 tsd.get_end_seq(), r_win_base, tsd.get_seg_seq(),
00576 r_nxt_ack + normalizer->get_stream_window(tsd));
00577
00578 if ( SEQ_LT(r_nxt_ack, r_win_base) )
00579 left_seq = r_nxt_ack;
00580 else
00581 left_seq = r_win_base;
00582
00583 if ( tsd.get_seg_len() )
00584 right_ok = SEQ_GT(tsd.get_end_seq(), left_seq);
00585 else
00586 right_ok = SEQ_GEQ(tsd.get_end_seq(), left_seq);
00587
00588 if ( right_ok )
00589 {
00590 uint32_t win = normalizer->get_stream_window(tsd);
00591
00592 if ( SEQ_LEQ(tsd.get_seg_seq(), r_win_base + win) )
00593 {
00594 DebugMessage(DEBUG_STREAM_STATE, "seq is within window!\n");
00595 }
00596 else
00597 {
00598 DebugMessage(DEBUG_STREAM_STATE, "seq is past the end of the window!\n");
00599 valid_seq = false;
00600 }
00601 }
00602 else
00603 {
00604 DebugMessage(DEBUG_STREAM_STATE, "end_seq is before win_base\n");
00605 valid_seq = false;
00606 }
00607
00608 if ( !valid_seq )
00609 {
00610 inc_tcp_discards();
00611 normalizer->trim_win_payload(tsd);
00612 }
00613
00614 return valid_seq;
00615 }
00616
00617 void TcpTracker::print()
00618 {
00619 LogMessage(" + TcpTracker +\n");
00620 LogMessage(" state: %s\n", tcp_state_names[ tcp_state ]);
00621 LogMessage(" iss: 0x%X\n", iss);
00622 LogMessage(" ts_last: %u\n", ts_last);
00623 LogMessage(" wscale: %u\n", wscale);
00624 LogMessage(" mss: 0x%08X\n", mss);
00625 LogMessage(" snd_una: %X\n", snd_una);
00626 LogMessage(" snd_nxt: %X\n", snd_nxt);
00627 LogMessage(" snd_win: %u\n", snd_wnd);
00628 LogMessage(" rcv_nxt: %X\n", rcv_nxt);
00629 LogMessage(" r_win_base: %X\n", r_win_base);
00630 }
00631
END OF CODE