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 "decode.h"
28
29#include "detect.h"
30#include "detect-parse.h"
31#include "detect-engine.h"
33#include "detect-engine-build.h"
34
35#include "flow.h"
36#include "flow-var.h"
37
38#include "detect-flow.h"
39
40#include "util-unittest.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
49static DetectParseRegex parse_regex;
50
52 const Signature *, const SigMatchCtx *);
53static int DetectFlowSetup (DetectEngineCtx *, Signature *, const char *);
54#ifdef UNITTESTS
55static void DetectFlowRegisterTests(void);
56#endif
57void DetectFlowFree(DetectEngineCtx *, void *);
58
59static int PrefilterSetupFlow(DetectEngineCtx *de_ctx, SigGroupHead *sgh);
60static bool PrefilterFlowIsPrefilterable(const Signature *s);
61
62/**
63 * \brief Registration function for flow: keyword
64 */
86
87/**
88 * \param pflags packet flags (p->flags)
89 * \param pflowflags packet flow flags (p->flowflags)
90 * \param dflags detect flow flags
91 * \param match_cnt number of matches to trigger
92 */
93static inline int FlowMatch(const uint32_t pflags, const uint8_t pflowflags, const uint16_t dflags,
94 const uint16_t match_cnt)
95{
96 uint8_t cnt = 0;
97
98 if ((dflags & DETECT_FLOW_FLAG_NO_FRAG) &&
99 (!(pflags & PKT_REBUILT_FRAGMENT))) {
100 cnt++;
101 } else if ((dflags & DETECT_FLOW_FLAG_ONLY_FRAG) &&
102 (pflags & PKT_REBUILT_FRAGMENT)) {
103 cnt++;
104 }
105
106 if ((dflags & DETECT_FLOW_FLAG_TOSERVER) && (pflowflags & FLOW_PKT_TOSERVER)) {
107 cnt++;
108 } else if ((dflags & DETECT_FLOW_FLAG_TOCLIENT) && (pflowflags & FLOW_PKT_TOCLIENT)) {
109 cnt++;
110 }
111
112 if ((dflags & DETECT_FLOW_FLAG_ESTABLISHED) && (pflowflags & FLOW_PKT_ESTABLISHED)) {
113 cnt++;
114 } else if (dflags & DETECT_FLOW_FLAG_NOT_ESTABLISHED && (!(pflowflags & FLOW_PKT_ESTABLISHED))) {
115 cnt++;
116 } else if (dflags & DETECT_FLOW_FLAG_STATELESS) {
117 cnt++;
118 }
119
120 return (match_cnt == cnt) ? 1 : 0;
121}
122
123/**
124 * \brief This function is used to match flow flags set on a packet with those passed via flow:
125 *
126 * \param t pointer to thread vars
127 * \param det_ctx pointer to the pattern matcher thread
128 * \param p pointer to the current packet
129 * \param m pointer to the sigmatch that we will cast into DetectFlowData
130 *
131 * \retval 0 no match
132 * \retval 1 match
133 */
135 const Signature *s, const SigMatchCtx *ctx)
136{
137 SCEnter();
138
139 SCLogDebug("pkt %p", p);
140
141 if (p->flowflags & FLOW_PKT_TOSERVER) {
142 SCLogDebug("FLOW_PKT_TOSERVER");
143 } else if (p->flowflags & FLOW_PKT_TOCLIENT) {
144 SCLogDebug("FLOW_PKT_TOCLIENT");
145 }
146
148 SCLogDebug("FLOW_PKT_ESTABLISHED");
149 }
150
151 const DetectFlowData *fd = (const DetectFlowData *)ctx;
152
153 const int ret = FlowMatch(p->flags, p->flowflags, fd->flags, fd->match_cnt);
154 SCLogDebug("returning %" PRId32 " fd->match_cnt %" PRId32 " fd->flags 0x%02X p->flowflags 0x%02X",
155 ret, fd->match_cnt, fd->flags, p->flowflags);
156 SCReturnInt(ret);
157}
158
159/**
160 * \brief This function is used to parse flow options passed via flow: keyword
161 *
162 * \param de_ctx Pointer to the detection engine context
163 * \param flowstr Pointer to the user provided flow options
164 * \param[out] parse_flags keyword flags only used during parsing
165 *
166 * \retval fd pointer to DetectFlowData on success
167 * \retval NULL on failure
168 */
169static DetectFlowData *DetectFlowParse(
170 DetectEngineCtx *de_ctx, const char *flowstr, uint16_t *parse_flags)
171{
172 DetectFlowData *fd = NULL;
173 char *args[3] = {NULL,NULL,NULL};
174 int res = 0;
175 size_t pcre2len;
176 char str1[16] = "", str2[16] = "", str3[16] = "";
177 pcre2_match_data *match = NULL;
178
179 int ret = DetectParsePcreExec(&parse_regex, &match, flowstr, 0, 0);
180 if (ret < 1 || ret > 4) {
181 SCLogError("parse error, ret %" PRId32 ", string %s", ret, flowstr);
182 goto error;
183 }
184
185 if (ret > 1) {
186 pcre2len = sizeof(str1);
187 res = SC_Pcre2SubstringCopy(match, 1, (PCRE2_UCHAR8 *)str1, &pcre2len);
188 if (res < 0) {
189 SCLogError("pcre2_substring_copy_bynumber failed");
190 goto error;
191 }
192 args[0] = (char *)str1;
193
194 if (ret > 2) {
195 pcre2len = sizeof(str2);
196 res = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)str2, &pcre2len);
197 if (res < 0) {
198 SCLogError("pcre2_substring_copy_bynumber failed");
199 goto error;
200 }
201 args[1] = (char *)str2;
202 }
203 if (ret > 3) {
204 pcre2len = sizeof(str3);
205 res = pcre2_substring_copy_bynumber(match, 3, (PCRE2_UCHAR8 *)str3, &pcre2len);
206 if (res < 0) {
207 SCLogError("pcre2_substring_copy_bynumber failed");
208 goto error;
209 }
210 args[2] = (char *)str3;
211 }
212 }
213
214 fd = SCMalloc(sizeof(DetectFlowData));
215 if (unlikely(fd == NULL))
216 goto error;
217 fd->flags = 0;
218 fd->match_cnt = 0;
219
220 for (int i = 0; i < (ret - 1); i++) {
221 if (args[i]) {
222 /* inspect our options and set the flags */
223 if (strcasecmp(args[i], "established") == 0) {
225 SCLogError("DETECT_FLOW_FLAG_ESTABLISHED flag is already set");
226 goto error;
227 } else if (fd->flags & DETECT_FLOW_FLAG_NOT_ESTABLISHED) {
228 SCLogError("cannot set DETECT_FLOW_FLAG_ESTABLISHED, "
229 "DETECT_FLOW_FLAG_NOT_ESTABLISHED already set");
230 goto error;
231 } else if (fd->flags & DETECT_FLOW_FLAG_STATELESS) {
232 SCLogError("DETECT_FLOW_FLAG_STATELESS already set");
233 goto error;
234 }
236 fd->match_cnt++;
237 } else if (strcasecmp(args[i], "not_established") == 0) {
239 SCLogError("DETECT_FLOW_FLAG_NOT_ESTABLISHED flag is already set");
240 goto error;
241 } else if (fd->flags & DETECT_FLOW_FLAG_ESTABLISHED) {
242 SCLogError("cannot set DETECT_FLOW_FLAG_NOT_ESTABLISHED, "
243 "DETECT_FLOW_FLAG_ESTABLISHED already set");
244 goto error;
245 }
247 fd->match_cnt++;
248 } else if (strcasecmp(args[i], "stateless") == 0) {
250 SCLogError("DETECT_FLOW_FLAG_STATELESS flag is already set");
251 goto error;
252 } else if (fd->flags & DETECT_FLOW_FLAG_ESTABLISHED) {
253 SCLogError("cannot set DETECT_FLOW_FLAG_STATELESS, "
254 "DETECT_FLOW_FLAG_ESTABLISHED already set");
255 goto error;
256 }
258 fd->match_cnt++;
259 } else if (strcasecmp(args[i], "to_client") == 0 || strcasecmp(args[i], "from_server") == 0) {
261 SCLogError("cannot set DETECT_FLOW_FLAG_TOCLIENT flag is already set");
262 goto error;
263 } else if (fd->flags & DETECT_FLOW_FLAG_TOSERVER) {
264 SCLogError("cannot set to_client, DETECT_FLOW_FLAG_TOSERVER already set");
265 goto error;
266 }
268 fd->match_cnt++;
269 } else if (strcasecmp(args[i], "to_server") == 0 || strcasecmp(args[i], "from_client") == 0){
271 SCLogError("cannot set DETECT_FLOW_FLAG_TOSERVER flag is already set");
272 goto error;
273 } else if (fd->flags & DETECT_FLOW_FLAG_TOCLIENT) {
274 SCLogError("cannot set to_server, DETECT_FLOW_FLAG_TO_CLIENT flag already set");
275 goto error;
276 }
278 fd->match_cnt++;
279 } else if (strcasecmp(args[i], "no_frag") == 0) {
281 SCLogError("cannot set no_frag flag is already set");
282 goto error;
283 } else if (fd->flags & DETECT_FLOW_FLAG_ONLY_FRAG) {
284 SCLogError("cannot set no_frag flag, only_frag already set");
285 goto error;
286 }
288 fd->match_cnt++;
289 } else if (strcasecmp(args[i], "only_frag") == 0) {
291 SCLogError("cannot set only_frag flag is already set");
292 goto error;
293 } else if (fd->flags & DETECT_FLOW_FLAG_NO_FRAG) {
294 SCLogError("cannot set only_frag flag, no_frag already set");
295 goto error;
296 }
298 fd->match_cnt++;
299
300 /* special case: these only affect parsing, not matching */
301
302 } else if (strcasecmp(args[i], "only_stream") == 0) {
303 if (*parse_flags & DETECT_FLOW_FLAG_ONLYSTREAM) {
304 SCLogError("cannot set only_stream flag is already set");
305 goto error;
306 } else if (*parse_flags & DETECT_FLOW_FLAG_NOSTREAM) {
308 "cannot set only_stream flag, DETECT_FLOW_FLAG_NOSTREAM already set");
309 goto error;
310 }
311 *parse_flags |= DETECT_FLOW_FLAG_ONLYSTREAM;
312 } else if (strcasecmp(args[i], "no_stream") == 0) {
313 if (*parse_flags & DETECT_FLOW_FLAG_NOSTREAM) {
314 SCLogError("cannot set no_stream flag is already set");
315 goto error;
316 } else if (*parse_flags & DETECT_FLOW_FLAG_ONLYSTREAM) {
318 "cannot set no_stream flag, DETECT_FLOW_FLAG_ONLYSTREAM already set");
319 goto error;
320 }
321 *parse_flags |= DETECT_FLOW_FLAG_NOSTREAM;
322 } else {
323 SCLogError("invalid flow option \"%s\"", args[i]);
324 goto error;
325 }
326 }
327 }
328 pcre2_match_data_free(match);
329 return fd;
330
331error:
332 if (match) {
333 pcre2_match_data_free(match);
334 }
335 if (fd != NULL)
337 return NULL;
338
339}
340
342{
343#define SIG_FLAG_BOTH (SIG_FLAG_TOSERVER|SIG_FLAG_TOCLIENT)
344 BUG_ON(flags == 0);
347
348 SCLogDebug("want %08x", flags & SIG_FLAG_BOTH);
349 SCLogDebug("have %08x", s->flags & SIG_FLAG_BOTH);
350
351 if (flags & SIG_FLAG_TOSERVER) {
352 if ((s->flags & SIG_FLAG_BOTH) == SIG_FLAG_BOTH) {
353 /* both is set if we just have 'flow:established' */
354 s->flags &= ~SIG_FLAG_TOCLIENT;
355 } else if (s->flags & SIG_FLAG_TOCLIENT) {
356 return -1;
357 }
359 } else {
360 if ((s->flags & SIG_FLAG_BOTH) == SIG_FLAG_BOTH) {
361 /* both is set if we just have 'flow:established' */
362 s->flags &= ~SIG_FLAG_TOSERVER;
363 } else if (s->flags & SIG_FLAG_TOSERVER) {
364 return -1;
365 }
367 }
368 return 0;
369#undef SIG_FLAG_BOTH
370}
371
372/**
373 * \brief this function is used to add the parsed flowdata into the current signature
374 *
375 * \param de_ctx pointer to the Detection Engine Context
376 * \param s pointer to the Current Signature
377 * \param flowstr pointer to the user provided flow options
378 *
379 * \retval 0 on Success
380 * \retval -1 on Failure
381 */
382int DetectFlowSetup (DetectEngineCtx *de_ctx, Signature *s, const char *flowstr)
383{
384 uint16_t parse_flags = 0;
385
386 /* ensure only one flow option */
388 SCLogError("A signature may have only one flow option.");
389 return -1;
390 }
391
392 DetectFlowData *fd = DetectFlowParse(de_ctx, flowstr, &parse_flags);
393 if (fd == NULL)
394 return -1;
395
396 bool appendsm = true;
397 /* set the signature direction flags */
399 if (s->flags & SIG_FLAG_TXBOTHDIR) {
401 "rule %u means to use both directions, cannot specify a flow direction", s->id);
402 goto error;
403 }
404 if (s->flags & SIG_FLAG_TOCLIENT) {
405 SCLogError("rule %u has flow to_server but a hook to_client", s->id);
406 goto error;
407 }
409 } else if (fd->flags & DETECT_FLOW_FLAG_TOCLIENT) {
410 if (s->flags & SIG_FLAG_TXBOTHDIR) {
412 "rule %u means to use both directions, cannot specify a flow direction", s->id);
413 goto error;
414 }
415 if (s->flags & SIG_FLAG_TOSERVER) {
416 SCLogError("rule %u has flow to_client but a hook to_server", s->id);
417 goto error;
418 }
420 } else {
421 /* if direction wasn't already set, e.g. by rule hook, assume both */
422 if ((s->flags & (SIG_FLAG_TOSERVER | SIG_FLAG_TOCLIENT)) == 0) {
425 }
426 }
427 if (fd->flags == 0 || fd->flags == DETECT_FLOW_FLAG_TOSERVER ||
429 /* no direct flow is needed for just direction,
430 * no sigmatch is needed either. */
431 appendsm = false;
432 } else {
434 }
435
436 if (appendsm) {
438 de_ctx, s, DETECT_FLOW, (SigMatchCtx *)fd, DETECT_SM_LIST_MATCH) == NULL) {
439 goto error;
440 }
441 } else {
443 }
444
445 if (parse_flags & DETECT_FLOW_FLAG_ONLYSTREAM) {
447 }
448 if (parse_flags & DETECT_FLOW_FLAG_NOSTREAM) {
450 }
451 return 0;
452
453error:
454 if (fd != NULL)
456 return -1;
457
458}
459
460/**
461 * \brief this function will free memory associated with DetectFlowData
462 *
463 * \param fd pointer to DetectFlowData
464 */
466{
467 DetectFlowData *fd = (DetectFlowData *)ptr;
468 SCFree(fd);
469}
470
471static void
472PrefilterPacketFlowMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
473{
474 SCEnter();
475
476 const PrefilterPacketHeaderCtx *ctx = pectx;
477
478 if (!PrefilterPacketHeaderExtraMatch(ctx, p))
479 return;
480
481 if (FlowMatch(p->flags, p->flowflags, ctx->v1.u16[0], ctx->v1.u16[1])) {
482 SCLogDebug("match: adding sids");
483 PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
484 }
485 SCReturn;
486}
487
488static void
489PrefilterPacketFlowSet(PrefilterPacketHeaderValue *v, void *smctx)
490{
491 const DetectFlowData *fb = smctx;
492 v->u16[0] = fb->flags;
493 v->u16[1] = fb->match_cnt;
494}
495
496static bool
497PrefilterPacketFlowCompare(PrefilterPacketHeaderValue v, void *smctx)
498{
499 const DetectFlowData *fb = smctx;
500 if (v.u16[0] == fb->flags && v.u16[1] == fb->match_cnt) {
501 return true;
502 }
503 return false;
504}
505
506static int PrefilterSetupFlow(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
507{
508 return PrefilterSetupPacketHeader(de_ctx, sgh, DETECT_FLOW, 0, PrefilterPacketFlowSet,
509 PrefilterPacketFlowCompare, PrefilterPacketFlowMatch);
510}
511
512static bool PrefilterFlowIsPrefilterable(const Signature *s)
513{
514 const SigMatch *sm;
515 for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
516 switch (sm->type) {
517 case DETECT_FLOW:
518 return true;
519 }
520 }
521 return false;
522}
523
524#ifdef UNITTESTS
525#include "detect-engine-alert.h"
526
527/**
528 * \test DetectFlowTestParse01 is a test to make sure that we return "something"
529 * when given valid flow opt
530 */
531static int DetectFlowTestParse01 (void)
532{
533 uint16_t parsed_flags = 0;
534 DetectFlowData *fd = DetectFlowParse(NULL, "established", &parsed_flags);
535 FAIL_IF_NULL(fd);
536 FAIL_IF_NOT(parsed_flags == 0);
537 DetectFlowFree(NULL, fd);
538 PASS;
539}
540
541/**
542 * \test DetectFlowTestParse02 is a test for setting the established flow opt
543 */
544static int DetectFlowTestParse02 (void)
545{
546 uint16_t parsed_flags = 0;
547 DetectFlowData *fd = DetectFlowParse(NULL, "established", &parsed_flags);
548 FAIL_IF_NULL(fd);
550 fd->match_cnt == 1);
551 PASS;
552}
553
554/**
555 * \test DetectFlowTestParse03 is a test for setting the stateless flow opt
556 */
557static int DetectFlowTestParse03 (void)
558{
559 uint16_t parsed_flags = 0;
560 DetectFlowData *fd = DetectFlowParse(NULL, "stateless", &parsed_flags);
561 FAIL_IF_NULL(fd);
563 DetectFlowFree(NULL, fd);
564 PASS;
565}
566
567/**
568 * \test DetectFlowTestParse04 is a test for setting the to_client flow opt
569 */
570static int DetectFlowTestParse04 (void)
571{
572 uint16_t parsed_flags = 0;
573 DetectFlowData *fd = DetectFlowParse(NULL, "to_client", &parsed_flags);
574 FAIL_IF_NULL(fd);
576 DetectFlowFree(NULL, fd);
577 PASS;
578}
579
580/**
581 * \test DetectFlowTestParse05 is a test for setting the to_server flow opt
582 */
583static int DetectFlowTestParse05 (void)
584{
585 uint16_t parsed_flags = 0;
586 DetectFlowData *fd = DetectFlowParse(NULL, "to_server", &parsed_flags);
587 FAIL_IF_NULL(fd);
589 DetectFlowFree(NULL, fd);
590 PASS;
591}
592
593/**
594 * \test DetectFlowTestParse06 is a test for setting the from_server flow opt
595 */
596static int DetectFlowTestParse06 (void)
597{
598 uint16_t parsed_flags = 0;
599 DetectFlowData *fd = DetectFlowParse(NULL, "from_server", &parsed_flags);
600 FAIL_IF_NULL(fd);
602 DetectFlowFree(NULL, fd);
603 PASS;
604}
605
606/**
607 * \test DetectFlowTestParse07 is a test for setting the from_client flow opt
608 */
609static int DetectFlowTestParse07 (void)
610{
611 uint16_t parsed_flags = 0;
612 DetectFlowData *fd = DetectFlowParse(NULL, "from_client", &parsed_flags);
613 FAIL_IF_NULL(fd);
615 DetectFlowFree(NULL, fd);
616 PASS;
617}
618
619/**
620 * \test DetectFlowTestParse08 is a test for setting the established,to_client flow opts
621 */
622static int DetectFlowTestParse08 (void)
623{
624 uint16_t parsed_flags = 0;
625 DetectFlowData *fd = DetectFlowParse(NULL, "established,to_client", &parsed_flags);
626 FAIL_IF_NULL(fd);
628 DetectFlowFree(NULL, fd);
629 PASS;
630}
631
632/**
633 * \test DetectFlowTestParse09 is a test for setting the to_client,stateless flow opts (order of state,dir reversed)
634 */
635static int DetectFlowTestParse09 (void)
636{
637 uint16_t parsed_flags = 0;
638 DetectFlowData *fd = DetectFlowParse(NULL, "to_client,stateless", &parsed_flags);
639 FAIL_IF_NULL(fd);
642 fd->match_cnt == 2);
643 DetectFlowFree(NULL, fd);
644 PASS;
645}
646
647/**
648 * \test DetectFlowTestParse10 is a test for setting the from_server,stateless flow opts (order of state,dir reversed)
649 */
650static int DetectFlowTestParse10 (void)
651{
652 uint16_t parsed_flags = 0;
653 DetectFlowData *fd = DetectFlowParse(NULL, "from_server,stateless", &parsed_flags);
654 FAIL_IF_NULL(fd);
657 fd->match_cnt == 2);
658 DetectFlowFree(NULL, fd);
659 PASS;
660}
661
662/**
663 * \test DetectFlowTestParse11 is a test for setting the from_server,stateless flow opts with spaces all around
664 */
665static int DetectFlowTestParse11 (void)
666{
667 uint16_t parsed_flags = 0;
668 DetectFlowData *fd = DetectFlowParse(NULL, " from_server , stateless ", &parsed_flags);
669 FAIL_IF_NULL(fd);
672 fd->match_cnt == 2);
673 DetectFlowFree(NULL, fd);
674 PASS;
675}
676
677/**
678 * \test DetectFlowTestParseNocase01 is a test to make sure that we return "something"
679 * when given valid flow opt
680 */
681static int DetectFlowTestParseNocase01 (void)
682{
683 uint16_t parsed_flags = 0;
684 DetectFlowData *fd = DetectFlowParse(NULL, "ESTABLISHED", &parsed_flags);
685 FAIL_IF_NULL(fd);
686 DetectFlowFree(NULL, fd);
687 PASS;
688}
689
690/**
691 * \test DetectFlowTestParseNocase02 is a test for setting the established flow opt
692 */
693static int DetectFlowTestParseNocase02 (void)
694{
695 uint16_t parsed_flags = 0;
696 DetectFlowData *fd = DetectFlowParse(NULL, "ESTABLISHED", &parsed_flags);
697 FAIL_IF_NULL(fd);
699 fd->match_cnt == 1);
700 DetectFlowFree(NULL, fd);
701 PASS;
702}
703
704/**
705 * \test DetectFlowTestParseNocase03 is a test for setting the stateless flow opt
706 */
707static int DetectFlowTestParseNocase03 (void)
708{
709 uint16_t parsed_flags = 0;
710 DetectFlowData *fd = DetectFlowParse(NULL, "STATELESS", &parsed_flags);
711 FAIL_IF_NULL(fd);
713 DetectFlowFree(NULL, fd);
714 PASS;
715}
716
717/**
718 * \test DetectFlowTestParseNocase04 is a test for setting the to_client flow opt
719 */
720static int DetectFlowTestParseNocase04 (void)
721{
722 uint16_t parsed_flags = 0;
723 DetectFlowData *fd = DetectFlowParse(NULL, "TO_CLIENT", &parsed_flags);
724 FAIL_IF_NULL(fd);
726 DetectFlowFree(NULL, fd);
727 PASS;
728}
729
730/**
731 * \test DetectFlowTestParseNocase05 is a test for setting the to_server flow opt
732 */
733static int DetectFlowTestParseNocase05 (void)
734{
735 uint16_t parsed_flags = 0;
736 DetectFlowData *fd = DetectFlowParse(NULL, "TO_SERVER", &parsed_flags);
737 FAIL_IF_NULL(fd);
739 DetectFlowFree(NULL, fd);
740 PASS;
741}
742
743/**
744 * \test DetectFlowTestParseNocase06 is a test for setting the from_server flow opt
745 */
746static int DetectFlowTestParseNocase06 (void)
747{
748 uint16_t parsed_flags = 0;
749 DetectFlowData *fd = DetectFlowParse(NULL, "FROM_SERVER", &parsed_flags);
750 FAIL_IF_NULL(fd);
752 DetectFlowFree(NULL, fd);
753 PASS;
754}
755
756/**
757 * \test DetectFlowTestParseNocase07 is a test for setting the from_client flow opt
758 */
759static int DetectFlowTestParseNocase07 (void)
760{
761 uint16_t parsed_flags = 0;
762 DetectFlowData *fd = DetectFlowParse(NULL, "FROM_CLIENT", &parsed_flags);
763 FAIL_IF_NULL(fd);
765 DetectFlowFree(NULL, fd);
766 PASS;
767}
768
769/**
770 * \test DetectFlowTestParseNocase08 is a test for setting the established,to_client flow opts
771 */
772static int DetectFlowTestParseNocase08 (void)
773{
774 uint16_t parsed_flags = 0;
775 DetectFlowData *fd = DetectFlowParse(NULL, "ESTABLISHED,TO_CLIENT", &parsed_flags);
776 FAIL_IF_NULL(fd);
779 fd->match_cnt == 2);
780 DetectFlowFree(NULL, fd);
781 PASS;
782}
783
784/**
785 * \test DetectFlowTestParseNocase09 is a test for setting the to_client,stateless flow opts (order of state,dir reversed)
786 */
787static int DetectFlowTestParseNocase09 (void)
788{
789 uint16_t parsed_flags = 0;
790 DetectFlowData *fd = DetectFlowParse(NULL, "TO_CLIENT,STATELESS", &parsed_flags);
791 FAIL_IF_NULL(fd);
794 fd->match_cnt == 2);
795 DetectFlowFree(NULL, fd);
796 PASS;
797}
798
799/**
800 * \test DetectFlowTestParseNocase10 is a test for setting the from_server,stateless flow opts (order of state,dir reversed)
801 */
802static int DetectFlowTestParseNocase10 (void)
803{
804 uint16_t parsed_flags = 0;
805 DetectFlowData *fd = DetectFlowParse(NULL, "FROM_SERVER,STATELESS", &parsed_flags);
806 FAIL_IF_NULL(fd);
809 fd->match_cnt == 2);
810 DetectFlowFree(NULL, fd);
811 PASS;
812}
813
814/**
815 * \test DetectFlowTestParseNocase11 is a test for setting the from_server,stateless flow opts with spaces all around
816 */
817static int DetectFlowTestParseNocase11 (void)
818{
819 uint16_t parsed_flags = 0;
820 DetectFlowData *fd = DetectFlowParse(NULL, " FROM_SERVER , STATELESS ", &parsed_flags);
821 FAIL_IF_NULL(fd);
824 fd->match_cnt == 2);
825 DetectFlowFree(NULL, fd);
826 PASS;
827}
828
829/**
830 * \test DetectFlowTestParse12 is a test for setting an invalid separator :
831 */
832static int DetectFlowTestParse12 (void)
833{
834 uint16_t parsed_flags = 0;
835 DetectFlowData *fd = DetectFlowParse(NULL, "from_server:stateless", &parsed_flags);
837 PASS;
838}
839
840/**
841 * \test DetectFlowTestParse13 is a test for an invalid option
842 */
843static int DetectFlowTestParse13 (void)
844{
845 uint16_t parsed_flags = 0;
846 DetectFlowData *fd = DetectFlowParse(NULL, "invalidoptiontest", &parsed_flags);
848 PASS;
849}
850
851/**
852 * \test DetectFlowTestParse14 is a test for a empty option
853 */
854static int DetectFlowTestParse14 (void)
855{
856 uint16_t parsed_flags = 0;
857 DetectFlowData *fd = DetectFlowParse(NULL, "", &parsed_flags);
859 PASS;
860}
861
862/**
863 * \test DetectFlowTestParse15 is a test for an invalid combo of options established,stateless
864 */
865static int DetectFlowTestParse15 (void)
866{
867 uint16_t parsed_flags = 0;
868 DetectFlowData *fd = DetectFlowParse(NULL, "established,stateless", &parsed_flags);
870 PASS;
871}
872
873/**
874 * \test DetectFlowTestParse16 is a test for an invalid combo of options to_client,to_server
875 */
876static int DetectFlowTestParse16 (void)
877{
878 uint16_t parsed_flags = 0;
879 DetectFlowData *fd = DetectFlowParse(NULL, "to_client,to_server", &parsed_flags);
881 PASS;
882}
883
884/**
885 * \test DetectFlowTestParse16 is a test for an invalid combo of options to_client,from_server
886 * flowbit flags are the same
887 */
888static int DetectFlowTestParse17 (void)
889{
890 uint16_t parsed_flags = 0;
891 DetectFlowData *fd = DetectFlowParse(NULL, "to_client,from_server", &parsed_flags);
893 PASS;
894}
895
896/**
897 * \test DetectFlowTestParse18 is a test for setting the from_server,stateless,only_stream flow opts (order of state,dir reversed)
898 */
899static int DetectFlowTestParse18 (void)
900{
901 uint16_t parsed_flags = 0;
902 DetectFlowData *fd =
903 DetectFlowParse(NULL, "from_server,established,only_stream", &parsed_flags);
904 FAIL_IF_NULL(fd);
907 FAIL_IF_NOT(fd->match_cnt == 2);
908 DetectFlowFree(NULL, fd);
909 PASS;
910}
911
912/**
913 * \test DetectFlowTestParseNocase18 is a test for setting the from_server,stateless,only_stream flow opts (order of state,dir reversed)
914 */
915static int DetectFlowTestParseNocase18 (void)
916{
917 uint16_t parsed_flags = 0;
918 DetectFlowData *fd =
919 DetectFlowParse(NULL, "FROM_SERVER,ESTABLISHED,ONLY_STREAM", &parsed_flags);
920 FAIL_IF_NULL(fd);
923 FAIL_IF_NOT(fd->match_cnt == 2);
924 DetectFlowFree(NULL, fd);
925 PASS;
926}
927
928
929/**
930 * \test DetectFlowTestParse19 is a test for one to many options passed to DetectFlowParse
931 */
932static int DetectFlowTestParse19 (void)
933{
934 uint16_t parsed_flags = 0;
935 DetectFlowData *fd =
936 DetectFlowParse(NULL, "from_server,established,only_stream,a", &parsed_flags);
938 PASS;
939}
940
941/**
942 * \test DetectFlowTestParse20 is a test for setting from_server, established, no_stream
943 */
944static int DetectFlowTestParse20 (void)
945{
946 uint16_t parsed_flags = 0;
947 DetectFlowData *fd = DetectFlowParse(NULL, "from_server,established,no_stream", &parsed_flags);
948 FAIL_IF_NULL(fd);
950 FAIL_IF_NOT(parsed_flags == DETECT_FLOW_FLAG_NOSTREAM);
951 FAIL_IF_NOT(fd->match_cnt == 2);
952 DetectFlowFree(NULL, fd);
953 PASS;
954}
955
956/**
957 * \test DetectFlowTestParse20 is a test for setting from_server, established, no_stream
958 */
959static int DetectFlowTestParseNocase20 (void)
960{
961 uint16_t parsed_flags = 0;
962 DetectFlowData *fd = DetectFlowParse(NULL, "FROM_SERVER,ESTABLISHED,NO_STREAM", &parsed_flags);
963 FAIL_IF_NULL(fd);
965 FAIL_IF_NOT(parsed_flags == DETECT_FLOW_FLAG_NOSTREAM);
966 FAIL_IF_NOT(fd->match_cnt == 2);
967 DetectFlowFree(NULL, fd);
968 PASS;
969}
970
971/**
972 * \test DetectFlowTestParse21 is a test for an invalid opt between to valid opts
973 */
974static int DetectFlowTestParse21 (void)
975{
976 uint16_t parsed_flags = 0;
977 DetectFlowData *fd = DetectFlowParse(NULL, "from_server,a,no_stream", &parsed_flags);
979 PASS;
980}
981
982/**
983 * \test DetectFlowTestParse22 is a test for setting the established,not_established flow opts both
984 */
985static int DetectFlowTestParse22(void)
986{
987 uint16_t parsed_flags = 0;
988 DetectFlowData *fd = DetectFlowParse(NULL, "established,not_established", &parsed_flags);
990 fd = DetectFlowParse(NULL, "not_established,established", &parsed_flags);
992 PASS;
993}
994
995static int DetectFlowSigTest01(void)
996{
997 uint8_t *buf = (uint8_t *)"supernovaduper";
998 uint16_t buflen = strlen((char *)buf);
999 ThreadVars th_v;
1001 memset(&dtv, 0, sizeof(DecodeThreadVars));
1002 memset(&th_v, 0, sizeof(th_v));
1003
1004 Packet *p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
1005 FAIL_IF_NULL(p);
1006
1007 const char *sig1 = "alert tcp any any -> any any (msg:\"dummy\"; "
1008 "content:\"nova\"; flow:no_stream; sid:1;)";
1009
1012 de_ctx->flags |= DE_QUIET;
1013
1014 de_ctx->sig_list = SigInit(de_ctx, sig1);
1016
1018 DetectEngineThreadCtx *det_ctx = NULL;
1019 DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1020 FAIL_IF_NULL(det_ctx);
1021
1022 SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1023 FAIL_IF(PacketAlertCheck(p, 1) != 1);
1024
1025 DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1027 UTHFreePacket(p);
1028
1029 PASS;
1030}
1031
1032/**
1033 * \test Test parsing of the not_established keyword.
1034 */
1035static int DetectFlowTestParseNotEstablished(void)
1036{
1037 uint16_t parsed_flags = 0;
1038 DetectFlowData *fd = DetectFlowParse(NULL, "not_established", &parsed_flags);
1039 FAIL_IF_NULL(fd);
1041 DetectFlowFree(NULL, fd);
1042 PASS;
1043}
1044
1045/**
1046 * \test Test parsing of the "no_frag" flow argument.
1047 */
1048static int DetectFlowTestParseNoFrag(void)
1049{
1050 uint16_t parsed_flags = 0;
1051 DetectFlowData *fd = DetectFlowParse(NULL, "no_frag", &parsed_flags);
1052 FAIL_IF_NULL(fd);
1054 DetectFlowFree(NULL, fd);
1055 PASS;
1056}
1057
1058/**
1059 * \test Test parsing of the "only_frag" flow argument.
1060 */
1061static int DetectFlowTestParseOnlyFrag(void)
1062{
1063 uint16_t parsed_flags = 0;
1064 DetectFlowData *fd = DetectFlowParse(NULL, "only_frag", &parsed_flags);
1065 FAIL_IF_NULL(fd);
1067 DetectFlowFree(NULL, fd);
1068 PASS;
1069}
1070
1071/**
1072 * \test Test that parsing of only_frag and no_frag together fails.
1073 */
1074static int DetectFlowTestParseNoFragOnlyFrag(void)
1075{
1076 uint16_t parsed_flags = 0;
1077 DetectFlowData *fd = DetectFlowParse(NULL, "no_frag,only_frag", &parsed_flags);
1078 FAIL_IF_NOT_NULL(fd);
1079 PASS;
1080}
1081
1082/**
1083 * \test Test no_frag matching.
1084 */
1085static int DetectFlowTestNoFragMatch(void)
1086{
1087 uint16_t parsed_flags = 0;
1088 uint32_t pflags = 0;
1089 DetectFlowData *fd = DetectFlowParse(NULL, "no_frag", &parsed_flags);
1090 FAIL_IF_NULL(fd);
1092 FAIL_IF_NOT(fd->match_cnt == 1);
1093 FAIL_IF_NOT(FlowMatch(pflags, 0, fd->flags, fd->match_cnt));
1094 pflags |= PKT_REBUILT_FRAGMENT;
1095 FAIL_IF(FlowMatch(pflags, 0, fd->flags, fd->match_cnt));
1096 PASS;
1097}
1098
1099/**
1100 * \test Test only_frag matching.
1101 */
1102static int DetectFlowTestOnlyFragMatch(void)
1103{
1104 uint16_t parsed_flags = 0;
1105 uint32_t pflags = 0;
1106 DetectFlowData *fd = DetectFlowParse(NULL, "only_frag", &parsed_flags);
1107 FAIL_IF_NULL(fd);
1109 FAIL_IF_NOT(fd->match_cnt == 1);
1110 FAIL_IF(FlowMatch(pflags, 0, fd->flags, fd->match_cnt));
1111 pflags |= PKT_REBUILT_FRAGMENT;
1112 FAIL_IF_NOT(FlowMatch(pflags, 0, fd->flags, fd->match_cnt));
1113 PASS;
1114}
1115
1116/**
1117 * \brief this function registers unit tests for DetectFlow
1118 */
1119static void DetectFlowRegisterTests(void)
1120{
1121 UtRegisterTest("DetectFlowTestParse01", DetectFlowTestParse01);
1122 UtRegisterTest("DetectFlowTestParse02", DetectFlowTestParse02);
1123 UtRegisterTest("DetectFlowTestParse03", DetectFlowTestParse03);
1124 UtRegisterTest("DetectFlowTestParse04", DetectFlowTestParse04);
1125 UtRegisterTest("DetectFlowTestParse05", DetectFlowTestParse05);
1126 UtRegisterTest("DetectFlowTestParse06", DetectFlowTestParse06);
1127 UtRegisterTest("DetectFlowTestParse07", DetectFlowTestParse07);
1128 UtRegisterTest("DetectFlowTestParse08", DetectFlowTestParse08);
1129 UtRegisterTest("DetectFlowTestParse09", DetectFlowTestParse09);
1130 UtRegisterTest("DetectFlowTestParse10", DetectFlowTestParse10);
1131 UtRegisterTest("DetectFlowTestParse11", DetectFlowTestParse11);
1132 UtRegisterTest("DetectFlowTestParseNocase01", DetectFlowTestParseNocase01);
1133 UtRegisterTest("DetectFlowTestParseNocase02", DetectFlowTestParseNocase02);
1134 UtRegisterTest("DetectFlowTestParseNocase03", DetectFlowTestParseNocase03);
1135 UtRegisterTest("DetectFlowTestParseNocase04", DetectFlowTestParseNocase04);
1136 UtRegisterTest("DetectFlowTestParseNocase05", DetectFlowTestParseNocase05);
1137 UtRegisterTest("DetectFlowTestParseNocase06", DetectFlowTestParseNocase06);
1138 UtRegisterTest("DetectFlowTestParseNocase07", DetectFlowTestParseNocase07);
1139 UtRegisterTest("DetectFlowTestParseNocase08", DetectFlowTestParseNocase08);
1140 UtRegisterTest("DetectFlowTestParseNocase09", DetectFlowTestParseNocase09);
1141 UtRegisterTest("DetectFlowTestParseNocase10", DetectFlowTestParseNocase10);
1142 UtRegisterTest("DetectFlowTestParseNocase11", DetectFlowTestParseNocase11);
1143 UtRegisterTest("DetectFlowTestParse12", DetectFlowTestParse12);
1144 UtRegisterTest("DetectFlowTestParse13", DetectFlowTestParse13);
1145 UtRegisterTest("DetectFlowTestParse14", DetectFlowTestParse14);
1146 UtRegisterTest("DetectFlowTestParse15", DetectFlowTestParse15);
1147 UtRegisterTest("DetectFlowTestParse16", DetectFlowTestParse16);
1148 UtRegisterTest("DetectFlowTestParse17", DetectFlowTestParse17);
1149 UtRegisterTest("DetectFlowTestParse18", DetectFlowTestParse18);
1150 UtRegisterTest("DetectFlowTestParseNocase18", DetectFlowTestParseNocase18);
1151 UtRegisterTest("DetectFlowTestParse19", DetectFlowTestParse19);
1152 UtRegisterTest("DetectFlowTestParse20", DetectFlowTestParse20);
1153 UtRegisterTest("DetectFlowTestParseNocase20", DetectFlowTestParseNocase20);
1154 UtRegisterTest("DetectFlowTestParse21", DetectFlowTestParse21);
1155 UtRegisterTest("DetectFlowTestParse22", DetectFlowTestParse22);
1156 UtRegisterTest("DetectFlowTestParseNotEstablished",
1157 DetectFlowTestParseNotEstablished);
1158 UtRegisterTest("DetectFlowTestParseNoFrag", DetectFlowTestParseNoFrag);
1159 UtRegisterTest("DetectFlowTestParseOnlyFrag",
1160 DetectFlowTestParseOnlyFrag);
1161 UtRegisterTest("DetectFlowTestParseNoFragOnlyFrag",
1162 DetectFlowTestParseNoFragOnlyFrag);
1163 UtRegisterTest("DetectFlowTestNoFragMatch", DetectFlowTestNoFragMatch);
1164 UtRegisterTest("DetectFlowTestOnlyFragMatch", DetectFlowTestOnlyFragMatch);
1165
1166 UtRegisterTest("DetectFlowSigTest01", DetectFlowSigTest01);
1167}
1168#endif /* UNITTESTS */
uint8_t flags
Definition decode-gre.h:0
#define PKT_REBUILT_FRAGMENT
Definition decode.h:1302
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
int PrefilterSetupPacketHeader(DetectEngineCtx *de_ctx, SigGroupHead *sgh, int sm_type, SignatureMask mask, void(*Set)(PrefilterPacketHeaderValue *v, void *), bool(*Compare)(PrefilterPacketHeaderValue v, void *), void(*Match)(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx))
DetectEngineCtx * DetectEngineCtxInit(void)
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data)
initialize thread specific detection engine context
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data)
void DetectFlowFree(DetectEngineCtx *, void *)
this function will free memory associated with DetectFlowData
#define SIG_FLAG_BOTH
int DetectFlowSetupImplicit(Signature *s, uint32_t flags)
void DetectFlowRegister(void)
Registration function for flow: keyword.
Definition detect-flow.c:65
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:
#define PARSE_REGEX
Regex for parsing our flow options.
Definition detect-flow.c:47
#define DETECT_FLOW_FLAG_NOSTREAM
Definition detect-flow.h:33
#define DETECT_FLOW_FLAG_ESTABLISHED
Definition detect-flow.h:29
#define DETECT_FLOW_FLAG_STATELESS
Definition detect-flow.h:31
#define DETECT_FLOW_FLAG_ONLYSTREAM
Definition detect-flow.h:32
#define DETECT_FLOW_FLAG_TOSERVER
Definition detect-flow.h:27
#define DETECT_FLOW_FLAG_ONLY_FRAG
Definition detect-flow.h:35
#define DETECT_FLOW_FLAG_NOT_ESTABLISHED
Definition detect-flow.h:30
#define DETECT_FLOW_FLAG_TOCLIENT
Definition detect-flow.h:28
#define DETECT_FLOW_FLAG_NO_FRAG
Definition detect-flow.h:34
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
int SC_Pcre2SubstringCopy(pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR *buffer, PCRE2_SIZE *bufflen)
Signature * SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
Parses a signature and adds it to the Detection Engine Context.
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
SigTableElmt * sigmatch_table
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition detect.c:2420
#define DETECT_TABLE_APP_TD_FLAG
Definition detect.h:566
#define DE_QUIET
Definition detect.h:330
#define DETECT_TABLE_PACKET_TD_FLAG
Definition detect.h:564
#define SIG_FLAG_REQUIRE_PACKET
Definition detect.h:254
#define SIG_FLAG_TOCLIENT
Definition detect.h:272
#define DETECT_TABLE_APP_FILTER_FLAG
Definition detect.h:565
#define SIGMATCH_SUPPORT_FIREWALL
Definition detect.h:1682
#define SIG_FLAG_INIT_FLOW
Definition detect.h:292
#define DETECT_TABLE_PACKET_PRE_STREAM_FLAG
Definition detect.h:562
#define DETECT_TABLE_PACKET_FILTER_FLAG
Definition detect.h:563
#define SIG_FLAG_TOSERVER
Definition detect.h:271
#define SIG_FLAG_REQUIRE_STREAM_ONLY
Definition detect.h:261
@ DETECT_SM_LIST_MATCH
Definition detect.h:117
#define SIG_FLAG_TXBOTHDIR
Definition detect.h:250
#define SIG_FLAG_REQUIRE_STREAM
Definition detect.h:255
#define FLOW_PKT_TOSERVER
Definition flow.h:233
#define FLOW_PKT_ESTABLISHED
Definition flow.h:235
#define FLOW_PKT_TOCLIENT
Definition flow.h:234
DecodeThreadVars * dtv
DetectEngineCtx * de_ctx
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
struct Thresholds ctx
Structure to hold thread specific data for all decode modules.
Definition decode.h:963
main detection engine ctx
Definition detect.h:932
uint8_t flags
Definition detect.h:934
Signature * sig_list
Definition detect.h:941
PrefilterRuleStore pmq
Definition detect.h:1349
uint8_t match_cnt
Definition detect-flow.h:39
uint8_t flowflags
Definition decode.h:532
uint32_t flags
Definition decode.h:544
Container for matching data for a signature group.
Definition detect.h:1629
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition detect.h:351
a single match condition for a signature
Definition detect.h:356
uint16_t type
Definition detect.h:357
struct SigMatch_ * next
Definition detect.h:360
const char * url
Definition detect.h:1462
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition detect.h:1441
int(* SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh)
Definition detect.h:1444
void(* Free)(DetectEngineCtx *, void *)
Definition detect.h:1446
uint16_t flags
Definition detect.h:1450
const char * desc
Definition detect.h:1461
void(* RegisterTests)(void)
Definition detect.h:1448
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition detect.h:1421
uint8_t tables
Definition detect.h:1454
const char * name
Definition detect.h:1459
bool(* SupportsPrefilter)(const Signature *s)
Definition detect.h:1443
uint32_t init_flags
Definition detect.h:608
struct SigMatch_ * smlists[DETECT_SM_LIST_MAX]
Definition detect.h:642
Signature container.
Definition detect.h:668
uint32_t flags
Definition detect.h:669
SignatureInitData * init_data
Definition detect.h:747
uint32_t id
Definition detect.h:713
Per thread variable structure.
Definition threadvars.h:58
#define BUG_ON(x)
uint32_t cnt
#define SCEnter(...)
Definition util-debug.h:277
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCReturnInt(x)
Definition util-debug.h:281
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define SCReturn
Definition util-debug.h:279
#define SCMalloc(sz)
Definition util-mem.h:47
#define SCFree(p)
Definition util-mem.h:61
#define unlikely(expr)
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.
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.