]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stream: track packet flags in packet
authorVictor Julien <vjulien@oisf.net>
Thu, 16 Feb 2023 05:17:24 +0000 (06:17 +0100)
committerVictor Julien <vjulien@oisf.net>
Fri, 24 Feb 2023 09:45:36 +0000 (10:45 +0100)
These flags can then later be used by stream logging.

src/decode-tcp.h
src/stream-tcp-private.h
src/stream-tcp.c

index 3b291dd9a43431a911746278a8d5169db3f319c9..4b26df5c26f4db27b38aa54a32e5713f79f0c181 100644 (file)
@@ -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;
index 0a42f306f8314c972df716f518af620dfb5815c1..77d0dc43073bbfa91bbb4645ea04937b41af304c 100644 (file)
@@ -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__ */
index 4e4225d7e88389b0c96a6048c36b6fdd1ed44bdf..7738d1b0f387ab95ddd804a5ff04c300f95a9412 100644 (file)
@@ -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);