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