]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
Eve: use mac addresses from flow for flow timeout
authorJoyce Yu <joyce.yu@cyber.gc.ca>
Mon, 17 Mar 2025 18:58:50 +0000 (14:58 -0400)
committerVictor Julien <victor@inliniac.net>
Thu, 20 Mar 2025 12:11:59 +0000 (13:11 +0100)
Ethernet metadata is missing for events triggered on flow timeout
pseudopackets. Use the first set of mac addresses stored with the
flow to fill in the ether field.

Ticket: #5486

src/output-json.c
src/util-macset.c
src/util-macset.h

index 422191adbc3574fe5bc52f0b08fd46aaa7c27506..b6ce328cabd987b80db2fe82413dcf06e755975a 100644 (file)
@@ -767,6 +767,22 @@ static int CreateJSONEther(
             JSONFormatAndAddMACAddr(js, "src_mac", src, false);
             JSONFormatAndAddMACAddr(js, "dest_mac", dst, false);
             jb_close(js);
+        } else if (f != NULL) {
+            /* When pseudopackets do not have associated ethernet metadata,
+               use the first set of mac addresses stored with their flow.
+               The first set of macs should come from the flow's first packet,
+               providing the most fitting representation of the event's ethernet. */
+            MacSet *ms = FlowGetStorageById(f, MacSetGetFlowStorageID());
+            if (ms != NULL && MacSetSize(ms) > 0) {
+                uint8_t *src = MacSetGetFirst(ms, MAC_SET_SRC);
+                uint8_t *dst = MacSetGetFirst(ms, MAC_SET_DST);
+                if (dst != NULL && src != NULL) {
+                    jb_open_object(js, "ether");
+                    JSONFormatAndAddMACAddr(js, "src_mac", src, false);
+                    JSONFormatAndAddMACAddr(js, "dest_mac", dst, false);
+                    jb_close(js);
+                }
+            }
         }
     } else if (f != NULL) {
         /* we are creating an ether object in a flow context, so we need to
index bf3edf05721e076b622df9a37d17cbdf0fa2d773..bf50c098bbbc63dcb2522ea95710cd58ffd3ba41 100644 (file)
@@ -230,6 +230,19 @@ int MacSetForEach(const MacSet *ms, MacSetIteratorFunc IterFunc, void *data)
     return MacSetIterateSide(ms, IterFunc, MAC_SET_DST, data);
 }
 
+uint8_t *MacSetGetFirst(const MacSet *ms, MacSetSide side)
+{
+    switch (ms->state[side]) {
+        case EMPTY_SET:
+            return NULL;
+        case SINGLE_MAC:
+            return (uint8_t *)ms->singles[side];
+        case MULTI_MAC:
+            return (uint8_t *)ms->buf[side][0];
+    }
+    return NULL;
+}
+
 int MacSetSize(const MacSet *ms)
 {
     int size = 0;
@@ -416,6 +429,39 @@ static int MacSetTest05(void)
     PASS;
 }
 
+static int MacSetTest06(void)
+{
+    SC_ATOMIC_SET(flow_config.memcap, 128);
+
+    MacSet *ms = MacSetInit(10);
+    FAIL_IF_NULL(ms);
+    FAIL_IF_NOT(MacSetSize(ms) == 0);
+
+    uint8_t *src0 = MacSetGetFirst(ms, MAC_SET_SRC);
+    uint8_t *dst0 = MacSetGetFirst(ms, MAC_SET_DST);
+
+    MacAddr addr1 = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x1 }, addr2 = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x2 },
+            addr3 = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x3 }, addr4 = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x4 };
+
+    MacSetAdd(ms, addr1, addr2);
+    uint8_t *src1 = MacSetGetFirst(ms, MAC_SET_SRC);
+    uint8_t *dst1 = MacSetGetFirst(ms, MAC_SET_DST);
+
+    MacSetAdd(ms, addr3, addr4);
+    uint8_t *src2 = MacSetGetFirst(ms, MAC_SET_SRC);
+    uint8_t *dst2 = MacSetGetFirst(ms, MAC_SET_DST);
+
+    FAIL_IF_NOT_NULL(src0);
+    FAIL_IF_NOT_NULL(dst0);
+    FAIL_IF_NOT(src1[5] == addr1[5]);
+    FAIL_IF_NOT(dst1[5] == addr2[5]);
+    FAIL_IF_NOT(src2[5] == addr1[5]);
+    FAIL_IF_NOT(dst2[5] == addr2[5]);
+
+    MacSetFree(ms);
+    PASS;
+}
+
 #endif /* UNITTESTS */
 
 void MacSetRegisterTests(void)
@@ -427,5 +473,6 @@ void MacSetRegisterTests(void)
     UtRegisterTest("MacSetTest03", MacSetTest03);
     UtRegisterTest("MacSetTest04", MacSetTest04);
     UtRegisterTest("MacSetTest05", MacSetTest05);
+    UtRegisterTest("MacSetTest06", MacSetTest06);
 #endif
 }
index 5f60aa2a18cd04ebcc3dc3b7a80e9948676f2296..9749f2aa63111b963c819c9edfc52f99adbc8927 100644 (file)
@@ -37,6 +37,7 @@ void MacSetAdd(MacSet *, const uint8_t *src_addr, const uint8_t *dst_addr);
 void MacSetAddWithCtr(MacSet *, const uint8_t *src_addr, const uint8_t *dst_addr, ThreadVars *tv,
         uint16_t ctr_src, uint16_t ctr_dst);
 int     MacSetForEach(const MacSet*, MacSetIteratorFunc, void*);
+uint8_t *MacSetGetFirst(const MacSet *, MacSetSide);
 int     MacSetSize(const MacSet*);
 void    MacSetReset(MacSet*);
 void    MacSetFree(MacSet*);