packet/stream: mpm prefilter engine

pull/2310/head
Victor Julien 9 years ago
parent 72f2a78b1f
commit 9ff5703c49

@ -48,6 +48,7 @@
#include "detect-content.h"
#include "detect-engine-payload.h"
#include "detect-engine-uri.h"
#include "detect-engine-hmd.h"
@ -1230,6 +1231,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
sh->mpm_packet_ctx = mpm_store->mpm_ctx;
if (sh->mpm_packet_ctx)
sh->flags |= SIG_GROUP_HEAD_MPM_PACKET;
PrefilterPktPayloadRegister(sh, mpm_store->mpm_ctx);
}
mpm_store = MpmStorePrepareBuffer(de_ctx, sh, MPMB_TCP_STREAM_TS);
@ -1239,6 +1242,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
sh->mpm_stream_ctx = mpm_store->mpm_ctx;
if (sh->mpm_stream_ctx)
sh->flags |= SIG_GROUP_HEAD_MPM_STREAM;
PrefilterPktStreamRegister(sh, mpm_store->mpm_ctx);
}
}
if (SGH_DIRECTION_TC(sh)) {
@ -1248,6 +1253,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
sh->mpm_packet_ctx = mpm_store->mpm_ctx;
if (sh->mpm_packet_ctx)
sh->flags |= SIG_GROUP_HEAD_MPM_PACKET;
PrefilterPktPayloadRegister(sh, mpm_store->mpm_ctx);
}
mpm_store = MpmStorePrepareBuffer(de_ctx, sh, MPMB_TCP_STREAM_TC);
@ -1256,6 +1263,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
sh->mpm_stream_ctx = mpm_store->mpm_ctx;
if (sh->mpm_stream_ctx)
sh->flags |= SIG_GROUP_HEAD_MPM_STREAM;
PrefilterPktStreamRegister(sh, mpm_store->mpm_ctx);
}
}
} else if (SGH_PROTO(sh, IPPROTO_UDP)) {
@ -1268,6 +1277,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
if (sh->mpm_packet_ctx != NULL)
sh->flags |= SIG_GROUP_HEAD_MPM_PACKET;
PrefilterPktPayloadRegister(sh, mpm_store->mpm_ctx);
}
}
if (SGH_DIRECTION_TC(sh)) {
@ -1278,6 +1289,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
if (sh->mpm_packet_ctx != NULL)
sh->flags |= SIG_GROUP_HEAD_MPM_PACKET;
PrefilterPktPayloadRegister(sh, mpm_store->mpm_ctx);
}
}
} else {
@ -1288,6 +1301,8 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
if (sh->mpm_packet_ctx != NULL)
sh->flags |= SIG_GROUP_HEAD_MPM_PACKET;
PrefilterPktPayloadRegister(sh, mpm_store->mpm_ctx);
}
}

@ -40,9 +40,6 @@ void DetectMpmPrepareBuiltinMpms(DetectEngineCtx *de_ctx);
uint32_t PatternStrength(uint8_t *, uint16_t);
uint16_t PatternMatchDefaultMatcher(void);
uint32_t PacketPatternSearchWithStreamCtx(DetectEngineThreadCtx *, Packet *);
uint32_t PacketPatternSearch(DetectEngineThreadCtx *, Packet *);
uint32_t StreamPatternSearch(DetectEngineThreadCtx *, Packet *, StreamMsg *, uint8_t);
uint32_t DnsQueryPatternSearch(DetectEngineThreadCtx *det_ctx, uint8_t *buffer, uint32_t buffer_len, uint8_t flags);
void PacketPatternCleanup(ThreadVars *, DetectEngineThreadCtx *);

