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