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