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