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