suricata
detect-tcp-flags.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2020 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Breno Silva <breno.silva@gmail.com>
22  *
23  * Implements the flags keyword
24  */
25 
26 #include "suricata-common.h"
27 #include "suricata.h"
28 #include "decode.h"
29 
30 #include "detect.h"
31 #include "detect-parse.h"
34 
35 #include "flow-var.h"
36 #include "decode-events.h"
37 
38 #include "detect-tcp-flags.h"
39 #include "util-unittest.h"
40 
41 #include "util-debug.h"
42 
43 /**
44  * Regex (by Brian Rectanus)
45  * flags: [!+*](SAPRFU120)[,SAPRFU12]
46  */
47 #define PARSE_REGEX "^\\s*(?:([\\+\\*!]))?\\s*([SAPRFU120CE\\+\\*!]+)(?:\\s*,\\s*([SAPRFU12CE]+))?\\s*$"
48 
49 /**
50  * Flags args[0] *(3) +(2) !(1)
51  *
52  */
53 
54 #define MODIFIER_NOT 1
55 #define MODIFIER_PLUS 2
56 #define MODIFIER_ANY 3
57 
58 static DetectParseRegex parse_regex;
59 
60 static int DetectFlagsMatch (DetectEngineThreadCtx *, Packet *,
61  const Signature *, const SigMatchCtx *);
62 static int DetectFlagsSetup (DetectEngineCtx *, Signature *, const char *);
63 static void DetectFlagsFree(DetectEngineCtx *, void *);
64 
65 static bool PrefilterTcpFlagsIsPrefilterable(const Signature *s);
66 static int PrefilterSetupTcpFlags(DetectEngineCtx *de_ctx, SigGroupHead *sgh);
67 #ifdef UNITTESTS
68 static void FlagsRegisterTests(void);
69 #endif
70 
71 /**
72  * \brief Registration function for flags: keyword
73  */
74 
76 {
77  sigmatch_table[DETECT_FLAGS].name = "tcp.flags";
79  sigmatch_table[DETECT_FLAGS].desc = "detect which flags are set in the TCP header";
80  sigmatch_table[DETECT_FLAGS].url = "/rules/header-keywords.html#tcp-flags";
81  sigmatch_table[DETECT_FLAGS].Match = DetectFlagsMatch;
82  sigmatch_table[DETECT_FLAGS].Setup = DetectFlagsSetup;
83  sigmatch_table[DETECT_FLAGS].Free = DetectFlagsFree;
84 #ifdef UNITTESTS
85  sigmatch_table[DETECT_FLAGS].RegisterTests = FlagsRegisterTests;
86 #endif
87  sigmatch_table[DETECT_FLAGS].SupportsPrefilter = PrefilterTcpFlagsIsPrefilterable;
88  sigmatch_table[DETECT_FLAGS].SetupPrefilter = PrefilterSetupTcpFlags;
89 
90  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
91 }
92 
93 static inline int FlagsMatch(const uint8_t pflags, const uint8_t modifier,
94  const uint8_t dflags, const uint8_t iflags)
95 {
96  if (!dflags && pflags) {
97  if(modifier == MODIFIER_NOT) {
98  SCReturnInt(1);
99  }
100 
101  SCReturnInt(0);
102  }
103 
104  const uint8_t flags = pflags & iflags;
105 
106  switch (modifier) {
107  case MODIFIER_ANY:
108  if ((flags & dflags) > 0) {
109  SCReturnInt(1);
110  }
111  SCReturnInt(0);
112 
113  case MODIFIER_PLUS:
114  if (((flags & dflags) == dflags)) {
115  SCReturnInt(1);
116  }
117  SCReturnInt(0);
118 
119  case MODIFIER_NOT:
120  if ((flags & dflags) != dflags) {
121  SCReturnInt(1);
122  }
123  SCReturnInt(0);
124 
125  default:
126  SCLogDebug("flags %"PRIu8" and de->flags %"PRIu8"", flags, dflags);
127  if (flags == dflags) {
128  SCReturnInt(1);
129  }
130  }
131 
132  SCReturnInt(0);
133 }
134 
135 /**
136  * \internal
137  * \brief This function is used to match flags on a packet with those passed via flags:
138  *
139  * \param t pointer to thread vars
140  * \param det_ctx pointer to the pattern matcher thread
141  * \param p pointer to the current packet
142  * \param s pointer to the Signature
143  * \param m pointer to the sigmatch
144  *
145  * \retval 0 no match
146  * \retval 1 match
147  */
148 static int DetectFlagsMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
149  const Signature *s, const SigMatchCtx *ctx)
150 {
151  SCEnter();
152 
153  if (!(PKT_IS_TCP(p)) || PKT_IS_PSEUDOPKT(p)) {
154  SCReturnInt(0);
155  }
156 
157  const DetectFlagsData *de = (const DetectFlagsData *)ctx;
158  const uint8_t flags = p->tcph->th_flags;
159 
160  return FlagsMatch(flags, de->modifier, de->flags, de->ignored_flags);
161 }
162 
163 /**
164  * \internal
165  * \brief This function is used to parse flags options passed via flags: keyword
166  *
167  * \param rawstr Pointer to the user provided flags options
168  *
169  * \retval de pointer to DetectFlagsData on success
170  * \retval NULL on failure
171  */
172 static DetectFlagsData *DetectFlagsParse (const char *rawstr)
173 {
174  SCEnter();
175 
176  int ret = 0, found = 0, ignore = 0, res = 0;
177  size_t pcre2len;
178  char *ptr;
179 
180  char arg1[16] = "";
181  char arg2[16] = "";
182  char arg3[16] = "";
183 
184  ret = DetectParsePcreExec(&parse_regex, rawstr, 0, 0);
185  SCLogDebug("input '%s', pcre said %d", rawstr, ret);
186  if (ret < 3) {
187  SCLogError(SC_ERR_PCRE_MATCH, "pcre match failed");
188  SCReturnPtr(NULL, "DetectFlagsData");
189  }
190 
191  pcre2len = sizeof(arg1);
192  res = SC_Pcre2SubstringCopy(parse_regex.match, 1, (PCRE2_UCHAR8 *)arg1, &pcre2len);
193  if (res < 0) {
194  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_copy_bynumber failed");
195  SCReturnPtr(NULL, "DetectFlagsData");
196  }
197  if (ret >= 2) {
198  pcre2len = sizeof(arg2);
199  res = pcre2_substring_copy_bynumber(parse_regex.match, 2, (PCRE2_UCHAR8 *)arg2, &pcre2len);
200  if (res < 0) {
201  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_copy_bynumber failed");
202  SCReturnPtr(NULL, "DetectFlagsData");
203  }
204  }
205  if (ret >= 3) {
206  pcre2len = sizeof(arg3);
207  res = SC_Pcre2SubstringCopy(parse_regex.match, 3, (PCRE2_UCHAR8 *)arg3, &pcre2len);
208  if (res < 0) {
209  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_copy_bynumber failed");
210  SCReturnPtr(NULL, "DetectFlagsData");
211  }
212  }
213  SCLogDebug("args '%s', '%s', '%s'", arg1, arg2, arg3);
214 
215  if (strlen(arg2) == 0) {
216  SCLogDebug("empty argument");
217  SCReturnPtr(NULL, "DetectFlagsData");
218  }
219 
221  if (unlikely(de == NULL))
222  goto error;
223  memset(de, 0, sizeof(DetectFlagsData));
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(SC_ERR_FLAGS_MODIFIER, "\"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(SC_ERR_FLAGS_MODIFIER, "\"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(SC_ERR_FLAGS_MODIFIER, "\"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  SCLogDebug("found %"PRId32" ignore %"PRId32"", found, ignore);
454  SCReturnPtr(de, "DetectFlagsData");
455 
456 error:
457  if (de) {
458  SCFree(de);
459  }
460  SCReturnPtr(NULL, "DetectFlagsData");
461 }
462 
463 /**
464  * \internal
465  * \brief this function is used to add the parsed flags into the current signature
466  *
467  * \param de_ctx pointer to the Detection Engine Context
468  * \param s pointer to the Current Signature
469  * \param m pointer to the Current SigMatch
470  * \param rawstr pointer to the user provided flags options
471  *
472  * \retval 0 on Success
473  * \retval -1 on Failure
474  */
475 static int DetectFlagsSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
476 {
477  DetectFlagsData *de = NULL;
478  SigMatch *sm = NULL;
479 
480  de = DetectFlagsParse(rawstr);
481  if (de == NULL)
482  goto error;
483 
484  sm = SigMatchAlloc();
485  if (sm == NULL)
486  goto error;
487 
488  sm->type = DETECT_FLAGS;
489  sm->ctx = (SigMatchCtx *)de;
490 
493 
494  return 0;
495 
496 error:
497  if (de) SCFree(de);
498  if (sm) SCFree(sm);
499  return -1;
500 }
501 
502 /**
503  * \internal
504  * \brief this function will free memory associated with DetectFlagsData
505  *
506  * \param de pointer to DetectFlagsData
507  */
508 static void DetectFlagsFree(DetectEngineCtx *de_ctx, void *de_ptr)
509 {
510  DetectFlagsData *de = (DetectFlagsData *)de_ptr;
511  if(de) SCFree(de);
512 }
513 
515 {
516  const SigMatch *sm;
517  for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
518  switch (sm->type) {
519  case DETECT_FLAGS:
520  {
521  const DetectFlagsData *fl = (const DetectFlagsData *)sm->ctx;
522 
523  if (!(fl->modifier == MODIFIER_NOT) && (fl->flags & TH_SYN)) {
524  return 1;
525  }
526  break;
527  }
528  }
529  }
530  return 0;
531 }
532 
534 {
535  const SigMatch *sm;
536  for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
537  switch (sm->type) {
538  case DETECT_FLAGS:
539  {
540  const DetectFlagsData *fl = (const DetectFlagsData *)sm->ctx;
541 
542  if (!(fl->modifier == MODIFIER_NOT) && (fl->flags == TH_SYN)) {
543  return 1;
544  }
545  break;
546  }
547  }
548  }
549  return 0;
550 }
551 
552 static void
553 PrefilterPacketFlagsMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx)
554 {
555  if (!(PKT_IS_TCP(p)) || PKT_IS_PSEUDOPKT(p)) {
556  SCReturn;
557  }
558 
559  const PrefilterPacketHeaderCtx *ctx = pectx;
560  if (!PrefilterPacketHeaderExtraMatch(ctx, p))
561  return;
562 
563  const uint8_t flags = p->tcph->th_flags;
564  if (FlagsMatch(flags, ctx->v1.u8[0], ctx->v1.u8[1], ctx->v1.u8[2]))
565  {
566  SCLogDebug("packet matches TCP flags %02x", ctx->v1.u8[1]);
567  PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
568  }
569 }
570 
571 static void
572 PrefilterPacketFlagsSet(PrefilterPacketHeaderValue *v, void *smctx)
573 {
574  const DetectFlagsData *a = smctx;
575  v->u8[0] = a->modifier;
576  v->u8[1] = a->flags;
577  v->u8[2] = a->ignored_flags;
578  SCLogDebug("v->u8[0] = %02x", v->u8[0]);
579 }
580 
581 static bool
582 PrefilterPacketFlagsCompare(PrefilterPacketHeaderValue v, void *smctx)
583 {
584  const DetectFlagsData *a = smctx;
585  if (v.u8[0] == a->modifier &&
586  v.u8[1] == a->flags &&
587  v.u8[2] == a->ignored_flags)
588  return true;
589  return false;
590 }
591 
592 static int PrefilterSetupTcpFlags(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
593 {
595  PrefilterPacketFlagsSet,
596  PrefilterPacketFlagsCompare,
597  PrefilterPacketFlagsMatch);
598 
599 }
600 
601 static bool PrefilterTcpFlagsIsPrefilterable(const Signature *s)
602 {
603  const SigMatch *sm;
604  for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
605  switch (sm->type) {
606  case DETECT_FLAGS:
607  return true;
608  }
609  }
610  return false;
611 }
612 
613 /*
614  * ONLY TESTS BELOW THIS COMMENT
615  */
616 
617 #ifdef UNITTESTS
618 /**
619  * \test FlagsTestParse01 is a test for a valid flags value
620  *
621  * \retval 1 on succces
622  * \retval 0 on failure
623  */
624 static int FlagsTestParse01 (void)
625 {
626  DetectFlagsData *de = DetectFlagsParse("S");
627  FAIL_IF_NULL(de);
628  FAIL_IF_NOT(de->flags == TH_SYN);
629  DetectFlagsFree(NULL, de);
630  PASS;
631 }
632 
633 /**
634  * \test FlagsTestParse02 is a test for an invalid flags value
635  *
636  * \retval 1 on succces
637  * \retval 0 on failure
638  */
639 static int FlagsTestParse02 (void)
640 {
641  DetectFlagsData *de = NULL;
642  de = DetectFlagsParse("G");
643  if (de) {
644  DetectFlagsFree(NULL, de);
645  return 0;
646  }
647 
648  return 1;
649 }
650 
651 /**
652  * \test FlagsTestParse03 test if ACK and PUSH are set. Must return success
653  *
654  * \retval 1 on success
655  * \retval 0 on failure
656  */
657 static int FlagsTestParse03 (void)
658 {
660  if (unlikely(p == NULL))
661  return 0;
662  ThreadVars tv;
663  int ret = 0;
664  DetectFlagsData *de = NULL;
665  SigMatch *sm = NULL;
666  IPV4Hdr ipv4h;
667  TCPHdr tcph;
668 
669  memset(&tv, 0, sizeof(ThreadVars));
670  memset(p, 0, SIZE_OF_PACKET);
671  memset(&ipv4h, 0, sizeof(IPV4Hdr));
672  memset(&tcph, 0, sizeof(TCPHdr));
673 
674  p->ip4h = &ipv4h;
675  p->tcph = &tcph;
676  p->tcph->th_flags = TH_ACK|TH_PUSH|TH_SYN|TH_RST;
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 succces
710  * \retval 0 on failure
711  */
712 static int FlagsTestParse04 (void)
713 {
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(p, 0, SIZE_OF_PACKET);
726  memset(&ipv4h, 0, sizeof(IPV4Hdr));
727  memset(&tcph, 0, sizeof(TCPHdr));
728 
729  p->ip4h = &ipv4h;
730  p->tcph = &tcph;
731  p->tcph->th_flags = TH_SYN;
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 {
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(p, 0, SIZE_OF_PACKET);
782  memset(&ipv4h, 0, sizeof(IPV4Hdr));
783  memset(&tcph, 0, sizeof(TCPHdr));
784 
785  p->ip4h = &ipv4h;
786  p->tcph = &tcph;
787  p->tcph->th_flags = TH_ACK|TH_PUSH|TH_SYN|TH_RST;
788 
789  de = DetectFlagsParse("+AP,SR");
790 
791  if (de == NULL || (de->modifier != MODIFIER_PLUS) || (de->flags != (TH_ACK|TH_PUSH)) || (de->ignored_flags != (TH_SYN|TH_RST)))
792  goto error;
793 
794  sm = SigMatchAlloc();
795  if (sm == NULL)
796  goto error;
797 
798  sm->type = DETECT_FLAGS;
799  sm->ctx = (SigMatchCtx *)de;
800 
801  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
802 
803  if(ret) {
804  if (de) SCFree(de);
805  if (sm) SCFree(sm);
806  SCFree(p);
807  return 0;
808  }
809 
810  /* Error expected. */
811 error:
812  if (de) SCFree(de);
813  if (sm) SCFree(sm);
814  SCFree(p);
815  return 1;
816 }
817 
818 /**
819  * \test FlagsTestParse06 test if ACK+PUSH and more flags are set. Ignore URG and RST bits.
820  * Must return success.
821  * \retval 1 on success
822  * \retval 0 on failure
823  */
824 static int FlagsTestParse06 (void)
825 {
827  if (unlikely(p == NULL))
828  return 0;
829  ThreadVars tv;
830  int ret = 0;
831  DetectFlagsData *de = NULL;
832  SigMatch *sm = NULL;
833  IPV4Hdr ipv4h;
834  TCPHdr tcph;
835 
836  memset(&tv, 0, sizeof(ThreadVars));
837  memset(p, 0, SIZE_OF_PACKET);
838  memset(&ipv4h, 0, sizeof(IPV4Hdr));
839  memset(&tcph, 0, sizeof(TCPHdr));
840 
841  p->ip4h = &ipv4h;
842  p->tcph = &tcph;
843  p->tcph->th_flags = TH_ACK|TH_PUSH|TH_SYN|TH_RST;
844 
845  de = DetectFlagsParse("+AP,UR");
846 
847  if (de == NULL || (de->modifier != MODIFIER_PLUS) || (de->flags != (TH_ACK|TH_PUSH)) || ((0xff - de->ignored_flags) != (TH_URG|TH_RST)))
848  goto error;
849 
850  sm = SigMatchAlloc();
851  if (sm == NULL)
852  goto error;
853 
854  sm->type = DETECT_FLAGS;
855  sm->ctx = (SigMatchCtx *)de;
856 
857  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
858 
859  if(ret) {
860  if (de) SCFree(de);
861  if (sm) SCFree(sm);
862  SCFree(p);
863  return 1;
864  }
865 
866 error:
867  if (de) SCFree(de);
868  if (sm) SCFree(sm);
869  SCFree(p);
870  return 0;
871 }
872 
873 /**
874  * \test FlagsTestParse07 test if SYN or RST are set. Must fails.
875  *
876  * \retval 1 on success
877  * \retval 0 on failure
878  */
879 static int FlagsTestParse07 (void)
880 {
882  if (unlikely(p == NULL))
883  return 0;
884  ThreadVars tv;
885  int ret = 0;
886  DetectFlagsData *de = NULL;
887  SigMatch *sm = NULL;
888  IPV4Hdr ipv4h;
889  TCPHdr tcph;
890 
891  memset(&tv, 0, sizeof(ThreadVars));
892  memset(p, 0, SIZE_OF_PACKET);
893  memset(&ipv4h, 0, sizeof(IPV4Hdr));
894  memset(&tcph, 0, sizeof(TCPHdr));
895 
896  p->ip4h = &ipv4h;
897  p->tcph = &tcph;
898  p->tcph->th_flags = TH_SYN|TH_RST;
899 
900  de = DetectFlagsParse("*AP");
901 
902  if (de == NULL || (de->modifier != MODIFIER_ANY) || (de->flags != (TH_ACK|TH_PUSH)))
903  goto error;
904 
905  sm = SigMatchAlloc();
906  if (sm == NULL)
907  goto error;
908 
909  sm->type = DETECT_FLAGS;
910  sm->ctx = (SigMatchCtx *)de;
911 
912  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
913 
914  if(ret) {
915  if (de) SCFree(de);
916  if (sm) SCFree(sm);
917  SCFree(p);
918  return 0;
919  }
920 
921  /* Error expected. */
922 error:
923  if (de) SCFree(de);
924  if (sm) SCFree(sm);
925  SCFree(p);
926  return 1;
927 }
928 
929 /**
930  * \test FlagsTestParse08 test if SYN or RST are set. Must return success.
931  *
932  * \retval 1 on success
933  * \retval 0 on failure
934  */
935 static int FlagsTestParse08 (void)
936 {
938  if (unlikely(p == NULL))
939  return 0;
940  ThreadVars tv;
941  int ret = 0;
942  DetectFlagsData *de = NULL;
943  SigMatch *sm = NULL;
944  IPV4Hdr ipv4h;
945  TCPHdr tcph;
946 
947  memset(&tv, 0, sizeof(ThreadVars));
948  memset(p, 0, SIZE_OF_PACKET);
949  memset(&ipv4h, 0, sizeof(IPV4Hdr));
950  memset(&tcph, 0, sizeof(TCPHdr));
951 
952  p->ip4h = &ipv4h;
953  p->tcph = &tcph;
954  p->tcph->th_flags = TH_SYN|TH_RST;
955 
956  de = DetectFlagsParse("*SA");
957 
958  if (de == NULL || (de->modifier != MODIFIER_ANY) || (de->flags != (TH_ACK|TH_SYN)))
959  goto error;
960 
961  sm = SigMatchAlloc();
962  if (sm == NULL)
963  goto error;
964 
965  sm->type = DETECT_FLAGS;
966  sm->ctx = (SigMatchCtx *)de;
967 
968  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
969 
970  if(ret) {
971  if (de) SCFree(de);
972  if (sm) SCFree(sm);
973  SCFree(p);
974  return 1;
975  }
976 
977 error:
978  if (de) SCFree(de);
979  if (sm) SCFree(sm);
980  SCFree(p);
981  return 0;
982 }
983 
984 /**
985  * \test FlagsTestParse09 test if SYN and RST are not set. Must fails.
986  *
987  * \retval 1 on success
988  * \retval 0 on failure
989  */
990 static int FlagsTestParse09 (void)
991 {
993  if (unlikely(p == NULL))
994  return 0;
995  ThreadVars tv;
996  int ret = 0;
997  DetectFlagsData *de = NULL;
998  SigMatch *sm = NULL;
999  IPV4Hdr ipv4h;
1000  TCPHdr tcph;
1001 
1002  memset(&tv, 0, sizeof(ThreadVars));
1003  memset(p, 0, SIZE_OF_PACKET);
1004  memset(&ipv4h, 0, sizeof(IPV4Hdr));
1005  memset(&tcph, 0, sizeof(TCPHdr));
1006 
1007  p->ip4h = &ipv4h;
1008  p->tcph = &tcph;
1009  p->tcph->th_flags = TH_SYN|TH_RST;
1010 
1011  de = DetectFlagsParse("!PA");
1012 
1013  if (de == NULL || (de->modifier != MODIFIER_NOT) || (de->flags != (TH_ACK|TH_PUSH)))
1014  goto error;
1015 
1016  sm = SigMatchAlloc();
1017  if (sm == NULL)
1018  goto error;
1019 
1020  sm->type = DETECT_FLAGS;
1021  sm->ctx = (SigMatchCtx *)de;
1022 
1023  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
1024 
1025  if(ret) {
1026  if (de) SCFree(de);
1027  if (sm) SCFree(sm);
1028  SCFree(p);
1029  return 1;
1030  }
1031 
1032 error:
1033  if (de) SCFree(de);
1034  if (sm) SCFree(sm);
1035  SCFree(p);
1036  return 0;
1037 }
1038 
1039 /**
1040  * \test FlagsTestParse10 test if ACK and PUSH are not set. Must return success.
1041  *
1042  * \retval 1 on success
1043  * \retval 0 on failure
1044  */
1045 static int FlagsTestParse10 (void)
1046 {
1048  if (unlikely(p == NULL))
1049  return 0;
1050  ThreadVars tv;
1051  int ret = 0;
1052  DetectFlagsData *de = NULL;
1053  SigMatch *sm = NULL;
1054  IPV4Hdr ipv4h;
1055  TCPHdr tcph;
1056 
1057  memset(&tv, 0, sizeof(ThreadVars));
1058  memset(p, 0, SIZE_OF_PACKET);
1059  memset(&ipv4h, 0, sizeof(IPV4Hdr));
1060  memset(&tcph, 0, sizeof(TCPHdr));
1061 
1062  p->ip4h = &ipv4h;
1063  p->tcph = &tcph;
1064  p->tcph->th_flags = TH_SYN|TH_RST;
1065 
1066  de = DetectFlagsParse("!AP");
1067 
1068  if (de == NULL || (de->modifier != MODIFIER_NOT) || (de->flags != (TH_ACK|TH_PUSH)))
1069  goto error;
1070 
1071  sm = SigMatchAlloc();
1072  if (sm == NULL)
1073  goto error;
1074 
1075  sm->type = DETECT_FLAGS;
1076  sm->ctx = (SigMatchCtx *)de;
1077 
1078  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
1079 
1080  if(ret) {
1081  if (de) SCFree(de);
1082  if (sm) SCFree(sm);
1083  SCFree(p);
1084  return 1;
1085  }
1086 
1087 error:
1088  if (de) SCFree(de);
1089  if (sm) SCFree(sm);
1090  SCFree(p);
1091  return 0;
1092 }
1093 
1094 /**
1095  * \test FlagsTestParse11 test if ACK or PUSH are set. Ignore SYN and RST. Must fails.
1096  *
1097  * \retval 1 on success
1098  * \retval 0 on failure
1099  */
1100 static int FlagsTestParse11 (void)
1101 {
1103  if (unlikely(p == NULL))
1104  return 0;
1105  ThreadVars tv;
1106  int ret = 0;
1107  DetectFlagsData *de = NULL;
1108  SigMatch *sm = NULL;
1109  IPV4Hdr ipv4h;
1110  TCPHdr tcph;
1111 
1112  memset(&tv, 0, sizeof(ThreadVars));
1113  memset(p, 0, SIZE_OF_PACKET);
1114  memset(&ipv4h, 0, sizeof(IPV4Hdr));
1115  memset(&tcph, 0, sizeof(TCPHdr));
1116 
1117  p->ip4h = &ipv4h;
1118  p->tcph = &tcph;
1119  p->tcph->th_flags = TH_SYN|TH_RST|TH_URG;
1120 
1121  de = DetectFlagsParse("*AP,SR");
1122 
1123  if (de == NULL || (de->modifier != MODIFIER_ANY) || (de->flags != (TH_ACK|TH_PUSH)) || ((0xff - de->ignored_flags) != (TH_SYN|TH_RST)))
1124  goto error;
1125 
1126  sm = SigMatchAlloc();
1127  if (sm == NULL)
1128  goto error;
1129 
1130  sm->type = DETECT_FLAGS;
1131  sm->ctx = (SigMatchCtx *)de;
1132 
1133  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
1134 
1135  if(ret) {
1136  if (de) SCFree(de);
1137  if (sm) SCFree(sm);
1138  SCFree(p);
1139  return 0;
1140  }
1141 
1142  /* Expected. */
1143 error:
1144  if (de) SCFree(de);
1145  if (sm) SCFree(sm);
1146  SCFree(p);
1147  return 1;
1148 }
1149 
1150 /**
1151  * \test FlagsTestParse12 check if no flags are set. Must fails.
1152  *
1153  * \retval 1 on succces
1154  * \retval 0 on failure
1155  */
1156 static int FlagsTestParse12 (void)
1157 {
1159  if (unlikely(p == NULL))
1160  return 0;
1161  ThreadVars tv;
1162  int ret = 0;
1163  DetectFlagsData *de = NULL;
1164  SigMatch *sm = NULL;
1165  IPV4Hdr ipv4h;
1166  TCPHdr tcph;
1167 
1168  memset(&tv, 0, sizeof(ThreadVars));
1169  memset(p, 0, SIZE_OF_PACKET);
1170  memset(&ipv4h, 0, sizeof(IPV4Hdr));
1171  memset(&tcph, 0, sizeof(TCPHdr));
1172 
1173  p->ip4h = &ipv4h;
1174  p->tcph = &tcph;
1175  p->tcph->th_flags = TH_SYN;
1176 
1177  de = DetectFlagsParse("0");
1178 
1179  if (de == NULL || de->flags != 0) {
1180  printf("de setup: ");
1181  goto error;
1182  }
1183 
1184  sm = SigMatchAlloc();
1185  if (sm == NULL)
1186  goto error;
1187 
1188  sm->type = DETECT_FLAGS;
1189  sm->ctx = (SigMatchCtx *)de;
1190 
1191  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
1192 
1193  if(ret) {
1194  if (de) SCFree(de);
1195  if (sm) SCFree(sm);
1196  SCFree(p);
1197  return 0;
1198  }
1199 
1200  /* Expected. */
1201 error:
1202  if (de) SCFree(de);
1203  if (sm) SCFree(sm);
1204  SCFree(p);
1205  return 1;
1206 }
1207 
1208 /**
1209  * \test test for a valid flags value
1210  *
1211  * \retval 1 on succces
1212  * \retval 0 on failure
1213  */
1214 static int FlagsTestParse13 (void)
1215 {
1216  DetectFlagsData *de = NULL;
1217  de = DetectFlagsParse("+S*");
1218  if (de != NULL) {
1219  DetectFlagsFree(NULL, de);
1220  return 0;
1221  }
1222 
1223  return 1;
1224 }
1225 
1226 /**
1227  * \test Parse 'C' and 'E' flags.
1228  *
1229  * \retval 1 on success.
1230  * \retval 0 on failure.
1231  */
1232 static int FlagsTestParse14(void)
1233 {
1234  DetectFlagsData *de = DetectFlagsParse("CE");
1235  if (de != NULL && (de->flags == (TH_CWR | TH_ECN)) ) {
1236  DetectFlagsFree(NULL, de);
1237  return 1;
1238  }
1239 
1240  return 0;
1241 }
1242 
1243 static int FlagsTestParse15(void)
1244 {
1246  if (unlikely(p == NULL))
1247  return 0;
1248  ThreadVars tv;
1249  int ret = 0;
1250  DetectFlagsData *de = NULL;
1251  SigMatch *sm = NULL;
1252  IPV4Hdr ipv4h;
1253  TCPHdr tcph;
1254 
1255  memset(&tv, 0, sizeof(ThreadVars));
1256  memset(p, 0, SIZE_OF_PACKET);
1257  memset(&ipv4h, 0, sizeof(IPV4Hdr));
1258  memset(&tcph, 0, sizeof(TCPHdr));
1259 
1260  p->ip4h = &ipv4h;
1261  p->tcph = &tcph;
1262  p->tcph->th_flags = TH_ECN | TH_CWR | TH_SYN | TH_RST;
1263 
1264  de = DetectFlagsParse("EC+");
1265 
1266  if (de == NULL || (de->flags != (TH_ECN | TH_CWR)) )
1267  goto error;
1268 
1269  sm = SigMatchAlloc();
1270  if (sm == NULL)
1271  goto error;
1272 
1273  sm->type = DETECT_FLAGS;
1274  sm->ctx = (SigMatchCtx *)de;
1275 
1276  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
1277 
1278  if (ret) {
1279  if (de)
1280  SCFree(de);
1281  if (sm)
1282  SCFree(sm);
1283  SCFree(p);
1284  return 1;
1285  }
1286 
1287 error:
1288  if (de)
1289  SCFree(de);
1290  if (sm)
1291  SCFree(sm);
1292  SCFree(p);
1293  return 0;
1294 }
1295 
1296 static int FlagsTestParse16(void)
1297 {
1299  if (unlikely(p == NULL))
1300  return 0;
1301  ThreadVars tv;
1302  int ret = 0;
1303  DetectFlagsData *de = NULL;
1304  SigMatch *sm = NULL;
1305  IPV4Hdr ipv4h;
1306  TCPHdr tcph;
1307 
1308  memset(&tv, 0, sizeof(ThreadVars));
1309  memset(p, 0, SIZE_OF_PACKET);
1310  memset(&ipv4h, 0, sizeof(IPV4Hdr));
1311  memset(&tcph, 0, sizeof(TCPHdr));
1312 
1313  p->ip4h = &ipv4h;
1314  p->tcph = &tcph;
1315  p->tcph->th_flags = TH_ECN | TH_SYN | TH_RST;
1316 
1317  de = DetectFlagsParse("EC*");
1318 
1319  if (de == NULL || (de->flags != (TH_ECN | TH_CWR)) )
1320  goto error;
1321 
1322  sm = SigMatchAlloc();
1323  if (sm == NULL)
1324  goto error;
1325 
1326  sm->type = DETECT_FLAGS;
1327  sm->ctx = (SigMatchCtx *)de;
1328 
1329  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
1330 
1331  if (ret) {
1332  if (de)
1333  SCFree(de);
1334  if (sm)
1335  SCFree(sm);
1336  SCFree(p);
1337  return 1;
1338  }
1339 
1340 error:
1341  if (de)
1342  SCFree(de);
1343  if (sm)
1344  SCFree(sm);
1345  SCFree(p);
1346  return 0;
1347 }
1348 
1349 /**
1350  * \test Negative test.
1351  */
1352 static int FlagsTestParse17(void)
1353 {
1355  if (unlikely(p == NULL))
1356  return 0;
1357  ThreadVars tv;
1358  int ret = 0;
1359  DetectFlagsData *de = NULL;
1360  SigMatch *sm = NULL;
1361  IPV4Hdr ipv4h;
1362  TCPHdr tcph;
1363 
1364  memset(&tv, 0, sizeof(ThreadVars));
1365  memset(p, 0, SIZE_OF_PACKET);
1366  memset(&ipv4h, 0, sizeof(IPV4Hdr));
1367  memset(&tcph, 0, sizeof(TCPHdr));
1368 
1369  p->ip4h = &ipv4h;
1370  p->tcph = &tcph;
1371  p->tcph->th_flags = TH_ECN | TH_SYN | TH_RST;
1372 
1373  de = DetectFlagsParse("EC+");
1374 
1375  if (de == NULL || (de->flags != (TH_ECN | TH_CWR)) )
1376  goto error;
1377 
1378  sm = SigMatchAlloc();
1379  if (sm == NULL)
1380  goto error;
1381 
1382  sm->type = DETECT_FLAGS;
1383  sm->ctx = (SigMatchCtx *)de;
1384 
1385  ret = DetectFlagsMatch(NULL, p, NULL, sm->ctx);
1386 
1387  if (ret == 0) {
1388  if (de)
1389  SCFree(de);
1390  if (sm)
1391  SCFree(sm);
1392  SCFree(p);
1393  return 1;
1394  }
1395 
1396 error:
1397  if (de)
1398  SCFree(de);
1399  if (sm)
1400  SCFree(sm);
1401  SCFree(p);
1402  return 0;
1403 }
1404 
1405 /**
1406  * \brief this function registers unit tests for Flags
1407  */
1408 static void FlagsRegisterTests(void)
1409 {
1410  UtRegisterTest("FlagsTestParse01", FlagsTestParse01);
1411  UtRegisterTest("FlagsTestParse02", FlagsTestParse02);
1412  UtRegisterTest("FlagsTestParse03", FlagsTestParse03);
1413  UtRegisterTest("FlagsTestParse04", FlagsTestParse04);
1414  UtRegisterTest("FlagsTestParse05", FlagsTestParse05);
1415  UtRegisterTest("FlagsTestParse06", FlagsTestParse06);
1416  UtRegisterTest("FlagsTestParse07", FlagsTestParse07);
1417  UtRegisterTest("FlagsTestParse08", FlagsTestParse08);
1418  UtRegisterTest("FlagsTestParse09", FlagsTestParse09);
1419  UtRegisterTest("FlagsTestParse10", FlagsTestParse10);
1420  UtRegisterTest("FlagsTestParse11", FlagsTestParse11);
1421  UtRegisterTest("FlagsTestParse12", FlagsTestParse12);
1422  UtRegisterTest("FlagsTestParse13", FlagsTestParse13);
1423  UtRegisterTest("FlagsTestParse14", FlagsTestParse14);
1424  UtRegisterTest("FlagsTestParse15", FlagsTestParse15);
1425  UtRegisterTest("FlagsTestParse16", FlagsTestParse16);
1426  UtRegisterTest("FlagsTestParse17", FlagsTestParse17);
1427 }
1428 #endif /* UNITTESTS */
detect-tcp-flags.h
DetectParseRegex::match
pcre2_match_data * match
Definition: detect-parse.h:45
SigTableElmt_::url
const char * url
Definition: detect.h:1204
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:533
SigTableElmt_::desc
const char * desc
Definition: detect.h:1203
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, const char *str, int start_offset, int options)
Definition: detect-parse.c:2435
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1191
DetectParseRegex
Definition: detect-parse.h:42
SigTableElmt_::name
const char * name
Definition: detect.h:1201
PKT_IS_PSEUDOPKT
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1201
SigGroupHead_
Container for matching data for a signature group.
Definition: detect.h:1346
DetectFlagsData_::modifier
uint8_t modifier
Definition: detect-tcp-flags.h:43
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
DetectFlagsData_::flags
uint8_t flags
Definition: detect-tcp-flags.h:42
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
PARSE_REGEX
#define PARSE_REGEX
Definition: detect-tcp-flags.c:47
MODIFIER_NOT
#define MODIFIER_NOT
Definition: detect-tcp-flags.c:54
TH_RST
#define TH_RST
Definition: decode-tcp.h:36
DetectEngineThreadCtx_::pmq
PrefilterRuleStore pmq
Definition: detect.h:1101
TH_FIN
#define TH_FIN
Definition: decode-tcp.h:34
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:758
DetectFlagsSignatureNeedsSynPackets
int DetectFlagsSignatureNeedsSynPackets(const Signature *s)
Definition: detect-tcp-flags.c:514
PrefilterPacketHeaderCtx_::sigs_array
SigIntId * sigs_array
Definition: detect-engine-prefilter-common.h:41
PrefilterPacketHeaderValue::u8
uint8_t u8[16]
Definition: detect-engine-prefilter-common.h:22
PrefilterPacketHeaderCtx_::sigs_cnt
uint32_t sigs_cnt
Definition: detect-engine-prefilter-common.h:40
SC_ERR_PCRE_GET_SUBSTRING
@ SC_ERR_PCRE_GET_SUBSTRING
Definition: util-error.h:34
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1186
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:1189
PKT_IS_TCP
#define PKT_IS_TCP(p)
Definition: decode.h:261
PrefilterPacketHeaderCtx_
Definition: detect-engine-prefilter-common.h:33
decode.h
util-debug.h
SC_ERR_PCRE_MATCH
@ SC_ERR_PCRE_MATCH
Definition: util-error.h:32
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1003
MODIFIER_PLUS
#define MODIFIER_PLUS
Definition: detect-tcp-flags.c:55
res
PoolThreadReserved res
Definition: stream-tcp-private.h:0
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2558
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
de
int de
Definition: app-layer-htp.c:527
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:324
TH_ACK
#define TH_ACK
Definition: decode-tcp.h:38
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:89
SIZE_OF_PACKET
#define SIZE_OF_PACKET
Definition: decode.h:634
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:323
SCReturn
#define SCReturn
Definition: util-debug.h:302
Signature_::flags
uint32_t flags
Definition: detect.h:518
DetectFlagsData_::ignored_flags
uint8_t ignored_flags
Definition: detect-tcp-flags.h:44
Packet_
Definition: decode.h:414
Packet_::ip4h
IPV4Hdr * ip4h
Definition: decode.h:509
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:587
SCReturnPtr
#define SCReturnPtr(x, type)
Definition: util-debug.h:316
TH_ECN
#define TH_ECN
Definition: decode-tcp.h:41
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1169
SignatureInitData_::smlists
struct SigMatch_ ** smlists
Definition: detect.h:511
SigMatchAlloc
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:235
TH_URG
#define TH_URG
Definition: decode-tcp.h:39
decode-events.h
SigMatch_::type
uint8_t type
Definition: detect.h:321
PrefilterPacketHeaderCtx_::v1
PrefilterPacketHeaderValue v1
Definition: detect-engine-prefilter-common.h:34
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:315
IPV4Hdr_
Definition: decode-ipv4.h:71
TH_PUSH
#define TH_PUSH
Definition: decode-tcp.h:37
TH_SYN
#define TH_SYN
Definition: decode-tcp.h:35
flags
uint8_t flags
Definition: decode-gre.h:0
SigTableElmt_::alias
const char * alias
Definition: detect.h:1202
suricata-common.h
Packet_::tcph
TCPHdr * tcph
Definition: decode.h:531
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
PrefilterSetupPacketHeader
int PrefilterSetupPacketHeader(DetectEngineCtx *de_ctx, SigGroupHead *sgh, int sm_type, void(*Set)(PrefilterPacketHeaderValue *v, void *), bool(*Compare)(PrefilterPacketHeaderValue v, void *), void(*Match)(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx))
Definition: detect-engine-prefilter-common.c:417
DetectFlagsRegister
void DetectFlagsRegister(void)
Registration function for flags: keyword.
Definition: detect-tcp-flags.c:75
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
SCFree
#define SCFree(p)
Definition: util-mem.h:61
SigTableElmt_::SupportsPrefilter
bool(* SupportsPrefilter)(const Signature *s)
Definition: detect.h:1188
detect-parse.h
Signature_
Signature container.
Definition: detect.h:517
SigMatch_
a single match condition for a signature
Definition: detect.h:320
TH_CWR
#define TH_CWR
Definition: decode-tcp.h:43
DetectFlagsData_
Definition: detect-tcp-flags.h:41
SC_Pcre2SubstringCopy
int SC_Pcre2SubstringCopy(pcre2_match_data *match_data, uint32_t number, PCRE2_UCHAR *buffer, PCRE2_SIZE *bufflen)
Definition: detect-parse.c:2534
suricata.h
SC_ERR_FLAGS_MODIFIER
@ SC_ERR_FLAGS_MODIFIER
Definition: util-error.h:133
MODIFIER_ANY
#define MODIFIER_ANY
Definition: detect-tcp-flags.c:56
PrefilterPacketHeaderValue
Definition: detect-engine-prefilter-common.h:21
detect-engine-prefilter-common.h
DETECT_FLAGS
@ DETECT_FLAGS
Definition: detect-engine-register.h:40
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:304
flow-var.h
SigMatchAppendSMToList
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:349
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1193
SIG_FLAG_REQUIRE_PACKET
#define SIG_FLAG_REQUIRE_PACKET
Definition: detect.h:223