use a single populatempm() function to add the right content for mpm

remotes/origin/master-1.1.x
Anoop Saldanha 15 years ago committed by Victor Julien
parent 4a038511ff
commit 46b4806d8e

@ -37,6 +37,7 @@
#include "detect-parse.h"
#include "util-mpm.h"
#include "conf.h"
#include "detect-fast-pattern.h"
#include "flow.h"
#include "flow-var.h"
@ -66,6 +67,10 @@
#endif
//#define PM MPM_B3G
#define POPULATE_MPM_AVOID_PACKET_MPM_PATTERNS 0x01
#define POPULATE_MPM_AVOID_STREAM_MPM_PATTERNS 0x02
#define POPULATE_MPM_AVOID_URI_MPM_PATTERNS 0x04
/* holds the string-enum mapping for the enums that define the different MPM
* algos in util-mpm.h */
SCEnumCharMap sc_mpm_algo_map[] = {
@ -540,8 +545,382 @@ uint32_t PatternStrength(uint8_t *pat, uint16_t patlen) {
return s;
}
/**
* \brief Setup the mpm content.
*
* \param de_ctx Pointer to the detect engine context.
* \param sgh Pointer to the signature group head against which we are
* adding patterns to the mpm ctx.
*
* \retval 0 Always.
*/
static int PatternMatchPreparePopulateMpm(DetectEngineCtx *de_ctx,
SigGroupHead *sgh,
uint8_t populate_mpm_flags)
{
uint32_t sig;
uint32_t *fast_pattern = NULL;
fast_pattern = (uint32_t *)SCMalloc(sgh->sig_cnt * sizeof(uint32_t));
if (fast_pattern == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
exit(EXIT_FAILURE);
}
memset(fast_pattern, 0, sgh->sig_cnt * sizeof(uint32_t));
/* add all mpm candidates to a hash */
for (sig = 0; sig < sgh->sig_cnt; sig++) {
Signature *s = sgh->match_array[sig];
if (s == NULL)
continue;
int sig_has_no_pkt_and_stream_content = 0;
if (!SignatureHasPacketContent(s) && !SignatureHasStreamContent(s)) {
sig_has_no_pkt_and_stream_content = 1;
}
int list_id = 0;
for ( ; list_id < DETECT_SM_LIST_MAX; list_id++) {
/* we have no keywords that support fp in this Signature sm list */
if (!SCFPDoWeSupportFPForSMList(list_id))
continue;
SigMatch *sm = NULL;
/* get the total no of patterns in this Signature, as well as find out
* if we have a fast_pattern set in this Signature */
for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) {
/* this keyword isn't registered for fp support */
if (!SCFPDoWeSupportFPForSMType(sm->type))
continue;
DetectContentData *cd = NULL;
DetectUricontentData *ud = NULL;
switch (sm->type) {
case DETECT_CONTENT:
if (sig_has_no_pkt_and_stream_content ||
(populate_mpm_flags & POPULATE_MPM_AVOID_PACKET_MPM_PATTERNS &&
populate_mpm_flags & POPULATE_MPM_AVOID_STREAM_MPM_PATTERNS)) {
break;
}
cd = (DetectContentData *)sm->ctx;
/* special handling of fast pattern keyword */
if (cd->flags & DETECT_CONTENT_FAST_PATTERN) {
fast_pattern[sig] = 1;
}
break;
case DETECT_URICONTENT:
if (populate_mpm_flags & POPULATE_MPM_AVOID_URI_MPM_PATTERNS) {
break;
}
ud = (DetectUricontentData *)sm->ctx;
/* special handling of fast pattern keyword */
if (ud->flags & DETECT_URICONTENT_FAST_PATTERN) {
fast_pattern[sig] = 1;
}
break;
default:
SCLogError(SC_ERR_FATAL, "We shouldn't even be seeing this");
exit(EXIT_FAILURE);
} /* switch (sm->type) */
/* found a fast pattern for the sig. Let's get outta here */
if (fast_pattern[sig])
break;
} /* for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) */
/* found a fast pattern for the sig. Let's get outta here */
if (fast_pattern[sig])
break;
} /* for ( ; list_id < DETECT_SM_LIST_MAX; list_id++) */
} /* for (sig = 0; sig < sgh->sig_cnt; sig++) { */
/* now determine which one to add to the mpm phase */
for (sig = 0; sig < sgh->sig_cnt; sig++) {
Signature *s = sgh->match_array[sig];
if (s == NULL)
continue;
int sig_has_no_pkt_and_stream_content = 0;
if (!SignatureHasPacketContent(s) && !SignatureHasStreamContent(s)) {
sig_has_no_pkt_and_stream_content = 1;
}
SigMatch *mpm_sm = NULL;
SigMatch *sm = NULL;
int list_id = 0;
for ( ; list_id < DETECT_SM_LIST_MAX; list_id++) {
if (!SCFPDoWeSupportFPForSMList(list_id))
continue;
for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) {
if (!SCFPDoWeSupportFPForSMType(sm->type))
continue;
/* skip in case of:
* 1. we expect a fastpattern but this isn't it
* 2. we have a smaller content than mpm_content_maxlen */
if (fast_pattern[sig]) {
DetectContentData *cd = NULL;
DetectUricontentData *ud = NULL;
switch (sm->type) {
case DETECT_CONTENT:
cd = (DetectContentData *)sm->ctx;
if (!(cd->flags & DETECT_CONTENT_FAST_PATTERN)) {
SCLogDebug("not a fast pattern %"PRIu32"", co->id);
continue;
}
SCLogDebug("fast pattern %"PRIu32"", co->id);
break;
case DETECT_URICONTENT:
ud = (DetectUricontentData *)sm->ctx;
if (!(ud->flags & DETECT_URICONTENT_FAST_PATTERN)) {
SCLogDebug("not a fast pattern %"PRIu32"", co->id);
continue;
}
SCLogDebug("fast pattern %"PRIu32"", co->id);
break;
} /* switch (sm->type) */
} else {
DetectContentData *cd = NULL;
DetectUricontentData *ud = NULL;
switch (sm->type) {
case DETECT_CONTENT:
if (sig_has_no_pkt_and_stream_content ||
(populate_mpm_flags & POPULATE_MPM_AVOID_PACKET_MPM_PATTERNS &&
populate_mpm_flags & POPULATE_MPM_AVOID_STREAM_MPM_PATTERNS)) {
continue;
}
cd = (DetectContentData *)sm->ctx;
if (cd->content_len < sgh->mpm_content_maxlen)
continue;
break;
case DETECT_URICONTENT:
if (populate_mpm_flags & POPULATE_MPM_AVOID_URI_MPM_PATTERNS) {
continue;
}
ud = (DetectUricontentData *)sm->ctx;
if (ud->content_len < sgh->mpm_uricontent_maxlen)
continue;
break;
} /* switch (sm->type) */
} /* else - if (fast_pattern[sig] == 1) */
if (mpm_sm == NULL) {
mpm_sm = sm;
if (fast_pattern[sig])
break;
} else {
DetectContentData *data1 = (DetectContentData *)sm->ctx;
DetectContentData *data2 = (DetectContentData *)mpm_sm->ctx;
uint32_t ls = PatternStrength(data1->content, data1->content_len);
uint32_t ss = PatternStrength(data2->content, data2->content_len);
if (ls > ss) {
mpm_sm = sm;
} else if (ls == ss) {
/* if 2 patterns are of equal strength, we pick the longest */
if (data1->content_len > data2->content_len)
mpm_sm = sm;
} else {
SCLogDebug("sticking with mpm_sm");
}
} /* else - if (mpm == NULL) */
} /* for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) */
if (mpm_sm != NULL && fast_pattern[sig])
break;
} /* for ( ; list_id < DETECT_SM_LIST_MAX; list_id++) */
/* now add the mpm_ch to the mpm ctx */
if (mpm_sm != NULL) {
uint8_t flags = 0;
char scan_negated = 0;
DetectContentData *cd = NULL;
DetectUricontentData *ud = NULL;
switch (mpm_sm->type) {
case DETECT_CONTENT:
cd = (DetectContentData *)mpm_sm->ctx;
if (cd->flags & DETECT_CONTENT_NEGATED)
scan_negated = 1;
break;
case DETECT_URICONTENT:
ud = (DetectUricontentData *)mpm_sm->ctx;
if (ud->flags & DETECT_URICONTENT_NEGATED)
scan_negated = 1;
break;
}
switch (mpm_sm->type) {
case DETECT_CONTENT:
{
cd = (DetectContentData *)mpm_sm->ctx;
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) {
/* add the content to the "packet" mpm */
if (cd->flags & DETECT_CONTENT_NOCASE) {
mpm_table[sgh->mpm_ctx->mpm_type].
AddPatternNocase(sgh->mpm_ctx,
cd->content + cd->fp_chop_offset,
cd->fp_chop_len,
0, 0, cd->id, s->num, flags);
} else {
mpm_table[sgh->mpm_ctx->mpm_type].
AddPattern(sgh->mpm_ctx,
cd->content + cd->fp_chop_offset,
cd->fp_chop_len,
0, 0, cd->id, s->num, flags);
}
} else {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
cd->avoid_double_check = 1;
/* see if we can bypass the match validation for this pattern */
} else {
if (!(cd->flags & DETECT_CONTENT_RELATIVE_NEXT) &&
!(cd->flags & DETECT_CONTENT_DEPTH) &&
!(cd->flags & DETECT_CONTENT_OFFSET)) {
SigMatch *prev_sm = SigMatchGetLastSMFromLists(s, 2,
mpm_sm->type, mpm_sm->prev);
if (prev_sm != NULL) {
DetectContentData *prev_cd = (DetectContentData *)prev_sm->ctx;
if (!(prev_cd->flags & DETECT_CONTENT_RELATIVE_NEXT)) {
cd->avoid_double_check = 1;
}
}
}
} /* else - if (co->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) */
if (SignatureHasPacketContent(s) &&
!(populate_mpm_flags & POPULATE_MPM_AVOID_PACKET_MPM_PATTERNS)) {
/* add the content to the "packet" mpm */
if (cd->flags & DETECT_CONTENT_NOCASE) {
mpm_table[sgh->mpm_ctx->mpm_type].
AddPatternNocase(sgh->mpm_ctx,
cd->content, cd->content_len,
0, 0, cd->id, s->num, flags);
} else {
mpm_table[sgh->mpm_ctx->mpm_type].
AddPattern(sgh->mpm_ctx,
cd->content, cd->content_len,
0, 0, cd->id, s->num, flags);
}
/* tell matcher we are inspecting packet */
s->flags |= SIG_FLAG_MPM_PACKET;
s->mpm_pattern_id_div_8 = cd->id / 8;
s->mpm_pattern_id_mod_8 = 1 << (cd->id % 8);
}
if (SignatureHasStreamContent(s) &&
!(populate_mpm_flags & POPULATE_MPM_AVOID_STREAM_MPM_PATTERNS)) {
/* add the content to the "packet" mpm */
if (cd->flags & DETECT_CONTENT_NOCASE) {
mpm_table[sgh->mpm_stream_ctx->mpm_type].
AddPatternNocase(sgh->mpm_stream_ctx,
cd->content, cd->content_len,
0, 0, cd->id, s->num, flags);
} else {
mpm_table[sgh->mpm_stream_ctx->mpm_type].
AddPattern(sgh->mpm_stream_ctx,
cd->content, cd->content_len,
0, 0, cd->id, s->num, flags);
}
/* tell matcher we are inspecting stream */
s->flags |= SIG_FLAG_MPM_STREAM;
s->mpm_stream_pattern_id_div_8 = cd->id / 8;
s->mpm_stream_pattern_id_mod_8 = 1 << (cd->id % 8);
}
}
break;
} /* case DETECT_CONTENT */
case DETECT_URICONTENT:
{
ud = (DetectUricontentData *)mpm_sm->ctx;
if (ud->flags & DETECT_URICONTENT_FAST_PATTERN_CHOP) {
/* add the content to the "uri" mpm */
if (ud->flags & DETECT_URICONTENT_NOCASE) {
mpm_table[sgh->mpm_ctx->mpm_type].
AddPatternNocase(sgh->mpm_ctx,
ud->content + ud->fp_chop_offset,
ud->fp_chop_len,
0, 0, ud->id, s->num, flags);
} else {
mpm_table[sgh->mpm_ctx->mpm_type].
AddPattern(sgh->mpm_ctx,
ud->content + ud->fp_chop_offset,
ud->fp_chop_len,
0, 0, ud->id, s->num, flags);
}
} else {
if (ud->flags & DETECT_CONTENT_FAST_PATTERN_ONLY) {
ud->avoid_double_check = 1;
/* see if we can bypass the match validation for this pattern */
} else {
if (!(ud->flags & DETECT_CONTENT_RELATIVE_NEXT) &&
!(ud->flags & DETECT_CONTENT_DEPTH) &&
!(ud->flags & DETECT_CONTENT_OFFSET)) {
SigMatch *prev_sm = SigMatchGetLastSMFromLists(s, 2,
mpm_sm->type, mpm_sm->prev);
if (prev_sm != NULL) {
DetectContentData *prev_ud = (DetectContentData *)prev_sm->ctx;
if (!(prev_ud->flags & DETECT_CONTENT_RELATIVE_NEXT)) {
ud->avoid_double_check = 1;
}
}
}
} /* else - if (ud->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) */
/* add the content to the "packet" mpm */
if (ud->flags & DETECT_CONTENT_NOCASE) {
mpm_table[sgh->mpm_uri_ctx->mpm_type].
AddPatternNocase(sgh->mpm_uri_ctx,
ud->content, ud->content_len,
0, 0, ud->id, s->num, flags);
} else {
mpm_table[sgh->mpm_uri_ctx->mpm_type].
AddPattern(sgh->mpm_uri_ctx,
ud->content, ud->content_len,
0, 0, ud->id, s->num, flags);
}
}
/* tell matcher we are inspecting uri */
s->flags |= SIG_FLAG_MPM_URI;
s->mpm_uripattern_id = ud->id;
break;
} /* case DETECT_URICONTENT */
} /* switch (mpm_sm->type) */
if (scan_negated) {
SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id);
s->flags |= SIG_FLAG_MPM_NEGCONTENT;
}
SCLogDebug("%"PRIu32" adding co->id %"PRIu32" to the mpm phase (s->num %"PRIu32")", s->id, co->id, s->num);
} else {
SCLogDebug("%"PRIu32" no mpm pattern selected", s->id);
}
}
if (fast_pattern != NULL)
SCFree(fast_pattern);
return 0;
}
/** \brief Setup the content portion of the sig group head */
static int PatternMatchPreprarePopulateMpm(DetectEngineCtx *de_ctx, SigGroupHead *sgh) {
static int PatternMatchPreprarePopulateMpmPacket(DetectEngineCtx *de_ctx, SigGroupHead *sgh) {
uint32_t sig;
uint32_t *fast_pattern = NULL;
@ -1310,6 +1689,7 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
uint32_t has_co_uri = 0; /**< our sgh has uri inspecting content */
uint32_t cnt = 0;
uint32_t sig = 0;
uint8_t populate_mpm_flags = 0;
if (!(sh->flags & SIG_GROUP_HEAD_MPM_COPY))
sh->mpm_content_maxlen = 0;
@ -1351,7 +1731,9 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
}
/* intialize contexes */
populate_mpm_flags |= POPULATE_MPM_AVOID_PACKET_MPM_PATTERNS;
if (sh->flags & SIG_GROUP_HAVECONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_COPY)) {
populate_mpm_flags &= ~POPULATE_MPM_AVOID_PACKET_MPM_PATTERNS;
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
sh->mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_packet);
} else {
@ -1365,7 +1747,9 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
#endif
}
populate_mpm_flags |= POPULATE_MPM_AVOID_STREAM_MPM_PATTERNS;
if (sh->flags & SIG_GROUP_HAVESTREAMCONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_STREAM_COPY)) {
populate_mpm_flags &= ~POPULATE_MPM_AVOID_STREAM_MPM_PATTERNS;
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
sh->mpm_stream_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_stream);
} else {
@ -1379,7 +1763,9 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
#endif
}
populate_mpm_flags |= POPULATE_MPM_AVOID_URI_MPM_PATTERNS;
if (sh->flags & SIG_GROUP_HAVEURICONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_URI_COPY)) {
populate_mpm_flags &= ~POPULATE_MPM_AVOID_URI_MPM_PATTERNS;
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
sh->mpm_uri_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx->sgh_mpm_context_uri);
} else {
@ -1522,42 +1908,78 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
}
}
/* uricontent */
if (sh->flags & SIG_GROUP_HAVEURICONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_URI_COPY)) {
PatternMatchPreprarePopulateMpmUri(de_ctx, sh);
if (!((populate_mpm_flags & POPULATE_MPM_AVOID_PACKET_MPM_PATTERNS) &&
(populate_mpm_flags & POPULATE_MPM_AVOID_STREAM_MPM_PATTERNS) &&
(populate_mpm_flags & POPULATE_MPM_AVOID_URI_MPM_PATTERNS))) {
if (mpm_table[sh->mpm_uri_ctx->mpm_type].Prepare != NULL) {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
mpm_table[sh->mpm_uri_ctx->mpm_type].Prepare(sh->mpm_uri_ctx);
}
}
PatternMatchPreparePopulateMpm(de_ctx, sh, populate_mpm_flags);
//sh->mpm_uri_ctx->PrintCtx(sh->mpm_uri_ctx);
}
/* content */
if (sh->flags & SIG_GROUP_HAVECONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_COPY)) {
PatternMatchPreprarePopulateMpm(de_ctx, sh);
if (mpm_table[sh->mpm_ctx->mpm_type].Prepare != NULL) {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
mpm_table[sh->mpm_ctx->mpm_type].Prepare(sh->mpm_ctx);
//if (mpm_table[sh->mpm_ctx->mpm_type].Prepare != NULL) {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
if (sh->mpm_ctx != NULL) {
if (sh->mpm_ctx->pattern_cnt == 0) {
sh->mpm_ctx = NULL;
} else {
if (!(populate_mpm_flags & POPULATE_MPM_AVOID_PACKET_MPM_PATTERNS))
mpm_table[sh->mpm_ctx->mpm_type].Prepare(sh->mpm_ctx);
}
}
}
}
/* stream content */
if (sh->flags & SIG_GROUP_HAVESTREAMCONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_STREAM_COPY)) {
PatternMatchPreprarePopulateMpmStream(de_ctx, sh);
SCLogDebug("preparing mpm_stream_ctx %p", sh->mpm_stream_ctx);
if (mpm_table[sh->mpm_stream_ctx->mpm_type].Prepare != NULL) {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
mpm_table[sh->mpm_stream_ctx->mpm_type].Prepare(sh->mpm_stream_ctx);
if (sh->mpm_stream_ctx != NULL) {
if (sh->mpm_stream_ctx->pattern_cnt == 0) {
sh->mpm_stream_ctx = NULL;
} else {
if (!(populate_mpm_flags & POPULATE_MPM_AVOID_STREAM_MPM_PATTERNS))
mpm_table[sh->mpm_stream_ctx->mpm_type].Prepare(sh->mpm_stream_ctx);
}
}
if (sh->mpm_uri_ctx != NULL) {
if (sh->mpm_uri_ctx->pattern_cnt == 0) {
sh->mpm_uri_ctx = NULL;
} else {
if (!(populate_mpm_flags & POPULATE_MPM_AVOID_URI_MPM_PATTERNS))
mpm_table[sh->mpm_uri_ctx->mpm_type].Prepare(sh->mpm_uri_ctx);
}
}
}
//}
}
///* uricontent */
//if (sh->flags & SIG_GROUP_HAVEURICONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_URI_COPY)) {
// PatternMatchPreprarePopulateMpmUri(de_ctx, sh);
//
// if (mpm_table[sh->mpm_uri_ctx->mpm_type].Prepare != NULL) {
// if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
// mpm_table[sh->mpm_uri_ctx->mpm_type].Prepare(sh->mpm_uri_ctx);
// }
// }
//
// //sh->mpm_uri_ctx->PrintCtx(sh->mpm_uri_ctx);
//
//}
//
///* content */
//if (sh->flags & SIG_GROUP_HAVECONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_COPY)) {
// PatternMatchPreprarePopulateMpmPacket(de_ctx, sh);
//
// if (mpm_table[sh->mpm_ctx->mpm_type].Prepare != NULL) {
// if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
// mpm_table[sh->mpm_ctx->mpm_type].Prepare(sh->mpm_ctx);
// }
// }
//}
//
///* stream content */
//if (sh->flags & SIG_GROUP_HAVESTREAMCONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_STREAM_COPY)) {
// PatternMatchPreprarePopulateMpmStream(de_ctx, sh);
// SCLogDebug("preparing mpm_stream_ctx %p", sh->mpm_stream_ctx);
// if (mpm_table[sh->mpm_stream_ctx->mpm_type].Prepare != NULL) {
// if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
// mpm_table[sh->mpm_stream_ctx->mpm_type].Prepare(sh->mpm_stream_ctx);
// }
// }
//}
return 0;
//error:
/* XXX */

