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