Remove unused pseudo packet reassembly code.

remotes/origin/master-1.1.x
Victor Julien 15 years ago
parent bf88a6de09
commit 16cd31a408

@ -59,8 +59,6 @@ typedef struct TcpStream_ {
uint8_t os_policy; /**< target based OS policy used for reassembly and handling packets*/
uint16_t flags; /**< Flag specific to the stream e.g. Timestamp */
TcpSegment *seg_list_tail; /**< Last segment in the reassembled stream seg list*/
uint32_t pseudo_ra_base_seq; /**< Base sequence until when we have
reassembled the psuedo packet */
} TcpStream;
/* from /usr/include/netinet/tcp.h */
@ -152,7 +150,6 @@ enum
(stream)->ra_raw_base_seq = (seq); \
(stream)->ra_app_base_seq = (seq); \
(stream)->tmp_ra_app_base_seq = (seq); \
(stream)->pseudo_ra_base_seq = (seq); \
} while(0); \
}

@ -2534,234 +2534,6 @@ int StreamTcpReassembleHandleSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_
SCReturnInt(0);
}
/**
* \brief Function to copy the reassembled stream segments in to the pseudo
* packet payload.
*
* @param stream pointer to the stream of which segments are to be copied
* @param p pointer to the original received packet
* @param pq pointer to the packet queue where pseudo packet will be
* enqueued
*/
void StreamTcpReassemblePseudoPacketCreate(TcpStream *stream, Packet *p,
PacketQueue *pq)
{
SCEnter();
if (stream->seg_list == NULL) {
SCLogDebug("there is no segments in the stream, so return");
SCReturn;
}
Packet *np = StreamTcpPseudoSetup(p, p->pkt, p->pktlen);
if (np == NULL) {
SCLogDebug("The packet received from packet allocation is NULL");
SCReturn;
}
/* Setup the IP and TCP headers */
StreamTcpPseudoPacketSetupHeader(np,p);
/* Start the reassembling of received reassembled segments in to the
pseudo packet to scan and detect the unwanted attacks. Resistance is
FUTILE ;) */
uint16_t pseudo_offset = 0;
uint16_t payload_offset = 0;
uint16_t payload_len = 0;
TcpSegment *seg = stream->seg_list;
uint32_t next_seq = stream->pseudo_ra_base_seq + 1;
/* loop through the segments and fill one or more msgs */
for (; seg != NULL && SEQ_LT(seg->seq, stream->last_ack);) {
SCLogDebug("seg %p", seg);
/* If packets are fully before ra_base_seq, skip them. We do this
* because we've reassembled up to the ra_base_seq point already,
* so we won't do anything with segments before it anyway. */
SCLogDebug("checking for pre pseudo_ra_base_seq %"PRIu32" seg %p seq %"PRIu32""
" len %"PRIu16", combined %"PRIu32" and stream->last_ack "
"%"PRIu32"", stream->pseudo_ra_base_seq, seg, seg->seq,
seg->payload_len, seg->seq+seg->payload_len, stream->last_ack);
if (SEQ_LEQ((seg->seq + seg->payload_len), (stream->pseudo_ra_base_seq+1)) ||
SEQ_LEQ(stream->last_ack, (stream->pseudo_ra_base_seq +
(stream->pseudo_ra_base_seq - seg->seq))))
{
SCLogDebug("continue to next segment, as pre ra_base_seq %"PRIu32""
" seg %p seq %"PRIu32" len %"PRIu16"", stream->pseudo_ra_base_seq, seg,
seg->seq, seg->payload_len);
seg = seg->next;
continue;
}
/* we've run into a sequence gap */
if (SEQ_GT(seg->seq, next_seq)) {
SCLogDebug("expected next_seq %" PRIu32 ", got %" PRIu32 " , "
"stream->last_ack %" PRIu32 ".", next_seq, seg->seq,
stream->last_ack);
next_seq = seg->seq;
/* We have missed the packet and end host has ack'd it, so
* IDS should advance it's ra_base_seq and should not consider this
* packet any longer, even if it is retransmitted, as end host will
* drop it anyway */
stream->pseudo_ra_base_seq = seg->seq - 1;
/* As we have a gap in the next payload, so if we have some data in
the current pseudo packet then fetch another packet, under new
packet as the parent */
if (np->payload_len > 0) {
/* Set the correct payload length in the IP header */
if (PKT_IS_IPV4(np)) {
np->ip4h->ip_len = (IPV4_GET_HLEN(np)) + (TCP_GET_HLEN(np)) +
np->payload_len;
} else if (PKT_IS_IPV6(np)) {
np->ip6h->s_ip6_plen = (TCP_GET_HLEN(np)) + np->payload_len;
}
PacketEnqueue(pq, np);
Packet *gap = StreamTcpPseudoSetup(p, p->pkt, p->pktlen);
if (gap == NULL) {
SCLogDebug("The packet received from packet allocation is NULL");
SCReturn;
}
np = gap;
StreamTcpPseudoPacketSetupHeader(np,p);
}
}
/* if the segment ends beyond ra_base_seq we need to consider it */
if (SEQ_GT((seg->seq + seg->payload_len), stream->pseudo_ra_base_seq)) {
SCLogDebug("seg->seq %" PRIu32 ", seg->payload_len %" PRIu32 ", "
"stream->pseudo_ra_base_seq %" PRIu32 "", seg->seq,
seg->payload_len, stream->pseudo_ra_base_seq);
/* handle segments partly before ra_base_seq */
if (SEQ_GT(stream->pseudo_ra_base_seq, seg->seq)) {
payload_offset = stream->pseudo_ra_base_seq - seg->seq;
if (SEQ_LT(stream->last_ack, (seg->seq + seg->payload_len))) {
if (SEQ_LT(stream->last_ack, stream->pseudo_ra_base_seq)) {
payload_len = (stream->last_ack - seg->seq);
} else {
payload_len = (stream->last_ack - seg->seq) -
payload_offset;
}
} else {
payload_len = seg->payload_len - payload_offset;
}
if (SCLogDebugEnabled()) {
BUG_ON(payload_offset > seg->payload_len);
BUG_ON((payload_len + payload_offset) > seg->payload_len);
}
} else {
payload_offset = 0;
if (SEQ_LT(stream->last_ack, (seg->seq + seg->payload_len))) {
payload_len = stream->last_ack - seg->seq;
} else {
payload_len = seg->payload_len;
}
}
SCLogDebug("payload_offset is %"PRIu16", payload_len is %"PRIu16""
" and stream->last_ack is %"PRIu32"", payload_offset,
payload_len, stream->last_ack);
/* copy the data into the pseudo packet payload */
uint16_t copy_size = PSEUDO_PACKET_PAYLOAD_SIZE - np->payload_len - pseudo_offset;
if (copy_size > payload_len) {
copy_size = payload_len;
}
if (SCLogDebugEnabled()) {
BUG_ON(copy_size > PSEUDO_PACKET_PAYLOAD_SIZE);
}
SCLogDebug("copy_size is %"PRIu16"", copy_size);
memcpy(np->payload + pseudo_offset, seg->payload + payload_offset,
copy_size);
pseudo_offset += copy_size;
stream->pseudo_ra_base_seq += copy_size;
SCLogDebug("stream->pseudo_ra_base_seq %"PRIu32"", stream->pseudo_ra_base_seq);
np->payload_len += copy_size;
if (np->payload_len == PSEUDO_PACKET_PAYLOAD_SIZE) {
/* Set the correct payload length in the IP header */
if (PKT_IS_IPV4(np)) {
np->ip4h->ip_len = (IPV4_GET_HLEN(np)) + (TCP_GET_HLEN(np)) +
np->payload_len;
} else if (PKT_IS_IPV6(np)) {
np->ip6h->s_ip6_plen = (TCP_GET_HLEN(np)) + np->payload_len;
}
PacketEnqueue(pq, np);
Packet *newp = StreamTcpPseudoSetup(p, p->pkt, p->pktlen);
if (newp == NULL) {
SCLogDebug("The packet received from Allocation queue is NULL");
SCReturn;
}
np = newp;
StreamTcpPseudoPacketSetupHeader(np,p);
}
/* if the payload len is bigger than what we copied, we handle the
* rest of the payload next... */
if (copy_size < payload_len) {
SCLogDebug("copy_size %" PRIu32 " < %" PRIu32 "", copy_size,
payload_len);
payload_offset += copy_size;
payload_len -= copy_size;
SCLogDebug("payload_offset is %"PRIu16", seg->payload_len is "
"%"PRIu16" and stream->last_ack is %"PRIu32"",
payload_offset, seg->payload_len, stream->last_ack);
if (SCLogDebugEnabled()) {
BUG_ON(payload_offset > seg->payload_len);
}
copy_size = PSEUDO_PACKET_PAYLOAD_SIZE - np->payload_len - pseudo_offset;
if (copy_size > (seg->payload_len - payload_offset)) {
copy_size = (seg->payload_len - payload_offset);
}
if (SCLogDebugEnabled()) {
BUG_ON(copy_size > PSEUDO_PACKET_PAYLOAD_SIZE);
}
SCLogDebug("copy_size is %"PRIu16"", copy_size);
memcpy(np->payload + pseudo_offset, seg->payload + payload_offset,
copy_size);
pseudo_offset += copy_size;
stream->pseudo_ra_base_seq += copy_size;
SCLogDebug("stream->pseudo_ra_base_seq %"PRIu32"", stream->pseudo_ra_base_seq);
np->payload_len += copy_size;
SCLogDebug("copied payload_offset %" PRIu32 ", "
"pseudo_offset %" PRIu32 ", copy_size %" PRIu32 "",
payload_offset, pseudo_offset, copy_size);
} else {
payload_offset = 0;
}
}
/* done with this segment, switch to the next if any */
next_seq = seg->seq + seg->payload_len;
seg = seg->next;
}
/* XXX VJ can you check how to set the TCP header length properly. As in IPv4
* case, after running the following if the contents are changing in the unit
* test */
//PrintRawDataFp(stdout, np->payload, np->payload_len);
/* Set the correct payload length in the IP header */
if (PKT_IS_IPV4(np)) {
np->ip4h->ip_len = (IPV4_GET_HLEN(np)) + (TCP_GET_HLEN(np)) +
np->payload_len;
} else if (PKT_IS_IPV6(np)) {
np->ip6h->s_ip6_plen = (TCP_GET_HLEN(np)) + np->payload_len;
}
//PrintRawDataFp(stdout, np->payload, np->payload_len);
PacketEnqueue(pq, np);
SCReturn;
}
/**
* \brief Function to replace the data from a specific point up to given length.
*
@ -4518,7 +4290,6 @@ static int StreamTcpReassembleTest28 (void) {
ssn.server.last_ack = 22;
ssn.server.ra_raw_base_seq = ssn.server.ra_app_base_seq = 6;
ssn.server.pseudo_ra_base_seq = 6;
ssn.server.isn = 6;
StreamTcpCreateTestPacket(payload, 0x41, 2, 4); /*AA*/
@ -4526,7 +4297,6 @@ static int StreamTcpReassembleTest28 (void) {
ack = 20;
if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 2, th_flag, flowflags, TCP_ESTABLISHED) == -1) {
printf("failed in segments reassembly (1): ");
abort();
goto end;
}
@ -4536,7 +4306,6 @@ abort();
ack = 12;
if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 0, th_flags, flowflags, TCP_ESTABLISHED) == -1) {
printf("failed in segments reassembly (2): ");
abort();
goto end;
}
@ -4552,7 +4321,6 @@ abort();
ack = 20;
if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 3, th_flag, flowflags, TCP_ESTABLISHED) == -1) {
printf("failed in segments reassembly (4): ");
abort();
goto end;
}
@ -4562,13 +4330,11 @@ abort();
ack = 15;
if (StreamTcpTestMissedPacket (ra_ctx, &ssn, seq, ack, payload, 0, th_flags, flowflags, TCP_TIME_WAIT) == -1) {
printf("failed in segments reassembly (5): ");
abort();
goto end;
}
if (StreamTcpCheckQueue(check_contents, q, 1) == 0) {
printf("failed in stream matching (6): ");
abort();
goto end;
}
@ -4692,7 +4458,6 @@ static int StreamTcpReassembleTest30 (void) {
ssn.server.last_ack = 22;
ssn.server.ra_raw_base_seq = ssn.server.ra_app_base_seq = 9;
ssn.server.pseudo_ra_base_seq = 9;
ssn.server.isn = 9;
StreamTcpInitConfig(TRUE);
@ -7042,240 +6807,6 @@ end:
SCFree(p);
return ret;
}
#if 0
/**
* \test Test to make sure we setup the ipv4 pseudo packet properly
*
* \retval On success it returns 1 and on failure 0.
*/
static int StreamTcpReassembleTest48 (void) {
int ret = 0;
Flow f;
TcpSession ssn;
char srcip[] = "1.2.3.4";
char dstip[] = "1.2.3.5";
PacketQueue pq;
memset(&pq,0,sizeof(PacketQueue));
memset(&f, 0, sizeof (Flow));
memset(&ssn, 0, sizeof(TcpSession));
ThreadVars tv;
memset(&tv, 0, sizeof (ThreadVars));
FLOW_INITIALIZE(&f);
StreamTcpInitConfig(TRUE);
TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx();
AppLayerDetectProtoThreadInit();
uint8_t httpbuf1[] = "GET /EVILSTUFF HTTP/1.1\r\n\r\n";
uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
Packet *p = UTHBuildPacketReal(httpbuf1, httplen1, IPPROTO_TCP, srcip,
dstip, 80, 2345);
STREAMTCP_SET_RA_BASE_SEQ(&ssn.server, 572799781UL);
ssn.server.isn = 572799781UL;
ssn.server.last_ack = 572799782UL;
STREAMTCP_SET_RA_BASE_SEQ(&ssn.client, 4294967289UL);
ssn.client.isn = 4294967289UL;
ssn.client.last_ack = 21;
f.alproto = ALPROTO_UNKNOWN;
SET_IPV4_SRC_ADDR(p,&f.src);
SET_IPV4_DST_ADDR(p,&f.dst);
f.src.family = AF_INET;
f.dst.family = AF_INET;
f.sp = p->sp;
f.dp = p->dp;
f.protoctx = &ssn;
p->flow = &f;
p->tcph->th_win = htons(5480);
ssn.state = TCP_ESTABLISHED;
TcpStream *s = NULL;
uint8_t cnt = 0;
p->tcph->th_seq = htonl(ssn.client.isn + 1 + cnt);
p->tcph->th_ack = htonl(572799782UL);
p->tcph->th_flags = TH_ACK|TH_PUSH;
p->flowflags = FLOW_PKT_TOSERVER;
s = &ssn.client;
if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) {
printf("failed in segments reassembly, while processing toserver "
"packet\n");
goto end;
}
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload = NULL;
p->payload_len = 0;
p->tcph->th_seq = htonl(572799782UL);
p->tcph->th_ack = htonl(ssn.client.isn + 1 + cnt);
p->tcph->th_flags = TH_RST|TH_ACK;
s = &ssn.server;
if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) {
printf("failed in segments reassembly, while processing toserver "
"packet\n");
goto end;
}
/* Process stream smsgs we may have in queue */
if (StreamTcpReassembleProcessAppLayer(ra_ctx) < 0) {
printf("failed in processing stream smsgs\n");
goto end;
}
if (f.alproto != ALPROTO_HTTP) {
printf("App layer protocol (HTTP) should have been detected\n");
goto end;
}
Packet *pp = PacketDequeue(&pq);
if (pp == NULL) {
printf("pp == NULL: ");
goto end;
}
char srcip1[16], dstip1[16];
inet_ntop(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(pp), srcip1, sizeof(srcip1));
inet_ntop(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(pp), dstip1, sizeof(dstip1));
if ((strcmp(srcip1, dstip) != 0) || (strcmp(dstip1, srcip) != 0)) {
printf("failed in setting ip address properly srcip1 %s dstip1 %s srcip %s dstip %s\n",
srcip1, dstip1, srcip, dstip);
goto end;
}
if (memcmp(httpbuf1, pp->payload, pp->payload_len) != 0) {
PrintRawDataFp(stdout, pp->payload, pp->payload_len);
PrintRawDataFp(stdout, httpbuf1, pp->payload_len);
goto end;
}
ret = 1;
end:
StreamTcpFreeConfig(TRUE);
StreamTcpReassembleFreeThreadCtx(ra_ctx);
return ret;
}
/**
* \test Test to make sure we setup the ipv6 pseudo packet properly
*
* \retval On success it returns 1 and on failure 0.
*/
static int StreamTcpReassembleTest49 (void) {
int ret = 0;
Flow f;
TcpSession ssn;
char srcip[] = "::1";
char dstip[] = "::1";
PacketQueue pq;
memset(&pq,0,sizeof(PacketQueue));
memset(&f, 0, sizeof (Flow));
memset(&ssn, 0, sizeof(TcpSession));
ThreadVars tv;
memset(&tv, 0, sizeof (ThreadVars));
FLOW_INITIALIZE(&f);
StreamTcpInitConfig(TRUE);
TcpReassemblyThreadCtx *ra_ctx = StreamTcpReassembleInitThreadCtx();
AppLayerDetectProtoThreadInit();
uint8_t httpbuf1[] = "GET /EVILSTUFF HTTP/1.1\r\n\r\n";
uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
Packet *p = UTHBuildPacketIPV6Real(httpbuf1, httplen1, IPPROTO_TCP, srcip,
dstip, 80, 2345);
STREAMTCP_SET_RA_BASE_SEQ(&ssn.server, 572799781UL);
ssn.server.isn = 572799781UL;
ssn.server.last_ack = 572799782UL;
STREAMTCP_SET_RA_BASE_SEQ(&ssn.client, 4294967289UL);
ssn.client.isn = 4294967289UL;
ssn.client.last_ack = 21;
f.alproto = ALPROTO_UNKNOWN;
SET_IPV6_SRC_ADDR(p,&f.src);
SET_IPV6_DST_ADDR(p,&f.dst);
f.src.family = AF_INET6;
f.dst.family = AF_INET6;
f.sp = p->sp;
f.dp = p->dp;
f.protoctx = &ssn;
p->flow = &f;
p->tcph->th_win = htons(5480);
ssn.state = TCP_ESTABLISHED;
TcpStream *s = NULL;
uint8_t cnt = 0;
p->tcph->th_seq = htonl(ssn.client.isn + 1 + cnt);
p->tcph->th_ack = htonl(572799782UL);
p->tcph->th_flags = TH_ACK|TH_PUSH;
p->flowflags = FLOW_PKT_TOSERVER;
s = &ssn.client;
if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) {
printf("failed in segments reassembly, while processing toserver "
"packet\n");
goto end;
}
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload = NULL;
p->payload_len = 0;
p->tcph->th_seq = htonl(572799782UL);
p->tcph->th_ack = htonl(ssn.client.isn + 1 + cnt);
p->tcph->th_flags = TH_ACK;
s = &ssn.server;
if (StreamTcpReassembleHandleSegment(&tv, ra_ctx, &ssn, s, p, &pq) == -1) {
printf("failed in segments reassembly, while processing toserver "
"packet\n");
goto end;
}
/* Process stream smsgs we may have in queue */
if (StreamTcpReassembleProcessAppLayer(ra_ctx) < 0) {
printf("failed in processing stream smsgs\n");
goto end;
}
if (f.alproto != ALPROTO_HTTP) {
printf("App layer protocol (HTTP) should have been detected\n");
goto end;
}
Packet *pp = PacketDequeue(&pq);
if (pp == NULL) {
printf("pp == NULL: ");
goto end;
}
char srcip1[46], dstip1[46];
inet_ntop(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(pp), srcip1, sizeof(srcip1));
inet_ntop(AF_INET6, (const void *)GET_IPV6_DST_ADDR(pp), dstip1, sizeof(dstip1));
if ((strcmp(srcip1, dstip) != 0) || (strcmp(dstip1, srcip) != 0)) {
printf("failed in setting ip address properly srcip1 %s dstip1 %s srcip %s dstip %s\n",
srcip1, dstip1, srcip, dstip);
goto end;
}
if (memcmp(httpbuf1, pp->payload, pp->payload_len) != 0) {
PrintRawDataFp(stdout, pp->payload, pp->payload_len);
PrintRawDataFp(stdout, httpbuf1, pp->payload_len);
goto end;
}
ret = 1;
end:
StreamTcpFreeConfig(TRUE);
StreamTcpReassembleFreeThreadCtx(ra_ctx);
return ret;
}
#endif
#endif /* UNITTESTS */
/** \brief The Function Register the Unit tests to test the reassembly engine
@ -7331,8 +6862,6 @@ void StreamTcpReassembleRegisterTests(void) {
UtRegisterTest("StreamTcpReassembleTest45 -- Depth Test", StreamTcpReassembleTest45, 1);
UtRegisterTest("StreamTcpReassembleTest46 -- Depth Test", StreamTcpReassembleTest46, 1);
UtRegisterTest("StreamTcpReassembleTest47 -- TCP Sequence Wraparound Test", StreamTcpReassembleTest47, 1);
// UtRegisterTest("StreamTcpReassembleTest48 -- Pseudo IPv4 Packet Test", StreamTcpReassembleTest48, 1);
// UtRegisterTest("StreamTcpReassembleTest49 -- Pseudo IPv6 Packet Test", StreamTcpReassembleTest49, 1);
StreamTcpInlineRegisterTests();
#endif /* UNITTESTS */

Loading…
Cancel
Save