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-helper.h"
40 
41 #define PARSE_REGEX "^(\\s*only\\s*)|\\s*([0-9]+)\\s*,\\s*([0-9]+)\\s*$"
42 
43 static DetectParseRegex parse_regex;
44 
45 static int DetectFastPatternSetup(DetectEngineCtx *, Signature *, const char *);
46 #ifdef UNITTESTS
47 static void DetectFastPatternRegisterTests(void);
48 #endif
49 
50 /* holds the list of sm match lists that need to be searched for a keyword
51  * that has fp support */
52 static SCFPSupportSMList *g_fp_support_smlist_list = NULL;
53 
54 /**
55  * \brief Checks if a particular buffer is in the list
56  * of lists that need to be searched for a keyword that has fp support.
57  *
58  * \param list_id The list id.
59  *
60  * \retval 1 If supported.
61  * \retval 0 If not.
62  */
64  const int list_id)
65 {
66  if (de_ctx->fp_support_smlist_list == NULL) {
67  return 0;
68  }
69 
70  if (list_id == DETECT_SM_LIST_PMATCH)
71  return 1;
72 
74 }
75 
76 static void Add(SCFPSupportSMList **list, const int list_id, const int priority)
77 {
78  SCFPSupportSMList *ip = NULL;
79  /* insertion point - ip */
80  for (SCFPSupportSMList *tmp = *list; tmp != NULL; tmp = tmp->next) {
81  if (list_id == tmp->list_id) {
82  SCLogDebug("SM list already registered.");
83  return;
84  }
85 
86  /* We need a strict check to be sure that the current list
87  * was not already registered
88  * and other lists with the same priority hide it.
89  */
90  if (priority < tmp->priority)
91  break;
92 
93  ip = tmp;
94  }
95 
96  if (*list == NULL) {
97  SCFPSupportSMList *new = SCCalloc(1, sizeof(SCFPSupportSMList));
98  if (unlikely(new == NULL))
99  exit(EXIT_FAILURE);
100  new->list_id = list_id;
101  new->priority = priority;
102 
103  *list = new;
104  return;
105  }
106 
107  SCFPSupportSMList *new = SCCalloc(1, sizeof(SCFPSupportSMList));
108  if (unlikely(new == NULL))
109  exit(EXIT_FAILURE);
110  new->list_id = list_id;
111  new->priority = priority;
112  if (ip == NULL) {
113  new->next = *list;
114  *list = new;
115  } else {
116  new->next = ip->next;
117  ip->next = new;
118  }
119 }
120 
121 /**
122  * \brief Lets one add a sm list id to be searched for potential fp supported
123  * keywords later.
124  *
125  * \param list_id SM list id.
126  * \param priority Priority for this list.
127  */
128 void SupportFastPatternForSigMatchList(int list_id, int priority)
129 {
130  Add(&g_fp_support_smlist_list, list_id, priority);
131 }
132 
134 {
135  Add(&de_ctx->fp_support_smlist_list, list_id, priority);
136 }
137 
138 /**
139  * \brief Registers the keywords(SMs) that should be given fp support.
140  */
142 {
144 
145  /* other types are handled by DetectMpmAppLayerRegister() */
146 }
147 
149 {
150  SCFPSupportSMList *last = NULL;
151  for (SCFPSupportSMList *tmp = g_fp_support_smlist_list; tmp != NULL; tmp = tmp->next) {
152  SCFPSupportSMList *n = SCCalloc(1, sizeof(*n));
153  if (n == NULL) {
154  FatalError("out of memory: %s", strerror(errno));
155  }
156  n->list_id = tmp->list_id;
157  n->priority = tmp->priority;
158 
159  // append
160  if (de_ctx->fp_support_smlist_list == NULL) {
161  last = de_ctx->fp_support_smlist_list = n;
162  } else {
163  BUG_ON(last == NULL);
164  last->next = n;
165  last = n;
166  }
167  }
168 }
169 
171 {
172  for (SCFPSupportSMList *tmp = de_ctx->fp_support_smlist_list; tmp != NULL;) {
173  SCFPSupportSMList *next = tmp->next;
174  SCFree(tmp);
175  tmp = next;
176  }
178 }
179 
180 /**
181  * \brief Registration function for fast_pattern keyword
182  */
184 {
185  sigmatch_table[DETECT_FAST_PATTERN].name = "fast_pattern";
186  sigmatch_table[DETECT_FAST_PATTERN].desc = "force using preceding content in the multi pattern matcher";
187  sigmatch_table[DETECT_FAST_PATTERN].url = "/rules/prefilter-keywords.html#fast-pattern";
189  sigmatch_table[DETECT_FAST_PATTERN].Setup = DetectFastPatternSetup;
191 #ifdef UNITTESTS
192  sigmatch_table[DETECT_FAST_PATTERN].RegisterTests = DetectFastPatternRegisterTests;
193 #endif
195 
196  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
197 }
198 
199 /**
200  * \brief Configures the previous content context for a fast_pattern modifier
201  * keyword used in the rule.
202  *
203  * \param de_ctx Pointer to the Detection Engine Context.
204  * \param s Pointer to the Signature to which the current keyword belongs.
205  * \param arg May hold an argument
206  *
207  * \retval 0 On success.
208  * \retval -1 On failure.
209  */
210 static int DetectFastPatternSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
211 {
212  int res = 0;
213  size_t pcre2len;
214  char arg_substr[128] = "";
215  DetectContentData *cd = NULL;
216  pcre2_match_data *match = NULL;
217 
220  if (pm1 == NULL && pm2 == NULL) {
221  SCLogError("fast_pattern found inside "
222  "the rule, without a content context. Please use a "
223  "content based keyword before using fast_pattern");
224  return -1;
225  }
226 
227  SigMatch *pm = NULL;
228  if (pm1 && pm2) {
229  if (pm1->idx > pm2->idx)
230  pm = pm1;
231  else
232  pm = pm2;
233  } else if (pm1 && !pm2) {
234  pm = pm1;
235  } else {
236  pm = pm2;
237  }
238 
239  if (s->flags & SIG_FLAG_TXBOTHDIR && s->init_data->curbuf != NULL) {
242  SCLogError("fast_pattern cannot be used on to_client keyword for "
243  "transactional rule with a streaming buffer to server %u",
244  s->id);
245  goto error;
246  }
248  }
249  }
250 
251  cd = (DetectContentData *)pm->ctx;
252  if ((cd->flags & DETECT_CONTENT_NEGATED) &&
253  ((cd->flags & DETECT_CONTENT_DISTANCE) ||
254  (cd->flags & DETECT_CONTENT_WITHIN) ||
255  (cd->flags & DETECT_CONTENT_OFFSET) ||
256  (cd->flags & DETECT_CONTENT_DEPTH))) {
257 
258  /* we can't have any of these if we are having "only" */
259  SCLogError("fast_pattern; cannot be "
260  "used with negated content, along with relative modifiers");
261  goto error;
262  }
263 
264  if (arg == NULL|| strcmp(arg, "") == 0) {
266  SCLogError("can't use multiple fast_pattern "
267  "options for the same content");
268  goto error;
269  }
270  else { /*allow only one content to have fast_pattern modifier*/
271  for (uint32_t list_id = 0; list_id < DETECT_SM_LIST_MAX; list_id++) {
272  SigMatch *sm = NULL;
273  for (sm = s->init_data->smlists[list_id]; sm != NULL; sm = sm->next) {
274  if (sm->type == DETECT_CONTENT) {
275  DetectContentData *tmp_cd = (DetectContentData *)sm->ctx;
276  if (tmp_cd->flags & DETECT_CONTENT_FAST_PATTERN) {
277  SCLogError("fast_pattern "
278  "can be used on only one content in a rule");
279  goto error;
280  }
281  }
282  }
283  }
284  }
286  SCLogError("fast_pattern cannot be used with base64_data");
287  goto error;
288  }
290  return 0;
291  }
292 
293  /* Execute the regex and populate args with captures. */
294  int ret = DetectParsePcreExec(&parse_regex, &match, arg, 0, 0);
295  /* fast pattern only */
296  if (ret == 2) {
297  if ((cd->flags & DETECT_CONTENT_NEGATED) ||
298  (cd->flags & DETECT_CONTENT_DISTANCE) ||
299  (cd->flags & DETECT_CONTENT_WITHIN) ||
300  (cd->flags & DETECT_CONTENT_OFFSET) ||
301  (cd->flags & DETECT_CONTENT_DEPTH)) {
302 
303  /* we can't have any of these if we are having "only" */
304  SCLogError("fast_pattern: only; cannot be "
305  "used with negated content or with any of the relative "
306  "modifiers like distance, within, offset, depth");
307  goto error;
308  }
310 
311  /* fast pattern chop */
312  } else if (ret == 4) {
313  pcre2len = sizeof(arg_substr);
314  res = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
315  if (res < 0) {
316  SCLogError("pcre2_substring_copy_bynumber failed "
317  "for fast_pattern offset");
318  goto error;
319  }
320  uint16_t offset;
321  if (StringParseUint16(&offset, 10, 0, (const char *)arg_substr) <= 0) {
322  SCLogError("Invalid fast pattern offset:"
323  " \"%s\"",
324  arg_substr);
325  goto error;
326  }
327 
328  pcre2len = sizeof(arg_substr);
329  res = pcre2_substring_copy_bynumber(match, 3, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
330  if (res < 0) {
331  SCLogError("pcre2_substring_copy_bynumber failed "
332  "for fast_pattern offset");
333  goto error;
334  }
335  uint16_t length;
336  if (StringParseUint16(&length, 10, 0, (const char *)arg_substr) <= 0) {
337  SCLogError("Invalid value for fast "
338  "pattern: \"%s\"",
339  arg_substr);
340  goto error;
341  }
342 
343  // Avoiding integer overflow
344  if (offset > (65535 - length)) {
345  SCLogError("Fast pattern (length + offset) "
346  "exceeds limit pattern length limit");
347  goto error;
348  }
349 
350  if (offset + length > cd->content_len) {
351  SCLogError("Fast pattern (length + "
352  "offset (%u)) exceeds pattern length (%u)",
353  offset + length, cd->content_len);
354  goto error;
355  }
356 
357  cd->fp_chop_offset = offset;
358  cd->fp_chop_len = length;
360 
361  } else {
362  SCLogError("parse error, ret %" PRId32 ", string %s", ret, arg);
363  goto error;
364  }
365 
367 
368  pcre2_match_data_free(match);
369  return 0;
370 
371  error:
372  if (match) {
373  pcre2_match_data_free(match);
374  }
375  return -1;
376 }
377 
378 /*----------------------------------Unittests---------------------------------*/
379 
380 #ifdef UNITTESTS
381 #include "detect-engine-alert.h"
382 #include "detect-engine-buffer.h"
383 static SigMatch *GetMatches(Signature *s, const int list)
384 {
385  SigMatch *sm = DetectBufferGetFirstSigMatch(s, list);
386  if (sm == NULL && list < DETECT_SM_LIST_MAX) {
387  sm = s->init_data->smlists[list];
388  }
389  return sm;
390 }
391 
392 static int DetectFastPatternStickySingle(const char *sticky, const int list)
393 {
396  char string[1024];
397  snprintf(string, sizeof(string),
398  "alert tcp any any -> any any "
399  "(%s%scontent:\"one\"; fast_pattern; sid:1;)",
400  sticky ? sticky : "", sticky ? "; " : " ");
401  Signature *s = DetectEngineAppendSig(de_ctx, string);
402  FAIL_IF_NULL(s);
403  SigMatch *sm = GetMatches(s, list);
404  FAIL_IF_NULL(sm);
410  PASS;
411 }
412 
413 static int DetectFastPatternModifierSingle(const char *sticky, const int list)
414 {
417  char string[1024];
418  snprintf(string, sizeof(string),
419  "alert tcp any any -> any any "
420  "(content:\"one\"; %s%sfast_pattern; sid:1;)",
421  sticky ? sticky : "", sticky ? "; " : " ");
422  Signature *s = DetectEngineAppendSig(de_ctx, string);
423  FAIL_IF_NULL(s);
424  SigMatch *sm = GetMatches(s, list);
425  FAIL_IF_NULL(sm);
431  PASS;
432 }
433 
434 static int DetectFastPatternStickySingleNoFP(const char *sticky, const int list)
435 {
438  char string[1024];
439  snprintf(string, sizeof(string),
440  "alert tcp any any -> any any "
441  "(%s%scontent:\"one\"; sid:1;)",
442  sticky ? sticky : "", sticky ? "; " : " ");
443  Signature *s = DetectEngineAppendSig(de_ctx, string);
444  FAIL_IF_NULL(s);
445  SigMatch *sm = GetMatches(s, list);
446  FAIL_IF_NULL(sm);
452  PASS;
453 }
454 
455 static int DetectFastPatternModifierSingleNoFP(const char *sticky, const int list)
456 {
459  char string[1024];
460  snprintf(string, sizeof(string),
461  "alert tcp any any -> any any "
462  "(content:\"one\"; %s%ssid:1;)",
463  sticky ? sticky : "", sticky ? "; " : " ");
464  Signature *s = DetectEngineAppendSig(de_ctx, string);
465  FAIL_IF_NULL(s);
466  SigMatch *sm = GetMatches(s, list);
467  FAIL_IF_NULL(sm);
473  PASS;
474 }
475 
476 static int DetectFastPatternStickySingleBadArg(const char *sticky)
477 {
480  char string[1024];
481  /* bogus argument to fast_pattern */
482  snprintf(string, sizeof(string),
483  "alert tcp any any -> any any "
484  "(%s%scontent:\"one\"; fast_pattern:boo; sid:1;)",
485  sticky ? sticky : "", sticky ? "; " : " ");
486  Signature *s = DetectEngineAppendSig(de_ctx, string);
487  FAIL_IF_NOT_NULL(s);
488  /* fast_pattern only with distance */
489  snprintf(string, sizeof(string),
490  "alert tcp any any -> any any "
491  "(%s%scontent:\"one\"; fast_pattern:only; content:\"two\"; distance:10; sid:1;)",
492  sticky ? sticky : "", sticky ? "; " : " ");
493  s = DetectEngineAppendSig(de_ctx, string);
494  FAIL_IF_NOT_NULL(s);
495  /* fast_pattern only with distance */
496  snprintf(string, sizeof(string),
497  "alert tcp any any -> any any "
498  "(%s%scontent:\"one\"; content:\"two\"; fast_pattern:only; distance:10; sid:1;)",
499  sticky ? sticky : "", sticky ? "; " : " ");
500  s = DetectEngineAppendSig(de_ctx, string);
501  FAIL_IF_NOT_NULL(s);
502  /* fast_pattern only with distance */
503  snprintf(string, sizeof(string),
504  "alert tcp any any -> any any "
505  "(%s%scontent:\"one\"; content:\"two\"; distance:10; fast_pattern:only; sid:1;)",
506  sticky ? sticky : "", sticky ? "; " : " ");
507  s = DetectEngineAppendSig(de_ctx, string);
508  FAIL_IF_NOT_NULL(s);
509  /* fast_pattern chop with invalid values */
510  snprintf(string, sizeof(string),
511  "alert tcp any any -> any any "
512  "(%s%scontent:\"one\"; fast_pattern:5,6; sid:1;)",
513  sticky ? sticky : "", sticky ? "; " : " ");
514  s = DetectEngineAppendSig(de_ctx, string);
515  FAIL_IF_NOT_NULL(s);
517  PASS;
518 }
519 
520 static int DetectFastPatternModifierBadRules(const char *sticky)
521 {
524  char string[1024];
525  /* bogus argument to fast_pattern */
526  snprintf(string, sizeof(string),
527  "alert tcp any any -> any any "
528  "(content:\"one\"; %s%sfast_pattern:boo; sid:1;)",
529  sticky ? sticky : "", sticky ? "; " : " ");
530  Signature *s = DetectEngineAppendSig(de_ctx, string);
531  FAIL_IF_NOT_NULL(s);
532  /* fast_pattern only with distance */
533  snprintf(string, sizeof(string),
534  "alert tcp any any -> any any "
535  "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%sdistance:10; sid:1;)",
536  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
537  s = DetectEngineAppendSig(de_ctx, string);
538  FAIL_IF_NOT_NULL(s);
539 #if 0 // TODO bug?
540  /* fast_pattern only with distance */
541  snprintf(string, sizeof(string), "alert tcp any any -> any any "
542  "(content:\"one\"; %s%s content:\"two\"; %s%sdistance:10; fast_pattern:only; sid:1;)",
543  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
544  s = DetectEngineAppendSig(de_ctx, string);
545  FAIL_IF_NOT_NULL(s);
546 #endif
547  /* fast_pattern only with within */
548  snprintf(string, sizeof(string),
549  "alert tcp any any -> any any "
550  "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%swithin:10; sid:1;)",
551  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
552  s = DetectEngineAppendSig(de_ctx, string);
553  FAIL_IF_NOT_NULL(s);
554  /* fast_pattern only with within */
555  snprintf(string, sizeof(string),
556  "alert tcp any any -> any any "
557  "(content:\"one\"; %s%s content:\"two\"; %s%swithin:10; fast_pattern:only; sid:1;)",
558  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
559  s = DetectEngineAppendSig(de_ctx, string);
560  FAIL_IF_NOT_NULL(s);
561  /* fast_pattern only with offset */
562  snprintf(string, sizeof(string),
563  "alert tcp any any -> any any "
564  "(content:\"one\"; %s%sfast_pattern:only; offset:10; sid:1;)",
565  sticky ? sticky : "", sticky ? "; " : " ");
566  s = DetectEngineAppendSig(de_ctx, string);
567  FAIL_IF_NOT_NULL(s);
568  /* fast_pattern only with offset */
569  snprintf(string, sizeof(string),
570  "alert tcp any any -> any any "
571  "(content:\"one\"; %s%s offset:10; fast_pattern:only; sid:1;)",
572  sticky ? sticky : "", sticky ? "; " : " ");
573  s = DetectEngineAppendSig(de_ctx, string);
574  FAIL_IF_NOT_NULL(s);
575  /* fast_pattern only with depth */
576  snprintf(string, sizeof(string),
577  "alert tcp any any -> any any "
578  "(content:\"one\"; %s%sfast_pattern:only; depth:10; sid:1;)",
579  sticky ? sticky : "", sticky ? "; " : " ");
580  s = DetectEngineAppendSig(de_ctx, string);
581  FAIL_IF_NOT_NULL(s);
582  /* fast_pattern only with depth */
583  snprintf(string, sizeof(string),
584  "alert tcp any any -> any any "
585  "(content:\"one\"; %s%s depth:10; fast_pattern:only; sid:1;)",
586  sticky ? sticky : "", sticky ? "; " : " ");
587  s = DetectEngineAppendSig(de_ctx, string);
588  FAIL_IF_NOT_NULL(s);
589  /* fast_pattern only negate */
590  snprintf(string, sizeof(string),
591  "alert tcp any any -> any any "
592  "(content:\"one\"; %s%s content:!\"two\"; %s%sfast_pattern:only; sid:1;)",
593  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
594  s = DetectEngineAppendSig(de_ctx, string);
595  FAIL_IF_NOT_NULL(s);
596  /* fast_pattern chop with invalid values */
597  snprintf(string, sizeof(string),
598  "alert tcp any any -> any any "
599  "(content:\"one\"; %s%sfast_pattern:5,6; sid:1;)",
600  sticky ? sticky : "", sticky ? "; " : " ");
601  s = DetectEngineAppendSig(de_ctx, string);
602  FAIL_IF_NOT_NULL(s);
603  /* fast_pattern chop with invalid values */
604  snprintf(string, sizeof(string),
605  "alert tcp any any -> any any "
606  "(content:\"one\"; %s%sfast_pattern:65977,2; sid:1;)",
607  sticky ? sticky : "", sticky ? "; " : " ");
608  s = DetectEngineAppendSig(de_ctx, string);
609  FAIL_IF_NOT_NULL(s);
610  /* fast_pattern chop with invalid values */
611  snprintf(string, sizeof(string),
612  "alert tcp any any -> any any "
613  "(content:\"one\"; %s%sfast_pattern:2,65977; sid:1;)",
614  sticky ? sticky : "", sticky ? "; " : " ");
615  s = DetectEngineAppendSig(de_ctx, string);
616  FAIL_IF_NOT_NULL(s);
617  /* fast_pattern chop with invalid values */
618  snprintf(string, sizeof(string),
619  "alert tcp any any -> any any "
620  "(content:\"one\"; %s%sfast_pattern:2,65534; sid:1;)",
621  sticky ? sticky : "", sticky ? "; " : " ");
622  s = DetectEngineAppendSig(de_ctx, string);
623  FAIL_IF_NOT_NULL(s);
624  /* fast_pattern chop with invalid values */
625  snprintf(string, sizeof(string),
626  "alert tcp any any -> any any "
627  "(content:\"one\"; %s%sfast_pattern:65534,2; sid:1;)",
628  sticky ? sticky : "", sticky ? "; " : " ");
629  s = DetectEngineAppendSig(de_ctx, string);
630  FAIL_IF_NOT_NULL(s);
631  /* negated fast_pattern with distance */
632  snprintf(string, sizeof(string),
633  "alert tcp any any -> any any "
634  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdistance:10; sid:1;)",
635  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
636  s = DetectEngineAppendSig(de_ctx, string);
637  FAIL_IF_NOT_NULL(s);
638  /* negated fast_pattern with within */
639  snprintf(string, sizeof(string),
640  "alert tcp any any -> any any "
641  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%swithin:10; sid:1;)",
642  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
643  s = DetectEngineAppendSig(de_ctx, string);
644  FAIL_IF_NOT_NULL(s);
645  /* negated fast_pattern with depth */
646  snprintf(string, sizeof(string),
647  "alert tcp any any -> any any "
648  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdepth:10; sid:1;)",
649  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
650  s = DetectEngineAppendSig(de_ctx, string);
651  FAIL_IF_NOT_NULL(s);
652  /* negated fast_pattern with offset */
653  snprintf(string, sizeof(string),
654  "alert tcp any any -> any any "
655  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%soffset:10; sid:1;)",
656  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
657  s = DetectEngineAppendSig(de_ctx, string);
658  FAIL_IF_NOT_NULL(s);
660  PASS;
661 }
662 
663 static int DetectFastPatternStickySingleFPOnly(const char *sticky, const int list)
664 {
667  char string[1024];
668  snprintf(string, sizeof(string),
669  "alert tcp any any -> any any "
670  "(%s%scontent:\"one\"; fast_pattern:only; sid:1;)",
671  sticky ? sticky : "", sticky ? "; " : " ");
672  Signature *s = DetectEngineAppendSig(de_ctx, string);
673  FAIL_IF_NULL(s);
674  SigMatch *sm = GetMatches(s, list);
675  FAIL_IF_NULL(sm);
682  PASS;
683 }
684 
685 static int DetectFastPatternModifierFPOnly(const char *sticky, const int list)
686 {
689  char string[1024];
690  snprintf(string, sizeof(string),
691  "alert tcp any any -> any any "
692  "(content:\"one\"; %s%sfast_pattern:only; sid:1;)",
693  sticky ? sticky : "", sticky ? "; " : " ");
694  Signature *s = DetectEngineAppendSig(de_ctx, string);
695  FAIL_IF_NULL(s);
696  SigMatch *sm = GetMatches(s, list);
697  FAIL_IF_NULL(sm);
703 
704  snprintf(string, sizeof(string),
705  "alert tcp any any -> any any "
706  "(content:\"one\"; %s%scontent:\"two\"; %s%sfast_pattern:only; sid:2;)",
707  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
708  s = DetectEngineAppendSig(de_ctx, string);
709  FAIL_IF_NULL(s);
710  sm = GetMatches(s, list);
711  FAIL_IF_NULL(sm);
712  FAIL_IF_NULL(sm->next);
714  cd = (DetectContentData *)sm->ctx;
716  FAIL_IF_NOT(
718  sm = sm->next;
720  cd = (DetectContentData *)sm->ctx;
724 
725  snprintf(string, sizeof(string),
726  "alert tcp any any -> any any "
727  "(content:\"one\"; %s%scontent:\"two\"; distance:10; %s%scontent:\"three\"; "
728  "%s%sfast_pattern:only; sid:3;)",
729  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
730  sticky ? sticky : "", sticky ? "; " : " ");
731  s = DetectEngineAppendSig(de_ctx, string);
732  FAIL_IF_NULL(s);
733  sm = GetMatches(s, list);
734  FAIL_IF_NULL(sm);
735  FAIL_IF_NULL(sm->next);
737  cd = (DetectContentData *)sm->ctx;
739  FAIL_IF_NOT(
741  sm = sm->next;
742  FAIL_IF_NULL(sm->next);
744  cd = (DetectContentData *)sm->ctx;
746  FAIL_IF_NOT(
748  sm = sm->next;
749  FAIL_IF_NOT_NULL(sm->next);
751  cd = (DetectContentData *)sm->ctx;
755 
756  snprintf(string, sizeof(string),
757  "alert tcp any any -> any any "
758  "(content:\"one\"; %s%scontent:\"two\"; within:10; %s%scontent:\"three\"; "
759  "%s%sfast_pattern:only; sid:4;)",
760  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
761  sticky ? sticky : "", sticky ? "; " : " ");
762  s = DetectEngineAppendSig(de_ctx, string);
763  FAIL_IF_NULL(s);
764  sm = GetMatches(s, list);
765  FAIL_IF_NULL(sm);
766  FAIL_IF_NULL(sm->next);
768  cd = (DetectContentData *)sm->ctx;
770  FAIL_IF_NOT(
772  sm = sm->next;
773  FAIL_IF_NULL(sm->next);
775  cd = (DetectContentData *)sm->ctx;
777  FAIL_IF_NOT(
779  sm = sm->next;
780  FAIL_IF_NOT_NULL(sm->next);
782  cd = (DetectContentData *)sm->ctx;
786 
787  snprintf(string, sizeof(string),
788  "alert tcp any any -> any any "
789  "(content:\"one\"; %s%scontent:\"two\"; offset:10; %s%scontent:\"three\"; "
790  "%s%sfast_pattern:only; sid:5;)",
791  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
792  sticky ? sticky : "", sticky ? "; " : " ");
793  s = DetectEngineAppendSig(de_ctx, string);
794  FAIL_IF_NULL(s);
795  sm = GetMatches(s, list);
796  FAIL_IF_NULL(sm);
797  FAIL_IF_NULL(sm->next);
799  cd = (DetectContentData *)sm->ctx;
801  FAIL_IF_NOT(
803  sm = sm->next;
804  FAIL_IF_NULL(sm->next);
806  cd = (DetectContentData *)sm->ctx;
808  FAIL_IF_NOT(
810  sm = sm->next;
811  FAIL_IF_NOT_NULL(sm->next);
813  cd = (DetectContentData *)sm->ctx;
817 
818  snprintf(string, sizeof(string),
819  "alert tcp any any -> any any "
820  "(content:\"one\"; %s%scontent:\"two\"; depth:10; %s%scontent:\"three\"; "
821  "%s%sfast_pattern:only; sid:6;)",
822  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
823  sticky ? sticky : "", sticky ? "; " : " ");
824  s = DetectEngineAppendSig(de_ctx, string);
825  FAIL_IF_NULL(s);
826  sm = GetMatches(s, list);
827  FAIL_IF_NULL(sm);
828  FAIL_IF_NULL(sm->next);
830  cd = (DetectContentData *)sm->ctx;
832  FAIL_IF_NOT(
834  sm = sm->next;
835  FAIL_IF_NULL(sm->next);
837  cd = (DetectContentData *)sm->ctx;
839  FAIL_IF_NOT(
841  sm = sm->next;
842  FAIL_IF_NOT_NULL(sm->next);
844  cd = (DetectContentData *)sm->ctx;
848 
849  snprintf(string, sizeof(string),
850  "alert tcp any any -> any any "
851  "(content:!\"one\"; %s%sfast_pattern; content:\"two\"; depth:10; %s%ssid:7;)",
852  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
853  s = DetectEngineAppendSig(de_ctx, string);
854  FAIL_IF_NULL(s);
855  sm = GetMatches(s, list);
856  FAIL_IF_NULL(sm);
857  FAIL_IF_NULL(sm->next);
859  cd = (DetectContentData *)sm->ctx;
864  sm = sm->next;
865  FAIL_IF_NOT_NULL(sm->next);
867  cd = (DetectContentData *)sm->ctx;
869  FAIL_IF_NOT(
871 
873  PASS;
874 }
875 
876 static int DetectFastPatternStickyFPChop(const char *sticky, const int list)
877 {
880  char string[1024];
881  snprintf(string, sizeof(string),
882  "alert tcp any any -> any any "
883  "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; sid:1;)",
884  sticky ? sticky : "", sticky ? "; " : " ");
885  Signature *s = DetectEngineAppendSig(de_ctx, string);
886  FAIL_IF_NULL(s);
887  SigMatch *sm = GetMatches(s, list);
888  FAIL_IF_NULL(sm);
895  FAIL_IF_NOT(cd->fp_chop_offset == 3);
896  FAIL_IF_NOT(cd->fp_chop_len == 4);
897 
898  snprintf(string, sizeof(string),
899  "alert tcp any any -> any any "
900  "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; content:\"xyz\"; distance:10; sid:2;)",
901  sticky ? sticky : "", sticky ? "; " : " ");
902  s = DetectEngineAppendSig(de_ctx, string);
903  FAIL_IF_NULL(s);
904  sm = GetMatches(s, list);
905  FAIL_IF_NULL(sm);
907  cd = (DetectContentData *)sm->ctx;
912  FAIL_IF_NOT(cd->fp_chop_offset == 3);
913  FAIL_IF_NOT(cd->fp_chop_len == 4);
914 
916  PASS;
917 }
918 
919 static int DetectFastPatternModifierFPChop(const char *sticky, const int list)
920 {
923  char string[1024];
924  snprintf(string, sizeof(string),
925  "alert tcp any any -> any any "
926  "(content:\"onetwothree\"; %s%sfast_pattern:3,4; sid:1;)",
927  sticky ? sticky : "", sticky ? "; " : " ");
928  Signature *s = DetectEngineAppendSig(de_ctx, string);
929  FAIL_IF_NULL(s);
930  SigMatch *sm = GetMatches(s, list);
931  FAIL_IF_NULL(sm);
938  FAIL_IF_NOT(cd->fp_chop_offset == 3);
939  FAIL_IF_NOT(cd->fp_chop_len == 4);
940 
941  snprintf(string, sizeof(string),
942  "alert tcp any any -> any any "
943  "(content:!\"onetwothree\"; %s%sfast_pattern:3,4; sid:2;)",
944  sticky ? sticky : "", sticky ? "; " : " ");
945  s = DetectEngineAppendSig(de_ctx, string);
946  FAIL_IF_NULL(s);
947  sm = GetMatches(s, list);
948  FAIL_IF_NULL(sm);
950  cd = (DetectContentData *)sm->ctx;
957  FAIL_IF_NOT(cd->fp_chop_offset == 3);
958  FAIL_IF_NOT(cd->fp_chop_len == 4);
959 
961  PASS;
962 }
963 
964 /**
965  * \test Checks if a fast_pattern is registered in a Signature
966  */
967 static int DetectFastPatternTest01(void)
968 {
969  FAIL_IF_NOT(DetectFastPatternStickySingle(NULL, DETECT_SM_LIST_PMATCH));
970  FAIL_IF_NOT(DetectFastPatternModifierSingle(NULL, DETECT_SM_LIST_PMATCH));
971  FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(NULL, DETECT_SM_LIST_PMATCH));
972  FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(NULL, DETECT_SM_LIST_PMATCH));
973  FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(NULL));
974  FAIL_IF_NOT(DetectFastPatternModifierBadRules(NULL));
975  FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(NULL, DETECT_SM_LIST_PMATCH));
976  FAIL_IF_NOT(DetectFastPatternModifierFPOnly(NULL, DETECT_SM_LIST_PMATCH));
977  FAIL_IF_NOT(DetectFastPatternStickyFPChop(NULL, DETECT_SM_LIST_PMATCH));
978  FAIL_IF_NOT(DetectFastPatternModifierFPChop(NULL, DETECT_SM_LIST_PMATCH));
979 
980  struct {
981  const char *buffer_name;
982  const char *sb_name;
983  const char *mod_name;
984  } keywords[] = {
985  { "file_data", "file.data", NULL },
986  { "http_uri", "http.uri", "http_uri" },
987  { "http_raw_uri", "http.uri.raw", "http_raw_uri" },
988  { "http_user_agent", "http.user_agent", "http_user_agent" },
989  { "http_header", "http.header", "http_header" },
990  // http_raw_header requires sigs to have a direction
991  //{ "http_raw_header", "http.header.raw", "http_raw_header" },
992  { "http_method", "http.method", "http_method" },
993  { "http_cookie", "http.cookie", "http_cookie" },
994  { "http_host", "http.host", "http_host" },
995  { "http_raw_host", "http.host.raw", "http_raw_host" },
996  { "http_stat_code", "http.stat_code", "http_stat_code" },
997  { "http_stat_msg", "http.stat_msg", "http_stat_msg" },
998  { "http_client_body", "http.request_body", "http_client_body" },
999  { NULL, NULL, NULL },
1000  };
1001 
1002  for (int i = 0; keywords[i].buffer_name != NULL; i++) {
1003  const int list_id = DetectBufferTypeGetByName(keywords[i].buffer_name);
1004  FAIL_IF(list_id == -1);
1005 
1006  const char *k = keywords[i].sb_name;
1007  if (k) {
1008  FAIL_IF_NOT(DetectFastPatternStickySingle(k, list_id));
1009  FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(k, list_id));
1010  FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(k));
1011  FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(k, list_id));
1012  FAIL_IF_NOT(DetectFastPatternStickyFPChop(k, list_id));
1013  }
1014  k = keywords[i].mod_name;
1015  if (k) {
1016  FAIL_IF_NOT(DetectFastPatternModifierSingle(k, list_id));
1017  FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(k, list_id));
1018  FAIL_IF_NOT(DetectFastPatternModifierBadRules(k));
1019  FAIL_IF_NOT(DetectFastPatternModifierFPOnly(k, list_id));
1020  FAIL_IF_NOT(DetectFastPatternModifierFPChop(k, list_id));
1021  }
1022  }
1023 
1024  PASS;
1025 }
1026 
1027 /**
1028  * \test Checks to make sure that other sigs work that should when fast_pattern is inspecting on the
1029  * same payload
1030  *
1031  */
1032 static int DetectFastPatternTest14(void)
1033 {
1034  uint8_t *buf = (uint8_t *)"Dummy is our name. Oh yes. From right here "
1035  "right now, all the way to hangover. right. strings5_imp now here "
1036  "comes our dark knight strings_string5. Yes here is our dark knight";
1037  uint16_t buflen = strlen((char *)buf);
1038  ThreadVars th_v;
1039  DetectEngineThreadCtx *det_ctx = NULL;
1040 
1041  memset(&th_v, 0, sizeof(th_v));
1043  Packet *p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
1044  FAIL_IF_NULL(p);
1045 
1048  de_ctx->flags |= DE_QUIET;
1049 
1051 
1053  "alert tcp any any -> any any "
1054  "(msg:\"fast_pattern test\"; content:\"strings_string5\"; content:\"knight\"; "
1055  "fast_pattern; sid:1;)");
1056  FAIL_IF_NULL(s);
1057 
1059  "alert tcp any any -> any any "
1060  "(msg:\"test different content\"; content:\"Dummy is our name\"; sid:2;)");
1061  FAIL_IF_NULL(s);
1062 
1064  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1065 
1066  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1069 
1070  UTHFreePackets(&p, 1);
1071  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1073  FlowShutdown();
1075  PASS;
1076 }
1077 
1078 /**
1079  * Unittest to check
1080  * - if we assign different content_ids to duplicate patterns, but one of the
1081  * patterns has a fast_pattern chop set.
1082  * - if 2 unique patterns get unique ids.
1083  * - if 2 duplicate patterns, with no chop set get unique ids.
1084  */
1085 static int DetectFastPatternTest671(void)
1086 {
1089  de_ctx->flags |= DE_QUIET;
1090 
1091  Signature *s[6];
1092  s[0] = DetectEngineAppendSig(
1093  de_ctx, "alert tcp any any -> any any (content:\"onetwothreefour\"; sid:1;)");
1094  FAIL_IF_NULL(s[0]);
1095  s[1] = DetectEngineAppendSig(
1096  de_ctx, "alert tcp any any -> any any (content:\"onetwothreefour\"; sid:2;)");
1097  FAIL_IF_NULL(s[1]);
1098  s[2] = DetectEngineAppendSig(
1099  de_ctx, "alert tcp any any -> any any (content:\"uniquepattern\"; sid:3;)");
1100  FAIL_IF_NULL(s[2]);
1102  "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:3,5; sid:4;)");
1103  FAIL_IF_NULL(s[3]);
1104  s[4] = DetectEngineAppendSig(
1105  de_ctx, "alert tcp any any -> any any (content:\"twoth\"; sid:5;)");
1106  FAIL_IF_NULL(s[4]);
1108  "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:0,15; "
1109  "sid:6;)");
1110  FAIL_IF_NULL(s[5]);
1111 
1113 
1115  DetectContentData *cd = (DetectContentData *)smd->ctx;
1116  FAIL_IF(cd->id != 0);
1117 
1118  smd = s[1]->sm_arrays[DETECT_SM_LIST_PMATCH];
1119  cd = (DetectContentData *)smd->ctx;
1120  FAIL_IF(cd->id != 0);
1121 
1122  smd = s[2]->sm_arrays[DETECT_SM_LIST_PMATCH];
1123  cd = (DetectContentData *)smd->ctx;
1124  FAIL_IF(cd->id != 2);
1125 
1126  smd = s[3]->sm_arrays[DETECT_SM_LIST_PMATCH];
1127  cd = (DetectContentData *)smd->ctx;
1128  FAIL_IF(cd->id != 1);
1129 
1130  smd = s[4]->sm_arrays[DETECT_SM_LIST_PMATCH];
1131  cd = (DetectContentData *)smd->ctx;
1132  FAIL_IF(cd->id != 1);
1133 
1134  smd = s[5]->sm_arrays[DETECT_SM_LIST_PMATCH];
1135  cd = (DetectContentData *)smd->ctx;
1136  FAIL_IF(cd->id != 0);
1137 
1139  PASS;
1140 }
1141 
1142 static int DetectFastPatternPrefilter(void)
1143 {
1146  const char *string = "alert tcp any any -> any any "
1147  "(content:\"one\"; prefilter; sid:1;)";
1148  Signature *s = DetectEngineAppendSig(de_ctx, string);
1149  FAIL_IF_NULL(s);
1151  FAIL_IF_NULL(sm);
1157  PASS;
1158 }
1159 
1160 static void DetectFastPatternRegisterTests(void)
1161 {
1162  UtRegisterTest("DetectFastPatternTest01", DetectFastPatternTest01);
1163  UtRegisterTest("DetectFastPatternTest14", DetectFastPatternTest14);
1164  /* Unittest to check
1165  * - if we assign different content_ids to duplicate patterns, but one of the
1166  * patterns has a fast_pattern chop set.
1167  * - if 2 unique patterns get unique ids.
1168  * - if 2 duplicate patterns, with no chop set get unique ids.
1169  */
1170  UtRegisterTest("DetectFastPatternTest671", DetectFastPatternTest671);
1171 
1172  UtRegisterTest("DetectFastPatternPrefilter", DetectFastPatternPrefilter);
1173 }
1174 #endif
util-byte.h
SCFPSupportSMList_
Definition: detect.h:869
SigTableElmt_::url
const char * url
Definition: detect.h:1545
detect-content.h
detect-engine.h
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:120
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:666
DetectContentData_::fp_chop_len
uint16_t fp_chop_len
Definition: detect-content.h:98
SigTableElmt_::desc
const char * desc
Definition: detect.h:1544
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:78
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1529
SCFPSupportSMList_::next
struct SCFPSupportSMList_ * next
Definition: detect.h:872
DetectBufferGetFirstSigMatch
SigMatch * DetectBufferGetFirstSigMatch(const Signature *s, const uint32_t buf_id)
Definition: detect-engine-buffer.c:157
DetectParseRegex
Definition: detect-parse.h:94
SCFPSupportSMList_::list_id
int list_id
Definition: detect.h:870
SigTableElmt_::name
const char * name
Definition: detect.h:1542
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:101
DETECT_CONTENT
@ DETECT_CONTENT
Definition: detect-engine-register.h:78
SigTableElmt_::flags
uint32_t flags
Definition: detect.h:1533
Signature_::alproto
AppProto alproto
Definition: detect.h:697
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
SIG_FLAG_INIT_TXDIR_FAST_TOCLIENT
#define SIG_FLAG_INIT_TXDIR_FAST_TOCLIENT
Definition: detect.h:310
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:144
DETECT_FAST_PATTERN
@ DETECT_FAST_PATTERN
Definition: detect-engine-register.h:89
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:372
SCDetectGetLastSMFromLists
SigMatch * SCDetectGetLastSMFromLists(const Signature *s,...)
Returns the sm with the largest index (added latest) from the lists passed to us.
Definition: detect-parse.c:600
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:995
StringParseUint16
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:295
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2912
SupportFastPatternForSigMatchTypes
void SupportFastPatternForSigMatchTypes(void)
Registers the keywords(SMs) that should be given fp support.
Definition: detect-fast-pattern.c:141
SIG_FLAG_TXBOTHDIR
#define SIG_FLAG_TXBOTHDIR
Definition: detect.h:253
DE_QUIET
#define DE_QUIET
Definition: detect.h:334
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:241
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:3305
p
Packet * p
Definition: fuzz_dataset.c:30
Signature_::sm_arrays
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
Definition: detect.h:759
SignatureInitData_::init_flags
uint32_t init_flags
Definition: detect.h:625
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
Definition: detect-parse.c:4019
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:3965
SigMatchData_
Data needed for Match()
Definition: detect.h:369
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1524
DetectEngineRegisterFastPatternForId
void DetectEngineRegisterFastPatternForId(DetectEngineCtx *de_ctx, int list_id, int priority)
Definition: detect-fast-pattern.c:133
PARSE_REGEX
#define PARSE_REGEX
Definition: detect-fast-pattern.c:41
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:1452
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:574
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:22
DetectEngineThreadCtx_
Definition: detect.h:1316
DetectGetLastSMFromMpmLists
SigMatch * DetectGetLastSMFromMpmLists(const DetectEngineCtx *de_ctx, const Signature *s)
get the last SigMatch from lists that support MPM.
Definition: detect-parse.c:563
length
uint16_t length
Definition: decode-sctp.h:2
DETECT_SM_LIST_BASE64_DATA
@ DETECT_SM_LIST_BASE64_DATA
Definition: detect.h:125
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:4145
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
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
Definition: detect-engine.c:3660
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:364
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:363
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:322
DetectBufferToClient
bool DetectBufferToClient(const DetectEngineCtx *de_ctx, int buf_id, AppProto alproto)
Definition: detect-engine-mpm.c:1162
Signature_::flags
uint32_t flags
Definition: detect.h:693
DetectEngineInitializeFastPatternList
void DetectEngineInitializeFastPatternList(DetectEngineCtx *de_ctx)
Definition: detect-fast-pattern.c:148
Packet_
Definition: decode.h:516
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:775
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:63
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1504
SCFPSupportSMList_::priority
int priority
Definition: detect.h:871
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2300
DetectEngineBufferTypeSupportsMpmGetById
bool DetectEngineBufferTypeSupportsMpmGetById(const DetectEngineCtx *de_ctx, const int id)
Definition: detect-engine.c:1639
StatsThreadInit
void StatsThreadInit(StatsThreadContext *stats)
Definition: counters.c:1332
detect-fast-pattern.h
th_v
ThreadVars * th_v
Definition: fuzz_dataset.c:29
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:362
SigMatch_::type
uint16_t type
Definition: detect.h:361
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:718
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:128
SIGMATCH_OPTIONAL_OPT
#define SIGMATCH_OPTIONAL_OPT
Definition: detect-engine-register.h:315
SignatureInitData_::curbuf
SignatureInitDataBuffer * curbuf
Definition: detect.h:674
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
Definition: detect-engine.c:3905
detect-engine-buffer.h
FatalError
#define FatalError(...)
Definition: util-debug.h:517
DetectEngineFreeFastPatternList
void DetectEngineFreeFastPatternList(DetectEngineCtx *de_ctx)
Definition: detect-fast-pattern.c:170
SIG_FLAG_INIT_TXDIR_STREAMING_TOSERVER
#define SIG_FLAG_INIT_TXDIR_STREAMING_TOSERVER
Definition: detect.h:308
HtpBodyChunk_::next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:124
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:274
SigMatchListSMBelongsTo
int SigMatchListSMBelongsTo(const Signature *s, const SigMatch *key_sm)
Definition: detect-parse.c:799
SCFree
#define SCFree(p)
Definition: util-mem.h:61
Signature_::id
uint32_t id
Definition: detect.h:741
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
SignatureInitDataBuffer_::id
uint32_t id
Definition: detect.h:534
Signature_
Signature container.
Definition: detect.h:692
SigMatch_
a single match condition for a signature
Definition: detect.h:360
DETECT_SM_LIST_MAX
@ DETECT_SM_LIST_MAX
Definition: detect.h:136
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2873
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:43
DetectFastPatternRegister
void DetectFastPatternRegister(void)
Registration function for fast_pattern keyword.
Definition: detect-fast-pattern.c:183
DetectContentData_::content_len
uint16_t content_len
Definition: detect-content.h:95
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:997
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
ThreadVars_::stats
StatsThreadContext stats
Definition: threadvars.h:120
StatsThreadCleanup
void StatsThreadCleanup(StatsThreadContext *stats)
Definition: counters.c:1428
DetectEngineCtx_::fp_support_smlist_list
SCFPSupportSMList * fp_support_smlist_list
Definition: detect.h:1176
DETECT_CONTENT_WITHIN
#define DETECT_CONTENT_WITHIN
Definition: detect-content.h:31
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1531
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:453