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-fast-pattern.h"
34 
35 #include "util-error.h"
36 #include "util-byte.h"
37 #include "util-debug.h"
38 #include "util-unittest.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 list(Signature->sm_lists[]) 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) {
98  if (unlikely(new == NULL))
99  exit(EXIT_FAILURE);
100  memset(new, 0, sizeof(SCFPSupportSMList));
101  new->list_id = list_id;
102  new->priority = priority;
103 
104  *list = new;
105  return;
106  }
107 
109  if (unlikely(new == NULL))
110  exit(EXIT_FAILURE);
111  memset(new, 0, sizeof(SCFPSupportSMList));
112  new->list_id = list_id;
113  new->priority = priority;
114  if (ip == NULL) {
115  new->next = *list;
116  *list = new;
117  } else {
118  new->next = ip->next;
119  ip->next = new;
120  }
121  return;
122 }
123 
124 /**
125  * \brief Lets one add a sm list id to be searched for potential fp supported
126  * keywords later.
127  *
128  * \param list_id SM list id.
129  * \param priority Priority for this list.
130  */
131 void SupportFastPatternForSigMatchList(int list_id, int priority)
132 {
133  Add(&g_fp_support_smlist_list, list_id, priority);
134 }
135 
137 {
138  Add(&de_ctx->fp_support_smlist_list, list_id, priority);
139 }
140 
141 /**
142  * \brief Registers the keywords(SMs) that should be given fp support.
143  */
145 {
147 
148  /* other types are handled by DetectMpmAppLayerRegister() */
149 }
150 
152 {
153  SCFPSupportSMList *last = NULL;
154  for (SCFPSupportSMList *tmp = g_fp_support_smlist_list; tmp != NULL; tmp = tmp->next) {
155  SCFPSupportSMList *n = SCCalloc(1, sizeof(*n));
156  if (n == NULL) {
157  FatalError(SC_ERR_FATAL, "out of memory: %s", strerror(errno));
158  }
159  n->list_id = tmp->list_id;
160  n->priority = tmp->priority;
161 
162  // append
163  if (de_ctx->fp_support_smlist_list == NULL) {
164  last = de_ctx->fp_support_smlist_list = n;
165  } else {
166  BUG_ON(last == NULL);
167  last->next = n;
168  last = n;
169  }
170  }
171 }
172 
174 {
175  for (SCFPSupportSMList *tmp = de_ctx->fp_support_smlist_list; tmp != NULL;) {
176  SCFPSupportSMList *next = tmp->next;
177  SCFree(tmp);
178  tmp = next;
179  }
181 }
182 
183 /**
184  * \brief Registration function for fast_pattern keyword
185  */
187 {
188  sigmatch_table[DETECT_FAST_PATTERN].name = "fast_pattern";
189  sigmatch_table[DETECT_FAST_PATTERN].desc = "force using preceding content in the multi pattern matcher";
190  sigmatch_table[DETECT_FAST_PATTERN].url = "/rules/prefilter-keywords.html#fast-pattern";
192  sigmatch_table[DETECT_FAST_PATTERN].Setup = DetectFastPatternSetup;
194 #ifdef UNITTESTS
195  sigmatch_table[DETECT_FAST_PATTERN].RegisterTests = DetectFastPatternRegisterTests;
196 #endif
198 
199  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
200 }
201 
202 /**
203  * \brief Configures the previous content context for a fast_pattern modifier
204  * keyword used in the rule.
205  *
206  * \param de_ctx Pointer to the Detection Engine Context.
207  * \param s Pointer to the Signature to which the current keyword belongs.
208  * \param arg May hold an argument
209  *
210  * \retval 0 On success.
211  * \retval -1 On failure.
212  */
213 static int DetectFastPatternSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
214 {
215  int ret = 0, res = 0;
216  size_t pcre2len;
217  char arg_substr[128] = "";
218  DetectContentData *cd = NULL;
219 
222  if (pm1 == NULL && pm2 == NULL) {
223  SCLogError(SC_ERR_INVALID_SIGNATURE, "fast_pattern found inside "
224  "the rule, without a content context. Please use a "
225  "content based keyword before using fast_pattern");
226  return -1;
227  }
228 
229  SigMatch *pm = NULL;
230  if (pm1 && pm2) {
231  if (pm1->idx > pm2->idx)
232  pm = pm1;
233  else
234  pm = pm2;
235  } else if (pm1 && !pm2) {
236  pm = pm1;
237  } else {
238  pm = pm2;
239  }
240 
241  cd = (DetectContentData *)pm->ctx;
242  if ((cd->flags & DETECT_CONTENT_NEGATED) &&
243  ((cd->flags & DETECT_CONTENT_DISTANCE) ||
244  (cd->flags & DETECT_CONTENT_WITHIN) ||
245  (cd->flags & DETECT_CONTENT_OFFSET) ||
246  (cd->flags & DETECT_CONTENT_DEPTH))) {
247 
248  /* we can't have any of these if we are having "only" */
249  SCLogError(SC_ERR_INVALID_SIGNATURE, "fast_pattern; cannot be "
250  "used with negated content, along with relative modifiers");
251  goto error;
252  }
253 
254  if (arg == NULL|| strcmp(arg, "") == 0) {
256  SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use multiple fast_pattern "
257  "options for the same content");
258  goto error;
259  }
260  else { /*allow only one content to have fast_pattern modifier*/
261  uint32_t list_id = 0;
262  for (list_id = 0; list_id < s->init_data->smlists_array_size; list_id++) {
263  SigMatch *sm = NULL;
264  for (sm = s->init_data->smlists[list_id]; sm != NULL; sm = sm->next) {
265  if (sm->type == DETECT_CONTENT) {
266  DetectContentData *tmp_cd = (DetectContentData *)sm->ctx;
267  if (tmp_cd->flags & DETECT_CONTENT_FAST_PATTERN) {
268  SCLogError(SC_ERR_INVALID_SIGNATURE, "fast_pattern "
269  "can be used on only one content in a rule");
270  goto error;
271  }
272  }
273  } /* for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) */
274  }
275  }
277  return 0;
278  }
279 
280  /* Execute the regex and populate args with captures. */
281  ret = DetectParsePcreExec(&parse_regex, arg, 0, 0);
282  /* fast pattern only */
283  if (ret == 2) {
284  if ((cd->flags & DETECT_CONTENT_NEGATED) ||
285  (cd->flags & DETECT_CONTENT_DISTANCE) ||
286  (cd->flags & DETECT_CONTENT_WITHIN) ||
287  (cd->flags & DETECT_CONTENT_OFFSET) ||
288  (cd->flags & DETECT_CONTENT_DEPTH)) {
289 
290  /* we can't have any of these if we are having "only" */
291  SCLogError(SC_ERR_INVALID_SIGNATURE, "fast_pattern: only; cannot be "
292  "used with negated content or with any of the relative "
293  "modifiers like distance, within, offset, depth");
294  goto error;
295  }
297 
298  /* fast pattern chop */
299  } else if (ret == 4) {
300  pcre2len = sizeof(arg_substr);
301  res = pcre2_substring_copy_bynumber(
302  parse_regex.match, 2, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
303  if (res < 0) {
304  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_copy_bynumber failed "
305  "for fast_pattern offset");
306  goto error;
307  }
308  uint16_t offset;
309  if (StringParseUint16(&offset, 10, 0,
310  (const char *)arg_substr) < 0) {
311  SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid fast pattern offset:"
312  " \"%s\"", arg_substr);
313  goto error;
314  }
315 
316  pcre2len = sizeof(arg_substr);
317  res = pcre2_substring_copy_bynumber(
318  parse_regex.match, 3, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
319  if (res < 0) {
320  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_copy_bynumber failed "
321  "for fast_pattern offset");
322  goto error;
323  }
324  uint16_t length;
325  if (StringParseUint16(&length, 10, 0,
326  (const char *)arg_substr) < 0) {
327  SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid value for fast "
328  "pattern: \"%s\"", arg_substr);
329  goto error;
330  }
331 
332  // Avoiding integer overflow
333  if (offset > (65535 - length)) {
334  SCLogError(SC_ERR_INVALID_SIGNATURE, "Fast pattern (length + offset) "
335  "exceeds limit pattern length limit");
336  goto error;
337  }
338 
339  if (offset + length > cd->content_len) {
340  SCLogError(SC_ERR_INVALID_SIGNATURE, "Fast pattern (length + "
341  "offset (%u)) exceeds pattern length (%u)",
342  offset + length, cd->content_len);
343  goto error;
344  }
345 
346  cd->fp_chop_offset = offset;
347  cd->fp_chop_len = length;
349 
350  } else {
351  SCLogError(SC_ERR_PCRE_PARSE, "parse error, ret %" PRId32
352  ", string %s", ret, arg);
353  goto error;
354  }
355 
357 
358  return 0;
359 
360  error:
361  return -1;
362 }
363 
364 /*----------------------------------Unittests---------------------------------*/
365 
366 #ifdef UNITTESTS
367 static int DetectFastPatternStickySingle(const char *sticky, const int list)
368 {
371  char string[1024];
372  snprintf(string, sizeof(string),
373  "alert tcp any any -> any any "
374  "(%s%scontent:\"one\"; fast_pattern; sid:1;)",
375  sticky ? sticky : "", sticky ? "; " : " ");
376  Signature *s = DetectEngineAppendSig(de_ctx, string);
377  FAIL_IF_NULL(s);
378  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
379  FAIL_IF_NULL(sm);
385  PASS;
386 }
387 
388 static int DetectFastPatternModifierSingle(const char *sticky, const int list)
389 {
392  char string[1024];
393  snprintf(string, sizeof(string),
394  "alert tcp any any -> any any "
395  "(content:\"one\"; %s%sfast_pattern; sid:1;)",
396  sticky ? sticky : "", sticky ? "; " : " ");
397  Signature *s = DetectEngineAppendSig(de_ctx, string);
398  FAIL_IF_NULL(s);
399  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
400  FAIL_IF_NULL(sm);
406  PASS;
407 }
408 
409 static int DetectFastPatternStickySingleNoFP(const char *sticky, const int list)
410 {
413  char string[1024];
414  snprintf(string, sizeof(string),
415  "alert tcp any any -> any any "
416  "(%s%scontent:\"one\"; sid:1;)",
417  sticky ? sticky : "", sticky ? "; " : " ");
418  Signature *s = DetectEngineAppendSig(de_ctx, string);
419  FAIL_IF_NULL(s);
420  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
421  FAIL_IF_NULL(sm);
427  PASS;
428 }
429 
430 static int DetectFastPatternModifierSingleNoFP(const char *sticky, const int list)
431 {
434  char string[1024];
435  snprintf(string, sizeof(string),
436  "alert tcp any any -> any any "
437  "(content:\"one\"; %s%ssid:1;)",
438  sticky ? sticky : "", sticky ? "; " : " ");
439  Signature *s = DetectEngineAppendSig(de_ctx, string);
440  FAIL_IF_NULL(s);
441  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
442  FAIL_IF_NULL(sm);
448  PASS;
449 }
450 
451 static int DetectFastPatternStickySingleBadArg(const char *sticky)
452 {
455  char string[1024];
456  /* bogus argument to fast_pattern */
457  snprintf(string, sizeof(string),
458  "alert tcp any any -> any any "
459  "(%s%scontent:\"one\"; fast_pattern:boo; sid:1;)",
460  sticky ? sticky : "", sticky ? "; " : " ");
461  Signature *s = DetectEngineAppendSig(de_ctx, string);
462  FAIL_IF_NOT_NULL(s);
463  /* fast_pattern only with distance */
464  snprintf(string, sizeof(string),
465  "alert tcp any any -> any any "
466  "(%s%scontent:\"one\"; fast_pattern:only; content:\"two\"; distance:10; sid:1;)",
467  sticky ? sticky : "", sticky ? "; " : " ");
468  s = DetectEngineAppendSig(de_ctx, string);
469  FAIL_IF_NOT_NULL(s);
470  /* fast_pattern only with distance */
471  snprintf(string, sizeof(string),
472  "alert tcp any any -> any any "
473  "(%s%scontent:\"one\"; content:\"two\"; fast_pattern:only; distance:10; sid:1;)",
474  sticky ? sticky : "", sticky ? "; " : " ");
475  s = DetectEngineAppendSig(de_ctx, string);
476  FAIL_IF_NOT_NULL(s);
477  /* fast_pattern only with distance */
478  snprintf(string, sizeof(string),
479  "alert tcp any any -> any any "
480  "(%s%scontent:\"one\"; content:\"two\"; distance:10; fast_pattern:only; sid:1;)",
481  sticky ? sticky : "", sticky ? "; " : " ");
482  s = DetectEngineAppendSig(de_ctx, string);
483  FAIL_IF_NOT_NULL(s);
484  /* fast_pattern chop with invalid values */
485  snprintf(string, sizeof(string),
486  "alert tcp any any -> any any "
487  "(%s%scontent:\"one\"; fast_pattern:5,6; sid:1;)",
488  sticky ? sticky : "", sticky ? "; " : " ");
489  s = DetectEngineAppendSig(de_ctx, string);
490  FAIL_IF_NOT_NULL(s);
492  PASS;
493 }
494 
495 static int DetectFastPatternModifierBadRules(const char *sticky)
496 {
499  char string[1024];
500  /* bogus argument to fast_pattern */
501  snprintf(string, sizeof(string),
502  "alert tcp any any -> any any "
503  "(content:\"one\"; %s%sfast_pattern:boo; sid:1;)",
504  sticky ? sticky : "", sticky ? "; " : " ");
505  Signature *s = DetectEngineAppendSig(de_ctx, string);
506  FAIL_IF_NOT_NULL(s);
507  /* fast_pattern only with distance */
508  snprintf(string, sizeof(string),
509  "alert tcp any any -> any any "
510  "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%sdistance:10; sid:1;)",
511  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
512  s = DetectEngineAppendSig(de_ctx, string);
513  FAIL_IF_NOT_NULL(s);
514 #if 0 // TODO bug?
515  /* fast_pattern only with distance */
516  snprintf(string, sizeof(string), "alert tcp any any -> any any "
517  "(content:\"one\"; %s%s content:\"two\"; %s%sdistance:10; fast_pattern:only; sid:1;)",
518  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
519  s = DetectEngineAppendSig(de_ctx, string);
520  FAIL_IF_NOT_NULL(s);
521 #endif
522  /* fast_pattern only with within */
523  snprintf(string, sizeof(string),
524  "alert tcp any any -> any any "
525  "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%swithin:10; sid:1;)",
526  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
527  s = DetectEngineAppendSig(de_ctx, string);
528  FAIL_IF_NOT_NULL(s);
529  /* fast_pattern only with within */
530  snprintf(string, sizeof(string),
531  "alert tcp any any -> any any "
532  "(content:\"one\"; %s%s content:\"two\"; %s%swithin:10; fast_pattern:only; sid:1;)",
533  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
534  s = DetectEngineAppendSig(de_ctx, string);
535  FAIL_IF_NOT_NULL(s);
536  /* fast_pattern only with offset */
537  snprintf(string, sizeof(string),
538  "alert tcp any any -> any any "
539  "(content:\"one\"; %s%sfast_pattern:only; offset:10; sid:1;)",
540  sticky ? sticky : "", sticky ? "; " : " ");
541  s = DetectEngineAppendSig(de_ctx, string);
542  FAIL_IF_NOT_NULL(s);
543  /* fast_pattern only with offset */
544  snprintf(string, sizeof(string),
545  "alert tcp any any -> any any "
546  "(content:\"one\"; %s%s offset:10; fast_pattern:only; sid:1;)",
547  sticky ? sticky : "", sticky ? "; " : " ");
548  s = DetectEngineAppendSig(de_ctx, string);
549  FAIL_IF_NOT_NULL(s);
550  /* fast_pattern only with depth */
551  snprintf(string, sizeof(string),
552  "alert tcp any any -> any any "
553  "(content:\"one\"; %s%sfast_pattern:only; depth:10; sid:1;)",
554  sticky ? sticky : "", sticky ? "; " : " ");
555  s = DetectEngineAppendSig(de_ctx, string);
556  FAIL_IF_NOT_NULL(s);
557  /* fast_pattern only with depth */
558  snprintf(string, sizeof(string),
559  "alert tcp any any -> any any "
560  "(content:\"one\"; %s%s depth:10; fast_pattern:only; sid:1;)",
561  sticky ? sticky : "", sticky ? "; " : " ");
562  s = DetectEngineAppendSig(de_ctx, string);
563  FAIL_IF_NOT_NULL(s);
564  /* fast_pattern only negate */
565  snprintf(string, sizeof(string),
566  "alert tcp any any -> any any "
567  "(content:\"one\"; %s%s content:!\"two\"; %s%sfast_pattern:only; sid:1;)",
568  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
569  s = DetectEngineAppendSig(de_ctx, string);
570  FAIL_IF_NOT_NULL(s);
571  /* fast_pattern chop with invalid values */
572  snprintf(string, sizeof(string),
573  "alert tcp any any -> any any "
574  "(content:\"one\"; %s%sfast_pattern:5,6; sid:1;)",
575  sticky ? sticky : "", sticky ? "; " : " ");
576  s = DetectEngineAppendSig(de_ctx, string);
577  FAIL_IF_NOT_NULL(s);
578  /* fast_pattern chop with invalid values */
579  snprintf(string, sizeof(string),
580  "alert tcp any any -> any any "
581  "(content:\"one\"; %s%sfast_pattern:65977,2; sid:1;)",
582  sticky ? sticky : "", sticky ? "; " : " ");
583  s = DetectEngineAppendSig(de_ctx, string);
584  FAIL_IF_NOT_NULL(s);
585  /* fast_pattern chop with invalid values */
586  snprintf(string, sizeof(string),
587  "alert tcp any any -> any any "
588  "(content:\"one\"; %s%sfast_pattern:2,65977; sid:1;)",
589  sticky ? sticky : "", sticky ? "; " : " ");
590  s = DetectEngineAppendSig(de_ctx, string);
591  FAIL_IF_NOT_NULL(s);
592  /* fast_pattern chop with invalid values */
593  snprintf(string, sizeof(string),
594  "alert tcp any any -> any any "
595  "(content:\"one\"; %s%sfast_pattern:2,65534; sid:1;)",
596  sticky ? sticky : "", sticky ? "; " : " ");
597  s = DetectEngineAppendSig(de_ctx, string);
598  FAIL_IF_NOT_NULL(s);
599  /* fast_pattern chop with invalid values */
600  snprintf(string, sizeof(string),
601  "alert tcp any any -> any any "
602  "(content:\"one\"; %s%sfast_pattern:65534,2; sid:1;)",
603  sticky ? sticky : "", sticky ? "; " : " ");
604  s = DetectEngineAppendSig(de_ctx, string);
605  FAIL_IF_NOT_NULL(s);
606  /* negated fast_pattern with distance */
607  snprintf(string, sizeof(string),
608  "alert tcp any any -> any any "
609  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdistance:10; sid:1;)",
610  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
611  s = DetectEngineAppendSig(de_ctx, string);
612  FAIL_IF_NOT_NULL(s);
613  /* negated fast_pattern with within */
614  snprintf(string, sizeof(string),
615  "alert tcp any any -> any any "
616  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%swithin:10; sid:1;)",
617  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
618  s = DetectEngineAppendSig(de_ctx, string);
619  FAIL_IF_NOT_NULL(s);
620  /* negated fast_pattern with depth */
621  snprintf(string, sizeof(string),
622  "alert tcp any any -> any any "
623  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdepth:10; sid:1;)",
624  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
625  s = DetectEngineAppendSig(de_ctx, string);
626  FAIL_IF_NOT_NULL(s);
627  /* negated fast_pattern with offset */
628  snprintf(string, sizeof(string),
629  "alert tcp any any -> any any "
630  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%soffset:10; sid:1;)",
631  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
632  s = DetectEngineAppendSig(de_ctx, string);
633  FAIL_IF_NOT_NULL(s);
635  PASS;
636 }
637 
638 static int DetectFastPatternStickySingleFPOnly(const char *sticky, const int list)
639 {
642  char string[1024];
643  snprintf(string, sizeof(string),
644  "alert tcp any any -> any any "
645  "(%s%scontent:\"one\"; fast_pattern:only; sid:1;)",
646  sticky ? sticky : "", sticky ? "; " : " ");
647  Signature *s = DetectEngineAppendSig(de_ctx, string);
648  FAIL_IF_NULL(s);
649  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
650  FAIL_IF_NULL(sm);
657  PASS;
658 }
659 
660 static int DetectFastPatternModifierFPOnly(const char *sticky, const int list)
661 {
664  char string[1024];
665  snprintf(string, sizeof(string),
666  "alert tcp any any -> any any "
667  "(content:\"one\"; %s%sfast_pattern:only; sid:1;)",
668  sticky ? sticky : "", sticky ? "; " : " ");
669  Signature *s = DetectEngineAppendSig(de_ctx, string);
670  FAIL_IF_NULL(s);
671  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
672  FAIL_IF_NULL(sm);
678 
679  snprintf(string, sizeof(string),
680  "alert tcp any any -> any any "
681  "(content:\"one\"; %s%scontent:\"two\"; %s%sfast_pattern:only; sid:2;)",
682  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
683  s = DetectEngineAppendSig(de_ctx, string);
684  FAIL_IF_NULL(s);
685  sm = de_ctx->sig_list->sm_lists[list];
686  FAIL_IF_NULL(sm);
687  FAIL_IF_NULL(sm->next);
689  cd = (DetectContentData *)sm->ctx;
691  FAIL_IF_NOT(
693  sm = sm->next;
695  cd = (DetectContentData *)sm->ctx;
699 
700  snprintf(string, sizeof(string),
701  "alert tcp any any -> any any "
702  "(content:\"one\"; %s%scontent:\"two\"; distance:10; %s%scontent:\"three\"; "
703  "%s%sfast_pattern:only; sid:3;)",
704  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
705  sticky ? sticky : "", sticky ? "; " : " ");
706  s = DetectEngineAppendSig(de_ctx, string);
707  FAIL_IF_NULL(s);
708  sm = de_ctx->sig_list->sm_lists[list];
709  FAIL_IF_NULL(sm);
710  FAIL_IF_NULL(sm->next);
712  cd = (DetectContentData *)sm->ctx;
714  FAIL_IF_NOT(
716  sm = sm->next;
717  FAIL_IF_NULL(sm->next);
719  cd = (DetectContentData *)sm->ctx;
721  FAIL_IF_NOT(
723  sm = sm->next;
724  FAIL_IF_NOT_NULL(sm->next);
726  cd = (DetectContentData *)sm->ctx;
730 
731  snprintf(string, sizeof(string),
732  "alert tcp any any -> any any "
733  "(content:\"one\"; %s%scontent:\"two\"; within:10; %s%scontent:\"three\"; "
734  "%s%sfast_pattern:only; sid:4;)",
735  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
736  sticky ? sticky : "", sticky ? "; " : " ");
737  s = DetectEngineAppendSig(de_ctx, string);
738  FAIL_IF_NULL(s);
739  sm = de_ctx->sig_list->sm_lists[list];
740  FAIL_IF_NULL(sm);
741  FAIL_IF_NULL(sm->next);
743  cd = (DetectContentData *)sm->ctx;
745  FAIL_IF_NOT(
747  sm = sm->next;
748  FAIL_IF_NULL(sm->next);
750  cd = (DetectContentData *)sm->ctx;
752  FAIL_IF_NOT(
754  sm = sm->next;
755  FAIL_IF_NOT_NULL(sm->next);
757  cd = (DetectContentData *)sm->ctx;
761 
762  snprintf(string, sizeof(string),
763  "alert tcp any any -> any any "
764  "(content:\"one\"; %s%scontent:\"two\"; offset:10; %s%scontent:\"three\"; "
765  "%s%sfast_pattern:only; sid:5;)",
766  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
767  sticky ? sticky : "", sticky ? "; " : " ");
768  s = DetectEngineAppendSig(de_ctx, string);
769  FAIL_IF_NULL(s);
770  sm = de_ctx->sig_list->sm_lists[list];
771  FAIL_IF_NULL(sm);
772  FAIL_IF_NULL(sm->next);
774  cd = (DetectContentData *)sm->ctx;
776  FAIL_IF_NOT(
778  sm = sm->next;
779  FAIL_IF_NULL(sm->next);
781  cd = (DetectContentData *)sm->ctx;
783  FAIL_IF_NOT(
785  sm = sm->next;
786  FAIL_IF_NOT_NULL(sm->next);
788  cd = (DetectContentData *)sm->ctx;
792 
793  snprintf(string, sizeof(string),
794  "alert tcp any any -> any any "
795  "(content:\"one\"; %s%scontent:\"two\"; depth:10; %s%scontent:\"three\"; "
796  "%s%sfast_pattern:only; sid:6;)",
797  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
798  sticky ? sticky : "", sticky ? "; " : " ");
799  s = DetectEngineAppendSig(de_ctx, string);
800  FAIL_IF_NULL(s);
801  sm = de_ctx->sig_list->sm_lists[list];
802  FAIL_IF_NULL(sm);
803  FAIL_IF_NULL(sm->next);
805  cd = (DetectContentData *)sm->ctx;
807  FAIL_IF_NOT(
809  sm = sm->next;
810  FAIL_IF_NULL(sm->next);
812  cd = (DetectContentData *)sm->ctx;
814  FAIL_IF_NOT(
816  sm = sm->next;
817  FAIL_IF_NOT_NULL(sm->next);
819  cd = (DetectContentData *)sm->ctx;
823 
824  snprintf(string, sizeof(string),
825  "alert tcp any any -> any any "
826  "(content:!\"one\"; %s%sfast_pattern; content:\"two\"; depth:10; %s%ssid:7;)",
827  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
828  s = DetectEngineAppendSig(de_ctx, string);
829  FAIL_IF_NULL(s);
830  sm = de_ctx->sig_list->sm_lists[list];
831  FAIL_IF_NULL(sm);
832  FAIL_IF_NULL(sm->next);
834  cd = (DetectContentData *)sm->ctx;
839  sm = sm->next;
840  FAIL_IF_NOT_NULL(sm->next);
842  cd = (DetectContentData *)sm->ctx;
844  FAIL_IF_NOT(
846 
848  PASS;
849 }
850 
851 static int DetectFastPatternStickyFPChop(const char *sticky, const int list)
852 {
855  char string[1024];
856  snprintf(string, sizeof(string),
857  "alert tcp any any -> any any "
858  "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; sid:1;)",
859  sticky ? sticky : "", sticky ? "; " : " ");
860  Signature *s = DetectEngineAppendSig(de_ctx, string);
861  FAIL_IF_NULL(s);
862  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
863  FAIL_IF_NULL(sm);
870  FAIL_IF_NOT(cd->fp_chop_offset == 3);
871  FAIL_IF_NOT(cd->fp_chop_len == 4);
872 
873  snprintf(string, sizeof(string),
874  "alert tcp any any -> any any "
875  "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; content:\"xyz\"; distance:10; sid:2;)",
876  sticky ? sticky : "", sticky ? "; " : " ");
877  s = DetectEngineAppendSig(de_ctx, string);
878  FAIL_IF_NULL(s);
879  sm = de_ctx->sig_list->sm_lists[list];
880  FAIL_IF_NULL(sm);
882  cd = (DetectContentData *)sm->ctx;
887  FAIL_IF_NOT(cd->fp_chop_offset == 3);
888  FAIL_IF_NOT(cd->fp_chop_len == 4);
889 
891  PASS;
892 }
893 
894 static int DetectFastPatternModifierFPChop(const char *sticky, const int list)
895 {
898  char string[1024];
899  snprintf(string, sizeof(string),
900  "alert tcp any any -> any any "
901  "(content:\"onetwothree\"; %s%sfast_pattern:3,4; sid:1;)",
902  sticky ? sticky : "", sticky ? "; " : " ");
903  Signature *s = DetectEngineAppendSig(de_ctx, string);
904  FAIL_IF_NULL(s);
905  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
906  FAIL_IF_NULL(sm);
913  FAIL_IF_NOT(cd->fp_chop_offset == 3);
914  FAIL_IF_NOT(cd->fp_chop_len == 4);
915 
916  snprintf(string, sizeof(string),
917  "alert tcp any any -> any any "
918  "(content:!\"onetwothree\"; %s%sfast_pattern:3,4; sid:2;)",
919  sticky ? sticky : "", sticky ? "; " : " ");
920  s = DetectEngineAppendSig(de_ctx, string);
921  FAIL_IF_NULL(s);
922  sm = de_ctx->sig_list->sm_lists[list];
923  FAIL_IF_NULL(sm);
925  cd = (DetectContentData *)sm->ctx;
932  FAIL_IF_NOT(cd->fp_chop_offset == 3);
933  FAIL_IF_NOT(cd->fp_chop_len == 4);
934 
936  PASS;
937 }
938 
939 /**
940  * \test Checks if a fast_pattern is registered in a Signature
941  */
942 static int DetectFastPatternTest01(void)
943 {
944  FAIL_IF_NOT(DetectFastPatternStickySingle(NULL, DETECT_SM_LIST_PMATCH));
945  FAIL_IF_NOT(DetectFastPatternModifierSingle(NULL, DETECT_SM_LIST_PMATCH));
946  FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(NULL, DETECT_SM_LIST_PMATCH));
947  FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(NULL, DETECT_SM_LIST_PMATCH));
948  FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(NULL));
949  FAIL_IF_NOT(DetectFastPatternModifierBadRules(NULL));
950  FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(NULL, DETECT_SM_LIST_PMATCH));
951  FAIL_IF_NOT(DetectFastPatternModifierFPOnly(NULL, DETECT_SM_LIST_PMATCH));
952  FAIL_IF_NOT(DetectFastPatternStickyFPChop(NULL, DETECT_SM_LIST_PMATCH));
953  FAIL_IF_NOT(DetectFastPatternModifierFPChop(NULL, DETECT_SM_LIST_PMATCH));
954 
955  struct {
956  const char *buffer_name;
957  const char *sb_name;
958  const char *mod_name;
959  } keywords[] = {
960  { "file_data", "file.data", NULL },
961  { "http_uri", "http.uri", "http_uri" },
962  { "http_raw_uri", "http.uri.raw", "http_raw_uri" },
963  { "http_user_agent", "http.user_agent", "http_user_agent" },
964  { "http_header", "http.header", "http_header" },
965  // http_raw_header requires sigs to have a direction
966  //{ "http_raw_header", "http.header.raw", "http_raw_header" },
967  { "http_method", "http.method", "http_method" },
968  { "http_cookie", "http.cookie", "http_cookie" },
969  { "http_host", "http.host", "http_host" },
970  { "http_raw_host", "http.host.raw", "http_raw_host" },
971  { "http_stat_code", "http.stat_code", "http_stat_code" },
972  { "http_stat_msg", "http.stat_msg", "http_stat_msg" },
973  { "http_client_body", "http.request_body", "http_client_body" },
974  { NULL, NULL, NULL },
975  };
976 
977  for (int i = 0; keywords[i].buffer_name != NULL; i++) {
978  const int list_id = DetectBufferTypeGetByName(keywords[i].buffer_name);
979  FAIL_IF(list_id == -1);
980 
981  const char *k = keywords[i].sb_name;
982  if (k) {
983  FAIL_IF_NOT(DetectFastPatternStickySingle(k, list_id));
984  FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(k, list_id));
985  FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(k));
986  FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(k, list_id));
987  FAIL_IF_NOT(DetectFastPatternStickyFPChop(k, list_id));
988  }
989  k = keywords[i].mod_name;
990  if (k) {
991  FAIL_IF_NOT(DetectFastPatternModifierSingle(k, list_id));
992  FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(k, list_id));
993  FAIL_IF_NOT(DetectFastPatternModifierBadRules(k));
994  FAIL_IF_NOT(DetectFastPatternModifierFPOnly(k, list_id));
995  FAIL_IF_NOT(DetectFastPatternModifierFPChop(k, list_id));
996  }
997  }
998 
999  PASS;
1000 }
1001 
1002 /**
1003  * \test Checks to make sure that other sigs work that should when fast_pattern is inspecting on the
1004  * same payload
1005  *
1006  */
1007 static int DetectFastPatternTest14(void)
1008 {
1009  uint8_t *buf = (uint8_t *)"Dummy is our name. Oh yes. From right here "
1010  "right now, all the way to hangover. right. strings5_imp now here "
1011  "comes our dark knight strings_string5. Yes here is our dark knight";
1012  uint16_t buflen = strlen((char *)buf);
1013  ThreadVars th_v;
1014  DetectEngineThreadCtx *det_ctx = NULL;
1015 
1016  memset(&th_v, 0, sizeof(th_v));
1017  Packet *p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
1018  FAIL_IF_NULL(p);
1019 
1022  de_ctx->flags |= DE_QUIET;
1023 
1025 
1027  "alert tcp any any -> any any "
1028  "(msg:\"fast_pattern test\"; content:\"strings_string5\"; content:\"knight\"; "
1029  "fast_pattern; sid:1;)");
1030  FAIL_IF_NULL(s);
1031 
1033  "alert tcp any any -> any any "
1034  "(msg:\"test different content\"; content:\"Dummy is our name\"; sid:2;)");
1035  FAIL_IF_NULL(s);
1036 
1038  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1039 
1040  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1043 
1044  UTHFreePackets(&p, 1);
1045  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1047  FlowShutdown();
1048  PASS;
1049 }
1050 
1051 /**
1052  * Unittest to check
1053  * - if we assign different content_ids to duplicate patterns, but one of the
1054  * patterns has a fast_pattern chop set.
1055  * - if 2 unique patterns get unique ids.
1056  * - if 2 duplicate patterns, with no chop set get unique ids.
1057  */
1058 static int DetectFastPatternTest671(void)
1059 {
1062  de_ctx->flags |= DE_QUIET;
1063 
1064  Signature *s[6];
1065  s[0] = DetectEngineAppendSig(
1066  de_ctx, "alert tcp any any -> any any (content:\"onetwothreefour\"; sid:1;)");
1067  FAIL_IF_NULL(s[0]);
1068  s[1] = DetectEngineAppendSig(
1069  de_ctx, "alert tcp any any -> any any (content:\"onetwothreefour\"; sid:2;)");
1070  FAIL_IF_NULL(s[1]);
1071  s[2] = DetectEngineAppendSig(
1072  de_ctx, "alert tcp any any -> any any (content:\"uniquepattern\"; sid:3;)");
1073  FAIL_IF_NULL(s[2]);
1075  "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:3,5; sid:4;)");
1076  FAIL_IF_NULL(s[3]);
1077  s[4] = DetectEngineAppendSig(
1078  de_ctx, "alert tcp any any -> any any (content:\"twoth\"; sid:5;)");
1079  FAIL_IF_NULL(s[4]);
1081  "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:0,15; "
1082  "sid:6;)");
1083  FAIL_IF_NULL(s[5]);
1084 
1086 
1088  DetectContentData *cd = (DetectContentData *)smd->ctx;
1089  FAIL_IF(cd->id != 0);
1090 
1091  smd = s[1]->sm_arrays[DETECT_SM_LIST_PMATCH];
1092  cd = (DetectContentData *)smd->ctx;
1093  FAIL_IF(cd->id != 0);
1094 
1095  smd = s[2]->sm_arrays[DETECT_SM_LIST_PMATCH];
1096  cd = (DetectContentData *)smd->ctx;
1097  FAIL_IF(cd->id != 2);
1098 
1099  smd = s[3]->sm_arrays[DETECT_SM_LIST_PMATCH];
1100  cd = (DetectContentData *)smd->ctx;
1101  FAIL_IF(cd->id != 1);
1102 
1103  smd = s[4]->sm_arrays[DETECT_SM_LIST_PMATCH];
1104  cd = (DetectContentData *)smd->ctx;
1105  FAIL_IF(cd->id != 1);
1106 
1107  smd = s[5]->sm_arrays[DETECT_SM_LIST_PMATCH];
1108  cd = (DetectContentData *)smd->ctx;
1109  FAIL_IF(cd->id != 0);
1110 
1112  PASS;
1113 }
1114 
1115 static int DetectFastPatternPrefilter(void)
1116 {
1119  const char *string = "alert tcp any any -> any any "
1120  "(content:\"one\"; prefilter; sid:1;)";
1121  Signature *s = DetectEngineAppendSig(de_ctx, string);
1122  FAIL_IF_NULL(s);
1123  SigMatch *sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH];
1124  FAIL_IF_NULL(sm);
1130  PASS;
1131 }
1132 
1133 static void DetectFastPatternRegisterTests(void)
1134 {
1135  UtRegisterTest("DetectFastPatternTest01", DetectFastPatternTest01);
1136  UtRegisterTest("DetectFastPatternTest14", DetectFastPatternTest14);
1137  /* Unittest to check
1138  * - if we assign different content_ids to duplicate patterns, but one of the
1139  * patterns has a fast_pattern chop set.
1140  * - if 2 unique patterns get unique ids.
1141  * - if 2 duplicate patterns, with no chop set get unique ids.
1142  */
1143  UtRegisterTest("DetectFastPatternTest671", DetectFastPatternTest671);
1144 
1145  UtRegisterTest("DetectFastPatternPrefilter", DetectFastPatternPrefilter);
1146 }
1147 #endif
util-byte.h
SCFPSupportSMList_
Definition: detect.h:708
DetectParseRegex::match
pcre2_match_data * match
Definition: detect-parse.h:45
SigTableElmt_::url
const char * url
Definition: detect.h:1253
detect-content.h
detect-engine.h
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:90
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
DetectContentData_::fp_chop_len
uint16_t fp_chop_len
Definition: detect-content.h:91
SigTableElmt_::desc
const char * desc
Definition: detect.h:1252
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, const char *str, int start_offset, int options)
Definition: detect-parse.c:2475
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1240
SCFPSupportSMList_::next
struct SCFPSupportSMList_ * next
Definition: detect.h:711
DetectParseRegex
Definition: detect-parse.h:42
SCFPSupportSMList_::list_id
int list_id
Definition: detect.h:709
SigTableElmt_::name
const char * name
Definition: detect.h:1250
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:60
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
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:137
DETECT_FAST_PATTERN
@ DETECT_FAST_PATTERN
Definition: detect-engine-register.h:71
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:335
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1244
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:794
StringParseUint16
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:336
SC_ERR_INVALID_SIGNATURE
@ SC_ERR_INVALID_SIGNATURE
Definition: util-error.h:69
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2439
SupportFastPatternForSigMatchTypes
void SupportFastPatternForSigMatchTypes(void)
Registers the keywords(SMs) that should be given fp support.
Definition: detect-fast-pattern.c:144
DE_QUIET
#define DE_QUIET
Definition: detect.h:297
UTHBuildPacket
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
Definition: util-unittest-helper.c:337
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1782
Signature_::sm_arrays
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
Definition: detect.h:604
DetectContentData_
Definition: detect-content.h:86
SC_ERR_PCRE_GET_SUBSTRING
@ SC_ERR_PCRE_GET_SUBSTRING
Definition: util-error.h:34
DetectContentData_::fp_chop_offset
uint16_t fp_chop_offset
Definition: detect-content.h:93
SigMatchData_
Data needed for Match()
Definition: detect.h:332
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1235
DetectEngineRegisterFastPatternForId
void DetectEngineRegisterFastPatternForId(DetectEngineCtx *de_ctx, int list_id, int priority)
Definition: detect-fast-pattern.c:136
PARSE_REGEX
#define PARSE_REGEX
Definition: detect-fast-pattern.c:41
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:1084
SC_ERR_PCRE_PARSE
@ SC_ERR_PCRE_PARSE
Definition: util-error.h:37
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:523
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
util-error.h
DETECT_CONTENT_DISTANCE
#define DETECT_CONTENT_DISTANCE
Definition: detect-content.h:30
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1043
DetectGetLastSMFromMpmLists
SigMatch * DetectGetLastSMFromMpmLists(const DetectEngineCtx *de_ctx, const Signature *s)
get the last SigMatch from lists that support MPM.
Definition: detect-parse.c:429
res
PoolThreadReserved res
Definition: stream-tcp-private.h:0
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2598
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
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:327
DETECT_CONTENT_IS_SINGLE
#define DETECT_CONTENT_IS_SINGLE(c)
Definition: detect-content.h:66
DETECT_CONTENT_NEGATED
#define DETECT_CONTENT_NEGATED
Definition: detect-content.h:40
DetectContentData_::id
PatIntId id
Definition: detect-content.h:98
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:326
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:281
DetectEngineInitializeFastPatternList
void DetectEngineInitializeFastPatternList(DetectEngineCtx *de_ctx)
Definition: detect-fast-pattern.c:151
Packet_
Definition: decode.h:442
DetectContentData_::flags
uint32_t flags
Definition: detect-content.h:97
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:620
FastPatternSupportEnabledForSigMatchList
int FastPatternSupportEnabledForSigMatchList(const DetectEngineCtx *de_ctx, const int list_id)
Checks if a particular list(Signature->sm_lists[]) is in the list of lists that need to be searched f...
Definition: detect-fast-pattern.c:63
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1218
SignatureInitData_::smlists
struct SigMatch_ ** smlists
Definition: detect.h:543
SCFPSupportSMList_::priority
int priority
Definition: detect.h:710
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:1954
DetectEngineBufferTypeSupportsMpmGetById
bool DetectEngineBufferTypeSupportsMpmGetById(const DetectEngineCtx *de_ctx, const int id)
Definition: detect-engine.c:1251
detect-fast-pattern.h
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2421
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:3146
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3358
SigMatch_::idx
uint16_t idx
Definition: detect.h:325
SigMatch_::type
uint16_t type
Definition: detect.h:324
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:670
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:131
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
FatalError
#define FatalError(x,...)
Definition: util-debug.h:532
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:800
SIGMATCH_OPTIONAL_OPT
#define SIGMATCH_OPTIONAL_OPT
Definition: detect.h:1445
DetectEngineFreeFastPatternList
void DetectEngineFreeFastPatternList(DetectEngineCtx *de_ctx)
Definition: detect-fast-pattern.c:173
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
HtpBodyChunk_::next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:184
SCFree
#define SCFree(p)
Definition: util-mem.h:61
SC_ERR_FATAL
@ SC_ERR_FATAL
Definition: util-error.h:203
DETECT_CONTENT_OFFSET
#define DETECT_CONTENT_OFFSET
Definition: detect-content.h:32
DETECT_CONTENT_FAST_PATTERN_ONLY
#define DETECT_CONTENT_FAST_PATTERN_ONLY
Definition: detect-content.h:35
detect-parse.h
Signature_
Signature container.
Definition: detect.h:549
SigMatch_
a single match condition for a signature
Definition: detect.h:323
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2400
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:43
DetectFastPatternRegister
void DetectFastPatternRegister(void)
Registration function for fast_pattern keyword.
Definition: detect-fast-pattern.c:186
DetectContentData_::content_len
uint16_t content_len
Definition: detect-content.h:88
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:468
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:795
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:987
DETECT_CONTENT_WITHIN
#define DETECT_CONTENT_WITHIN
Definition: detect-content.h:31
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1242
SignatureInitData_::smlists_array_size
uint32_t smlists_array_size
Definition: detect.h:541
UTHFreePackets
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:468