]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/dnp3: add dnp3.data with v2 api support
authorVictor Julien <victor@inliniac.net>
Fri, 3 May 2019 12:02:46 +0000 (14:02 +0200)
committerVictor Julien <victor@inliniac.net>
Fri, 3 May 2019 13:56:50 +0000 (15:56 +0200)
Adds MPM support as well. Add TxDetectFlags support to the parser
to avoid duplicate matches.

src/app-layer-dnp3.c
src/app-layer-dnp3.h
src/detect-dnp3.c

index 7f27ce4f543bc9b048330fc4f10cf87fb1cdfea0..723f2706ded95ae4ac19aaa5b30ee2d970e03855 100644 (file)
@@ -1568,6 +1568,27 @@ int DNP3PrefixIsSize(uint8_t prefix_code)
     }
 }
 
+static uint64_t DNP3GetTxDetectFlags(void *vtx, uint8_t dir)
+{
+    DNP3Transaction *tx = (DNP3Transaction *)vtx;
+    if (dir & STREAM_TOSERVER) {
+        return tx->detect_flags_ts;
+    } else {
+        return tx->detect_flags_tc;
+    }
+}
+
+static void DNP3SetTxDetectFlags(void *vtx, uint8_t dir, uint64_t detect_flags)
+{
+    DNP3Transaction *tx = (DNP3Transaction *)vtx;
+    if (dir & STREAM_TOSERVER) {
+        tx->detect_flags_ts = detect_flags;
+    } else {
+        tx->detect_flags_tc = detect_flags;
+    }
+    return;
+}
+
 /**
  * \brief Register the DNP3 application protocol parser.
  */
@@ -1618,6 +1639,8 @@ void RegisterDNP3Parsers(void)
             DNP3GetEvents);
         AppLayerParserRegisterDetectStateFuncs(IPPROTO_TCP, ALPROTO_DNP3,
             DNP3GetTxDetectState, DNP3SetTxDetectState);
+        AppLayerParserRegisterDetectFlagsFuncs(IPPROTO_TCP, ALPROTO_DNP3,
+            DNP3GetTxDetectFlags, DNP3SetTxDetectFlags);
 
         AppLayerParserRegisterGetTx(IPPROTO_TCP, ALPROTO_DNP3, DNP3GetTx);
         AppLayerParserRegisterGetTxCnt(IPPROTO_TCP, ALPROTO_DNP3, DNP3GetTxCnt);
index 13cebc7478eb17281e068d0b469f873ec9717f3d..7519b92ff898edf113d17a2247ef3962671d56a6 100644 (file)
@@ -207,6 +207,10 @@ typedef TAILQ_HEAD(DNP3ObjectList_, DNP3Object_) DNP3ObjectList;
  * \brief DNP3 transaction.
  */
 typedef struct DNP3Transaction_ {
+    /** detection engine flags */
+    uint64_t detect_flags_ts;
+    uint64_t detect_flags_tc;
+
     uint64_t tx_num; /**< Internal transaction ID. */
     uint32_t logged; /**< Flags indicating which loggers have logged this tx. */
 
index b035673507d4bb99e347eea1bfe0938e86705cac..2ff1b32e95378834d79d6b26f14bef27bd2c08d5 100644 (file)
@@ -23,6 +23,8 @@
 #include "detect-parse.h"
 #include "detect-dnp3.h"
 #include "detect-engine.h"
+#include "detect-engine-mpm.h"
+#include "detect-engine-prefilter.h"
 #include "detect-engine-content-inspection.h"
 
 #include "app-layer-dnp3.h"
@@ -141,30 +143,35 @@ static char *TrimString(char *str)
     return str;
 }
 
