Target Based Stream Reassembly with comments

remotes/origin/master-1.0.x
Gurvinder Singh 17 years ago committed by Victor Julien
parent 25f696106c
commit 994473cea0

@ -21,6 +21,7 @@ typedef struct TcpStream_ {
/* reassembly */
u_int32_t ra_base_seq; /* reassembled seq. We've reassembled up to this point. */
TcpSegment *seg_list;
u_int8_t os_policy; /* target based OS policy used for reassembly and handling packets*/
} TcpStream;
/* from /usr/include/netinet/tcp.h */
@ -32,7 +33,7 @@ enum
TCP_FIN_WAIT1,
TCP_FIN_WAIT2,
TCP_TIME_WAIT,
TCP_CLOSE,
TCP_CLOSED,
TCP_CLOSE_WAIT,
TCP_LAST_ACK,
TCP_LISTEN,
@ -53,5 +54,4 @@ typedef struct TcpSession_ {
TcpStream client;
void **l7data;
} TcpSession;
#endif /* __STREAM_TCP_PRIVATE_H__ */

File diff suppressed because it is too large Load Diff

@ -1,10 +1,31 @@
/* Copyright (c) 2008 Victor Julien <victor@inliniac.net> */
/* 2009 Gurvinder Singh <gurvindersinghdahiya@gmail.com>*/
#ifndef __STREAM_TCP_REASSEMBLE_H__
#define __STREAM_TCP_REASSEMBLE_H__
/*Supported OS list and default OS policy is BSD*/
enum
{
OS_POLICY_BSD = 1,
OS_POLICY_OLD_LINUX,
OS_POLICY_LINUX,
OS_POLICY_SOLARIS,
OS_POLICY_HPUX10,
OS_POLICY_HPUX11,
OS_POLICY_IRIX,
OS_POLICY_MACOS,
OS_POLICY_WINDOWS,
OS_POLICY_VISTA,
OS_POLICY_WINDOWS2K3,
OS_POLICY_FIRST,
OS_POLICY_LAST
};
#define OS_POLICY_DEFAULT OS_POLICY_BSD
int StreamTcpReassembleHandleSegment (TcpSession *ssn, TcpStream *stream, Packet *p);
int StreamTcpReassembleInit(void);
void SreamTcpReassembleRegisterTests (void);
#endif /* __STREAM_TCP_REASSEMBLE_H__ */

