suricata
detect-bytejump.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2020 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 Brian Rectanus <brectanu@gmail.com>
22  *
23  * Implements byte_jump keyword.
24  */
25 
26 #include "suricata-common.h"
27 #include "decode.h"
28 #include "detect.h"
29 #include "detect-parse.h"
30 #include "detect-engine.h"
31 #include "app-layer.h"
32 
33 #include "detect-byte.h"
34 #include "detect-byte-extract.h"
35 #include "detect-bytejump.h"
36 #include "detect-content.h"
37 #include "detect-uricontent.h"
38 
39 #include "util-byte.h"
40 #include "util-unittest.h"
41 #include "util-debug.h"
42 #include "util-validate.h"
43 #include "detect-pcre.h"
44 #include "detect-engine-build.h"
45 
46 /**
47  * \brief Regex for parsing our options
48  */
49 #define PARSE_REGEX "^\\s*" \
50  "([^\\s,]+\\s*,\\s*[^\\s,]+)" \
51  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
52  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
53  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
54  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
55  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
56  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
57  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
58  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
59  "(?:\\s*,\\s*((?:multiplier|post_offset)\\s+[^\\s,]+|[^\\s,]+))?" \
60  "\\s*$"
61 
62 static DetectParseRegex parse_regex;
63 
64 static DetectBytejumpData *DetectBytejumpParse(
65  DetectEngineCtx *de_ctx, const char *optstr, char **nbytes, char **offset);
66 static int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, const char *optstr);
67 static void DetectBytejumpFree(DetectEngineCtx*, void *ptr);
68 #ifdef UNITTESTS
69 static void DetectBytejumpRegisterTests(void);
70 #endif
71 
73 {
74  sigmatch_table[DETECT_BYTEJUMP].name = "byte_jump";
75  sigmatch_table[DETECT_BYTEJUMP].desc = "allow the ability to select a <num of bytes> from an <offset> and move the detection pointer to that position";
76  sigmatch_table[DETECT_BYTEJUMP].url = "/rules/payload-keywords.html#byte-jump";
78  sigmatch_table[DETECT_BYTEJUMP].Setup = DetectBytejumpSetup;
79  sigmatch_table[DETECT_BYTEJUMP].Free = DetectBytejumpFree;
80 #ifdef UNITTESTS
81  sigmatch_table[DETECT_BYTEJUMP].RegisterTests = DetectBytejumpRegisterTests;
82 #endif
83  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
84 }
85 
86 /* 23 - This is the largest string (octal, with a zero prefix) that
87  * will not overflow uint64_t. The only way this length
88  * could be over 23 and still not overflow is if it were zero
89  * prefixed and we only support 1 byte of zero prefix for octal.
90  *
91  * "01777777777777777777777" = 0xffffffffffffffff
92  *
93  * 8 - Without string, the maximum byte extract count is 8.
94  */
95 static inline bool DetectBytejumpValidateNbytesOnly(const DetectBytejumpData *data, int32_t nbytes)
96 {
97  return (data->flags & DETECT_BYTEJUMP_STRING && nbytes <= 23) || (nbytes <= 8);
98 }
99 
100 static bool DetectBytejumpValidateNbytes(const DetectBytejumpData *data, int32_t nbytes)
101 {
102  if (!DetectBytejumpValidateNbytesOnly(data, nbytes)) {
103  if (data->flags & DETECT_BYTEJUMP_STRING) {
104  /* 23 - This is the largest string (octal, with a zero prefix) that
105  * will not overflow uint64_t. The only way this length
106  * could be over 23 and still not overflow is if it were zero
107  * prefixed and we only support 1 byte of zero prefix for octal.
108  *
109  * "01777777777777777777777" = 0xffffffffffffffff
110  */
111  if (nbytes > 23) {
112  SCLogError("Cannot test more than 23 bytes "
113  "with \"string\"");
114  }
115  } else {
116  if (nbytes > 8) {
117  SCLogError("Cannot test more than 8 bytes "
118  "without \"string\"");
119  }
120  }
121  return false;
122  }
123 
124  return true;
125 }
126 
127 /** \brief Byte jump match function
128  * \param det_ctx thread detect engine ctx
129  * \param s signature
130  * \param m byte jump sigmatch
131  * \param payload ptr to the payload
132  * \param payload_len length of the payload
133  * \retval true match
134  * \retval false no match
135  */
137  const SigMatchCtx *ctx, const uint8_t *payload, uint32_t payload_len, uint16_t flags,
138  int32_t nbytes, int32_t offset)
139 {
140  SCEnter();
141 
142  const DetectBytejumpData *data = (const DetectBytejumpData *)ctx;
143  const uint8_t *ptr = NULL;
144  int32_t len = 0;
145  uint64_t val = 0;
146  int extbytes;
147 
148  if (payload_len == 0) {
149  SCReturnBool(false);
150  }
151 
152  /* Validate the number of bytes we are testing
153  * If the validation is successful, we know that
154  * it contains a value <= 23. Thus, we can
155  * safely cast it when extracting bytes
156  */
157  if (data->flags & DETECT_BYTEJUMP_NBYTES_VAR) {
158  if (!DetectBytejumpValidateNbytesOnly(data, nbytes)) {
159  SCLogDebug("Invalid byte_jump nbytes "
160  "seen in byte_jump - %d",
161  nbytes);
162  SCReturnBool(false);
163  }
164  }
165 
166  /* Calculate the ptr value for the bytejump and length remaining in
167  * the packet from that point.
168  */
169  ptr = payload + offset;
170  len = payload_len - offset;
172  ptr += det_ctx->buffer_offset;
173  len -= det_ctx->buffer_offset;
174 
175  SCLogDebug("[relative] after: ptr %p [len %d]", ptr, len);
176 
177  /* No match if there is no relative base */
178  if (ptr == NULL || (nbytes && len <= 0)) {
179  SCReturnBool(false);
180  }
181  }
182 
183  /* Verify the to-be-extracted data is within the packet */
184  if (ptr < payload || nbytes > len) {
185  SCLogDebug("Data not within payload "
186  "pkt=%p, ptr=%p, len=%" PRIi32 ", nbytes=%" PRIi32,
187  payload, ptr, len, nbytes);
188  SCReturnBool(false);
189  }
190 
191  /* Extract the byte data */
193  extbytes = ByteExtractStringUint64(&val, data->base, nbytes, (const char *)ptr);
194  if(extbytes <= 0) {
195  SCLogDebug("error extracting %d bytes of string data: %d", nbytes, extbytes);
196  SCReturnBool(false);
197  }
198  }
199  else {
201  extbytes = ByteExtractUint64(&val, endianness, (uint16_t)nbytes, ptr);
202  if (extbytes != nbytes) {
203  SCLogDebug("error extracting %d bytes of numeric data: %d", nbytes, extbytes);
204  SCReturnBool(false);
205  }
206  }
207 
208  SCLogDebug("VAL: (%" PRIu64 " x %" PRIu32 ") + %" PRIi32 " + %" PRId32, val, data->multiplier,
209  extbytes, data->post_offset);
210 
211  /* Adjust the jump value based on flags */
212  val *= data->multiplier;
214  if ((val % 4) != 0) {
215  val += 4 - (val % 4);
216  }
217  }
218  val += data->post_offset;
219  SCLogDebug("val: %" PRIi64 " post_offset: %" PRIi32, val, data->post_offset);
220 
221  const uint8_t *jumpptr;
222  /* Calculate the jump location */
224  jumpptr = payload + (int64_t)val;
225  SCLogDebug("NEWVAL: payload %p + %" PRIi64 " = %p", payload, (int64_t)val, jumpptr + val);
226  } else if (flags & DETECT_BYTEJUMP_END) {
227  jumpptr = payload + payload_len + (int64_t)val;
228  SCLogDebug(
229  "NEWVAL: payload %p + %" PRIu32 " + %" PRIi64, payload, payload_len, (int64_t)val);
230  } else {
231  jumpptr = ptr + (int64_t)val + extbytes;
232  SCLogDebug("NEWVAL: ptr %p + %" PRIi64 " = %p", ptr, val, jumpptr);
233  }
234 
235  /* Validate that the jump location is still in the packet
236  * \todo Should this validate it is still in the *payload*?
237  */
238  if (jumpptr < payload) {
239  jumpptr = payload;
240  SCLogDebug("jump location is before buffer start; resetting to buffer start");
241  } else if (jumpptr > (payload + payload_len)) {
242  SCLogDebug("Jump location (%" PRIu64 ") is not within payload (%" PRIu32 ")",
243  payload_len + val, payload_len);
244  SCReturnBool(false);
245  }
246 
247 #ifdef DEBUG
248  if (SCLogDebugEnabled()) {
249  const uint8_t *sptr = (flags & DETECT_BYTEJUMP_BEGIN) ? payload : ptr;
250  SCLogDebug("jumping %" PRId64 " bytes from %p (%08x)", val, sptr, (int)(sptr - payload));
251  }
252 #endif /* DEBUG */
253 
254  /* Adjust the detection context to the jump location. */
255  DEBUG_VALIDATE_BUG_ON(jumpptr < payload);
256  det_ctx->buffer_offset = jumpptr - payload;
257 
258  SCReturnBool(true);
259 }
260 
261 static DetectBytejumpData *DetectBytejumpParse(
262  DetectEngineCtx *de_ctx, const char *optstr, char **nbytes_str, char **offset)
263 {
264  DetectBytejumpData *data = NULL;
265  char args[10][64];
266  int res = 0;
267  size_t pcre2len;
268  int numargs = 0;
269  int i = 0;
270  uint32_t nbytes = 0;
271  char *str_ptr;
272  char *end_ptr;
273  pcre2_match_data *match = NULL;
274 
275  memset(args, 0x00, sizeof(args));
276 
277  /* Execute the regex and populate args with captures. */
278  int ret = DetectParsePcreExec(&parse_regex, &match, optstr, 0, 0);
279  if (ret < 2 || ret > 10) {
280  SCLogError("parse error, ret %" PRId32 ", string \"%s\"", ret, optstr);
281  goto error;
282  }
283 
284  /* The first two arguments are stashed in the first PCRE substring.
285  * This is because byte_jump can take 10 arguments, but PCRE only
286  * supports 9 substrings, sigh.
287  */
288  char str[512] = "";
289  pcre2len = sizeof(str);
290  res = pcre2_substring_copy_bynumber(match, 1, (PCRE2_UCHAR8 *)str, &pcre2len);
291  if (res < 0) {
292  SCLogError("pcre2_substring_copy_bynumber failed "
293  "for arg 1");
294  goto error;
295  }
296 
297  /* Break up first substring into two parameters
298  *
299  * NOTE: Because of this, we cannot free args[1] as it is part of args[0],
300  * and *yes* this *is* ugly.
301  */
302  end_ptr = str;
303  while (!(isspace((unsigned char)*end_ptr) || (*end_ptr == ','))) end_ptr++;
304  *(end_ptr++) = '\0';
305  strlcpy(args[0], str, sizeof(args[0]));
306  numargs++;
307 
308  str_ptr = end_ptr;
309  while (isspace((unsigned char)*str_ptr) || (*str_ptr == ',')) str_ptr++;
310  end_ptr = str_ptr;
311  while (!(isspace((unsigned char)*end_ptr) || (*end_ptr == ',')) && (*end_ptr != '\0'))
312  end_ptr++;
313  *(end_ptr++) = '\0';
314  strlcpy(args[1], str_ptr, sizeof(args[1]));
315  numargs++;
316 
317  /* The remaining args are directly from PCRE substrings */
318  for (i = 1; i < (ret - 1); i++) {
319  pcre2len = sizeof(args[0]);
320  res = pcre2_substring_copy_bynumber(match, i + 1, (PCRE2_UCHAR8 *)args[i + 1], &pcre2len);
321  if (res < 0) {
322  SCLogError("pcre2_substring_copy_bynumber failed for arg %d", i + 1);
323  goto error;
324  }
325  numargs++;
326  }
327 
328  /* Initialize the data */
329  data = SCMalloc(sizeof(DetectBytejumpData));
330  if (unlikely(data == NULL))
331  goto error;
333  data->flags = 0;
334  data->multiplier = 1;
335  data->post_offset = 0;
336 
337  /*
338  * The first two options are required and positional. The
339  * remaining arguments are flags and are not positional.
340  */
341 
342  /* Number of bytes */
343  if (args[0][0] != '-' && isalpha((unsigned char)args[0][0])) {
344  if (nbytes_str == NULL) {
345  SCLogError("byte_jump supplied with "
346  "var name for nbytes. \"value\" argument supplied to "
347  "this function has to be non-NULL");
348  goto error;
349  }
350  *nbytes_str = SCStrdup(args[0]);
351  if (*nbytes_str == NULL)
352  goto error;
354  } else {
355  if (StringParseUint32(&nbytes, 10, (uint16_t)strlen(args[0]), args[0]) <= 0) {
356  SCLogError("Malformed number of bytes: %s", optstr);
357  goto error;
358  }
359  }
360 
361  /* Offset */
362  if (args[1][0] != '-' && isalpha((unsigned char)args[1][0])) {
363  if (offset == NULL) {
364  SCLogError("byte_jump supplied with "
365  "var name for offset. \"value\" argument supplied to "
366  "this function has to be non-NULL");
367  goto error;
368  }
369  *offset = SCStrdup(args[1]);
370  if (*offset == NULL)
371  goto error;
372  } else {
374  &data->offset, 10, (uint16_t)strlen(args[1]), args[1], -65535, 65535) <= 0) {
375  SCLogError("Malformed offset: %s", optstr);
376  goto error;
377  }
378  }
379 
380  /* The remaining options are flags. */
381  /** \todo Error on dups? */
382  for (i = 2; i < numargs; i++) {
383  if (strcmp("relative", args[i]) == 0) {
385  } else if (strcasecmp("string", args[i]) == 0) {
386  data->flags |= DETECT_BYTEJUMP_STRING;
387  } else if (strcasecmp("dec", args[i]) == 0) {
389  } else if (strcasecmp("hex", args[i]) == 0) {
391  } else if (strcasecmp("oct", args[i]) == 0) {
393  } else if (strcasecmp("big", args[i]) == 0) {
394  if (data->flags & DETECT_BYTEJUMP_LITTLE) {
395  data->flags ^= DETECT_BYTEJUMP_LITTLE;
396  }
397  data->flags |= DETECT_BYTEJUMP_BIG;
398  } else if (strcasecmp("little", args[i]) == 0) {
399  data->flags |= DETECT_BYTEJUMP_LITTLE;
400  } else if (strcasecmp("from_beginning", args[i]) == 0) {
401  data->flags |= DETECT_BYTEJUMP_BEGIN;
402  } else if (strcasecmp("from_end", args[i]) == 0) {
403  data->flags |= DETECT_BYTEJUMP_END;
404  } else if (strcasecmp("align", args[i]) == 0) {
405  data->flags |= DETECT_BYTEJUMP_ALIGN;
406  } else if (strncasecmp("multiplier ", args[i], 11) == 0) {
407  if (StringParseU16RangeCheck(&data->multiplier, 10, (uint16_t)strlen(args[i]) - 11,
408  args[i] + 11, 1, 65535) <= 0) {
409  SCLogError("Malformed multiplier: %s", optstr);
410  goto error;
411  }
412  } else if (strncasecmp("post_offset ", args[i], 12) == 0) {
413  if (StringParseI32RangeCheck(&data->post_offset, 10, (uint16_t)strlen(args[i]) - 12,
414  args[i] + 12, -65535, 65535) <= 0) {
415  SCLogError("Malformed post_offset: %s", optstr);
416  goto error;
417  }
418  SCLogDebug("post_offset: %s [%d]", optstr, data->post_offset);
419  } else if (strcasecmp("dce", args[i]) == 0) {
420  data->flags |= DETECT_BYTEJUMP_DCE;
421  } else {
422  SCLogError("Unknown option: \"%s\"", args[i]);
423  goto error;
424  }
425  }
426 
427  if ((data->flags & DETECT_BYTEJUMP_END) && (data->flags & DETECT_BYTEJUMP_BEGIN)) {
428  SCLogError("'from_end' and 'from_beginning' "
429  "cannot be used in the same byte_jump statement");
430  goto error;
431  }
432 
433  if (!(data->flags & DETECT_BYTEJUMP_NBYTES_VAR)) {
434  if (!DetectBytejumpValidateNbytes(data, nbytes)) {
435  goto error;
436  }
437 
438  /* This is max 23 so it will fit in a byte (see validation function) */
439  data->nbytes = (uint8_t)nbytes;
440  }
441  if (!(data->flags & DETECT_BYTEJUMP_STRING)) {
442  if (data->base != DETECT_BYTEJUMP_BASE_UNSET) {
443  SCLogError("Cannot use a base "
444  "without \"string\": %s",
445  optstr);
446  goto error;
447  }
448  }
449 
450  pcre2_match_data_free(match);
451  return data;
452 
453 error:
454  if (offset != NULL && *offset != NULL) {
455  SCFree(*offset);
456  *offset = NULL;
457  }
458  if (nbytes_str != NULL && *nbytes_str != NULL) {
459  SCFree(*nbytes_str);
460  *nbytes_str = NULL;
461  }
462  if (data != NULL)
463  DetectBytejumpFree(de_ctx, data);
464  if (match) {
465  pcre2_match_data_free(match);
466  }
467  return NULL;
468 }
469 
470 static int DetectBytejumpSetup(DetectEngineCtx *de_ctx, Signature *s, const char *optstr)
471 {
472  SigMatch *prev_pm = NULL;
473  DetectBytejumpData *data = NULL;
474  char *offset = NULL;
475  char *nbytes = NULL;
476  int ret = -1;
477 
478  data = DetectBytejumpParse(de_ctx, optstr, &nbytes, &offset);
479  if (data == NULL)
480  goto error;
481 
482  int sm_list;
483  if (s->init_data->list != DETECT_SM_LIST_NOTSET) {
484  if (DetectBufferGetActiveList(de_ctx, s) == -1)
485  goto error;
486 
487  sm_list = s->init_data->list;
488 
489  if (data->flags & DETECT_BYTEJUMP_RELATIVE) {
491  }
492  } else if (data->flags & DETECT_BYTEJUMP_DCE) {
493  if (data->flags & DETECT_BYTEJUMP_RELATIVE) {
494  prev_pm = DetectGetLastSMFromLists(s,
498  if (prev_pm == NULL) {
499  sm_list = DETECT_SM_LIST_PMATCH;
500  } else {
501  sm_list = SigMatchListSMBelongsTo(s, prev_pm);
502  if (sm_list < 0)
503  goto error;
504  }
505  } else {
506  sm_list = DETECT_SM_LIST_PMATCH;
507  }
508 
510  goto error;
511 
512  } else if (data->flags & DETECT_BYTEJUMP_RELATIVE) {
513  prev_pm = DetectGetLastSMFromLists(s,
517  if (prev_pm == NULL) {
518  sm_list = DETECT_SM_LIST_PMATCH;
519  } else {
520  sm_list = SigMatchListSMBelongsTo(s, prev_pm);
521  if (sm_list < 0)
522  goto error;
523  }
524 
525  } else {
526  sm_list = DETECT_SM_LIST_PMATCH;
527  }
528 
529  if (data->flags & DETECT_BYTEJUMP_DCE) {
530  if ((data->flags & DETECT_BYTEJUMP_STRING) ||
531  (data->flags & DETECT_BYTEJUMP_LITTLE) ||
532  (data->flags & DETECT_BYTEJUMP_BIG) ||
533  (data->flags & DETECT_BYTEJUMP_BEGIN) ||
534  (data->flags & DETECT_BYTEJUMP_END) ||
535  (data->base == DETECT_BYTEJUMP_BASE_DEC) ||
536  (data->base == DETECT_BYTEJUMP_BASE_HEX) ||
537  (data->base == DETECT_BYTEJUMP_BASE_OCT) ) {
538  SCLogError("Invalid option. "
539  "A byte_jump keyword with dce holds other invalid modifiers.");
540  goto error;
541  }
542  }
543 
544  if (nbytes != NULL) {
545  DetectByteIndexType index;
546  if (!DetectByteRetrieveSMVar(nbytes, s, &index)) {
547  SCLogError("Unknown byte_extract var "
548  "seen in byte_jump - %s",
549  nbytes);
550  goto error;
551  }
552  data->nbytes = index;
553  SCFree(nbytes);
554  nbytes = NULL;
555  }
556 
557  if (offset != NULL) {
558  DetectByteIndexType index;
559  if (!DetectByteRetrieveSMVar(offset, s, &index)) {
560  SCLogError("Unknown byte_extract var "
561  "seen in byte_jump - %s",
562  offset);
563  goto error;
564  }
565  data->offset = index;
567  SCFree(offset);
568  offset = NULL;
569  }
570 
571  if (SigMatchAppendSMToList(de_ctx, s, DETECT_BYTEJUMP, (SigMatchCtx *)data, sm_list) == NULL) {
572  goto error;
573  }
574 
575  if (!(data->flags & DETECT_BYTEJUMP_RELATIVE))
576  goto okay;
577 
578  if (prev_pm == NULL)
579  goto okay;
580 
581  if (prev_pm->type == DETECT_CONTENT) {
582  DetectContentData *cd = (DetectContentData *)prev_pm->ctx;
584  } else if (prev_pm->type == DETECT_PCRE) {
585  DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx;
587  }
588 
589  okay:
590  ret = 0;
591  return ret;
592 
593  error:
594  if (nbytes != NULL) {
595  SCFree(nbytes);
596  }
597  if (offset != NULL) {
598  SCFree(offset);
599  }
600  DetectBytejumpFree(de_ctx, data);
601  return ret;
602 }
603 
604 /**
605  * \brief this function will free memory associated with DetectBytejumpData
606  *
607  * \param data pointer to DetectBytejumpData
608  */
609 static void DetectBytejumpFree(DetectEngineCtx *de_ctx, void *ptr)
610 {
611  if (ptr == NULL)
612  return;
613 
614  DetectBytejumpData *data = (DetectBytejumpData *)ptr;
615  SCFree(data);
616 }
617 
618 
619 /* UNITTESTS */
620 #ifdef UNITTESTS
621 #include "util-unittest-helper.h"
622 static int g_file_data_buffer_id = 0;
623 static int g_dce_stub_data_buffer_id = 0;
624 
625 /**
626  * \test DetectBytejumpTestParse01 is a test to make sure that we return
627  * "something" when given valid bytejump opt
628  */
629 static int DetectBytejumpTestParse01(void)
630 {
631  DetectBytejumpData *data = NULL;
632  data = DetectBytejumpParse(NULL, "4,0", NULL, NULL);
633  FAIL_IF_NULL(data);
634 
635  DetectBytejumpFree(NULL, data);
636  PASS;
637 }
638 
639 /**
640  * \test DetectBytejumpTestParse02 is a test for setting the required opts
641  */
642 static int DetectBytejumpTestParse02(void)
643 {
644  DetectBytejumpData *data = NULL;
645  data = DetectBytejumpParse(NULL, "4, 0", NULL, NULL);
646  FAIL_IF_NULL(data);
647  FAIL_IF_NOT(data->nbytes == 4);
648  FAIL_IF_NOT(data->offset == 0);
649  FAIL_IF_NOT(data->multiplier == 1);
650  FAIL_IF_NOT(data->post_offset == 0);
651  FAIL_IF_NOT(data->flags == 0);
653 
654  DetectBytejumpFree(NULL, data);
655  PASS;
656 }
657 
658 /**
659  * \test DetectBytejumpTestParse03 is a test for setting the optional flags
660  */
661 static int DetectBytejumpTestParse03(void)
662 {
663  DetectBytejumpData *data = NULL;
664  data = DetectBytejumpParse(NULL,
665  " 4,0 , relative , little, string, "
666  "dec, align, from_beginning",
667  NULL, NULL);
668  FAIL_IF_NULL(data);
669  FAIL_IF_NOT(data->nbytes == 4);
670  FAIL_IF_NOT(data->offset == 0);
671  FAIL_IF_NOT(data->multiplier == 1);
672  FAIL_IF_NOT(data->post_offset == 0);
673  FAIL_IF_NOT(data->flags ==
677 
678  DetectBytejumpFree(NULL, data);
679  PASS;
680 }
681 
682 /**
683  * \test DetectBytejumpTestParse04 is a test for setting the optional flags
684  * with parameters
685  *
686  * \todo This fails because we can only have 9 captures and there are 10.
687  */
688 static int DetectBytejumpTestParse04(void)
689 {
690  DetectBytejumpData *data = NULL;
691  data = DetectBytejumpParse(NULL,
692  " 4,0 , relative , little, string, "
693  "dec, align, from_beginning , "
694  "multiplier 2 , post_offset -16 ",
695  NULL, NULL);
696  FAIL_IF_NULL(data);
697  FAIL_IF_NOT(data->nbytes == 4);
698  FAIL_IF_NOT(data->offset == 0);
699  FAIL_IF_NOT(data->multiplier == 2);
700  FAIL_IF_NOT(data->post_offset == -16);
701  FAIL_IF_NOT(data->flags ==
705 
706  DetectBytejumpFree(NULL, data);
707  PASS;
708 }
709 
710 /**
711  * \test DetectBytejumpTestParse05 is a test for setting base without string
712  */
713 static int DetectBytejumpTestParse05(void)
714 {
715  DetectBytejumpData *data = NULL;
716  data = DetectBytejumpParse(NULL,
717  " 4,0 , relative , little, dec, "
718  "align, from_beginning",
719  NULL, NULL);
720  FAIL_IF_NOT_NULL(data);
721 
722  PASS;
723 }
724 
725 /**
726  * \test DetectBytejumpTestParse06 is a test for too many bytes to extract
727  */
728 static int DetectBytejumpTestParse06(void)
729 {
730  DetectBytejumpData *data = NULL;
731  data = DetectBytejumpParse(NULL, "9, 0", NULL, NULL);
732  FAIL_IF_NOT_NULL(data);
733 
734  PASS;
735 }
736 
737 /**
738  * \test DetectBytejumpTestParse07 is a test for too many string bytes to extract
739  */
740 static int DetectBytejumpTestParse07(void)
741 {
742  DetectBytejumpData *data = NULL;
743  data = DetectBytejumpParse(NULL, "24, 0, string, dec", NULL, NULL);
744  FAIL_IF_NOT_NULL(data);
745 
746  PASS;
747 }
748 
749 /**
750  * \test DetectBytejumpTestParse08 is a test for offset too big
751  */
752 static int DetectBytejumpTestParse08(void)
753 {
754  DetectBytejumpData *data = NULL;
755  data = DetectBytejumpParse(NULL, "4, 0xffffffffffffffff", NULL, NULL);
756  FAIL_IF_NOT_NULL(data);
757 
758  PASS;
759 }
760 
761 /**
762  * \test Test dce option.
763  */
764 static int DetectBytejumpTestParse09(void)
765 {
766  Signature *s = SigAlloc();
767  FAIL_IF_NULL(s);
768 
770 
771  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
772  "4,0, align, multiplier 2, "
773  "post_offset -16,dce") == 0);
774  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s,
775  "4,0, multiplier 2, "
776  "post_offset -16,dce") == 0);
777  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0,post_offset -16,dce") == 0);
778  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0,dce") == 0);
779  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0,dce") == 0);
780  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, string, dce") == -1);
781  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, big, dce") == -1);
782  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, little, dce") == -1);
783  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, string, dec, dce") == -1);
784  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, string, oct, dce") == -1);
785  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, string, hex, dce") == -1);
786  FAIL_IF_NOT(DetectBytejumpSetup(NULL, s, "4,0, from_beginning, dce") == -1);
787 
789  SigMatch *sm = DetectBufferGetFirstSigMatch(s, g_dce_stub_data_buffer_id);
790  FAIL_IF_NOT_NULL(sm);
791 
792  SigFree(NULL, s);
793  PASS;
794 }
795 
796 /**
797  * \test Test dce option.
798  */
799 static int DetectBytejumpTestParse10(void)
800 {
803  de_ctx->flags |= DE_QUIET;
804 
805  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
806  "(msg:\"Testing bytejump_body\"; "
807  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
808  "dce_stub_data; "
809  "content:\"one\"; distance:0; "
810  "byte_jump:4,0,align,multiplier 2, "
811  "post_offset -16,relative,dce; sid:1;)");
812  FAIL_IF_NULL(s);
813  SigMatch *sm = DetectBufferGetFirstSigMatch(s, g_dce_stub_data_buffer_id);
814  FAIL_IF_NULL(sm);
816  FAIL_IF_NULL(sm->next);
817  sm = sm->next;
819 
826 
827  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
828  "(msg:\"Testing bytejump_body\"; "
829  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
830  "dce_stub_data; "
831  "content:\"one\"; distance:0; "
832  "byte_jump:4,0,align,multiplier 2, "
833  "post_offset -16,relative,dce; sid:2;)");
834  FAIL_IF_NULL(s);
835  sm = DetectBufferGetFirstSigMatch(s, g_dce_stub_data_buffer_id);
836  FAIL_IF_NULL(sm);
837 
839  FAIL_IF_NULL(sm->next);
840  sm = sm->next;
842 
843  bd = (DetectBytejumpData *)sm->ctx;
849 
850  s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
851  "(msg:\"Testing bytejump_body\"; "
852  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
853  "dce_stub_data; "
854  "content:\"one\"; distance:0; "
855  "byte_jump:4,0,align,multiplier 2, "
856  "post_offset -16,relative; sid:3;)");
857  FAIL_IF_NULL(s);
858  sm = DetectBufferGetFirstSigMatch(s, g_dce_stub_data_buffer_id);
859  FAIL_IF_NULL(sm);
860 
862  FAIL_IF_NULL(sm->next);
863  sm = sm->next;
865 
866  bd = (DetectBytejumpData *)sm->ctx;
872 
874  PASS;
875 }
876 
877 /**
878  * \test Test dce option.
879  */
880 static int DetectBytejumpTestParse11(void)
881 {
882  DetectEngineCtx *de_ctx = NULL;
883  Signature *s = NULL;
884 
887 
888  de_ctx->flags |= DE_QUIET;
889  s = SigInit(de_ctx, "alert tcp any any -> any any "
890  "(msg:\"Testing bytejump_body\"; "
891  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
892  "dce_stub_data; "
893  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
894  "post_offset -16,string,dce; sid:1;)");
895  FAIL_IF_NOT_NULL(s);
896 
897  s = SigInit(de_ctx, "alert tcp any any -> any any "
898  "(msg:\"Testing bytejump_body\"; "
899  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
900  "dce_sub_data; "
901  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
902  "post_offset -16,big,dce; sid:1;)");
903  FAIL_IF_NOT_NULL(s);
904 
905  s = SigInit(de_ctx, "alert tcp any any -> any any "
906  "(msg:\"Testing bytejump_body\"; "
907  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
908  "dce_stub_data; "
909  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
910  "post_offset -16,little,dce; sid:1;)");
911  FAIL_IF_NOT_NULL(s);
912 
913  s = SigInit(de_ctx, "alert tcp any any -> any any "
914  "(msg:\"Testing bytejump_body\"; "
915  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
916  "dce_stub_data; "
917  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
918  "post_offset -16,string,hex,dce; sid:1;)");
919  FAIL_IF_NOT_NULL(s);
920 
921  s = SigInit(de_ctx, "alert tcp any any -> any any "
922  "(msg:\"Testing bytejump_body\"; "
923  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
924  "dce_stub_data; "
925  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
926  "post_offset -16,string,dec,dce; sid:1;)");
927  FAIL_IF_NOT_NULL(s);
928 
929  s = SigInit(de_ctx, "alert tcp any any -> any any "
930  "(msg:\"Testing bytejump_body\"; "
931  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
932  "dce_stub_data; "
933  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
934  "post_offset -16,string,oct,dce; sid:1;)");
935  FAIL_IF_NOT_NULL(s);
936 
937  s = SigInit(de_ctx, "alert tcp any any -> any any "
938  "(msg:\"Testing bytejump_body\"; "
939  "dce_iface:3919286a-b10c-11d0-9ba8-00c04fd92ef5; "
940  "dce_stub_data; "
941  "content:\"one\"; byte_jump:4,0,align,multiplier 2, "
942  "post_offset -16,from_beginning,dce; sid:1;)");
943  FAIL_IF_NOT_NULL(s);
944 
948  PASS;
949 }
950 
951 /**
952  * \test Test file_data
953  */
954 static int DetectBytejumpTestParse12(void)
955 {
958  de_ctx->flags |= DE_QUIET;
959 
960  Signature *s = DetectEngineAppendSig(de_ctx, "alert tcp any any -> any any "
961  "(file_data; byte_jump:4,0,align,multiplier 2, "
962  "post_offset -16,relative; sid:1;)");
963  FAIL_IF_NULL(s);
964 
965  SigMatch *sm = DetectBufferGetFirstSigMatch(s, g_file_data_buffer_id);
966  FAIL_IF_NULL(sm);
968 
971  FAIL_IF((bd->flags &
974 
976  PASS;
977 }
978 
979 static int DetectBytejumpTestParse13(void)
980 {
981  DetectBytejumpData *data = DetectBytejumpParse(NULL,
982  " 4,0 , relative , little, string, dec, "
983  "align, from_end",
984  NULL, NULL);
985  FAIL_IF_NULL(data);
987 
988  DetectBytejumpFree(NULL, data);
989 
990  PASS;
991 }
992 
993 static int DetectBytejumpTestParse14(void)
994 {
995  DetectBytejumpData *data = DetectBytejumpParse(NULL,
996  " 4,0 , relative , little, string, dec, "
997  "align, from_beginning, from_end",
998  NULL, NULL);
999 
1000  FAIL_IF_NOT_NULL(data);
1001 
1002  PASS;
1003 }
1004 
1005 /**
1006  * \test DetectByteJumpTestPacket01 is a test to check matches of
1007  * byte_jump and byte_jump relative works if the previous keyword is pcre
1008  * (bug 142)
1009  */
1010 static int DetectByteJumpTestPacket01 (void)
1011 {
1012  uint8_t *buf = (uint8_t *)"GET /AllWorkAndNoPlayMakesWillADullBoy HTTP/1.0"
1013  "User-Agent: Wget/1.11.4"
1014  "Accept: */*"
1015  "Host: www.google.com"
1016  "Connection: Keep-Alive"
1017  "Date: Mon, 04 Jan 2010 17:29:39 GMT";
1018  uint16_t buflen = strlen((char *)buf);
1019  Packet *p;
1020  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1021 
1022  FAIL_IF_NULL(p);
1023 
1024  char sig[] = "alert tcp any any -> any any (msg:\"pcre + byte_test + "
1025  "relative\"; pcre:\"/AllWorkAndNoPlayMakesWillADullBoy/\"; byte_jump:1,6,"
1026  "relative,string,dec; content:\"0\"; sid:134; rev:1;)";
1027 
1028  FAIL_IF_NOT(UTHPacketMatchSig(p, sig));
1029 
1030  UTHFreePacket(p);
1031  PASS;
1032 }
1033 
1034 /**
1035  * \test DetectByteJumpTestPacket02 is a test to check matches of
1036  * byte_jump and byte_jump relative works if the previous keyword is byte_jump
1037  * (bug 165)
1038  */
1039 static int DetectByteJumpTestPacket02 (void)
1040 {
1041  uint8_t buf[] = { 0x00, 0x00, 0x00, 0x77, 0xff, 0x53,
1042  0x4d, 0x42, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x18,
1043  0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1044  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
1045  0x92, 0xa4, 0x01, 0x08, 0x17, 0x5c, 0x0e, 0xff,
1046  0x00, 0x00, 0x00, 0x01, 0x40, 0x48, 0x00, 0x00,
1047  0x00, 0xff };
1048  uint16_t buflen = sizeof(buf);
1049  Packet *p;
1050  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1051 
1052  FAIL_IF_NULL(p);
1053 
1054  char sig[] = "alert tcp any any -> any any (msg:\"byte_jump with byte_jump"
1055  " + relative\"; byte_jump:1,13; byte_jump:4,0,relative; "
1056  "content:\"|48 00 00|\"; within:3; sid:144; rev:1;)";
1057 
1058  FAIL_IF_NOT(UTHPacketMatchSig(p, sig));
1059 
1060  UTHFreePacket(p);
1061  PASS;
1062 }
1063 
1064 static int DetectByteJumpTestPacket03(void)
1065 {
1066  uint8_t *buf = NULL;
1067  uint16_t buflen = 0;
1068  buf = SCMalloc(4);
1069  if (unlikely(buf == NULL)) {
1070  printf("malloc failed\n");
1071  exit(EXIT_FAILURE);
1072  }
1073  memcpy(buf, "boom", 4);
1074  buflen = 4;
1075 
1076  Packet *p;
1077  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1078 
1079  FAIL_IF_NULL(p);
1080 
1081  char sig[] = "alert tcp any any -> any any (msg:\"byte_jump\"; "
1082  "byte_jump:1,214748364; sid:1; rev:1;)";
1083 
1084  FAIL_IF(UTHPacketMatchSig(p, sig));
1085 
1086  UTHFreePacket(p);
1087  FAIL_IF_NULL(buf);
1088 
1089  SCFree(buf);
1090  PASS;
1091 }
1092 
1093 /**
1094  * \test check matches of with from_beginning (bug 626/627)
1095  */
1096 static int DetectByteJumpTestPacket04 (void)
1097 {
1098  uint8_t *buf = (uint8_t *)"XYZ04abcdABCD";
1099  uint16_t buflen = strlen((char *)buf);
1100  Packet *p;
1101  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1102 
1103  FAIL_IF_NULL(p);
1104 
1105  char sig[] = "alert tcp any any -> any any (content:\"XYZ\"; byte_jump:2,0,relative,string,dec; content:\"ABCD\"; distance:0; within:4; sid:1; rev:1;)";
1106 
1107  FAIL_IF_NOT(UTHPacketMatchSig(p, sig));
1108 
1109  UTHFreePacket(p);
1110  PASS;
1111 }
1112 
1113 /**
1114  * \test check matches of with from_beginning (bug 626/627)
1115  */
1116 static int DetectByteJumpTestPacket05 (void)
1117 {
1118  uint8_t *buf = (uint8_t *)"XYZ04abcdABCD";
1119  uint16_t buflen = strlen((char *)buf);
1120  Packet *p;
1121  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1122 
1123  FAIL_IF_NULL(p);
1124 
1125  char sig[] = "alert tcp any any -> any any (content:\"XYZ\"; byte_jump:2,0,relative,string,dec; content:\"cdABCD\"; within:6; sid:1; rev:1;)";
1126 
1127  FAIL_IF_NOT(UTHPacketMatchSig(p, sig) ? 0 : 1);
1128 
1129  UTHFreePacket(p);
1130  PASS;
1131 }
1132 
1133 /**
1134  * \test check matches of with from_beginning (bug 626/627)
1135  */
1136 static int DetectByteJumpTestPacket06 (void)
1137 {
1138  uint8_t *buf = (uint8_t *)"XX04abcdABCD";
1139  uint16_t buflen = strlen((char *)buf);
1140  Packet *p;
1141  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1142 
1143  FAIL_IF_NULL(p);
1144 
1145  char sig[] = "alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,relative,string,dec,from_beginning; content:\"ABCD\"; distance:4; within:4; sid:1; rev:1;)";
1146 
1147  FAIL_IF_NOT(UTHPacketMatchSig(p, sig));
1148 
1149  UTHFreePacket(p);
1150  PASS;
1151 }
1152 
1153 /**
1154  * \test check matches of with from_beginning (bug 626/627)
1155  */
1156 static int DetectByteJumpTestPacket07 (void)
1157 {
1158  uint8_t *buf = (uint8_t *)"XX04abcdABCD";
1159  uint16_t buflen = strlen((char *)buf);
1160  Packet *p;
1161  p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1162 
1163  FAIL_IF_NULL(p);
1164 
1165  char sig[] = "alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,relative,string,dec,from_beginning; content:\"abcdABCD\"; distance:0; within:8; sid:1; rev:1;)";
1166 
1167  FAIL_IF_NOT(UTHPacketMatchSig(p, sig) ? 1 : 0);
1168 
1169  UTHFreePacket(p);
1170  PASS;
1171 }
1172 
1173 /**
1174  * \test check matches of with from_end
1175  */
1176 static int DetectByteJumpTestPacket08 (void)
1177 {
1178  uint8_t *buf = (uint8_t *)"XX04abcdABCD";
1179  uint16_t buflen = strlen((char *)buf);
1180  Packet *p = UTHBuildPacket((uint8_t *)buf, buflen, IPPROTO_TCP);
1181 
1182  FAIL_IF_NULL(p);
1183 
1184  char sig[] = "alert tcp any any -> any any (content:\"XX\"; byte_jump:2,0,"
1185  "relative,string,dec,from_end, post_offset -8; content:\"ABCD\"; sid:1; rev:1;)";
1186 
1187  FAIL_IF_NOT(UTHPacketMatchSig(p, sig));
1188 
1189  UTHFreePacket(p);
1190 
1191  PASS;
1192 }
1193 
1194 /**
1195  * \brief this function registers unit tests for DetectBytejump
1196  */
1197 static void DetectBytejumpRegisterTests(void)
1198 {
1199  g_file_data_buffer_id = DetectBufferTypeGetByName("file_data");
1200  g_dce_stub_data_buffer_id = DetectBufferTypeGetByName("dce_stub_data");
1201 
1202  UtRegisterTest("DetectBytejumpTestParse01", DetectBytejumpTestParse01);
1203  UtRegisterTest("DetectBytejumpTestParse02", DetectBytejumpTestParse02);
1204  UtRegisterTest("DetectBytejumpTestParse03", DetectBytejumpTestParse03);
1205  UtRegisterTest("DetectBytejumpTestParse04", DetectBytejumpTestParse04);
1206  UtRegisterTest("DetectBytejumpTestParse05", DetectBytejumpTestParse05);
1207  UtRegisterTest("DetectBytejumpTestParse06", DetectBytejumpTestParse06);
1208  UtRegisterTest("DetectBytejumpTestParse07", DetectBytejumpTestParse07);
1209  UtRegisterTest("DetectBytejumpTestParse08", DetectBytejumpTestParse08);
1210  UtRegisterTest("DetectBytejumpTestParse09", DetectBytejumpTestParse09);
1211  UtRegisterTest("DetectBytejumpTestParse10", DetectBytejumpTestParse10);
1212  UtRegisterTest("DetectBytejumpTestParse11", DetectBytejumpTestParse11);
1213  UtRegisterTest("DetectBytejumpTestParse12", DetectBytejumpTestParse12);
1214  UtRegisterTest("DetectBytejumpTestParse13", DetectBytejumpTestParse13);
1215  UtRegisterTest("DetectBytejumpTestParse14", DetectBytejumpTestParse14);
1216 
1217  UtRegisterTest("DetectByteJumpTestPacket01", DetectByteJumpTestPacket01);
1218  UtRegisterTest("DetectByteJumpTestPacket02", DetectByteJumpTestPacket02);
1219  UtRegisterTest("DetectByteJumpTestPacket03", DetectByteJumpTestPacket03);
1220  UtRegisterTest("DetectByteJumpTestPacket04", DetectByteJumpTestPacket04);
1221  UtRegisterTest("DetectByteJumpTestPacket05", DetectByteJumpTestPacket05);
1222  UtRegisterTest("DetectByteJumpTestPacket06", DetectByteJumpTestPacket06);
1223  UtRegisterTest("DetectByteJumpTestPacket07", DetectByteJumpTestPacket07);
1224  UtRegisterTest("DetectByteJumpTestPacket08", DetectByteJumpTestPacket08);
1225 }
1226 #endif /* UNITTESTS */
DetectBytejumpData_::post_offset
int32_t post_offset
Definition: detect-bytejump.h:51
util-byte.h
SigTableElmt_::url
const char * url
Definition: detect.h:1296
DETECT_CONTENT_RELATIVE_NEXT
#define DETECT_CONTENT_RELATIVE_NEXT
Definition: detect-content.h:66
DetectSignatureSetAppProto
int DetectSignatureSetAppProto(Signature *s, AppProto alproto)
Definition: detect-parse.c:1753
detect-content.h
len
uint8_t len
Definition: app-layer-dnp3.h:2
DetectEngineThreadCtx_::buffer_offset
uint32_t buffer_offset
Definition: detect.h:1121
detect-engine.h
DETECT_SM_LIST_PMATCH
@ DETECT_SM_LIST_PMATCH
Definition: detect.h:113
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
SignatureInitData_::smlists
struct SigMatch_ * smlists[DETECT_SM_LIST_MAX]
Definition: detect.h:578
SigTableElmt_::desc
const char * desc
Definition: detect.h:1295
ByteExtractUint64
int ByteExtractUint64(uint64_t *res, int e, uint16_t len, const uint8_t *bytes)
Definition: util-byte.c:122
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:1283
PARSE_REGEX
#define PARSE_REGEX
Regex for parsing our options.
Definition: detect-bytejump.c:49
DetectParseRegex
Definition: detect-parse.h:62
SigTableElmt_::name
const char * name
Definition: detect.h:1293
DETECT_BYTEJUMP
@ DETECT_BYTEJUMP
Definition: detect-engine-register.h:76
SigFree
void SigFree(DetectEngineCtx *, Signature *)
Definition: detect-parse.c:1644
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
DETECT_BYTEJUMP_LITTLE
#define DETECT_BYTEJUMP_LITTLE
Definition: detect-bytejump.h:35
DETECT_CONTENT
@ DETECT_CONTENT
Definition: detect-engine-register.h:62
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
DETECT_BYTEJUMP_NBYTES_VAR
#define DETECT_BYTEJUMP_NBYTES_VAR
Definition: detect-bytejump.h:43
DETECT_BYTEJUMP_BASE_OCT
#define DETECT_BYTEJUMP_BASE_OCT
Definition: detect-bytejump.h:29
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:836
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2580
DE_QUIET
#define DE_QUIET
Definition: detect.h:321
UTHPacketMatchSig
int UTHPacketMatchSig(Packet *p, const char *sig)
Definition: util-unittest-helper.c:823
DETECT_BYTEJUMP_DCE
#define DETECT_BYTEJUMP_DCE
Definition: detect-bytejump.h:40
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:338
DetectParsePcreExec
int DetectParsePcreExec(DetectParseRegex *parse_regex, pcre2_match_data **match, const char *str, int start_offset, int options)
Definition: detect-parse.c:2674
DetectContentData_
Definition: detect-content.h:93
DetectPcreData_::flags
uint16_t flags
Definition: detect-pcre.h:46
SigCleanSignatures
void SigCleanSignatures(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:54
ByteExtractStringUint64
int ByteExtractStringUint64(uint64_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:234
DetectEngineAppendSig
Signature * DetectEngineAppendSig(DetectEngineCtx *, const char *)
Parse and append a Signature into the Detection Engine Context signature list.
Definition: detect-parse.c:2620
DetectBufferGetActiveList
int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
Definition: detect-engine.c:1450
DETECT_BYTEJUMP_BIG
#define DETECT_BYTEJUMP_BIG
Definition: detect-bytejump.h:36
DetectBytejumpData_::base
uint8_t base
Definition: detect-bytejump.h:48
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1278
detect-pcre.h
DetectBytejumpData_
Definition: detect-bytejump.h:46
DetectByteIndexType
uint8_t DetectByteIndexType
Definition: detect-byte.h:28
util-unittest.h
DetectBytejumpData_::offset
int32_t offset
Definition: detect-bytejump.h:50
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
DetectBytejumpData_::multiplier
uint16_t multiplier
Definition: detect-bytejump.h:52
DetectBufferTypeGetByName
int DetectBufferTypeGetByName(const char *name)
Definition: detect-engine.c:1119
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
SCReturnBool
#define SCReturnBool(x)
Definition: util-debug.h:289
DetectBytejumpRegister
void DetectBytejumpRegister(void)
Definition: detect-bytejump.c:72
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
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:17
DetectEngineThreadCtx_
Definition: detect.h:1092
DETECT_BYTEJUMP_ALIGN
#define DETECT_BYTEJUMP_ALIGN
Definition: detect-bytejump.h:39
StringParseI32RangeCheck
int StringParseI32RangeCheck(int32_t *res, int base, size_t len, const char *str, int32_t min, int32_t max)
Definition: util-byte.c:716
DetectSetupParseRegexes
void DetectSetupParseRegexes(const char *parse_str, DetectParseRegex *detect_parse)
Definition: detect-parse.c:2791
DETECT_BYTEJUMP_END
#define DETECT_BYTEJUMP_END
Definition: detect-bytejump.h:42
SignatureInitData_::list
int list
Definition: detect.h:562
SCEnter
#define SCEnter(...)
Definition: util-debug.h:271
detect.h
StringParseU16RangeCheck
int StringParseU16RangeCheck(uint16_t *res, int base, size_t len, const char *str, uint16_t min, uint16_t max)
Definition: util-byte.c:433
SigMatch_::next
struct SigMatch_ * next
Definition: detect.h:351
StringParseUint32
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:313
SigInit
Signature * SigInit(DetectEngineCtx *de_ctx, const char *sigstr)
Parses a signature and adds it to the Detection Engine Context.
Definition: detect-parse.c:2314
SigMatch_::ctx
SigMatchCtx * ctx
Definition: detect.h:350
BYTE_BIG_ENDIAN
#define BYTE_BIG_ENDIAN
Definition: util-byte.h:29
DetectBytejumpDoMatch
bool DetectBytejumpDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchCtx *ctx, const uint8_t *payload, uint32_t payload_len, uint16_t flags, int32_t nbytes, int32_t offset)
Byte jump match function.
Definition: detect-bytejump.c:136
SigGroupCleanup
int SigGroupCleanup(DetectEngineCtx *de_ctx)
Definition: detect-engine-build.c:2218
Packet_
Definition: decode.h:436
detect-engine-build.h
detect-bytejump.h
DetectContentData_::flags
uint32_t flags
Definition: detect-content.h:104
DETECT_BYTEJUMP_BASE_UNSET
#define DETECT_BYTEJUMP_BASE_UNSET
Definition: detect-bytejump.h:28
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:662
SigTableElmt_::Match
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1261
detect-byte.h
DETECT_BYTEJUMP_BASE_HEX
#define DETECT_BYTEJUMP_BASE_HEX
Definition: detect-bytejump.h:31
DETECT_PCRE
@ DETECT_PCRE
Definition: detect-engine-register.h:64
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:342
DETECT_SM_LIST_NOTSET
#define DETECT_SM_LIST_NOTSET
Definition: detect.h:138
DETECT_BYTETEST
@ DETECT_BYTETEST
Definition: detect-engine-register.h:75
BYTE_LITTLE_ENDIAN
#define BYTE_LITTLE_ENDIAN
Definition: util-byte.h:30
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
DetectByteRetrieveSMVar
bool DetectByteRetrieveSMVar(const char *arg, const Signature *s, DetectByteIndexType *index)
Used to retrieve args from BM.
Definition: detect-byte.c:40
flags
uint8_t flags
Definition: decode-gre.h:0
suricata-common.h
SigMatch_::type
uint16_t type
Definition: detect.h:348
detect-byte-extract.h
DetectBytejumpData_::nbytes
uint8_t nbytes
Definition: detect-bytejump.h:47
sigmatch_table
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect-parse.c:127
DetectBufferGetFirstSigMatch
SigMatch * DetectBufferGetFirstSigMatch(const Signature *s, const uint32_t buf_id)
Definition: detect-engine.c:1351
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
DETECT_BYTEJUMP_BASE_DEC
#define DETECT_BYTEJUMP_BASE_DEC
Definition: detect-bytejump.h:30
util-validate.h
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
str
#define str(s)
Definition: suricata-common.h:291
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
SigMatchListSMBelongsTo
int SigMatchListSMBelongsTo(const Signature *s, const SigMatch *key_sm)
Definition: detect-parse.c:820
SCFree
#define SCFree(p)
Definition: util-mem.h:61
UTHFreePacket
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
Definition: util-unittest-helper.c:486
DETECT_BYTE_EXTRACT
@ DETECT_BYTE_EXTRACT
Definition: detect-engine-register.h:184
detect-parse.h
Signature_
Signature container.
Definition: detect.h:593
SigMatch_
a single match condition for a signature
Definition: detect.h:347
payload_len
uint16_t payload_len
Definition: stream-tcp-private.h:1
DETECT_ISDATAAT
@ DETECT_ISDATAAT
Definition: detect-engine-register.h:82
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2541
DETECT_PCRE_RELATIVE_NEXT
#define DETECT_PCRE_RELATIVE_NEXT
Definition: detect-pcre.h:34
DetectPcreData_
Definition: detect-pcre.h:42
DETECT_BYTEMATH
@ DETECT_BYTEMATH
Definition: detect-engine-register.h:77
DETECT_BYTEJUMP_STRING
#define DETECT_BYTEJUMP_STRING
Definition: detect-bytejump.h:37
detect-uricontent.h
DetectGetLastSMFromLists
SigMatch * DetectGetLastSMFromLists(const Signature *s,...)
Returns the sm with the largest index (added latest) from the lists passed to us.
Definition: detect-parse.c:619
SigMatchAppendSMToList
SigMatch * SigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:447
DETECT_BYTEJUMP_BEGIN
#define DETECT_BYTEJUMP_BEGIN
Definition: detect-bytejump.h:34
DetectEngineCtx_::flags
uint8_t flags
Definition: detect.h:838
SigAlloc
Signature * SigAlloc(void)
Definition: detect-parse.c:1529
SCLogDebugEnabled
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition: util-debug.c:771
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:103
DETECT_BYTEJUMP_RELATIVE
#define DETECT_BYTEJUMP_RELATIVE
Definition: detect-bytejump.h:38
SigTableElmt_::RegisterTests
void(* RegisterTests)(void)
Definition: detect.h:1285
DETECT_BYTEJUMP_OFFSET_VAR
#define DETECT_BYTEJUMP_OFFSET_VAR
Definition: detect-bytejump.h:44
DetectBytejumpData_::flags
uint16_t flags
Definition: detect-bytejump.h:49
app-layer.h