suricata
util-mpm-ac-ks.c
Go to the documentation of this file.
1 /* Copyright (C) 2013-2014 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Ken Steele <suricata@tilera.com>
22  * \author Anoop Saldanha <anoopsaldanha@gmail.com>
23  *
24  * Aho-corasick MPM optimized for the Tilera Tile-Gx architecture.
25  *
26  * Efficient String Matching: An Aid to Bibliographic Search
27  * Alfred V. Aho and Margaret J. Corasick
28  *
29  * - Started with util-mpm-ac.c:
30  * - Uses the delta table for calculating transitions,
31  * instead of having separate goto and failure
32  * transitions.
33  * - If we cross 2 ** 16 states, we use 4 bytes in the
34  * transition table to hold each state, otherwise we use
35  * 2 bytes.
36  * - This version of the MPM is heavy on memory, but it
37  * performs well. If you can fit the ruleset with this
38  * mpm on your box without hitting swap, this is the MPM
39  * to go for.
40  *
41  * - Added these optimizations:
42  * - Compress the input alphabet from 256 characters down
43  * to the actual characters used in the patterns, plus
44  * one character for all the unused characters.
45  * - Reduce the size of the delta table so that each state
46  * is the smallest power of two that is larger than the
47  * size of the compressed alphabet.
48  * - Specialized the search function based on state count
49  * (small for 8-bit large for 16-bit) and the size of
50  * the alphabet, so that it is constant inside the
51  * function for better optimization.
52  *
53  * \todo - Do a proper analyis of our existing MPMs and suggest a good
54  * one based on the pattern distribution and the expected
55  * traffic(say http).
56 
57  * - Irrespective of whether we cross 2 ** 16 states or
58  * not,shift to using uint32_t for state type, so that we can
59  * integrate it's status as a final state or not in the
60  * topmost byte. We are already doing it if state_count is >
61  * 2 ** 16.
62  * - Test case-senstive patterns if they have any ascii chars.
63  * If they don't treat them as nocase.
64  * - Reorder the compressed alphabet to put the most common characters
65  * first.
66  */
67 
68 #include "suricata-common.h"
69 #include "suricata.h"
70 
71 #include "detect.h"
72 #include "detect-parse.h"
73 #include "detect-engine.h"
74 
75 #include "conf.h"
76 #include "util-debug.h"
77 #include "util-unittest.h"
78 #include "util-unittest-helper.h"
79 #include "util-memcmp.h"
80 #include "util-memcpy.h"
81 #include "util-validate.h"
82 #include "util-mpm-ac-ks.h"
83 
84 #if __BYTE_ORDER == __LITTLE_ENDIAN
85 
86 void SCACTileInitCtx(MpmCtx *);
90 int SCACTileAddPatternCI(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t,
91  uint32_t, SigIntId, uint8_t);
92 int SCACTileAddPatternCS(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t,
93  uint32_t, SigIntId, uint8_t);
94 int SCACTilePreparePatterns(MpmCtx *mpm_ctx);
95 uint32_t SCACTileSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx,
96  PrefilterRuleStore *pmq, const uint8_t *buf,
97  uint32_t buflen);
98 void SCACTilePrintInfo(MpmCtx *mpm_ctx);
99 void SCACTilePrintSearchStats(MpmThreadCtx *mpm_thread_ctx);
100 void SCACTileRegisterTests(void);
101 
102 uint32_t SCACTileSearchLarge(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
103  PrefilterRuleStore *pmq,
104  const uint8_t *buf, uint32_t buflen);
105 uint32_t SCACTileSearchSmall256(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
106  PrefilterRuleStore *pmq,
107  const uint8_t *buf, uint32_t buflen);
108 uint32_t SCACTileSearchSmall128(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
109  PrefilterRuleStore *pmq,
110  const uint8_t *buf, uint32_t buflen);
111 uint32_t SCACTileSearchSmall64(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
112  PrefilterRuleStore *pmq,
113  const uint8_t *buf, uint32_t buflen);
114 uint32_t SCACTileSearchSmall32(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
115  PrefilterRuleStore *pmq,
116  const uint8_t *buf, uint32_t buflen);
117 uint32_t SCACTileSearchSmall16(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
118  PrefilterRuleStore *pmq,
119  const uint8_t *buf, uint32_t buflen);
120 uint32_t SCACTileSearchSmall8(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
121  PrefilterRuleStore *pmq,
122  const uint8_t *buf, uint32_t buflen);
123 
124 uint32_t SCACTileSearchTiny256(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
125  PrefilterRuleStore *pmq,
126  const uint8_t *buf, uint32_t buflen);
127 uint32_t SCACTileSearchTiny128(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
128  PrefilterRuleStore *pmq,
129  const uint8_t *buf, uint32_t buflen);
130 uint32_t SCACTileSearchTiny64(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
131  PrefilterRuleStore *pmq,
132  const uint8_t *buf, uint32_t buflen);
133 uint32_t SCACTileSearchTiny32(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
134  PrefilterRuleStore *pmq,
135  const uint8_t *buf, uint32_t buflen);
136 uint32_t SCACTileSearchTiny16(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
137  PrefilterRuleStore *pmq,
138  const uint8_t *buf, uint32_t buflen);
139 uint32_t SCACTileSearchTiny8(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
140  PrefilterRuleStore *pmq,
141  const uint8_t *buf, uint32_t buflen);
142 
143 
144 static void SCACTileDestroyInitCtx(MpmCtx *mpm_ctx);
145 
146 
147 /* a placeholder to denote a failure transition in the goto table */
148 #define SC_AC_TILE_FAIL (-1)
149 
150 #define STATE_QUEUE_CONTAINER_SIZE 65536
151 
152 /**
153  * \brief Helper structure used by AC during state table creation
154  */
155 typedef struct StateQueue_ {
157  int top;
158  int bot;
160 
161 /**
162  * \internal
163  * \brief Initialize the AC context with user specified conf parameters. We
164  * aren't retrieving anything for AC conf now, but we will certainly
165  * need it, when we customize AC.
166  */
167 static void SCACTileGetConfig(void)
168 {
169 }
170 
171 
172 /**
173  * \internal
174  * \brief Count the occurences of each character in the pattern and
175  * accumulate into a histogram. Really only used to detect unused
176  * characters, so could just set to 1 instead of counting.
177  */
178 static inline void SCACTileHistogramAlphabet(SCACTileCtx *ctx,
179  MpmPattern *p)
180 {
181  for (int i = 0; i < p->len; i++) {
182  ctx->alpha_hist[p->ci[i]]++;
183  }
184 }
185 
186 /* Use Alpahbet Histogram to create compressed alphabet.
187  */
188 static void SCACTileInitTranslateTable(SCACTileCtx *ctx)
189 {
190  /* Count the number of ASCII values actually appearing in any
191  * pattern. Create compressed mapping table with unused
192  * characters mapping to zero.
193  */
194  for (int i = 0; i < 256; i++) {
195  /* Move all upper case counts to lower case */
196  if (i >= 'A' && i <= 'Z') {
197  ctx->alpha_hist[i - 'A' + 'a'] += ctx->alpha_hist[i];
198  ctx->alpha_hist[i] = 0;
199  }
200  if (ctx->alpha_hist[i]) {
201  ctx->alphabet_size++;
202  DEBUG_VALIDATE_BUG_ON(ctx->alphabet_size > UINT8_MAX);
203  ctx->translate_table[i] = (uint8_t)ctx->alphabet_size;
204  } else
205  ctx->translate_table[i] = 0;
206  }
207  /* Fix up translation table for uppercase */
208  for (int i = 'A'; i <= 'Z'; i++)
209  ctx->translate_table[i] = ctx->translate_table[i - 'A' + 'a'];
210 
211  SCLogDebug(" Alphabet size %d", ctx->alphabet_size);
212 
213  /* Round alphabet size up to next power-of-two Leave one extra
214  * space For the unused-chararacters = 0 mapping.
215  */
216  ctx->alphabet_size += 1; /* Extra space for unused-character */
217  if (ctx->alphabet_size <= 8) {
218  ctx->alphabet_storage = 8;
219  } else if (ctx->alphabet_size <= 16) {
220  ctx->alphabet_storage = 16;
221  } else if (ctx->alphabet_size <= 32) {
222  ctx->alphabet_storage = 32;
223  } else if (ctx->alphabet_size <= 64) {
224  ctx->alphabet_storage = 64;
225  } else if (ctx->alphabet_size <= 128) {
226  ctx->alphabet_storage = 128;
227  } else
228  ctx->alphabet_storage = 256;
229 }
230 
231 static void SCACTileReallocOutputTable(SCACTileCtx *ctx, int new_state_count)
232 {
233 
234  /* reallocate space in the output table for the new state */
235  size_t size = ctx->allocated_state_count * sizeof(SCACTileOutputTable);
236  void *ptmp = SCRealloc(ctx->output_table, size);
237  if (ptmp == NULL) {
238  SCFree(ctx->output_table);
239  ctx->output_table = NULL;
240  FatalError(SC_ERR_FATAL, "Error allocating memory");
241  }
242  ctx->output_table = ptmp;
243 }
244 
245 static void SCACTileReallocState(SCACTileCtx *ctx, int new_state_count)
246 {
247  /* reallocate space in the goto table to include a new state */
248  size_t size = ctx->allocated_state_count * sizeof(int32_t) * 256;
249  void *ptmp = SCRealloc(ctx->goto_table, size);
250  if (ptmp == NULL) {
251  SCFree(ctx->goto_table);
252  ctx->goto_table = NULL;
253  FatalError(SC_ERR_FATAL, "Error allocating memory");
254  }
255  ctx->goto_table = ptmp;
256 
257  SCACTileReallocOutputTable(ctx, new_state_count);
258 }
259 
260 /**
261  * \internal
262  * \brief Initialize a new state in the goto and output tables.
263  *
264  * \param mpm_ctx Pointer to the mpm context.
265  *
266  * \retval The state id, of the newly created state.
267  */
268 static inline int SCACTileInitNewState(MpmCtx *mpm_ctx)
269 {
270  SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
271  SCACTileCtx *ctx = search_ctx->init_ctx;
272  int aa = 0;
273 
274  /* Exponentially increase the allocated space when needed. */
275  if (ctx->allocated_state_count < ctx->state_count + 1) {
276  if (ctx->allocated_state_count == 0)
277  ctx->allocated_state_count = 256;
278  else
279  ctx->allocated_state_count *= 2;
280 
281  SCACTileReallocState(ctx, ctx->allocated_state_count);
282  }
283 
284  /* set all transitions for the newly assigned state as FAIL transitions */
285  for (aa = 0; aa < ctx->alphabet_size; aa++) {
286  ctx->goto_table[ctx->state_count][aa] = SC_AC_TILE_FAIL;
287  }
288 
289  memset(ctx->output_table + ctx->state_count, 0,
290  sizeof(SCACTileOutputTable));
291 
292  return ctx->state_count++;
293 }
294 
295 /**
296  * \internal
297  * \brief Adds a pid to the output table for a state.
298  *
299  * \param state The state to whose output table we should add the pid.
300  * \param pid The pattern id to add.
301  * \param mpm_ctx Pointer to the mpm context.
302  */
303 static void SCACTileSetOutputState(int32_t state, MpmPatternIndex pindex, MpmCtx *mpm_ctx)
304 {
305  void *ptmp;
306  SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
307  SCACTileCtx *ctx = search_ctx->init_ctx;
308 
309  SCACTileOutputTable *output_state = &ctx->output_table[state];
310  uint32_t i = 0;
311 
312  /* Don't add the pattern more than once to the same state. */
313  for (i = 0; i < output_state->no_of_entries; i++) {
314  if (output_state->patterns[i] == pindex)
315  return;
316  }
317 
318  /* Increase the size of the array of pids for this state and add
319  * the new pid. */
320  output_state->no_of_entries++;
321  ptmp = SCRealloc(output_state->patterns,
322  output_state->no_of_entries * sizeof(MpmPatternIndex));
323  if (ptmp == NULL) {
324  SCFree(output_state->patterns);
325  output_state->patterns = NULL;
326  FatalError(SC_ERR_FATAL, "Error allocating memory");
327  }
328  output_state->patterns = ptmp;
329 
330  output_state->patterns[output_state->no_of_entries - 1] = pindex;
331 }
332 
333 /**
334  * \brief Helper function used by SCACTileCreateGotoTable. Adds a
335  * pattern to the goto table.
336  *
337  * \param pattern Pointer to the pattern.
338  * \param pattern_len Pattern length.
339  * \param pid The pattern id, that corresponds to this pattern. We
340  * need it to updated the output table for this pattern.
341  * \param mpm_ctx Pointer to the mpm context.
342  */
343 static void SCACTileEnter(uint8_t *pattern, uint16_t pattern_len,
344  MpmPatternIndex pindex, MpmCtx *mpm_ctx)
345 {
346  SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
347  SCACTileCtx *ctx = search_ctx->init_ctx;
348 
349  int32_t state = 0;
350  int32_t newstate = 0;
351  int i = 0;
352  int p = 0;
353  int tc;
354 
355  /* Walk down the trie till we have a match for the pattern prefix */
356  state = 0;
357  for (i = 0; i < pattern_len; i++) {
358  tc = ctx->translate_table[pattern[i]];
359  if (ctx->goto_table[state][tc] == SC_AC_TILE_FAIL)
360  break;
361  state = ctx->goto_table[state][tc];
362  }
363 
364  /* Add the non-matching pattern suffix to the trie, from the last state
365  * we left off */
366  for (p = i; p < pattern_len; p++) {
367  newstate = SCACTileInitNewState(mpm_ctx);
368  tc = ctx->translate_table[pattern[p]];
369  ctx->goto_table[state][tc] = newstate;
370  state = newstate;
371  }
372 
373  /* Add this pattern id, to the output table of the last state, where the
374  * pattern ends in the trie */
375  SCACTileSetOutputState(state, pindex, mpm_ctx);
376 }
377 
378 /**
379  * \internal
380  * \brief Create the goto table.
381  *
382  * \param mpm_ctx Pointer to the mpm context.
383  */
384 static void SCACTileCreateGotoTable(MpmCtx *mpm_ctx)
385 {
386  SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
387  SCACTileCtx *ctx = search_ctx->init_ctx;
388 
389  uint32_t i = 0;
390 
391  /* add each pattern to create the goto table */
392  for (i = 0; i < mpm_ctx->pattern_cnt; i++) {
393  SCACTileEnter(ctx->parray[i]->ci, ctx->parray[i]->len,
394  i, mpm_ctx);
395  }
396 
397  int aa = 0;
398  for (aa = 0; aa < ctx->alphabet_size; aa++) {
399  if (ctx->goto_table[0][aa] == SC_AC_TILE_FAIL) {
400  ctx->goto_table[0][aa] = 0;
401  }
402  }
403 }
404 
405 static inline int SCACTileStateQueueIsEmpty(StateQueue *q)
406 {
407  if (q->top == q->bot)
408  return 1;
409  else
410  return 0;
411 }
412 
413 static inline void SCACTileEnqueue(StateQueue *q, int32_t state)
414 {
415  int i = 0;
416 
417  /*if we already have this */
418  for (i = q->bot; i < q->top; i++) {
419  if (q->store[i] == state)
420  return;
421  }
422 
423  q->store[q->top++] = state;
424 
426  q->top = 0;
427 
428  if (q->top == q->bot) {
429  SCLogCritical(SC_ERR_AHO_CORASICK, "Just ran out of space in the queue. "
430  "Fatal Error. Exiting. Please file a bug report on this");
431  exit(EXIT_FAILURE);
432  }
433 }
434 
435 static inline int32_t SCACTileDequeue(StateQueue *q)
436 {
438  q->bot = 0;
439 
440  if (q->bot == q->top) {
441  SCLogCritical(SC_ERR_AHO_CORASICK, "StateQueue behaving weirdly. "
442  "Fatal Error. Exiting. Please file a bug report on this");
443  exit(EXIT_FAILURE);
444  }
445 
446  return q->store[q->bot++];
447 }
448 
449 /**
450  * \internal
451  * \brief Club the output data from 2 states and store it in the 1st state.
452  * dst_state_data = {dst_state_data} UNION {src_state_data}
453  *
454  * \param dst_state First state(also the destination) for the union operation.
455  * \param src_state Second state for the union operation.
456  * \param mpm_ctx Pointer to the mpm context.
457  */
458 static void SCACTileClubOutputStates(int32_t dst_state,
459  int32_t src_state,
460  MpmCtx *mpm_ctx)
461 {
462  void *ptmp;
463  SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
464  SCACTileCtx *ctx = search_ctx->init_ctx;
465 
466  uint32_t i = 0;
467  uint32_t j = 0;
468 
469  SCACTileOutputTable *output_dst_state = &ctx->output_table[dst_state];
470  SCACTileOutputTable *output_src_state = &ctx->output_table[src_state];
471 
472  for (i = 0; i < output_src_state->no_of_entries; i++) {
473  for (j = 0; j < output_dst_state->no_of_entries; j++) {
474  if (output_src_state->patterns[i] == output_dst_state->patterns[j]) {
475  break;
476  }
477  }
478  if (j == output_dst_state->no_of_entries) {
479  output_dst_state->no_of_entries++;
480 
481  ptmp = SCRealloc(output_dst_state->patterns,
482  (output_dst_state->no_of_entries * sizeof(uint32_t)));
483  if (ptmp == NULL) {
484  SCFree(output_dst_state->patterns);
485  output_dst_state->patterns = NULL;
486  FatalError(SC_ERR_FATAL, "Error allocating memory");
487  }
488  output_dst_state->patterns = ptmp;
489 
490  output_dst_state->patterns[output_dst_state->no_of_entries - 1] =
491  output_src_state->patterns[i];
492  }
493  }
494 }
495 
496 /**
497  * \internal
498  * \brief Create the failure table.
499  *
500  * \param mpm_ctx Pointer to the mpm context.
501  */
502 static void SCACTileCreateFailureTable(MpmCtx *mpm_ctx)
503 {
504  SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
505  SCACTileCtx *ctx = search_ctx->init_ctx;
506 
507  int aa = 0;
508  int32_t state = 0;
509  int32_t r_state = 0;
510 
511  StateQueue q;
512  memset(&q, 0, sizeof(StateQueue));
513 
514  /* Allocate space for the failure table. A failure entry in the table for
515  * every state(SCACTileCtx->state_count) */
516  ctx->failure_table = SCMalloc(ctx->state_count * sizeof(int32_t));
517  if (ctx->failure_table == NULL) {
518  FatalError(SC_ERR_FATAL, "Error allocating memory");
519  }
520  memset(ctx->failure_table, 0, ctx->state_count * sizeof(int32_t));
521 
522  /* Add the failure transitions for the 0th state, and add every non-fail
523  * transition from the 0th state to the queue for further processing
524  * of failure states */
525  for (aa = 0; aa < ctx->alphabet_size; aa++) {
526  int32_t temp_state = ctx->goto_table[0][aa];
527  if (temp_state != 0) {
528  SCACTileEnqueue(&q, temp_state);
529  ctx->failure_table[temp_state] = 0;
530  }
531  }
532 
533  while (!SCACTileStateQueueIsEmpty(&q)) {
534  /* pick up every state from the queue and add failure transitions */
535  r_state = SCACTileDequeue(&q);
536  for (aa = 0; aa < ctx->alphabet_size; aa++) {
537  int32_t temp_state = ctx->goto_table[r_state][aa];
538  if (temp_state == SC_AC_TILE_FAIL)
539  continue;
540  SCACTileEnqueue(&q, temp_state);
541  state = ctx->failure_table[r_state];
542 
543  while(ctx->goto_table[state][aa] == SC_AC_TILE_FAIL)
544  state = ctx->failure_table[state];
545  ctx->failure_table[temp_state] = ctx->goto_table[state][aa];
546  SCACTileClubOutputStates(temp_state, ctx->failure_table[temp_state],
547  mpm_ctx);
548  }
549  }
550 }
551 
552 /*
553  * Set the next state for 1 byte next-state.
554  */
555 static void SCACTileSetState1Byte(SCACTileCtx *ctx, int state, int aa,
556  int next_state, int outputs)
557 {
558  uint8_t *state_table = (uint8_t*)ctx->state_table;
559  DEBUG_VALIDATE_BUG_ON(next_state < 0 || next_state > UINT8_MAX);
560  uint8_t encoded_next_state = (uint8_t)next_state;
561 
562  if (next_state == SC_AC_TILE_FAIL) {
563  FatalError(SC_ERR_FATAL, "Error FAIL state in output");
564  }
565 
566  if (outputs == 0)
567  encoded_next_state |= (1 << 7);
568 
569  state_table[state * ctx->alphabet_storage + aa] = encoded_next_state;
570 }
571 
572 /*
573  * Set the next state for 2 byte next-state.
574  */
575 static void SCACTileSetState2Bytes(SCACTileCtx *ctx, int state, int aa,
576  int next_state, int outputs)
577 {
578  uint16_t *state_table = (uint16_t*)ctx->state_table;
579  DEBUG_VALIDATE_BUG_ON(next_state < 0 || next_state > UINT16_MAX);
580  uint16_t encoded_next_state = (uint16_t)next_state;
581 
582  if (next_state == SC_AC_TILE_FAIL) {
583  FatalError(SC_ERR_FATAL, "Error FAIL state in output");
584  }
585 
586  if (outputs == 0)
587  encoded_next_state |= (1 << 15);
588 
589  state_table[state * ctx->alphabet_storage + aa] = encoded_next_state;
590 }
591 
592 /*
593  * Set the next state for 4 byte next-state.
594  */
595 static void SCACTileSetState4Bytes(SCACTileCtx *ctx, int state, int aa,
596  int next_state, int outputs)
597 {
598  uint32_t *state_table = (uint32_t*)ctx->state_table;
599  uint32_t encoded_next_state = next_state;
600 
601  if (next_state == SC_AC_TILE_FAIL) {
602  FatalError(SC_ERR_FATAL, "Error FAIL state in output");
603  }
604 
605  if (outputs == 0)
606  encoded_next_state |= (1UL << 31);
607 
608  state_table[state * ctx->alphabet_storage + aa] = encoded_next_state;
609 }
610 
611 /**
612  * \internal
613  * \brief Create the delta table.
614  *
615  * \param mpm_ctx Pointer to the mpm context.
616  */
617 static inline void SCACTileCreateDeltaTable(MpmCtx *mpm_ctx)
618 {
619  SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
620  SCACTileCtx *ctx = search_ctx->init_ctx;
621 
622  int aa = 0;
623  int32_t r_state = 0;
624 
625  if (ctx->state_count < 32767) {
626  if (ctx->state_count < 128) {
627  ctx->bytes_per_state = 1;
628  ctx->SetNextState = SCACTileSetState1Byte;
629 
630  switch(ctx->alphabet_storage) {
631  case 8:
633  break;
634  case 16:
636  break;
637  case 32:
639  break;
640  case 64:
642  break;
643  case 128:
645  break;
646  default:
648  }
649  } else {
650  /* 16-bit state needed */
651  ctx->bytes_per_state = 2;
652  ctx->SetNextState = SCACTileSetState2Bytes;
653 
654  switch(ctx->alphabet_storage) {
655  case 8:
657  break;
658  case 16:
660  break;
661  case 32:
663  break;
664  case 64:
666  break;
667  case 128:
669  break;
670  default:
672  }
673  }
674  } else {
675  /* 32-bit next state */
677  ctx->bytes_per_state = 4;
678  ctx->SetNextState = SCACTileSetState4Bytes;
679 
680  ctx->alphabet_storage = 256; /* Change? */
681  }
682 
683  StateQueue q;
684  memset(&q, 0, sizeof(StateQueue));
685 
686  for (aa = 0; aa < ctx->alphabet_size; aa++) {
687  int temp_state = ctx->goto_table[0][aa];
688  if (temp_state != 0)
689  SCACTileEnqueue(&q, temp_state);
690  }
691 
692  while (!SCACTileStateQueueIsEmpty(&q)) {
693  r_state = SCACTileDequeue(&q);
694 
695  for (aa = 0; aa < ctx->alphabet_size; aa++) {
696  int temp_state = ctx->goto_table[r_state][aa];
697  if (temp_state != SC_AC_TILE_FAIL) {
698  SCACTileEnqueue(&q, temp_state);
699  } else {
700  int f_state = ctx->failure_table[r_state];
701  ctx->goto_table[r_state][aa] = ctx->goto_table[f_state][aa];
702  }
703  }
704  }
705 }
706 
707 static void SCACTileClubOutputStatePresenceWithDeltaTable(MpmCtx *mpm_ctx)
708 {
709  SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
710  SCACTileCtx *ctx = search_ctx->init_ctx;
711 
712  int aa = 0;
713  uint32_t state = 0;
714 
715  /* Allocate next-state table. */
716  int size = ctx->state_count * ctx->bytes_per_state * ctx->alphabet_storage;
717  void *state_table = SCMalloc(size);
718  if (unlikely(state_table == NULL)) {
719  FatalError(SC_ERR_FATAL, "Error allocating memory");
720  }
721  memset(state_table, 0, size);
722  ctx->state_table = state_table;
723 
724  mpm_ctx->memory_cnt++;
725  mpm_ctx->memory_size += size;
726 
727  SCLogDebug("Delta Table size %d, alphabet: %d, %d-byte states: %d",
728  size, ctx->alphabet_size, ctx->bytes_per_state, ctx->state_count);
729 
730  /* Copy next state from Goto table, which is 32 bits and encode it into the next
731  * state table, which can be 1, 2 or 4 bytes each and include if there is an
732  * output.
733  */
734  for (state = 0; state < ctx->state_count; state++) {
735  for (aa = 0; aa < ctx->alphabet_size; aa++) {
736  int next_state = ctx->goto_table[state][aa];
737  int next_state_outputs = ctx->output_table[next_state].no_of_entries;
738  ctx->SetNextState(ctx, state, aa, next_state, next_state_outputs);
739  }
740  }
741 }
742 
743 static inline void SCACTileInsertCaseSensitiveEntriesForPatterns(MpmCtx *mpm_ctx)
744 {
745  SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
746  SCACTileCtx *ctx = search_ctx->init_ctx;
747 
748  uint32_t state = 0;
749  uint32_t k = 0;
750 
751  for (state = 0; state < ctx->state_count; state++) {
752  if (ctx->output_table[state].no_of_entries == 0)
753  continue;
754 
755  for (k = 0; k < ctx->output_table[state].no_of_entries; k++) {
756  if (ctx->pattern_list[ctx->output_table[state].patterns[k]].cs != NULL) {
757  /* TODO - Find better way to store this. */
758  ctx->output_table[state].patterns[k] &= 0x0FFFFFFF;
759  ctx->output_table[state].patterns[k] |= (uint32_t)1 << 31;
760  }
761  }
762  }
763 }
764 
765 #if 0
766 static void SCACTilePrintDeltaTable(MpmCtx *mpm_ctx)
767 {
768  SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
769  SCACTileCtx *ctx = search_ctx->init_ctx;
770 
771  int i = 0, j = 0;
772 
773  printf("##############Delta Table##############\n");
774  for (i = 0; i < ctx->state_count; i++) {
775  printf("%d: \n", i);
776  for (j = 0; j < ctx->alphabet_size; j++) {
777  if (SCACTileGetDelta(i, j, mpm_ctx) != 0) {
778  printf(" %c -> %d\n", j, SCACTileGetDelta(i, j, mpm_ctx));
779  }
780  }
781  }
782 }
783 #endif
784 
785 /**
786  * \brief Process the patterns and prepare the state table.
787  *
788  * \param mpm_ctx Pointer to the mpm context.
789  */
790 static void SCACTilePrepareStateTable(MpmCtx *mpm_ctx)
791 {
792  SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
793  SCACTileCtx *ctx = search_ctx->init_ctx;
794 
795  /* Create Alphabet compression and Lower Case translation table. */
796  SCACTileInitTranslateTable(ctx);
797 
798  /* create the 0th state in the goto table and output_table */
799  SCACTileInitNewState(mpm_ctx);
800 
801  /* create the goto table */
802  SCACTileCreateGotoTable(mpm_ctx);
803  /* create the failure table */
804  SCACTileCreateFailureTable(mpm_ctx);
805  /* create the final state(delta) table */
806  SCACTileCreateDeltaTable(mpm_ctx);
807  /* club the output state presence with delta transition entries */
808  SCACTileClubOutputStatePresenceWithDeltaTable(mpm_ctx);
809 
810  /* club nocase entries */
811  SCACTileInsertCaseSensitiveEntriesForPatterns(mpm_ctx);
812 
813 #if 0
814  SCACTilePrintDeltaTable(mpm_ctx);
815 #endif
816 
817  /* we don't need these anymore */
818  SCFree(ctx->goto_table);
819  ctx->goto_table = NULL;
820  SCFree(ctx->failure_table);
821  ctx->failure_table = NULL;
822 }
823 
824 
825 /**
826  * \brief Process Internal AC MPM tables to create the Search Context
827  *
828  * The search context is only the data needed to search the MPM.
829  *
830  * \param mpm_ctx Pointer to the mpm context.
831  */
832 static void SCACTilePrepareSearch(MpmCtx *mpm_ctx)
833 {
834  SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
835  SCACTileCtx *ctx = search_ctx->init_ctx;
836 
837  /* Resize the output table to be only as big as its final size. */
838  SCACTileReallocOutputTable(ctx, ctx->state_count);
839 
840  search_ctx->Search = ctx->Search;
841  memcpy(search_ctx->translate_table, ctx->translate_table, sizeof(ctx->translate_table));
842 
843  /* Move the state table from the Init context */
844  search_ctx->state_table = ctx->state_table;
845  ctx->state_table = NULL; /* So that it won't get freed twice. */
846 
847  /* Move the output_table from the Init context to the Search Context */
848  /* TODO: Could be made more compact */
849  search_ctx->output_table = ctx->output_table;
850  ctx->output_table = NULL;
851  search_ctx->state_count = ctx->state_count;
852 
853  search_ctx->pattern_list = ctx->pattern_list;
854  ctx->pattern_list = NULL;
855  search_ctx->pattern_cnt = mpm_ctx->pattern_cnt;
856 
857  /* One bit per pattern, rounded up to the next byte size. */
858  search_ctx->mpm_bitarray_size = (mpm_ctx->pattern_cnt + 7) / 8;
859 
860  /* Can now free the Initialization data */
861  SCACTileDestroyInitCtx(mpm_ctx);
862 }
863 
864 /**
865  * \brief Process the patterns added to the mpm, and create the internal tables.
866  *
867  * \param mpm_ctx Pointer to the mpm context.
868  */
870 {
871  SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
872 
873  if (mpm_ctx->pattern_cnt == 0 || search_ctx->init_ctx == NULL) {
874  SCLogDebug("no patterns supplied to this mpm_ctx");
875  return 0;
876  }
877  SCACTileCtx *ctx = search_ctx->init_ctx;
878  if (mpm_ctx->init_hash == NULL) {
879  SCLogDebug("no patterns supplied to this mpm_ctx");
880  return 0;
881  }
882 
883  /* alloc the pattern array */
884  ctx->parray = (MpmPattern **)SCMalloc(mpm_ctx->pattern_cnt *
885  sizeof(MpmPattern *));
886  if (ctx->parray == NULL)
887  goto error;
888  memset(ctx->parray, 0, mpm_ctx->pattern_cnt * sizeof(MpmPattern *));
889 
890  /* populate it with the patterns in the hash */
891  uint32_t i = 0, p = 0;
892  for (i = 0; i < MPM_INIT_HASH_SIZE; i++) {
893  MpmPattern *node = mpm_ctx->init_hash[i], *nnode = NULL;
894  while(node != NULL) {
895  nnode = node->next;
896  node->next = NULL;
897  ctx->parray[p++] = node;
898  SCACTileHistogramAlphabet(ctx, node);
899  node = nnode;
900  }
901  }
902 
903  /* we no longer need the hash, so free it's memory */
904  SCFree(mpm_ctx->init_hash);
905  mpm_ctx->init_hash = NULL;
906 
907  /* Handle case patterns by storing a copy of the pattern to compare
908  * to each possible match (no-case).
909  *
910  * Allocate the memory for the array and each of the strings as one block.
911  */
912  size_t string_space_needed = 0;
913  for (i = 0; i < mpm_ctx->pattern_cnt; i++) {
914  if (!(ctx->parray[i]->flags & MPM_PATTERN_FLAG_NOCASE)) {
915  /* Round up to next 8 byte aligned length */
916  uint32_t space = ((ctx->parray[i]->len + 7) / 8) * 8;
917  string_space_needed += space;
918  }
919  }
920 
921  size_t pattern_list_size = mpm_ctx->pattern_cnt * sizeof(SCACTilePatternList);
922  size_t mem_size = string_space_needed + pattern_list_size;
923  void *mem_block = SCCalloc(1, mem_size);
924  if (mem_block == NULL) {
925  FatalError(SC_ERR_FATAL, "Error allocating memory");
926  }
927  mpm_ctx->memory_cnt++;
928  mpm_ctx->memory_size += mem_size;
929  /* Split the allocated block into pattern list array and string space. */
930  ctx->pattern_list = mem_block;
931  uint8_t *string_space = mem_block + pattern_list_size;
932 
933  /* Now make the copies of the no-case strings. */
934  for (i = 0; i < mpm_ctx->pattern_cnt; i++) {
935  if (!(ctx->parray[i]->flags & MPM_PATTERN_FLAG_NOCASE)) {
936  uint16_t len = ctx->parray[i]->len;
937  uint32_t space = ((len + 7) / 8) * 8;
938  memcpy(string_space, ctx->parray[i]->original_pat, len);
939  ctx->pattern_list[i].cs = string_space;
940  ctx->pattern_list[i].patlen = len;
941  string_space += space;
942  }
943  ctx->pattern_list[i].offset = ctx->parray[i]->offset;
944  ctx->pattern_list[i].depth = ctx->parray[i]->depth;
945  ctx->pattern_list[i].pid = ctx->parray[i]->id;
946 
947  /* ACPatternList now owns this memory */
948  ctx->pattern_list[i].sids_size = ctx->parray[i]->sids_size;
949  ctx->pattern_list[i].sids = ctx->parray[i]->sids;
950  ctx->parray[i]->sids = NULL;
951  ctx->parray[i]->sids_size = 0;
952  }
953 
954  /* prepare the state table required by AC */
955  SCACTilePrepareStateTable(mpm_ctx);
956 
957  /* Convert to the Search Context structure */
958  SCACTilePrepareSearch(mpm_ctx);
959 
960  return 0;
961 
962 error:
963  return -1;
964 }
965 
966 /**
967  * \brief Init the mpm thread context.
968  *
969  * \param mpm_ctx Pointer to the mpm context.
970  * \param mpm_thread_ctx Pointer to the mpm thread context.
971  */
972 void SCACTileInitThreadCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx)
973 {
974  memset(mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
975 
976  mpm_thread_ctx->ctx = SCMalloc(sizeof(SCACTileThreadCtx));
977  if (mpm_thread_ctx->ctx == NULL) {
978  exit(EXIT_FAILURE);
979  }
980  memset(mpm_thread_ctx->ctx, 0, sizeof(SCACTileThreadCtx));
981  mpm_thread_ctx->memory_cnt++;
982  mpm_thread_ctx->memory_size += sizeof(SCACTileThreadCtx);
983 }
984 
985 /**
986  * \brief Initialize the AC context.
987  *
988  * \param mpm_ctx Mpm context.
989  */
990 void SCACTileInitCtx(MpmCtx *mpm_ctx)
991 {
992  if (mpm_ctx->ctx != NULL)
993  return;
994 
995  /* Search Context */
996  mpm_ctx->ctx = SCMalloc(sizeof(SCACTileSearchCtx));
997  if (mpm_ctx->ctx == NULL) {
998  exit(EXIT_FAILURE);
999  }
1000  memset(mpm_ctx->ctx, 0, sizeof(SCACTileSearchCtx));
1001 
1002  mpm_ctx->memory_cnt++;
1003  mpm_ctx->memory_size += sizeof(SCACTileSearchCtx);
1004 
1005  SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
1006 
1007  /* MPM Creation context */
1008  search_ctx->init_ctx = SCMalloc(sizeof(SCACTileCtx));
1009  if (search_ctx->init_ctx == NULL) {
1010  exit(EXIT_FAILURE);
1011  }
1012  memset(search_ctx->init_ctx, 0, sizeof(SCACTileCtx));
1013 
1014  mpm_ctx->memory_cnt++;
1015  mpm_ctx->memory_size += sizeof(SCACTileCtx);
1016 
1017  /* initialize the hash we use to speed up pattern insertions */
1018  mpm_ctx->init_hash = SCMalloc(sizeof(MpmPattern *) * MPM_INIT_HASH_SIZE);
1019  if (mpm_ctx->init_hash == NULL) {
1020  exit(EXIT_FAILURE);
1021  }
1022  memset(mpm_ctx->init_hash, 0, sizeof(MpmPattern *) * MPM_INIT_HASH_SIZE);
1023 
1024  /* get conf values for AC from our yaml file. We have no conf values for
1025  * now. We will certainly need this, as we develop the algo */
1026  SCACTileGetConfig();
1027 }
1028 
1029 /**
1030  * \brief Destroy the mpm thread context.
1031  *
1032  * \param mpm_ctx Pointer to the mpm context.
1033  * \param mpm_thread_ctx Pointer to the mpm thread context.
1034  */
1035 void SCACTileDestroyThreadCtx(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx)
1036 {
1037  SCACTilePrintSearchStats(mpm_thread_ctx);
1038 
1039  if (mpm_thread_ctx->ctx != NULL) {
1040  SCFree(mpm_thread_ctx->ctx);
1041  mpm_thread_ctx->ctx = NULL;
1042  mpm_thread_ctx->memory_cnt--;
1043  mpm_thread_ctx->memory_size -= sizeof(SCACTileThreadCtx);
1044  }
1045 }
1046 
1047 static void SCACTileDestroyInitCtx(MpmCtx *mpm_ctx)
1048 {
1049  SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
1050  SCACTileCtx *ctx = search_ctx->init_ctx;
1051 
1052  if (ctx == NULL)
1053  return;
1054 
1055  if (mpm_ctx->init_hash != NULL) {
1056  SCFree(mpm_ctx->init_hash);
1057  mpm_ctx->init_hash = NULL;
1058  }
1059 
1060  if (ctx->parray != NULL) {
1061  uint32_t i;
1062  for (i = 0; i < mpm_ctx->pattern_cnt; i++) {
1063  if (ctx->parray[i] != NULL) {
1064  MpmFreePattern(mpm_ctx, ctx->parray[i]);
1065  }
1066  }
1067 
1068  SCFree(ctx->parray);
1069  ctx->parray = NULL;
1070  }
1071 
1072  if (ctx->state_table != NULL) {
1073  SCFree(ctx->state_table);
1074 
1075  mpm_ctx->memory_cnt--;
1076  mpm_ctx->memory_size -= (ctx->state_count *
1077  ctx->bytes_per_state * ctx->alphabet_storage);
1078  }
1079 
1080  if (ctx->output_table != NULL) {
1081  uint32_t state;
1082  for (state = 0; state < ctx->state_count; state++) {
1083  if (ctx->output_table[state].patterns != NULL) {
1084  SCFree(ctx->output_table[state].patterns);
1085  }
1086  }
1087  SCFree(ctx->output_table);
1088  }
1089 
1090  if (ctx->pattern_list != NULL) {
1091  uint32_t i;
1092  for (i = 0; i < mpm_ctx->pattern_cnt; i++) {
1093  if (ctx->pattern_list[i].cs != NULL)
1094  SCFree(ctx->pattern_list[i].cs);
1095  if (ctx->pattern_list[i].sids != NULL)
1096  SCFree(ctx->pattern_list[i].sids);
1097  }
1098  SCFree(ctx->pattern_list);
1099  }
1100 
1101  SCFree(ctx);
1102  search_ctx->init_ctx = NULL;
1103  mpm_ctx->memory_cnt--;
1104  mpm_ctx->memory_size -= sizeof(SCACTileCtx);
1105 }
1106 
1107 /**
1108  * \brief Destroy the mpm context.
1109  *
1110  * \param mpm_ctx Pointer to the mpm context.
1111  */
1113 {
1114  SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
1115  if (search_ctx == NULL)
1116  return;
1117 
1118  /* Destroy Initialization data */
1119  SCACTileDestroyInitCtx(mpm_ctx);
1120 
1121  /* Free Search tables */
1122  SCFree(search_ctx->state_table);
1123 
1124  if (search_ctx->pattern_list != NULL) {
1125  uint32_t i;
1126  for (i = 0; i < search_ctx->pattern_cnt; i++) {
1127  if (search_ctx->pattern_list[i].sids != NULL)
1128  SCFree(search_ctx->pattern_list[i].sids);
1129  }
1130  SCFree(search_ctx->pattern_list);
1131  }
1132 
1133  if (search_ctx->output_table != NULL) {
1134  uint32_t state;
1135  for (state = 0; state < search_ctx->state_count; state++) {
1136  if (search_ctx->output_table[state].patterns != NULL) {
1137  SCFree(search_ctx->output_table[state].patterns);
1138  }
1139  }
1140  SCFree(search_ctx->output_table);
1141  }
1142 
1143  SCFree(search_ctx);
1144  mpm_ctx->ctx = NULL;
1145 
1146  mpm_ctx->memory_cnt--;
1147  mpm_ctx->memory_size -= sizeof(SCACTileSearchCtx);
1148 }
1149 
1150 /*
1151  * Heavily optimized pattern matching routine for TILE-Gx.
1152  */
1153 
1154 #define SCHECK(x) ((x) > 0)
1155 #define BUF_TYPE int32_t
1156 // Extract byte N=0,1,2,3 from x
1157 #define BYTE0(x) (((x) & 0x000000ff) >> 0)
1158 #define BYTE1(x) (((x) & 0x0000ff00) >> 8)
1159 #define BYTE2(x) (((x) & 0x00ff0000) >> 16)
1160 #define BYTE3(x) (((x) & 0xff000000) >> 24)
1161 #define EXTRA 4 // need 4 extra bytes to avoid OOB reads
1163 static int CheckMatch(const SCACTileSearchCtx *ctx, PrefilterRuleStore *pmq,
1164  const uint8_t *buf, uint32_t buflen,
1165  uint16_t state, int i, int matches,
1166  uint8_t *mpm_bitarray)
1167 {
1168  const SCACTilePatternList *pattern_list = ctx->pattern_list;
1169  const uint8_t *buf_offset = buf + i + 1; // Lift out of loop
1170  uint32_t no_of_entries = ctx->output_table[state].no_of_entries;
1171  MpmPatternIndex *patterns = ctx->output_table[state].patterns;
1172  uint32_t k;
1173 
1174  for (k = 0; k < no_of_entries; k++) {
1175  MpmPatternIndex pindex = patterns[k] & 0x0FFFFFFF;
1176  if (mpm_bitarray[pindex / 8] & (1 << (pindex % 8))) {
1177  /* Pattern already seen by this MPM. */
1178  /* NOTE: This is faster then rechecking if it is a case-sensitive match
1179  * since we know this pattern has already been seen, but imcrementing
1180  * matches here could over report matches. For example if the case-sensitive
1181  * pattern is "Foo" and the string is "Foo bar foo", matches would be reported
1182  * as 2, when it should really be 1, since "foo" is not a true match.
1183  */
1184  matches++;
1185  continue;
1186  }
1187  const SCACTilePatternList *pat = &pattern_list[pindex];
1188  const int offset = i - pat->patlen + 1;
1189  if (offset < (int)pat->offset || (pat->depth && i > pat->depth))
1190  continue;
1191 
1192  /* Double check case-sensitve match now. */
1193  if (patterns[k] >> 31) {
1194  const uint16_t patlen = pat->patlen;
1195  if (SCMemcmp(pat->cs, buf_offset - patlen, patlen) != 0) {
1196  /* Case-sensitive match failed. */
1197  continue;
1198  }
1199  }
1200  /* New match found */
1201  mpm_bitarray[pindex / 8] |= (1 << (pindex % 8));
1202 
1203  /* Always add the Signature IDs, since they could be different in the current MPM
1204  * than in a previous MPM on the same PMQ when finding the same pattern.
1205  */
1206  PrefilterAddSids(pmq, pattern_list[pindex].sids,
1207  pattern_list[pindex].sids_size);
1208  matches++;
1209  }
1210 
1211  return matches;
1212 }
1213 
1214 /**
1215  * \brief The aho corasick search function.
1216  *
1217  * \param mpm_ctx Pointer to the mpm context.
1218  * \param mpm_thread_ctx Pointer to the mpm thread context.
1219  * \param pmq Pointer to the Pattern Matcher Queue to hold
1220  * search matches.
1221  * \param buf Buffer to be searched.
1222  * \param buflen Buffer length.
1223  *
1224  * \retval matches Match count.
1225  */
1226 uint32_t SCACTileSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx,
1227  PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen)
1228 {
1229  const SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
1230 
1231  if (buflen == 0)
1232  return 0;
1233 
1234  /* Context specific matching function. */
1235  return search_ctx->Search(search_ctx, mpm_thread_ctx, pmq, buf, buflen);
1236 }
1237 
1238 /* This function handles (ctx->state_count >= 32767) */
1239 uint32_t SCACTileSearchLarge(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
1240  PrefilterRuleStore *pmq,
1241  const uint8_t *buf, uint32_t buflen)
1242 {
1243  uint32_t i = 0;
1244  int matches = 0;
1245 
1246  uint8_t mpm_bitarray[ctx->mpm_bitarray_size];
1247  memset(mpm_bitarray, 0, ctx->mpm_bitarray_size);
1248 
1249  const uint8_t* restrict xlate = ctx->translate_table;
1250  register int state = 0;
1251  int32_t (*state_table_u32)[256] = ctx->state_table;
1252  for (i = 0; i < buflen; i++) {
1253  state = state_table_u32[state & 0x00FFFFFF][xlate[buf[i]]];
1254  if (SCHECK(state)) {
1255  DEBUG_VALIDATE_BUG_ON(state < 0 || state > UINT16_MAX);
1256  matches = CheckMatch(ctx, pmq, buf, buflen, (uint16_t)state, i, matches, mpm_bitarray);
1257  }
1258  } /* for (i = 0; i < buflen; i++) */
1259 
1260  return matches;
1261 }
1262 
1263 /*
1264  * Search with Alphabet size of 256 and 16-bit next-state entries.
1265  * Next state entry has MSB as "match" and 15 LSB bits as next-state index.
1266  */
1267 // y = 1<<log_mult * (x & (1<<width -1))
1268 #define SINDEX_INTERNAL(y, x, log_mult, width) \
1269  ((1<<log_mult) * (x & ((1<<width) - 1)))
1270 
1271 /* Type of next_state */
1272 #define STYPE int16_t
1273 #define SLOAD(x) *(STYPE * restrict)(x)
1275 #define FUNC_NAME SCACTileSearchSmall256
1276 // y = 256 * (x & 0x7FFF)
1277 #define SINDEX(y,x) SINDEX_INTERNAL(y, x, 8, 15)
1278 #include "util-mpm-ac-ks-small.c"
1279 
1280 /* Search with Alphabet size of 128 */
1281 #undef FUNC_NAME
1282 #undef SINDEX
1283 #define FUNC_NAME SCACTileSearchSmall128
1284 // y = 128 * (x & 0x7FFF)
1285 #define SINDEX(y,x) SINDEX_INTERNAL(y, x, 7, 15)
1286 #include "util-mpm-ac-ks-small.c"
1287 
1288 /* Search with Alphabet size of 64 */
1289 #undef FUNC_NAME
1290 #undef SINDEX
1291 #define FUNC_NAME SCACTileSearchSmall64
1292 // y = 64 * (x & 0x7FFF)
1293 #define SINDEX(y,x) SINDEX_INTERNAL(y, x, 6, 15)
1294 #include "util-mpm-ac-ks-small.c"
1295 
1296 /* Search with Alphabet size of 32 */
1297 #undef FUNC_NAME
1298 #undef SINDEX
1299 #define FUNC_NAME SCACTileSearchSmall32
1300 // y = 32 * (x & 0x7FFF)
1301 #define SINDEX(y,x) SINDEX_INTERNAL(y, x, 5, 15)
1302 #include "util-mpm-ac-ks-small.c"
1303 
1304 /* Search with Alphabet size of 16 */
1305 #undef FUNC_NAME
1306 #undef SINDEX
1307 #define FUNC_NAME SCACTileSearchSmall16
1308 // y = 16 * (x & 0x7FFF)
1309 #define SINDEX(y,x) SINDEX_INTERNAL(y, x, 4, 15)
1310 #include "util-mpm-ac-ks-small.c"
1311 
1312 /* Search with Alphabet size of 8 */
1313 #undef FUNC_NAME
1314 #undef SINDEX
1315 #define FUNC_NAME SCACTileSearchSmall8
1316 // y = 8 * (x & 0x7FFF)
1317 #define SINDEX(y,x) SINDEX_INTERNAL(y, x, 3, 15)
1318 #include "util-mpm-ac-ks-small.c"
1319 
1320 /*
1321  * Search with Alphabet size of 256 and 8-bit next-state entries.
1322  * Next state entry has MSB as "match" and 15 LSB bits as next-state index.
1323  */
1324 #undef STYPE
1325 #define STYPE int8_t
1327 #undef FUNC_NAME
1328 #undef SINDEX
1329 #define FUNC_NAME SCACTileSearchTiny256
1330 // y = 256 * (x & 0x7F)
1331 #define SINDEX(y,x) SINDEX_INTERNAL(y, x, 8, 7)
1332 #include "util-mpm-ac-ks-small.c"
1333 
1334 /* Search with Alphabet size of 128 */
1335 #undef FUNC_NAME
1336 #undef SINDEX
1337 #define FUNC_NAME SCACTileSearchTiny128
1338 // y = 128 * (x & 0x7F)
1339 #define SINDEX(y,x) SINDEX_INTERNAL(y, x, 7, 7)
1340 #include "util-mpm-ac-ks-small.c"
1341 
1342 /* Search with Alphabet size of 64 */
1343 #undef FUNC_NAME
1344 #undef SINDEX
1345 #define FUNC_NAME SCACTileSearchTiny64
1346 // y = 64 * (x & 0x7F)
1347 #define SINDEX(y,x) SINDEX_INTERNAL(y, x, 6, 7)
1348 #include "util-mpm-ac-ks-small.c"
1349 
1350 /* Search with Alphabet size of 32 */
1351 #undef FUNC_NAME
1352 #undef SINDEX
1353 #define FUNC_NAME SCACTileSearchTiny32
1354 // y = 32 * (x & 0x7F)
1355 #define SINDEX(y,x) SINDEX_INTERNAL(y, x, 5, 7)
1356 #include "util-mpm-ac-ks-small.c"
1357 
1358 /* Search with Alphabet size of 16 */
1359 #undef FUNC_NAME
1360 #undef SINDEX
1361 #define FUNC_NAME SCACTileSearchTiny16
1362 // y = 16 * (x & 0x7F)
1363 #define SINDEX(y,x) SINDEX_INTERNAL(y, x, 4, 7)
1364 #include "util-mpm-ac-ks-small.c"
1365 
1366 /* Search with Alphabet size of 8 */
1367 #undef FUNC_NAME
1368 #undef SINDEX
1369 #define FUNC_NAME SCACTileSearchTiny8
1370 // y = 8 * (x & 0x7F)
1371 #define SINDEX(y,x) SINDEX_INTERNAL(y, x, 3, 7)
1373 
1374 
1375 /**
1376  * \brief Add a case insensitive pattern. Although we have different calls for
1377  * adding case sensitive and insensitive patterns, we make a single call
1378  * for either case. No special treatment for either case.
1379  *
1380  * \param mpm_ctx Pointer to the mpm context.
1381  * \param pat The pattern to add.
1382  * \param patnen The pattern length.
1383  * \param offset Ignored.
1384  * \param depth Ignored.
1385  * \param pid The pattern id.
1386  * \param sid Ignored.
1387  * \param flags Flags associated with this pattern.
1388  *
1389  * \retval 0 On success.
1390  * \retval -1 On failure.
1391  */
1392 int SCACTileAddPatternCI(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
1393  uint16_t offset, uint16_t depth, uint32_t pid,
1394  SigIntId sid, uint8_t flags)
1395 {
1397  return MpmAddPattern(mpm_ctx, pat, patlen, offset, depth,
1398  pid, sid, flags);
1399 }
1400 
1401 /**
1402  * \brief Add a case sensitive pattern. Although we have different calls for
1403  * adding case sensitive and insensitive patterns, we make a single call
1404  * for either case. No special treatment for either case.
1405  *
1406  * \param mpm_ctx Pointer to the mpm context.
1407  * \param pat The pattern to add.
1408  * \param patnen The pattern length.
1409  * \param offset Ignored.
1410  * \param depth Ignored.
1411  * \param pid The pattern id.
1412  * \param sid Ignored.
1413  * \param flags Flags associated with this pattern.
1414  *
1415  * \retval 0 On success.
1416  * \retval -1 On failure.
1417  */
1418 int SCACTileAddPatternCS(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
1419  uint16_t offset, uint16_t depth, uint32_t pid,
1420  SigIntId sid, uint8_t flags)
1421 {
1422  return MpmAddPattern(mpm_ctx, pat, patlen, offset, depth,
1423  pid, sid, flags);
1424 }
1425 
1427 {
1428 #ifdef SC_AC_TILE_COUNTERS
1429  SCACTileThreadCtx *ctx = (SCACTileThreadCtx *)mpm_thread_ctx->ctx;
1430  printf("AC Thread Search stats (ctx %p)\n", ctx);
1431  printf("Total calls: %" PRIu32 "\n", ctx->total_calls);
1432  printf("Total matches: %" PRIu64 "\n", ctx->total_matches);
1433 #endif /* SC_AC_TILE_COUNTERS */
1434 }
1435 
1437 {
1438  SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
1439  SCACTileCtx *ctx = search_ctx->init_ctx;
1440 
1441  printf("MPM AC Information:\n");
1442  printf("Memory allocs: %" PRIu32 "\n", mpm_ctx->memory_cnt);
1443  printf("Memory alloced: %" PRIu32 "\n", mpm_ctx->memory_size);
1444  printf(" Sizeof:\n");
1445  printf(" MpmCtx %" PRIuMAX "\n", (uintmax_t)sizeof(MpmCtx));
1446  printf(" SCACTileCtx: %" PRIuMAX "\n", (uintmax_t)sizeof(SCACTileCtx));
1447  printf(" MpmPattern %" PRIuMAX "\n", (uintmax_t)sizeof(MpmPattern));
1448  printf(" MpmPattern %" PRIuMAX "\n", (uintmax_t)sizeof(MpmPattern));
1449  printf("Unique Patterns: %" PRIu32 "\n", mpm_ctx->pattern_cnt);
1450  printf("Smallest: %" PRIu32 "\n", mpm_ctx->minlen);
1451  printf("Largest: %" PRIu32 "\n", mpm_ctx->maxlen);
1452  printf("Total states in the state table: %u\n", ctx->state_count);
1453  printf("\n");
1454 }
1455 
1456 /************************** Mpm Registration ***************************/
1457 
1458 /**
1459  * \brief Register the aho-corasick mpm 'ks' originally developed by
1460  * Ken Steele for Tilera Tile-Gx processor.
1461  */
1463 {
1464  mpm_table[MPM_AC_KS].name = "ac-ks";
1476 }
1477 
1478 
1479 /*************************************Unittests********************************/
1480 
1481 #ifdef UNITTESTS
1482 
1483 static int SCACTileTest01(void)
1484 {
1485  int result = 0;
1486  MpmCtx mpm_ctx;
1487  MpmThreadCtx mpm_thread_ctx;
1488  PrefilterRuleStore pmq;
1489 
1490  memset(&mpm_ctx, 0, sizeof(MpmCtx));
1491  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
1492  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
1493  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1494 
1495  /* 1 match */
1496  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0);
1497  PmqSetup(&pmq);
1498 
1499  SCACTilePreparePatterns(&mpm_ctx);
1500 
1501  const char *buf = "abcdefghjiklmnopqrstuvwxyz";
1502 
1503  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
1504  (uint8_t *)buf, strlen(buf));
1505 
1506  if (cnt == 1)
1507  result = 1;
1508  else
1509  printf("1 != %" PRIu32 " ",cnt);
1510 
1511  SCACTileDestroyCtx(&mpm_ctx);
1512  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1513  PmqFree(&pmq);
1514  return result;
1515 }
1516 
1517 static int SCACTileTest02(void)
1518 {
1519  int result = 0;
1520  MpmCtx mpm_ctx;
1521  MpmThreadCtx mpm_thread_ctx;
1522  PrefilterRuleStore pmq;
1523 
1524  memset(&mpm_ctx, 0, sizeof(MpmCtx));
1525  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
1526  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
1527  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1528 
1529  /* 1 match */
1530  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abce", 4, 0, 0, 0, 0, 0);
1531  PmqSetup(&pmq);
1532 
1533  SCACTilePreparePatterns(&mpm_ctx);
1534 
1535  const char *buf = "abcdefghjiklmnopqrstuvwxyz";
1536  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
1537  (uint8_t *)buf, strlen(buf));
1538 
1539  if (cnt == 0)
1540  result = 1;
1541  else
1542  printf("0 != %" PRIu32 " ",cnt);
1543 
1544  SCACTileDestroyCtx(&mpm_ctx);
1545  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1546  PmqFree(&pmq);
1547  return result;
1548 }
1549 
1550 static int SCACTileTest03(void)
1551 {
1552  int result = 0;
1553  MpmCtx mpm_ctx;
1554  MpmThreadCtx mpm_thread_ctx;
1555  PrefilterRuleStore pmq;
1556 
1557  memset(&mpm_ctx, 0x00, sizeof(MpmCtx));
1558  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
1559  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
1560  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1561 
1562  /* 1 match */
1563  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0);
1564  /* 1 match */
1565  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcde", 4, 0, 0, 1, 0, 0);
1566  /* 1 match */
1567  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"fghj", 4, 0, 0, 2, 0, 0);
1568  PmqSetup(&pmq);
1569 
1570  SCACTilePreparePatterns(&mpm_ctx);
1571 
1572  const char *buf = "abcdefghjiklmnopqrstuvwxyz";
1573  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
1574  (uint8_t *)buf, strlen(buf));
1575 
1576  if (cnt == 3)
1577  result = 1;
1578  else
1579  printf("3 != %" PRIu32 " ",cnt);
1580 
1581  SCACTileDestroyCtx(&mpm_ctx);
1582  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1583  PmqFree(&pmq);
1584  return result;
1585 }
1586 
1587 static int SCACTileTest04(void)
1588 {
1589  int result = 0;
1590  MpmCtx mpm_ctx;
1591  MpmThreadCtx mpm_thread_ctx;
1592  PrefilterRuleStore pmq;
1593 
1594  memset(&mpm_ctx, 0, sizeof(MpmCtx));
1595  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
1596  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
1597  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1598 
1599  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0);
1600  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"bcdegh", 6, 0, 0, 1, 0, 0);
1601  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"fghjxyz", 7, 0, 0, 2, 0, 0);
1602  PmqSetup(&pmq);
1603 
1604  SCACTilePreparePatterns(&mpm_ctx);
1605 
1606  const char *buf = "abcdefghjiklmnopqrstuvwxyz";
1607  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
1608  (uint8_t *)buf, strlen(buf));
1609 
1610  if (cnt == 1)
1611  result = 1;
1612  else
1613  printf("1 != %" PRIu32 " ",cnt);
1614 
1615  SCACTileDestroyCtx(&mpm_ctx);
1616  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1617  PmqFree(&pmq);
1618  return result;
1619 }
1620 
1621 static int SCACTileTest05(void)
1622 {
1623  int result = 0;
1624  MpmCtx mpm_ctx;
1625  MpmThreadCtx mpm_thread_ctx;
1626  PrefilterRuleStore pmq;
1627 
1628  memset(&mpm_ctx, 0x00, sizeof(MpmCtx));
1629  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
1630  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
1631  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1632 
1633  MpmAddPatternCI(&mpm_ctx, (uint8_t *)"ABCD", 4, 0, 0, 0, 0, 0);
1634  MpmAddPatternCI(&mpm_ctx, (uint8_t *)"bCdEfG", 6, 0, 0, 1, 0, 0);
1635  MpmAddPatternCI(&mpm_ctx, (uint8_t *)"fghJikl", 7, 0, 0, 2, 0, 0);
1636  PmqSetup(&pmq);
1637 
1638  SCACTilePreparePatterns(&mpm_ctx);
1639 
1640  const char *buf = "abcdefghjiklmnopqrstuvwxyz";
1641  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
1642  (uint8_t *)buf, strlen(buf));
1643 
1644  if (cnt == 3)
1645  result = 1;
1646  else
1647  printf("3 != %" PRIu32 " ",cnt);
1648 
1649  SCACTileDestroyCtx(&mpm_ctx);
1650  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1651  PmqFree(&pmq);
1652  return result;
1653 }
1654 
1655 static int SCACTileTest06(void)
1656 {
1657  int result = 0;
1658  MpmCtx mpm_ctx;
1659  MpmThreadCtx mpm_thread_ctx;
1660  PrefilterRuleStore pmq;
1661 
1662  memset(&mpm_ctx, 0, sizeof(MpmCtx));
1663  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
1664  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
1665  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1666 
1667  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0);
1668  PmqSetup(&pmq);
1669 
1670  SCACTilePreparePatterns(&mpm_ctx);
1671 
1672  const char *buf = "abcd";
1673  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
1674  (uint8_t *)buf, strlen(buf));
1675 
1676  if (cnt == 1)
1677  result = 1;
1678  else
1679  printf("1 != %" PRIu32 " ",cnt);
1680 
1681  SCACTileDestroyCtx(&mpm_ctx);
1682  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1683  PmqFree(&pmq);
1684  return result;
1685 }
1686 
1687 static int SCACTileTest07(void)
1688 {
1689  int result = 0;
1690  MpmCtx mpm_ctx;
1691  MpmThreadCtx mpm_thread_ctx;
1692  PrefilterRuleStore pmq;
1693 
1694  memset(&mpm_ctx, 0, sizeof(MpmCtx));
1695  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
1696  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
1697  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1698 
1699  /* should match 30 times */
1700  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"A", 1, 0, 0, 0, 0, 0);
1701  /* should match 29 times */
1702  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 1, 0, 0);
1703  /* should match 28 times */
1704  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAA", 3, 0, 0, 2, 0, 0);
1705  /* 26 */
1706  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAA", 5, 0, 0, 3, 0, 0);
1707  /* 21 */
1708  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAA", 10, 0, 0, 4, 0, 0);
1709  /* 1 */
1710  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
1711  30, 0, 0, 5, 0, 0);
1712  PmqSetup(&pmq);
1713  /* total matches: 135 */
1714 
1715  SCACTilePreparePatterns(&mpm_ctx);
1716 
1717  const char *buf = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
1718  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
1719  (uint8_t *)buf, strlen(buf));
1720 
1721  if (cnt == 135)
1722  result = 1;
1723  else
1724  printf("135 != %" PRIu32 " ",cnt);
1725 
1726  SCACTileDestroyCtx(&mpm_ctx);
1727  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1728  PmqFree(&pmq);
1729  return result;
1730 }
1731 
1732 static int SCACTileTest08(void)
1733 {
1734  int result = 0;
1735  MpmCtx mpm_ctx;
1736  MpmThreadCtx mpm_thread_ctx;
1737  PrefilterRuleStore pmq;
1738 
1739  memset(&mpm_ctx, 0, sizeof(MpmCtx));
1740  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
1741  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
1742  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1743 
1744  /* 1 match */
1745  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0);
1746  PmqSetup(&pmq);
1747 
1748  SCACTilePreparePatterns(&mpm_ctx);
1749 
1750  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
1751  (uint8_t *)"a", 1);
1752 
1753  if (cnt == 0)
1754  result = 1;
1755  else
1756  printf("0 != %" PRIu32 " ",cnt);
1757 
1758  SCACTileDestroyCtx(&mpm_ctx);
1759  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1760  PmqFree(&pmq);
1761  return result;
1762 }
1763 
1764 static int SCACTileTest09(void)
1765 {
1766  int result = 0;
1767  MpmCtx mpm_ctx;
1768  MpmThreadCtx mpm_thread_ctx;
1769  PrefilterRuleStore pmq;
1770 
1771  memset(&mpm_ctx, 0, sizeof(MpmCtx));
1772  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
1773  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
1774  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1775 
1776  /* 1 match */
1777  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"ab", 2, 0, 0, 0, 0, 0);
1778  PmqSetup(&pmq);
1779 
1780  SCACTilePreparePatterns(&mpm_ctx);
1781 
1782  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
1783  (uint8_t *)"ab", 2);
1784 
1785  if (cnt == 1)
1786  result = 1;
1787  else
1788  printf("1 != %" PRIu32 " ",cnt);
1789 
1790  SCACTileDestroyCtx(&mpm_ctx);
1791  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1792  PmqFree(&pmq);
1793  return result;
1794 }
1795 
1796 static int SCACTileTest10(void)
1797 {
1798  int result = 0;
1799  MpmCtx mpm_ctx;
1800  MpmThreadCtx mpm_thread_ctx;
1801  PrefilterRuleStore pmq;
1802 
1803  memset(&mpm_ctx, 0, sizeof(MpmCtx));
1804  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
1805  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
1806  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1807 
1808  /* 1 match */
1809  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcdefgh", 8, 0, 0, 0, 0, 0);
1810  PmqSetup(&pmq);
1811 
1812  SCACTilePreparePatterns(&mpm_ctx);
1813 
1814  const char *buf = "01234567890123456789012345678901234567890123456789"
1815  "01234567890123456789012345678901234567890123456789"
1816  "abcdefgh"
1817  "01234567890123456789012345678901234567890123456789"
1818  "01234567890123456789012345678901234567890123456789";
1819  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
1820  (uint8_t *)buf, strlen(buf));
1821 
1822  if (cnt == 1)
1823  result = 1;
1824  else
1825  printf("1 != %" PRIu32 " ",cnt);
1826 
1827  SCACTileDestroyCtx(&mpm_ctx);
1828  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1829  PmqFree(&pmq);
1830  return result;
1831 }
1832 
1833 static int SCACTileTest11(void)
1834 {
1835  int result = 0;
1836  MpmCtx mpm_ctx;
1837  MpmThreadCtx mpm_thread_ctx;
1838  PrefilterRuleStore pmq;
1839 
1840  memset(&mpm_ctx, 0, sizeof(MpmCtx));
1841  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
1842  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
1843  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1844 
1845  if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"he", 2, 0, 0, 1, 0, 0) == -1)
1846  goto end;
1847  if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"she", 3, 0, 0, 2, 0, 0) == -1)
1848  goto end;
1849  if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"his", 3, 0, 0, 3, 0, 0) == -1)
1850  goto end;
1851  if (MpmAddPatternCS(&mpm_ctx, (uint8_t *)"hers", 4, 0, 0, 4, 0, 0) == -1)
1852  goto end;
1853  PmqSetup(&pmq);
1854 
1855  if (SCACTilePreparePatterns(&mpm_ctx) == -1)
1856  goto end;
1857 
1858  result = 1;
1859 
1860  const char *buf = "he";
1861  result &= (SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1862  strlen(buf)) == 1);
1863  buf = "she";
1864  result &= (SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1865  strlen(buf)) == 2);
1866  buf = "his";
1867  result &= (SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1868  strlen(buf)) == 1);
1869  buf = "hers";
1870  result &= (SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq, (uint8_t *)buf,
1871  strlen(buf)) == 2);
1872 
1873  end:
1874  SCACTileDestroyCtx(&mpm_ctx);
1875  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1876  PmqFree(&pmq);
1877  return result;
1878 }
1879 
1880 static int SCACTileTest12(void)
1881 {
1882  int result = 0;
1883  MpmCtx mpm_ctx;
1884  MpmThreadCtx mpm_thread_ctx;
1885  PrefilterRuleStore pmq;
1886 
1887  memset(&mpm_ctx, 0x00, sizeof(MpmCtx));
1888  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
1889  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
1890  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1891 
1892  /* 1 match */
1893  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"wxyz", 4, 0, 0, 0, 0, 0);
1894  /* 1 match */
1895  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"vwxyz", 5, 0, 0, 1, 0, 0);
1896  PmqSetup(&pmq);
1897 
1898  SCACTilePreparePatterns(&mpm_ctx);
1899 
1900  const char *buf = "abcdefghijklmnopqrstuvwxyz";
1901  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
1902  (uint8_t *)buf, strlen(buf));
1903 
1904  if (cnt == 2)
1905  result = 1;
1906  else
1907  printf("2 != %" PRIu32 " ",cnt);
1908 
1909  SCACTileDestroyCtx(&mpm_ctx);
1910  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1911  PmqFree(&pmq);
1912  return result;
1913 }
1914 
1915 static int SCACTileTest13(void)
1916 {
1917  int result = 0;
1918  MpmCtx mpm_ctx;
1919  MpmThreadCtx mpm_thread_ctx;
1920  PrefilterRuleStore pmq;
1921 
1922  memset(&mpm_ctx, 0x00, sizeof(MpmCtx));
1923  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
1924  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
1925  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1926 
1927  /* 1 match */
1928  const char pat[] = "abcdefghijklmnopqrstuvwxyzABCD";
1929  MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, sizeof(pat) - 1, 0, 0, 0, 0, 0);
1930  PmqSetup(&pmq);
1931 
1932  SCACTilePreparePatterns(&mpm_ctx);
1933 
1934  const char *buf = "abcdefghijklmnopqrstuvwxyzABCD";
1935  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
1936  (uint8_t *)buf, strlen(buf));
1937 
1938  if (cnt == 1)
1939  result = 1;
1940  else
1941  printf("1 != %" PRIu32 " ",cnt);
1942 
1943  SCACTileDestroyCtx(&mpm_ctx);
1944  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1945  PmqFree(&pmq);
1946  return result;
1947 }
1948 
1949 static int SCACTileTest14(void)
1950 {
1951  int result = 0;
1952  MpmCtx mpm_ctx;
1953  MpmThreadCtx mpm_thread_ctx;
1954  PrefilterRuleStore pmq;
1955 
1956  memset(&mpm_ctx, 0x00, sizeof(MpmCtx));
1957  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
1958  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
1959  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1960 
1961  /* 1 match */
1962  const char pat[] = "abcdefghijklmnopqrstuvwxyzABCDE";
1963  MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, sizeof(pat) - 1, 0, 0, 0, 0, 0);
1964  PmqSetup(&pmq);
1965 
1966  SCACTilePreparePatterns(&mpm_ctx);
1967 
1968  const char *buf = "abcdefghijklmnopqrstuvwxyzABCDE";
1969  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
1970  (uint8_t *)buf, strlen(buf));
1971 
1972  if (cnt == 1)
1973  result = 1;
1974  else
1975  printf("1 != %" PRIu32 " ",cnt);
1976 
1977  SCACTileDestroyCtx(&mpm_ctx);
1978  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1979  PmqFree(&pmq);
1980  return result;
1981 }
1982 
1983 static int SCACTileTest15(void)
1984 {
1985  int result = 0;
1986  MpmCtx mpm_ctx;
1987  MpmThreadCtx mpm_thread_ctx;
1988  PrefilterRuleStore pmq;
1989 
1990  memset(&mpm_ctx, 0x00, sizeof(MpmCtx));
1991  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
1992  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
1993  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
1994 
1995  /* 1 match */
1996  const char pat[] = "abcdefghijklmnopqrstuvwxyzABCDEF";
1997  MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, sizeof(pat) - 1, 0, 0, 0, 0, 0);
1998  PmqSetup(&pmq);
1999 
2000  SCACTilePreparePatterns(&mpm_ctx);
2001 
2002  const char *buf = "abcdefghijklmnopqrstuvwxyzABCDEF";
2003  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
2004  (uint8_t *)buf, strlen(buf));
2005 
2006  if (cnt == 1)
2007  result = 1;
2008  else
2009  printf("1 != %" PRIu32 " ",cnt);
2010 
2011  SCACTileDestroyCtx(&mpm_ctx);
2012  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2013  PmqFree(&pmq);
2014  return result;
2015 }
2016 
2017 static int SCACTileTest16(void)
2018 {
2019  int result = 0;
2020  MpmCtx mpm_ctx;
2021  MpmThreadCtx mpm_thread_ctx;
2022  PrefilterRuleStore pmq;
2023 
2024  memset(&mpm_ctx, 0x00, sizeof(MpmCtx));
2025  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
2026  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
2027  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2028 
2029  /* 1 match */
2030  const char pat[] = "abcdefghijklmnopqrstuvwxyzABC";
2031  MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, sizeof(pat) - 1, 0, 0, 0, 0, 0);
2032  PmqSetup(&pmq);
2033 
2034  SCACTilePreparePatterns(&mpm_ctx);
2035 
2036  const char *buf = "abcdefghijklmnopqrstuvwxyzABC";
2037  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
2038  (uint8_t *)buf, strlen(buf));
2039 
2040  if (cnt == 1)
2041  result = 1;
2042  else
2043  printf("1 != %" PRIu32 " ",cnt);
2044 
2045  SCACTileDestroyCtx(&mpm_ctx);
2046  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2047  PmqFree(&pmq);
2048  return result;
2049 }
2050 
2051 static int SCACTileTest17(void)
2052 {
2053  int result = 0;
2054  MpmCtx mpm_ctx;
2055  MpmThreadCtx mpm_thread_ctx;
2056  PrefilterRuleStore pmq;
2057 
2058  memset(&mpm_ctx, 0x00, sizeof(MpmCtx));
2059  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
2060  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
2061  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2062 
2063  /* 1 match */
2064  const char pat[] = "abcdefghijklmnopqrstuvwxyzAB";
2065  MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, sizeof(pat) - 1, 0, 0, 0, 0, 0);
2066  PmqSetup(&pmq);
2067 
2068  SCACTilePreparePatterns(&mpm_ctx);
2069 
2070  const char *buf = "abcdefghijklmnopqrstuvwxyzAB";
2071  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
2072  (uint8_t *)buf, strlen(buf));
2073 
2074  if (cnt == 1)
2075  result = 1;
2076  else
2077  printf("1 != %" PRIu32 " ",cnt);
2078 
2079  SCACTileDestroyCtx(&mpm_ctx);
2080  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2081  PmqFree(&pmq);
2082  return result;
2083 }
2084 
2085 static int SCACTileTest18(void)
2086 {
2087  int result = 0;
2088  MpmCtx mpm_ctx;
2089  MpmThreadCtx mpm_thread_ctx;
2090  PrefilterRuleStore pmq;
2091 
2092  memset(&mpm_ctx, 0x00, sizeof(MpmCtx));
2093  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
2094  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
2095  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2096 
2097  /* 1 match */
2098  const char pat[] = "abcde"
2099  "fghij"
2100  "klmno"
2101  "pqrst"
2102  "uvwxy"
2103  "z";
2104  MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, sizeof(pat) - 1, 0, 0, 0, 0, 0);
2105  PmqSetup(&pmq);
2106 
2107  SCACTilePreparePatterns(&mpm_ctx);
2108 
2109  const char *buf = "abcde""fghij""klmno""pqrst""uvwxy""z";
2110  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
2111  (uint8_t *)buf, strlen(buf));
2112 
2113  if (cnt == 1)
2114  result = 1;
2115  else
2116  printf("1 != %" PRIu32 " ",cnt);
2117 
2118  SCACTileDestroyCtx(&mpm_ctx);
2119  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2120  PmqFree(&pmq);
2121  return result;
2122 }
2123 
2124 static int SCACTileTest19(void)
2125 {
2126  int result = 0;
2127  MpmCtx mpm_ctx;
2128  MpmThreadCtx mpm_thread_ctx;
2129  PrefilterRuleStore pmq;
2130 
2131  memset(&mpm_ctx, 0x00, sizeof(MpmCtx));
2132  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
2133  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
2134  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2135 
2136  /* 1 */
2137  const char pat[] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
2138  MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, sizeof(pat) - 1, 0, 0, 0, 0, 0);
2139  PmqSetup(&pmq);
2140 
2141  SCACTilePreparePatterns(&mpm_ctx);
2142 
2143  const char *buf = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
2144  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
2145  (uint8_t *)buf, strlen(buf));
2146 
2147  if (cnt == 1)
2148  result = 1;
2149  else
2150  printf("1 != %" PRIu32 " ",cnt);
2151 
2152  SCACTileDestroyCtx(&mpm_ctx);
2153  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2154  PmqFree(&pmq);
2155  return result;
2156 }
2157 
2158 static int SCACTileTest20(void)
2159 {
2160  int result = 0;
2161  MpmCtx mpm_ctx;
2162  MpmThreadCtx mpm_thread_ctx;
2163  PrefilterRuleStore pmq;
2164 
2165  memset(&mpm_ctx, 0x00, sizeof(MpmCtx));
2166  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
2167  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
2168  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2169 
2170  /* 1 */
2171  const char pat[] = "AAAAA"
2172  "AAAAA"
2173  "AAAAA"
2174  "AAAAA"
2175  "AAAAA"
2176  "AAAAA"
2177  "AA";
2178  MpmAddPatternCS(&mpm_ctx, (uint8_t *)pat, sizeof(pat) - 1, 0, 0, 0, 0, 0);
2179  PmqSetup(&pmq);
2180 
2181  SCACTilePreparePatterns(&mpm_ctx);
2182 
2183  const char *buf = "AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AAAAA""AA";
2184  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
2185  (uint8_t *)buf, strlen(buf));
2186 
2187  if (cnt == 1)
2188  result = 1;
2189  else
2190  printf("1 != %" PRIu32 " ",cnt);
2191 
2192  SCACTileDestroyCtx(&mpm_ctx);
2193  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2194  PmqFree(&pmq);
2195  return result;
2196 }
2197 
2198 static int SCACTileTest21(void)
2199 {
2200  int result = 0;
2201  MpmCtx mpm_ctx;
2202  MpmThreadCtx mpm_thread_ctx;
2203  PrefilterRuleStore pmq;
2204 
2205  memset(&mpm_ctx, 0x00, sizeof(MpmCtx));
2206  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
2207  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
2208  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2209 
2210  /* 1 */
2211  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0);
2212  PmqSetup(&pmq);
2213 
2214  SCACTilePreparePatterns(&mpm_ctx);
2215 
2216  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
2217  (uint8_t *)"AA", 2);
2218 
2219  if (cnt == 1)
2220  result = 1;
2221  else
2222  printf("1 != %" PRIu32 " ",cnt);
2223 
2224  SCACTileDestroyCtx(&mpm_ctx);
2225  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2226  PmqFree(&pmq);
2227  return result;
2228 }
2229 
2230 static int SCACTileTest22(void)
2231 {
2232  int result = 0;
2233  MpmCtx mpm_ctx;
2234  MpmThreadCtx mpm_thread_ctx;
2235  PrefilterRuleStore pmq;
2236 
2237  memset(&mpm_ctx, 0x00, sizeof(MpmCtx));
2238  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
2239  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
2240  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2241 
2242  /* 1 match */
2243  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcd", 4, 0, 0, 0, 0, 0);
2244  /* 1 match */
2245  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"abcde", 5, 0, 0, 1, 0, 0);
2246  PmqSetup(&pmq);
2247 
2248  SCACTilePreparePatterns(&mpm_ctx);
2249 
2250  const char *buf = "abcdefghijklmnopqrstuvwxyz";
2251  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
2252  (uint8_t *)buf, strlen(buf));
2253 
2254  if (cnt == 2)
2255  result = 1;
2256  else
2257  printf("2 != %" PRIu32 " ",cnt);
2258 
2259  SCACTileDestroyCtx(&mpm_ctx);
2260  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2261  PmqFree(&pmq);
2262  return result;
2263 }
2264 
2265 static int SCACTileTest23(void)
2266 {
2267  int result = 0;
2268  MpmCtx mpm_ctx;
2269  MpmThreadCtx mpm_thread_ctx;
2270  PrefilterRuleStore pmq;
2271 
2272  memset(&mpm_ctx, 0x00, sizeof(MpmCtx));
2273  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
2274  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
2275  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2276 
2277  /* 1 */
2278  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0);
2279  PmqSetup(&pmq);
2280 
2281  SCACTilePreparePatterns(&mpm_ctx);
2282 
2283  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
2284  (uint8_t *)"aa", 2);
2285 
2286  if (cnt == 0)
2287  result = 1;
2288  else
2289  printf("1 != %" PRIu32 " ",cnt);
2290 
2291  SCACTileDestroyCtx(&mpm_ctx);
2292  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2293  PmqFree(&pmq);
2294  return result;
2295 }
2296 
2297 static int SCACTileTest24(void)
2298 {
2299  int result = 0;
2300  MpmCtx mpm_ctx;
2301  MpmThreadCtx mpm_thread_ctx;
2302  PrefilterRuleStore pmq;
2303 
2304  memset(&mpm_ctx, 0x00, sizeof(MpmCtx));
2305  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
2306  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
2307  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2308 
2309  /* 1 */
2310  MpmAddPatternCI(&mpm_ctx, (uint8_t *)"AA", 2, 0, 0, 0, 0, 0);
2311  PmqSetup(&pmq);
2312 
2313  SCACTilePreparePatterns(&mpm_ctx);
2314 
2315  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
2316  (uint8_t *)"aa", 2);
2317 
2318  if (cnt == 1)
2319  result = 1;
2320  else
2321  printf("1 != %" PRIu32 " ",cnt);
2322 
2323  SCACTileDestroyCtx(&mpm_ctx);
2324  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2325  PmqFree(&pmq);
2326  return result;
2327 }
2328 
2329 static int SCACTileTest25(void)
2330 {
2331  int result = 0;
2332  MpmCtx mpm_ctx;
2333  MpmThreadCtx mpm_thread_ctx;
2334  PrefilterRuleStore pmq;
2335 
2336  memset(&mpm_ctx, 0x00, sizeof(MpmCtx));
2337  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
2338  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
2339  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2340 
2341  MpmAddPatternCI(&mpm_ctx, (uint8_t *)"ABCD", 4, 0, 0, 0, 0, 0);
2342  MpmAddPatternCI(&mpm_ctx, (uint8_t *)"bCdEfG", 6, 0, 0, 1, 0, 0);
2343  MpmAddPatternCI(&mpm_ctx, (uint8_t *)"fghiJkl", 7, 0, 0, 2, 0, 0);
2344  PmqSetup(&pmq);
2345 
2346  SCACTilePreparePatterns(&mpm_ctx);
2347 
2348  const char *buf = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
2349  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
2350  (uint8_t *)buf, strlen(buf));
2351 
2352  if (cnt == 3)
2353  result = 1;
2354  else
2355  printf("3 != %" PRIu32 " ",cnt);
2356 
2357  SCACTileDestroyCtx(&mpm_ctx);
2358  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2359  PmqFree(&pmq);
2360  return result;
2361 }
2362 
2363 static int SCACTileTest26(void)
2364 {
2365  int result = 0;
2366  MpmCtx mpm_ctx;
2367  MpmThreadCtx mpm_thread_ctx;
2368  PrefilterRuleStore pmq;
2369 
2370  memset(&mpm_ctx, 0x00, sizeof(MpmCtx));
2371  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
2372  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
2373  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2374 
2375  MpmAddPatternCI(&mpm_ctx, (uint8_t *)"Works", 5, 0, 0, 0, 0, 0);
2376  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"Works", 5, 0, 0, 1, 0, 0);
2377  PmqSetup(&pmq);
2378 
2379  SCACTilePreparePatterns(&mpm_ctx);
2380 
2381  const char *buf = "works";
2382  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
2383  (uint8_t *)buf, strlen(buf));
2384 
2385  if (cnt == 1)
2386  result = 1;
2387  else
2388  printf("3 != %" PRIu32 " ",cnt);
2389 
2390  SCACTileDestroyCtx(&mpm_ctx);
2391  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2392  PmqFree(&pmq);
2393  return result;
2394 }
2395 
2396 static int SCACTileTest27(void)
2397 {
2398  int result = 0;
2399  MpmCtx mpm_ctx;
2400  MpmThreadCtx mpm_thread_ctx;
2401  PrefilterRuleStore pmq;
2402 
2403  memset(&mpm_ctx, 0, sizeof(MpmCtx));
2404  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
2405  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
2406  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2407 
2408  /* 0 match */
2409  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"ONE", 3, 0, 0, 0, 0, 0);
2410  PmqSetup(&pmq);
2411 
2412  SCACTilePreparePatterns(&mpm_ctx);
2413 
2414  const char *buf = "tone";
2415  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
2416  (uint8_t *)buf, strlen(buf));
2417 
2418  if (cnt == 0)
2419  result = 1;
2420  else
2421  printf("0 != %" PRIu32 " ",cnt);
2422 
2423  SCACTileDestroyCtx(&mpm_ctx);
2424  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2425  PmqFree(&pmq);
2426  return result;
2427 }
2428 
2429 static int SCACTileTest28(void)
2430 {
2431  int result = 0;
2432  MpmCtx mpm_ctx;
2433  MpmThreadCtx mpm_thread_ctx;
2434  PrefilterRuleStore pmq;
2435 
2436  memset(&mpm_ctx, 0, sizeof(MpmCtx));
2437  memset(&mpm_thread_ctx, 0, sizeof(MpmThreadCtx));
2438  MpmInitCtx(&mpm_ctx, MPM_AC_KS);
2439  SCACTileInitThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2440 
2441  /* 0 match */
2442  MpmAddPatternCS(&mpm_ctx, (uint8_t *)"one", 3, 0, 0, 0, 0, 0);
2443  PmqSetup(&pmq);
2444 
2445  SCACTilePreparePatterns(&mpm_ctx);
2446 
2447  const char *buf = "tONE";
2448  uint32_t cnt = SCACTileSearch(&mpm_ctx, &mpm_thread_ctx, &pmq,
2449  (uint8_t *)buf, strlen(buf));
2450 
2451  if (cnt == 0)
2452  result = 1;
2453  else
2454  printf("0 != %" PRIu32 " ",cnt);
2455 
2456  SCACTileDestroyCtx(&mpm_ctx);
2457  SCACTileDestroyThreadCtx(&mpm_ctx, &mpm_thread_ctx);
2458  PmqFree(&pmq);
2459  return result;
2460 }
2461 
2462 static int SCACTileTest29(void)
2463 {
2464  uint8_t buf[] = "onetwothreefourfivesixseveneightnine";
2465  uint16_t buflen = sizeof(buf) - 1;
2466  Packet *p = NULL;
2467  ThreadVars th_v;
2468  DetectEngineThreadCtx *det_ctx = NULL;
2469  int result = 0;
2470 
2471  memset(&th_v, 0, sizeof(th_v));
2472  p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
2473 
2475  if (de_ctx == NULL)
2476  goto end;
2477 
2478  de_ctx->flags |= DE_QUIET;
2479 
2480  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2481  "(content:\"onetwothreefourfivesixseveneightnine\"; sid:1;)");
2482  if (de_ctx->sig_list == NULL)
2483  goto end;
2484  de_ctx->sig_list->next = SigInit(de_ctx, "alert tcp any any -> any any "
2485  "(content:\"onetwothreefourfivesixseveneightnine\"; fast_pattern:3,3; sid:2;)");
2486  if (de_ctx->sig_list->next == NULL)
2487  goto end;
2488 
2490  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2491 
2492  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2493  if (PacketAlertCheck(p, 1) != 1) {
2494  printf("if (PacketAlertCheck(p, 1) != 1) failure\n");
2495  goto end;
2496  }
2497  if (PacketAlertCheck(p, 2) != 1) {
2498  printf("if (PacketAlertCheck(p, 1) != 2) failure\n");
2499  goto end;
2500  }
2501 
2502  result = 1;
2503 end:
2504  if (de_ctx != NULL) {
2507 
2508  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2510  }
2511 
2512  UTHFreePackets(&p, 1);
2513  return result;
2514 }
2515 
2516 #endif /* UNITTESTS */
2517 
2519 {
2520 
2521 #ifdef UNITTESTS
2522  UtRegisterTest("SCACTileTest01", SCACTileTest01);
2523  UtRegisterTest("SCACTileTest02", SCACTileTest02);
2524  UtRegisterTest("SCACTileTest03", SCACTileTest03);
2525  UtRegisterTest("SCACTileTest04", SCACTileTest04);
2526  UtRegisterTest("SCACTileTest05", SCACTileTest05);
2527  UtRegisterTest("SCACTileTest06", SCACTileTest06);
2528  UtRegisterTest("SCACTileTest07", SCACTileTest07);
2529  UtRegisterTest("SCACTileTest08", SCACTileTest08);
2530  UtRegisterTest("SCACTileTest09", SCACTileTest09);
2531  UtRegisterTest("SCACTileTest10", SCACTileTest10);
2532  UtRegisterTest("SCACTileTest11", SCACTileTest11);
2533  UtRegisterTest("SCACTileTest12", SCACTileTest12);
2534  UtRegisterTest("SCACTileTest13", SCACTileTest13);
2535  UtRegisterTest("SCACTileTest14", SCACTileTest14);
2536  UtRegisterTest("SCACTileTest15", SCACTileTest15);
2537  UtRegisterTest("SCACTileTest16", SCACTileTest16);
2538  UtRegisterTest("SCACTileTest17", SCACTileTest17);
2539  UtRegisterTest("SCACTileTest18", SCACTileTest18);
2540  UtRegisterTest("SCACTileTest19", SCACTileTest19);
2541  UtRegisterTest("SCACTileTest20", SCACTileTest20);
2542  UtRegisterTest("SCACTileTest21", SCACTileTest21);
2543  UtRegisterTest("SCACTileTest22", SCACTileTest22);
2544  UtRegisterTest("SCACTileTest23", SCACTileTest23);
2545  UtRegisterTest("SCACTileTest24", SCACTileTest24);
2546  UtRegisterTest("SCACTileTest25", SCACTileTest25);
2547  UtRegisterTest("SCACTileTest26", SCACTileTest26);
2548  UtRegisterTest("SCACTileTest27", SCACTileTest27);
2549  UtRegisterTest("SCACTileTest28", SCACTileTest28);
2550  UtRegisterTest("SCACTileTest29", SCACTileTest29);
2551 #endif
2552 }
2553 
2554 #else /* we're big endian */
2555 
2556 void MpmACTileRegister(void)
2557 {
2558  /* no-op on big endian */
2559 }
2560 
2561 #endif /* little endian check */
MpmTableElmt_::PrintThreadCtx
void(* PrintThreadCtx)(struct MpmThreadCtx_ *)
Definition: util-mpm.h:167
SCACTileSearchCtx
struct SCACTileSearchCtx_ SCACTileSearchCtx
SCACTileRegisterTests
void SCACTileRegisterTests(void)
Definition: util-mpm-ac-ks.c:2518
len
uint8_t len
Definition: app-layer-dnp3.h:2
detect-engine.h
SCACTileSearchCtx_
Definition: util-mpm-ac-ks.h:115
MpmPatternIndex
uint32_t MpmPatternIndex
Definition: util-mpm.h:44
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
SCACTileCtx_::Search
uint32_t(* Search)(const struct SCACTileSearchCtx_ *ctx, struct MpmThreadCtx_ *, PrefilterRuleStore *, const uint8_t *, uint32_t)
Definition: util-mpm-ac-ks.h:69
MpmTableElmt_::InitThreadCtx
void(* InitThreadCtx)(struct MpmCtx_ *, struct MpmThreadCtx_ *)
Definition: util-mpm.h:147
SCACTileCtx_::allocated_state_count
uint32_t allocated_state_count
Definition: util-mpm-ac-ks.h:96
MpmThreadCtx_
Definition: util-mpm.h:46
SCACTileSearchSmall256
uint32_t SCACTileSearchSmall256(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen)
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
MpmFreePattern
void MpmFreePattern(MpmCtx *mpm_ctx, MpmPattern *p)
Definition: util-mpm.c:349
SCACTileSearchCtx_::Search
uint32_t(* Search)(const struct SCACTileSearchCtx_ *ctx, struct MpmThreadCtx_ *, PrefilterRuleStore *, const uint8_t *, uint32_t)
Definition: util-mpm-ac-ks.h:122
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
MpmTableElmt_::name
const char * name
Definition: util-mpm.h:145
SC_ERR_AHO_CORASICK
@ SC_ERR_AHO_CORASICK
Definition: util-error.h:206
STATE_QUEUE_CONTAINER_SIZE
#define STATE_QUEUE_CONTAINER_SIZE
Definition: util-mpm-ac-ks.c:150
PrefilterRuleStore_
structure for storing potential rule matches
Definition: util-prefilter.h:32
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
util-mpm-ac-ks.h
SCACTileCtx_::pattern_list
SCACTilePatternList * pattern_list
Definition: util-mpm-ac-ks.h:81
SCACTileSearchSmall32
uint32_t SCACTileSearchSmall32(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen)
PacketAlertCheck
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
Definition: detect-engine-alert.c:137
MpmThreadCtx_::memory_cnt
uint32_t memory_cnt
Definition: util-mpm.h:49
SigInit
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:2115
StateQueue_
Helper structure used by AC during state table creation.
Definition: util-mpm-ac-bs.c:87
SC_AC_TILE_FAIL
#define SC_AC_TILE_FAIL
Definition: util-mpm-ac-ks.c:148
SCACTileThreadCtx
struct SCACTileThreadCtx_ SCACTileThreadCtx
SCACTilePatternList_::offset
uint16_t offset
Definition: util-mpm-ac-ks.h:33
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:811
util-memcpy.h
MpmCtx_::memory_size
uint32_t memory_size
Definition: util-mpm.h:103
SCACTileThreadCtx_::total_matches
uint64_t total_matches
Definition: util-mpm-ac-ks.h:153
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2433
SCACTileSearchTiny8
uint32_t SCACTileSearchTiny8(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen)
SCACTileOutputTable
struct SCACTileOutputTable_ SCACTileOutputTable
MpmTableElmt_::AddPatternNocase
int(* AddPatternNocase)(struct MpmCtx_ *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t)
Definition: util-mpm.h:163
SCACTileOutputTable_::no_of_entries
uint32_t no_of_entries
Definition: util-mpm-ac-ks.h:48
SCACTileSearchCtx_::output_table
SCACTileOutputTable * output_table
Definition: util-mpm-ac-ks.h:132
SCACTileSearchSmall128
uint32_t SCACTileSearchSmall128(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen)
DE_QUIET
#define DE_QUIET
Definition: detect.h:295
MpmCtx_::maxlen
uint16_t maxlen
Definition: util-mpm.h:100
MpmTableElmt_::AddPattern
int(* AddPattern)(struct MpmCtx_ *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t)
Definition: util-mpm.h:162
UTHBuildPacket
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
Definition: util-unittest-helper.c:337
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1790
StateQueue
struct StateQueue_ StateQueue
Helper structure used by AC during state table creation.
SigCleanSignatures
void SigCleanSignatures(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:42
MpmPattern_::original_pat
uint8_t * original_pat
Definition: util-mpm.h:67
SCACTileSearchCtx_::pattern_cnt
uint32_t pattern_cnt
Definition: util-mpm-ac-ks.h:141
SCACTileSearchCtx_::state_table
void * state_table
Definition: util-mpm-ac-ks.h:129
MpmTableElmt_::InitCtx
void(* InitCtx)(struct MpmCtx_ *)
Definition: util-mpm.h:146
util-unittest.h
SCACTileCtx_::goto_table
int32_t(* goto_table)[256]
Definition: util-mpm-ac-ks.h:90
util-unittest-helper.h
MpmPattern_::flags
uint8_t flags
Definition: util-mpm.h:58
SCHECK
#define SCHECK(x)
Definition: util-mpm-ac-ks.c:1154
util-memcmp.h
SCACTileSearchCtx_::state_count
uint32_t state_count
Definition: util-mpm-ac-ks.h:139
MpmInitCtx
void MpmInitCtx(MpmCtx *mpm_ctx, uint8_t matcher)
Definition: util-mpm.c:200
Signature_::next
struct Signature_ * next
Definition: detect.h:622
MpmTableElmt_::PrintCtx
void(* PrintCtx)(struct MpmCtx_ *)
Definition: util-mpm.h:166
SCACTileOutputTable_
Definition: util-mpm-ac-ks.h:44
SCACTileThreadCtx_
Definition: util-mpm-ac-ks.h:149
util-debug.h
SCACTileSearchTiny16
uint32_t SCACTileSearchTiny16(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen)
MpmPattern_::next
struct MpmPattern_ * next
Definition: util-mpm.h:79
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1060
SCACTileSearchCtx_::mpm_bitarray_size
uint32_t mpm_bitarray_size
Definition: util-mpm-ac-ks.h:136
MpmPattern_::id
uint32_t id
Definition: util-mpm.h:73
SCACTileSearchSmall8
uint32_t SCACTileSearchSmall8(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen)
SCACTileCtx_::state_count
uint32_t state_count
Definition: util-mpm-ac-ks.h:94
MpmThreadCtx_::memory_size
uint32_t memory_size
Definition: util-mpm.h:50
SCACTileOutputTable_::patterns
MpmPatternIndex * patterns
Definition: util-mpm-ac-ks.h:46
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
SCACTilePatternList
struct SCACTilePatternList_ SCACTilePatternList
util-mpm-ac-ks-small.c
SCACTilePreparePatterns
int SCACTilePreparePatterns(MpmCtx *mpm_ctx)
Process the patterns added to the mpm, and create the internal tables.
Definition: util-mpm-ac-ks.c:869
SCACTileSearch
uint32_t SCACTileSearch(const MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen)
The aho corasick search function.
Definition: util-mpm-ac-ks.c:1226
MpmCtx_::minlen
uint16_t minlen
Definition: util-mpm.h:99
SCACTileSearchCtx_::init_ctx
SCACTileCtx * init_ctx
Definition: util-mpm-ac-ks.h:144
SigGroupCleanup
int SigGroupCleanup(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:2016
SCLogCritical
#define SCLogCritical(err_code,...)
Macro used to log CRITICAL messages.
Definition: util-debug.h:270
MpmPattern_::sids_size
uint32_t sids_size
Definition: util-mpm.h:76
MPM_AC_KS
@ MPM_AC_KS
Definition: util-mpm.h:37
Packet_
Definition: decode.h:427
conf.h
MPM_INIT_HASH_SIZE
#define MPM_INIT_HASH_SIZE
Definition: util-mpm.h:29
SCACTileSearchTiny128
uint32_t SCACTileSearchTiny128(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen)
SCACTilePatternList_::pid
uint32_t pid
Definition: util-mpm-ac-ks.h:37
MpmTableElmt_::Prepare
int(* Prepare)(struct MpmCtx_ *)
Definition: util-mpm.h:164
SCACTilePatternList_::sids
SigIntId * sids
Definition: util-mpm-ac-ks.h:41
StateQueue_::bot
int bot
Definition: util-mpm-ac-bs.c:90
SCACTileCtx_::alpha_hist
uint32_t alpha_hist[256]
Definition: util-mpm-ac-ks.h:98
MpmPattern_
Definition: util-mpm.h:54
MpmTableElmt_::Search
uint32_t(* Search)(const struct MpmCtx_ *, struct MpmThreadCtx_ *, PrefilterRuleStore *, const uint8_t *, uint32_t)
Definition: util-mpm.h:165
MpmAddPatternCS
int MpmAddPatternCS(struct MpmCtx_ *mpm_ctx, uint8_t *pat, uint16_t patlen, uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags)
Definition: util-mpm.c:241
SCACTilePrintSearchStats
void SCACTilePrintSearchStats(MpmThreadCtx *mpm_thread_ctx)
Definition: util-mpm-ac-ks.c:1426
SCACTilePrintInfo
void SCACTilePrintInfo(MpmCtx *mpm_ctx)
Definition: util-mpm-ac-ks.c:1436
SCACTileSearchCtx_::pattern_list
SCACTilePatternList * pattern_list
Definition: util-mpm-ac-ks.h:133
SCACTileSearchTiny64
uint32_t SCACTileSearchTiny64(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen)
SCACTileCtx_::bytes_per_state
uint8_t bytes_per_state
Definition: util-mpm-ac-ks.h:107
MpmACTileRegister
void MpmACTileRegister(void)
Register the aho-corasick mpm 'ks' originally developed by Ken Steele for Tilera Tile-Gx processor.
Definition: util-mpm-ac-ks.c:1462
SCACTileCtx_::alphabet_storage
uint16_t alphabet_storage
Definition: util-mpm-ac-ks.h:104
SCACTilePatternList_::cs
uint8_t * cs
Definition: util-mpm-ac-ks.h:30
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:1948
MpmPattern_::ci
uint8_t * ci
Definition: util-mpm.h:71
SCACTileCtx_::SetNextState
void(* SetNextState)(struct SCACTileCtx_ *ctx, int state, int aa, int new_state, int outputs)
Definition: util-mpm-ac-ks.h:75
SCRealloc
#define SCRealloc(ptr, sz)
Definition: util-mem.h:50
MPM_PATTERN_FLAG_NOCASE
#define MPM_PATTERN_FLAG_NOCASE
Definition: util-mpm.h:131
SCACTileThreadCtx_::total_calls
uint32_t total_calls
Definition: util-mpm-ac-ks.h:151
SCACTileCtx_::translate_table
uint8_t translate_table[256]
Definition: util-mpm-ac-ks.h:57
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:3142
flags
uint8_t flags
Definition: decode-gre.h:0
SCACTilePatternList_::depth
uint16_t depth
Definition: util-mpm-ac-ks.h:34
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3354
SCACTileCtx_::state_table
void * state_table
Definition: util-mpm-ac-ks.h:62
MpmCtx_::pattern_cnt
uint32_t pattern_cnt
Definition: util-mpm.h:97
SCACTilePatternList_::patlen
uint16_t patlen
Definition: util-mpm-ac-ks.h:31
SCACTileSearchTiny256
uint32_t SCACTileSearchTiny256(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen)
SCACTileAddPatternCI
int SCACTileAddPatternCI(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t)
Add a case insensitive pattern. Although we have different calls for adding case sensitive and insens...
Definition: util-mpm-ac-ks.c:1392
PmqFree
void PmqFree(PrefilterRuleStore *)
Cleanup and free a Pmq.
Definition: util-prefilter.c:125
MpmPattern_::offset
uint16_t offset
Definition: util-mpm.h:61
FatalError
#define FatalError(x,...)
Definition: util-debug.h:532
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:817
util-validate.h
SCACTileCtx
struct SCACTileCtx_ SCACTileCtx
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
MpmPattern_::sids
SigIntId * sids
Definition: util-mpm.h:77
MpmPattern_::depth
uint16_t depth
Definition: util-mpm.h:64
SCACTileCtx_
Definition: util-mpm-ac-ks.h:54
SCACTilePatternList_
Definition: util-mpm-ac-ks.h:29
MpmTableElmt_::DestroyCtx
void(* DestroyCtx)(struct MpmCtx_ *)
Definition: util-mpm.h:148
SCFree
#define SCFree(p)
Definition: util-mem.h:61
SC_ERR_FATAL
@ SC_ERR_FATAL
Definition: util-error.h:203
PmqSetup
int PmqSetup(PrefilterRuleStore *)
Setup a pmq.
Definition: util-prefilter.c:36
detect-parse.h
MpmCtx_::memory_cnt
uint32_t memory_cnt
Definition: util-mpm.h:102
MpmCtx_::init_hash
MpmPattern ** init_hash
Definition: util-mpm.h:108
SCACTileInitCtx
void SCACTileInitCtx(MpmCtx *)
Initialize the AC context.
Definition: util-mpm-ac-ks.c:990
MpmPattern_::len
uint16_t len
Definition: util-mpm.h:56
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2394
SCACTileDestroyThreadCtx
void SCACTileDestroyThreadCtx(MpmCtx *, MpmThreadCtx *)
Destroy the mpm thread context.
Definition: util-mpm-ac-ks.c:1035
mpm_table
MpmTableElmt mpm_table[MPM_TABLE_SIZE]
Definition: util-mpm.c:48
SCACTileSearchLarge
uint32_t SCACTileSearchLarge(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen)
Definition: util-mpm-ac-ks.c:1239
SCACTileDestroyCtx
void SCACTileDestroyCtx(MpmCtx *)
Destroy the mpm context.
Definition: util-mpm-ac-ks.c:1112
suricata.h
SCACTileCtx_::parray
MpmPattern ** parray
Definition: util-mpm-ac-ks.h:85
SCACTilePatternList_::sids_size
uint32_t sids_size
Definition: util-mpm-ac-ks.h:40
SCACTileSearchTiny32
uint32_t SCACTileSearchTiny32(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen)
MpmAddPattern
int MpmAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags)
Definition: util-mpm.c:427
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:812
MpmTableElmt_::DestroyThreadCtx
void(* DestroyThreadCtx)(struct MpmCtx_ *, struct MpmThreadCtx_ *)
Definition: util-mpm.h:149
MpmCtx_
Definition: util-mpm.h:88
SigIntId
#define SigIntId
Definition: suricata-common.h:296
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCACTileSearchCtx_::translate_table
uint8_t translate_table[256]
Definition: util-mpm-ac-ks.h:126
MpmCtx_::ctx
void * ctx
Definition: util-mpm.h:89
MpmAddPatternCI
int MpmAddPatternCI(struct MpmCtx_ *mpm_ctx, uint8_t *pat, uint16_t patlen, uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags)
Definition: util-mpm.c:250
SCACTileAddPatternCS
int SCACTileAddPatternCS(MpmCtx *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t)
Add a case sensitive pattern. Although we have different calls for adding case sensitive and insensit...
Definition: util-mpm-ac-ks.c:1418
SCMemcmp
#define SCMemcmp(a, b, c)
Definition: util-memcmp.h:289
SCACTileCtx_::failure_table
int32_t * failure_table
Definition: util-mpm-ac-ks.h:91
MpmThreadCtx_::ctx
void * ctx
Definition: util-mpm.h:47
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:111
SCACTileCtx_::output_table
SCACTileOutputTable * output_table
Definition: util-mpm-ac-ks.h:79
MpmTableElmt_::RegisterUnittests
void(* RegisterUnittests)(void)
Definition: util-mpm.h:168
SCACTileInitThreadCtx
void SCACTileInitThreadCtx(MpmCtx *, MpmThreadCtx *)
Init the mpm thread context.
Definition: util-mpm-ac-ks.c:972
SCACTileSearchSmall16
uint32_t SCACTileSearchSmall16(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen)
SCACTileSearchSmall64
uint32_t SCACTileSearchSmall64(const SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx, PrefilterRuleStore *pmq, const uint8_t *buf, uint32_t buflen)
StateQueue_::top
int top
Definition: util-mpm-ac-bs.c:89
StateQueue_::store
int32_t store[STATE_QUEUE_CONTAINER_SIZE]
Definition: util-mpm-ac-bs.c:88
SCACTileCtx_::alphabet_size
uint16_t alphabet_size
Definition: util-mpm-ac-ks.h:100
UTHFreePackets
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:468