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