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