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