#include #include #include #include #include #include "util-mpm.h" /* include pattern matchers */ #include "util-mpm-trie.h" #include "util-mpm-wumanber.h" /* cleanup list with all matches * * used at search runtime (or actually once per search) */ void MpmMatchCleanup(MpmThreadCtx *thread_ctx) { #ifdef DEBUG printf("MpmMatchCleanup: mem %u\n", thread_ctx->memory_size); #endif MpmMatch *nxt; MpmMatch *m = thread_ctx->qlist; while (m != NULL) { nxt = m->qnext; /* clear the bucket */ m->mb->top = NULL; m->mb->bot = NULL; m->mb->len = 0; thread_ctx->qlist = m->qnext; /* add to the spare list */ if (thread_ctx->sparelist == NULL) { thread_ctx->sparelist = m; m->qnext = NULL; } else { m->qnext = thread_ctx->sparelist; thread_ctx->sparelist = m; } m = nxt; } } /* allocate a match * * used at search runtime */ inline MpmMatch * MpmMatchAlloc(MpmThreadCtx *thread_ctx) { MpmMatch *m = malloc(sizeof(MpmMatch)); if (m == NULL) return NULL; thread_ctx->memory_cnt++; thread_ctx->memory_size += sizeof(MpmMatch); m->offset = 0; m->next = NULL; m->qnext = NULL; m->mb = NULL; return m; } /* append a match to a bucket * * used at search runtime */ inline void MpmMatchAppend(MpmThreadCtx *thread_ctx, MpmEndMatch *em, MpmMatchBucket *mb, u_int16_t offset) { if (em->flags & MPM_ENDMATCH_SINGLE && mb->len) return; MpmMatch *m; /* pull a match from the spare list */ if (thread_ctx->sparelist != NULL) { m = thread_ctx->sparelist; thread_ctx->sparelist = m->qnext; } else { m = MpmMatchAlloc(thread_ctx); if (m == NULL) return; } m->offset = offset; m->mb = mb; m->next = NULL; m->qnext = NULL; /* append to the mb list */ if (mb->bot == NULL) { /* empty list */ mb->top = m; mb->bot = m; } else { /* more items in list */ mb->bot->next = m; mb->bot = m; } mb->len++; /* put in the queue list */ if (thread_ctx->qlist == NULL) { /* empty list */ thread_ctx->qlist = m; } else { /* more items in list */ m->qnext = thread_ctx->qlist; thread_ctx->qlist = m; } #ifdef DEBUG printf("MpmMatchAppend: len %u (offset %u)\n", mb->len, m->offset); MpmMatch *tmp = thread_ctx->qlist; while (tmp) { printf("tmp %p tmp->next %p\n", tmp, tmp->next); tmp = tmp->qnext; } #endif } void MpmMatchFree(MpmThreadCtx *ctx, MpmMatch *m) { ctx->memory_cnt--; ctx->memory_size -= sizeof(MpmMatch); free(m); } void MpmMatchFreeSpares(MpmThreadCtx *mpm_ctx, MpmMatch *m) { while(m) { MpmMatch *tm = m->qnext; MpmMatchFree(mpm_ctx, m); m = tm; } } /* allocate an endmatch * * Only used in the initialization phase */ MpmEndMatch *MpmAllocEndMatch (MpmCtx *ctx) { MpmEndMatch *e = malloc(sizeof(MpmEndMatch)); if (e == NULL) return NULL; memset(e, 0, sizeof(MpmEndMatch)); ctx->memory_cnt++; ctx->memory_size += sizeof(MpmEndMatch); ctx->endmatches++; return e; } void MpmEndMatchFree(MpmCtx *ctx, MpmEndMatch *em) { ctx->memory_cnt--; ctx->memory_size -= sizeof(MpmEndMatch); free(em); } void MpmEndMatchFreeAll(MpmCtx *mpm_ctx, MpmEndMatch *em) { while(em) { MpmEndMatch *tem = em->next; MpmEndMatchFree(mpm_ctx, em); em = tem; } } void MpmInitCtx (MpmCtx *mpm_ctx, u_int16_t matcher) { mpm_table[matcher].InitCtx(mpm_ctx); mpm_ctx->InitCtx = mpm_table[matcher].InitCtx; mpm_ctx->InitThreadCtx = mpm_table[matcher].InitThreadCtx; mpm_ctx->DestroyCtx = mpm_table[matcher].DestroyCtx; mpm_ctx->DestroyThreadCtx = mpm_table[matcher].DestroyThreadCtx; mpm_ctx->AddPattern = mpm_table[matcher].AddPattern; mpm_ctx->AddPatternNocase = mpm_table[matcher].AddPatternNocase; mpm_ctx->Prepare = mpm_table[matcher].Prepare; mpm_ctx->Search = mpm_table[matcher].Search; mpm_ctx->PrintCtx = mpm_table[matcher].PrintCtx; mpm_ctx->PrintThreadCtx = mpm_table[matcher].PrintThreadCtx; mpm_ctx->Cleanup = mpm_table[matcher].Cleanup; } void MpmTableSetup(void) { memset(mpm_table, 0, sizeof(mpm_table)); MpmTrieRegister(); MpmWuManberRegister(); } void MpmRegisterTests(void) { u_int16_t i; for (i = 0; i < MPM_TABLE_SIZE; i++) { if (mpm_table[i].RegisterUnittests != NULL) { mpm_table[i].RegisterUnittests(); } else { printf("Warning: mpm %s has no unittest registration function...", mpm_table[i].name); } } }