suricata
detect-tcp-flags.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 Breno Silva <breno.silva@gmail.com>
22  *
23  * Implements the flags keyword
24  */
25 
26 #include "suricata-common.h"
27 #include "suricata.h"
28 #include "decode.h"
29 
30 #include "detect.h"
31 #include "detect-parse.h"
34 
35 #include "flow-var.h"
36 #include "decode-events.h"
37 
38 #include "detect-tcp-flags.h"
39 #include "util-unittest.h"
40 
41 #include "util-debug.h"
42 
43 /**
44  * Regex (by Brian Rectanus)
45  * flags: [!+*](SAPRFU120)[,SAPRFU12]
46  */
47 #define PARSE_REGEX "^\\s*(?:([\\+\\*!]))?\\s*([SAPRFU120CE\\+\\*!]+)(?:\\s*,\\s*([SAPRFU12CE]+))?\\s*$"
48 
49 /**
50  * Flags args[0] *(3) +(2) !(1)
51  *
52  */
53 
54 #define MODIFIER_NOT 1
55 #define MODIFIER_PLUS 2
56 #define MODIFIER_ANY 3
57 
58 static DetectParseRegex parse_regex;
59 
60 static int DetectFlagsMatch (DetectEngineThreadCtx *, Packet *,
61  const Signature *, const SigMatchCtx *);
62 static int DetectFlagsSetup (DetectEngineCtx *, Signature *, const char *);
63 static void DetectFlagsFree(DetectEngineCtx *, void *);
64 
65 static bool PrefilterTcpFlagsIsPrefilterable(const Signature *s);
66 static int PrefilterSetupTcpFlags(DetectEngineCtx *de_ctx, SigGroupHead *sgh);
67 #ifdef UNITTESTS
68 static void FlagsRegisterTests(void);
69 #endif
70 
71 /**
72  * \brief Registration function for flags: keyword
73  */
74 
76 {
77  sigmatch_table[DETECT_FLAGS].name = "tcp.flags";
79  sigmatch_table[DETECT_FLAGS].desc = "detect which flags are set in the TCP header";
80  sigmatch_table[DETECT_FLAGS].url = "/rules/header-keywords.html#tcp-flags";
81  sigmatch_table[DETECT_FLAGS].Match = DetectFlagsMatch;
82  sigmatch_table[DETECT_FLAGS].Setup = DetectFlagsSetup;
83  sigmatch_table[DETECT_FLAGS].Free = DetectFlagsFree;
84 #ifdef UNITTESTS
85  sigmatch_table[DETECT_FLAGS].RegisterTests = FlagsRegisterTests;
86 #endif
87  sigmatch_table[DETECT_FLAGS].SupportsPrefilter = PrefilterTcpFlagsIsPrefilterable;
88  sigmatch_table[DETECT_FLAGS].SetupPrefilter = PrefilterSetupTcpFlags;
89 
90  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
91 }
92 
93 static inline int FlagsMatch(const uint8_t pflags, const uint8_t modifier,
94  const uint8_t dflags, const uint8_t iflags)
95 {
96  if (!dflags && pflags) {
97  if(modifier == MODIFIER_NOT) {
98  SCReturnInt(1);
99  }
100 
101  SCReturnInt(0);
102  }
103 
104  const uint8_t flags = pflags & iflags;
105 
106  switch (modifier) {
107  case MODIFIER_ANY:
108  if ((flags & dflags) > 0) {
109  SCReturnInt(1);
110  }
111  SCReturnInt(0);
112 
113  case MODIFIER_PLUS:
114  if (((flags & dflags) == dflags)) {
115  SCReturnInt(1);
116  }
117  SCReturnInt(0);
118 
119  case MODIFIER_NOT:
120  if ((flags & dflags) != dflags) {
121  SCReturnInt(1);
122  }
123  SCReturnInt(0);
124 
125  default:
126  SCLogDebug("flags %"PRIu8" and de->flags %"PRIu8"", flags, dflags);
127  if (flags == dflags) {
128  SCReturnInt(1);
129  }
130  }
131 
132  SCReturnInt(0);
133 }
134 
135 /**
136  * \internal
137  * \brief This function is used to match flags on a packet with those passed via flags:
138  *
139  * \param t pointer to thread vars
140  * \param det_ctx pointer to the pattern matcher thread
141  * \param p pointer to the current packet
142  * \param s pointer to the Signature
143  * \param m pointer to the sigmatch
144  *
145  * \retval 0 no match
146  * \retval 1 match
147  */
148 static int DetectFlagsMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
149  const Signature *s, const SigMatchCtx *ctx)
150 {
151  SCEnter();
152 
153  if (!(PKT_IS_TCP(p)) || PKT_IS_PSEUDOPKT(p)) {
154  SCReturnInt(0);
155  }
156 
157  const DetectFlagsData *de = (const DetectFlagsData *)ctx;
158  const uint8_t flags = p->tcph->th_flags;
159 
160  return FlagsMatch(flags, de->modifier, de->flags, de->ignored_flags);
161 }
162 
163 /**
164  * \internal
165  * \brief This function is used to parse flags options passed via flags: keyword
166  *
167  * \param rawstr Pointer to the user provided flags options
168  *
169  * \retval de pointer to DetectFlagsData on success
170  * \retval NULL on failure
171  */
172 static DetectFlagsData *DetectFlagsParse (const char *rawstr)
173 {
174  SCEnter();
175 
176  int ret = 0, found = 0, ignore = 0, res = 0;
177  int ov[MAX_SUBSTRINGS];
178  char *ptr;
179 
180  char arg1[16] = "";
181  char arg2[16] = "";
182  char arg3[16] = "";
183 
184  ret = DetectParsePcreExec(&parse_regex, rawstr, 0, 0, ov, MAX_SUBSTRINGS);
185  SCLogDebug("input '%s', pcre said %d", rawstr, ret);
186  if (ret < 3) {
187  SCLogError(SC_ERR_PCRE_MATCH, "pcre match failed");
188  SCReturnPtr(NULL, "DetectFlagsData");
189  }
190 
191  res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 1, arg1, sizeof(arg1));
192  if (res < 0) {
193  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
194  SCReturnPtr(NULL, "DetectFlagsData");
195  }
196  if (ret >= 2) {
197  res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 2, arg2, sizeof(arg2));
198  if (res < 0) {
199  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
200  SCReturnPtr(NULL, "DetectFlagsData");
201  }
202  }
203  if (ret >= 3) {
204  res = pcre_copy_substring((char *)rawstr, ov, MAX_SUBSTRINGS, 3, arg3, sizeof(arg3));
205  if (res < 0) {
206  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
207  SCReturnPtr(NULL, "DetectFlagsData");
208  }
209  }
210  SCLogDebug("args '%s', '%s', '%s'", arg1, arg2, arg3);
211 
212  if (strlen(arg2) == 0) {
213  SCLogDebug("empty argument");
214  SCReturnPtr(NULL, "DetectFlagsData");
215  }
216 
218  if (unlikely(de == NULL))
219  goto error;
220  memset(de, 0, sizeof(DetectFlagsData));
221  de->ignored_flags = 0xff;
222 
223  /** First parse args1 */
224  ptr = arg1;
225  while (*ptr != '\0') {
226  switch (*ptr) {
227  case 'S':
228  case 's':
229  de->flags |= TH_SYN;
230  found++;
231  break;
232  case 'A':
233  case 'a':
234  de->flags |= TH_ACK;
235  found++;
236  break;
237  case 'F':
238  case 'f':
239  de->flags |= TH_FIN;
240  found++;
241  break;
242  case 'R':
243  case 'r':
244  de->flags |= TH_RST;
245  found++;
246  break;
247  case 'P':
248  case 'p':
249  de->flags |= TH_PUSH;
250  found++;
251  break;
252  case 'U':
253  case 'u':
254  de->flags |= TH_URG;
255  found++;
256  break;
257  case '1':
258  de->flags |= TH_CWR;
259  found++;
260  break;
261  case '2':
262  de->flags |= TH_ECN;
263  found++;
264  break;
265  case 'C':
266  case 'c':
267  de->flags |= TH_CWR;
268  found++;
269  break;
270  case 'E':
271  case 'e':
272  de->flags |= TH_ECN;
273  found++;
274  break;
275  case '0':
276  de->flags = 0;
277  found++;
278  break;
279 
280  case '!':
281  de->modifier = MODIFIER_NOT;
282  break;
283  case '+':
284  de->modifier = MODIFIER_PLUS;
285  break;
286  case '*':
287  de->modifier = MODIFIER_ANY;
288  break;
289  }
290  ptr++;
291  }
292 
293  /** Second parse first set of flags */
294  if (strlen(arg2) > 0) {
295  ptr = arg2;
296  while (*ptr != '\0') {
297  switch (*ptr) {
298  case 'S':
299  case 's':
300  de->flags |= TH_SYN;
301  found++;
302  break;
303  case 'A':
304  case 'a':
305  de->flags |= TH_ACK;
306  found++;
307  break;
308  case 'F':
309  case 'f':
310  de->flags |= TH_FIN;
311  found++;
312  break;
313  case 'R':
314  case 'r':
315  de->flags |= TH_RST;
316  found++;
317  break;
318  case 'P':
319  case 'p':
320  de->flags |= TH_PUSH;
321  found++;
322  break;
323  case 'U':
324  case 'u':
325  de->flags |= TH_URG;
326  found++;
327  break;
328  case '1':
329  case 'C':
330  case 'c':
331  de->flags |= TH_CWR;
332  found++;
333  break;
334  case '2':
335  case 'E':
336  case 'e':
337  de->flags |= TH_ECN;
338  found++;
339  break;
340  case '0':
341  de->flags = 0;
342  found++;
343  break;
344 
345  case '!':
346  if (de->modifier != 0) {
347  SCLogError(SC_ERR_FLAGS_MODIFIER, "\"flags\" supports only"
348  " one modifier at a time");
349  goto error;
350  }
351  de->modifier = MODIFIER_NOT;
352  SCLogDebug("NOT modifier is set");
353  break;
354  case '+':
355  if (de->modifier != 0) {
356  SCLogError(SC_ERR_FLAGS_MODIFIER, "\"flags\" supports only"
357  " one modifier at a time");
358  goto error;
359  }
360  de->modifier = MODIFIER_PLUS;
361  SCLogDebug("PLUS modifier is set");
362  break;
363  case '*':
364  if (de->modifier != 0) {
365  SCLogError(SC_ERR_FLAGS_MODIFIER, "\"flags\" supports only"
366  " one modifier at a time");
367  goto error;
368  }
369  de->modifier = MODIFIER_ANY;
370  SCLogDebug("ANY modifier is set");
371  break;
372  default:
373  break;
374  }
375  ptr++;
376  }
377 
378  if (found == 0)
379  goto error;
380  }
381 
382  /** Finally parse ignored flags */
383  if (strlen(arg3) > 0) {
384  ptr = arg3;
385 
386  while (*ptr != '\0') {
387  switch (*ptr) {
388  case 'S':
389  case 's':
390  de->ignored_flags &= ~TH_SYN;
391  ignore++;
392  break;
393  case 'A':
394  case 'a':
395  de->ignored_flags &= ~TH_ACK;
396  ignore++;
397  break;
398  case 'F':
399  case 'f':
400  de->ignored_flags &= ~TH_FIN;
401  ignore++;
402  break;
403  case 'R':
404  case 'r':
405  de->ignored_flags &= ~TH_RST;
406  ignore++;
407  break;
408  case 'P':
409  case 'p':
410  de->ignored_flags &= ~TH_PUSH;
411  ignore++;
412  break;
413  case 'U':
414  case 'u':
415  de->ignored_flags &= ~TH_URG;
416  ignore++;
417  break;
418  case '1':
419  de->ignored_flags &= ~TH_CWR;
420  ignore++;
421  break;
422  case '2':
423  de->ignored_flags &= ~TH_ECN;
424  ignore++;
425  break;
426  case 'C':
427  case 'c':
428  de->ignored_flags &= ~TH_CWR;
429  ignore++;
430  break;
431  case 'E':
432  case 'e':
433  de->ignored_flags &= ~TH_ECN;
434  ignore++;
435  break;
436  case '0':
437  break;
438  default:
439  break;
440  }
441  ptr++;
442  }
443 
444  if (ignore == 0) {
445  SCLogDebug("ignore == 0");
446  goto error;
447  }
448  }
449 
450  SCLogDebug("found %"PRId32" ignore %"PRId32"", found, ignore);
451  SCReturnPtr(de, "DetectFlagsData");
452 
453 error:
454  if (de) {
455  SCFree(de);
456  }
457  SCReturnPtr(NULL, "DetectFlagsData");
458 }
459 
460 /**
461  * \internal
462  * \brief this function is used to add the parsed flags into the current signature
463  *
464  * \param de_ctx pointer to the Detection Engine Context
465  * \param s pointer to the Current Signature
466  * \param m pointer to the Current SigMatch
467  * \param rawstr pointer to the user provided flags options
468  *
469  * \retval 0 on Success
470  * \retval -1 on Failure
471  */
472 static int DetectFlagsSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
473 {
474  DetectFlagsData *de = NULL;
475  SigMatch *sm = NULL;
476 
477  de = DetectFlagsParse(rawstr);
478  if (de == NULL)
479  goto error;
480 
481  sm = SigMatchAlloc();
482  if (sm == NULL)
483  goto error;
484 
485  sm->type = DETECT_FLAGS;
486  sm->ctx = (SigMatchCtx *)de;
487 
490 
491  return 0;
492 
493 error:
494  if (de) SCFree(de);
495  if (sm) SCFree(sm);
496  return -1;
497 }
498 
499 /**
500  * \internal
501  * \brief this function will free memory associated with DetectFlagsData
502  *
503  * \param de pointer to DetectFlagsData
504  */
505 static void DetectFlagsFree(DetectEngineCtx *de_ctx, void *de_ptr)
506 {
507  DetectFlagsData *de = (DetectFlagsData *)de_ptr;
508  if(de) SCFree(de);
509 }
510 
512 {
513  const SigMatch *sm;
514  for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
515  switch (sm->type) {
516  case DETECT_FLAGS:
517  {
518  const DetectFlagsData *fl = (const DetectFlagsData *)sm->ctx;
519 
520  if (!(fl->modifier == MODIFIER_NOT) && (fl->flags & TH_SYN)) {
521  return 1;
522  }
523  break;
524  }
525  }
526  }
527  return 0;
528 }
529 
531 {
532  const SigMatch *sm;
533  for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
534  switch (sm->type) {
535  case DETECT_FLAGS:
536  {
537  const DetectFlagsData *fl = (const DetectFlagsData *)sm->ctx;
538 
539  if (!(fl->modifier == MODIFIER_NOT) && (fl->flags == TH_SYN)) {
540  return 1;
541  }
542  break;
543  }
544  }
545  }
546  return 0;
547 }
548 
549 static void
550 PrefilterPacketFlagsMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
551 {
552  if (!(PKT_IS_TCP(p)) || PKT_IS_PSEUDOPKT(p)) {
553  SCReturn;
554  }
555 
556  const PrefilterPacketHeaderCtx *ctx = pectx;
557  if (PrefilterPacketHeaderExtraMatch(ctx, p) == FALSE)
558  return;
559 
560  const uint8_t flags = p->tcph->th_flags;
561  if (FlagsMatch(flags, ctx->v1.u8[0], ctx->v1.u8[1], ctx->v1.u8[2]))
562  {
563  SCLogDebug("packet matches TCP flags %02x", ctx->v1.u8[1]);
564  PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
565  }
566 }
567 
568 static void
569 PrefilterPacketFlagsSet(PrefilterPacketHeaderValue *v, void *smctx)
570 {
571  const DetectFlagsData *a = smctx;
572  v->u8[0] = a->modifier;
573  v->u8[1] = a->flags;
574  v->u8[2] = a->ignored_flags;
575  SCLogDebug("v->u8[0] = %02x", v->u8[0]);
576 }
577 
578 static bool
579 PrefilterPacketFlagsCompare(PrefilterPacketHeaderValue v, void *smctx)
580 {
581  const DetectFlagsData *a = smctx;
582  if (v.u8[0] == a->modifier &&
583  v.u8[1] == a->flags &&
584  v.u8[2] == a->ignored_flags)
585  return TRUE;
586  return FALSE;
587 }
588 
589 static int PrefilterSetupTcpFlags(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
590 {
592  PrefilterPacketFlagsSet,
593  PrefilterPacketFlagsCompare,
594  PrefilterPacketFlagsMatch);
595 
596 }
597 
598 static bool PrefilterTcpFlagsIsPrefilterable(const Signature *s)
599 {
600  const SigMatch *sm;
601  for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
602  switch (sm->type) {
603  case DETECT_FLAGS:
604  return TRUE;
605  }
606  }
607  return FALSE;
608 }
609 
610 /*
611  * ONLY TESTS BELOW THIS COMMENT
612  */
613 
614 #ifdef UNITTESTS
615 /**
616  * \test FlagsTestParse01 is a test for a valid flags value
617  *
618  * \retval 1 on succces
619  * \retval 0 on failure
620  */
621 static int FlagsTestParse01 (void)
622 {
623  DetectFlagsData *de = DetectFlagsParse("S");
624  FAIL_IF_NULL(de);
625  FAIL_IF_NOT(de->flags == TH_SYN);
626  DetectFlagsFree(NULL, de);
627  PASS;
628 }
629 
630 /**
631  * \test FlagsTestParse02 is a test for an invalid flags value
632  *
633  * \retval 1 on succces
634  * \retval 0 on failure
635  */
636 static int FlagsTestParse02 (void)
637 {
638  DetectFlagsData *de = NULL;
639  de = DetectFlagsParse("G");
640  if (de) {
641  DetectFlagsFree(NULL, de);
642  return 0;
643  }
644 
645  return 1;
646 }
647 
648 /**
649  * \test FlagsTestParse03 test if ACK and PUSH are set. Must return success
650  *
651  * \retval 1 on success
652  * \retval 0 on failure
653  */
654 static int FlagsTestParse03 (void)
655 {
657  if (unlikely(p == NULL))
658  return 0;
659  ThreadVars tv;
660  int ret = 0;
661  DetectFlagsData *de = NULL;
662  SigMatch *sm = NULL;
663  IPV4Hdr ipv4h;
664  TCPHdr tcph;
665 
666  memset(&tv, 0, sizeof(ThreadVars));
667  memset(p, 0, SIZE_OF_PACKET);
668  memset(&ipv4h, 0, sizeof(IPV4Hdr));
669  memset(&tcph, 0, sizeof(TCPHdr));
670 
671  p->ip4h = &ipv4h;
672  p->tcph = &tcph;
673  p->tcph->th_flags = TH_ACK|TH_PUSH|TH_SYN|TH_RST;
674 
675  de = DetectFlagsParse("AP+");
676 
677  if (de == NULL || (de->flags != (TH_ACK|TH_PUSH)) )
678  goto error;
679 
680  sm = SigMatchAlloc();
681  if (sm == NULL)
682  goto error;
683 
684  sm->type = DETECT_FLAGS;
685  sm->ctx = (SigMatchCtx *)de;
686 
687  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
688 
689  if(ret) {
690  if (de) SCFree(de);
691  if (sm) SCFree(sm);
692  SCFree(p);
693  return 1;
694  }
695 
696 error:
697  if (de) SCFree(de);
698  if (sm) SCFree(sm);
699  SCFree(p);
700  return 0;
701 }
702 
703 /**
704  * \test FlagsTestParse04 check if ACK bit is set. Must fails.
705  *
706  * \retval 1 on succces
707  * \retval 0 on failure
708  */
709 static int FlagsTestParse04 (void)
710 {
712  if (unlikely(p == NULL))
713  return 0;
714  ThreadVars tv;
715  int ret = 0;
716  DetectFlagsData *de = NULL;
717  SigMatch *sm = NULL;
718  IPV4Hdr ipv4h;
719  TCPHdr tcph;
720 
721  memset(&tv, 0, sizeof(ThreadVars));
722  memset(p, 0, SIZE_OF_PACKET);
723  memset(&ipv4h, 0, sizeof(IPV4Hdr));
724  memset(&tcph, 0, sizeof(TCPHdr));
725 
726  p->ip4h = &ipv4h;
727  p->tcph = &tcph;
728  p->tcph->th_flags = TH_SYN;
729 
730  de = DetectFlagsParse("A");
731 
732  if (de == NULL || de->flags != TH_ACK)
733  goto error;
734 
735  sm = SigMatchAlloc();
736  if (sm == NULL)
737  goto error;
738 
739  sm->type = DETECT_FLAGS;
740  sm->ctx = (SigMatchCtx *)de;
741 
742  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
743 
744  if(ret) {
745  if (de) SCFree(de);
746  if (sm) SCFree(sm);
747  SCFree(p);
748  return 0;
749  }
750 
751  /* Error expected. */
752 error:
753  if (de) SCFree(de);
754  if (sm) SCFree(sm);
755  SCFree(p);
756  return 1;
757 }
758 
759 /**
760  * \test FlagsTestParse05 test if ACK+PUSH and more flags are set. Ignore SYN and RST bits.
761  * Must fails.
762  * \retval 1 on success
763  * \retval 0 on failure
764  */
765 static int FlagsTestParse05 (void)
766 {
768  if (unlikely(p == NULL))
769  return 0;
770  ThreadVars tv;
771  int ret = 0;
772  DetectFlagsData *de = NULL;
773  SigMatch *sm = NULL;
774  IPV4Hdr ipv4h;
775  TCPHdr tcph;
776 
777  memset(&tv, 0, sizeof(ThreadVars));
778  memset(p, 0, SIZE_OF_PACKET);
779  memset(&ipv4h, 0, sizeof(IPV4Hdr));
780  memset(&tcph, 0, sizeof(TCPHdr));
781 
782  p->ip4h = &ipv4h;
783  p->tcph = &tcph;
784  p->tcph->th_flags = TH_ACK|TH_PUSH|TH_SYN|TH_RST;
785 
786  de = DetectFlagsParse("+AP,SR");
787 
788  if (de == NULL || (de->modifier != MODIFIER_PLUS) || (de->flags != (TH_ACK|TH_PUSH)) || (de->ignored_flags != (TH_SYN|TH_RST)))
789  goto error;
790 
791  sm = SigMatchAlloc();
792  if (sm == NULL)
793  goto error;
794 
795  sm->type = DETECT_FLAGS;
796  sm->ctx = (SigMatchCtx *)de;
797 
798  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
799 
800  if(ret) {
801  if (de) SCFree(de);
802  if (sm) SCFree(sm);
803  SCFree(p);
804  return 0;
805  }
806 
807  /* Error expected. */
808 error:
809  if (de) SCFree(de);
810  if (sm) SCFree(sm);
811  SCFree(p);
812  return 1;
813 }
814 
815 /**
816  * \test FlagsTestParse06 test if ACK+PUSH and more flags are set. Ignore URG and RST bits.
817  * Must return success.
818  * \retval 1 on success
819  * \retval 0 on failure
820  */
821 static int FlagsTestParse06 (void)
822 {
824  if (unlikely(p == NULL))
825  return 0;
826  ThreadVars tv;
827  int ret = 0;
828  DetectFlagsData *de = NULL;
829  SigMatch *sm = NULL;
830  IPV4Hdr ipv4h;
831  TCPHdr tcph;
832 
833  memset(&tv, 0, sizeof(ThreadVars));
834  memset(p, 0, SIZE_OF_PACKET);
835  memset(&ipv4h, 0, sizeof(IPV4Hdr));
836  memset(&tcph, 0, sizeof(TCPHdr));
837 
838  p->ip4h = &ipv4h;
839  p->tcph = &tcph;
840  p->tcph->th_flags = TH_ACK|TH_PUSH|TH_SYN|TH_RST;
841 
842  de = DetectFlagsParse("+AP,UR");
843 
844  if (de == NULL || (de->modifier != MODIFIER_PLUS) || (de->flags != (TH_ACK|TH_PUSH)) || ((0xff - de->ignored_flags) != (TH_URG|TH_RST)))
845  goto error;
846 
847  sm = SigMatchAlloc();
848  if (sm == NULL)
849  goto error;
850 
851  sm->type = DETECT_FLAGS;
852  sm->ctx = (SigMatchCtx *)de;
853 
854  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
855 
856  if(ret) {
857  if (de) SCFree(de);
858  if (sm) SCFree(sm);
859  SCFree(p);
860  return 1;
861  }
862 
863 error:
864  if (de) SCFree(de);
865  if (sm) SCFree(sm);
866  SCFree(p);
867  return 0;
868 }
869 
870 /**
871  * \test FlagsTestParse07 test if SYN or RST are set. Must fails.
872  *
873  * \retval 1 on success
874  * \retval 0 on failure
875  */
876 static int FlagsTestParse07 (void)
877 {
879  if (unlikely(p == NULL))
880  return 0;
881  ThreadVars tv;
882  int ret = 0;
883  DetectFlagsData *de = NULL;
884  SigMatch *sm = NULL;
885  IPV4Hdr ipv4h;
886  TCPHdr tcph;
887 
888  memset(&tv, 0, sizeof(ThreadVars));
889  memset(p, 0, SIZE_OF_PACKET);
890  memset(&ipv4h, 0, sizeof(IPV4Hdr));
891  memset(&tcph, 0, sizeof(TCPHdr));
892 
893  p->ip4h = &ipv4h;
894  p->tcph = &tcph;
895  p->tcph->th_flags = TH_SYN|TH_RST;
896 
897  de = DetectFlagsParse("*AP");
898 
899  if (de == NULL || (de->modifier != MODIFIER_ANY) || (de->flags != (TH_ACK|TH_PUSH)))
900  goto error;
901 
902  sm = SigMatchAlloc();
903  if (sm == NULL)
904  goto error;
905 
906  sm->type = DETECT_FLAGS;
907  sm->ctx = (SigMatchCtx *)de;
908 
909  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
910 
911  if(ret) {
912  if (de) SCFree(de);
913  if (sm) SCFree(sm);
914  SCFree(p);
915  return 0;
916  }
917 
918  /* Error expected. */
919 error:
920  if (de) SCFree(de);
921  if (sm) SCFree(sm);
922  SCFree(p);
923  return 1;
924 }
925 
926 /**
927  * \test FlagsTestParse08 test if SYN or RST are set. Must return success.
928  *
929  * \retval 1 on success
930  * \retval 0 on failure
931  */
932 static int FlagsTestParse08 (void)
933 {
935  if (unlikely(p == NULL))
936  return 0;
937  ThreadVars tv;
938  int ret = 0;
939  DetectFlagsData *de = NULL;
940  SigMatch *sm = NULL;
941  IPV4Hdr ipv4h;
942  TCPHdr tcph;
943 
944  memset(&tv, 0, sizeof(ThreadVars));
945  memset(p, 0, SIZE_OF_PACKET);
946  memset(&ipv4h, 0, sizeof(IPV4Hdr));
947  memset(&tcph, 0, sizeof(TCPHdr));
948 
949  p->ip4h = &ipv4h;
950  p->tcph = &tcph;
951  p->tcph->th_flags = TH_SYN|TH_RST;
952 
953  de = DetectFlagsParse("*SA");
954 
955  if (de == NULL || (de->modifier != MODIFIER_ANY) || (de->flags != (TH_ACK|TH_SYN)))
956  goto error;
957 
958  sm = SigMatchAlloc();
959  if (sm == NULL)
960  goto error;
961 
962  sm->type = DETECT_FLAGS;
963  sm->ctx = (SigMatchCtx *)de;
964 
965  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
966 
967  if(ret) {
968  if (de) SCFree(de);
969  if (sm) SCFree(sm);
970  SCFree(p);
971  return 1;
972  }
973 
974 error:
975  if (de) SCFree(de);
976  if (sm) SCFree(sm);
977  SCFree(p);
978  return 0;
979 }
980 
981 /**
982  * \test FlagsTestParse09 test if SYN and RST are not set. Must fails.
983  *
984  * \retval 1 on success
985  * \retval 0 on failure
986  */
987 static int FlagsTestParse09 (void)
988 {
990  if (unlikely(p == NULL))
991  return 0;
992  ThreadVars tv;
993  int ret = 0;
994  DetectFlagsData *de = NULL;
995  SigMatch *sm = NULL;
996  IPV4Hdr ipv4h;
997  TCPHdr tcph;
998 
999  memset(&tv, 0, sizeof(ThreadVars));
1000  memset(p, 0, SIZE_OF_PACKET);
1001  memset(&ipv4h, 0, sizeof(IPV4Hdr));
1002  memset(&tcph, 0, sizeof(TCPHdr));
1003 
1004  p->ip4h = &ipv4h;
1005  p->tcph = &tcph;
1006  p->tcph->th_flags = TH_SYN|TH_RST;
1007 
1008  de = DetectFlagsParse("!PA");
1009 
1010  if (de == NULL || (de->modifier != MODIFIER_NOT) || (de->flags != (TH_ACK|TH_PUSH)))
1011  goto error;
1012 
1013  sm = SigMatchAlloc();
1014  if (sm == NULL)
1015  goto error;
1016 
1017  sm->type = DETECT_FLAGS;
1018  sm->ctx = (SigMatchCtx *)de;
1019 
1020  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
1021 
1022  if(ret) {
1023  if (de) SCFree(de);
1024  if (sm) SCFree(sm);
1025  SCFree(p);
1026  return 1;
1027  }
1028 
1029 error:
1030  if (de) SCFree(de);
1031  if (sm) SCFree(sm);
1032  SCFree(p);
1033  return 0;
1034 }
1035 
1036 /**
1037  * \test FlagsTestParse10 test if ACK and PUSH are not set. Must return success.
1038  *
1039  * \retval 1 on success
1040  * \retval 0 on failure
1041  */
1042 static int FlagsTestParse10 (void)
1043 {
1045  if (unlikely(p == NULL))
1046  return 0;
1047  ThreadVars tv;
1048  int ret = 0;
1049  DetectFlagsData *de = NULL;
1050  SigMatch *sm = NULL;
1051  IPV4Hdr ipv4h;
1052  TCPHdr tcph;
1053 
1054  memset(&tv, 0, sizeof(ThreadVars));
1055  memset(p, 0, SIZE_OF_PACKET);
1056  memset(&ipv4h, 0, sizeof(IPV4Hdr));
1057  memset(&tcph, 0, sizeof(TCPHdr));
1058 
1059  p->ip4h = &ipv4h;
1060  p->tcph = &tcph;
1061  p->tcph->th_flags = TH_SYN|TH_RST;
1062 
1063  de = DetectFlagsParse("!AP");
1064 
1065  if (de == NULL || (de->modifier != MODIFIER_NOT) || (de->flags != (TH_ACK|TH_PUSH)))
1066  goto error;
1067 
1068  sm = SigMatchAlloc();
1069  if (sm == NULL)
1070  goto error;
1071 
1072  sm->type = DETECT_FLAGS;
1073  sm->ctx = (SigMatchCtx *)de;
1074 
1075  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
1076 
1077  if(ret) {
1078  if (de) SCFree(de);
1079  if (sm) SCFree(sm);
1080  SCFree(p);
1081  return 1;
1082  }
1083 
1084 error:
1085  if (de) SCFree(de);
1086  if (sm) SCFree(sm);
1087  SCFree(p);
1088  return 0;
1089 }
1090 
1091 /**
1092  * \test FlagsTestParse11 test if ACK or PUSH are set. Ignore SYN and RST. Must fails.
1093  *
1094  * \retval 1 on success
1095  * \retval 0 on failure
1096  */
1097 static int FlagsTestParse11 (void)
1098 {
1100  if (unlikely(p == NULL))
1101  return 0;
1102  ThreadVars tv;
1103  int ret = 0;
1104  DetectFlagsData *de = NULL;
1105  SigMatch *sm = NULL;
1106  IPV4Hdr ipv4h;
1107  TCPHdr tcph;
1108 
1109  memset(&tv, 0, sizeof(ThreadVars));
1110  memset(p, 0, SIZE_OF_PACKET);
1111  memset(&ipv4h, 0, sizeof(IPV4Hdr));
1112  memset(&tcph, 0, sizeof(TCPHdr));
1113 
1114  p->ip4h = &ipv4h;
1115  p->tcph = &tcph;
1116  p->tcph->th_flags = TH_SYN|TH_RST|TH_URG;
1117 
1118  de = DetectFlagsParse("*AP,SR");
1119 
1120  if (de == NULL || (de->modifier != MODIFIER_ANY) || (de->flags != (TH_ACK|TH_PUSH)) || ((0xff - de->ignored_flags) != (TH_SYN|TH_RST)))
1121  goto error;
1122 
1123  sm = SigMatchAlloc();
1124  if (sm == NULL)
1125  goto error;
1126 
1127  sm->type = DETECT_FLAGS;
1128  sm->ctx = (SigMatchCtx *)de;
1129 
1130  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
1131 
1132  if(ret) {
1133  if (de) SCFree(de);
1134  if (sm) SCFree(sm);
1135  SCFree(p);
1136  return 0;
1137  }
1138 
1139  /* Expected. */
1140 error:
1141  if (de) SCFree(de);
1142  if (sm) SCFree(sm);
1143  SCFree(p);
1144  return 1;
1145 }
1146 
1147 /**
1148  * \test FlagsTestParse12 check if no flags are set. Must fails.
1149  *
1150  * \retval 1 on succces
1151  * \retval 0 on failure
1152  */
1153 static int FlagsTestParse12 (void)
1154 {
1156  if (unlikely(p == NULL))
1157  return 0;
1158  ThreadVars tv;
1159  int ret = 0;
1160  DetectFlagsData *de = NULL;
1161  SigMatch *sm = NULL;
1162  IPV4Hdr ipv4h;
1163  TCPHdr tcph;
1164 
1165  memset(&tv, 0, sizeof(ThreadVars));
1166  memset(p, 0, SIZE_OF_PACKET);
1167  memset(&ipv4h, 0, sizeof(IPV4Hdr));
1168  memset(&tcph, 0, sizeof(TCPHdr));
1169 
1170  p->ip4h = &ipv4h;
1171  p->tcph = &tcph;
1172  p->tcph->th_flags = TH_SYN;
1173 
1174  de = DetectFlagsParse("0");
1175 
1176  if (de == NULL || de->flags != 0) {
1177  printf("de setup: ");
1178  goto error;
1179  }
1180 
1181  sm = SigMatchAlloc();
1182  if (sm == NULL)
1183  goto error;
1184 
1185  sm->type = DETECT_FLAGS;
1186  sm->ctx = (SigMatchCtx *)de;
1187 
1188  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
1189 
1190  if(ret) {
1191  if (de) SCFree(de);
1192  if (sm) SCFree(sm);
1193  SCFree(p);
1194  return 0;
1195  }
1196 
1197  /* Expected. */
1198 error:
1199  if (de) SCFree(de);
1200  if (sm) SCFree(sm);
1201  SCFree(p);
1202  return 1;
1203 }
1204 
1205 /**
1206  * \test test for a valid flags value
1207  *
1208  * \retval 1 on succces
1209  * \retval 0 on failure
1210  */
1211 static int FlagsTestParse13 (void)
1212 {
1213  DetectFlagsData *de = NULL;
1214  de = DetectFlagsParse("+S*");
1215  if (de != NULL) {
1216  DetectFlagsFree(NULL, de);
1217  return 0;
1218  }
1219 
1220  return 1;
1221 }
1222 
1223 /**
1224  * \test Parse 'C' and 'E' flags.
1225  *
1226  * \retval 1 on success.
1227  * \retval 0 on failure.
1228  */
1229 static int FlagsTestParse14(void)
1230 {
1231  DetectFlagsData *de = DetectFlagsParse("CE");
1232  if (de != NULL && (de->flags == (TH_CWR | TH_ECN)) ) {
1233  DetectFlagsFree(NULL, de);
1234  return 1;
1235  }
1236 
1237  return 0;
1238 }
1239 
1240 static int FlagsTestParse15(void)
1241 {
1243  if (unlikely(p == NULL))
1244  return 0;
1245  ThreadVars tv;
1246  int ret = 0;
1247  DetectFlagsData *de = NULL;
1248  SigMatch *sm = NULL;
1249  IPV4Hdr ipv4h;
1250  TCPHdr tcph;
1251 
1252  memset(&tv, 0, sizeof(ThreadVars));
1253  memset(p, 0, SIZE_OF_PACKET);
1254  memset(&ipv4h, 0, sizeof(IPV4Hdr));
1255  memset(&tcph, 0, sizeof(TCPHdr));
1256 
1257  p->ip4h = &ipv4h;
1258  p->tcph = &tcph;
1259  p->tcph->th_flags = TH_ECN | TH_CWR | TH_SYN | TH_RST;
1260 
1261  de = DetectFlagsParse("EC+");
1262 
1263  if (de == NULL || (de->flags != (TH_ECN | TH_CWR)) )
1264  goto error;
1265 
1266  sm = SigMatchAlloc();
1267  if (sm == NULL)
1268  goto error;
1269 
1270  sm->type = DETECT_FLAGS;
1271  sm->ctx = (SigMatchCtx *)de;
1272 
1273  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
1274 
1275  if (ret) {
1276  if (de)
1277  SCFree(de);
1278  if (sm)
1279  SCFree(sm);
1280  SCFree(p);
1281  return 1;
1282  }
1283 
1284 error:
1285  if (de)
1286  SCFree(de);
1287  if (sm)
1288  SCFree(sm);
1289  SCFree(p);
1290  return 0;
1291 }
1292 
1293 static int FlagsTestParse16(void)
1294 {
1296  if (unlikely(p == NULL))
1297  return 0;
1298  ThreadVars tv;
1299  int ret = 0;
1300  DetectFlagsData *de = NULL;
1301  SigMatch *sm = NULL;
1302  IPV4Hdr ipv4h;
1303  TCPHdr tcph;
1304 
1305  memset(&tv, 0, sizeof(ThreadVars));
1306  memset(p, 0, SIZE_OF_PACKET);
1307  memset(&ipv4h, 0, sizeof(IPV4Hdr));
1308  memset(&tcph, 0, sizeof(TCPHdr));
1309 
1310  p->ip4h = &ipv4h;
1311  p->tcph = &tcph;
1312  p->tcph->th_flags = TH_ECN | TH_SYN | TH_RST;
1313 
1314  de = DetectFlagsParse("EC*");
1315 
1316  if (de == NULL || (de->flags != (TH_ECN | TH_CWR)) )
1317  goto error;
1318 
1319  sm = SigMatchAlloc();
1320  if (sm == NULL)
1321  goto error;
1322 
1323  sm->type = DETECT_FLAGS;
1324  sm->ctx = (SigMatchCtx *)de;
1325 
1326  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
1327 
1328  if (ret) {
1329  if (de)
1330  SCFree(de);
1331  if (sm)
1332  SCFree(sm);
1333  SCFree(p);
1334  return 1;
1335  }
1336 
1337 error:
1338  if (de)
1339  SCFree(de);
1340  if (sm)
1341  SCFree(sm);
1342  SCFree(p);
1343  return 0;
1344 }
1345 
1346 /**
1347  * \test Negative test.
1348  */
1349 static int FlagsTestParse17(void)
1350 {
1352  if (unlikely(p == NULL))
1353  return 0;
1354  ThreadVars tv;
1355  int ret = 0;
1356  DetectFlagsData *de = NULL;
1357  SigMatch *sm = NULL;
1358  IPV4Hdr ipv4h;
1359  TCPHdr tcph;
1360 
1361  memset(&tv, 0, sizeof(ThreadVars));
1362  memset(p, 0, SIZE_OF_PACKET);
1363  memset(&ipv4h, 0, sizeof(IPV4Hdr));
1364  memset(&tcph, 0, sizeof(TCPHdr));
1365 
1366  p->ip4h = &ipv4h;
1367  p->tcph = &tcph;
1368  p->tcph->th_flags = TH_ECN | TH_SYN | TH_RST;
1369 
1370  de = DetectFlagsParse("EC+");
1371 
1372  if (de == NULL || (de->flags != (TH_ECN | TH_CWR)) )
1373  goto error;
1374 
1375  sm = SigMatchAlloc();
1376  if (sm == NULL)
1377  goto error;
1378 
1379  sm->type = DETECT_FLAGS;
1380  sm->ctx = (SigMatchCtx *)de;
1381 
1382  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
1383 
1384  if (ret == 0) {
1385  if (de)
1386  SCFree(de);
1387  if (sm)
1388  SCFree(sm);
1389  SCFree(p);
1390  return 1;
1391  }
1392 
1393 error:
1394  if (de)
1395  SCFree(de);
1396  if (sm)
1397  SCFree(sm);
1398  SCFree(p);
1399  return 0;
1400 }
1401 
1402 /**
1403  * \brief this function registers unit tests for Flags
1404  */
1405 static void FlagsRegisterTests(void)
1406 {
1407  UtRegisterTest("FlagsTestParse01", FlagsTestParse01);
1408  UtRegisterTest("FlagsTestParse02", FlagsTestParse02);
1409  UtRegisterTest("FlagsTestParse03", FlagsTestParse03);
1410  UtRegisterTest("FlagsTestParse04", FlagsTestParse04);
1411  UtRegisterTest("FlagsTestParse05", FlagsTestParse05);
1412  UtRegisterTest("FlagsTestParse06", FlagsTestParse06);
1413  UtRegisterTest("FlagsTestParse07", FlagsTestParse07);
1414  UtRegisterTest("FlagsTestParse08", FlagsTestParse08);
1415  UtRegisterTest("FlagsTestParse09", FlagsTestParse09);
1416  UtRegisterTest("FlagsTestParse10", FlagsTestParse10);
1417  UtRegisterTest("FlagsTestParse11", FlagsTestParse11);
1418  UtRegisterTest("FlagsTestParse12", FlagsTestParse12);
1419  UtRegisterTest("FlagsTestParse13", FlagsTestParse13);
1420  UtRegisterTest("FlagsTestParse14", FlagsTestParse14);
1421  UtRegisterTest("FlagsTestParse15", FlagsTestParse15);
1422  UtRegisterTest("FlagsTestParse16", FlagsTestParse16);
1423  UtRegisterTest("FlagsTestParse17", FlagsTestParse17);
1424 }
1425 #endif /* UNITTESTS */
detect-tcp-flags.h
SigTableElmt_::url
const char * url
Definition: detect.h:1213
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
DetectFlagsSignatureNeedsSynOnlyPackets
int DetectFlagsSignatureNeedsSynOnlyPackets(const Signature *s)
Definition: detect-tcp-flags.c:530
SigTableElmt_::desc
const char * desc
Definition: detect.h:1212
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1200
SigTableElmt_::name
const char * name
Definition: detect.h:1210
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1142
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1346
DetectFlagsData_::modifier
uint8_t modifier
Definition: detect-tcp-flags.h:43
MAX_SUBSTRINGS
#define MAX_SUBSTRINGS
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
DetectFlagsData_::flags
uint8_t flags
Definition: detect-tcp-flags.h:42
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
PARSE_REGEX
#define PARSE_REGEX
Definition: detect-tcp-flags.c:47
MODIFIER_NOT
#define MODIFIER_NOT
Definition: detect-tcp-flags.c:54
TH_RST
#define TH_RST
Definition: decode-tcp.h:36
DetectEngineThreadCtx_::pmq
PrefilterRuleStore pmq
Definition: detect.h:1110
TH_FIN
#define TH_FIN
Definition: decode-tcp.h:34
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:766
DetectFlagsSignatureNeedsSynPackets
int DetectFlagsSignatureNeedsSynPackets(const Signature *s)
Definition: detect-tcp-flags.c:511
PrefilterPacketHeaderCtx_::sigs_array
SigIntId * sigs_array
Definition: detect-engine-prefilter-common.h:41
PrefilterPacketHeaderValue::u8
uint8_t u8[16]
Definition: detect-engine-prefilter-common.h:22
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
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1195
detect-engine-prefilter.h
util-unittest.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:1198
PKT_IS_TCP
#define PKT_IS_TCP(p)
Definition: decode.h:257
PrefilterPacketHeaderCtx_
Definition: detect-engine-prefilter-common.h:33
decode.h
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:1009
MODIFIER_PLUS
#define MODIFIER_PLUS
Definition: detect-tcp-flags.c:55
res
PoolThreadReserved res
Definition: stream-tcp-private.h:0
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2476
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
de
int de
Definition: app-layer-htp.c:575
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:323
TH_ACK
#define TH_ACK
Definition: decode-tcp.h:38
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:89
SIZE_OF_PACKET
#define SIZE_OF_PACKET
Definition: decode.h:625
TRUE
#define TRUE
Definition: suricata-common.h:33
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:322
FALSE
#define FALSE
Definition: suricata-common.h:34
SCReturn
#define SCReturn
Definition: util-debug.h:302
Signature_::flags
uint32_t flags
Definition: detect.h:528
DetectFlagsData_::ignored_flags
uint8_t ignored_flags
Definition: detect-tcp-flags.h:44
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, const char *str, int start_offset, int options, int *ovector, int ovector_size)
Definition: detect-parse.c:2406
Packet_
Definition: decode.h:412
Packet_::ip4h
IPV4Hdr * ip4h
Definition: decode.h:507
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:596
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:316
TH_ECN
#define TH_ECN
Definition: decode-tcp.h:41
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1178
SignatureInitData_::smlists
struct SigMatch_ ** smlists
Definition: detect.h:521
SigMatchAlloc
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:235
TH_URG
#define TH_URG
Definition: decode-tcp.h:39
decode-events.h
SigMatch_::type
uint8_t type
Definition: detect.h:320
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:314
IPV4Hdr_
Definition: decode-ipv4.h:71
TH_PUSH
#define TH_PUSH
Definition: decode-tcp.h:37
TH_SYN
#define TH_SYN
Definition: decode-tcp.h:35
flags
uint8_t flags
Definition: decode-gre.h:0
SigTableElmt_::alias
const char * alias
Definition: detect.h:1211
suricata-common.h
Packet_::tcph
TCPHdr * tcph
Definition: decode.h:529
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
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
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
DetectFlagsRegister
void DetectFlagsRegister(void)
Registration function for flags: keyword.
Definition: detect-tcp-flags.c:75
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
SCFree
#define SCFree(p)
Definition: util-mem.h:61
SigTableElmt_::SupportsPrefilter
bool(* SupportsPrefilter)(const Signature *s)
Definition: detect.h:1197
detect-parse.h
Signature_
Signature container.
Definition: detect.h:527
SigMatch_
a single match condition for a signature
Definition: detect.h:319
TH_CWR
#define TH_CWR
Definition: decode-tcp.h:43
DetectFlagsData_
Definition: detect-tcp-flags.h:41
suricata.h
SC_ERR_FLAGS_MODIFIER
@ SC_ERR_FLAGS_MODIFIER
Definition: util-error.h:133
MODIFIER_ANY
#define MODIFIER_ANY
Definition: detect-tcp-flags.c:56
PrefilterPacketHeaderValue
Definition: detect-engine-prefilter-common.h:21
detect-engine-prefilter-common.h
DETECT_FLAGS
@ DETECT_FLAGS
Definition: detect-engine-register.h:40
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:304
flow-var.h
SigMatchAppendSMToList
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:349
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1202
SIG_FLAG_REQUIRE_PACKET
#define SIG_FLAG_REQUIRE_PACKET
Definition: detect.h:223