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