suricata
detect-content.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2019 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  * Simple content match part of the detection engine.
24  */
25 
26 #include "suricata-common.h"
27 #include "decode.h"
28 #include "detect.h"
29 #include "detect-content.h"
30 #include "detect-uricontent.h"
31 #include "detect-engine-mpm.h"
32 #include "detect-engine.h"
33 #include "detect-engine-state.h"
34 #include "detect-parse.h"
35 #include "detect-pcre.h"
36 #include "util-mpm.h"
37 #include "flow.h"
38 #include "flow-util.h"
39 #include "flow-var.h"
40 #include "detect-flow.h"
41 #include "app-layer.h"
42 #include "util-unittest.h"
43 #include "util-print.h"
44 #include "util-debug.h"
45 #include "util-spm.h"
46 #include "threads.h"
47 #include "util-unittest-helper.h"
48 #include "pkt-var.h"
49 #include "host.h"
50 #include "util-profiling.h"
51 #include "detect-dsize.h"
52 
53 static void DetectContentRegisterTests(void);
54 
56 {
57  sigmatch_table[DETECT_CONTENT].name = "content";
58  sigmatch_table[DETECT_CONTENT].desc = "match on payload content";
59  sigmatch_table[DETECT_CONTENT].url = "/rules/payload-keywords.html#content";
63  sigmatch_table[DETECT_CONTENT].RegisterTests = DetectContentRegisterTests;
65 }
66 
67 /**
68  * \brief Parse a content string, ie "abc|DE|fgh"
69  *
70  * \param content_str null terminated string containing the content
71  * \param result result pointer to pass the fully parsed byte array
72  * \param result_len size of the resulted data
73  * \param flags flags to be set by this parsing function
74  *
75  * \retval -1 error
76  * \retval 0 ok
77  */
78 int DetectContentDataParse(const char *keyword, const char *contentstr,
79  uint8_t **pstr, uint16_t *plen)
80 {
81  char *str = NULL;
82  size_t slen = 0;
83 
84  slen = strlen(contentstr);
85  if (slen == 0) {
86  return -1;
87  }
88  uint8_t buffer[slen + 1];
89  strlcpy((char *)&buffer, contentstr, slen + 1);
90  str = (char *)buffer;
91 
92  SCLogDebug("\"%s\", len %" PRIuMAX, str, (uintmax_t)slen);
93 
94  //SCLogDebug("DetectContentParse: \"%s\", len %" PRIu32 "", str, len);
95  char converted = 0;
96 
97  {
98  uint16_t i, x;
99  uint8_t bin = 0;
100  uint8_t escape = 0;
101  uint8_t binstr[3] = "";
102  uint8_t binpos = 0;
103  uint16_t bin_count = 0;
104 
105  for (i = 0, x = 0; i < slen; i++) {
106  // SCLogDebug("str[%02u]: %c", i, str[i]);
107  if (str[i] == '|') {
108  bin_count++;
109  if (bin) {
110  bin = 0;
111  } else {
112  bin = 1;
113  }
114  } else if(!escape && str[i] == '\\') {
115  escape = 1;
116  } else {
117  if (bin) {
118  if (isdigit((unsigned char)str[i]) ||
119  str[i] == 'A' || str[i] == 'a' ||
120  str[i] == 'B' || str[i] == 'b' ||
121  str[i] == 'C' || str[i] == 'c' ||
122  str[i] == 'D' || str[i] == 'd' ||
123  str[i] == 'E' || str[i] == 'e' ||
124  str[i] == 'F' || str[i] == 'f')
125  {
126  // SCLogDebug("part of binary: %c", str[i]);
127 
128  binstr[binpos] = (char)str[i];
129  binpos++;
130 
131  if (binpos == 2) {
132  uint8_t c = strtol((char *)binstr, (char **) NULL, 16) & 0xFF;
133  binpos = 0;
134  str[x] = c;
135  x++;
136  converted = 1;
137  }
138  } else if (str[i] == ' ') {
139  // SCLogDebug("space as part of binary string");
140  }
141  else if (str[i] != ',') {
142  SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid hex code in "
143  "content - %s, hex %c. Invalidating signature.", str, str[i]);
144  goto error;
145  }
146  } else if (escape) {
147  if (str[i] == ':' ||
148  str[i] == ';' ||
149  str[i] == '\\' ||
150  str[i] == '\"')
151  {
152  str[x] = str[i];
153  x++;
154  } else {
155  SCLogError(SC_ERR_INVALID_SIGNATURE, "'%c' has to be escaped", str[i-1]);
156  goto error;
157  }
158  escape = 0;
159  converted = 1;
160  } else if (str[i] == '"') {
161  SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid unescaped double quote within content section.");
162  goto error;
163  } else {
164  str[x] = str[i];
165  x++;
166  }
167  }
168  }
169 
170  if (bin_count % 2 != 0) {
171  SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid hex code assembly in "
172  "%s - %s. Invalidating signature.", keyword, contentstr);
173  goto error;
174  }
175 
176  if (converted) {
177  slen = x;
178  }
179  }
180 
181  if (slen) {
182  uint8_t *ptr = SCCalloc(1, slen);
183  if (ptr == NULL) {
184  return -1;
185  }
186  memcpy(ptr, str, slen);
187 
188  *plen = (uint16_t)slen;
189  *pstr = ptr;
190  return 0;
191  }
192 error:
193  return -1;
194 }
195 /**
196  * \brief DetectContentParse
197  * \initonly
198  */
200  const char *contentstr)
201 {
202  DetectContentData *cd = NULL;
203  uint8_t *content = NULL;
204  uint16_t len = 0;
205  int ret;
206 
207  ret = DetectContentDataParse("content", contentstr, &content, &len);
208  if (ret == -1) {
209  return NULL;
210  }
211 
212  cd = SCMalloc(sizeof(DetectContentData) + len);
213  if (unlikely(cd == NULL)) {
214  SCFree(content);
215  exit(EXIT_FAILURE);
216  }
217 
218  memset(cd, 0, sizeof(DetectContentData) + len);
219 
220  cd->content = (uint8_t *)cd + sizeof(DetectContentData);
221  memcpy(cd->content, content, len);
222  cd->content_len = len;
223 
224  /* Prepare SPM search context. */
225  cd->spm_ctx = SpmInitCtx(cd->content, cd->content_len, 0,
226  spm_global_thread_ctx);
227  if (cd->spm_ctx == NULL) {
228  SCFree(content);
229  SCFree(cd);
230  return NULL;
231  }
232 
233  cd->depth = 0;
234  cd->offset = 0;
235  cd->within = 0;
236  cd->distance = 0;
237 
238  SCFree(content);
239  return cd;
240 
241 }
242 
244  const char *contentstr)
245 {
246  return DetectContentParse(spm_global_thread_ctx, contentstr);
247 }
248 
249 /**
250  * \brief Helper function to print a DetectContentData
251  */
253 {
254  int i = 0;
255  if (cd == NULL) {
256  SCLogDebug("DetectContentData \"cd\" is NULL");
257  return;
258  }
259  char *tmpstr = SCMalloc(sizeof(char) * cd->content_len + 1);
260  if (tmpstr != NULL) {
261  for (i = 0; i < cd->content_len; i++) {
262  if (isprint(cd->content[i]))
263  tmpstr[i] = cd->content[i];
264  else
265  tmpstr[i] = '.';
266  }
267  tmpstr[i] = '\0';
268  SCLogDebug("Content: \"%s\"", tmpstr);
269  SCFree(tmpstr);
270  } else {
271  SCLogDebug("Content: ");
272  for (i = 0; i < cd->content_len; i++)
273  SCLogDebug("%c", cd->content[i]);
274  }
275 
276  SCLogDebug("Content_id: %"PRIu32, cd->id);
277  SCLogDebug("Content_len: %"PRIu16, cd->content_len);
278  SCLogDebug("Depth: %"PRIu16, cd->depth);
279  SCLogDebug("Offset: %"PRIu16, cd->offset);
280  SCLogDebug("Within: %"PRIi32, cd->within);
281  SCLogDebug("Distance: %"PRIi32, cd->distance);
282  SCLogDebug("flags: %u ", cd->flags);
283  SCLogDebug("negated: %s ", cd->flags & DETECT_CONTENT_NEGATED ? "true" : "false");
284  SCLogDebug("relative match next: %s ", cd->flags & DETECT_CONTENT_RELATIVE_NEXT ? "true" : "false");
285 
286  if (cd->replace && cd->replace_len) {
287  char *tmprstr = SCMalloc(sizeof(char) * cd->replace_len + 1);
288 
289  if (tmprstr != NULL) {
290  for (i = 0; i < cd->replace_len; i++) {
291  if (isprint(cd->replace[i]))
292  tmprstr[i] = cd->replace[i];
293  else
294  tmprstr[i] = '.';
295  }
296  tmprstr[i] = '\0';
297  SCLogDebug("Replace: \"%s\"", tmprstr);
298  SCFree(tmprstr);
299  } else {
300  SCLogDebug("Replace: ");
301  for (i = 0; i < cd->replace_len; i++)
302  SCLogDebug("%c", cd->replace[i]);
303  }
304  }
305  SCLogDebug("-----------");
306 }
307 
308 /**
309  * \brief Function to setup a content pattern.
310  *
311  * \param de_ctx pointer to the current detection_engine
312  * \param s pointer to the current Signature
313  * \param m pointer to the last parsed SigMatch
314  * \param contentstr pointer to the current keyword content string
315  * \retval -1 if error
316  * \retval 0 if all was ok
317  */
318 int DetectContentSetup(DetectEngineCtx *de_ctx, Signature *s, const char *contentstr)
319 {
320  DetectContentData *cd = NULL;
321  SigMatch *sm = NULL;
322 
324  if (cd == NULL)
325  goto error;
326  if (s->init_data->negated == true) {
328  }
329 
330  DetectContentPrint(cd);
331 
332  if (DetectBufferGetActiveList(de_ctx, s) == -1)
333  goto error;
334 
335  int sm_list = s->init_data->list;
336  if (sm_list == DETECT_SM_LIST_NOTSET) {
337  sm_list = DETECT_SM_LIST_PMATCH;
338  } else if (sm_list > DETECT_SM_LIST_MAX &&
339  0 == (cd->flags & DETECT_CONTENT_NEGATED)) {
340  /* Check transform compatibility */
341  const char *tstr;
343  cd->content_len, &tstr)) {
345  "content string \"%s\" incompatible with %s transform",
346  contentstr, tstr);
347  goto error;
348  }
349  }
350 
351  sm = SigMatchAlloc();
352  if (sm == NULL)
353  goto error;
354  sm->ctx = (void *)cd;
355  sm->type = DETECT_CONTENT;
356  SigMatchAppendSMToList(s, sm, sm_list);
357 
358  return 0;
359 
360 error:
362  return -1;
363 }
364 
365 /**
366  * \brief this function will SCFree memory associated with DetectContentData
367  *
368  * \param cd pointer to DetectContentData
369  */
371 {
372  SCEnter();
374 
375  if (cd == NULL)
376  SCReturn;
377 
378  SpmDestroyCtx(cd->spm_ctx);
379 
380  SCFree(cd);
381  SCReturn;
382 }
383 
384 /**
385  * \retval 1 valid
386  * \retval 0 invalid
387  */
389 {
390  if (!(s->flags & SIG_FLAG_DSIZE)) {
391  return TRUE;
392  }
393 
394  int max_right_edge_i = SigParseGetMaxDsize(s);
395  if (max_right_edge_i < 0) {
396  return TRUE;
397  }
398 
399  uint32_t max_right_edge = (uint32_t)max_right_edge_i;
400 
402  for ( ; sm != NULL; sm = sm->next) {
403  if (sm->type != DETECT_CONTENT)
404  continue;
405  const DetectContentData *cd = (const DetectContentData *)sm->ctx;
406  uint32_t right_edge = cd->content_len + cd->offset;
407  if (cd->content_len > max_right_edge) {
409  "signature can't match as content length %u is bigger than dsize %u.",
410  cd->content_len, max_right_edge);
411  return FALSE;
412  }
413  if (right_edge > max_right_edge) {
415  "signature can't match as content length %u with offset %u (=%u) is bigger than dsize %u.",
416  cd->content_len, cd->offset, right_edge, max_right_edge);
417  return FALSE;
418  }
419  }
420  return TRUE;
421 }
422 
423 /** \brief apply depth/offset and distance/within to content matches
424  *
425  * The idea is that any limitation we can set is a win, as the mpm
426  * can use this to reduce match candidates.
427  *
428  * E.g. if we have 'content:"1"; depth:1; content:"2"; distance:0; within:1;'
429  * we know that we can add 'offset:1; depth:2;' to the 2nd condition. This
430  * will then be used in mpm if the 2nd condition would be selected for mpm.
431  *
432  * Another example: 'content:"1"; depth:1; content:"2"; distance:0;'. Here we
433  * cannot set a depth, but we can set an offset of 'offset:1;'. This will
434  * make the mpm a bit more precise.
435  */
437 {
438  BUG_ON(s == NULL || s->init_data == NULL);
439 
440  uint32_t list = 0;
441  for (list = 0; list < s->init_data->smlists_array_size; list++) {
442  uint16_t offset = 0;
443  uint16_t offset_plus_pat = 0;
444  uint16_t depth = 0;
445  bool last_reset = false; // TODO really last reset 'depth'
446 
447  bool has_depth = false;
448  bool has_ends_with = false;
449  uint16_t ends_with_depth = 0;
450 
451  bool have_anchor = false;
452 
453  SigMatch *sm = s->init_data->smlists[list];
454  for ( ; sm != NULL; sm = sm->next) {
455  switch (sm->type) {
456  case DETECT_CONTENT: {
459  offset = depth = 0;
460  offset_plus_pat = cd->content_len;
461  SCLogDebug("reset");
462  last_reset = true;
463  have_anchor = false;
464  continue;
465  }
466  if (cd->flags & DETECT_CONTENT_NEGATED) {
467  offset = depth = 0;
468  offset_plus_pat = 0;
469  SCLogDebug("reset because of negation");
470  last_reset = true;
471  have_anchor = false;
472  continue;
473  }
474 
475  if (cd->depth) {
476  has_depth = true;
477  have_anchor = true;
478  }
479 
480  SCLogDebug("sm %p depth %u offset %u distance %d within %d", sm, cd->depth, cd->offset, cd->distance, cd->within);
481 
482  SCLogDebug("stored: offset %u depth %u offset_plus_pat %u", offset, depth, offset_plus_pat);
483 
484  if ((cd->flags & DETECT_CONTENT_WITHIN) == 0) {
485  if (depth)
486  SCLogDebug("no within, reset depth");
487  depth = 0;
488  }
489  if ((cd->flags & DETECT_CONTENT_DISTANCE) == 0) {
490  if (offset_plus_pat)
491  SCLogDebug("no distance, reset offset_plus_pat & offset");
492  offset_plus_pat = offset = 0;
493  }
494 
495  SCLogDebug("stored: offset %u depth %u offset_plus_pat %u", offset, depth, offset_plus_pat);
496 
497  if (cd->flags & DETECT_CONTENT_DISTANCE && cd->distance >= 0) {
498  offset = cd->offset = offset_plus_pat + cd->distance;
499  SCLogDebug("updated content to have offset %u", cd->offset);
500  }
501  if (have_anchor && !last_reset && offset_plus_pat && cd->flags & DETECT_CONTENT_WITHIN && cd->within >= 0) {
502  if (depth && depth > offset_plus_pat) {
503  uint16_t dist = 0;
504  if (cd->flags & DETECT_CONTENT_DISTANCE && cd->distance > 0) {
505  dist = cd->distance;
506  SCLogDebug("distance to add: %u. depth + dist %u", dist, depth + dist);
507  }
508  SCLogDebug("depth %u + cd->within %u", depth, cd->within);
509  depth = cd->depth = depth + cd->within + dist;
510  } else {
511  SCLogDebug("offset %u + cd->within %u", offset, cd->within);
512  depth = cd->depth = offset + cd->within;
513  }
514  SCLogDebug("updated content to have depth %u", cd->depth);
515  } else {
516  if (cd->depth == 0 && depth != 0) {
517  if (cd->within > 0) {
518  SCLogDebug("within %d distance %d", cd->within, cd->distance);
519  if (cd->flags & DETECT_CONTENT_DISTANCE && cd->distance >= 0) {
520  cd->offset = offset_plus_pat + cd->distance;
521  SCLogDebug("updated content to have offset %u", cd->offset);
522  }
523 
524  cd->depth = cd->within + depth;
525  depth = cd->depth;
526  SCLogDebug("updated content to have depth %u", cd->depth);
527 
528  if (cd->flags & DETECT_CONTENT_ENDS_WITH) {
529  has_ends_with = true;
530  if (ends_with_depth == 0)
531  ends_with_depth = depth;
532  ends_with_depth = MIN(ends_with_depth, depth);
533  }
534  }
535  }
536  }
537  if (cd->offset == 0) {// && offset != 0) {
538  if (cd->flags & DETECT_CONTENT_DISTANCE && cd->distance >= 0) {
539  cd->offset = offset_plus_pat;
540  SCLogDebug("update content to have offset %u", cd->offset);
541  }
542  }
543 
546  if (cd->distance >= 0) {
547  // only distance
548  offset = cd->offset = offset_plus_pat + cd->distance;
549  offset_plus_pat = offset + cd->content_len;
550  SCLogDebug("offset %u offset_plus_pat %u", offset, offset_plus_pat);
551  }
552  }
553  if (cd->flags & DETECT_CONTENT_OFFSET) {
554  offset = cd->offset;
555  offset_plus_pat = offset + cd->content_len;
556  SCLogDebug("stored offset %u offset_plus_pat %u", offset, offset_plus_pat);
557  }
558  if (cd->depth) {
559  depth = cd->depth;
560  SCLogDebug("stored depth now %u", depth);
561  offset_plus_pat = offset + cd->content_len;
562  if (cd->flags & DETECT_CONTENT_ENDS_WITH) {
563  has_ends_with = true;
564  if (ends_with_depth == 0)
565  ends_with_depth = depth;
566  ends_with_depth = MIN(ends_with_depth, depth);
567  }
568  }
569  if ((cd->flags & (DETECT_CONTENT_WITHIN|DETECT_CONTENT_DEPTH)) == 0) {
570  last_reset = true;
571  depth = 0;
572  } else {
573  last_reset = false;
574  }
575  break;
576  }
577  case DETECT_PCRE: {
578  // relative could leave offset_plus_pat set.
579  DetectPcreData *pd = (DetectPcreData *)sm->ctx;
580  if (pd->flags & DETECT_PCRE_RELATIVE) {
581  depth = 0;
582  last_reset = true;
583  } else {
584  SCLogDebug("non-anchored PCRE not supported, reset offset_plus_pat & offset");
585  offset_plus_pat = offset = depth = 0;
586  last_reset = true;
587  }
588  break;
589  }
590  default: {
591  SCLogDebug("keyword not supported, reset offset_plus_pat & offset");
592  offset_plus_pat = offset = depth = 0;
593  last_reset = true;
594  break;
595  }
596  }
597  }
598  /* apply anchored 'ends with' as depth to all patterns */
599  if (has_depth && has_ends_with) {
600  sm = s->init_data->smlists[list];
601  for ( ; sm != NULL; sm = sm->next) {
602  switch (sm->type) {
603  case DETECT_CONTENT: {
605  if (cd->depth == 0)
606  cd->depth = ends_with_depth;
607  cd->depth = MIN(ends_with_depth, cd->depth);
608  if (cd->depth)
610  break;
611  }
612  }
613  }
614  }
615  }
616 }
617 
618 #ifdef UNITTESTS /* UNITTESTS */
619 
620 static bool TestLastContent(const Signature *s, uint16_t o, uint16_t d)
621 {
623  if (!sm) {
624  SCLogDebug("no sm");
625  return false;
626  }
627  if (!(sm->type == DETECT_CONTENT)) {
628  SCLogDebug("not content");
629  return false;
630  }
631  const DetectContentData *cd = (const DetectContentData *)sm->ctx;
632  if (o != cd->offset) {
633  SCLogDebug("offset mismatch %u != %u", o, cd->offset);
634  return false;
635  }
636  if (d != cd->depth) {
637  SCLogDebug("depth mismatch %u != %u", d, cd->depth);
638  return false;
639  }
640  return true;
641 }
642 
643 #define TEST_RUN(sig, o, d) \
644 { \
645  SCLogDebug("TEST_RUN start: '%s'", (sig)); \
646  DetectEngineCtx *de_ctx = DetectEngineCtxInit(); \
647  FAIL_IF_NULL(de_ctx); \
648  char rule[2048]; \
649  snprintf(rule, sizeof(rule), "alert tcp any any -> any any (%s sid:1; rev:1;)", (sig)); \
650  Signature *s = DetectEngineAppendSig(de_ctx, rule); \
651  FAIL_IF_NULL(s); \
652  SigAddressPrepareStage1(de_ctx); \
653  bool res = TestLastContent(s, (o), (d)); \
654  FAIL_IF(res == false); \
655  DetectEngineCtxFree(de_ctx); \
656 }
657 
658 #define TEST_DONE \
659  PASS
660 
661 /** \test test propagation of depth/offset/distance/within */
662 static int DetectContentDepthTest01(void)
663 {
664  // straight depth/offset
665  TEST_RUN("content:\"abc\"; offset:1; depth:3;", 1, 4);
666  // dsize applied as depth
667  TEST_RUN("dsize:10; content:\"abc\";", 0, 10);
668 
669  // relative match, directly following anchored content
670  TEST_RUN("content:\"abc\"; depth:3; content:\"xyz\"; distance:0; within:3; ", 3, 6);
671  // relative match, directly following anchored content
672  TEST_RUN("content:\"abc\"; offset:3; depth:3; content:\"xyz\"; distance:0; within:3; ", 6, 9);
673  TEST_RUN("content:\"abc\"; depth:6; content:\"xyz\"; distance:0; within:3; ", 3, 9);
674 
675  // multiple relative matches after anchored content
676  TEST_RUN("content:\"abc\"; depth:3; content:\"klm\"; distance:0; within:3; content:\"xyz\"; distance:0; within:3; ", 6, 9);
677  // test 'reset' due to unanchored content
678  TEST_RUN("content:\"abc\"; depth:3; content:\"klm\"; content:\"xyz\"; distance:0; within:3; ", 3, 0);
679  // test 'reset' due to unanchored pcre
680  TEST_RUN("content:\"abc\"; depth:3; pcre:/\"klm\"/; content:\"xyz\"; distance:0; within:3; ", 0, 0);
681  // test relative pcre. We can use previous offset+pattern len
682  TEST_RUN("content:\"abc\"; depth:3; pcre:/\"klm\"/R; content:\"xyz\"; distance:0; within:3; ", 3, 0);
683  TEST_RUN("content:\"abc\"; offset:3; depth:3; pcre:/\"klm\"/R; content:\"xyz\"; distance:0; within:3; ", 6, 0);
684 
685  TEST_RUN("content:\"abc\"; depth:3; content:\"klm\"; within:3; content:\"xyz\"; within:3; ", 0, 9);
686 
687  TEST_RUN("content:\"abc\"; depth:3; content:\"klm\"; distance:0; content:\"xyz\"; distance:0; ", 6, 0);
688 
689  // tests to see if anchored 'ends_with' is applied to other content as depth
690  TEST_RUN("content:\"abc\"; depth:6; isdataat:!1,relative; content:\"klm\";", 0, 6);
691  TEST_RUN("content:\"abc\"; depth:3; content:\"klm\"; within:3; content:\"xyz\"; within:3; isdataat:!1,relative; content:\"def\"; ", 0, 9);
692 
693  TEST_RUN("content:\"|03|\"; depth:1; content:\"|e0|\"; distance:4; within:1;", 5, 6);
694  TEST_RUN("content:\"|03|\"; depth:1; content:\"|e0|\"; distance:4; within:1; content:\"Cookie|3a|\"; distance:5; within:7;", 11, 18);
695 
696  TEST_RUN("content:\"this\"; content:\"is\"; within:6; content:\"big\"; within:8; content:\"string\"; within:8;", 0, 0);
697 
698  TEST_RUN("dsize:<80; content:!\"|00 22 02 00|\"; depth: 4; content:\"|00 00 04|\"; distance:8; within:3; content:\"|00 00 00 00 00|\"; distance:6; within:5;", 17, 80);
699  TEST_RUN("content:!\"|00 22 02 00|\"; depth: 4; content:\"|00 00 04|\"; distance:8; within:3; content:\"|00 00 00 00 00|\"; distance:6; within:5;", 17, 0);
700 
701  TEST_RUN("content:\"|0d 0a 0d 0a|\"; content:\"code=\"; distance:0;", 4, 0);
702  TEST_RUN("content:\"|0d 0a 0d 0a|\"; content:\"code=\"; distance:0; content:\"xploit.class\"; distance:2; within:18;", 11, 0);
703 
704  TEST_RUN("content:\"|16 03|\"; depth:2; content:\"|55 04 0a|\"; distance:0;", 2, 0);
705  TEST_RUN("content:\"|16 03|\"; depth:2; content:\"|55 04 0a|\"; distance:0; content:\"|0d|LogMeIn, Inc.\"; distance:1; within:14;", 6, 0);
706  TEST_RUN("content:\"|16 03|\"; depth:2; content:\"|55 04 0a|\"; distance:0; content:\"|0d|LogMeIn, Inc.\"; distance:1; within:14; content:\".app\";", 0, 0);
707 
708  TEST_RUN("content:\"=\"; offset:4; depth:9;", 4, 13);
709  // low end: offset 4 + patlen 1 = 5. So 5 + distance 55 = 60.
710  // hi end: depth '13' (4+9) + distance 55 = 68 + within 2 = 70
711  TEST_RUN("content:\"=\"; offset:4; depth:9; content:\"=&\"; distance:55; within:2;", 60, 70);
712 
713  TEST_DONE;
714 }
715 
716 /**
717  * \brief Print list of DETECT_CONTENT SigMatch's allocated in a
718  * SigMatch list, from the current sm to the end
719  * \param sm pointer to the current SigMatch to start printing from
720  */
721 static void DetectContentPrintAll(SigMatch *sm)
722 {
723 #ifdef DEBUG
724  if (SCLogDebugEnabled()) {
725  int i = 0;
726 
727  if (sm == NULL)
728  return;
729 
730  SigMatch *first_sm = sm;
731 
732  /* Print all of them */
733  for (; first_sm != NULL; first_sm = first_sm->next) {
734  if (first_sm->type == DETECT_CONTENT) {
735  SCLogDebug("Printing SigMatch DETECT_CONTENT %d", ++i);
737  }
738  }
739  }
740 #endif /* DEBUG */
741 }
742 
743 static int g_file_data_buffer_id = 0;
744 static int g_dce_stub_data_buffer_id = 0;
745 
746 /**
747  * \test DetectCotentParseTest01 this is a test to make sure we can deal with escaped colons
748  */
749 static int DetectContentParseTest01 (void)
750 {
751  int result = 1;
752  DetectContentData *cd = NULL;
753  const char *teststring = "abc\\:def";
754  const char *teststringparsed = "abc:def";
755 
756  uint16_t spm_matcher = SinglePatternMatchDefaultMatcher();
757  SpmGlobalThreadCtx *spm_global_thread_ctx = SpmInitGlobalThreadCtx(spm_matcher);
758  FAIL_IF(spm_global_thread_ctx == NULL);
759 
760  cd = DetectContentParse(spm_global_thread_ctx, teststring);
761  if (cd != NULL) {
762  if (memcmp(cd->content, teststringparsed, strlen(teststringparsed)) != 0) {
763  SCLogDebug("expected %s got ", teststringparsed);
764  PrintRawUriFp(stdout,cd->content,cd->content_len);
765  SCLogDebug(": ");
766  result = 0;
767  DetectContentFree(NULL, cd);
768  }
769  } else {
770  SCLogDebug("expected %s got NULL: ", teststringparsed);
771  result = 0;
772  }
773  SpmDestroyGlobalThreadCtx(spm_global_thread_ctx);
774  return result;
775 }
776 
777 /**
778  * \test DetectCotentParseTest02 this is a test to make sure we can deal with escaped semi-colons
779  */
780 static int DetectContentParseTest02 (void)
781 {
782  int result = 1;
783  DetectContentData *cd = NULL;
784  const char *teststring = "abc\\;def";
785  const char *teststringparsed = "abc;def";
786 
787  uint16_t spm_matcher = SinglePatternMatchDefaultMatcher();
788  SpmGlobalThreadCtx *spm_global_thread_ctx = SpmInitGlobalThreadCtx(spm_matcher);
789  FAIL_IF(spm_global_thread_ctx == NULL);
790 
791  cd = DetectContentParse(spm_global_thread_ctx, teststring);
792  if (cd != NULL) {
793  if (memcmp(cd->content, teststringparsed, strlen(teststringparsed)) != 0) {
794  SCLogDebug("expected %s got ", teststringparsed);
795  PrintRawUriFp(stdout,cd->content,cd->content_len);
796  SCLogDebug(": ");
797  result = 0;
798  DetectContentFree(NULL, cd);
799  }
800  } else {
801  SCLogDebug("expected %s got NULL: ", teststringparsed);
802  result = 0;
803  }
804  SpmDestroyGlobalThreadCtx(spm_global_thread_ctx);
805  return result;
806 }
807 
808 /**
809  * \test DetectCotentParseTest03 this is a test to make sure we can deal with escaped double-quotes
810  */
811 static int DetectContentParseTest03 (void)
812 {
813  int result = 1;
814  DetectContentData *cd = NULL;
815  const char *teststring = "abc\\\"def";
816  const char *teststringparsed = "abc\"def";
817 
818  uint16_t spm_matcher = SinglePatternMatchDefaultMatcher();
819  SpmGlobalThreadCtx *spm_global_thread_ctx = SpmInitGlobalThreadCtx(spm_matcher);
820  FAIL_IF(spm_global_thread_ctx == NULL);
821 
822  cd = DetectContentParse(spm_global_thread_ctx, teststring);
823  if (cd != NULL) {
824  if (memcmp(cd->content, teststringparsed, strlen(teststringparsed)) != 0) {
825  SCLogDebug("expected %s got ", teststringparsed);
826  PrintRawUriFp(stdout,cd->content,cd->content_len);
827  SCLogDebug(": ");
828  result = 0;
829  DetectContentFree(NULL, cd);
830  }
831  } else {
832  SCLogDebug("expected %s got NULL: ", teststringparsed);
833  result = 0;
834  }
835  SpmDestroyGlobalThreadCtx(spm_global_thread_ctx);
836  return result;
837 }
838 
839 /**
840  * \test DetectCotentParseTest04 this is a test to make sure we can deal with escaped backslashes
841  */
842 static int DetectContentParseTest04 (void)
843 {
844  int result = 1;
845  DetectContentData *cd = NULL;
846  const char *teststring = "abc\\\\def";
847  const char *teststringparsed = "abc\\def";
848 
849  uint16_t spm_matcher = SinglePatternMatchDefaultMatcher();
850  SpmGlobalThreadCtx *spm_global_thread_ctx = SpmInitGlobalThreadCtx(spm_matcher);
851  FAIL_IF(spm_global_thread_ctx == NULL);
852 
853  cd = DetectContentParse(spm_global_thread_ctx, teststring);
854  if (cd != NULL) {
855  uint16_t len = (cd->content_len > strlen(teststringparsed));
856  if (memcmp(cd->content, teststringparsed, len) != 0) {
857  SCLogDebug("expected %s got ", teststringparsed);
858  PrintRawUriFp(stdout,cd->content,cd->content_len);
859  SCLogDebug(": ");
860  result = 0;
861  DetectContentFree(NULL, cd);
862  }
863  } else {
864  SCLogDebug("expected %s got NULL: ", teststringparsed);
865  result = 0;
866  }
867  SpmDestroyGlobalThreadCtx(spm_global_thread_ctx);
868  return result;
869 }
870 
871 /**
872  * \test DetectCotentParseTest05 test illegal escape
873  */
874 static int DetectContentParseTest05 (void)
875 {
876  int result = 1;
877  DetectContentData *cd = NULL;
878  const char *teststring = "abc\\def";
879 
880  uint16_t spm_matcher = SinglePatternMatchDefaultMatcher();
881  SpmGlobalThreadCtx *spm_global_thread_ctx = SpmInitGlobalThreadCtx(spm_matcher);
882  FAIL_IF(spm_global_thread_ctx == NULL);
883 
884  cd = DetectContentParse(spm_global_thread_ctx, teststring);
885  if (cd != NULL) {
886  SCLogDebug("expected NULL got ");
887  PrintRawUriFp(stdout,cd->content,cd->content_len);
888  SCLogDebug(": ");
889  result = 0;
890  DetectContentFree(NULL, cd);
891  }
892  SpmDestroyGlobalThreadCtx(spm_global_thread_ctx);
893  return result;
894 }
895 
896 /**
897  * \test DetectCotentParseTest06 test a binary content
898  */
899 static int DetectContentParseTest06 (void)
900 {
901  int result = 1;
902  DetectContentData *cd = NULL;
903  const char *teststring = "a|42|c|44|e|46|";
904  const char *teststringparsed = "abcdef";
905 
906  uint16_t spm_matcher = SinglePatternMatchDefaultMatcher();
907  SpmGlobalThreadCtx *spm_global_thread_ctx = SpmInitGlobalThreadCtx(spm_matcher);
908  FAIL_IF(spm_global_thread_ctx == NULL);
909 
910  cd = DetectContentParse(spm_global_thread_ctx, teststring);
911  if (cd != NULL) {
912  uint16_t len = (cd->content_len > strlen(teststringparsed));
913  if (memcmp(cd->content, teststringparsed, len) != 0) {
914  SCLogDebug("expected %s got ", teststringparsed);
915  PrintRawUriFp(stdout,cd->content,cd->content_len);
916  SCLogDebug(": ");
917  result = 0;
918  DetectContentFree(NULL, cd);
919  }
920  } else {
921  SCLogDebug("expected %s got NULL: ", teststringparsed);
922  result = 0;
923  }
924  SpmDestroyGlobalThreadCtx(spm_global_thread_ctx);
925  return result;
926 }
927 
928 /**
929  * \test DetectCotentParseTest07 test an empty content
930  */
931 static int DetectContentParseTest07 (void)
932 {
933  int result = 1;
934  DetectContentData *cd = NULL;
935  const char *teststring = "";
936 
937  uint16_t spm_matcher = SinglePatternMatchDefaultMatcher();
938  SpmGlobalThreadCtx *spm_global_thread_ctx = SpmInitGlobalThreadCtx(spm_matcher);
939  FAIL_IF(spm_global_thread_ctx == NULL);
940 
941  cd = DetectContentParse(spm_global_thread_ctx, teststring);
942  if (cd != NULL) {
943  SCLogDebug("expected NULL got %p: ", cd);
944  result = 0;
945  DetectContentFree(NULL, cd);
946  }
947  SpmDestroyGlobalThreadCtx(spm_global_thread_ctx);
948  return result;
949 }
950 
951 /**
952  * \test DetectCotentParseTest08 test an empty content
953  */
954 static int DetectContentParseTest08 (void)
955 {
956  int result = 1;
957  DetectContentData *cd = NULL;
958  const char *teststring = "";
959 
960  uint16_t spm_matcher = SinglePatternMatchDefaultMatcher();
961  SpmGlobalThreadCtx *spm_global_thread_ctx = SpmInitGlobalThreadCtx(spm_matcher);
962  FAIL_IF(spm_global_thread_ctx == NULL);
963 
964  cd = DetectContentParse(spm_global_thread_ctx, teststring);
965  if (cd != NULL) {
966  SCLogDebug("expected NULL got %p: ", cd);
967  result = 0;
968  DetectContentFree(NULL, cd);
969  }
970  SpmDestroyGlobalThreadCtx(spm_global_thread_ctx);
971  return result;
972 }
973 
974 /**
975  * \test Test packet Matches
976  * \param raw_eth_pkt pointer to the ethernet packet
977  * \param pktsize size of the packet
978  * \param sig pointer to the signature to test
979  * \param sid sid number of the signature
980  * \retval return 1 if match
981  * \retval return 0 if not
982  */
983 static int DetectContentLongPatternMatchTest(uint8_t *raw_eth_pkt, uint16_t pktsize, const char *sig,
984  uint32_t sid)
985 {
986  int result = 0;
987 
989  if (unlikely(p == NULL))
990  return 0;
992 
993  ThreadVars th_v;
994  DetectEngineThreadCtx *det_ctx = NULL;
995 
996  memset(p, 0, SIZE_OF_PACKET);
997  memset(&dtv, 0, sizeof(DecodeThreadVars));
998  memset(&th_v, 0, sizeof(th_v));
999 
1001  DecodeEthernet(&th_v, &dtv, p, raw_eth_pkt, pktsize);
1002 
1004  if (de_ctx == NULL) {
1005  goto end;
1006  }
1007 
1008  de_ctx->flags |= DE_QUIET;
1009 
1010  de_ctx->sig_list = SigInit(de_ctx, sig);
1011  if (de_ctx->sig_list == NULL) {
1012  goto end;
1013  }
1014  de_ctx->sig_list->next = NULL;
1015 
1016  if (de_ctx->sig_list->sm_lists_tail[DETECT_SM_LIST_PMATCH]->type == DETECT_CONTENT) {
1018  if (co->flags & DETECT_CONTENT_RELATIVE_NEXT) {
1019  printf("relative next flag set on final match which is content: ");
1020  goto end;
1021  }
1022  }
1023 
1024  SCLogDebug("---DetectContentLongPatternMatchTest---");
1025  DetectContentPrintAll(de_ctx->sig_list->sm_lists[DETECT_SM_LIST_MATCH]);
1026 
1028  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1029 
1030  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1031  if (PacketAlertCheck(p, sid) != 1) {
1032  goto end;
1033  }
1034 
1035  result = 1;
1036 end:
1037  if (de_ctx != NULL)
1038  {
1041  if (det_ctx != NULL)
1042  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
1044  }
1045  PACKET_RECYCLE(p);
1046  FlowShutdown();
1047 
1048  SCFree(p);
1049  return result;
1050 }
1051 
1052 /**
1053  * \brief Wrapper for DetectContentLongPatternMatchTest
1054  */
1055 static int DetectContentLongPatternMatchTestWrp(const char *sig, uint32_t sid)
1056 {
1057  /** Real packet with the following tcp data:
1058  * "Hi, this is a big test to check content matches of splitted"
1059  * "patterns between multiple chunks!"
1060  * (without quotes! :) )
1061  */
1062  uint8_t raw_eth_pkt[] = {
1063  0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,
1064  0x00,0x00,0x00,0x00,0x08,0x00,0x45,0x00,
1065  0x00,0x85,0x00,0x01,0x00,0x00,0x40,0x06,
1066  0x7c,0x70,0x7f,0x00,0x00,0x01,0x7f,0x00,
1067  0x00,0x01,0x00,0x14,0x00,0x50,0x00,0x00,
1068  0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x02,
1069  0x20,0x00,0xc9,0xad,0x00,0x00,0x48,0x69,
1070  0x2c,0x20,0x74,0x68,0x69,0x73,0x20,0x69,
1071  0x73,0x20,0x61,0x20,0x62,0x69,0x67,0x20,
1072  0x74,0x65,0x73,0x74,0x20,0x74,0x6f,0x20,
1073  0x63,0x68,0x65,0x63,0x6b,0x20,0x63,0x6f,
1074  0x6e,0x74,0x65,0x6e,0x74,0x20,0x6d,0x61,
1075  0x74,0x63,0x68,0x65,0x73,0x20,0x6f,0x66,
1076  0x20,0x73,0x70,0x6c,0x69,0x74,0x74,0x65,
1077  0x64,0x20,0x70,0x61,0x74,0x74,0x65,0x72,
1078  0x6e,0x73,0x20,0x62,0x65,0x74,0x77,0x65,
1079  0x65,0x6e,0x20,0x6d,0x75,0x6c,0x74,0x69,
1080  0x70,0x6c,0x65,0x20,0x63,0x68,0x75,0x6e,
1081  0x6b,0x73,0x21 }; /* end raw_eth_pkt */
1082 
1083  return DetectContentLongPatternMatchTest(raw_eth_pkt, (uint16_t)sizeof(raw_eth_pkt),
1084  sig, sid);
1085 }
1086 
1087 /**
1088  * \test Check if we match a normal pattern (not splitted)
1089  */
1090 static int DetectContentLongPatternMatchTest01(void)
1091 {
1092  const char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";"
1093  " content:\"Hi, this is a big test\"; sid:1;)";
1094  return DetectContentLongPatternMatchTestWrp(sig, 1);
1095 }
1096 
1097 /**
1098  * \test Check if we match a splitted pattern
1099  */
1100 static int DetectContentLongPatternMatchTest02(void)
1101 {
1102  const char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";"
1103  " content:\"Hi, this is a big test to check content matches of"
1104  " splitted patterns between multiple chunks!\"; sid:1;)";
1105  return DetectContentLongPatternMatchTestWrp(sig, 1);
1106 }
1107 
1108 /**
1109  * \test Check that we don't match the signature if one of the splitted
1110  * chunks doesn't match the packet
1111  */
1112 static int DetectContentLongPatternMatchTest03(void)
1113 {
1114  /** The last chunk of the content should not match */
1115  const char *sig = "alert tcp any any -> any any (msg:\"Nothing..\";"
1116  " content:\"Hi, this is a big test to check content matches of"
1117  " splitted patterns between multiple splitted chunks!\"; sid:1;)";
1118  return (DetectContentLongPatternMatchTestWrp(sig, 1) == 0) ? 1: 0;
1119 }
1120 
1121 /**
1122  * \test Check if we match multiple content (not splitted)
1123  */
1124 static int DetectContentLongPatternMatchTest04(void)
1125 {
1126  const char *sig = "alert tcp any any -> any any (msg:\"Nothing..\"; "
1127  " content:\"Hi, this is\"; depth:15 ;content:\"a big test\"; "
1128  " within:15; content:\"to check content matches of\"; "
1129  " within:30; content:\"splitted patterns\"; distance:1; "
1130  " within:30; "
1131  " sid:1;)";
1132  return DetectContentLongPatternMatchTestWrp(sig, 1);
1133 }
1134 
1135 /**
1136  * \test Check that we match packets with multiple chunks and not chunks
1137  * Here we should specify only contents that fit in 32 bytes
1138  * Each of them with their modifier values
1139  */
1140 static int DetectContentLongPatternMatchTest05(void)
1141 {
1142  const char *sig = "alert tcp any any -> any any (msg:\"Nothing..\"; "
1143  " content:\"Hi, this is a big\"; depth:17; "
1144  " isdataat:30, relative; "
1145  " content:\"test\"; within: 5; distance:1; "
1146  " isdataat:15, relative; "
1147  " content:\"of splitted\"; within:37; distance:15; "
1148  " isdataat:20,relative; "
1149  " content:\"patterns\"; within:9; distance:1; "
1150  " isdataat:10, relative; "
1151  " sid:1;)";
1152  return DetectContentLongPatternMatchTestWrp(sig, 1);
1153 }
1154 
1155 /**
1156  * \test Check that we match packets with multiple chunks and not chunks
1157  * Here we should specify contents that fit and contents that must be splitted
1158  * Each of them with their modifier values
1159  */
1160 static int DetectContentLongPatternMatchTest06(void)
1161 {
1162  const char *sig = "alert tcp any any -> any any (msg:\"Nothing..\"; "
1163  " content:\"Hi, this is a big test to check cont\"; depth:36;"
1164  " content:\"ent matches\"; within:11; distance:0; "
1165  " content:\"of splitted patterns between multiple\"; "
1166  " within:38; distance:1; "
1167  " content:\"chunks!\"; within: 8; distance:1; "
1168  " sid:1;)";
1169  return DetectContentLongPatternMatchTestWrp(sig, 1);
1170 }
1171 
1172 /**
1173  * \test Check if we match contents that are in the payload
1174  * but not in the same order as specified in the signature
1175  */
1176 static int DetectContentLongPatternMatchTest07(void)
1177 {
1178  const char *sig = "alert tcp any any -> any any (msg:\"Nothing..\"; "
1179  " content:\"chunks!\"; "
1180  " content:\"content matches\"; offset:32; depth:47; "
1181  " content:\"of splitted patterns between multiple\"; "
1182  " content:\"Hi, this is a big\"; offset:0; depth:17; "
1183  " sid:1;)";
1184  return DetectContentLongPatternMatchTestWrp(sig, 1);
1185 }
1186 
1187 /**
1188  * \test Check if we match contents that are in the payload
1189  * but not in the same order as specified in the signature
1190  */
1191 static int DetectContentLongPatternMatchTest08(void)
1192 {
1193  const char *sig = "alert tcp any any -> any any (msg:\"Nothing..\"; "
1194  " content:\"ent matches\"; "
1195  " content:\"of splitted patterns between multiple\"; "
1196  " within:38; distance:1; "
1197  " content:\"chunks!\"; within: 8; distance:1; "
1198  " content:\"Hi, this is a big test to check cont\"; depth:36;"
1199  " sid:1;)";
1200  return DetectContentLongPatternMatchTestWrp(sig, 1);
1201 }
1202 
1203 /**
1204  * \test Check if we match contents that are in the payload
1205  * but not in the same order as specified in the signature
1206  */
1207 static int DetectContentLongPatternMatchTest09(void)
1208 {
1209  const char *sig = "alert tcp any any -> any any (msg:\"Nothing..\"; "
1210  " content:\"ent matches\"; "
1211  " content:\"of splitted patterns between multiple\"; "
1212  " offset:47; depth:85; "
1213  " content:\"chunks!\"; within: 8; distance:1; "
1214  " content:\"Hi, this is a big test to chec\"; depth:36;"
1215  " content:\"k cont\"; distance:0; within:6;"
1216  " sid:1;)";
1217  return DetectContentLongPatternMatchTestWrp(sig, 1);
1218 }
1219 
1220 /**
1221  * \test Check if we match two consecutive simple contents
1222  */
1223 static int DetectContentLongPatternMatchTest10(void)
1224 {
1225  const char *sig = "alert tcp any any -> any any (msg:\"Nothing..\"; "
1226  " content:\"Hi, this is a big test to check \"; "
1227  " content:\"con\"; "
1228  " sid:1;)";
1229  return DetectContentLongPatternMatchTestWrp(sig, 1);
1230 }
1231 
1232 /**
1233  * \test Check if we match two contents of length 1
1234  */
1235 static int DetectContentLongPatternMatchTest11(void)
1236 {
1237  const char *sig = "alert tcp any any -> any any (msg:\"Nothing..\"; "
1238  " content:\"H\"; "
1239  " content:\"i\"; "
1240  " sid:1;)";
1241  return DetectContentLongPatternMatchTestWrp(sig, 1);
1242 }
1243 
1244 static int DetectContentParseTest09(void)
1245 {
1246  DetectContentData *cd = NULL;
1247  const char *teststring = "boo";
1248 
1249  uint16_t spm_matcher = SinglePatternMatchDefaultMatcher();
1250  SpmGlobalThreadCtx *spm_global_thread_ctx = SpmInitGlobalThreadCtx(spm_matcher);
1251  FAIL_IF(spm_global_thread_ctx == NULL);
1252 
1253  cd = DetectContentParse(spm_global_thread_ctx, teststring);
1254  FAIL_IF_NULL(cd);
1255  DetectContentFree(NULL, cd);
1256  SpmDestroyGlobalThreadCtx(spm_global_thread_ctx);
1257  PASS;
1258 }
1259 
1260 /**
1261  * \test Test cases where if within specified is < content lenggth we invalidate
1262  * the sig.
1263  */
1264 static int DetectContentParseTest17(void)
1265 {
1266  int result = 0;
1267  const char *sigstr = "alert tcp any any -> any any (msg:\"Dummy\"; "
1268  "content:\"one\"; content:\"two\"; within:2; sid:1;)";
1269 
1271  if (de_ctx == NULL)
1272  goto end;
1273 
1274  de_ctx->sig_list = SigInit(de_ctx, sigstr);
1275  if (de_ctx->sig_list != NULL)
1276  goto end;
1277 
1278  result = 1;
1279 
1280 end:
1282  if (de_ctx != NULL)
1284  return result;
1285 }
1286 
1287 /**
1288  * \test Test content for dce sig.
1289  */
1290 static int DetectContentParseTest18(void)
1291 {
1292  Signature *s = SigAlloc();
1293  int result = 1;
1295  if (de_ctx == NULL) {
1296  result = 0;
1297  goto end;
1298  }
1299 
1301  goto end;
1302 
1303  result &= (DetectContentSetup(de_ctx, s, "one") == 0);
1304  result &= (s->sm_lists[g_dce_stub_data_buffer_id] == NULL && s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL);
1305 
1306  SigFree(de_ctx, s);
1307 
1308  s = SigAlloc();
1309  if (s == NULL)
1310  return 0;
1311 
1312  result &= (DetectContentSetup(de_ctx, s, "one") == 0);
1313  result &= (s->sm_lists[g_dce_stub_data_buffer_id] == NULL && s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL);
1314 
1315  end:
1316  SigFree(de_ctx, s);
1318 
1319  return result;
1320 }
1321 
1322 /**
1323  * \test Test content for dce sig.
1324  */
1325 
1326 static int DetectContentParseTest19(void)
1327 {
1328  DetectEngineCtx *de_ctx = NULL;
1329  int result = 1;
1330  Signature *s = NULL;
1331  DetectContentData *data = NULL;
1332 
1334  if (de_ctx == NULL)
1335  goto end;
1336 
1337  de_ctx->flags |= DE_QUIET;
1338  de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1339  "(msg:\"Testing dce iface, stub_data with content\"; "
1340  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1341  "dce_stub_data; "
1342  "content:\"one\"; distance:0; sid:1;)");
1343  if (de_ctx->sig_list == NULL) {
1344  printf ("failed dce iface, stub_data with content ");
1345  result = 0;
1346  goto end;
1347  }
1348  s = de_ctx->sig_list;
1349  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
1350  result = 0;
1351  goto end;
1352  }
1353  result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_CONTENT);
1354  result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL);
1355  data = (DetectContentData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1356  if (data->flags & DETECT_CONTENT_RAWBYTES ||
1357  data->flags & DETECT_CONTENT_NOCASE ||
1358  data->flags & DETECT_CONTENT_WITHIN ||
1359  !(data->flags & DETECT_CONTENT_DISTANCE) ||
1361  data->flags & DETECT_CONTENT_NEGATED ||
1362  result == 0) {
1363  result = 0;
1364  goto end;
1365  }
1366 
1367  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1368  "(msg:\"Testing dce iface, stub_data with contents & distance, within\"; "
1369  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1370  "dce_stub_data; "
1371  "content:\"one\"; distance:0; content:\"two\"; within:10; sid:1;)");
1372  if (s->next == NULL) {
1373  printf("failed dce iface, stub_data with content & distance, within");
1374  result = 0;
1375  goto end;
1376  }
1377  s = s->next;
1378  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
1379  result = 0;
1380  goto end;
1381  }
1382  result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_CONTENT);
1383  result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL);
1384  data = (DetectContentData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1385  if (data->flags & DETECT_CONTENT_RAWBYTES ||
1386  data->flags & DETECT_CONTENT_NOCASE ||
1387  !(data->flags & DETECT_CONTENT_WITHIN) ||
1388  data->flags & DETECT_CONTENT_DISTANCE ||
1390  data->flags & DETECT_CONTENT_NEGATED ||
1391  result == 0) {
1392  result = 0;
1393  goto end;
1394  }
1395  result &= (data->within == 10);
1396 /*
1397  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1398  "(msg:\"Testing dce iface, stub_data with contents & offset, depth\"; "
1399  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1400  "dce_stub_data; "
1401  "content:\"one\"; offset:5; depth:9; "
1402  "content:\"two\"; within:10; sid:1;)");
1403  if (s->next == NULL) {
1404  printf ("failed dce iface, stub_data with contents & offset, depth");
1405  result = 0;
1406  goto end;
1407  }
1408  s = s->next;
1409  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
1410  result = 0;
1411  goto end;
1412  }
1413  result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_CONTENT);
1414  result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL);
1415  data = (DetectContentData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1416  if (data->flags & DETECT_CONTENT_RAWBYTES ||
1417  data->flags & DETECT_CONTENT_NOCASE ||
1418  data->flags & DETECT_CONTENT_WITHIN ||
1419  data->flags & DETECT_CONTENT_DISTANCE ||
1420  data->flags & DETECT_CONTENT_FAST_PATTERN ||
1421  data->flags & DETECT_CONTENT_NEGATED ||
1422  result == 0) {
1423  result = 0;
1424  goto end;
1425  }
1426  result &= (data->offset == 5 && data->depth == 9);
1427  data = (DetectContentData *)s->sm_lists[g_dce_stub_data_buffer_id]->ctx;
1428  if (data->flags & DETECT_CONTENT_RAWBYTES ||
1429  data->flags & DETECT_CONTENT_NOCASE ||
1430  !(data->flags & DETECT_CONTENT_WITHIN) ||
1431  data->flags & DETECT_CONTENT_DISTANCE ||
1432  data->flags & DETECT_CONTENT_FAST_PATTERN ||
1433  data->flags & DETECT_CONTENT_NEGATED ||
1434  result == 0) {
1435  result = 0;
1436  goto end;
1437  }
1438 
1439  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1440  "(msg:\"Testing dce iface, stub with contents, distance\"; "
1441  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1442  "dce_stub_data; "
1443  "content:\"one\"; distance:0; "
1444  "content:\"two\"; distance:2; sid:1;)");
1445  if (s->next == NULL) {
1446  result = 0;
1447  goto end;
1448  }
1449  s = s->next;
1450  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
1451  result = 0;
1452  goto end;
1453  }
1454  result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_CONTENT);
1455  result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL);
1456  data = (DetectContentData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1457  if (data->flags & DETECT_CONTENT_RAWBYTES ||
1458  data->flags & DETECT_CONTENT_NOCASE ||
1459  data->flags & DETECT_CONTENT_WITHIN ||
1460  !(data->flags & DETECT_CONTENT_DISTANCE) ||
1461  data->flags & DETECT_CONTENT_FAST_PATTERN ||
1462  data->flags & DETECT_CONTENT_NEGATED ||
1463  result == 0) {
1464  result = 0;
1465  goto end;
1466  }
1467  result &= (data->distance == 2);
1468 */
1469  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1470  "(msg:\"Testing dce iface, stub with contents, distance, within\"; "
1471  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1472  "dce_stub_data; "
1473  "content:\"one\"; distance:0; "
1474  "content:\"two\"; within:10; distance:2; sid:1;)");
1475  if (s->next == NULL) {
1476  result = 0;
1477  goto end;
1478  }
1479  s = s->next;
1480  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
1481  result = 0;
1482  goto end;
1483  }
1484  result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_CONTENT);
1485  result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL);
1486  data = (DetectContentData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1487  if (data->flags & DETECT_CONTENT_RAWBYTES ||
1488  data->flags & DETECT_CONTENT_NOCASE ||
1489  !(data->flags & DETECT_CONTENT_WITHIN) ||
1490  !(data->flags & DETECT_CONTENT_DISTANCE) ||
1492  data->flags & DETECT_CONTENT_NEGATED ||
1493  result == 0) {
1494  result = 0;
1495  goto end;
1496  }
1497  result &= (data->within == 10 && data->distance == 2);
1498 /*
1499  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1500  "(msg:\"Testing dce iface, stub_data with content, offset\"; "
1501  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1502  "dce_stub_data; "
1503  "content:\"one\"; offset:10; sid:1;)");
1504  if (s->next == NULL) {
1505  printf ("Failed dce iface, stub_data with content, offset ");
1506  result = 0;
1507  goto end;
1508  }
1509  s = s->next;
1510  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
1511  result = 0;
1512  goto end;
1513  }
1514  result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_CONTENT);
1515  result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL);
1516  data = (DetectContentData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1517  if (data->flags & DETECT_CONTENT_RAWBYTES ||
1518  data->flags & DETECT_CONTENT_NOCASE ||
1519  data->flags & DETECT_CONTENT_WITHIN ||
1520  data->flags & DETECT_CONTENT_DISTANCE ||
1521  data->flags & DETECT_CONTENT_FAST_PATTERN ||
1522  data->flags & DETECT_CONTENT_NEGATED ||
1523  result == 0) {
1524  result = 0;
1525  goto end;
1526  }
1527  result &= (data->offset == 10);
1528 
1529  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1530  "(msg:\"Testing dce iface, stub_data with content, depth\"; "
1531  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1532  "dce_stub_data; "
1533  "content:\"one\"; depth:10; sid:1;)");
1534  if (s->next == NULL) {
1535  printf ("failed dce iface, stub_data with content, depth");
1536  result = 0;
1537  goto end;
1538  }
1539  s = s->next;
1540  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
1541  result = 0;
1542  goto end;
1543  }
1544  result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_CONTENT);
1545  result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL);
1546  data = (DetectContentData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1547  if (data->flags & DETECT_CONTENT_RAWBYTES ||
1548  data->flags & DETECT_CONTENT_NOCASE ||
1549  data->flags & DETECT_CONTENT_WITHIN ||
1550  data->flags & DETECT_CONTENT_DISTANCE ||
1551  data->flags & DETECT_CONTENT_FAST_PATTERN ||
1552  data->flags & DETECT_CONTENT_NEGATED ||
1553  result == 0) {
1554  result = 0;
1555  goto end;
1556  }
1557  result &= (data->depth == 10);
1558 
1559  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1560  "(msg:\"Testing dce iface, stub_data with content, offset, depth\"; "
1561  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
1562  "dce_stub_data; "
1563  "content:\"one\"; offset:10; depth:3; sid:1;)");
1564  if (s->next == NULL) {
1565  printf("failed dce iface, stub_data with content, offset, depth");
1566  result = 0;
1567  goto end;
1568  }
1569  s = s->next;
1570  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] == NULL) {
1571  result = 0;
1572  goto end;
1573  }
1574  result &= (s->sm_lists_tail[g_dce_stub_data_buffer_id]->type == DETECT_CONTENT);
1575  result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] == NULL);
1576  data = (DetectContentData *)s->sm_lists_tail[g_dce_stub_data_buffer_id]->ctx;
1577  if (data->flags & DETECT_CONTENT_RAWBYTES ||
1578  data->flags & DETECT_CONTENT_NOCASE ||
1579  data->flags & DETECT_CONTENT_WITHIN ||
1580  data->flags & DETECT_CONTENT_DISTANCE ||
1581  data->flags & DETECT_CONTENT_FAST_PATTERN ||
1582  data->flags & DETECT_CONTENT_NEGATED ||
1583  result == 0) {
1584  result = 0;
1585  goto end;
1586  }
1587  result &= (data->offset == 10 && data->depth == 13);
1588 */
1589  s->next = SigInit(de_ctx, "alert tcp any any -> any any "
1590  "(msg:\"Testing content\"; "
1591  "content:\"one\"; sid:1;)");
1592  if (s->next == NULL) {
1593  printf ("failed testing content");
1594  result = 0;
1595  goto end;
1596  }
1597  s = s->next;
1598  if (s->sm_lists_tail[g_dce_stub_data_buffer_id] != NULL) {
1599  result = 0;
1600  goto end;
1601  }
1602  result &= (s->sm_lists[DETECT_SM_LIST_PMATCH] != NULL);
1603 
1604  end:
1608 
1609  return result;
1610 }
1611 
1612 /**
1613  * \test Test content for dce sig.
1614  */
1615 static int DetectContentParseTest20(void)
1616 {
1617  DetectEngineCtx *de_ctx = NULL;
1618  int result = 1;
1619 
1621  if (de_ctx == NULL)
1622  goto end;
1623 
1624  de_ctx->flags |= DE_QUIET;
1626  "alert udp any any -> any any "
1627  "(msg:\"test\"; content:\"\"; sid:238012;)");
1628  if (de_ctx->sig_list != NULL) {
1629  result = 0;
1630  goto end;
1631  }
1632 
1633  end:
1637 
1638  return result;
1639 }
1640 
1641 /**
1642  * \test Parsing test
1643  */
1644 static int DetectContentParseTest21(void)
1645 {
1646  DetectEngineCtx *de_ctx = NULL;
1647  int result = 1;
1648 
1650  if (de_ctx == NULL)
1651  goto end;
1652 
1653  de_ctx->flags |= DE_QUIET;
1655  "alert udp any any -> any any "
1656  "(msg:\"test\"; content:\"; sid:238012;)");
1657  if (de_ctx->sig_list != NULL) {
1658  result = 0;
1659  goto end;
1660  }
1661 
1662  end:
1666 
1667  return result;
1668 }
1669 
1670 /**
1671  * \test Parsing test
1672  */
1673 static int DetectContentParseTest22(void)
1674 {
1675  DetectEngineCtx *de_ctx = NULL;
1676  int result = 1;
1677 
1679  if (de_ctx == NULL)
1680  goto end;
1681 
1682  de_ctx->flags |= DE_QUIET;
1684  "alert udp any any -> any any "
1685  "(msg:\"test\"; content:\"boo; sid:238012;)");
1686  if (de_ctx->sig_list != NULL) {
1687  result = 0;
1688  goto end;
1689  }
1690 
1691  end:
1695 
1696  return result;
1697 }
1698 
1699 /**
1700  * \test Parsing test
1701  */
1702 static int DetectContentParseTest23(void)
1703 {
1704  DetectEngineCtx *de_ctx = NULL;
1705  int result = 1;
1706 
1708  if (de_ctx == NULL)
1709  goto end;
1710 
1711  de_ctx->flags |= DE_QUIET;
1713  "alert udp any any -> any any "
1714  "(msg:\"test\"; content:boo\"; sid:238012;)");
1715  if (de_ctx->sig_list != NULL) {
1716  result = 0;
1717  goto end;
1718  }
1719 
1720  end:
1724 
1725  return result;
1726 }
1727 
1728 /**
1729  * \test Parsing test
1730  */
1731 static int DetectContentParseTest24(void)
1732 {
1733  DetectEngineCtx *de_ctx = NULL;
1734  DetectContentData *cd = 0;
1735  Signature *s = NULL;
1736  int result = 1;
1737 
1739  if (de_ctx == NULL)
1740  goto end;
1741 
1742  de_ctx->flags |= DE_QUIET;
1743  s = de_ctx->sig_list = SigInit(de_ctx,
1744  "alert udp any any -> any any "
1745  "(msg:\"test\"; content: !\"boo\"; sid:238012;)");
1746  if (de_ctx->sig_list == NULL) {
1747  printf("de_ctx->sig_list == NULL: ");
1748  result = 0;
1749  goto end;
1750  }
1751 
1752  if (s->sm_lists_tail[DETECT_SM_LIST_PMATCH] == NULL || s->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx == NULL) {
1753  printf("de_ctx->pmatch_tail == NULL || de_ctx->pmatch_tail->ctx == NULL: ");
1754  result = 0;
1755  goto end;
1756  }
1757 
1758  cd = (DetectContentData *)s->sm_lists_tail[DETECT_SM_LIST_PMATCH]->ctx;
1759  result = (strncmp("boo", (char *)cd->content, cd->content_len) == 0);
1760 
1761 end:
1765 
1766  return result;
1767 }
1768 
1769 /**
1770  * \test Parsing test
1771  */
1772 static int DetectContentParseTest25(void)
1773 {
1774  DetectEngineCtx *de_ctx = NULL;
1775  int result = 1;
1776 
1778  if (de_ctx == NULL)
1779  goto end;
1780 
1781  de_ctx->flags |= DE_QUIET;
1783  "alert udp any any -> any any "
1784  "(msg:\"test\"; content:\"|\"; sid:1;)");
1785  if (de_ctx->sig_list != NULL) {
1786  result = 0;
1787  goto end;
1788  }
1789 
1790  end:
1794 
1795  return result;
1796 }
1797 
1798 /**
1799  * \test Parsing test
1800  */
1801 static int DetectContentParseTest26(void)
1802 {
1803  DetectEngineCtx *de_ctx = NULL;
1804  int result = 1;
1805 
1807  if (de_ctx == NULL)
1808  goto end;
1809 
1810  de_ctx->flags |= DE_QUIET;
1812  "alert udp any any -> any any "
1813  "(msg:\"test\"; content:\"|af\"; sid:1;)");
1814  if (de_ctx->sig_list != NULL) {
1815  result = 0;
1816  goto end;
1817  }
1818 
1819  end:
1823 
1824  return result;
1825 }
1826 
1827 /**
1828  * \test Parsing test
1829  */
1830 static int DetectContentParseTest27(void)
1831 {
1832  DetectEngineCtx *de_ctx = NULL;
1833  int result = 1;
1834 
1836  if (de_ctx == NULL)
1837  goto end;
1838 
1839  de_ctx->flags |= DE_QUIET;
1841  "alert udp any any -> any any "
1842  "(msg:\"test\"; content:\"af|\"; sid:1;)");
1843  if (de_ctx->sig_list != NULL) {
1844  result = 0;
1845  goto end;
1846  }
1847 
1848  end:
1852 
1853  return result;
1854 }
1855 
1856 /**
1857  * \test Parsing test
1858  */
1859 static int DetectContentParseTest28(void)
1860 {
1861  DetectEngineCtx *de_ctx = NULL;
1862  int result = 1;
1863 
1865  if (de_ctx == NULL)
1866  goto end;
1867 
1868  de_ctx->flags |= DE_QUIET;
1870  "alert udp any any -> any any "
1871  "(msg:\"test\"; content:\"|af|\"; sid:1;)");
1872  if (de_ctx->sig_list == NULL) {
1873  result = 0;
1874  goto end;
1875  }
1876 
1877  end:
1881 
1882  return result;
1883 }
1884 
1885 /**
1886  * \test Parsing test
1887  */
1888 static int DetectContentParseTest29(void)
1889 {
1890  DetectEngineCtx *de_ctx = NULL;
1891  int result = 1;
1892 
1894  if (de_ctx == NULL)
1895  goto end;
1896 
1897  de_ctx->flags |= DE_QUIET;
1899  "alert udp any any -> any any "
1900  "(msg:\"test\"; content:\"aast|\"; sid:1;)");
1901  if (de_ctx->sig_list != NULL) {
1902  result = 0;
1903  goto end;
1904  }
1905 
1906  end:
1910 
1911  return result;
1912 }
1913 
1914 /**
1915  * \test Parsing test
1916  */
1917 static int DetectContentParseTest30(void)
1918 {
1919  DetectEngineCtx *de_ctx = NULL;
1920  int result = 1;
1921 
1923  if (de_ctx == NULL)
1924  goto end;
1925 
1926  de_ctx->flags |= DE_QUIET;
1928  "alert udp any any -> any any "
1929  "(msg:\"test\"; content:\"aast|af\"; sid:1;)");
1930  if (de_ctx->sig_list != NULL) {
1931  result = 0;
1932  goto end;
1933  }
1934 
1935  end:
1939 
1940  return result;
1941 }
1942 
1943 /**
1944  * \test Parsing test
1945  */
1946 static int DetectContentParseTest31(void)
1947 {
1948  DetectEngineCtx *de_ctx = NULL;
1949  int result = 1;
1950 
1952  if (de_ctx == NULL)
1953  goto end;
1954 
1955  de_ctx->flags |= DE_QUIET;
1957  "alert udp any any -> any any "
1958  "(msg:\"test\"; content:\"aast|af|\"; sid:1;)");
1959  if (de_ctx->sig_list == NULL) {
1960  result = 0;
1961  goto end;
1962  }
1963 
1964  end:
1968 
1969  return result;
1970 }
1971 
1972 /**
1973  * \test Parsing test
1974  */
1975 static int DetectContentParseTest32(void)
1976 {
1977  DetectEngineCtx *de_ctx = NULL;
1978  int result = 1;
1979 
1981  if (de_ctx == NULL)
1982  goto end;
1983 
1984  de_ctx->flags |= DE_QUIET;
1986  "alert udp any any -> any any "
1987  "(msg:\"test\"; content:\"|af|asdf\"; sid:1;)");
1988  if (de_ctx->sig_list == NULL) {
1989  result = 0;
1990  goto end;
1991  }
1992 
1993  end:
1997 
1998  return result;
1999 }
2000 
2001 /**
2002  * \test Parsing test
2003  */
2004 static int DetectContentParseTest33(void)
2005 {
2006  DetectEngineCtx *de_ctx = NULL;
2007  int result = 1;
2008 
2010  if (de_ctx == NULL)
2011  goto end;
2012 
2013  de_ctx->flags |= DE_QUIET;
2015  "alert udp any any -> any any "
2016  "(msg:\"test\"; content:\"|af|af|\"; sid:1;)");
2017  if (de_ctx->sig_list != NULL) {
2018  result = 0;
2019  goto end;
2020  }
2021 
2022  end:
2026 
2027  return result;
2028 }
2029 
2030 /**
2031  * \test Parsing test
2032  */
2033 static int DetectContentParseTest34(void)
2034 {
2035  DetectEngineCtx *de_ctx = NULL;
2036  int result = 1;
2037 
2039  if (de_ctx == NULL)
2040  goto end;
2041 
2042  de_ctx->flags |= DE_QUIET;
2044  "alert udp any any -> any any "
2045  "(msg:\"test\"; content:\"|af|af|af\"; sid:1;)");
2046  if (de_ctx->sig_list != NULL) {
2047  result = 0;
2048  goto end;
2049  }
2050 
2051  end:
2055 
2056  return result;
2057 }
2058 
2059 /**
2060  * \test Parsing test
2061  */
2062 static int DetectContentParseTest35(void)
2063 {
2064  DetectEngineCtx *de_ctx = NULL;
2065  int result = 1;
2066 
2068  if (de_ctx == NULL)
2069  goto end;
2070 
2071  de_ctx->flags |= DE_QUIET;
2073  "alert udp any any -> any any "
2074  "(msg:\"test\"; content:\"|af|af|af|\"; sid:1;)");
2075  if (de_ctx->sig_list == NULL) {
2076  result = 0;
2077  goto end;
2078  }
2079 
2080  end:
2084 
2085  return result;
2086 }
2087 
2088 /**
2089  * \test Parsing test: file_data
2090  */
2091 static int DetectContentParseTest36(void)
2092 {
2093  DetectEngineCtx *de_ctx = NULL;
2094  int result = 0;
2095 
2097  if (de_ctx == NULL)
2098  goto end;
2099 
2100  de_ctx->flags |= DE_QUIET;
2102  "alert tcp any any -> any any "
2103  "(msg:\"test\"; file_data; content:\"abc\"; sid:1;)");
2104  if (de_ctx->sig_list == NULL) {
2105  printf("sig parse failed: ");
2106  goto end;
2107  }
2108 
2109  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2110  printf("content still in PMATCH list: ");
2111  goto end;
2112  }
2113 
2114  if (de_ctx->sig_list->sm_lists[g_file_data_buffer_id] == NULL) {
2115  printf("content not in FILEDATA list: ");
2116  goto end;
2117  }
2118 
2119  result = 1;
2120 end:
2124 
2125  return result;
2126 }
2127 
2128 /**
2129  * \test Parsing test: file_data
2130  */
2131 static int DetectContentParseTest37(void)
2132 {
2133  DetectEngineCtx *de_ctx = NULL;
2134  int result = 0;
2135 
2137  if (de_ctx == NULL)
2138  goto end;
2139 
2140  de_ctx->flags |= DE_QUIET;
2142  "alert tcp any any -> any any "
2143  "(msg:\"test\"; file_data; content:\"abc\"; content:\"def\"; sid:1;)");
2144  if (de_ctx->sig_list == NULL) {
2145  printf("sig parse failed: ");
2146  goto end;
2147  }
2148 
2149  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2150  printf("content still in PMATCH list: ");
2151  goto end;
2152  }
2153 
2154  if (de_ctx->sig_list->sm_lists[g_file_data_buffer_id] == NULL) {
2155  printf("content not in FILEDATA list: ");
2156  goto end;
2157  }
2158 
2159  result = 1;
2160 end:
2164 
2165  return result;
2166 }
2167 
2168 /**
2169  * \test Parsing test: file_data
2170  */
2171 static int DetectContentParseTest38(void)
2172 {
2173  DetectEngineCtx *de_ctx = NULL;
2174  int result = 0;
2175 
2177  if (de_ctx == NULL)
2178  goto end;
2179 
2180  de_ctx->flags |= DE_QUIET;
2182  "alert tcp any any -> any any "
2183  "(msg:\"test\"; file_data; content:\"abc\"; content:\"def\"; within:8; sid:1;)");
2184  if (de_ctx->sig_list == NULL) {
2185  printf("sig parse failed: ");
2186  goto end;
2187  }
2188 
2189  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2190  printf("content still in PMATCH list: ");
2191  goto end;
2192  }
2193 
2194  if (de_ctx->sig_list->sm_lists[g_file_data_buffer_id] == NULL) {
2195  printf("content not in FILEDATA list: ");
2196  goto end;
2197  }
2198 
2199  result = 1;
2200 end:
2204 
2205  return result;
2206 }
2207 
2208 static int SigTestPositiveTestContent(const char *rule, uint8_t *buf)
2209 {
2210  uint16_t buflen = strlen((char *)buf);
2211  ThreadVars th_v;
2212  DetectEngineThreadCtx *det_ctx = NULL;
2213 
2214  memset(&th_v, 0, sizeof(th_v));
2215  Packet *p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
2216  FAIL_IF_NULL(p);
2217 
2220  de_ctx->flags |= DE_QUIET;
2221 
2222  de_ctx->sig_list = SigInit(de_ctx, rule);
2224 
2226  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2227  FAIL_IF_NULL(det_ctx);
2228 
2229  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2230 
2231  FAIL_IF(PacketAlertCheck(p, 1) != 1);
2232 
2233  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2235 
2236  UTHFreePackets(&p, 1);
2237  PASS;
2238 }
2239 
2240 /**
2241  * \test Parsing test: file_data, within relative to file_data
2242  */
2243 static int DetectContentParseTest39(void)
2244 {
2245  DetectEngineCtx *de_ctx = NULL;
2246  int result = 0;
2247 
2249  if (de_ctx == NULL)
2250  goto end;
2251 
2252  de_ctx->flags |= DE_QUIET;
2254  "alert tcp any any -> any any "
2255  "(msg:\"test\"; file_data; content:\"abc\"; within:8; sid:1;)");
2256  if (de_ctx->sig_list == NULL) {
2257  printf("sig parse failed: ");
2258  goto end;
2259  }
2260 
2261  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2262  printf("content still in PMATCH list: ");
2263  goto end;
2264  }
2265 
2266  if (de_ctx->sig_list->sm_lists[g_file_data_buffer_id] == NULL) {
2267  printf("content not in FILEDATA list: ");
2268  goto end;
2269  }
2270 
2271  result = 1;
2272 end:
2276 
2277  return result;
2278 }
2279 
2280 /**
2281  * \test Parsing test: file_data, distance relative to file_data
2282  */
2283 static int DetectContentParseTest40(void)
2284 {
2285  DetectEngineCtx *de_ctx = NULL;
2286  int result = 0;
2287 
2289  if (de_ctx == NULL)
2290  goto end;
2291 
2292  de_ctx->flags |= DE_QUIET;
2294  "alert tcp any any -> any any "
2295  "(msg:\"test\"; file_data; content:\"abc\"; distance:3; sid:1;)");
2296  if (de_ctx->sig_list == NULL) {
2297  printf("sig parse failed: ");
2298  goto end;
2299  }
2300 
2301  if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
2302  printf("content still in PMATCH list: ");
2303  goto end;
2304  }
2305 
2306  if (de_ctx->sig_list->sm_lists[g_file_data_buffer_id] == NULL) {
2307  printf("content not in FILEDATA list: ");
2308  goto end;
2309  }
2310 
2311  result = 1;
2312 end:
2316 
2317  return result;
2318 }
2319 
2320 static int DetectContentParseTest41(void)
2321 {
2322  int result = 1;
2323  DetectContentData *cd = NULL;
2324  int patlen = 255;
2325  char *teststring = SCMalloc(sizeof(char) * (patlen + 1));
2326  if (unlikely(teststring == NULL))
2327  return 0;
2328  int idx = 0;
2329  for (int i = 0; i < patlen; idx++, i++) {
2330  teststring[idx] = 'a';
2331  }
2332  teststring[idx++] = '\0';
2333 
2334  uint16_t spm_matcher = SinglePatternMatchDefaultMatcher();
2335  SpmGlobalThreadCtx *spm_global_thread_ctx = SpmInitGlobalThreadCtx(spm_matcher);
2336  FAIL_IF(spm_global_thread_ctx == NULL);
2337 
2338  cd = DetectContentParse(spm_global_thread_ctx, teststring);
2339  if (cd == NULL) {
2340  SCLogDebug("expected not NULL");
2341  result = 0;
2342  }
2343 
2344  SpmDestroyGlobalThreadCtx(spm_global_thread_ctx);
2345  SCFree(teststring);
2346  DetectContentFree(NULL, cd);
2347  return result;
2348 }
2349 
2350 /**
2351  * Tests that content lengths > 255 are supported.
2352  */
2353 static int DetectContentParseTest42(void)
2354 {
2355  int result = 1;
2356  DetectContentData *cd = NULL;
2357  int patlen = 256;
2358  char *teststring = SCMalloc(sizeof(char) * (patlen + 1));
2359  if (unlikely(teststring == NULL))
2360  return 0;
2361  int idx = 0;
2362  for (int i = 0; i < patlen; idx++, i++) {
2363  teststring[idx] = 'a';
2364  }
2365  teststring[idx++] = '\0';
2366 
2367  uint16_t spm_matcher = SinglePatternMatchDefaultMatcher();
2368  SpmGlobalThreadCtx *spm_global_thread_ctx = SpmInitGlobalThreadCtx(spm_matcher);
2369  FAIL_IF(spm_global_thread_ctx == NULL);
2370 
2371  cd = DetectContentParse(spm_global_thread_ctx, teststring);
2372  if (cd == NULL) {
2373  SCLogDebug("expected not NULL");
2374  result = 0;
2375  }
2376 
2377  SpmDestroyGlobalThreadCtx(spm_global_thread_ctx);
2378  SCFree(teststring);
2379  DetectContentFree(NULL, cd);
2380  return result;
2381 }
2382 
2383 static int DetectContentParseTest43(void)
2384 {
2385  int result = 1;
2386  DetectContentData *cd = NULL;
2387  int patlen = 258;
2388  char *teststring = SCMalloc(sizeof(char) * (patlen + 1));
2389  if (unlikely(teststring == NULL))
2390  return 0;
2391  int idx = 0;
2392  teststring[idx++] = '|';
2393  teststring[idx++] = '4';
2394  teststring[idx++] = '6';
2395  teststring[idx++] = '|';
2396  for (int i = 0; i < (patlen - 4); idx++, i++) {
2397  teststring[idx] = 'a';
2398  }
2399  teststring[idx++] = '\0';
2400 
2401  uint16_t spm_matcher = SinglePatternMatchDefaultMatcher();
2402  SpmGlobalThreadCtx *spm_global_thread_ctx = SpmInitGlobalThreadCtx(spm_matcher);
2403  FAIL_IF(spm_global_thread_ctx == NULL);
2404 
2405  cd = DetectContentParse(spm_global_thread_ctx, teststring);
2406  if (cd == NULL) {
2407  SCLogDebug("expected not NULL");
2408  result = 0;
2409  }
2410 
2411  SpmDestroyGlobalThreadCtx(spm_global_thread_ctx);
2412  SCFree(teststring);
2413  DetectContentFree(NULL, cd);
2414  return result;
2415 }
2416 
2417 /**
2418  * Tests that content lengths > 255 are supported.
2419  */
2420 static int DetectContentParseTest44(void)
2421 {
2422  int result = 1;
2423  DetectContentData *cd = NULL;
2424  int patlen = 259;
2425  char *teststring = SCMalloc(sizeof(char) * (patlen + 1));
2426  if (unlikely(teststring == NULL))
2427  return 0;
2428  int idx = 0;
2429  teststring[idx++] = '|';
2430  teststring[idx++] = '4';
2431  teststring[idx++] = '6';
2432  teststring[idx++] = '|';
2433  for (int i = 0; i < (patlen - 4); idx++, i++) {
2434  teststring[idx] = 'a';
2435  }
2436  teststring[idx++] = '\0';
2437 
2438  uint16_t spm_matcher = SinglePatternMatchDefaultMatcher();
2439  SpmGlobalThreadCtx *spm_global_thread_ctx = SpmInitGlobalThreadCtx(spm_matcher);
2440  FAIL_IF(spm_global_thread_ctx == NULL);
2441 
2442  cd = DetectContentParse(spm_global_thread_ctx, teststring);
2443  if (cd == NULL) {
2444  SCLogDebug("expected not NULL");
2445  result = 0;
2446  }
2447 
2448  SpmDestroyGlobalThreadCtx(spm_global_thread_ctx);
2449  SCFree(teststring);
2450  DetectContentFree(NULL, cd);
2451  return result;
2452 }
2453 
2454 /**
2455  * \test Parsing test to check for unescaped quote within content section
2456  */
2457 static int DetectContentParseTest45(void)
2458 {
2459  DetectEngineCtx *de_ctx = NULL;
2460 
2463 
2464  de_ctx->flags |= DE_QUIET;
2466  "alert tcp any any -> any any "
2467  "(msg:\"test\"; content:\"|ff|\" content:\"TEST\"; sid:1;)");
2469 
2471 
2472  PASS;
2473 }
2474 
2475 static int SigTestNegativeTestContent(const char *rule, uint8_t *buf)
2476 {
2477  uint16_t buflen = strlen((char *)buf);
2478  Packet *p = NULL;
2479  ThreadVars th_v;
2480  DetectEngineThreadCtx *det_ctx = NULL;
2481  int result = 0;
2482  memset(&th_v, 0, sizeof(th_v));
2483 
2484  p = UTHBuildPacket(buf, buflen, IPPROTO_TCP);
2485 
2487  if (de_ctx == NULL)
2488  goto end;
2489 
2490  de_ctx->flags |= DE_QUIET;
2491 
2492  de_ctx->sig_list = SigInit(de_ctx, rule);
2493  if (de_ctx->sig_list == NULL) {
2494  goto end;
2495  }
2496 
2498  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
2499 
2500  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
2501  if (PacketAlertCheck(p, 1) != 0) {
2502  goto end;
2503  }
2504 
2505  result = 1;
2506 end:
2507  if (det_ctx != NULL) {
2508  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
2509  }
2510  if (de_ctx != NULL) {
2514  }
2515  UTHFreePackets(&p, 1);
2516  return result;
2517 }
2518 
2519 /**
2520  * \test A positive test that checks that the content string doesn't contain
2521  * the negated content
2522  */
2523 static int SigTest41TestNegatedContent(void)
2524 {
2525  return SigTestPositiveTestContent("alert tcp any any -> any any "
2526  "(msg:\"HTTP URI cap\"; content:!\"GES\"; sid:1;)",
2527 
2528  (uint8_t *)"GET /one/ HTTP/1.1\r\n Host: one.example.org\r\n\r\n\r\n"
2529  "GET /two/ HTTP/1.1\r\nHost: two.example.org\r\n\r\n\r\n");
2530 }
2531 
2532 /**
2533  * \test crash condition: as packet has no direction, it defaults to toclient
2534  * in stream ctx inspection of packet. There a null ptr deref happens
2535  * We don't care about the match/nomatch here.
2536  */
2537 static int SigTest41aTestNegatedContent(void)
2538 {
2539  (void)SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; flow:to_server; content:\"GET\"; sid:1;)", (uint8_t *)"GET /one/ HTTP/1.1\r\n Host: one.example.org\r\n\r\n\r\nGET /two/ HTTP/1.1\r\nHost: two.example.org\r\n\r\n\r\n");
2540  return 1;
2541 }
2542 
2543 
2544 /**
2545  * \test A positive test that checks that the content string doesn't contain
2546  * the negated content within the specified depth
2547  */
2548 static int SigTest42TestNegatedContent(void)
2549 { // 01 5 10 15 20 24
2550  return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:!\"twentythree\"; depth:22; offset:35; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2551 }
2552 
2553 /**
2554  * \test A negative test that checks that the content string doesn't contain
2555  * the negated content within the specified depth, and also after the
2556  * specified offset. Since the content is there, the match fails.
2557  *
2558  * Match is at offset:23, depth:34
2559  */
2560 static int SigTest43TestNegatedContent(void)
2561 {
2562  return SigTestNegativeTestContent("alert tcp any any -> any any (content:!\"twentythree\"; depth:34; offset:23; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2563 }
2564 
2565 /**
2566  * \test A negative test that checks that the content string doesn't contain
2567  * the negated content after the specified offset and within the specified
2568  * depth.
2569  */
2570 static int SigTest44TestNegatedContent(void)
2571 {
2572  return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:!\"twentythree\"; offset:40; depth:35; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2573 }
2574 
2575 /**
2576  * \test A positive test that uses a combination of content string with negated
2577  * content string
2578  */
2579 static int SigTest45TestNegatedContent(void)
2580 {
2581  return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; depth:5; content:!\"twentythree\"; depth:23; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2582 }
2583 
2584 /**
2585  * \test A negative test that uses a combination of content string with negated
2586  * content string, with we receiving a failure for 'onee' itself.
2587  */
2588 static int SigTest46TestNegatedContent(void)
2589 {
2590  return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"onee\"; content:!\"twentythree\"; depth:23; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2591 }
2592 
2593 /**
2594  * \test A negative test that uses a combination of content string with negated
2595  * content string, with we receiving a failure of first content's offset
2596  * condition
2597  */
2598 static int SigTest47TestNegatedContent(void)
2599 {
2600  return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; offset:5; content:!\"twentythree\"; depth:23; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2601 }
2602 
2603 /**
2604  * \test A positive test that checks that we don't have a negated content within
2605  * the specified length from the previous content match.
2606  */
2607 static int SigTest48TestNegatedContent(void)
2608 {
2609  return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"GET\"; content:!\"GES\"; within:26; sid:1;)", (uint8_t *)"GET /one/ HTTP/1.1\r\n Host: one.example.org\r\n\r\n\r\nGET /two/ HTTP/1.1\r\nHost: two.example.org\r\n\r\n\r\n");
2610 }
2611 
2612 /**
2613  * \test A negative test that checks the combined use of content and negated
2614  * content with the use of within
2615  */
2616 static int SigTest49TestNegatedContent(void)
2617 {
2618  return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"GET\"; content:!\"Host\"; within:26; sid:1;)", (uint8_t *)"GET /one/ HTTP/1.1\r\n Host: one.example.org\r\n\r\n\r\nGET /two/ HTTP/1.1\r\nHost: two.example.org\r\n\r\n\r\n");
2619 }
2620 
2621 /**
2622  * \test A positive test that checks the combined use of content and negated
2623  * content with the use of distance
2624  */
2625 static int SigTest50TestNegatedContent(void)
2626 {
2627  return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"GET\"; content:!\"GES\"; distance:25; sid:1;)", (uint8_t *)"GET /one/ HTTP/1.1\r\n Host: one.example.org\r\n\r\n\r\nGET /two/ HTTP/1.1\r\nHost: two.example.org\r\n\r\n\r\n");
2628 }
2629 
2630 /**
2631  * \test A negative test that checks the combined use of content and negated
2632  * content with the use of distance
2633  *
2634  * First GET at offset 0
2635  * First Host at offset 21
2636  */
2637 static int SigTest51TestNegatedContent(void)
2638 {
2639  return SigTestNegativeTestContent("alert tcp any any -> any any (content:\"GET\"; content:!\"Host\"; distance:17; sid:1;)", (uint8_t *)"GET /one/ HTTP/1.1\r\nHost: one.example.org\r\n\r\n\r\nGET /two/ HTTP/1.1\r\nHost: two.example.org\r\n\r\n\r\n");
2640 }
2641 
2642 /**
2643  * \test A negative test that checks the combined use of content and negated
2644  * content, with the content not being present
2645  */
2646 static int SigTest52TestNegatedContent(void)
2647 {
2648  return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"GES\"; content:!\"BOO\"; sid:1;)", (uint8_t *)"GET /one/ HTTP/1.1\r\n Host: one.example.org\r\n\r\n\r\nGET /two/ HTTP/1.1\r\nHost: two.example.org\r\n\r\n\r\n");
2649 }
2650 
2651 /**
2652  * \test A negative test that checks the combined use of content and negated
2653  * content, in the presence of within
2654  */
2655 static int SigTest53TestNegatedContent(void)
2656 {
2657  return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; content:!\"fourty\"; within:56; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2658 }
2659 
2660 /**
2661  * \test A positive test that checks the combined use of content and negated
2662  * content, in the presence of within
2663  */
2664 static int SigTest54TestNegatedContent(void)
2665 {
2666  return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; content:!\"fourty\"; within:20; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2667 }
2668 
2669 /**
2670  * \test A negative test that checks the use of negated content along with
2671  * the presence of depth
2672  */
2673 static int SigTest55TestNegatedContent(void)
2674 {
2675  return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:!\"one\"; depth:5; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2676 }
2677 
2678 /**
2679  * \test A positive test that checks the combined use of 2 contents in the
2680  * presence of within
2681  */
2682 static int SigTest56TestNegatedContent(void)
2683 {
2684  return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; content:\"fourty\"; within:56; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2685 }
2686 
2687 /**
2688  * \test A negative test that checks the combined use of content and negated
2689  * content, in the presence of within
2690  */
2691 static int SigTest57TestNegatedContent(void)
2692 {
2693  return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; content:!\"fourty\"; within:56; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2694 }
2695 
2696 /**
2697  * \test A positive test that checks the combined use of content and negated
2698  * content, in the presence of distance
2699  */
2700 static int SigTest58TestNegatedContent(void)
2701 {
2702  return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; content:!\"fourty\"; distance:57; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2703 }
2704 
2705 /**
2706  * \test A negative test that checks the combined use of content and negated
2707  * content, in the presence of distance
2708  */
2709 static int SigTest59TestNegatedContent(void)
2710 {
2711  return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; content:!\"fourty\"; distance:30; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2712 }
2713 
2714 static int SigTest60TestNegatedContent(void)
2715 {
2716  return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:!\"one\"; content:\"fourty\"; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2717 }
2718 
2719 static int SigTest61TestNegatedContent(void)
2720 {
2721  return SigTestPositiveTestContent("alert tcp any any -> any any (content:\"one\"; depth:10; content:!\"fourty\"; within:30; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2722 }
2723 
2724 /** \test Test negation in combination with within and depth
2725  *
2726  * Match of "one" at offset:0, depth:3
2727  * Match of "fourty" at offset:46, depth:52
2728  *
2729  * This signature should not match for the test to pass.
2730  */
2731 static int SigTest62TestNegatedContent(void)
2732 {
2733  return SigTestNegativeTestContent("alert tcp any any -> any any (content:\"one\"; depth:10; content:!\"fourty\"; within:49; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2734 }
2735 
2736 static int SigTest63TestNegatedContent(void)
2737 {
2738  return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; depth:10; content:!\"fourty\"; within:56; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2739 }
2740 
2741 static int SigTest64TestNegatedContent(void)
2742 {
2743  return SigTestPositiveTestContent("alert tcp any any -> any any (content:\"one\"; depth:10; content:!\"fourty\"; within:30; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2744 }
2745 
2746 /** \test Test negation in combination with within and depth
2747  *
2748  * Match of "one" at offset:0, depth:3
2749  * Match of "fourty" at offset:46, depth:52
2750  *
2751  * This signature should not match for the test to pass.
2752  */
2753 static int SigTest65TestNegatedContent(void)
2754 {
2755  return SigTestNegativeTestContent("alert tcp any any -> any any (content:\"one\"; depth:10; content:!\"fourty\"; distance:0; within:49; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2756 }
2757 
2758 static int SigTest66TestNegatedContent(void)
2759 {
2760  return SigTestPositiveTestContent("alert tcp any any -> any any (content:\"one\"; depth:10; content:!\"fourty\"; within:30; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2761 }
2762 
2763 static int SigTest67TestNegatedContent(void)
2764 {
2765  return SigTestNegativeTestContent("alert tcp any any -> any any (content:\"one\"; depth:10; content:!\"four\"; within:56; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2766 }
2767 
2768 static int SigTest68TestNegatedContent(void)
2769 {
2770  return SigTestPositiveTestContent("alert tcp any any -> any any (content:\"one\"; depth:10; content:\"nine\"; offset:8; content:!\"fourty\"; within:28; content:\"fiftysix\"; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2771 }
2772 
2773 static int SigTest69TestNegatedContent(void)
2774 {
2775  return SigTestNegativeTestContent("alert tcp any any -> any any (content:\"one\"; depth:10; content:\"nine\"; offset:8; content:!\"fourty\"; within:48; content:\"fiftysix\"; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2776 }
2777 
2778 static int SigTest70TestNegatedContent(void)
2779 {
2780  return SigTestNegativeTestContent("alert tcp any any -> any any (content:\"one\"; content:!\"fourty\"; within:52; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2781 }
2782 
2783 /** \test within and distance */
2784 static int SigTest71TestNegatedContent(void)
2785 {
2786  return SigTestNegativeTestContent("alert tcp any any -> any any (content:\"one\"; content:!\"fourty\"; within:40; distance:43; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2787 }
2788 
2789 static int SigTest72TestNegatedContent(void)
2790 {
2791  return SigTestNegativeTestContent("alert tcp any any -> any any (content:\"one\"; content:!\"fourty\"; within:49; distance:43; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2792 }
2793 
2794 static int SigTest73TestNegatedContent(void)
2795 {
2796  return SigTestNegativeTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"one\"; depth:5; content:!\"twentythree\"; depth:35; sid:1;)", (uint8_t *)"one four nine fourteen twentythree thirtyfive fourtysix fiftysix");
2797 }
2798 
2799 static int SigTest74TestNegatedContent(void)
2800 {
2801  return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"USER\"; content:!\"PASS\"; sid:1;)", (uint8_t *)"USER apple");
2802 }
2803 
2804 static int SigTest75TestNegatedContent(void)
2805 {
2806  return SigTestPositiveTestContent("alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"USER\"; content:\"!PASS\"; sid:1;)", (uint8_t *)"USER !PASS");
2807 }
2808 
2809 static int SigTest76TestBug134(void)
2810 {
2811  uint8_t *buf = (uint8_t *)"test detect ${IFS} in traffic";
2812  uint16_t buflen = strlen((char *)buf);
2813  Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_TCP);
2814  int result = 0;
2815  Flow f;
2816 
2817  memset(&f, 0, sizeof(Flow));
2818  FLOW_INITIALIZE(&f);
2819 
2820  p->dp = 515;
2823  p->flow = &f;
2824  p->flags |= PKT_HAS_FLOW;
2825 
2826  char sig[] = "alert tcp any any -> any 515 "
2827  "(msg:\"detect IFS\"; flow:to_server,established; content:\"${IFS}\";"
2828  " depth:50; offset:0; sid:900091; rev:1;)";
2829  if (UTHPacketMatchSigMpm(p, sig, MPM_AC) == 0) {
2830  result = 0;
2831  goto end;
2832  }
2833 
2834  result = 1;
2835 end:
2836  if (p != NULL)
2837  UTHFreePacket(p);
2838 
2839  FLOW_DESTROY(&f);
2840  return result;
2841 }
2842 
2843 static int SigTest77TestBug139(void)
2844 {
2845  uint8_t buf[] = {
2846  0x12, 0x23, 0x34, 0x35, 0x52, 0x52, 0x24, 0x42, 0x22, 0x24,
2847  0x52, 0x24, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x34 };
2848  uint16_t buflen = sizeof(buf);
2849  Packet *p = UTHBuildPacket( buf, buflen, IPPROTO_UDP);
2850  int result = 0;
2851 
2852  p->dp = 53;
2853  char sig[] = "alert udp any any -> any 53 (msg:\"dns testing\";"
2854  " content:\"|00 00|\"; depth:5; offset:13; sid:9436601;"
2855  " rev:1;)";
2856  if (UTHPacketMatchSigMpm(p, sig, MPM_AC) == 0) {
2857  result = 0;
2858  goto end;
2859  }
2860 
2861  result = 1;
2862 end:
2863  if (p != NULL)
2864  UTHFreePacket(p);
2865  return result;
2866 }
2867 
2868 static int DetectLongContentTestCommon(const char *sig, uint32_t sid)
2869 {
2870  /* Packet with 512 A's in it for testing long content. */
2871  static uint8_t pkt[739] = {
2872  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2873  0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
2874  0x02, 0xd5, 0x4a, 0x18, 0x40, 0x00, 0x40, 0x06,
2875  0xd7, 0xd6, 0x0a, 0x10, 0x01, 0x0b, 0x0a, 0x10,
2876  0x01, 0x0a, 0xdb, 0x36, 0x00, 0x50, 0xca, 0xc5,
2877  0xcc, 0xd1, 0x95, 0x77, 0x0f, 0x7d, 0x80, 0x18,
2878  0x00, 0xe5, 0x77, 0x9d, 0x00, 0x00, 0x01, 0x01,
2879  0x08, 0x0a, 0x1d, 0xe0, 0x86, 0xc6, 0xfc, 0x73,
2880  0x49, 0xf3, 0x50, 0x4f, 0x53, 0x54, 0x20, 0x2f,
2881  0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e,
2882  0x31, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2883  0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x63,
2884  0x75, 0x72, 0x6c, 0x2f, 0x37, 0x2e, 0x33, 0x37,
2885  0x2e, 0x30, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74,
2886  0x3a, 0x20, 0x31, 0x30, 0x2e, 0x31, 0x36, 0x2e,
2887  0x31, 0x2e, 0x31, 0x30, 0x0d, 0x0a, 0x41, 0x63,
2888  0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f,
2889  0x2a, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65,
2890  0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74,
2891  0x68, 0x3a, 0x20, 0x35, 0x32, 0x38, 0x0d, 0x0a,
2892  0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d,
2893  0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70,
2894  0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
2895  0x6e, 0x2f, 0x78, 0x2d, 0x77, 0x77, 0x77, 0x2d,
2896  0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x75, 0x72, 0x6c,
2897  0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x0d,
2898  0x0a, 0x0d, 0x0a, 0x58, 0x58, 0x58, 0x58, 0x58,
2899  0x58, 0x58, 0x58, 0x41, 0x41, 0x41, 0x41, 0x41,
2900  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2901  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2902  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2903  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2904  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2905  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2906  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2907  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2908  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2909  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2910  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2911  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2912  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2913  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2914  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2915  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2916  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2917  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2918  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2919  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2920  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2921  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2922  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2923  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2924  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2925  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2926  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2927  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2928  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2929  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2930  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2931  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2932  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2933  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2934  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2935  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2936  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2937  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2938  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2939  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2940  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2941  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2942  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2943  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2944  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2945  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2946  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2947  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2948  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2949  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2950  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2951  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2952  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2953  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2954  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2955  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2956  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2957  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2958  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2959  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2960  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2961  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2962  0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
2963  0x41, 0x41, 0x41, 0x58, 0x58, 0x58, 0x58, 0x58,
2964  0x58, 0x58, 0x58
2965  };
2966 
2967  return DetectContentLongPatternMatchTest(pkt, (uint16_t)sizeof(pkt), sig,
2968  sid);
2969 }
2970 
2971 static int DetectLongContentTest1(void)
2972 {
2973  /* Signature with 256 A's. */
2974  const char *sig = "alert tcp any any -> any any (msg:\"Test Rule\"; content:\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"; sid:1;)";
2975 
2976  return DetectLongContentTestCommon(sig, 1);
2977 }
2978 
2979 static int DetectLongContentTest2(void)
2980 {
2981  /* Signature with 512 A's. */
2982  const char *sig = "alert tcp any any -> any any (msg:\"Test Rule\"; content:\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"; sid:1;)";
2983 
2984  return DetectLongContentTestCommon(sig, 1);
2985 }
2986 
2987 static int DetectLongContentTest3(void)
2988 {
2989  /* Signature with 513 A's. */
2990  const char *sig = "alert tcp any any -> any any (msg:\"Test Rule\"; content:\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"; sid:1;)";
2991 
2992  return !DetectLongContentTestCommon(sig, 1);
2993 }
2994 
2995 #endif /* UNITTESTS */
2996 
2997 /**
2998  * \brief this function registers unit tests for DetectContent
2999  */
3000 static void DetectContentRegisterTests(void)
3001 {
3002 #ifdef UNITTESTS /* UNITTESTS */
3003  g_file_data_buffer_id = DetectBufferTypeGetByName("file_data");
3004  g_dce_stub_data_buffer_id = DetectBufferTypeGetByName("dce_stub_data");
3005 
3006  UtRegisterTest("DetectContentDepthTest01", DetectContentDepthTest01);
3007 
3008  UtRegisterTest("DetectContentParseTest01", DetectContentParseTest01);
3009  UtRegisterTest("DetectContentParseTest02", DetectContentParseTest02);
3010  UtRegisterTest("DetectContentParseTest03", DetectContentParseTest03);
3011  UtRegisterTest("DetectContentParseTest04", DetectContentParseTest04);
3012  UtRegisterTest("DetectContentParseTest05", DetectContentParseTest05);
3013  UtRegisterTest("DetectContentParseTest06", DetectContentParseTest06);
3014  UtRegisterTest("DetectContentParseTest07", DetectContentParseTest07);
3015  UtRegisterTest("DetectContentParseTest08", DetectContentParseTest08);
3016  UtRegisterTest("DetectContentParseTest09", DetectContentParseTest09);
3017  UtRegisterTest("DetectContentParseTest17", DetectContentParseTest17);
3018  UtRegisterTest("DetectContentParseTest18", DetectContentParseTest18);
3019  UtRegisterTest("DetectContentParseTest19", DetectContentParseTest19);
3020  UtRegisterTest("DetectContentParseTest20", DetectContentParseTest20);
3021  UtRegisterTest("DetectContentParseTest21", DetectContentParseTest21);
3022  UtRegisterTest("DetectContentParseTest22", DetectContentParseTest22);
3023  UtRegisterTest("DetectContentParseTest23", DetectContentParseTest23);
3024  UtRegisterTest("DetectContentParseTest24", DetectContentParseTest24);
3025  UtRegisterTest("DetectContentParseTest25", DetectContentParseTest25);
3026  UtRegisterTest("DetectContentParseTest26", DetectContentParseTest26);
3027  UtRegisterTest("DetectContentParseTest27", DetectContentParseTest27);
3028  UtRegisterTest("DetectContentParseTest28", DetectContentParseTest28);
3029  UtRegisterTest("DetectContentParseTest29", DetectContentParseTest29);
3030  UtRegisterTest("DetectContentParseTest30", DetectContentParseTest30);
3031  UtRegisterTest("DetectContentParseTest31", DetectContentParseTest31);
3032  UtRegisterTest("DetectContentParseTest32", DetectContentParseTest32);
3033  UtRegisterTest("DetectContentParseTest33", DetectContentParseTest33);
3034  UtRegisterTest("DetectContentParseTest34", DetectContentParseTest34);
3035  UtRegisterTest("DetectContentParseTest35", DetectContentParseTest35);
3036  UtRegisterTest("DetectContentParseTest36", DetectContentParseTest36);
3037  UtRegisterTest("DetectContentParseTest37", DetectContentParseTest37);
3038  UtRegisterTest("DetectContentParseTest38", DetectContentParseTest38);
3039  UtRegisterTest("DetectContentParseTest39", DetectContentParseTest39);
3040  UtRegisterTest("DetectContentParseTest40", DetectContentParseTest40);
3041  UtRegisterTest("DetectContentParseTest41", DetectContentParseTest41);
3042  UtRegisterTest("DetectContentParseTest42", DetectContentParseTest42);
3043  UtRegisterTest("DetectContentParseTest43", DetectContentParseTest43);
3044  UtRegisterTest("DetectContentParseTest44", DetectContentParseTest44);
3045  UtRegisterTest("DetectContentParseTest45", DetectContentParseTest45);
3046 
3047  /* The reals */
3048  UtRegisterTest("DetectContentLongPatternMatchTest01",
3049  DetectContentLongPatternMatchTest01);
3050  UtRegisterTest("DetectContentLongPatternMatchTest02",
3051  DetectContentLongPatternMatchTest02);
3052  UtRegisterTest("DetectContentLongPatternMatchTest03",
3053  DetectContentLongPatternMatchTest03);
3054  UtRegisterTest("DetectContentLongPatternMatchTest04",
3055  DetectContentLongPatternMatchTest04);
3056  UtRegisterTest("DetectContentLongPatternMatchTest05",
3057  DetectContentLongPatternMatchTest05);
3058  UtRegisterTest("DetectContentLongPatternMatchTest06",
3059  DetectContentLongPatternMatchTest06);
3060  UtRegisterTest("DetectContentLongPatternMatchTest07",
3061  DetectContentLongPatternMatchTest07);
3062  UtRegisterTest("DetectContentLongPatternMatchTest08",
3063  DetectContentLongPatternMatchTest08);
3064  UtRegisterTest("DetectContentLongPatternMatchTest09",
3065  DetectContentLongPatternMatchTest09);
3066  UtRegisterTest("DetectContentLongPatternMatchTest10",
3067  DetectContentLongPatternMatchTest10);
3068  UtRegisterTest("DetectContentLongPatternMatchTest11",
3069  DetectContentLongPatternMatchTest11);
3070 
3071  /* Negated content tests */
3072  UtRegisterTest("SigTest41TestNegatedContent", SigTest41TestNegatedContent);
3073  UtRegisterTest("SigTest41aTestNegatedContent",
3074  SigTest41aTestNegatedContent);
3075  UtRegisterTest("SigTest42TestNegatedContent", SigTest42TestNegatedContent);
3076  UtRegisterTest("SigTest43TestNegatedContent", SigTest43TestNegatedContent);
3077  UtRegisterTest("SigTest44TestNegatedContent", SigTest44TestNegatedContent);
3078  UtRegisterTest("SigTest45TestNegatedContent", SigTest45TestNegatedContent);
3079  UtRegisterTest("SigTest46TestNegatedContent", SigTest46TestNegatedContent);
3080  UtRegisterTest("SigTest47TestNegatedContent", SigTest47TestNegatedContent);
3081  UtRegisterTest("SigTest48TestNegatedContent", SigTest48TestNegatedContent);
3082  UtRegisterTest("SigTest49TestNegatedContent", SigTest49TestNegatedContent);
3083  UtRegisterTest("SigTest50TestNegatedContent", SigTest50TestNegatedContent);
3084  UtRegisterTest("SigTest51TestNegatedContent", SigTest51TestNegatedContent);
3085  UtRegisterTest("SigTest52TestNegatedContent", SigTest52TestNegatedContent);
3086  UtRegisterTest("SigTest53TestNegatedContent", SigTest53TestNegatedContent);
3087  UtRegisterTest("SigTest54TestNegatedContent", SigTest54TestNegatedContent);
3088  UtRegisterTest("SigTest55TestNegatedContent", SigTest55TestNegatedContent);
3089  UtRegisterTest("SigTest56TestNegatedContent", SigTest56TestNegatedContent);
3090  UtRegisterTest("SigTest57TestNegatedContent", SigTest57TestNegatedContent);
3091  UtRegisterTest("SigTest58TestNegatedContent", SigTest58TestNegatedContent);
3092  UtRegisterTest("SigTest59TestNegatedContent", SigTest59TestNegatedContent);
3093  UtRegisterTest("SigTest60TestNegatedContent", SigTest60TestNegatedContent);
3094  UtRegisterTest("SigTest61TestNegatedContent", SigTest61TestNegatedContent);
3095  UtRegisterTest("SigTest62TestNegatedContent", SigTest62TestNegatedContent);
3096  UtRegisterTest("SigTest63TestNegatedContent", SigTest63TestNegatedContent);
3097  UtRegisterTest("SigTest64TestNegatedContent", SigTest64TestNegatedContent);
3098  UtRegisterTest("SigTest65TestNegatedContent", SigTest65TestNegatedContent);
3099  UtRegisterTest("SigTest66TestNegatedContent", SigTest66TestNegatedContent);
3100  UtRegisterTest("SigTest67TestNegatedContent", SigTest67TestNegatedContent);
3101  UtRegisterTest("SigTest68TestNegatedContent", SigTest68TestNegatedContent);
3102  UtRegisterTest("SigTest69TestNegatedContent", SigTest69TestNegatedContent);
3103  UtRegisterTest("SigTest70TestNegatedContent", SigTest70TestNegatedContent);
3104  UtRegisterTest("SigTest71TestNegatedContent", SigTest71TestNegatedContent);
3105  UtRegisterTest("SigTest72TestNegatedContent", SigTest72TestNegatedContent);
3106  UtRegisterTest("SigTest73TestNegatedContent", SigTest73TestNegatedContent);
3107  UtRegisterTest("SigTest74TestNegatedContent", SigTest74TestNegatedContent);
3108  UtRegisterTest("SigTest75TestNegatedContent", SigTest75TestNegatedContent);
3109 
3110  UtRegisterTest("SigTest76TestBug134", SigTest76TestBug134);
3111  UtRegisterTest("SigTest77TestBug139", SigTest77TestBug139);
3112 
3113  UtRegisterTest("DetectLongContentTest1", DetectLongContentTest1);
3114  UtRegisterTest("DetectLongContentTest2", DetectLongContentTest2);
3115  UtRegisterTest("DetectLongContentTest3", DetectLongContentTest3);
3116 #endif /* UNITTESTS */
3117 }
DETECT_CONTENT_NOCASE
#define DETECT_CONTENT_NOCASE
Definition: detect-content.h:29
DetectContentData_::offset
uint16_t offset
Definition: detect-content.h:100
host.h
SigTableElmt_::url
const char * url
Definition: detect.h:1212
DETECT_CONTENT_RELATIVE_NEXT
#define DETECT_CONTENT_RELATIVE_NEXT
Definition: detect-content.h:64
DetectSignatureSetAppProto
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
Definition: detect-parse.c:1468
detect-content.h
len
uint8_t len
Definition: app-layer-dnp3.h:2
detect-engine.h
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:90
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SigTableElmt_::desc
const char * desc
Definition: detect.h:1211
detect-dsize.h
PKT_HAS_FLOW
#define PKT_HAS_FLOW
Definition: decode.h:1087
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
ALPROTO_DCERPC
@ ALPROTO_DCERPC
Definition: app-layer-protos.h:38
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1200
flow-util.h
SigTableElmt_::name
const char * name
Definition: detect.h:1209
SigFree
void SigFree(DetectEngineCtx *, Signature *)
Definition: detect-parse.c:1369
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
DetectContentData_::within
int32_t within
Definition: detect-content.h:102
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
DETECT_CONTENT
@ DETECT_CONTENT
Definition: detect-engine-register.h:59
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
SigParseGetMaxDsize
int SigParseGetMaxDsize(const Signature *s)
get max dsize "depth"
Definition: detect-dsize.c:379
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
Packet_::flags
uint32_t flags
Definition: decode.h:446
threads.h
Flow_
Flow data structure.
Definition: flow.h:343
SigInit
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:2033
SigTableElmt_::flags
uint16_t flags
Definition: detect.h:1203
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:766
FlowInitConfig
void FlowInitConfig(char quiet)
initialize the configuration
Definition: flow.c:530
DETECT_CONTENT_RAWBYTES
#define DETECT_CONTENT_RAWBYTES
Definition: detect-content.h:38
UTHPacketMatchSigMpm
int UTHPacketMatchSigMpm(Packet *p, char *sig, uint16_t mpm_type)
Definition: util-unittest-helper.c:820
SC_ERR_INVALID_SIGNATURE
@ SC_ERR_INVALID_SIGNATURE
Definition: util-error.h:69
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2089
FLOW_PKT_TOSERVER
#define FLOW_PKT_TOSERVER
Definition: flow.h:218
MIN
#define MIN(x, y)
Definition: suricata-common.h:377
DE_QUIET
#define DE_QUIET
Definition: detect.h:293
UTHBuildPacket
Packet * UTHBuildPacket(uint8_t *payload, uint16_t payload_len, uint8_t ipproto)
UTHBuildPacket is a wrapper that build packets with default ip and port fields.
Definition: util-unittest-helper.c:336
DetectContentData_
Definition: detect-content.h:86
DetectPcreData_::flags
uint16_t flags
Definition: detect-pcre.h:48
SigCleanSignatures
void SigCleanSignatures(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:39
Packet_::flowflags
uint8_t flowflags
Definition: decode.h:442
DetectBufferGetActiveList
int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
Definition: detect-engine.c:1001
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1195
detect-pcre.h
DetectContentFree
void DetectContentFree(DetectEngineCtx *de_ctx, void *ptr)
this function will SCFree memory associated with DetectContentData
Definition: detect-content.c:370
DetectContentPMATCHValidateCallback
bool DetectContentPMATCHValidateCallback(const Signature *s)
Definition: detect-content.c:388
util-unittest.h
util-unittest-helper.h
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:876
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
Signature_::next
struct Signature_ * next
Definition: detect.h:599
SignatureInitData_::smlists_tail
struct SigMatch_ ** smlists_tail
Definition: detect.h:523
SIGMATCH_QUOTES_MANDATORY
#define SIGMATCH_QUOTES_MANDATORY
Definition: detect.h:1394
FLOW_INITIALIZE
#define FLOW_INITIALIZE(f)
Definition: flow-util.h:39
DetectContentPrint
void DetectContentPrint(DetectContentData *cd)
Helper function to print a DetectContentData.
Definition: detect-content.c:252
decode.h
FAIL_IF_NOT_NULL
#define FAIL_IF_NOT_NULL(expr)
Fail a test if expression evaluates to non-NULL.
Definition: util-unittest.h:96
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
DETECT_CONTENT_ENDS_WITH
#define DETECT_CONTENT_ENDS_WITH
Definition: detect-content.h:42
DETECT_CONTENT_DISTANCE
#define DETECT_CONTENT_DISTANCE
Definition: detect-content.h:30
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectContentSetup
int DetectContentSetup(DetectEngineCtx *de_ctx, Signature *s, const char *contentstr)
Function to setup a content pattern.
Definition: detect-content.c:318
MPM_AC
@ MPM_AC
Definition: util-mpm.h:35
DetectEngineThreadCtx_
Definition: detect.h:1009
DetectContentRegister
void DetectContentRegister(void)
Definition: detect-content.c:55
DETECT_CONTENT_DEPTH
#define DETECT_CONTENT_DEPTH
Definition: detect-content.h:33
DetectBufferTypeValidateTransform
bool DetectBufferTypeValidateTransform(DetectEngineCtx *de_ctx, int sm_list, const uint8_t *content, uint16_t content_len, const char **namestr)
Check content byte array compatibility with transforms.
Definition: detect-engine.c:1182
SignatureInitData_::list
int list
Definition: detect.h:504
util-print.h
SCEnter
#define SCEnter(...)
Definition: util-debug.h:300
detect-engine-mpm.h
detect.h
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
pkt-var.h
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:323
DETECT_CONTENT_NEGATED
#define DETECT_CONTENT_NEGATED
Definition: detect-content.h:40
DETECT_SM_LIST_MATCH
@ DETECT_SM_LIST_MATCH
Definition: detect.h:89
SIZE_OF_PACKET
#define SIZE_OF_PACKET
Definition: decode.h:621
DetectContentPropagateLimits
void DetectContentPropagateLimits(Signature *s)
apply depth/offset and distance/within to content matches
Definition: detect-content.c:436
DetectContentData_::id
PatIntId id
Definition: detect-content.h:98
TRUE
#define TRUE
Definition: suricata-common.h:33
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:322
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:282
SigMatchSignatures
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1668
SigGroupCleanup
int SigGroupCleanup(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:1949
util-profiling.h
FALSE
#define FALSE
Definition: suricata-common.h:34
SCReturn
#define SCReturn
Definition: util-debug.h:302
Signature_::flags
uint32_t flags
Definition: detect.h:528
DetectContentData_::depth
uint16_t depth
Definition: detect-content.h:99
Packet_
Definition: decode.h:411
DetectContentData_::flags
uint32_t flags
Definition: detect-content.h:97
SinglePatternMatchDefaultMatcher
uint16_t SinglePatternMatchDefaultMatcher(void)
Returns the single pattern matcher algorithm to be used, based on the spm-algo setting in yaml.
Definition: util-spm.c:68
DetectContentData_::replace_len
uint16_t replace_len
Definition: detect-content.h:89
SIGMATCH_HANDLE_NEGATION
#define SIGMATCH_HANDLE_NEGATION
Definition: detect.h:1398
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:596
detect-engine-state.h
Data structures and function prototypes for keeping state for the detection engine.
SignatureInitData_::negated
bool negated
Definition: detect.h:484
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1178
SignatureInitData_::smlists
struct SigMatch_ ** smlists
Definition: detect.h:521
DetectContentData_::replace
uint8_t * replace
Definition: detect-content.h:106
SigMatchAlloc
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:235
DETECT_PCRE
@ DETECT_PCRE
Definition: detect-engine-register.h:61
SpmDestroyGlobalThreadCtx
void SpmDestroyGlobalThreadCtx(SpmGlobalThreadCtx *global_thread_ctx)
Definition: util-spm.c:139
SigGroupBuild
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
Definition: detect-engine-build.c:1878
SigMatch_::type
uint8_t type
Definition: detect.h:320
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:30
DETECT_SM_LIST_NOTSET
#define DETECT_SM_LIST_NOTSET
Definition: detect.h:115
DetectContentDataParse
int DetectContentDataParse(const char *keyword, const char *contentstr, uint8_t **pstr, uint16_t *plen)
Parse a content string, ie "abc|DE|fgh".
Definition: detect-content.c:78
Packet_::flow
struct Flow_ * flow
Definition: decode.h:448
DetectEngineThreadCtxInit
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
Definition: detect-engine.c:2793
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
util-mpm.h
suricata-common.h
DetectEngineThreadCtxDeinit
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
Definition: detect-engine.c:3001
DetectContentData_::distance
int32_t distance
Definition: detect-content.h:101
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:685
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:73
util-spm.h
DetectContentData_::content
uint8_t * content
Definition: detect-content.h:87
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
DetectEngineCtx_::sig_list
Signature * sig_list
Definition: detect.h:772
SpmGlobalThreadCtx_
Definition: util-spm.h:49
detect-flow.h
PrintRawUriFp
void PrintRawUriFp(FILE *fp, uint8_t *buf, uint32_t buflen)
Definition: util-print.c:93
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
DetectContentData_::spm_ctx
SpmCtx * spm_ctx
Definition: detect-content.h:104
str
#define str(s)
Definition: suricata-common.h:273
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:625
UTHFreePacket
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:484
DETECT_CONTENT_OFFSET
#define DETECT_CONTENT_OFFSET
Definition: detect-content.h:32
TEST_RUN
#define TEST_RUN(sig, o, d)
Definition: detect-content.c:643
detect-parse.h
Signature_
Signature container.
Definition: detect.h:527
SigMatch_
a single match condition for a signature
Definition: detect.h:319
DETECT_SM_LIST_MAX
@ DETECT_SM_LIST_MAX
Definition: detect.h:106
FLOW_PKT_ESTABLISHED
#define FLOW_PKT_ESTABLISHED
Definition: flow.h:220
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2044
DetectPcreData_
Definition: detect-pcre.h:39
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:38
DetectContentData_::content_len
uint16_t content_len
Definition: detect-content.h:88
detect-uricontent.h
DetectEngineCtx_::spm_global_thread_ctx
SpmGlobalThreadCtx * spm_global_thread_ctx
Definition: detect.h:820
DetectContentParse
DetectContentData * DetectContentParse(SpmGlobalThreadCtx *spm_global_thread_ctx, const char *contentstr)
DetectContentParse \initonly.
Definition: detect-content.c:199
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:767
DetectContentParseEncloseQuotes
DetectContentData * DetectContentParseEncloseQuotes(SpmGlobalThreadCtx *spm_global_thread_ctx, const char *contentstr)
Definition: detect-content.c:243
SpmInitGlobalThreadCtx
SpmGlobalThreadCtx * SpmInitGlobalThreadCtx(uint16_t matcher)
Definition: util-spm.c:133
DETECT_PCRE_RELATIVE
#define DETECT_PCRE_RELATIVE
Definition: detect-pcre.h:29
SigAlloc
Signature * SigAlloc(void)
Definition: detect-parse.c:1246
flow.h
SpmDestroyCtx
void SpmDestroyCtx(SpmCtx *ctx)
Definition: util-spm.c:178
DETECT_CONTENT_FAST_PATTERN
#define DETECT_CONTENT_FAST_PATTERN
Definition: detect-content.h:34
Packet_::dp
Port dp
Definition: decode.h:426
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
flow-var.h
SpmInitCtx
SpmCtx * SpmInitCtx(const uint8_t *needle, uint16_t needle_len, int nocase, SpmGlobalThreadCtx *global_thread_ctx)
Definition: util-spm.c:168
SCLogDebugEnabled
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition: util-debug.c:662
DecodeEthernet
int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-ethernet.c:41
SigMatchAppendSMToList
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:349
FLOW_DESTROY
#define FLOW_DESTROY(f)
Definition: flow-util.h:121
DETECT_CONTENT_WITHIN
#define DETECT_CONTENT_WITHIN
Definition: detect-content.h:31
PACKET_RECYCLE
#define PACKET_RECYCLE(p)
Definition: decode.h:807
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1201
SIG_FLAG_DSIZE
#define SIG_FLAG_DSIZE
Definition: detect.h:217
TEST_DONE
#define TEST_DONE
Definition: detect-content.c:658
app-layer.h
SignatureInitData_::smlists_array_size
uint32_t smlists_array_size
Definition: detect.h:519
UTHFreePackets
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:467