From d03773840bfa424ead3826ff7e5636bf542ed1a5 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Thu, 16 Feb 2023 06:17:24 +0100 Subject: [PATCH] stream: track packet flags in packet These flags can then later be used by stream logging. --- src/decode-tcp.h | 1 + src/stream-tcp-private.h | 32 ++++++++++++++++++++++---------- src/stream-tcp.c | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/decode-tcp.h b/src/decode-tcp.h index 3b291dd9a4..4b26df5c26 100644 --- a/src/decode-tcp.h +++ b/src/decode-tcp.h @@ -160,6 +160,7 @@ typedef struct TCPVars_ bool ts_set; uint32_t ts_val; /* host-order */ uint32_t ts_ecr; /* host-order */ + uint16_t stream_pkt_flags; TCPOpt sack; TCPOpt sackok; TCPOpt ws; diff --git a/src/stream-tcp-private.h b/src/stream-tcp-private.h index 0a42f306f8..77d0dc4307 100644 --- a/src/stream-tcp-private.h +++ b/src/stream-tcp-private.h @@ -259,16 +259,18 @@ enum TcpState { } while(0); \ } -#define StreamTcpSetEvent(p, e) { \ - if ((p)->flags & PKT_STREAM_NO_EVENTS) { \ - SCLogDebug("not setting event %d on pkt %p (%"PRIu64"), " \ - "stream in known bad condition", (e), p, (p)->pcap_cnt); \ - } else { \ - SCLogDebug("setting event %d on pkt %p (%"PRIu64")", \ - (e), p, (p)->pcap_cnt); \ - ENGINE_SET_EVENT((p), (e)); \ - } \ -} +#define StreamTcpSetEvent(p, e) \ + { \ + if ((p)->flags & PKT_STREAM_NO_EVENTS) { \ + SCLogDebug("not setting event %d on pkt %p (%" PRIu64 "), " \ + "stream in known bad condition", \ + (e), p, (p)->pcap_cnt); \ + } else { \ + SCLogDebug("setting event %d on pkt %p (%" PRIu64 ")", (e), p, (p)->pcap_cnt); \ + ENGINE_SET_EVENT((p), (e)); \ + p->tcpvars.stream_pkt_flags |= STREAM_PKT_FLAG_EVENTSET; \ + } \ + } typedef struct TcpSession_ { PoolThreadId pool_id; @@ -297,4 +299,14 @@ typedef struct TcpSession_ { ((ssn)->flags |= STREAMTCP_FLAG_APP_LAYER_DISABLED); \ } while (0); +#define STREAM_PKT_FLAG_RETRANSMISSION BIT_U16(0) +#define STREAM_PKT_FLAG_SPURIOUS_RETRANSMISSION BIT_U16(1) +#define STREAM_PKT_FLAG_STATE_UPDATE BIT_U16(2) +#define STREAM_PKT_FLAG_KEEPALIVE BIT_U16(3) +#define STREAM_PKT_FLAG_KEEPALIVEACK BIT_U16(4) +#define STREAM_PKT_FLAG_WINDOWUPDATE BIT_U16(5) +#define STREAM_PKT_FLAG_EVENTSET BIT_U16(6) + +#define STREAM_PKT_FLAG_SET(p, f) (p)->tcpvars.stream_pkt_flags |= (f) + #endif /* __STREAM_TCP_PRIVATE_H__ */ diff --git a/src/stream-tcp.c b/src/stream-tcp.c index 4e4225d7e8..7738d1b0f3 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -763,6 +763,7 @@ static void StreamTcpPacketSetState(Packet *p, TcpSession *ssn, ssn->pstate = ssn->state; ssn->state = state; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_STATE_UPDATE); /* update the flow state */ switch(ssn->state) { @@ -2897,9 +2898,9 @@ static bool StreamTcpPacketIsOutdatedAck(TcpSession *ssn, Packet *p) * \brief check if packet is before ack'd windows * If packet is before last ack, we will not accept it */ -static bool StreamTcpPacketIsSpuriousRetransmission(TcpSession *ssn, Packet *p) +static bool StreamTcpPacketIsSpuriousRetransmission(const TcpSession *ssn, Packet *p) { - TcpStream *stream; + const TcpStream *stream; if (PKT_IS_TOCLIENT(p)) { stream = &ssn->server; } else { @@ -2912,6 +2913,7 @@ static bool StreamTcpPacketIsSpuriousRetransmission(TcpSession *ssn, Packet *p) SCLogDebug("ssn %p: spurious retransmission; packet entirely before last_ack: SEQ %u(%u) " "last_ack %u", ssn, TCP_GET_SEQ(p), TCP_GET_SEQ(p) + p->payload_len, stream->last_ack); + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_SPURIOUS_RETRANSMISSION); return true; } SCLogDebug("ssn %p: NOT spurious retransmission; packet NOT entirely before last_ack: SEQ " @@ -3309,6 +3311,7 @@ static int StreamTcpPacketStateFinWait1( if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq - 1) || SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) { @@ -3361,10 +3364,13 @@ static int StreamTcpPacketStateFinWait1( if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); + } else if (SEQ_EQ(ssn->server.next_seq - 1, TCP_GET_SEQ(p)) && SEQ_EQ(ssn->client.last_ack, TCP_GET_ACK(p))) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq - 1) || SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) { @@ -3425,6 +3431,7 @@ static int StreamTcpPacketStateFinWait1( if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq - 1) || SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) { @@ -3479,6 +3486,7 @@ static int StreamTcpPacketStateFinWait1( if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq - 1) || SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) { @@ -3544,6 +3552,7 @@ static int StreamTcpPacketStateFinWait1( if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { @@ -3618,6 +3627,7 @@ static int StreamTcpPacketStateFinWait1( if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { @@ -3746,9 +3756,11 @@ static int StreamTcpPacketStateFinWait2( SEQ_EQ(TCP_GET_ACK(p), ssn->server.last_ack)) { SCLogDebug("ssn %p: retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } else if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->client.next_seq) || SEQ_GT(TCP_GET_SEQ(p), (ssn->client.last_ack + ssn->client.window))) @@ -3804,9 +3816,11 @@ static int StreamTcpPacketStateFinWait2( SEQ_EQ(TCP_GET_ACK(p), ssn->client.last_ack)) { SCLogDebug("ssn %p: retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } else if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } else if (SEQ_LT(TCP_GET_SEQ(p), ssn->server.next_seq) || SEQ_GT(TCP_GET_SEQ(p), (ssn->server.last_ack + ssn->server.window))) @@ -3869,6 +3883,7 @@ static int StreamTcpPacketStateFinWait2( if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { @@ -3924,6 +3939,7 @@ static int StreamTcpPacketStateFinWait2( if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } if (StreamTcpValidateAck(ssn, &ssn->client, p) == -1) { @@ -4045,6 +4061,7 @@ static int StreamTcpPacketStateClosing( if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } if (TCP_GET_SEQ(p) != ssn->client.next_seq) { @@ -4090,6 +4107,7 @@ static int StreamTcpPacketStateClosing( if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } if (TCP_GET_SEQ(p) != ssn->server.next_seq) { @@ -4212,6 +4230,7 @@ static int StreamTcpPacketStateCloseWait( if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } if (!retransmission) { @@ -4262,6 +4281,7 @@ static int StreamTcpPacketStateCloseWait( if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } if (!retransmission) { @@ -4327,6 +4347,7 @@ static int StreamTcpPacketStateCloseWait( if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } if (p->payload_len > 0 && (SEQ_LEQ((TCP_GET_SEQ(p) + p->payload_len), ssn->client.last_ack))) { @@ -4379,6 +4400,7 @@ static int StreamTcpPacketStateCloseWait( if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } if (p->payload_len > 0 && (SEQ_LEQ((TCP_GET_SEQ(p) + p->payload_len), ssn->server.last_ack))) { @@ -4504,6 +4526,7 @@ static int StreamTcpPacketStateLastAck( if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } if (StreamTcpValidateAck(ssn, &ssn->server, p) == -1) { @@ -4623,6 +4646,7 @@ static int StreamTcpPacketStateTimeWait( if (StreamTcpPacketIsRetransmission(&ssn->client, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } else if (TCP_GET_SEQ(p) != ssn->client.next_seq && TCP_GET_SEQ(p) != ssn->client.next_seq+1) { SCLogDebug("ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32 "" @@ -4668,6 +4692,7 @@ static int StreamTcpPacketStateTimeWait( if (StreamTcpPacketIsRetransmission(&ssn->server, p)) { SCLogDebug("ssn %p: packet is retransmission", ssn); retransmission = 1; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_RETRANSMISSION); } else if (TCP_GET_SEQ(p) != ssn->server.next_seq - 1 && TCP_GET_SEQ(p) != ssn->server.next_seq) { if (p->payload_len > 0 && TCP_GET_SEQ(p) == ssn->server.last_ack) { @@ -4820,6 +4845,7 @@ static int StreamTcpPacketIsKeepAlive(TcpSession *ssn, Packet *p) if (ack == ostream->last_ack && seq == (stream->next_seq - 1)) { SCLogDebug("packet is TCP keep-alive: %"PRIu64, p->pcap_cnt); stream->flags |= STREAMTCP_STREAM_FLAG_KEEPALIVE; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_KEEPALIVE); return 1; } SCLogDebug("seq %u (%u), ack %u (%u)", seq, (stream->next_seq - 1), ack, ostream->last_ack); @@ -4867,6 +4893,7 @@ static int StreamTcpPacketIsKeepAliveACK(TcpSession *ssn, Packet *p) if ((ostream->flags & STREAMTCP_STREAM_FLAG_KEEPALIVE) && ack == ostream->last_ack && seq == stream->next_seq) { SCLogDebug("packet is TCP keep-aliveACK: %"PRIu64, p->pcap_cnt); ostream->flags &= ~STREAMTCP_STREAM_FLAG_KEEPALIVE; + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_KEEPALIVEACK); return 1; } SCLogDebug("seq %u (%u), ack %u (%u) FLAG_KEEPALIVE: %s", seq, stream->next_seq, ack, ostream->last_ack, @@ -4936,6 +4963,7 @@ static int StreamTcpPacketIsWindowUpdate(TcpSession *ssn, Packet *p) if (ack == ostream->last_ack && seq == stream->next_seq) { SCLogDebug("packet is TCP window update: %"PRIu64, p->pcap_cnt); + STREAM_PKT_FLAG_SET(p, STREAM_PKT_FLAG_WINDOWUPDATE); return 1; } SCLogDebug("seq %u (%u), ack %u (%u)", seq, stream->next_seq, ack, ostream->last_ack);