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  if (s->flags & SIG_FLAG_TXBOTHDIR && s->init_data->curbuf != NULL) {
243  SCLogError("fast_pattern cannot be used on to_client keyword for "
244  "transactional rule with a streaming buffer to server %u",
245  s->id);
246  goto error;
247  }
249  }
250  }
251 
252  cd = (DetectContentData *)pm->ctx;
253  if ((cd->flags & DETECT_CONTENT_NEGATED) &&
254  ((cd->flags & DETECT_CONTENT_DISTANCE) ||
255  (cd->flags & DETECT_CONTENT_WITHIN) ||
256  (cd->flags & DETECT_CONTENT_OFFSET) ||
257  (cd->flags & DETECT_CONTENT_DEPTH))) {
258 
259  /* we can't have any of these if we are having "only" */
260  SCLogError("fast_pattern; cannot be "
261  "used with negated content, along with relative modifiers");
262  goto error;
263  }
264 
265  if (arg == NULL|| strcmp(arg, "") == 0) {
267  SCLogError("can't use multiple fast_pattern "
268  "options for the same content");
269  goto error;
270  }
271  else { /*allow only one content to have fast_pattern modifier*/
272  for (uint32_t list_id = 0; list_id < DETECT_SM_LIST_MAX; list_id++) {
273  SigMatch *sm = NULL;
274  for (sm = s->init_data->smlists[list_id]; sm != NULL; sm = sm->next) {
275  if (sm->type == DETECT_CONTENT) {
276  DetectContentData *tmp_cd = (DetectContentData *)sm->ctx;
277  if (tmp_cd->flags & DETECT_CONTENT_FAST_PATTERN) {
278  SCLogError("fast_pattern "
279  "can be used on only one content in a rule");
280  goto error;
281  }
282  }
283  }
284  }
285  }
287  SCLogError("fast_pattern cannot be used with base64_data");
288  goto error;
289  }
291  return 0;
292  }
293 
294  /* Execute the regex and populate args with captures. */
295  int ret = DetectParsePcreExec(&parse_regex, &match, arg, 0, 0);
296  /* fast pattern only */
297  if (ret == 2) {
298  if ((cd->flags & DETECT_CONTENT_NEGATED) ||
299  (cd->flags & DETECT_CONTENT_DISTANCE) ||
300  (cd->flags & DETECT_CONTENT_WITHIN) ||
301  (cd->flags & DETECT_CONTENT_OFFSET) ||
302  (cd->flags & DETECT_CONTENT_DEPTH)) {
303 
304  /* we can't have any of these if we are having "only" */
305  SCLogError("fast_pattern: only; cannot be "
306  "used with negated content or with any of the relative "
307  "modifiers like distance, within, offset, depth");
308  goto error;
309  }
311 
312  /* fast pattern chop */
313  } else if (ret == 4) {
314  pcre2len = sizeof(arg_substr);
315  res = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
316  if (res < 0) {
317  SCLogError("pcre2_substring_copy_bynumber failed "
318  "for fast_pattern offset");
319  goto error;
320  }
321  uint16_t offset;
322  if (StringParseUint16(&offset, 10, 0,
323  (const char *)arg_substr) < 0) {
324  SCLogError("Invalid fast pattern offset:"
325  " \"%s\"",
326  arg_substr);
327  goto error;
328  }
329 
330  pcre2len = sizeof(arg_substr);
331  res = pcre2_substring_copy_bynumber(match, 3, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
332  if (res < 0) {
333  SCLogError("pcre2_substring_copy_bynumber failed "
334  "for fast_pattern offset");
335  goto error;
336  }
337  uint16_t length;
338  if (StringParseUint16(&length, 10, 0,
339  (const char *)arg_substr) < 0) {
340  SCLogError("Invalid value for fast "
341  "pattern: \"%s\"",
342  arg_substr);
343  goto error;
344  }
345 
346  // Avoiding integer overflow
347  if (offset > (65535 - length)) {
348  SCLogError("Fast pattern (length + offset) "
349  "exceeds limit pattern length limit");
350  goto error;
351  }
352 
353  if (offset + length > cd->content_len) {
354  SCLogError("Fast pattern (length + "
355  "offset (%u)) exceeds pattern length (%u)",
356  offset + length, cd->content_len);
357  goto error;
358  }
359 
360  cd->fp_chop_offset = offset;
361  cd->fp_chop_len = length;
363 
364  } else {
365  SCLogError("parse error, ret %" PRId32 ", string %s", ret, arg);
366  goto error;
367  }
368 
370 
371  pcre2_match_data_free(match);
372  return 0;
373 
374  error:
375  if (match) {
376  pcre2_match_data_free(match);
377  }
378  return -1;
379 }
380 
381 /*----------------------------------Unittests---------------------------------*/
382 
383 #ifdef UNITTESTS
384 #include "detect-engine-alert.h"
385 #include "detect-engine-buffer.h"
386 static SigMatch *GetMatches(Signature *s, const int list)
387 {
388  SigMatch *sm = DetectBufferGetFirstSigMatch(s, list);
389  if (sm == NULL && list < DETECT_SM_LIST_MAX) {
390  sm = s->init_data->smlists[list];
391  }
392  return sm;
393 }
394 
395 static int DetectFastPatternStickySingle(const char *sticky, const int list)
396 {
399  char string[1024];
400  snprintf(string, sizeof(string),
401  "alert tcp any any -> any any "
402  "(%s%scontent:\"one\"; fast_pattern; sid:1;)",
403  sticky ? sticky : "", sticky ? "; " : " ");
404  Signature *s = DetectEngineAppendSig(de_ctx, string);
405  FAIL_IF_NULL(s);
406  SigMatch *sm = GetMatches(s, list);
407  FAIL_IF_NULL(sm);
413  PASS;
414 }
415 
416 static int DetectFastPatternModifierSingle(const char *sticky, const int list)
417 {
420  char string[1024];
421  snprintf(string, sizeof(string),
422  "alert tcp any any -> any any "
423  "(content:\"one\"; %s%sfast_pattern; sid:1;)",
424  sticky ? sticky : "", sticky ? "; " : " ");
425  Signature *s = DetectEngineAppendSig(de_ctx, string);
426  FAIL_IF_NULL(s);
427  SigMatch *sm = GetMatches(s, list);
428  FAIL_IF_NULL(sm);
434  PASS;
435 }
436 
437 static int DetectFastPatternStickySingleNoFP(const char *sticky, const int list)
438 {
441  char string[1024];
442  snprintf(string, sizeof(string),
443  "alert tcp any any -> any any "
444  "(%s%scontent:\"one\"; sid:1;)",
445  sticky ? sticky : "", sticky ? "; " : " ");
446  Signature *s = DetectEngineAppendSig(de_ctx, string);
447  FAIL_IF_NULL(s);
448  SigMatch *sm = GetMatches(s, list);
449  FAIL_IF_NULL(sm);
455  PASS;
456 }
457 
458 static int DetectFastPatternModifierSingleNoFP(const char *sticky, const int list)
459 {
462  char string[1024];
463  snprintf(string, sizeof(string),
464  "alert tcp any any -> any any "
465  "(content:\"one\"; %s%ssid:1;)",
466  sticky ? sticky : "", sticky ? "; " : " ");
467  Signature *s = DetectEngineAppendSig(de_ctx, string);
468  FAIL_IF_NULL(s);
469  SigMatch *sm = GetMatches(s, list);
470  FAIL_IF_NULL(sm);
476  PASS;
477 }
478 
479 static int DetectFastPatternStickySingleBadArg(const char *sticky)
480 {
483  char string[1024];
484  /* bogus argument to fast_pattern */
485  snprintf(string, sizeof(string),
486  "alert tcp any any -> any any "
487  "(%s%scontent:\"one\"; fast_pattern:boo; sid:1;)",
488  sticky ? sticky : "", sticky ? "; " : " ");
489  Signature *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\"; fast_pattern:only; content:\"two\"; distance:10; sid:1;)",
495  sticky ? sticky : "", sticky ? "; " : " ");
496  s = DetectEngineAppendSig(de_ctx, string);
497  FAIL_IF_NOT_NULL(s);
498  /* fast_pattern only with distance */
499  snprintf(string, sizeof(string),
500  "alert tcp any any -> any any "
501  "(%s%scontent:\"one\"; content:\"two\"; fast_pattern:only; distance:10; sid:1;)",
502  sticky ? sticky : "", sticky ? "; " : " ");
503  s = DetectEngineAppendSig(de_ctx, string);
504  FAIL_IF_NOT_NULL(s);
505  /* fast_pattern only with distance */
506  snprintf(string, sizeof(string),
507  "alert tcp any any -> any any "
508  "(%s%scontent:\"one\"; content:\"two\"; distance:10; fast_pattern:only; sid:1;)",
509  sticky ? sticky : "", sticky ? "; " : " ");
510  s = DetectEngineAppendSig(de_ctx, string);
511  FAIL_IF_NOT_NULL(s);
512  /* fast_pattern chop with invalid values */
513  snprintf(string, sizeof(string),
514  "alert tcp any any -> any any "
515  "(%s%scontent:\"one\"; fast_pattern:5,6; sid:1;)",
516  sticky ? sticky : "", sticky ? "; " : " ");
517  s = DetectEngineAppendSig(de_ctx, string);
518  FAIL_IF_NOT_NULL(s);
520  PASS;
521 }
522 
523 static int DetectFastPatternModifierBadRules(const char *sticky)
524 {
527  char string[1024];
528  /* bogus argument to fast_pattern */
529  snprintf(string, sizeof(string),
530  "alert tcp any any -> any any "
531  "(content:\"one\"; %s%sfast_pattern:boo; sid:1;)",
532  sticky ? sticky : "", sticky ? "; " : " ");
533  Signature *s = DetectEngineAppendSig(de_ctx, string);
534  FAIL_IF_NOT_NULL(s);
535  /* fast_pattern only with distance */
536  snprintf(string, sizeof(string),
537  "alert tcp any any -> any any "
538  "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%sdistance:10; sid:1;)",
539  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
540  s = DetectEngineAppendSig(de_ctx, string);
541  FAIL_IF_NOT_NULL(s);
542 #if 0 // TODO bug?
543  /* fast_pattern only with distance */
544  snprintf(string, sizeof(string), "alert tcp any any -> any any "
545  "(content:\"one\"; %s%s content:\"two\"; %s%sdistance:10; fast_pattern:only; sid:1;)",
546  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
547  s = DetectEngineAppendSig(de_ctx, string);
548  FAIL_IF_NOT_NULL(s);
549 #endif
550  /* fast_pattern only with within */
551  snprintf(string, sizeof(string),
552  "alert tcp any any -> any any "
553  "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%swithin:10; sid:1;)",
554  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
555  s = DetectEngineAppendSig(de_ctx, string);
556  FAIL_IF_NOT_NULL(s);
557  /* fast_pattern only with within */
558  snprintf(string, sizeof(string),
559  "alert tcp any any -> any any "
560  "(content:\"one\"; %s%s content:\"two\"; %s%swithin:10; fast_pattern:only; sid:1;)",
561  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
562  s = DetectEngineAppendSig(de_ctx, string);
563  FAIL_IF_NOT_NULL(s);
564  /* fast_pattern only with offset */
565  snprintf(string, sizeof(string),
566  "alert tcp any any -> any any "
567  "(content:\"one\"; %s%sfast_pattern:only; offset:10; sid:1;)",
568  sticky ? sticky : "", sticky ? "; " : " ");
569  s = DetectEngineAppendSig(de_ctx, string);
570  FAIL_IF_NOT_NULL(s);
571  /* fast_pattern only with offset */
572  snprintf(string, sizeof(string),
573  "alert tcp any any -> any any "
574  "(content:\"one\"; %s%s offset: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 with depth */
579  snprintf(string, sizeof(string),
580  "alert tcp any any -> any any "
581  "(content:\"one\"; %s%sfast_pattern:only; depth:10; sid:1;)",
582  sticky ? sticky : "", sticky ? "; " : " ");
583  s = DetectEngineAppendSig(de_ctx, string);
584  FAIL_IF_NOT_NULL(s);
585  /* fast_pattern only with depth */
586  snprintf(string, sizeof(string),
587  "alert tcp any any -> any any "
588  "(content:\"one\"; %s%s depth:10; fast_pattern:only; sid:1;)",
589  sticky ? sticky : "", sticky ? "; " : " ");
590  s = DetectEngineAppendSig(de_ctx, string);
591  FAIL_IF_NOT_NULL(s);
592  /* fast_pattern only negate */
593  snprintf(string, sizeof(string),
594  "alert tcp any any -> any any "
595  "(content:\"one\"; %s%s content:!\"two\"; %s%sfast_pattern:only; sid:1;)",
596  sticky ? sticky : "", sticky ? "; " : " ", 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:5,6; 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:65977,2; 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:2,65977; sid:1;)",
617  sticky ? sticky : "", sticky ? "; " : " ");
618  s = DetectEngineAppendSig(de_ctx, string);
619  FAIL_IF_NOT_NULL(s);
620  /* fast_pattern chop with invalid values */
621  snprintf(string, sizeof(string),
622  "alert tcp any any -> any any "
623  "(content:\"one\"; %s%sfast_pattern:2,65534; sid:1;)",
624  sticky ? sticky : "", sticky ? "; " : " ");
625  s = DetectEngineAppendSig(de_ctx, string);
626  FAIL_IF_NOT_NULL(s);
627  /* fast_pattern chop with invalid values */
628  snprintf(string, sizeof(string),
629  "alert tcp any any -> any any "
630  "(content:\"one\"; %s%sfast_pattern:65534,2; sid:1;)",
631  sticky ? sticky : "", sticky ? "; " : " ");
632  s = DetectEngineAppendSig(de_ctx, string);
633  FAIL_IF_NOT_NULL(s);
634  /* negated fast_pattern with distance */
635  snprintf(string, sizeof(string),
636  "alert tcp any any -> any any "
637  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdistance: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 within */
642  snprintf(string, sizeof(string),
643  "alert tcp any any -> any any "
644  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%swithin:10; sid:1;)",
645  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
646  s = DetectEngineAppendSig(de_ctx, string);
647  FAIL_IF_NOT_NULL(s);
648  /* negated fast_pattern with depth */
649  snprintf(string, sizeof(string),
650  "alert tcp any any -> any any "
651  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdepth:10; sid:1;)",
652  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
653  s = DetectEngineAppendSig(de_ctx, string);
654  FAIL_IF_NOT_NULL(s);
655  /* negated fast_pattern with offset */
656  snprintf(string, sizeof(string),
657  "alert tcp any any -> any any "
658  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%soffset:10; sid:1;)",
659  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
660  s = DetectEngineAppendSig(de_ctx, string);
661  FAIL_IF_NOT_NULL(s);
663  PASS;
664 }
665 
666 static int DetectFastPatternStickySingleFPOnly(const char *sticky, const int list)
667 {
670  char string[1024];
671  snprintf(string, sizeof(string),
672  "alert tcp any any -> any any "
673  "(%s%scontent:\"one\"; fast_pattern:only; sid:1;)",
674  sticky ? sticky : "", sticky ? "; " : " ");
675  Signature *s = DetectEngineAppendSig(de_ctx, string);
676  FAIL_IF_NULL(s);
677  SigMatch *sm = GetMatches(s, list);
678  FAIL_IF_NULL(sm);
685  PASS;
686 }
687 
688 static int DetectFastPatternModifierFPOnly(const char *sticky, const int list)
689 {
692  char string[1024];
693  snprintf(string, sizeof(string),
694  "alert tcp any any -> any any "
695  "(content:\"one\"; %s%sfast_pattern:only; sid:1;)",
696  sticky ? sticky : "", sticky ? "; " : " ");
697  Signature *s = DetectEngineAppendSig(de_ctx, string);
698  FAIL_IF_NULL(s);
699  SigMatch *sm = GetMatches(s, list);
700  FAIL_IF_NULL(sm);
706 
707  snprintf(string, sizeof(string),
708  "alert tcp any any -> any any "
709  "(content:\"one\"; %s%scontent:\"two\"; %s%sfast_pattern:only; sid:2;)",
710  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
711  s = DetectEngineAppendSig(de_ctx, string);
712  FAIL_IF_NULL(s);
713  sm = GetMatches(s, list);
714  FAIL_IF_NULL(sm);
715  FAIL_IF_NULL(sm->next);
717  cd = (DetectContentData *)sm->ctx;
719  FAIL_IF_NOT(
721  sm = sm->next;
723  cd = (DetectContentData *)sm->ctx;
727 
728  snprintf(string, sizeof(string),
729  "alert tcp any any -> any any "
730  "(content:\"one\"; %s%scontent:\"two\"; distance:10; %s%scontent:\"three\"; "
731  "%s%sfast_pattern:only; sid:3;)",
732  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
733  sticky ? sticky : "", sticky ? "; " : " ");
734  s = DetectEngineAppendSig(de_ctx, string);
735  FAIL_IF_NULL(s);
736  sm = GetMatches(s, list);
737  FAIL_IF_NULL(sm);
738  FAIL_IF_NULL(sm->next);
740  cd = (DetectContentData *)sm->ctx;
742  FAIL_IF_NOT(
744  sm = sm->next;
745  FAIL_IF_NULL(sm->next);
747  cd = (DetectContentData *)sm->ctx;
749  FAIL_IF_NOT(
751  sm = sm->next;
752  FAIL_IF_NOT_NULL(sm->next);
754  cd = (DetectContentData *)sm->ctx;
758 
759  snprintf(string, sizeof(string),
760  "alert tcp any any -> any any "
761  "(content:\"one\"; %s%scontent:\"two\"; within:10; %s%scontent:\"three\"; "
762  "%s%sfast_pattern:only; sid:4;)",
763  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
764  sticky ? sticky : "", sticky ? "; " : " ");
765  s = DetectEngineAppendSig(de_ctx, string);
766  FAIL_IF_NULL(s);
767  sm = GetMatches(s, list);
768  FAIL_IF_NULL(sm);
769  FAIL_IF_NULL(sm->next);
771  cd = (DetectContentData *)sm->ctx;
773  FAIL_IF_NOT(
775  sm = sm->next;
776  FAIL_IF_NULL(sm->next);
778  cd = (DetectContentData *)sm->ctx;
780  FAIL_IF_NOT(
782  sm = sm->next;
783  FAIL_IF_NOT_NULL(sm->next);
785  cd = (DetectContentData *)sm->ctx;
789 
790  snprintf(string, sizeof(string),
791  "alert tcp any any -> any any "
792  "(content:\"one\"; %s%scontent:\"two\"; offset:10; %s%scontent:\"three\"; "
793  "%s%sfast_pattern:only; sid:5;)",
794  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
795  sticky ? sticky : "", sticky ? "; " : " ");
796  s = DetectEngineAppendSig(de_ctx, string);
797  FAIL_IF_NULL(s);
798  sm = GetMatches(s, list);
799  FAIL_IF_NULL(sm);
800  FAIL_IF_NULL(sm->next);
802  cd = (DetectContentData *)sm->ctx;
804  FAIL_IF_NOT(
806  sm = sm->next;
807  FAIL_IF_NULL(sm->next);
809  cd = (DetectContentData *)sm->ctx;
811  FAIL_IF_NOT(
813  sm = sm->next;
814  FAIL_IF_NOT_NULL(sm->next);
816  cd = (DetectContentData *)sm->ctx;
820 
821  snprintf(string, sizeof(string),
822  "alert tcp any any -> any any "
823  "(content:\"one\"; %s%scontent:\"two\"; depth:10; %s%scontent:\"three\"; "
824  "%s%sfast_pattern:only; sid:6;)",
825  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
826  sticky ? sticky : "", sticky ? "; " : " ");
827  s = DetectEngineAppendSig(de_ctx, string);
828  FAIL_IF_NULL(s);
829  sm = GetMatches(s, list);
830  FAIL_IF_NULL(sm);
831  FAIL_IF_NULL(sm->next);
833  cd = (DetectContentData *)sm->ctx;
835  FAIL_IF_NOT(
837  sm = sm->next;
838  FAIL_IF_NULL(sm->next);
840  cd = (DetectContentData *)sm->ctx;
842  FAIL_IF_NOT(
844  sm = sm->next;
845  FAIL_IF_NOT_NULL(sm->next);
847  cd = (DetectContentData *)sm->ctx;
851 
852  snprintf(string, sizeof(string),
853  "alert tcp any any -> any any "
854  "(content:!\"one\"; %s%sfast_pattern; content:\"two\"; depth:10; %s%ssid:7;)",
855  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
856  s = DetectEngineAppendSig(de_ctx, string);
857  FAIL_IF_NULL(s);
858  sm = GetMatches(s, list);
859  FAIL_IF_NULL(sm);
860  FAIL_IF_NULL(sm->next);
862  cd = (DetectContentData *)sm->ctx;
867  sm = sm->next;
868  FAIL_IF_NOT_NULL(sm->next);
870  cd = (DetectContentData *)sm->ctx;
872  FAIL_IF_NOT(
874 
876  PASS;
877 }
878 
879 static int DetectFastPatternStickyFPChop(const char *sticky, const int list)
880 {
883  char string[1024];
884  snprintf(string, sizeof(string),
885  "alert tcp any any -> any any "
886  "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; sid:1;)",
887  sticky ? sticky : "", sticky ? "; " : " ");
888  Signature *s = DetectEngineAppendSig(de_ctx, string);
889  FAIL_IF_NULL(s);
890  SigMatch *sm = GetMatches(s, list);
891  FAIL_IF_NULL(sm);
898  FAIL_IF_NOT(cd->fp_chop_offset == 3);
899  FAIL_IF_NOT(cd->fp_chop_len == 4);
900 
901  snprintf(string, sizeof(string),
902  "alert tcp any any -> any any "
903  "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; content:\"xyz\"; distance:10; sid:2;)",
904  sticky ? sticky : "", sticky ? "; " : " ");
905  s = DetectEngineAppendSig(de_ctx, string);
906  FAIL_IF_NULL(s);
907  sm = GetMatches(s, list);
908  FAIL_IF_NULL(sm);
910  cd = (DetectContentData *)sm->ctx;
915  FAIL_IF_NOT(cd->fp_chop_offset == 3);
916  FAIL_IF_NOT(cd->fp_chop_len == 4);
917 
919  PASS;
920 }
921 
922 static int DetectFastPatternModifierFPChop(const char *sticky, const int list)
923 {
926  char string[1024];
927  snprintf(string, sizeof(string),
928  "alert tcp any any -> any any "
929  "(content:\"onetwothree\"; %s%sfast_pattern:3,4; sid:1;)",
930  sticky ? sticky : "", sticky ? "; " : " ");
931  Signature *s = DetectEngineAppendSig(de_ctx, string);
932  FAIL_IF_NULL(s);
933  SigMatch *sm = GetMatches(s, list);
934  FAIL_IF_NULL(sm);
941  FAIL_IF_NOT(cd->fp_chop_offset == 3);
942  FAIL_IF_NOT(cd->fp_chop_len == 4);
943 
944  snprintf(string, sizeof(string),
945  "alert tcp any any -> any any "
946  "(content:!\"onetwothree\"; %s%sfast_pattern:3,4; sid:2;)",
947  sticky ? sticky : "", sticky ? "; " : " ");
948  s = DetectEngineAppendSig(de_ctx, string);
949  FAIL_IF_NULL(s);
950  sm = GetMatches(s, list);
951  FAIL_IF_NULL(sm);
953  cd = (DetectContentData *)sm->ctx;
960  FAIL_IF_NOT(cd->fp_chop_offset == 3);
961  FAIL_IF_NOT(cd->fp_chop_len == 4);
962 
964  PASS;
965 }
966 
967 /**
968  * \test Checks if a fast_pattern is registered in a Signature
969  */
970 static int DetectFastPatternTest01(void)
971 {
972  FAIL_IF_NOT(DetectFastPatternStickySingle(NULL, DETECT_SM_LIST_PMATCH));
973  FAIL_IF_NOT(DetectFastPatternModifierSingle(NULL, DETECT_SM_LIST_PMATCH));
974  FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(NULL, DETECT_SM_LIST_PMATCH));
975  FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(NULL, DETECT_SM_LIST_PMATCH));
976  FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(NULL));
977  FAIL_IF_NOT(DetectFastPatternModifierBadRules(NULL));
978  FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(NULL, DETECT_SM_LIST_PMATCH));
979  FAIL_IF_NOT(DetectFastPatternModifierFPOnly(NULL, DETECT_SM_LIST_PMATCH));
980  FAIL_IF_NOT(DetectFastPatternStickyFPChop(NULL, DETECT_SM_LIST_PMATCH));
981  FAIL_IF_NOT(DetectFastPatternModifierFPChop(NULL, DETECT_SM_LIST_PMATCH));
982 
983  struct {
984  const char *buffer_name;
985  const char *sb_name;
986  const char *mod_name;
987  } keywords[] = {
988  { "file_data", "file.data", NULL },
989  { "http_uri", "http.uri", "http_uri" },
990  { "http_raw_uri", "http.uri.raw", "http_raw_uri" },
991  { "http_user_agent", "http.user_agent", "http_user_agent" },
992  { "http_header", "http.header", "http_header" },
993  // http_raw_header requires sigs to have a direction
994  //{ "http_raw_header", "http.header.raw", "http_raw_header" },
995  { "http_method", "http.method", "http_method" },
996  { "http_cookie", "http.cookie", "http_cookie" },
997  { "http_host", "http.host", "http_host" },
998  { "http_raw_host", "http.host.raw", "http_raw_host" },
999  { "http_stat_code", "http.stat_code", "http_stat_code" },
1000  { "http_stat_msg", "http.stat_msg", "http_stat_msg" },
1001  { "http_client_body", "http.request_body", "http_client_body" },
1002  { NULL, NULL, NULL },
1003  };
1004 
1005  for (int i = 0; keywords[i].buffer_name != NULL; i++) {
1006  const int list_id = DetectBufferTypeGetByName(keywords[i].buffer_name);
1007  FAIL_IF(list_id == -1);
1008 
1009  const char *k = keywords[i].sb_name;
1010  if (k) {
1011  FAIL_IF_NOT(DetectFastPatternStickySingle(k, list_id));
1012  FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(k, list_id));
1013  FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(k));
1014  FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(k, list_id));
1015  FAIL_IF_NOT(DetectFastPatternStickyFPChop(k, list_id));
1016  }
1017  k = keywords[i].mod_name;
1018  if (k) {
1019  FAIL_IF_NOT(DetectFastPatternModifierSingle(k, list_id));
1020  FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(k, list_id));
1021  FAIL_IF_NOT(DetectFastPatternModifierBadRules(k));
1022  FAIL_IF_NOT(DetectFastPatternModifierFPOnly(k, list_id));
1023  FAIL_IF_NOT(DetectFastPatternModifierFPChop(k, list_id));
1024  }
1025  }
1026 
1027  PASS;
1028 }
1029 
1030 /**
1031  * \test Checks to make sure that other sigs work that should when fast_pattern is inspecting on the
1032  * same payload
1033  *
1034  */
1035 static int DetectFastPatternTest14(void)
1036 {
1037  uint8_t *buf = (uint8_t *)"Dummy is our name. Oh yes. From right here "
1038  "right now, all the way to hangover. right. strings5_imp now here "
1039  "comes our dark knight strings_string5. Yes here is our dark knight";
1040  uint16_t buflen = strlen((char *)buf);
1041  ThreadVars th_v;
1042  DetectEngineThreadCtx *det_ctx = NULL;
1043 
1044  memset(&th_v, 0, sizeof(th_v));
1045  Packet *p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
1046  FAIL_IF_NULL(p);
1047 
1050  de_ctx->flags |= DE_QUIET;
1051 
1053 
1055  "alert tcp any any -> any any "
1056  "(msg:\"fast_pattern test\"; content:\"strings_string5\"; content:\"knight\"; "
1057  "fast_pattern; sid:1;)");
1058  FAIL_IF_NULL(s);
1059 
1061  "alert tcp any any -> any any "
1062  "(msg:\"test different content\"; content:\"Dummy is our name\"; sid:2;)");
1063  FAIL_IF_NULL(s);
1064 
1066  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1067 
1068  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1071 
1072  UTHFreePackets(&p, 1);
1073  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1075  FlowShutdown();
1076  PASS;
1077 }
1078 
1079 /**
1080  * Unittest to check
1081  * - if we assign different content_ids to duplicate patterns, but one of the
1082  * patterns has a fast_pattern chop set.
1083  * - if 2 unique patterns get unique ids.
1084  * - if 2 duplicate patterns, with no chop set get unique ids.
1085  */
1086 static int DetectFastPatternTest671(void)
1087 {
1090  de_ctx->flags |= DE_QUIET;
1091 
1092  Signature *s[6];
1093  s[0] = DetectEngineAppendSig(
1094  de_ctx, "alert tcp any any -> any any (content:\"onetwothreefour\"; sid:1;)");
1095  FAIL_IF_NULL(s[0]);
1096  s[1] = DetectEngineAppendSig(
1097  de_ctx, "alert tcp any any -> any any (content:\"onetwothreefour\"; sid:2;)");
1098  FAIL_IF_NULL(s[1]);
1099  s[2] = DetectEngineAppendSig(
1100  de_ctx, "alert tcp any any -> any any (content:\"uniquepattern\"; sid:3;)");
1101  FAIL_IF_NULL(s[2]);
1103  "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:3,5; sid:4;)");
1104  FAIL_IF_NULL(s[3]);
1105  s[4] = DetectEngineAppendSig(
1106  de_ctx, "alert tcp any any -> any any (content:\"twoth\"; sid:5;)");
1107  FAIL_IF_NULL(s[4]);
1109  "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:0,15; "
1110  "sid:6;)");
1111  FAIL_IF_NULL(s[5]);
1112 
1114 
1116  DetectContentData *cd = (DetectContentData *)smd->ctx;
1117  FAIL_IF(cd->id != 0);
1118 
1119  smd = s[1]->sm_arrays[DETECT_SM_LIST_PMATCH];
1120  cd = (DetectContentData *)smd->ctx;
1121  FAIL_IF(cd->id != 0);
1122 
1123  smd = s[2]->sm_arrays[DETECT_SM_LIST_PMATCH];
1124  cd = (DetectContentData *)smd->ctx;
1125  FAIL_IF(cd->id != 2);
1126 
1127  smd = s[3]->sm_arrays[DETECT_SM_LIST_PMATCH];
1128  cd = (DetectContentData *)smd->ctx;
1129  FAIL_IF(cd->id != 1);
1130 
1131  smd = s[4]->sm_arrays[DETECT_SM_LIST_PMATCH];
1132  cd = (DetectContentData *)smd->ctx;
1133  FAIL_IF(cd->id != 1);
1134 
1135  smd = s[5]->sm_arrays[DETECT_SM_LIST_PMATCH];
1136  cd = (DetectContentData *)smd->ctx;
1137  FAIL_IF(cd->id != 0);
1138 
1140  PASS;
1141 }
1142 
1143 static int DetectFastPatternPrefilter(void)
1144 {
1147  const char *string = "alert tcp any any -> any any "
1148  "(content:\"one\"; prefilter; sid:1;)";
1149  Signature *s = DetectEngineAppendSig(de_ctx, string);
1150  FAIL_IF_NULL(s);
1152  FAIL_IF_NULL(sm);
1158  PASS;
1159 }
1160 
1161 static void DetectFastPatternRegisterTests(void)
1162 {
1163  UtRegisterTest("DetectFastPatternTest01", DetectFastPatternTest01);
1164  UtRegisterTest("DetectFastPatternTest14", DetectFastPatternTest14);
1165  /* Unittest to check
1166  * - if we assign different content_ids to duplicate patterns, but one of the
1167  * patterns has a fast_pattern chop set.
1168  * - if 2 unique patterns get unique ids.
1169  * - if 2 duplicate patterns, with no chop set get unique ids.
1170  */
1171  UtRegisterTest("DetectFastPatternTest671", DetectFastPatternTest671);
1172 
1173  UtRegisterTest("DetectFastPatternPrefilter", DetectFastPatternPrefilter);
1174 }
1175 #endif
util-byte.h
SCFPSupportSMList_
Definition: detect.h:817
SigTableElmt_::url
const char * url
Definition: detect.h:1408
detect-content.h
detect-engine.h
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:119
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:621
DetectContentData_::fp_chop_len
uint16_t fp_chop_len
Definition: detect-content.h:98
SigTableElmt_::desc
const char * desc
Definition: detect.h:1407
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:155
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1395
SCFPSupportSMList_::next
struct SCFPSupportSMList_ * next
Definition: detect.h:820
DetectBufferGetFirstSigMatch
SigMatch * DetectBufferGetFirstSigMatch(const Signature *s, const uint32_t buf_id)
Definition: detect-engine-buffer.c:157
DetectParseRegex
Definition: detect-parse.h:62
SCFPSupportSMList_::list_id
int list_id
Definition: detect.h:818
SigTableElmt_::name
const char * name
Definition: detect.h:1405
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:69
Signature_::alproto
AppProto alproto
Definition: detect.h:652
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
SIG_FLAG_INIT_TXDIR_FAST_TOCLIENT
#define SIG_FLAG_INIT_TXDIR_FAST_TOCLIENT
Definition: detect.h:306
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:80
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:369
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1399
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:908
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:2440
SupportFastPatternForSigMatchTypes
void SupportFastPatternForSigMatchTypes(void)
Registers the keywords(SMs) that should be given fp support.
Definition: detect-fast-pattern.c:142
SIG_FLAG_TXBOTHDIR
#define SIG_FLAG_TXBOTHDIR
Definition: detect.h:250
DE_QUIET
#define DE_QUIET
Definition: detect.h:330
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:365
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:2348
Signature_::sm_arrays
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
Definition: detect.h:710
SignatureInitData_::init_flags
uint32_t init_flags
Definition: detect.h:587
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
Definition: detect-parse.c:3468
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:3414
SigMatchData_
Data needed for Match()
Definition: detect.h:366
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1390
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:1154
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:546
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:18
DetectEngineThreadCtx_
Definition: detect.h:1200
DetectGetLastSMFromMpmLists
SigMatch * DetectGetLastSMFromMpmLists(const DetectEngineCtx *de_ctx, const Signature *s)
get the last SigMatch from lists that support MPM.
Definition: detect-parse.c:603
DETECT_SM_LIST_BASE64_DATA
@ DETECT_SM_LIST_BASE64_DATA
Definition: detect.h:124
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:3594
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:3166
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:361
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:360
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:317
DetectBufferToClient
bool DetectBufferToClient(const DetectEngineCtx *de_ctx, int buf_id, AppProto alproto)
Definition: detect-engine-mpm.c:1067
Signature_::flags
uint32_t flags
Definition: detect.h:648
DetectEngineInitializeFastPatternList
void DetectEngineInitializeFastPatternList(DetectEngineCtx *de_ctx)
Definition: detect-fast-pattern.c:149
Packet_
Definition: decode.h:492
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:726
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:1373
SCFPSupportSMList_::priority
int priority
Definition: detect.h:819
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2130
DetectEngineBufferTypeSupportsMpmGetById
bool DetectEngineBufferTypeSupportsMpmGetById(const DetectEngineCtx *de_ctx, const int id)
Definition: detect-engine.c:1330
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:359
SigMatch_::type
uint16_t type
Definition: detect.h:358
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:690
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
SignatureInitData_::curbuf
SignatureInitDataBuffer * curbuf
Definition: detect.h:629
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
Definition: detect-engine.c:3392
detect-engine-buffer.h
FatalError
#define FatalError(...)
Definition: util-debug.h:502
SIGMATCH_OPTIONAL_OPT
#define SIGMATCH_OPTIONAL_OPT
Definition: detect.h:1607
DetectEngineFreeFastPatternList
void DetectEngineFreeFastPatternList(DetectEngineCtx *de_ctx)
Definition: detect-fast-pattern.c:171
SIG_FLAG_INIT_TXDIR_STREAMING_TOSERVER
#define SIG_FLAG_INIT_TXDIR_STREAMING_TOSERVER
Definition: detect.h:304
HtpBodyChunk_::next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:123
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:839
SCFree
#define SCFree(p)
Definition: util-mem.h:61
Signature_::id
uint32_t id
Definition: detect.h:692
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:516
Signature_
Signature container.
Definition: detect.h:647
SigMatch_
a single match condition for a signature
Definition: detect.h:357
DETECT_SM_LIST_MAX
@ DETECT_SM_LIST_MAX
Definition: detect.h:135
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2401
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:640
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:910
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:1082
DETECT_CONTENT_WITHIN
#define DETECT_CONTENT_WITHIN
Definition: detect-content.h:31
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1397
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:456