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