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