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