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) {
99  if (unlikely(new == NULL))
100  exit(EXIT_FAILURE);
101  memset(new, 0, sizeof(SCFPSupportSMList));
102  new->list_id = list_id;
103  new->priority = priority;
104 
105  *list = new;
106  return;
107  }
108 
110  if (unlikely(new == NULL))
111  exit(EXIT_FAILURE);
112  memset(new, 0, sizeof(SCFPSupportSMList));
113  new->list_id = list_id;
114  new->priority = priority;
115  if (ip == NULL) {
116  new->next = *list;
117  *list = new;
118  } else {
119  new->next = ip->next;
120  ip->next = new;
121  }
122  return;
123 }
124 
125 /**
126  * \brief Lets one add a sm list id to be searched for potential fp supported
127  * keywords later.
128  *
129  * \param list_id SM list id.
130  * \param priority Priority for this list.
131  */
132 void SupportFastPatternForSigMatchList(int list_id, int priority)
133 {
134  Add(&g_fp_support_smlist_list, list_id, priority);
135 }
136 
138 {
139  Add(&de_ctx->fp_support_smlist_list, list_id, priority);
140 }
141 
142 /**
143  * \brief Registers the keywords(SMs) that should be given fp support.
144  */
146 {
148 
149  /* other types are handled by DetectMpmAppLayerRegister() */
150 }
151 
153 {
154  SCFPSupportSMList *last = NULL;
155  for (SCFPSupportSMList *tmp = g_fp_support_smlist_list; tmp != NULL; tmp = tmp->next) {
156  SCFPSupportSMList *n = SCCalloc(1, sizeof(*n));
157  if (n == NULL) {
158  FatalError("out of memory: %s", strerror(errno));
159  }
160  n->list_id = tmp->list_id;
161  n->priority = tmp->priority;
162 
163  // append
164  if (de_ctx->fp_support_smlist_list == NULL) {
165  last = de_ctx->fp_support_smlist_list = n;
166  } else {
167  BUG_ON(last == NULL);
168  last->next = n;
169  last = n;
170  }
171  }
172 }
173 
175 {
176  for (SCFPSupportSMList *tmp = de_ctx->fp_support_smlist_list; tmp != NULL;) {
177  SCFPSupportSMList *next = tmp->next;
178  SCFree(tmp);
179  tmp = next;
180  }
182 }
183 
184 /**
185  * \brief Registration function for fast_pattern keyword
186  */
188 {
189  sigmatch_table[DETECT_FAST_PATTERN].name = "fast_pattern";
190  sigmatch_table[DETECT_FAST_PATTERN].desc = "force using preceding content in the multi pattern matcher";
191  sigmatch_table[DETECT_FAST_PATTERN].url = "/rules/prefilter-keywords.html#fast-pattern";
193  sigmatch_table[DETECT_FAST_PATTERN].Setup = DetectFastPatternSetup;
195 #ifdef UNITTESTS
196  sigmatch_table[DETECT_FAST_PATTERN].RegisterTests = DetectFastPatternRegisterTests;
197 #endif
199 
200  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
201 }
202 
203 /**
204  * \brief Configures the previous content context for a fast_pattern modifier
205  * keyword used in the rule.
206  *
207  * \param de_ctx Pointer to the Detection Engine Context.
208  * \param s Pointer to the Signature to which the current keyword belongs.
209  * \param arg May hold an argument
210  *
211  * \retval 0 On success.
212  * \retval -1 On failure.
213  */
214 static int DetectFastPatternSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
215 {
216  int res = 0;
217  size_t pcre2len;
218  char arg_substr[128] = "";
219  DetectContentData *cd = NULL;
220  pcre2_match_data *match = NULL;
221 
224  if (pm1 == NULL && pm2 == NULL) {
225  SCLogError("fast_pattern found inside "
226  "the rule, without a content context. Please use a "
227  "content based keyword before using fast_pattern");
228  return -1;
229  }
230 
231  SigMatch *pm = NULL;
232  if (pm1 && pm2) {
233  if (pm1->idx > pm2->idx)
234  pm = pm1;
235  else
236  pm = pm2;
237  } else if (pm1 && !pm2) {
238  pm = pm1;
239  } else {
240  pm = pm2;
241  }
242 
243  cd = (DetectContentData *)pm->ctx;
244  if ((cd->flags & DETECT_CONTENT_NEGATED) &&
245  ((cd->flags & DETECT_CONTENT_DISTANCE) ||
246  (cd->flags & DETECT_CONTENT_WITHIN) ||
247  (cd->flags & DETECT_CONTENT_OFFSET) ||
248  (cd->flags & DETECT_CONTENT_DEPTH))) {
249 
250  /* we can't have any of these if we are having "only" */
251  SCLogError("fast_pattern; cannot be "
252  "used with negated content, along with relative modifiers");
253  goto error;
254  }
255 
256  if (arg == NULL|| strcmp(arg, "") == 0) {
258  SCLogError("can't use multiple fast_pattern "
259  "options for the same content");
260  goto error;
261  }
262  else { /*allow only one content to have fast_pattern modifier*/
263  for (uint32_t list_id = 0; list_id < DETECT_SM_LIST_MAX; list_id++) {
264  SigMatch *sm = NULL;
265  for (sm = s->init_data->smlists[list_id]; sm != NULL; sm = sm->next) {
266  if (sm->type == DETECT_CONTENT) {
267  DetectContentData *tmp_cd = (DetectContentData *)sm->ctx;
268  if (tmp_cd->flags & DETECT_CONTENT_FAST_PATTERN) {
269  SCLogError("fast_pattern "
270  "can be used on only one content in a rule");
271  goto error;
272  }
273  }
274  }
275  }
276  }
278  return 0;
279  }
280 
281  /* Execute the regex and populate args with captures. */
282  int ret = DetectParsePcreExec(&parse_regex, &match, arg, 0, 0);
283  /* fast pattern only */
284  if (ret == 2) {
285  if ((cd->flags & DETECT_CONTENT_NEGATED) ||
286  (cd->flags & DETECT_CONTENT_DISTANCE) ||
287  (cd->flags & DETECT_CONTENT_WITHIN) ||
288  (cd->flags & DETECT_CONTENT_OFFSET) ||
289  (cd->flags & DETECT_CONTENT_DEPTH)) {
290 
291  /* we can't have any of these if we are having "only" */
292  SCLogError("fast_pattern: only; cannot be "
293  "used with negated content or with any of the relative "
294  "modifiers like distance, within, offset, depth");
295  goto error;
296  }
298 
299  /* fast pattern chop */
300  } else if (ret == 4) {
301  pcre2len = sizeof(arg_substr);
302  res = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
303  if (res < 0) {
304  SCLogError("pcre2_substring_copy_bynumber failed "
305  "for fast_pattern offset");
306  goto error;
307  }
308  uint16_t offset;
309  if (StringParseUint16(&offset, 10, 0,
310  (const char *)arg_substr) < 0) {
311  SCLogError("Invalid fast pattern offset:"
312  " \"%s\"",
313  arg_substr);
314  goto error;
315  }
316 
317  pcre2len = sizeof(arg_substr);
318  res = pcre2_substring_copy_bynumber(match, 3, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
319  if (res < 0) {
320  SCLogError("pcre2_substring_copy_bynumber failed "
321  "for fast_pattern offset");
322  goto error;
323  }
324  uint16_t length;
325  if (StringParseUint16(&length, 10, 0,
326  (const char *)arg_substr) < 0) {
327  SCLogError("Invalid value for fast "
328  "pattern: \"%s\"",
329  arg_substr);
330  goto error;
331  }
332 
333  // Avoiding integer overflow
334  if (offset > (65535 - length)) {
335  SCLogError("Fast pattern (length + offset) "
336  "exceeds limit pattern length limit");
337  goto error;
338  }
339 
340  if (offset + length > cd->content_len) {
341  SCLogError("Fast pattern (length + "
342  "offset (%u)) exceeds pattern length (%u)",
343  offset + length, cd->content_len);
344  goto error;
345  }
346 
347  cd->fp_chop_offset = offset;
348  cd->fp_chop_len = length;
350 
351  } else {
352  SCLogError("parse error, ret %" PRId32 ", string %s", ret, arg);
353  goto error;
354  }
355 
357 
358  pcre2_match_data_free(match);
359  return 0;
360 
361  error:
362  if (match) {
363  pcre2_match_data_free(match);
364  }
365  return -1;
366 }
367 
368 /*----------------------------------Unittests---------------------------------*/
369 
370 #ifdef UNITTESTS
371 #include "detect-engine-alert.h"
372 static SigMatch *GetMatches(Signature *s, const int list)
373 {
374  SigMatch *sm = DetectBufferGetFirstSigMatch(s, list);
375  if (sm == NULL && list < DETECT_SM_LIST_MAX) {
376  sm = s->init_data->smlists[list];
377  }
378  return sm;
379 }
380 
381 static int DetectFastPatternStickySingle(const char *sticky, const int list)
382 {
385  char string[1024];
386  snprintf(string, sizeof(string),
387  "alert tcp any any -> any any "
388  "(%s%scontent:\"one\"; fast_pattern; sid:1;)",
389  sticky ? sticky : "", sticky ? "; " : " ");
390  Signature *s = DetectEngineAppendSig(de_ctx, string);
391  FAIL_IF_NULL(s);
392  SigMatch *sm = GetMatches(s, list);
393  FAIL_IF_NULL(sm);
399  PASS;
400 }
401 
402 static int DetectFastPatternModifierSingle(const char *sticky, const int list)
403 {
406  char string[1024];
407  snprintf(string, sizeof(string),
408  "alert tcp any any -> any any "
409  "(content:\"one\"; %s%sfast_pattern; sid:1;)",
410  sticky ? sticky : "", sticky ? "; " : " ");
411  Signature *s = DetectEngineAppendSig(de_ctx, string);
412  FAIL_IF_NULL(s);
413  SigMatch *sm = GetMatches(s, list);
414  FAIL_IF_NULL(sm);
420  PASS;
421 }
422 
423 static int DetectFastPatternStickySingleNoFP(const char *sticky, const int list)
424 {
427  char string[1024];
428  snprintf(string, sizeof(string),
429  "alert tcp any any -> any any "
430  "(%s%scontent:\"one\"; sid:1;)",
431  sticky ? sticky : "", sticky ? "; " : " ");
432  Signature *s = DetectEngineAppendSig(de_ctx, string);
433  FAIL_IF_NULL(s);
434  SigMatch *sm = GetMatches(s, list);
435  FAIL_IF_NULL(sm);
441  PASS;
442 }
443 
444 static int DetectFastPatternModifierSingleNoFP(const char *sticky, const int list)
445 {
448  char string[1024];
449  snprintf(string, sizeof(string),
450  "alert tcp any any -> any any "
451  "(content:\"one\"; %s%ssid:1;)",
452  sticky ? sticky : "", sticky ? "; " : " ");
453  Signature *s = DetectEngineAppendSig(de_ctx, string);
454  FAIL_IF_NULL(s);
455  SigMatch *sm = GetMatches(s, list);
456  FAIL_IF_NULL(sm);
462  PASS;
463 }
464 
465 static int DetectFastPatternStickySingleBadArg(const char *sticky)
466 {
469  char string[1024];
470  /* bogus argument to fast_pattern */
471  snprintf(string, sizeof(string),
472  "alert tcp any any -> any any "
473  "(%s%scontent:\"one\"; fast_pattern:boo; sid:1;)",
474  sticky ? sticky : "", sticky ? "; " : " ");
475  Signature *s = DetectEngineAppendSig(de_ctx, string);
476  FAIL_IF_NOT_NULL(s);
477  /* fast_pattern only with distance */
478  snprintf(string, sizeof(string),
479  "alert tcp any any -> any any "
480  "(%s%scontent:\"one\"; fast_pattern:only; content:\"two\"; distance:10; sid:1;)",
481  sticky ? sticky : "", sticky ? "; " : " ");
482  s = DetectEngineAppendSig(de_ctx, string);
483  FAIL_IF_NOT_NULL(s);
484  /* fast_pattern only with distance */
485  snprintf(string, sizeof(string),
486  "alert tcp any any -> any any "
487  "(%s%scontent:\"one\"; content:\"two\"; fast_pattern:only; distance:10; sid:1;)",
488  sticky ? sticky : "", sticky ? "; " : " ");
489  s = DetectEngineAppendSig(de_ctx, string);
490  FAIL_IF_NOT_NULL(s);
491  /* fast_pattern only with distance */
492  snprintf(string, sizeof(string),
493  "alert tcp any any -> any any "
494  "(%s%scontent:\"one\"; content:\"two\"; distance:10; fast_pattern:only; sid:1;)",
495  sticky ? sticky : "", sticky ? "; " : " ");
496  s = DetectEngineAppendSig(de_ctx, string);
497  FAIL_IF_NOT_NULL(s);
498  /* fast_pattern chop with invalid values */
499  snprintf(string, sizeof(string),
500  "alert tcp any any -> any any "
501  "(%s%scontent:\"one\"; fast_pattern:5,6; sid:1;)",
502  sticky ? sticky : "", sticky ? "; " : " ");
503  s = DetectEngineAppendSig(de_ctx, string);
504  FAIL_IF_NOT_NULL(s);
506  PASS;
507 }
508 
509 static int DetectFastPatternModifierBadRules(const char *sticky)
510 {
513  char string[1024];
514  /* bogus argument to fast_pattern */
515  snprintf(string, sizeof(string),
516  "alert tcp any any -> any any "
517  "(content:\"one\"; %s%sfast_pattern:boo; sid:1;)",
518  sticky ? sticky : "", sticky ? "; " : " ");
519  Signature *s = DetectEngineAppendSig(de_ctx, string);
520  FAIL_IF_NOT_NULL(s);
521  /* fast_pattern only with distance */
522  snprintf(string, sizeof(string),
523  "alert tcp any any -> any any "
524  "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%sdistance:10; sid:1;)",
525  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
526  s = DetectEngineAppendSig(de_ctx, string);
527  FAIL_IF_NOT_NULL(s);
528 #if 0 // TODO bug?
529  /* fast_pattern only with distance */
530  snprintf(string, sizeof(string), "alert tcp any any -> any any "
531  "(content:\"one\"; %s%s content:\"two\"; %s%sdistance:10; fast_pattern:only; sid:1;)",
532  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
533  s = DetectEngineAppendSig(de_ctx, string);
534  FAIL_IF_NOT_NULL(s);
535 #endif
536  /* fast_pattern only with within */
537  snprintf(string, sizeof(string),
538  "alert tcp any any -> any any "
539  "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%swithin:10; sid:1;)",
540  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
541  s = DetectEngineAppendSig(de_ctx, string);
542  FAIL_IF_NOT_NULL(s);
543  /* fast_pattern only with within */
544  snprintf(string, sizeof(string),
545  "alert tcp any any -> any any "
546  "(content:\"one\"; %s%s content:\"two\"; %s%swithin:10; fast_pattern:only; sid:1;)",
547  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
548  s = DetectEngineAppendSig(de_ctx, string);
549  FAIL_IF_NOT_NULL(s);
550  /* fast_pattern only with offset */
551  snprintf(string, sizeof(string),
552  "alert tcp any any -> any any "
553  "(content:\"one\"; %s%sfast_pattern:only; offset:10; sid:1;)",
554  sticky ? sticky : "", sticky ? "; " : " ");
555  s = DetectEngineAppendSig(de_ctx, string);
556  FAIL_IF_NOT_NULL(s);
557  /* fast_pattern only with offset */
558  snprintf(string, sizeof(string),
559  "alert tcp any any -> any any "
560  "(content:\"one\"; %s%s offset:10; fast_pattern:only; sid:1;)",
561  sticky ? sticky : "", sticky ? "; " : " ");
562  s = DetectEngineAppendSig(de_ctx, string);
563  FAIL_IF_NOT_NULL(s);
564  /* fast_pattern only with depth */
565  snprintf(string, sizeof(string),
566  "alert tcp any any -> any any "
567  "(content:\"one\"; %s%sfast_pattern:only; depth:10; sid:1;)",
568  sticky ? sticky : "", sticky ? "; " : " ");
569  s = DetectEngineAppendSig(de_ctx, string);
570  FAIL_IF_NOT_NULL(s);
571  /* fast_pattern only with depth */
572  snprintf(string, sizeof(string),
573  "alert tcp any any -> any any "
574  "(content:\"one\"; %s%s depth:10; fast_pattern:only; sid:1;)",
575  sticky ? sticky : "", sticky ? "; " : " ");
576  s = DetectEngineAppendSig(de_ctx, string);
577  FAIL_IF_NOT_NULL(s);
578  /* fast_pattern only negate */
579  snprintf(string, sizeof(string),
580  "alert tcp any any -> any any "
581  "(content:\"one\"; %s%s content:!\"two\"; %s%sfast_pattern:only; sid:1;)",
582  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
583  s = DetectEngineAppendSig(de_ctx, string);
584  FAIL_IF_NOT_NULL(s);
585  /* fast_pattern chop with invalid values */
586  snprintf(string, sizeof(string),
587  "alert tcp any any -> any any "
588  "(content:\"one\"; %s%sfast_pattern:5,6; sid:1;)",
589  sticky ? sticky : "", sticky ? "; " : " ");
590  s = DetectEngineAppendSig(de_ctx, string);
591  FAIL_IF_NOT_NULL(s);
592  /* fast_pattern chop with invalid values */
593  snprintf(string, sizeof(string),
594  "alert tcp any any -> any any "
595  "(content:\"one\"; %s%sfast_pattern:65977,2; sid:1;)",
596  sticky ? sticky : "", sticky ? "; " : " ");
597  s = DetectEngineAppendSig(de_ctx, string);
598  FAIL_IF_NOT_NULL(s);
599  /* fast_pattern chop with invalid values */
600  snprintf(string, sizeof(string),
601  "alert tcp any any -> any any "
602  "(content:\"one\"; %s%sfast_pattern:2,65977; sid:1;)",
603  sticky ? sticky : "", sticky ? "; " : " ");
604  s = DetectEngineAppendSig(de_ctx, string);
605  FAIL_IF_NOT_NULL(s);
606  /* fast_pattern chop with invalid values */
607  snprintf(string, sizeof(string),
608  "alert tcp any any -> any any "
609  "(content:\"one\"; %s%sfast_pattern:2,65534; sid:1;)",
610  sticky ? sticky : "", sticky ? "; " : " ");
611  s = DetectEngineAppendSig(de_ctx, string);
612  FAIL_IF_NOT_NULL(s);
613  /* fast_pattern chop with invalid values */
614  snprintf(string, sizeof(string),
615  "alert tcp any any -> any any "
616  "(content:\"one\"; %s%sfast_pattern:65534,2; sid:1;)",
617  sticky ? sticky : "", sticky ? "; " : " ");
618  s = DetectEngineAppendSig(de_ctx, string);
619  FAIL_IF_NOT_NULL(s);
620  /* negated fast_pattern with distance */
621  snprintf(string, sizeof(string),
622  "alert tcp any any -> any any "
623  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdistance:10; sid:1;)",
624  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
625  s = DetectEngineAppendSig(de_ctx, string);
626  FAIL_IF_NOT_NULL(s);
627  /* negated fast_pattern with within */
628  snprintf(string, sizeof(string),
629  "alert tcp any any -> any any "
630  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%swithin:10; sid:1;)",
631  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
632  s = DetectEngineAppendSig(de_ctx, string);
633  FAIL_IF_NOT_NULL(s);
634  /* negated fast_pattern with depth */
635  snprintf(string, sizeof(string),
636  "alert tcp any any -> any any "
637  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdepth:10; sid:1;)",
638  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
639  s = DetectEngineAppendSig(de_ctx, string);
640  FAIL_IF_NOT_NULL(s);
641  /* negated fast_pattern with offset */
642  snprintf(string, sizeof(string),
643  "alert tcp any any -> any any "
644  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%soffset:10; sid:1;)",
645  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
646  s = DetectEngineAppendSig(de_ctx, string);
647  FAIL_IF_NOT_NULL(s);
649  PASS;
650 }
651 
652 static int DetectFastPatternStickySingleFPOnly(const char *sticky, const int list)
653 {
656  char string[1024];
657  snprintf(string, sizeof(string),
658  "alert tcp any any -> any any "
659  "(%s%scontent:\"one\"; fast_pattern:only; sid:1;)",
660  sticky ? sticky : "", sticky ? "; " : " ");
661  Signature *s = DetectEngineAppendSig(de_ctx, string);
662  FAIL_IF_NULL(s);
663  SigMatch *sm = GetMatches(s, list);
664  FAIL_IF_NULL(sm);
671  PASS;
672 }
673 
674 static int DetectFastPatternModifierFPOnly(const char *sticky, const int list)
675 {
678  char string[1024];
679  snprintf(string, sizeof(string),
680  "alert tcp any any -> any any "
681  "(content:\"one\"; %s%sfast_pattern:only; sid:1;)",
682  sticky ? sticky : "", sticky ? "; " : " ");
683  Signature *s = DetectEngineAppendSig(de_ctx, string);
684  FAIL_IF_NULL(s);
685  SigMatch *sm = GetMatches(s, list);
686  FAIL_IF_NULL(sm);
692 
693  snprintf(string, sizeof(string),
694  "alert tcp any any -> any any "
695  "(content:\"one\"; %s%scontent:\"two\"; %s%sfast_pattern:only; sid:2;)",
696  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
697  s = DetectEngineAppendSig(de_ctx, string);
698  FAIL_IF_NULL(s);
699  sm = GetMatches(s, list);
700  FAIL_IF_NULL(sm);
701  FAIL_IF_NULL(sm->next);
703  cd = (DetectContentData *)sm->ctx;
705  FAIL_IF_NOT(
707  sm = sm->next;
709  cd = (DetectContentData *)sm->ctx;
713 
714  snprintf(string, sizeof(string),
715  "alert tcp any any -> any any "
716  "(content:\"one\"; %s%scontent:\"two\"; distance:10; %s%scontent:\"three\"; "
717  "%s%sfast_pattern:only; sid:3;)",
718  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
719  sticky ? sticky : "", sticky ? "; " : " ");
720  s = DetectEngineAppendSig(de_ctx, string);
721  FAIL_IF_NULL(s);
722  sm = GetMatches(s, list);
723  FAIL_IF_NULL(sm);
724  FAIL_IF_NULL(sm->next);
726  cd = (DetectContentData *)sm->ctx;
728  FAIL_IF_NOT(
730  sm = sm->next;
731  FAIL_IF_NULL(sm->next);
733  cd = (DetectContentData *)sm->ctx;
735  FAIL_IF_NOT(
737  sm = sm->next;
738  FAIL_IF_NOT_NULL(sm->next);
740  cd = (DetectContentData *)sm->ctx;
744 
745  snprintf(string, sizeof(string),
746  "alert tcp any any -> any any "
747  "(content:\"one\"; %s%scontent:\"two\"; within:10; %s%scontent:\"three\"; "
748  "%s%sfast_pattern:only; sid:4;)",
749  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
750  sticky ? sticky : "", sticky ? "; " : " ");
751  s = DetectEngineAppendSig(de_ctx, string);
752  FAIL_IF_NULL(s);
753  sm = GetMatches(s, list);
754  FAIL_IF_NULL(sm);
755  FAIL_IF_NULL(sm->next);
757  cd = (DetectContentData *)sm->ctx;
759  FAIL_IF_NOT(
761  sm = sm->next;
762  FAIL_IF_NULL(sm->next);
764  cd = (DetectContentData *)sm->ctx;
766  FAIL_IF_NOT(
768  sm = sm->next;
769  FAIL_IF_NOT_NULL(sm->next);
771  cd = (DetectContentData *)sm->ctx;
775 
776  snprintf(string, sizeof(string),
777  "alert tcp any any -> any any "
778  "(content:\"one\"; %s%scontent:\"two\"; offset:10; %s%scontent:\"three\"; "
779  "%s%sfast_pattern:only; sid:5;)",
780  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
781  sticky ? sticky : "", sticky ? "; " : " ");
782  s = DetectEngineAppendSig(de_ctx, string);
783  FAIL_IF_NULL(s);
784  sm = GetMatches(s, list);
785  FAIL_IF_NULL(sm);
786  FAIL_IF_NULL(sm->next);
788  cd = (DetectContentData *)sm->ctx;
790  FAIL_IF_NOT(
792  sm = sm->next;
793  FAIL_IF_NULL(sm->next);
795  cd = (DetectContentData *)sm->ctx;
797  FAIL_IF_NOT(
799  sm = sm->next;
800  FAIL_IF_NOT_NULL(sm->next);
802  cd = (DetectContentData *)sm->ctx;
806 
807  snprintf(string, sizeof(string),
808  "alert tcp any any -> any any "
809  "(content:\"one\"; %s%scontent:\"two\"; depth:10; %s%scontent:\"three\"; "
810  "%s%sfast_pattern:only; sid:6;)",
811  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
812  sticky ? sticky : "", sticky ? "; " : " ");
813  s = DetectEngineAppendSig(de_ctx, string);
814  FAIL_IF_NULL(s);
815  sm = GetMatches(s, list);
816  FAIL_IF_NULL(sm);
817  FAIL_IF_NULL(sm->next);
819  cd = (DetectContentData *)sm->ctx;
821  FAIL_IF_NOT(
823  sm = sm->next;
824  FAIL_IF_NULL(sm->next);
826  cd = (DetectContentData *)sm->ctx;
828  FAIL_IF_NOT(
830  sm = sm->next;
831  FAIL_IF_NOT_NULL(sm->next);
833  cd = (DetectContentData *)sm->ctx;
837 
838  snprintf(string, sizeof(string),
839  "alert tcp any any -> any any "
840  "(content:!\"one\"; %s%sfast_pattern; content:\"two\"; depth:10; %s%ssid:7;)",
841  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
842  s = DetectEngineAppendSig(de_ctx, string);
843  FAIL_IF_NULL(s);
844  sm = GetMatches(s, list);
845  FAIL_IF_NULL(sm);
846  FAIL_IF_NULL(sm->next);
848  cd = (DetectContentData *)sm->ctx;
853  sm = sm->next;
854  FAIL_IF_NOT_NULL(sm->next);
856  cd = (DetectContentData *)sm->ctx;
858  FAIL_IF_NOT(
860 
862  PASS;
863 }
864 
865 static int DetectFastPatternStickyFPChop(const char *sticky, const int list)
866 {
869  char string[1024];
870  snprintf(string, sizeof(string),
871  "alert tcp any any -> any any "
872  "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; sid:1;)",
873  sticky ? sticky : "", sticky ? "; " : " ");
874  Signature *s = DetectEngineAppendSig(de_ctx, string);
875  FAIL_IF_NULL(s);
876  SigMatch *sm = GetMatches(s, list);
877  FAIL_IF_NULL(sm);
884  FAIL_IF_NOT(cd->fp_chop_offset == 3);
885  FAIL_IF_NOT(cd->fp_chop_len == 4);
886 
887  snprintf(string, sizeof(string),
888  "alert tcp any any -> any any "
889  "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; content:\"xyz\"; distance:10; sid:2;)",
890  sticky ? sticky : "", sticky ? "; " : " ");
891  s = DetectEngineAppendSig(de_ctx, string);
892  FAIL_IF_NULL(s);
893  sm = GetMatches(s, list);
894  FAIL_IF_NULL(sm);
896  cd = (DetectContentData *)sm->ctx;
901  FAIL_IF_NOT(cd->fp_chop_offset == 3);
902  FAIL_IF_NOT(cd->fp_chop_len == 4);
903 
905  PASS;
906 }
907 
908 static int DetectFastPatternModifierFPChop(const char *sticky, const int list)
909 {
912  char string[1024];
913  snprintf(string, sizeof(string),
914  "alert tcp any any -> any any "
915  "(content:\"onetwothree\"; %s%sfast_pattern:3,4; sid:1;)",
916  sticky ? sticky : "", sticky ? "; " : " ");
917  Signature *s = DetectEngineAppendSig(de_ctx, string);
918  FAIL_IF_NULL(s);
919  SigMatch *sm = GetMatches(s, list);
920  FAIL_IF_NULL(sm);
927  FAIL_IF_NOT(cd->fp_chop_offset == 3);
928  FAIL_IF_NOT(cd->fp_chop_len == 4);
929 
930  snprintf(string, sizeof(string),
931  "alert tcp any any -> any any "
932  "(content:!\"onetwothree\"; %s%sfast_pattern:3,4; sid:2;)",
933  sticky ? sticky : "", sticky ? "; " : " ");
934  s = DetectEngineAppendSig(de_ctx, string);
935  FAIL_IF_NULL(s);
936  sm = GetMatches(s, list);
937  FAIL_IF_NULL(sm);
939  cd = (DetectContentData *)sm->ctx;
946  FAIL_IF_NOT(cd->fp_chop_offset == 3);
947  FAIL_IF_NOT(cd->fp_chop_len == 4);
948 
950  PASS;
951 }
952 
953 /**
954  * \test Checks if a fast_pattern is registered in a Signature
955  */
956 static int DetectFastPatternTest01(void)
957 {
958  FAIL_IF_NOT(DetectFastPatternStickySingle(NULL, DETECT_SM_LIST_PMATCH));
959  FAIL_IF_NOT(DetectFastPatternModifierSingle(NULL, DETECT_SM_LIST_PMATCH));
960  FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(NULL, DETECT_SM_LIST_PMATCH));
961  FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(NULL, DETECT_SM_LIST_PMATCH));
962  FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(NULL));
963  FAIL_IF_NOT(DetectFastPatternModifierBadRules(NULL));
964  FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(NULL, DETECT_SM_LIST_PMATCH));
965  FAIL_IF_NOT(DetectFastPatternModifierFPOnly(NULL, DETECT_SM_LIST_PMATCH));
966  FAIL_IF_NOT(DetectFastPatternStickyFPChop(NULL, DETECT_SM_LIST_PMATCH));
967  FAIL_IF_NOT(DetectFastPatternModifierFPChop(NULL, DETECT_SM_LIST_PMATCH));
968 
969  struct {
970  const char *buffer_name;
971  const char *sb_name;
972  const char *mod_name;
973  } keywords[] = {
974  { "file_data", "file.data", NULL },
975  { "http_uri", "http.uri", "http_uri" },
976  { "http_raw_uri", "http.uri.raw", "http_raw_uri" },
977  { "http_user_agent", "http.user_agent", "http_user_agent" },
978  { "http_header", "http.header", "http_header" },
979  // http_raw_header requires sigs to have a direction
980  //{ "http_raw_header", "http.header.raw", "http_raw_header" },
981  { "http_method", "http.method", "http_method" },
982  { "http_cookie", "http.cookie", "http_cookie" },
983  { "http_host", "http.host", "http_host" },
984  { "http_raw_host", "http.host.raw", "http_raw_host" },
985  { "http_stat_code", "http.stat_code", "http_stat_code" },
986  { "http_stat_msg", "http.stat_msg", "http_stat_msg" },
987  { "http_client_body", "http.request_body", "http_client_body" },
988  { NULL, NULL, NULL },
989  };
990 
991  for (int i = 0; keywords[i].buffer_name != NULL; i++) {
992  const int list_id = DetectBufferTypeGetByName(keywords[i].buffer_name);
993  FAIL_IF(list_id == -1);
994 
995  const char *k = keywords[i].sb_name;
996  if (k) {
997  FAIL_IF_NOT(DetectFastPatternStickySingle(k, list_id));
998  FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(k, list_id));
999  FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(k));
1000  FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(k, list_id));
1001  FAIL_IF_NOT(DetectFastPatternStickyFPChop(k, list_id));
1002  }
1003  k = keywords[i].mod_name;
1004  if (k) {
1005  FAIL_IF_NOT(DetectFastPatternModifierSingle(k, list_id));
1006  FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(k, list_id));
1007  FAIL_IF_NOT(DetectFastPatternModifierBadRules(k));
1008  FAIL_IF_NOT(DetectFastPatternModifierFPOnly(k, list_id));
1009  FAIL_IF_NOT(DetectFastPatternModifierFPChop(k, list_id));
1010  }
1011  }
1012 
1013  PASS;
1014 }
1015 
1016 /**
1017  * \test Checks to make sure that other sigs work that should when fast_pattern is inspecting on the
1018  * same payload
1019  *
1020  */
1021 static int DetectFastPatternTest14(void)
1022 {
1023  uint8_t *buf = (uint8_t *)"Dummy is our name. Oh yes. From right here "
1024  "right now, all the way to hangover. right. strings5_imp now here "
1025  "comes our dark knight strings_string5. Yes here is our dark knight";
1026  uint16_t buflen = strlen((char *)buf);
1027  ThreadVars th_v;
1028  DetectEngineThreadCtx *det_ctx = NULL;
1029 
1030  memset(&th_v, 0, sizeof(th_v));
1031  Packet *p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
1032  FAIL_IF_NULL(p);
1033 
1036  de_ctx->flags |= DE_QUIET;
1037 
1039 
1041  "alert tcp any any -> any any "
1042  "(msg:\"fast_pattern test\"; content:\"strings_string5\"; content:\"knight\"; "
1043  "fast_pattern; sid:1;)");
1044  FAIL_IF_NULL(s);
1045 
1047  "alert tcp any any -> any any "
1048  "(msg:\"test different content\"; content:\"Dummy is our name\"; sid:2;)");
1049  FAIL_IF_NULL(s);
1050 
1052  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1053 
1054  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1057 
1058  UTHFreePackets(&p, 1);
1059  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1061  FlowShutdown();
1062  PASS;
1063 }
1064 
1065 /**
1066  * Unittest to check
1067  * - if we assign different content_ids to duplicate patterns, but one of the
1068  * patterns has a fast_pattern chop set.
1069  * - if 2 unique patterns get unique ids.
1070  * - if 2 duplicate patterns, with no chop set get unique ids.
1071  */
1072 static int DetectFastPatternTest671(void)
1073 {
1076  de_ctx->flags |= DE_QUIET;
1077 
1078  Signature *s[6];
1079  s[0] = DetectEngineAppendSig(
1080  de_ctx, "alert tcp any any -> any any (content:\"onetwothreefour\"; sid:1;)");
1081  FAIL_IF_NULL(s[0]);
1082  s[1] = DetectEngineAppendSig(
1083  de_ctx, "alert tcp any any -> any any (content:\"onetwothreefour\"; sid:2;)");
1084  FAIL_IF_NULL(s[1]);
1085  s[2] = DetectEngineAppendSig(
1086  de_ctx, "alert tcp any any -> any any (content:\"uniquepattern\"; sid:3;)");
1087  FAIL_IF_NULL(s[2]);
1089  "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:3,5; sid:4;)");
1090  FAIL_IF_NULL(s[3]);
1091  s[4] = DetectEngineAppendSig(
1092  de_ctx, "alert tcp any any -> any any (content:\"twoth\"; sid:5;)");
1093  FAIL_IF_NULL(s[4]);
1095  "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:0,15; "
1096  "sid:6;)");
1097  FAIL_IF_NULL(s[5]);
1098 
1100 
1102  DetectContentData *cd = (DetectContentData *)smd->ctx;
1103  FAIL_IF(cd->id != 0);
1104 
1105  smd = s[1]->sm_arrays[DETECT_SM_LIST_PMATCH];
1106  cd = (DetectContentData *)smd->ctx;
1107  FAIL_IF(cd->id != 0);
1108 
1109  smd = s[2]->sm_arrays[DETECT_SM_LIST_PMATCH];
1110  cd = (DetectContentData *)smd->ctx;
1111  FAIL_IF(cd->id != 2);
1112 
1113  smd = s[3]->sm_arrays[DETECT_SM_LIST_PMATCH];
1114  cd = (DetectContentData *)smd->ctx;
1115  FAIL_IF(cd->id != 1);
1116 
1117  smd = s[4]->sm_arrays[DETECT_SM_LIST_PMATCH];
1118  cd = (DetectContentData *)smd->ctx;
1119  FAIL_IF(cd->id != 1);
1120 
1121  smd = s[5]->sm_arrays[DETECT_SM_LIST_PMATCH];
1122  cd = (DetectContentData *)smd->ctx;
1123  FAIL_IF(cd->id != 0);
1124 
1126  PASS;
1127 }
1128 
1129 static int DetectFastPatternPrefilter(void)
1130 {
1133  const char *string = "alert tcp any any -> any any "
1134  "(content:\"one\"; prefilter; sid:1;)";
1135  Signature *s = DetectEngineAppendSig(de_ctx, string);
1136  FAIL_IF_NULL(s);
1138  FAIL_IF_NULL(sm);
1144  PASS;
1145 }
1146 
1147 static void DetectFastPatternRegisterTests(void)
1148 {
1149  UtRegisterTest("DetectFastPatternTest01", DetectFastPatternTest01);
1150  UtRegisterTest("DetectFastPatternTest14", DetectFastPatternTest14);
1151  /* Unittest to check
1152  * - if we assign different content_ids to duplicate patterns, but one of the
1153  * patterns has a fast_pattern chop set.
1154  * - if 2 unique patterns get unique ids.
1155  * - if 2 duplicate patterns, with no chop set get unique ids.
1156  */
1157  UtRegisterTest("DetectFastPatternTest671", DetectFastPatternTest671);
1158 
1159  UtRegisterTest("DetectFastPatternPrefilter", DetectFastPatternPrefilter);
1160 }
1161 #endif
util-byte.h
SCFPSupportSMList_
Definition: detect.h:740
SigTableElmt_::url
const char * url
Definition: detect.h:1287
detect-content.h
detect-engine.h
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:110
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:566
DetectContentData_::fp_chop_len
uint16_t fp_chop_len
Definition: detect-content.h:98
SigTableElmt_::desc
const char * desc
Definition: detect.h:1286
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1274
SCFPSupportSMList_::next
struct SCFPSupportSMList_ * next
Definition: detect.h:743
DetectParseRegex
Definition: detect-parse.h:62
SCFPSupportSMList_::list_id
int list_id
Definition: detect.h:741
SigTableElmt_::name
const char * name
Definition: detect.h:1284
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:352
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1278
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:826
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:2592
SupportFastPatternForSigMatchTypes
void SupportFastPatternForSigMatchTypes(void)
Registers the keywords(SMs) that should be given fp support.
Definition: detect-fast-pattern.c:145
DE_QUIET
#define DE_QUIET
Definition: detect.h:314
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:337
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1824
Signature_::sm_arrays
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
Definition: detect.h:637
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
Definition: detect-parse.c:2623
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:2569
SigMatchData_
Data needed for Match()
Definition: detect.h:349
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1269
DetectEngineRegisterFastPatternForId
void DetectEngineRegisterFastPatternForId(DetectEngineCtx *de_ctx, int list_id, int priority)
Definition: detect-fast-pattern.c:137
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:1124
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:549
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:1074
DetectGetLastSMFromMpmLists
SigMatch * DetectGetLastSMFromMpmLists(const DetectEngineCtx *de_ctx, const Signature *s)
get the last SigMatch from lists that support MPM.
Definition: detect-parse.c:549
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2747
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:344
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:343
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:295
DetectEngineInitializeFastPatternList
void DetectEngineInitializeFastPatternList(DetectEngineCtx *de_ctx)
Definition: detect-fast-pattern.c:152
Packet_
Definition: decode.h:430
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:653
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:1252
SCFPSupportSMList_::priority
int priority
Definition: detect.h:742
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:1973
DetectEngineBufferTypeSupportsMpmGetById
bool DetectEngineBufferTypeSupportsMpmGetById(const DetectEngineCtx *de_ctx, const int id)
Definition: detect-engine.c:1300
detect-fast-pattern.h
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:3308
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:3522
SigMatch_::idx
uint16_t idx
Definition: detect.h:342
SigMatch_::type
uint16_t type
Definition: detect.h:341
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:697
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:129
DetectBufferGetFirstSigMatch
SigMatch * DetectBufferGetFirstSigMatch(const Signature *s, const uint32_t buf_id)
Definition: detect-engine.c:1356
FatalError
#define FatalError(...)
Definition: util-debug.h:502
SIGMATCH_OPTIONAL_OPT
#define SIGMATCH_OPTIONAL_OPT
Definition: detect.h:1475
DetectEngineFreeFastPatternList
void DetectEngineFreeFastPatternList(DetectEngineCtx *de_ctx)
Definition: detect-fast-pattern.c:174
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
HtpBodyChunk_::next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:178
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:581
SigMatch_
a single match condition for a signature
Definition: detect.h:340
DETECT_SM_LIST_MAX
@ DETECT_SM_LIST_MAX
Definition: detect.h:126
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2553
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:41
DetectFastPatternRegister
void DetectFastPatternRegister(void)
Registration function for fast_pattern keyword.
Definition: detect-fast-pattern.c:187
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:586
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:828
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:1002
DETECT_CONTENT_WITHIN
#define DETECT_CONTENT_WITHIN
Definition: detect-content.h:31
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1276
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:468