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