From: Victor Julien Date: Wed, 19 Jun 2019 07:08:15 +0000 (+0200) Subject: detect/mpm: add l4-header support X-Git-Tag: suricata-5.0.0-rc1~248 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=47ef8f58224ebc7836570c7e9d3cfab513681a35;p=thirdparty%2Fsuricata.git detect/mpm: add l4-header support 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. --- diff --git a/src/detect-engine-build.c b/src/detect-engine-build.c index 47c6c3d11a..849f1bda33 100644 --- a/src/detect-engine-build.c +++ b/src/detect-engine-build.c @@ -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) || diff --git a/src/detect-engine-content-inspection.h b/src/detect-engine-content-inspection.h index bc0229cf30..6a3ce9a281 100644 --- a/src/detect-engine-content-inspection.h +++ b/src/detect-engine-content-inspection.h @@ -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, }; diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index 282ed9d33c..7bbb1b8f9d 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -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); diff --git a/src/detect-engine.c b/src/detect-engine.c index 681c1e15ee..3b53f03c00 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -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"; diff --git a/src/detect-fast-pattern.c b/src/detect-fast-pattern.c index 564178b6fe..3ba1390a05 100644 --- a/src/detect-fast-pattern.c +++ b/src/detect-fast-pattern.c @@ -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); diff --git a/src/detect.h b/src/detect.h index 8702a4be28..c2117d7a49 100644 --- a/src/detect.h +++ b/src/detect.h @@ -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, };