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