/* Copyright (C) 2007-2010 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free * Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * version 2 along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ /** * \file * * \author Anoop Saldanha * * Implements the fast_pattern keyword */ #include "suricata-common.h" #include "detect.h" #include "flow.h" #include "detect-content.h" #include "detect-parse.h" #include "detect-engine.h" #include "detect-engine-mpm.h" #include "detect-fast-pattern.h" #include "util-error.h" #include "util-debug.h" #include "util-unittest.h" static int DetectFastPatternSetup(DetectEngineCtx *, Signature *, char *); void DetectFastPatternRegisterTests(void); /** * \brief Registration function for fast_pattern keyword */ void DetectFastPatternRegister(void) { sigmatch_table[DETECT_FAST_PATTERN].name = "fast_pattern"; sigmatch_table[DETECT_FAST_PATTERN].Match = NULL; sigmatch_table[DETECT_FAST_PATTERN].Setup = DetectFastPatternSetup; sigmatch_table[DETECT_FAST_PATTERN].Free = NULL; sigmatch_table[DETECT_FAST_PATTERN].RegisterTests = DetectFastPatternRegisterTests; sigmatch_table[DETECT_FAST_PATTERN].flags |= SIGMATCH_PAYLOAD; } /** * \brief Configures the previous content context for a fast_pattern modifier * keyword used in the rule * * \param de_ctx Pointer to the Detection Engine Context * \param s Pointer to the Signature to which the current keyword belongs * \param m Pointer to the SigMatch * \param null_str Should hold an empty string always * * \retval 0 On success * \retval -1 On failure */ static int DetectFastPatternSetup(DetectEngineCtx *de_ctx, Signature *s, char *null_str) { if (null_str != NULL && strcmp(null_str, "") != 0) { SCLogError(SC_ERR_INVALID_ARGUMENT, "DetectFastPatternSetup: fast_pattern " "shouldn't be supplied with a value"); return -1; } if (s->pmatch_tail == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "fast_pattern found inside the " "rule, without any preceding keywords"); return -1; } SigMatch *pm = DetectContentGetLastPattern(s->pmatch_tail); if (pm == NULL) { SCLogError(SC_ERR_INVALID_SIGNATURE, "fast_pattern found inside " "the rule, without a content context. Please use a " "content keyword before using fast pattern"); return -1; } ((DetectContentData *)pm->ctx)->flags |= DETECT_CONTENT_FAST_PATTERN; return 0; } /*----------------------------------Unittests---------------------------------*/ #ifdef UNITTESTS /** * \test Checks if a fast_pattern is registered in a Signature */ int DetectFastPatternTest01(void) { SigMatch *sm = NULL; DetectEngineCtx *de_ctx = NULL; int result = 0; if ( (de_ctx = DetectEngineCtxInit()) == NULL) goto end; de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " "(content:\"/one/\"; tcpv4-csum:valid; fast_pattern; " "msg:\"Testing fast_pattern\"; sid:1;)"); if (de_ctx->sig_list == NULL) goto end; result = 0; sm = de_ctx->sig_list->pmatch; while (sm != NULL) { if (sm->type == DETECT_CONTENT) { if ( ((DetectContentData *)sm->ctx)->flags & DETECT_CONTENT_FAST_PATTERN) { result = 1; break; } else { result = 0; break; } } sm = sm->next; } end: SigCleanSignatures(de_ctx); DetectEngineCtxFree(de_ctx); return result; } /** * \test Checks if a fast_pattern is registered in a Signature */ int DetectFastPatternTest02(void) { SigMatch *sm = NULL; DetectEngineCtx *de_ctx = NULL; int result = 0; if ( (de_ctx = DetectEngineCtxInit()) == NULL) goto end; de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " "(content:\"/one/\"; fast_pattern; " "content:boo; fast_pattern; " "msg:\"Testing fast_pattern\"; sid:1;)"); if (de_ctx->sig_list == NULL) goto end; result = 0; sm = de_ctx->sig_list->pmatch; while (sm != NULL) { if (sm->type == DETECT_CONTENT) { if (((DetectContentData *)sm->ctx)->flags & DETECT_CONTENT_FAST_PATTERN) { result = 1; } else { result = 0; break; } } sm = sm->next; } end: SigCleanSignatures(de_ctx); DetectEngineCtxFree(de_ctx); return result; } /** * \test Checks that we have no fast_pattern registerd for a Signature when the * Signature doesn't contain a fast_pattern */ int DetectFastPatternTest03(void) { SigMatch *sm = NULL; DetectEngineCtx *de_ctx = NULL; int result = 0; if ( (de_ctx = DetectEngineCtxInit()) == NULL) goto end; de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " "(content:\"/one/\"; " "msg:\"Testing fast_pattern\"; sid:1;)"); if (de_ctx->sig_list == NULL) goto end; result = 0; sm = de_ctx->sig_list->pmatch; while (sm != NULL) { if (sm->type == DETECT_CONTENT) { if ( !(((DetectContentData *)sm->ctx)->flags & DETECT_CONTENT_FAST_PATTERN)) { result = 1; } else { result = 0; break; } } sm = sm->next; } end: SigCleanSignatures(de_ctx); DetectEngineCtxFree(de_ctx); return result; } /** * \test Checks that a fast_pattern is not registered in a Signature, when we * supply a fast_pattern with an argument */ int DetectFastPatternTest04(void) { DetectEngineCtx *de_ctx = NULL; int result = 0; if ( (de_ctx = DetectEngineCtxInit()) == NULL) goto end; de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " "(content:\"/one/\"; fast_pattern:boo; " "msg:\"Testing fast_pattern\"; sid:1;)"); if (de_ctx->sig_list == NULL) result = 1; end: SigCleanSignatures(de_ctx); DetectEngineCtxFree(de_ctx); return result; } /** * \test Checks that a fast_pattern is used in the mpm phase. */ int DetectFastPatternTest05(void) { uint8_t *buf = (uint8_t *) "Oh strin1. But what " "strin2. This is strings3. We strins_str4. we " "have strins_string5"; uint16_t buflen = strlen((char *)buf); Packet p; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; int result = 0; memset(&th_v, 0, sizeof(th_v)); memset(&p, 0, sizeof(p)); p.src.family = AF_INET; p.dst.family = AF_INET; p.payload = buf; p.payload_len = buflen; p.proto = IPPROTO_TCP; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"fast_pattern test\"; content:string1; " "content:string2; content:strings3; fast_pattern; " "content:strings_str4; content:strings_string5; " "sid:1;)"); if (de_ctx->sig_list == NULL) { printf("sig parse failed: "); goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, &p); if (PacketPatternSearch(&th_v, det_ctx, &p) != 0) result = 1; SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); end: DetectEngineCtxFree(de_ctx); return result; } /** * \test Checks that a fast_pattern is used in the mpm phase. */ int DetectFastPatternTest06(void) { uint8_t *buf = (uint8_t *) "Oh this is a string1. But what is this with " "string2. This is strings3. We have strings_str4. We also have " "strings_string5"; uint16_t buflen = strlen((char *)buf); Packet p; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; int result = 0; memset(&th_v, 0, sizeof(th_v)); memset(&p, 0, sizeof(p)); p.src.family = AF_INET; p.dst.family = AF_INET; p.payload = buf; p.payload_len = buflen; p.proto = IPPROTO_TCP; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"fast_pattern test\"; content:string1; " "content:string2; content:strings3; fast_pattern; " "content:strings_str4; content:strings_string5; " "sid:1;)"); if (de_ctx->sig_list == NULL) goto end; SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, &p); if (PacketPatternSearch(&th_v, det_ctx, &p) != 0) result = 1; SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); end: DetectEngineCtxFree(de_ctx); return result; } /** * \test Checks that a fast_pattern is used in the mpm phase, when the payload * doesn't contain the fast_pattern string within it. */ int DetectFastPatternTest07(void) { uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " "right now, all the way to hangover. right. now here comes our " "dark knight strings_string5. Yes here is our dark knight"; uint16_t buflen = strlen((char *)buf); Packet p; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; int result = 0; memset(&th_v, 0, sizeof(th_v)); memset(&p, 0, sizeof(p)); p.src.family = AF_INET; p.dst.family = AF_INET; p.payload = buf; p.payload_len = buflen; p.proto = IPPROTO_TCP; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"fast_pattern test\"; content:string1; " "content:string2; content:strings3; fast_pattern; " "content:strings_str4; content:strings_string5; " "sid:1;)"); if (de_ctx->sig_list == NULL) goto end; SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, &p); if (PacketPatternSearch(&th_v, det_ctx, &p) == 0) result = 1; SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); end: DetectEngineCtxFree(de_ctx); return result; } /** * \test Checks that a fast_pattern is used in the mpm phase and that we get * exactly 1 match for the mpm phase. */ int DetectFastPatternTest08(void) { uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " "right now, all the way to hangover. right. now here comes our " "dark knight strings3. Yes here is our dark knight"; uint16_t buflen = strlen((char *)buf); Packet p; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; int result = 0; memset(&th_v, 0, sizeof(th_v)); memset(&p, 0, sizeof(p)); p.src.family = AF_INET; p.dst.family = AF_INET; p.payload = buf; p.payload_len = buflen; p.proto = IPPROTO_TCP; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { printf("de_ctx init: "); goto end; } de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"fast_pattern test\"; content:string1; " "content:string2; content:strings3; fast_pattern; " "content:strings_str4; content:strings_string5; " "sid:1;)"); if (de_ctx->sig_list == NULL) { printf("sig parse failed: "); goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, &p); uint32_t r = PacketPatternSearch(&th_v, det_ctx, &p); if (r != 1) { printf("expected 1, got %"PRIu32": ", r); goto end; } result = 1; end: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); return result; } /** * \test Checks that a fast_pattern is used in the mpm phase, when the payload * doesn't contain the fast_pattern string within it. */ int DetectFastPatternTest09(void) { uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " "right now, all the way to hangover. right. no_strings4 _imp now here " "comes our dark knight strings3. Yes here is our dark knight"; uint16_t buflen = strlen((char *)buf); Packet p; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; int result = 0; memset(&th_v, 0, sizeof(th_v)); memset(&p, 0, sizeof(p)); p.src.family = AF_INET; p.dst.family = AF_INET; p.payload = buf; p.payload_len = buflen; p.proto = IPPROTO_TCP; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"fast_pattern test\"; content:string1; " "content:string2; content:strings3; fast_pattern; " "content:strings4_imp; fast_pattern; " "content:strings_string5; sid:1;)"); if (de_ctx->sig_list == NULL) goto end; SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, &p); if (PacketPatternSearch(&th_v, det_ctx, &p) == 0) result = 1; SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); end: DetectEngineCtxFree(de_ctx); return result; } /** * \test Checks that a the SigInit chooses the fast_pattern with better pattern * strength, when we have multiple fast_patterns in the Signature. Also * checks that we get a match for the fast_pattern from the mpm phase. */ int DetectFastPatternTest10(void) { uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " "right now, all the way to hangover. right. strings4_imp now here " "comes our dark knight strings5. Yes here is our dark knight"; uint16_t buflen = strlen((char *)buf); Packet p; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; int result = 0; memset(&th_v, 0, sizeof(th_v)); memset(&p, 0, sizeof(p)); p.src.family = AF_INET; p.dst.family = AF_INET; p.payload = buf; p.payload_len = buflen; p.proto = IPPROTO_TCP; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { printf("de_ctx init: "); goto end; } de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"fast_pattern test\"; content:string1; " "content:string2; content:strings3; fast_pattern; " "content:strings4_imp; fast_pattern; " "content:strings_string5; sid:1;)"); if (de_ctx->sig_list == NULL) { printf("sig parse failed: "); goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, &p); uint32_t r = PacketPatternSearch(&th_v, det_ctx, &p); if (r != 1) { printf("expected 1, got %"PRIu32": ", r); goto end; } result = 1; end: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); return result; } /** * \test Checks that a the SigInit chooses the fast_pattern with better pattern * strength, when we have multiple fast_patterns in the Signature. Also * checks that we get no matches for the fast_pattern from the mpm phase. */ int DetectFastPatternTest11(void) { uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " "right now, all the way to hangover. right. strings5_imp now here " "comes our dark knight strings5. Yes here is our dark knight"; uint16_t buflen = strlen((char *)buf); Packet p; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; int result = 0; memset(&th_v, 0, sizeof(th_v)); memset(&p, 0, sizeof(p)); p.src.family = AF_INET; p.dst.family = AF_INET; p.payload = buf; p.payload_len = buflen; p.proto = IPPROTO_TCP; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"fast_pattern test\"; content:string1; " "content:string2; content:strings3; fast_pattern; " "content:strings4_imp; fast_pattern; " "content:strings_string5; sid:1;)"); if (de_ctx->sig_list == NULL) goto end; SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, &p); if (PacketPatternSearch(&th_v, det_ctx, &p) == 0) result = 1; end: if (de_ctx != NULL) { SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); if (det_ctx != NULL) DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); } return result; } /** * \test Checks that we don't get a match for the mpm phase. */ int DetectFastPatternTest12(void) { uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " "right now, all the way to hangover. right. strings5_imp now here " "comes our dark knight strings5. Yes here is our dark knight"; uint16_t buflen = strlen((char *)buf); Packet p; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; int result = 0; memset(&th_v, 0, sizeof(th_v)); memset(&p, 0, sizeof(p)); p.src.family = AF_INET; p.dst.family = AF_INET; p.payload = buf; p.payload_len = buflen; p.proto = IPPROTO_TCP; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"fast_pattern test\"; content:string1; " "content:string2; content:strings3; " "content:strings4_imp; " "content:strings_string5; sid:1;)"); if (de_ctx->sig_list == NULL) goto end; SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, &p); if (PacketPatternSearch(&th_v, det_ctx, &p) == 0) result = 1; SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); end: DetectEngineCtxFree(de_ctx); return result; } /** * \test Checks that a the SigInit chooses the fast_pattern with a better * strength from the available patterns, when we don't specify a * fast_pattern. We also check that we get a match from the mpm * phase. */ int DetectFastPatternTest13(void) { uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " "right now, all the way to hangover. right. strings5_imp now here " "comes our dark knight strings_string5. Yes here is our dark knight"; uint16_t buflen = strlen((char *)buf); Packet p; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; int result = 0; memset(&th_v, 0, sizeof(th_v)); memset(&p, 0, sizeof(p)); p.src.family = AF_INET; p.dst.family = AF_INET; p.payload = buf; p.payload_len = buflen; p.proto = IPPROTO_TCP; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) { printf("de_ctx init: "); goto end; } de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"fast_pattern test\"; content:string1; " "content:string2; content:strings3; " "content:strings4_imp; " "content:strings_string5; sid:1;)"); if (de_ctx->sig_list == NULL) { printf("sig parse failed: "); goto end; } SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); /* start the search phase */ det_ctx->sgh = SigMatchSignaturesGetSgh(de_ctx, det_ctx, &p); uint32_t r = PacketPatternSearch(&th_v, det_ctx, &p); if (r != 1) { printf("expected 1 result, got %"PRIu32": ", r); goto end; } result = 1; end: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); return result; } /** * \test Checks to make sure that other sigs work that should when fast_pattern is inspecting on the same payload * */ int DetectFastPatternTest14(void) { uint8_t *buf = (uint8_t *) "Dummy is our name. Oh yes. From right here " "right now, all the way to hangover. right. strings5_imp now here " "comes our dark knight strings_string5. Yes here is our dark knight"; uint16_t buflen = strlen((char *)buf); Packet p; ThreadVars th_v; DetectEngineThreadCtx *det_ctx = NULL; int alertcnt = 0; int result = 0; memset(&th_v, 0, sizeof(th_v)); memset(&p, 0, sizeof(p)); p.src.family = AF_INET; p.dst.family = AF_INET; p.payload = buf; p.payload_len = buflen; p.proto = IPPROTO_TCP; DetectEngineCtx *de_ctx = DetectEngineCtxInit(); if (de_ctx == NULL) goto end; FlowInitConfig(FLOW_QUIET); de_ctx->mpm_matcher = MPM_B3G; de_ctx->flags |= DE_QUIET; de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"fast_pattern test\"; content:\"strings_string5\"; content:\"knight\"; fast_pattern; sid:1;)"); if (de_ctx->sig_list == NULL) goto end; de_ctx->sig_list->next = SigInit(de_ctx, "alert tcp any any -> any any " "(msg:\"test different content\"; content:\"Dummy is our name\"; sid:2;)"); if (de_ctx->sig_list->next == NULL) goto end; SigGroupBuild(de_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, &p); if (PacketAlertCheck(&p, 1)){ alertcnt++; }else{ SCLogInfo("could not match on sig 1 with when fast_pattern is inspecting payload"); goto end; } if (PacketAlertCheck(&p, 2)){ result = 1; }else{ SCLogInfo("match on sig 1 fast_pattern no match sig 2 inspecting same payload"); } end: SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); FlowShutdown(); return result; } #endif void DetectFastPatternRegisterTests(void) { #ifdef UNITTESTS UtRegisterTest("DetectFastPatternTest01", DetectFastPatternTest01, 1); UtRegisterTest("DetectFastPatternTest02", DetectFastPatternTest02, 1); UtRegisterTest("DetectFastPatternTest03", DetectFastPatternTest03, 1); UtRegisterTest("DetectFastPatternTest04", DetectFastPatternTest04, 1); UtRegisterTest("DetectFastPatternTest05", DetectFastPatternTest05, 1); UtRegisterTest("DetectFastPatternTest06", DetectFastPatternTest06, 1); UtRegisterTest("DetectFastPatternTest07", DetectFastPatternTest07, 1); UtRegisterTest("DetectFastPatternTest08", DetectFastPatternTest08, 1); UtRegisterTest("DetectFastPatternTest09", DetectFastPatternTest09, 1); UtRegisterTest("DetectFastPatternTest10", DetectFastPatternTest10, 1); UtRegisterTest("DetectFastPatternTest11", DetectFastPatternTest11, 1); UtRegisterTest("DetectFastPatternTest12", DetectFastPatternTest12, 1); UtRegisterTest("DetectFastPatternTest13", DetectFastPatternTest13, 1); UtRegisterTest("DetectFastPatternTest14", DetectFastPatternTest14, 1); #endif }