mirror of https://github.com/OISF/suricata
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
236 lines
6.7 KiB
C
236 lines
6.7 KiB
C
17 years ago
|
/* Multi pattern matcher */
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <ctype.h>
|
||
|
|
||
|
#include "decode.h"
|
||
|
#include "detect.h"
|
||
17 years ago
|
#include "detect-siggroup.h"
|
||
17 years ago
|
#include "detect-mpm.h"
|
||
|
#include "util-mpm.h"
|
||
|
|
||
|
#include "flow.h"
|
||
|
#include "flow-var.h"
|
||
|
#include "detect-flow.h"
|
||
|
|
||
|
#include "detect-content.h"
|
||
|
#include "detect-uricontent.h"
|
||
|
|
||
|
u_int32_t PacketPatternMatch(ThreadVars *t, PatternMatcherThread *pmt, Packet *p) {
|
||
|
u_int32_t ret;
|
||
|
|
||
17 years ago
|
ret = pmt->mc->Search(pmt->mc, &pmt->mtc, p->tcp_payload, p->tcp_payload_len);
|
||
17 years ago
|
|
||
|
//printf("PacketPatternMatch: ret %u\n", ret);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
/* cleans up the mpm instance after a match */
|
||
17 years ago
|
void PacketPatternCleanup(ThreadVars *t, PatternMatcherThread *pmt) {
|
||
|
/* content */
|
||
|
if (pmt->mc != NULL && pmt->mc->Cleanup != NULL) {
|
||
|
pmt->mc->Cleanup(&pmt->mtc);
|
||
17 years ago
|
}
|
||
17 years ago
|
/* uricontent */
|
||
|
if (pmt->mcu != NULL && pmt->mcu->Cleanup != NULL) {
|
||
|
pmt->mcu->Cleanup(&pmt->mtcu);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* XXX remove this once we got rid of the global mpm_ctx */
|
||
|
void PatternMatchDestroy(MpmCtx *mc) {
|
||
17 years ago
|
mc->DestroyCtx(mc);
|
||
17 years ago
|
}
|
||
|
|
||
17 years ago
|
/* TODO remove this when we move to the rule groups completely */
|
||
|
void PatternMatchPrepare(MpmCtx *mc)
|
||
|
{
|
||
17 years ago
|
MpmInitCtx(mc, MPM_WUMANBER);
|
||
17 years ago
|
}
|
||
|
|
||
|
|
||
|
/* free the pattern matcher part of a SigGroupHead */
|
||
|
void PatternMatchDestroyGroup(SigGroupHead *sh) {
|
||
|
/* content */
|
||
17 years ago
|
if (sh->flags & SIG_GROUP_HAVECONTENT && sh->mpm_ctx != NULL &&
|
||
|
!(sh->flags & SIG_GROUP_HEAD_MPM_COPY)) {
|
||
17 years ago
|
sh->mpm_ctx->DestroyCtx(sh->mpm_ctx);
|
||
|
free(sh->mpm_ctx);
|
||
|
|
||
|
/* ready for reuse */
|
||
|
sh->mpm_ctx = NULL;
|
||
|
sh->flags &= ~SIG_GROUP_HAVECONTENT;
|
||
|
}
|
||
|
|
||
|
/* uricontent */
|
||
17 years ago
|
if (sh->flags & SIG_GROUP_HAVEURICONTENT && sh->mpm_uri_ctx != NULL &&
|
||
|
!(sh->flags & SIG_GROUP_HEAD_MPM_URI_COPY)) {
|
||
17 years ago
|
sh->mpm_uri_ctx->DestroyCtx(sh->mpm_uri_ctx);
|
||
|
free(sh->mpm_uri_ctx);
|
||
|
|
||
|
/* ready for reuse */
|
||
|
sh->mpm_uri_ctx = NULL;
|
||
|
sh->flags &= ~SIG_GROUP_HAVEURICONTENT;
|
||
17 years ago
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
*
|
||
|
* TODO
|
||
|
* - determine if a content match can set the 'single' flag
|
||
|
*
|
||
|
*
|
||
17 years ago
|
* XXX do error checking
|
||
17 years ago
|
* XXX rewrite the COPY stuff
|
||
17 years ago
|
*/
|
||
17 years ago
|
int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
|
||
17 years ago
|
{
|
||
|
Signature *s;
|
||
17 years ago
|
u_int32_t co_cnt = 0;
|
||
|
u_int32_t ur_cnt = 0;
|
||
|
u_int32_t cnt = 0;
|
||
17 years ago
|
u_int32_t sig;
|
||
17 years ago
|
|
||
|
/* see if this head has content and/or uricontent */
|
||
17 years ago
|
for (sig = 0; sig < sh->sig_cnt; sig++) {
|
||
|
u_int32_t num = sh->match_array[sig];
|
||
|
|
||
|
s = de_ctx->sig_array[num];
|
||
|
if (s == NULL)
|
||
|
continue;
|
||
17 years ago
|
|
||
|
/* find flow setting of this rule */
|
||
|
SigMatch *sm;
|
||
17 years ago
|
|
||
17 years ago
|
for (sm = s->match; sm != NULL; sm = sm->next) {
|
||
|
if (sm->type == DETECT_CONTENT) {
|
||
|
co_cnt++;
|
||
|
} else if (sm->type == DETECT_URICONTENT) {
|
||
|
ur_cnt++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
17 years ago
|
|
||
17 years ago
|
if (co_cnt > 0) {
|
||
|
sh->flags |= SIG_GROUP_HAVECONTENT;
|
||
|
}
|
||
|
if (ur_cnt > 0) {
|
||
|
sh->flags |= SIG_GROUP_HAVEURICONTENT;
|
||
|
}
|
||
17 years ago
|
|
||
|
/* intialize contexes */
|
||
17 years ago
|
if (sh->flags & SIG_GROUP_HAVECONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_COPY)) {
|
||
17 years ago
|
sh->mpm_ctx = malloc(sizeof(MpmCtx));
|
||
|
if (sh->mpm_ctx == NULL)
|
||
|
goto error;
|
||
|
|
||
|
MpmInitCtx(sh->mpm_ctx, MPM_WUMANBER);
|
||
17 years ago
|
}
|
||
17 years ago
|
if (sh->flags & SIG_GROUP_HAVEURICONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_URI_COPY)) {
|
||
17 years ago
|
sh->mpm_uri_ctx = malloc(sizeof(MpmCtx));
|
||
|
if (sh->mpm_uri_ctx == NULL)
|
||
|
goto error;
|
||
17 years ago
|
|
||
17 years ago
|
MpmInitCtx(sh->mpm_uri_ctx, MPM_WUMANBER);
|
||
|
}
|
||
17 years ago
|
|
||
17 years ago
|
/* for each signature in this group do */
|
||
17 years ago
|
for (sig = 0; sig < sh->sig_cnt; sig++) {
|
||
|
u_int32_t num = sh->match_array[sig];
|
||
|
|
||
|
s = de_ctx->sig_array[num];
|
||
|
if (s == NULL)
|
||
|
continue;
|
||
|
|
||
17 years ago
|
cnt++;
|
||
17 years ago
|
|
||
17 years ago
|
/* find flow setting of this rule */
|
||
|
SigMatch *sm;
|
||
17 years ago
|
for (sm = s->match; sm != NULL; sm = sm->next) {
|
||
17 years ago
|
if (sm->type == DETECT_CONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_COPY)) {
|
||
17 years ago
|
DetectContentData *cd = (DetectContentData *)sm->ctx;
|
||
|
|
||
17 years ago
|
if (cd->flags & DETECT_CONTENT_NOCASE) {
|
||
|
sh->mpm_ctx->AddPatternNocase(sh->mpm_ctx, cd->content, cd->content_len, cd->id);
|
||
17 years ago
|
} else {
|
||
17 years ago
|
sh->mpm_ctx->AddPattern(sh->mpm_ctx, cd->content, cd->content_len, cd->id);
|
||
17 years ago
|
}
|
||
17 years ago
|
} else if (sm->type == DETECT_URICONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_URI_COPY)) {
|
||
17 years ago
|
DetectUricontentData *ud = (DetectUricontentData *)sm->ctx;
|
||
|
|
||
17 years ago
|
if (ud->flags & DETECT_URICONTENT_NOCASE) {
|
||
|
sh->mpm_uri_ctx->AddPatternNocase(sh->mpm_uri_ctx, ud->uricontent, ud->uricontent_len, ud->id);
|
||
17 years ago
|
} else {
|
||
17 years ago
|
sh->mpm_uri_ctx->AddPattern(sh->mpm_uri_ctx, ud->uricontent, ud->uricontent_len, ud->id);
|
||
17 years ago
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
17 years ago
|
/* content */
|
||
17 years ago
|
if (sh->flags & SIG_GROUP_HAVECONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_COPY)) {
|
||
17 years ago
|
if (sh->mpm_ctx->Prepare != NULL) {
|
||
|
sh->mpm_ctx->Prepare(sh->mpm_ctx);
|
||
|
}
|
||
17 years ago
|
//sh->mpm_ctx->PrintCtx(sh->mpm_ctx);
|
||
17 years ago
|
}
|
||
|
/* uricontent */
|
||
17 years ago
|
if (sh->flags & SIG_GROUP_HAVEURICONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_URI_COPY)) {
|
||
17 years ago
|
if (sh->mpm_uri_ctx->Prepare != NULL) {
|
||
|
sh->mpm_uri_ctx->Prepare(sh->mpm_uri_ctx);
|
||
17 years ago
|
}
|
||
17 years ago
|
//sh->mpm_uri_ctx->PrintCtx(sh->mpm_uri_ctx);
|
||
17 years ago
|
}
|
||
|
|
||
|
//printf("Printing info...\n");
|
||
17 years ago
|
//sh->mpm_ctx.PrintCtx(&sh->mpm_ctx);
|
||
|
//sh->mpm_uri_ctx.PrintCtx(&sh->mpm_uri_ctx);
|
||
|
//printf("mpm_ctx %p\n", &sh->mpm_uri_ctx);
|
||
17 years ago
|
|
||
17 years ago
|
return 0;
|
||
|
error:
|
||
|
/* XXX */
|
||
|
return -1;
|
||
17 years ago
|
}
|
||
|
|
||
|
int PatternMatcherThreadInit(ThreadVars *t, void **data) {
|
||
|
PatternMatcherThread *pmt = malloc(sizeof(PatternMatcherThread));
|
||
|
if (pmt == NULL) {
|
||
|
return -1;
|
||
|
}
|
||
|
memset(pmt, 0, sizeof(PatternMatcherThread));
|
||
|
|
||
17 years ago
|
/* XXX we still depend on the global mpm_ctx here
|
||
|
*
|
||
|
* Initialize the thread pattern match ctx with the max size
|
||
|
* of the content and uricontent id's so our match lookup
|
||
|
* table is always big enough
|
||
|
*/
|
||
|
mpm_ctx[0].InitThreadCtx(&mpm_ctx[0], &pmt->mtc, DetectContentMaxId());
|
||
|
mpm_ctx[0].InitThreadCtx(&mpm_ctx[0], &pmt->mtcu, DetectUricontentMaxId());
|
||
17 years ago
|
|
||
|
*data = (void *)pmt;
|
||
|
//printf("PatternMatcherThreadInit: data %p pmt %p\n", *data, pmt);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int PatternMatcherThreadDeinit(ThreadVars *t, void *data) {
|
||
|
PatternMatcherThread *pmt = (PatternMatcherThread *)data;
|
||
|
|
||
17 years ago
|
/* XXX */
|
||
|
mpm_ctx[0].DestroyThreadCtx(&mpm_ctx[0], &pmt->mtc);
|
||
|
mpm_ctx[0].DestroyThreadCtx(&mpm_ctx[0], &pmt->mtcu);
|
||
17 years ago
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
void PatternMatcherThreadInfo(ThreadVars *t, PatternMatcherThread *pmt) {
|
||
17 years ago
|
/* XXX */
|
||
|
mpm_ctx[0].PrintThreadCtx(&pmt->mtc);
|
||
|
mpm_ctx[0].PrintThreadCtx(&pmt->mtcu);
|
||
17 years ago
|
}
|
||
|
|