suricata
detect-fast-pattern.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 Anoop Saldanha <anoopsaldanha@gmail.com>
22  *
23  * Implements the fast_pattern keyword
24  */
25 
26 #include "suricata-common.h"
27 #include "detect.h"
28 #include "flow.h"
29 #include "detect-content.h"
30 #include "detect-parse.h"
31 #include "detect-engine.h"
32 #include "detect-engine-mpm.h"
33 #include "detect-engine-build.h"
34 #include "detect-fast-pattern.h"
35 
36 #include "util-error.h"
37 #include "util-byte.h"
38 #include "util-debug.h"
39 #include "util-unittest.h"
40 #include "util-unittest-helper.h"
41 
42 #define PARSE_REGEX "^(\\s*only\\s*)|\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*$"
43 
44 static DetectParseRegex parse_regex;
45 
46 static int DetectFastPatternSetup(DetectEngineCtx *, Signature *, const char *);
47 #ifdef UNITTESTS
48 static void DetectFastPatternRegisterTests(void);
49 #endif
50 
51 /* holds the list of sm match lists that need to be searched for a keyword
52  * that has fp support */
53 static SCFPSupportSMList *g_fp_support_smlist_list = NULL;
54 
55 /**
56  * \brief Checks if a particular buffer is in the list
57  * of lists that need to be searched for a keyword that has fp support.
58  *
59  * \param list_id The list id.
60  *
61  * \retval 1 If supported.
62  * \retval 0 If not.
63  */
65  const int list_id)
66 {
67  if (de_ctx->fp_support_smlist_list == NULL) {
68  return 0;
69  }
70 
71  if (list_id == DETECT_SM_LIST_PMATCH)
72  return 1;
73 
75 }
76 
77 static void Add(SCFPSupportSMList **list, const int list_id, const int priority)
78 {
79  SCFPSupportSMList *ip = NULL;
80  /* insertion point - ip */
81  for (SCFPSupportSMList *tmp = *list; tmp != NULL; tmp = tmp->next) {
82  if (list_id == tmp->list_id) {
83  SCLogDebug("SM list already registered.");
84  return;
85  }
86 
87  /* We need a strict check to be sure that the current list
88  * was not already registered
89  * and other lists with the same priority hide it.
90  */
91  if (priority < tmp->priority)
92  break;
93 
94  ip = tmp;
95  }
96 
97  if (*list == NULL) {
98  SCFPSupportSMList *new = SCCalloc(1, sizeof(SCFPSupportSMList));
99  if (unlikely(new == NULL))
100  exit(EXIT_FAILURE);
101  new->list_id = list_id;
102  new->priority = priority;
103 
104  *list = new;
105  return;
106  }
107 
108  SCFPSupportSMList *new = SCCalloc(1, sizeof(SCFPSupportSMList));
109  if (unlikely(new == NULL))
110  exit(EXIT_FAILURE);
111  new->list_id = list_id;
112  new->priority = priority;
113  if (ip == NULL) {
114  new->next = *list;
115  *list = new;
116  } else {
117  new->next = ip->next;
118  ip->next = new;
119  }
120  return;
121 }
122 
123 /**
124  * \brief Lets one add a sm list id to be searched for potential fp supported
125  * keywords later.
126  *
127  * \param list_id SM list id.
128  * \param priority Priority for this list.
129  */
130 void SupportFastPatternForSigMatchList(int list_id, int priority)
131 {
132  Add(&g_fp_support_smlist_list, list_id, priority);
133 }
134 
136 {
137  Add(&de_ctx->fp_support_smlist_list, list_id, priority);
138 }
139 
140 /**
141  * \brief Registers the keywords(SMs) that should be given fp support.
142  */
144 {
146 
147  /* other types are handled by DetectMpmAppLayerRegister() */
148 }
149 
151 {
152  SCFPSupportSMList *last = NULL;
153  for (SCFPSupportSMList *tmp = g_fp_support_smlist_list; tmp != NULL; tmp = tmp->next) {
154  SCFPSupportSMList *n = SCCalloc(1, sizeof(*n));
155  if (n == NULL) {
156  FatalError("out of memory: %s", strerror(errno));
157  }
158  n->list_id = tmp->list_id;
159  n->priority = tmp->priority;
160 
161  // append
162  if (de_ctx->fp_support_smlist_list == NULL) {
163  last = de_ctx->fp_support_smlist_list = n;
164  } else {
165  BUG_ON(last == NULL);
166  last->next = n;
167  last = n;
168  }
169  }
170 }
171 
173 {
174  for (SCFPSupportSMList *tmp = de_ctx->fp_support_smlist_list; tmp != NULL;) {
175  SCFPSupportSMList *next = tmp->next;
176  SCFree(tmp);
177  tmp = next;
178  }
180 }
181 
182 /**
183  * \brief Registration function for fast_pattern keyword
184  */
186 {
187  sigmatch_table[DETECT_FAST_PATTERN].name = "fast_pattern";
188  sigmatch_table[DETECT_FAST_PATTERN].desc = "force using preceding content in the multi pattern matcher";
189  sigmatch_table[DETECT_FAST_PATTERN].url = "/rules/prefilter-keywords.html#fast-pattern";
191  sigmatch_table[DETECT_FAST_PATTERN].Setup = DetectFastPatternSetup;
193 #ifdef UNITTESTS
194  sigmatch_table[DETECT_FAST_PATTERN].RegisterTests = DetectFastPatternRegisterTests;
195 #endif
197 
198  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
199 }
200 
201 /**
202  * \brief Configures the previous content context for a fast_pattern modifier
203  * keyword used in the rule.
204  *
205  * \param de_ctx Pointer to the Detection Engine Context.
206  * \param s Pointer to the Signature to which the current keyword belongs.
207  * \param arg May hold an argument
208  *
209  * \retval 0 On success.
210  * \retval -1 On failure.
211  */
212 static int DetectFastPatternSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
213 {
214  int res = 0;
215  size_t pcre2len;
216  char arg_substr[128] = "";
217  DetectContentData *cd = NULL;
218  pcre2_match_data *match = NULL;
219 
222  if (pm1 == NULL && pm2 == NULL) {
223  SCLogError("fast_pattern found inside "
224  "the rule, without a content context. Please use a "
225  "content based keyword before using fast_pattern");
226  return -1;
227  }
228 
229  SigMatch *pm = NULL;
230  if (pm1 && pm2) {
231  if (pm1->idx > pm2->idx)
232  pm = pm1;
233  else
234  pm = pm2;
235  } else if (pm1 && !pm2) {
236  pm = pm1;
237  } else {
238  pm = pm2;
239  }
240 
241  cd = (DetectContentData *)pm->ctx;
242  if ((cd->flags & DETECT_CONTENT_NEGATED) &&
243  ((cd->flags & DETECT_CONTENT_DISTANCE) ||
244  (cd->flags & DETECT_CONTENT_WITHIN) ||
245  (cd->flags & DETECT_CONTENT_OFFSET) ||
246  (cd->flags & DETECT_CONTENT_DEPTH))) {
247 
248  /* we can't have any of these if we are having "only" */
249  SCLogError("fast_pattern; cannot be "
250  "used with negated content, along with relative modifiers");
251  goto error;
252  }
253 
254  if (arg == NULL|| strcmp(arg, "") == 0) {
256  SCLogError("can't use multiple fast_pattern "
257  "options for the same content");
258  goto error;
259  }
260  else { /*allow only one content to have fast_pattern modifier*/
261  for (uint32_t list_id = 0; list_id < DETECT_SM_LIST_MAX; list_id++) {
262  SigMatch *sm = NULL;
263  for (sm = s->init_data->smlists[list_id]; sm != NULL; sm = sm->next) {
264  if (sm->type == DETECT_CONTENT) {
265  DetectContentData *tmp_cd = (DetectContentData *)sm->ctx;
266  if (tmp_cd->flags & DETECT_CONTENT_FAST_PATTERN) {
267  SCLogError("fast_pattern "
268  "can be used on only one content in a rule");
269  goto error;
270  }
271  }
272  }
273  }
274  }
276  return 0;
277  }
278 
279  /* Execute the regex and populate args with captures. */
280  int ret = DetectParsePcreExec(&parse_regex, &match, arg, 0, 0);
281  /* fast pattern only */
282  if (ret == 2) {
283  if ((cd->flags & DETECT_CONTENT_NEGATED) ||
284  (cd->flags & DETECT_CONTENT_DISTANCE) ||
285  (cd->flags & DETECT_CONTENT_WITHIN) ||
286  (cd->flags & DETECT_CONTENT_OFFSET) ||
287  (cd->flags & DETECT_CONTENT_DEPTH)) {
288 
289  /* we can't have any of these if we are having "only" */
290  SCLogError("fast_pattern: only; cannot be "
291  "used with negated content or with any of the relative "
292  "modifiers like distance, within, offset, depth");
293  goto error;
294  }
296 
297  /* fast pattern chop */
298  } else if (ret == 4) {
299  pcre2len = sizeof(arg_substr);
300  res = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
301  if (res < 0) {
302  SCLogError("pcre2_substring_copy_bynumber failed "
303  "for fast_pattern offset");
304  goto error;
305  }
306  uint16_t offset;
307  if (StringParseUint16(&offset, 10, 0,
308  (const char *)arg_substr) < 0) {
309  SCLogError("Invalid fast pattern offset:"
310  " \"%s\"",
311  arg_substr);
312  goto error;
313  }
314 
315  pcre2len = sizeof(arg_substr);
316  res = pcre2_substring_copy_bynumber(match, 3, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
317  if (res < 0) {
318  SCLogError("pcre2_substring_copy_bynumber failed "
319  "for fast_pattern offset");
320  goto error;
321  }
322  uint16_t length;
323  if (StringParseUint16(&length, 10, 0,
324  (const char *)arg_substr) < 0) {
325  SCLogError("Invalid value for fast "
326  "pattern: \"%s\"",
327  arg_substr);
328  goto error;
329  }
330 
331  // Avoiding integer overflow
332  if (offset > (65535 - length)) {
333  SCLogError("Fast pattern (length + offset) "
334  "exceeds limit pattern length limit");
335  goto error;
336  }
337 
338  if (offset + length > cd->content_len) {
339  SCLogError("Fast pattern (length + "
340  "offset (%u)) exceeds pattern length (%u)",
341  offset + length, cd->content_len);
342  goto error;
343  }
344 
345  cd->fp_chop_offset = offset;
346  cd->fp_chop_len = length;
348 
349  } else {
350  SCLogError("parse error, ret %" PRId32 ", string %s", ret, arg);
351  goto error;
352  }
353 
355 
356  pcre2_match_data_free(match);
357  return 0;
358 
359  error:
360  if (match) {
361  pcre2_match_data_free(match);
362  }
363  return -1;
364 }
365 
366 /*----------------------------------Unittests---------------------------------*/
367 
368 #ifdef UNITTESTS
369 #include "detect-engine-alert.h"
370 static SigMatch *GetMatches(Signature *s, const int list)
371 {
372  SigMatch *sm = DetectBufferGetFirstSigMatch(s, list);
373  if (sm == NULL && list < DETECT_SM_LIST_MAX) {
374  sm = s->init_data->smlists[list];
375  }
376  return sm;
377 }
378 
379 static int DetectFastPatternStickySingle(const char *sticky, const int list)
380 {
383  char string[1024];
384  snprintf(string, sizeof(string),
385  "alert tcp any any -> any any "
386  "(%s%scontent:\"one\"; fast_pattern; sid:1;)",
387  sticky ? sticky : "", sticky ? "; " : " ");
388  Signature *s = DetectEngineAppendSig(de_ctx, string);
389  FAIL_IF_NULL(s);
390  SigMatch *sm = GetMatches(s, list);
391  FAIL_IF_NULL(sm);
397  PASS;
398 }
399 
400 static int DetectFastPatternModifierSingle(const char *sticky, const int list)
401 {
404  char string[1024];
405  snprintf(string, sizeof(string),
406  "alert tcp any any -> any any "
407  "(content:\"one\"; %s%sfast_pattern; sid:1;)",
408  sticky ? sticky : "", sticky ? "; " : " ");
409  Signature *s = DetectEngineAppendSig(de_ctx, string);
410  FAIL_IF_NULL(s);
411  SigMatch *sm = GetMatches(s, list);
412  FAIL_IF_NULL(sm);
418  PASS;
419 }
420 
421 static int DetectFastPatternStickySingleNoFP(const char *sticky, const int list)
422 {
425  char string[1024];
426  snprintf(string, sizeof(string),
427  "alert tcp any any -> any any "
428  "(%s%scontent:\"one\"; sid:1;)",
429  sticky ? sticky : "", sticky ? "; " : " ");
430  Signature *s = DetectEngineAppendSig(de_ctx, string);
431  FAIL_IF_NULL(s);
432  SigMatch *sm = GetMatches(s, list);
433  FAIL_IF_NULL(sm);
439  PASS;
440 }
441 
442 static int DetectFastPatternModifierSingleNoFP(const char *sticky, const int list)
443 {
446  char string[1024];
447  snprintf(string, sizeof(string),
448  "alert tcp any any -> any any "
449  "(content:\"one\"; %s%ssid:1;)",
450  sticky ? sticky : "", sticky ? "; " : " ");
451  Signature *s = DetectEngineAppendSig(de_ctx, string);
452  FAIL_IF_NULL(s);
453  SigMatch *sm = GetMatches(s, list);
454  FAIL_IF_NULL(sm);
460  PASS;
461 }
462 
463 static int DetectFastPatternStickySingleBadArg(const char *sticky)
464 {
467  char string[1024];
468  /* bogus argument to fast_pattern */
469  snprintf(string, sizeof(string),
470  "alert tcp any any -> any any "
471  "(%s%scontent:\"one\"; fast_pattern:boo; sid:1;)",
472  sticky ? sticky : "", sticky ? "; " : " ");
473  Signature *s = DetectEngineAppendSig(de_ctx, string);
474  FAIL_IF_NOT_NULL(s);
475  /* fast_pattern only with distance */
476  snprintf(string, sizeof(string),
477  "alert tcp any any -> any any "
478  "(%s%scontent:\"one\"; fast_pattern:only; content:\"two\"; distance:10; sid:1;)",
479  sticky ? sticky : "", sticky ? "; " : " ");
480  s = DetectEngineAppendSig(de_ctx, string);
481  FAIL_IF_NOT_NULL(s);
482  /* fast_pattern only with distance */
483  snprintf(string, sizeof(string),
484  "alert tcp any any -> any any "
485  "(%s%scontent:\"one\"; content:\"two\"; fast_pattern:only; distance:10; sid:1;)",
486  sticky ? sticky : "", sticky ? "; " : " ");
487  s = DetectEngineAppendSig(de_ctx, string);
488  FAIL_IF_NOT_NULL(s);
489  /* fast_pattern only with distance */
490  snprintf(string, sizeof(string),
491  "alert tcp any any -> any any "
492  "(%s%scontent:\"one\"; content:\"two\"; distance:10; fast_pattern:only; sid:1;)",
493  sticky ? sticky : "", sticky ? "; " : " ");
494  s = DetectEngineAppendSig(de_ctx, string);
495  FAIL_IF_NOT_NULL(s);
496  /* fast_pattern chop with invalid values */
497  snprintf(string, sizeof(string),
498  "alert tcp any any -> any any "
499  "(%s%scontent:\"one\"; fast_pattern:5,6; sid:1;)",
500  sticky ? sticky : "", sticky ? "; " : " ");
501  s = DetectEngineAppendSig(de_ctx, string);
502  FAIL_IF_NOT_NULL(s);
504  PASS;
505 }
506 
507 static int DetectFastPatternModifierBadRules(const char *sticky)
508 {
511  char string[1024];
512  /* bogus argument to fast_pattern */
513  snprintf(string, sizeof(string),
514  "alert tcp any any -> any any "
515  "(content:\"one\"; %s%sfast_pattern:boo; sid:1;)",
516  sticky ? sticky : "", sticky ? "; " : " ");
517  Signature *s = DetectEngineAppendSig(de_ctx, string);
518  FAIL_IF_NOT_NULL(s);
519  /* fast_pattern only with distance */
520  snprintf(string, sizeof(string),
521  "alert tcp any any -> any any "
522  "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%sdistance:10; sid:1;)",
523  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
524  s = DetectEngineAppendSig(de_ctx, string);
525  FAIL_IF_NOT_NULL(s);
526 #if 0 // TODO bug?
527  /* fast_pattern only with distance */
528  snprintf(string, sizeof(string), "alert tcp any any -> any any "
529  "(content:\"one\"; %s%s content:\"two\"; %s%sdistance:10; fast_pattern:only; sid:1;)",
530  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
531  s = DetectEngineAppendSig(de_ctx, string);
532  FAIL_IF_NOT_NULL(s);
533 #endif
534  /* fast_pattern only with within */
535  snprintf(string, sizeof(string),
536  "alert tcp any any -> any any "
537  "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%swithin:10; sid:1;)",
538  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
539  s = DetectEngineAppendSig(de_ctx, string);
540  FAIL_IF_NOT_NULL(s);
541  /* fast_pattern only with within */
542  snprintf(string, sizeof(string),
543  "alert tcp any any -> any any "
544  "(content:\"one\"; %s%s content:\"two\"; %s%swithin:10; fast_pattern:only; sid:1;)",
545  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
546  s = DetectEngineAppendSig(de_ctx, string);
547  FAIL_IF_NOT_NULL(s);
548  /* fast_pattern only with offset */
549  snprintf(string, sizeof(string),
550  "alert tcp any any -> any any "
551  "(content:\"one\"; %s%sfast_pattern:only; offset:10; sid:1;)",
552  sticky ? sticky : "", sticky ? "; " : " ");
553  s = DetectEngineAppendSig(de_ctx, string);
554  FAIL_IF_NOT_NULL(s);
555  /* fast_pattern only with offset */
556  snprintf(string, sizeof(string),
557  "alert tcp any any -> any any "
558  "(content:\"one\"; %s%s offset:10; fast_pattern:only; sid:1;)",
559  sticky ? sticky : "", sticky ? "; " : " ");
560  s = DetectEngineAppendSig(de_ctx, string);
561  FAIL_IF_NOT_NULL(s);
562  /* fast_pattern only with depth */
563  snprintf(string, sizeof(string),
564  "alert tcp any any -> any any "
565  "(content:\"one\"; %s%sfast_pattern:only; depth:10; sid:1;)",
566  sticky ? sticky : "", sticky ? "; " : " ");
567  s = DetectEngineAppendSig(de_ctx, string);
568  FAIL_IF_NOT_NULL(s);
569  /* fast_pattern only with depth */
570  snprintf(string, sizeof(string),
571  "alert tcp any any -> any any "
572  "(content:\"one\"; %s%s depth:10; fast_pattern:only; sid:1;)",
573  sticky ? sticky : "", sticky ? "; " : " ");
574  s = DetectEngineAppendSig(de_ctx, string);
575  FAIL_IF_NOT_NULL(s);
576  /* fast_pattern only negate */
577  snprintf(string, sizeof(string),
578  "alert tcp any any -> any any "
579  "(content:\"one\"; %s%s content:!\"two\"; %s%sfast_pattern:only; sid:1;)",
580  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
581  s = DetectEngineAppendSig(de_ctx, string);
582  FAIL_IF_NOT_NULL(s);
583  /* fast_pattern chop with invalid values */
584  snprintf(string, sizeof(string),
585  "alert tcp any any -> any any "
586  "(content:\"one\"; %s%sfast_pattern:5,6; sid:1;)",
587  sticky ? sticky : "", sticky ? "; " : " ");
588  s = DetectEngineAppendSig(de_ctx, string);
589  FAIL_IF_NOT_NULL(s);
590  /* fast_pattern chop with invalid values */
591  snprintf(string, sizeof(string),
592  "alert tcp any any -> any any "
593  "(content:\"one\"; %s%sfast_pattern:65977,2; sid:1;)",
594  sticky ? sticky : "", sticky ? "; " : " ");
595  s = DetectEngineAppendSig(de_ctx, string);
596  FAIL_IF_NOT_NULL(s);
597  /* fast_pattern chop with invalid values */
598  snprintf(string, sizeof(string),
599  "alert tcp any any -> any any "
600  "(content:\"one\"; %s%sfast_pattern:2,65977; sid:1;)",
601  sticky ? sticky : "", sticky ? "; " : " ");
602  s = DetectEngineAppendSig(de_ctx, string);
603  FAIL_IF_NOT_NULL(s);
604  /* fast_pattern chop with invalid values */
605  snprintf(string, sizeof(string),
606  "alert tcp any any -> any any "
607  "(content:\"one\"; %s%sfast_pattern:2,65534; sid:1;)",
608  sticky ? sticky : "", sticky ? "; " : " ");
609  s = DetectEngineAppendSig(de_ctx, string);
610  FAIL_IF_NOT_NULL(s);
611  /* fast_pattern chop with invalid values */
612  snprintf(string, sizeof(string),
613  "alert tcp any any -> any any "
614  "(content:\"one\"; %s%sfast_pattern:65534,2; sid:1;)",
615  sticky ? sticky : "", sticky ? "; " : " ");
616  s = DetectEngineAppendSig(de_ctx, string);
617  FAIL_IF_NOT_NULL(s);
618  /* negated fast_pattern with distance */
619  snprintf(string, sizeof(string),
620  "alert tcp any any -> any any "
621  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdistance:10; sid:1;)",
622  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
623  s = DetectEngineAppendSig(de_ctx, string);
624  FAIL_IF_NOT_NULL(s);
625  /* negated fast_pattern with within */
626  snprintf(string, sizeof(string),
627  "alert tcp any any -> any any "
628  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%swithin:10; sid:1;)",
629  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
630  s = DetectEngineAppendSig(de_ctx, string);
631  FAIL_IF_NOT_NULL(s);
632  /* negated fast_pattern with depth */
633  snprintf(string, sizeof(string),
634  "alert tcp any any -> any any "
635  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdepth:10; sid:1;)",
636  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
637  s = DetectEngineAppendSig(de_ctx, string);
638  FAIL_IF_NOT_NULL(s);
639  /* negated fast_pattern with offset */
640  snprintf(string, sizeof(string),
641  "alert tcp any any -> any any "
642  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%soffset:10; sid:1;)",
643  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
644  s = DetectEngineAppendSig(de_ctx, string);
645  FAIL_IF_NOT_NULL(s);
647  PASS;
648 }
649 
650 static int DetectFastPatternStickySingleFPOnly(const char *sticky, const int list)
651 {
654  char string[1024];
655  snprintf(string, sizeof(string),
656  "alert tcp any any -> any any "
657  "(%s%scontent:\"one\"; fast_pattern:only; sid:1;)",
658  sticky ? sticky : "", sticky ? "; " : " ");
659  Signature *s = DetectEngineAppendSig(de_ctx, string);
660  FAIL_IF_NULL(s);
661  SigMatch *sm = GetMatches(s, list);
662  FAIL_IF_NULL(sm);
669  PASS;
670 }
671 
672 static int DetectFastPatternModifierFPOnly(const char *sticky, const int list)
673 {
676  char string[1024];
677  snprintf(string, sizeof(string),
678  "alert tcp any any -> any any "
679  "(content:\"one\"; %s%sfast_pattern:only; sid:1;)",
680  sticky ? sticky : "", sticky ? "; " : " ");
681  Signature *s = DetectEngineAppendSig(de_ctx, string);
682  FAIL_IF_NULL(s);
683  SigMatch *sm = GetMatches(s, list);
684  FAIL_IF_NULL(sm);
690 
691  snprintf(string, sizeof(string),
692  "alert tcp any any -> any any "
693  "(content:\"one\"; %s%scontent:\"two\"; %s%sfast_pattern:only; sid:2;)",
694  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
695  s = DetectEngineAppendSig(de_ctx, string);
696  FAIL_IF_NULL(s);
697  sm = GetMatches(s, list);
698  FAIL_IF_NULL(sm);
699  FAIL_IF_NULL(sm->next);
701  cd = (DetectContentData *)sm->ctx;
703  FAIL_IF_NOT(
705  sm = sm->next;
707  cd = (DetectContentData *)sm->ctx;
711 
712  snprintf(string, sizeof(string),
713  "alert tcp any any -> any any "
714  "(content:\"one\"; %s%scontent:\"two\"; distance:10; %s%scontent:\"three\"; "
715  "%s%sfast_pattern:only; sid:3;)",
716  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
717  sticky ? sticky : "", sticky ? "; " : " ");
718  s = DetectEngineAppendSig(de_ctx, string);
719  FAIL_IF_NULL(s);
720  sm = GetMatches(s, list);
721  FAIL_IF_NULL(sm);
722  FAIL_IF_NULL(sm->next);
724  cd = (DetectContentData *)sm->ctx;
726  FAIL_IF_NOT(
728  sm = sm->next;
729  FAIL_IF_NULL(sm->next);
731  cd = (DetectContentData *)sm->ctx;
733  FAIL_IF_NOT(
735  sm = sm->next;
736  FAIL_IF_NOT_NULL(sm->next);
738  cd = (DetectContentData *)sm->ctx;
742 
743  snprintf(string, sizeof(string),
744  "alert tcp any any -> any any "
745  "(content:\"one\"; %s%scontent:\"two\"; within:10; %s%scontent:\"three\"; "
746  "%s%sfast_pattern:only; sid:4;)",
747  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
748  sticky ? sticky : "", sticky ? "; " : " ");
749  s = DetectEngineAppendSig(de_ctx, string);
750  FAIL_IF_NULL(s);
751  sm = GetMatches(s, list);
752  FAIL_IF_NULL(sm);
753  FAIL_IF_NULL(sm->next);
755  cd = (DetectContentData *)sm->ctx;
757  FAIL_IF_NOT(
759  sm = sm->next;
760  FAIL_IF_NULL(sm->next);
762  cd = (DetectContentData *)sm->ctx;
764  FAIL_IF_NOT(
766  sm = sm->next;
767  FAIL_IF_NOT_NULL(sm->next);
769  cd = (DetectContentData *)sm->ctx;
773 
774  snprintf(string, sizeof(string),
775  "alert tcp any any -> any any "
776  "(content:\"one\"; %s%scontent:\"two\"; offset:10; %s%scontent:\"three\"; "
777  "%s%sfast_pattern:only; sid:5;)",
778  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
779  sticky ? sticky : "", sticky ? "; " : " ");
780  s = DetectEngineAppendSig(de_ctx, string);
781  FAIL_IF_NULL(s);
782  sm = GetMatches(s, list);
783  FAIL_IF_NULL(sm);
784  FAIL_IF_NULL(sm->next);
786  cd = (DetectContentData *)sm->ctx;
788  FAIL_IF_NOT(
790  sm = sm->next;
791  FAIL_IF_NULL(sm->next);
793  cd = (DetectContentData *)sm->ctx;
795  FAIL_IF_NOT(
797  sm = sm->next;
798  FAIL_IF_NOT_NULL(sm->next);
800  cd = (DetectContentData *)sm->ctx;
804 
805  snprintf(string, sizeof(string),
806  "alert tcp any any -> any any "
807  "(content:\"one\"; %s%scontent:\"two\"; depth:10; %s%scontent:\"three\"; "
808  "%s%sfast_pattern:only; sid:6;)",
809  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
810  sticky ? sticky : "", sticky ? "; " : " ");
811  s = DetectEngineAppendSig(de_ctx, string);
812  FAIL_IF_NULL(s);
813  sm = GetMatches(s, list);
814  FAIL_IF_NULL(sm);
815  FAIL_IF_NULL(sm->next);
817  cd = (DetectContentData *)sm->ctx;
819  FAIL_IF_NOT(
821  sm = sm->next;
822  FAIL_IF_NULL(sm->next);
824  cd = (DetectContentData *)sm->ctx;
826  FAIL_IF_NOT(
828  sm = sm->next;
829  FAIL_IF_NOT_NULL(sm->next);
831  cd = (DetectContentData *)sm->ctx;
835 
836  snprintf(string, sizeof(string),
837  "alert tcp any any -> any any "
838  "(content:!\"one\"; %s%sfast_pattern; content:\"two\"; depth:10; %s%ssid:7;)",
839  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
840  s = DetectEngineAppendSig(de_ctx, string);
841  FAIL_IF_NULL(s);
842  sm = GetMatches(s, list);
843  FAIL_IF_NULL(sm);
844  FAIL_IF_NULL(sm->next);
846  cd = (DetectContentData *)sm->ctx;
851  sm = sm->next;
852  FAIL_IF_NOT_NULL(sm->next);
854  cd = (DetectContentData *)sm->ctx;
856  FAIL_IF_NOT(
858 
860  PASS;
861 }
862 
863 static int DetectFastPatternStickyFPChop(const char *sticky, const int list)
864 {
867  char string[1024];
868  snprintf(string, sizeof(string),
869  "alert tcp any any -> any any "
870  "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; sid:1;)",
871  sticky ? sticky : "", sticky ? "; " : " ");
872  Signature *s = DetectEngineAppendSig(de_ctx, string);
873  FAIL_IF_NULL(s);
874  SigMatch *sm = GetMatches(s, list);
875  FAIL_IF_NULL(sm);
882  FAIL_IF_NOT(cd->fp_chop_offset == 3);
883  FAIL_IF_NOT(cd->fp_chop_len == 4);
884 
885  snprintf(string, sizeof(string),
886  "alert tcp any any -> any any "
887  "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; content:\"xyz\"; distance:10; sid:2;)",
888  sticky ? sticky : "", sticky ? "; " : " ");
889  s = DetectEngineAppendSig(de_ctx, string);
890  FAIL_IF_NULL(s);
891  sm = GetMatches(s, list);
892  FAIL_IF_NULL(sm);
894  cd = (DetectContentData *)sm->ctx;
899  FAIL_IF_NOT(cd->fp_chop_offset == 3);
900  FAIL_IF_NOT(cd->fp_chop_len == 4);
901 
903  PASS;
904 }
905 
906 static int DetectFastPatternModifierFPChop(const char *sticky, const int list)
907 {
910  char string[1024];
911  snprintf(string, sizeof(string),
912  "alert tcp any any -> any any "
913  "(content:\"onetwothree\"; %s%sfast_pattern:3,4; sid:1;)",
914  sticky ? sticky : "", sticky ? "; " : " ");
915  Signature *s = DetectEngineAppendSig(de_ctx, string);
916  FAIL_IF_NULL(s);
917  SigMatch *sm = GetMatches(s, list);
918  FAIL_IF_NULL(sm);
925  FAIL_IF_NOT(cd->fp_chop_offset == 3);
926  FAIL_IF_NOT(cd->fp_chop_len == 4);
927 
928  snprintf(string, sizeof(string),
929  "alert tcp any any -> any any "
930  "(content:!\"onetwothree\"; %s%sfast_pattern:3,4; sid:2;)",
931  sticky ? sticky : "", sticky ? "; " : " ");
932  s = DetectEngineAppendSig(de_ctx, string);
933  FAIL_IF_NULL(s);
934  sm = GetMatches(s, list);
935  FAIL_IF_NULL(sm);
937  cd = (DetectContentData *)sm->ctx;
944  FAIL_IF_NOT(cd->fp_chop_offset == 3);
945  FAIL_IF_NOT(cd->fp_chop_len == 4);
946 
948  PASS;
949 }
950 
951 /**
952  * \test Checks if a fast_pattern is registered in a Signature
953  */
954 static int DetectFastPatternTest01(void)
955 {
956  FAIL_IF_NOT(DetectFastPatternStickySingle(NULL, DETECT_SM_LIST_PMATCH));
957  FAIL_IF_NOT(DetectFastPatternModifierSingle(NULL, DETECT_SM_LIST_PMATCH));
958  FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(NULL, DETECT_SM_LIST_PMATCH));
959  FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(NULL, DETECT_SM_LIST_PMATCH));
960  FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(NULL));
961  FAIL_IF_NOT(DetectFastPatternModifierBadRules(NULL));
962  FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(NULL, DETECT_SM_LIST_PMATCH));
963  FAIL_IF_NOT(DetectFastPatternModifierFPOnly(NULL, DETECT_SM_LIST_PMATCH));
964  FAIL_IF_NOT(DetectFastPatternStickyFPChop(NULL, DETECT_SM_LIST_PMATCH));
965  FAIL_IF_NOT(DetectFastPatternModifierFPChop(NULL, DETECT_SM_LIST_PMATCH));
966 
967  struct {
968  const char *buffer_name;
969  const char *sb_name;
970  const char *mod_name;
971  } keywords[] = {
972  { "file_data", "file.data", NULL },
973  { "http_uri", "http.uri", "http_uri" },
974  { "http_raw_uri", "http.uri.raw", "http_raw_uri" },
975  { "http_user_agent", "http.user_agent", "http_user_agent" },
976  { "http_header", "http.header", "http_header" },
977  // http_raw_header requires sigs to have a direction
978  //{ "http_raw_header", "http.header.raw", "http_raw_header" },
979  { "http_method", "http.method", "http_method" },
980  { "http_cookie", "http.cookie", "http_cookie" },
981  { "http_host", "http.host", "http_host" },
982  { "http_raw_host", "http.host.raw", "http_raw_host" },
983  { "http_stat_code", "http.stat_code", "http_stat_code" },
984  { "http_stat_msg", "http.stat_msg", "http_stat_msg" },
985  { "http_client_body", "http.request_body", "http_client_body" },
986  { NULL, NULL, NULL },
987  };
988 
989  for (int i = 0; keywords[i].buffer_name != NULL; i++) {
990  const int list_id = DetectBufferTypeGetByName(keywords[i].buffer_name);
991  FAIL_IF(list_id == -1);
992 
993  const char *k = keywords[i].sb_name;
994  if (k) {
995  FAIL_IF_NOT(DetectFastPatternStickySingle(k, list_id));
996  FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(k, list_id));
997  FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(k));
998  FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(k, list_id));
999  FAIL_IF_NOT(DetectFastPatternStickyFPChop(k, list_id));
1000  }
1001  k = keywords[i].mod_name;
1002  if (k) {
1003  FAIL_IF_NOT(DetectFastPatternModifierSingle(k, list_id));
1004  FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(k, list_id));
1005  FAIL_IF_NOT(DetectFastPatternModifierBadRules(k));
1006  FAIL_IF_NOT(DetectFastPatternModifierFPOnly(k, list_id));
1007  FAIL_IF_NOT(DetectFastPatternModifierFPChop(k, list_id));
1008  }
1009  }
1010 
1011  PASS;
1012 }
1013 
1014 /**
1015  * \test Checks to make sure that other sigs work that should when fast_pattern is inspecting on the
1016  * same payload
1017  *
1018  */
1019 static int DetectFastPatternTest14(void)
1020 {
1021  uint8_t *buf = (uint8_t *)"Dummy is our name. Oh yes. From right here "
1022  "right now, all the way to hangover. right. strings5_imp now here "
1023  "comes our dark knight strings_string5. Yes here is our dark knight";
1024  uint16_t buflen = strlen((char *)buf);
1025  ThreadVars th_v;
1026  DetectEngineThreadCtx *det_ctx = NULL;
1027 
1028  memset(&th_v, 0, sizeof(th_v));
1029  Packet *p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
1030  FAIL_IF_NULL(p);
1031 
1034  de_ctx->flags |= DE_QUIET;
1035 
1037 
1039  "alert tcp any any -> any any "
1040  "(msg:\"fast_pattern test\"; content:\"strings_string5\"; content:\"knight\"; "
1041  "fast_pattern; sid:1;)");
1042  FAIL_IF_NULL(s);
1043 
1045  "alert tcp any any -> any any "
1046  "(msg:\"test different content\"; content:\"Dummy is our name\"; sid:2;)");
1047  FAIL_IF_NULL(s);
1048 
1050  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1051 
1052  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1055 
1056  UTHFreePackets(&p, 1);
1057  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1059  FlowShutdown();
1060  PASS;
1061 }
1062 
1063 /**
1064  * Unittest to check
1065  * - if we assign different content_ids to duplicate patterns, but one of the
1066  * patterns has a fast_pattern chop set.
1067  * - if 2 unique patterns get unique ids.
1068  * - if 2 duplicate patterns, with no chop set get unique ids.
1069  */
1070 static int DetectFastPatternTest671(void)
1071 {
1074  de_ctx->flags |= DE_QUIET;
1075 
1076  Signature *s[6];
1077  s[0] = DetectEngineAppendSig(
1078  de_ctx, "alert tcp any any -> any any (content:\"onetwothreefour\"; sid:1;)");
1079  FAIL_IF_NULL(s[0]);
1080  s[1] = DetectEngineAppendSig(
1081  de_ctx, "alert tcp any any -> any any (content:\"onetwothreefour\"; sid:2;)");
1082  FAIL_IF_NULL(s[1]);
1083  s[2] = DetectEngineAppendSig(
1084  de_ctx, "alert tcp any any -> any any (content:\"uniquepattern\"; sid:3;)");
1085  FAIL_IF_NULL(s[2]);
1087  "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:3,5; sid:4;)");
1088  FAIL_IF_NULL(s[3]);
1089  s[4] = DetectEngineAppendSig(
1090  de_ctx, "alert tcp any any -> any any (content:\"twoth\"; sid:5;)");
1091  FAIL_IF_NULL(s[4]);
1093  "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:0,15; "
1094  "sid:6;)");
1095  FAIL_IF_NULL(s[5]);
1096 
1098 
1100  DetectContentData *cd = (DetectContentData *)smd->ctx;
1101  FAIL_IF(cd->id != 0);
1102 
1103  smd = s[1]->sm_arrays[DETECT_SM_LIST_PMATCH];
1104  cd = (DetectContentData *)smd->ctx;
1105  FAIL_IF(cd->id != 0);
1106 
1107  smd = s[2]->sm_arrays[DETECT_SM_LIST_PMATCH];
1108  cd = (DetectContentData *)smd->ctx;
1109  FAIL_IF(cd->id != 2);
1110 
1111  smd = s[3]->sm_arrays[DETECT_SM_LIST_PMATCH];
1112  cd = (DetectContentData *)smd->ctx;
1113  FAIL_IF(cd->id != 1);
1114 
1115  smd = s[4]->sm_arrays[DETECT_SM_LIST_PMATCH];
1116  cd = (DetectContentData *)smd->ctx;
1117  FAIL_IF(cd->id != 1);
1118 
1119  smd = s[5]->sm_arrays[DETECT_SM_LIST_PMATCH];
1120  cd = (DetectContentData *)smd->ctx;
1121  FAIL_IF(cd->id != 0);
1122 
1124  PASS;
1125 }
1126 
1127 static int DetectFastPatternPrefilter(void)
1128 {
1131  const char *string = "alert tcp any any -> any any "
1132  "(content:\"one\"; prefilter; sid:1;)";
1133  Signature *s = DetectEngineAppendSig(de_ctx, string);
1134  FAIL_IF_NULL(s);
1136  FAIL_IF_NULL(sm);
1142  PASS;
1143 }
1144 
1145 static void DetectFastPatternRegisterTests(void)
1146 {
1147  UtRegisterTest("DetectFastPatternTest01", DetectFastPatternTest01);
1148  UtRegisterTest("DetectFastPatternTest14", DetectFastPatternTest14);
1149  /* Unittest to check
1150  * - if we assign different content_ids to duplicate patterns, but one of the
1151  * patterns has a fast_pattern chop set.
1152  * - if 2 unique patterns get unique ids.
1153  * - if 2 duplicate patterns, with no chop set get unique ids.
1154  */
1155  UtRegisterTest("DetectFastPatternTest671", DetectFastPatternTest671);
1156 
1157  UtRegisterTest("DetectFastPatternPrefilter", DetectFastPatternPrefilter);
1158 }
1159 #endif
util-byte.h
SCFPSupportSMList_
Definition: detect.h:752
SigTableElmt_::url
const char * url
Definition: detect.h:1299
detect-content.h
detect-engine.h
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:116
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
DETECT_CONTENT_FAST_PATTERN_CHOP
#define DETECT_CONTENT_FAST_PATTERN_CHOP
Definition: detect-content.h:36
SignatureInitData_::smlists
struct SigMatch_ * smlists[DETECT_SM_LIST_MAX]
Definition: detect.h:581
DetectContentData_::fp_chop_len
uint16_t fp_chop_len
Definition: detect-content.h:98
SigTableElmt_::desc
const char * desc
Definition: detect.h:1298
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1286
SCFPSupportSMList_::next
struct SCFPSupportSMList_ * next
Definition: detect.h:755
DetectParseRegex
Definition: detect-parse.h:62
SCFPSupportSMList_::list_id
int list_id
Definition: detect.h:753
SigTableElmt_::name
const char * name
Definition: detect.h:1296
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
DETECT_CONTENT
@ DETECT_CONTENT
Definition: detect-engine-register.h:62
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
PacketAlertCheck
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
Definition: detect-engine-alert.c:141
DETECT_FAST_PATTERN
@ DETECT_FAST_PATTERN
Definition: detect-engine-register.h:73
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:362
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1290
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:839
StringParseUint16
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:337
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2533
SupportFastPatternForSigMatchTypes
void SupportFastPatternForSigMatchTypes(void)
Registers the keywords(SMs) that should be given fp support.
Definition: detect-fast-pattern.c:143
DE_QUIET
#define DE_QUIET
Definition: detect.h:324
UTHBuildPacket
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
Definition: util-unittest-helper.c:340
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1895
Signature_::sm_arrays
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
Definition: detect.h:649
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
Definition: detect-parse.c:2674
DetectContentData_
Definition: detect-content.h:93
DetectContentData_::fp_chop_offset
uint16_t fp_chop_offset
Definition: detect-content.h:100
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2620
SigMatchData_
Data needed for Match()
Definition: detect.h:359
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1281
DetectEngineRegisterFastPatternForId
void DetectEngineRegisterFastPatternForId(DetectEngineCtx *de_ctx, int list_id, int priority)
Definition: detect-fast-pattern.c:135
PARSE_REGEX
#define PARSE_REGEX
Definition: detect-fast-pattern.c:42
util-unittest.h
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:1072
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:537
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
util-error.h
DETECT_CONTENT_DISTANCE
#define DETECT_CONTENT_DISTANCE
Definition: detect-content.h:30
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1095
DetectGetLastSMFromMpmLists
SigMatch * DetectGetLastSMFromMpmLists(const DetectEngineCtx *de_ctx, const Signature *s)
get the last SigMatch from lists that support MPM.
Definition: detect-parse.c:582
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2791
DETECT_CONTENT_DEPTH
#define DETECT_CONTENT_DEPTH
Definition: detect-content.h:33
detect-engine-mpm.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:354
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
DetectContentData_::id
PatIntId id
Definition: detect-content.h:105
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:353
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:300
DetectEngineInitializeFastPatternList
void DetectEngineInitializeFastPatternList(DetectEngineCtx *de_ctx)
Definition: detect-fast-pattern.c:150
Packet_
Definition: decode.h:437
detect-engine-build.h
detect-engine-alert.h
DetectContentData_::flags
uint32_t flags
Definition: detect-content.h:104
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:665
FastPatternSupportEnabledForSigMatchList
int FastPatternSupportEnabledForSigMatchList(const DetectEngineCtx *de_ctx, const int list_id)
Checks if a particular buffer is in the list of lists that need to be searched for a keyword that has...
Definition: detect-fast-pattern.c:64
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1264
SCFPSupportSMList_::priority
int priority
Definition: detect.h:754
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2149
DetectEngineBufferTypeSupportsMpmGetById
bool DetectEngineBufferTypeSupportsMpmGetById(const DetectEngineCtx *de_ctx, const int id)
Definition: detect-engine.c:1248
detect-fast-pattern.h
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:3244
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3454
SigMatch_::idx
uint16_t idx
Definition: detect.h:352
SigMatch_::type
uint16_t type
Definition: detect.h:351
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:685
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:130
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:127
DetectBufferGetFirstSigMatch
SigMatch * DetectBufferGetFirstSigMatch(const Signature *s, const uint32_t buf_id)
Definition: detect-engine.c:1304
FatalError
#define FatalError(...)
Definition: util-debug.h:502
SIGMATCH_OPTIONAL_OPT
#define SIGMATCH_OPTIONAL_OPT
Definition: detect.h:1485
DetectEngineFreeFastPatternList
void DetectEngineFreeFastPatternList(DetectEngineCtx *de_ctx)
Definition: detect-fast-pattern.c:172
HtpBodyChunk_::next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:179
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DETECT_CONTENT_OFFSET
#define DETECT_CONTENT_OFFSET
Definition: detect-content.h:32
DETECT_CONTENT_FAST_PATTERN_ONLY
#define DETECT_CONTENT_FAST_PATTERN_ONLY
Definition: detect-content.h:35
detect-parse.h
Signature_
Signature container.
Definition: detect.h:596
SigMatch_
a single match condition for a signature
Definition: detect.h:350
DETECT_SM_LIST_MAX
@ DETECT_SM_LIST_MAX
Definition: detect.h:132
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2494
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:42
DetectFastPatternRegister
void DetectFastPatternRegister(void)
Registration function for fast_pattern keyword.
Definition: detect-fast-pattern.c:185
DetectContentData_::content_len
uint16_t content_len
Definition: detect-content.h:95
DetectGetLastSMFromLists
SigMatch * DetectGetLastSMFromLists(const Signature *s,...)
Returns the sm with the largest index (added latest) from the lists passed to us.
Definition: detect-parse.c:619
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:841
flow.h
DETECT_CONTENT_FAST_PATTERN
#define DETECT_CONTENT_FAST_PATTERN
Definition: detect-content.h:34
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
DetectEngineCtx_::fp_support_smlist_list
SCFPSupportSMList * fp_support_smlist_list
Definition: detect.h:1017
DETECT_CONTENT_WITHIN
#define DETECT_CONTENT_WITHIN
Definition: detect-content.h:31
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1288
UTHFreePackets
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:431