@ -96,8 +96,8 @@ static int DoInspectPacketPayload(DetectEngineCtx *de_ctx,
/* we might have already have this content matched by the mpm.
* (if there is any other reason why we'd want to avoid checking
* it here, please fill it in) */
if (cd->avoid_double_check)
goto match;
//if (cd->avoid_double_check)
// goto match;
/* rule parsers should take care of this */
BUG_ON(cd->depth != 0 && cd->depth <= cd->offset);

@ -45,6 +45,89 @@ static pcre_extra *parse_regex_study = NULL;
static int DetectFastPatternSetup(DetectEngineCtx *, Signature *, char *);
void DetectFastPatternRegisterTests(void);
/* holds the list of sm's that should be given fp support */
SCFPSupportSMType *sm_fp_support_smtype_list = NULL;
/* holds the list of sm match lists that need to be searched for a keyword
* that has fp support */
SCFPSupportSMList *sm_fp_support_smlist_list = NULL;
/**
* \brief Lets one add a sm list id to be searched for potential fp supported
* keywords later.
*
* \param list_id SM list id.
*/
static void SCFPAddFPSupportForSMList(int list_id)
{
if (sm_fp_support_smlist_list != NULL) {
SCFPSupportSMList *tmp_smlist_fp = sm_fp_support_smlist_list;
while (tmp_smlist_fp != NULL) {
if (tmp_smlist_fp->list_id == list_id)
return;
tmp_smlist_fp = tmp_smlist_fp->next;
}
}
SCFPSupportSMList *new_smlist_fp = malloc(sizeof(SCFPSupportSMList));
if (new_smlist_fp == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
exit(EXIT_FAILURE);
}
memset(new_smlist_fp, 0, sizeof(SCFPSupportSMList));
new_smlist_fp->list_id = list_id;
new_smlist_fp->next = sm_fp_support_smlist_list;
sm_fp_support_smlist_list = new_smlist_fp;
return;
}
/**
* \brief Lets one add a sigmatch type for fast pattern support(explains the weird
* name the function has).
*
* \param sm_type The sigmatch for which fp support has to be added.
*/
static void SCFPAddFPSupportForSMType(uint8_t sm_type)
{
if (sm_fp_support_smtype_list != NULL) {
SCFPSupportSMType *tmp_smtype_fp = sm_fp_support_smtype_list;
while (tmp_smtype_fp != NULL) {
if (tmp_smtype_fp->sm_type == sm_type) {
return;
}
tmp_smtype_fp = tmp_smtype_fp->next;
}
}
SCFPSupportSMType *new_smtype_fp = malloc(sizeof(SCFPSupportSMType));
if (new_smtype_fp == NULL) {
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
exit(EXIT_FAILURE);
}
memset(new_smtype_fp, 0, sizeof(SCFPSupportSMType));
new_smtype_fp->sm_type = sm_type;
new_smtype_fp->next = sm_fp_support_smtype_list;
sm_fp_support_smtype_list = new_smtype_fp;
return;
}
/**
* \brief Registers the keywords(SMs) that should be given fp support.
*/
void SCFPAddFPSupportForSMTypes(void)
{
SCFPAddFPSupportForSMType(DETECT_CONTENT);
SCFPAddFPSupportForSMList(DETECT_SM_LIST_PMATCH);
SCFPAddFPSupportForSMType(DETECT_URICONTENT);
SCFPAddFPSupportForSMList(DETECT_SM_LIST_UMATCH);
return;
}
/**
* \brief Registration function for fast_pattern keyword
*/
@ -666,7 +749,7 @@ int DetectFastPatternTest09(void)
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:string2; content:strings3; "
"content:strings4_imp; fast_pattern; "
"content:strings_string5; sid:1;)");
if (de_ctx->sig_list == NULL)
@ -720,7 +803,7 @@ int DetectFastPatternTest10(void)
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:string2; content:strings3; "
"content:strings4_imp; fast_pattern; "
"content:strings_string5; sid:1;)");
if (de_ctx->sig_list == NULL) {

@ -24,6 +24,76 @@
#ifndef __DETECT_FAST_PATTERN_H__
#define __DETECT_FAST_PATTERN_H__
typedef struct SCFPSupportSMType_ {
/* the sm type */
uint8_t sm_type;
/* the next member in the list */
struct SCFPSupportSMType_ *next;
} SCFPSupportSMType;
typedef struct SCFPSupportSMList_ {
/* the list id. Have a look at Signature->sm_lists[] */
int list_id;
/* the next memeber in the list */
struct SCFPSupportSMList_ *next;
} SCFPSupportSMList;
extern SCFPSupportSMType *sm_fp_support_smtype_list;
extern SCFPSupportSMList *sm_fp_support_smlist_list;
/**
* \brief Checks if a particular sigmatch type has fast pattern support.
*
* \param sm_type The sigmatch that has to be checked.
*
* \retval 1 If supported.
* \retval 0 If not.
*/
static inline int SCFPDoWeSupportFPForSMType(uint8_t sm_type)
{
if (sm_fp_support_smtype_list == NULL)
return 0;
SCFPSupportSMType *tmp_smtype_fp = sm_fp_support_smtype_list;
while (tmp_smtype_fp != NULL) {
if (tmp_smtype_fp->sm_type == sm_type)
return 1;
tmp_smtype_fp = tmp_smtype_fp->next;
}
return 0;
}
/**
* \brief Checks if a particular list(Signature->sm_lists[]) is in the list
* of lists that need to be searched for a keyword that has fp support.
*
* \param list_id The list id.
*
* \retval 1 If supported.
* \retval 0 If not.
*/
static inline int SCFPDoWeSupportFPForSMList(int list_id)
{
if (sm_fp_support_smlist_list == NULL)
return 0;
SCFPSupportSMList *tmp_smlist_fp = sm_fp_support_smlist_list;
while (tmp_smlist_fp != NULL) {
if (tmp_smlist_fp->list_id == list_id)
return 1;
tmp_smlist_fp = tmp_smlist_fp->next;
}
return 0;
}
void SCFPAddFPSupportForSMTypes(void);
/* not implemented as of now. If there's a need we'll implement it */
void SCFPRemoveFPSupportForSMType(uint8_t);
void DetectFastPatternRegister(void);
#endif /* __DETECT_FAST_PATTERN_H__ */

@ -1294,7 +1294,7 @@ Signature *SigInit(DetectEngineCtx *de_ctx, char *sigstr) {
if (ud == NULL)
continue;
sig->flags |= SIG_FLAG_MPM_URI;
//sig->flags |= SIG_FLAG_MPM_URI;
if (ud->flags & DETECT_URICONTENT_NEGATED) {
sig->flags |= SIG_FLAG_MPM_URI_NEG;
@ -1436,7 +1436,7 @@ Signature *SigInitReal(DetectEngineCtx *de_ctx, char *sigstr) {
if (ud == NULL)
continue;
sig->flags |= SIG_FLAG_MPM_URI;
//sig->flags |= SIG_FLAG_MPM_URI;
if (ud->flags & DETECT_URICONTENT_NEGATED) {
sig->flags |= SIG_FLAG_MPM_URI_NEG;

@ -55,6 +55,7 @@
#include "detect-engine-uri.h"
#include "detect-engine-state.h"
#include "detect-engine-tag.h"
#include "detect-fast-pattern.h"
#include "tm-queuehandlers.h"
#include "tm-queues.h"
@ -825,6 +826,7 @@ int main(int argc, char **argv)
SigTableSetup(); /* load the rule keywords */
TmqhSetup();
SCFPAddFPSupportForSMTypes();
CIDRInit();
SigParsePrepare();
//PatternMatchPrepare(mpm_ctx, MPM_B2G);

Loading…
Cancel
Save