timestamp support

remotes/origin/master-1.0.x
Gurvinder Singh 15 years ago committed by Victor Julien
parent 7aaad91f39
commit 3350245f75

@ -18,7 +18,9 @@ typedef struct TcpStream_ {
uint32_t window; /**< current window setting */
uint8_t wscale; /**< wscale setting in this direction */
uint32_t last_ts; /*Time stamp of last seen packet*/
uint32_t last_ts; /**< Time stamp of last seen packet*/
uint32_t last_pkt_ts; /**< Time of last seen packet for this stream (needed for PAWS update)*/
/* reassembly */
uint32_t ra_base_seq; /**< reassembled seq. We've reassembled up to this point. */
TcpSegment *seg_list; /**< list of TCP segments that are not yet (fully) used in reassembly */
@ -44,8 +46,11 @@ enum
#define STREAMTCP_FLAG_MIDSTREAM 0x01 /*Flag for mid stream session*/
#define STREAMTCP_FLAG_MIDSTREAM_ESTABLISHED 0x02 /*Flag for mid stream established session*/
#define STREAMTCP_TIMESTAMP 0x04 /*Flag for TCP Timestamp option*/
#define STREAMTCP_FLAG_SERVER_WSCALE 0x08 /**< Server supports wscale (even though it can be 0) */
#define PAWS_24DAYS 2073600 /* 24 days in seconds */
/* Macro's for comparing Sequence numbers
* Page 810 from TCP/IP Illustrated, Volume 2. */
#define SEQ_EQ(a,b) ((int)((a) - (b)) == 0)
@ -54,6 +59,8 @@ enum
#define SEQ_GT(a,b) ((int)((a) - (b)) > 0)
#define SEQ_GEQ(a,b) ((int)((a) - (b)) >= 0)
#define GET_TIMESTAMP(p) ((u_int32_t) ntohl (*(u_int32_t *)(p)))
typedef struct TcpSession_ {
uint8_t state;
uint8_t flags;

@ -36,6 +36,7 @@ void StreamTcpReturnStreamSegments (TcpStream *);
void StreamTcpInitConfig(char);
extern void StreamTcpSegmentReturntoPool(TcpSegment *);
int StreamTcpGetFlowState(void *);
static int ValidTimestamp(TcpSession * , Packet *);
#define STREAMTCP_DEFAULT_SESSIONS 262144
#define STREAMTCP_DEFAULT_PREALLOC 32768
@ -292,8 +293,15 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p, StreamTcpThread *
ssn->client.isn = TCP_GET_SEQ(p);
ssn->client.ra_base_seq = ssn->client.isn;
ssn->client.next_seq = ssn->client.isn + 1;
if (p->tcpvars.ts != NULL)
ssn->client.last_ts = *p->tcpvars.ts->data;
if (p->tcpvars.ts != NULL) {
ssn->client.last_ts = GET_TIMESTAMP(p->tcpvars.ts->data);
#ifdef DEBUG
printf("StreamTcpPacketStateNone (%p): p->tcpvars.ts %p, %02x\n", ssn, p->tcpvars.ts, ssn->client.last_ts);
#endif
ssn->client.last_pkt_ts = p->ts.tv_sec;
}
ssn->server.window = TCP_GET_WINDOW(p);
if (p->tcpvars.ws != NULL) {
@ -351,6 +359,19 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p, StreamTcpThread *
printf("StreamTcpPacketStateNone (%p): ssn->server.isn %"PRIu32", ssn->server.next_seq %"PRIu32", ssn->server.last_ack %"PRIu32"\n",
ssn, ssn->server.isn, ssn->server.next_seq, ssn->server.last_ack);
#endif
if (p->tcpvars.ts != NULL) {
ssn->server.last_ts = GET_TIMESTAMP(p->tcpvars.ts->data);
ssn->client.last_ts = GET_TIMESTAMP((p->tcpvars.ts->data) + 4);
#ifdef DEBUG
printf("StreamTcpPacketStateNone (%p): ssn->server.last_ts %" PRIu32" ssn->client.last_ts %" PRIu32"\n", ssn, ssn->server.last_ts, ssn->client.last_ts);
#endif
ssn->flags |= STREAMTCP_TIMESTAMP;
ssn->server.last_pkt_ts = p->ts.tv_sec;
} else {
ssn->server.last_ts = 0;
ssn->client.last_ts = 0;
}
break;
/* Handle SYN/ACK and 3WHS shake missed together as it is almost similar. */
case TH_ACK:
@ -400,6 +421,19 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p, StreamTcpThread *
ssn->client.wscale = TCP_WSCALE_MAX;
ssn->server.wscale = TCP_WSCALE_MAX;
if (p->tcpvars.ts != NULL) {
ssn->server.last_ts = GET_TIMESTAMP (p->tcpvars.ts->data);
ssn->client.last_ts = GET_TIMESTAMP ((p->tcpvars.ts->data) + 4);
#ifdef DEBUG
printf("StreamTcpPacketStateNone (%p): ssn->server.last_ts %" PRIu32" ssn->client.last_ts %" PRIu32"\n", ssn, ssn->server.last_ts, ssn->client.last_ts);
#endif
ssn->flags |= STREAMTCP_TIMESTAMP;
ssn->client.last_pkt_ts = p->ts.tv_sec;
} else {
ssn->server.last_ts = 0;
ssn->client.last_ts = 0;
}
StreamTcpReassembleHandleSegment(ssn, &ssn->client, p);
break;
case TH_RST:
@ -477,8 +511,13 @@ static int StreamTcpPacketStateSynSent(ThreadVars *tv, Packet *p, StreamTcpThrea
#ifdef DEBUG
printf("StreamTcpPacketStateSynSent (%p): window %" PRIu32 "\n", ssn, ssn->server.window);
#endif
if (p->tcpvars.ts != NULL) {
ssn->server.last_ts = *p->tcpvars.ts->data;
if (p->tcpvars.ts != NULL && ssn->client.last_ts != 0) {
ssn->server.last_ts = GET_TIMESTAMP (p->tcpvars.ts->data);
#ifdef DEBUG
printf("StreamTcpPacketStateSynSent (%p): ssn->server.last_ts %" PRIu32" ssn->client.last_ts %" PRIu32"\n", ssn, ssn->server.last_ts, ssn->client.last_ts);
#endif
ssn->flags |= STREAMTCP_TIMESTAMP;
ssn->server.last_pkt_ts = p->ts.tv_sec;
} else {
ssn->client.last_ts = 0;
ssn->server.last_ts = 0;
@ -584,6 +623,9 @@ static int StreamTcpPacketStateSynRecv(ThreadVars *tv, Packet *p, StreamTcpThrea
ssn->server.window = TCP_GET_WINDOW(p) << ssn->server.wscale;
ssn->server.next_win = ssn->server.last_ack + ssn->server.window;
if (ssn->flags & STREAMTCP_TIMESTAMP)
ssn->client.last_pkt_ts = p->ts.tv_sec;
#ifdef DEBUG
printf("StreamTcpPacketStateSynRecv (%p): ssn->server.next_win %" PRIu32 ", ssn->server.last_ack %"PRIu32"\n", ssn, ssn->server.next_win, ssn->server.last_ack);
#endif
@ -638,6 +680,10 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, StreamTcpT
break;
case TH_ACK:
case TH_ACK|TH_PUSH:
if (!ValidTimestamp(ssn, p))
return -1;
if (PKT_IS_TOSERVER(p)) {
#ifdef DEBUG
printf("StreamTcpPacketStateEstablished (%p): =+ pkt (%" PRIu32 ") is to server: SEQ %" PRIu32 ", ACK %" PRIu32 ", WIN %"PRIu16"\n",
@ -648,6 +694,8 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, StreamTcpT
#ifdef DEBUG
printf("StreamTcpPacketStateEstablished (%p): ssn->client.next_seq %" PRIu32 "\n", ssn, ssn->client.next_seq);
#endif
if (ssn->flags & STREAMTCP_TIMESTAMP)
ssn->client.last_ts = GET_TIMESTAMP(p->tcpvars.ts->data);
}
if (SEQ_GEQ(TCP_GET_SEQ(p), ssn->client.last_ack)) {
@ -671,6 +719,8 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, StreamTcpT
printf("StreamTcpPacketStateEstablished (%p): seq %"PRIu32", updated ssn->server.next_win %" PRIu32 " (win %"PRIu32")\n", ssn, TCP_GET_SEQ(p), ssn->server.next_win, ssn->server.window);
#endif
}
if (ssn->flags & STREAMTCP_TIMESTAMP)
ssn->client.last_pkt_ts = p->ts.tv_sec;
StreamTcpReassembleHandleSegment(ssn, &ssn->client, p);
} else {
@ -712,6 +762,8 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, StreamTcpT
#ifdef DEBUG
printf("StreamTcpPacketStateEstablished (%p): ssn->server.next_seq %" PRIu32 "\n", ssn, ssn->server.next_seq);
#endif
if (ssn->flags & STREAMTCP_TIMESTAMP)
ssn->server.last_ts = GET_TIMESTAMP(p->tcpvars.ts->data);
}
if (SEQ_GEQ(TCP_GET_SEQ(p), ssn->server.last_ack)) {
@ -738,6 +790,8 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p, StreamTcpT
printf("StreamTcpPacketStateEstablished (%p): seq %"PRIu32", keeping ssn->client.next_win %" PRIu32 " the same (win %"PRIu32")\n", ssn, TCP_GET_SEQ(p), ssn->client.next_win, ssn->client.window);
#endif
}
if (ssn->flags & STREAMTCP_TIMESTAMP)
ssn->server.last_pkt_ts = p->ts.tv_sec;
StreamTcpReassembleHandleSegment(ssn, &ssn->server, p);
} else {
@ -1736,6 +1790,15 @@ int StreamTcpGetFlowState(void *s) {
return FLOW_STATE_CLOSED;
}
static int ValidTimestamp (TcpSession *ssn, Packet *p) {
/*XXX GS its WIP*/
if (!(ssn->flags & STREAMTCP_TIMESTAMP)) {
return 1;
} else {
}
return 1;
}
#ifdef UNITTESTS

Loading…
Cancel
Save