suricata
detect-hostbits.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2010 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 Victor Julien <victor@inliniac.net>
22  *
23  * Implements the hostbits keyword
24  */
25 
26 #include "suricata-common.h"
27 #include "decode.h"
28 #include "detect.h"
29 #include "threads.h"
30 #include "flow.h"
31 #include "flow-util.h"
32 #include "detect-hostbits.h"
33 #include "util-spm.h"
34 
35 #include "detect-engine-sigorder.h"
36 
37 #include "app-layer-parser.h"
38 
39 #include "detect-parse.h"
40 #include "detect-engine.h"
41 #include "detect-engine-mpm.h"
42 #include "detect-engine-state.h"
43 
44 #include "flow-bit.h"
45 #include "host-bit.h"
46 #include "util-var-name.h"
47 #include "util-unittest.h"
48 #include "util-debug.h"
49 
50 /*
51  hostbits:isset,bitname;
52  hostbits:set,bitname;
53 
54  hostbits:set,bitname,src;
55  hostbits:set,bitname,dst;
56 TODO:
57  hostbits:set,bitname,both;
58 
59  hostbits:set,bitname,src,3600;
60  hostbits:set,bitname,dst,60;
61  hostbits:set,bitname,both,120;
62  */
63 
64 #define PARSE_REGEX "^([a-z]+)" /* Action */ \
65  "(?:\\s*,\\s*([^\\s,]+))?(?:\\s*)?" /* Name. */ \
66  "(?:\\s*,\\s*([^,\\s]+))?(?:\\s*)?" /* Direction. */ \
67  "(.+)?" /* Any remainding data. */
68 static pcre *parse_regex;
69 static pcre_extra *parse_regex_study;
70 
71 static int DetectHostbitMatch (DetectEngineThreadCtx *, Packet *,
72  const Signature *, const SigMatchCtx *);
73 static int DetectHostbitSetup (DetectEngineCtx *, Signature *, const char *);
74 void DetectHostbitFree (void *);
75 void HostBitsRegisterTests(void);
76 
78 {
79  sigmatch_table[DETECT_HOSTBITS].name = "hostbits";
80  sigmatch_table[DETECT_HOSTBITS].desc = "operate on host flag";
81 // sigmatch_table[DETECT_HOSTBITS].url = DOC_URL DOC_VERSION "/rules/flow-keywords.html#flowbits";
82  sigmatch_table[DETECT_HOSTBITS].Match = DetectHostbitMatch;
83  sigmatch_table[DETECT_HOSTBITS].Setup = DetectHostbitSetup;
86  /* this is compatible to ip-only signatures */
88 
89  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex, &parse_regex_study);
90 }
91 
92 static int DetectHostbitMatchToggle (Packet *p, const DetectXbitsData *fd)
93 {
94  switch (fd->tracker) {
96  if (p->host_src == NULL) {
98  if (p->host_src == NULL)
99  return 0;
100  }
101  else
102  HostLock(p->host_src);
103 
104  HostBitToggle(p->host_src,fd->idx,p->ts.tv_sec + fd->expire);
105  HostUnlock(p->host_src);
106  break;
108  if (p->host_dst == NULL) {
109  p->host_dst = HostGetHostFromHash(&p->dst);
110  if (p->host_dst == NULL)
111  return 0;
112  }
113  else
114  HostLock(p->host_dst);
115 
116  HostBitToggle(p->host_dst,fd->idx,p->ts.tv_sec + fd->expire);
117  HostUnlock(p->host_dst);
118  break;
119  }
120  return 1;
121 }
122 
123 /* return true even if bit not found */
124 static int DetectHostbitMatchUnset (Packet *p, const DetectXbitsData *fd)
125 {
126  switch (fd->tracker) {
128  if (p->host_src == NULL) {
130  if (p->host_src == NULL)
131  return 1;
132  } else
133  HostLock(p->host_src);
134 
135  HostBitUnset(p->host_src,fd->idx);
136  HostUnlock(p->host_src);
137  break;
139  if (p->host_dst == NULL) {
141  if (p->host_dst == NULL)
142  return 1;
143  } else
144  HostLock(p->host_dst);
145 
146  HostBitUnset(p->host_dst,fd->idx);
147  HostUnlock(p->host_dst);
148  break;
149  }
150  return 1;
151 }
152 
153 static int DetectHostbitMatchSet (Packet *p, const DetectXbitsData *fd)
154 {
155  switch (fd->tracker) {
157  if (p->host_src == NULL) {
158  p->host_src = HostGetHostFromHash(&p->src);
159  if (p->host_src == NULL)
160  return 0;
161  } else
162  HostLock(p->host_src);
163 
164  HostBitSet(p->host_src,fd->idx,p->ts.tv_sec + fd->expire);
165  HostUnlock(p->host_src);
166  break;
168  if (p->host_dst == NULL) {
169  p->host_dst = HostGetHostFromHash(&p->dst);
170  if (p->host_dst == NULL)
171  return 0;
172  } else
173  HostLock(p->host_dst);
174 
175  HostBitSet(p->host_dst,fd->idx, p->ts.tv_sec + fd->expire);
176  HostUnlock(p->host_dst);
177  break;
178  }
179  return 1;
180 }
181 
182 static int DetectHostbitMatchIsset (Packet *p, const DetectXbitsData *fd)
183 {
184  int r = 0;
185  switch (fd->tracker) {
187  if (p->host_src == NULL) {
189  if (p->host_src == NULL)
190  return 0;
191  } else
192  HostLock(p->host_src);
193 
194  r = HostBitIsset(p->host_src,fd->idx, p->ts.tv_sec);
195  HostUnlock(p->host_src);
196  return r;
198  if (p->host_dst == NULL) {
200  if (p->host_dst == NULL)
201  return 0;
202  } else
203  HostLock(p->host_dst);
204 
205  r = HostBitIsset(p->host_dst,fd->idx, p->ts.tv_sec);
206  HostUnlock(p->host_dst);
207  return r;
208  }
209  return 0;
210 }
211 
212 static int DetectHostbitMatchIsnotset (Packet *p, const DetectXbitsData *fd)
213 {
214  int r = 0;
215  switch (fd->tracker) {
217  if (p->host_src == NULL) {
219  if (p->host_src == NULL)
220  return 1;
221  } else
222  HostLock(p->host_src);
223 
224  r = HostBitIsnotset(p->host_src,fd->idx, p->ts.tv_sec);
225  HostUnlock(p->host_src);
226  return r;
228  if (p->host_dst == NULL) {
230  if (p->host_dst == NULL)
231  return 1;
232  } else
233  HostLock(p->host_dst);
234 
235  r = HostBitIsnotset(p->host_dst,fd->idx, p->ts.tv_sec);
236  HostUnlock(p->host_dst);
237  return r;
238  }
239  return 0;
240 }
241 
243 {
244  switch (xd->cmd) {
246  return DetectHostbitMatchIsset(p,xd);
248  return DetectHostbitMatchIsnotset(p,xd);
250  return DetectHostbitMatchSet(p,xd);
252  return DetectHostbitMatchUnset(p,xd);
254  return DetectHostbitMatchToggle(p,xd);
255  default:
256  SCLogError(SC_ERR_UNKNOWN_VALUE, "unknown cmd %" PRIu32 "", xd->cmd);
257  return 0;
258  }
259 
260  return 0;
261 }
262 
263 /*
264  * returns 0: no match
265  * 1: match
266  * -1: error
267  */
268 
269 static int DetectHostbitMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
270  const Signature *s, const SigMatchCtx *ctx)
271 {
272  const DetectXbitsData *xd = (const DetectXbitsData *)ctx;
273  if (xd == NULL)
274  return 0;
275 
276  return DetectXbitMatchHost(p, xd);
277 }
278 
279 static int DetectHostbitParse(const char *str, char *cmd, int cmd_len,
280  char *name, int name_len, char *dir, int dir_len)
281 {
282  const int max_substrings = 30;
283  int count, rc;
284  int ov[max_substrings];
285 
286  count = pcre_exec(parse_regex, parse_regex_study, str, strlen(str), 0, 0,
287  ov, max_substrings);
288  if (count != 2 && count != 3 && count != 4) {
290  "\"%s\" is not a valid setting for hostbits.", str);
291  return 0;
292  }
293 
294  rc = pcre_copy_substring((char *)str, ov, max_substrings, 1, cmd, cmd_len);
295  if (rc < 0) {
296  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
297  return 0;
298  }
299 
300  if (count >= 3) {
301  rc = pcre_copy_substring((char *)str, ov, max_substrings, 2, name,
302  name_len);
303  if (rc < 0) {
304  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_copy_substring failed");
305  return 0;
306  }
307  if (count >= 4) {
308  rc = pcre_copy_substring((char *)str, ov, max_substrings, 3, dir,
309  dir_len);
310  if (rc < 0) {
312  "pcre_copy_substring failed");
313  return 0;
314  }
315  }
316  }
317 
318  return 1;
319 }
320 
321 int DetectHostbitSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
322 {
323  DetectXbitsData *cd = NULL;
324  SigMatch *sm = NULL;
325  uint8_t fb_cmd = 0;
326  uint8_t hb_dir = 0;
327  char fb_cmd_str[16] = "", fb_name[256] = "";
328  char hb_dir_str[16] = "";
329 
330  if (!DetectHostbitParse(rawstr, fb_cmd_str, sizeof(fb_cmd_str),
331  fb_name, sizeof(fb_name), hb_dir_str, sizeof(hb_dir_str))) {
332  return -1;
333  }
334 
335  if (strlen(hb_dir_str) > 0) {
336  if (strcmp(hb_dir_str, "src") == 0)
337  hb_dir = DETECT_XBITS_TRACK_IPSRC;
338  else if (strcmp(hb_dir_str, "dst") == 0)
339  hb_dir = DETECT_XBITS_TRACK_IPDST;
340  else if (strcmp(hb_dir_str, "both") == 0) {
341  //hb_dir = DETECT_XBITS_TRACK_IPBOTH;
342  SCLogError(SC_ERR_UNIMPLEMENTED, "'both' not implemented");
343  goto error;
344  } else {
345  // TODO
346  goto error;
347  }
348  }
349 
350  if (strcmp(fb_cmd_str,"noalert") == 0) {
351  fb_cmd = DETECT_XBITS_CMD_NOALERT;
352  } else if (strcmp(fb_cmd_str,"isset") == 0) {
353  fb_cmd = DETECT_XBITS_CMD_ISSET;
354  } else if (strcmp(fb_cmd_str,"isnotset") == 0) {
355  fb_cmd = DETECT_XBITS_CMD_ISNOTSET;
356  } else if (strcmp(fb_cmd_str,"set") == 0) {
357  fb_cmd = DETECT_XBITS_CMD_SET;
358  } else if (strcmp(fb_cmd_str,"unset") == 0) {
359  fb_cmd = DETECT_XBITS_CMD_UNSET;
360  } else if (strcmp(fb_cmd_str,"toggle") == 0) {
361  fb_cmd = DETECT_XBITS_CMD_TOGGLE;
362  } else {
363  SCLogError(SC_ERR_UNKNOWN_VALUE, "ERROR: flowbits action \"%s\" is not supported.", fb_cmd_str);
364  goto error;
365  }
366 
367  switch (fb_cmd) {
369  if (strlen(fb_name) != 0)
370  goto error;
371  s->flags |= SIG_FLAG_NOALERT;
372  return 0;
378  default:
379  if (strlen(fb_name) == 0)
380  goto error;
381  break;
382  }
383 
384  cd = SCMalloc(sizeof(DetectXbitsData));
385  if (unlikely(cd == NULL))
386  goto error;
387 
389  cd->cmd = fb_cmd;
390  cd->tracker = hb_dir;
391  cd->type = VAR_TYPE_HOST_BIT;
392  cd->expire = 300;
393 
394  SCLogDebug("idx %" PRIu32 ", cmd %s, name %s",
395  cd->idx, fb_cmd_str, strlen(fb_name) ? fb_name : "(none)");
396 
397  /* Okay so far so good, lets get this into a SigMatch
398  * and put it in the Signature. */
399  sm = SigMatchAlloc();
400  if (sm == NULL)
401  goto error;
402 
403  sm->type = DETECT_HOSTBITS;
404  sm->ctx = (void *)cd;
405 
406  switch (fb_cmd) {
407  /* case DETECT_XBITS_CMD_NOALERT can't happen here */
408 
411  /* checks, so packet list */
413  break;
414 
418  /* modifiers, only run when entire sig has matched */
420  break;
421 
422  // suppress coverity warning as scan-build-7 warns w/o this.
423  // coverity[deadcode : FALSE]
424  default:
425  goto error;
426  }
427 
428  return 0;
429 
430 error:
431  if (cd != NULL)
432  SCFree(cd);
433  if (sm != NULL)
434  SCFree(sm);
435  return -1;
436 }
437 
438 void DetectHostbitFree (void *ptr)
439 {
440  DetectXbitsData *fd = (DetectXbitsData *)ptr;
441 
442  if (fd == NULL)
443  return;
444 
445  SCFree(fd);
446 }
447 
448 #ifdef UNITTESTS
449 
450 static void HostBitsTestSetup(void)
451 {
452  StorageInit();
453  HostBitInitCtx();
454  StorageFinalize();
456 }
457 
458 static void HostBitsTestShutdown(void)
459 {
460  HostCleanup();
461  StorageCleanup();
462 }
463 
464 static int HostBitsTestParse01(void)
465 {
466  char cmd[16] = "", name[256] = "", dir[16] = "";
467 
468  /* No direction. */
469  FAIL_IF(!DetectHostbitParse("isset,name", cmd, sizeof(cmd), name,
470  sizeof(name), dir, sizeof(dir)));
471  FAIL_IF(strcmp(cmd, "isset") != 0);
472  FAIL_IF(strcmp(name, "name") != 0);
473  FAIL_IF(strlen(dir));
474 
475  /* No direction, leading space. */
476  *cmd = '\0';
477  *name = '\0';
478  *dir = '\0';
479  FAIL_IF(!DetectHostbitParse("isset, name", cmd, sizeof(cmd), name,
480  sizeof(name), dir, sizeof(dir)));
481  FAIL_IF(strcmp(cmd, "isset") != 0);
482  FAIL_IF(strcmp(name, "name") != 0);
483 
484  /* No direction, trailing space. */
485  *cmd = '\0';
486  *name = '\0';
487  *dir = '\0';
488  FAIL_IF(!DetectHostbitParse("isset,name ", cmd, sizeof(cmd), name,
489  sizeof(name), dir, sizeof(dir)));
490  FAIL_IF(strcmp(cmd, "isset") != 0);
491  FAIL_IF(strcmp(name, "name") != 0);
492 
493  /* No direction, leading and trailing space. */
494  *cmd = '\0';
495  *name = '\0';
496  *dir = '\0';
497  FAIL_IF(!DetectHostbitParse("isset, name ", cmd, sizeof(cmd), name,
498  sizeof(name), dir, sizeof(dir)));
499  FAIL_IF(strcmp(cmd, "isset") != 0);
500  FAIL_IF(strcmp(name, "name") != 0);
501 
502  /* With direction. */
503  *cmd = '\0';
504  *name = '\0';
505  *dir = '\0';
506  FAIL_IF(!DetectHostbitParse("isset,name,src", cmd, sizeof(cmd), name,
507  sizeof(name), dir, sizeof(dir)));
508  FAIL_IF(strcmp(cmd, "isset") != 0);
509  FAIL_IF(strcmp(name, "name") != 0);
510  FAIL_IF(strcmp(dir, "src") != 0);
511 
512  /* With direction - leading and trailing spaces on name. */
513  *cmd = '\0';
514  *name = '\0';
515  *dir = '\0';
516  FAIL_IF(!DetectHostbitParse("isset, name ,src", cmd, sizeof(cmd), name,
517  sizeof(name), dir, sizeof(dir)));
518  FAIL_IF(strcmp(cmd, "isset") != 0);
519  FAIL_IF(strcmp(name, "name") != 0);
520  FAIL_IF(strcmp(dir, "src") != 0);
521 
522  /* With direction - space around direction. */
523  *cmd = '\0';
524  *name = '\0';
525  *dir = '\0';
526  FAIL_IF(!DetectHostbitParse("isset, name , src ", cmd, sizeof(cmd), name,
527  sizeof(name), dir, sizeof(dir)));
528  FAIL_IF(strcmp(cmd, "isset") != 0);
529  FAIL_IF(strcmp(name, "name") != 0);
530  FAIL_IF(strcmp(dir, "src") != 0);
531 
532  /* Name with space, no direction - should fail. */
533  *cmd = '\0';
534  *name = '\0';
535  *dir = '\0';
536  FAIL_IF(DetectHostbitParse("isset, name withspace ", cmd, sizeof(cmd), name,
537  sizeof(name), dir, sizeof(dir)));
538 
539  PASS;
540 }
541 
542 /**
543  * \test HostBitsTestSig01 is a test for a valid noalert flowbits option
544  *
545  * \retval 1 on succces
546  * \retval 0 on failure
547  */
548 
549 static int HostBitsTestSig01(void)
550 {
551  uint8_t *buf = (uint8_t *)
552  "GET /one/ HTTP/1.1\r\n"
553  "Host: one.example.org\r\n"
554  "\r\n";
555  uint16_t buflen = strlen((char *)buf);
557  FAIL_IF_NULL(p);
558  Signature *s = NULL;
559  ThreadVars th_v;
560  DetectEngineThreadCtx *det_ctx = NULL;
561  DetectEngineCtx *de_ctx = NULL;
562 
563  memset(&th_v, 0, sizeof(th_v));
564  memset(p, 0, SIZE_OF_PACKET);
565  p->src.family = AF_INET;
566  p->dst.family = AF_INET;
567  p->payload = buf;
568  p->payload_len = buflen;
569  p->proto = IPPROTO_TCP;
570 
571  HostBitsTestSetup();
572 
573  de_ctx = DetectEngineCtxInit();
574  FAIL_IF_NULL(de_ctx);
575 
576  de_ctx->flags |= DE_QUIET;
577 
578  s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (hostbits:set,abc; content:\"GET \"; sid:1;)");
579  FAIL_IF_NULL(s);
580 
581  SigGroupBuild(de_ctx);
582  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
583 
584  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
585 
586  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
587  DetectEngineCtxFree(de_ctx);
588  HostBitsTestShutdown();
589 
590  SCFree(p);
591  PASS;
592 }
593 
594 /**
595  * \test various options
596  *
597  * \retval 1 on succces
598  * \retval 0 on failure
599  */
600 
601 static int HostBitsTestSig02(void)
602 {
603  Signature *s = NULL;
604  ThreadVars th_v;
605  DetectEngineCtx *de_ctx = NULL;
606 
607  memset(&th_v, 0, sizeof(th_v));
608 
609  de_ctx = DetectEngineCtxInit();
610  FAIL_IF_NULL(de_ctx);
611 
612  de_ctx->flags |= DE_QUIET;
613 
614  s = DetectEngineAppendSig(de_ctx,
615  "alert ip any any -> any any (hostbits:isset,abc,src; content:\"GET \"; sid:1;)");
616  FAIL_IF_NULL(s);
617 
618  s = DetectEngineAppendSig(de_ctx,
619  "alert ip any any -> any any (hostbits:isnotset,abc,dst; content:\"GET \"; sid:2;)");
620  FAIL_IF_NULL(s);
621 
622  s = DetectEngineAppendSig(de_ctx,
623  "alert ip any any -> any any (hostbits:!isset,abc,dst; content:\"GET \"; sid:3;)");
624  FAIL_IF_NOT_NULL(s);
625 
626 /* TODO reenable after both is supported
627  s = DetectEngineAppendSig(de_ctx,
628  "alert ip any any -> any any (hostbits:set,abc,both; content:\"GET \"; sid:3;)");
629  FAIL_IF_NULL(s);
630 */
631  s = DetectEngineAppendSig(de_ctx,
632  "alert ip any any -> any any (hostbits:unset,abc,src; content:\"GET \"; sid:4;)");
633  FAIL_IF_NULL(s);
634 
635  s = DetectEngineAppendSig(de_ctx,
636  "alert ip any any -> any any (hostbits:toggle,abc,dst; content:\"GET \"; sid:5;)");
637  FAIL_IF_NULL(s);
638 
639  DetectEngineCtxFree(de_ctx);
640  PASS;
641 }
642 
643 #if 0
644 /**
645  * \test HostBitsTestSig03 is a test for a invalid flowbits option
646  *
647  * \retval 1 on succces
648  * \retval 0 on failure
649  */
650 
651 static int HostBitsTestSig03(void)
652 {
653  uint8_t *buf = (uint8_t *)
654  "GET /one/ HTTP/1.1\r\n"
655  "Host: one.example.org\r\n"
656  "\r\n";
657  uint16_t buflen = strlen((char *)buf);
659  if (unlikely(p == NULL))
660  return 0;
661  Signature *s = NULL;
662  ThreadVars th_v;
663  DetectEngineThreadCtx *det_ctx = NULL;
664  DetectEngineCtx *de_ctx = NULL;
665  int result = 0;
666 
667  memset(&th_v, 0, sizeof(th_v));
668  memset(p, 0, SIZE_OF_PACKET);
669  p->src.family = AF_INET;
670  p->dst.family = AF_INET;
671  p->payload = buf;
672  p->payload_len = buflen;
673  p->proto = IPPROTO_TCP;
674 
675  de_ctx = DetectEngineCtxInit();
676 
677  if (de_ctx == NULL) {
678  goto end;
679  }
680 
681  de_ctx->flags |= DE_QUIET;
682 
683  s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Unknown cmd\"; flowbits:wrongcmd; content:\"GET \"; sid:1;)");
684 
685  if (s == NULL) {
686  goto end;
687  }
688 
689  SigGroupBuild(de_ctx);
690  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
691 
692  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
693 
694  result = 1;
695 
696  SigGroupCleanup(de_ctx);
697  SigCleanSignatures(de_ctx);
698 
699  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
700  DetectEngineCtxFree(de_ctx);
701 
702 end:
703 
704  if (de_ctx != NULL) {
705  SigGroupCleanup(de_ctx);
706  SigCleanSignatures(de_ctx);
707  }
708 
709  if (det_ctx != NULL) {
710  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
711  }
712 
713  if (de_ctx != NULL) {
714  DetectEngineCtxFree(de_ctx);
715  }
716 
717 
718  SCFree(p);
719  return result;
720 }
721 #endif
722 
723 /**
724  * \test HostBitsTestSig04 is a test check idx value
725  *
726  * \retval 1 on succces
727  * \retval 0 on failure
728  */
729 
730 static int HostBitsTestSig04(void)
731 {
732  uint8_t *buf = (uint8_t *)
733  "GET /one/ HTTP/1.1\r\n"
734  "Host: one.example.org\r\n"
735  "\r\n";
736  uint16_t buflen = strlen((char *)buf);
738  if (unlikely(p == NULL))
739  return 0;
740  Signature *s = NULL;
741  ThreadVars th_v;
742  DetectEngineThreadCtx *det_ctx = NULL;
743  DetectEngineCtx *de_ctx = NULL;
744  int idx = 0;
745 
746  memset(&th_v, 0, sizeof(th_v));
747  memset(p, 0, SIZE_OF_PACKET);
748  p->src.family = AF_INET;
749  p->dst.family = AF_INET;
750  p->payload = buf;
751  p->payload_len = buflen;
752  p->proto = IPPROTO_TCP;
753 
754  HostBitsTestSetup();
755 
756  de_ctx = DetectEngineCtxInit();
757  FAIL_IF_NULL(de_ctx);
758 
759  de_ctx->flags |= DE_QUIET;
760 
761  s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"isset option\"; hostbits:isset,fbt; content:\"GET \"; sid:1;)");
762  FAIL_IF_NULL(s);
763 
765  FAIL_IF(idx != 1);
766 
767  SigGroupBuild(de_ctx);
768  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
769 
770  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
771 
772  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
773  DetectEngineCtxFree(de_ctx);
774  HostBitsTestShutdown();
775 
776  SCFree(p);
777  PASS;
778 }
779 
780 /**
781  * \test HostBitsTestSig05 is a test check noalert flag
782  *
783  * \retval 1 on succces
784  * \retval 0 on failure
785  */
786 
787 static int HostBitsTestSig05(void)
788 {
789  uint8_t *buf = (uint8_t *)
790  "GET /one/ HTTP/1.1\r\n"
791  "Host: one.example.org\r\n"
792  "\r\n";
793  uint16_t buflen = strlen((char *)buf);
795  if (unlikely(p == NULL))
796  return 0;
797  Signature *s = NULL;
798  ThreadVars th_v;
799  DetectEngineThreadCtx *det_ctx = NULL;
800  DetectEngineCtx *de_ctx = NULL;
801 
802  memset(&th_v, 0, sizeof(th_v));
803  memset(p, 0, SIZE_OF_PACKET);
804  p->src.family = AF_INET;
805  p->dst.family = AF_INET;
806  p->payload = buf;
807  p->payload_len = buflen;
808  p->proto = IPPROTO_TCP;
809 
810  HostBitsTestSetup();
811 
812  de_ctx = DetectEngineCtxInit();
813  FAIL_IF_NULL(de_ctx);
814 
815  de_ctx->flags |= DE_QUIET;
816 
817  s = de_ctx->sig_list = SigInit(de_ctx,
818  "alert ip any any -> any any (hostbits:noalert; content:\"GET \"; sid:1;)");
819  FAIL_IF_NULL(s);
821 
822  SigGroupBuild(de_ctx);
823  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
824 
825  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
826 
827  FAIL_IF(PacketAlertCheck(p, 1));
828 
829  SigGroupCleanup(de_ctx);
830  SigCleanSignatures(de_ctx);
831 
832  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
833  DetectEngineCtxFree(de_ctx);
834 
835  HostBitsTestShutdown();
836 
837  SCFree(p);
838  PASS;
839 }
840 
841 #if 0
842 /**
843  * \test HostBitsTestSig06 is a test set flowbits option
844  *
845  * \retval 1 on succces
846  * \retval 0 on failure
847  */
848 
849 static int HostBitsTestSig06(void)
850 {
851  uint8_t *buf = (uint8_t *)
852  "GET /one/ HTTP/1.1\r\n"
853  "Host: one.example.org\r\n"
854  "\r\n";
855  uint16_t buflen = strlen((char *)buf);
857  if (unlikely(p == NULL))
858  return 0;
859  Signature *s = NULL;
860  ThreadVars th_v;
861  DetectEngineThreadCtx *det_ctx = NULL;
862  DetectEngineCtx *de_ctx = NULL;
863  Flow f;
864  GenericVar flowvar, *gv = NULL;
865  int result = 0;
866  int idx = 0;
867 
868  memset(p, 0, SIZE_OF_PACKET);
869  memset(&th_v, 0, sizeof(th_v));
870  memset(&f, 0, sizeof(Flow));
871  memset(&flowvar, 0, sizeof(GenericVar));
872 
873  FLOW_INITIALIZE(&f);
874  p->flow = &f;
875  p->flow->flowvar = &flowvar;
876 
877  p->src.family = AF_INET;
878  p->dst.family = AF_INET;
879  p->payload = buf;
880  p->payload_len = buflen;
881  p->proto = IPPROTO_TCP;
882  p->flags |= PKT_HAS_FLOW;
884 
885  de_ctx = DetectEngineCtxInit();
886 
887  if (de_ctx == NULL) {
888  goto end;
889  }
890 
891  de_ctx->flags |= DE_QUIET;
892 
893  s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Flowbit set\"; flowbits:set,myflow; sid:10;)");
894 
895  if (s == NULL) {
896  goto end;
897  }
898 
899  SigGroupBuild(de_ctx);
900  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
901 
902  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
903 
904  idx = VariableNameGetIdx(de_ctx, "myflow", VAR_TYPE_HOST_BIT);
905 
906  gv = p->flow->flowvar;
907 
908  for ( ; gv != NULL; gv = gv->next) {
909  if (gv->type == DETECT_HOSTBITS && gv->idx == idx) {
910  result = 1;
911  }
912  }
913 
914  SigGroupCleanup(de_ctx);
915  SigCleanSignatures(de_ctx);
916 
917  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
918  DetectEngineCtxFree(de_ctx);
919 
920  if(gv) GenericVarFree(gv);
921  FLOW_DESTROY(&f);
922 
923  SCFree(p);
924  return result;
925 end:
926 
927  if (de_ctx != NULL) {
928  SigGroupCleanup(de_ctx);
929  SigCleanSignatures(de_ctx);
930  }
931 
932  if (det_ctx != NULL) {
933  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
934  }
935 
936  if (de_ctx != NULL) {
937  DetectEngineCtxFree(de_ctx);
938  }
939 
940  if(gv) GenericVarFree(gv);
941  FLOW_DESTROY(&f);
942  SCFree(p);
943  return result;
944 }
945 
946 /**
947  * \test HostBitsTestSig07 is a test unset flowbits option
948  *
949  * \retval 1 on succces
950  * \retval 0 on failure
951  */
952 
953 static int HostBitsTestSig07(void)
954 {
955  uint8_t *buf = (uint8_t *)
956  "GET /one/ HTTP/1.1\r\n"
957  "Host: one.example.org\r\n"
958  "\r\n";
959  uint16_t buflen = strlen((char *)buf);
961  if (unlikely(p == NULL))
962  return 0;
963  Signature *s = NULL;
964  ThreadVars th_v;
965  DetectEngineThreadCtx *det_ctx = NULL;
966  DetectEngineCtx *de_ctx = NULL;
967  Flow f;
968  GenericVar flowvar, *gv = NULL;
969  int result = 0;
970  int idx = 0;
971 
972  memset(p, 0, SIZE_OF_PACKET);
973  memset(&th_v, 0, sizeof(th_v));
974  memset(&f, 0, sizeof(Flow));
975  memset(&flowvar, 0, sizeof(GenericVar));
976 
977  FLOW_INITIALIZE(&f);
978  p->flow = &f;
979  p->flow->flowvar = &flowvar;
980 
981  p->src.family = AF_INET;
982  p->dst.family = AF_INET;
983  p->payload = buf;
984  p->payload_len = buflen;
985  p->proto = IPPROTO_TCP;
986 
987  de_ctx = DetectEngineCtxInit();
988 
989  if (de_ctx == NULL) {
990  goto end;
991  }
992 
993  de_ctx->flags |= DE_QUIET;
994 
995  s = de_ctx->sig_list = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Flowbit set\"; flowbits:set,myflow2; sid:10;)");
996  if (s == NULL) {
997  goto end;
998  }
999 
1000  s = s->next = SigInit(de_ctx,"alert ip any any -> any any (msg:\"Flowbit unset\"; flowbits:unset,myflow2; sid:11;)");
1001  if (s == NULL) {
1002  goto end;
1003  }
1004 
1005  SigGroupBuild(de_ctx);
1006  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1007 
1008  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1009 
1010  idx = VariableNameGetIdx(de_ctx, "myflow", VAR_TYPE_HOST_BIT);
1011 
1012  gv = p->flow->flowvar;
1013 
1014  for ( ; gv != NULL; gv = gv->next) {
1015  if (gv->type == DETECT_HOSTBITS && gv->idx == idx) {
1016  result = 1;
1017  }
1018  }
1019 
1020  SigGroupCleanup(de_ctx);
1021  SigCleanSignatures(de_ctx);
1022 
1023  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1024  DetectEngineCtxFree(de_ctx);
1025 
1026  if(gv) GenericVarFree(gv);
1027  FLOW_DESTROY(&f);
1028 
1029  SCFree(p);
1030  return result;
1031 end:
1032 
1033  if (de_ctx != NULL) {
1034  SigGroupCleanup(de_ctx);
1035  SigCleanSignatures(de_ctx);
1036  }
1037 
1038  if (det_ctx != NULL) {
1039  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1040  }
1041 
1042  if (de_ctx != NULL) {
1043  DetectEngineCtxFree(de_ctx);
1044  }
1045 
1046  if(gv) GenericVarFree(gv);
1047  FLOW_DESTROY(&f);
1048 
1049  SCFree(p);
1050  return result;}
1051 #endif
1052 
1053 /**
1054  * \test set / isset
1055  *
1056  * \retval 1 on succces
1057  * \retval 0 on failure
1058  */
1059 static int HostBitsTestSig07(void)
1060 {
1061  uint8_t *buf = (uint8_t *)
1062  "GET /one/ HTTP/1.1\r\n"
1063  "Host: one.example.org\r\n"
1064  "\r\n";
1065  uint16_t buflen = strlen((char *)buf);
1067  if (unlikely(p == NULL))
1068  return 0;
1069  Signature *s = NULL;
1070  ThreadVars th_v;
1071  DetectEngineThreadCtx *det_ctx = NULL;
1072  DetectEngineCtx *de_ctx = NULL;
1073  Flow f;
1074  int result = 0;
1075 
1076  memset(p, 0, SIZE_OF_PACKET);
1077  memset(&th_v, 0, sizeof(th_v));
1078  memset(&f, 0, sizeof(Flow));
1079 
1080  HostBitsTestSetup();
1081 
1082  FLOW_INITIALIZE(&f);
1083  p->flow = &f;
1085 
1086  p->src.family = AF_INET;
1087  p->dst.family = AF_INET;
1088  p->payload = buf;
1089  p->payload_len = buflen;
1090  p->proto = IPPROTO_TCP;
1091 
1092  de_ctx = DetectEngineCtxInit();
1093  FAIL_IF_NULL(de_ctx);
1094 
1095  de_ctx->flags |= DE_QUIET;
1096 
1097  s = de_ctx->sig_list = SigInit(de_ctx,
1098  "alert ip any any -> any any (hostbits:set,myflow2; sid:10;)");
1099  FAIL_IF_NULL(s);
1100 
1101  s = s->next = SigInit(de_ctx,
1102  "alert ip any any -> any any (hostbits:isset,myflow2; sid:11;)");
1103  FAIL_IF_NULL(s);
1104 
1105  SigGroupBuild(de_ctx);
1106  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1107 
1108  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1109 
1110  SCLogInfo("p->host_src %p", p->host_src);
1111 
1112  if (HostHasHostBits(p->host_src) == 1) {
1113  if (PacketAlertCheck(p, 11)) {
1114  result = 1;
1115  }
1116  }
1117  FAIL_IF_NOT(result);
1118 
1119  SigGroupCleanup(de_ctx);
1120  SigCleanSignatures(de_ctx);
1121 
1122  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1123  DetectEngineCtxFree(de_ctx);
1124 
1125  FLOW_DESTROY(&f);
1126 
1127  HostBitsTestShutdown();
1128  SCFree(p);
1129  PASS;
1130 }
1131 
1132 /**
1133  * \test set / toggle / toggle / isset
1134  *
1135  * \retval 1 on succces
1136  * \retval 0 on failure
1137  */
1138 static int HostBitsTestSig08(void)
1139 {
1140  uint8_t *buf = (uint8_t *)
1141  "GET /one/ HTTP/1.1\r\n"
1142  "Host: one.example.org\r\n"
1143  "\r\n";
1144  uint16_t buflen = strlen((char *)buf);
1146  if (unlikely(p == NULL))
1147  return 0;
1148  Signature *s = NULL;
1149  ThreadVars th_v;
1150  DetectEngineThreadCtx *det_ctx = NULL;
1151  DetectEngineCtx *de_ctx = NULL;
1152  Flow f;
1153 
1154  memset(p, 0, SIZE_OF_PACKET);
1155  memset(&th_v, 0, sizeof(th_v));
1156  memset(&f, 0, sizeof(Flow));
1157 
1158  HostBitsTestSetup();
1159 
1160  FLOW_INITIALIZE(&f);
1161  p->flow = &f;
1162 
1163  p->src.family = AF_INET;
1164  p->dst.family = AF_INET;
1165  p->payload = buf;
1166  p->payload_len = buflen;
1167  p->proto = IPPROTO_TCP;
1168 
1169  de_ctx = DetectEngineCtxInit();
1170  FAIL_IF_NULL(de_ctx);
1171 
1172  de_ctx->flags |= DE_QUIET;
1173 
1174  s = DetectEngineAppendSig(de_ctx,
1175  "alert ip any any -> any any (hostbits:set,myflow2; sid:10;)");
1176  FAIL_IF_NULL(s);
1177  s = DetectEngineAppendSig(de_ctx,
1178  "alert ip any any -> any any (hostbits:toggle,myflow2; sid:11;)");
1179  FAIL_IF_NULL(s);
1180  s = DetectEngineAppendSig(de_ctx,
1181  "alert ip any any -> any any (hostbits:toggle,myflow2; sid:12;)");
1182  FAIL_IF_NULL(s);
1183  s = DetectEngineAppendSig(de_ctx,
1184  "alert ip any any -> any any (hostbits:isset,myflow2; sid:13;)");
1185  FAIL_IF_NULL(s);
1186 
1188  SCSigOrderSignatures(de_ctx);
1190 
1191  SigGroupBuild(de_ctx);
1192  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1193 
1194  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1195 
1196  SCLogInfo("p->host_src %p", p->host_src);
1197 
1198  if (HostHasHostBits(p->host_src) == 1) {
1199  if (PacketAlertCheck(p, 10)) {
1200  SCLogInfo("sid 10 matched");
1201  }
1202  if (PacketAlertCheck(p, 11)) {
1203  SCLogInfo("sid 11 matched");
1204  }
1205  if (PacketAlertCheck(p, 12)) {
1206  SCLogInfo("sid 12 matched");
1207  }
1208  if (PacketAlertCheck(p, 13)) {
1209  SCLogInfo("sid 13 matched");
1210  } else {
1211  FAIL;
1212  }
1213  }
1214 
1215  SigGroupCleanup(de_ctx);
1216  SigCleanSignatures(de_ctx);
1217 
1218  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1219  DetectEngineCtxFree(de_ctx);
1220 
1221  FLOW_DESTROY(&f);
1222 
1223  HostBitsTestShutdown();
1224 
1225  SCFree(p);
1226  PASS;
1227 }
1228 #endif /* UNITTESTS */
1229 
1230 /**
1231  * \brief this function registers unit tests for HostBits
1232  */
1234 {
1235 #ifdef UNITTESTS
1236  UtRegisterTest("HostBitsTestParse01", HostBitsTestParse01);
1237  UtRegisterTest("HostBitsTestSig01", HostBitsTestSig01);
1238  UtRegisterTest("HostBitsTestSig02", HostBitsTestSig02);
1239 #if 0
1240  UtRegisterTest("HostBitsTestSig03", HostBitsTestSig03, 0);
1241 #endif
1242  UtRegisterTest("HostBitsTestSig04", HostBitsTestSig04);
1243  UtRegisterTest("HostBitsTestSig05", HostBitsTestSig05);
1244 #if 0
1245  UtRegisterTest("HostBitsTestSig06", HostBitsTestSig06, 1);
1246 #endif
1247  UtRegisterTest("HostBitsTestSig07", HostBitsTestSig07);
1248  UtRegisterTest("HostBitsTestSig08", HostBitsTestSig08);
1249 #endif /* UNITTESTS */
1250 }
Signature * DetectEngineAppendSig(DetectEngineCtx *de_ctx, const char *sigstr)
Parse and append a Signature into the Detection Engine Context signature list.
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1448
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1186
uint8_t type
Definition: util-var.h:49
#define SCLogDebug(...)
Definition: util-debug.h:335
void HostCleanup(void)
Cleanup the host engine.
Definition: host.c:344
struct Flow_ * flow
Definition: decode.h:446
void HostBitInitCtx(void)
Definition: host-bit.c:49
int StorageFinalize(void)
Definition: util-storage.c:139
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
uint32_t flags
Definition: detect.h:523
#define PASS
Pass the test.
#define unlikely(expr)
Definition: util-optimize.h:35
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
int HostBitIsset(Host *h, uint32_t idx, uint32_t ts)
Definition: host-bit.c:158
int HostBitIsnotset(Host *h, uint32_t idx, uint32_t ts)
Definition: host-bit.c:171
Signature * sig_list
Definition: detect.h:767
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
Address dst
Definition: decode.h:414
void SigCleanSignatures(DetectEngineCtx *de_ctx)
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
const char * name
Definition: detect.h:1200
uint32_t idx
Definition: util-var.h:51
void HostBitToggle(Host *h, uint32_t idx, uint32_t expire)
Definition: host-bit.c:148
Signature container.
Definition: detect.h:522
int HostHasHostBits(Host *host)
Definition: host-bit.c:59
#define TRUE
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:313
int DetectXbitMatchHost(Packet *p, const DetectXbitsData *xd)
void HostBitSet(Host *h, uint32_t idx, uint32_t expire)
Definition: host-bit.c:132
void SCSigOrderSignatures(DetectEngineCtx *de_ctx)
Orders the signatures.
struct Host_ * host_src
Definition: decode.h:558
main detection engine ctx
Definition: detect.h:761
void HostInitConfig(char quiet)
initialize the configuration
Definition: host.c:168
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
#define DETECT_XBITS_TRACK_IPSRC
Definition: detect-xbits.h:35
void SCSigRegisterSignatureOrderingFuncs(DetectEngineCtx *de_ctx)
Lets you register the Signature ordering functions. The order in which the functions are registered...
#define DETECT_XBITS_CMD_ISSET
Definition: detect-xbits.h:31
#define DETECT_XBITS_CMD_UNSET
Definition: detect-xbits.h:29
struct GenericVar_ * next
Definition: util-var.h:52
enum VarTypes type
Definition: detect-xbits.h:48
#define DE_QUIET
Definition: detect.h:292
#define DETECT_XBITS_CMD_NOALERT
Definition: detect-xbits.h:32
#define SIZE_OF_PACKET
Definition: decode.h:619
#define str(s)
char family
Definition: decode.h:112
uint8_t proto
Definition: decode.h:431
uint8_t flags
Definition: detect.h:762
#define DETECT_XBITS_CMD_SET
Definition: detect-xbits.h:27
void DetectHostbitFree(void *)
Data structures and function prototypes for keeping state for the detection engine.
void(* Free)(void *)
Definition: detect.h:1191
#define PARSE_REGEX
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
#define FLOW_DESTROY(f)
Definition: flow-util.h:121
#define DETECT_XBITS_CMD_TOGGLE
Definition: detect-xbits.h:28
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1670
void DetectSetupParseRegexes(const char *parse_str, pcre **parse_regex, pcre_extra **parse_regex_study)
void SCSigSignatureOrderingModuleCleanup(DetectEngineCtx *de_ctx)
De-registers all the signature ordering functions registered.
struct Host_ * host_dst
Definition: decode.h:559
uint8_t flowflags
Definition: decode.h:440
#define FLOW_PKT_TOSERVER
Definition: flow.h:201
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1170
int SigGroupCleanup(DetectEngineCtx *de_ctx)
struct Signature_ * next
Definition: detect.h:594
uint8_t type
Definition: detect.h:319
Host * HostGetHostFromHash(Address *a)
Definition: host.c:500
void HostBitUnset(Host *h, uint32_t idx)
Definition: host-bit.c:140
GenericVar * flowvar
Definition: flow.h:448
const char * desc
Definition: detect.h:1202
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:346
#define FAIL
Definition: util-unittest.h:60
SigMatchCtx * ctx
Definition: detect.h:321
#define SCMalloc(a)
Definition: util-mem.h:222
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:254
#define SCFree(a)
Definition: util-mem.h:322
#define SIG_FLAG_NOALERT
Definition: detect.h:216
void StorageInit(void)
Definition: util-storage.c:67
void GenericVarFree(GenericVar *gv)
Definition: util-var.c:47
void StorageCleanup(void)
Definition: util-storage.c:75
void DetectHostbitsRegister(void)
uint32_t VarNameStoreSetupAdd(const char *name, const enum VarTypes type)
add to staging or return existing id if already in there
void HostUnlock(Host *h)
Definition: host.c:486
#define DETECT_XBITS_TRACK_IPDST
Definition: detect-xbits.h:36
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
void HostBitsRegisterTests(void)
this function registers unit tests for HostBits
#define PKT_HAS_FLOW
Definition: decode.h:1094
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
#define SIGMATCH_IPONLY_COMPAT
Definition: detect.h:1371
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:232
Per thread variable structure.
Definition: threadvars.h:57
struct timeval ts
Definition: decode.h:452
uint32_t flags
Definition: decode.h:444
Host * HostLookupHostFromHash(Address *a)
look up a host in the hash
Definition: host.c:599
uint16_t payload_len
Definition: decode.h:542
uint16_t flags
Definition: detect.h:1194
#define DETECT_XBITS_CMD_ISNOTSET
Definition: detect-xbits.h:30
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Flow data structure.
Definition: flow.h:325
uint8_t * payload
Definition: decode.h:541
void(* RegisterTests)(void)
Definition: detect.h:1192
a single match condition for a signature
Definition: detect.h:318
#define FAIL_IF_NOT(expr)
Fail a test if expression to true.
Definition: util-unittest.h:82
Address src
Definition: decode.h:413
void HostLock(Host *h)
Definition: host.c:481
DetectEngineCtx * DetectEngineCtxInit(void)