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