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 list(Signature->sm_lists[]) is in the list
57  * of lists that need to be searched for a keyword that has fp support.
58  *
59  * \param list_id The list id.
60  *
61  * \retval 1 If supported.
62  * \retval 0 If not.
63  */
65  const int list_id)
66 {
67  if (de_ctx->fp_support_smlist_list == NULL) {
68  return 0;
69  }
70 
71  if (list_id == DETECT_SM_LIST_PMATCH)
72  return 1;
73 
75 }
76 
77 static void Add(SCFPSupportSMList **list, const int list_id, const int priority)
78 {
79  SCFPSupportSMList *ip = NULL;
80  /* insertion point - ip */
81  for (SCFPSupportSMList *tmp = *list; tmp != NULL; tmp = tmp->next) {
82  if (list_id == tmp->list_id) {
83  SCLogDebug("SM list already registered.");
84  return;
85  }
86 
87  /* We need a strict check to be sure that the current list
88  * was not already registered
89  * and other lists with the same priority hide it.
90  */
91  if (priority < tmp->priority)
92  break;
93 
94  ip = tmp;
95  }
96 
97  if (*list == NULL) {
99  if (unlikely(new == NULL))
100  exit(EXIT_FAILURE);
101  memset(new, 0, sizeof(SCFPSupportSMList));
102  new->list_id = list_id;
103  new->priority = priority;
104 
105  *list = new;
106  return;
107  }
108 
110  if (unlikely(new == NULL))
111  exit(EXIT_FAILURE);
112  memset(new, 0, sizeof(SCFPSupportSMList));
113  new->list_id = list_id;
114  new->priority = priority;
115  if (ip == NULL) {
116  new->next = *list;
117  *list = new;
118  } else {
119  new->next = ip->next;
120  ip->next = new;
121  }
122  return;
123 }
124 
125 /**
126  * \brief Lets one add a sm list id to be searched for potential fp supported
127  * keywords later.
128  *
129  * \param list_id SM list id.
130  * \param priority Priority for this list.
131  */
132 void SupportFastPatternForSigMatchList(int list_id, int priority)
133 {
134  Add(&g_fp_support_smlist_list, list_id, priority);
135 }
136 
138 {
139  Add(&de_ctx->fp_support_smlist_list, list_id, priority);
140 }
141 
142 /**
143  * \brief Registers the keywords(SMs) that should be given fp support.
144  */
146 {
148 
149  /* other types are handled by DetectMpmAppLayerRegister() */
150 }
151 
153 {
154  SCFPSupportSMList *last = NULL;
155  for (SCFPSupportSMList *tmp = g_fp_support_smlist_list; tmp != NULL; tmp = tmp->next) {
156  SCFPSupportSMList *n = SCCalloc(1, sizeof(*n));
157  if (n == NULL) {
158  FatalError("out of memory: %s", strerror(errno));
159  }
160  n->list_id = tmp->list_id;
161  n->priority = tmp->priority;
162 
163  // append
164  if (de_ctx->fp_support_smlist_list == NULL) {
165  last = de_ctx->fp_support_smlist_list = n;
166  } else {
167  BUG_ON(last == NULL);
168  last->next = n;
169  last = n;
170  }
171  }
172 }
173 
175 {
176  for (SCFPSupportSMList *tmp = de_ctx->fp_support_smlist_list; tmp != NULL;) {
177  SCFPSupportSMList *next = tmp->next;
178  SCFree(tmp);
179  tmp = next;
180  }
182 }
183 
184 /**
185  * \brief Registration function for fast_pattern keyword
186  */
188 {
189  sigmatch_table[DETECT_FAST_PATTERN].name = "fast_pattern";
190  sigmatch_table[DETECT_FAST_PATTERN].desc = "force using preceding content in the multi pattern matcher";
191  sigmatch_table[DETECT_FAST_PATTERN].url = "/rules/prefilter-keywords.html#fast-pattern";
193  sigmatch_table[DETECT_FAST_PATTERN].Setup = DetectFastPatternSetup;
195 #ifdef UNITTESTS
196  sigmatch_table[DETECT_FAST_PATTERN].RegisterTests = DetectFastPatternRegisterTests;
197 #endif
199 
200  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
201 }
202 
203 /**
204  * \brief Configures the previous content context for a fast_pattern modifier
205  * keyword used in the rule.
206  *
207  * \param de_ctx Pointer to the Detection Engine Context.
208  * \param s Pointer to the Signature to which the current keyword belongs.
209  * \param arg May hold an argument
210  *
211  * \retval 0 On success.
212  * \retval -1 On failure.
213  */
214 static int DetectFastPatternSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
215 {
216  int ret = 0, res = 0;
217  size_t pcre2len;
218  char arg_substr[128] = "";
219  DetectContentData *cd = NULL;
220 
223  if (pm1 == NULL && pm2 == NULL) {
224  SCLogError("fast_pattern found inside "
225  "the rule, without a content context. Please use a "
226  "content based keyword before using fast_pattern");
227  return -1;
228  }
229 
230  SigMatch *pm = NULL;
231  if (pm1 && pm2) {
232  if (pm1->idx > pm2->idx)
233  pm = pm1;
234  else
235  pm = pm2;
236  } else if (pm1 && !pm2) {
237  pm = pm1;
238  } else {
239  pm = pm2;
240  }
241 
242  cd = (DetectContentData *)pm->ctx;
243  if ((cd->flags & DETECT_CONTENT_NEGATED) &&
244  ((cd->flags & DETECT_CONTENT_DISTANCE) ||
245  (cd->flags & DETECT_CONTENT_WITHIN) ||
246  (cd->flags & DETECT_CONTENT_OFFSET) ||
247  (cd->flags & DETECT_CONTENT_DEPTH))) {
248 
249  /* we can't have any of these if we are having "only" */
250  SCLogError("fast_pattern; cannot be "
251  "used with negated content, along with relative modifiers");
252  goto error;
253  }
254 
255  if (arg == NULL|| strcmp(arg, "") == 0) {
257  SCLogError("can't use multiple fast_pattern "
258  "options for the same content");
259  goto error;
260  }
261  else { /*allow only one content to have fast_pattern modifier*/
262  uint32_t list_id = 0;
263  for (list_id = 0; list_id < s->init_data->smlists_array_size; list_id++) {
264  SigMatch *sm = NULL;
265  for (sm = s->init_data->smlists[list_id]; sm != NULL; sm = sm->next) {
266  if (sm->type == DETECT_CONTENT) {
267  DetectContentData *tmp_cd = (DetectContentData *)sm->ctx;
268  if (tmp_cd->flags & DETECT_CONTENT_FAST_PATTERN) {
269  SCLogError("fast_pattern "
270  "can be used on only one content in a rule");
271  goto error;
272  }
273  }
274  } /* for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) */
275  }
276  }
278  return 0;
279  }
280 
281  /* Execute the regex and populate args with captures. */
282  ret = DetectParsePcreExec(&parse_regex, arg, 0, 0);
283  /* fast pattern only */
284  if (ret == 2) {
285  if ((cd->flags & DETECT_CONTENT_NEGATED) ||
286  (cd->flags & DETECT_CONTENT_DISTANCE) ||
287  (cd->flags & DETECT_CONTENT_WITHIN) ||
288  (cd->flags & DETECT_CONTENT_OFFSET) ||
289  (cd->flags & DETECT_CONTENT_DEPTH)) {
290 
291  /* we can't have any of these if we are having "only" */
292  SCLogError("fast_pattern: only; cannot be "
293  "used with negated content or with any of the relative "
294  "modifiers like distance, within, offset, depth");
295  goto error;
296  }
298 
299  /* fast pattern chop */
300  } else if (ret == 4) {
301  pcre2len = sizeof(arg_substr);
302  res = pcre2_substring_copy_bynumber(
303  parse_regex.match, 2, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
304  if (res < 0) {
305  SCLogError("pcre2_substring_copy_bynumber failed "
306  "for fast_pattern offset");
307  goto error;
308  }
309  uint16_t offset;
310  if (StringParseUint16(&offset, 10, 0,
311  (const char *)arg_substr) < 0) {
312  SCLogError("Invalid fast pattern offset:"
313  " \"%s\"",
314  arg_substr);
315  goto error;
316  }
317 
318  pcre2len = sizeof(arg_substr);
319  res = pcre2_substring_copy_bynumber(
320  parse_regex.match, 3, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
321  if (res < 0) {
322  SCLogError("pcre2_substring_copy_bynumber failed "
323  "for fast_pattern offset");
324  goto error;
325  }
326  uint16_t length;
327  if (StringParseUint16(&length, 10, 0,
328  (const char *)arg_substr) < 0) {
329  SCLogError("Invalid value for fast "
330  "pattern: \"%s\"",
331  arg_substr);
332  goto error;
333  }
334 
335  // Avoiding integer overflow
336  if (offset > (65535 - length)) {
337  SCLogError("Fast pattern (length + offset) "
338  "exceeds limit pattern length limit");
339  goto error;
340  }
341 
342  if (offset + length > cd->content_len) {
343  SCLogError("Fast pattern (length + "
344  "offset (%u)) exceeds pattern length (%u)",
345  offset + length, cd->content_len);
346  goto error;
347  }
348 
349  cd->fp_chop_offset = offset;
350  cd->fp_chop_len = length;
352 
353  } else {
354  SCLogError("parse error, ret %" PRId32 ", string %s", ret, arg);
355  goto error;
356  }
357 
359 
360  return 0;
361 
362  error:
363  return -1;
364 }
365 
366 /*----------------------------------Unittests---------------------------------*/
367 
368 #ifdef UNITTESTS
369 #include "detect-engine-alert.h"
370 static int DetectFastPatternStickySingle(const char *sticky, const int list)
371 {
374  char string[1024];
375  snprintf(string, sizeof(string),
376  "alert tcp any any -> any any "
377  "(%s%scontent:\"one\"; fast_pattern; sid:1;)",
378  sticky ? sticky : "", sticky ? "; " : " ");
379  Signature *s = DetectEngineAppendSig(de_ctx, string);
380  FAIL_IF_NULL(s);
381  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
382  FAIL_IF_NULL(sm);
388  PASS;
389 }
390 
391 static int DetectFastPatternModifierSingle(const char *sticky, const int list)
392 {
395  char string[1024];
396  snprintf(string, sizeof(string),
397  "alert tcp any any -> any any "
398  "(content:\"one\"; %s%sfast_pattern; sid:1;)",
399  sticky ? sticky : "", sticky ? "; " : " ");
400  Signature *s = DetectEngineAppendSig(de_ctx, string);
401  FAIL_IF_NULL(s);
402  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
403  FAIL_IF_NULL(sm);
409  PASS;
410 }
411 
412 static int DetectFastPatternStickySingleNoFP(const char *sticky, const int list)
413 {
416  char string[1024];
417  snprintf(string, sizeof(string),
418  "alert tcp any any -> any any "
419  "(%s%scontent:\"one\"; sid:1;)",
420  sticky ? sticky : "", sticky ? "; " : " ");
421  Signature *s = DetectEngineAppendSig(de_ctx, string);
422  FAIL_IF_NULL(s);
423  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
424  FAIL_IF_NULL(sm);
430  PASS;
431 }
432 
433 static int DetectFastPatternModifierSingleNoFP(const char *sticky, const int list)
434 {
437  char string[1024];
438  snprintf(string, sizeof(string),
439  "alert tcp any any -> any any "
440  "(content:\"one\"; %s%ssid:1;)",
441  sticky ? sticky : "", sticky ? "; " : " ");
442  Signature *s = DetectEngineAppendSig(de_ctx, string);
443  FAIL_IF_NULL(s);
444  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
445  FAIL_IF_NULL(sm);
451  PASS;
452 }
453 
454 static int DetectFastPatternStickySingleBadArg(const char *sticky)
455 {
458  char string[1024];
459  /* bogus argument to fast_pattern */
460  snprintf(string, sizeof(string),
461  "alert tcp any any -> any any "
462  "(%s%scontent:\"one\"; fast_pattern:boo; sid:1;)",
463  sticky ? sticky : "", sticky ? "; " : " ");
464  Signature *s = DetectEngineAppendSig(de_ctx, string);
465  FAIL_IF_NOT_NULL(s);
466  /* fast_pattern only with distance */
467  snprintf(string, sizeof(string),
468  "alert tcp any any -> any any "
469  "(%s%scontent:\"one\"; fast_pattern:only; content:\"two\"; distance:10; sid:1;)",
470  sticky ? sticky : "", sticky ? "; " : " ");
471  s = DetectEngineAppendSig(de_ctx, string);
472  FAIL_IF_NOT_NULL(s);
473  /* fast_pattern only with distance */
474  snprintf(string, sizeof(string),
475  "alert tcp any any -> any any "
476  "(%s%scontent:\"one\"; content:\"two\"; fast_pattern:only; distance:10; sid:1;)",
477  sticky ? sticky : "", sticky ? "; " : " ");
478  s = DetectEngineAppendSig(de_ctx, string);
479  FAIL_IF_NOT_NULL(s);
480  /* fast_pattern only with distance */
481  snprintf(string, sizeof(string),
482  "alert tcp any any -> any any "
483  "(%s%scontent:\"one\"; content:\"two\"; distance:10; fast_pattern:only; sid:1;)",
484  sticky ? sticky : "", sticky ? "; " : " ");
485  s = DetectEngineAppendSig(de_ctx, string);
486  FAIL_IF_NOT_NULL(s);
487  /* fast_pattern chop with invalid values */
488  snprintf(string, sizeof(string),
489  "alert tcp any any -> any any "
490  "(%s%scontent:\"one\"; fast_pattern:5,6; sid:1;)",
491  sticky ? sticky : "", sticky ? "; " : " ");
492  s = DetectEngineAppendSig(de_ctx, string);
493  FAIL_IF_NOT_NULL(s);
495  PASS;
496 }
497 
498 static int DetectFastPatternModifierBadRules(const char *sticky)
499 {
502  char string[1024];
503  /* bogus argument to fast_pattern */
504  snprintf(string, sizeof(string),
505  "alert tcp any any -> any any "
506  "(content:\"one\"; %s%sfast_pattern:boo; sid:1;)",
507  sticky ? sticky : "", sticky ? "; " : " ");
508  Signature *s = DetectEngineAppendSig(de_ctx, string);
509  FAIL_IF_NOT_NULL(s);
510  /* fast_pattern only with distance */
511  snprintf(string, sizeof(string),
512  "alert tcp any any -> any any "
513  "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%sdistance:10; sid:1;)",
514  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
515  s = DetectEngineAppendSig(de_ctx, string);
516  FAIL_IF_NOT_NULL(s);
517 #if 0 // TODO bug?
518  /* fast_pattern only with distance */
519  snprintf(string, sizeof(string), "alert tcp any any -> any any "
520  "(content:\"one\"; %s%s content:\"two\"; %s%sdistance:10; fast_pattern:only; sid:1;)",
521  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
522  s = DetectEngineAppendSig(de_ctx, string);
523  FAIL_IF_NOT_NULL(s);
524 #endif
525  /* fast_pattern only with within */
526  snprintf(string, sizeof(string),
527  "alert tcp any any -> any any "
528  "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%swithin:10; sid:1;)",
529  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
530  s = DetectEngineAppendSig(de_ctx, string);
531  FAIL_IF_NOT_NULL(s);
532  /* fast_pattern only with within */
533  snprintf(string, sizeof(string),
534  "alert tcp any any -> any any "
535  "(content:\"one\"; %s%s content:\"two\"; %s%swithin:10; fast_pattern:only; sid:1;)",
536  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
537  s = DetectEngineAppendSig(de_ctx, string);
538  FAIL_IF_NOT_NULL(s);
539  /* fast_pattern only with offset */
540  snprintf(string, sizeof(string),
541  "alert tcp any any -> any any "
542  "(content:\"one\"; %s%sfast_pattern:only; offset:10; sid:1;)",
543  sticky ? sticky : "", sticky ? "; " : " ");
544  s = DetectEngineAppendSig(de_ctx, string);
545  FAIL_IF_NOT_NULL(s);
546  /* fast_pattern only with offset */
547  snprintf(string, sizeof(string),
548  "alert tcp any any -> any any "
549  "(content:\"one\"; %s%s offset:10; fast_pattern:only; sid:1;)",
550  sticky ? sticky : "", sticky ? "; " : " ");
551  s = DetectEngineAppendSig(de_ctx, string);
552  FAIL_IF_NOT_NULL(s);
553  /* fast_pattern only with depth */
554  snprintf(string, sizeof(string),
555  "alert tcp any any -> any any "
556  "(content:\"one\"; %s%sfast_pattern:only; depth:10; sid:1;)",
557  sticky ? sticky : "", sticky ? "; " : " ");
558  s = DetectEngineAppendSig(de_ctx, string);
559  FAIL_IF_NOT_NULL(s);
560  /* fast_pattern only with depth */
561  snprintf(string, sizeof(string),
562  "alert tcp any any -> any any "
563  "(content:\"one\"; %s%s depth:10; fast_pattern:only; sid:1;)",
564  sticky ? sticky : "", sticky ? "; " : " ");
565  s = DetectEngineAppendSig(de_ctx, string);
566  FAIL_IF_NOT_NULL(s);
567  /* fast_pattern only negate */
568  snprintf(string, sizeof(string),
569  "alert tcp any any -> any any "
570  "(content:\"one\"; %s%s content:!\"two\"; %s%sfast_pattern:only; sid:1;)",
571  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
572  s = DetectEngineAppendSig(de_ctx, string);
573  FAIL_IF_NOT_NULL(s);
574  /* fast_pattern chop with invalid values */
575  snprintf(string, sizeof(string),
576  "alert tcp any any -> any any "
577  "(content:\"one\"; %s%sfast_pattern:5,6; sid:1;)",
578  sticky ? sticky : "", sticky ? "; " : " ");
579  s = DetectEngineAppendSig(de_ctx, string);
580  FAIL_IF_NOT_NULL(s);
581  /* fast_pattern chop with invalid values */
582  snprintf(string, sizeof(string),
583  "alert tcp any any -> any any "
584  "(content:\"one\"; %s%sfast_pattern:65977,2; sid:1;)",
585  sticky ? sticky : "", sticky ? "; " : " ");
586  s = DetectEngineAppendSig(de_ctx, string);
587  FAIL_IF_NOT_NULL(s);
588  /* fast_pattern chop with invalid values */
589  snprintf(string, sizeof(string),
590  "alert tcp any any -> any any "
591  "(content:\"one\"; %s%sfast_pattern:2,65977; sid:1;)",
592  sticky ? sticky : "", sticky ? "; " : " ");
593  s = DetectEngineAppendSig(de_ctx, string);
594  FAIL_IF_NOT_NULL(s);
595  /* fast_pattern chop with invalid values */
596  snprintf(string, sizeof(string),
597  "alert tcp any any -> any any "
598  "(content:\"one\"; %s%sfast_pattern:2,65534; sid:1;)",
599  sticky ? sticky : "", sticky ? "; " : " ");
600  s = DetectEngineAppendSig(de_ctx, string);
601  FAIL_IF_NOT_NULL(s);
602  /* fast_pattern chop with invalid values */
603  snprintf(string, sizeof(string),
604  "alert tcp any any -> any any "
605  "(content:\"one\"; %s%sfast_pattern:65534,2; sid:1;)",
606  sticky ? sticky : "", sticky ? "; " : " ");
607  s = DetectEngineAppendSig(de_ctx, string);
608  FAIL_IF_NOT_NULL(s);
609  /* negated fast_pattern with distance */
610  snprintf(string, sizeof(string),
611  "alert tcp any any -> any any "
612  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdistance:10; sid:1;)",
613  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
614  s = DetectEngineAppendSig(de_ctx, string);
615  FAIL_IF_NOT_NULL(s);
616  /* negated fast_pattern with within */
617  snprintf(string, sizeof(string),
618  "alert tcp any any -> any any "
619  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%swithin:10; sid:1;)",
620  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
621  s = DetectEngineAppendSig(de_ctx, string);
622  FAIL_IF_NOT_NULL(s);
623  /* negated fast_pattern with depth */
624  snprintf(string, sizeof(string),
625  "alert tcp any any -> any any "
626  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdepth:10; sid:1;)",
627  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
628  s = DetectEngineAppendSig(de_ctx, string);
629  FAIL_IF_NOT_NULL(s);
630  /* negated fast_pattern with offset */
631  snprintf(string, sizeof(string),
632  "alert tcp any any -> any any "
633  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%soffset:10; sid:1;)",
634  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
635  s = DetectEngineAppendSig(de_ctx, string);
636  FAIL_IF_NOT_NULL(s);
638  PASS;
639 }
640 
641 static int DetectFastPatternStickySingleFPOnly(const char *sticky, const int list)
642 {
645  char string[1024];
646  snprintf(string, sizeof(string),
647  "alert tcp any any -> any any "
648  "(%s%scontent:\"one\"; fast_pattern:only; sid:1;)",
649  sticky ? sticky : "", sticky ? "; " : " ");
650  Signature *s = DetectEngineAppendSig(de_ctx, string);
651  FAIL_IF_NULL(s);
652  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
653  FAIL_IF_NULL(sm);
660  PASS;
661 }
662 
663 static int DetectFastPatternModifierFPOnly(const char *sticky, const int list)
664 {
667  char string[1024];
668  snprintf(string, sizeof(string),
669  "alert tcp any any -> any any "
670  "(content:\"one\"; %s%sfast_pattern:only; sid:1;)",
671  sticky ? sticky : "", sticky ? "; " : " ");
672  Signature *s = DetectEngineAppendSig(de_ctx, string);
673  FAIL_IF_NULL(s);
674  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
675  FAIL_IF_NULL(sm);
681 
682  snprintf(string, sizeof(string),
683  "alert tcp any any -> any any "
684  "(content:\"one\"; %s%scontent:\"two\"; %s%sfast_pattern:only; sid:2;)",
685  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
686  s = DetectEngineAppendSig(de_ctx, string);
687  FAIL_IF_NULL(s);
688  sm = de_ctx->sig_list->sm_lists[list];
689  FAIL_IF_NULL(sm);
690  FAIL_IF_NULL(sm->next);
692  cd = (DetectContentData *)sm->ctx;
694  FAIL_IF_NOT(
696  sm = sm->next;
698  cd = (DetectContentData *)sm->ctx;
702 
703  snprintf(string, sizeof(string),
704  "alert tcp any any -> any any "
705  "(content:\"one\"; %s%scontent:\"two\"; distance:10; %s%scontent:\"three\"; "
706  "%s%sfast_pattern:only; sid:3;)",
707  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
708  sticky ? sticky : "", sticky ? "; " : " ");
709  s = DetectEngineAppendSig(de_ctx, string);
710  FAIL_IF_NULL(s);
711  sm = de_ctx->sig_list->sm_lists[list];
712  FAIL_IF_NULL(sm);
713  FAIL_IF_NULL(sm->next);
715  cd = (DetectContentData *)sm->ctx;
717  FAIL_IF_NOT(
719  sm = sm->next;
720  FAIL_IF_NULL(sm->next);
722  cd = (DetectContentData *)sm->ctx;
724  FAIL_IF_NOT(
726  sm = sm->next;
727  FAIL_IF_NOT_NULL(sm->next);
729  cd = (DetectContentData *)sm->ctx;
733 
734  snprintf(string, sizeof(string),
735  "alert tcp any any -> any any "
736  "(content:\"one\"; %s%scontent:\"two\"; within:10; %s%scontent:\"three\"; "
737  "%s%sfast_pattern:only; sid:4;)",
738  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
739  sticky ? sticky : "", sticky ? "; " : " ");
740  s = DetectEngineAppendSig(de_ctx, string);
741  FAIL_IF_NULL(s);
742  sm = de_ctx->sig_list->sm_lists[list];
743  FAIL_IF_NULL(sm);
744  FAIL_IF_NULL(sm->next);
746  cd = (DetectContentData *)sm->ctx;
748  FAIL_IF_NOT(
750  sm = sm->next;
751  FAIL_IF_NULL(sm->next);
753  cd = (DetectContentData *)sm->ctx;
755  FAIL_IF_NOT(
757  sm = sm->next;
758  FAIL_IF_NOT_NULL(sm->next);
760  cd = (DetectContentData *)sm->ctx;
764 
765  snprintf(string, sizeof(string),
766  "alert tcp any any -> any any "
767  "(content:\"one\"; %s%scontent:\"two\"; offset:10; %s%scontent:\"three\"; "
768  "%s%sfast_pattern:only; sid:5;)",
769  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
770  sticky ? sticky : "", sticky ? "; " : " ");
771  s = DetectEngineAppendSig(de_ctx, string);
772  FAIL_IF_NULL(s);
773  sm = de_ctx->sig_list->sm_lists[list];
774  FAIL_IF_NULL(sm);
775  FAIL_IF_NULL(sm->next);
777  cd = (DetectContentData *)sm->ctx;
779  FAIL_IF_NOT(
781  sm = sm->next;
782  FAIL_IF_NULL(sm->next);
784  cd = (DetectContentData *)sm->ctx;
786  FAIL_IF_NOT(
788  sm = sm->next;
789  FAIL_IF_NOT_NULL(sm->next);
791  cd = (DetectContentData *)sm->ctx;
795 
796  snprintf(string, sizeof(string),
797  "alert tcp any any -> any any "
798  "(content:\"one\"; %s%scontent:\"two\"; depth:10; %s%scontent:\"three\"; "
799  "%s%sfast_pattern:only; sid:6;)",
800  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
801  sticky ? sticky : "", sticky ? "; " : " ");
802  s = DetectEngineAppendSig(de_ctx, string);
803  FAIL_IF_NULL(s);
804  sm = de_ctx->sig_list->sm_lists[list];
805  FAIL_IF_NULL(sm);
806  FAIL_IF_NULL(sm->next);
808  cd = (DetectContentData *)sm->ctx;
810  FAIL_IF_NOT(
812  sm = sm->next;
813  FAIL_IF_NULL(sm->next);
815  cd = (DetectContentData *)sm->ctx;
817  FAIL_IF_NOT(
819  sm = sm->next;
820  FAIL_IF_NOT_NULL(sm->next);
822  cd = (DetectContentData *)sm->ctx;
826 
827  snprintf(string, sizeof(string),
828  "alert tcp any any -> any any "
829  "(content:!\"one\"; %s%sfast_pattern; content:\"two\"; depth:10; %s%ssid:7;)",
830  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
831  s = DetectEngineAppendSig(de_ctx, string);
832  FAIL_IF_NULL(s);
833  sm = de_ctx->sig_list->sm_lists[list];
834  FAIL_IF_NULL(sm);
835  FAIL_IF_NULL(sm->next);
837  cd = (DetectContentData *)sm->ctx;
842  sm = sm->next;
843  FAIL_IF_NOT_NULL(sm->next);
845  cd = (DetectContentData *)sm->ctx;
847  FAIL_IF_NOT(
849 
851  PASS;
852 }
853 
854 static int DetectFastPatternStickyFPChop(const char *sticky, const int list)
855 {
858  char string[1024];
859  snprintf(string, sizeof(string),
860  "alert tcp any any -> any any "
861  "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; sid:1;)",
862  sticky ? sticky : "", sticky ? "; " : " ");
863  Signature *s = DetectEngineAppendSig(de_ctx, string);
864  FAIL_IF_NULL(s);
865  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
866  FAIL_IF_NULL(sm);
873  FAIL_IF_NOT(cd->fp_chop_offset == 3);
874  FAIL_IF_NOT(cd->fp_chop_len == 4);
875 
876  snprintf(string, sizeof(string),
877  "alert tcp any any -> any any "
878  "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; content:\"xyz\"; distance:10; sid:2;)",
879  sticky ? sticky : "", sticky ? "; " : " ");
880  s = DetectEngineAppendSig(de_ctx, string);
881  FAIL_IF_NULL(s);
882  sm = de_ctx->sig_list->sm_lists[list];
883  FAIL_IF_NULL(sm);
885  cd = (DetectContentData *)sm->ctx;
890  FAIL_IF_NOT(cd->fp_chop_offset == 3);
891  FAIL_IF_NOT(cd->fp_chop_len == 4);
892 
894  PASS;
895 }
896 
897 static int DetectFastPatternModifierFPChop(const char *sticky, const int list)
898 {
901  char string[1024];
902  snprintf(string, sizeof(string),
903  "alert tcp any any -> any any "
904  "(content:\"onetwothree\"; %s%sfast_pattern:3,4; sid:1;)",
905  sticky ? sticky : "", sticky ? "; " : " ");
906  Signature *s = DetectEngineAppendSig(de_ctx, string);
907  FAIL_IF_NULL(s);
908  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
909  FAIL_IF_NULL(sm);
916  FAIL_IF_NOT(cd->fp_chop_offset == 3);
917  FAIL_IF_NOT(cd->fp_chop_len == 4);
918 
919  snprintf(string, sizeof(string),
920  "alert tcp any any -> any any "
921  "(content:!\"onetwothree\"; %s%sfast_pattern:3,4; sid:2;)",
922  sticky ? sticky : "", sticky ? "; " : " ");
923  s = DetectEngineAppendSig(de_ctx, string);
924  FAIL_IF_NULL(s);
925  sm = de_ctx->sig_list->sm_lists[list];
926  FAIL_IF_NULL(sm);
928  cd = (DetectContentData *)sm->ctx;
935  FAIL_IF_NOT(cd->fp_chop_offset == 3);
936  FAIL_IF_NOT(cd->fp_chop_len == 4);
937 
939  PASS;
940 }
941 
942 /**
943  * \test Checks if a fast_pattern is registered in a Signature
944  */
945 static int DetectFastPatternTest01(void)
946 {
947  FAIL_IF_NOT(DetectFastPatternStickySingle(NULL, DETECT_SM_LIST_PMATCH));
948  FAIL_IF_NOT(DetectFastPatternModifierSingle(NULL, DETECT_SM_LIST_PMATCH));
949  FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(NULL, DETECT_SM_LIST_PMATCH));
950  FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(NULL, DETECT_SM_LIST_PMATCH));
951  FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(NULL));
952  FAIL_IF_NOT(DetectFastPatternModifierBadRules(NULL));
953  FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(NULL, DETECT_SM_LIST_PMATCH));
954  FAIL_IF_NOT(DetectFastPatternModifierFPOnly(NULL, DETECT_SM_LIST_PMATCH));
955  FAIL_IF_NOT(DetectFastPatternStickyFPChop(NULL, DETECT_SM_LIST_PMATCH));
956  FAIL_IF_NOT(DetectFastPatternModifierFPChop(NULL, DETECT_SM_LIST_PMATCH));
957 
958  struct {
959  const char *buffer_name;
960  const char *sb_name;
961  const char *mod_name;
962  } keywords[] = {
963  { "file_data", "file.data", NULL },
964  { "http_uri", "http.uri", "http_uri" },
965  { "http_raw_uri", "http.uri.raw", "http_raw_uri" },
966  { "http_user_agent", "http.user_agent", "http_user_agent" },
967  { "http_header", "http.header", "http_header" },
968  // http_raw_header requires sigs to have a direction
969  //{ "http_raw_header", "http.header.raw", "http_raw_header" },
970  { "http_method", "http.method", "http_method" },
971  { "http_cookie", "http.cookie", "http_cookie" },
972  { "http_host", "http.host", "http_host" },
973  { "http_raw_host", "http.host.raw", "http_raw_host" },
974  { "http_stat_code", "http.stat_code", "http_stat_code" },
975  { "http_stat_msg", "http.stat_msg", "http_stat_msg" },
976  { "http_client_body", "http.request_body", "http_client_body" },
977  { NULL, NULL, NULL },
978  };
979 
980  for (int i = 0; keywords[i].buffer_name != NULL; i++) {
981  const int list_id = DetectBufferTypeGetByName(keywords[i].buffer_name);
982  FAIL_IF(list_id == -1);
983 
984  const char *k = keywords[i].sb_name;
985  if (k) {
986  FAIL_IF_NOT(DetectFastPatternStickySingle(k, list_id));
987  FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(k, list_id));
988  FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(k));
989  FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(k, list_id));
990  FAIL_IF_NOT(DetectFastPatternStickyFPChop(k, list_id));
991  }
992  k = keywords[i].mod_name;
993  if (k) {
994  FAIL_IF_NOT(DetectFastPatternModifierSingle(k, list_id));
995  FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(k, list_id));
996  FAIL_IF_NOT(DetectFastPatternModifierBadRules(k));
997  FAIL_IF_NOT(DetectFastPatternModifierFPOnly(k, list_id));
998  FAIL_IF_NOT(DetectFastPatternModifierFPChop(k, list_id));
999  }
1000  }
1001 
1002  PASS;
1003 }
1004 
1005 /**
1006  * \test Checks to make sure that other sigs work that should when fast_pattern is inspecting on the
1007  * same payload
1008  *
1009  */
1010 static int DetectFastPatternTest14(void)
1011 {
1012  uint8_t *buf = (uint8_t *)"Dummy is our name. Oh yes. From right here "
1013  "right now, all the way to hangover. right. strings5_imp now here "
1014  "comes our dark knight strings_string5. Yes here is our dark knight";
1015  uint16_t buflen = strlen((char *)buf);
1016  ThreadVars th_v;
1017  DetectEngineThreadCtx *det_ctx = NULL;
1018 
1019  memset(&th_v, 0, sizeof(th_v));
1020  Packet *p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
1021  FAIL_IF_NULL(p);
1022 
1025  de_ctx->flags |= DE_QUIET;
1026 
1028 
1030  "alert tcp any any -> any any "
1031  "(msg:\"fast_pattern test\"; content:\"strings_string5\"; content:\"knight\"; "
1032  "fast_pattern; sid:1;)");
1033  FAIL_IF_NULL(s);
1034 
1036  "alert tcp any any -> any any "
1037  "(msg:\"test different content\"; content:\"Dummy is our name\"; sid:2;)");
1038  FAIL_IF_NULL(s);
1039 
1041  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1042 
1043  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1046 
1047  UTHFreePackets(&p, 1);
1048  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1050  FlowShutdown();
1051  PASS;
1052 }
1053 
1054 /**
1055  * Unittest to check
1056  * - if we assign different content_ids to duplicate patterns, but one of the
1057  * patterns has a fast_pattern chop set.
1058  * - if 2 unique patterns get unique ids.
1059  * - if 2 duplicate patterns, with no chop set get unique ids.
1060  */
1061 static int DetectFastPatternTest671(void)
1062 {
1065  de_ctx->flags |= DE_QUIET;
1066 
1067  Signature *s[6];
1068  s[0] = DetectEngineAppendSig(
1069  de_ctx, "alert tcp any any -> any any (content:\"onetwothreefour\"; sid:1;)");
1070  FAIL_IF_NULL(s[0]);
1071  s[1] = DetectEngineAppendSig(
1072  de_ctx, "alert tcp any any -> any any (content:\"onetwothreefour\"; sid:2;)");
1073  FAIL_IF_NULL(s[1]);
1074  s[2] = DetectEngineAppendSig(
1075  de_ctx, "alert tcp any any -> any any (content:\"uniquepattern\"; sid:3;)");
1076  FAIL_IF_NULL(s[2]);
1078  "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:3,5; sid:4;)");
1079  FAIL_IF_NULL(s[3]);
1080  s[4] = DetectEngineAppendSig(
1081  de_ctx, "alert tcp any any -> any any (content:\"twoth\"; sid:5;)");
1082  FAIL_IF_NULL(s[4]);
1084  "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:0,15; "
1085  "sid:6;)");
1086  FAIL_IF_NULL(s[5]);
1087 
1089 
1091  DetectContentData *cd = (DetectContentData *)smd->ctx;
1092  FAIL_IF(cd->id != 0);
1093 
1094  smd = s[1]->sm_arrays[DETECT_SM_LIST_PMATCH];
1095  cd = (DetectContentData *)smd->ctx;
1096  FAIL_IF(cd->id != 0);
1097 
1098  smd = s[2]->sm_arrays[DETECT_SM_LIST_PMATCH];
1099  cd = (DetectContentData *)smd->ctx;
1100  FAIL_IF(cd->id != 2);
1101 
1102  smd = s[3]->sm_arrays[DETECT_SM_LIST_PMATCH];
1103  cd = (DetectContentData *)smd->ctx;
1104  FAIL_IF(cd->id != 1);
1105 
1106  smd = s[4]->sm_arrays[DETECT_SM_LIST_PMATCH];
1107  cd = (DetectContentData *)smd->ctx;
1108  FAIL_IF(cd->id != 1);
1109 
1110  smd = s[5]->sm_arrays[DETECT_SM_LIST_PMATCH];
1111  cd = (DetectContentData *)smd->ctx;
1112  FAIL_IF(cd->id != 0);
1113 
1115  PASS;
1116 }
1117 
1118 static int DetectFastPatternPrefilter(void)
1119 {
1122  const char *string = "alert tcp any any -> any any "
1123  "(content:\"one\"; prefilter; sid:1;)";
1124  Signature *s = DetectEngineAppendSig(de_ctx, string);
1125  FAIL_IF_NULL(s);
1126  SigMatch *sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH];
1127  FAIL_IF_NULL(sm);
1133  PASS;
1134 }
1135 
1136 static void DetectFastPatternRegisterTests(void)
1137 {
1138  UtRegisterTest("DetectFastPatternTest01", DetectFastPatternTest01);
1139  UtRegisterTest("DetectFastPatternTest14", DetectFastPatternTest14);
1140  /* Unittest to check
1141  * - if we assign different content_ids to duplicate patterns, but one of the
1142  * patterns has a fast_pattern chop set.
1143  * - if 2 unique patterns get unique ids.
1144  * - if 2 duplicate patterns, with no chop set get unique ids.
1145  */
1146  UtRegisterTest("DetectFastPatternTest671", DetectFastPatternTest671);
1147 
1148  UtRegisterTest("DetectFastPatternPrefilter", DetectFastPatternPrefilter);
1149 }
1150 #endif
util-byte.h
SCFPSupportSMList_
Definition: detect.h:699
DetectParseRegex::match
pcre2_match_data * match
Definition: detect-parse.h:47
SigTableElmt_::url
const char * url
Definition: detect.h:1241
detect-content.h
detect-engine.h
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:79
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:1240
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, const char *str, int start_offset, int options)
Definition: detect-parse.c:2488
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1228
SCFPSupportSMList_::next
struct SCFPSupportSMList_ * next
Definition: detect.h:702
DetectParseRegex
Definition: detect-parse.h:44
SCFPSupportSMList_::list_id
int list_id
Definition: detect.h:700
SigTableElmt_::name
const char * name
Definition: detect.h:1238
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
DETECT_CONTENT
@ DETECT_CONTENT
Definition: detect-engine-register.h:62
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
PacketAlertCheck
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
Definition: detect-engine-alert.c:141
DETECT_FAST_PATTERN
@ DETECT_FAST_PATTERN
Definition: detect-engine-register.h:73
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:325
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1232
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:785
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:2442
SupportFastPatternForSigMatchTypes
void SupportFastPatternForSigMatchTypes(void)
Registers the keywords(SMs) that should be given fp support.
Definition: detect-fast-pattern.c:145
DE_QUIET
#define DE_QUIET
Definition: detect.h:287
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:1809
Signature_::sm_arrays
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
Definition: detect.h:595
DetectContentData_
Definition: detect-content.h:86
DetectContentData_::fp_chop_offset
uint16_t fp_chop_offset
Definition: detect-content.h:93
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2434
SigMatchData_
Data needed for Match()
Definition: detect.h:322
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1223
DetectEngineRegisterFastPatternForId
void DetectEngineRegisterFastPatternForId(DetectEngineCtx *de_ctx, int list_id, int priority)
Definition: detect-fast-pattern.c:137
PARSE_REGEX
#define PARSE_REGEX
Definition: detect-fast-pattern.c:42
util-unittest.h
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:1079
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:543
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:1025
DetectGetLastSMFromMpmLists
SigMatch * DetectGetLastSMFromMpmLists(const DetectEngineCtx *de_ctx, const Signature *s)
get the last SigMatch from lists that support MPM.
Definition: detect-parse.c:434
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2609
DETECT_CONTENT_DEPTH
#define DETECT_CONTENT_DEPTH
Definition: detect-content.h:33
detect-engine-mpm.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:317
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:316
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:289
DetectEngineInitializeFastPatternList
void DetectEngineInitializeFastPatternList(DetectEngineCtx *de_ctx)
Definition: detect-fast-pattern.c:152
Packet_
Definition: decode.h:428
detect-engine-build.h
detect-engine-alert.h
DetectContentData_::flags
uint32_t flags
Definition: detect-content.h:97
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:611
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:64
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1206
SignatureInitData_::smlists
struct SigMatch_ ** smlists
Definition: detect.h:534
SCFPSupportSMList_::priority
int priority
Definition: detect.h:701
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:1951
DetectEngineBufferTypeSupportsMpmGetById
bool DetectEngineBufferTypeSupportsMpmGetById(const DetectEngineCtx *de_ctx, const int id)
Definition: detect-engine.c:1246
detect-fast-pattern.h
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:3153
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:3367
SigMatch_::idx
uint16_t idx
Definition: detect.h:315
SigMatch_::type
uint16_t type
Definition: detect.h:314
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:689
SupportFastPatternForSigMatchList
void SupportFastPatternForSigMatchList(int list_id, int priority)
Lets one add a sm list id to be searched for potential fp supported keywords later.
Definition: detect-fast-pattern.c:132
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:76
FatalError
#define FatalError(...)
Definition: util-debug.h:502
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:791
SIGMATCH_OPTIONAL_OPT
#define SIGMATCH_OPTIONAL_OPT
Definition: detect.h:1432
DetectEngineFreeFastPatternList
void DetectEngineFreeFastPatternList(DetectEngineCtx *de_ctx)
Definition: detect-fast-pattern.c:174
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
HtpBodyChunk_::next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:177
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DETECT_CONTENT_OFFSET
#define DETECT_CONTENT_OFFSET
Definition: detect-content.h:32
DETECT_CONTENT_FAST_PATTERN_ONLY
#define DETECT_CONTENT_FAST_PATTERN_ONLY
Definition: detect-content.h:35
detect-parse.h
Signature_
Signature container.
Definition: detect.h:540
SigMatch_
a single match condition for a signature
Definition: detect.h:313
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2403
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:41
DetectFastPatternRegister
void DetectFastPatternRegister(void)
Registration function for fast_pattern keyword.
Definition: detect-fast-pattern.c:187
DetectContentData_::content_len
uint16_t content_len
Definition: detect-content.h: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:474
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:786
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:978
DETECT_CONTENT_WITHIN
#define DETECT_CONTENT_WITHIN
Definition: detect-content.h:31
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1230
SignatureInitData_::smlists_array_size
uint32_t smlists_array_size
Definition: detect.h:532
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