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