snort::DetectionEngine::disable_content(trs.sos.tsd->get_pkt());
trs.sos.keep_segment = false;
tcpStats.full_retransmits++;
-
}
else
{
// seq is always greater than left->seq
assert(SEQ_GT(trs.sos.seq, trs.sos.left->i_seq));
- trs.sos.len = trs.sos.tsd->get_len();
trs.sos.overlap = trs.sos.left->i_seq + trs.sos.left->i_len - trs.sos.seq;
if ( trs.sos.len < trs.sos.overlap )
{
if (trs.sos.tcp_ips_data == NORM_MODE_ON)
{
- unsigned offset = trs.sos.tsd->get_seq() - trs.sos.left->i_seq;
+ unsigned offset = trs.sos.tsd->get_seq() - (trs.sos.left->i_seq - trs.sos.left->o_offset);
trs.sos.tsd->rewrite_payload(0, trs.sos.left->data + offset);
}
norm_stats[PC_TCP_IPS_DATA][trs.sos.tcp_ips_data]++;
{
if ( trs.sos.tcp_ips_data == NORM_MODE_ON )
{
- unsigned offset = trs.sos.tsd->get_seq() - trs.sos.left->i_seq;
- unsigned length =
- trs.sos.left->i_seq + trs.sos.left->i_len - trs.sos.tsd->get_seq();
+ unsigned offset = trs.sos.tsd->get_seq() - (trs.sos.left->i_seq - trs.sos.left->o_offset);
+ unsigned length = trs.sos.left->i_seq + trs.sos.left->i_len - trs.sos.tsd->get_seq();
trs.sos.tsd->rewrite_payload(0, trs.sos.left->data + offset, length);
}
{
assert(SEQ_GT(trs.sos.seq, trs.sos.left->i_seq));
- trs.sos.len = trs.sos.tsd->get_len();
trs.sos.overlap = trs.sos.left->i_seq + trs.sos.left->i_len - trs.sos.seq;
if ( trs.sos.overlap > 0 )
{
assert(SEQ_GT(trs.sos.seq, trs.sos.left->i_seq));
- trs.sos.len = trs.sos.tsd->get_len();
trs.sos.overlap = trs.sos.left->i_seq + trs.sos.left->i_len - trs.sos.seq;
if ( trs.sos.overlap > 0 )
trs.sos.right->c_len -= delta;
trs.sos.right->i_len -= delta;
trs.sos.right->offset += delta;
+ trs.sos.right->o_offset += delta;
- trs.sos.seg_bytes_logical -= delta;
+ trs.sos.seg_bytes_logical -= trs.sos.len;
}
else
{
if ( SEQ_EQ(trs.sos.right->i_seq, trs.sos.seq) &&
( trs.sos.reassembly_policy != StreamPolicy::OS_LAST ) )
{
- trs.sos.slide = ( trs.sos.right->i_seq + trs.sos.right->i_len - trs.sos.seq );
- trs.sos.seq += trs.sos.slide;
+ trs.sos.seq += trs.sos.overlap;
}
else
{
trs.sos.right->i_seq += trs.sos.overlap;
trs.sos.right->c_seq = trs.sos.right->i_seq;
trs.sos.right->offset += trs.sos.overlap;
+ trs.sos.right->o_offset += trs.sos.overlap;
trs.sos.right->c_len -= (int16_t)trs.sos.overlap;
trs.sos.right->i_len -= ( int16_t )trs.sos.overlap;
trs.sos.seg_bytes_logical -= trs.sos.overlap;
if (trs.sos.tcp_ips_data == NORM_MODE_ON)
{
unsigned offset = trs.sos.right->i_seq - trs.sos.tsd->get_seq();
- unsigned length =
- trs.sos.tsd->get_seq() + trs.sos.tsd->get_len() - trs.sos.right->i_seq;
- trs.sos.tsd->rewrite_payload(offset, trs.sos.right->data, length);
+ unsigned length = trs.sos.tsd->get_seq() + trs.sos.tsd->get_len() - trs.sos.right->i_seq;
+ trs.sos.tsd->rewrite_payload(offset, trs.sos.right->data + trs.sos.right->o_offset, length);
}
norm_stats[PC_TCP_IPS_DATA][trs.sos.tcp_ips_data]++;
return;
}
- trs.sos.tsd->rewrite_payload(offset, trs.sos.right->data, trs.sos.right->i_len);
+ trs.sos.tsd->rewrite_payload(offset, trs.sos.right->data + trs.sos.right->o_offset, trs.sos.right->i_len);
}
norm_stats[PC_TCP_IPS_DATA][trs.sos.tcp_ips_data]++;
trs.sos.seq += trs.sos.right->i_len;
trs.sos.left = trs.sos.right;
trs.sos.right = trs.sos.right->next;
-
- /* Adjusted seq is fully overlapped */
- if ( SEQ_EQ(trs.sos.seq, trs.sos.seq_end) )
- return;
}
else
{
- /* seq is less than right->i_seq, trunc length is reset to 0 at beginning of loop */
+ // seq is less than right->i_seq, set trunc length and slide
+ // and insert chunk before current right segment...
trs.sos.trunc_len = trs.sos.overlap;
-
- /* insert this one, and see if we need to chunk it up
- Adjust slide so that is correct relative to orig seq */
trs.sos.slide = trs.sos.seq - trs.sos.tsd->get_seq();
add_reassembly_segment(trs, *trs.sos.tsd, trs.sos.len, trs.sos.slide,
trs.sos.trunc_len, trs.sos.seq, trs.sos.left);
if ( SEQ_EQ(trs.sos.right->i_seq, trs.sos.seq) && (trs.sos.right->i_len == trs.sos.len)
&& (trs.sos.left && !SEQ_EQ(trs.sos.left->i_seq + trs.sos.left->i_len, trs.sos.seq)) )
{
- right_overlap_truncate_new(trs);
-
+ trs.sos.trunc_len = trs.sos.right->i_len;
trs.sos.rdata += trs.sos.right->i_len;
trs.sos.rsize -= trs.sos.right->i_len;
trs.sos.rseq += trs.sos.right->i_len;
TcpSegmentNode* const tsn = TcpSegmentNode::init(tsd);
tsn->offset = slide;
+ tsn->o_offset = slide;
tsn->c_len = (uint16_t)new_size;
tsn->i_len = (uint16_t)new_size;
tsn->i_seq = tsn->c_seq = seq;
void TcpReassembler::insert_segment_in_empty_seglist(
TcpReassemblerState& trs, TcpSegmentDescriptor& tsd)
{
- const tcp::TCPHdr* tcph = tsd.get_tcph();
-
uint32_t overlap = 0;
- uint32_t seq = tsd.get_seq();
-
- if ( tcph->is_syn() )
- seq++;
- if ( SEQ_GT(trs.sos.seglist_base_seq, seq) )
+ if ( SEQ_GT(trs.sos.seglist_base_seq, tsd.get_seq()) )
{
overlap = trs.sos.seglist_base_seq - tsd.get_seq();
if ( overlap >= tsd.get_len() )
}
add_reassembly_segment(
- trs, tsd, tsd.get_len(), overlap, 0, seq + overlap, nullptr);
+ trs, tsd, tsd.get_len(), overlap, 0, tsd.get_seq() + overlap, nullptr);
}
void TcpReassembler::init_overlap_editor(
for ( tsn = trs.sos.seglist.head; tsn; tsn = tsn->next )
{
right = tsn;
-
if ( SEQ_GEQ(right->i_seq, tsd.get_seq() ) )
break;
for ( tsn = trs.sos.seglist.tail; tsn; tsn = tsn->prev )
{
left = tsn;
-
if ( SEQ_LT(left->i_seq, tsd.get_seq() ) )
break;
return;
}
- /* Adjust slide so that is correct relative to orig seq */
- trs.sos.slide = trs.sos.seq - tsd.get_seq();
- // FIXIT-L for some reason length - slide - trunc_len is sometimes negative
- if (trs.sos.len - trs.sos.slide - trs.sos.trunc_len < 0)
- return;
+ // slide is current seq number - initial seq number unless all data
+ // truncated from right, then slide is 0
+ if ( trs.sos.len - trs.sos.trunc_len > 0 )
+ trs.sos.slide = trs.sos.seq - tsd.get_seq();
+ else
+ trs.sos.slide = 0;
add_reassembly_segment(
trs, tsd, trs.sos.len, trs.sos.slide, trs.sos.trunc_len, trs.sos.seq, trs.sos.left);
client.normalizer.init(client_os_policy, this, &client, &server);
server.normalizer.init(server_os_policy, this, &server, &client);
+ if (Normalize_GetMode(NORM_TCP_IPS) == NORM_MODE_ON)
+ {
+ client_os_policy = StreamPolicy::OS_FIRST;
+ server_os_policy = StreamPolicy::OS_FIRST;
+ }
+
client.reassembler.init(this, &client, client_os_policy, false);
server.reassembler.init(this, &server, server_os_policy, true);
}
if ( !listener->normalizer.trim_syn_payload(tsd) )
{
+ // skip the byte in sequence space for SYN...data starts at the next byte
+ tsd.update_seq(1);
handle_data_segment(tsd);
tel.set_tcp_event(EVENT_DATA_ON_SYN);
}
else
server.set_tcp_options_len(tcp_options_len);
- uint32_t seq = tsd.get_tcph()->is_syn() ? tsd.get_seq() + 1 : tsd.get_seq();
- bool stream_is_inorder = ( seq == listener->rcv_nxt );
+ bool stream_is_inorder = ( tsd.get_seq() == listener->rcv_nxt );
- int rc = listener->normalizer.apply_normalizations(tsd, seq, stream_is_inorder);
+ int rc = listener->normalizer.apply_normalizations(tsd, tsd.get_seq(), stream_is_inorder);
switch ( rc )
{
case TcpNormalizer::NORM_OK: