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 
154  if (!(PacketIsTCP(p)) || PKT_IS_PSEUDOPKT(p)) {
155  SCReturnInt(0);
156  }
157 
158  const DetectFlagsData *de = (const DetectFlagsData *)ctx;
159  const TCPHdr *tcph = PacketGetTCP(p);
160  const uint8_t flags = tcph->th_flags;
161 
162  return FlagsMatch(flags, de->modifier, de->flags, de->ignored_flags);
163 }
164 
165 /**
166  * \internal
167  * \brief This function is used to parse flags options passed via flags: keyword
168  *
169  * \param rawstr Pointer to the user provided flags options
170  *
171  * \retval de pointer to DetectFlagsData on success
172  * \retval NULL on failure
173  */
174 static DetectFlagsData *DetectFlagsParse (const char *rawstr)
175 {
176  SCEnter();
177 
178  int found = 0, ignore = 0;
179  char *ptr;
180  DetectFlagsData *de = NULL;
181 
182  char arg1[16] = "";
183  char arg2[16] = "";
184  char arg3[16] = "";
185 
186  pcre2_match_data *match = NULL;
187  int ret = DetectParsePcreExec(&parse_regex, &match, rawstr, 0, 0);
188  SCLogDebug("input '%s', pcre said %d", rawstr, ret);
189  if (ret < 3) {
190  SCLogError("pcre match failed");
191  goto error;
192  }
193 
194  size_t pcre2len = sizeof(arg1);
195  int res = SC_Pcre2SubstringCopy(match, 1, (PCRE2_UCHAR8 *)arg1, &pcre2len);
196  if (res < 0) {
197  SCLogError("pcre2_substring_copy_bynumber failed");
198  goto error;
199  }
200  if (ret >= 2) {
201  pcre2len = sizeof(arg2);
202  res = pcre2_substring_copy_bynumber(match, 2, (PCRE2_UCHAR8 *)arg2, &pcre2len);
203  if (res < 0) {
204  SCLogError("pcre2_substring_copy_bynumber failed");
205  goto error;
206  }
207  }
208  if (ret >= 3) {
209  pcre2len = sizeof(arg3);
210  res = SC_Pcre2SubstringCopy(match, 3, (PCRE2_UCHAR8 *)arg3, &pcre2len);
211  if (res < 0) {
212  SCLogError("pcre2_substring_copy_bynumber failed");
213  goto error;
214  }
215  }
216  SCLogDebug("args '%s', '%s', '%s'", arg1, arg2, arg3);
217 
218  if (strlen(arg2) == 0) {
219  SCLogDebug("empty argument");
220  goto error;
221  }
222 
223  de = SCCalloc(1, sizeof(DetectFlagsData));
224  if (unlikely(de == NULL))
225  goto error;
226  de->ignored_flags = 0xff;
227 
228  /** First parse args1 */
229  ptr = arg1;
230  while (*ptr != '\0') {
231  switch (*ptr) {
232  case 'S':
233  case 's':
234  de->flags |= TH_SYN;
235  found++;
236  break;
237  case 'A':
238  case 'a':
239  de->flags |= TH_ACK;
240  found++;
241  break;
242  case 'F':
243  case 'f':
244  de->flags |= TH_FIN;
245  found++;
246  break;
247  case 'R':
248  case 'r':
249  de->flags |= TH_RST;
250  found++;
251  break;
252  case 'P':
253  case 'p':
254  de->flags |= TH_PUSH;
255  found++;
256  break;
257  case 'U':
258  case 'u':
259  de->flags |= TH_URG;
260  found++;
261  break;
262  case '1':
263  de->flags |= TH_CWR;
264  found++;
265  break;
266  case '2':
267  de->flags |= TH_ECN;
268  found++;
269  break;
270  case 'C':
271  case 'c':
272  de->flags |= TH_CWR;
273  found++;
274  break;
275  case 'E':
276  case 'e':
277  de->flags |= TH_ECN;
278  found++;
279  break;
280  case '0':
281  de->flags = 0;
282  found++;
283  break;
284 
285  case '!':
286  de->modifier = MODIFIER_NOT;
287  break;
288  case '+':
289  de->modifier = MODIFIER_PLUS;
290  break;
291  case '*':
292  de->modifier = MODIFIER_ANY;
293  break;
294  }
295  ptr++;
296  }
297 
298  /** Second parse first set of flags */
299  if (strlen(arg2) > 0) {
300  ptr = arg2;
301  while (*ptr != '\0') {
302  switch (*ptr) {
303  case 'S':
304  case 's':
305  de->flags |= TH_SYN;
306  found++;
307  break;
308  case 'A':
309  case 'a':
310  de->flags |= TH_ACK;
311  found++;
312  break;
313  case 'F':
314  case 'f':
315  de->flags |= TH_FIN;
316  found++;
317  break;
318  case 'R':
319  case 'r':
320  de->flags |= TH_RST;
321  found++;
322  break;
323  case 'P':
324  case 'p':
325  de->flags |= TH_PUSH;
326  found++;
327  break;
328  case 'U':
329  case 'u':
330  de->flags |= TH_URG;
331  found++;
332  break;
333  case '1':
334  case 'C':
335  case 'c':
336  de->flags |= TH_CWR;
337  found++;
338  break;
339  case '2':
340  case 'E':
341  case 'e':
342  de->flags |= TH_ECN;
343  found++;
344  break;
345  case '0':
346  de->flags = 0;
347  found++;
348  break;
349 
350  case '!':
351  if (de->modifier != 0) {
352  SCLogError("\"flags\" supports only"
353  " one modifier at a time");
354  goto error;
355  }
356  de->modifier = MODIFIER_NOT;
357  SCLogDebug("NOT modifier is set");
358  break;
359  case '+':
360  if (de->modifier != 0) {
361  SCLogError("\"flags\" supports only"
362  " one modifier at a time");
363  goto error;
364  }
365  de->modifier = MODIFIER_PLUS;
366  SCLogDebug("PLUS modifier is set");
367  break;
368  case '*':
369  if (de->modifier != 0) {
370  SCLogError("\"flags\" supports only"
371  " one modifier at a time");
372  goto error;
373  }
374  de->modifier = MODIFIER_ANY;
375  SCLogDebug("ANY modifier is set");
376  break;
377  default:
378  break;
379  }
380  ptr++;
381  }
382 
383  if (found == 0)
384  goto error;
385  }
386 
387  /** Finally parse ignored flags */
388  if (strlen(arg3) > 0) {
389  ptr = arg3;
390 
391  while (*ptr != '\0') {
392  switch (*ptr) {
393  case 'S':
394  case 's':
395  de->ignored_flags &= ~TH_SYN;
396  ignore++;
397  break;
398  case 'A':
399  case 'a':
400  de->ignored_flags &= ~TH_ACK;
401  ignore++;
402  break;
403  case 'F':
404  case 'f':
405  de->ignored_flags &= ~TH_FIN;
406  ignore++;
407  break;
408  case 'R':
409  case 'r':
410  de->ignored_flags &= ~TH_RST;
411  ignore++;
412  break;
413  case 'P':
414  case 'p':
415  de->ignored_flags &= ~TH_PUSH;
416  ignore++;
417  break;
418  case 'U':
419  case 'u':
420  de->ignored_flags &= ~TH_URG;
421  ignore++;
422  break;
423  case '1':
424  de->ignored_flags &= ~TH_CWR;
425  ignore++;
426  break;
427  case '2':
428  de->ignored_flags &= ~TH_ECN;
429  ignore++;
430  break;
431  case 'C':
432  case 'c':
433  de->ignored_flags &= ~TH_CWR;
434  ignore++;
435  break;
436  case 'E':
437  case 'e':
438  de->ignored_flags &= ~TH_ECN;
439  ignore++;
440  break;
441  case '0':
442  break;
443  default:
444  break;
445  }
446  ptr++;
447  }
448 
449  if (ignore == 0) {
450  SCLogDebug("ignore == 0");
451  goto error;
452  }
453  }
454 
455  pcre2_match_data_free(match);
456  SCLogDebug("found %"PRId32" ignore %"PRId32"", found, ignore);
457  SCReturnPtr(de, "DetectFlagsData");
458 
459 error:
460  if (de) {
461  SCFree(de);
462  }
463  if (match) {
464  pcre2_match_data_free(match);
465  }
466  SCReturnPtr(NULL, "DetectFlagsData");
467 }
468 
469 /**
470  * \internal
471  * \brief this function is used to add the parsed flags into the current signature
472  *
473  * \param de_ctx pointer to the Detection Engine Context
474  * \param s pointer to the Current Signature
475  * \param m pointer to the Current SigMatch
476  * \param rawstr pointer to the user provided flags options
477  *
478  * \retval 0 on Success
479  * \retval -1 on Failure
480  */
481 static int DetectFlagsSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
482 {
483  DetectFlagsData *de = NULL;
484 
485  de = DetectFlagsParse(rawstr);
486  if (de == NULL)
487  goto error;
488 
490  NULL) {
491  goto error;
492  }
494 
495  return 0;
496 
497 error:
498  if (de)
499  SCFree(de);
500  return -1;
501 }
502 
503 /**
504  * \internal
505  * \brief this function will free memory associated with DetectFlagsData
506  *
507  * \param de pointer to DetectFlagsData
508  */
509 static void DetectFlagsFree(DetectEngineCtx *de_ctx, void *de_ptr)
510 {
511  DetectFlagsData *de = (DetectFlagsData *)de_ptr;
512  if(de) SCFree(de);
513 }
514 
516 {
517  const SigMatch *sm;
518  for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
519  switch (sm->type) {
520  case DETECT_FLAGS:
521  {
522  const DetectFlagsData *fl = (const DetectFlagsData *)sm->ctx;
523 
524  if (!(fl->modifier == MODIFIER_NOT) && (fl->flags & TH_SYN)) {
525  return 1;
526  }
527  break;
528  }
529  }
530  }
531  return 0;
532 }
533 
535 {
536  const SigMatch *sm;
537  for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
538  switch (sm->type) {
539  case DETECT_FLAGS:
540  {
541  const DetectFlagsData *fl = (const DetectFlagsData *)sm->ctx;
542 
543  if (!(fl->modifier == MODIFIER_NOT) && (fl->flags == TH_SYN)) {
544  return 1;
545  }
546  break;
547  }
548  }
549  }
550  return 0;
551 }
552 
553 static void
554 PrefilterPacketFlagsMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
555 {
556  if (!(PacketIsTCP(p)) || PKT_IS_PSEUDOPKT(p)) {
557  SCReturn;
558  }
559 
560  const PrefilterPacketHeaderCtx *ctx = pectx;
561  if (!PrefilterPacketHeaderExtraMatch(ctx, p))
562  return;
563 
564  const TCPHdr *tcph = PacketGetTCP(p);
565  const uint8_t flags = tcph->th_flags;
566  if (FlagsMatch(flags, ctx->v1.u8[0], ctx->v1.u8[1], ctx->v1.u8[2]))
567  {
568  SCLogDebug("packet matches TCP flags %02x", ctx->v1.u8[1]);
569  PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
570  }
571 }
572 
573 static void
574 PrefilterPacketFlagsSet(PrefilterPacketHeaderValue *v, void *smctx)
575 {
576  const DetectFlagsData *a = smctx;
577  v->u8[0] = a->modifier;
578  v->u8[1] = a->flags;
579  v->u8[2] = a->ignored_flags;
580  SCLogDebug("v->u8[0] = %02x", v->u8[0]);
581 }
582 
583 static bool
584 PrefilterPacketFlagsCompare(PrefilterPacketHeaderValue v, void *smctx)
585 {
586  const DetectFlagsData *a = smctx;
587  if (v.u8[0] == a->modifier &&
588  v.u8[1] == a->flags &&
589  v.u8[2] == a->ignored_flags)
590  return true;
591  return false;
592 }
593 
594 static int PrefilterSetupTcpFlags(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
595 {
597  PrefilterPacketFlagsSet,
598  PrefilterPacketFlagsCompare,
599  PrefilterPacketFlagsMatch);
600 
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:1299
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:534
SignatureInitData_::smlists
struct SigMatch_ * smlists[DETECT_SM_LIST_MAX]
Definition: detect.h:581
SigTableElmt_::desc
const char * desc
Definition: detect.h:1298
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1286
DetectParseRegex
Definition: detect-parse.h:62
SigTableElmt_::name
const char * name
Definition: detect.h:1296
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1315
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1448
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:1204
UTHSetIPV4Hdr
void UTHSetIPV4Hdr(Packet *p, IPV4Hdr *ip4h)
Definition: util-unittest-helper.c:126
TH_FIN
#define TH_FIN
Definition: decode-tcp.h:34
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:839
DetectFlagsSignatureNeedsSynPackets
int DetectFlagsSignatureNeedsSynPackets(const Signature *s)
Definition: detect-tcp-flags.c:515
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
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: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:1281
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:1284
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:1095
MODIFIER_PLUS
#define MODIFIER_PLUS
Definition: detect-tcp-flags.c:56
de
uint8_t de
Definition: app-layer-htp.c:581
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2800
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:354
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:353
SCReturn
#define SCReturn
Definition: util-debug.h:273
Signature_::flags
uint32_t flags
Definition: detect.h:597
DetectFlagsData_::ignored_flags
uint8_t ignored_flags
Definition: detect-tcp-flags.h:40
Packet_
Definition: decode.h:488
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:665
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:1264
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:345
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:1297
suricata-common.h
SigMatch_::type
uint16_t type
Definition: detect.h:351
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:229
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:1283
detect-parse.h
Signature_
Signature container.
Definition: detect.h:596
SigMatch_
a single match condition for a signature
Definition: detect.h:350
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:2776
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: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
TCPHdr_
Definition: decode-tcp.h:149
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1288
SIG_FLAG_REQUIRE_PACKET
#define SIG_FLAG_REQUIRE_PACKET
Definition: detect.h:249