]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/mpm: add l4-header support
authorVictor Julien <victor@inliniac.net>
Wed, 19 Jun 2019 07:08:15 +0000 (09:08 +0200)
committerVictor Julien <victor@inliniac.net>
Fri, 21 Jun 2019 05:16:17 +0000 (07:16 +0200)
Prepare MPM part of the detection engine for a new type of per
packet matching, where the L4 header will be inspected.

Preparation for TCP header inspection keyword.

src/detect-engine-build.c
src/detect-engine-content-inspection.h
src/detect-engine-mpm.c
src/detect-engine.c
src/detect-fast-pattern.c
src/detect.h

index 47c6c3d11a03824bb248467bd5b12a9d7ec63263..849f1bda330fadb8c227f791dde3240190dc3d48 100644 (file)
@@ -191,6 +191,8 @@ int SignatureIsIPOnly(DetectEngineCtx *de_ctx, const Signature *s)
 
     if (s->init_data->smlists[DETECT_SM_LIST_PMATCH] != NULL)
         return 0;
+    if (s->init_data->smlists[DETECT_SM_LIST_L4HDR] != NULL)
+        return 0;
 
     /* if flow dir is set we can't process it in ip-only */
     if (!(((s->flags & (SIG_FLAG_TOSERVER|SIG_FLAG_TOCLIENT)) == 0) ||
index bc0229cf300d6e62434fe97963c515566e1657dd..6a3ce9a281e1e661ba69a53479e770687a4ffcbd 100644 (file)
@@ -29,7 +29,8 @@
  *  we're inspecting
  */
 enum {
-    DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD = 0,
+    DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD = 0,  /* enables 'replace' logic */
+    DETECT_ENGINE_CONTENT_INSPECTION_MODE_HEADER,
     DETECT_ENGINE_CONTENT_INSPECTION_MODE_STREAM,
     DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE,
 };
index 282ed9d33ccaf118556042111710e8b782ce41e1..7bbb1b8f9d05cd44a22fc3343866f9262a194b6c 100644 (file)
@@ -67,6 +67,8 @@ const char *builtin_mpms[] = {
     "toserver UDP packet",
     "toclient UDP packet",
     "other IP packet",
+    "toserver L4 header",
+    "toclient L4 header",
 
     NULL };
 
@@ -336,6 +338,7 @@ void DetectMpmInitializeBuiltinMpms(DetectEngineCtx *de_ctx)
 
     de_ctx->sgh_mpm_context_proto_udp_packet = SetupBuiltinMpm(de_ctx, "udp-packet");
     de_ctx->sgh_mpm_context_proto_other_packet = SetupBuiltinMpm(de_ctx, "other-ip");
+    de_ctx->sgh_mpm_context_l4_header = SetupBuiltinMpm(de_ctx, "l4-header");
 }
 
 /**
@@ -387,6 +390,17 @@ int DetectMpmPrepareBuiltinMpms(DetectEngineCtx *de_ctx)
         }
     }
 
+    if (de_ctx->sgh_mpm_context_l4_header != MPM_CTX_FACTORY_UNIQUE_CONTEXT) {
+        mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_l4_header, 0);
+        if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
+            r |= mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
+        }
+        mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_l4_header, 1);
+        if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
+            r |= mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
+        }
+    }
+
     return r;
 }
 
@@ -1015,13 +1029,14 @@ static void MpmStoreSetup(const DetectEngineCtx *de_ctx, MpmStore *ms)
     int dir = 0;
 
     if (ms->buffer != MPMB_MAX) {
-        BUG_ON(ms->sm_list != DETECT_SM_LIST_PMATCH);
+        BUG_ON(ms->sm_list != DETECT_SM_LIST_PMATCH && ms->sm_list != DETECT_SM_LIST_L4HDR);
 
         switch (ms->buffer) {
             /* TS is 1 */
             case MPMB_TCP_PKT_TS:
             case MPMB_TCP_STREAM_TS:
             case MPMB_UDP_TS:
+            case MPMB_L4HDR_TS:
                 dir = 1;
                 break;
 
@@ -1031,6 +1046,7 @@ static void MpmStoreSetup(const DetectEngineCtx *de_ctx, MpmStore *ms)
             case MPMB_TCP_STREAM_TC:
             case MPMB_TCP_PKT_TC:
             case MPMB_OTHERIP:          /**< use 0 for other */
+            case MPMB_L4HDR_TC:
                 dir = 0;
                 break;
         }