@ -32,6 +32,7 @@
#include "detect-engine.h"
#include "detect-parse.h"
#include "detect-engine-content-inspection.h"
#include "detect-engine-prefilter.h"
#include "stream.h"
@ -44,100 +45,77 @@
#include "util-mpm-ac.h"
uint32_t PacketPatternSearchWithStreamCtx(DetectEngineThreadCtx *det_ctx,
const Packet *p)
static void PrefilterPktStream(DetectEngineThreadCtx *det_ctx,
Packet *p, const void *pectx)
{
SCEnter();
uint32_t ret = 0;
const MpmCtx *mpm_ctx = (MpmCtx *)pectx;
const StreamMsg *smsg = det_ctx->smsg;
DEBUG_VALIDATE_BUG_ON(det_ctx->sgh->mpm_stream_ctx == NULL);
if (det_ctx->sgh->mpm_stream_ctx == NULL)
SCReturnInt(0);
/* for established packets inspect any smsg we may have queued up */
if (p->flowflags & FLOW_PKT_ESTABLISHED) {
SCLogDebug("p->flowflags & FLOW_PKT_ESTABLISHED");
if (p->payload_len >= det_ctx->sgh->mpm_stream_ctx->minlen) {
ret = mpm_table[det_ctx->sgh->mpm_stream_ctx->mpm_type].
Search(det_ctx->sgh->mpm_stream_ctx, &det_ctx->mtc, &det_ctx->pmq,
p->payload, p->payload_len);
for ( ; smsg != NULL; smsg = smsg->next) {
if (smsg->data_len >= mpm_ctx->minlen) {
(void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
&det_ctx->mtcs, &det_ctx->pmq,
smsg->data, smsg->data_len);
}
}
} else {
SCLogDebug("NOT p->flowflags & FLOW_PKT_ESTABLISHED");
}
SCReturnInt(ret);
}
/** \brief Pattern match -- searches for only one pattern per signature.
*
* \param det_ctx detection engine thread ctx
* \param p packet
* \param smsg stream msg (reassembled stream data)
* \param flags stream flags
*
* \retval ret number of matches
*/
uint32_t StreamPatternSearch(DetectEngineThreadCtx *det_ctx, const Packet *p,
const StreamMsg *smsg, const uint8_t flags)
{
SCEnter();
uint32_t ret = 0;
//PrintRawDataFp(stdout, smsg->data.data, smsg->data.data_len);
uint32_t r;
for ( ; smsg != NULL; smsg = smsg->next) {
if (smsg->data_len >= det_ctx->sgh->mpm_stream_ctx->minlen) {
r = mpm_table[det_ctx->sgh->mpm_stream_ctx->mpm_type].
Search(det_ctx->sgh->mpm_stream_ctx, &det_ctx->mtcs,
&det_ctx->pmq, smsg->data, smsg->data_len);
if (r > 0) {
ret += r;
}
/* packets that have not been added to the stream will be inspected
* as if they are stream chunks */
if ((!(p->flags & PKT_NOPAYLOAD_INSPECTION)) &&
!(p->flags & PKT_STREAM_ADD))
{
if (p->payload_len >= mpm_ctx->minlen) {
(void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
&det_ctx->mtc, &det_ctx->pmq,
p->payload, p->payload_len);
}
}
}
SCReturnInt(ret);
int PrefilterPktStreamRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx)
{
return PrefilterAppendEngine(sgh, PrefilterPktStream, mpm_ctx, NULL);
}
/** \brief Pattern match -- searches for only one pattern per signature.
*
* \param det_ctx detection engine thread ctx
* \param p packet to inspect
*
* \retval ret number of matches
*/
uint32_t PacketPatternSearch(DetectEngineThreadCtx *det_ctx, Packet *p)
static void PrefilterPktPayload(DetectEngineThreadCtx *det_ctx,
Packet *p, const void *pectx)
{
SCEnter();
uint32_t ret = 0;
const MpmCtx *mpm_ctx = NULL;
mpm_ctx = det_ctx->sgh->mpm_packet_ctx;
if (unlikely(mpm_ctx == NULL))
SCReturnInt(0);
const MpmCtx *mpm_ctx = (MpmCtx *)pectx;
if (p->payload_len < mpm_ctx->minlen)
SCReturnInt(0);
SCReturn;
#ifdef __SC_CUDA_SUPPORT__
if (p->cuda_pkt_vars.cuda_mpm_enabled && p->pkt_src == PKT_SRC_WIRE) {
ret = SCACCudaPacketResultsProcessing(p, mpm_ctx, &det_ctx->pmq);
(void)SCACCudaPacketResultsProcessing(p, mpm_ctx, &det_ctx->pmq);
} else {
ret = mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
&det_ctx->mtc,
&det_ctx->pmq,
p->payload,
p->payload_len);
(void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
&det_ctx->mtc, &det_ctx->pmq,
p->payload, p->payload_len);
}
#else
ret = mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
&det_ctx->mtc,
&det_ctx->pmq,
p->payload,
p->payload_len);
(void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
&det_ctx->mtc, &det_ctx->pmq,
p->payload, p->payload_len);
#endif
}
SCReturnInt(ret);
int PrefilterPktPayloadRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx)
{
return PrefilterAppendEngine(sgh, PrefilterPktPayload, mpm_ctx, NULL);
}
/**
* \brief Do the content inspection & validation for a signature
*

@ -24,6 +24,9 @@
#ifndef __DETECT_ENGINE_PAYLOAD_H__
#define __DETECT_ENGINE_PAYLOAD_H__
int PrefilterPktPayloadRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx);
int PrefilterPktStreamRegister(SigGroupHead *sgh, MpmCtx *mpm_ctx);
int DetectEngineInspectPacketPayload(DetectEngineCtx *,
DetectEngineThreadCtx *, Signature *, Flow *, Packet *);
int DetectEngineInspectStreamPayload(DetectEngineCtx *,

@ -518,488 +518,6 @@ int DetectFastPatternTest04(void)
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 = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
int result = 0;
memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacket(buf,buflen,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 (PacketPatternSearchWithStreamCtx(det_ctx, p) != 0)
result = 1;
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
end:
UTHFreePackets(&p, 1);
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 = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
int result = 0;
memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacket(buf,buflen,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 (PacketPatternSearchWithStreamCtx(det_ctx, p) != 0)
result = 1;
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
end:
UTHFreePackets(&p, 1);
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 = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
int result = 0;
memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacket(buf,buflen,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 (PacketPatternSearchWithStreamCtx(det_ctx, p) == 0)
result = 1;
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
end:
UTHFreePackets(&p, 1);
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 = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
int result = 0;
memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacket(buf,buflen,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 = PacketPatternSearchWithStreamCtx(det_ctx, p);
if (r != 1) {
printf("expected 1, got %"PRIu32": ", r);
goto end;
}
result = 1;
end:
UTHFreePackets(&p, 1);
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 = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
int result = 0;
memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacket(buf,buflen,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\"; 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 (PacketPatternSearchWithStreamCtx(det_ctx, p) == 0)
result = 1;
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
end:
UTHFreePackets(&p, 1);
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 = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
int result = 0;
memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacket(buf,buflen,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\"; 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 = PacketPatternSearchWithStreamCtx(det_ctx, p);
if (r != 1) {
printf("expected 1, got %"PRIu32": ", r);
goto end;
}
result = 1;
end:
UTHFreePackets(&p, 1);
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 = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
int result = 0;
memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacket(buf,buflen,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\"; 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 (PacketPatternSearchWithStreamCtx(det_ctx, p) == 0)
result = 1;
end:
UTHFreePackets(&p, 1);
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 = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
int result = 0;
memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacket(buf,buflen,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 (PacketPatternSearchWithStreamCtx(det_ctx, p) == 0)
result = 1;
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
end:
UTHFreePackets(&p, 1);
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 = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
int result = 0;
memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacket(buf,buflen,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 = PacketPatternSearchWithStreamCtx(det_ctx, p);
if (r != 1) {
printf("expected 1 result, got %"PRIu32": ", r);
goto end;
}
result = 1;
end:
UTHFreePackets(&p, 1);
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
*
@ -19430,15 +18948,6 @@ void DetectFastPatternRegisterTests(void)
UtRegisterTest("DetectFastPatternTest02", DetectFastPatternTest02);
UtRegisterTest("DetectFastPatternTest03", DetectFastPatternTest03);
UtRegisterTest("DetectFastPatternTest04", DetectFastPatternTest04);
UtRegisterTest("DetectFastPatternTest05", DetectFastPatternTest05);
UtRegisterTest("DetectFastPatternTest06", DetectFastPatternTest06);
UtRegisterTest("DetectFastPatternTest07", DetectFastPatternTest07);
UtRegisterTest("DetectFastPatternTest08", DetectFastPatternTest08);
UtRegisterTest("DetectFastPatternTest09", DetectFastPatternTest09);
UtRegisterTest("DetectFastPatternTest10", DetectFastPatternTest10);
UtRegisterTest("DetectFastPatternTest11", DetectFastPatternTest11);
UtRegisterTest("DetectFastPatternTest12", DetectFastPatternTest12);
UtRegisterTest("DetectFastPatternTest13", DetectFastPatternTest13);
UtRegisterTest("DetectFastPatternTest14", DetectFastPatternTest14);
UtRegisterTest("DetectFastPatternTest15", DetectFastPatternTest15);
UtRegisterTest("DetectFastPatternTest16", DetectFastPatternTest16);

@ -1072,42 +1072,9 @@ static inline void DetectMpmPrefilter(DetectEngineCtx *de_ctx,
}
}
}
if (smsg != NULL && (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_STREAM)) {
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_STREAM);
StreamPatternSearch(det_ctx, p, smsg, flags);
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_STREAM);
} else {
SCLogDebug("smsg NULL or no stream mpm for this sgh");
}
} else {
SCLogDebug("NOT p->flowflags & FLOW_PKT_ESTABLISHED");
}
if (p->payload_len > 0 && (!(p->flags & PKT_NOPAYLOAD_INSPECTION))) {
if (!(p->flags & PKT_STREAM_ADD) && (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_STREAM)) {
*sms_runflags |= SMS_USED_PM;
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_PKT_STREAM);
PacketPatternSearchWithStreamCtx(det_ctx, p);
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_PKT_STREAM);
}
if (det_ctx->sgh->flags & SIG_GROUP_HEAD_MPM_PACKET) {
/* run the multi packet matcher against the payload of the packet */
SCLogDebug("search: (%p, sgh->sig_cnt %" PRIu32 ")",
det_ctx->sgh, det_ctx->sgh->sig_cnt);
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM_PACKET);
PacketPatternSearch(det_ctx, p);
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM_PACKET);
*sms_runflags |= SMS_USED_PM;
} else {
SCLogDebug("not packet");
}
} else {
SCLogDebug("how did we get here?");
}
/* UDP DNS inspection is independent of est or not */
if (alproto == ALPROTO_DNS && has_state) {
if (p->flowflags & FLOW_PKT_TOSERVER) {
@ -1266,7 +1233,6 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
int smatch = 0; /* signature match: 1, no match: 0 */
#endif
uint8_t flow_flags = 0; /* flow/state flags */
StreamMsg *smsg = NULL;
Signature *s = NULL;
Signature *next_s = NULL;
uint8_t alversion = 0;
@ -1281,7 +1247,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
p->alerts.cnt = 0;
det_ctx->filestore_cnt = 0;
det_ctx->smsg = NULL;
det_ctx->base64_decoded_len = 0;
/* No need to perform any detection on this packet, if the the given flag is set.*/
@ -1358,7 +1324,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
}
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_GETSGH);
smsg = SigMatchSignaturesGetSmsg(pflow, p, flow_flags);
det_ctx->smsg = SigMatchSignaturesGetSmsg(pflow, p, flow_flags);
#if 0
StreamMsg *tmpsmsg = smsg;
while (tmpsmsg) {
@ -1428,7 +1394,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
#ifdef DEBUG
if (pflow) {
DebugInspectIds(p, pflow, smsg);
DebugInspectIds(p, pflow, det_ctx->smsg);
}
#endif
} else { /* p->flags & PKT_HAS_FLOW */
@ -1472,7 +1438,8 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
/* create our prefilter mask */
SignatureMask mask = 0;
PacketCreateMask(p, &mask, alproto, has_state, smsg, app_decoder_events);
PacketCreateMask(p, &mask, alproto, has_state, det_ctx->smsg,
app_decoder_events);
/* build and prefilter non_pf list against the mask of the packet */
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_NONMPMLIST);
@ -1487,7 +1454,8 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
/* run the mpm for each type */
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_MPM);
DetectMpmPrefilter(de_ctx, det_ctx, smsg, p, flow_flags, alproto, has_state, &sms_runflags);
DetectMpmPrefilter(de_ctx, det_ctx, det_ctx->smsg, p, flow_flags,
alproto, has_state, &sms_runflags);
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_MPM);
#ifdef PROFILING
@ -1663,12 +1631,12 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
* but not for a "dsize" signature */
if (sflags & SIG_FLAG_REQUIRE_STREAM) {
char pmatch = 0;
if (smsg != NULL) {
if (det_ctx->smsg != NULL) {
uint8_t pmq_idx = 0;
StreamMsg *smsg_inspect = smsg;
StreamMsg *smsg_inspect = det_ctx->smsg;
for ( ; smsg_inspect != NULL; smsg_inspect = smsg_inspect->next, pmq_idx++) {
if (DetectEngineInspectStreamPayload(de_ctx, det_ctx, s, pflow, smsg_inspect->data, smsg_inspect->data_len) == 1) {
SCLogDebug("match in smsg %p", smsg);
SCLogDebug("match in smsg %p", smsg_inspect);
pmatch = 1;
det_ctx->flags |= DETECT_ENGINE_THREAD_CTX_STREAM_CONTENT_MATCH;
/* Tell the engine that this reassembled stream can drop the
@ -1937,7 +1905,8 @@ end:
/* if we had no alerts that involved the smsgs,
* we can get rid of them now. */
StreamMsgReturnListToPool(smsg);
StreamMsgReturnListToPool(det_ctx->smsg);
det_ctx->smsg = NULL;
}
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_CLEANUP);

@ -45,6 +45,8 @@
#include "detect-mark.h"
#include "stream.h"
#define DETECT_MAX_RULE_SIZE 8192
/* forward declarations for the structures from detect-engine-sigorder.h */
@ -834,6 +836,8 @@ typedef struct DetectEngineThreadCtx_ {
MpmThreadCtx mtcs; /**< thread ctx for stream mpm */
PrefilterRuleStore pmq;
StreamMsg *smsg;
/** SPM thread context used for scanning. This has been cloned from the
* prototype held by DetectEngineCtx. */
SpmThreadCtx *spm_thread_ctx;

Loading…
Cancel
Save