From 6a73b3c90b8c083a908de97dd890440f2052e679 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Tue, 28 Nov 2023 12:01:19 +0100 Subject: [PATCH] mpm: remove ac-bs implementation Ticket: #6586. --- src/Makefile.am | 2 - src/detect-engine.c | 2 +- src/util-mpm-ac-bs.c | 2373 ------------------------------------------ src/util-mpm-ac-bs.h | 74 -- src/util-mpm.c | 2 - src/util-mpm.h | 1 - 6 files changed, 1 insertion(+), 2453 deletions(-) delete mode 100644 src/util-mpm-ac-bs.c delete mode 100644 src/util-mpm-ac-bs.h diff --git a/src/Makefile.am b/src/Makefile.am index 21e1dfe5fbeb..4695c2d35f51 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -578,7 +578,6 @@ noinst_HEADERS = \ util-mem.h \ util-memrchr.h \ util-misc.h \ - util-mpm-ac-bs.h \ util-mpm-ac.h \ util-mpm-ac-ks.h \ util-mpm.h \ @@ -1177,7 +1176,6 @@ libsuricata_c_a_SOURCES = \ util-memcmp.c \ util-memrchr.c \ util-misc.c \ - util-mpm-ac-bs.c \ util-mpm-ac.c \ util-mpm-ac-ks.c \ util-mpm-ac-ks-small.c \ diff --git a/src/detect-engine.c b/src/detect-engine.c index b197369f100a..a4ce2126544d 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -2728,7 +2728,7 @@ static int DetectEngineCtxLoadConf(DetectEngineCtx *de_ctx) /* for now, since we still haven't implemented any intelligence into * understanding the patterns and distributing mpm_ctx across sgh */ if (de_ctx->mpm_matcher == MPM_AC || de_ctx->mpm_matcher == MPM_AC_KS || - de_ctx->mpm_matcher == MPM_HS || de_ctx->mpm_matcher == MPM_AC_BS) { + de_ctx->mpm_matcher == MPM_HS) { de_ctx->sgh_mpm_ctx_cnf = ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE; } else { de_ctx->sgh_mpm_ctx_cnf = ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL; diff --git a/src/util-mpm-ac-bs.c b/src/util-mpm-ac-bs.c deleted file mode 100644 index 72d2065ca7c1..000000000000 --- a/src/util-mpm-ac-bs.c +++ /dev/null @@ -1,2373 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - * First iteration of aho-corasick MPM from - - * - * Efficient String Matching: An Aid to Bibliographic Search - * Alfred V. Aho and Margaret J. Corasick - * - * - Uses the delta table for calculating transitions, instead of having - * separate goto and failure transitions. - * - If we cross 2 ** 16 states, we use 4 bytes in the transition table - * to hold each state, otherwise we use 2 bytes. - * - This version of the MPM is heavy on memory, but it performs well. - * If you can fit the ruleset with this mpm on your box without hitting - * swap, this is the MPM to go for. - * - * \todo - Do a proper analysis of our existing MPMs and suggest a good one based - * on the pattern distribution and the expected traffic(say http). - * - Tried out loop unrolling without any perf increase. Need to dig deeper. - * - Irrespective of whether we cross 2 ** 16 states or not,shift to using - * uint32_t for state type, so that we can integrate it's status as a - * final state or not in the topmost byte. We are already doing it if - * state_count is > 2 ** 16. - * - Test case-sensitive patterns if they have any ascii chars. If they - * don't treat them as nocase. - * - Carry out other optimizations we are working on. hashes, compression. - */ - -#include "suricata-common.h" -#include "suricata.h" - -#include "detect.h" -#include "detect-parse.h" -#include "detect-engine.h" -#include "detect-engine-build.h" -#include "util-mpm-ac-bs.h" - -#include "conf.h" -#include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-memcmp.h" -#include "util-memcpy.h" -#include "util-validate.h" - -void SCACBSInitCtx(MpmCtx *); -void SCACBSDestroyCtx(MpmCtx *); -int SCACBSAddPatternCI(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, - uint32_t, SigIntId, uint8_t); -int SCACBSAddPatternCS(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, - uint32_t, SigIntId, uint8_t); -int SCACBSPreparePatterns(MpmCtx *mpm_ctx); -uint32_t SCACBSSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen); -void SCACBSPrintInfo(MpmCtx *mpm_ctx); -void SCACBSRegisterTests(void); - -/* a placeholder to denote a failure transition in the goto table */ -#define SC_AC_BS_FAIL (-1) - -#define STATE_QUEUE_CONTAINER_SIZE 65536 - -/** - * \brief Helper structure used by AC during state table creation - */ -typedef struct StateQueue_ { - int32_t store[STATE_QUEUE_CONTAINER_SIZE]; - int top; - int bot; -} StateQueue; - -/** - * \brief Register the aho-corasick mpm. - */ -void MpmACBSRegister(void) -{ - mpm_table[MPM_AC_BS].name = "ac-bs"; - mpm_table[MPM_AC_BS].InitCtx = SCACBSInitCtx; - mpm_table[MPM_AC_BS].DestroyCtx = SCACBSDestroyCtx; - mpm_table[MPM_AC_BS].AddPattern = SCACBSAddPatternCS; - mpm_table[MPM_AC_BS].AddPatternNocase = SCACBSAddPatternCI; - mpm_table[MPM_AC_BS].Prepare = SCACBSPreparePatterns; - mpm_table[MPM_AC_BS].Search = SCACBSSearch; - mpm_table[MPM_AC_BS].PrintCtx = SCACBSPrintInfo; - mpm_table[MPM_AC_BS].RegisterUnittests = SCACBSRegisterTests; -} - -/** - * \internal - * \brief Initialize the AC context with user specified conf parameters. We - * aren't retrieving anything for AC conf now, but we will certainly - * need it, when we customize AC. - */ -static void SCACBSGetConfig(void) -{ - //ConfNode *ac_conf; - //const char *hash_val = NULL; - - //ConfNode *pm = ConfGetNode("pattern-matcher"); - - return; -} - -/** - * \internal - * \brief Initialize a new state in the goto and output tables. - * - * \param mpm_ctx Pointer to the mpm context. - * - * \retval The state id, of the newly created state. - */ -static inline int SCACBSInitNewState(MpmCtx *mpm_ctx) -{ - void *ptmp; - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - int ascii_code = 0; - int size = 0; - - /* reallocate space in the goto table to include a new state */ - size = (ctx->state_count + 1) * ctx->single_state_size; - ptmp = SCRealloc(ctx->goto_table, size); - if (ptmp == NULL) { - SCFree(ctx->goto_table); - ctx->goto_table = NULL; - FatalError("Error allocating memory"); - } - ctx->goto_table = ptmp; - - /* set all transitions for the newly assigned state as FAIL transitions */ - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - ctx->goto_table[ctx->state_count][ascii_code] = SC_AC_BS_FAIL; - } - - /* reallocate space in the output table for the new state */ - size = (ctx->state_count + 1) * sizeof(SCACBSOutputTable); - ptmp = SCRealloc(ctx->output_table, size); - if (ptmp == NULL) { - SCFree(ctx->output_table); - ctx->output_table = NULL; - FatalError("Error allocating memory"); - } - ctx->output_table = ptmp; - - memset(ctx->output_table + ctx->state_count, 0, sizeof(SCACBSOutputTable)); - - /* \todo using it temporarily now during dev, since I have restricted - * state var in SCACBSCtx->state_table to uint16_t. */ - //if (ctx->state_count > 65536) { - // printf("state count exceeded\n"); - // exit(EXIT_FAILURE); - //} - - return ctx->state_count++; -} - -/** - * \internal - * \brief Adds a pid to the output table for a state. - * - * \param state The state to whose output table we should add the pid. - * \param pid The pattern id to add. - * \param mpm_ctx Pointer to the mpm context. - */ -static void SCACBSSetOutputState(int32_t state, uint32_t pid, MpmCtx *mpm_ctx) -{ - void *ptmp; - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - SCACBSOutputTable *output_state = &ctx->output_table[state]; - uint32_t i = 0; - - for (i = 0; i < output_state->no_of_entries; i++) { - if (output_state->pids[i] == pid) - return; - } - - output_state->no_of_entries++; - ptmp = SCRealloc(output_state->pids, - output_state->no_of_entries * sizeof(uint32_t)); - if (ptmp == NULL) { - SCFree(output_state->pids); - output_state->pids = NULL; - FatalError("Error allocating memory"); - } - output_state->pids = ptmp; - - output_state->pids[output_state->no_of_entries - 1] = pid; - - return; -} - -/** - * \brief Helper function used by SCACBSCreateGotoTable. Adds a pattern to the - * goto table. - * - * \param pattern Pointer to the pattern. - * \param pattern_len Pattern length. - * \param pid The pattern id, that corresponds to this pattern. We - * need it to updated the output table for this pattern. - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACBSEnter(uint8_t *pattern, uint16_t pattern_len, uint32_t pid, - MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - int32_t state = 0; - int32_t newstate = 0; - int i = 0; - int p = 0; - - /* walk down the trie till we have a match for the pattern prefix */ - state = 0; - for (i = 0; i < pattern_len; i++) { - if (ctx->goto_table[state][pattern[i]] != SC_AC_BS_FAIL) { - state = ctx->goto_table[state][pattern[i]]; - } else { - break; - } - } - - /* add the non-matching pattern suffix to the trie, from the last state - * we left off */ - for (p = i; p < pattern_len; p++) { - newstate = SCACBSInitNewState(mpm_ctx); - ctx->goto_table[state][pattern[p]] = newstate; - state = newstate; - } - - /* add this pattern id, to the output table of the last state, where the - * pattern ends in the trie */ - SCACBSSetOutputState(state, pid, mpm_ctx); - - return; -} - -/** - * \internal - * \brief Create the goto table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACBSCreateGotoTable(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - uint32_t i = 0; - - /* add each pattern to create the goto table */ - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - SCACBSEnter(ctx->parray[i]->ci, ctx->parray[i]->len, - ctx->parray[i]->id, mpm_ctx); - } - - int ascii_code = 0; - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - if (ctx->goto_table[0][ascii_code] == SC_AC_BS_FAIL) { - ctx->goto_table[0][ascii_code] = 0; - } - } - - return; -} - -static inline int SCACBSStateQueueIsEmpty(StateQueue *q) -{ - if (q->top == q->bot) - return 1; - else - return 0; -} - -static inline void SCACBSEnqueue(StateQueue *q, int32_t state) -{ - int i = 0; - - /*if we already have this */ - for (i = q->bot; i < q->top; i++) { - if (q->store[i] == state) - return; - } - - q->store[q->top++] = state; - - if (q->top == STATE_QUEUE_CONTAINER_SIZE) - q->top = 0; - - if (q->top == q->bot) { - FatalError("Just ran out of space in the queue. " - "Fatal Error. Exiting. Please file a bug report on this"); - } - - return; -} - -static inline int32_t SCACBSDequeue(StateQueue *q) -{ - if (q->bot == STATE_QUEUE_CONTAINER_SIZE) - q->bot = 0; - - if (q->bot == q->top) { - FatalError("StateQueue behaving weirdly. " - "Fatal Error. Exiting. Please file a bug report on this"); - } - - return q->store[q->bot++]; -} - -/* -#define SCACBSStateQueueIsEmpty(q) (((q)->top == (q)->bot) ? 1 : 0) - -#define SCACBSEnqueue(q, state) do { \ - int i = 0; \ - \ - for (i = (q)->bot; i < (q)->top; i++) { \ - if ((q)->store[i] == state) \ - return; \ - } \ - \ - (q)->store[(q)->top++] = state; \ - \ - if ((q)->top == STATE_QUEUE_CONTAINER_SIZE) \ - (q)->top = 0; \ - \ - if ((q)->top == (q)->bot) { \ - FatalError("Just ran out of space in the queue. " \ - "Fatal Error. Exiting. Please file a bug report on -this"); \ - } \ - } while (0) - -#define SCACBSDequeue(q) ( (((q)->bot == STATE_QUEUE_CONTAINER_SIZE)? ((q)->bot = 0): 0), \ - (((q)->bot == (q)->top) ? \ - (printf("StateQueue behaving " \ - "weirdly. Fatal Error. Exiting. Please " \ - "file a bug report on this"), \ - exit(EXIT_FAILURE)) : 0), \ - (q)->store[(q)->bot++]) \ -*/ - -/** - * \internal - * \brief Club the output data from 2 states and store it in the 1st state. - * dst_state_data = {dst_state_data} UNION {src_state_data} - * - * \param dst_state First state(also the destination) for the union operation. - * \param src_state Second state for the union operation. - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACBSClubOutputStates(int32_t dst_state, int32_t src_state, - MpmCtx *mpm_ctx) -{ - void *ptmp; - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - uint32_t i = 0; - uint32_t j = 0; - - SCACBSOutputTable *output_dst_state = &ctx->output_table[dst_state]; - SCACBSOutputTable *output_src_state = &ctx->output_table[src_state]; - - for (i = 0; i < output_src_state->no_of_entries; i++) { - for (j = 0; j < output_dst_state->no_of_entries; j++) { - if (output_src_state->pids[i] == output_dst_state->pids[j]) { - break; - } - } - if (j == output_dst_state->no_of_entries) { - output_dst_state->no_of_entries++; - - ptmp = SCRealloc(output_dst_state->pids, - (output_dst_state->no_of_entries * sizeof(uint32_t))); - if (ptmp == NULL) { - SCFree(output_dst_state->pids); - output_dst_state->pids = NULL; - FatalError("Error allocating memory"); - } - else { - output_dst_state->pids = ptmp; - } - - output_dst_state->pids[output_dst_state->no_of_entries - 1] = - output_src_state->pids[i]; - } - } - - return; -} - -/** - * \internal - * \brief Create the failure table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACBSCreateFailureTable(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - int ascii_code = 0; - int32_t state = 0; - int32_t r_state = 0; - - StateQueue q; - memset(&q, 0, sizeof(StateQueue)); - - /* allot space for the failure table. A failure entry in the table for - * every state(SCACBSCtx->state_count) */ - ctx->failure_table = SCCalloc(ctx->state_count, sizeof(int32_t)); - if (ctx->failure_table == NULL) { - FatalError("Error allocating memory"); - } - - /* add the failure transitions for the 0th state, and add every non-fail - * transition from the 0th state to the queue for further processing - * of failure states */ - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - int32_t temp_state = ctx->goto_table[0][ascii_code]; - if (temp_state != 0) { - SCACBSEnqueue(&q, temp_state); - ctx->failure_table[temp_state] = 0; - } - } - - while (!SCACBSStateQueueIsEmpty(&q)) { - /* pick up every state from the queue and add failure transitions */ - r_state = SCACBSDequeue(&q); - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - int32_t temp_state = ctx->goto_table[r_state][ascii_code]; - if (temp_state == SC_AC_BS_FAIL) - continue; - SCACBSEnqueue(&q, temp_state); - state = ctx->failure_table[r_state]; - - while(ctx->goto_table[state][ascii_code] == SC_AC_BS_FAIL) - state = ctx->failure_table[state]; - ctx->failure_table[temp_state] = ctx->goto_table[state][ascii_code]; - SCACBSClubOutputStates(temp_state, ctx->failure_table[temp_state], - mpm_ctx); - } - } - - return; -} - -/** - * \internal - * \brief Create the delta table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACBSCreateDeltaTable(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - int ascii_code = 0; - int32_t r_state = 0; - - if (ctx->state_count < 32767) { - ctx->state_table_u16 = SCCalloc(ctx->state_count, sizeof(*ctx->state_table_u16)); - if (ctx->state_table_u16 == NULL) { - FatalError("Error allocating memory"); - } - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (ctx->state_count * sizeof(*ctx->state_table_u16)); - - StateQueue q; - memset(&q, 0, sizeof(StateQueue)); - - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - DEBUG_VALIDATE_BUG_ON(ctx->goto_table[0][ascii_code] > UINT16_MAX); - SC_AC_BS_STATE_TYPE_U16 temp_state = (uint16_t)ctx->goto_table[0][ascii_code]; - ctx->state_table_u16[0][ascii_code] = temp_state; - if (temp_state != 0) - SCACBSEnqueue(&q, temp_state); - } - - while (!SCACBSStateQueueIsEmpty(&q)) { - r_state = SCACBSDequeue(&q); - - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - int32_t temp_state = ctx->goto_table[r_state][ascii_code]; - if (temp_state != SC_AC_BS_FAIL) { - SCACBSEnqueue(&q, temp_state); - DEBUG_VALIDATE_BUG_ON(temp_state > UINT16_MAX); - ctx->state_table_u16[r_state][ascii_code] = (uint16_t)temp_state; - } else { - ctx->state_table_u16[r_state][ascii_code] = - ctx->state_table_u16[ctx->failure_table[r_state]][ascii_code]; - } - } - } - } else { - /* create space for the state table. We could have used the existing goto - * table, but since we have it set to hold 32 bit state values, we will create - * a new state table here of type SC_AC_BS_STATE_TYPE(current set to uint16_t) */ - ctx->state_table_u32 = SCCalloc(ctx->state_count, sizeof(*ctx->state_table_u32)); - if (ctx->state_table_u32 == NULL) { - FatalError("Error allocating memory"); - } - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (ctx->state_count * sizeof(*ctx->state_table_u32)); - - StateQueue q; - memset(&q, 0, sizeof(StateQueue)); - - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - SC_AC_BS_STATE_TYPE_U32 temp_state = ctx->goto_table[0][ascii_code]; - ctx->state_table_u32[0][ascii_code] = temp_state; - if (temp_state != 0) - SCACBSEnqueue(&q, temp_state); - } - - while (!SCACBSStateQueueIsEmpty(&q)) { - r_state = SCACBSDequeue(&q); - - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - int32_t temp_state = ctx->goto_table[r_state][ascii_code]; - if (temp_state != SC_AC_BS_FAIL) { - SCACBSEnqueue(&q, temp_state); - ctx->state_table_u32[r_state][ascii_code] = temp_state; - } else { - ctx->state_table_u32[r_state][ascii_code] = - ctx->state_table_u32[ctx->failure_table[r_state]][ascii_code]; - } - } - } - } - - return; -} - -static inline void SCACBSClubOutputStatePresenceWithDeltaTable(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - int ascii_code = 0; - uint32_t state = 0; - uint32_t temp_state = 0; - - if (ctx->state_count < 32767) { - for (state = 0; state < ctx->state_count; state++) { - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - temp_state = ctx->state_table_u16[state & 0x7FFF][ascii_code]; - if (ctx->output_table[temp_state & 0x7FFF].no_of_entries != 0) - ctx->state_table_u16[state & 0x7FFF][ascii_code] |= (1 << 15); - } - } - } else { - for (state = 0; state < ctx->state_count; state++) { - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - temp_state = ctx->state_table_u32[state & 0x00FFFFFF][ascii_code]; - if (ctx->output_table[temp_state & 0x00FFFFFF].no_of_entries != 0) - ctx->state_table_u32[state & 0x00FFFFFF][ascii_code] |= (1 << 24); - } - } - } - - return; -} - -static inline void SCACBSInsertCaseSensitiveEntriesForPatterns(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - uint32_t state = 0; - uint32_t k = 0; - - for (state = 0; state < ctx->state_count; state++) { - if (ctx->output_table[state].no_of_entries == 0) - continue; - - for (k = 0; k < ctx->output_table[state].no_of_entries; k++) { - if (ctx->pid_pat_list[ctx->output_table[state].pids[k]].cs != NULL) { - ctx->output_table[state].pids[k] &= 0x0000FFFF; - ctx->output_table[state].pids[k] |= 1 << 16; - } - } - } - - return; -} - -#if 0 -static void SCACBSPrintDeltaTable(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - int i = 0, j = 0; - - printf("##############Delta Table##############\n"); - for (i = 0; i < ctx->state_count; i++) { - printf("%d: \n", i); - for (j = 0; j < 256; j++) { - if (SCACBSGetDelta(i, j, mpm_ctx) != 0) { - printf(" %c -> %d\n", j, SCACBSGetDelta(i, j, mpm_ctx)); - } - } - } - - return; -} -#endif - -static inline int SCACBSZeroTransitionPresent(SCACBSCtx *ctx, uint32_t state) -{ - if (state == 0) - return 1; - - if (ctx->state_count < 32767) { - int ascii; - for (ascii = 0; ascii < 256; ascii++) { - if ((ctx->state_table_u16[0][ascii] & 0x7fff) == (state & 0x7fff)) { - return 1; - } - } - - return 0; - } else { - int ascii; - for (ascii = 0; ascii < 256; ascii++) { - if ((ctx->state_table_u32[0][ascii] & 0x00FFFFFF) == - (state & 0x00FFFFFF)) { - return 1; - } - } - - return 0; - } -} - -/** - * \internal - * \brief Creates a new goto table structure(throw out all the failure - * transitions), to hold the existing goto table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACBSCreateModDeltaTable(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - - if (ctx->state_count < 32767) { - int size = 0; - uint32_t state; - - for (state = 1; state < ctx->state_count; state++) { - int ascii_code; - int k = 0; - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - uint32_t temp_state = ctx->state_table_u16[state][ascii_code]; - if (SCACBSZeroTransitionPresent(ctx, temp_state)) - continue; - k++; - } - size += sizeof(uint16_t) * k * 2; - } - - /* Let us use uint16_t for all. That way we don//'t have to worry about - * alignment. Technically 8 bits is all we need to store ascii codes, - * but by avoiding it, we save a lot of time on handling alignment */ - size += (ctx->state_count * sizeof(SC_AC_BS_STATE_TYPE_U16) + - 256 * sizeof(SC_AC_BS_STATE_TYPE_U16) * 1); - ctx->state_table_mod = SCCalloc(1, size); - if (ctx->state_table_mod == NULL) { - FatalError("Error allocating memory"); - } - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += size; - - /* buffer to hold pointers in the buffer, so that a state can use it - * directly to access its state data */ - ctx->state_table_mod_pointers = SCCalloc(ctx->state_count, sizeof(uint8_t *)); - if (ctx->state_table_mod_pointers == NULL) { - FatalError("Error allocating memory"); - } - - SC_AC_BS_STATE_TYPE_U16 temp_states[256]; - uint16_t *curr_loc = (uint16_t *)ctx->state_table_mod; - uint16_t *no_of_entries = NULL; - uint16_t *ascii_codes = NULL; - uint16_t ascii_code = 0; - uint16_t k = 0; - for (state = 0; state < ctx->state_count; state++) { - /* store the starting location in the buffer for this state */ - ctx->state_table_mod_pointers[state] = (uint8_t *)curr_loc; - no_of_entries = curr_loc++; - ascii_codes = curr_loc; - k = 0; - /* store all states that have non 0 transitions in the temp buffer */ - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - uint32_t temp_state = ctx->state_table_u16[state][ascii_code]; - if (state != 0 && SCACBSZeroTransitionPresent(ctx, temp_state)) - continue; - - ascii_codes[k] = ascii_code; - temp_states[k] = ctx->state_table_u16[state][ascii_code]; - k++; - } - /* if we have any non 0 transitions from our previous for search, - * store the ascii codes as well the corresponding states */ - if (k > 0) { - no_of_entries[0] = k; - if (state != 0) - curr_loc += k; - memcpy(curr_loc, temp_states, k * sizeof(SC_AC_BS_STATE_TYPE_U16)); - curr_loc += k; - } - } - - /* > 33766 */ - } else { - int size = 0; - uint32_t state; - for (state = 1; state < ctx->state_count; state++) { - int ascii_code; - int k = 0; - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - uint32_t temp_state = ctx->state_table_u32[state][ascii_code]; - if (SCACBSZeroTransitionPresent(ctx, temp_state)) - continue; - k++; - } - size += sizeof(uint32_t) * k * 2; - } - - /* Let us use uint32_t for all. That way we don//'t have to worry about - * alignment. Technically 8 bits is all we need to store ascii codes, - * but by avoiding it, we save a lot of time on handling alignment */ - size += (ctx->state_count * sizeof(SC_AC_BS_STATE_TYPE_U32) + - 256 * sizeof(SC_AC_BS_STATE_TYPE_U32) * 1); - ctx->state_table_mod = SCCalloc(1, size); - if (ctx->state_table_mod == NULL) { - FatalError("Error allocating memory"); - } - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += size; - - /* buffer to hold pointers in the buffer, so that a state can use it - * directly to access its state data */ - ctx->state_table_mod_pointers = SCCalloc(ctx->state_count, sizeof(uint8_t *)); - if (ctx->state_table_mod_pointers == NULL) { - FatalError("Error allocating memory"); - } - - SC_AC_BS_STATE_TYPE_U32 temp_states[256]; - uint32_t *curr_loc = (uint32_t *)ctx->state_table_mod; - uint32_t *no_of_entries = NULL; - uint32_t *ascii_codes = NULL; - uint32_t ascii_code = 0; - uint32_t k = 0; - for (state = 0; state < ctx->state_count; state++) { - /* store the starting location in the buffer for this state */ - ctx->state_table_mod_pointers[state] = (uint8_t *)curr_loc; - no_of_entries = curr_loc++; - ascii_codes = curr_loc; - k = 0; - /* store all states that have non 0 transitions in the temp buffer */ - for (ascii_code = 0; ascii_code < 256; ascii_code++) { - uint32_t temp_state = ctx->state_table_u32[state][ascii_code]; - if (state != 0 && SCACBSZeroTransitionPresent(ctx, temp_state)) - continue; - - ascii_codes[k] = ascii_code; - temp_states[k] = ctx->state_table_u32[state][ascii_code]; - k++; - } - /* if we have any non 0 transitions from our previous for search, - * store the ascii codes as well the corresponding states */ - if (k > 0) { - no_of_entries[0] = k; - if (state != 0) - curr_loc += k; - memcpy(curr_loc, temp_states, k * sizeof(SC_AC_BS_STATE_TYPE_U32)); - curr_loc += k; - } - } - - } - - return; -} - -/** - * \brief Process the patterns and prepare the state table. - * - * \param mpm_ctx Pointer to the mpm context. - */ -static inline void SCACBSPrepareStateTable(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - - /* create the 0th state in the goto table and output_table */ - SCACBSInitNewState(mpm_ctx); - - /* create the goto table */ - SCACBSCreateGotoTable(mpm_ctx); - /* create the failure table */ - SCACBSCreateFailureTable(mpm_ctx); - /* create the final state(delta) table */ - SCACBSCreateDeltaTable(mpm_ctx); - /* club the output state presence with delta transition entries */ - SCACBSClubOutputStatePresenceWithDeltaTable(mpm_ctx); - /* create the modified table */ - SCACBSCreateModDeltaTable(mpm_ctx); - - /* club nocase entries */ - SCACBSInsertCaseSensitiveEntriesForPatterns(mpm_ctx); - -// int state = 0; -// for (state = 0; state < ctx->state_count; state++) { -// int i = 0; -// for (i = 0; i < 256; i++) { -// if (ctx->state_table_u16[state][i] != 0) { -// printf("%d-%d-%d\n", state, i, ctx->state_table_u16[state][i] & 0x7fff) ; -// } -// } -// } - -#if 0 - SCACBSPrintDeltaTable(mpm_ctx); -#endif - - /* we don't need these anymore */ - SCFree(ctx->goto_table); - ctx->goto_table = NULL; - SCFree(ctx->failure_table); - ctx->failure_table = NULL; - SCFree(ctx->state_table_u16); - ctx->state_table_u16 = NULL; - SCFree(ctx->state_table_u32); - ctx->state_table_u32 = NULL; - - return; -} - -/** - * \brief Process the patterns added to the mpm, and create the internal tables. - * - * \param mpm_ctx Pointer to the mpm context. - */ -int SCACBSPreparePatterns(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - - if (mpm_ctx->pattern_cnt == 0 || mpm_ctx->init_hash == NULL) { - SCLogDebug("no patterns supplied to this mpm_ctx"); - return 0; - } - - /* alloc the pattern array */ - ctx->parray = (MpmPattern **)SCCalloc(mpm_ctx->pattern_cnt, sizeof(MpmPattern *)); - if (ctx->parray == NULL) - goto error; - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += (mpm_ctx->pattern_cnt * sizeof(MpmPattern *)); - - /* populate it with the patterns in the hash */ - uint32_t i = 0, p = 0; - for (i = 0; i < MPM_INIT_HASH_SIZE; i++) { - MpmPattern *node = mpm_ctx->init_hash[i], *nnode = NULL; - while(node != NULL) { - nnode = node->next; - node->next = NULL; - ctx->parray[p++] = node; - node = nnode; - } - } - - /* we no longer need the hash, so free it's memory */ - SCFree(mpm_ctx->init_hash); - mpm_ctx->init_hash = NULL; - - /* the memory consumed by a single state in our goto table */ - ctx->single_state_size = sizeof(int32_t) * 256; - - /* handle no case patterns */ - ctx->pid_pat_list = SCCalloc((mpm_ctx->max_pat_id + 1), sizeof(SCACBSPatternList)); - if (ctx->pid_pat_list == NULL) { - FatalError("Error allocating memory"); - } - - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (!(ctx->parray[i]->flags & MPM_PATTERN_FLAG_NOCASE)) { - ctx->pid_pat_list[ctx->parray[i]->id].cs = SCMalloc(ctx->parray[i]->len); - if (ctx->pid_pat_list[ctx->parray[i]->id].cs == NULL) { - FatalError("Error allocating memory"); - } - memcpy(ctx->pid_pat_list[ctx->parray[i]->id].cs, - ctx->parray[i]->original_pat, ctx->parray[i]->len); - ctx->pid_pat_list[ctx->parray[i]->id].patlen = ctx->parray[i]->len; - } - - /* ACPatternList now owns this memory */ - ctx->pid_pat_list[ctx->parray[i]->id].sids_size = ctx->parray[i]->sids_size; - ctx->pid_pat_list[ctx->parray[i]->id].sids = ctx->parray[i]->sids; - } - - /* prepare the state table required by AC */ - SCACBSPrepareStateTable(mpm_ctx); - - /* free all the stored patterns. Should save us a good 100-200 mbs */ - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (ctx->parray[i] != NULL) { - MpmFreePattern(mpm_ctx, ctx->parray[i]); - } - } - SCFree(ctx->parray); - ctx->parray = NULL; - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (mpm_ctx->pattern_cnt * sizeof(MpmPattern *)); - - ctx->pattern_id_bitarray_size = (mpm_ctx->max_pat_id / 8) + 1; - - return 0; - -error: - return -1; -} - -/** - * \brief Initialize the AC context. - * - * \param mpm_ctx Mpm context. - */ -void SCACBSInitCtx(MpmCtx *mpm_ctx) -{ - if (mpm_ctx->ctx != NULL) - return; - - mpm_ctx->ctx = SCCalloc(1, sizeof(SCACBSCtx)); - if (mpm_ctx->ctx == NULL) { - exit(EXIT_FAILURE); - } - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size += sizeof(SCACBSCtx); - - /* initialize the hash we use to speed up pattern insertions */ - mpm_ctx->init_hash = SCCalloc(MPM_INIT_HASH_SIZE, sizeof(MpmPattern *)); - if (mpm_ctx->init_hash == NULL) { - exit(EXIT_FAILURE); - } - - /* get conf values for AC from our yaml file. We have no conf values for - * now. We will certainly need this, as we develop the algo */ - SCACBSGetConfig(); - - SCReturn; -} - -/** - * \brief Destroy the mpm context. - * - * \param mpm_ctx Pointer to the mpm context. - */ -void SCACBSDestroyCtx(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - if (ctx == NULL) - return; - - if (mpm_ctx->init_hash != NULL) { - SCFree(mpm_ctx->init_hash); - mpm_ctx->init_hash = NULL; - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (MPM_INIT_HASH_SIZE * sizeof(MpmPattern *)); - } - - if (ctx->parray != NULL) { - uint32_t i; - for (i = 0; i < mpm_ctx->pattern_cnt; i++) { - if (ctx->parray[i] != NULL) { - MpmFreePattern(mpm_ctx, ctx->parray[i]); - } - } - - SCFree(ctx->parray); - ctx->parray = NULL; - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= (mpm_ctx->pattern_cnt * sizeof(MpmPattern *)); - } - - if (ctx->state_table_u16 != NULL) { - SCFree(ctx->state_table_u16); - ctx->state_table_u16 = NULL; - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size -= (ctx->state_count * - sizeof(SC_AC_BS_STATE_TYPE_U16) * 256); - } else if (ctx->state_table_u32 != NULL) { - SCFree(ctx->state_table_u32); - ctx->state_table_u32 = NULL; - - mpm_ctx->memory_cnt++; - mpm_ctx->memory_size -= (ctx->state_count * - sizeof(SC_AC_BS_STATE_TYPE_U32) * 256); - } - - if (ctx->output_table != NULL) { - uint32_t state_count; - for (state_count = 0; state_count < ctx->state_count; state_count++) { - if (ctx->output_table[state_count].pids != NULL) { - SCFree(ctx->output_table[state_count].pids); - } - } - SCFree(ctx->output_table); - } - - if (ctx->pid_pat_list != NULL) { - uint32_t i; - for (i = 0; i < (mpm_ctx->max_pat_id + 1); i++) { - if (ctx->pid_pat_list[i].cs != NULL) - SCFree(ctx->pid_pat_list[i].cs); - if (ctx->pid_pat_list[i].sids != NULL) - SCFree(ctx->pid_pat_list[i].sids); - } - SCFree(ctx->pid_pat_list); - } - - if (ctx->state_table_mod != NULL) { - SCFree(ctx->state_table_mod); - ctx->state_table_mod = NULL; - } - - if (ctx->state_table_mod_pointers != NULL) { - SCFree(ctx->state_table_mod_pointers); - ctx->state_table_mod_pointers = NULL; - } - - SCFree(mpm_ctx->ctx); - mpm_ctx->memory_cnt--; - mpm_ctx->memory_size -= sizeof(SCACBSCtx); - - return; -} - -/** - * \brief The aho corasick search function. - * - * \param mpm_ctx Pointer to the mpm context. - * \param mpm_thread_ctx Pointer to the mpm thread context. - * \param pmq Pointer to the Pattern Matcher Queue to hold - * search matches. - * \param buf Buffer to be searched. - * \param buflen Buffer length. - * - * \retval matches Match count. - */ -uint32_t SCACBSSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, - PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen) -{ - const SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - uint32_t i = 0; - int matches = 0; - uint8_t buf_local; - - /* \todo tried loop unrolling with register var, with no perf increase. Need - * to dig deeper */ - /* \todo Change it for stateful MPM. Supply the state using mpm_thread_ctx */ - SCACBSPatternList *pid_pat_list = ctx->pid_pat_list; - - uint8_t bitarray[ctx->pattern_id_bitarray_size]; - memset(bitarray, 0, ctx->pattern_id_bitarray_size); - - if (ctx->state_count < 32767) { - register SC_AC_BS_STATE_TYPE_U16 state = 0; - uint16_t no_of_entries; - uint16_t *ascii_codes; - uint16_t **state_table_mod_pointers = (uint16_t **)ctx->state_table_mod_pointers; - uint16_t *zero_state = state_table_mod_pointers[0] + 1; - - for (i = 0; i < buflen; i++) { - if (state == 0) { - state = zero_state[u8_tolower(buf[i])]; - } else { - no_of_entries = *(state_table_mod_pointers[state & 0x7FFF]); - if (no_of_entries == 1) { - ascii_codes = state_table_mod_pointers[state & 0x7FFF] + 1; - buf_local = u8_tolower(buf[i]); - if (buf_local == ascii_codes[0]) { - state = *(ascii_codes + no_of_entries); - } else { - state = zero_state[buf_local]; - } - } else { - if (no_of_entries == 0) { - state = zero_state[u8_tolower(buf[i])]; - goto match_u16; - } - buf_local = u8_tolower(buf[i]); - ascii_codes = state_table_mod_pointers[state & 0x7FFF] + 1; - int low = 0; - int high = no_of_entries; - int mid; - while (low <= high) { - mid = (low + high) / 2; - if (ascii_codes[mid] == buf_local) { - state = ((ascii_codes + no_of_entries))[mid]; - goto match_u16; - } else if (ascii_codes[mid] < buf_local) { - low = mid + 1; - } else { - high = mid - 1; - } - } /* while */ - state = zero_state[buf_local]; - } /* else - if (no_of_entires == 1) */ - } - - match_u16: - if (state & 0x8000) { - uint32_t nentries = ctx->output_table[state & 0x7FFF].no_of_entries; - uint32_t *pids = ctx->output_table[state & 0x7FFF].pids; - uint32_t k; - for (k = 0; k < nentries; k++) { - if (pids[k] & 0xFFFF0000) { - uint32_t lower_pid = pids[k] & 0x0000FFFF; - if (SCMemcmp(pid_pat_list[lower_pid].cs, - buf + i - pid_pat_list[lower_pid].patlen + 1, - pid_pat_list[lower_pid].patlen) != 0) { - /* inside loop */ - continue; - } - if (bitarray[(lower_pid) / 8] & (1 << ((lower_pid) % 8))) { - ; - } else { - bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8)); - PrefilterAddSids(pmq, pid_pat_list[lower_pid].sids, - pid_pat_list[lower_pid].sids_size); - } - matches++; - } else { - if (bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { - ; - } else { - bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); - PrefilterAddSids(pmq, pid_pat_list[pids[k]].sids, - pid_pat_list[pids[k]].sids_size); - } - matches++; - } - //loop1: - //; - } - } - } /* for (i = 0; i < buflen; i++) */ - - } else { - register SC_AC_BS_STATE_TYPE_U32 state = 0; - uint32_t no_of_entries; - uint32_t *ascii_codes; - uint32_t **state_table_mod_pointers = (uint32_t **)ctx->state_table_mod_pointers; - uint32_t *zero_state = state_table_mod_pointers[0] + 1; - - for (i = 0; i < buflen; i++) { - if (state == 0) { - state = zero_state[u8_tolower(buf[i])]; - } else { - no_of_entries = *(state_table_mod_pointers[state & 0x00FFFFFF]); - if (no_of_entries == 1) { - ascii_codes = state_table_mod_pointers[state & 0x00FFFFFF] + 1; - buf_local = u8_tolower(buf[i]); - if (buf_local == ascii_codes[0]) { - state = *(ascii_codes + no_of_entries); - } else { - state = zero_state[buf_local]; - } - } else { - if (no_of_entries == 0) { - state = zero_state[u8_tolower(buf[i])]; - goto match_u32; - } - buf_local = u8_tolower(buf[i]); - ascii_codes = state_table_mod_pointers[state & 0x00FFFFFF] + 1; - int low = 0; - int high = no_of_entries; - int mid; - while (low <= high) { - mid = (low + high) / 2; - if (ascii_codes[mid] == buf_local) { - state = ((ascii_codes + no_of_entries))[mid]; - goto match_u32; - } else if (ascii_codes[mid] < buf_local) { - low = mid + 1; - } else { - high = mid - 1; - } - } /* while */ - state = zero_state[buf_local]; - } /* else - if (no_of_entires == 1) */ - } - - match_u32: - if (state & 0xFF000000) { - uint32_t nentries = ctx->output_table[state & 0x00FFFFFF].no_of_entries; - uint32_t *pids = ctx->output_table[state & 0x00FFFFFF].pids; - uint32_t k; - for (k = 0; k < nentries; k++) { - if (pids[k] & 0xFFFF0000) { - uint32_t lower_pid = pids[k] & 0x0000FFFF; - if (SCMemcmp(pid_pat_list[lower_pid].cs, - buf + i - pid_pat_list[lower_pid].patlen + 1, - pid_pat_list[lower_pid].patlen) != 0) { - /* inside loop */ - continue; - } - if (bitarray[(lower_pid) / 8] & (1 << ((lower_pid) % 8))) { - ; - } else { - bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8)); - PrefilterAddSids(pmq, pid_pat_list[lower_pid].sids, - pid_pat_list[lower_pid].sids_size); - } - matches++; - } else { - if (bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { - ; - } else { - bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); - PrefilterAddSids(pmq, pid_pat_list[pids[k]].sids, - pid_pat_list[pids[k]].sids_size); - } - matches++; - } - //loop1: - //; - } - } - } /* for (i = 0; i < buflen; i++) */ - } - - return matches; -} - -/** - * \brief Add a case insensitive pattern. Although we have different calls for - * adding case sensitive and insensitive patterns, we make a single call - * for either case. No special treatment for either case. - * - * \param mpm_ctx Pointer to the mpm context. - * \param pat The pattern to add. - * \param patnen The pattern length. - * \param offset Ignored. - * \param depth Ignored. - * \param pid The pattern id. - * \param sid Ignored. - * \param flags Flags associated with this pattern. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCACBSAddPatternCI(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, - SigIntId sid, uint8_t flags) -{ - flags |= MPM_PATTERN_FLAG_NOCASE; - return MpmAddPattern(mpm_ctx, pat, patlen, offset, depth, pid, sid, flags); -} - -/** - * \brief Add a case sensitive pattern. Although we have different calls for - * adding case sensitive and insensitive patterns, we make a single call - * for either case. No special treatment for either case. - * - * \param mpm_ctx Pointer to the mpm context. - * \param pat The pattern to add. - * \param patnen The pattern length. - * \param offset Ignored. - * \param depth Ignored. - * \param pid The pattern id. - * \param sid Ignored. - * \param flags Flags associated with this pattern. - * - * \retval 0 On success. - * \retval -1 On failure. - */ -int SCACBSAddPatternCS(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, - uint16_t offset, uint16_t depth, uint32_t pid, - SigIntId sid, uint8_t flags) -{ - return MpmAddPattern(mpm_ctx, pat, patlen, offset, depth, pid, sid, flags); -} - -void SCACBSPrintInfo(MpmCtx *mpm_ctx) -{ - SCACBSCtx *ctx = (SCACBSCtx *)mpm_ctx->ctx; - - printf("MPM AC Information:\n"); - printf("Memory allocs: %" PRIu32 "\n", mpm_ctx->memory_cnt); - printf("Memory alloced: %" PRIu32 "\n", mpm_ctx->memory_size); - printf(" Sizeof:\n"); - printf(" MpmCtx %" PRIuMAX "\n", (uintmax_t)sizeof(MpmCtx)); - printf(" SCACBSCtx: %" PRIuMAX "\n", (uintmax_t)sizeof(SCACBSCtx)); - printf(" MpmPattern %" PRIuMAX "\n", (uintmax_t)sizeof(MpmPattern)); - printf(" MpmPattern %" PRIuMAX "\n", (uintmax_t)sizeof(MpmPattern)); - printf("Unique Patterns: %" PRIu32 "\n", mpm_ctx->pattern_cnt); - printf("Smallest: %" PRIu32 "\n", mpm_ctx->minlen); - printf("Largest: %" PRIu32 "\n", mpm_ctx->maxlen); - printf("Total states in the state table: %" PRIu32 "\n", ctx->state_count); - printf("\n"); - - return; -} - -/*************************************Unittests********************************/ - -#ifdef UNITTESTS -#include "detect-engine-alert.h" - -static int SCACBSTest01(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "abcdefghjiklmnopqrstuvwxyz"; - - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest02(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abce", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest03(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcde", 4, 0, 0, 1, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"fghj", 4, 0, 0, 2, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest04(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcdegh", 6, 0, 0, 1, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"fghjxyz", 7, 0, 0, 2, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest05(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"ABCD", 4, 0, 0, 0, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"bCdEfG", 6, 0, 0, 1, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"fghJikl", 7, 0, 0, 2, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "abcdefghjiklmnopqrstuvwxyz"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest06(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "abcd"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest07(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* should match 30 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"A", 1, 0, 0, 0, 0, 0); - /* should match 29 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 1, 0, 0); - /* should match 28 times */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAA", 3, 0, 0, 2, 0, 0); - /* 26 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAA", 5, 0, 0, 3, 0, 0); - /* 21 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAA", 10, 0, 0, 4, 0, 0); - /* 1 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - 30, 0, 0, 5, 0, 0); - PmqSetup(&pmq); - /* total matches: 135 */ - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 135) - result = 1; - else - printf("135 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest08(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"a", 1); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest09(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"ab", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"ab", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest10(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcdefgh", 8, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "01234567890123456789012345678901234567890123456789" - "01234567890123456789012345678901234567890123456789" - "abcdefgh" - "01234567890123456789012345678901234567890123456789" - "01234567890123456789012345678901234567890123456789"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest11(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"he", 2, 0, 0, 1, 0, 0) == -1) - goto end; - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"she", 3, 0, 0, 2, 0, 0) == -1) - goto end; - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"his", 3, 0, 0, 3, 0, 0) == -1) - goto end; - if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"hers", 4, 0, 0, 4, 0, 0) == -1) - goto end; - PmqSetup(&pmq); - - if (SCACBSPreparePatterns(&mpm_ctx) == -1) - goto end; - - result = 1; - - const char *buf = "he"; - result &= (SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 1); - buf = "she"; - result &= (SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 2); - buf = "his"; - result &= (SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 1); - buf = "hers"; - result &= (SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf, - strlen(buf)) == 2); - - end: - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest12(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"wxyz", 4, 0, 0, 0, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"vwxyz", 5, 0, 0, 1, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "abcdefghijklmnopqrstuvwxyz"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 2) - result = 1; - else - printf("2 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest13(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 match */ - const char pat[] = "abcdefghijklmnopqrstuvwxyzABCD"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, sizeof(pat) - 1, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "abcdefghijklmnopqrstuvwxyzABCD"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest14(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 match */ - const char pat[] = "abcdefghijklmnopqrstuvwxyzABCDE"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, sizeof(pat) - 1, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "abcdefghijklmnopqrstuvwxyzABCDE"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest15(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 match */ - const char pat[] = "abcdefghijklmnopqrstuvwxyzABCDEF"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, sizeof(pat) - 1, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "abcdefghijklmnopqrstuvwxyzABCDEF"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest16(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 match */ - const char pat[] = "abcdefghijklmnopqrstuvwxyzABC"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, sizeof(pat) - 1, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "abcdefghijklmnopqrstuvwxyzABC"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest17(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 match */ - const char pat[] = "abcdefghijklmnopqrstuvwxyzAB"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, sizeof(pat) - 1, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "abcdefghijklmnopqrstuvwxyzAB"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest18(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 match */ - const char pat[] = "abcde" - "fghij" - "klmno" - "pqrst" - "uvwxy" - "z"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, sizeof(pat) - 1, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "abcde""fghij""klmno""pqrst""uvwxy""z"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest19(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 */ - const char pat[] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, sizeof(pat) - 1, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest20(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 */ - const char pat[] = "AAAAA" - "AAAAA" - "AAAAA" - "AAAAA" - "AAAAA" - "AAAAA" - "AA"; - MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, sizeof(pat) - 1, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AA"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest21(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"AA", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest22(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0); - /* 1 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcde", 5, 0, 0, 1, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "abcdefghijklmnopqrstuvwxyz"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 2) - result = 1; - else - printf("2 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest23(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"aa", 2); - - if (cnt == 0) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest24(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 1 */ - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)"aa", 2); - - if (cnt == 1) - result = 1; - else - printf("1 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest25(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"ABCD", 4, 0, 0, 0, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"bCdEfG", 6, 0, 0, 1, 0, 0); - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"fghiJkl", 7, 0, 0, 2, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 3) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest26(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - MpmAddPatternCI(&mpm_ctx, (uint8_t *)"Works", 5, 0, 0, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"Works", 5, 0, 0, 1, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "works"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 1) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest27(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 0 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"ONE", 3, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "tone"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest28(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - /* 0 match */ - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"one", 3, 0, 0, 0, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "tONE"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 0) - result = 1; - else - printf("0 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest29(void) -{ - int result = 0; - MpmCtx mpm_ctx; - MpmThreadCtx mpm_thread_ctx; - PrefilterRuleStore pmq; - - memset(&mpm_ctx, 0x00, sizeof(MpmCtx)); - memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx)); - MpmInitCtx(&mpm_ctx, MPM_AC_BS); - - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcde", 5, 0, 0, 0, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcdef", 5, 0, 0, 1, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"cdefg", 5, 0, 0, 3, 0, 0); - MpmAddPatternCS(&mpm_ctx, (uint8_t *)"defgh", 5, 0, 0, 4, 0, 0); - PmqSetup(&pmq); - - SCACBSPreparePatterns(&mpm_ctx); - - const char *buf = "abcdefgh"; - uint32_t cnt = SCACBSSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, - (uint8_t *)buf, strlen(buf)); - - if (cnt == 4) - result = 1; - else - printf("3 != %" PRIu32 " ",cnt); - - SCACBSDestroyCtx(&mpm_ctx); - PmqFree(&pmq); - return result; -} - -static int SCACBSTest30(void) -{ - uint8_t buf[] = "onetwothreefourfivesixseveneightnine"; - uint16_t buflen = sizeof(buf) - 1; - 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->mpm_matcher = MPM_AC_BS; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"onetwothreefourfivesixseveneightnine\"; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - de_ctx->sig_list->next = SigInit(de_ctx, "alert tcp any any -> any any " - "(content:\"onetwothreefourfivesixseveneightnine\"; fast_pattern:3,3; sid:2;)"); - if (de_ctx->sig_list->next == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - if (PacketAlertCheck(p, 1) != 1) { - printf("if (PacketAlertCheck(p, 1) != 1) failure\n"); - goto end; - } - if (PacketAlertCheck(p, 2) != 1) { - printf("if (PacketAlertCheck(p, 1) != 2) failure\n"); - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) { - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - DetectEngineCtxFree(de_ctx); - } - - UTHFreePackets(&p, 1); - return result; -} - -#endif /* UNITTESTS */ - -void SCACBSRegisterTests(void) -{ - -#ifdef UNITTESTS - UtRegisterTest("SCACBSTest01", SCACBSTest01); - UtRegisterTest("SCACBSTest02", SCACBSTest02); - UtRegisterTest("SCACBSTest03", SCACBSTest03); - UtRegisterTest("SCACBSTest04", SCACBSTest04); - UtRegisterTest("SCACBSTest05", SCACBSTest05); - UtRegisterTest("SCACBSTest06", SCACBSTest06); - UtRegisterTest("SCACBSTest07", SCACBSTest07); - UtRegisterTest("SCACBSTest08", SCACBSTest08); - UtRegisterTest("SCACBSTest09", SCACBSTest09); - UtRegisterTest("SCACBSTest10", SCACBSTest10); - UtRegisterTest("SCACBSTest11", SCACBSTest11); - UtRegisterTest("SCACBSTest12", SCACBSTest12); - UtRegisterTest("SCACBSTest13", SCACBSTest13); - UtRegisterTest("SCACBSTest14", SCACBSTest14); - UtRegisterTest("SCACBSTest15", SCACBSTest15); - UtRegisterTest("SCACBSTest16", SCACBSTest16); - UtRegisterTest("SCACBSTest17", SCACBSTest17); - UtRegisterTest("SCACBSTest18", SCACBSTest18); - UtRegisterTest("SCACBSTest19", SCACBSTest19); - UtRegisterTest("SCACBSTest20", SCACBSTest20); - UtRegisterTest("SCACBSTest21", SCACBSTest21); - UtRegisterTest("SCACBSTest22", SCACBSTest22); - UtRegisterTest("SCACBSTest23", SCACBSTest23); - UtRegisterTest("SCACBSTest24", SCACBSTest24); - UtRegisterTest("SCACBSTest25", SCACBSTest25); - UtRegisterTest("SCACBSTest26", SCACBSTest26); - UtRegisterTest("SCACBSTest27", SCACBSTest27); - UtRegisterTest("SCACBSTest28", SCACBSTest28); - UtRegisterTest("SCACBSTest29", SCACBSTest29); - UtRegisterTest("SCACBSTest30", SCACBSTest30); -#endif - - return; -} diff --git a/src/util-mpm-ac-bs.h b/src/util-mpm-ac-bs.h deleted file mode 100644 index d1135b1cfea6..000000000000 --- a/src/util-mpm-ac-bs.h +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (C) 2007-2014 Open Information Security Foundation - * - * You can copy, redistribute or modify this Program under the terms of - * the GNU General Public License version 2 as published by the Free - * Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -/** - * \file - * - * \author Anoop Saldanha - * - */ - -#include "util-mpm.h" - -#define SC_AC_BS_STATE_TYPE_U16 uint16_t -#define SC_AC_BS_STATE_TYPE_U32 uint32_t - -typedef struct SCACBSPatternList_ { - uint8_t *cs; - uint16_t patlen; - - /* sid(s) for this pattern */ - uint32_t sids_size; - SigIntId *sids; -} SCACBSPatternList; - -typedef struct SCACBSOutputTable_ { - /* list of pattern sids */ - uint32_t *pids; - /* no of entries we have in pids */ - uint32_t no_of_entries; -} SCACBSOutputTable; - -typedef struct SCACBSCtx_ { - /* pattern arrays. We need this only during the goto table creation phase */ - MpmPattern **parray; - - /* no of states used by ac */ - uint32_t state_count; - - uint32_t pattern_id_bitarray_size; - - /* the all important memory hungry state_table */ - SC_AC_BS_STATE_TYPE_U16 (*state_table_u16)[256]; - /* the all important memory hungry state_table */ - SC_AC_BS_STATE_TYPE_U32 (*state_table_u32)[256]; - /* the modified goto_table */ - uint8_t *state_table_mod; - uint8_t **state_table_mod_pointers; - - /* goto_table, failure table and output table. Needed to create state_table. - * Will be freed, once we have created the state_table */ - int32_t (*goto_table)[256]; - int32_t *failure_table; - SCACBSOutputTable *output_table; - SCACBSPatternList *pid_pat_list; - - /* the size of each state */ - uint16_t single_state_size; -} SCACBSCtx; - -void MpmACBSRegister(void); diff --git a/src/util-mpm.c b/src/util-mpm.c index 0638a8876c53..47a19b2c8e88 100644 --- a/src/util-mpm.c +++ b/src/util-mpm.c @@ -29,7 +29,6 @@ /* include pattern matchers */ #include "util-mpm-ac.h" -#include "util-mpm-ac-bs.h" #include "util-mpm-ac-ks.h" #include "util-mpm-hs.h" #include "util-hashlist.h" @@ -229,7 +228,6 @@ void MpmTableSetup(void) mpm_default_matcher = DEFAULT_MPM; MpmACRegister(); - MpmACBSRegister(); MpmACTileRegister(); #ifdef BUILD_HYPERSCAN #ifdef HAVE_HS_VALID_PLATFORM diff --git a/src/util-mpm.h b/src/util-mpm.h index 87eec5e793a9..67988efd0314 100644 --- a/src/util-mpm.h +++ b/src/util-mpm.h @@ -34,7 +34,6 @@ enum { /* aho-corasick */ MPM_AC, - MPM_AC_BS, MPM_AC_KS, MPM_HS, /* table size */