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