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