diff --git a/src/detect-bytejump.c b/src/detect-bytejump.c index 29931b7d3d..5b28d341bd 100644 --- a/src/detect-bytejump.c +++ b/src/detect-bytejump.c @@ -45,6 +45,8 @@ void DetectBytejumpRegister (void) { sigmatch_table[DETECT_BYTEJUMP].Free = DetectBytejumpFree; sigmatch_table[DETECT_BYTEJUMP].RegisterTests = DetectBytejumpRegisterTests; + sigmatch_table[DETECT_BYTEJUMP].flags |= SIGMATCH_PAYLOAD; + parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); if(parse_regex == NULL) { diff --git a/src/detect-bytetest.c b/src/detect-bytetest.c index b60e127790..52ff567afa 100644 --- a/src/detect-bytetest.c +++ b/src/detect-bytetest.c @@ -46,6 +46,8 @@ void DetectBytetestRegister (void) { sigmatch_table[DETECT_BYTETEST].Free = DetectBytetestFree; sigmatch_table[DETECT_BYTETEST].RegisterTests = DetectBytetestRegisterTests; + sigmatch_table[DETECT_BYTETEST].flags |= SIGMATCH_PAYLOAD; + parse_regex = pcre_compile(PARSE_REGEX, opts, &eb, &eo, NULL); if(parse_regex == NULL) { diff --git a/src/detect-content.c b/src/detect-content.c index a54d797246..91d6284fea 100644 --- a/src/detect-content.c +++ b/src/detect-content.c @@ -51,6 +51,8 @@ void DetectContentRegister (void) { sigmatch_table[DETECT_CONTENT].Setup = DetectContentSetup; sigmatch_table[DETECT_CONTENT].Free = DetectContentFree; sigmatch_table[DETECT_CONTENT].RegisterTests = DetectContentRegisterTests; + + sigmatch_table[DETECT_CONTENT].flags |= SIGMATCH_PAYLOAD; } /* pass on the content_max_id */ diff --git a/src/detect-depth.c b/src/detect-depth.c index 93a9eb3ee9..2f96dc65ce 100644 --- a/src/detect-depth.c +++ b/src/detect-depth.c @@ -15,6 +15,8 @@ void DetectDepthRegister (void) { sigmatch_table[DETECT_DEPTH].Setup = DetectDepthSetup; sigmatch_table[DETECT_DEPTH].Free = NULL; sigmatch_table[DETECT_DEPTH].RegisterTests = NULL; + + sigmatch_table[DETECT_DEPTH].flags |= SIGMATCH_PAYLOAD; } int DetectDepthSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *depthstr) diff --git a/src/detect-distance.c b/src/detect-distance.c index fc482a85a3..c14a68636d 100644 --- a/src/detect-distance.c +++ b/src/detect-distance.c @@ -16,6 +16,8 @@ void DetectDistanceRegister (void) { sigmatch_table[DETECT_DISTANCE].Setup = DetectDistanceSetup; sigmatch_table[DETECT_DISTANCE].Free = NULL; sigmatch_table[DETECT_DISTANCE].RegisterTests = NULL; + + sigmatch_table[DETECT_DISTANCE].flags |= SIGMATCH_PAYLOAD; } int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *distancestr) diff --git a/src/detect-isdataat.c b/src/detect-isdataat.c index b8667fb535..62752d8f5b 100644 --- a/src/detect-isdataat.c +++ b/src/detect-isdataat.c @@ -43,6 +43,8 @@ void DetectIsdataatRegister (void) { sigmatch_table[DETECT_ISDATAAT].Free = DetectIsdataatFree; sigmatch_table[DETECT_ISDATAAT].RegisterTests = DetectIsdataatRegisterTests; + sigmatch_table[DETECT_ISDATAAT].flags |= SIGMATCH_PAYLOAD; + const char *eb; int eo; int opts = 0; diff --git a/src/detect-nocase.c b/src/detect-nocase.c index be455f7c44..1698eea3d8 100644 --- a/src/detect-nocase.c +++ b/src/detect-nocase.c @@ -19,6 +19,7 @@ void DetectNocaseRegister (void) { sigmatch_table[DETECT_NOCASE].RegisterTests = NULL; sigmatch_table[DETECT_NOCASE].flags |= SIGMATCH_NOOPT; + sigmatch_table[DETECT_NOCASE].flags |= SIGMATCH_PAYLOAD; } int DetectNocaseSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *nullstr) diff --git a/src/detect-offset.c b/src/detect-offset.c index b4c2bec377..ace3bff197 100644 --- a/src/detect-offset.c +++ b/src/detect-offset.c @@ -17,6 +17,8 @@ void DetectOffsetRegister (void) { sigmatch_table[DETECT_OFFSET].Setup = DetectOffsetSetup; sigmatch_table[DETECT_OFFSET].Free = NULL; sigmatch_table[DETECT_OFFSET].RegisterTests = NULL; + + sigmatch_table[DETECT_OFFSET].flags |= SIGMATCH_PAYLOAD; } int DetectOffsetSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *offsetstr) diff --git a/src/detect-pcre.c b/src/detect-pcre.c index ae0535d78a..47d0776ba8 100644 --- a/src/detect-pcre.c +++ b/src/detect-pcre.c @@ -33,6 +33,8 @@ void DetectPcreRegister (void) { sigmatch_table[DETECT_PCRE].Free = DetectPcreFree; sigmatch_table[DETECT_PCRE].RegisterTests = NULL; + sigmatch_table[DETECT_PCRE].flags |= SIGMATCH_PAYLOAD; + const char *eb; int eo; int opts = 0; diff --git a/src/detect-pktvar.c b/src/detect-pktvar.c index 0bae9e27db..aa04c6087b 100644 --- a/src/detect-pktvar.c +++ b/src/detect-pktvar.c @@ -25,6 +25,8 @@ void DetectPktvarRegister (void) { sigmatch_table[DETECT_PKTVAR].Free = NULL; sigmatch_table[DETECT_PKTVAR].RegisterTests = NULL; + sigmatch_table[DETECT_PKTVAR].flags |= SIGMATCH_PAYLOAD; + const char *eb; int eo; int opts = 0; diff --git a/src/detect-rawbytes.c b/src/detect-rawbytes.c index cbe8f3562c..bcd3c39c21 100644 --- a/src/detect-rawbytes.c +++ b/src/detect-rawbytes.c @@ -19,6 +19,7 @@ void DetectRawbytesRegister (void) { sigmatch_table[DETECT_RAWBYTES].RegisterTests = NULL; sigmatch_table[DETECT_RAWBYTES].flags |= SIGMATCH_NOOPT; + sigmatch_table[DETECT_RAWBYTES].flags |= SIGMATCH_PAYLOAD; } int DetectRawbytesSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *nullstr) diff --git a/src/detect-uricontent.c b/src/detect-uricontent.c index c0eb5e3c01..251e16a062 100644 --- a/src/detect-uricontent.c +++ b/src/detect-uricontent.c @@ -26,6 +26,8 @@ void DetectUricontentRegister (void) { sigmatch_table[DETECT_URICONTENT].Setup = DetectUricontentSetup; sigmatch_table[DETECT_URICONTENT].Free = NULL; sigmatch_table[DETECT_URICONTENT].RegisterTests = HttpUriRegisterTests; + + sigmatch_table[DETECT_URICONTENT].flags |= SIGMATCH_PAYLOAD; } /* pass on the uricontent_max_id */ diff --git a/src/detect-within.c b/src/detect-within.c index cfe5f86e2a..8a2ab05cea 100644 --- a/src/detect-within.c +++ b/src/detect-within.c @@ -20,6 +20,8 @@ void DetectWithinRegister (void) { sigmatch_table[DETECT_WITHIN].Setup = DetectWithinSetup; sigmatch_table[DETECT_WITHIN].Free = NULL; sigmatch_table[DETECT_WITHIN].RegisterTests = NULL; + + sigmatch_table[DETECT_WITHIN].flags |= SIGMATCH_PAYLOAD; } int DetectWithinSetup (DetectEngineCtx *de_ctx, Signature *s, SigMatch *m, char *withinstr) diff --git a/src/detect.c b/src/detect.c index c3f2230a11..8f0f401639 100644 --- a/src/detect.c +++ b/src/detect.c @@ -340,10 +340,6 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh FlowSetIPOnlyFlag(p->flow, p->flowflags & FLOW_PKT_TOSERVER ? 1 : 0); } - /* if we don't need any pattern matcher or other content inspection, then return*/ - if (p->flags & PKT_NOPAYLOAD_INSPECTION) - return 1; - /* we assume we don't have an uri when we start inspection */ det_ctx->de_have_httpuri = 0; @@ -397,6 +393,11 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh //sig = det_ctx->pmq.sig_id_array[idx]; s = de_ctx->sig_array[sig]; + /* filter out the sigs that inspects the payload, if packet + no payload inspection flag is set*/ + if ((p->flags & PKT_NOPAYLOAD_INSPECTION) && (s->flags & SIG_FLAG_PAYLOAD)) + continue; + /* filter out sigs that want pattern matches, but * have no matches */ if (!(det_ctx->pmq.sig_bitarray[(sig / 8)] & (1<<(sig % 8))) && @@ -605,12 +606,35 @@ iponly: } return 1; } +/** + * \brief Check if the initialized signature is inspecting the packet payload + * \param de_ctx detection engine ctx + * \param s the signature + * \retval 1 sig is inspecting the payload + * \retval 0 sig is not inspecting the payload + */ +static int SignatureIsInspectingPayload(DetectEngineCtx *de_ctx, Signature *s) { + + SigMatch *sm = s->match; + if (sm == NULL) + goto inspect_payload; + + for (; sm != NULL; sm = sm->next) + if (!(sigmatch_table[sm->type].flags & SIGMATCH_PAYLOAD)) + return 0; + +inspect_payload: + if (!(de_ctx->flags & DE_QUIET)) + SCLogDebug("Signature (%" PRIu32 "): is inspecting payload.", s->id); + return 1; +} /* add all signatures to their own source address group */ int SigAddressPrepareStage1(DetectEngineCtx *de_ctx) { Signature *tmp_s = NULL; DetectAddressGroup *gr = NULL; uint32_t cnt = 0, cnt_iponly = 0; + uint32_t cnt_payload = 0; //DetectAddressGroupPrintMemory(); //DetectSigGroupPrintMemory(); @@ -642,7 +666,9 @@ int SigAddressPrepareStage1(DetectEngineCtx *de_ctx) { tmp_s->flags |= SIG_FLAG_IPONLY; cnt_iponly++; //printf("(IP only)\n"); - } else { + } else if (SignatureIsInspectingPayload(de_ctx, tmp_s) == 1) { + tmp_s->flags |= SIG_FLAG_PAYLOAD; + cnt_payload++; //printf("\n"); //if (tmp_s->proto.flags & DETECT_PROTO_ANY) { //printf("Signature %" PRIu32 " applies to all protocols.\n",tmp_s->id); @@ -704,8 +730,8 @@ int SigAddressPrepareStage1(DetectEngineCtx *de_ctx) { //DetectPortPrintMemory(); if (!(de_ctx->flags & DE_QUIET)) { - SCLogInfo("%" PRIu32 " signatures processed. %" PRIu32 " are IP-only rules", - de_ctx->sig_cnt, cnt_iponly); + SCLogInfo("%" PRIu32 " signatures processed. %" PRIu32 " are IP-only rules and %" PRIu32 " are inspecting packet payload", + de_ctx->sig_cnt, cnt_iponly, cnt_payload); SCLogInfo("building signature grouping structure, stage 1: " "adding signatures to signature source addresses... done"); } diff --git a/src/detect.h b/src/detect.h index d2f23e13bf..e35a64004f 100644 --- a/src/detect.h +++ b/src/detect.h @@ -127,6 +127,7 @@ typedef struct DetectPort_ { #define SIG_FLAG_IPONLY 0x0040 /**< ip only signature */ #define SIG_FLAG_MPM 0x0080 /**< sig has mpm portion (content, uricontent, etc) */ #define SIG_FLAG_DEONLY 0x0100 /**< decode event only signature */ +#define SIG_FLAG_PAYLOAD 0x0200 /**< signature is inspecting the packet payload */ /* Detection Engine flags */ #define DE_QUIET 0x01 /**< DE is quiet (esp for unittests) */ @@ -383,6 +384,8 @@ typedef struct SigGroupHead_ { #define SIGMATCH_IPONLY_COMPAT 0x02 /** sigmatch is compatible with a decode event only rule */ #define SIGMATCH_DEONLY_COMPAT 0x04 +/**< Flag to indicate that the signature inspects the packet payload */ +#define SIGMATCH_PAYLOAD 0x08 /** Remember to add the options in SignatureIsIPOnly() at detect.c otherwise it wont be part of a signature group */