Don't handle and validate the TCP timestamp at the same time. Instead validate first, then later when all other validation has been done as well, handle.

remotes/origin/master-1.1.x
Victor Julien 15 years ago
parent 8d3f9c53a9
commit a8bb98836b

@ -103,6 +103,7 @@ int StreamTcpGetFlowState(void *);
void StreamTcpSetOSPolicy(TcpStream*, Packet*);
void StreamTcpPseudoPacketCreateStreamEndPacket(Packet *, TcpSession *, PacketQueue *);
static int StreamTcpValidateTimestamp(TcpSession * , Packet *);
static int StreamTcpHandleTimestamp(TcpSession * , Packet *);
static int StreamTcpValidateRst(TcpSession * , Packet *);
static inline int StreamTcpValidateAck(TcpStream *, Packet *);
@ -1302,7 +1303,7 @@ static int StreamTcpPacketStateSynRecv(ThreadVars *tv, Packet *p,
* stream->last_ts. If the timestamp is valid then process the
* packet normally otherwise the drop the packet (RFC 1323)*/
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
if (!(StreamTcpHandleTimestamp(ssn, p))) {
if (!(StreamTcpValidateTimestamp(ssn, p))) {
return -1;
}
}
@ -1327,6 +1328,10 @@ static int StreamTcpPacketStateSynRecv(ThreadVars *tv, Packet *p,
"%" PRIu32 ", ACK %" PRIu32 "", ssn, p->payload_len,
TCP_GET_SEQ(p), TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
ssn->server.next_seq += p->payload_len;
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
@ -1377,6 +1382,10 @@ static int StreamTcpPacketStateSynRecv(ThreadVars *tv, Packet *p,
/* process the packet normal, No Async streams :) */
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
ssn->client.next_seq += p->payload_len;
@ -1414,6 +1423,10 @@ static int StreamTcpPacketStateSynRecv(ThreadVars *tv, Packet *p,
ssn->client.window = TCP_GET_WINDOW(p) << ssn->client.wscale;
ssn->client.last_ack = TCP_GET_ACK(p);
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
if (ssn->flags & STREAMTCP_FLAG_MIDSTREAM) {
ssn->server.window = TCP_GET_WINDOW(p);
ssn->client.next_win = ssn->server.last_ack +
@ -1497,6 +1510,10 @@ static int StreamTcpPacketStateSynRecv(ThreadVars *tv, Packet *p,
SCLogDebug("ssn %p: Reset received and state changed to "
"TCP_CLOSED", ssn);
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
StreamTcpSessionPktFree(p);
}
} else
@ -1506,7 +1523,7 @@ static int StreamTcpPacketStateSynRecv(ThreadVars *tv, Packet *p,
/* FIN is handled in the same way as in TCP_ESTABLISHED case */;
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
if (!StreamTcpHandleTimestamp(ssn, p))
if (!StreamTcpValidateTimestamp(ssn, p))
return -1;
}
@ -1630,6 +1647,10 @@ static int HandleEstablishedPacketToServer(ThreadVars *tv, TcpSession *ssn, Pack
/* Check if the ACK value is sane and inside the window limit */
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the server packet
and client has already received and acked it */
if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p)))
@ -1732,6 +1753,10 @@ static int HandleEstablishedPacketToClient(ThreadVars *tv, TcpSession *ssn, Pack
StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client packet
and server has already received and acked it */
if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p)))
@ -1852,7 +1877,7 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p,
* stream->last_ts. If the timestamp is valid then process the
* packet normally otherwise the drop the packet (RFC 1323) */
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
if (!StreamTcpHandleTimestamp(ssn, p))
if (!StreamTcpValidateTimestamp(ssn, p))
return -1;
}
@ -1886,7 +1911,7 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p,
case TH_FIN|TH_ACK|TH_PUSH|TH_ECN|TH_CWR:
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
if (!StreamTcpHandleTimestamp(ssn, p))
if (!StreamTcpValidateTimestamp(ssn, p))
return -1;
}
@ -1923,6 +1948,10 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn,
&ssn->client, p, pq);
SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
@ -1943,6 +1972,10 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
StreamTcpReassembleHandleSegment(tv, stt->ra_ctx, ssn,
&ssn->server, p, pq);
SCLogDebug("ssn %p: =+ next SEQ %" PRIu32 ", last ACK "
@ -1978,7 +2011,6 @@ static int StreamTcpPacketStateEstablished(ThreadVars *tv, Packet *p,
static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt,
TcpSession *ssn, Packet *p, PacketQueue *pq)
{
if (PKT_IS_TOSERVER(p)) {
SCLogDebug("ssn %p: pkt (%" PRIu32 ") is to server: SEQ %" PRIu32 ","
" ACK %" PRIu32 "", ssn, p->payload_len, TCP_GET_SEQ(p),
@ -2013,6 +2045,10 @@ static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt,
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client packet
and server has already received and acked it */
if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p)))
@ -2056,6 +2092,10 @@ static int StreamTcpHandleFin(ThreadVars *tv, StreamTcpThread *stt,
StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client packet
and server has already received and acked it */
if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p)))
@ -2097,7 +2137,7 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
case TH_ACK|TH_ECN|TH_CWR:
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
if (!StreamTcpHandleTimestamp(ssn, p))
if (!StreamTcpValidateTimestamp(ssn, p))
return -1;
}
@ -2128,6 +2168,10 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client
packet and server has already received and acked it */
if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p)))
@ -2173,6 +2217,10 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client
packet and server has already received and acked it */
if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p)))
@ -2202,7 +2250,7 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
case TH_FIN|TH_ACK|TH_PUSH|TH_ECN|TH_CWR:
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
if (!StreamTcpHandleTimestamp(ssn, p))
if (!StreamTcpValidateTimestamp(ssn, p))
return -1;
}
@ -2234,6 +2282,10 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client
packet and server has already received and acked it */
if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p)))
@ -2279,6 +2331,10 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client
packet and server has already received and acked it */
if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p)))
@ -2313,6 +2369,10 @@ static int StreamTcpPacketStateFinWait1(ThreadVars *tv, Packet *p,
SCLogDebug("ssn %p: Reset received state changed to TCP_CLOSED",
ssn);
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
StreamTcpSessionPktFree(p);
}
else
@ -2350,7 +2410,7 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
case TH_ACK|TH_ECN|TH_CWR:
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
if (!StreamTcpHandleTimestamp(ssn, p))
if (!StreamTcpValidateTimestamp(ssn, p))
return -1;
}
@ -2380,6 +2440,10 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
if (SEQ_EQ(ssn->client.next_seq, TCP_GET_SEQ(p))) {
ssn->client.next_seq += p->payload_len;
SCLogDebug("ssn %p: ssn->client.next_seq %" PRIu32 "",
@ -2418,6 +2482,10 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
if (SEQ_EQ(ssn->server.next_seq, TCP_GET_SEQ(p))) {
ssn->server.next_seq += p->payload_len;
SCLogDebug("ssn %p: ssn->server.next_seq %" PRIu32 "",
@ -2447,6 +2515,10 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
SCLogDebug("ssn %p: Reset received state changed to TCP_CLOSED",
ssn);
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
StreamTcpSessionPktFree(p);
}
else
@ -2455,7 +2527,7 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
case TH_FIN:
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
if (!StreamTcpHandleTimestamp(ssn, p))
if (!StreamTcpValidateTimestamp(ssn, p))
return -1;
}
@ -2487,6 +2559,10 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client
packet and server has already received and acked it */
if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p)))
@ -2526,6 +2602,10 @@ static int StreamTcpPacketStateFinWait2(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client
packet and server has already received and acked it */
if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p)))
@ -2569,7 +2649,7 @@ static int StreamTcpPacketStateClosing(ThreadVars *tv, Packet *p,
case TH_ACK|TH_ECN|TH_CWR:
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
if (!StreamTcpHandleTimestamp(ssn, p))
if (!StreamTcpValidateTimestamp(ssn, p))
return -1;
}
@ -2599,6 +2679,9 @@ static int StreamTcpPacketStateClosing(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client
packet and server has already received and acked it */
if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p)))
@ -2635,6 +2718,10 @@ static int StreamTcpPacketStateClosing(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client
packet and server has already received and acked it */
if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p)))
@ -2690,7 +2777,7 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p,
case TH_FIN|TH_ACK|TH_ECN|TH_CWR:
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
if (!StreamTcpHandleTimestamp(ssn, p))
if (!StreamTcpValidateTimestamp(ssn, p))
SCReturnInt(-1);
}
@ -2722,6 +2809,10 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client
packet and server has already received and acked it */
if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p)))
@ -2760,6 +2851,10 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client
packet and server has already received and acked it */
if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p)))
@ -2778,7 +2873,7 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p,
case TH_ACK|TH_ECN:
case TH_ACK|TH_ECN|TH_CWR:
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
if (!StreamTcpHandleTimestamp(ssn, p))
if (!StreamTcpValidateTimestamp(ssn, p))
SCReturnInt(-1);
}
@ -2807,6 +2902,10 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client
packet and server has already received and acked it */
if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p)))
@ -2845,6 +2944,10 @@ static int StreamTcpPacketStateCloseWait(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client
packet and server has already received and acked it */
if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p)))
@ -2890,7 +2993,7 @@ static int StreamTcpPakcetStateLastAck(ThreadVars *tv, Packet *p,
case TH_ACK|TH_ECN|TH_CWR:
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
if (!StreamTcpHandleTimestamp(ssn, p))
if (!StreamTcpValidateTimestamp(ssn, p))
return -1;
}
@ -2920,6 +3023,10 @@ static int StreamTcpPakcetStateLastAck(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client
packet and server has already received and acked it */
if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p)))
@ -2964,7 +3071,7 @@ static int StreamTcpPacketStateTimeWait(ThreadVars *tv, Packet *p,
case TH_ACK|TH_ECN|TH_CWR:
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
if (!StreamTcpHandleTimestamp(ssn, p))
if (!StreamTcpValidateTimestamp(ssn, p))
return -1;
}
@ -2994,6 +3101,10 @@ static int StreamTcpPacketStateTimeWait(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->server, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client
packet and server has already received and acked it */
if (SEQ_LT(ssn->server.next_seq, TCP_GET_ACK(p)))
@ -3032,6 +3143,10 @@ static int StreamTcpPacketStateTimeWait(ThreadVars *tv, Packet *p,
StreamTcpUpdateLastAck(ssn, &ssn->client, TCP_GET_ACK(p));
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
StreamTcpHandleTimestamp(ssn, p);
}
/* Update the next_seq, in case if we have missed the client
packet and server has already received and acked it */
if (SEQ_LT(ssn->client.next_seq, TCP_GET_ACK(p)))
@ -3363,7 +3478,7 @@ static int StreamTcpValidateRst(TcpSession *ssn, Packet *p)
uint8_t os_policy;
if (ssn->flags & STREAMTCP_FLAG_TIMESTAMP) {
if (!StreamTcpHandleTimestamp(ssn, p))
if (!StreamTcpValidateTimestamp(ssn, p))
return -1;
}
@ -3537,6 +3652,152 @@ int StreamTcpGetFlowState(void *s)
SCReturnInt(FLOW_STATE_CLOSED);
}
/**
* \brief Function to check the validity of the received timestamp based on
* the target OS of the given stream.
*
* It's passive except for:
* 1. it sets the os policy on the stream if necessary
* 2. it sets an event in the packet if necessary
*
* \param ssn TCP session to which the given packet belongs
* \param p Packet which has to be checked for its validity
*
* \retval 1 if the timestamp is valid
* \retval 0 if the timestamp is invalid
*/
static int StreamTcpValidateTimestamp (TcpSession *ssn, Packet *p)
{
SCEnter();
TcpStream *sender_stream;
TcpStream *receiver_stream;
uint8_t ret = 1;
uint8_t check_ts = 1;
if (PKT_IS_TOSERVER(p)) {
sender_stream = &ssn->client;
receiver_stream = &ssn->server;
} else {
sender_stream = &ssn->server;
receiver_stream = &ssn->client;
}
/* Set up the os_policy to be used in validating the timestamps based on
the target system */
if (receiver_stream->os_policy == 0) {
StreamTcpSetOSPolicy(receiver_stream, p);
}
if (p->tcpvars.ts != NULL) {
uint32_t ts = TCP_GET_TSVAL(p);
uint32_t last_pkt_ts = sender_stream->last_pkt_ts;
uint32_t last_ts = sender_stream->last_ts;
if (sender_stream->flags & STREAMTCP_FLAG_ZERO_TIMESTAMP) {
/* The 3whs used the timestamp with 0 value. */
switch (receiver_stream->os_policy) {
case OS_POLICY_LINUX:
case OS_POLICY_WINDOWS2K3:
/* Linux and windows 2003 does not allow the use of 0 as
* timestamp in the 3whs. */
check_ts = 0;
break;
case OS_POLICY_OLD_LINUX:
case OS_POLICY_WINDOWS:
case OS_POLICY_VISTA:
if (SEQ_EQ(sender_stream->next_seq, TCP_GET_SEQ(p))) {
last_ts = ts;
check_ts = 0; /*next packet will be checked for validity
and stream TS has been updated with this
one.*/
}
break;
}
}
if (receiver_stream->os_policy == OS_POLICY_HPUX11) {
/* HPUX11 igoners the timestamp of out of order packets */
if (!SEQ_EQ(sender_stream->next_seq, TCP_GET_SEQ(p)))
check_ts = 0;
}
if (ts == 0) {
switch (receiver_stream->os_policy) {
case OS_POLICY_OLD_LINUX:
case OS_POLICY_WINDOWS:
case OS_POLICY_WINDOWS2K3:
case OS_POLICY_VISTA:
case OS_POLICY_SOLARIS:
/* Old Linux and windows allowed packet with 0 timestamp. */
break;
default:
/* other OS simply drop the pakcet with 0 timestamp, when
* 3whs has valid timestamp*/
goto invalid;
}
}
if (check_ts) {
int32_t result = 0;
SCLogDebug("ts %"PRIu32", last_ts %"PRIu32"", ts, last_ts);
if (receiver_stream->os_policy == OS_POLICY_LINUX) {
/* Linux accepts TS which are off by one.*/
result = (int32_t) ((ts - last_ts) + 1);
} else {
result = (int32_t) (ts - last_ts);
}
SCLogDebug("result %"PRIi32", p->ts.tv_sec %"PRIuMAX"", result, (uintmax_t)p->ts.tv_sec);
if (last_pkt_ts == 0 &&
(ssn->flags & STREAMTCP_FLAG_MIDSTREAM))
{
last_pkt_ts = p->ts.tv_sec;
}
if (result < 0) {
SCLogDebug("timestamp is not valid last_ts "
"%" PRIu32 " p->tcpvars->ts %" PRIu32 " result "
"%" PRId32 "", last_ts, ts, result);
/* candidate for rejection */
ret = 0;
} else if ((sender_stream->last_ts != 0) &&
(((uint32_t) p->ts.tv_sec) >
last_pkt_ts + PAWS_24DAYS))
{
SCLogDebug("packet is not valid last_pkt_ts "
"%" PRIu32 " p->ts.tv_sec %" PRIu32 "",
last_pkt_ts, (uint32_t) p->ts.tv_sec);
/* candidate for rejection */
ret = 0;
}
if (ret == 0) {
/* if the timestamp of packet is not valid then, check if the
* current stream timestamp is not so old. if so then we need to
* accept the packet and update the stream->last_ts (RFC 1323)*/
if ((SEQ_EQ(sender_stream->next_seq, TCP_GET_SEQ(p))) &&
(((uint32_t) p->ts.tv_sec > (last_pkt_ts + PAWS_24DAYS))))
{
SCLogDebug("timestamp considered valid anyway");
} else {
goto invalid;
}
}
}
}
SCReturnInt(1);
invalid:
StreamTcpSetEvent(p, STREAM_PKT_INVALID_TIMESTAMP);
SCReturnInt(0);
}
/**
* \brief Function to check the validity of the received timestamp based on
* the target OS of the given stream and update the session.

Loading…
Cancel
Save