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 */
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 (sm_fp_support_smlist_list == NULL)
67  return 0;
68 
69  if (list_id == DETECT_SM_LIST_PMATCH)
70  return 1;
71 
73 }
74 
75 /**
76  * \brief Lets one add a sm list id to be searched for potential fp supported
77  * keywords later.
78  *
79  * \param list_id SM list id.
80  * \param priority Priority for this list.
81  */
82 void SupportFastPatternForSigMatchList(int list_id, int priority)
83 {
84  SCFPSupportSMList *ip = NULL;
85  /* insertion point - ip */
86  for (SCFPSupportSMList *tmp = sm_fp_support_smlist_list; tmp != NULL; tmp = tmp->next) {
87  if (list_id == tmp->list_id) {
88  SCLogDebug("SM list already registered.");
89  return;
90  }
91 
92  /* We need a strict check to be sure that the current list
93  * was not already registered
94  * and other lists with the same priority hide it.
95  */
96  if (priority < tmp->priority)
97  break;
98 
99  ip = tmp;
100  }
101 
102  if (sm_fp_support_smlist_list == NULL) {
104  if (unlikely(new == NULL))
105  exit(EXIT_FAILURE);
106  memset(new, 0, sizeof(SCFPSupportSMList));
107  new->list_id = list_id;
108  new->priority = priority;
109 
111 
112  return;
113  }
114 
116  if (unlikely(new == NULL))
117  exit(EXIT_FAILURE);
118  memset(new, 0, sizeof(SCFPSupportSMList));
119  new->list_id = list_id;
120  new->priority = priority;
121  if (ip == NULL) {
122  new->next = sm_fp_support_smlist_list;
124  } else {
125  new->next = ip->next;
126  ip->next = new;
127  }
128 
129  return;
130 }
131 
132 /**
133  * \brief Registers the keywords(SMs) that should be given fp support.
134  */
136 {
138 
139  /* other types are handled by DetectMpmAppLayerRegister() */
140 }
141 
142 /**
143  * \brief Registration function for fast_pattern keyword
144  */
146 {
147  sigmatch_table[DETECT_FAST_PATTERN].name = "fast_pattern";
148  sigmatch_table[DETECT_FAST_PATTERN].desc = "force using preceding content in the multi pattern matcher";
149  sigmatch_table[DETECT_FAST_PATTERN].url = "/rules/prefilter-keywords.html#fast-pattern";
151  sigmatch_table[DETECT_FAST_PATTERN].Setup = DetectFastPatternSetup;
153 #ifdef UNITTESTS
154  sigmatch_table[DETECT_FAST_PATTERN].RegisterTests = DetectFastPatternRegisterTests;
155 #endif
157 
158  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
159 }
160 
161 /**
162  * \brief Configures the previous content context for a fast_pattern modifier
163  * keyword used in the rule.
164  *
165  * \param de_ctx Pointer to the Detection Engine Context.
166  * \param s Pointer to the Signature to which the current keyword belongs.
167  * \param arg May hold an argument
168  *
169  * \retval 0 On success.
170  * \retval -1 On failure.
171  */
172 static int DetectFastPatternSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
173 {
174  int ret = 0, res = 0;
175  size_t pcre2len;
176  char arg_substr[128] = "";
177  DetectContentData *cd = NULL;
178 
181  if (pm1 == NULL && pm2 == NULL) {
182  SCLogError(SC_ERR_INVALID_SIGNATURE, "fast_pattern found inside "
183  "the rule, without a content context. Please use a "
184  "content based keyword before using fast_pattern");
185  return -1;
186  }
187 
188  SigMatch *pm = NULL;
189  if (pm1 && pm2) {
190  if (pm1->idx > pm2->idx)
191  pm = pm1;
192  else
193  pm = pm2;
194  } else if (pm1 && !pm2) {
195  pm = pm1;
196  } else {
197  pm = pm2;
198  }
199 
200  cd = (DetectContentData *)pm->ctx;
201  if ((cd->flags & DETECT_CONTENT_NEGATED) &&
202  ((cd->flags & DETECT_CONTENT_DISTANCE) ||
203  (cd->flags & DETECT_CONTENT_WITHIN) ||
204  (cd->flags & DETECT_CONTENT_OFFSET) ||
205  (cd->flags & DETECT_CONTENT_DEPTH))) {
206 
207  /* we can't have any of these if we are having "only" */
208  SCLogError(SC_ERR_INVALID_SIGNATURE, "fast_pattern; cannot be "
209  "used with negated content, along with relative modifiers");
210  goto error;
211  }
212 
213  if (arg == NULL|| strcmp(arg, "") == 0) {
215  SCLogError(SC_ERR_INVALID_SIGNATURE, "can't use multiple fast_pattern "
216  "options for the same content");
217  goto error;
218  }
219  else { /*allow only one content to have fast_pattern modifier*/
220  uint32_t list_id = 0;
221  for (list_id = 0; list_id < s->init_data->smlists_array_size; list_id++) {
222  SigMatch *sm = NULL;
223  for (sm = s->init_data->smlists[list_id]; sm != NULL; sm = sm->next) {
224  if (sm->type == DETECT_CONTENT) {
225  DetectContentData *tmp_cd = (DetectContentData *)sm->ctx;
226  if (tmp_cd->flags & DETECT_CONTENT_FAST_PATTERN) {
227  SCLogError(SC_ERR_INVALID_SIGNATURE, "fast_pattern "
228  "can be used on only one content in a rule");
229  goto error;
230  }
231  }
232  } /* for (sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) */
233  }
234  }
236  return 0;
237  }
238 
239  /* Execute the regex and populate args with captures. */
240  ret = DetectParsePcreExec(&parse_regex, arg, 0, 0);
241  /* fast pattern only */
242  if (ret == 2) {
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(SC_ERR_INVALID_SIGNATURE, "fast_pattern: only; cannot be "
251  "used with negated content or with any of the relative "
252  "modifiers like distance, within, offset, depth");
253  goto error;
254  }
256 
257  /* fast pattern chop */
258  } else if (ret == 4) {
259  pcre2len = sizeof(arg_substr);
260  res = pcre2_substring_copy_bynumber(
261  parse_regex.match, 2, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
262  if (res < 0) {
263  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_copy_bynumber failed "
264  "for fast_pattern offset");
265  goto error;
266  }
267  uint16_t offset;
268  if (StringParseUint16(&offset, 10, 0,
269  (const char *)arg_substr) < 0) {
270  SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid fast pattern offset:"
271  " \"%s\"", arg_substr);
272  goto error;
273  }
274 
275  pcre2len = sizeof(arg_substr);
276  res = pcre2_substring_copy_bynumber(
277  parse_regex.match, 3, (PCRE2_UCHAR8 *)arg_substr, &pcre2len);
278  if (res < 0) {
279  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_copy_bynumber failed "
280  "for fast_pattern offset");
281  goto error;
282  }
283  uint16_t length;
284  if (StringParseUint16(&length, 10, 0,
285  (const char *)arg_substr) < 0) {
286  SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid value for fast "
287  "pattern: \"%s\"", arg_substr);
288  goto error;
289  }
290 
291  // Avoiding integer overflow
292  if (offset > (65535 - length)) {
293  SCLogError(SC_ERR_INVALID_SIGNATURE, "Fast pattern (length + offset) "
294  "exceeds limit pattern length limit");
295  goto error;
296  }
297 
298  if (offset + length > cd->content_len) {
299  SCLogError(SC_ERR_INVALID_SIGNATURE, "Fast pattern (length + "
300  "offset (%u)) exceeds pattern length (%u)",
301  offset + length, cd->content_len);
302  goto error;
303  }
304 
305  cd->fp_chop_offset = offset;
306  cd->fp_chop_len = length;
308 
309  } else {
310  SCLogError(SC_ERR_PCRE_PARSE, "parse error, ret %" PRId32
311  ", string %s", ret, arg);
312  goto error;
313  }
314 
316 
317  return 0;
318 
319  error:
320  return -1;
321 }
322 
323 /*----------------------------------Unittests---------------------------------*/
324 
325 #ifdef UNITTESTS
326 static int DetectFastPatternStickySingle(const char *sticky, const int list)
327 {
330  char string[1024];
331  snprintf(string, sizeof(string),
332  "alert tcp any any -> any any "
333  "(%s%scontent:\"one\"; fast_pattern; sid:1;)",
334  sticky ? sticky : "", sticky ? "; " : " ");
335  Signature *s = DetectEngineAppendSig(de_ctx, string);
336  FAIL_IF_NULL(s);
337  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
338  FAIL_IF_NULL(sm);
344  PASS;
345 }
346 
347 static int DetectFastPatternModifierSingle(const char *sticky, const int list)
348 {
351  char string[1024];
352  snprintf(string, sizeof(string),
353  "alert tcp any any -> any any "
354  "(content:\"one\"; %s%sfast_pattern; sid:1;)",
355  sticky ? sticky : "", sticky ? "; " : " ");
356  Signature *s = DetectEngineAppendSig(de_ctx, string);
357  FAIL_IF_NULL(s);
358  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
359  FAIL_IF_NULL(sm);
365  PASS;
366 }
367 
368 static int DetectFastPatternStickySingleNoFP(const char *sticky, const int list)
369 {
372  char string[1024];
373  snprintf(string, sizeof(string),
374  "alert tcp any any -> any any "
375  "(%s%scontent:\"one\"; sid:1;)",
376  sticky ? sticky : "", sticky ? "; " : " ");
377  Signature *s = DetectEngineAppendSig(de_ctx, string);
378  FAIL_IF_NULL(s);
379  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
380  FAIL_IF_NULL(sm);
386  PASS;
387 }
388 
389 static int DetectFastPatternModifierSingleNoFP(const char *sticky, const int list)
390 {
393  char string[1024];
394  snprintf(string, sizeof(string),
395  "alert tcp any any -> any any "
396  "(content:\"one\"; %s%ssid:1;)",
397  sticky ? sticky : "", sticky ? "; " : " ");
398  Signature *s = DetectEngineAppendSig(de_ctx, string);
399  FAIL_IF_NULL(s);
400  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
401  FAIL_IF_NULL(sm);
407  PASS;
408 }
409 
410 static int DetectFastPatternStickySingleBadArg(const char *sticky)
411 {
414  char string[1024];
415  /* bogus argument to fast_pattern */
416  snprintf(string, sizeof(string),
417  "alert tcp any any -> any any "
418  "(%s%scontent:\"one\"; fast_pattern:boo; sid:1;)",
419  sticky ? sticky : "", sticky ? "; " : " ");
420  Signature *s = DetectEngineAppendSig(de_ctx, string);
421  FAIL_IF_NOT_NULL(s);
422  /* fast_pattern only with distance */
423  snprintf(string, sizeof(string),
424  "alert tcp any any -> any any "
425  "(%s%scontent:\"one\"; fast_pattern:only; content:\"two\"; distance:10; sid:1;)",
426  sticky ? sticky : "", sticky ? "; " : " ");
427  s = DetectEngineAppendSig(de_ctx, string);
428  FAIL_IF_NOT_NULL(s);
429  /* fast_pattern only with distance */
430  snprintf(string, sizeof(string),
431  "alert tcp any any -> any any "
432  "(%s%scontent:\"one\"; content:\"two\"; fast_pattern:only; distance:10; sid:1;)",
433  sticky ? sticky : "", sticky ? "; " : " ");
434  s = DetectEngineAppendSig(de_ctx, string);
435  FAIL_IF_NOT_NULL(s);
436  /* fast_pattern only with distance */
437  snprintf(string, sizeof(string),
438  "alert tcp any any -> any any "
439  "(%s%scontent:\"one\"; content:\"two\"; distance:10; fast_pattern:only; sid:1;)",
440  sticky ? sticky : "", sticky ? "; " : " ");
441  s = DetectEngineAppendSig(de_ctx, string);
442  FAIL_IF_NOT_NULL(s);
443  /* fast_pattern chop with invalid values */
444  snprintf(string, sizeof(string),
445  "alert tcp any any -> any any "
446  "(%s%scontent:\"one\"; fast_pattern:5,6; sid:1;)",
447  sticky ? sticky : "", sticky ? "; " : " ");
448  s = DetectEngineAppendSig(de_ctx, string);
449  FAIL_IF_NOT_NULL(s);
451  PASS;
452 }
453 
454 static int DetectFastPatternModifierBadRules(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  "(content:\"one\"; %s%sfast_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  "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%sdistance:10; sid:1;)",
470  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
471  s = DetectEngineAppendSig(de_ctx, string);
472  FAIL_IF_NOT_NULL(s);
473 #if 0 // TODO bug?
474  /* fast_pattern only with distance */
475  snprintf(string, sizeof(string), "alert tcp any any -> any any "
476  "(content:\"one\"; %s%s content:\"two\"; %s%sdistance:10; fast_pattern:only; sid:1;)",
477  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
478  s = DetectEngineAppendSig(de_ctx, string);
479  FAIL_IF_NOT_NULL(s);
480 #endif
481  /* fast_pattern only with within */
482  snprintf(string, sizeof(string),
483  "alert tcp any any -> any any "
484  "(content:\"one\"; %s%sfast_pattern:only; content:\"two\"; %s%swithin:10; sid:1;)",
485  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
486  s = DetectEngineAppendSig(de_ctx, string);
487  FAIL_IF_NOT_NULL(s);
488  /* fast_pattern only with within */
489  snprintf(string, sizeof(string),
490  "alert tcp any any -> any any "
491  "(content:\"one\"; %s%s content:\"two\"; %s%swithin:10; fast_pattern:only; sid:1;)",
492  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
493  s = DetectEngineAppendSig(de_ctx, string);
494  FAIL_IF_NOT_NULL(s);
495  /* fast_pattern only with offset */
496  snprintf(string, sizeof(string),
497  "alert tcp any any -> any any "
498  "(content:\"one\"; %s%sfast_pattern:only; offset:10; sid:1;)",
499  sticky ? sticky : "", sticky ? "; " : " ");
500  s = DetectEngineAppendSig(de_ctx, string);
501  FAIL_IF_NOT_NULL(s);
502  /* fast_pattern only with offset */
503  snprintf(string, sizeof(string),
504  "alert tcp any any -> any any "
505  "(content:\"one\"; %s%s offset:10; fast_pattern:only; sid:1;)",
506  sticky ? sticky : "", sticky ? "; " : " ");
507  s = DetectEngineAppendSig(de_ctx, string);
508  FAIL_IF_NOT_NULL(s);
509  /* fast_pattern only with depth */
510  snprintf(string, sizeof(string),
511  "alert tcp any any -> any any "
512  "(content:\"one\"; %s%sfast_pattern:only; depth:10; sid:1;)",
513  sticky ? sticky : "", sticky ? "; " : " ");
514  s = DetectEngineAppendSig(de_ctx, string);
515  FAIL_IF_NOT_NULL(s);
516  /* fast_pattern only with depth */
517  snprintf(string, sizeof(string),
518  "alert tcp any any -> any any "
519  "(content:\"one\"; %s%s depth:10; fast_pattern:only; sid:1;)",
520  sticky ? sticky : "", sticky ? "; " : " ");
521  s = DetectEngineAppendSig(de_ctx, string);
522  FAIL_IF_NOT_NULL(s);
523  /* fast_pattern only negate */
524  snprintf(string, sizeof(string),
525  "alert tcp any any -> any any "
526  "(content:\"one\"; %s%s content:!\"two\"; %s%sfast_pattern:only; sid:1;)",
527  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
528  s = DetectEngineAppendSig(de_ctx, string);
529  FAIL_IF_NOT_NULL(s);
530  /* fast_pattern chop with invalid values */
531  snprintf(string, sizeof(string),
532  "alert tcp any any -> any any "
533  "(content:\"one\"; %s%sfast_pattern:5,6; sid:1;)",
534  sticky ? sticky : "", sticky ? "; " : " ");
535  s = DetectEngineAppendSig(de_ctx, string);
536  FAIL_IF_NOT_NULL(s);
537  /* fast_pattern chop with invalid values */
538  snprintf(string, sizeof(string),
539  "alert tcp any any -> any any "
540  "(content:\"one\"; %s%sfast_pattern:65977,2; sid:1;)",
541  sticky ? sticky : "", sticky ? "; " : " ");
542  s = DetectEngineAppendSig(de_ctx, string);
543  FAIL_IF_NOT_NULL(s);
544  /* fast_pattern chop with invalid values */
545  snprintf(string, sizeof(string),
546  "alert tcp any any -> any any "
547  "(content:\"one\"; %s%sfast_pattern:2,65977; sid:1;)",
548  sticky ? sticky : "", sticky ? "; " : " ");
549  s = DetectEngineAppendSig(de_ctx, string);
550  FAIL_IF_NOT_NULL(s);
551  /* fast_pattern chop with invalid values */
552  snprintf(string, sizeof(string),
553  "alert tcp any any -> any any "
554  "(content:\"one\"; %s%sfast_pattern:2,65534; sid:1;)",
555  sticky ? sticky : "", sticky ? "; " : " ");
556  s = DetectEngineAppendSig(de_ctx, string);
557  FAIL_IF_NOT_NULL(s);
558  /* fast_pattern chop with invalid values */
559  snprintf(string, sizeof(string),
560  "alert tcp any any -> any any "
561  "(content:\"one\"; %s%sfast_pattern:65534,2; sid:1;)",
562  sticky ? sticky : "", sticky ? "; " : " ");
563  s = DetectEngineAppendSig(de_ctx, string);
564  FAIL_IF_NOT_NULL(s);
565  /* negated fast_pattern with distance */
566  snprintf(string, sizeof(string),
567  "alert tcp any any -> any any "
568  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdistance:10; sid:1;)",
569  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
570  s = DetectEngineAppendSig(de_ctx, string);
571  FAIL_IF_NOT_NULL(s);
572  /* negated fast_pattern with within */
573  snprintf(string, sizeof(string),
574  "alert tcp any any -> any any "
575  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%swithin:10; sid:1;)",
576  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
577  s = DetectEngineAppendSig(de_ctx, string);
578  FAIL_IF_NOT_NULL(s);
579  /* negated fast_pattern with depth */
580  snprintf(string, sizeof(string),
581  "alert tcp any any -> any any "
582  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%sdepth:10; sid:1;)",
583  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
584  s = DetectEngineAppendSig(de_ctx, string);
585  FAIL_IF_NOT_NULL(s);
586  /* negated fast_pattern with offset */
587  snprintf(string, sizeof(string),
588  "alert tcp any any -> any any "
589  "(content:\"one\"; %s%scontent:!\"two\"; fast_pattern:1,2; %s%soffset:10; sid:1;)",
590  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
591  s = DetectEngineAppendSig(de_ctx, string);
592  FAIL_IF_NOT_NULL(s);
594  PASS;
595 }
596 
597 static int DetectFastPatternStickySingleFPOnly(const char *sticky, const int list)
598 {
601  char string[1024];
602  snprintf(string, sizeof(string),
603  "alert tcp any any -> any any "
604  "(%s%scontent:\"one\"; fast_pattern:only; sid:1;)",
605  sticky ? sticky : "", sticky ? "; " : " ");
606  Signature *s = DetectEngineAppendSig(de_ctx, string);
607  FAIL_IF_NULL(s);
608  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
609  FAIL_IF_NULL(sm);
616  PASS;
617 }
618 
619 static int DetectFastPatternModifierFPOnly(const char *sticky, const int list)
620 {
623  char string[1024];
624  snprintf(string, sizeof(string),
625  "alert tcp any any -> any any "
626  "(content:\"one\"; %s%sfast_pattern:only; sid:1;)",
627  sticky ? sticky : "", sticky ? "; " : " ");
628  Signature *s = DetectEngineAppendSig(de_ctx, string);
629  FAIL_IF_NULL(s);
630  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
631  FAIL_IF_NULL(sm);
637 
638  snprintf(string, sizeof(string),
639  "alert tcp any any -> any any "
640  "(content:\"one\"; %s%scontent:\"two\"; %s%sfast_pattern:only; sid:2;)",
641  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
642  s = DetectEngineAppendSig(de_ctx, string);
643  FAIL_IF_NULL(s);
644  sm = de_ctx->sig_list->sm_lists[list];
645  FAIL_IF_NULL(sm);
646  FAIL_IF_NULL(sm->next);
648  cd = (DetectContentData *)sm->ctx;
650  FAIL_IF_NOT(
652  sm = sm->next;
654  cd = (DetectContentData *)sm->ctx;
658 
659  snprintf(string, sizeof(string),
660  "alert tcp any any -> any any "
661  "(content:\"one\"; %s%scontent:\"two\"; distance:10; %s%scontent:\"three\"; "
662  "%s%sfast_pattern:only; sid:3;)",
663  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
664  sticky ? sticky : "", sticky ? "; " : " ");
665  s = DetectEngineAppendSig(de_ctx, string);
666  FAIL_IF_NULL(s);
667  sm = de_ctx->sig_list->sm_lists[list];
668  FAIL_IF_NULL(sm);
669  FAIL_IF_NULL(sm->next);
671  cd = (DetectContentData *)sm->ctx;
673  FAIL_IF_NOT(
675  sm = sm->next;
676  FAIL_IF_NULL(sm->next);
678  cd = (DetectContentData *)sm->ctx;
680  FAIL_IF_NOT(
682  sm = sm->next;
683  FAIL_IF_NOT_NULL(sm->next);
685  cd = (DetectContentData *)sm->ctx;
689 
690  snprintf(string, sizeof(string),
691  "alert tcp any any -> any any "
692  "(content:\"one\"; %s%scontent:\"two\"; within:10; %s%scontent:\"three\"; "
693  "%s%sfast_pattern:only; sid:4;)",
694  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
695  sticky ? sticky : "", sticky ? "; " : " ");
696  s = DetectEngineAppendSig(de_ctx, string);
697  FAIL_IF_NULL(s);
698  sm = de_ctx->sig_list->sm_lists[list];
699  FAIL_IF_NULL(sm);
700  FAIL_IF_NULL(sm->next);
702  cd = (DetectContentData *)sm->ctx;
704  FAIL_IF_NOT(
706  sm = sm->next;
707  FAIL_IF_NULL(sm->next);
709  cd = (DetectContentData *)sm->ctx;
711  FAIL_IF_NOT(
713  sm = sm->next;
714  FAIL_IF_NOT_NULL(sm->next);
716  cd = (DetectContentData *)sm->ctx;
720 
721  snprintf(string, sizeof(string),
722  "alert tcp any any -> any any "
723  "(content:\"one\"; %s%scontent:\"two\"; offset:10; %s%scontent:\"three\"; "
724  "%s%sfast_pattern:only; sid:5;)",
725  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
726  sticky ? sticky : "", sticky ? "; " : " ");
727  s = DetectEngineAppendSig(de_ctx, string);
728  FAIL_IF_NULL(s);
729  sm = de_ctx->sig_list->sm_lists[list];
730  FAIL_IF_NULL(sm);
731  FAIL_IF_NULL(sm->next);
733  cd = (DetectContentData *)sm->ctx;
735  FAIL_IF_NOT(
737  sm = sm->next;
738  FAIL_IF_NULL(sm->next);
740  cd = (DetectContentData *)sm->ctx;
742  FAIL_IF_NOT(
744  sm = sm->next;
745  FAIL_IF_NOT_NULL(sm->next);
747  cd = (DetectContentData *)sm->ctx;
751 
752  snprintf(string, sizeof(string),
753  "alert tcp any any -> any any "
754  "(content:\"one\"; %s%scontent:\"two\"; depth:10; %s%scontent:\"three\"; "
755  "%s%sfast_pattern:only; sid:6;)",
756  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ",
757  sticky ? sticky : "", sticky ? "; " : " ");
758  s = DetectEngineAppendSig(de_ctx, string);
759  FAIL_IF_NULL(s);
760  sm = de_ctx->sig_list->sm_lists[list];
761  FAIL_IF_NULL(sm);
762  FAIL_IF_NULL(sm->next);
764  cd = (DetectContentData *)sm->ctx;
766  FAIL_IF_NOT(
768  sm = sm->next;
769  FAIL_IF_NULL(sm->next);
771  cd = (DetectContentData *)sm->ctx;
773  FAIL_IF_NOT(
775  sm = sm->next;
776  FAIL_IF_NOT_NULL(sm->next);
778  cd = (DetectContentData *)sm->ctx;
782 
783  snprintf(string, sizeof(string),
784  "alert tcp any any -> any any "
785  "(content:!\"one\"; %s%sfast_pattern; content:\"two\"; depth:10; %s%ssid:7;)",
786  sticky ? sticky : "", sticky ? "; " : " ", sticky ? sticky : "", sticky ? "; " : " ");
787  s = DetectEngineAppendSig(de_ctx, string);
788  FAIL_IF_NULL(s);
789  sm = de_ctx->sig_list->sm_lists[list];
790  FAIL_IF_NULL(sm);
791  FAIL_IF_NULL(sm->next);
793  cd = (DetectContentData *)sm->ctx;
798  sm = sm->next;
799  FAIL_IF_NOT_NULL(sm->next);
801  cd = (DetectContentData *)sm->ctx;
803  FAIL_IF_NOT(
805 
807  PASS;
808 }
809 
810 static int DetectFastPatternStickyFPChop(const char *sticky, const int list)
811 {
814  char string[1024];
815  snprintf(string, sizeof(string),
816  "alert tcp any any -> any any "
817  "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; sid:1;)",
818  sticky ? sticky : "", sticky ? "; " : " ");
819  Signature *s = DetectEngineAppendSig(de_ctx, string);
820  FAIL_IF_NULL(s);
821  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
822  FAIL_IF_NULL(sm);
829  FAIL_IF_NOT(cd->fp_chop_offset == 3);
830  FAIL_IF_NOT(cd->fp_chop_len == 4);
831 
832  snprintf(string, sizeof(string),
833  "alert tcp any any -> any any "
834  "(%s%scontent:\"onetwothree\"; fast_pattern:3,4; content:\"xyz\"; distance:10; sid:2;)",
835  sticky ? sticky : "", sticky ? "; " : " ");
836  s = DetectEngineAppendSig(de_ctx, string);
837  FAIL_IF_NULL(s);
838  sm = de_ctx->sig_list->sm_lists[list];
839  FAIL_IF_NULL(sm);
841  cd = (DetectContentData *)sm->ctx;
846  FAIL_IF_NOT(cd->fp_chop_offset == 3);
847  FAIL_IF_NOT(cd->fp_chop_len == 4);
848 
850  PASS;
851 }
852 
853 static int DetectFastPatternModifierFPChop(const char *sticky, const int list)
854 {
857  char string[1024];
858  snprintf(string, sizeof(string),
859  "alert tcp any any -> any any "
860  "(content:\"onetwothree\"; %s%sfast_pattern:3,4; sid:1;)",
861  sticky ? sticky : "", sticky ? "; " : " ");
862  Signature *s = DetectEngineAppendSig(de_ctx, string);
863  FAIL_IF_NULL(s);
864  SigMatch *sm = de_ctx->sig_list->sm_lists[list];
865  FAIL_IF_NULL(sm);
872  FAIL_IF_NOT(cd->fp_chop_offset == 3);
873  FAIL_IF_NOT(cd->fp_chop_len == 4);
874 
875  snprintf(string, sizeof(string),
876  "alert tcp any any -> any any "
877  "(content:!\"onetwothree\"; %s%sfast_pattern:3,4; sid:2;)",
878  sticky ? sticky : "", sticky ? "; " : " ");
879  s = DetectEngineAppendSig(de_ctx, string);
880  FAIL_IF_NULL(s);
881  sm = de_ctx->sig_list->sm_lists[list];
882  FAIL_IF_NULL(sm);
884  cd = (DetectContentData *)sm->ctx;
891  FAIL_IF_NOT(cd->fp_chop_offset == 3);
892  FAIL_IF_NOT(cd->fp_chop_len == 4);
893 
895  PASS;
896 }
897 
898 /**
899  * \test Checks if a fast_pattern is registered in a Signature
900  */
901 static int DetectFastPatternTest01(void)
902 {
903  FAIL_IF_NOT(DetectFastPatternStickySingle(NULL, DETECT_SM_LIST_PMATCH));
904  FAIL_IF_NOT(DetectFastPatternModifierSingle(NULL, DETECT_SM_LIST_PMATCH));
905  FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(NULL, DETECT_SM_LIST_PMATCH));
906  FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(NULL, DETECT_SM_LIST_PMATCH));
907  FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(NULL));
908  FAIL_IF_NOT(DetectFastPatternModifierBadRules(NULL));
909  FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(NULL, DETECT_SM_LIST_PMATCH));
910  FAIL_IF_NOT(DetectFastPatternModifierFPOnly(NULL, DETECT_SM_LIST_PMATCH));
911  FAIL_IF_NOT(DetectFastPatternStickyFPChop(NULL, DETECT_SM_LIST_PMATCH));
912  FAIL_IF_NOT(DetectFastPatternModifierFPChop(NULL, DETECT_SM_LIST_PMATCH));
913 
914  struct {
915  const char *buffer_name;
916  const char *sb_name;
917  const char *mod_name;
918  } keywords[] = {
919  { "file_data", "file.data", NULL },
920  { "http_uri", "http.uri", "http_uri" },
921  { "http_raw_uri", "http.uri.raw", "http_raw_uri" },
922  { "http_user_agent", "http.user_agent", "http_user_agent" },
923  { "http_header", "http.header", "http_header" },
924  // http_raw_header requires sigs to have a direction
925  //{ "http_raw_header", "http.header.raw", "http_raw_header" },
926  { "http_method", "http.method", "http_method" },
927  { "http_cookie", "http.cookie", "http_cookie" },
928  { "http_host", "http.host", "http_host" },
929  { "http_raw_host", "http.host.raw", "http_raw_host" },
930  { "http_stat_code", "http.stat_code", "http_stat_code" },
931  { "http_stat_msg", "http.stat_msg", "http_stat_msg" },
932  { "http_client_body", "http.request_body", "http_client_body" },
933  { NULL, NULL, NULL },
934  };
935 
936  for (int i = 0; keywords[i].buffer_name != NULL; i++) {
937  const int list_id = DetectBufferTypeGetByName(keywords[i].buffer_name);
938  FAIL_IF(list_id == -1);
939 
940  const char *k = keywords[i].sb_name;
941  if (k) {
942  FAIL_IF_NOT(DetectFastPatternStickySingle(k, list_id));
943  FAIL_IF_NOT(DetectFastPatternStickySingleNoFP(k, list_id));
944  FAIL_IF_NOT(DetectFastPatternStickySingleBadArg(k));
945  FAIL_IF_NOT(DetectFastPatternStickySingleFPOnly(k, list_id));
946  FAIL_IF_NOT(DetectFastPatternStickyFPChop(k, list_id));
947  }
948  k = keywords[i].mod_name;
949  if (k) {
950  FAIL_IF_NOT(DetectFastPatternModifierSingle(k, list_id));
951  FAIL_IF_NOT(DetectFastPatternModifierSingleNoFP(k, list_id));
952  FAIL_IF_NOT(DetectFastPatternModifierBadRules(k));
953  FAIL_IF_NOT(DetectFastPatternModifierFPOnly(k, list_id));
954  FAIL_IF_NOT(DetectFastPatternModifierFPChop(k, list_id));
955  }
956  }
957 
958  PASS;
959 }
960 
961 /**
962  * \test Checks to make sure that other sigs work that should when fast_pattern is inspecting on the
963  * same payload
964  *
965  */
966 static int DetectFastPatternTest14(void)
967 {
968  uint8_t *buf = (uint8_t *)"Dummy is our name. Oh yes. From right here "
969  "right now, all the way to hangover. right. strings5_imp now here "
970  "comes our dark knight strings_string5. Yes here is our dark knight";
971  uint16_t buflen = strlen((char *)buf);
972  ThreadVars th_v;
973  DetectEngineThreadCtx *det_ctx = NULL;
974 
975  memset(&th_v, 0, sizeof(th_v));
976  Packet *p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
977  FAIL_IF_NULL(p);
978 
981  de_ctx->flags |= DE_QUIET;
982 
984 
986  "alert tcp any any -> any any "
987  "(msg:\"fast_pattern test\"; content:\"strings_string5\"; content:\"knight\"; "
988  "fast_pattern; sid:1;)");
989  FAIL_IF_NULL(s);
990 
992  "alert tcp any any -> any any "
993  "(msg:\"test different content\"; content:\"Dummy is our name\"; sid:2;)");
994  FAIL_IF_NULL(s);
995 
997  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
998 
999  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1002 
1003  UTHFreePackets(&p, 1);
1004  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1006  FlowShutdown();
1007  PASS;
1008 }
1009 
1010 /**
1011  * Unittest to check
1012  * - if we assign different content_ids to duplicate patterns, but one of the
1013  * patterns has a fast_pattern chop set.
1014  * - if 2 unique patterns get unique ids.
1015  * - if 2 duplicate patterns, with no chop set get unique ids.
1016  */
1017 static int DetectFastPatternTest671(void)
1018 {
1021  de_ctx->flags |= DE_QUIET;
1022 
1023  Signature *s[6];
1024  s[0] = DetectEngineAppendSig(
1025  de_ctx, "alert tcp any any -> any any (content:\"onetwothreefour\"; sid:1;)");
1026  FAIL_IF_NULL(s[0]);
1027  s[1] = DetectEngineAppendSig(
1028  de_ctx, "alert tcp any any -> any any (content:\"onetwothreefour\"; sid:2;)");
1029  FAIL_IF_NULL(s[1]);
1030  s[2] = DetectEngineAppendSig(
1031  de_ctx, "alert tcp any any -> any any (content:\"uniquepattern\"; sid:3;)");
1032  FAIL_IF_NULL(s[2]);
1034  "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:3,5; sid:4;)");
1035  FAIL_IF_NULL(s[3]);
1036  s[4] = DetectEngineAppendSig(
1037  de_ctx, "alert tcp any any -> any any (content:\"twoth\"; sid:5;)");
1038  FAIL_IF_NULL(s[4]);
1040  "alert tcp any any -> any any (content:\"onetwothreefour\"; fast_pattern:0,15; "
1041  "sid:6;)");
1042  FAIL_IF_NULL(s[5]);
1043 
1045 
1047  DetectContentData *cd = (DetectContentData *)smd->ctx;
1048  FAIL_IF(cd->id != 0);
1049 
1050  smd = s[1]->sm_arrays[DETECT_SM_LIST_PMATCH];
1051  cd = (DetectContentData *)smd->ctx;
1052  FAIL_IF(cd->id != 0);
1053 
1054  smd = s[2]->sm_arrays[DETECT_SM_LIST_PMATCH];
1055  cd = (DetectContentData *)smd->ctx;
1056  FAIL_IF(cd->id != 2);
1057 
1058  smd = s[3]->sm_arrays[DETECT_SM_LIST_PMATCH];
1059  cd = (DetectContentData *)smd->ctx;
1060  FAIL_IF(cd->id != 1);
1061 
1062  smd = s[4]->sm_arrays[DETECT_SM_LIST_PMATCH];
1063  cd = (DetectContentData *)smd->ctx;
1064  FAIL_IF(cd->id != 1);
1065 
1066  smd = s[5]->sm_arrays[DETECT_SM_LIST_PMATCH];
1067  cd = (DetectContentData *)smd->ctx;
1068  FAIL_IF(cd->id != 0);
1069 
1071  PASS;
1072 }
1073 
1074 static int DetectFastPatternPrefilter(void)
1075 {
1078  const char *string = "alert tcp any any -> any any "
1079  "(content:\"one\"; prefilter; sid:1;)";
1080  Signature *s = DetectEngineAppendSig(de_ctx, string);
1081  FAIL_IF_NULL(s);
1082  SigMatch *sm = de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH];
1083  FAIL_IF_NULL(sm);
1089  PASS;
1090 }
1091 
1092 static void DetectFastPatternRegisterTests(void)
1093 {
1094  UtRegisterTest("DetectFastPatternTest01", DetectFastPatternTest01);
1095  UtRegisterTest("DetectFastPatternTest14", DetectFastPatternTest14);
1096  /* Unittest to check
1097  * - if we assign different content_ids to duplicate patterns, but one of the
1098  * patterns has a fast_pattern chop set.
1099  * - if 2 unique patterns get unique ids.
1100  * - if 2 duplicate patterns, with no chop set get unique ids.
1101  */
1102  UtRegisterTest("DetectFastPatternTest671", DetectFastPatternTest671);
1103 
1104  UtRegisterTest("DetectFastPatternPrefilter", DetectFastPatternPrefilter);
1105 }
1106 #endif
util-byte.h
SCFPSupportSMList_
Definition: detect-fast-pattern.h:27
DetectParseRegex::match
pcre2_match_data * match
Definition: detect-parse.h:45
SigTableElmt_::url
const char * url
Definition: detect.h:1204
detect-content.h
detect-engine.h
StringParseUint16
int StringParseUint16(uint16_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:336
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:1203
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, const char *str, int start_offset, int options)
Definition: detect-parse.c:2435
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1191
SCFPSupportSMList_::next
struct SCFPSupportSMList_ * next
Definition: detect-fast-pattern.h:32
DetectParseRegex
Definition: detect-parse.h:42
SigTableElmt_::name
const char * name
Definition: detect.h:1201
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
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:138
DETECT_FAST_PATTERN
@ DETECT_FAST_PATTERN
Definition: detect-engine-register.h:71
SigMatchData_::ctx
SigMatchCtx * ctx
Definition: detect.h:332
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1195
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:758
SC_ERR_INVALID_SIGNATURE
@ SC_ERR_INVALID_SIGNATURE
Definition: util-error.h:69
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2068
SupportFastPatternForSigMatchTypes
void SupportFastPatternForSigMatchTypes(void)
Registers the keywords(SMs) that should be given fp support.
Definition: detect-fast-pattern.c:135
DE_QUIET
#define DE_QUIET
Definition: detect.h:294
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:1653
Signature_::sm_arrays
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
Definition: detect.h:571
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:329
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1186
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 to true.
Definition: util-unittest.h:82
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:829
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:1003
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:2558
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:324
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:323
sm_fp_support_smlist_list
SCFPSupportSMList * sm_fp_support_smlist_list
Definition: detect-fast-pattern.c:52
Packet_
Definition: decode.h:414
DetectContentData_::flags
uint32_t flags
Definition: detect-content.h:97
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:587
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:1169
SignatureInitData_::smlists
struct SigMatch_ ** smlists
Definition: detect.h:511
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:1932
SigMatch_::type
uint8_t type
Definition: detect.h:321
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:2381
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:2772
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:2980
SigMatch_::idx
uint16_t idx
Definition: detect.h:322
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:651
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:82
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
DetectBufferTypeSupportsMpmGetById
bool DetectBufferTypeSupportsMpmGetById(const DetectEngineCtx *de_ctx, const int id)
Definition: detect-engine.c:893
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:764
SIGMATCH_OPTIONAL_OPT
#define SIGMATCH_OPTIONAL_OPT
Definition: detect.h:1382
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
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:517
SigMatch_
a single match condition for a signature
Definition: detect.h:320
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2023
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:42
DetectFastPatternRegister
void DetectFastPatternRegister(void)
Registration function for fast_pattern keyword.
Definition: detect-fast-pattern.c:145
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:759
flow.h
DETECT_CONTENT_FAST_PATTERN
#define DETECT_CONTENT_FAST_PATTERN
Definition: detect-content.h:34
DETECT_CONTENT_WITHIN
#define DETECT_CONTENT_WITHIN
Definition: detect-content.h:31
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1193
SignatureInitData_::smlists_array_size
uint32_t smlists_array_size
Definition: detect.h:509
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