suricata
detect-engine-mpm.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2021 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  * \author Anoop Saldanha <anoopsaldanha@gmail.com>
23  *
24  * Multi pattern matcher
25  */
26 
27 #include "suricata.h"
28 #include "suricata-common.h"
29 
30 #include "app-layer-protos.h"
31 
32 #include "decode.h"
33 #include "detect.h"
34 #include "detect-engine.h"
35 #include "detect-engine-siggroup.h"
36 #include "detect-engine-mpm.h"
37 #include "detect-engine-iponly.h"
38 #include "detect-parse.h"
40 #include "util-mpm.h"
41 #include "util-memcmp.h"
42 #include "util-memcpy.h"
43 #include "conf.h"
44 #include "detect-fast-pattern.h"
45 
46 #include "detect-tcphdr.h"
47 #include "detect-udphdr.h"
48 
49 #include "flow.h"
50 #include "flow-var.h"
51 #include "detect-flow.h"
52 
53 #include "detect-content.h"
54 
55 #include "detect-engine-payload.h"
56 
57 #include "stream.h"
58 
59 #include "util-misc.h"
60 #include "util-enum.h"
61 #include "util-debug.h"
62 #include "util-print.h"
63 #include "util-validate.h"
64 #include "util-hash-string.h"
65 
66 const char *builtin_mpms[] = {
67  "toserver TCP packet",
68  "toclient TCP packet",
69  "toserver TCP stream",
70  "toclient TCP stream",
71  "toserver UDP packet",
72  "toclient UDP packet",
73  "other IP packet",
74 
75  NULL };
76 
77 /* Registry for mpm keywords
78  *
79  * Keywords are registered at engine start up
80  */
81 
82 static DetectBufferMpmRegistery *g_mpm_list[DETECT_BUFFER_MPM_TYPE_SIZE] = { NULL, NULL, NULL };
83 static int g_mpm_list_cnt[DETECT_BUFFER_MPM_TYPE_SIZE] = { 0, 0, 0 };
84 
85 /** \brief register a MPM engine
86  *
87  * \note to be used at start up / registration only. Errors are fatal.
88  */
89 void DetectAppLayerMpmRegister2(const char *name,
90  int direction, int priority,
91  int (*PrefilterRegister)(DetectEngineCtx *de_ctx,
92  SigGroupHead *sgh, MpmCtx *mpm_ctx,
93  const DetectBufferMpmRegistery *mpm_reg, int list_id),
95  AppProto alproto, int tx_min_progress)
96 {
97  SCLogDebug("registering %s/%d/%d/%p/%p/%u/%d", name, direction, priority,
98  PrefilterRegister, GetData, alproto, tx_min_progress);
99 
100  BUG_ON(tx_min_progress >= 48);
101 
102  if (PrefilterRegister == PrefilterGenericMpmRegister && GetData == NULL) {
103  // must register GetData with PrefilterGenericMpmRegister
104  abort();
105  }
106 
109  int sm_list = DetectBufferTypeGetByName(name);
110  if (sm_list == -1) {
112  "MPM engine registration for %s failed", name);
113  }
114 
115  DetectBufferMpmRegistery *am = SCCalloc(1, sizeof(*am));
116  BUG_ON(am == NULL);
117  am->name = name;
118  snprintf(am->pname, sizeof(am->pname), "%s", am->name);
119  am->direction = direction;
120  DEBUG_VALIDATE_BUG_ON(sm_list < 0 || sm_list > INT16_MAX);
121  am->sm_list = (int16_t)sm_list;
122  am->sm_list_base = (int16_t)sm_list;
123  am->priority = priority;
125 
126  am->PrefilterRegisterWithListId = PrefilterRegister;
127  am->app_v2.GetData = GetData;
128  am->app_v2.alproto = alproto;
129  am->app_v2.tx_min_progress = tx_min_progress;
130 
131  if (g_mpm_list[DETECT_BUFFER_MPM_TYPE_APP] == NULL) {
132  g_mpm_list[DETECT_BUFFER_MPM_TYPE_APP] = am;
133  } else {
135  while (t->next != NULL) {
136  t = t->next;
137  }
138 
139  t->next = am;
140  am->id = t->id + 1;
141  }
142  g_mpm_list_cnt[DETECT_BUFFER_MPM_TYPE_APP]++;
143 
144  SupportFastPatternForSigMatchList(sm_list, priority);
145 }
146 
147 /** \brief copy a mpm engine from parent_id, add in transforms */
149  const int id, const int parent_id,
150  DetectEngineTransforms *transforms)
151 {
152  SCLogDebug("registering %d/%d", id, parent_id);
153 
155  while (t) {
156  if (t->sm_list == parent_id) {
157  DetectBufferMpmRegistery *am = SCCalloc(1, sizeof(*am));
158  BUG_ON(am == NULL);
159  am->name = t->name;
160  am->direction = t->direction;
161  DEBUG_VALIDATE_BUG_ON(id < 0 || id > INT16_MAX);
162  am->sm_list = (uint16_t)id; // use new id
163  am->sm_list_base = t->sm_list;
166  am->app_v2.GetData = t->app_v2.GetData;
167  am->app_v2.alproto = t->app_v2.alproto;
168  am->app_v2.tx_min_progress = t->app_v2.tx_min_progress;
169  am->priority = t->priority;
172  am->next = t->next;
173  if (transforms) {
174  memcpy(&am->transforms, transforms, sizeof(*transforms));
175 
176  /* create comma separated string of the names of the
177  * transforms and then shorten it if necessary. Finally
178  * use it to construct the 'profile' name for the engine */
179  char xforms[1024] = "";
180  for (int i = 0; i < transforms->cnt; i++) {
181  char ttstr[64];
182  (void)snprintf(ttstr,sizeof(ttstr), "%s,",
183  sigmatch_table[transforms->transforms[i].transform].name);
184  strlcat(xforms, ttstr, sizeof(xforms));
185  }
186  xforms[strlen(xforms)-1] = '\0';
187 
188  size_t space = sizeof(am->pname) - strlen(am->name) - 3;
189  char toprint[space + 1];
190  memset(toprint, 0x00, space + 1);
191  if (space < strlen(xforms)) {
192  ShortenString(xforms, toprint, space, '~');
193  } else {
194  strlcpy(toprint, xforms,sizeof(toprint));
195  }
196  (void)snprintf(am->pname, sizeof(am->pname), "%s#%d (%s)",
197  am->name, id, toprint);
198  } else {
199  (void)snprintf(am->pname, sizeof(am->pname), "%s#%d",
200  am->name, id);
201  }
202  am->id = de_ctx->app_mpms_list_cnt++;
203 
205  t->next = am;
206  SCLogDebug("copied mpm registration for %s id %u "
207  "with parent %u and GetData %p",
208  t->name, id, parent_id, am->app_v2.GetData);
209  t = am;
210  }
211  t = t->next;
212  }
213 }
214 
216 {
217  const DetectBufferMpmRegistery *list = g_mpm_list[DETECT_BUFFER_MPM_TYPE_APP];
219  while (list != NULL) {
220  DetectBufferMpmRegistery *n = SCCalloc(1, sizeof(*n));
221  BUG_ON(n == NULL);
222 
223  *n = *list;
224  n->next = NULL;
225 
226  if (toadd == NULL) {
227  toadd = n;
228  de_ctx->app_mpms_list = n;
229  } else {
230  toadd->next = n;
231  toadd = toadd->next;
232  }
233 
234  /* default to whatever the global setting is */
236 
237  /* see if we use a unique or shared mpm ctx for this type */
238  int confshared = 0;
239  char confstring[256] = "detect.mpm.";
240  strlcat(confstring, n->name, sizeof(confstring));
241  strlcat(confstring, ".shared", sizeof(confstring));
242  if (ConfGetBool(confstring, &confshared) == 1)
243  shared = confshared;
244 
245  if (shared == 0) {
246  if (!(de_ctx->flags & DE_QUIET)) {
247  SCLogPerf("using unique mpm ctx' for %s", n->name);
248  }
250  } else {
251  if (!(de_ctx->flags & DE_QUIET)) {
252  SCLogPerf("using shared mpm ctx' for %s", n->name);
253  }
255  }
256 
257  list = list->next;
258  }
260  SCLogDebug("mpm: de_ctx app_mpms_list %p %u",
262 }
263 
264 /**
265  * \brief initialize mpm contexts for applayer buffers that are in
266  * "single or "shared" mode.
267  */
269 {
270  int r = 0;
272  while (am != NULL) {
273  int dir = (am->direction == SIG_FLAG_TOSERVER) ? 1 : 0;
274 
276  {
278  if (mpm_ctx != NULL) {
279  if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
280  r |= mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
281  }
282  }
283  }
284  am = am->next;
285  }
286  return r;
287 }
288 
289 /** \brief register a MPM engine
290  *
291  * \note to be used at start up / registration only. Errors are fatal.
292  */
293 void DetectFrameMpmRegister(const char *name, int direction, int priority,
294  int (*PrefilterRegister)(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx,
295  const DetectBufferMpmRegistery *mpm_reg, int list_id),
296  AppProto alproto, uint8_t type)
297 {
298  SCLogDebug("registering %s/%d/%p/%s/%u", name, priority, PrefilterRegister,
299  AppProtoToString(alproto), type);
300 
304  int sm_list = DetectBufferTypeGetByName(name);
305  if (sm_list < 0 || sm_list > UINT16_MAX) {
306  FatalError(SC_ERR_INITIALIZATION, "MPM engine registration for %s failed", name);
307  }
308 
309  DetectBufferMpmRegistery *am = SCCalloc(1, sizeof(*am));
310  BUG_ON(am == NULL);
311  am->name = name;
312  snprintf(am->pname, sizeof(am->pname), "%s", am->name);
313  am->sm_list = (uint16_t)sm_list;
314  am->direction = direction;
315  am->priority = priority;
317 
318  am->PrefilterRegisterWithListId = PrefilterRegister;
319  am->frame_v1.alproto = alproto;
320  am->frame_v1.type = type;
321  SCLogDebug("type %u", type);
322  SCLogDebug("am type %u", am->frame_v1.type);
323 
324  if (g_mpm_list[DETECT_BUFFER_MPM_TYPE_FRAME] == NULL) {
325  g_mpm_list[DETECT_BUFFER_MPM_TYPE_FRAME] = am;
326  } else {
328  while (t->next != NULL) {
329  t = t->next;
330  }
331  t->next = am;
332  am->id = t->id + 1;
333  }
334  g_mpm_list_cnt[DETECT_BUFFER_MPM_TYPE_FRAME]++;
335 
336  SupportFastPatternForSigMatchList(sm_list, priority);
337  SCLogDebug("%s/%d done", name, sm_list);
338 }
339 
340 /** \brief copy a mpm engine from parent_id, add in transforms */
341 void DetectFrameMpmRegisterByParentId(DetectEngineCtx *de_ctx, const int id, const int parent_id,
342  DetectEngineTransforms *transforms)
343 {
344  SCLogDebug("registering %d/%d", id, parent_id);
345 
347  while (t) {
348  if (t->sm_list == parent_id) {
349  DetectBufferMpmRegistery *am = SCCalloc(1, sizeof(*am));
350  BUG_ON(am == NULL);
351  am->name = t->name;
352  snprintf(am->pname, sizeof(am->pname), "%s#%d", am->name, id);
353  DEBUG_VALIDATE_BUG_ON(id < 0 || id > UINT16_MAX);
354  am->sm_list = (uint16_t)id; // use new id
355  am->sm_list_base = t->sm_list;
358  am->frame_v1 = t->frame_v1;
359  SCLogDebug("am type %u", am->frame_v1.type);
360  am->priority = t->priority;
361  am->direction = t->direction;
363  am->next = t->next;
364  if (transforms) {
365  memcpy(&am->transforms, transforms, sizeof(*transforms));
366  }
367  am->id = de_ctx->frame_mpms_list_cnt++;
368 
370  t->next = am;
371  SCLogDebug("copied mpm registration for %s id %u "
372  "with parent %u",
373  t->name, id, parent_id);
374  t = am;
375  }
376  t = t->next;
377  }
378 }
379 
380 void DetectEngineFrameMpmRegister(DetectEngineCtx *de_ctx, const char *name, int direction,
381  int priority,
382  int (*PrefilterRegister)(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx,
383  const DetectBufferMpmRegistery *mpm_reg, int list_id),
384  AppProto alproto, uint8_t type)
385 {
386  SCLogDebug("registering %s/%d/%p/%s/%u", name, priority, PrefilterRegister,
387  AppProtoToString(alproto), type);
388 
389  const int sm_list = DetectEngineBufferTypeRegister(de_ctx, name);
390  if (sm_list < 0 || sm_list > UINT16_MAX) {
391  FatalError(SC_ERR_INITIALIZATION, "MPM engine registration for %s failed", name);
392  }
393 
397 
398  DetectBufferMpmRegistery *am = SCCalloc(1, sizeof(*am));
399  BUG_ON(am == NULL);
400  am->name = name;
401  snprintf(am->pname, sizeof(am->pname), "%s", am->name);
402  am->sm_list = (uint16_t)sm_list;
403  am->direction = direction;
404  am->priority = priority;
406 
407  am->PrefilterRegisterWithListId = PrefilterRegister;
408  am->frame_v1.alproto = alproto;
409  am->frame_v1.type = type;
410 
411  // TODO is it ok to do this here?
412 
413  /* default to whatever the global setting is */
415  /* see if we use a unique or shared mpm ctx for this type */
416  int confshared = 0;
417  if (ConfGetBool("detect.mpm.frame.shared", &confshared) == 1)
418  shared = confshared;
419 
420  if (shared == 0) {
422  } else {
424  }
425 
426  if (de_ctx->frame_mpms_list == NULL) {
427  de_ctx->frame_mpms_list = am;
428  } else {
430  while (t->next != NULL) {
431  t = t->next;
432  }
433 
434  t->next = am;
435  }
437 
438  DetectEngineRegisterFastPatternForId(de_ctx, sm_list, priority);
439  SCLogDebug("%s/%d done", name, sm_list);
440 }
441 
443 {
444  const DetectBufferMpmRegistery *list = g_mpm_list[DETECT_BUFFER_MPM_TYPE_FRAME];
445  while (list != NULL) {
446  DetectBufferMpmRegistery *n = SCCalloc(1, sizeof(*n));
447  BUG_ON(n == NULL);
448 
449  *n = *list;
450  n->next = NULL;
451 
452  if (de_ctx->frame_mpms_list == NULL) {
453  de_ctx->frame_mpms_list = n;
454  } else {
456  while (t->next != NULL) {
457  t = t->next;
458  }
459 
460  t->next = n;
461  }
462 
463  /* default to whatever the global setting is */
465 
466  /* see if we use a unique or shared mpm ctx for this type */
467  int confshared = 0;
468  char confstring[256] = "detect.mpm.";
469  strlcat(confstring, n->name, sizeof(confstring));
470  strlcat(confstring, ".shared", sizeof(confstring));
471  if (ConfGetBool(confstring, &confshared) == 1)
472  shared = confshared;
473 
474  if (shared == 0) {
475  if (!(de_ctx->flags & DE_QUIET)) {
476  SCLogPerf("using unique mpm ctx' for %s", n->name);
477  }
479  } else {
480  if (!(de_ctx->flags & DE_QUIET)) {
481  SCLogPerf("using shared mpm ctx' for %s", n->name);
482  }
484  }
485 
486  list = list->next;
487  }
489  SCLogDebug("mpm: de_ctx frame_mpms_list %p %u", de_ctx->frame_mpms_list,
491 }
492 
493 /**
494  * \brief initialize mpm contexts for applayer buffers that are in
495  * "single or "shared" mode.
496  */
498 {
499  SCLogDebug("preparing frame mpm");
500  int r = 0;
502  while (am != NULL) {
503  SCLogDebug("am %p %s sgh_mpm_context %d", am, am->name, am->sgh_mpm_context);
504  SCLogDebug("%s", am->name);
506  int dir = (am->direction == SIG_FLAG_TOSERVER) ? 1 : 0;
508  SCLogDebug("%s: %d mpm_Ctx %p", am->name, r, mpm_ctx);
509  if (mpm_ctx != NULL) {
510  if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
511  r |= mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
512  SCLogDebug("%s: %d", am->name, r);
513  }
514  }
515  }
516  am = am->next;
517  }
518  return r;
519 }
520 
521 /** \brief register a MPM engine
522  *
523  * \note to be used at start up / registration only. Errors are fatal.
524  */
525 void DetectPktMpmRegister(const char *name,
526  int priority,
527  int (*PrefilterRegister)(DetectEngineCtx *de_ctx,
528  SigGroupHead *sgh, MpmCtx *mpm_ctx,
529  const DetectBufferMpmRegistery *mpm_reg, int list_id),
531 {
532  SCLogDebug("registering %s/%d/%p/%p", name, priority,
533  PrefilterRegister, GetData);
534 
535  if (PrefilterRegister == PrefilterGenericMpmPktRegister && GetData == NULL) {
536  // must register GetData with PrefilterGenericMpmRegister
537  abort();
538  }
539 
542  int sm_list = DetectBufferTypeGetByName(name);
543  if (sm_list == -1) {
545  "MPM engine registration for %s failed", name);
546  }
547 
548  DetectBufferMpmRegistery *am = SCCalloc(1, sizeof(*am));
549  BUG_ON(am == NULL);
550  am->name = name;
551  snprintf(am->pname, sizeof(am->pname), "%s", am->name);
552  DEBUG_VALIDATE_BUG_ON(sm_list < 0 || sm_list > INT16_MAX);
553  am->sm_list = (uint16_t)sm_list;
554  am->priority = priority;
556 
557  am->PrefilterRegisterWithListId = PrefilterRegister;
558  am->pkt_v1.GetData = GetData;
559 
560  if (g_mpm_list[DETECT_BUFFER_MPM_TYPE_PKT] == NULL) {
561  g_mpm_list[DETECT_BUFFER_MPM_TYPE_PKT] = am;
562  } else {
564  while (t->next != NULL) {
565  t = t->next;
566  }
567  t->next = am;
568  am->id = t->id + 1;
569  }
570  g_mpm_list_cnt[DETECT_BUFFER_MPM_TYPE_PKT]++;
571 
572  SupportFastPatternForSigMatchList(sm_list, priority);
573  SCLogDebug("%s/%d done", name, sm_list);
574 }
575 
576 /** \brief copy a mpm engine from parent_id, add in transforms */
578  const int id, const int parent_id,
579  DetectEngineTransforms *transforms)
580 {
581  SCLogDebug("registering %d/%d", id, parent_id);
582 
584  while (t) {
585  if (t->sm_list == parent_id) {
586  DetectBufferMpmRegistery *am = SCCalloc(1, sizeof(*am));
587  BUG_ON(am == NULL);
588  am->name = t->name;
589  snprintf(am->pname, sizeof(am->pname), "%s#%d", am->name, id);
590  DEBUG_VALIDATE_BUG_ON(id < 0 || id > INT16_MAX);
591  am->sm_list = (uint16_t)id; // use new id
592  am->sm_list_base = t->sm_list;
595  am->pkt_v1.GetData = t->pkt_v1.GetData;
596  am->priority = t->priority;
598  am->next = t->next;
599  if (transforms) {
600  memcpy(&am->transforms, transforms, sizeof(*transforms));
601  }
602  am->id = de_ctx->pkt_mpms_list_cnt++;
603 
605  t->next = am;
606  SCLogDebug("copied mpm registration for %s id %u "
607  "with parent %u and GetData %p",
608  t->name, id, parent_id, am->pkt_v1.GetData);
609  t = am;
610  }
611  t = t->next;
612  }
613 }
614 
616 {
617  const DetectBufferMpmRegistery *list = g_mpm_list[DETECT_BUFFER_MPM_TYPE_PKT];
618  while (list != NULL) {
619  DetectBufferMpmRegistery *n = SCCalloc(1, sizeof(*n));
620  BUG_ON(n == NULL);
621 
622  *n = *list;
623  n->next = NULL;
624 
625  if (de_ctx->pkt_mpms_list == NULL) {
626  de_ctx->pkt_mpms_list = n;
627  } else {
629  while (t->next != NULL) {
630  t = t->next;
631  }
632 
633  t->next = n;
634  }
635 
636  /* default to whatever the global setting is */
638 
639  /* see if we use a unique or shared mpm ctx for this type */
640  int confshared = 0;
641  char confstring[256] = "detect.mpm.";
642  strlcat(confstring, n->name, sizeof(confstring));
643  strlcat(confstring, ".shared", sizeof(confstring));
644  if (ConfGetBool(confstring, &confshared) == 1)
645  shared = confshared;
646 
647  if (shared == 0) {
648  if (!(de_ctx->flags & DE_QUIET)) {
649  SCLogPerf("using unique mpm ctx' for %s", n->name);
650  }
652  } else {
653  if (!(de_ctx->flags & DE_QUIET)) {
654  SCLogPerf("using shared mpm ctx' for %s", n->name);
655  }
657  }
658 
659  list = list->next;
660  }
662  SCLogDebug("mpm: de_ctx pkt_mpms_list %p %u",
664 }
665 
666 /**
667  * \brief initialize mpm contexts for applayer buffers that are in
668  * "single or "shared" mode.
669  */
671 {
672  SCLogDebug("preparing pkt mpm");
673  int r = 0;
675  while (am != NULL) {
676  SCLogDebug("%s", am->name);
678  {
680  if (mpm_ctx != NULL) {
681  if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
682  r |= mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
683  SCLogDebug("%s: %d", am->name, r);
684  }
685  }
686  }
687  am = am->next;
688  }
689  return r;
690 }
691 
692 static int32_t SetupBuiltinMpm(DetectEngineCtx *de_ctx, const char *name)
693 {
694  /* default to whatever the global setting is */
696 
697  /* see if we use a unique or shared mpm ctx for this type */
698  int confshared = 0;
699  char confstring[256] = "detect.mpm.";
700  strlcat(confstring, name, sizeof(confstring));
701  strlcat(confstring, ".shared", sizeof(confstring));
702  if (ConfGetBool(confstring, &confshared) == 1)
703  shared = confshared;
704 
705  int32_t ctx;
706  if (shared == 0) {
708  SCLogPerf("using unique mpm ctx' for %s", name);
709  } else {
711  SCLogPerf("using shared mpm ctx' for %s", name);
712  }
713  return ctx;
714 }
715 
717 {
718  de_ctx->sgh_mpm_context_proto_tcp_packet = SetupBuiltinMpm(de_ctx, "tcp-packet");
719  de_ctx->sgh_mpm_context_stream = SetupBuiltinMpm(de_ctx, "tcp-stream");
720 
721  de_ctx->sgh_mpm_context_proto_udp_packet = SetupBuiltinMpm(de_ctx, "udp-packet");
722  de_ctx->sgh_mpm_context_proto_other_packet = SetupBuiltinMpm(de_ctx, "other-ip");
723 }
724 
725 /**
726  * \brief initialize mpm contexts for builtin buffers that are in
727  * "single or "shared" mode.
728  */
730 {
731  int r = 0;
732  MpmCtx *mpm_ctx = NULL;
733 
736  if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
737  r |= mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
738  }
740  if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
741  r |= mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
742  }
743  }
744 
747  if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
748  r |= mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
749  }
751  if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
752  r |= mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
753  }
754  }
755 
758  if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
759  r |= mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
760  }
761  }
762 
765  if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
766  r |= mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
767  }
769  if (mpm_table[de_ctx->mpm_matcher].Prepare != NULL) {
770  r |= mpm_table[de_ctx->mpm_matcher].Prepare(mpm_ctx);
771  }
772  }
773 
774  return r;
775 }
776 
777 /**
778  * \brief check if a signature has patterns that are to be inspected
779  * against a packets payload (as opposed to the stream payload)
780  *
781  * \param s signature
782  *
783  * \retval 1 true
784  * \retval 0 false
785  */
787 {
788  SCEnter();
789 
790  if (s == NULL) {
791  SCReturnInt(0);
792  }
793 
794  if (!(s->proto.proto[IPPROTO_TCP / 8] & 1 << (IPPROTO_TCP % 8))) {
795  SCReturnInt(1);
796  }
797 
798  if ((s->init_data != NULL && s->init_data->smlists[DETECT_SM_LIST_PMATCH] == NULL) ||
799  (s->init_data == NULL && s->sm_arrays[DETECT_SM_LIST_PMATCH] == NULL))
800  {
801  SCLogDebug("no mpm");
802  SCReturnInt(0);
803  }
804 
805  if (!(s->flags & SIG_FLAG_REQUIRE_PACKET)) {
806  SCReturnInt(0);
807  }
808 
809  SCReturnInt(1);
810 }
811 
812 /**
813  * \brief check if a signature has patterns that are to be inspected
814  * against the stream payload (as opposed to the individual packets
815  * payload(s))
816  *
817  * \param s signature
818  *
819  * \retval 1 true
820  * \retval 0 false
821  */
823 {
824  SCEnter();
825 
826  if (s == NULL) {
827  SCReturnInt(0);
828  }
829 
830  if (!(s->proto.proto[IPPROTO_TCP / 8] & 1 << (IPPROTO_TCP % 8))) {
831  SCReturnInt(0);
832  }
833 
834  if ((s->init_data != NULL && s->init_data->smlists[DETECT_SM_LIST_PMATCH] == NULL) ||
835  (s->init_data == NULL && s->sm_arrays[DETECT_SM_LIST_PMATCH] == NULL))
836  {
837  SCLogDebug("no mpm");
838  SCReturnInt(0);
839  }
840 
841  if (!(s->flags & SIG_FLAG_REQUIRE_STREAM)) {
842  SCReturnInt(0);
843  }
844 
845  SCReturnInt(1);
846 }
847 
848 
849 /**
850  * \brief Function to return the multi pattern matcher algorithm to be
851  * used by the engine, based on the mpm-algo setting in yaml
852  * Use the default mpm if none is specified in the yaml file.
853  *
854  * \retval mpm algo value
855  */
857 {
858  const char *mpm_algo;
859  uint8_t mpm_algo_val = mpm_default_matcher;
860 
861  /* Get the mpm algo defined in config file by the user */
862  if ((ConfGet("mpm-algo", &mpm_algo)) == 1) {
863  if (mpm_algo != NULL) {
864 #if __BYTE_ORDER == __BIG_ENDIAN
865  if (strcmp(mpm_algo, "ac-ks") == 0) {
866  FatalError(SC_ERR_FATAL, "ac-ks does "
867  "not work on big endian systems at this time.");
868  }
869 #endif
870  if (strcmp("auto", mpm_algo) == 0) {
871  goto done;
872  }
873  for (uint8_t u = 0; u < MPM_TABLE_SIZE; u++) {
874  if (mpm_table[u].name == NULL)
875  continue;
876 
877  if (strcmp(mpm_table[u].name, mpm_algo) == 0) {
878  mpm_algo_val = u;
879  goto done;
880  }
881  }
882 
883 #ifndef BUILD_HYPERSCAN
884  if ((strcmp(mpm_algo, "hs") == 0)) {
885  FatalError(SC_ERR_INVALID_VALUE, "Hyperscan (hs) support for mpm-algo is "
886  "not compiled into Suricata.");
887  }
888 #endif
889  }
890  FatalError(SC_ERR_INVALID_YAML_CONF_ENTRY, "Invalid mpm algo supplied "
891  "in the yaml conf file: \"%s\"", mpm_algo);
892  }
893 
894  done:
895  return mpm_algo_val;
896 }
897 
898 void PatternMatchDestroy(MpmCtx *mpm_ctx, uint16_t mpm_matcher)
899 {
900  SCLogDebug("mpm_ctx %p, mpm_matcher %"PRIu16"", mpm_ctx, mpm_matcher);
901  mpm_table[mpm_matcher].DestroyCtx(mpm_ctx);
902 }
903 
904 void PatternMatchThreadPrint(MpmThreadCtx *mpm_thread_ctx, uint16_t mpm_matcher)
905 {
906  SCLogDebug("mpm_thread_ctx %p, mpm_matcher %"PRIu16" defunct", mpm_thread_ctx, mpm_matcher);
907  //mpm_table[mpm_matcher].PrintThreadCtx(mpm_thread_ctx);
908 }
909 void PatternMatchThreadDestroy(MpmThreadCtx *mpm_thread_ctx, uint16_t mpm_matcher)
910 {
911  SCLogDebug("mpm_thread_ctx %p, mpm_matcher %"PRIu16"", mpm_thread_ctx, mpm_matcher);
912  if (mpm_table[mpm_matcher].DestroyThreadCtx != NULL)
913  mpm_table[mpm_matcher].DestroyThreadCtx(NULL, mpm_thread_ctx);
914 }
915 void PatternMatchThreadPrepare(MpmThreadCtx *mpm_thread_ctx, uint16_t mpm_matcher)
916 {
917  SCLogDebug("mpm_thread_ctx %p, type %"PRIu16, mpm_thread_ctx, mpm_matcher);
918  MpmInitThreadCtx(mpm_thread_ctx, mpm_matcher);
919 }
920 
921 /** \brief Predict a strength value for patterns
922  *
923  * Patterns with high character diversity score higher.
924  * Alpha chars score not so high
925  * Other printable + a few common codes a little higher
926  * Everything else highest.
927  * Longer patterns score better than short patters.
928  *
929  * \param pat pattern
930  * \param patlen length of the pattern
931  *
932  * \retval s pattern score
933  */
934 uint32_t PatternStrength(uint8_t *pat, uint16_t patlen)
935 {
936  uint8_t a[256];
937  memset(&a, 0 ,sizeof(a));
938 
939  uint32_t s = 0;
940  uint16_t u = 0;
941  for (u = 0; u < patlen; u++) {
942  if (a[pat[u]] == 0) {
943  if (isalpha(pat[u]))
944  s += 3;
945  else if (isprint(pat[u]) || pat[u] == 0x00 || pat[u] == 0x01 || pat[u] == 0xFF)
946  s += 4;
947  else
948  s += 6;
949 
950  a[pat[u]] = 1;
951  } else {
952  s++;
953  }
954  }
955 
956  return s;
957 }
958 
959 static void PopulateMpmHelperAddPattern(MpmCtx *mpm_ctx,
960  const DetectContentData *cd,
961  const Signature *s, uint8_t flags,
962  int chop)
963 {
964  uint16_t pat_offset = cd->offset;
965  uint16_t pat_depth = cd->depth;
966 
967  /* recompute offset/depth to cope with chop */
968  if (chop && (pat_depth || pat_offset)) {
969  pat_offset += cd->fp_chop_offset;
970  if (pat_depth) {
971  pat_depth -= cd->content_len;
972  pat_depth += cd->fp_chop_offset + cd->fp_chop_len;
973  }
974  }
975 
976  /* We have to effectively "wild card" values that will be coming from
977  * byte_extract variables
978  */
980  pat_depth = pat_offset = 0;
981  }
982 
983  if (cd->flags & DETECT_CONTENT_NOCASE) {
984  if (chop) {
985  MpmAddPatternCI(mpm_ctx,
986  cd->content + cd->fp_chop_offset, cd->fp_chop_len,
987  pat_offset, pat_depth,
989  } else {
990  MpmAddPatternCI(mpm_ctx,
991  cd->content, cd->content_len,
992  pat_offset, pat_depth,
994  }
995  } else {
996  if (chop) {
997  MpmAddPatternCS(mpm_ctx,
998  cd->content + cd->fp_chop_offset, cd->fp_chop_len,
999  pat_offset, pat_depth,
1000  cd->id, s->num, flags|MPM_PATTERN_CTX_OWNS_ID);
1001  } else {
1002  MpmAddPatternCS(mpm_ctx,
1003  cd->content, cd->content_len,
1004  pat_offset, pat_depth,
1005  cd->id, s->num, flags|MPM_PATTERN_CTX_OWNS_ID);
1006  }
1007  }
1008 
1009  return;
1010 }
1011 
1012 #define SGH_PROTO(sgh, p) ((sgh)->init->protos[(p)] == 1)
1013 #define SGH_DIRECTION_TS(sgh) ((sgh)->init->direction & SIG_FLAG_TOSERVER)
1014 #define SGH_DIRECTION_TC(sgh) ((sgh)->init->direction & SIG_FLAG_TOCLIENT)
1016 static void SetMpm(Signature *s, SigMatch *mpm_sm, const int mpm_sm_list)
1017 {
1018  if (s == NULL || mpm_sm == NULL)
1019  return;
1020 
1021  DetectContentData *cd = (DetectContentData *)mpm_sm->ctx;
1023  if (DETECT_CONTENT_IS_SINGLE(cd) &&
1024  !(cd->flags & DETECT_CONTENT_NEGATED) &&
1025  !(cd->flags & DETECT_CONTENT_REPLACE) &&
1026  cd->content_len == cd->fp_chop_len)
1027  {
1029  }
1030  } else {
1031  if (DETECT_CONTENT_IS_SINGLE(cd) &&
1032  !(cd->flags & DETECT_CONTENT_NEGATED) &&
1033  !(cd->flags & DETECT_CONTENT_REPLACE))
1034  {
1036  }
1037  }
1038  cd->flags |= DETECT_CONTENT_MPM;
1039  s->init_data->mpm_sm_list = mpm_sm_list;
1040  s->init_data->mpm_sm = mpm_sm;
1041  return;
1042 }
1043 
1044 static SigMatch *GetMpmForList(const Signature *s, const int list, SigMatch *mpm_sm,
1045  uint16_t max_len, bool skip_negated_content)
1046 {
1047  for (SigMatch *sm = s->init_data->smlists[list]; sm != NULL; sm = sm->next) {
1048  if (sm->type != DETECT_CONTENT)
1049  continue;
1050 
1051  const DetectContentData *cd = (DetectContentData *)sm->ctx;
1052  /* skip_negated_content is only set if there's absolutely no
1053  * non-negated content present in the sig */
1054  if ((cd->flags & DETECT_CONTENT_NEGATED) && skip_negated_content)
1055  continue;
1056  if (cd->content_len != max_len)
1057  continue;
1058 
1059  if (mpm_sm == NULL) {
1060  mpm_sm = sm;
1061  } else {
1062  DetectContentData *data1 = (DetectContentData *)sm->ctx;
1063  DetectContentData *data2 = (DetectContentData *)mpm_sm->ctx;
1064  uint32_t ls = PatternStrength(data1->content, data1->content_len);
1065  uint32_t ss = PatternStrength(data2->content, data2->content_len);
1066  if (ls > ss) {
1067  mpm_sm = sm;
1068  } else if (ls == ss) {
1069  /* if 2 patterns are of equal strength, we pick the longest */
1070  if (data1->content_len > data2->content_len)
1071  mpm_sm = sm;
1072  } else {
1073  SCLogDebug("sticking with mpm_sm");
1074  }
1075  }
1076  }
1077  return mpm_sm;
1078 }
1079 
1081 {
1082  if (s->init_data->mpm_sm != NULL)
1083  return;
1084 
1085  SigMatch *sm = NULL;
1086  const int nlists = s->init_data->smlists_array_size;
1087  int nn_sm_list[nlists];
1088  int n_sm_list[nlists];
1089  memset(nn_sm_list, 0, nlists * sizeof(int));
1090  memset(n_sm_list, 0, nlists * sizeof(int));
1091  int count_nn_sm_list = 0;
1092  int count_n_sm_list = 0;
1093 
1094  /* inspect rule to see if we have the fast_pattern reg to
1095  * force using a sig, otherwise keep stats about the patterns */
1096  for (int list_id = DETECT_SM_LIST_PMATCH; list_id < nlists; list_id++) {
1097  if (s->init_data->smlists[list_id] == NULL)
1098  continue;
1099 
1100  if (list_id == DETECT_SM_LIST_POSTMATCH || list_id == DETECT_SM_LIST_TMATCH ||
1101  list_id == DETECT_SM_LIST_SUPPRESS || list_id == DETECT_SM_LIST_THRESHOLD)
1102  continue;
1103 
1105  continue;
1106 
1107  for (sm = s->init_data->smlists[list_id]; sm != NULL; sm = sm->next) {
1108  if (sm->type != DETECT_CONTENT)
1109  continue;
1110 
1111  const DetectContentData *cd = (DetectContentData *)sm->ctx;
1112  /* fast_pattern set in rule, so using this pattern */
1113  if ((cd->flags & DETECT_CONTENT_FAST_PATTERN)) {
1114  SetMpm(s, sm, list_id);
1115  return;
1116  }
1117 
1118  if (cd->flags & DETECT_CONTENT_NEGATED) {
1119  n_sm_list[list_id] = 1;
1120  count_n_sm_list++;
1121  } else {
1122  nn_sm_list[list_id] = 1;
1123  count_nn_sm_list++;
1124  }
1125  }
1126  }
1127 
1128  /* prefer normal not-negated over negated */
1129  int *curr_sm_list = NULL;
1130  int skip_negated_content = 1;
1131  if (count_nn_sm_list > 0) {
1132  curr_sm_list = nn_sm_list;
1133  } else if (count_n_sm_list > 0) {
1134  curr_sm_list = n_sm_list;
1135  skip_negated_content = 0;
1136  } else {
1137  return;
1138  }
1139 
1140  int final_sm_list[nlists];
1141  memset(&final_sm_list, 0, (nlists * sizeof(int)));
1142 
1143  int count_final_sm_list = 0;
1144  int priority;
1145 
1147  while (tmp != NULL) {
1148  for (priority = tmp->priority;
1149  tmp != NULL && priority == tmp->priority;
1150  tmp = tmp->next)
1151  {
1152  SCLogDebug("tmp->list_id %d tmp->priority %d", tmp->list_id, tmp->priority);
1153  if (tmp->list_id >= nlists)
1154  continue;
1155  if (curr_sm_list[tmp->list_id] == 0)
1156  continue;
1157  final_sm_list[count_final_sm_list++] = tmp->list_id;
1158  }
1159  if (count_final_sm_list != 0)
1160  break;
1161  }
1162 
1163  BUG_ON(count_final_sm_list == 0);
1164 
1165  uint16_t max_len = 0;
1166  for (int i = 0; i < count_final_sm_list; i++) {
1167  if (final_sm_list[i] >= (int)s->init_data->smlists_array_size)
1168  continue;
1169 
1170  for (sm = s->init_data->smlists[final_sm_list[i]]; sm != NULL; sm = sm->next) {
1171  if (sm->type != DETECT_CONTENT)
1172  continue;
1173 
1174  const DetectContentData *cd = (DetectContentData *)sm->ctx;
1175  /* skip_negated_content is only set if there's absolutely no
1176  * non-negated content present in the sig */
1177  if ((cd->flags & DETECT_CONTENT_NEGATED) && skip_negated_content)
1178  continue;
1179  if (max_len < cd->content_len)
1180  max_len = cd->content_len;
1181  }
1182  }
1183 
1184  SigMatch *mpm_sm = NULL;
1185  int mpm_sm_list = -1;
1186  for (int i = 0; i < count_final_sm_list; i++) {
1187  if (final_sm_list[i] >= (int)s->init_data->smlists_array_size)
1188  continue;
1189 
1190  /* GetMpmForList may keep `mpm_sm` the same, so track if it changed */
1191  SigMatch *prev_mpm_sm = mpm_sm;
1192  mpm_sm = GetMpmForList(s, final_sm_list[i], mpm_sm, max_len, skip_negated_content);
1193  if (mpm_sm != prev_mpm_sm) {
1194  mpm_sm_list = final_sm_list[i];
1195  }
1196  }
1197 
1198 #ifdef DEBUG
1199  if (mpm_sm != NULL) {
1200  BUG_ON(mpm_sm_list == -1);
1201  int check_list = SigMatchListSMBelongsTo(s, mpm_sm);
1202  BUG_ON(check_list != mpm_sm_list);
1203  }
1204 #endif
1205  /* assign to signature */
1206  SetMpm(s, mpm_sm, mpm_sm_list);
1207  return;
1208 }
1209 
1210 /** \internal
1211  * \brief The hash function for MpmStore
1212  *
1213  * \param ht Pointer to the hash table.
1214  * \param data Pointer to the MpmStore.
1215  * \param datalen Not used in our case.
1216  *
1217  * \retval hash The generated hash value.
1218  */
1219 static uint32_t MpmStoreHashFunc(HashListTable *ht, void *data, uint16_t datalen)
1220 {
1221  const MpmStore *ms = (MpmStore *)data;
1222  uint32_t hash = 0;
1223  uint32_t b = 0;
1224 
1225  for (b = 0; b < ms->sid_array_size; b++)
1226  hash += ms->sid_array[b];
1227 
1228  return hash % ht->array_size;
1229 }
1230 
1231 /**
1232  * \brief The Compare function for MpmStore
1233  *
1234  * \param data1 Pointer to the first MpmStore.
1235  * \param len1 Not used.
1236  * \param data2 Pointer to the second MpmStore.
1237  * \param len2 Not used.
1238  *
1239  * \retval 1 If the 2 MpmStores sent as args match.
1240  * \retval 0 If the 2 MpmStores sent as args do not match.
1241  */
1242 static char MpmStoreCompareFunc(void *data1, uint16_t len1, void *data2,
1243  uint16_t len2)
1244 {
1245  const MpmStore *ms1 = (MpmStore *)data1;
1246  const MpmStore *ms2 = (MpmStore *)data2;
1247 
1248  if (ms1->sid_array_size != ms2->sid_array_size)
1249  return 0;
1250 
1251  if (ms1->buffer != ms2->buffer)
1252  return 0;
1253 
1254  if (ms1->direction != ms2->direction)
1255  return 0;
1256 
1257  if (ms1->sm_list != ms2->sm_list)
1258  return 0;
1259 
1260  if (SCMemcmp(ms1->sid_array, ms2->sid_array,
1261  ms1->sid_array_size) != 0)
1262  {
1263  return 0;
1264  }
1265 
1266  return 1;
1267 }
1268 
1269 static void MpmStoreFreeFunc(void *ptr)
1270 {
1271  MpmStore *ms = ptr;
1272  if (ms != NULL) {
1273  if (ms->mpm_ctx != NULL && !(ms->mpm_ctx->flags & MPMCTX_FLAGS_GLOBAL))
1274  {
1275  SCLogDebug("destroying mpm_ctx %p", ms->mpm_ctx);
1277  SCFree(ms->mpm_ctx);
1278  }
1279  ms->mpm_ctx = NULL;
1280 
1281  SCFree(ms->sid_array);
1282  SCFree(ms);
1283  }
1284 }
1285 
1286 /**
1287  * \brief Initializes the MpmStore mpm hash table to be used by the detection
1288  * engine context.
1289  *
1290  * \param de_ctx Pointer to the detection engine context.
1291  *
1292  * \retval 0 On success.
1293  * \retval -1 On failure.
1294  */
1296 {
1298  MpmStoreHashFunc,
1299  MpmStoreCompareFunc,
1300  MpmStoreFreeFunc);
1301  if (de_ctx->mpm_hash_table == NULL)
1302  goto error;
1303 
1304  return 0;
1305 
1306 error:
1307  return -1;
1308 }
1309 
1310 /**
1311  * \brief Adds a MpmStore to the detection engine context MpmStore
1312  *
1313  * \param de_ctx Pointer to the detection engine context.
1314  * \param sgh Pointer to the MpmStore.
1315  *
1316  * \retval ret 0 on Successfully adding the argument sgh; -1 on failure.
1317  */
1318 static int MpmStoreAdd(DetectEngineCtx *de_ctx, MpmStore *s)
1319 {
1320  int ret = HashListTableAdd(de_ctx->mpm_hash_table, (void *)s, 0);
1321  return ret;
1322 }
1323 
1324 /**
1325  * \brief Used to lookup a MpmStore from the MpmStore
1326  *
1327  * \param de_ctx Pointer to the detection engine context.
1328  * \param sgh Pointer to the MpmStore.
1329  *
1330  * \retval rsgh On success a pointer to the MpmStore if the MpmStore is
1331  * found in the hash table; NULL on failure.
1332  */
1333 static MpmStore *MpmStoreLookup(DetectEngineCtx *de_ctx, MpmStore *s)
1334 {
1336  (void *)s, 0);
1337  return rs;
1338 }
1339 
1340 static const DetectBufferMpmRegistery *GetByMpmStore(const DetectEngineCtx *de_ctx,
1341  const MpmStore *ms)
1342 {
1344  while (am != NULL) {
1345  if (ms->sm_list == am->sm_list &&
1346  ms->direction == am->direction) {
1347  return am;
1348  }
1349  am = am->next;
1350  }
1351  am = de_ctx->pkt_mpms_list;
1352  while (am != NULL) {
1353  if (ms->sm_list == am->sm_list) {
1354  return am;
1355  }
1356  am = am->next;
1357  }
1358  return NULL;
1359 }
1360 
1362 {
1363  HashListTableBucket *htb = NULL;
1364 
1365  uint32_t stats[MPMB_MAX] = {0};
1366  int app_mpms_cnt = de_ctx->buffer_type_id;
1367  uint32_t appstats[app_mpms_cnt + 1]; // +1 to silence scan-build
1368  memset(&appstats, 0x00, sizeof(appstats));
1369  int pkt_mpms_cnt = de_ctx->buffer_type_id;
1370  uint32_t pktstats[pkt_mpms_cnt + 1]; // +1 to silence scan-build
1371  memset(&pktstats, 0x00, sizeof(pktstats));
1372  int frame_mpms_cnt = de_ctx->buffer_type_id;
1373  uint32_t framestats[frame_mpms_cnt + 1]; // +1 to silence scan-build
1374  memset(&framestats, 0x00, sizeof(framestats));
1375 
1377  htb != NULL;
1378  htb = HashListTableGetListNext(htb))
1379  {
1380  const MpmStore *ms = (MpmStore *)HashListTableGetListData(htb);
1381  if (ms == NULL || ms->mpm_ctx == NULL) {
1382  continue;
1383  }
1384  if (ms->buffer < MPMB_MAX)
1385  stats[ms->buffer]++;
1386  else if (ms->sm_list != DETECT_SM_LIST_PMATCH) {
1387  const DetectBufferMpmRegistery *am = GetByMpmStore(de_ctx, ms);
1388  if (am != NULL) {
1389  switch (am->type) {
1391  SCLogDebug("%s: %u patterns. Min %u, Max %u. Ctx %p",
1392  am->name,
1393  ms->mpm_ctx->pattern_cnt,
1394  ms->mpm_ctx->minlen, ms->mpm_ctx->maxlen,
1395  ms->mpm_ctx);
1396  pktstats[am->sm_list]++;
1397  break;
1399  SCLogDebug("%s %s: %u patterns. Min %u, Max %u. Ctx %p",
1400  am->name,
1401  am->direction == SIG_FLAG_TOSERVER ? "toserver":"toclient",
1402  ms->mpm_ctx->pattern_cnt,
1403  ms->mpm_ctx->minlen, ms->mpm_ctx->maxlen,
1404  ms->mpm_ctx);
1405  appstats[am->sm_list]++;
1406  break;
1408  SCLogDebug("%s: %u patterns. Min %u, Max %u. Ctx %p", am->name,
1409  ms->mpm_ctx->pattern_cnt, ms->mpm_ctx->minlen, ms->mpm_ctx->maxlen,
1410  ms->mpm_ctx);
1411  framestats[am->sm_list]++;
1412  break;
1414  break;
1415  }
1416  }
1417  }
1418  }
1419 
1420  if (!(de_ctx->flags & DE_QUIET)) {
1421  for (int x = 0; x < MPMB_MAX; x++) {
1422  SCLogPerf("Builtin MPM \"%s\": %u", builtin_mpms[x], stats[x]);
1423  }
1425  while (am != NULL) {
1426  if (appstats[am->sm_list] > 0) {
1427  const char *name = am->name;
1428  const char *direction = am->direction == SIG_FLAG_TOSERVER ? "toserver" : "toclient";
1429  SCLogPerf("AppLayer MPM \"%s %s (%s)\": %u", direction, name,
1430  AppProtoToString(am->app_v2.alproto), appstats[am->sm_list]);
1431  }
1432  am = am->next;
1433  }
1435  while (pm != NULL) {
1436  if (pktstats[pm->sm_list] > 0) {
1437  const char *name = pm->name;
1438  SCLogPerf("Pkt MPM \"%s\": %u", name, pktstats[pm->sm_list]);
1439  }
1440  pm = pm->next;
1441  }
1443  while (um != NULL) {
1444  if (framestats[um->sm_list] > 0) {
1445  const char *name = um->name;
1446  SCLogPerf("Frame MPM \"%s\": %u", name, framestats[um->sm_list]);
1447  }
1448  um = um->next;
1449  }
1450  }
1451 }
1452 
1453 /**
1454  * \brief Frees the hash table - DetectEngineCtx->mpm_hash_table, allocated by
1455  * MpmStoreInit() function.
1456  *
1457  * \param de_ctx Pointer to the detection engine context.
1458  */
1460 {
1461  if (de_ctx->mpm_hash_table == NULL)
1462  return;
1463 
1465  de_ctx->mpm_hash_table = NULL;
1466  return;
1467 }
1468 
1469 static void MpmStoreSetup(const DetectEngineCtx *de_ctx, MpmStore *ms)
1470 {
1471  const Signature *s = NULL;
1472  uint32_t sig;
1473  int dir = 0;
1474 
1475  if (ms->buffer != MPMB_MAX) {
1477 
1478  switch (ms->buffer) {
1479  /* TS is 1 */
1480  case MPMB_TCP_PKT_TS:
1481  case MPMB_TCP_STREAM_TS:
1482  case MPMB_UDP_TS:
1483  dir = 1;
1484  break;
1485 
1486  /* TC is 0 */
1487  default:
1488  case MPMB_UDP_TC:
1489  case MPMB_TCP_STREAM_TC:
1490  case MPMB_TCP_PKT_TC:
1491  case MPMB_OTHERIP: /**< use 0 for other */
1492  dir = 0;
1493  break;
1494  }
1495  } else {
1497 
1498  if (ms->direction == SIG_FLAG_TOSERVER)
1499  dir = 1;
1500  else
1501  dir = 0;
1502  }
1503 
1505  if (ms->mpm_ctx == NULL) {
1506  return;
1507  }
1508 
1510 
1511  /* add the patterns */
1512  for (sig = 0; sig < (ms->sid_array_size * 8); sig++) {
1513  if (ms->sid_array[sig / 8] & (1 << (sig % 8))) {
1514  s = de_ctx->sig_array[sig];
1515  if (s == NULL)
1516  continue;
1517  if ((s->flags & ms->direction) == 0) {
1518  SCLogDebug("s->flags %x ms->direction %x", s->flags, ms->direction);
1519  continue;
1520  }
1521  if (s->init_data->mpm_sm == NULL)
1522  continue;
1523  int list = s->init_data->mpm_sm_list;
1524  if (list < 0)
1525  continue;
1526  if (list != ms->sm_list)
1527  continue;
1528 
1529  SCLogDebug("adding %u", s->id);
1530 
1532 
1533  int skip = 0;
1534  /* negated logic: if mpm match can't be used to be sure about this
1535  * pattern, we have to inspect the rule fully regardless of mpm
1536  * match. So in this case there is no point of adding it at all.
1537  * The non-mpm list entry for the sig will make sure the sig is
1538  * inspected. */
1539  if ((cd->flags & DETECT_CONTENT_NEGATED) &&
1541  {
1542  skip = 1;
1543  SCLogDebug("not adding negated mpm as it's not 'single'");
1544  }
1545 
1546  if (!skip) {
1547  PopulateMpmHelperAddPattern(ms->mpm_ctx,
1548  cd, s, 0, (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP));
1549  }
1550  }
1551  }
1552 
1553  if (ms->mpm_ctx->pattern_cnt == 0) {
1555  ms->mpm_ctx = NULL;
1556  } else {
1558  if (mpm_table[ms->mpm_ctx->mpm_type].Prepare != NULL) {
1560  }
1561  }
1562  }
1563 }
1564 
1565 
1566 /** \brief Get MpmStore for a built-in buffer type
1567  *
1568  */
1570  enum MpmBuiltinBuffers buf)
1571 {
1572  const Signature *s = NULL;
1573  uint32_t sig;
1574  uint32_t cnt = 0;
1575  int direction = 0;
1576  uint32_t max_sid = DetectEngineGetMaxSigId(de_ctx) / 8 + 1;
1577  uint8_t sids_array[max_sid];
1578  memset(sids_array, 0x00, max_sid);
1579  int sgh_mpm_context = 0;
1580  int sm_list = DETECT_SM_LIST_PMATCH;
1581 
1582  switch (buf) {
1583  case MPMB_TCP_PKT_TS:
1584  case MPMB_TCP_PKT_TC:
1585  sgh_mpm_context = de_ctx->sgh_mpm_context_proto_tcp_packet;
1586  break;
1587  case MPMB_TCP_STREAM_TS:
1588  case MPMB_TCP_STREAM_TC:
1589  sgh_mpm_context = de_ctx->sgh_mpm_context_stream;
1590  break;
1591  case MPMB_UDP_TS:
1592  case MPMB_UDP_TC:
1593  sgh_mpm_context = de_ctx->sgh_mpm_context_proto_udp_packet;
1594  break;
1595  case MPMB_OTHERIP:
1596  sgh_mpm_context = de_ctx->sgh_mpm_context_proto_other_packet;
1597  break;
1598  default:
1599  break;
1600  }
1601 
1602  switch(buf) {
1603  case MPMB_TCP_PKT_TS:
1604  case MPMB_TCP_STREAM_TS:
1605  case MPMB_UDP_TS:
1606  direction = SIG_FLAG_TOSERVER;
1607  break;
1608 
1609  case MPMB_TCP_PKT_TC:
1610  case MPMB_TCP_STREAM_TC:
1611  case MPMB_UDP_TC:
1612  direction = SIG_FLAG_TOCLIENT;
1613  break;
1614 
1615  case MPMB_OTHERIP:
1616  direction = (SIG_FLAG_TOCLIENT|SIG_FLAG_TOSERVER);
1617  break;
1618 
1619  case MPMB_MAX:
1620  BUG_ON(1);
1621  break;
1622  }
1623 
1624  for (sig = 0; sig < sgh->init->sig_cnt; sig++) {
1625  s = sgh->init->match_array[sig];
1626  if (s == NULL)
1627  continue;
1628 
1629  if (s->init_data->mpm_sm == NULL)
1630  continue;
1631 
1632  int list = s->init_data->mpm_sm_list;
1633  if (list < 0)
1634  continue;
1635 
1636  if (list != DETECT_SM_LIST_PMATCH)
1637  continue;
1638 
1639  switch (buf) {
1640  case MPMB_TCP_PKT_TS:
1641  case MPMB_TCP_PKT_TC:
1642  if (SignatureHasPacketContent(s) == 1)
1643  {
1644  sids_array[s->num / 8] |= 1 << (s->num % 8);
1645  cnt++;
1646  }
1647  break;
1648  case MPMB_TCP_STREAM_TS:
1649  case MPMB_TCP_STREAM_TC:
1650  if (SignatureHasStreamContent(s) == 1)
1651  {
1652  sids_array[s->num / 8] |= 1 << (s->num % 8);
1653  cnt++;
1654  }
1655  break;
1656  case MPMB_UDP_TS:
1657  case MPMB_UDP_TC:
1658  sids_array[s->num / 8] |= 1 << (s->num % 8);
1659  cnt++;
1660  break;
1661  case MPMB_OTHERIP:
1662  sids_array[s->num / 8] |= 1 << (s->num % 8);
1663  cnt++;
1664  break;
1665  default:
1666  break;
1667  }
1668  }
1669 
1670  if (cnt == 0)
1671  return NULL;
1672 
1673  MpmStore lookup = { sids_array, max_sid, direction, buf, sm_list, 0, NULL};
1674 
1675  MpmStore *result = MpmStoreLookup(de_ctx, &lookup);
1676  if (result == NULL) {
1677  MpmStore *copy = SCCalloc(1, sizeof(MpmStore));
1678  if (copy == NULL)
1679  return NULL;
1680  uint8_t *sids = SCCalloc(1, max_sid);
1681  if (sids == NULL) {
1682  SCFree(copy);
1683  return NULL;
1684  }
1685 
1686  memcpy(sids, sids_array, max_sid);
1687  copy->sid_array = sids;
1688  copy->sid_array_size = max_sid;
1689  copy->buffer = buf;
1690  copy->direction = direction;
1691  copy->sm_list = sm_list;
1692  copy->sgh_mpm_context = sgh_mpm_context;
1693 
1694  MpmStoreSetup(de_ctx, copy);
1695  MpmStoreAdd(de_ctx, copy);
1696  return copy;
1697  } else {
1698  return result;
1699  }
1700 }
1701 
1702 struct SidsArray {
1703  uint8_t *sids_array;
1705  /* indicates this has an active engine */
1706  bool active;
1707 
1709 };
1710 
1711 static MpmStore *MpmStorePrepareBufferAppLayer(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
1712  const DetectBufferMpmRegistery *am, const struct SidsArray *sa)
1713 {
1714  SCLogDebug("handling %s direction %s for list %d", am->name,
1715  am->direction == SIG_FLAG_TOSERVER ? "toserver" : "toclient",
1716  am->sm_list);
1717 
1718  if (sa->active == false || sa->sids_array_size == 0 || sa->sids_array == NULL)
1719  return NULL;
1720 
1721  MpmStore lookup = { sa->sids_array, sa->sids_array_size, am->direction, MPMB_MAX, am->sm_list,
1722  0, NULL };
1723  SCLogDebug("am->direction %d am->sm_list %d",
1724  am->direction, am->sm_list);
1725 
1726  MpmStore *result = MpmStoreLookup(de_ctx, &lookup);
1727  if (result == NULL) {
1728  SCLogDebug("new unique mpm for %s %s", am->name,
1729  am->direction == SIG_FLAG_TOSERVER ? "toserver" : "toclient");
1730 
1731  MpmStore *copy = SCCalloc(1, sizeof(MpmStore));
1732  if (copy == NULL)
1733  return NULL;
1734  uint8_t *sids = SCCalloc(1, sa->sids_array_size);
1735  if (sids == NULL) {
1736  SCFree(copy);
1737  return NULL;
1738  }
1739 
1740  memcpy(sids, sa->sids_array, sa->sids_array_size);
1741  copy->sid_array = sids;
1742  copy->sid_array_size = sa->sids_array_size;
1743  copy->buffer = MPMB_MAX;
1744  copy->direction = am->direction;
1745  copy->sm_list = am->sm_list;
1746  copy->sgh_mpm_context = am->sgh_mpm_context;
1747 
1748  MpmStoreSetup(de_ctx, copy);
1749  MpmStoreAdd(de_ctx, copy);
1750  return copy;
1751  } else {
1752  SCLogDebug("using existing mpm %p", result);
1753  return result;
1754  }
1755  return NULL;
1756 }
1757 
1758 static MpmStore *MpmStorePrepareBufferPkt(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
1759  const DetectBufferMpmRegistery *am, const struct SidsArray *sa)
1760 {
1761  SCLogDebug("handling %s for list %d", am->name,
1762  am->sm_list);
1763 
1764  if (sa->active == false || sa->sids_array_size == 0 || sa->sids_array == NULL)
1765  return NULL;
1766 
1768  MPMB_MAX, am->sm_list, 0, NULL };
1769  SCLogDebug("am->sm_list %d", am->sm_list);
1770 
1771  MpmStore *result = MpmStoreLookup(de_ctx, &lookup);
1772  if (result == NULL) {
1773  SCLogDebug("new unique mpm for %s", am->name);
1774 
1775  MpmStore *copy = SCCalloc(1, sizeof(MpmStore));
1776  if (copy == NULL)
1777  return NULL;
1778  uint8_t *sids = SCCalloc(1, sa->sids_array_size);
1779  if (sids == NULL) {
1780  SCFree(copy);
1781  return NULL;
1782  }
1783 
1784  memcpy(sids, sa->sids_array, sa->sids_array_size);
1785  copy->sid_array = sids;
1786  copy->sid_array_size = sa->sids_array_size;
1787  copy->buffer = MPMB_MAX;
1789  copy->sm_list = am->sm_list;
1790  copy->sgh_mpm_context = am->sgh_mpm_context;
1791 
1792  MpmStoreSetup(de_ctx, copy);
1793  MpmStoreAdd(de_ctx, copy);
1794  return copy;
1795  } else {
1796  SCLogDebug("using existing mpm %p", result);
1797  return result;
1798  }
1799  return NULL;
1800 }
1801 
1802 static MpmStore *MpmStorePrepareBufferFrame(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
1803  const DetectBufferMpmRegistery *am, const struct SidsArray *sa)
1804 {
1805  SCLogDebug("handling %s for list %d", am->name, am->sm_list);
1806 
1807  if (sa->active == false || sa->sids_array_size == 0 || sa->sids_array == NULL)
1808  return NULL;
1809 
1810  MpmStore lookup = { sa->sids_array, sa->sids_array_size, am->direction, MPMB_MAX, am->sm_list,
1811  0, NULL };
1812  SCLogDebug("am->sm_list %d", am->sm_list);
1813 
1814  MpmStore *result = MpmStoreLookup(de_ctx, &lookup);
1815  if (result == NULL) {
1816  SCLogDebug("new unique mpm for %s", am->name);
1817 
1818  MpmStore *copy = SCCalloc(1, sizeof(MpmStore));
1819  if (copy == NULL)
1820  return NULL;
1821  uint8_t *sids = SCCalloc(1, sa->sids_array_size);
1822  if (sids == NULL) {
1823  SCFree(copy);
1824  return NULL;
1825  }
1826 
1827  memcpy(sids, sa->sids_array, sa->sids_array_size);
1828  copy->sid_array = sids;
1829  copy->sid_array_size = sa->sids_array_size;
1830  copy->buffer = MPMB_MAX;
1831  copy->direction = am->direction;
1832  copy->sm_list = am->sm_list;
1833  copy->sgh_mpm_context = am->sgh_mpm_context;
1834 
1835  MpmStoreSetup(de_ctx, copy);
1836  MpmStoreAdd(de_ctx, copy);
1837  return copy;
1838  } else {
1839  SCLogDebug("using existing mpm %p", result);
1840  return result;
1841  }
1842  return NULL;
1843 }
1844 
1845 static void SetRawReassemblyFlag(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
1846 {
1847  const Signature *s = NULL;
1848  uint32_t sig;
1849 
1850  for (sig = 0; sig < sgh->init->sig_cnt; sig++) {
1851  s = sgh->init->match_array[sig];
1852  if (s == NULL)
1853  continue;
1854 
1855  if (SignatureHasStreamContent(s) == 1) {
1857  SCLogDebug("rule group %p has SIG_GROUP_HEAD_HAVERAWSTREAM set", sgh);
1858  return;
1859  }
1860  }
1861  SCLogDebug("rule group %p does NOT have SIG_GROUP_HEAD_HAVERAWSTREAM set", sgh);
1862 }
1863 
1864 static void PrepareMpms(DetectEngineCtx *de_ctx, SigGroupHead *sh)
1865 {
1866  const int max_buffer_id = de_ctx->buffer_type_id + 1;
1867  struct SidsArray sids[max_buffer_id][2];
1868  memset(sids, 0, sizeof(sids));
1869  const uint32_t max_sid = DetectEngineGetMaxSigId(de_ctx) / 8 + 1;
1870 
1871  /* flag the list+directions we have engines for as active */
1872  for (DetectBufferMpmRegistery *a = de_ctx->pkt_mpms_list; a != NULL; a = a->next) {
1873  struct SidsArray *sa = &sids[a->sm_list][0];
1874  sa->active = true;
1875  sa->type = a->type;
1876  }
1877  for (DetectBufferMpmRegistery *a = de_ctx->frame_mpms_list; a != NULL; a = a->next) {
1878  sids[a->sm_list][0].type = a->type;
1879  if ((a->direction == SIG_FLAG_TOSERVER) && SGH_DIRECTION_TS(sh)) {
1880  struct SidsArray *sa = &sids[a->sm_list][0];
1881  sa->active = true;
1882  }
1883  if ((a->direction == SIG_FLAG_TOCLIENT) && SGH_DIRECTION_TC(sh)) {
1884  struct SidsArray *sa = &sids[a->sm_list][1];
1885  sa->active = true;
1886  }
1887  }
1888  for (DetectBufferMpmRegistery *a = de_ctx->app_mpms_list; a != NULL; a = a->next) {
1889  sids[a->sm_list][0].type = a->type;
1890  if ((a->direction == SIG_FLAG_TOSERVER) && SGH_DIRECTION_TS(sh)) {
1891  struct SidsArray *sa = &sids[a->sm_list][0];
1892  sa->active = true;
1893  }
1894  if ((a->direction == SIG_FLAG_TOCLIENT) && SGH_DIRECTION_TC(sh)) {
1895  struct SidsArray *sa = &sids[a->sm_list][1];
1896  sa->active = true;
1897  }
1898  }
1899 
1900  for (uint32_t sig = 0; sig < sh->init->sig_cnt; sig++) {
1901  const Signature *s = sh->init->match_array[sig];
1902  if (s == NULL)
1903  continue;
1904  if (s->init_data->mpm_sm == NULL)
1905  continue;
1906  const int list = s->init_data->mpm_sm_list;
1907  if (list < 0)
1908  continue;
1909  if (list == DETECT_SM_LIST_PMATCH)
1910  continue;
1911 
1912  switch (sids[list][0].type) {
1913  /* app/frame engines are direction aware */
1916  if (s->flags & SIG_FLAG_TOSERVER) {
1917  struct SidsArray *sa = &sids[list][0];
1918  if (sa->active) {
1919  if (sa->sids_array == NULL) {
1920  sa->sids_array = SCCalloc(1, max_sid);
1921  sa->sids_array_size = max_sid;
1922  BUG_ON(sa->sids_array == NULL); // TODO
1923  }
1924  sa->sids_array[s->num / 8] |= 1 << (s->num % 8);
1925  }
1926  }
1927  if (s->flags & SIG_FLAG_TOCLIENT) {
1928  struct SidsArray *sa = &sids[list][1];
1929  if (sa->active) {
1930  if (sa->sids_array == NULL) {
1931  sa->sids_array = SCCalloc(1, max_sid);
1932  sa->sids_array_size = max_sid;
1933  BUG_ON(sa->sids_array == NULL); // TODO
1934  }
1935  sa->sids_array[s->num / 8] |= 1 << (s->num % 8);
1936  }
1937  }
1938  break;
1939  /* pkt engines are directionless, so only use index 0 */
1941  struct SidsArray *sa = &sids[list][0];
1942  if (sa->active) {
1943  if (sa->sids_array == NULL) {
1944  sa->sids_array = SCCalloc(1, max_sid);
1945  sa->sids_array_size = max_sid;
1946  BUG_ON(sa->sids_array == NULL); // TODO
1947  }
1948  sa->sids_array[s->num / 8] |= 1 << (s->num % 8);
1949  }
1950  break;
1951  }
1952  default:
1953  abort();
1954  break;
1955  }
1956  }
1957 
1958  sh->init->app_mpms = SCCalloc(de_ctx->app_mpms_list_cnt, sizeof(MpmCtx *));
1959  BUG_ON(sh->init->app_mpms == NULL);
1960 
1961  sh->init->pkt_mpms = SCCalloc(de_ctx->pkt_mpms_list_cnt, sizeof(MpmCtx *));
1962  BUG_ON(sh->init->pkt_mpms == NULL);
1963 
1965  BUG_ON(sh->init->frame_mpms == NULL);
1966 
1967  for (DetectBufferMpmRegistery *a = de_ctx->pkt_mpms_list; a != NULL; a = a->next) {
1968  struct SidsArray *sa = &sids[a->sm_list][0];
1969 
1970  MpmStore *mpm_store = MpmStorePrepareBufferPkt(de_ctx, sh, a, sa);
1971  if (mpm_store != NULL) {
1972  sh->init->pkt_mpms[a->id] = mpm_store->mpm_ctx;
1973 
1974  SCLogDebug("a %p a->name %s a->reg->PrefilterRegisterWithListId %p "
1975  "mpm_store->mpm_ctx %p", a, a->name,
1976  a->PrefilterRegisterWithListId, mpm_store->mpm_ctx);
1977 
1978  /* if we have just certain types of negated patterns,
1979  * mpm_ctx can be NULL */
1980  if (a->PrefilterRegisterWithListId && mpm_store->mpm_ctx) {
1981  BUG_ON(a->PrefilterRegisterWithListId(de_ctx,
1982  sh, mpm_store->mpm_ctx,
1983  a, a->sm_list) != 0);
1984  SCLogDebug("mpm %s %d set up", a->name, a->sm_list);
1985  }
1986  }
1987  }
1988  for (DetectBufferMpmRegistery *a = de_ctx->frame_mpms_list; a != NULL; a = a->next) {
1989  if ((a->direction == SIG_FLAG_TOSERVER && SGH_DIRECTION_TS(sh)) ||
1990  (a->direction == SIG_FLAG_TOCLIENT && SGH_DIRECTION_TC(sh))) {
1991  const int dir = a->direction == SIG_FLAG_TOCLIENT;
1992  struct SidsArray *sa = &sids[a->sm_list][dir];
1993 
1994  SCLogDebug("a %s direction %d PrefilterRegisterWithListId %p", a->name, a->direction,
1995  a->PrefilterRegisterWithListId);
1996  MpmStore *mpm_store = MpmStorePrepareBufferFrame(de_ctx, sh, a, sa);
1997  if (mpm_store != NULL) {
1998  sh->init->frame_mpms[a->id] = mpm_store->mpm_ctx;
1999 
2000  SCLogDebug("a %p a->name %s a->reg->PrefilterRegisterWithListId %p "
2001  "mpm_store->mpm_ctx %p",
2002  a, a->name, a->PrefilterRegisterWithListId, mpm_store->mpm_ctx);
2003 
2004  /* if we have just certain types of negated patterns,
2005  * mpm_ctx can be NULL */
2006  SCLogDebug("mpm_store %p mpm_ctx %p", mpm_store, mpm_store->mpm_ctx);
2007  if (a->PrefilterRegisterWithListId && mpm_store->mpm_ctx) {
2008  BUG_ON(a->PrefilterRegisterWithListId(
2009  de_ctx, sh, mpm_store->mpm_ctx, a, a->sm_list) != 0);
2010  SCLogDebug("mpm %s %d set up", a->name, a->sm_list);
2011  }
2012  }
2013  }
2014  }
2015  for (DetectBufferMpmRegistery *a = de_ctx->app_mpms_list; a != NULL; a = a->next) {
2016  if ((a->direction == SIG_FLAG_TOSERVER && SGH_DIRECTION_TS(sh)) ||
2017  (a->direction == SIG_FLAG_TOCLIENT && SGH_DIRECTION_TC(sh))) {
2018  const int dir = a->direction == SIG_FLAG_TOCLIENT;
2019  struct SidsArray *sa = &sids[a->sm_list][dir];
2020 
2021  MpmStore *mpm_store = MpmStorePrepareBufferAppLayer(de_ctx, sh, a, sa);
2022  if (mpm_store != NULL) {
2023  sh->init->app_mpms[a->id] = mpm_store->mpm_ctx;
2024 
2025  SCLogDebug("a %p a->name %s a->PrefilterRegisterWithListId %p "
2026  "mpm_store->mpm_ctx %p",
2027  a, a->name, a->PrefilterRegisterWithListId, mpm_store->mpm_ctx);
2028 
2029  /* if we have just certain types of negated patterns,
2030  * mpm_ctx can be NULL */
2031  if (a->PrefilterRegisterWithListId && mpm_store->mpm_ctx) {
2032  BUG_ON(a->PrefilterRegisterWithListId(
2033  de_ctx, sh, mpm_store->mpm_ctx, a, a->sm_list) != 0);
2034  SCLogDebug("mpm %s %d set up", a->name, a->sm_list);
2035  }
2036  }
2037  }
2038  }
2039 
2040  /* free temp sig arrays */
2041  for (int i = 0; i < max_buffer_id; i++) {
2042  struct SidsArray *sa;
2043  sa = &sids[i][0];
2044  if (sa->sids_array != NULL)
2045  SCFree(sa->sids_array);
2046  sa = &sids[i][1];
2047  if (sa->sids_array != NULL)
2048  SCFree(sa->sids_array);
2049  }
2050 }
2051 
2052 /** \brief Prepare the pattern matcher ctx in a sig group head.
2053  *
2054  */
2056 {
2057  MpmStore *mpm_store = NULL;
2058  if (SGH_PROTO(sh, IPPROTO_TCP)) {
2059  if (SGH_DIRECTION_TS(sh)) {
2060  mpm_store = MpmStorePrepareBuffer(de_ctx, sh, MPMB_TCP_PKT_TS);
2061  if (mpm_store != NULL) {
2062  PrefilterPktPayloadRegister(de_ctx, sh, mpm_store->mpm_ctx);
2063  }
2064 
2066  if (mpm_store != NULL) {
2067  PrefilterPktStreamRegister(de_ctx, sh, mpm_store->mpm_ctx);
2068  }
2069 
2070  SetRawReassemblyFlag(de_ctx, sh);
2071  }
2072  if (SGH_DIRECTION_TC(sh)) {
2073  mpm_store = MpmStorePrepareBuffer(de_ctx, sh, MPMB_TCP_PKT_TC);
2074  if (mpm_store != NULL) {
2075  PrefilterPktPayloadRegister(de_ctx, sh, mpm_store->mpm_ctx);
2076  }
2077 
2079  if (mpm_store != NULL) {
2080  PrefilterPktStreamRegister(de_ctx, sh, mpm_store->mpm_ctx);
2081  }
2082 
2083  SetRawReassemblyFlag(de_ctx, sh);
2084  }
2085  } else if (SGH_PROTO(sh, IPPROTO_UDP)) {
2086  if (SGH_DIRECTION_TS(sh)) {
2087  mpm_store = MpmStorePrepareBuffer(de_ctx, sh, MPMB_UDP_TS);
2088  if (mpm_store != NULL) {
2089  PrefilterPktPayloadRegister(de_ctx, sh, mpm_store->mpm_ctx);
2090  }
2091  }
2092  if (SGH_DIRECTION_TC(sh)) {
2093  mpm_store = MpmStorePrepareBuffer(de_ctx, sh, MPMB_UDP_TC);
2094  if (mpm_store != NULL) {
2095  PrefilterPktPayloadRegister(de_ctx, sh, mpm_store->mpm_ctx);
2096  }
2097  }
2098  } else {
2099  mpm_store = MpmStorePrepareBuffer(de_ctx, sh, MPMB_OTHERIP);
2100  if (mpm_store != NULL) {
2101  PrefilterPktPayloadRegister(de_ctx, sh, mpm_store->mpm_ctx);
2102  }
2103  }
2104 
2105  PrepareMpms(de_ctx, sh);
2106  return 0;
2107 }
2108 
2109 static inline uint32_t ContentFlagsForHash(const DetectContentData *cd)
2110 {
2113 }
2114 
2115 /** \internal
2116  * \brief The hash function for Pattern. Hashes pattern after chop is applied.
2117  *
2118  * \param ht Pointer to the hash table.
2119  * \param data Pointer to the Pattern.
2120  * \param datalen Not used in our case.
2121  *
2122  * \retval hash The generated hash value.
2123  */
2124 static uint32_t PatternChopHashFunc(HashListTable *ht, void *data, uint16_t datalen)
2125 {
2126  const DetectPatternTracker *p = (DetectPatternTracker *)data;
2127  uint32_t hash = p->sm_list + ContentFlagsForHash(p->cd);
2128  uint16_t content_len = p->cd->content_len;
2129  const uint8_t *content = p->cd->content;
2131  content += p->cd->fp_chop_offset;
2132  content_len = p->cd->fp_chop_len;
2133  }
2134  hash += StringHashDjb2(content, content_len);
2135  return hash % ht->array_size;
2136 }
2137 
2138 /** \internal
2139  * \brief The hash function for Pattern. Ignores chop.
2140  *
2141  * \param ht Pointer to the hash table.
2142  * \param data Pointer to the Pattern.
2143  * \param datalen Not used in our case.
2144  *
2145  * \retval hash The generated hash value.
2146  */
2147 static uint32_t PatternNoChopHashFunc(HashListTable *ht, void *data, uint16_t datalen)
2148 {
2149  const DetectPatternTracker *p = (DetectPatternTracker *)data;
2150  uint32_t hash = p->sm_list + ContentFlagsForHash(p->cd);
2151  hash += StringHashDjb2(p->cd->content, p->cd->content_len);
2152  return hash % ht->array_size;
2153 }
2154 
2155 /**
2156  * \brief The Compare function for Pattern. Compares patterns after chop is applied.
2157  *
2158  * \param data1 Pointer to the first Pattern.
2159  * \param len1 Not used.
2160  * \param data2 Pointer to the second Pattern.
2161  * \param len2 Not used.
2162  *
2163  * \retval 1 If the 2 Patterns sent as args match.
2164  * \retval 0 If the 2 Patterns sent as args do not match.
2165  */
2166 static char PatternChopCompareFunc(void *data1, uint16_t len1, void *data2, uint16_t len2)
2167 {
2168  const DetectPatternTracker *p1 = (DetectPatternTracker *)data1;
2169  const DetectPatternTracker *p2 = (DetectPatternTracker *)data2;
2170 
2171  if (p1->sm_list != p2->sm_list)
2172  return 0;
2173 
2174  if (ContentFlagsForHash(p1->cd) != ContentFlagsForHash(p2->cd))
2175  return 0;
2176 
2177  uint16_t p1_content_len = p1->cd->content_len;
2178  uint8_t *p1_content = p1->cd->content;
2180  p1_content += p1->cd->fp_chop_offset;
2181  p1_content_len = p1->cd->fp_chop_len;
2182  }
2183  uint16_t p2_content_len = p2->cd->content_len;
2184  uint8_t *p2_content = p2->cd->content;
2186  p2_content += p2->cd->fp_chop_offset;
2187  p2_content_len = p2->cd->fp_chop_len;
2188  }
2189 
2190  if (p1_content_len != p2_content_len)
2191  return 0;
2192 
2193  if (memcmp(p1_content, p2_content, p1_content_len) != 0) {
2194  return 0;
2195  }
2196 
2197  return 1;
2198 }
2199 
2200 /**
2201  * \brief The Compare function for Pattern. Ignores chop settings
2202  *
2203  * \param data1 Pointer to the first Pattern.
2204  * \param len1 Not used.
2205  * \param data2 Pointer to the second Pattern.
2206  * \param len2 Not used.
2207  *
2208  * \retval 1 If the 2 Patterns sent as args match.
2209  * \retval 0 If the 2 Patterns sent as args do not match.
2210  */
2211 static char PatternNoChopCompareFunc(void *data1, uint16_t len1, void *data2, uint16_t len2)
2212 {
2213  const DetectPatternTracker *p1 = (DetectPatternTracker *)data1;
2214  const DetectPatternTracker *p2 = (DetectPatternTracker *)data2;
2215 
2216  if (p1->sm_list != p2->sm_list)
2217  return 0;
2218 
2219  if (ContentFlagsForHash(p1->cd) != ContentFlagsForHash(p2->cd))
2220  return 0;
2221 
2222  if (p1->cd->content_len != p2->cd->content_len)
2223  return 0;
2224 
2225  if (memcmp(p1->cd->content, p2->cd->content, p1->cd->content_len) != 0) {
2226  return 0;
2227  }
2228 
2229  return 1;
2230 }
2231 
2232 static void PatternFreeFunc(void *ptr)
2233 {
2234  SCFree(ptr);
2235 }
2236 
2237 /**
2238  * \brief Figure out the FP and their respective content ids for all the
2239  * sigs in the engine.
2240  *
2241  * \param de_ctx Detection engine context.
2242  *
2243  * \retval 0 On success.
2244  * \retval -1 On failure.
2245  */
2247 {
2248  uint32_t cnt = 0;
2249  for (Signature *s = de_ctx->sig_list; s != NULL; s = s->next) {
2250  if (s->flags & SIG_FLAG_PREFILTER)
2251  continue;
2252 
2254  if (s->init_data->mpm_sm != NULL) {
2255  s->flags |= SIG_FLAG_PREFILTER;
2256  cnt++;
2257  }
2258  }
2259  /* no mpm rules */
2260  if (cnt == 0)
2261  return 0;
2262 
2263  HashListTable *ht =
2264  HashListTableInit(4096, PatternChopHashFunc, PatternChopCompareFunc, PatternFreeFunc);
2265  BUG_ON(ht == NULL);
2266  PatIntId max_id = 0;
2267 
2268  for (Signature *s = de_ctx->sig_list; s != NULL; s = s->next) {
2269  if (s->init_data->mpm_sm == NULL)
2270  continue;
2271 
2272  const int sm_list = s->init_data->mpm_sm_list;
2273  BUG_ON(sm_list == -1);
2274 
2276 
2277  DetectPatternTracker lookup = { .cd = cd, .sm_list = sm_list, .cnt = 0, .mpm = 0 };
2278  DetectPatternTracker *res = HashListTableLookup(ht, &lookup, 0);
2279  if (res) {
2280  res->cnt++;
2281  res->mpm += ((cd->flags & DETECT_CONTENT_MPM) != 0);
2282 
2283  cd->id = res->cd->id;
2284  SCLogDebug("%u: res id %u cnt %u", s->id, res->cd->id, res->cnt);
2285  } else {
2286  DetectPatternTracker *add = SCCalloc(1, sizeof(*add));
2287  BUG_ON(add == NULL);
2288  add->cd = cd;
2289  add->sm_list = sm_list;
2290  add->cnt = 1;
2291  add->mpm = ((cd->flags & DETECT_CONTENT_MPM) != 0);
2292  HashListTableAdd(ht, (void *)add, 0);
2293 
2294  cd->id = max_id++;
2295  SCLogDebug("%u: add id %u cnt %u", s->id, add->cd->id, add->cnt);
2296  }
2297  }
2298 
2299  de_ctx->max_fp_id = max_id;
2300 
2301  HashListTableFree(ht);
2302 
2303  return 0;
2304 }
2305 
2306 /** \brief add all patterns on our stats hash
2307  * Used to fill the hash later used by DumpPatterns()
2308  * \note sets up the hash table on first call
2309  */
2311 {
2312  if (de_ctx->pattern_hash_table == NULL) {
2314  4096, PatternNoChopHashFunc, PatternNoChopCompareFunc, PatternFreeFunc);
2315  BUG_ON(de_ctx->pattern_hash_table == NULL);
2316  }
2317  if (s->sm_arrays[DETECT_SM_LIST_PMATCH]) {
2319  do {
2320  switch (smd->type) {
2321  case DETECT_CONTENT: {
2322  const DetectContentData *cd = (const DetectContentData *)smd->ctx;
2323  DetectPatternTracker lookup = {
2324  .cd = cd, .sm_list = DETECT_SM_LIST_PMATCH, .cnt = 0, .mpm = 0
2325  };
2326  DetectPatternTracker *res =
2328  if (res) {
2329  res->cnt++;
2330  res->mpm += ((cd->flags & DETECT_CONTENT_MPM) != 0);
2331  } else {
2332  DetectPatternTracker *add = SCCalloc(1, sizeof(*add));
2333  BUG_ON(add == NULL);
2334  add->cd = cd;
2336  add->cnt = 1;
2337  add->mpm = ((cd->flags & DETECT_CONTENT_MPM) != 0);
2338  HashListTableAdd(de_ctx->pattern_hash_table, (void *)add, 0);
2339  }
2340  break;
2341  }
2342  }
2343  if (smd->is_last)
2344  break;
2345  smd++;
2346  } while (1);
2347  }
2348 
2350  for (; app != NULL; app = app->next) {
2351  SigMatchData *smd = app->smd;
2352  do {
2353  switch (smd->type) {
2354  case DETECT_CONTENT: {
2355  const DetectContentData *cd = (const DetectContentData *)smd->ctx;
2356 
2357  DetectPatternTracker lookup = {
2358  .cd = cd, .sm_list = app->sm_list, .cnt = 0, .mpm = 0
2359  };
2360  DetectPatternTracker *res =
2362  if (res) {
2363  res->cnt++;
2364  res->mpm += ((cd->flags & DETECT_CONTENT_MPM) != 0);
2365  } else {
2366  DetectPatternTracker *add = SCCalloc(1, sizeof(*add));
2367  BUG_ON(add == NULL);
2368  add->cd = cd;
2369  add->sm_list = app->sm_list;
2370  add->cnt = 1;
2371  add->mpm = ((cd->flags & DETECT_CONTENT_MPM) != 0);
2372  HashListTableAdd(de_ctx->pattern_hash_table, (void *)add, 0);
2373  }
2374  break;
2375  }
2376  }
2377  if (smd->is_last)
2378  break;
2379  smd++;
2380  } while (1);
2381  }
2383  for (; pkt != NULL; pkt = pkt->next) {
2384  SigMatchData *smd = pkt->smd;
2385  do {
2386  if (smd == NULL) {
2388  smd = s->sm_arrays[pkt->sm_list];
2389  }
2390  switch (smd->type) {
2391  case DETECT_CONTENT: {
2392  const DetectContentData *cd = (const DetectContentData *)smd->ctx;
2393 
2394  DetectPatternTracker lookup = {
2395  .cd = cd, .sm_list = pkt->sm_list, .cnt = 0, .mpm = 0
2396  };
2397  DetectPatternTracker *res =
2399  if (res) {
2400  res->cnt++;
2401  res->mpm += ((cd->flags & DETECT_CONTENT_MPM) != 0);
2402  } else {
2403  DetectPatternTracker *add = SCCalloc(1, sizeof(*add));
2404  BUG_ON(add == NULL);
2405  add->cd = cd;
2406  add->sm_list = pkt->sm_list;
2407  add->cnt = 1;
2408  add->mpm = ((cd->flags & DETECT_CONTENT_MPM) != 0);
2409  HashListTableAdd(de_ctx->pattern_hash_table, (void *)add, 0);
2410  }
2411  break;
2412  }
2413  }
2414  if (smd->is_last)
2415  break;
2416  smd++;
2417  } while (1);
2418  }
2420  for (; frame != NULL; frame = frame->next) {
2421  SigMatchData *smd = frame->smd;
2422  do {
2423  if (smd == NULL) {
2425  smd = s->sm_arrays[frame->sm_list];
2426  }
2427  switch (smd->type) {
2428  case DETECT_CONTENT: {
2429  const DetectContentData *cd = (const DetectContentData *)smd->ctx;
2430 
2431  DetectPatternTracker lookup = {
2432  .cd = cd, .sm_list = frame->sm_list, .cnt = 0, .mpm = 0
2433  };
2434  DetectPatternTracker *res =
2436  if (res) {
2437  res->cnt++;
2438  res->mpm += ((cd->flags & DETECT_CONTENT_MPM) != 0);
2439  } else {
2440  DetectPatternTracker *add = SCCalloc(1, sizeof(*add));
2441  BUG_ON(add == NULL);
2442  add->cd = cd;
2443  add->sm_list = frame->sm_list;
2444  add->cnt = 1;
2445  add->mpm = ((cd->flags & DETECT_CONTENT_MPM) != 0);
2446  HashListTableAdd(de_ctx->pattern_hash_table, (void *)add, 0);
2447  }
2448  break;
2449  }
2450  }
2451  if (smd->is_last)
2452  break;
2453  smd++;
2454  } while (1);
2455  }
2456 }
MpmInitThreadCtx
void MpmInitThreadCtx(MpmThreadCtx *mpm_thread_ctx, uint16_t matcher)
Definition: util-mpm.c:195
DETECT_CONTENT_NOCASE
#define DETECT_CONTENT_NOCASE
Definition: detect-content.h:29
SignatureHasPacketContent
int SignatureHasPacketContent(const Signature *s)
check if a signature has patterns that are to be inspected against a packets payload (as opposed to t...
Definition: detect-engine-mpm.c:786
DetectEngineCtx_::pkt_mpms_list_cnt
uint32_t pkt_mpms_list_cnt
Definition: detect.h:955
HashListTableGetListData
#define HashListTableGetListData(hb)
Definition: util-hashlist.h:59
DetectEngineCtx_::frame_mpms_list_cnt
uint32_t frame_mpms_list_cnt
Definition: detect.h:958
DetectContentData_::offset
uint16_t offset
Definition: detect-content.h:100
DetectPatternTracker
Definition: detect.h:668
SCFPSupportSMList_
Definition: detect.h:698
DetectEngineAppInspectionEngine_
Definition: detect.h:389
util-hash-string.h
MPMB_UDP_TS
@ MPMB_UDP_TS
Definition: detect.h:1278
DetectBufferMpmRegistery_::direction
int direction
Definition: detect.h:628
detect-content.h
SGH_DIRECTION_TC
#define SGH_DIRECTION_TC(sgh)
Definition: detect-engine-mpm.c:1014
MpmCtx_::mpm_type
uint8_t mpm_type
Definition: util-mpm.h:90
detect-engine.h
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:79
DETECT_CONTENT_FAST_PATTERN_CHOP
#define DETECT_CONTENT_FAST_PATTERN_CHOP
Definition: detect-content.h:36
PatternMatchDestroy
void PatternMatchDestroy(MpmCtx *mpm_ctx, uint16_t mpm_matcher)
Definition: detect-engine-mpm.c:898
MpmStore_::sid_array_size
uint32_t sid_array_size
Definition: detect.h:1286
DetectContentData_::fp_chop_len
uint16_t fp_chop_len
Definition: detect-content.h:91
MpmStore_::sid_array
uint8_t * sid_array
Definition: detect.h:1285
DetectEngineCtx_::sgh_mpm_context_proto_tcp_packet
int32_t sgh_mpm_context_proto_tcp_packet
Definition: detect.h:870
SC_ERR_INVALID_VALUE
@ SC_ERR_INVALID_VALUE
Definition: util-error.h:160
PatternMatchPrepareGroup
int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
Prepare the pattern matcher ctx in a sig group head.
Definition: detect-engine-mpm.c:2055
SCFPSupportSMList_::next
struct SCFPSupportSMList_ * next
Definition: detect.h:701
DetectPktMpmRegister
void DetectPktMpmRegister(const char *name, int priority, int(*PrefilterRegister)(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistery *mpm_reg, int list_id), InspectionBufferGetPktDataPtr GetData)
register a MPM engine
Definition: detect-engine-mpm.c:525
DetectEnginePktInspectionEngine
Definition: detect.h:442
DetectEngineAppInspectionEngine_::next
struct DetectEngineAppInspectionEngine_ * next
Definition: detect.h:408
detect-engine-siggroup.h
SCFPSupportSMList_::list_id
int list_id
Definition: detect.h:699
SigTableElmt_::name
const char * name
Definition: detect.h:1235
MpmStoreFree
void MpmStoreFree(DetectEngineCtx *de_ctx)
Frees the hash table - DetectEngineCtx->mpm_hash_table, allocated by MpmStoreInit() function.
Definition: detect-engine-mpm.c:1459
DetectFrameMpmRegisterByParentId
void DetectFrameMpmRegisterByParentId(DetectEngineCtx *de_ctx, const int id, const int parent_id, DetectEngineTransforms *transforms)
copy a mpm engine from parent_id, add in transforms
Definition: detect-engine-mpm.c:341
MpmThreadCtx_
Definition: util-mpm.h:46
DetectPatternTracker::mpm
uint32_t mpm
Definition: detect.h:672
Signature_::num
SigIntId num
Definition: detect.h:550
ConfGetBool
int ConfGetBool(const char *name, int *val)
Retrieve a configuration value as an boolen.
Definition: conf.c:473
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1392
DetectEngineCtx_::pattern_hash_table
HashListTable * pattern_hash_table
Definition: detect.h:826
DetectEngineTransforms
Definition: detect.h:371
MpmFactoryReClaimMpmCtx
void MpmFactoryReClaimMpmCtx(const DetectEngineCtx *de_ctx, MpmCtx *mpm_ctx)
Definition: util-mpm.c:156
DETECT_CONTENT
@ DETECT_CONTENT
Definition: detect-engine-register.h:62
MpmStoreReportStats
void MpmStoreReportStats(const DetectEngineCtx *de_ctx)
Definition: detect-engine-mpm.c:1361
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:296
MPMB_OTHERIP
@ MPMB_OTHERIP
Definition: detect.h:1280
DetectEngineCtx_::max_fp_id
uint32_t max_fp_id
Definition: detect.h:852
DetectBufferTypeSupportsFrames
void DetectBufferTypeSupportsFrames(const char *name)
Definition: detect-engine.c:1045
DetectMpmInitializeFrameMpms
void DetectMpmInitializeFrameMpms(DetectEngineCtx *de_ctx)
Definition: detect-engine-mpm.c:442
AppProto
uint16_t AppProto
Definition: app-layer-protos.h:80
DETECT_SM_LIST_DYNAMIC_START
@ DETECT_SM_LIST_DYNAMIC_START
Definition: detect.h:98
DetectBufferMpmRegistery_::transforms
DetectEngineTransforms transforms
Definition: detect.h:639
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:325
DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED
#define DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED
Definition: detect-content.h:55
MpmStore_::sm_list
int sm_list
Definition: detect.h:1290
PatternStrength
uint32_t PatternStrength(uint8_t *pat, uint16_t patlen)
Predict a strength value for patterns.
Definition: detect-engine-mpm.c:934
DETECT_BUFFER_MPM_TYPE_FRAME
@ DETECT_BUFFER_MPM_TYPE_FRAME
Definition: detect.h:619
DETECT_SM_LIST_THRESHOLD
@ DETECT_SM_LIST_THRESHOLD
Definition: detect.h:93
ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE
@ ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE
Definition: detect.h:993
DetectSetFastPatternAndItsId
int DetectSetFastPatternAndItsId(DetectEngineCtx *de_ctx)
Figure out the FP and their respective content ids for all the sigs in the engine.
Definition: detect-engine-mpm.c:2246
InspectionBufferGetDataPtr
InspectionBuffer *(* InspectionBufferGetDataPtr)(struct DetectEngineThreadCtx_ *det_ctx, const DetectEngineTransforms *transforms, Flow *f, const uint8_t flow_flags, void *txv, const int list_id)
Definition: detect.h:377
PrefilterGenericMpmRegister
int PrefilterGenericMpmRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistery *mpm_reg, int list_id)
Definition: detect-engine-prefilter.c:749
DetectEngineCtx_::frame_mpms_list
DetectBufferMpmRegistery * frame_mpms_list
Definition: detect.h:957
AppProtoToString
const char * AppProtoToString(AppProto alproto)
Maps the ALPROTO_*, to its string equivalent.
Definition: app-layer-protos.c:30
DetectBufferMpmRegistery_::app_v2
struct DetectBufferMpmRegistery_::@87::@89 app_v2
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:784
DetectBufferMpmRegistery_::type
enum DetectBufferMpmType type
Definition: detect.h:633
DetectEnginePktInspectionEngine::smd
SigMatchData * smd
Definition: detect.h:443
util-memcpy.h
DETECT_CONTENT_MPM_IS_CONCLUSIVE
#define DETECT_CONTENT_MPM_IS_CONCLUSIVE(c)
Definition: detect-content.h:76
HashListTableGetListHead
HashListTableBucket * HashListTableGetListHead(HashListTable *ht)
Definition: util-hashlist.c:290
DETECT_CONTENT_DEPTH_VAR
#define DETECT_CONTENT_DEPTH_VAR
Definition: detect-content.h:46
InspectionBufferGetPktDataPtr
InspectionBuffer *(* InspectionBufferGetPktDataPtr)(struct DetectEngineThreadCtx_ *det_ctx, const DetectEngineTransforms *transforms, Packet *p, const int list_id)
Definition: detect.h:437
DetectMpmInitializeBuiltinMpms
void DetectMpmInitializeBuiltinMpms(DetectEngineCtx *de_ctx)
Definition: detect-engine-mpm.c:716
SIG_FLAG_REQUIRE_STREAM
#define SIG_FLAG_REQUIRE_STREAM
Definition: detect.h:216
DetectPatternTracker::cnt
uint32_t cnt
Definition: detect.h:671
DE_QUIET
#define DE_QUIET
Definition: detect.h:287
MpmCtx_::maxlen
uint16_t maxlen
Definition: util-mpm.h:100
MPMB_TCP_STREAM_TS
@ MPMB_TCP_STREAM_TS
Definition: detect.h:1276
DetectPatternTracker::cd
const struct DetectContentData_ * cd
Definition: detect.h:669
PatIntId
#define PatIntId
Definition: suricata-common.h:307
DetectBufferMpmRegistery_
one time registration of keywords at start up
Definition: detect.h:625
SIG_GROUP_HEAD_HAVERAWSTREAM
#define SIG_GROUP_HEAD_HAVERAWSTREAM
Definition: detect.h:1264
mpm_default_matcher
uint8_t mpm_default_matcher
Definition: util-mpm.c:49
Signature_::sm_arrays
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
Definition: detect.h:594
DetectContentData_
Definition: detect-content.h:86
DetectContentData_::fp_chop_offset
uint16_t fp_chop_offset
Definition: detect-content.h:93
HashListTableLookup
void * HashListTableLookup(HashListTable *ht, void *data, uint16_t datalen)
Definition: util-hashlist.c:248
detect-engine-payload.h
SIG_FLAG_TOCLIENT
#define SIG_FLAG_TOCLIENT
Definition: detect.h:229
MPMB_MAX
@ MPMB_MAX
Definition: detect.h:1281
SigMatchData_
Data needed for Match()
Definition: detect.h:322
DetectEngineCtx_::sgh_mpm_context_proto_udp_packet
int32_t sgh_mpm_context_proto_udp_packet
Definition: detect.h:871
ShortenString
void ShortenString(const char *input, char *output, size_t output_size, char c)
Definition: util-misc.c:217
SigMatchData_::type
uint16_t type
Definition: detect.h:323
DetectEngineRegisterFastPatternForId
void DetectEngineRegisterFastPatternForId(DetectEngineCtx *de_ctx, int list_id, int priority)
Definition: detect-fast-pattern.c:137
SidsArray
Definition: detect-engine-mpm.c:1702
MPMB_TCP_STREAM_TC
@ MPMB_TCP_STREAM_TC
Definition: detect.h:1277
detect-engine-prefilter.h
DetectBufferMpmRegistery_::id
int id
Definition: detect.h:632
EngineAnalysisAddAllRulePatterns
void EngineAnalysisAddAllRulePatterns(DetectEngineCtx *de_ctx, const Signature *s)
add all patterns on our stats hash Used to fill the hash later used by DumpPatterns()
Definition: detect-engine-mpm.c:2310
Signature_::frame_inspect
DetectEngineFrameInspectionEngine * frame_inspect
Definition: detect.h:590
DetectBufferMpmRegistery_::frame_v1
struct DetectBufferMpmRegistery_::@87::@91 frame_v1
MpmBuiltinBuffers
MpmBuiltinBuffers
Definition: detect.h:1273
DetectEngineCtx_::app_mpms_list
DetectBufferMpmRegistery * app_mpms_list
Definition: detect.h:951
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:1085
HashListTableAdd
int HashListTableAdd(HashListTable *ht, void *data, uint16_t datalen)
Definition: util-hashlist.c:116
detect-udphdr.h
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
HashListTable_::array_size
uint32_t array_size
Definition: util-hashlist.h:41
DetectAppLayerMpmRegisterByParentId
void DetectAppLayerMpmRegisterByParentId(DetectEngineCtx *de_ctx, const int id, const int parent_id, DetectEngineTransforms *transforms)
copy a mpm engine from parent_id, add in transforms
Definition: detect-engine-mpm.c:148
util-memcmp.h
SigGroupHeadInitData_::pkt_mpms
MpmCtx ** pkt_mpms
Definition: detect.h:1373
MpmInitCtx
void MpmInitCtx(MpmCtx *mpm_ctx, uint8_t matcher)
Definition: util-mpm.c:200
DetectBufferMpmRegistery_::sgh_mpm_context
int sgh_mpm_context
Definition: detect.h:634
Signature_::next
struct Signature_ * next
Definition: detect.h:613
DetectEngineCtx_::sgh_mpm_context_proto_other_packet
int32_t sgh_mpm_context_proto_other_packet
Definition: detect.h:872
DetectEngineAppInspectionEngine_::sm_list
uint16_t sm_list
Definition: detect.h:395
ConfGet
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:331
MpmFactoryRegisterMpmCtxProfile
int32_t MpmFactoryRegisterMpmCtxProfile(DetectEngineCtx *de_ctx, const char *name, const int sm_list)
Register a new Mpm Context.
Definition: util-mpm.c:59
HashListTableGetListNext
#define HashListTableGetListNext(hb)
Definition: util-hashlist.h:58
DetectBufferMpmType
DetectBufferMpmType
Definition: detect.h:616
DETECT_SM_LIST_POSTMATCH
@ DETECT_SM_LIST_POSTMATCH
Definition: detect.h:87
DetectEngineFrameMpmRegister
void DetectEngineFrameMpmRegister(DetectEngineCtx *de_ctx, const char *name, int direction, int priority, int(*PrefilterRegister)(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistery *mpm_reg, int list_id), AppProto alproto, uint8_t type)
Definition: detect-engine-mpm.c:380
SIG_FLAG_TOSERVER
#define SIG_FLAG_TOSERVER
Definition: detect.h:228
HashListTableInit
HashListTable * HashListTableInit(uint32_t size, uint32_t(*Hash)(struct HashListTable_ *, void *, uint16_t), char(*Compare)(void *, uint16_t, void *, uint16_t), void(*Free)(void *))
Definition: util-hashlist.c:35
decode.h
util-debug.h
type
uint8_t type
Definition: decode-icmpv4.h:0
SigGroupHeadInitData_::sig_cnt
SigIntId sig_cnt
Definition: detect.h:1382
SidsArray::sids_array_size
uint32_t sids_array_size
Definition: detect-engine-mpm.c:1704
DETECT_CONTENT_ENDS_WITH
#define DETECT_CONTENT_ENDS_WITH
Definition: detect-content.h:42
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
MpmFactoryGetMpmCtxForProfile
MpmCtx * MpmFactoryGetMpmCtxForProfile(const DetectEngineCtx *de_ctx, int32_t id, int direction)
Definition: util-mpm.c:130
DetectEnginePktInspectionEngine::sm_list
uint16_t sm_list
Definition: detect.h:445
DetectMpmInitializePktMpms
void DetectMpmInitializePktMpms(DetectEngineCtx *de_ctx)
Definition: detect-engine-mpm.c:615
MPM_PATTERN_CTX_OWNS_ID
#define MPM_PATTERN_CTX_OWNS_ID
Definition: util-mpm.h:142
strlcat
size_t strlcat(char *, const char *src, size_t siz)
Definition: util-strlcatu.c:45
MpmStore_
Definition: detect.h:1284
SignatureInitData_::mpm_sm
SigMatch * mpm_sm
Definition: detect.h:511
DetectBufferMpmRegistery_::PrefilterRegisterWithListId
int(* PrefilterRegisterWithListId)(struct DetectEngineCtx_ *de_ctx, struct SigGroupHead_ *sgh, MpmCtx *mpm_ctx, const struct DetectBufferMpmRegistery_ *mpm_reg, int list_id)
Definition: detect.h:636
DetectEngineGetMaxSigId
#define DetectEngineGetMaxSigId(de_ctx)
Definition: detect-engine.h:100
SignatureInitData_::mpm_sm_list
int mpm_sm_list
Definition: detect.h:509
SidsArray::sids_array
uint8_t * sids_array
Definition: detect-engine-mpm.c:1703
DETECT_CONTENT_DEPTH
#define DETECT_CONTENT_DEPTH
Definition: detect-content.h:33
Signature_::pkt_inspect
DetectEnginePktInspectionEngine * pkt_inspect
Definition: detect.h:589
util-print.h
SCEnter
#define SCEnter(...)
Definition: util-debug.h:298
detect-engine-mpm.h
detect.h
DetectEngineFrameInspectionEngine::sm_list
uint16_t sm_list
Definition: detect.h:472
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:317
DetectEngineCtx_::mpm_matcher
uint8_t mpm_matcher
Definition: detect.h:834
DETECT_CONTENT_IS_SINGLE
#define DETECT_CONTENT_IS_SINGLE(c)
Definition: detect-content.h:66
DETECT_CONTENT_NEGATED
#define DETECT_CONTENT_NEGATED
Definition: detect-content.h:40
PatternMatchThreadPrepare
void PatternMatchThreadPrepare(MpmThreadCtx *mpm_thread_ctx, uint16_t mpm_matcher)
Definition: detect-engine-mpm.c:915
DetectEngineBufferTypeRegister
int DetectEngineBufferTypeRegister(DetectEngineCtx *de_ctx, const char *name)
Definition: detect-engine.c:1172
SigGroupHead_::init
SigGroupHeadInitData * init
Definition: detect.h:1415
DetectContentData_::id
PatIntId id
Definition: detect-content.h:98
Signature_::app_inspect
DetectEngineAppInspectionEngine * app_inspect
Definition: detect.h:588
MpmCtx_::minlen
uint16_t minlen
Definition: util-mpm.h:99
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:316
DetectProto_::proto
uint8_t proto[256/8]
Definition: detect-engine-proto.h:37
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:289
MpmStore_::direction
int direction
Definition: detect.h:1288
MPMCTX_FLAGS_GLOBAL
#define MPMCTX_FLAGS_GLOBAL
Definition: util-mpm.h:85
DetectBufferMpmRegistery_::name
const char * name
Definition: detect.h:626
Signature_::flags
uint32_t flags
Definition: detect.h:540
DetectContentData_::depth
uint16_t depth
Definition: detect-content.h:99
DetectFrameMpmRegister
void DetectFrameMpmRegister(const char *name, int direction, int priority, int(*PrefilterRegister)(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistery *mpm_reg, int list_id), AppProto alproto, uint8_t type)
register a MPM engine
Definition: detect-engine-mpm.c:293
stream.h
PatternMatchThreadPrint
void PatternMatchThreadPrint(MpmThreadCtx *mpm_thread_ctx, uint16_t mpm_matcher)
Definition: detect-engine-mpm.c:904
DetectEngineCtx_::sgh_mpm_context_stream
int32_t sgh_mpm_context_stream
Definition: detect.h:873
DetectEngineBufferTypeSupportsFrames
void DetectEngineBufferTypeSupportsFrames(DetectEngineCtx *de_ctx, const char *name)
Definition: detect-engine.c:1211
conf.h
DetectEngineCtx_::sgh_mpm_ctx_cnf
uint8_t sgh_mpm_ctx_cnf
Definition: detect.h:847
DetectContentData_::flags
uint32_t flags
Definition: detect-content.h:97
PrefilterPktPayloadRegister
int PrefilterPktPayloadRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx)
Definition: detect-engine-payload.c:133
DetectEngineFrameInspectionEngine
Definition: detect.h:467
DETECT_BUFFER_MPM_TYPE_PKT
@ DETECT_BUFFER_MPM_TYPE_PKT
Definition: detect.h:617
MpmTableElmt_::Prepare
int(* Prepare)(struct MpmCtx_ *)
Definition: util-mpm.h:164
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:610
FastPatternSupportEnabledForSigMatchList
int FastPatternSupportEnabledForSigMatchList(const DetectEngineCtx *de_ctx, const int list_id)
Checks if a particular list(Signature->sm_lists[]) is in the list of lists that need to be searched f...
Definition: detect-fast-pattern.c:64
SignatureInitData_::smlists
struct SigMatch_ ** smlists
Definition: detect.h:533
SCFPSupportSMList_::priority
int priority
Definition: detect.h:700
HashListTable_
Definition: util-hashlist.h:37
DetectEngineTransforms::transforms
TransformData transforms[DETECT_TRANSFORMS_MAX]
Definition: detect.h:372
SidsArray::type
enum DetectBufferMpmType type
Definition: detect-engine-mpm.c:1708
SigGroupHeadInitData_::app_mpms
MpmCtx ** app_mpms
Definition: detect.h:1372
MpmAddPatternCS
int MpmAddPatternCS(struct MpmCtx_ *mpm_ctx, uint8_t *pat, uint16_t patlen, uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags)
Definition: util-mpm.c:241
SC_ERR_INVALID_YAML_CONF_ENTRY
@ SC_ERR_INVALID_YAML_CONF_ENTRY
Definition: util-error.h:169
DetectEngineBufferTypeSupportsTransformations
void DetectEngineBufferTypeSupportsTransformations(DetectEngineCtx *de_ctx, const char *name)
Definition: detect-engine.c:1235
SGH_DIRECTION_TS
#define SGH_DIRECTION_TS(sgh)
Definition: detect-engine-mpm.c:1013
DetectPatternTracker::sm_list
int sm_list
Definition: detect.h:670
DetectEngineAppInspectionEngine_::smd
SigMatchData * smd
Definition: detect.h:406
MpmStore_::mpm_ctx
MpmCtx * mpm_ctx
Definition: detect.h:1293
detect-fast-pattern.h
MpmStorePrepareBuffer
MpmStore * MpmStorePrepareBuffer(DetectEngineCtx *de_ctx, SigGroupHead *sgh, enum MpmBuiltinBuffers buf)
Get MpmStore for a built-in buffer type.
Definition: detect-engine-mpm.c:1569
DetectBufferMpmRegistery_::priority
int priority
Definition: detect.h:631
MPM_TABLE_SIZE
@ MPM_TABLE_SIZE
Definition: util-mpm.h:40
DetectAppLayerMpmRegister2
void DetectAppLayerMpmRegister2(const char *name, int direction, int priority, int(*PrefilterRegister)(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistery *mpm_reg, int list_id), InspectionBufferGetDataPtr GetData, AppProto alproto, int tx_min_progress)
register a MPM engine
Definition: detect-engine-mpm.c:89
MPMB_TCP_PKT_TC
@ MPMB_TCP_PKT_TC
Definition: detect.h:1275
DetectMpmPrepareFrameMpms
int DetectMpmPrepareFrameMpms(DetectEngineCtx *de_ctx)
initialize mpm contexts for applayer buffers that are in "single or "shared" mode.
Definition: detect-engine-mpm.c:497
SignatureHasStreamContent
int SignatureHasStreamContent(const Signature *s)
check if a signature has patterns that are to be inspected against the stream payload (as opposed to ...
Definition: detect-engine-mpm.c:822
util-mpm.h
DetectBufferMpmRegistery_::pname
char pname[32]
Definition: detect.h:627
flags
uint8_t flags
Definition: decode-gre.h:0
Signature_::proto
DetectProto proto
Definition: detect.h:557
MpmStoreInit
int MpmStoreInit(DetectEngineCtx *de_ctx)
Initializes the MpmStore mpm hash table to be used by the detection engine context.
Definition: detect-engine-mpm.c:1295
SigMatchData_::is_last
uint8_t is_last
Definition: detect.h:324
suricata-common.h
SigMatch_::type
uint16_t type
Definition: detect.h:314
MpmCtx_::pattern_cnt
uint32_t pattern_cnt
Definition: util-mpm.h:97
DETECT_BUFFER_MPM_TYPE_APP
@ DETECT_BUFFER_MPM_TYPE_APP
Definition: detect.h:618
DetectBufferTypeSupportsMpm
void DetectBufferTypeSupportsMpm(const char *name)
Definition: detect-engine.c:1065
HashListTableFree
void HashListTableFree(HashListTable *ht)
Definition: util-hashlist.c:82
SigGroupHeadInitData_::match_array
Signature ** match_array
Definition: detect.h:1385
SupportFastPatternForSigMatchList
void SupportFastPatternForSigMatchList(int list_id, int priority)
Lets one add a sm list id to be searched for potential fp supported keywords later.
Definition: detect-fast-pattern.c:132
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:76
DetectEngineFrameInspectionEngine::next
struct DetectEngineFrameInspectionEngine * next
Definition: detect.h:480
SCLogPerf
#define SCLogPerf(...)
Definition: util-debug.h:222
DetectEnginePktInspectionEngine::next
struct DetectEnginePktInspectionEngine * next
Definition: detect.h:453
DetectContentData_::content
uint8_t * content
Definition: detect-content.h:87
PatternMatchDefaultMatcher
uint8_t PatternMatchDefaultMatcher(void)
Function to return the multi pattern matcher algorithm to be used by the engine, based on the mpm-alg...
Definition: detect-engine-mpm.c:856
FatalError
#define FatalError(x,...)
Definition: util-debug.h:530
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:790
DetectMpmPreparePktMpms
int DetectMpmPreparePktMpms(DetectEngineCtx *de_ctx)
initialize mpm contexts for applayer buffers that are in "single or "shared" mode.
Definition: detect-engine-mpm.c:670
DETECT_SM_LIST_TMATCH
@ DETECT_SM_LIST_TMATCH
Definition: detect.h:89
TransformData_::transform
int transform
Definition: detect.h:367
DetectEngineBufferTypeSupportsMpm
void DetectEngineBufferTypeSupportsMpm(DetectEngineCtx *de_ctx, const char *name)
Definition: detect-engine.c:1227
util-validate.h
detect-flow.h
DetectEngineCtx_::app_mpms_list_cnt
uint32_t app_mpms_list_cnt
Definition: detect.h:952
DetectBufferTypeSupportsTransformations
void DetectBufferTypeSupportsTransformations(const char *name)
Definition: detect-engine.c:1075
builtin_mpms
const char * builtin_mpms[]
Definition: detect-engine-mpm.c:66
DetectEngineCtx_::mpm_hash_table
HashListTable * mpm_hash_table
Definition: detect.h:825
MPMB_UDP_TC
@ MPMB_UDP_TC
Definition: detect.h:1279
MpmTableElmt_::DestroyCtx
void(* DestroyCtx)(struct MpmCtx_ *)
Definition: util-mpm.h:148
SigMatchListSMBelongsTo
int SigMatchListSMBelongsTo(const Signature *s, const SigMatch *key_sm)
Definition: detect-parse.c:628
SigGroupHead_::flags
uint32_t flags
Definition: detect.h:1393
SCFree
#define SCFree(p)
Definition: util-mem.h:61
MPM_CTX_FACTORY_UNIQUE_CONTEXT
#define MPM_CTX_FACTORY_UNIQUE_CONTEXT
Definition: util-mpm.h:113
DetectMpmPrepareBuiltinMpms
int DetectMpmPrepareBuiltinMpms(DetectEngineCtx *de_ctx)
initialize mpm contexts for builtin buffers that are in "single or "shared" mode.
Definition: detect-engine-mpm.c:729
SC_ERR_FATAL
@ SC_ERR_FATAL
Definition: util-error.h:203
Signature_::id
uint32_t id
Definition: detect.h:573
DETECT_CONTENT_OFFSET
#define DETECT_CONTENT_OFFSET
Definition: detect-content.h:32
HashListTableBucket_
Definition: util-hashlist.h:28
detect-tcphdr.h
DETECT_CONTENT_MPM
#define DETECT_CONTENT_MPM
Definition: detect-content.h:61
detect-engine-iponly.h
detect-parse.h
Signature_
Signature container.
Definition: detect.h:539
SigMatch_
a single match condition for a signature
Definition: detect.h:313
DetectBufferMpmRegistery_::pkt_v1
struct DetectBufferMpmRegistery_::@87::@90 pkt_v1
MPMB_TCP_PKT_TS
@ MPMB_TCP_PKT_TS
Definition: detect.h:1274
mpm_table
MpmTableElmt mpm_table[MPM_TABLE_SIZE]
Definition: util-mpm.c:48
app-layer-protos.h
DetectEngineCtx_::pkt_mpms_list
DetectBufferMpmRegistery * pkt_mpms_list
Definition: detect.h:954
DetectMpmInitializeAppMpms
void DetectMpmInitializeAppMpms(DetectEngineCtx *de_ctx)
Definition: detect-engine-mpm.c:215
DetectEngineTransforms::cnt
int cnt
Definition: detect.h:373
suricata.h
DetectEngineCtx_::sig_array
Signature ** sig_array
Definition: detect.h:799
DETECT_BUFFER_MPM_TYPE_SIZE
@ DETECT_BUFFER_MPM_TYPE_SIZE
Definition: detect.h:621
DetectContentData_::content_len
uint16_t content_len
Definition: detect-content.h:88
DetectEngineCtx_::buffer_type_id
uint32_t buffer_type_id
Definition: detect.h:946
PrefilterGenericMpmPktRegister
int PrefilterGenericMpmPktRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx, const DetectBufferMpmRegistery *mpm_reg, int list_id)
Definition: detect-engine-prefilter.c:820
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:785
MpmTableElmt_::DestroyThreadCtx
void(* DestroyThreadCtx)(struct MpmCtx_ *, struct MpmThreadCtx_ *)
Definition: util-mpm.h:149
SC_ERR_INITIALIZATION
@ SC_ERR_INITIALIZATION
Definition: util-error.h:75
MpmCtx_
Definition: util-mpm.h:88
SGH_PROTO
#define SGH_PROTO(sgh, p)
Definition: detect-engine-mpm.c:1012
DETECT_CONTENT_REPLACE
#define DETECT_CONTENT_REPLACE
Definition: detect-content.h:51
util-misc.h
flow.h
MpmCtx_::flags
uint8_t flags
Definition: util-mpm.h:92
DetectPktMpmRegisterByParentId
void DetectPktMpmRegisterByParentId(DetectEngineCtx *de_ctx, const int id, const int parent_id, DetectEngineTransforms *transforms)
copy a mpm engine from parent_id, add in transforms
Definition: detect-engine-mpm.c:577
DETECT_CONTENT_FAST_PATTERN
#define DETECT_CONTENT_FAST_PATTERN
Definition: detect-content.h:34
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
DetectBufferMpmRegistery_::sm_list
int16_t sm_list
Definition: detect.h:629
util-enum.h
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:302
SidsArray::active
bool active
Definition: detect-engine-mpm.c:1706
MpmAddPatternCI
int MpmAddPatternCI(struct MpmCtx_ *mpm_ctx, uint8_t *pat, uint16_t patlen, uint16_t offset, uint16_t depth, uint32_t pid, SigIntId sid, uint8_t flags)
Definition: util-mpm.c:250
flow-var.h
SCMemcmp
#define SCMemcmp(a, b, c)
Definition: util-memcmp.h:290
DetectMpmPrepareAppMpms
int DetectMpmPrepareAppMpms(DetectEngineCtx *de_ctx)
initialize mpm contexts for applayer buffers that are in "single or "shared" mode.
Definition: detect-engine-mpm.c:268
DETECT_SM_LIST_SUPPRESS
@ DETECT_SM_LIST_SUPPRESS
Definition: detect.h:92
DetectEngineCtx_::fp_support_smlist_list
SCFPSupportSMList * fp_support_smlist_list
Definition: detect.h:977
MpmStore_::sgh_mpm_context
int32_t sgh_mpm_context
Definition: detect.h:1291
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:111
SIG_FLAG_PREFILTER
#define SIG_FLAG_PREFILTER
Definition: detect.h:235
PatternMatchThreadDestroy
void PatternMatchThreadDestroy(MpmThreadCtx *mpm_thread_ctx, uint16_t mpm_matcher)
Definition: detect-engine-mpm.c:909
MpmStore_::buffer
enum MpmBuiltinBuffers buffer
Definition: detect.h:1289
RetrieveFPForSig
void RetrieveFPForSig(const DetectEngineCtx *de_ctx, Signature *s)
Definition: detect-engine-mpm.c:1080
StringHashDjb2
uint32_t StringHashDjb2(const uint8_t *data, uint32_t datalen)
Definition: util-hash-string.c:22
PrefilterPktStreamRegister
int PrefilterPktStreamRegister(DetectEngineCtx *de_ctx, SigGroupHead *sgh, MpmCtx *mpm_ctx)
Definition: detect-engine-payload.c:110
DetectBufferMpmRegistery_::next
struct DetectBufferMpmRegistery_ * next
Definition: detect.h:664
DETECT_CONTENT_OFFSET_VAR
#define DETECT_CONTENT_OFFSET_VAR
Definition: detect-content.h:45
SignatureInitData_::smlists_array_size
uint32_t smlists_array_size
Definition: detect.h:531
DetectBufferMpmRegistery_::sm_list_base
int16_t sm_list_base
Definition: detect.h:630
SigGroupHeadInitData_::frame_mpms
MpmCtx ** frame_mpms
Definition: detect.h:1374
SIG_FLAG_REQUIRE_PACKET
#define SIG_FLAG_REQUIRE_PACKET
Definition: detect.h:215
DetectEngineFrameInspectionEngine::smd
SigMatchData * smd
Definition: detect.h:479