-static int DetectEngineInspectDNP3Data(ThreadVars *tv, DetectEngineCtx *de_ctx,
-    DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd,
-    Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
+static InspectionBuffer *GetDNP3Data(DetectEngineThreadCtx *det_ctx,
+        const DetectEngineTransforms *transforms,
+        Flow *_f, const uint8_t flow_flags,
+        void *txv, const int list_id)
 {
-    SCEnter();
-    DNP3Transaction *tx = (DNP3Transaction *)txv;
-
-    int r = 0;
+    SCLogDebug("list_id %d", list_id);
+    InspectionBuffer *buffer = InspectionBufferGet(det_ctx, list_id);
+    if (buffer->inspect == NULL) {
+        DNP3Transaction *tx = (DNP3Transaction *)txv;
+        SCLogDebug("tx %p", tx);
+
+        const uint8_t *data = NULL;
+        uint32_t data_len = 0;
+
+        if (flow_flags & STREAM_TOSERVER) {
+            data = tx->request_buffer;
+            data_len = tx->request_buffer_len;
+        } else if (flow_flags & STREAM_TOCLIENT) {
+            data = tx->response_buffer;
+            data_len = tx->response_buffer_len;
+        }
+        if (data == NULL || data_len == 0)
+            return NULL;
 
-    /* Content match - should probably be put into its own file. */
-    if (flags & STREAM_TOSERVER && tx->request_buffer != NULL) {
-        r = DetectEngineContentInspection(de_ctx, det_ctx, s,
-            smd, NULL, f, tx->request_buffer,
-            tx->request_buffer_len, 0, DETECT_CI_FLAGS_SINGLE,
-            DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE);
+        SCLogDebug("tx %p data %p data_len %u", tx, data, data_len);
+        InspectionBufferSetup(buffer, data, data_len);
+        InspectionBufferApplyTransforms(buffer, transforms);
     }
-    else if (flags & STREAM_TOCLIENT && tx->response_buffer != NULL) {
-        r = DetectEngineContentInspection(de_ctx, det_ctx, s,
-            smd, NULL, f, tx->response_buffer,
-            tx->response_buffer_len, 0, DETECT_CI_FLAGS_SINGLE,
-            DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE);
-    }
-
-    SCReturnInt(r);
+    return buffer;
 }
 
 static int DetectEngineInspectDNP3(ThreadVars *tv, DetectEngineCtx *de_ctx,
@@ -533,7 +540,9 @@ static int DetectDNP3DataSetup(DetectEngineCtx *de_ctx, Signature *s, const char
     if (DetectSignatureSetAppProto(s, ALPROTO_DNP3) != 0)
         return -1;
 
-    DetectBufferSetActiveList(s, g_dnp3_data_buffer_id);
+    if (DetectBufferSetActiveList(s, g_dnp3_data_buffer_id) != 0)
+        return -1;
+
     SCReturnInt(0);
 }
 
@@ -541,21 +550,29 @@ static void DetectDNP3DataRegister(void)
 {
     SCEnter();
 
-    sigmatch_table[DETECT_AL_DNP3DATA].name          = "dnp3_data";
-    sigmatch_table[DETECT_AL_DNP3DATA].Match         = NULL;
+    sigmatch_table[DETECT_AL_DNP3DATA].name          = "dnp3.data";
+    sigmatch_table[DETECT_AL_DNP3DATA].alias         = "dnp3_data";
     sigmatch_table[DETECT_AL_DNP3DATA].Setup         = DetectDNP3DataSetup;
-    sigmatch_table[DETECT_AL_DNP3DATA].Free          = NULL;
     sigmatch_table[DETECT_AL_DNP3DATA].RegisterTests =
         DetectDNP3DataRegisterTests;
 
-    sigmatch_table[DETECT_AL_DNP3DATA].flags |= SIGMATCH_NOOPT;
+    sigmatch_table[DETECT_AL_DNP3DATA].flags |= SIGMATCH_NOOPT|SIGMATCH_INFO_STICKY_BUFFER;
 
-    DetectAppLayerInspectEngineRegister("dnp3_data",
+    DetectAppLayerInspectEngineRegister2("dnp3_data",
             ALPROTO_DNP3, SIG_FLAG_TOSERVER, 0,
-            DetectEngineInspectDNP3Data);
-    DetectAppLayerInspectEngineRegister("dnp3_data",
+            DetectEngineInspectBufferGeneric,
+            GetDNP3Data);
+    DetectAppLayerMpmRegister2("dnp3_data", SIG_FLAG_TOSERVER, 2,
+            PrefilterGenericMpmRegister, GetDNP3Data,
+            ALPROTO_DNP3, 0);
+
+    DetectAppLayerInspectEngineRegister2("dnp3_data",
             ALPROTO_DNP3, SIG_FLAG_TOCLIENT, 0,
-            DetectEngineInspectDNP3Data);
+            DetectEngineInspectBufferGeneric,
+            GetDNP3Data);
+    DetectAppLayerMpmRegister2("dnp3_data", SIG_FLAG_TOCLIENT, 2,
+            PrefilterGenericMpmRegister, GetDNP3Data,
+            ALPROTO_DNP3, 0);
 
     g_dnp3_data_buffer_id = DetectBufferTypeGetByName("dnp3_data");
     SCReturn;