@@ -1118,6 +1134,7 @@ MpmStore *MpmStorePrepareBuffer(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
     uint8_t sids_array[max_sid];
     memset(sids_array, 0x00, max_sid);
     int sgh_mpm_context = 0;
+    int sm_list = DETECT_SM_LIST_PMATCH;
 
     switch (buf) {
         case MPMB_TCP_PKT_TS:
@@ -1135,6 +1152,11 @@ MpmStore *MpmStorePrepareBuffer(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
         case MPMB_OTHERIP:
             sgh_mpm_context = de_ctx->sgh_mpm_context_proto_other_packet;
             break;
+        case MPMB_L4HDR_TS:
+        case MPMB_L4HDR_TC:
+            sgh_mpm_context = de_ctx->sgh_mpm_context_l4_header;
+            sm_list = DETECT_SM_LIST_L4HDR;
+            break;
         default:
             break;
     }
@@ -1143,12 +1165,14 @@ MpmStore *MpmStorePrepareBuffer(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
         case MPMB_TCP_PKT_TS:
         case MPMB_TCP_STREAM_TS:
         case MPMB_UDP_TS:
+        case MPMB_L4HDR_TS:
             direction = SIG_FLAG_TOSERVER;
             break;
 
         case MPMB_TCP_PKT_TC:
         case MPMB_TCP_STREAM_TC:
         case MPMB_UDP_TC:
+        case MPMB_L4HDR_TC:
             direction = SIG_FLAG_TOCLIENT;
             break;
 
@@ -1173,7 +1197,7 @@ MpmStore *MpmStorePrepareBuffer(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
         if (list < 0)
             continue;
 
-        if (list != DETECT_SM_LIST_PMATCH)
+        if (list != DETECT_SM_LIST_PMATCH && list != DETECT_SM_LIST_L4HDR)
             continue;
 
         switch (buf) {
@@ -1202,6 +1226,11 @@ MpmStore *MpmStorePrepareBuffer(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
                 sids_array[s->num / 8] |= 1 << (s->num % 8);
                 cnt++;
                 break;
+            case MPMB_L4HDR_TS:
+            case MPMB_L4HDR_TC:
+                sids_array[s->num / 8] |= 1 << (s->num % 8);
+                cnt++;
+                break;
             default:
                 break;
         }
@@ -1210,7 +1239,7 @@ MpmStore *MpmStorePrepareBuffer(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
     if (cnt == 0)
         return NULL;
 
-    MpmStore lookup = { sids_array, max_sid, direction, buf, DETECT_SM_LIST_PMATCH, 0, NULL};
+    MpmStore lookup = { sids_array, max_sid, direction, buf, sm_list, 0, NULL};
 
     MpmStore *result = MpmStoreLookup(de_ctx, &lookup);
     if (result == NULL) {
@@ -1228,7 +1257,7 @@ MpmStore *MpmStorePrepareBuffer(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
         copy->sid_array_size = max_sid;
         copy->buffer = buf;
         copy->direction = direction;
-        copy->sm_list = DETECT_SM_LIST_PMATCH;
+        copy->sm_list = sm_list;
         copy->sgh_mpm_context = sgh_mpm_context;
 
         MpmStoreSetup(de_ctx, copy);
index 681c1e15ee20cf8f08c8a9ec00a0c636fafcda4e..3b53f03c0051c6b496a2aebc39fe81c5477abc8e 100644 (file)
@@ -3930,6 +3930,8 @@ const char *DetectSigmatchListEnumToString(enum DetectSigmatchListEnum type)
             return "packet";
         case DETECT_SM_LIST_PMATCH:
             return "packet/stream payload";
+        case DETECT_SM_LIST_L4HDR:
+            return "layer 4 header";
 
         case DETECT_SM_LIST_TMATCH:
             return "tag";
index 564178b6fe6e460e9c18a38d50eae8e396037797..3ba1390a051206b076625832c1d58d5f102516a0 100644 (file)
@@ -64,7 +64,7 @@ int FastPatternSupportEnabledForSigMatchList(const DetectEngineCtx *de_ctx,
     if (sm_fp_support_smlist_list == NULL)
         return 0;
 
-    if (list_id == DETECT_SM_LIST_PMATCH)
+    if (list_id == DETECT_SM_LIST_PMATCH || list_id == DETECT_SM_LIST_L4HDR)
         return 1;
 
     return DetectBufferTypeSupportsMpmGetById(de_ctx, list_id);
index 8702a4be281f13cabfbbc1a92f78ec64fca8c3f7..c2117d7a4917c2b399df1d0f928b96726d6a7978 100644 (file)
@@ -91,6 +91,7 @@ struct SCSigSignatureWrapper_;
 enum DetectSigmatchListEnum {
     DETECT_SM_LIST_MATCH = 0,
     DETECT_SM_LIST_PMATCH,
+    DETECT_SM_LIST_L4HDR,
 
     /* base64_data keyword uses some hardcoded logic so consider
      * built-in
@@ -828,6 +829,7 @@ typedef struct DetectEngineCtx_ {
     int32_t sgh_mpm_context_proto_udp_packet;
     int32_t sgh_mpm_context_proto_other_packet;
     int32_t sgh_mpm_context_stream;
+    int32_t sgh_mpm_context_l4_header;
 
     /* the max local id used amongst all sigs */
     int32_t byte_extract_max_local_id;
@@ -1224,6 +1226,8 @@ enum MpmBuiltinBuffers {
     MPMB_UDP_TS,
     MPMB_UDP_TC,
     MPMB_OTHERIP,
+    MPMB_L4HDR_TS,
+    MPMB_L4HDR_TC,
     MPMB_MAX,
 };