]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
eve/drop: log drop reason
authorVictor Julien <vjulien@oisf.net>
Mon, 21 Mar 2022 20:57:04 +0000 (21:57 +0100)
committerVictor Julien <vjulien@oisf.net>
Tue, 14 Jun 2022 19:12:35 +0000 (21:12 +0200)
Ticket: #5202.
(cherry picked from commit 0035673208e7d3a1d73bd2f18e03a69e78fbc4ba)

src/decode.c
src/decode.h
src/detect-engine-threshold.c
src/detect.c
src/output-json-drop.c
src/stream-tcp.c

index fa1e3735b1fb2c58d1a58947c834f562f985c85d..e7317a66af1733b1d750fa63c9ed1ab7b6d0e20d 100644 (file)
@@ -766,6 +766,38 @@ const char *PktSrcToString(enum PktSrcEnum pkt_src)
     return pkt_src_str;
 }
 
+const char *PacketDropReasonToString(enum PacketDropReason r)
+{
+    switch (r) {
+        case PKT_DROP_REASON_DECODE_ERROR:
+            return "decode error";
+        case PKT_DROP_REASON_DEFRAG_ERROR:
+            return "defrag error";
+        case PKT_DROP_REASON_DEFRAG_MEMCAP:
+            return "defrag memcap";
+        case PKT_DROP_REASON_FLOW_MEMCAP:
+            return "flow memcap";
+        case PKT_DROP_REASON_FLOW_DROP:
+            return "flow drop";
+        case PKT_DROP_REASON_STREAM_ERROR:
+            return "stream error";
+        case PKT_DROP_REASON_STREAM_MEMCAP:
+            return "stream memcap";
+        case PKT_DROP_REASON_APPLAYER_ERROR:
+            return "applayer error";
+        case PKT_DROP_REASON_APPLAYER_MEMCAP:
+            return "applayer memcap";
+        case PKT_DROP_REASON_RULES:
+            return "rules";
+        case PKT_DROP_REASON_RULES_THRESHOLD:
+            return "threshold detection_filter";
+        case PKT_DROP_REASON_NOT_SET:
+        default:
+            return NULL;
+    }
+}
+
+/* TODO drop reason stats! */
 void CaptureStatsUpdate(ThreadVars *tv, CaptureStats *s, const Packet *p)
 {
     if (unlikely(PACKET_TEST_ACTION(p, (ACTION_REJECT|ACTION_REJECT_DST|ACTION_REJECT_BOTH)))) {
index 3a433ca5c5bc1bcc5242ef910bc1f3c7b10e8b69..53fc0fe43e05679e9a3235a4b3bac71c20c2c57d 100644 (file)
@@ -397,6 +397,21 @@ typedef struct PktProfiling_ {
 
 #endif /* PROFILING */
 
+enum PacketDropReason {
+    PKT_DROP_REASON_NOT_SET = 0,
+    PKT_DROP_REASON_DECODE_ERROR,
+    PKT_DROP_REASON_DEFRAG_ERROR,
+    PKT_DROP_REASON_DEFRAG_MEMCAP,
+    PKT_DROP_REASON_FLOW_MEMCAP,
+    PKT_DROP_REASON_FLOW_DROP,
+    PKT_DROP_REASON_STREAM_ERROR,
+    PKT_DROP_REASON_STREAM_MEMCAP,
+    PKT_DROP_REASON_APPLAYER_ERROR,
+    PKT_DROP_REASON_APPLAYER_MEMCAP,
+    PKT_DROP_REASON_RULES,
+    PKT_DROP_REASON_RULES_THRESHOLD, /**< detection_filter in action */
+};
+
 /* forward declaration since Packet struct definition requires this */
 struct PacketQueue_;
 
@@ -588,6 +603,14 @@ typedef struct Packet_
     /** data linktype in host order */
     int datalink;
 
+    /* count decoded layers of packet : too many layers
+     * cause issues with performance and stability (stack exhaustion)
+     */
+    uint8_t nb_decoded_layers;
+
+    /* enum PacketDropReason::PKT_DROP_REASON_* as uint8_t for compactness */
+    uint8_t drop_reason;
+
     /* tunnel/encapsulation handling */
     struct Packet_ *root; /* in case of tunnel this is a ptr
                            * to the 'real' packet, the one we
@@ -613,11 +636,6 @@ typedef struct Packet_
      */
     struct PktPool_ *pool;
 
-    /* count decoded layers of packet : too many layers
-     * cause issues with performance and stability (stack exhaustion)
-     */
-    uint8_t nb_decoded_layers;
-
 #ifdef PROFILING
     PktProfiling *profile;
 #endif
@@ -788,6 +806,7 @@ void CaptureStatsSetup(ThreadVars *tv, CaptureStats *s);
         (p)->ts.tv_sec = 0;                                                                        \
         (p)->ts.tv_usec = 0;                                                                       \
         (p)->datalink = 0;                                                                         \
+        (p)->drop_reason = 0;                                                                      \
         (p)->action = 0;                                                                           \
         if ((p)->pktvar != NULL) {                                                                 \
             PktVarFree((p)->pktvar);                                                               \
@@ -877,8 +896,6 @@ void CaptureStatsSetup(ThreadVars *tv, CaptureStats *s);
 
 #define PACKET_ACCEPT(p) PACKET_SET_ACTION(p, ACTION_ACCEPT)
 
-#define PACKET_DROP(p) PACKET_SET_ACTION(p, ACTION_DROP)
-
 #define PACKET_REJECT(p) PACKET_SET_ACTION(p, (ACTION_REJECT|ACTION_DROP))
 
 #define PACKET_REJECT_DST(p) PACKET_SET_ACTION(p, (ACTION_REJECT_DST|ACTION_DROP))
@@ -887,10 +904,26 @@ void CaptureStatsSetup(ThreadVars *tv, CaptureStats *s);
 
 #define PACKET_PASS(p) PACKET_SET_ACTION(p, ACTION_PASS)
 
-#define PACKET_TEST_ACTION(p, a) \
-    ((p)->root ? \
-     ((p)->root->action & a) : \
-     ((p)->action & a))
+#define PACKET_TEST_ACTION_DO(p, a) (p)->action &(a)
+
+static inline void PacketDrop(Packet *p, enum PacketDropReason r)
+{
+    if (p->drop_reason == PKT_DROP_REASON_NOT_SET)
+        p->drop_reason = (uint8_t)r;
+
+    PACKET_SET_ACTION(p, ACTION_DROP);
+}
+#define PACKET_DROP(p) PacketDrop((p), PKT_DROP_REASON_NOT_SET)
+
+static inline uint8_t PacketTestAction(const Packet *p, const uint8_t a)
+{
+    if (likely(p->root == NULL)) {
+        return PACKET_TEST_ACTION_DO(p, a);
+    } else {
+        return PACKET_TEST_ACTION_DO(p->root, a);
+    }
+}
+#define PACKET_TEST_ACTION(p, a) PacketTestAction((p), (a))
 
 #define PACKET_UPDATE_ACTION(p, a) do { \
     ((p)->root ? \
@@ -955,6 +988,7 @@ DecodeThreadVars *DecodeThreadVarsAlloc(ThreadVars *);
 void DecodeThreadVarsFree(ThreadVars *, DecodeThreadVars *);
 void DecodeUpdatePacketCounters(ThreadVars *tv,
                                 const DecodeThreadVars *dtv, const Packet *p);
+const char *PacketDropReasonToString(enum PacketDropReason r);
 
 /* decoder functions */
 int DecodeEthernet(ThreadVars *, DecodeThreadVars *, Packet *, const uint8_t *, uint32_t);
index 826ceeacdf45e5652b776133df052bdf2e3dfb2d..132867578d8e1d73abf04e3dc67063229854162c 100644 (file)
@@ -300,7 +300,7 @@ static inline void RateFilterSetAction(Packet *p, PacketAlert *pa, uint8_t new_a
             pa->flags |= PACKET_ALERT_RATE_FILTER_MODIFIED;
             break;
         case TH_ACTION_DROP:
-            PACKET_DROP(p);
+            PacketDrop(p, PKT_DROP_REASON_RULES_THRESHOLD);
             pa->flags |= PACKET_ALERT_RATE_FILTER_MODIFIED;
             break;
         case TH_ACTION_REJECT:
index 2c2900c52a163aafcbfe20634370bf58cf9395b8..b8d480e197eff50cc17dd8a7f5e71dc9f634f48a 100644 (file)
@@ -1560,7 +1560,7 @@ static void DetectFlow(ThreadVars *tv,
 
     /* if flow is set to drop, we enforce that here */
     if (p->flow->flags & FLOW_ACTION_DROP) {
-        PACKET_DROP(p);
+        PacketDrop(p, PKT_DROP_REASON_FLOW_DROP);
         SCReturn;
     }
 
index 3eb7e6832b056612975cf0d8584abb02d71fde49..8c403791f043dca2d3471eed67cebec201e2b195 100644 (file)
@@ -147,6 +147,10 @@ static int DropLogJSON (JsonDropLogThread *aft, const Packet *p)
             }
             break;
     }
+    if (p->drop_reason != 0) {
+        const char *str = PacketDropReasonToString(p->drop_reason);
+        jb_set_string(js, "reason", str);
+    }
 
     /* Close drop. */
     jb_close(js);
index da455ce2ad644a5f9dbd65d6cc59236fa6a41f88..57db84c8a770898ddc4ab2a7d40ddb3d10966540 100644 (file)
@@ -4859,7 +4859,7 @@ int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt,
         FlowSetNoPacketInspectionFlag(p->flow);
         DecodeSetNoPacketInspectionFlag(p);
         StreamTcpDisableAppLayer(p->flow);
-        PACKET_DROP(p);
+        PacketDrop(p, PKT_DROP_REASON_FLOW_DROP);
         /* return the segments to the pool */
         StreamTcpSessionPktFree(p);
         SCReturnInt(0);
@@ -5018,7 +5018,7 @@ error:
          * anyway. Doesn't disable all detection, so we can still
          * match on the stream event that was set. */
         DecodeSetNoPayloadInspectionFlag(p);
-        PACKET_DROP(p);
+        PacketDrop(p, PKT_DROP_REASON_STREAM_ERROR);
     }
     SCReturnInt(-1);
 }