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