suricata
detect-flow.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2020 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 Victor Julien <victor@inliniac.net>
22  *
23  * FLOW part of the detection engine.
24  */
25 
26 #include "suricata-common.h"
27 #include "debug.h"
28 #include "decode.h"
29 
30 #include "detect.h"
31 #include "detect-parse.h"
32 #include "detect-engine.h"
34 
35 #include "flow.h"
36 #include "flow-var.h"
37 
38 #include "detect-flow.h"
39 
40 #include "util-unittest.h"
41 #include "util-unittest-helper.h"
42 #include "util-debug.h"
43 
44 /**
45  * \brief Regex for parsing our flow options
46  */
47 #define PARSE_REGEX "^\\s*([A-z_]+)\\s*(?:,\\s*([A-z_]+))?\\s*(?:,\\s*([A-z_]+))?\\s*$"
48 
49 static DetectParseRegex parse_regex;
50 
52  const Signature *, const SigMatchCtx *);
53 static int DetectFlowSetup (DetectEngineCtx *, Signature *, const char *);
54 #ifdef UNITTESTS
55 static void DetectFlowRegisterTests(void);
56 #endif
57 void DetectFlowFree(DetectEngineCtx *, void *);
58 
59 static int PrefilterSetupFlow(DetectEngineCtx *de_ctx, SigGroupHead *sgh);
60 static bool PrefilterFlowIsPrefilterable(const Signature *s);
61 
62 /**
63  * \brief Registration function for flow: keyword
64  */
65 void DetectFlowRegister (void)
66 {
68  sigmatch_table[DETECT_FLOW].desc = "match on direction and state of the flow";
69  sigmatch_table[DETECT_FLOW].url = "/rules/flow-keywords.html#flow";
71  sigmatch_table[DETECT_FLOW].Setup = DetectFlowSetup;
73 #ifdef UNITTESTS
74  sigmatch_table[DETECT_FLOW].RegisterTests = DetectFlowRegisterTests;
75 #endif
76  sigmatch_table[DETECT_FLOW].SupportsPrefilter = PrefilterFlowIsPrefilterable;
77  sigmatch_table[DETECT_FLOW].SetupPrefilter = PrefilterSetupFlow;
78 
79  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
80 }
81 
82 /**
83  * \param pflags packet flags (p->flags)
84  * \param pflowflags packet flow flags (p->flowflags)
85  * \param tflags detection flags (det_ctx->flags)
86  * \param dflags detect flow flags
87  * \param match_cnt number of matches to trigger
88  */
89 static inline int FlowMatch(const uint32_t pflags, const uint8_t pflowflags,
90  const uint16_t tflags, const uint16_t dflags, const uint8_t match_cnt)
91 {
92  uint8_t cnt = 0;
93 
94  if ((dflags & DETECT_FLOW_FLAG_NO_FRAG) &&
95  (!(pflags & PKT_REBUILT_FRAGMENT))) {
96  cnt++;
97  } else if ((dflags & DETECT_FLOW_FLAG_ONLY_FRAG) &&
98  (pflags & PKT_REBUILT_FRAGMENT)) {
99  cnt++;
100  }
101 
102  if ((dflags & DETECT_FLOW_FLAG_TOSERVER) && (pflowflags & FLOW_PKT_TOSERVER)) {
103  cnt++;
104  } else if ((dflags & DETECT_FLOW_FLAG_TOCLIENT) && (pflowflags & FLOW_PKT_TOCLIENT)) {
105  cnt++;
106  }
107 
108  if ((dflags & DETECT_FLOW_FLAG_ESTABLISHED) && (pflowflags & FLOW_PKT_ESTABLISHED)) {
109  cnt++;
110  } else if (dflags & DETECT_FLOW_FLAG_NOT_ESTABLISHED && (!(pflowflags & FLOW_PKT_ESTABLISHED))) {
111  cnt++;
112  } else if (dflags & DETECT_FLOW_FLAG_STATELESS) {
113  cnt++;
114  }
115 
117  if (dflags & DETECT_FLOW_FLAG_ONLYSTREAM)
118  cnt++;
119  } else {
120  if (dflags & DETECT_FLOW_FLAG_NOSTREAM)
121  cnt++;
122  }
123 
124  return (match_cnt == cnt) ? 1 : 0;
125 }
126 
127 /**
128  * \brief This function is used to match flow flags set on a packet with those passed via flow:
129  *
130  * \param t pointer to thread vars
131  * \param det_ctx pointer to the pattern matcher thread
132  * \param p pointer to the current packet
133  * \param m pointer to the sigmatch that we will cast into DetectFlowData
134  *
135  * \retval 0 no match
136  * \retval 1 match
137  */
139  const Signature *s, const SigMatchCtx *ctx)
140 {
141  SCEnter();
142 
143  SCLogDebug("pkt %p", p);
144 
145  if (p->flowflags & FLOW_PKT_TOSERVER) {
146  SCLogDebug("FLOW_PKT_TOSERVER");
147  } else if (p->flowflags & FLOW_PKT_TOCLIENT) {
148  SCLogDebug("FLOW_PKT_TOCLIENT");
149  }
150 
151  if (p->flowflags & FLOW_PKT_ESTABLISHED) {
152  SCLogDebug("FLOW_PKT_ESTABLISHED");
153  }
154 
155  const DetectFlowData *fd = (const DetectFlowData *)ctx;
156 
157  const int ret = FlowMatch(p->flags, p->flowflags, det_ctx->flags, fd->flags, fd->match_cnt);
158  SCLogDebug("returning %" PRId32 " fd->match_cnt %" PRId32 " fd->flags 0x%02X p->flowflags 0x%02X",
159  ret, fd->match_cnt, fd->flags, p->flowflags);
160  SCReturnInt(ret);
161 }
162 
163 /**
164  * \brief This function is used to parse flow options passed via flow: keyword
165  *
166  * \param de_ctx Pointer to the detection engine context
167  * \param flowstr Pointer to the user provided flow options
168  *
169  * \retval fd pointer to DetectFlowData on success
170  * \retval NULL on failure
171  */
172 static DetectFlowData *DetectFlowParse (DetectEngineCtx *de_ctx, const char *flowstr)
173 {
174  DetectFlowData *fd = NULL;
175  char *args[3] = {NULL,NULL,NULL};
176  int ret = 0, res = 0;
177  int ov[MAX_SUBSTRINGS];
178  char str1[16] = "", str2[16] = "", str3[16] = "";
179 
180  ret = DetectParsePcreExec(&parse_regex, flowstr, 0, 0, ov, MAX_SUBSTRINGS);
181  if (ret < 1 || ret > 4) {
182  SCLogError(SC_ERR_PCRE_MATCH, "parse error, ret %" PRId32 ", string %s", ret, flowstr);
183  goto error;
184  }
185 
186  if (ret > 1) {
187  res = pcre_copy_substring((char *)flowstr, ov, MAX_SUBSTRINGS, 1, str1, sizeof(str1));
188  if (res < 0) {
189  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
190  goto error;
191  }
192  args[0] = (char *)str1;
193 
194  if (ret > 2) {
195  res = pcre_copy_substring((char *)flowstr, ov, MAX_SUBSTRINGS, 2, str2, sizeof(str2));
196  if (res < 0) {
197  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
198  goto error;
199  }
200  args[1] = (char *)str2;
201  }
202  if (ret > 3) {
203  res = pcre_copy_substring((char *)flowstr, ov, MAX_SUBSTRINGS, 3, str3, sizeof(str3));
204  if (res < 0) {
205  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
206  goto error;
207  }
208  args[2] = (char *)str3;
209  }
210  }
211 
212  fd = SCMalloc(sizeof(DetectFlowData));
213  if (unlikely(fd == NULL))
214  goto error;
215  fd->flags = 0;
216  fd->match_cnt = 0;
217 
218  int i;
219  for (i = 0; i < (ret - 1); i++) {
220  if (args[i]) {
221  /* inspect our options and set the flags */
222  if (strcasecmp(args[i], "established") == 0) {
224  SCLogError(SC_ERR_FLAGS_MODIFIER, "DETECT_FLOW_FLAG_ESTABLISHED flag is already set");
225  goto error;
226  } else if (fd->flags & DETECT_FLOW_FLAG_STATELESS) {
227  SCLogError(SC_ERR_FLAGS_MODIFIER, "DETECT_FLOW_FLAG_STATELESS already set");
228  goto error;
229  }
231  } else if (strcasecmp(args[i], "not_established") == 0) {
233  SCLogError(SC_ERR_FLAGS_MODIFIER, "DETECT_FLOW_FLAG_NOT_ESTABLISHED flag is already set");
234  goto error;
235  } else if (fd->flags & DETECT_FLOW_FLAG_NOT_ESTABLISHED) {
236  SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set DETECT_FLOW_FLAG_NOT_ESTABLISHED, DETECT_FLOW_FLAG_ESTABLISHED already set");
237  goto error;
238  }
240  } else if (strcasecmp(args[i], "stateless") == 0) {
241  if (fd->flags & DETECT_FLOW_FLAG_STATELESS) {
242  SCLogError(SC_ERR_FLAGS_MODIFIER, "DETECT_FLOW_FLAG_STATELESS flag is already set");
243  goto error;
244  } else if (fd->flags & DETECT_FLOW_FLAG_ESTABLISHED) {
245  SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set DETECT_FLOW_FLAG_STATELESS, DETECT_FLOW_FLAG_ESTABLISHED already set");
246  goto error;
247  }
249  } else if (strcasecmp(args[i], "to_client") == 0 || strcasecmp(args[i], "from_server") == 0) {
250  if (fd->flags & DETECT_FLOW_FLAG_TOCLIENT) {
251  SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set DETECT_FLOW_FLAG_TOCLIENT flag is already set");
252  goto error;
253  } else if (fd->flags & DETECT_FLOW_FLAG_TOSERVER) {
254  SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set to_client, DETECT_FLOW_FLAG_TOSERVER already set");
255  goto error;
256  }
258  } else if (strcasecmp(args[i], "to_server") == 0 || strcasecmp(args[i], "from_client") == 0){
259  if (fd->flags & DETECT_FLOW_FLAG_TOSERVER) {
260  SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set DETECT_FLOW_FLAG_TOSERVER flag is already set");
261  goto error;
262  } else if (fd->flags & DETECT_FLOW_FLAG_TOCLIENT) {
263  SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set to_server, DETECT_FLOW_FLAG_TO_CLIENT flag already set");
264  goto error;
265  }
267  } else if (strcasecmp(args[i], "only_stream") == 0) {
269  SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set only_stream flag is already set");
270  goto error;
271  } else if (fd->flags & DETECT_FLOW_FLAG_NOSTREAM) {
272  SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set only_stream flag, DETECT_FLOW_FLAG_NOSTREAM already set");
273  goto error;
274  }
276  } else if (strcasecmp(args[i], "no_stream") == 0) {
277  if (fd->flags & DETECT_FLOW_FLAG_NOSTREAM) {
278  SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set no_stream flag is already set");
279  goto error;
280  } else if (fd->flags & DETECT_FLOW_FLAG_ONLYSTREAM) {
281  SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set no_stream flag, DETECT_FLOW_FLAG_ONLYSTREAM already set");
282  goto error;
283  }
285  } else if (strcasecmp(args[i], "no_frag") == 0) {
286  if (fd->flags & DETECT_FLOW_FLAG_NO_FRAG) {
287  SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set no_frag flag is already set");
288  goto error;
289  } else if (fd->flags & DETECT_FLOW_FLAG_ONLY_FRAG) {
290  SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set no_frag flag, only_frag already set");
291  goto error;
292  }
294  } else if (strcasecmp(args[i], "only_frag") == 0) {
295  if (fd->flags & DETECT_FLOW_FLAG_ONLY_FRAG) {
296  SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set only_frag flag is already set");
297  goto error;
298  } else if (fd->flags & DETECT_FLOW_FLAG_NO_FRAG) {
299  SCLogError(SC_ERR_FLAGS_MODIFIER, "cannot set only_frag flag, no_frag already set");
300  goto error;
301  }
303  } else {
304  SCLogError(SC_ERR_INVALID_VALUE, "invalid flow option \"%s\"", args[i]);
305  goto error;
306  }
307 
308  fd->match_cnt++;
309  //printf("args[%" PRId32 "]: %s match_cnt: %" PRId32 " flags: 0x%02X\n", i, args[i], fd->match_cnt, fd->flags);
310  }
311  }
312  return fd;
313 
314 error:
315  if (fd != NULL)
316  DetectFlowFree(de_ctx, fd);
317  return NULL;
318 
319 }
320 
322 {
323 #define SIG_FLAG_BOTH (SIG_FLAG_TOSERVER|SIG_FLAG_TOCLIENT)
324  BUG_ON(flags == 0);
327 
328  SCLogDebug("want %08lx", flags & SIG_FLAG_BOTH);
329  SCLogDebug("have %08lx", s->flags & SIG_FLAG_BOTH);
330 
331  if (flags & SIG_FLAG_TOSERVER) {
332  if ((s->flags & SIG_FLAG_BOTH) == SIG_FLAG_BOTH) {
333  /* both is set if we just have 'flow:established' */
334  s->flags &= ~SIG_FLAG_TOCLIENT;
335  } else if (s->flags & SIG_FLAG_TOCLIENT) {
336  return -1;
337  }
338  s->flags |= SIG_FLAG_TOSERVER;
339  } else {
340  if ((s->flags & SIG_FLAG_BOTH) == SIG_FLAG_BOTH) {
341  /* both is set if we just have 'flow:established' */
342  s->flags &= ~SIG_FLAG_TOSERVER;
343  } else if (s->flags & SIG_FLAG_TOSERVER) {
344  return -1;
345  }
346  s->flags |= SIG_FLAG_TOCLIENT;
347  }
348  return 0;
349 #undef SIG_FLAG_BOTH
350 }
351 
352 /**
353  * \brief this function is used to add the parsed flowdata into the current signature
354  *
355  * \param de_ctx pointer to the Detection Engine Context
356  * \param s pointer to the Current Signature
357  * \param flowstr pointer to the user provided flow options
358  *
359  * \retval 0 on Success
360  * \retval -1 on Failure
361  */
362 int DetectFlowSetup (DetectEngineCtx *de_ctx, Signature *s, const char *flowstr)
363 {
364  /* ensure only one flow option */
366  SCLogError (SC_ERR_INVALID_SIGNATURE, "A signature may have only one flow option.");
367  return -1;
368  }
369 
370  DetectFlowData *fd = DetectFlowParse(de_ctx, flowstr);
371  if (fd == NULL)
372  return -1;
373 
374  SigMatch *sm = SigMatchAlloc();
375  if (sm == NULL)
376  goto error;
377 
378  sm->type = DETECT_FLOW;
379  sm->ctx = (SigMatchCtx *)fd;
380 
381  /* set the signature direction flags */
382  if (fd->flags & DETECT_FLOW_FLAG_TOSERVER) {
383  s->flags |= SIG_FLAG_TOSERVER;
384  } else if (fd->flags & DETECT_FLOW_FLAG_TOCLIENT) {
385  s->flags |= SIG_FLAG_TOCLIENT;
386  } else {
387  s->flags |= SIG_FLAG_TOSERVER;
388  s->flags |= SIG_FLAG_TOCLIENT;
389  }
392  }
393  if (fd->flags & DETECT_FLOW_FLAG_NOSTREAM) {
395  } else if (fd->flags == DETECT_FLOW_FLAG_TOSERVER ||
397  {
398  /* no direct flow is needed for just direction,
399  * no sigmatch is needed either. */
400  SigMatchFree(de_ctx, sm);
401  sm = NULL;
402  } else {
404  }
405 
406  if (sm != NULL) {
408  }
409  return 0;
410 
411 error:
412  if (fd != NULL)
413  DetectFlowFree(de_ctx, fd);
414  return -1;
415 
416 }
417 
418 /**
419  * \brief this function will free memory associated with DetectFlowData
420  *
421  * \param fd pointer to DetectFlowData
422  */
424 {
425  DetectFlowData *fd = (DetectFlowData *)ptr;
426  SCFree(fd);
427 }
428 
429 static void
430 PrefilterPacketFlowMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
431 {
432  const PrefilterPacketHeaderCtx *ctx = pectx;
433 
434  if (PrefilterPacketHeaderExtraMatch(ctx, p) == FALSE)
435  return;
436 
437  if (FlowMatch(p->flags, p->flowflags, det_ctx->flags, ctx->v1.u8[0], ctx->v1.u8[1]))
438  {
439  PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
440  }
441 }
442 
443 static void
444 PrefilterPacketFlowSet(PrefilterPacketHeaderValue *v, void *smctx)
445 {
446  const DetectFlowData *fb = smctx;
447  v->u8[0] = fb->flags;
448  v->u8[1] = fb->match_cnt;
449 }
450 
451 static bool
452 PrefilterPacketFlowCompare(PrefilterPacketHeaderValue v, void *smctx)
453 {
454  const DetectFlowData *fb = smctx;
455  if (v.u8[0] == fb->flags &&
456  v.u8[1] == fb->match_cnt)
457  {
458  return TRUE;
459  }
460  return FALSE;
461 }
462 
463 static int PrefilterSetupFlow(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
464 {
466  PrefilterPacketFlowSet,
467  PrefilterPacketFlowCompare,
468  PrefilterPacketFlowMatch);
469 }
470 
471 static bool PrefilterFlowIsPrefilterable(const Signature *s)
472 {
473  const SigMatch *sm;
474  for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
475  switch (sm->type) {
476  case DETECT_FLOW:
477  return TRUE;
478  }
479  }
480  return FALSE;
481 }
482 
483 #ifdef UNITTESTS
484 
485 /**
486  * \test DetectFlowTestParse01 is a test to make sure that we return "something"
487  * when given valid flow opt
488  */
489 static int DetectFlowTestParse01 (void)
490 {
491  DetectFlowData *fd = NULL;
492  fd = DetectFlowParse(NULL, "established");
493  FAIL_IF_NULL(fd);
494  DetectFlowFree(NULL, fd);
495  PASS;
496 }
497 
498 /**
499  * \test DetectFlowTestParse02 is a test for setting the established flow opt
500  */
501 static int DetectFlowTestParse02 (void)
502 {
503  DetectFlowData *fd = NULL;
504  fd = DetectFlowParse(NULL, "established");
505  FAIL_IF_NULL(fd);
507  fd->match_cnt == 1);
508  PASS;
509 }
510 
511 /**
512  * \test DetectFlowTestParse03 is a test for setting the stateless flow opt
513  */
514 static int DetectFlowTestParse03 (void)
515 {
516  DetectFlowData *fd = NULL;
517  fd = DetectFlowParse(NULL, "stateless");
518  FAIL_IF_NULL(fd);
520  DetectFlowFree(NULL, fd);
521  PASS;
522 }
523 
524 /**
525  * \test DetectFlowTestParse04 is a test for setting the to_client flow opt
526  */
527 static int DetectFlowTestParse04 (void)
528 {
529  DetectFlowData *fd = NULL;
530  fd = DetectFlowParse(NULL, "to_client");
531  FAIL_IF_NULL(fd);
533  DetectFlowFree(NULL, fd);
534  PASS;
535 }
536 
537 /**
538  * \test DetectFlowTestParse05 is a test for setting the to_server flow opt
539  */
540 static int DetectFlowTestParse05 (void)
541 {
542  DetectFlowData *fd = NULL;
543  fd = DetectFlowParse(NULL, "to_server");
544  FAIL_IF_NULL(fd);
546  DetectFlowFree(NULL, fd);
547  PASS;
548 }
549 
550 /**
551  * \test DetectFlowTestParse06 is a test for setting the from_server flow opt
552  */
553 static int DetectFlowTestParse06 (void)
554 {
555  DetectFlowData *fd = NULL;
556  fd = DetectFlowParse(NULL, "from_server");
557  FAIL_IF_NULL(fd);
559  DetectFlowFree(NULL, fd);
560  PASS;
561 }
562 
563 /**
564  * \test DetectFlowTestParse07 is a test for setting the from_client flow opt
565  */
566 static int DetectFlowTestParse07 (void)
567 {
568  DetectFlowData *fd = NULL;
569  fd = DetectFlowParse(NULL, "from_client");
570  FAIL_IF_NULL(fd);
572  DetectFlowFree(NULL, fd);
573  PASS;
574 }
575 
576 /**
577  * \test DetectFlowTestParse08 is a test for setting the established,to_client flow opts
578  */
579 static int DetectFlowTestParse08 (void)
580 {
581  DetectFlowData *fd = NULL;
582  fd = DetectFlowParse(NULL, "established,to_client");
583  FAIL_IF_NULL(fd);
585  DetectFlowFree(NULL, fd);
586  PASS;
587 }
588 
589 /**
590  * \test DetectFlowTestParse09 is a test for setting the to_client,stateless flow opts (order of state,dir reversed)
591  */
592 static int DetectFlowTestParse09 (void)
593 {
594  DetectFlowData *fd = NULL;
595  fd = DetectFlowParse(NULL, "to_client,stateless");
596  FAIL_IF_NULL(fd);
599  fd->match_cnt == 2);
600  DetectFlowFree(NULL, fd);
601  PASS;
602 }
603 
604 /**
605  * \test DetectFlowTestParse10 is a test for setting the from_server,stateless flow opts (order of state,dir reversed)
606  */
607 static int DetectFlowTestParse10 (void)
608 {
609  DetectFlowData *fd = NULL;
610  fd = DetectFlowParse(NULL, "from_server,stateless");
611  FAIL_IF_NULL(fd);
614  fd->match_cnt == 2);
615  DetectFlowFree(NULL, fd);
616  PASS;
617 }
618 
619 /**
620  * \test DetectFlowTestParse11 is a test for setting the from_server,stateless flow opts with spaces all around
621  */
622 static int DetectFlowTestParse11 (void)
623 {
624  DetectFlowData *fd = NULL;
625  fd = DetectFlowParse(NULL, " from_server , stateless ");
626  FAIL_IF_NULL(fd);
629  fd->match_cnt == 2);
630  DetectFlowFree(NULL, fd);
631  PASS;
632 }
633 
634 /**
635  * \test DetectFlowTestParseNocase01 is a test to make sure that we return "something"
636  * when given valid flow opt
637  */
638 static int DetectFlowTestParseNocase01 (void)
639 {
640  DetectFlowData *fd = NULL;
641  fd = DetectFlowParse(NULL, "ESTABLISHED");
642  FAIL_IF_NULL(fd);
643  DetectFlowFree(NULL, fd);
644  PASS;
645 }
646 
647 /**
648  * \test DetectFlowTestParseNocase02 is a test for setting the established flow opt
649  */
650 static int DetectFlowTestParseNocase02 (void)
651 {
652  DetectFlowData *fd = NULL;
653  fd = DetectFlowParse(NULL, "ESTABLISHED");
654  FAIL_IF_NULL(fd);
656  fd->match_cnt == 1);
657  DetectFlowFree(NULL, fd);
658  PASS;
659 }
660 
661 /**
662  * \test DetectFlowTestParseNocase03 is a test for setting the stateless flow opt
663  */
664 static int DetectFlowTestParseNocase03 (void)
665 {
666  DetectFlowData *fd = NULL;
667  fd = DetectFlowParse(NULL, "STATELESS");
668  FAIL_IF_NULL(fd);
670  PASS;
671 }
672 
673 /**
674  * \test DetectFlowTestParseNocase04 is a test for setting the to_client flow opt
675  */
676 static int DetectFlowTestParseNocase04 (void)
677 {
678  DetectFlowData *fd = NULL;
679  fd = DetectFlowParse(NULL, "TO_CLIENT");
680  FAIL_IF_NULL(fd);
682  DetectFlowFree(NULL, fd);
683  PASS;
684 }
685 
686 /**
687  * \test DetectFlowTestParseNocase05 is a test for setting the to_server flow opt
688  */
689 static int DetectFlowTestParseNocase05 (void)
690 {
691  DetectFlowData *fd = NULL;
692  fd = DetectFlowParse(NULL, "TO_SERVER");
693  FAIL_IF_NULL(fd);
695  DetectFlowFree(NULL, fd);
696  PASS;
697 }
698 
699 /**
700  * \test DetectFlowTestParseNocase06 is a test for setting the from_server flow opt
701  */
702 static int DetectFlowTestParseNocase06 (void)
703 {
704  DetectFlowData *fd = NULL;
705  fd = DetectFlowParse(NULL, "FROM_SERVER");
706  FAIL_IF_NULL(fd);
708  DetectFlowFree(NULL, fd);
709  PASS;
710 }
711 
712 /**
713  * \test DetectFlowTestParseNocase07 is a test for setting the from_client flow opt
714  */
715 static int DetectFlowTestParseNocase07 (void)
716 {
717  DetectFlowData *fd = NULL;
718  fd = DetectFlowParse(NULL, "FROM_CLIENT");
719  FAIL_IF_NULL(fd);
721  DetectFlowFree(NULL, fd);
722  PASS;
723 }
724 
725 /**
726  * \test DetectFlowTestParseNocase08 is a test for setting the established,to_client flow opts
727  */
728 static int DetectFlowTestParseNocase08 (void)
729 {
730  DetectFlowData *fd = NULL;
731  fd = DetectFlowParse(NULL, "ESTABLISHED,TO_CLIENT");
732  FAIL_IF_NULL(fd);
735  fd->match_cnt == 2);
736  DetectFlowFree(NULL, fd);
737  PASS;
738 }
739 
740 /**
741  * \test DetectFlowTestParseNocase09 is a test for setting the to_client,stateless flow opts (order of state,dir reversed)
742  */
743 static int DetectFlowTestParseNocase09 (void)
744 {
745  DetectFlowData *fd = NULL;
746  fd = DetectFlowParse(NULL, "TO_CLIENT,STATELESS");
747  FAIL_IF_NULL(fd);
750  fd->match_cnt == 2);
751  DetectFlowFree(NULL, fd);
752  PASS;
753 }
754 
755 /**
756  * \test DetectFlowTestParseNocase10 is a test for setting the from_server,stateless flow opts (order of state,dir reversed)
757  */
758 static int DetectFlowTestParseNocase10 (void)
759 {
760  DetectFlowData *fd = NULL;
761  fd = DetectFlowParse(NULL, "FROM_SERVER,STATELESS");
762  FAIL_IF_NULL(fd);
765  fd->match_cnt == 2);
766  DetectFlowFree(NULL, fd);
767  PASS;
768 }
769 
770 /**
771  * \test DetectFlowTestParseNocase11 is a test for setting the from_server,stateless flow opts with spaces all around
772  */
773 static int DetectFlowTestParseNocase11 (void)
774 {
775  DetectFlowData *fd = NULL;
776  fd = DetectFlowParse(NULL, " FROM_SERVER , STATELESS ");
777  FAIL_IF_NULL(fd);
780  fd->match_cnt == 2);
781  DetectFlowFree(NULL, fd);
782  PASS;
783 }
784 
785 /**
786  * \test DetectFlowTestParse12 is a test for setting an invalid seperator :
787  */
788 static int DetectFlowTestParse12 (void)
789 {
790  DetectFlowData *fd = NULL;
791  fd = DetectFlowParse(NULL, "from_server:stateless");
792  FAIL_IF_NOT_NULL(fd);
793  PASS;
794 }
795 
796 /**
797  * \test DetectFlowTestParse13 is a test for an invalid option
798  */
799 static int DetectFlowTestParse13 (void)
800 {
801  DetectFlowData *fd = NULL;
802  fd = DetectFlowParse(NULL, "invalidoptiontest");
803  FAIL_IF_NOT_NULL(fd);
804  PASS;
805 }
806 
807 /**
808  * \test DetectFlowTestParse14 is a test for a empty option
809  */
810 static int DetectFlowTestParse14 (void)
811 {
812  DetectFlowData *fd = NULL;
813  fd = DetectFlowParse(NULL, "");
814  FAIL_IF_NOT_NULL(fd);
815  PASS;
816 }
817 
818 /**
819  * \test DetectFlowTestParse15 is a test for an invalid combo of options established,stateless
820  */
821 static int DetectFlowTestParse15 (void)
822 {
823  DetectFlowData *fd = NULL;
824  fd = DetectFlowParse(NULL, "established,stateless");
825  FAIL_IF_NOT_NULL(fd);
826  PASS;
827 }
828 
829 /**
830  * \test DetectFlowTestParse16 is a test for an invalid combo of options to_client,to_server
831  */
832 static int DetectFlowTestParse16 (void)
833 {
834  DetectFlowData *fd = NULL;
835  fd = DetectFlowParse(NULL, "to_client,to_server");
836  FAIL_IF_NOT_NULL(fd);
837  PASS;
838 }
839 
840 /**
841  * \test DetectFlowTestParse16 is a test for an invalid combo of options to_client,from_server
842  * flowbit flags are the same
843  */
844 static int DetectFlowTestParse17 (void)
845 {
846  DetectFlowData *fd = NULL;
847  fd = DetectFlowParse(NULL, "to_client,from_server");
848  FAIL_IF_NOT_NULL(fd);
849  PASS;
850 }
851 
852 /**
853  * \test DetectFlowTestParse18 is a test for setting the from_server,stateless,only_stream flow opts (order of state,dir reversed)
854  */
855 static int DetectFlowTestParse18 (void)
856 {
857  DetectFlowData *fd = NULL;
858  fd = DetectFlowParse(NULL, "from_server,established,only_stream");
859  FAIL_IF_NULL(fd);
863  fd->match_cnt == 3);
864  DetectFlowFree(NULL, fd);
865  PASS;
866 }
867 
868 /**
869  * \test DetectFlowTestParseNocase18 is a test for setting the from_server,stateless,only_stream flow opts (order of state,dir reversed)
870  */
871 static int DetectFlowTestParseNocase18 (void)
872 {
873  DetectFlowData *fd = NULL;
874  fd = DetectFlowParse(NULL, "FROM_SERVER,ESTABLISHED,ONLY_STREAM");
875  FAIL_IF_NULL(fd);
879  fd->match_cnt == 3);
880  DetectFlowFree(NULL, fd);
881  PASS;
882 }
883 
884 
885 /**
886  * \test DetectFlowTestParse19 is a test for one to many options passed to DetectFlowParse
887  */
888 static int DetectFlowTestParse19 (void)
889 {
890  DetectFlowData *fd = NULL;
891  fd = DetectFlowParse(NULL, "from_server,established,only_stream,a");
892  FAIL_IF_NOT_NULL(fd);
893  PASS;
894 }
895 
896 /**
897  * \test DetectFlowTestParse20 is a test for setting from_server, established, no_stream
898  */
899 static int DetectFlowTestParse20 (void)
900 {
901  DetectFlowData *fd = NULL;
902  fd = DetectFlowParse(NULL, "from_server,established,no_stream");
903  FAIL_IF_NULL(fd);
907  fd->match_cnt == 3);
908  DetectFlowFree(NULL, fd);
909  PASS;
910 }
911 
912 /**
913  * \test DetectFlowTestParse20 is a test for setting from_server, established, no_stream
914  */
915 static int DetectFlowTestParseNocase20 (void)
916 {
917  DetectFlowData *fd = NULL;
918  fd = DetectFlowParse(NULL, "FROM_SERVER,ESTABLISHED,NO_STREAM");
919  FAIL_IF_NULL(fd);
923  fd->match_cnt == 3);
924  DetectFlowFree(NULL, fd);
925  PASS;
926 }
927 
928 /**
929  * \test DetectFlowTestParse21 is a test for an invalid opt between to valid opts
930  */
931 static int DetectFlowTestParse21 (void)
932 {
933  DetectFlowData *fd = NULL;
934  fd = DetectFlowParse(NULL, "from_server,a,no_stream");
935  FAIL_IF_NOT_NULL(fd);
936  PASS;
937 }
938 
939 static int DetectFlowSigTest01(void)
940 {
941  uint8_t *buf = (uint8_t *)"supernovaduper";
942  uint16_t buflen = strlen((char *)buf);
943  ThreadVars th_v;
945  memset(&dtv, 0, sizeof(DecodeThreadVars));
946  memset(&th_v, 0, sizeof(th_v));
947 
948  Packet *p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
949  FAIL_IF_NULL(p);
950 
951  const char *sig1 = "alert tcp any any -> any any (msg:\"dummy\"; "
952  "content:\"nova\"; flow:no_stream; sid:1;)";
953 
956  de_ctx->flags |= DE_QUIET;
957 
958  de_ctx->sig_list = SigInit(de_ctx, sig1);
960 
962  DetectEngineThreadCtx *det_ctx = NULL;
963  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
964  FAIL_IF_NULL(det_ctx);
965 
966  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
967  FAIL_IF(PacketAlertCheck(p, 1) != 1);
968 
969  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
971  UTHFreePacket(p);
972 
973  PASS;
974 }
975 
976 /**
977  * \test Test parsing of the not_established keyword.
978  */
979 static int DetectFlowTestParseNotEstablished(void)
980 {
981  DetectFlowData *fd = NULL;
982  fd = DetectFlowParse(NULL, "not_established");
983  FAIL_IF_NULL(fd);
985  DetectFlowFree(NULL, fd);
986  PASS;
987 }
988 
989 /**
990  * \test Test parsing of the "no_frag" flow argument.
991  */
992 static int DetectFlowTestParseNoFrag(void)
993 {
994  DetectFlowData *fd = NULL;
995  fd = DetectFlowParse(NULL, "no_frag");
996  FAIL_IF_NULL(fd);
998  DetectFlowFree(NULL, fd);
999  PASS;
1000 }
1001 
1002 /**
1003  * \test Test parsing of the "only_frag" flow argument.
1004  */
1005 static int DetectFlowTestParseOnlyFrag(void)
1006 {
1007  DetectFlowData *fd = NULL;
1008  fd = DetectFlowParse(NULL, "only_frag");
1009  FAIL_IF_NULL(fd);
1011  DetectFlowFree(NULL, fd);
1012  PASS;
1013 }
1014 
1015 /**
1016  * \test Test that parsing of only_frag and no_frag together fails.
1017  */
1018 static int DetectFlowTestParseNoFragOnlyFrag(void)
1019 {
1020  DetectFlowData *fd = NULL;
1021  fd = DetectFlowParse(NULL, "no_frag,only_frag");
1022  FAIL_IF_NOT_NULL(fd);
1023  PASS;
1024 }
1025 
1026 /**
1027  * \test Test no_frag matching.
1028  */
1029 static int DetectFlowTestNoFragMatch(void)
1030 {
1031  uint32_t pflags = 0;
1032  DetectFlowData *fd = DetectFlowParse(NULL, "no_frag");
1033  FAIL_IF_NULL(fd);
1035  FAIL_IF_NOT(fd->match_cnt == 1);
1036  FAIL_IF_NOT(FlowMatch(pflags, 0, 0, fd->flags, fd->match_cnt));
1037  pflags |= PKT_REBUILT_FRAGMENT;
1038  FAIL_IF(FlowMatch(pflags, 0, 0, fd->flags, fd->match_cnt));
1039  PASS;
1040 }
1041 
1042 /**
1043  * \test Test only_frag matching.
1044  */
1045 static int DetectFlowTestOnlyFragMatch(void)
1046 {
1047  uint32_t pflags = 0;
1048  DetectFlowData *fd = DetectFlowParse(NULL, "only_frag");
1049  FAIL_IF_NULL(fd);
1051  FAIL_IF_NOT(fd->match_cnt == 1);
1052  FAIL_IF(FlowMatch(pflags, 0, 0, fd->flags, fd->match_cnt));
1053  pflags |= PKT_REBUILT_FRAGMENT;
1054  FAIL_IF_NOT(FlowMatch(pflags, 0, 0, fd->flags, fd->match_cnt));
1055  PASS;
1056 }
1057 
1058 /**
1059  * \brief this function registers unit tests for DetectFlow
1060  */
1061 static void DetectFlowRegisterTests(void)
1062 {
1063  UtRegisterTest("DetectFlowTestParse01", DetectFlowTestParse01);
1064  UtRegisterTest("DetectFlowTestParse02", DetectFlowTestParse02);
1065  UtRegisterTest("DetectFlowTestParse03", DetectFlowTestParse03);
1066  UtRegisterTest("DetectFlowTestParse04", DetectFlowTestParse04);
1067  UtRegisterTest("DetectFlowTestParse05", DetectFlowTestParse05);
1068  UtRegisterTest("DetectFlowTestParse06", DetectFlowTestParse06);
1069  UtRegisterTest("DetectFlowTestParse07", DetectFlowTestParse07);
1070  UtRegisterTest("DetectFlowTestParse08", DetectFlowTestParse08);
1071  UtRegisterTest("DetectFlowTestParse09", DetectFlowTestParse09);
1072  UtRegisterTest("DetectFlowTestParse10", DetectFlowTestParse10);
1073  UtRegisterTest("DetectFlowTestParse11", DetectFlowTestParse11);
1074  UtRegisterTest("DetectFlowTestParseNocase01", DetectFlowTestParseNocase01);
1075  UtRegisterTest("DetectFlowTestParseNocase02", DetectFlowTestParseNocase02);
1076  UtRegisterTest("DetectFlowTestParseNocase03", DetectFlowTestParseNocase03);
1077  UtRegisterTest("DetectFlowTestParseNocase04", DetectFlowTestParseNocase04);
1078  UtRegisterTest("DetectFlowTestParseNocase05", DetectFlowTestParseNocase05);
1079  UtRegisterTest("DetectFlowTestParseNocase06", DetectFlowTestParseNocase06);
1080  UtRegisterTest("DetectFlowTestParseNocase07", DetectFlowTestParseNocase07);
1081  UtRegisterTest("DetectFlowTestParseNocase08", DetectFlowTestParseNocase08);
1082  UtRegisterTest("DetectFlowTestParseNocase09", DetectFlowTestParseNocase09);
1083  UtRegisterTest("DetectFlowTestParseNocase10", DetectFlowTestParseNocase10);
1084  UtRegisterTest("DetectFlowTestParseNocase11", DetectFlowTestParseNocase11);
1085  UtRegisterTest("DetectFlowTestParse12", DetectFlowTestParse12);
1086  UtRegisterTest("DetectFlowTestParse13", DetectFlowTestParse13);
1087  UtRegisterTest("DetectFlowTestParse14", DetectFlowTestParse14);
1088  UtRegisterTest("DetectFlowTestParse15", DetectFlowTestParse15);
1089  UtRegisterTest("DetectFlowTestParse16", DetectFlowTestParse16);
1090  UtRegisterTest("DetectFlowTestParse17", DetectFlowTestParse17);
1091  UtRegisterTest("DetectFlowTestParse18", DetectFlowTestParse18);
1092  UtRegisterTest("DetectFlowTestParseNocase18", DetectFlowTestParseNocase18);
1093  UtRegisterTest("DetectFlowTestParse19", DetectFlowTestParse19);
1094  UtRegisterTest("DetectFlowTestParse20", DetectFlowTestParse20);
1095  UtRegisterTest("DetectFlowTestParseNocase20", DetectFlowTestParseNocase20);
1096  UtRegisterTest("DetectFlowTestParse21", DetectFlowTestParse21);
1097  UtRegisterTest("DetectFlowTestParseNotEstablished",
1098  DetectFlowTestParseNotEstablished);
1099  UtRegisterTest("DetectFlowTestParseNoFrag", DetectFlowTestParseNoFrag);
1100  UtRegisterTest("DetectFlowTestParseOnlyFrag",
1101  DetectFlowTestParseOnlyFrag);
1102  UtRegisterTest("DetectFlowTestParseNoFragOnlyFrag",
1103  DetectFlowTestParseNoFragOnlyFrag);
1104  UtRegisterTest("DetectFlowTestNoFragMatch", DetectFlowTestNoFragMatch);
1105  UtRegisterTest("DetectFlowTestOnlyFragMatch", DetectFlowTestOnlyFragMatch);
1106 
1107  UtRegisterTest("DetectFlowSigTest01", DetectFlowSigTest01);
1108 }
1109 #endif /* UNITTESTS */
DETECT_FLOW_FLAG_TOCLIENT
#define DETECT_FLOW_FLAG_TOCLIENT
Definition: detect-flow.h:28
DETECT_FLOW_FLAG_STATELESS
#define DETECT_FLOW_FLAG_STATELESS
Definition: detect-flow.h:31
SigTableElmt_::url
const char * url
Definition: detect.h:1214
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SigTableElmt_::desc
const char * desc
Definition: detect.h:1213
SigMatchFree
void SigMatchFree(DetectEngineCtx *de_ctx, SigMatch *sm)
free a SigMatch
Definition: detect-parse.c:250
SC_ERR_INVALID_VALUE
@ SC_ERR_INVALID_VALUE
Definition: util-error.h:160
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1201
DetectFlowData_
Definition: detect-flow.h:37
DETECT_FLOW_FLAG_NOSTREAM
#define DETECT_FLOW_FLAG_NOSTREAM
Definition: detect-flow.h:33
SigTableElmt_::name
const char * name
Definition: detect.h:1211
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1347
SIG_FLAG_INIT_FLOW
#define SIG_FLAG_INIT_FLOW
Definition: detect.h:258
MAX_SUBSTRINGS
#define MAX_SUBSTRINGS
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_FLOW
@ DETECT_FLOW
Definition: detect-engine-register.h:51
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
Packet_::flags
uint32_t flags
Definition: decode.h:449
SigInit
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:2056
DetectFlowData_::match_cnt
uint8_t match_cnt
Definition: detect-flow.h:39
DetectEngineThreadCtx_::pmq
PrefilterRuleStore pmq
Definition: detect.h:1111
DetectFlowData_::flags
uint16_t flags
Definition: detect-flow.h:38
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:767
SC_ERR_INVALID_SIGNATURE
@ SC_ERR_INVALID_SIGNATURE
Definition: util-error.h:69
PrefilterPacketHeaderCtx_::sigs_array
SigIntId * sigs_array
Definition: detect-engine-prefilter-common.h:41
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2093
PrefilterPacketHeaderValue::u8
uint8_t u8[16]
Definition: detect-engine-prefilter-common.h:22
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:219
SIG_FLAG_REQUIRE_STREAM
#define SIG_FLAG_REQUIRE_STREAM
Definition: detect.h:224
DetectEngineThreadCtx_::flags
uint16_t flags
Definition: detect.h:1077
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
SignatureInitData_::init_flags
uint32_t init_flags
Definition: detect.h:493
PrefilterPacketHeaderCtx_::sigs_cnt
uint32_t sigs_cnt
Definition: detect-engine-prefilter-common.h:40
SC_ERR_PCRE_GET_SUBSTRING
@ SC_ERR_PCRE_GET_SUBSTRING
Definition: util-error.h:34
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:445
SIG_FLAG_TOCLIENT
#define SIG_FLAG_TOCLIENT
Definition: detect.h:237
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1196
DetectFlowSetupImplicit
int DetectFlowSetupImplicit(Signature *s, uint32_t flags)
Definition: detect-flow.c:321
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
SigTableElmt_::SetupPrefilter
int(* SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh)
Definition: detect.h:1199
DETECT_FLOW_FLAG_ONLYSTREAM
#define DETECT_FLOW_FLAG_ONLYSTREAM
Definition: detect-flow.h:32
SIG_FLAG_TOSERVER
#define SIG_FLAG_TOSERVER
Definition: detect.h:236
PrefilterPacketHeaderCtx_
Definition: detect-engine-prefilter-common.h:33
decode.h
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
SC_ERR_PCRE_MATCH
@ SC_ERR_PCRE_MATCH
Definition: util-error.h:32
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1010
PARSE_REGEX
#define PARSE_REGEX
Regex for parsing our flow options.
Definition: detect-flow.c:47
DETECT_FLOW_FLAG_TOSERVER
#define DETECT_FLOW_FLAG_TOSERVER
Definition: detect-flow.h:27
res
PoolThreadReserved res
Definition: stream-tcp-private.h:0
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2493
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:324
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:89
TRUE
#define TRUE
Definition: suricata-common.h:33
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:323
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:282
SigMatchSignatures
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1688
FALSE
#define FALSE
Definition: suricata-common.h:34
Signature_::flags
uint32_t flags
Definition: detect.h:529
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, const char *str, int start_offset, int options, int *ovector, int ovector_size)
Definition: detect-parse.c:2423
Packet_
Definition: decode.h:414
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:597
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1179
SignatureInitData_::smlists
struct SigMatch_ ** smlists
Definition: detect.h:522
FLOW_PKT_TOCLIENT
#define FLOW_PKT_TOCLIENT
Definition: flow.h:220
SigMatchAlloc
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:235
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:1888
SigMatch_::type
uint8_t type
Definition: detect.h:321
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:30
PrefilterPacketHeaderCtx_::v1
PrefilterPacketHeaderValue v1
Definition: detect-engine-prefilter-common.h:34
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:315
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:2797
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
flags
uint8_t flags
Definition: decode-gre.h:0
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3005
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
DetectParseRegex_
Definition: detect-parse.h:42
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:773
DetectFlowRegister
void DetectFlowRegister(void)
Registration function for flow: keyword.
Definition: detect-flow.c:65
SIG_FLAG_BOTH
#define SIG_FLAG_BOTH
PrefilterSetupPacketHeader
int PrefilterSetupPacketHeader(DetectEngineCtx *de_ctx, SigGroupHead *sgh, int sm_type, void(*Set)(PrefilterPacketHeaderValue *v, void *), bool(*Compare)(PrefilterPacketHeaderValue v, void *), void(*Match)(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx))
Definition: detect-engine-prefilter-common.c:407
DETECT_FLOW_FLAG_NOT_ESTABLISHED
#define DETECT_FLOW_FLAG_NOT_ESTABLISHED
Definition: detect-flow.h:30
detect-flow.h
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
DETECT_FLOW_FLAG_ONLY_FRAG
#define DETECT_FLOW_FLAG_ONLY_FRAG
Definition: detect-flow.h:35
DETECT_ENGINE_THREAD_CTX_STREAM_CONTENT_MATCH
#define DETECT_ENGINE_THREAD_CTX_STREAM_CONTENT_MATCH
Definition: detect.h:282
PKT_REBUILT_FRAGMENT
#define PKT_REBUILT_FRAGMENT
Definition: decode.h:1136
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:631
SigTableElmt_::SupportsPrefilter
bool(* SupportsPrefilter)(const Signature *s)
Definition: detect.h:1198
UTHFreePacket
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:485
DETECT_FLOW_FLAG_ESTABLISHED
#define DETECT_FLOW_FLAG_ESTABLISHED
Definition: detect-flow.h:29
detect-parse.h
DetectFlowFree
void DetectFlowFree(DetectEngineCtx *, void *)
this function will free memory associated with DetectFlowData
Definition: detect-flow.c:423
Signature_
Signature container.
Definition: detect.h:528
SigMatch_
a single match condition for a signature
Definition: detect.h:320
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:221
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2048
SC_ERR_FLAGS_MODIFIER
@ SC_ERR_FLAGS_MODIFIER
Definition: util-error.h:133
DetectFlowMatch
int DetectFlowMatch(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
This function is used to match flow flags set on a packet with those passed via flow:
Definition: detect-flow.c:138
PrefilterPacketHeaderValue
Definition: detect-engine-prefilter-common.h:21
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:768
detect-engine-prefilter-common.h
flow.h
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:304
flow-var.h
DETECT_FLOW_FLAG_NO_FRAG
#define DETECT_FLOW_FLAG_NO_FRAG
Definition: detect-flow.h:34
SigMatchAppendSMToList
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:349
debug.h
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1203
SIG_FLAG_REQUIRE_PACKET
#define SIG_FLAG_REQUIRE_PACKET
Definition: detect.h:223