@ -1,4 +1,8 @@
/* Copyright (c) 2008 Victor Julien <victor@inliniac.net> */
/* 2009 Gurvinder Singh <gurvindersinghdahiya@gmail.com>*/
#include "decode.h"
#include <stdio.h>
#include <stdlib.h>
@ -32,6 +36,9 @@ int StreamTcp (ThreadVars *, Packet *, void *, PacketQueue *);
int StreamTcpThreadInit(ThreadVars *, void *, void **);
int StreamTcpThreadDeinit(ThreadVars *, void *);
void StreamTcpExitPrintStats(ThreadVars *, void *);
static int ValidReset(TcpSession * , Packet *);
static int StreamTcpHandleFin(TcpSession *, Packet *);
void StreamTcpStreamReturntoPool (Packet *);
void *StreamTcpSessionAlloc(void *null) {
void *ptr = malloc(sizeof(TcpSession));
@ -55,7 +62,7 @@ void TmModuleStreamTcpRegister (void) {
tmm_modules[TMM_STREAMTCP].Func = StreamTcp;
tmm_modules[TMM_STREAMTCP].ExitPrintStats = StreamTcpExitPrintStats;
tmm_modules[TMM_STREAMTCP].Deinit = StreamTcpThreadDeinit;
tmm_modules[TMM_STREAMTCP].RegisterTests = NULL;
tmm_modules[TMM_STREAMTCP].RegisterTests = SreamTcpReassembleRegisterTests;
ssn_pool = PoolInit(262144, 32768, StreamTcpSessionAlloc, NULL, StreamTcpSessionFree);
if (ssn_pool == NULL) {
@ -69,10 +76,16 @@ typedef struct StreamTcpThread_ {
u_int64_t pkts;
} StreamTcpThread;
/* StreamTcpPacketStateNone
* Handle packets while the session state is None which means a
* newly initialized structure, or a fully closed session.
/**
* \brief Function to handle the TCP_CLOSED or NONE state. The function handles
* packets while the session state is None which means a newly
* initialized structure, or a fully closed session.
*
* \param tv Thread Variable containig input/output queue, cpu affinity etc.
* \param p Packet which has to be handled in this TCP state.
* \param stt Strean Thread module registered to handle the stream handling
*/
static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
switch (p->tcph->th_flags) {
case TH_SYN:
@ -107,12 +120,22 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p, StreamTcpThread *
}
break;
default:
//printf("StreamTcpPacketStateNone: default case\n");
printf("StreamTcpPacketStateNone: default case\n");
break;
}
return 0;
}
/**
* \brief Function to handle the TCP_SYN_SENT state. The function handles
* SYN, SYN/ACK, RSTpackets and correspondingly changes the connection
* state.
*
* \param tv Thread Variable containig input/output queue, cpu affinity etc.
* \param p Packet which has to be handled in this TCP state.
* \param stt Strean Thread module registered to handle the stream handling
*/
static int StreamTcpPacketStateSynSent(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
TcpSession *ssn = (TcpSession *)p->flow->stream;
@ -162,8 +185,16 @@ static int StreamTcpPacketStateSynSent(ThreadVars *tv, Packet *p, StreamTcpThrea
ssn, ssn->server.isn, ssn->server.next_seq, ssn->client.last_ack);
break;
case TH_RST:
case TH_RST|TH_ACK:
/* seq should be 0, win should be 0, ack should be isn +1.
* check Snort's stream4/5 for more security */
* check Snort's stream4/5 for more security*/
if(ValidReset(ssn, p)){
if(SEQ_EQ(TCP_GET_SEQ(p), ssn->client.isn) && SEQ_EQ(TCP_GET_WINDOW(p), 0) && SEQ_EQ(TCP_GET_ACK(p), (ssn->client.isn + 1))) {
ssn->state = TCP_CLOSED;
StreamTcpStreamReturntoPool(p);
}
} else
return -1;
break;
default:
printf("StreamTcpPacketStateSynSent (%p): default case\n", ssn);
@ -173,6 +204,16 @@ static int StreamTcpPacketStateSynSent(ThreadVars *tv, Packet *p, StreamTcpThrea
return 0;
}
/**
* \brief Function to handle the TCP_SYN_RECV state. The function handles
* SYN, SYN/ACK, ACK, FIN, RST packets and correspondingly changes
* the connection state.
*
* \param tv Thread Variable containig input/output queue, cpu affinity etc.
* \param p Packet which has to be handled in this TCP state.
* \param stt Strean Thread module registered to handle the stream handling
*/
static int StreamTcpPacketStateSynRecv(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
TcpSession *ssn = (TcpSession *)p->flow->stream;
@ -207,6 +248,19 @@ static int StreamTcpPacketStateSynRecv(ThreadVars *tv, Packet *p, StreamTcpThrea
ssn->client.next_win = ssn->client.last_ack + ssn->client.window;
printf("StreamTcpPacketStateSynRecv (%p): next_win %u\n", ssn, ssn->client.next_win);
break;
case TH_RST:
case TH_RST|TH_ACK:
if(ValidReset(ssn, p)) {
ssn->state = TCP_CLOSED;
StreamTcpStreamReturntoPool(p);
} else
return -1;
break;
case TH_FIN:
/*FIN is handled in the same way as in TCP_ESTABLISHED case */;
if((StreamTcpHandleFin(ssn, p)) == -1)
return -1;
break;
default:
printf("StreamTcpPacketStateSynRecv (%p): default case\n", ssn);
break;
@ -215,6 +269,17 @@ static int StreamTcpPacketStateSynRecv(ThreadVars *tv, Packet *p, StreamTcpThrea
return 0;
}
/**
* \brief Function to handle the TCP_ESTABLISHED state. The function handles
* ACK, FIN, RST packets and correspondingly changes the connection
* state. The function handles the data inside packets and call
* StreamTcpReassembleHandleSegment() to handle the reassembling.
*
* \param tv Thread Variable containig input/output queue, cpu affinity etc.
* \param p Packet which has to be handled in this TCP state.
* \param stt Strean Thread module registered to handle the stream handling
*/
static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
TcpSession *ssn = (TcpSession *)p->flow->stream;
@ -251,7 +316,7 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, StreamTcpT
StreamTcpReassembleHandleSegment(ssn, &ssn->client, p);
} else {
printf("StreamTcpPacketStateEstablished (%p): !!!!! => SEQ mismatch, packet SEQ %u, payload size %u (%u), last_ack %u, next_win %u\n",
printf("StreamTcpPacketStateEstablished (%p): server !!!!! => SEQ mismatch, packet SEQ %u, payload size %u (%u), last_ack %u, next_win %u\n",
ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p) + p->payload_len, ssn->client.last_ack, ssn->client.next_win);
}
printf("StreamTcpPacketStateEstablished (%p): next SEQ %u, last ACK %u, next win %u, win %u\n",
@ -280,7 +345,7 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, StreamTcpT
StreamTcpReassembleHandleSegment(ssn, &ssn->server, p);
} else {
printf("StreamTcpPacketStateEstablished (%p): !!!!! => SEQ mismatch, packet SEQ %u, payload size %u (%u), last_ack %u, next_win %u\n",
printf("StreamTcpPacketStateEstablished (%p): client !!!!! => SEQ mismatch, packet SEQ %u, payload size %u (%u), last_ack %u, next_win %u\n",
ssn, TCP_GET_SEQ(p), p->payload_len, TCP_GET_SEQ(p) + p->payload_len, ssn->server.last_ack, ssn->server.next_win);
}
@ -291,21 +356,185 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, StreamTcpT
case TH_FIN:
case TH_FIN|TH_ACK:
case TH_FIN|TH_ACK|TH_PUSH:
if((StreamTcpHandleFin(ssn, p)) == -1)
return -1;
break;
case TH_RST:
case TH_RST|TH_ACK:
if(ValidReset(ssn, p)) {
if(PKT_IS_TOSERVER(p)) {
printf("StreamTcpPacketStateEstablished (%p): Reset received and state changed to TCP_CLOSED\n", ssn);
ssn->state = TCP_CLOSED;
/*Similar remote application is closed, so jump to CLOSE_WAIT*/
ssn->client.next_seq = TCP_GET_ACK(p);
ssn->server.next_seq = TCP_GET_SEQ(p) + p->payload_len + 1;
printf("StreamTcpPacketStateEstablished (%p): ssn->server.next_seq %u\n", ssn, ssn->server.next_seq);
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack))
ssn->server.last_ack = TCP_GET_ACK(p);
StreamTcpReassembleHandleSegment(ssn, &ssn->client, p);
printf("StreamTcpPacketStateEstablished (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->client.next_seq, ssn->server.last_ack);
StreamTcpStreamReturntoPool(p);
} else {
printf("StreamTcpPacketStateEstablished (%p): Reset received and state changed to TCP_CLOSED\n", ssn);
ssn->state = TCP_CLOSED;
/*Similar remote application is closed, so jump to CLOSE_WAIT*/
ssn->server.next_seq = TCP_GET_SEQ(p) + p->payload_len + 1;
ssn->client.next_seq = TCP_GET_ACK(p);
printf("StreamTcpPacketStateEstablished (%p): ssn->server.next_seq %u\n", ssn, ssn->server.next_seq);
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack))
ssn->client.last_ack = TCP_GET_ACK(p);
StreamTcpReassembleHandleSegment(ssn, &ssn->server, p);
printf("StreamTcpPacketStateEstablished (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->server.next_seq, ssn->client.last_ack);
StreamTcpStreamReturntoPool(p);
}
} else
return -1;
break;
default:
printf("StreamTcpPacketStateEstablished (%p): default case\n", ssn);
break;
}
return 0;
}
/**
* \brief Function to handle the FIN packets for states TCP_SYN_RECV and
* TCP_ESTABLISHED and changes to another TCP state as required.
*
* \param tv Thread Variable containig input/output queue, cpu affinity etc.
* \param p Packet which has to be handled in this TCP state.
* \param stt Strean Thread module registered to handle the stream handling
*/
static int StreamTcpHandleFin(TcpSession *ssn, Packet *p) {
if (PKT_IS_TOSERVER(p)) {
printf("StreamTcpPacket (%p): pkt (%u) is to server: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) || SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) {
printf("StreamTcpPacket (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->client.next_seq);
return -1;
}
printf("StreamTcpPacket (%p): state changed to TCP_CLOSE_WAIT\n", ssn);
ssn->state = TCP_CLOSE_WAIT;
ssn->client.next_seq = TCP_GET_ACK(p);
ssn->server.next_seq = TCP_GET_SEQ(p) + p->payload_len + 1;
printf("StreamTcpPacket (%p): ssn->server.next_seq %u\n", ssn, ssn->server.next_seq);
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack))
ssn->server.last_ack = TCP_GET_ACK(p);
StreamTcpReassembleHandleSegment(ssn, &ssn->client, p);
printf("StreamTcpPacket (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->client.next_seq, ssn->server.last_ack);
} else { /* implied to client */
printf("StreamTcpPacket (%p): pkt (%u) is to client: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) || SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) {
printf("StreamTcpPacket (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->server.next_seq);
return -1;
}
printf("StreamTcpPacket (%p): state changed to TCP_FIN_WAIT1\n", ssn);
ssn->state = TCP_FIN_WAIT1;
ssn->server.next_seq = TCP_GET_SEQ(p) + p->payload_len + 1;
ssn->client.next_seq = TCP_GET_ACK(p);
printf("StreamTcpPacket (%p): ssn->server.next_seq %u\n", ssn, ssn->server.next_seq);
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack))
ssn->client.last_ack = TCP_GET_ACK(p);
StreamTcpReassembleHandleSegment(ssn, &ssn->server, p);
printf("StreamTcpPacket (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->server.next_seq, ssn->client.last_ack);
}
return 0;
}
/**
* \brief Function to handle the TCP_FIN_WAIT1 state. The function handles
* ACK, FIN, RST packets and correspondingly changes the connection
* state.
*
* \param tv Thread Variable containig input/output queue, cpu affinity etc.
* \param p Packet which has to be handled in this TCP state.
* \param stt Strean Thread module registered to handle the stream handling
*/
static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
TcpSession *ssn = (TcpSession *)p->flow->stream;
switch (p->tcph->th_flags) {
case TH_ACK:
if (PKT_IS_TOSERVER(p)) {
printf("StreamTcpPacketStateEstablished (%p): pkt (%u) is to server: SEQ %u, ACK %u\n",
printf("StreamTcpPacketStateFinWait1 (%p): pkt (%u) is to server: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (TCP_GET_SEQ(p) != ssn->client.next_seq) {
printf("StreamTcpPacketStateEstablished (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
printf("StreamTcpPacketStateFinWait1 (%p): state changed to TCP_FIN_WAIT2\n", ssn);
ssn->state = TCP_FIN_WAIT2;
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack))
ssn->server.last_ack = TCP_GET_ACK(p);
StreamTcpReassembleHandleSegment(ssn, &ssn->client, p);
printf("StreamTcpPacketStateFinWait1 (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->client.next_seq, ssn->server.last_ack);
} else { /* implied to client */
printf("StreamTcpPacketStateFinWait1 (%p): pkt (%u) is to client: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
printf("StreamTcpPacketStateFinWait1 (%p): state changed to TCP_FIN_WAIT2\n", ssn);
ssn->state = TCP_FIN_WAIT2;
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack))
ssn->client.last_ack = TCP_GET_ACK(p);
StreamTcpReassembleHandleSegment(ssn, &ssn->server, p);
printf("StreamTcpPacketStateFinWait1 (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->server.next_seq, ssn->client.last_ack);
}
break;
case TH_FIN:
case TH_FIN|TH_ACK:
case TH_FIN|TH_ACK|TH_PUSH:
if (PKT_IS_TOSERVER(p)) {
printf("StreamTcpPacketStateFinWait1 (%p): pkt (%u) is to server: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq || SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window)))) {
printf("StreamTcpPacketStateFinWait1 (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->client.next_seq);
return -1;
}
printf("StreamTcpPacketStateEstablished (%p): state changed to TCP_FIN_WAIT1\n", ssn);
ssn->state = TCP_FIN_WAIT1;
ssn->client.next_seq = TCP_GET_ACK(p);
ssn->server.next_seq = TCP_GET_SEQ(p) + p->payload_len + 1;
printf("StreamTcpPacketStateEstablished (%p): ssn->server.next_seq %u\n", ssn, ssn->server.next_seq);
printf("StreamTcpPacketStateFinWait1 (%p): state changed to TCP_TIME_WAIT\n", ssn);
ssn->state = TCP_TIME_WAIT;
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack))
@ -313,23 +542,20 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, StreamTcpT
StreamTcpReassembleHandleSegment(ssn, &ssn->client, p);
printf("StreamTcpPacketStateEstablished (%p): =+ next SEQ %u, last ACK %u\n",
printf("StreamTcpPacketStateFinWait1 (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->client.next_seq, ssn->server.last_ack);
} else { /* implied to client */
printf("StreamTcpPacketStateEstablished (%p): pkt (%u) is to client: SEQ %u, ACK %u\n",
printf("StreamTcpPacketStateFinWait1 (%p): pkt (%u) is to client: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (TCP_GET_SEQ(p) != ssn->server.next_seq) {
printf("StreamTcpPacketStateEstablished (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) || SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) {
printf("StreamTcpPacketStateFinWait1 (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->server.next_seq);
return -1;
}
printf("StreamTcpPacketStateEstablished (%p): state changed to TCP_FIN_WAIT1\n", ssn);
ssn->state = TCP_FIN_WAIT1;
ssn->server.next_seq = TCP_GET_SEQ(p) + p->payload_len + 1;
ssn->client.next_seq = TCP_GET_ACK(p);
printf("StreamTcpPacketStateEstablished (%p): ssn->server.next_seq %u\n", ssn, ssn->server.next_seq);
printf("StreamTcpPacketStateFinWait1 (%p): state changed to TCP_TIME_WAIT\n", ssn);
ssn->state = TCP_TIME_WAIT;
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack))
@ -337,36 +563,55 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, StreamTcpT
StreamTcpReassembleHandleSegment(ssn, &ssn->server, p);
printf("StreamTcpPacketStateEstablished (%p): =+ next SEQ %u, last ACK %u\n",
printf("StreamTcpPacketStateFinWait1 (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->server.next_seq, ssn->client.last_ack);
}
break;
case TH_RST:
case TH_RST|TH_ACK:
if(ValidReset(ssn, p)) {
printf("StreamTcpPacketStateFinWait1 (%p): Reset received state changed to TCP_CLOSED\n", ssn);
ssn->state = TCP_CLOSED;
StreamTcpStreamReturntoPool(p);
}
else
return -1;
break;
default:
printf("StreamTcpPacketStateFinWait1 (%p): default case\n", ssn);
break;
}
return 0;
}
static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
/**
* \brief Function to handle the TCP_FIN_WAIT2 state. The function handles
* ACK, RST, FIN packets and correspondingly changes the connection
* state.
*
* \param tv Thread Variable containig input/output queue, cpu affinity etc.
* \param p Packet which has to be handled in this TCP state.
* \param stt Strean Thread module registered to handle the stream handling
*/
static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
TcpSession *ssn = (TcpSession *)p->flow->stream;
switch (p->tcph->th_flags) {
case TH_FIN:
case TH_FIN|TH_ACK:
case TH_FIN|TH_ACK|TH_PUSH:
case TH_ACK:
if (PKT_IS_TOSERVER(p)) {
printf("StreamTcpPacketStateFinWait1 (%p): pkt (%u) is to server: SEQ %u, ACK %u\n",
printf("StreamTcpPacketStateFinWait2 (%p): pkt (%u) is to server: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (TCP_GET_SEQ(p) != ssn->client.next_seq) {
printf("StreamTcpPacketStateFinWait1 (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
printf("StreamTcpPacketStateFinWait2 (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->client.next_seq);
return -1;
}
printf("StreamTcpPacketStateFinWait1 (%p): state changed to TCP_FIN_WAIT2\n", ssn);
ssn->state = TCP_FIN_WAIT2;
printf("StreamTcpPacketStateFinWait2 (%p): state changed to TCP_TIME_WAIT\n", ssn);
ssn->state = TCP_TIME_WAIT;
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack))
@ -374,20 +619,20 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p, StreamTcpThre
StreamTcpReassembleHandleSegment(ssn, &ssn->client, p);
printf("StreamTcpPacketStateFinWait1 (%p): =+ next SEQ %u, last ACK %u\n",
printf("StreamTcpPacketStateFinWait2 (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->client.next_seq, ssn->server.last_ack);
} else { /* implied to client */
printf("StreamTcpPacketStateFinWait1 (%p): pkt (%u) is to client: SEQ %u, ACK %u\n",
printf("StreamTcpPacketStateFinWait2 (%p): pkt (%u) is to client: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (TCP_GET_SEQ(p) != ssn->server.next_seq) {
printf("StreamTcpPacketStateFinWait1 (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
printf("StreamTcpPacketStateFinWait2 (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->server.next_seq);
return -1;
}
printf("StreamTcpPacketStateFinWait1 (%p): state changed to TCP_FIN_WAIT2\n", ssn);
ssn->state = TCP_FIN_WAIT2;
printf("StreamTcpPacketStateFinWait2 (%p): state changed to TCP_TIME_WAIT\n", ssn);
ssn->state = TCP_TIME_WAIT;
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack))
@ -395,32 +640,101 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p, StreamTcpThre
StreamTcpReassembleHandleSegment(ssn, &ssn->server, p);
printf("StreamTcpPacketStateFinWait1 (%p): =+ next SEQ %u, last ACK %u\n",
printf("StreamTcpPacketStateFinWait2 (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->server.next_seq, ssn->client.last_ack);
}
break;
case TH_RST:
case TH_RST|TH_ACK:
if(ValidReset(ssn, p)) {
printf("StreamTcpPacketStateFinWait2 (%p): Reset received state changed to TCP_CLOSED\n", ssn);
ssn->state = TCP_CLOSED;
StreamTcpStreamReturntoPool(p);
}
else
return -1;
break;
case TH_FIN:
if (PKT_IS_TOSERVER(p)) {
printf("StreamTcpPacketStateFinWait2 (%p): pkt (%u) is to server: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq || SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window)))) {
printf("StreamTcpPacketStateFinWait2 (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->client.next_seq);
return -1;
}
printf("StreamTcpPacketStateFinWait2 (%p): state changed to TCP_TIME_WAIT\n", ssn);
ssn->state = TCP_TIME_WAIT;
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack))
ssn->server.last_ack = TCP_GET_ACK(p);
StreamTcpReassembleHandleSegment(ssn, &ssn->client, p);
printf("StreamTcpPacketStateFinWait2 (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->client.next_seq, ssn->server.last_ack);
} else { /* implied to client */
printf("StreamTcpPacketStateFinWait2 (%p): pkt (%u) is to client: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) || SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) {
printf("StreamTcpPacketStateFinWait2 (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->server.next_seq);
return -1;
}
printf("StreamTcpPacketStateFinWait2 (%p): state changed to TCP_TIME_WAIT\n", ssn);
ssn->state = TCP_TIME_WAIT;
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack))
ssn->client.last_ack = TCP_GET_ACK(p);
StreamTcpReassembleHandleSegment(ssn, &ssn->server, p);
printf("StreamTcpPacketStateFinWait2 (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->server.next_seq, ssn->client.last_ack);
}
break;
default:
printf("StreamTcpPacketStateFinWait2 (%p): default case\n", ssn);
break;
}
return 0;
}
static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
/**
* \brief Function to handle the TCP_CLOSING state. Upon arrival of ACK
* the connection goes to TCP_TIME_WAIT state. The state has been
* reached as both end application has been closed.
*
* \param tv Thread Variable containig input/output queue, cpu affinity etc.
* \param p Packet which has to be handled in this TCP state.
* \param stt Strean Thread module registered to handle the stream handling
*/
static int StreamTcpPacketStateClosing(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
TcpSession *ssn = (TcpSession *)p->flow->stream;
switch (p->tcph->th_flags) {
switch(p->tcph->th_flags) {
case TH_ACK:
if (PKT_IS_TOSERVER(p)) {
printf("StreamTcpPacketStateFinWait2 (%p): pkt (%u) is to server: SEQ %u, ACK %u\n",
printf("StreamTcpPacketStateClosing (%p): pkt (%u) is to server: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (TCP_GET_SEQ(p) != ssn->client.next_seq) {
printf("StreamTcpPacketStateFinWait2 (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
printf("StreamTcpPacketStateClosing (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->client.next_seq);
return -1;
}
printf("StreamTcpPacketStateFinWait2 (%p): state changed to 0\n", ssn);
ssn->state = 0;
printf("StreamTcpPacketStateClosing (%p): state changed to TCP_TIME_WAIT\n", ssn);
ssn->state = TCP_TIME_WAIT;
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack))
@ -428,20 +742,20 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p, StreamTcpThre
StreamTcpReassembleHandleSegment(ssn, &ssn->client, p);
printf("StreamTcpPacketStateFinWait2 (%p): =+ next SEQ %u, last ACK %u\n",
printf("StreamTcpPacketStateClosing (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->client.next_seq, ssn->server.last_ack);
} else { /* implied to client */
printf("StreamTcpPacketStateFinWait2 (%p): pkt (%u) is to client: SEQ %u, ACK %u\n",
printf("StreamTcpPacketStateClosing (%p): pkt (%u) is to client: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (TCP_GET_SEQ(p) != ssn->server.next_seq) {
printf("StreamTcpPacketStateFinWait2 (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
printf("StreamTcpPacketStateClosing (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->server.next_seq);
return -1;
}
printf("StreamTcpPacketStateFinWait2 (%p): state changed to 0\n", ssn);
ssn->state = 0;
printf("StreamTcpPacketStateClosing (%p): state changed to TCP_TIME_WAIT\n", ssn);
ssn->state = TCP_TIME_WAIT;
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack))
@ -449,12 +763,174 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p, StreamTcpThre
StreamTcpReassembleHandleSegment(ssn, &ssn->server, p);
printf("StreamTcpPacketStateFinWait2 (%p): =+ next SEQ %u, last ACK %u\n",
printf("StreamTcpPacketStateClosing (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->server.next_seq, ssn->client.last_ack);
}
break;
default:
printf("StreamTcpPacketStateClosing (%p): default case\n", ssn);
break;
}
return 0;
}
/**
* \brief Function to handle the TCP_CLOSE_WAIT state. Upon arrival of FIN
* packet from server the connection goes to TCP_LAST_ACK state.
* The state is possible only for server host.
*
* \param tv Thread Variable containig input/output queue, cpu affinity etc.
* \param p Packet which has to be handled in this TCP state.
* \param stt Strean Thread module registered to handle the stream handling
*/
static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
TcpSession *ssn = (TcpSession *)p->flow->stream;
switch(p->tcph->th_flags) {
case TH_FIN:
if (PKT_IS_TOCLIENT(p)) {
printf("StreamTcpPacketStateCloseWait (%p): pkt (%u) is to client: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) || SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) {
printf("StreamTcpPacketStateCloseWait (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->server.next_seq);
return -1;
}
printf("StreamTcpPacketStateCloseWait (%p): state changed to TCP_LAST_ACK\n", ssn);
ssn->state = TCP_LAST_ACK;
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack))
ssn->client.last_ack = TCP_GET_ACK(p);
StreamTcpReassembleHandleSegment(ssn, &ssn->server, p);
printf("StreamTcpPacketStateCloseWait (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->server.next_seq, ssn->client.last_ack);
}
break;
default:
printf("StreamTcpPacketStateCloseWait (%p): default case\n", ssn);
break;
}
return 0;
}
/**
* \brief Function to handle the TCP_LAST_ACK state. Upon arrival of ACK
* the connection goes to TCP_CLOSED state and stream memory is
* returned back to pool. The state is possible only for server host.
*
* \param tv Thread Variable containig input/output queue, cpu affinity etc.
* \param p Packet which has to be handled in this TCP state.
* \param stt Strean Thread module registered to handle the stream handling
*/
static int StreamTcpPakcetStateLastAck(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
TcpSession *ssn = (TcpSession *)p->flow->stream;
switch(p->tcph->th_flags) {
case TH_ACK:
if (PKT_IS_TOSERVER(p)) {
printf("StreamTcpPacketStateLastAck (%p): pkt (%u) is to server: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (TCP_GET_SEQ(p) != ssn->client.next_seq) {
printf("StreamTcpPacketStateLastAck (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->client.next_seq);
return -1;
}
printf("StreamTcpPacketStateLastAck (%p): state changed to TCP_CLOSED\n", ssn);
ssn->state = TCP_CLOSED;
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack))
ssn->server.last_ack = TCP_GET_ACK(p);
StreamTcpReassembleHandleSegment(ssn, &ssn->client, p);
printf("StreamTcpPacketStateLastAck (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->client.next_seq, ssn->server.last_ack);
StreamTcpStreamReturntoPool(p);
}
break;
default:
printf("StreamTcpPacketStateLastAck (%p): default case\n", ssn);
break;
}
return 0;
}
/**
* \brief Function to handle the TCP_TIME_WAIT state. Upon arrival of ACK
* the connection goes to TCP_CLOSED state and stream memory is
* returned back to pool.
*
* \param tv Thread Variable containig input/output queue, cpu affinity etc.
* \param p Packet which has to be handled in this TCP state.
* \param stt Strean Thread module registered to handle the stream handling
*/
static int StreamTcpPacketStateTimeWait(ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
TcpSession *ssn = (TcpSession *)p->flow->stream;
switch(p->tcph->th_flags) {
case TH_ACK:
if (PKT_IS_TOSERVER(p)) {
printf("StreamTcpPacketStateTimeWait (%p): pkt (%u) is to server: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (TCP_GET_SEQ(p) != ssn->client.next_seq) {
printf("StreamTcpPacketStateTimeWait (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->client.next_seq);
return -1;
}
printf("StreamTcpPacketStateTimeWait (%p): state changed to TCP_CLOSED\n", ssn);
ssn->state = TCP_CLOSED;
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->server.last_ack))
ssn->server.last_ack = TCP_GET_ACK(p);
StreamTcpReassembleHandleSegment(ssn, &ssn->client, p);
printf("StreamTcpPacketStateTimeWait (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->client.next_seq, ssn->server.last_ack);
StreamTcpStreamReturntoPool(p);
} else {
printf("StreamTcpPacketStateTimeWait (%p): pkt (%u) is to client: SEQ %u, ACK %u\n",
ssn, p->payload_len, TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (TCP_GET_SEQ(p) != ssn->server.next_seq) {
printf("StreamTcpPacketStateTimeWait (%p): -> SEQ mismatch, packet SEQ %u != %u from stream\n",
ssn, TCP_GET_SEQ(p), ssn->server.next_seq);
return -1;
}
printf("StreamTcpPacketStateTimeWait (%p): state changed to TCP_CLOSED\n", ssn);
ssn->state = TCP_CLOSED;
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
if (SEQ_GT(TCP_GET_ACK(p),ssn->client.last_ack))
ssn->client.last_ack = TCP_GET_ACK(p);
StreamTcpReassembleHandleSegment(ssn, &ssn->server, p);
printf("StreamTcpPacketStateTimeWait (%p): =+ next SEQ %u, last ACK %u\n",
ssn, ssn->server.next_seq, ssn->client.last_ack);
StreamTcpStreamReturntoPool(p);
}
break;
default:
printf("StreamTcpPacketStateTimeWait (%p): default case\n", ssn);
break;
}
return 0;
}
@ -462,7 +938,7 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p, StreamTcpThre
static int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
TcpSession *ssn = (TcpSession *)p->flow->stream;
if (ssn == NULL || ssn->state == 0) {
if (ssn == NULL || ssn->state == 0 || ssn->state == TCP_CLOSED) {
StreamTcpPacketStateNone(tv, p, stt);
} else {
switch (ssn->state) {
@ -481,6 +957,18 @@ static int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt) {
case TCP_FIN_WAIT2:
StreamTcpPacketStateFinWait2(tv, p, stt);
break;
case TCP_CLOSING:
StreamTcpPacketStateClosing(tv, p, stt);
break;
case TCP_CLOSE_WAIT:
StreamTcpPacketStateCloseWait(tv, p, stt);
break;
case TCP_LAST_ACK:
StreamTcpPakcetStateLastAck(tv, p, stt);
break;
case TCP_TIME_WAIT:
StreamTcpPacketStateTimeWait(tv, p, stt);
break;
}
}
@ -556,3 +1044,192 @@ void StreamTcpExitPrintStats(ThreadVars *tv, void *data) {
printf(" - (%s) Packets %llu.\n", tv->name, stt->pkts);
}
/**
* \brief Function to check the validity of the RST packets based on the target
* OS of the given packet.
*
* \param ssn TCP session to which the given packet belongs
* \param p Packet which has to be checked for its validity
*/
static int ValidReset(TcpSession *ssn, Packet *p) {
u_int8_t os_policy;
if (PKT_IS_TOSERVER(p))
os_policy = ssn->server.os_policy;
else
os_policy = ssn->client.os_policy;
switch(os_policy) {
case OS_POLICY_BSD:
case OS_POLICY_FIRST:
case OS_POLICY_HPUX10:
case OS_POLICY_IRIX:
case OS_POLICY_MACOS:
case OS_POLICY_LAST:
case OS_POLICY_WINDOWS:
case OS_POLICY_WINDOWS2K3:
case OS_POLICY_VISTA:
if(PKT_IS_TOSERVER(p)){
if(SEQ_EQ(TCP_GET_SEQ(p), ssn->client.next_seq)) {
printf("Reset is Valid! Pakcet SEQ: %d", TCP_GET_SEQ(p));
return 1;
} else {
printf("Reset is not Valid! Packet SEQ: %d and server SEQ: %d", TCP_GET_SEQ(p), ssn->client.next_seq );
return 0;
}
} else { /* implied to client */
if(SEQ_EQ(TCP_GET_SEQ(p), ssn->server.next_seq)) {
printf("Reset is Valid! Pakcet SEQ: %d", TCP_GET_SEQ(p));
return 1;
} else {
printf("Reset is not Valid! Packet SEQ: %d and client SEQ: %d", TCP_GET_SEQ(p), ssn->server.next_seq );
return 0;
}
}
break;
case OS_POLICY_HPUX11:
if(PKT_IS_TOSERVER(p)){
if(SEQ_GEQ(TCP_GET_SEQ(p), ssn->client.next_seq)) {
printf("Reset is Valid! Pakcet SEQ: %d", TCP_GET_SEQ(p));
return 1;
} else {
printf("Reset is not Valid! Packet SEQ: %d and server SEQ: %d", TCP_GET_SEQ(p), ssn->client.next_seq );
return 0;
}
} else { /* implied to client */
if(SEQ_GEQ(TCP_GET_SEQ(p), ssn->server.next_seq)) {
printf("Reset is Valid! Pakcet SEQ: %d", TCP_GET_SEQ(p));
return 1;
} else {
printf("Reset is not Valid! Packet SEQ: %d and client SEQ: %d", TCP_GET_SEQ(p), ssn->server.next_seq );
return 0;
}
}
break;
case OS_POLICY_OLD_LINUX:
case OS_POLICY_LINUX:
case OS_POLICY_SOLARIS:
if(PKT_IS_TOSERVER(p)){
if(SEQ_GEQ((TCP_GET_SEQ(p)+p->payload_len), ssn->client.last_ack)) { /*window base is needed !!*/
if(SEQ_LT(TCP_GET_SEQ(p), (ssn->client.next_seq + ssn->client.window))) {
printf("Reset is Valid! Pakcet SEQ: %d", TCP_GET_SEQ(p));
return 1;
}
} else {
printf("Reset is not Valid! Packet SEQ: %d and server SEQ: %d", TCP_GET_SEQ(p), ssn->client.next_seq );
return 0;
}
} else { /* implied to client */
if(SEQ_GEQ((TCP_GET_SEQ(p) + p->payload_len), ssn->server.last_ack)) { /*window base is needed !!*/
if(SEQ_LT(TCP_GET_SEQ(p), (ssn->server.next_seq + ssn->server.window))) {
printf("Reset is Valid! Pakcet SEQ: %d", TCP_GET_SEQ(p));
return 1;
}
} else {
printf("Reset is not Valid! Packet SEQ: %d and client SEQ: %d", TCP_GET_SEQ(p), ssn->server.next_seq );
return 0;
}
}
break;
default:
printf("Reset is not Valid! Packet SEQ: %d", TCP_GET_SEQ(p));
break;
}
return 0;
}
/**
* \brief Function to return the stream back to the pool.
*
* \param p Packet used to identify the stream.
*/
void StreamTcpStreamReturntoPool (Packet *p) {
/* get a stream */
mutex_lock(&ssn_pool_mutex);
PoolReturn(ssn_pool, p->flow->stream);
mutex_unlock(&ssn_pool_mutex);
p->flow->stream = NULL;
}
/*static int StreamTcpReassembleTest01 (void) {
TcpSession ssn;
TcpStream cstream, sstream;
Packet p;
ThreadVars tv;
Flow f;
StreamTcpThread stt;
TCPHdr tcph;
u_int8_t payload[] = { 0x41, 0x41, 0x41 };
memset(&tv, 0, sizeof(ThreadVars));
memset(&ssn, 0, sizeof(TcpSession));
memset(&cstream, 0, sizeof(TcpStream));
memset(&sstream, 0, sizeof(TcpStream));
memset(&p, 0, sizeof(Packet));
memset(&f, 0, sizeof(Flow));
memset(&stt, 0, sizeof(StreamTcpThread));
memset(&tcph, 0, sizeof(TCPHdr));
cstream.os_policy = OS_POLICY_BSD;
sstream.os_policy = OS_POLICY_BSD;
//ssn.state = 0;
ssn.client = cstream;
ssn.server = sstream;
ssn.client.isn = 10;
ssn.server.isn = 30;
f.stream = &ssn;
p.src.family = AF_INET;
p.dst.family = AF_INET;
//p.src = Address"10.0.0.1";
//p.dst = "10.0.0.2";
p.payload = NULL;
p.payload_len = 0;
p.proto = IPPROTO_TCP;
tcph.th_seq = htonl(10);
tcph.th_win = 5480;
tcph.th_flags = TH_SYN;
p.tcph = &tcph;
p.flowflags = FLOW_PKT_TOSERVER;
p.flow = &f;
printf("I am executing hello world!!\n");
//for (i=0; i<39; i++) {
//p = (Packet)pkts[i];
StreamTcpPacket(&tv, &p, &stt);
//}
tcph.th_seq = htonl(30);
tcph.th_ack = htonl(11);
tcph.th_win = 5480;
tcph.th_flags = TH_SYN|TH_ACK;
p.tcph = &tcph;
p.flowflags = FLOW_PKT_TOCLIENT;
StreamTcpPacket(&tv, &p, &stt);
tcph.th_seq = htonl(11);
tcph.th_ack = htonl(31);
tcph.th_win = 5480;
tcph.th_flags = TH_ACK;
p.tcph = &tcph;
p.flowflags = FLOW_PKT_TOSERVER;
StreamTcpPacket(&tv, &p, &stt);
tcph.th_seq = htonl(12);
tcph.th_ack = htonl(31);
tcph.th_win = 5480;
tcph.th_flags = TH_PUSH|TH_ACK;
p.tcph = &tcph;
//payload =
p.payload = payload;
p.payload_len = 3;
p.flowflags = FLOW_PKT_TOSERVER;
StreamTcpPacket(&tv, &p, &stt);
return 1;
}
void SreamTcpReassembleRegisterTests (void) {
UtRegisterTest("StreamTcpReassembleTest01", StreamTcpReassembleTest01, 1);
UtRunTests();
}*/

Loading…
Cancel
Save