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