#include "detection/detection_engine.h"
#include "main/snort_config.h"
-#include "main/snort_debug.h"
#include "managers/inspector_manager.h"
#include "memory/memory_cap.h"
#include "packet_io/active.h"
if ( ignore )
{
- DebugFormat(DEBUG_STREAM_STATE,
- "Stream: Ignoring packet from %s. Marking flow marked as ignore.\n",
- (p->packet_flags & PKT_FROM_CLIENT) ? "sender" : "responder");
-
flow->ssn_state.ignore_direction = ignore;
DetectionEngine::disable_all(p);
}
// this env var uses the upper 32 bits of the flags:
#define DEBUG_PLUGIN "SNORT_PP_DEBUG"
-#define DEBUG_FRAG 0x0000000100000000LL
#define DEBUG_STREAM 0x0000000200000000LL
-#define DEBUG_STREAM_STATE 0x0000000400000000LL
-#define DEBUG_STREAM_PAF 0x0000000800000000LL
#define DEBUG_CODEC 0x0001000000000000LL
#define DEBUG_IPS_ACTION 0x0004000000000000LL
#include "binder/binder.h"
#include "flow/flow_key.h"
-#include "main/snort_debug.h"
#include "managers/inspector_manager.h"
#include "stream/stream.h"
bool StreamHAClient::consume(Flow*& flow, FlowKey* key, HAMessage* msg)
{
- DebugMessage(DEBUG_HA,"StreamHAClient::consume()\n");
-
assert(key);
assert(msg);
bool StreamHAClient::produce(Flow* flow, HAMessage* msg)
{
- DebugMessage(DEBUG_HA,"StreamHAClient::produce()\n");
assert(flow);
assert(msg);
bool StreamHAClient::is_update_required(Flow* flow)
{
- DebugMessage(DEBUG_HA,"StreamHAClient::update_required()\n");
-
assert(flow);
assert(flow->ha_state);
bool StreamHAClient::is_delete_required(Flow*)
{
- DebugMessage(DEBUG_HA,"StreamHAClient::update_required()\n");
return true;
}
ProtocolHA::ProtocolHA(PktType protocol)
{
- DebugFormat(DEBUG_HA,"ProtocolHA::ProtocolHA(): protocol: %d\n",(int)protocol);
-
if ( proto_map == nullptr )
proto_map = new ProtocolMap;
if (ssn)
{
/* Mark this session as dead. */
- DebugMessage(DEBUG_STREAM_STATE,
- "Marking session as dead, per ICMP Unreachable!\n");
ssn->ssn_state.session_flags |= SSNFLAG_DROP_CLIENT;
ssn->ssn_state.session_flags |= SSNFLAG_DROP_SERVER;
ssn->session_state |= STREAM_STATE_UNREACH;
trace_log(stream_ip,
"[^^] Walking fraglist:\n");
- DebugMessage(DEBUG_FRAG,
- "[^^] Walking fraglist:\n");
}
/*
{
if ( p->is_from_client() )
{
- DebugMessage(DEBUG_STREAM_STATE,
- "Stream: Updating on packet from client\n");
-
lws->ssn_state.session_flags |= SSNFLAG_SEEN_CLIENT;
}
else
{
- DebugMessage(DEBUG_STREAM_STATE,
- "Stream: Updating on packet from server\n");
-
lws->ssn_state.session_flags |= SSNFLAG_SEEN_SERVER;
}
if ( (lws->ssn_state.session_flags & SSNFLAG_SEEN_CLIENT) &&
(lws->ssn_state.session_flags & SSNFLAG_SEEN_SERVER) )
{
- DebugMessage(DEBUG_STREAM_STATE,
- "Stream: session established!\n");
-
lws->ssn_state.session_flags |= SSNFLAG_ESTABLISHED;
lws->set_ttl(p, false);
bool IpSession::setup(Packet* p)
{
- DebugMessage(DEBUG_STREAM, "Stream IP session created!\n");
-
SESSION_STATS_ADD(ip_stats);
memset(&tracker, 0, sizeof(tracker));
#include "tcp_segment_descriptor.h"
#include "detection/rules.h"
-#include "main/snort_debug.h"
#include "protocols/tcp_options.h"
#include "stream/tcp/tcp_defs.h"
uint32_t TcpSegmentDescriptor::init_mss(uint16_t* value)
{
- DebugMessage(DEBUG_STREAM_STATE, "Getting MSS...\n");
-
tcp::TcpOptIterator iter(tcph, pkt);
for ( const tcp::TcpOption& opt : iter )
{
if ( opt.code == tcp::TcpOptCode::MAXSEG )
{
*value = extract_16bits(opt.data);
- DebugFormat(DEBUG_STREAM_STATE, "Found MSS %hu\n", *value);
return TF_MSS;
}
}
*value = 0;
- DebugMessage(DEBUG_STREAM_STATE, "No MSS...\n");
-
return TF_NONE;
}
uint32_t TcpSegmentDescriptor::init_wscale(uint16_t* value)
{
- DebugMessage(DEBUG_STREAM_STATE, "Getting wscale...\n");
-
tcp::TcpOptIterator iter(tcph, pkt);
for (const tcp::TcpOption& opt : iter)
if (opt.code == tcp::TcpOptCode::WSCALE)
{
*value = (uint16_t)opt.data[0];
- DebugFormat(DEBUG_STREAM_STATE, "Found wscale %d\n", *value);
// If scale specified in option is larger than 14, use 14 because of limitation
// in the math of shifting a 32bit value (max scaled window is 2^30th).
}
*value = 0;
- DebugMessage(DEBUG_STREAM_STATE, "No wscale...\n");
return TF_NONE;
}
{
uint16_t wscale;
- DebugMessage(DEBUG_STREAM_STATE, "Checking for wscale...\n");
-
if ( !(pkt->ptrs.decode_flags & DECODE_WSCALE) )
return false;
#include <iostream>
-#include "main/snort_debug.h"
#include "tcp_segment_descriptor.h"
#include "tcp_state_machine.h"
#include "tcp_stream_session.h"
#include "log/messages.h"
-#include "main/snort_debug.h"
#include "stream/tcp/tcp_ha.h"
using namespace snort;
void TcpStreamSession::update_session_on_server_packet(TcpSegmentDescriptor& tsd)
{
- DebugMessage(DEBUG_STREAM_STATE, "Stream: Updating on packet from server\n");
-
flow->set_session_flags(SSNFLAG_SEEN_SERVER);
talker = &server;
listener = &client;
void TcpStreamSession::update_session_on_client_packet(TcpSegmentDescriptor& tsd)
{
- DebugMessage(DEBUG_STREAM_STATE, "Stream: Updating on packet from client\n");
-
/* if we got here we had to see the SYN already... */
flow->set_session_flags(SSNFLAG_SEEN_CLIENT);
talker = &client;
{
Profile profile(s5TcpNewSessPerfStats);
- DebugMessage(DEBUG_STREAM_STATE, "Creating new session tracker on SYN_ACK!\n");
-
tsd.get_flow()->set_session_flags(SSNFLAG_SEEN_SERVER);
if (tsd.get_tcph()->are_flags_set(TH_CWR | TH_ECE))
tsd.get_flow()->set_session_flags(SSNFLAG_ECN_SERVER_REPLY);
}
else
{
- DebugFormat(DEBUG_STREAM_STATE,
- "Pkt Ack is Out of Bounds (%X, %X, %X) = (snd_una, snd_nxt, cur)\n",
- snd_una, snd_nxt, tsd.get_seg_ack());
inc_tcp_discards();
normalizer.trim_win_payload(tsd);
good_ack = false;
{
Flow* flow = tsd.get_flow();
- DebugMessage(DEBUG_STREAM_STATE, "Received Valid RST, bailing\n");
flow->set_session_flags(SSNFLAG_RESET);
if ( normalizer.is_tcp_ips_enabled() )
tcp_state = TcpStreamTracker::TCP_CLOSED;
}
else
{
- DebugMessage(DEBUG_STREAM_STATE, "Received RST with bad sequence number, bailing\n");
inc_tcp_discards();
normalizer.packet_dropper(tsd, NORM_TCP_BLOCK);
good_rst = false;
{
if ( SEQ_LT(tsd.get_end_seq(), r_win_base) )
{
- DebugMessage(DEBUG_STREAM_STATE, "FIN inside r_win_base, bailing\n");
return false;
}
int right_ok;
uint32_t left_seq;
- DebugFormat(DEBUG_STREAM_STATE,
- "Checking end_seq (%X) > r_win_base (%X) && seq (%X) < r_nxt_ack(%X)\n",
- tsd.get_end_seq(), r_win_base, tsd.get_seg_seq(),
- r_nxt_ack + normalizer.get_stream_window(tsd));
-
if ( SEQ_LT(r_nxt_ack, r_win_base) )
left_seq = r_nxt_ack;
else
if ( SEQ_LEQ(tsd.get_seg_seq(), r_win_base + win) )
{
- DebugMessage(DEBUG_STREAM_STATE, "seq is within window!\n");
+ return true;
}
else
{
- DebugMessage(DEBUG_STREAM_STATE, "seq is past the end of the window!\n");
valid_seq = false;
}
}
else
{
- DebugMessage(DEBUG_STREAM_STATE, "end_seq is before win_base\n");
valid_seq = false;
}
#include "paf.h"
-#include "main/snort_debug.h"
#include "protocols/packet.h"
using namespace snort;
uint32_t at = 0;
*flags &= ~(PKT_PDU_HEAD | PKT_PDU_TAIL);
- DebugFormat(DEBUG_STREAM_PAF,
- "%s: type=%d, fpt=%u, len=%u, tot=%u\n",
- __func__, px.ft, ps->fpt, px.len, ps->tot);
-
switch ( px.ft )
{
case FT_NOP:
StreamSplitter* ss, PAF_State* ps, PafAux& px, Flow* ssn,
uint32_t flags, const uint8_t* data, uint32_t len)
{
- DebugFormat(DEBUG_STREAM_PAF,
- "%s: paf=%d, idx=%u, len=%u, fpt=%u\n",
- __func__, ps->paf, px.idx, px.len, ps->fpt);
-
uint16_t fuzz = 0; // FIXIT-L PAF add a little zippedy-do-dah
switch ( ps->paf )
const uint8_t* data, uint32_t len, uint32_t total,
uint32_t seq, uint32_t* flags)
{
- DebugFormat(DEBUG_STREAM_PAF,
- "%s: len=%u, amt=%u, seq=%u, cur=%u, pos=%u, fpt=%u, tot=%u, paf=%d\n",
- __func__, len, total, seq, ps->seq, ps->pos, ps->fpt, ps->tot, ps->paf);
-
PafAux px;
if ( !paf_initialized(ps) )
#include "flow/prune_stats.h"
#include "main/snort.h"
#include "main/snort_config.h"
-#include "main/snort_debug.h"
#include "packet_io/active.h"
#include "protocols/vlan.h"
#include "stream/base/stream_module.h"
((p->is_from_client()) &&
(flow->ssn_state.session_flags & SSNFLAG_DROP_CLIENT)) )
{
- DebugFormat(DEBUG_STREAM_STATE,
- "Blocking %s packet as session was blocked\n",
- p->is_from_server() ? "server" : "client");
-
DetectionEngine::disable_content(p);
Active::drop_packet(p);
active_response(p, flow);
((p->is_from_client()) &&
(flow->ssn_state.ignore_direction & SSN_DIR_FROM_SERVER)) )
{
- DebugFormat(DEBUG_STREAM_STATE,
- "Stream Ignoring packet from %s. Session marked as ignore\n",
- p->is_from_client() ? "sender" : "responder");
-
DetectionEngine::disable_all(p);
return true;
}
if ( (flow->session_state & STREAM_STATE_TIMEDOUT)
|| StreamExpire(p, flow) )
{
- DebugMessage(DEBUG_STREAM, "Stream IP session timeout!\n");
flow->ssn_state.session_flags |= SSNFLAG_TIMEDOUT;
return true;
}
assert(SEQ_LEQ(trs.sos.seq, trs.sos.right->seq));
trs.sos.overlap = ( int )( trs.sos.seq_end - trs.sos.right->seq );
- DebugFormat(DEBUG_STREAM_STATE, "right overlap(%d): len: %d right->seq: 0x%X seq: 0x%X\n",
- trs.sos.overlap, trs.sos.len, trs.sos.right->seq, trs.sos.seq);
-
// 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());
void SegmentOverlapEditor::drop_old_segment(TcpReassemblerState& trs)
{
- DebugFormat(DEBUG_STREAM_STATE,
- "full right overlap, dropping old segment at seq %u, size %hu\n",
- trs.sos.right->seq, trs.sos.right->payload_size);
-
TcpSegmentNode* drop_seg = trs.sos.right;
trs.sos.right = trs.sos.right->next;
delete_reassembly_segment(trs, drop_seg);
int SegmentOverlapEditor::left_overlap_keep_first(TcpReassemblerState& trs)
{
- DebugFormat(DEBUG_STREAM_STATE, "left overlap %d\n", trs.sos.overlap);
-
// 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->seq));
tcpStats.overlaps++;
trs.sos.overlap_count++;
- DebugMessage(DEBUG_STREAM_STATE, "left overlap, honoring old data\n");
-
if ( SEQ_GT(trs.sos.left->seq + trs.sos.left->payload_size, trs.sos.seq_end) )
{
if (trs.sos.tcp_ips_data == NORM_MODE_ON)
int SegmentOverlapEditor::left_overlap_trim_first(TcpReassemblerState& trs)
{
- DebugFormat(DEBUG_STREAM_STATE, "left overlap %d\n", trs.sos.overlap);
assert(SEQ_GT(trs.sos.seq, trs.sos.left->seq));
trs.sos.len = trs.sos.tsd->get_seg_len();
if ( SEQ_GEQ(trs.sos.left->seq + trs.sos.left->payload_size, trs.sos.seq + trs.sos.len) )
{
// existing packet overlaps new on both sides. Drop the new data.
- DebugMessage(DEBUG_STREAM_STATE, "left overlap, honoring old data\n");
trs.sos.seq += trs.sos.len;
}
else
/* Otherwise, trim the old data accordingly */
trs.sos.left->payload_size -= ( int16_t )trs.sos.overlap;
trs.sos.seg_bytes_logical -= trs.sos.overlap;
- DebugMessage(DEBUG_STREAM_STATE, "left overlap, honoring new data\n");
}
}
int SegmentOverlapEditor::left_overlap_keep_last(TcpReassemblerState& trs)
{
- DebugFormat(DEBUG_STREAM_STATE, "left overlap %d\n", trs.sos.overlap);
assert(SEQ_GT(trs.sos.seq, trs.sos.left->seq));
trs.sos.len = trs.sos.tsd->get_seg_len();
void SegmentOverlapEditor::right_overlap_truncate_existing(TcpReassemblerState& trs)
{
- DebugMessage(DEBUG_STREAM_STATE, "Got partial right overlap\n");
if ( SEQ_EQ(trs.sos.right->seq, trs.sos.seq) && ( trs.sos.reassembly_policy != ReassemblyPolicy::OS_LAST ) )
{
trs.sos.slide = ( trs.sos.right->seq + trs.sos.right->payload_size - trs.sos.seq );
// REASSEMBLY_POLICY_VISTA:
int SegmentOverlapEditor::full_right_overlap_truncate_new(TcpReassemblerState& trs)
{
- DebugMessage(DEBUG_STREAM_STATE, "Got full right overlap, truncating new\n");
-
if ( trs.sos.tcp_ips_data == NORM_MODE_ON )
{
unsigned offset = trs.sos.right->seq - trs.sos.tsd->get_seg_seq();
{
tcpStats.internalEvents++;
snort::DetectionEngine::queue_event(GENERATOR_INTERNAL, eventSid);
- DebugFormat(DEBUG_STREAM, "Stream raised internal event %u\n", eventSid);
}
}
#include "tcp_ha.h"
-#include "main/snort_debug.h"
#include "stream/stream.h"
#include "tcp_session.h"
void TcpHA::deactivate_session(Flow* flow)
{
- DebugMessage(DEBUG_HA,"TcpHA::deactivate_session)\n");
assert( flow );
if ( flow->session )
((TcpSession*)(flow->session))->clear_session(true, true, false);
#include "stream/libtcp/tcp_stream_session.h"
#include "stream/libtcp/tcp_stream_tracker.h"
-#include "main/snort_debug.h"
#include "packet_io/active.h"
using namespace snort;
uint32_t TcpNormalizer::get_tcp_timestamp(
TcpNormalizerState& tns, TcpSegmentDescriptor& tsd, bool strip)
{
- DebugMessage(DEBUG_STREAM_STATE, "Getting timestamp...\n");
-
tcp::TcpOptIterator iter(tsd.get_tcph(), tsd.get_pkt() );
// using const because non-const is not supported
if (!stripped)
{
tsd.set_ts(extract_32bits(opt.data) );
- DebugFormat(DEBUG_STREAM_STATE, "Found timestamp %u\n", tsd.get_ts());
return TF_TSTAMP;
}
}
}
tsd.set_ts(0);
- DebugMessage(DEBUG_STREAM_STATE, "No timestamp...\n");
-
return TF_NONE;
}
bool TcpNormalizer::validate_rst_seq_geq(
TcpNormalizerState& tns, TcpSegmentDescriptor& tsd)
{
- DebugFormat(DEBUG_STREAM_STATE,
- "Checking end_seq (%X) > r_win_base (%X) && seq (%X) < r_nxt_ack(%X)\n",
- tsd.get_end_seq(), tns.tracker->r_win_base, tsd.get_seg_seq(), tns.tracker->r_nxt_ack +
- get_stream_window(tns, tsd));
-
// FIXIT-H check for r_win_base == 0 is hack for uninitialized r_win_base, fix this
if ( ( tns.tracker->r_nxt_ack == 0 ) || SEQ_GEQ(tsd.get_seg_seq(), tns.tracker->r_nxt_ack) )
{
- DebugMessage(DEBUG_STREAM_STATE, "rst is valid seq (>= next seq)!\n");
return true;
}
- DebugMessage(DEBUG_STREAM_STATE, "rst is not valid seq (>= next seq)!\n");
return false;
}
bool TcpNormalizer::validate_rst_end_seq_geq(
TcpNormalizerState& tns, TcpSegmentDescriptor& tsd)
{
- DebugFormat(DEBUG_STREAM_STATE,
- "Checking end_seq (%X) > r_win_base (%X) && seq (%X) < r_nxt_ack(%X)\n",
- tsd.get_end_seq(), tns.tracker->r_win_base, tsd.get_seg_seq(), tns.tracker->r_nxt_ack +
- get_stream_window(tns, tsd));
-
// FIXIT-H check for r_win_base == 0 is hack for uninitialized r_win_base, fix this
if ( tns.tracker->r_win_base == 0 )
return true;
// reset must be admitted when window closed
if (SEQ_LEQ(tsd.get_seg_seq(), tns.tracker->r_win_base + get_stream_window(tns, tsd)))
{
- DebugMessage(DEBUG_STREAM_STATE, "rst is valid seq (within window)!\n");
return true;
}
}
- DebugMessage(DEBUG_STREAM_STATE, "rst is not valid seq (within window)!\n");
return false;
}
bool TcpNormalizer::validate_rst_seq_eq(
TcpNormalizerState& tns, TcpSegmentDescriptor& tsd)
{
- DebugFormat(DEBUG_STREAM_STATE,
- "Checking end_seq (%X) > r_win_base (%X) && seq (%X) < r_nxt_ack(%X)\n",
- tsd.get_end_seq(), tns.tracker->r_win_base, tsd.get_seg_seq(),
- tns.tracker->r_nxt_ack + get_stream_window(tns, tsd));
-
// FIXIT-H check for r_nxt_ack == 0 is hack for uninitialized r_nxt_ack, fix this
if ( ( tns.tracker->r_nxt_ack == 0 ) || SEQ_EQ(tsd.get_seg_seq(), tns.tracker->r_nxt_ack) )
{
- DebugMessage(DEBUG_STREAM_STATE, "rst is valid seq (next seq)!\n");
return true;
}
- DebugMessage(DEBUG_STREAM_STATE, "rst is not valid seq (next seq)!\n");
return false;
}
{
if ( ( (int)( ( tsd.get_ts() - tns.peer_tracker->get_ts_last() ) + tns.paws_ts_fudge ) ) < 0 )
{
- DebugMessage(DEBUG_STREAM_STATE, "Packet outside PAWS window, dropping\n");
/* bail, we've got a packet outside the PAWS window! */
//inc_tcp_discards();
tns.session->tel.set_tcp_event(EVENT_BAD_TIMESTAMP);
PAWS_24DAYS ) )
{
/* this packet is from way too far into the future */
- DebugFormat(DEBUG_STREAM_STATE,
- "packet PAWS timestamp way too far ahead of last packet %ld %u...\n",
- tsd.get_pkt()->pkth->ts.tv_sec, tns.peer_tracker->get_ts_last_packet() );
//inc_tcp_discards();
tns.session->tel.set_tcp_event(EVENT_BAD_TIMESTAMP);
packet_dropper(tns, tsd, NORM_TCP_OPT);
}
else
{
- DebugMessage(DEBUG_STREAM_STATE, "packet PAWS ok...\n");
return ACTION_NOTHING;
}
}
// we've got a packet with no timestamp, but 3whs indicated talker was doing
// timestamps. This breaks protocol, however, some servers still ack the packet
// with the missing timestamp. Log an alert, but continue to process the packet
- DebugMessage(DEBUG_STREAM_STATE,
- "packet no timestamp, had one earlier from this side...ok for now...\n");
tns.session->tel.set_tcp_event(EVENT_NO_TIMESTAMP);
/* Ignore the timestamp for this first packet, next one will checked. */
if ( ( tns.paws_drop_zero_ts && ( tsd.get_ts() == 0 ) ) &&
( tns.tracker->get_tf_flags() & TF_TSTAMP ) )
{
- DebugMessage(DEBUG_STREAM_STATE, "Packet with 0 timestamp, dropping\n");
tns.session->tel.set_tcp_event(EVENT_BAD_TIMESTAMP);
return ACTION_BAD_PKT;
}
if ((tns.peer_tracker->get_tf_flags() & TF_TSTAMP) &&
(tns.tracker->get_tf_flags() & TF_TSTAMP))
{
- DebugMessage(DEBUG_STREAM_STATE, "Checking timestamps for PAWS\n");
return validate_paws(tns, tsd);
}
else if (tsd.get_tcph()->is_syn_only())
*/
if (SEQ_EQ(tsd.get_seg_seq(), listener->r_nxt_ack))
{
- DebugMessage(DEBUG_STREAM_STATE,
- "Got syn on established windows ssn, which causes Reset, bailing\n");
session->flow->set_session_flags(SSNFLAG_RESET);
talker->set_tcp_state(TcpStreamTracker::TCP_CLOSED);
return ACTION_RST;
}
else
{
- DebugMessage(DEBUG_STREAM_STATE,
- "Got syn on established windows ssn, not causing Reset, bailing\n");
inc_tcp_discards();
return ACTION_NOTHING;
}
/* If its not a retransmission of the actual SYN... RESET */
if (!SEQ_EQ(tsd.get_seg_seq(), talker->get_iss()))
{
- DebugMessage(DEBUG_STREAM_STATE,
- "Got syn on established ssn, which causes Reset, bailing\n");
session->flow->set_session_flags(SSNFLAG_RESET);
talker->set_tcp_state(TcpStreamTracker::TCP_CLOSED);
return ACTION_RST;
}
else
{
- DebugMessage(DEBUG_STREAM_STATE,
- "Got syn on established ssn, not causing Reset, bailing\n");
inc_tcp_discards();
return ACTION_NOTHING;
}
TcpNormalizerState&, TcpSegmentDescriptor&)
{
/* MACOS ignores a 2nd SYN, regardless of the sequence number. */
- DebugMessage(DEBUG_STREAM_STATE,
- "Got syn on established macos ssn, not causing Reset, bailing\n");
inc_tcp_discards();
return ACTION_NOTHING;
}
}
bool TcpNormalizerProxy::validate_rst(
- TcpNormalizerState& tns, TcpSegmentDescriptor& tsd)
-{
-#ifndef DEBUG_MSGS
- UNUSED(tsd);
-#endif
-
- // FIXIT-L will session->flow ever be null? convert to assert if possible
- if ( tns.session->flow )
- {
- DebugFormat(DEBUG_STREAM_STATE,
- "Proxy Normalizer - Not Valid\n end_seq (%X) > r_win_base (%X) && seq (%X) < r_nxt_ack(%X)\n",
- tsd.get_end_seq(), tns.tracker->r_win_base, tsd.get_seg_seq(), tns.tracker->r_nxt_ack +
- get_stream_window(tns, tsd));
- }
+ TcpNormalizerState&, TcpSegmentDescriptor&)
+{
return false;
}
int ret;
assert(tsn);
- DebugFormat(DEBUG_STREAM_STATE, "Dropping segment at seq %X, len %d\n", tsn->seq,
- tsn->payload_size);
-
if (tsn->prev)
tsn->prev->next = tsn->next;
else
if (delta < tsn->payload_size)
{
- DebugFormat(DEBUG_STREAM_STATE, "Left-Trimming segment at seq %X, len %d, delta %u\n",
- tsn->seq, tsn->payload_size, delta);
-
tsn->seq = flush_seq;
tsn->payload_size -= (uint16_t)delta;
trs.sos.seg_bytes_logical -= delta;
bool TcpReassembler::is_segment_fasttrack(
TcpReassemblerState&, TcpSegmentNode* tail, TcpSegmentDescriptor& tsd)
{
- DebugFormat(DEBUG_STREAM_STATE, "Checking seq for fast track: %X > %X\n",
- tsd.get_seg_seq(), tail->seq + tail->payload_size);
-
if ( SEQ_EQ(tsd.get_seg_seq(), tail->seq + tail->payload_size) )
return true;
//assert(newSize == 0);
// zero size data because of trimming. Don't insert it
- DebugFormat(DEBUG_STREAM_STATE, "zero size TCP data after left & right trimming "
- "(len: %hd slide: %u trunc: %u)\n", len, slide, trunc_len);
inc_tcp_discards();
trs.tracker->normalizer.trim_win_payload(tsd);
trs.sos.total_bytes_queued += tsn->payload_size;
tsd.get_pkt()->packet_flags |= PKT_STREAM_INSERT;
- DebugFormat(DEBUG_STREAM_STATE,
- "added %hu bytes on segment list @ seq: 0x%X, total %u, %u segments queued\n",
- tsn->payload_size, tsn->seq, trs.sos.seg_bytes_logical,
- get_pending_segment_count(trs, 0));
#ifdef SEG_TEST
CheckSegments(trs.tracker);
queue_reassembly_segment(trs, left, tsn);
- DebugFormat(DEBUG_STREAM_STATE,
- "added %hu bytes on segment list @ seq: 0x%X, total %u, %u segments queued\n",
- tsn->payload_size, tsn->seq, trs.sos.seg_bytes_logical,
- get_pending_segment_count(trs, 0));
-
*retSeg = tsn;
return STREAM_INSERT_OK;
}
int purged_bytes = 0;
uint32_t last_ts = 0;
- DebugFormat(DEBUG_STREAM_STATE, "In purge_to_seq, start seq = 0x%X end seq = 0x%X delta %u\n",
- tsn->seq, flush_seq, flush_seq-tsn->seq);
-
while ( tsn )
{
- DebugFormat(DEBUG_STREAM_STATE, "s: %X sz: %d\n", tsn->seq, tsn->payload_size);
dump_me = tsn;
tsn = tsn->next;
if ( SEQ_LT(trs.sos.seglist_base_seq, flush_seq) )
{
// FIXIT-M these lines are out of code coverage. Is this even possible?
- DebugFormat(DEBUG_STREAM_STATE, "setting seglist_base_seq to 0x%X\n", flush_seq);
trs.sos.seglist_base_seq = flush_seq;
}
uint32_t bytes_flushed = 0;
uint32_t segs = 0;
uint32_t flags = PKT_PDU_HEAD;
- DEBUG_WRAP(uint32_t bytes_queued = trs.sos.seg_bytes_logical; );
assert(trs.sos.seglist.next);
Profile profile(s5TcpBuildPacketPerfStats);
unsigned bytes_copied = 0;
assert(bytes_to_copy);
- DebugFormat(DEBUG_STREAM_STATE, "Flushing %u bytes from %X\n", bytes_to_copy, tsn->seq);
-
if ( !tsn->next or (bytes_to_copy < tsn->payload_size) or
SEQ_EQ(tsn->seq + bytes_to_copy, to_seq) or
(bytes_flushed + tsn->payload_size + tsn->next->payload_size >
break;
}
- DEBUG_WRAP(bytes_queued -= bytes_flushed; );
- DebugFormat(DEBUG_STREAM_STATE,
- "flushed %u bytes / %u segs on stream, %u bytes still queued\n",
- bytes_flushed, segs, bytes_queued);
-
return bytes_flushed;
}
p = pdu;
}
- DebugFormat(DEBUG_STREAM_STATE, "Attempting to flush %u bytes\n", bytes);
-
uint32_t bytes_processed = 0;
uint32_t stop_seq = trs.sos.seglist.next->seq + bytes;
tcpStats.rebuilt_buffers++; // FIXIT-L this is not accurate
}
- DebugFormat(DEBUG_STREAM_STATE, "setting trs.sos.seglist_base_seq to 0x%X\n",
- trs.sos.seglist_base_seq);
-
// FIXIT-L must check because above may clear trs.sos.session
if ( trs.tracker->splitter )
trs.tracker->splitter->update();
{
if ( !bytes || !trs.sos.seglist.next )
{
- DebugFormat(DEBUG_STREAM_STATE, "bailing: no bytes: %u or empty trs.sos.seglist: %p\n",
- bytes, (void*)trs.sos.seglist.next);
return 0;
}
if ( !flush_data_ready(trs) and !(trs.tracker->get_tf_flags() & TF_FORCE_FLUSH) and
!trs.tracker->splitter->is_paf() )
{
- DebugMessage(DEBUG_STREAM_STATE, "only 1 packet in trs.sos.seglist no need to flush\n");
return 0;
}
{
uint32_t flushed = 0;
- DebugMessage(DEBUG_STREAM_STATE, "In CheckFlushPolicyOnData\n");
- DebugFormat(DEBUG_STREAM_STATE, "Listener flush policy: %s\n",
- flush_policy_names[ trs.tracker->flush_policy ]);
-
switch ( trs.tracker->flush_policy )
{
case STREAM_FLPOLICY_IGNORE:
- DebugMessage(DEBUG_STREAM_STATE, "STREAM_FLPOLICY_IGNORE\n");
return 0;
case STREAM_FLPOLICY_ON_ACK:
{
uint32_t flushed = 0;
- DebugMessage(DEBUG_STREAM_STATE, "In CheckFlushPolicyOnAck\n");
- DebugFormat(DEBUG_STREAM_STATE, "Talker flush policy: %s\n",
- flush_policy_names[ trs.tracker->flush_policy ]);
-
switch (trs.tracker->flush_policy)
{
case STREAM_FLPOLICY_IGNORE:
- DebugMessage(DEBUG_STREAM_STATE, "STREAM_FLPOLICY_IGNORE\n");
return 0;
case STREAM_FLPOLICY_ON_ACK:
if ( SEQ_GT(trs.tracker->r_win_base, seq) )
{
- DebugMessage(DEBUG_STREAM_STATE, "segment overlaps ack'd data...\n");
overlap = trs.tracker->r_win_base - tsd.get_seg_seq();
if ( overlap >= tsd.get_seg_len() )
{
- DebugMessage(DEBUG_STREAM_STATE, "full overlap on ack'd data, dropping segment\n");
return;
}
}
add_reassembly_segment(
trs, tsd, tsd.get_seg_len(), overlap, 0, tsd.get_seg_seq() + overlap, nullptr);
- DebugFormat(DEBUG_STREAM_STATE,
- "Attached new queue to trs.sos.seglist, %u bytes queued, base_seq 0x%X\n",
- tsd.get_seg_len() - overlap, trs.sos.seglist_base_seq);
}
void TcpReassembler::init_overlap_editor(
int32_t dist_head;
int32_t dist_tail;
- DEBUG_WRAP(
- TcpSegmentNode *lastptr = nullptr;
- uint32_t base_seq = trs.sos.seglist_base_seq;
- int last = 0;
- );
-
if ( trs.sos.seglist.head && trs.sos.seglist.tail )
{
if ( SEQ_GT(tsd.get_seg_seq(), trs.sos.seglist.head->seq) )
{
for ( tsn = trs.sos.seglist.head; tsn; tsn = tsn->next )
{
- DEBUG_WRAP(
- DebugFormat(DEBUG_STREAM_STATE, "tsn: %p seq: 0x%X size: %hu delta: %u\n",
- (void*) tsn, tsn->seq, tsn->payload_size, ( tsn->seq - base_seq ) - last);
-
- last = tsn->seq - base_seq;
- lastptr = tsn;
-
- DebugFormat(DEBUG_STREAM_STATE, " lastptr: %p tsn->next: %p tsn->prev: %p\n",
- (void*) lastptr, (void*) tsn->next, (void*) tsn->prev);
- );
-
right = tsn;
if ( SEQ_GEQ(right->seq, tsd.get_seg_seq() ) )
{
for ( tsn = trs.sos.seglist.tail; tsn; tsn = tsn->prev )
{
- DEBUG_WRAP(
- DebugFormat(DEBUG_STREAM_STATE, "tsn: %p seq: 0x%X size: %hu delta: %u\n",
- (void*) tsn, tsn->seq, tsn->payload_size, ( tsn->seq - base_seq ) - last);
-
- last = tsn->seq - base_seq;
- lastptr = tsn;
-
- DebugFormat(DEBUG_STREAM_STATE, " lastptr: %p tsn->next: %p tsn->prev: %p\n",
- (void*) lastptr, (void*) tsn->next, (void*) tsn->prev);
- );
-
left = tsn;
if ( SEQ_LT(left->seq, tsd.get_seg_seq() ) )
left = nullptr;
}
- DebugMessage(DEBUG_STREAM_STATE, "!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+\n");
- DebugMessage(DEBUG_STREAM_STATE, "!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+\n");
-
- DebugFormat(DEBUG_STREAM_STATE, "left: %p:0x%X right: %p:0x%X\n",
- (void*) left, left ? left->seq : 0, (void*) right, right ? right->seq : 0);
trs.sos.init_soe(tsd, left, right);
}
{
int rc = STREAM_INSERT_OK;
- DebugFormat(DEBUG_STREAM_STATE,
- "Queuing %u bytes on stream!\nbase_seq: %X seq: %X seq_end: %X\n",
- tsd.get_end_seq() - tsd.get_seg_seq(), trs.sos.seglist_base_seq, tsd.get_seg_seq(),
- tsd.get_end_seq());
-
- DebugFormat(DEBUG_STREAM_STATE, "%u segments on trs.sos.seglist\n",
- get_pending_segment_count(trs, 0));
-
- DebugMessage(DEBUG_STREAM_STATE, "!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+\n");
- DebugMessage(DEBUG_STREAM_STATE, "!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+!+\n");
-
// 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 */
TcpSegmentNode* left = trs.sos.seglist.tail;
-
- DebugFormat(DEBUG_STREAM_STATE, "Fast tracking segment! (tail_seq %X size %d)\n",
- trs.sos.seglist.tail->seq, trs.sos.seglist.tail->payload_size);
-
+
// BLOCK add to existing block and/or allocate new block
rc = add_reassembly_segment(trs, tsd, tsd.get_seg_len(), 0, 0, tsd.get_seg_seq(), left);
return rc;
}
else
{
- DebugMessage(DEBUG_STREAM_STATE, "Fully truncated right overlap\n");
rc = STREAM_INSERT_OK;
}
using namespace snort;
-#ifdef DEBUG_MSGS
-static THREAD_LOCAL const char* t_name = nullptr;
-static THREAD_LOCAL const char* l_name = nullptr;
-#endif
-
TcpSession::TcpSession(Flow* flow)
: TcpStreamSession(flow)
{
{
if ( listener->flush_policy == STREAM_FLPOLICY_IGNORE )
{
- DebugMessage(DEBUG_STREAM_STATE, "Ignoring segment due to IGNORE flush_policy\n");
return true;
}
void TcpSession::process_tcp_stream(TcpSegmentDescriptor& tsd)
{
- DebugFormat(DEBUG_STREAM_STATE, "In ProcessTcpStream(), %d bytes to queue\n",
- tsd.get_seg_len());
-
if (tsd.get_pkt()->packet_flags & PKT_IGNORE)
return;
if ( flow_exceeds_config_thresholds(tsd) )
return;
- DebugMessage(DEBUG_STREAM_STATE, "queuing segment\n");
listener->reassembler.queue_packet_for_reassembly(tsd);
// Alert if overlap limit exceeded
else
{
- DebugMessage(DEBUG_STREAM_STATE, "Bailing, data on SYN, not MAC Policy!\n");
listener->normalizer.trim_syn_payload(tsd);
return STREAM_UNALIGNED;
} }
if (config->policy != StreamPolicy::OS_PROXY
and listener->normalizer.get_stream_window(tsd) == 0)
{
- DebugMessage(DEBUG_STREAM_STATE, "Bailing, we're out of the window!\n");
listener->normalizer.trim_win_payload(tsd);
return STREAM_UNALIGNED;
}
// original data. Let the reassembly policy decide how to handle the overlapping data.
// See HP, Solaris, et al. for those that favor duplicate data over the original in
// some cases.
- DebugFormat(DEBUG_STREAM_STATE,
- "out of order segment (tsd.seq: 0x%X l->r_nxt_ack: 0x%X!\n",
- tsd.get_seg_seq(), listener->r_nxt_ack);
/* check if we're in the window */
if (config->policy != StreamPolicy::OS_PROXY
and listener->normalizer.get_stream_window(tsd) == 0)
{
- DebugMessage(DEBUG_STREAM_STATE, "Bailing, we're out of the window!\n");
listener->normalizer.trim_win_payload(tsd);
return STREAM_UNALIGNED;
}
|| ( talker->get_tcp_state() == TcpStreamTracker::TCP_CLOSED ) )
{
// Listener previously issued a reset Talker is re-SYN-ing
- DebugMessage(DEBUG_STREAM_STATE, "Got SYN pkt on reset ssn, re-SYN-ing\n");
// FIXIT-M this leads to bogus 129:20
clear_session( true, true, true, tsd.get_pkt() );
else
{
listener->normalizer.trim_syn_payload(tsd);
- DebugMessage(DEBUG_STREAM_STATE, "Got data on SYN packet, not processing it\n");
tel.set_tcp_event(EVENT_DATA_ON_SYN);
pkt_action_mask |= ACTION_BAD_PKT;
}
void TcpSession::update_paws_timestamps(TcpSegmentDescriptor& tsd)
{
// update PAWS timestamps
- DebugFormat(DEBUG_STREAM_STATE, "PAWS update tsd.seq %u > listener->r_win_base %u\n",
- tsd.get_seg_seq(), listener->r_win_base);
if ( listener->normalizer.handling_timestamps()
&& SEQ_EQ(listener->r_win_base, tsd.get_seg_seq() ) )
( ( uint32_t )tsd.get_pkt()->pkth->ts.tv_sec
>= talker->get_ts_last_packet() + PAWS_24DAYS ) )
{
- DebugMessage(DEBUG_STREAM_STATE, "updating timestamps...\n");
talker->set_ts_last(tsd.get_ts());
talker->set_ts_last_packet(tsd.get_pkt()->pkth->ts.tv_sec);
}
}
- else
- {
- DebugMessage(DEBUG_STREAM_STATE, "not updating timestamps...\n");
- }
}
void TcpSession::check_for_session_hijack(TcpSegmentDescriptor& tsd)
{
if ( config->max_window && (tsd.get_seg_wnd() > config->max_window ) )
{
- DebugMessage(DEBUG_STREAM_STATE,
- "Got window that was beyond the allowed policy value, bailing\n");
/* got a window too large, alert! */
tel.set_tcp_event(EVENT_WINDOW_TOO_LARGE);
inc_tcp_discards();
&& !( tsd.get_tcph()->is_fin() | tsd.get_tcph()->is_rst() )
&& !(flow->get_session_flags() & SSNFLAG_MIDSTREAM))
{
- DebugMessage(DEBUG_STREAM_STATE, "Window slammed shut!\n");
/* got a window slam alert! */
tel.set_tcp_event(EVENT_WINDOW_SLAM);
inc_tcp_discards();
void TcpSession::handle_data_segment(TcpSegmentDescriptor& tsd)
{
- DebugFormat(DEBUG_STREAM_STATE, " %s state: %s(%d) getting data\n",
- l_name, tcp_state_names[listener->get_tcp_state()], listener->get_tcp_state());
-
- DebugFormat(DEBUG_STREAM_STATE, "Queuing data on listener, t %s, l %s...\n",
- flush_policy_names[talker->flush_policy],
- flush_policy_names[listener->flush_policy]);
-
if ( TcpStreamTracker::TCP_CLOSED != talker->get_tcp_state() )
{
uint8_t tcp_options_len = tsd.get_tcph()->options_len();
if ( final_flush && ( !tracker.splitter || !tracker.splitter->finish(flow) ) )
return;
- DebugFormat(DEBUG_STREAM_STATE, "Flushing tracker on packet from %s\n",
- (dir == PKT_FROM_CLIENT) ? "client" : "server");
tracker.set_tf_flags(TF_FORCE_FLUSH);
if ( tracker.reassembler.flush_stream(p, dir) )
tracker.reassembler.purge_flushed_ackd();
if (pkt_action_mask & ACTION_DISABLE_INSPECTION)
{
DetectionEngine::disable_all(p);
-
- DebugFormat(DEBUG_STREAM_STATE,
- "Stream Ignoring packet from %s. Session marked as ignore\n",
- p->is_from_server() ? "server" : "client");
}
}
// FIXIT-L can't get here without protocol being set to TCP, is this really needed??
if (flow->pkt_type != PktType::TCP)
{
- DebugMessage(DEBUG_STREAM_STATE, "Lightweight session not TCP on TCP packet\n");
return false;
}
if (p->is_from_client())
{
update_session_on_client_packet(tsd);
- DEBUG_WRAP(t_name = "Server"; l_name = "Client");
}
else
{
update_session_on_server_packet(tsd);
- DEBUG_WRAP(t_name = "Server"; l_name = "Client");
}
update_ignored_session(tsd);
set_window_scale(*talker, *listener, tsd);
check_for_session_hijack(tsd);
- DebugFormat(DEBUG_STREAM_STATE, " %s [talker] state: %s\n", t_name,
- tcp_state_names[talker->get_tcp_state()]);
- DebugFormat(DEBUG_STREAM_STATE, " %s state: %s(%d)\n", l_name,
- tcp_state_names[listener->get_tcp_state()], listener->get_tcp_state());
-
return true;
}
{
Profile profile(s5TcpPerfStats);
- DEBUG_WRAP
- (
- char flagbuf[9];
- CreateTCPFlagString(p->ptrs.tcph, flagbuf);
-
- char src_addr[INET6_ADDRSTRLEN];
- char dst_addr[INET6_ADDRSTRLEN];
-
- sfip_ntop(p->ptrs.ip_api.get_src(), src_addr, sizeof(src_addr));
- sfip_ntop(p->ptrs.ip_api.get_dst(), dst_addr, sizeof(dst_addr));
-
- DebugFormat((DEBUG_STREAM|DEBUG_STREAM_STATE),
- "Got TCP Packet %s:%hu -> %s:%hu %s\nseq: 0x%X ack:0x%X dsize: %hu\n",
- src_addr, p->ptrs.sp, dst_addr, p->ptrs.dp, flagbuf,
- p->ptrs.tcph->seq(), p->ptrs.tcph->ack(), p->dsize);
- );
-
assert(flow->ssn_server);
// FIXIT-H need to do something here to handle check for need to swap trackers??
{
if ( pkt_action_mask & ACTION_BAD_PKT )
{
- DebugMessage(DEBUG_STREAM_STATE, "bad packet, bailing\n");
inc_tcp_discards();
do_packet_analysis_post_checks(p);
}
}
- DebugMessage(DEBUG_STREAM_STATE,
- "Finished Stream TCP cleanly!\n---------------------------------------------------\n");
-
return ACTION_NOTHING;
}
#include "tcp_state_close_wait.h"
-#include "main/snort_debug.h"
#include "tcp_normalizers.h"
#include "tcp_session.h"
if ( SEQ_GT(tsd.get_seg_seq(), trk.get_fin_final_seq() ) )
{
- DebugMessage(DEBUG_STREAM_STATE, "FIN beyond previous, ignoring\n");
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);
#include "tcp_state_closing.h"
-#include "main/snort_debug.h"
-
#include "tcp_normalizers.h"
#include "tcp_session.h"
trk.update_tracker_ack_recv(tsd);
if ( SEQ_GT(tsd.get_seg_seq(), trk.get_fin_final_seq() ) )
{
- DebugMessage(DEBUG_STREAM_STATE, "FIN beyond previous, ignoring\n");
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);
#include "tcp_state_fin_wait1.h"
-#include "main/snort_debug.h"
-
#include "tcp_normalizers.h"
#include "tcp_module.h"
#include "tcp_session.h"
bool TcpStateFinWait1::check_for_window_slam(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk, bool* is_ack_valid)
{
- DebugFormat(DEBUG_STREAM_STATE, "tsd.ack %X >= listener->snd_nxt %X\n",
- tsd.get_seg_ack(), trk.get_snd_nxt());
-
if ( SEQ_EQ(tsd.get_seg_ack(), trk.get_snd_nxt() ) )
{
if ( (trk.normalizer.get_os_policy() == StreamPolicy::OS_WINDOWS)
}
else
{
- DebugMessage(DEBUG_STREAM_STATE, "Received RST with bad sequence number\n");
inc_tcp_discards();
trk.normalizer.packet_dropper(tsd, NORM_TCP_BLOCK);
trk.session->tel.set_tcp_event(EVENT_BAD_RST);
#include "tcp_state_time_wait.h"
-#include "main/snort_debug.h"
-
#include "tcp_normalizers.h"
#include "tcp_session.h"
trk.update_tracker_ack_recv(tsd);
if ( SEQ_GT(tsd.get_seg_seq(), trk.get_fin_final_seq() ) )
{
- DebugMessage(DEBUG_STREAM_STATE, "FIN beyond previous, ignoring\n");
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);
/* if both seen, mark established */
if (p->is_from_server())
{
- DebugMessage(DEBUG_STREAM_STATE,
- "Stream: Updating on packet from responder\n");
lwssn->ssn_state.session_flags |= SSNFLAG_SEEN_RESPONDER;
lwssn->set_ttl(p, false);
}
else
{
- DebugMessage(DEBUG_STREAM_STATE,
- "Stream: Updating on packet from client\n");
lwssn->ssn_state.session_flags |= SSNFLAG_SEEN_SENDER;
lwssn->set_ttl(p, true);
}