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