diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index fc4f855359..2a1902972f 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -172,6 +172,13 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) goto error; MpmInitCtx(sh->mpm_uri_ctx, MPM_WUMANBER); + + /* scan */ + sh->mpm_uri_scan_ctx = malloc(sizeof(MpmCtx)); + if (sh->mpm_uri_scan_ctx == NULL) + goto error; + + MpmInitCtx(sh->mpm_uri_scan_ctx, MPM_WUMANBER); } u_int16_t mpm_content_scan_maxlen = 65535, mpm_uricontent_scan_maxlen = 65535; @@ -326,16 +333,20 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) break; /* just add one per sig, * TODO see if we can select the best one */ } -/* - } else if (sm->type == DETECT_URICONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_URI_COPY)) { + } + } + for (sm = s->match; sm != NULL; sm = sm->next) { + if (sm->type == DETECT_URICONTENT && !(sh->flags & SIG_GROUP_HEAD_MPM_URI_COPY)) { DetectUricontentData *ud = (DetectUricontentData *)sm->ctx; + if (sh->mpm_uricontent_maxlen >= ud->uricontent_len) { - if (ud->flags & DETECT_URICONTENT_NOCASE) { - sh->mpm_uri_ctx->AddPatternNocase(sh->mpm_uri_ctx, ud->uricontent, ud->uricontent_len, ud->id); - } else { - sh->mpm_uri_ctx->AddPattern(sh->mpm_uri_ctx, ud->uricontent, ud->uricontent_len, ud->id); + if (ud->flags & DETECT_URICONTENT_NOCASE) { + sh->mpm_uri_ctx->AddPatternNocase(sh->mpm_uri_scan_ctx, ud->uricontent, ud->uricontent_len, ud->id); + } else { + sh->mpm_uri_ctx->AddPattern(sh->mpm_uri_scan_ctx, ud->uricontent, ud->uricontent_len, ud->id); + } + break; } -*/ } } //#endif @@ -400,6 +411,9 @@ int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh) if (sh->mpm_uri_ctx->Prepare != NULL) { sh->mpm_uri_ctx->Prepare(sh->mpm_uri_ctx); } + if (sh->mpm_uri_scan_ctx->Prepare != NULL) { + sh->mpm_uri_scan_ctx->Prepare(sh->mpm_uri_scan_ctx); + } if (mpm_uricontent_cnt && sh->mpm_uricontent_maxlen > 1) { // printf("mpm_uricontent_cnt %u, mpm_uricontent_maxlen %d\n", mpm_uricontent_cnt, mpm_uricontent_maxlen); g_uricontent_scan++; diff --git a/src/detect-uricontent.c b/src/detect-uricontent.c index 921a61ed6a..d9c1ff97f7 100644 --- a/src/detect-uricontent.c +++ b/src/detect-uricontent.c @@ -231,7 +231,7 @@ DoDetectUricontent(ThreadVars *t, PatternMatcherThread *pmt, Packet *p, SigMatch int DetectUricontentMatch (ThreadVars *t, PatternMatcherThread *pmt, Packet *p, Signature *s, SigMatch *m) { u_int32_t len = 0; - u_int32_t ret = 0; + u_int32_t ret = 0, scan = 0; //printf("scanning uricontent have %u scan %u\n", pmt->de_have_httpuri, pmt->de_scanned_httpuri); @@ -251,9 +251,27 @@ int DetectUricontentMatch (ThreadVars *t, PatternMatcherThread *pmt, Packet *p, u_int8_t i; for (i = 0; i < p->http_uri.cnt; i++) { //printf("p->http_uri.raw_size[%u] %u, %p, %s\n", i, p->http_uri.raw_size[i], p->http_uri.raw[i], p->http_uri.raw[i]); - //printf("pmt->mcu %p\n", pmt->mcu); - ret += pmt->mcu->Search(pmt->mcu, &pmt->mtcu, p->http_uri.raw[i], p->http_uri.raw_size[i]); - //printf("DetectUricontentMatch: ret %u\n", ret); + //printf("pmt->mcu %p, pmt->mcu_scan %p\n", pmt->mcu, pmt->mcu_scan); + + if (pmt->sgh->mpm_uricontent_maxlen <= p->http_uri.raw_size[i]) { + if (pmt->sgh->mpm_uricontent_maxlen == 1) pmt->pkts_uri_scanned1++; + else if (pmt->sgh->mpm_uricontent_maxlen == 2) pmt->pkts_uri_scanned2++; + else if (pmt->sgh->mpm_uricontent_maxlen == 3) pmt->pkts_uri_scanned3++; + else if (pmt->sgh->mpm_uricontent_maxlen == 4) pmt->pkts_uri_scanned4++; + else pmt->pkts_uri_scanned++; + + scan = pmt->mcu_scan->Search(pmt->mcu_scan, &pmt->mtcu, p->http_uri.raw[i], p->http_uri.raw_size[i]); + if (scan > 0) { + if (pmt->sgh->mpm_uricontent_maxlen == 1) pmt->pkts_uri_searched1++; + else if (pmt->sgh->mpm_uricontent_maxlen == 2) pmt->pkts_uri_searched2++; + else if (pmt->sgh->mpm_uricontent_maxlen == 3) pmt->pkts_uri_searched3++; + else if (pmt->sgh->mpm_uricontent_maxlen == 4) pmt->pkts_uri_searched4++; + else pmt->pkts_uri_searched++; + + ret += pmt->mcu->Search(pmt->mcu, &pmt->mtcu, p->http_uri.raw[i], p->http_uri.raw_size[i]); + } + //printf("DetectUricontentMatch: ret %u\n", ret); + } } pmt->de_scanned_httpuri = 1; diff --git a/src/detect.c b/src/detect.c index 02d06f8e2e..5bb005de62 100644 --- a/src/detect.c +++ b/src/detect.c @@ -103,6 +103,37 @@ void DetectExitPrintStats(ThreadVars *tv, void *data) { pmt->pkts_searched, (float)(pmt->pkts_searched/(float)(pmt->pkts)*100), (float)(pmt->pkts_searched/(float)(pmt->pkts_scanned)*100)); + + printf(" - (%s) URI (1byte) Pkts %u, Scanned %u (%02.1f), Searched %u (%02.1f): %02.1f%%.\n", tv->name, + pmt->pkts, pmt->pkts_uri_scanned1, + (float)(pmt->pkts_uri_scanned1/(float)(pmt->pkts)*100), + pmt->pkts_uri_searched1, + (float)(pmt->pkts_uri_searched1/(float)(pmt->pkts)*100), + (float)(pmt->pkts_uri_searched1/(float)(pmt->pkts_uri_scanned1)*100)); + printf(" - (%s) URI (2byte) Pkts %u, Scanned %u (%02.1f), Searched %u (%02.1f): %02.1f%%.\n", tv->name, + pmt->pkts, pmt->pkts_uri_scanned2, + (float)(pmt->pkts_uri_scanned2/(float)(pmt->pkts)*100), + pmt->pkts_uri_searched2, + (float)(pmt->pkts_uri_searched2/(float)(pmt->pkts)*100), + (float)(pmt->pkts_uri_searched2/(float)(pmt->pkts_uri_scanned2)*100)); + printf(" - (%s) URI (3byte) Pkts %u, Scanned %u (%02.1f), Searched %u (%02.1f): %02.1f%%.\n", tv->name, + pmt->pkts, pmt->pkts_uri_scanned3, + (float)(pmt->pkts_uri_scanned3/(float)(pmt->pkts)*100), + pmt->pkts_uri_searched3, + (float)(pmt->pkts_uri_searched3/(float)(pmt->pkts)*100), + (float)(pmt->pkts_uri_searched3/(float)(pmt->pkts_uri_scanned3)*100)); + printf(" - (%s) URI (4byte) Pkts %u, Scanned %u (%02.1f), Searched %u (%02.1f): %02.1f%%.\n", tv->name, + pmt->pkts, pmt->pkts_uri_scanned4, + (float)(pmt->pkts_uri_scanned4/(float)(pmt->pkts)*100), + pmt->pkts_uri_searched4, + (float)(pmt->pkts_uri_searched4/(float)(pmt->pkts)*100), + (float)(pmt->pkts_uri_searched4/(float)(pmt->pkts_uri_scanned4)*100)); + printf(" - (%s) (+byte) Pkts %u, Scanned %u (%02.1f), Searched %u (%02.1f): %02.1f%%.\n", tv->name, + pmt->pkts, pmt->pkts_uri_scanned, + (float)(pmt->pkts_uri_scanned/(float)(pmt->pkts)*100), + pmt->pkts_uri_searched, + (float)(pmt->pkts_uri_searched/(float)(pmt->pkts)*100), + (float)(pmt->pkts_uri_searched/(float)(pmt->pkts_uri_scanned)*100)); } void SigLoadSignatures (void) @@ -367,7 +398,7 @@ int SigMatchSignatures(ThreadVars *th_v, PatternMatcherThread *pmt, Packet *p) Signature *s = NULL; SigMatch *sm = NULL; u_int32_t idx,sig; - SigGroupHead *sgh = NULL; + //SigGroupHead *sgh = NULL; pmt->pkts++; @@ -379,6 +410,8 @@ int SigMatchSignatures(ThreadVars *th_v, PatternMatcherThread *pmt, Packet *p) pmt->mc = NULL; pmt->mc_scan = NULL; pmt->mcu = NULL; + pmt->mcu_scan = NULL; + pmt->sgh = NULL; /* find the right mpm instance */ DetectAddressGroup *ag = DetectAddressLookupGroup(g_de_ctx->src_gh[p->proto],&p->src); @@ -390,7 +423,8 @@ int SigMatchSignatures(ThreadVars *th_v, PatternMatcherThread *pmt, Packet *p) pmt->mc = ag->sh->mpm_ctx; pmt->mc_scan = ag->sh->mpm_scan_ctx; pmt->mcu = ag->sh->mpm_uri_ctx; - sgh = ag->sh; + pmt->mcu_scan = ag->sh->mpm_uri_scan_ctx; + pmt->sgh = ag->sh; //printf("SigMatchSignatures: mc %p, mcu %p\n", pmt->mc, pmt->mcu); //printf("sigs %u\n", ag->sh->sig_cnt); @@ -404,7 +438,8 @@ int SigMatchSignatures(ThreadVars *th_v, PatternMatcherThread *pmt, Packet *p) pmt->mc = dport->sh->mpm_ctx; pmt->mc_scan = dport->sh->mpm_scan_ctx; pmt->mcu = dport->sh->mpm_uri_ctx; - sgh = dport->sh; + pmt->mcu_scan = dport->sh->mpm_uri_scan_ctx; + pmt->sgh = dport->sh; } } } @@ -413,30 +448,30 @@ int SigMatchSignatures(ThreadVars *th_v, PatternMatcherThread *pmt, Packet *p) /* if we didn't get a sig group head, we * have nothing to do.... */ - if (sgh == NULL) { + if (pmt->sgh == NULL) { //printf("SigMatchSignatures: no sgh\n"); return 0; } if (p->tcp_payload_len > 0 && pmt->mc != NULL) { /* run the pattern matcher against the packet */ - if (sgh->mpm_content_maxlen > p->tcp_payload_len) { + if (pmt->sgh->mpm_content_maxlen > p->tcp_payload_len) { //printf("Not scanning as pkt payload is smaller than the largest content length we need to match"); } else { - if (sgh->mpm_content_maxlen == 1) pmt->pkts_scanned1++; - else if (sgh->mpm_content_maxlen == 2) pmt->pkts_scanned2++; - else if (sgh->mpm_content_maxlen == 3) pmt->pkts_scanned3++; - else if (sgh->mpm_content_maxlen == 4) pmt->pkts_scanned4++; - else pmt->pkts_scanned++; + if (pmt->sgh->mpm_content_maxlen == 1) pmt->pkts_scanned1++; + else if (pmt->sgh->mpm_content_maxlen == 2) pmt->pkts_scanned2++; + else if (pmt->sgh->mpm_content_maxlen == 3) pmt->pkts_scanned3++; + else if (pmt->sgh->mpm_content_maxlen == 4) pmt->pkts_scanned4++; + else pmt->pkts_scanned++; u_int32_t cnt = PacketPatternScan(th_v, pmt, p); //printf("scan: cnt %u\n", cnt); if (cnt > 0) { - if (sgh->mpm_content_maxlen == 1) pmt->pkts_searched1++; - else if (sgh->mpm_content_maxlen == 2) pmt->pkts_searched2++; - else if (sgh->mpm_content_maxlen == 3) pmt->pkts_searched3++; - else if (sgh->mpm_content_maxlen == 4) pmt->pkts_searched4++; - else pmt->pkts_searched++; + if (pmt->sgh->mpm_content_maxlen == 1) pmt->pkts_searched1++; + else if (pmt->sgh->mpm_content_maxlen == 2) pmt->pkts_searched2++; + else if (pmt->sgh->mpm_content_maxlen == 3) pmt->pkts_searched3++; + else if (pmt->sgh->mpm_content_maxlen == 4) pmt->pkts_searched4++; + else pmt->pkts_searched++; cnt += PacketPatternMatch(th_v, pmt, p); //printf("search: cnt %u\n", cnt); @@ -445,8 +480,8 @@ int SigMatchSignatures(ThreadVars *th_v, PatternMatcherThread *pmt, Packet *p) } /* inspect the sigs against the packet */ - for (idx = 0; idx < sgh->sig_cnt; idx++) { - sig = sgh->match_array[idx]; + for (idx = 0; idx < pmt->sgh->sig_cnt; idx++) { + sig = pmt->sgh->match_array[idx]; s = g_de_ctx->sig_array[sig]; //printf("Sig %u\n", s->id); diff --git a/src/detect.h b/src/detect.h index 1eb429ef70..1b955711ae 100644 --- a/src/detect.h +++ b/src/detect.h @@ -39,10 +39,13 @@ typedef struct _PatternMatcherThread { MpmCtx *mc; /* search ctx */ MpmCtx *mc_scan; /* scan ctx */ MpmCtx *mcu; - //MpmCtx *mcu_scan; + MpmCtx *mcu_scan; + MpmThreadCtx mtc; MpmThreadCtx mtcu; + struct _SigGroupHead *sgh; + u_int32_t pkts; u_int32_t pkts_scanned; u_int32_t pkts_searched; @@ -54,6 +57,17 @@ typedef struct _PatternMatcherThread { u_int32_t pkts_searched3; u_int32_t pkts_scanned4; u_int32_t pkts_searched4; + + u_int32_t pkts_uri_scanned; + u_int32_t pkts_uri_searched; + u_int32_t pkts_uri_scanned1; + u_int32_t pkts_uri_searched1; + u_int32_t pkts_uri_scanned2; + u_int32_t pkts_uri_searched2; + u_int32_t pkts_uri_scanned3; + u_int32_t pkts_uri_searched3; + u_int32_t pkts_uri_scanned4; + u_int32_t pkts_uri_searched4; } PatternMatcherThread; typedef struct _Signature { @@ -176,7 +190,7 @@ typedef struct _SigGroupHead { MpmCtx *mpm_scan_ctx; /* scan */ u_int16_t mpm_content_maxlen; MpmCtx *mpm_uri_ctx; - MpmCtx *mpm_scan_uri_ctx; + MpmCtx *mpm_uri_scan_ctx; u_int16_t mpm_uricontent_maxlen; /* number of sigs in this head */