suricata
util-mpm.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-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 Victor Julien <victor@inliniac.net>
22  *
23  * Pattern matcher utility Functions
24  */
25 
26 #include "suricata-common.h"
27 #include "util-mpm.h"
28 #include "util-debug.h"
29 
30 /* include pattern matchers */
31 #include "util-mpm-ac.h"
32 #include "util-mpm-ac-bs.h"
33 #include "util-mpm-ac-tile.h"
34 #include "util-mpm-hs.h"
35 #include "util-hashlist.h"
36 
37 #include "detect-engine.h"
38 #include "util-misc.h"
39 #include "conf.h"
40 #include "conf-yaml-loader.h"
41 #include "queue.h"
42 #include "util-unittest.h"
43 #include "util-memcpy.h"
44 #ifdef BUILD_HYPERSCAN
45 #include "hs.h"
46 #endif
47 
48 /**
49  * \brief Register a new Mpm Context.
50  *
51  * \param name A new profile to be registered to store this MpmCtx.
52  *
53  * \retval id Return the id created for the new MpmCtx profile.
54  */
55 int32_t MpmFactoryRegisterMpmCtxProfile(DetectEngineCtx *de_ctx, const char *name)
56 {
57  void *ptmp;
58  /* the very first entry */
59  if (de_ctx->mpm_ctx_factory_container == NULL) {
61  if (de_ctx->mpm_ctx_factory_container == NULL) {
62  SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
63  exit(EXIT_FAILURE);
64  }
65  memset(de_ctx->mpm_ctx_factory_container, 0, sizeof(MpmCtxFactoryContainer));
66 
68  if (unlikely(item == NULL)) {
69  SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
70  exit(EXIT_FAILURE);
71  }
72 
73  item[0].name = name;
74 
75  /* toserver */
76  item[0].mpm_ctx_ts = SCMalloc(sizeof(MpmCtx));
77  if (item[0].mpm_ctx_ts == NULL) {
78  SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
79  exit(EXIT_FAILURE);
80  }
81  memset(item[0].mpm_ctx_ts, 0, sizeof(MpmCtx));
82  item[0].mpm_ctx_ts->global = 1;
83 
84  /* toclient */
85  item[0].mpm_ctx_tc = SCMalloc(sizeof(MpmCtx));
86  if (item[0].mpm_ctx_tc == NULL) {
87  SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
88  exit(EXIT_FAILURE);
89  }
90  memset(item[0].mpm_ctx_tc, 0, sizeof(MpmCtx));
91  item[0].mpm_ctx_tc->global = 1;
92 
93  /* our id starts from 0 always. Helps us with the ctx retrieval from
94  * the array */
95  item[0].id = 0;
96 
97  /* store the newly created item */
98  de_ctx->mpm_ctx_factory_container->items = item;
100 
101  /* the first id is always 0 */
102  return item[0].id;
103  } else {
104  int i;
106  for (i = 0; i < de_ctx->mpm_ctx_factory_container->no_of_items; i++) {
107  if (items[i].name != NULL && strcmp(items[i].name, name) == 0) {
108  /* looks like we have this mpm_ctx freed */
109  if (items[i].mpm_ctx_ts == NULL) {
110  items[i].mpm_ctx_ts = SCMalloc(sizeof(MpmCtx));
111  if (items[i].mpm_ctx_ts == NULL) {
112  SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
113  exit(EXIT_FAILURE);
114  }
115  memset(items[i].mpm_ctx_ts, 0, sizeof(MpmCtx));
116  items[i].mpm_ctx_ts->global = 1;
117  }
118  if (items[i].mpm_ctx_tc == NULL) {
119  items[i].mpm_ctx_tc = SCMalloc(sizeof(MpmCtx));
120  if (items[i].mpm_ctx_tc == NULL) {
121  SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
122  exit(EXIT_FAILURE);
123  }
124  memset(items[i].mpm_ctx_tc, 0, sizeof(MpmCtx));
125  items[i].mpm_ctx_tc->global = 1;
126  }
127  return items[i].id;
128  }
129  }
130 
131  /* let's make the new entry */
132  ptmp = SCRealloc(items,
133  (de_ctx->mpm_ctx_factory_container->no_of_items + 1) * sizeof(MpmCtxFactoryItem));
134  if (unlikely(ptmp == NULL)) {
135  SCFree(items);
136  items = NULL;
137  SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
138  exit(EXIT_FAILURE);
139  }
140  items = ptmp;
141 
142  de_ctx->mpm_ctx_factory_container->items = items;
143 
144  MpmCtxFactoryItem *new_item = &items[de_ctx->mpm_ctx_factory_container->no_of_items];
145  new_item[0].name = name;
146 
147  /* toserver */
148  new_item[0].mpm_ctx_ts = SCMalloc(sizeof(MpmCtx));
149  if (new_item[0].mpm_ctx_ts == NULL) {
150  SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
151  exit(EXIT_FAILURE);
152  }
153  memset(new_item[0].mpm_ctx_ts, 0, sizeof(MpmCtx));
154  new_item[0].mpm_ctx_ts->global = 1;
155 
156  /* toclient */
157  new_item[0].mpm_ctx_tc = SCMalloc(sizeof(MpmCtx));
158  if (new_item[0].mpm_ctx_tc == NULL) {
159  SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
160  exit(EXIT_FAILURE);
161  }
162  memset(new_item[0].mpm_ctx_tc, 0, sizeof(MpmCtx));
163  new_item[0].mpm_ctx_tc->global = 1;
164 
165  new_item[0].id = de_ctx->mpm_ctx_factory_container->no_of_items;
167 
168  /* the newly created id */
169  return new_item[0].id;
170  }
171 }
172 
173 int32_t MpmFactoryIsMpmCtxAvailable(const DetectEngineCtx *de_ctx, const MpmCtx *mpm_ctx)
174 {
175  if (mpm_ctx == NULL)
176  return 0;
177 
178  if (de_ctx->mpm_ctx_factory_container == NULL) {
179  return 0;
180  } else {
181  int i;
182  for (i = 0; i < de_ctx->mpm_ctx_factory_container->no_of_items; i++) {
183  if (mpm_ctx == de_ctx->mpm_ctx_factory_container->items[i].mpm_ctx_ts ||
184  mpm_ctx == de_ctx->mpm_ctx_factory_container->items[i].mpm_ctx_tc) {
185  return 1;
186  }
187  }
188  return 0;
189  }
190 }
191 
192 MpmCtx *MpmFactoryGetMpmCtxForProfile(const DetectEngineCtx *de_ctx, int32_t id, int direction)
193 {
194  if (id == MPM_CTX_FACTORY_UNIQUE_CONTEXT) {
195  MpmCtx *mpm_ctx = SCMalloc(sizeof(MpmCtx));
196  if (unlikely(mpm_ctx == NULL)) {
197  SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
198  exit(EXIT_FAILURE);
199  }
200  memset(mpm_ctx, 0, sizeof(MpmCtx));
201  return mpm_ctx;
202  } else if (id < -1) {
203  SCLogError(SC_ERR_INVALID_ARGUMENTS, "Invalid argument - %d\n", id);
204  return NULL;
205  } else if (id >= de_ctx->mpm_ctx_factory_container->no_of_items) {
206  /* this id does not exist */
207  return NULL;
208  } else {
209  return (direction == 0) ?
212  }
213 }
214 
215 void MpmFactoryReClaimMpmCtx(const DetectEngineCtx *de_ctx, MpmCtx *mpm_ctx)
216 {
217  if (mpm_ctx == NULL)
218  return;
219 
220  if (!MpmFactoryIsMpmCtxAvailable(de_ctx, mpm_ctx)) {
221  if (mpm_ctx->mpm_type != MPM_NOTSET)
222  mpm_table[mpm_ctx->mpm_type].DestroyCtx(mpm_ctx);
223  SCFree(mpm_ctx);
224  }
225 
226  return;
227 }
228 
230 {
231  if (de_ctx->mpm_ctx_factory_container == NULL)
232  return;
233 
234  int i = 0;
236  for (i = 0; i < de_ctx->mpm_ctx_factory_container->no_of_items; i++) {
237  if (items[i].mpm_ctx_ts != NULL) {
238  if (items[i].mpm_ctx_ts->mpm_type != MPM_NOTSET)
239  mpm_table[items[i].mpm_ctx_ts->mpm_type].DestroyCtx(items[i].mpm_ctx_ts);
240  SCFree(items[i].mpm_ctx_ts);
241  }
242  if (items[i].mpm_ctx_tc != NULL) {
243  if (items[i].mpm_ctx_tc->mpm_type != MPM_NOTSET)
244  mpm_table[items[i].mpm_ctx_tc->mpm_type].DestroyCtx(items[i].mpm_ctx_tc);
245  SCFree(items[i].mpm_ctx_tc);
246  }
247  }
248 
251  de_ctx->mpm_ctx_factory_container = NULL;
252 
253  return;
254 }
255 
256 void MpmInitThreadCtx(MpmThreadCtx *mpm_thread_ctx, uint16_t matcher)
257 {
258  mpm_table[matcher].InitThreadCtx(NULL, mpm_thread_ctx);
259 }
260 
261 void MpmInitCtx (MpmCtx *mpm_ctx, uint16_t matcher)
262 {
263  mpm_ctx->mpm_type = matcher;
264  mpm_table[matcher].InitCtx(mpm_ctx);
265 }
266 
267 /* MPM matcher to use by default, i.e. when "mpm-algo" is set to "auto".
268  * If Hyperscan is available, use it. Otherwise, use AC. */
269 #ifdef BUILD_HYPERSCAN
270 # define DEFAULT_MPM MPM_HS
271 # ifdef __tile__
272 # define DEFAULT_MPM_AC MPM_AC_TILE
273 # else
274 # define DEFAULT_MPM_AC MPM_AC
275 # endif
276 #else
277 # ifdef __tile__
278 # define DEFAULT_MPM MPM_AC_TILE
279 # else
280 # define DEFAULT_MPM MPM_AC
281 # endif
282 #endif
283 
284 void MpmTableSetup(void)
285 {
286  memset(mpm_table, 0, sizeof(mpm_table));
288 
289  MpmACRegister();
290  MpmACBSRegister();
292 #ifdef BUILD_HYPERSCAN
293  #ifdef HAVE_HS_VALID_PLATFORM
294  /* Enable runtime check for SSSE3. Do not use Hyperscan MPM matcher if
295  * check is not successful. */
296  if (hs_valid_platform() != HS_SUCCESS) {
297  SCLogInfo("SSSE3 support not detected, disabling Hyperscan for "
298  "MPM");
299  /* Fall back to best Aho-Corasick variant. */
300  mpm_default_matcher = DEFAULT_MPM_AC;
301  } else {
302  MpmHSRegister();
303  }
304  #else
305  MpmHSRegister();
306  #endif /* HAVE_HS_VALID_PLATFORM */
307 #endif /* BUILD_HYPERSCAN */
308 }
309 
310 int MpmAddPatternCS(struct MpmCtx_ *mpm_ctx, uint8_t *pat, uint16_t patlen,
311  uint16_t offset, uint16_t depth,
312  uint32_t pid, SigIntId sid, uint8_t flags)
313 {
314  return mpm_table[mpm_ctx->mpm_type].AddPattern(mpm_ctx, pat, patlen,
315  offset, depth,
316  pid, sid, flags);
317 }
318 
319 int MpmAddPatternCI(struct MpmCtx_ *mpm_ctx, uint8_t *pat, uint16_t patlen,
320  uint16_t offset, uint16_t depth,
321  uint32_t pid, SigIntId sid, uint8_t flags)
322 {
323  return mpm_table[mpm_ctx->mpm_type].AddPatternNocase(mpm_ctx, pat, patlen,
324  offset, depth,
325  pid, sid, flags);
326 }
327 
328 
329 /**
330  * \internal
331  * \brief Creates a hash of the pattern. We use it for the hashing process
332  * during the initial pattern insertion time, to cull duplicate sigs.
333  *
334  * \param pat Pointer to the pattern.
335  * \param patlen Pattern length.
336  *
337  * \retval hash A 32 bit unsigned hash.
338  */
339 static inline uint32_t MpmInitHashRaw(uint8_t *pat, uint16_t patlen)
340 {
341  uint32_t hash = patlen * pat[0];
342  if (patlen > 1)
343  hash += pat[1];
344 
345  return (hash % MPM_INIT_HASH_SIZE);
346 }
347 
348 /**
349  * \internal
350  * \brief Looks up a pattern. We use it for the hashing process during the
351  * the initial pattern insertion time, to cull duplicate sigs.
352  *
353  * \param ctx Pointer to the AC ctx.
354  * \param pat Pointer to the pattern.
355  * \param patlen Pattern length.
356  * \param flags Flags. We don't need this.
357  *
358  * \retval hash A 32 bit unsigned hash.
359  */
360 static inline MpmPattern *MpmInitHashLookup(MpmCtx *ctx,
361  uint8_t *pat, uint16_t patlen,
362  uint16_t offset, uint16_t depth,
363  uint8_t flags, uint32_t pid)
364 {
365  uint32_t hash = MpmInitHashRaw(pat, patlen);
366 
367  if (ctx->init_hash == NULL) {
368  return NULL;
369  }
370 
371  MpmPattern *t = ctx->init_hash[hash];
372  for ( ; t != NULL; t = t->next) {
373  if (!(flags & MPM_PATTERN_CTX_OWNS_ID)) {
374  if (t->id == pid)
375  return t;
376  } else {
377  if (t->len == patlen && t->offset == offset && t->depth == depth &&
378  memcmp(pat, t->original_pat, patlen) == 0 &&
379  t->flags == flags)
380  {
381  return t;
382  }
383  }
384  }
385 
386  return NULL;
387 }
388 
389 /**
390  * \internal
391  * \brief Allocs a new pattern instance.
392  *
393  * \param mpm_ctx Pointer to the mpm context.
394  *
395  * \retval p Pointer to the newly created pattern.
396  */
397 static inline MpmPattern *MpmAllocPattern(MpmCtx *mpm_ctx)
398 {
399  MpmPattern *p = SCMalloc(sizeof(MpmPattern));
400  if (unlikely(p == NULL)) {
401  exit(EXIT_FAILURE);
402  }
403  memset(p, 0, sizeof(MpmPattern));
404 
405  mpm_ctx->memory_cnt++;
406  mpm_ctx->memory_size += sizeof(MpmPattern);
407 
408  return p;
409 }
410 
411 /**
412  * \internal
413  * \brief Used to free MpmPattern instances.
414  *
415  * \param mpm_ctx Pointer to the mpm context.
416  * \param p Pointer to the MpmPattern instance to be freed.
417  */
418 void MpmFreePattern(MpmCtx *mpm_ctx, MpmPattern *p)
419 {
420  if (p != NULL && p->cs != NULL && p->cs != p->ci) {
421  SCFree(p->cs);
422  mpm_ctx->memory_cnt--;
423  mpm_ctx->memory_size -= p->len;
424  }
425 
426  if (p != NULL && p->ci != NULL) {
427  SCFree(p->ci);
428  mpm_ctx->memory_cnt--;
429  mpm_ctx->memory_size -= p->len;
430  }
431 
432  if (p != NULL && p->original_pat != NULL) {
433  SCFree(p->original_pat);
434  mpm_ctx->memory_cnt--;
435  mpm_ctx->memory_size -= p->len;
436  }
437 
438  if (p != NULL) {
439  SCFree(p);
440  mpm_ctx->memory_cnt--;
441  mpm_ctx->memory_size -= sizeof(MpmPattern);
442  }
443  return;
444 }
445 
446 static inline uint32_t MpmInitHash(MpmPattern *p)
447 {
448  uint32_t hash = p->len * p->original_pat[0];
449  if (p->len > 1)
450  hash += p->original_pat[1];
451 
452  return (hash % MPM_INIT_HASH_SIZE);
453 }
454 
455 static inline int MpmInitHashAdd(MpmCtx *ctx, MpmPattern *p)
456 {
457  uint32_t hash = MpmInitHash(p);
458 
459  if (ctx->init_hash == NULL) {
460  return -1;
461  }
462 
463  if (ctx->init_hash[hash] == NULL) {
464  ctx->init_hash[hash] = p;
465  return 0;
466  }
467 
468  MpmPattern *tt = NULL;
469  MpmPattern *t = ctx->init_hash[hash];
470 
471  /* get the list tail */
472  do {
473  tt = t;
474  t = t->next;
475  } while (t != NULL);
476 
477  tt->next = p;
478 
479  return 0;
480 }
481 
482 /**
483  * \internal
484  * \brief Add a pattern to the mpm-ac context.
485  *
486  * \param mpm_ctx Mpm context.
487  * \param pat Pointer to the pattern.
488  * \param patlen Length of the pattern.
489  * \param pid Pattern id
490  * \param sid Signature id (internal id).
491  * \param flags Pattern's MPM_PATTERN_* flags.
492  *
493  * \retval 0 On success.
494  * \retval -1 On failure.
495  */
496 int MpmAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
497  uint16_t offset, uint16_t depth, uint32_t pid,
498  SigIntId sid, uint8_t flags)
499 {
500  SCLogDebug("Adding pattern for ctx %p, patlen %"PRIu16" and pid %" PRIu32,
501  mpm_ctx, patlen, pid);
502 
503  if (patlen == 0) {
504  SCLogWarning(SC_ERR_INVALID_ARGUMENTS, "pattern length 0");
505  return 0;
506  }
507 
508  if (flags & MPM_PATTERN_CTX_OWNS_ID)
509  pid = UINT_MAX;
510 
511  /* check if we have already inserted this pattern */
512  MpmPattern *p = MpmInitHashLookup(mpm_ctx, pat, patlen,
513  offset, depth, flags, pid);
514  if (p == NULL) {
515  SCLogDebug("Allocing new pattern");
516 
517  /* p will never be NULL */
518  p = MpmAllocPattern(mpm_ctx);
519 
520  p->len = patlen;
521  p->flags = flags;
522  p->offset = offset;
523  p->depth = depth;
524  if (flags & MPM_PATTERN_CTX_OWNS_ID)
525  p->id = mpm_ctx->max_pat_id++;
526  else
527  p->id = pid;
528 
529  p->original_pat = SCMalloc(patlen);
530  if (p->original_pat == NULL)
531  goto error;
532  mpm_ctx->memory_cnt++;
533  mpm_ctx->memory_size += patlen;
534  memcpy(p->original_pat, pat, patlen);
535 
536  p->ci = SCMalloc(patlen);
537  if (p->ci == NULL)
538  goto error;
539  mpm_ctx->memory_cnt++;
540  mpm_ctx->memory_size += patlen;
541  memcpy_tolower(p->ci, pat, patlen);
542 
543  /* setup the case sensitive part of the pattern */
544  if (p->flags & MPM_PATTERN_FLAG_NOCASE) {
545  /* nocase means no difference between cs and ci */
546  p->cs = p->ci;
547  } else {
548  if (memcmp(p->ci, pat, p->len) == 0) {
549  /* no diff between cs and ci: pat is lowercase */
550  p->cs = p->ci;
551  } else {
552  p->cs = SCMalloc(patlen);
553  if (p->cs == NULL)
554  goto error;
555  mpm_ctx->memory_cnt++;
556  mpm_ctx->memory_size += patlen;
557  memcpy(p->cs, pat, patlen);
558  }
559  }
560 
561  /* put in the pattern hash */
562  if (MpmInitHashAdd(mpm_ctx, p) != 0)
563  goto error;
564 
565  mpm_ctx->pattern_cnt++;
566 
567  if (mpm_ctx->maxlen < patlen)
568  mpm_ctx->maxlen = patlen;
569 
570  if (mpm_ctx->minlen == 0) {
571  mpm_ctx->minlen = patlen;
572  } else {
573  if (mpm_ctx->minlen > patlen)
574  mpm_ctx->minlen = patlen;
575  }
576 
577  /* we need the max pat id */
578  if (p->id > mpm_ctx->max_pat_id)
579  mpm_ctx->max_pat_id = p->id;
580 
581  p->sids_size = 1;
582  p->sids = SCMalloc(p->sids_size * sizeof(SigIntId));
583  BUG_ON(p->sids == NULL);
584  p->sids[0] = sid;
585  } else {
586  /* we can be called multiple times for the same sid in the case
587  * of the 'single' modus. Here multiple rule groups share the
588  * same mpm ctx and might be adding the same pattern to the
589  * mpm_ctx */
590  int found = 0;
591  uint32_t x = 0;
592  for (x = 0; x < p->sids_size; x++) {
593  if (p->sids[x] == sid) {
594  found = 1;
595  break;
596  }
597  }
598 
599  if (!found) {
600  SigIntId *sids = SCRealloc(p->sids, (sizeof(SigIntId) * (p->sids_size + 1)));
601  BUG_ON(sids == NULL);
602  p->sids = sids;
603  p->sids[p->sids_size] = sid;
604  p->sids_size++;
605  }
606  }
607 
608  return 0;
609 
610 error:
611  MpmFreePattern(mpm_ctx, p);
612  return -1;
613 }
614 
615 
616 /************************************Unittests*********************************/
617 
618 #ifdef UNITTESTS
619 #endif /* UNITTESTS */
620 
622 {
623 #ifdef UNITTESTS
624  uint16_t i;
625 
626  for (i = 0; i < MPM_TABLE_SIZE; i++) {
627  if (i == MPM_NOTSET)
628  continue;
629 
630  g_ut_modules++;
631 
632  if (mpm_table[i].RegisterUnittests != NULL) {
633  g_ut_covered++;
635  } else {
636  if (coverage_unittests)
637  SCLogWarning(SC_WARN_NO_UNITTESTS, "mpm module %s has no "
638  "unittest registration function.", mpm_table[i].name);
639  }
640  }
641 
642 #endif
643 }
void MpmFactoryReClaimMpmCtx(const DetectEngineCtx *de_ctx, MpmCtx *mpm_ctx)
Definition: util-mpm.c:215
uint16_t flags
#define SCLogDebug(...)
Definition: util-debug.h:335
void MpmTableSetup(void)
Definition: util-mpm.c:284
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:310
uint16_t minlen
Definition: util-mpm.h:95
#define BUG_ON(x)
uint32_t pattern_cnt
Definition: util-mpm.h:93
void MpmFreePattern(MpmCtx *mpm_ctx, MpmPattern *p)
Definition: util-mpm.c:418
#define unlikely(expr)
Definition: util-optimize.h:35
#define MPM_PATTERN_FLAG_NOCASE
Definition: util-mpm.h:124
void(* InitCtx)(struct MpmCtx_ *)
Definition: util-mpm.h:139
void(* RegisterUnittests)(void)
Definition: util-mpm.h:161
uint64_t offset
void MpmInitThreadCtx(MpmThreadCtx *mpm_thread_ctx, uint16_t matcher)
Definition: util-mpm.c:256
uint16_t global
Definition: util-mpm.h:90
int g_ut_covered
Definition: suricata.c:863
uint32_t memory_cnt
Definition: util-mpm.h:98
void MpmFactoryDeRegisterAllMpmCtxProfiles(DetectEngineCtx *de_ctx)
Definition: util-mpm.c:229
struct MpmPattern_ * next
Definition: util-mpm.h:79
int32_t MpmFactoryRegisterMpmCtxProfile(DetectEngineCtx *de_ctx, const char *name)
Register a new Mpm Context.
Definition: util-mpm.c:55
main detection engine ctx
Definition: detect.h:720
void MpmACRegister(void)
Register the aho-corasick mpm.
Definition: util-mpm-ac.c:1239
struct MpmPattern_ MpmPattern
SigIntId * sids
Definition: util-mpm.h:77
uint16_t depth
Definition: util-mpm.h:64
#define DEFAULT_MPM
Definition: util-mpm.c:280
int MpmAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags)
Definition: util-mpm.c:496
uint16_t mpm_type
Definition: util-mpm.h:84
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
MpmCtxFactoryContainer * mpm_ctx_factory_container
Definition: detect.h:789
MpmCtx * mpm_ctx_ts
Definition: util-mpm.h:113
void MpmACTileRegister(void)
Register the aho-corasick mpm for Tilera Tile-Gx processor.
int32_t MpmFactoryIsMpmCtxAvailable(const DetectEngineCtx *de_ctx, const MpmCtx *mpm_ctx)
Definition: util-mpm.c:173
void(* DestroyCtx)(struct MpmCtx_ *)
Definition: util-mpm.h:141
#define MPM_PATTERN_CTX_OWNS_ID
Definition: util-mpm.h:135
uint32_t id
Definition: util-mpm.h:73
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:281
uint16_t offset
Definition: util-mpm.h:61
#define SCRealloc(x, a)
Definition: util-mem.h:190
uint32_t memory_size
Definition: util-mpm.h:99
void MpmRegisterTests(void)
Definition: util-mpm.c:621
#define MPM_INIT_HASH_SIZE
Definition: util-mpm.h:29
#define SCMalloc(a)
Definition: util-mem.h:174
void(* InitThreadCtx)(struct MpmCtx_ *, struct MpmThreadCtx_ *)
Definition: util-mpm.h:140
#define MPM_CTX_FACTORY_UNIQUE_CONTEXT
Definition: util-mpm.h:109
uint8_t * cs
Definition: util-mpm.h:69
int mpm_default_matcher
Definition: util-mpm.h:166
int coverage_unittests
Definition: suricata.c:861
uint16_t maxlen
Definition: util-mpm.h:96
void MpmInitCtx(MpmCtx *mpm_ctx, uint16_t matcher)
Definition: util-mpm.c:261
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:254
MpmTableElmt mpm_table[MPM_TABLE_SIZE]
Definition: util-mpm.h:165
int g_ut_modules
Definition: suricata.c:862
#define SCFree(a)
Definition: util-mem.h:236
MpmCtxFactoryItem * items
Definition: util-mpm.h:119
void MpmHSRegister(void)
MpmCtx * MpmFactoryGetMpmCtxForProfile(const DetectEngineCtx *de_ctx, int32_t id, int direction)
Definition: util-mpm.c:192
void MpmACBSRegister(void)
Register the aho-corasick mpm.
MpmPattern ** init_hash
Definition: util-mpm.h:104
uint32_t sids_size
Definition: util-mpm.h:76
uint8_t flags
Definition: util-mpm.h:58
uint32_t max_pat_id
Definition: util-mpm.h:101
int MpmAddPatternCI(struct MpmCtx_ *mpm_ctx, uint8_t *pat, uint16_t patlen, uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags)
Definition: util-mpm.c:319
const char * name
Definition: util-mpm.h:112
uint8_t * ci
Definition: util-mpm.h:71
MpmCtx * mpm_ctx_tc
Definition: util-mpm.h:114
uint16_t len
Definition: util-mpm.h:56
int(* AddPatternNocase)(struct MpmCtx_ *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t)
Definition: util-mpm.h:156
#define SigIntId
int(* AddPattern)(struct MpmCtx_ *, uint8_t *, uint16_t, uint16_t, uint16_t, uint32_t, SigIntId, uint8_t)
Definition: util-mpm.h:155
uint8_t * original_pat
Definition: util-mpm.h:67