suricata
detect-flowint.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 Pablo Rincon <pablo.rincon.crespo@gmail.com>
22  *
23  * Flowvar management for integer types, part of the detection engine
24  * Keyword: flowint
25  */
26 
27 #include "suricata-common.h"
28 #include "decode.h"
29 #include "detect.h"
30 #include "threads.h"
31 #include "flow.h"
32 #include "flow-var.h"
33 #include "detect-flowint.h"
34 #include "util-spm.h"
35 #include "util-var-name.h"
36 #include "util-debug.h"
37 #include "util-unittest.h"
38 #include "util-unittest-helper.h"
39 
40 #include "detect-parse.h"
41 #include "detect-engine.h"
42 #include "detect-engine-mpm.h"
43 #include "detect-engine-sigorder.h"
44 #include "detect-engine-build.h"
45 
46 #include "pkt-var.h"
47 #include "host.h"
48 #include "util-profiling.h"
49 
50 /* name modifiers value */
51 #define PARSE_REGEX "^\\s*([a-zA-Z][\\w\\d_./]+)\\s*,\\s*([+=-]{1}|==|!=|<|<=|>|>=|isset|notset)\\s*,?\\s*([a-zA-Z][\\w\\d]+|[\\d]{1,10})?\\s*$"
52 /* Varnames must begin with a letter */
53 
54 static DetectParseRegex parse_regex;
55 
57  const Signature *, const SigMatchCtx *);
58 static int DetectFlowintSetup(DetectEngineCtx *, Signature *, const char *);
59 void DetectFlowintFree(DetectEngineCtx *, void *);
60 #ifdef UNITTESTS
61 static void DetectFlowintRegisterTests(void);
62 #endif
63 
65 {
66  sigmatch_table[DETECT_FLOWINT].name = "flowint";
67  sigmatch_table[DETECT_FLOWINT].desc = "operate on a per-flow integer";
68  sigmatch_table[DETECT_FLOWINT].url = "/rules/flow-keywords.html#flowint";
70  sigmatch_table[DETECT_FLOWINT].Setup = DetectFlowintSetup;
72 #ifdef UNITTESTS
73  sigmatch_table[DETECT_FLOWINT].RegisterTests = DetectFlowintRegisterTests;
74 #endif
75  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
76 }
77 
78 /**
79  * \brief This function is used to create a flowint, add/substract values,
80  * compare it with other flowints, etc
81  *
82  * \param t pointer to thread vars
83  * \param det_ctx pointer to the pattern matcher thread
84  * \param p pointer to the current packet
85  * \param s pointer to the current Signature
86  * \param m pointer to the sigmatch that we will cast into DetectFlowintData
87  *
88  * \retval 0 no match, when a var doesn't exist
89  * \retval 1 match, when a var is initialized well, add/subtracted, or a true
90  * condition
91  */
93  Packet *p, const Signature *s, const SigMatchCtx *ctx)
94 {
95  const DetectFlowintData *sfd = (const DetectFlowintData *)ctx;
96  FlowVar *fv;
97  FlowVar *fvt;
98  uint32_t targetval;
99  int ret = 0;
100 
101  if (p->flow == NULL)
102  return 0;
103 
104  /** ATM If we are going to compare the current var with another
105  * that doesn't exist, the default value will be zero;
106  * if you don't want this behaviour, you can use the keyword
107  * "isset" to make it match or not before using the default
108  * value of zero;
109  * But it is mandatory that the current var exist, otherwise, it will
110  * return zero(not match).
111  */
112  if (sfd->targettype == FLOWINT_TARGET_VAR) {
113  uint32_t tvar_idx = VarNameStoreLookupByName(sfd->target.tvar.name, VAR_TYPE_FLOW_INT);
114 
115  fvt = FlowVarGet(p->flow, tvar_idx);
116  /* We don't have that variable initialized yet */
117  if (fvt == NULL)
118  targetval = 0;
119  else
120  targetval = fvt->data.fv_int.value;
121  } else {
122  targetval = sfd->target.value;
123  }
124 
125  SCLogDebug("Our var %s is at idx: %"PRIu32"", sfd->name, sfd->idx);
126 
127  if (sfd->modifier == FLOWINT_MODIFIER_SET) {
128  FlowVarAddIntNoLock(p->flow, sfd->idx, targetval);
129  SCLogDebug("Setting %s = %u", sfd->name, targetval);
130  ret = 1;
131  goto end;
132  }
133 
134  fv = FlowVarGet(p->flow, sfd->idx);
135 
136  if (sfd->modifier == FLOWINT_MODIFIER_ISSET) {
137  SCLogDebug(" Isset %s? = %u", sfd->name,(fv) ? 1 : 0);
138  if (fv != NULL)
139  ret = 1;
140  goto end;
141  }
142 
143  if (sfd->modifier == FLOWINT_MODIFIER_NOTSET) {
144  SCLogDebug(" Not set %s? = %u", sfd->name,(fv) ? 0 : 1);
145  if (fv == NULL)
146  ret = 1;
147  goto end;
148  }
149 
150  if (fv != NULL && fv->datatype == FLOWVAR_TYPE_INT) {
151  if (sfd->modifier == FLOWINT_MODIFIER_ADD) {
152  SCLogDebug("Adding %u to %s", targetval, sfd->name);
153  FlowVarAddIntNoLock(p->flow, sfd->idx, fv->data.fv_int.value +
154  targetval);
155  ret = 1;
156  goto end;
157  }
158 
159  if (sfd->modifier == FLOWINT_MODIFIER_SUB) {
160  SCLogDebug("Subtracting %u to %s", targetval, sfd->name);
161  FlowVarAddIntNoLock(p->flow, sfd->idx, fv->data.fv_int.value -
162  targetval);
163  ret = 1;
164  goto end;
165  }
166 
167  switch(sfd->modifier) {
168  case FLOWINT_MODIFIER_EQ:
169  SCLogDebug("( %u EQ %u )", fv->data.fv_int.value, targetval);
170  ret = (fv->data.fv_int.value == targetval);
171  break;
172  case FLOWINT_MODIFIER_NE:
173  SCLogDebug("( %u NE %u )", fv->data.fv_int.value, targetval);
174  ret = (fv->data.fv_int.value != targetval);
175  break;
176  case FLOWINT_MODIFIER_LT:
177  SCLogDebug("( %u LT %u )", fv->data.fv_int.value, targetval);
178  ret = (fv->data.fv_int.value < targetval);
179  break;
180  case FLOWINT_MODIFIER_LE:
181  SCLogDebug("( %u LE %u )", fv->data.fv_int.value, targetval);
182  ret = (fv->data.fv_int.value <= targetval);
183  break;
184  case FLOWINT_MODIFIER_GT:
185  SCLogDebug("( %u GT %u )", fv->data.fv_int.value, targetval);
186  ret = (fv->data.fv_int.value > targetval);
187  break;
188  case FLOWINT_MODIFIER_GE:
189  SCLogDebug("( %u GE %u )", fv->data.fv_int.value, targetval);
190  ret = (fv->data.fv_int.value >= targetval);
191  break;
192  default:
193  SCLogDebug("Unknown Modifier!");
194 #ifdef DEBUG
195  BUG_ON(1);
196 #endif
197  }
198  } else {
199  /* allow a add on a non-existing var, it will init to the "add" value,
200  * so implying a 0 set. */
201  if (sfd->modifier == FLOWINT_MODIFIER_ADD) {
202  SCLogDebug("Adding %u to %s (new var)", targetval, sfd->name);
203  FlowVarAddIntNoLock(p->flow, sfd->idx, targetval);
204  ret = 1;
205  } else {
206  SCLogDebug("Var not found!");
207  /* It doesn't exist because it wasn't set
208  * or it is a string var, that we don't compare here
209  */
210  ret = 0;
211  }
212  }
213 
214 end:
215  return ret;
216 }
217 
218 /**
219  * \brief This function is used to parse a flowint option
220  *
221  * \param de_ctx pointer to the engine context
222  * \param rawstr pointer to the string holding the options
223  *
224  * \retval NULL if invalid option
225  * \retval DetectFlowintData pointer with the flowint parsed
226  */
227 static DetectFlowintData *DetectFlowintParse(DetectEngineCtx *de_ctx, const char *rawstr)
228 {
229  DetectFlowintData *sfd = NULL;
230  char *varname = NULL;
231  char *varval = NULL;
232  char *modstr = NULL;
233  int res = 0;
234  size_t pcre2_len;
235  uint8_t modifier = FLOWINT_MODIFIER_UNKNOWN;
236  unsigned long long value_long = 0;
237  const char *str_ptr;
238  pcre2_match_data *match = NULL;
239 
240  int ret = DetectParsePcreExec(&parse_regex, &match, rawstr, 0, 0);
241  if (ret < 3 || ret > 4) {
242  SCLogError("\"%s\" is not a valid setting for flowint(ret = %d).", rawstr, ret);
243  goto error;
244  }
245 
246  /* Get our flowint varname */
247  res = pcre2_substring_get_bynumber(match, 1, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
248  if (res < 0 || str_ptr == NULL) {
249  SCLogError("pcre2_substring_get_bynumber failed");
250  goto error;
251  }
252  varname = (char *)str_ptr;
253 
254  res = pcre2_substring_get_bynumber(match, 2, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
255  if (res < 0 || str_ptr == NULL) {
256  SCLogError("pcre2_substring_get_bynumber failed");
257  goto error;
258  }
259  modstr = (char *)str_ptr;
260 
261  /* Get the modifier */
262  if (strcmp("=", modstr) == 0)
263  modifier = FLOWINT_MODIFIER_SET;
264  if (strcmp("+", modstr) == 0)
265  modifier = FLOWINT_MODIFIER_ADD;
266  if (strcmp("-", modstr) == 0)
267  modifier = FLOWINT_MODIFIER_SUB;
268 
269  if (strcmp("<", modstr) == 0)
270  modifier = FLOWINT_MODIFIER_LT;
271  if (strcmp("<=", modstr) == 0)
272  modifier = FLOWINT_MODIFIER_LE;
273  if (strcmp("!=", modstr) == 0)
274  modifier = FLOWINT_MODIFIER_NE;
275  if (strcmp("==", modstr) == 0)
276  modifier = FLOWINT_MODIFIER_EQ;
277  if (strcmp(">=", modstr) == 0)
278  modifier = FLOWINT_MODIFIER_GE;
279  if (strcmp(">", modstr) == 0)
280  modifier = FLOWINT_MODIFIER_GT;
281  if (strcmp("isset", modstr) == 0)
282  modifier = FLOWINT_MODIFIER_ISSET;
283  if (strcmp("notset", modstr) == 0)
284  modifier = FLOWINT_MODIFIER_NOTSET;
285 
286  if (modifier == FLOWINT_MODIFIER_UNKNOWN) {
287  SCLogError("Unknown modifier");
288  goto error;
289  }
290 
291  sfd = SCMalloc(sizeof(DetectFlowintData));
292  if (unlikely(sfd == NULL))
293  goto error;
294 
295  /* If we need another arg, check it out(isset doesn't need another arg) */
296  if (modifier != FLOWINT_MODIFIER_ISSET && modifier != FLOWINT_MODIFIER_NOTSET) {
297  if (ret < 4)
298  goto error;
299 
300  res = pcre2_substring_get_bynumber(match, 3, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
301  varval = (char *)str_ptr;
302  if (res < 0 || varval == NULL || strcmp(varval, "") == 0) {
303  SCLogError("pcre2_substring_get_bynumber failed");
304  goto error;
305  }
306 
307  if (varval[0] >= '0' && varval[0] <= '9') { /* is digit, look at the regexp */
309  value_long = atoll(varval);
310  if (value_long > UINT32_MAX) {
311  SCLogDebug("DetectFlowintParse: Cannot load this value."
312  " Values should be between 0 and %"PRIu32, UINT32_MAX);
313  goto error;
314  }
315  sfd->target.value = (uint32_t) value_long;
316  } else {
318  sfd->target.tvar.name = SCStrdup(varval);
319  if (unlikely(sfd->target.tvar.name == NULL)) {
320  SCLogError("malloc from strdup failed");
321  goto error;
322  }
323  }
324  } else {
326  }
327 
328  /* Set the name of the origin var to modify/compared with the target */
329  sfd->name = SCStrdup(varname);
330  if (unlikely(sfd->name == NULL)) {
331  SCLogError("malloc from strdup failed");
332  goto error;
333  }
334  sfd->idx = VarNameStoreRegister(varname, VAR_TYPE_FLOW_INT);
335  SCLogDebug("sfd->name %s id %u", sfd->name, sfd->idx);
336  sfd->modifier = modifier;
337 
338  pcre2_substring_free((PCRE2_UCHAR *)varname);
339  pcre2_substring_free((PCRE2_UCHAR *)modstr);
340  if (varval)
341  pcre2_substring_free((PCRE2_UCHAR *)varval);
342  pcre2_match_data_free(match);
343  return sfd;
344 error:
345  if (match) {
346  pcre2_match_data_free(match);
347  }
348  if (varname)
349  pcre2_substring_free((PCRE2_UCHAR *)varname);
350  if (varval)
351  pcre2_substring_free((PCRE2_UCHAR *)varval);
352  if (modstr)
353  pcre2_substring_free((PCRE2_UCHAR *)modstr);
354  if (sfd != NULL)
355  SCFree(sfd);
356  return NULL;
357 }
358 
359 /**
360  * \brief This function is used to set up the SigMatch holding the flowint opt
361  *
362  * \param de_ctx pointer to the engine context
363  * \param s pointer to the current Signature
364  * \param rawstr pointer to the string holding the options
365  *
366  * \retval 0 if all is ok
367  * \retval -1 if we find any problem
368  */
369 static int DetectFlowintSetup(DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
370 {
371  DetectFlowintData *sfd = NULL;
372 
373  sfd = DetectFlowintParse(de_ctx, rawstr);
374  if (sfd == NULL)
375  goto error;
376 
377  /* Okay so far so good, lets get this into a SigMatch
378  * and put it in the Signature. */
379 
380  switch (sfd->modifier) {
385  DETECT_SM_LIST_POSTMATCH) == NULL) {
386  goto error;
387  }
388  break;
389 
390  case FLOWINT_MODIFIER_LT:
391  case FLOWINT_MODIFIER_LE:
392  case FLOWINT_MODIFIER_NE:
393  case FLOWINT_MODIFIER_EQ:
394  case FLOWINT_MODIFIER_GE:
395  case FLOWINT_MODIFIER_GT:
399  DETECT_SM_LIST_MATCH) == NULL) {
400  goto error;
401  }
402  break;
403  default:
404  goto error;
405  }
406 
407  return 0;
408 
409 error:
410  if (sfd)
412  return -1;
413 }
414 
415 /**
416  * \brief This function is used to free the data of DetectFlowintData
417  */
419 {
421  if (sfd != NULL) {
423  if (sfd->name != NULL)
424  SCFree(sfd->name);
425  if (sfd->targettype == FLOWINT_TARGET_VAR)
426  if (sfd->target.tvar.name != NULL)
427  SCFree(sfd->target.tvar.name);
428  SCFree(sfd);
429  }
430 }
431 
432 #ifdef UNITTESTS
433 #include "detect-engine-alert.h"
434 /**
435  * \brief This is a helper function used for debugging purposes
436  */
437 static void DetectFlowintPrintData(DetectFlowintData *sfd)
438 {
439  if (sfd == NULL) {
440  SCLogDebug("DetectFlowintPrintData: Error, DetectFlowintData == NULL!");
441  return;
442  }
443 
444  SCLogDebug("Varname: %s, modifier: %"PRIu8", idx: %"PRIu32" Target: ",
445  sfd->name, sfd->modifier, sfd->idx);
446  switch(sfd->targettype) {
447  case FLOWINT_TARGET_VAR:
448  SCLogDebug("target_var: %s",
449  sfd->target.tvar.name);
450  break;
451  case FLOWINT_TARGET_VAL:
452  SCLogDebug("Value: %"PRIu32"; ", sfd->target.value);
453  break;
454  default :
455  SCLogDebug("DetectFlowintPrintData: Error, Targettype not known!");
456  }
457 }
458 
459 /**
460  * \test DetectFlowintTestParseVal01 is a test to make sure that we set the
461  * DetectFlowint correctly for setting a valid target value
462  */
463 static int DetectFlowintTestParseVal01(void)
464 {
465  int result = 0;
466  DetectFlowintData *sfd = NULL;
469  if (de_ctx == NULL)
470  return 0;
471  de_ctx->flags |= DE_QUIET;
472 
473  sfd = DetectFlowintParse(de_ctx, "myvar,=,35");
474  DetectFlowintPrintData(sfd);
475  if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar")
476  && sfd->modifier == FLOWINT_MODIFIER_SET) {
477  result = 1;
478  }
479  if (sfd) DetectFlowintFree(NULL, sfd);
480 
482 
483  return result;
484 }
485 
486 /**
487  * \test DetectFlowintTestParseVar01 is a test to make sure that we set the
488  * DetectFlowint correctly for setting a valid target variable
489  */
490 static int DetectFlowintTestParseVar01(void)
491 {
492  int result = 0;
493  DetectFlowintData *sfd = NULL;
496  if (de_ctx == NULL)
497  return 0;
498  de_ctx->flags |= DE_QUIET;
499 
500  sfd = DetectFlowintParse(de_ctx, "myvar,=,targetvar");
501  DetectFlowintPrintData(sfd);
502  if (sfd != NULL && !strcmp(sfd->name, "myvar")
503  && sfd->targettype == FLOWINT_TARGET_VAR
504  && sfd->target.tvar.name != NULL
505  && !strcmp(sfd->target.tvar.name, "targetvar")
506  && sfd->modifier == FLOWINT_MODIFIER_SET) {
507 
508  result = 1;
509  }
510  if (sfd) DetectFlowintFree(NULL, sfd);
512 
513  return result;
514 }
515 
516 /**
517  * \test DetectFlowintTestParseVal02 is a test to make sure that we set the
518  * DetectFlowint correctly for adding a valid target value
519  */
520 static int DetectFlowintTestParseVal02(void)
521 {
522  int result = 0;
523  DetectFlowintData *sfd = NULL;
526  if (de_ctx == NULL)
527  return 0;
528  de_ctx->flags |= DE_QUIET;
529 
530  sfd = DetectFlowintParse(de_ctx, "myvar,+,35");
531  DetectFlowintPrintData(sfd);
532  if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar")
533  && sfd->modifier == FLOWINT_MODIFIER_ADD) {
534  result = 1;
535  }
536  if (sfd) DetectFlowintFree(NULL, sfd);
537 
539 
540  return result;
541 }
542 
543 /**
544  * \test DetectFlowintTestParseVar02 is a test to make sure that we set the
545  * DetectFlowint correctly for adding a valid target variable
546  */
547 static int DetectFlowintTestParseVar02(void)
548 {
549  int result = 0;
550  DetectFlowintData *sfd = NULL;
553  if (de_ctx == NULL)
554  return 0;
555  de_ctx->flags |= DE_QUIET;
556 
557  sfd = DetectFlowintParse(de_ctx, "myvar,+,targetvar");
558  DetectFlowintPrintData(sfd);
559  if (sfd != NULL && !strcmp(sfd->name, "myvar")
560  && sfd->targettype == FLOWINT_TARGET_VAR
561  && sfd->target.tvar.name != NULL
562  && !strcmp(sfd->target.tvar.name, "targetvar")
563  && sfd->modifier == FLOWINT_MODIFIER_ADD) {
564 
565  result = 1;
566  }
567  if (sfd) DetectFlowintFree(NULL, sfd);
569 
570  return result;
571 }
572 
573 /**
574  * \test DetectFlowintTestParseVal03 is a test to make sure that we set the
575  * DetectFlowint correctly for substract a valid target value
576  */
577 static int DetectFlowintTestParseVal03(void)
578 {
579  int result = 0;
580  DetectFlowintData *sfd = NULL;
583  if (de_ctx == NULL)
584  return 0;
585  de_ctx->flags |= DE_QUIET;
586 
587  sfd = DetectFlowintParse(de_ctx, "myvar,-,35");
588  DetectFlowintPrintData(sfd);
589  if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar")
590  && sfd->modifier == FLOWINT_MODIFIER_SUB) {
591  result = 1;
592  }
593  if (sfd) DetectFlowintFree(NULL, sfd);
594 
596 
597  return result;
598 }
599 
600 /**
601  * \test DetectFlowintTestParseVar03 is a test to make sure that we set the
602  * DetectFlowint correctly for substract a valid target variable
603  */
604 static int DetectFlowintTestParseVar03(void)
605 {
606  int result = 0;
607  DetectFlowintData *sfd = NULL;
610  if (de_ctx == NULL)
611  return 0;
612  de_ctx->flags |= DE_QUIET;
613 
614  sfd = DetectFlowintParse(de_ctx, "myvar,-,targetvar");
615  DetectFlowintPrintData(sfd);
616  if (sfd != NULL && !strcmp(sfd->name, "myvar")
617  && sfd->targettype == FLOWINT_TARGET_VAR
618  && sfd->target.tvar.name != NULL
619  && !strcmp(sfd->target.tvar.name, "targetvar")
620  && sfd->modifier == FLOWINT_MODIFIER_SUB) {
621 
622  result = 1;
623  }
624  if (sfd) DetectFlowintFree(NULL, sfd);
626 
627  return result;
628 }
629 
630 
631 /**
632  * \test DetectFlowintTestParseVal04 is a test to make sure that we set the
633  * DetectFlowint correctly for checking if equal to a valid target value
634  */
635 static int DetectFlowintTestParseVal04(void)
636 {
637  int result = 0;
638  DetectFlowintData *sfd = NULL;
641  if (de_ctx == NULL)
642  return 0;
643  de_ctx->flags |= DE_QUIET;
644 
645  sfd = DetectFlowintParse(de_ctx, "myvar,==,35");
646  DetectFlowintPrintData(sfd);
647  if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar")
648  && sfd->modifier == FLOWINT_MODIFIER_EQ) {
649  result = 1;
650  }
651  if (sfd) DetectFlowintFree(NULL, sfd);
652 
654 
655  return result;
656 }
657 
658 /**
659  * \test DetectFlowintTestParseVar04 is a test to make sure that we set the
660  * DetectFlowint correctly for checking if equal to a valid target variable
661  */
662 static int DetectFlowintTestParseVar04(void)
663 {
664  int result = 0;
665  DetectFlowintData *sfd = NULL;
668  if (de_ctx == NULL)
669  return 0;
670  de_ctx->flags |= DE_QUIET;
671 
672  sfd = DetectFlowintParse(de_ctx, "myvar,==,targetvar");
673  DetectFlowintPrintData(sfd);
674  if (sfd != NULL && !strcmp(sfd->name, "myvar")
675  && sfd->targettype == FLOWINT_TARGET_VAR
676  && sfd->target.tvar.name != NULL
677  && !strcmp(sfd->target.tvar.name, "targetvar")
678  && sfd->modifier == FLOWINT_MODIFIER_EQ) {
679 
680  result = 1;
681  }
682  if (sfd) DetectFlowintFree(NULL, sfd);
684 
685  return result;
686 }
687 
688 /**
689  * \test DetectFlowintTestParseVal05 is a test to make sure that we set the
690  * DetectFlowint correctly for checking if not equal to a valid target value
691  */
692 static int DetectFlowintTestParseVal05(void)
693 {
694  int result = 0;
695  DetectFlowintData *sfd = NULL;
698  if (de_ctx == NULL)
699  return 0;
700  de_ctx->flags |= DE_QUIET;
701 
702  sfd = DetectFlowintParse(de_ctx, "myvar,!=,35");
703  DetectFlowintPrintData(sfd);
704  if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar")
705  && sfd->modifier == FLOWINT_MODIFIER_NE) {
706  result = 1;
707  }
708  if (sfd) DetectFlowintFree(NULL, sfd);
709 
711 
712  return result;
713 }
714 
715 /**
716  * \test DetectFlowintTestParseVar05 is a test to make sure that we set the
717  * DetectFlowint correctly for checking if not equal to a valid target variable
718  */
719 static int DetectFlowintTestParseVar05(void)
720 {
721  int result = 0;
722  DetectFlowintData *sfd = NULL;
725  if (de_ctx == NULL)
726  return 0;
727  de_ctx->flags |= DE_QUIET;
728 
729  sfd = DetectFlowintParse(de_ctx, "myvar,!=,targetvar");
730  DetectFlowintPrintData(sfd);
731  if (sfd != NULL && !strcmp(sfd->name, "myvar")
732  && sfd->targettype == FLOWINT_TARGET_VAR
733  && sfd->target.tvar.name != NULL
734  && !strcmp(sfd->target.tvar.name, "targetvar")
735  && sfd->modifier == FLOWINT_MODIFIER_NE) {
736 
737  result = 1;
738  }
739  if (sfd) DetectFlowintFree(NULL, sfd);
741 
742  return result;
743 }
744 
745 /**
746  * \test DetectFlowintTestParseVal06 is a test to make sure that we set the
747  * DetectFlowint correctly for checking if greater than a valid target value
748  */
749 static int DetectFlowintTestParseVal06(void)
750 {
751  int result = 0;
752  DetectFlowintData *sfd = NULL;
755  if (de_ctx == NULL)
756  return 0;
757  de_ctx->flags |= DE_QUIET;
758 
759  sfd = DetectFlowintParse(de_ctx, "myvar, >,35");
760  DetectFlowintPrintData(sfd);
761  if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar")
762  && sfd->modifier == FLOWINT_MODIFIER_GT) {
763  result = 1;
764  }
765  if (sfd) DetectFlowintFree(NULL, sfd);
766 
768 
769  return result;
770 }
771 
772 /**
773  * \test DetectFlowintTestParseVar06 is a test to make sure that we set the
774  * DetectFlowint correctly for checking if greater than a valid target variable
775  */
776 static int DetectFlowintTestParseVar06(void)
777 {
778  int result = 0;
779  DetectFlowintData *sfd = NULL;
782  if (de_ctx == NULL)
783  return 0;
784  de_ctx->flags |= DE_QUIET;
785 
786  sfd = DetectFlowintParse(de_ctx, "myvar, >,targetvar");
787  DetectFlowintPrintData(sfd);
788  if (sfd != NULL && !strcmp(sfd->name, "myvar")
789  && sfd->targettype == FLOWINT_TARGET_VAR
790  && sfd->target.tvar.name != NULL
791  && !strcmp(sfd->target.tvar.name, "targetvar")
792  && sfd->modifier == FLOWINT_MODIFIER_GT) {
793 
794  result = 1;
795  }
796  if (sfd) DetectFlowintFree(NULL, sfd);
798 
799  return result;
800 }
801 
802 /**
803  * \test DetectFlowintTestParseVal07 is a test to make sure that we set the
804  * DetectFlowint correctly for checking if greater or equal than a valid target value
805  */
806 static int DetectFlowintTestParseVal07(void)
807 {
808  int result = 0;
809  DetectFlowintData *sfd = NULL;
812  if (de_ctx == NULL)
813  return 0;
814  de_ctx->flags |= DE_QUIET;
815 
816  sfd = DetectFlowintParse(de_ctx, "myvar, >= ,35");
817  DetectFlowintPrintData(sfd);
818  if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar")
819  && sfd->modifier == FLOWINT_MODIFIER_GE) {
820  result = 1;
821  }
822  if (sfd) DetectFlowintFree(NULL, sfd);
823 
825 
826  return result;
827 }
828 
829 /**
830  * \test DetectFlowintTestParseVar07 is a test to make sure that we set the
831  * DetectFlowint correctly for checking if greater or equal than a valid target variable
832  */
833 static int DetectFlowintTestParseVar07(void)
834 {
835  int result = 0;
836  DetectFlowintData *sfd = NULL;
839  if (de_ctx == NULL)
840  return 0;
841  de_ctx->flags |= DE_QUIET;
842 
843  sfd = DetectFlowintParse(de_ctx, "myvar, >= ,targetvar");
844  DetectFlowintPrintData(sfd);
845  if (sfd != NULL && !strcmp(sfd->name, "myvar")
846  && sfd->targettype == FLOWINT_TARGET_VAR
847  && sfd->target.tvar.name != NULL
848  && !strcmp(sfd->target.tvar.name, "targetvar")
849  && sfd->modifier == FLOWINT_MODIFIER_GE) {
850 
851  result = 1;
852  }
853  if (sfd) DetectFlowintFree(NULL, sfd);
855 
856  return result;
857 }
858 
859 /**
860  * \test DetectFlowintTestParseVal08 is a test to make sure that we set the
861  * DetectFlowint correctly for checking if lower or equal than a valid target value
862  */
863 static int DetectFlowintTestParseVal08(void)
864 {
865  int result = 0;
866  DetectFlowintData *sfd = NULL;
869  if (de_ctx == NULL)
870  return 0;
871  de_ctx->flags |= DE_QUIET;
872 
873  sfd = DetectFlowintParse(de_ctx, "myvar, <= ,35");
874  DetectFlowintPrintData(sfd);
875  if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar")
876  && sfd->modifier == FLOWINT_MODIFIER_LE) {
877  result = 1;
878  }
879  if (sfd) DetectFlowintFree(NULL, sfd);
880 
882 
883  return result;
884 }
885 
886 /**
887  * \test DetectFlowintTestParseVar08 is a test to make sure that we set the
888  * DetectFlowint correctly for checking if lower or equal than a valid target variable
889  */
890 static int DetectFlowintTestParseVar08(void)
891 {
892  int result = 0;
893  DetectFlowintData *sfd = NULL;
896  if (de_ctx == NULL)
897  return 0;
898  de_ctx->flags |= DE_QUIET;
899 
900  sfd = DetectFlowintParse(de_ctx, "myvar, <= ,targetvar");
901  DetectFlowintPrintData(sfd);
902  if (sfd != NULL && !strcmp(sfd->name, "myvar")
903  && sfd->targettype == FLOWINT_TARGET_VAR
904  && sfd->target.tvar.name != NULL
905  && !strcmp(sfd->target.tvar.name, "targetvar")
906  && sfd->modifier == FLOWINT_MODIFIER_LE) {
907 
908  result = 1;
909  }
910  if (sfd) DetectFlowintFree(NULL, sfd);
912 
913  return result;
914 }
915 
916 /**
917  * \test DetectFlowintTestParseVal09 is a test to make sure that we set the
918  * DetectFlowint correctly for checking if lower than a valid target value
919  */
920 static int DetectFlowintTestParseVal09(void)
921 {
922  int result = 0;
923  DetectFlowintData *sfd = NULL;
926  if (de_ctx == NULL)
927  return 0;
928  de_ctx->flags |= DE_QUIET;
929 
930  sfd = DetectFlowintParse(de_ctx, "myvar, < ,35");
931  DetectFlowintPrintData(sfd);
932  if (sfd != NULL && sfd->target.value == 35 && !strcmp(sfd->name, "myvar")
933  && sfd->modifier == FLOWINT_MODIFIER_LT) {
934  result = 1;
935  }
936  if (sfd) DetectFlowintFree(NULL, sfd);
937 
939 
940  return result;
941 }
942 
943 /**
944  * \test DetectFlowintTestParseVar09 is a test to make sure that we set the
945  * DetectFlowint correctly for checking if lower than a valid target variable
946  */
947 static int DetectFlowintTestParseVar09(void)
948 {
949  int result = 0;
950  DetectFlowintData *sfd = NULL;
953  if (de_ctx == NULL)
954  return 0;
955  de_ctx->flags |= DE_QUIET;
956 
957  sfd = DetectFlowintParse(de_ctx, "myvar, < ,targetvar");
958  DetectFlowintPrintData(sfd);
959  if (sfd != NULL && !strcmp(sfd->name, "myvar")
960  && sfd->targettype == FLOWINT_TARGET_VAR
961  && sfd->target.tvar.name != NULL
962  && !strcmp(sfd->target.tvar.name, "targetvar")
963  && sfd->modifier == FLOWINT_MODIFIER_LT) {
964 
965  result = 1;
966  }
967  if (sfd) DetectFlowintFree(NULL, sfd);
969 
970  return result;
971 }
972 
973 /**
974  * \test DetectFlowintTestParseVar09 is a test to make sure that handle the
975  * isset keyword correctly
976  */
977 static int DetectFlowintTestParseIsset10(void)
978 {
979  int result = 1;
980  DetectFlowintData *sfd = NULL;
983  if (de_ctx == NULL)
984  return 0;
985  de_ctx->flags |= DE_QUIET;
986 
987  sfd = DetectFlowintParse(de_ctx, "myvar, isset");
988  DetectFlowintPrintData(sfd);
989  if (sfd != NULL && !strcmp(sfd->name, "myvar")
991  && sfd->modifier == FLOWINT_MODIFIER_ISSET) {
992 
993  result &= 1;
994  } else {
995  result = 0;
996  }
997 
998  if (sfd) DetectFlowintFree(NULL, sfd);
999  sfd = DetectFlowintParse(de_ctx, "myvar, notset");
1000  DetectFlowintPrintData(sfd);
1001  if (sfd != NULL && !strcmp(sfd->name, "myvar")
1002  && sfd->targettype == FLOWINT_TARGET_SELF
1003  && sfd->modifier == FLOWINT_MODIFIER_NOTSET) {
1004 
1005  result &= 1;
1006  } else {
1007  result = 0;
1008  }
1009 
1010  if (sfd) DetectFlowintFree(NULL, sfd);
1012 
1013  return result;
1014 }
1015 
1016 /**
1017  * \test DetectFlowintTestParseInvalidSyntaxis01 is a test to make sure that we dont set the
1018  * DetectFlowint for a invalid input option
1019  */
1020 static int DetectFlowintTestParseInvalidSyntaxis01(void)
1021 {
1022  int result = 1;
1023  DetectFlowintData *sfd = NULL;
1026  if (de_ctx == NULL)
1027  goto error;
1028  de_ctx->flags |= DE_QUIET;
1029 
1030  sfd = DetectFlowintParse(de_ctx, "myvar,=,9999999999");
1031  if (sfd != NULL) {
1032  SCLogDebug("DetectFlowintTestParseInvalidSyntaxis01: ERROR: invalid option at myvar,=,9532458716234857");
1033  result = 0;
1034  }
1035  if (sfd) DetectFlowintFree(NULL, sfd);
1036 
1037  sfd = DetectFlowintParse(de_ctx, "myvar,=,45targetvar");
1038  if (sfd != NULL) {
1039  SCLogDebug("DetectFlowintTestParseInvalidSyntaxis01: ERROR: invalid option at myvar,=,45targetvar ");
1040  result = 0;
1041  }
1042  if (sfd) DetectFlowintFree(NULL, sfd);
1043 
1044  sfd = DetectFlowintParse(de_ctx, "657myvar,=,targetvar");
1045  if (sfd != NULL) {
1046  SCLogDebug("DetectFlowintTestParseInvalidSyntaxis01: ERROR: invalid option at 657myvar,=,targetvar ");
1047  result = 0;
1048  }
1049  if (sfd) DetectFlowintFree(NULL, sfd);
1050 
1051  sfd = DetectFlowintParse(de_ctx, "myvar,=<,targetvar");
1052  if (sfd != NULL) {
1053  SCLogDebug("DetectFlowintTestParseInvalidSyntaxis01: ERROR: invalid option at myvar,=<,targetvar ");
1054  result = 0;
1055  }
1056  if (sfd) DetectFlowintFree(NULL, sfd);
1057 
1058  sfd = DetectFlowintParse(de_ctx, "myvar,===,targetvar");
1059  if (sfd != NULL) {
1060  SCLogDebug("DetectFlowintTestParseInvalidSyntaxis01: ERROR: invalid option at myvar,===,targetvar ");
1061  result = 0;
1062  }
1063  if (sfd) DetectFlowintFree(NULL, sfd);
1064 
1065  sfd = DetectFlowintParse(de_ctx, "myvar,==");
1066  if (sfd != NULL) {
1067  SCLogDebug("DetectFlowintTestParseInvalidSyntaxis01: ERROR: invalid option at myvar,==");
1068  result = 0;
1069  }
1070  if (sfd) DetectFlowintFree(NULL, sfd);
1071 
1072  sfd = DetectFlowintParse(de_ctx, "myvar,");
1073  if (sfd != NULL) {
1074  SCLogDebug("DetectFlowintTestParseInvalidSyntaxis01: ERROR: invalid option at myvar,");
1075  result = 0;
1076  }
1077  if (sfd) DetectFlowintFree(NULL, sfd);
1078 
1079  sfd = DetectFlowintParse(de_ctx, "myvar");
1080  if (sfd != NULL) {
1081  SCLogDebug("DetectFlowintTestParseInvalidSyntaxis01: ERROR: invalid option at myvar");
1082  result = 0;
1083  }
1084  if (sfd) DetectFlowintFree(NULL, sfd);
1085 
1087 
1088  return result;
1089 error:
1090  if (de_ctx)
1092  return result;
1093 }
1094 
1095 /** \test DetectFlowintTestPacket01Real
1096  * \brief Set a counter when we see a content:"GET"
1097  * and increment it by 2 if we match a "Unauthorized"
1098  * When it reach 3(with the last +2), another counter starts
1099  * and when that counter reach 6 packets.
1100  *
1101  * All the Signatures generate an alert(its for testing)
1102  * but the signature that increment the second counter +1, that has
1103  * a "noalert", so we can do all increments
1104  * silently until we reach 6 next packets counted
1105  */
1106 static int DetectFlowintTestPacket01Real(void)
1107 {
1108  Packet *p = NULL;
1109  ThreadVars th_v;
1110  DetectEngineThreadCtx *det_ctx = NULL;
1111  memset(&th_v, 0, sizeof(th_v));
1112 
1114  FAIL_IF(de_ctx == NULL);
1115 
1116  de_ctx->flags |= DE_QUIET;
1117 
1118  const char *sigs[5];
1119  sigs[0] = "alert tcp any any -> any any (msg:\"Setting a flowint counter\"; content:\"GET\"; flowint:myvar,=,1; flowint:maxvar,=,6; sid:101;)";
1120  sigs[1] = "alert tcp any any -> any any (msg:\"Adding to flowint counter\"; content:\"Unauthorized\"; flowint: myvar,+,2; sid:102;)";
1121  sigs[2] = "alert tcp any any -> any any (msg:\"if the flowint counter is 3 create a new counter\"; content:\"Unauthorized\"; flowint: myvar,==,3; flowint: cntpackets, =, 0; sid:103;)";
1122  sigs[3] = "alert tcp any any -> any any (msg:\"and count the rest of the packets received without generating alerts!!!\"; flowint: myvar,==,3; flowint: cntpackets, +, 1; noalert;sid:104;)";
1123  sigs[4] = "alert tcp any any -> any any (msg:\" and fire this when it reach 6\"; flowint: cntpackets, ==, maxvar; sid:105;)";
1124  FAIL_IF(UTHAppendSigs(de_ctx, sigs, 5) == 0);
1125 
1130  DetectEngineThreadCtxInit(&th_v,(void *) de_ctx,(void *) &det_ctx);
1131 
1132  Flow *f = UTHBuildFlow(AF_INET, "192.168.1.5", "192.168.1.1",
1133  41424, 80);
1134  FAIL_IF(f == NULL);
1135  f->proto = IPPROTO_TCP;
1136 
1137  p = UTHBuildPacket((uint8_t *)"GET", 3, IPPROTO_TCP);
1138  FAIL_IF(p == NULL);
1139  UTHAssignFlow(p, f);
1140  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1141  FAIL_IF(!PacketAlertCheck(p, 101));
1142  UTHFreePacket(p);
1143 
1144  p = UTHBuildPacket((uint8_t *)"Unauthorized", 12, IPPROTO_TCP);
1145  FAIL_IF(p == NULL);
1146  UTHAssignFlow(p, f);
1147  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1148  FAIL_IF(!PacketAlertCheck(p, 102));
1149  FAIL_IF(!PacketAlertCheck(p, 103));
1150  UTHFreePacket(p);
1151 
1152  p = UTHBuildPacket((uint8_t *)"1", 1, IPPROTO_TCP);
1153  FAIL_IF(p == NULL);
1154  UTHAssignFlow(p, f);
1155  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1156  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1157  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1158  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1159  UTHFreePacket(p);
1160 
1161  p = UTHBuildPacket((uint8_t *)"X", 1, IPPROTO_TCP);
1162  FAIL_IF(p == NULL);
1163  UTHAssignFlow(p, f);
1164  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1165  FAIL_IF(!PacketAlertCheck(p, 105));
1166  UTHFreePacket(p);
1167 
1168  UTHFreeFlow(f);
1169  DetectEngineThreadCtxDeinit(&th_v,(void *) det_ctx);
1171 
1172  PASS;
1173 }
1174 
1175 /**
1176  * \test DetectFlowintTestPacket02Real
1177  * \brief like DetectFlowintTestPacket01Real but using isset/notset keywords
1178  */
1179 static int DetectFlowintTestPacket02Real(void)
1180 {
1181  Packet *p = NULL;
1182  ThreadVars th_v;
1183  DetectEngineThreadCtx *det_ctx = NULL;
1184  memset(&th_v, 0, sizeof(th_v));
1185 
1187  FAIL_IF(de_ctx == NULL);
1188 
1189  de_ctx->flags |= DE_QUIET;
1190 
1191  const char *sigs[5];
1192  sigs[0] = "alert tcp any any -> any any (msg:\"Setting a flowint counter\"; content:\"GET\"; flowint: myvar, notset; flowint:maxvar,notset; flowint: myvar,=,1; flowint: maxvar,=,6; sid:101;)";
1193  sigs[1] = "alert tcp any any -> any any (msg:\"Adding to flowint counter\"; content:\"Unauthorized\"; flowint:myvar,isset; flowint: myvar,+,2; sid:102;)";
1194  sigs[2] = "alert tcp any any -> any any (msg:\"if the flowint counter is 3 create a new counter\"; content:\"Unauthorized\"; flowint: myvar, isset; flowint: myvar,==,3; flowint:cntpackets,notset; flowint: cntpackets, =, 0; sid:103;)";
1195  sigs[3] = "alert tcp any any -> any any (msg:\"and count the rest of the packets received without generating alerts!!!\"; flowint: cntpackets,isset; flowint: cntpackets, +, 1; noalert;sid:104;)";
1196  sigs[4] = "alert tcp any any -> any any (msg:\" and fire this when it reach 6\"; flowint: cntpackets, isset; flowint: maxvar,isset; flowint: cntpackets, ==, maxvar; sid:105;)";
1197  FAIL_IF(UTHAppendSigs(de_ctx, sigs, 5) == 0);
1198 
1203  DetectEngineThreadCtxInit(&th_v,(void *) de_ctx,(void *) &det_ctx);
1204 
1205  Flow *f = UTHBuildFlow(AF_INET, "192.168.1.5", "192.168.1.1",
1206  41424, 80);
1207  FAIL_IF(f == NULL);
1208  f->proto = IPPROTO_TCP;
1209 
1210  p = UTHBuildPacket((uint8_t *)"GET", 3, IPPROTO_TCP);
1211  FAIL_IF(p == NULL);
1212  UTHAssignFlow(p, f);
1213  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1214  FAIL_IF(!PacketAlertCheck(p, 101));
1215  UTHFreePacket(p);
1216 
1217  p = UTHBuildPacket((uint8_t *)"Unauthorized", 12, IPPROTO_TCP);
1218  FAIL_IF(p == NULL);
1219  UTHAssignFlow(p, f);
1220  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1221  FAIL_IF(!PacketAlertCheck(p, 102));
1222  FAIL_IF(!PacketAlertCheck(p, 103));
1223  UTHFreePacket(p);
1224 
1225  p = UTHBuildPacket((uint8_t *)"1", 1, IPPROTO_TCP);
1226  FAIL_IF(p == NULL);
1227  UTHAssignFlow(p, f);
1228  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1229  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1230  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1231  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1232  UTHFreePacket(p);
1233 
1234  p = UTHBuildPacket((uint8_t *)"X", 1, IPPROTO_TCP);
1235  FAIL_IF(p == NULL);
1236  UTHAssignFlow(p, f);
1237  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1238  FAIL_IF(!PacketAlertCheck(p, 105));
1239  UTHFreePacket(p);
1240 
1241  UTHFreeFlow(f);
1242  DetectEngineThreadCtxDeinit(&th_v,(void *) det_ctx);
1244 
1245  PASS;
1246 }
1247 
1248 /**
1249  * \test DetectFlowintTestPacket03Real
1250  * \brief Check the behaviour of isset/notset
1251  */
1252 static int DetectFlowintTestPacket03Real(void)
1253 {
1254  Packet *p = NULL;
1255  ThreadVars th_v;
1256  DetectEngineThreadCtx *det_ctx = NULL;
1257  memset(&th_v, 0, sizeof(th_v));
1258 
1260  FAIL_IF(de_ctx == NULL);
1261 
1262  de_ctx->flags |= DE_QUIET;
1263 
1264  const char *sigs[3];
1265  sigs[0] = "alert tcp any any -> any any (msg:\"check notset\"; content:\"GET\"; flowint: myvar, notset; flowint: myvar,=,0; flowint: other,=,10; sid:101;)";
1266  sigs[1] = "alert tcp any any -> any any (msg:\"check isset\"; content:\"Unauthorized\"; flowint:myvar,isset; flowint: other,isset; sid:102;)";
1267  sigs[2] = "alert tcp any any -> any any (msg:\"check notset\"; content:\"Unauthorized\"; flowint:lala,isset; sid:103;)";
1268  FAIL_IF(UTHAppendSigs(de_ctx, sigs, 3) == 0);
1269 
1274  DetectEngineThreadCtxInit(&th_v,(void *) de_ctx,(void *) &det_ctx);
1275 
1276  Flow *f = UTHBuildFlow(AF_INET, "192.168.1.5", "192.168.1.1",
1277  41424, 80);
1278  FAIL_IF(f == NULL);
1279  f->proto = IPPROTO_TCP;
1280 
1281  p = UTHBuildPacket((uint8_t *)"GET", 3, IPPROTO_TCP);
1282  FAIL_IF(p == NULL);
1283  UTHAssignFlow(p, f);
1284  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1285  FAIL_IF(!PacketAlertCheck(p, 101));
1286  UTHFreePacket(p);
1287 
1288  p = UTHBuildPacket((uint8_t *)"Unauthorized", 12, IPPROTO_TCP);
1289  FAIL_IF(p == NULL);
1290  UTHAssignFlow(p, f);
1291  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1292  FAIL_IF(!PacketAlertCheck(p, 102));
1293  FAIL_IF(PacketAlertCheck(p, 103));
1294  UTHFreePacket(p);
1295 
1296  p = UTHBuildPacket((uint8_t *)"1", 1, IPPROTO_TCP);
1297  FAIL_IF(p == NULL);
1298  UTHAssignFlow(p, f);
1299  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1300  FAIL_IF(PacketAlertCheck(p, 102));
1301  FAIL_IF(PacketAlertCheck(p, 103));
1302  UTHFreePacket(p);
1303 
1304  UTHFreeFlow(f);
1305  DetectEngineThreadCtxDeinit(&th_v,(void *) det_ctx);
1307 
1308  PASS;
1309 }
1310 
1311 /**
1312  * \brief this function registers unit tests for DetectFlowint
1313  */
1314 void DetectFlowintRegisterTests(void)
1315 {
1316  UtRegisterTest("DetectFlowintTestParseVal01", DetectFlowintTestParseVal01);
1317  UtRegisterTest("DetectFlowintTestParseVar01", DetectFlowintTestParseVar01);
1318  UtRegisterTest("DetectFlowintTestParseVal02", DetectFlowintTestParseVal02);
1319  UtRegisterTest("DetectFlowintTestParseVar02", DetectFlowintTestParseVar02);
1320  UtRegisterTest("DetectFlowintTestParseVal03", DetectFlowintTestParseVal03);
1321  UtRegisterTest("DetectFlowintTestParseVar03", DetectFlowintTestParseVar03);
1322  UtRegisterTest("DetectFlowintTestParseVal04", DetectFlowintTestParseVal04);
1323  UtRegisterTest("DetectFlowintTestParseVar04", DetectFlowintTestParseVar04);
1324  UtRegisterTest("DetectFlowintTestParseVal05", DetectFlowintTestParseVal05);
1325  UtRegisterTest("DetectFlowintTestParseVar05", DetectFlowintTestParseVar05);
1326  UtRegisterTest("DetectFlowintTestParseVal06", DetectFlowintTestParseVal06);
1327  UtRegisterTest("DetectFlowintTestParseVar06", DetectFlowintTestParseVar06);
1328  UtRegisterTest("DetectFlowintTestParseVal07", DetectFlowintTestParseVal07);
1329  UtRegisterTest("DetectFlowintTestParseVar07", DetectFlowintTestParseVar07);
1330  UtRegisterTest("DetectFlowintTestParseVal08", DetectFlowintTestParseVal08);
1331  UtRegisterTest("DetectFlowintTestParseVar08", DetectFlowintTestParseVar08);
1332  UtRegisterTest("DetectFlowintTestParseVal09", DetectFlowintTestParseVal09);
1333  UtRegisterTest("DetectFlowintTestParseVar09", DetectFlowintTestParseVar09);
1334  UtRegisterTest("DetectFlowintTestParseIsset10",
1335  DetectFlowintTestParseIsset10);
1336  UtRegisterTest("DetectFlowintTestParseInvalidSyntaxis01",
1337  DetectFlowintTestParseInvalidSyntaxis01);
1338  UtRegisterTest("DetectFlowintTestPacket01Real",
1339  DetectFlowintTestPacket01Real);
1340  UtRegisterTest("DetectFlowintTestPacket02Real",
1341  DetectFlowintTestPacket02Real);
1342  UtRegisterTest("DetectFlowintTestPacket03Real",
1343  DetectFlowintTestPacket03Real);
1344 }
1345 #endif /* UNITTESTS */
host.h
SigTableElmt_::url
const char * url
Definition: detect.h:1311
FlowVar_::data
union FlowVar_::@114 data
detect-engine.h
SigTableElmt_::desc
const char * desc
Definition: detect.h:1310
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1298
DetectParseRegex
Definition: detect-parse.h:62
SigTableElmt_::name
const char * name
Definition: detect.h:1308
FLOWINT_MODIFIER_ADD
@ FLOWINT_MODIFIER_ADD
Definition: detect-flowint.h:31
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
FLOWINT_MODIFIER_NOTSET
@ FLOWINT_MODIFIER_NOTSET
Definition: detect-flowint.h:43
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
FLOWINT_MODIFIER_NE
@ FLOWINT_MODIFIER_NE
Definition: detect-flowint.h:38
Flow_::proto
uint8_t proto
Definition: flow.h:378
PacketAlertCheck
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
Definition: detect-engine-alert.c:141
DetectFlowintData_::targettype
uint8_t targettype
Definition: detect-flowint.h:71
threads.h
Flow_
Flow data structure.
Definition: flow.h:356
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:848
DetectFlowintData_
Definition: detect-flowint.h:61
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2588
detect-flowint.h
SCSigSignatureOrderingModuleCleanup
void SCSigSignatureOrderingModuleCleanup(DetectEngineCtx *de_ctx)
De-registers all the signature ordering functions registered.
Definition: detect-engine-sigorder.c:825
util-var-name.h
DE_QUIET
#define DE_QUIET
Definition: detect.h:324
UTHBuildPacket
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
Definition: util-unittest-helper.c:359
SigMatchSignatures
void SigMatchSignatures(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1899
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
Definition: detect-parse.c:2663
VarNameStoreRegister
uint32_t VarNameStoreRegister(const char *name, const enum VarTypes type)
Definition: util-var-name.c:155
FLOWVAR_TYPE_INT
#define FLOWVAR_TYPE_INT
Definition: flow-var.h:34
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1293
util-unittest.h
util-unittest-helper.h
UTHAssignFlow
void UTHAssignFlow(Packet *p, Flow *f)
Definition: util-unittest-helper.c:474
DetectFlowintData_::idx
uint32_t idx
Definition: detect-flowint.h:66
FlowVar_::fv_int
FlowVarTypeInt fv_int
Definition: flow-var.h:58
FLOWINT_MODIFIER_UNKNOWN
@ FLOWINT_MODIFIER_UNKNOWN
Definition: detect-flowint.h:45
DETECT_SM_LIST_POSTMATCH
@ DETECT_SM_LIST_POSTMATCH
Definition: detect.h:124
UTHBuildFlow
Flow * UTHBuildFlow(int family, const char *src, const char *dst, Port sp, Port dp)
Definition: util-unittest-helper.c:482
VarNameStoreLookupByName
uint32_t VarNameStoreLookupByName(const char *name, const enum VarTypes type)
find name for id+type at packet time.
Definition: util-var-name.c:322
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
DETECT_FLOWINT
@ DETECT_FLOWINT
Definition: detect-engine-register.h:87
DetectEngineThreadCtx_
Definition: detect.h:1104
FLOWINT_TARGET_VAL
@ FLOWINT_TARGET_VAL
Definition: detect-flowint.h:50
SCSigOrderSignatures
void SCSigOrderSignatures(DetectEngineCtx *de_ctx)
Orders the signatures.
Definition: detect-engine-sigorder.c:733
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2789
detect-engine-mpm.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
pkt-var.h
VarNameStoreUnregister
void VarNameStoreUnregister(const uint32_t id, const enum VarTypes type)
Definition: util-var-name.c:201
SCSigRegisterSignatureOrderingFuncs
void SCSigRegisterSignatureOrderingFuncs(DetectEngineCtx *de_ctx)
Lets you register the Signature ordering functions. The order in which the functions are registered s...
Definition: detect-engine-sigorder.c:805
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:114
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:300
util-profiling.h
Packet_
Definition: decode.h:482
detect-engine-build.h
FLOWINT_MODIFIER_LE
@ FLOWINT_MODIFIER_LE
Definition: detect-flowint.h:36
detect-engine-alert.h
DetectFlowintData_::modifier
uint8_t modifier
Definition: detect-flowint.h:70
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1276
FLOWINT_TARGET_SELF
@ FLOWINT_TARGET_SELF
Definition: detect-flowint.h:52
FlowVarTypeInt_::value
uint32_t value
Definition: flow-var.h:44
FLOWINT_MODIFIER_GT
@ FLOWINT_MODIFIER_GT
Definition: detect-flowint.h:40
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:2150
UTHFreeFlow
void UTHFreeFlow(Flow *flow)
Definition: util-unittest-helper.c:487
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:345
FLOWINT_MODIFIER_LT
@ FLOWINT_MODIFIER_LT
Definition: detect-flowint.h:35
DetectFlowintData_::target
union DetectFlowintData_::@68 target
Packet_::flow
struct Flow_ * flow
Definition: decode.h:521
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:3299
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
FLOWINT_TARGET_VAR
@ FLOWINT_TARGET_VAR
Definition: detect-flowint.h:51
DetectFlowintMatch
int DetectFlowintMatch(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
This function is used to create a flowint, add/substract values, compare it with other flowints,...
Definition: detect-flowint.c:92
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3513
FLOWINT_MODIFIER_SET
@ FLOWINT_MODIFIER_SET
Definition: detect-flowint.h:30
FLOWINT_MODIFIER_ISSET
@ FLOWINT_MODIFIER_ISSET
Definition: detect-flowint.h:42
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:127
util-spm.h
DetectFlowintFree
void DetectFlowintFree(DetectEngineCtx *, void *)
This function is used to free the data of DetectFlowintData.
Definition: detect-flowint.c:418
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
detect-engine-sigorder.h
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
SCFree
#define SCFree(p)
Definition: util-mem.h:61
UTHFreePacket
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:467
detect-parse.h
Signature_
Signature container.
Definition: detect.h:602
FlowVarAddIntNoLock
void FlowVarAddIntNoLock(Flow *f, uint32_t idx, uint32_t value)
Definition: flow-var.c:135
DetectFlowintData_::tvar
TargetVar tvar
Definition: detect-flowint.h:77
VAR_TYPE_FLOW_INT
@ VAR_TYPE_FLOW_INT
Definition: util-var.h:36
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2549
DetectFlowintRegister
void DetectFlowintRegister(void)
Definition: detect-flowint.c:64
SigMatchAppendSMToList
SigMatch * SigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:436
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:850
FlowVarGet
FlowVar * FlowVarGet(Flow *f, uint32_t idx)
get the flowvar with index 'idx' from the flow
Definition: flow-var.c:78
TargetVar_::name
char * name
Definition: detect-flowint.h:57
UTHAppendSigs
int UTHAppendSigs(DetectEngineCtx *de_ctx, const char *sigs[], int numsigs)
UTHAppendSigs: Add sigs to the detection_engine checking for errors.
Definition: util-unittest-helper.c:638
FLOWINT_MODIFIER_EQ
@ FLOWINT_MODIFIER_EQ
Definition: detect-flowint.h:37
flow.h
PARSE_REGEX
#define PARSE_REGEX
Definition: detect-flowint.c:51
flow-var.h
FLOWINT_MODIFIER_SUB
@ FLOWINT_MODIFIER_SUB
Definition: detect-flowint.h:32
FlowVar_
Definition: flow-var.h:48
FlowVar_::datatype
uint8_t datatype
Definition: flow-var.h:50
DetectFlowintData_::name
char * name
Definition: detect-flowint.h:64
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1300
FLOWINT_MODIFIER_GE
@ FLOWINT_MODIFIER_GE
Definition: detect-flowint.h:39
DetectFlowintData_::value
uint32_t value
Definition: detect-flowint.h:75