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