suricata
detect-engine-content-inspection.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2017 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 Anoop Saldanha <anoopsaldanha@gmail.com>
22  *
23  * Performs content inspection on any buffer supplied.
24  */
25 
26 #include "suricata-common.h"
27 #include "suricata.h"
28 
29 #include "decode.h"
30 
31 #include "detect.h"
32 #include "detect-engine.h"
33 #include "detect-parse.h"
34 #include "detect-content.h"
35 #include "detect-pcre.h"
36 #include "detect-isdataat.h"
37 #include "detect-bytetest.h"
38 #include "detect-bytejump.h"
39 #include "detect-byte-extract.h"
40 #include "detect-replace.h"
42 #include "detect-uricontent.h"
43 #include "detect-urilen.h"
44 #include "detect-bsize.h"
45 #include "detect-lua.h"
46 #include "detect-base64-decode.h"
47 #include "detect-base64-data.h"
48 
49 #include "app-layer-dcerpc.h"
50 
51 #include "util-spm.h"
52 #include "util-debug.h"
53 #include "util-print.h"
54 
55 #include "util-unittest.h"
56 #include "util-unittest-helper.h"
57 #include "util-profiling.h"
58 
59 #ifdef HAVE_LUA
60 #include "util-lua.h"
61 #endif
62 
63 /**
64  * \brief Run the actual payload match functions
65  *
66  * The following keywords are inspected:
67  * - content, including all the http and dce modified contents
68  * - isdaatat
69  * - pcre
70  * - bytejump
71  * - bytetest
72  * - byte_extract
73  * - urilen
74  * -
75  *
76  * All keywords are evaluated against the buffer with buffer_len.
77  *
78  * For accounting the last match in relative matching the
79  * det_ctx->buffer_offset int is used.
80  *
81  * \param de_ctx Detection engine context
82  * \param det_ctx Detection engine thread context
83  * \param s Signature to inspect
84  * \param sm SigMatch to inspect
85  * \param f Flow (for pcre flowvar storage)
86  * \param buffer Ptr to the buffer to inspect
87  * \param buffer_len Length of the payload
88  * \param stream_start_offset Indicates the start of the current buffer in
89  * the whole buffer stream inspected. This
90  * applies if the current buffer is inspected
91  * in chunks.
92  * \param inspection_mode Refers to the engine inspection mode we are currently
93  * inspecting. Can be payload, stream, one of the http
94  * buffer inspection modes or dce inspection mode.
95  * \param data Used to send some custom data. For example in
96  * payload inspection mode, data contains packet ptr,
97  * and under dce inspection mode, contains dce state.
98  *
99  * \retval 0 no match
100  * \retval 1 match
101  */
103  const Signature *s, const SigMatchData *smd,
104  Flow *f,
105  uint8_t *buffer, uint32_t buffer_len,
106  uint32_t stream_start_offset, uint8_t flags,
107  uint8_t inspection_mode, void *data)
108 {
109  SCEnter();
111 
112  det_ctx->inspection_recursion_counter++;
113 
115  det_ctx->discontinue_matching = 1;
116  KEYWORD_PROFILING_END(det_ctx, smd->type, 0);
117  SCReturnInt(0);
118  }
119 
120  if (smd == NULL || buffer_len == 0) {
121  KEYWORD_PROFILING_END(det_ctx, smd->type, 0);
122  SCReturnInt(0);
123  }
124 
125  /* \todo unify this which is phase 2 of payload inspection unification */
126  if (smd->type == DETECT_CONTENT) {
127 
129  SCLogDebug("inspecting content %"PRIu32" buffer_len %"PRIu32, cd->id, buffer_len);
130 
131  /* we might have already have this content matched by the mpm.
132  * (if there is any other reason why we'd want to avoid checking
133  * it here, please fill it in) */
134  //if (cd->flags & DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED) {
135  // goto match;
136  //}
137 
138  /* rule parsers should take care of this */
139 #ifdef DEBUG
140  BUG_ON(cd->depth != 0 && cd->depth <= cd->offset);
141 #endif
142 
143  /* search for our pattern, checking the matches recursively.
144  * if we match we look for the next SigMatch as well */
145  uint8_t *found = NULL;
146  uint32_t offset = 0;
147  uint32_t depth = buffer_len;
148  uint32_t prev_offset = 0; /**< used in recursive searching */
149  uint32_t prev_buffer_offset = det_ctx->buffer_offset;
150 
151  do {
152  if ((cd->flags & DETECT_CONTENT_DISTANCE) ||
153  (cd->flags & DETECT_CONTENT_WITHIN)) {
154  SCLogDebug("det_ctx->buffer_offset %"PRIu32, det_ctx->buffer_offset);
155 
156  offset = prev_buffer_offset;
157  depth = buffer_len;
158 
159  int distance = cd->distance;
160  if (cd->flags & DETECT_CONTENT_DISTANCE) {
161  if (cd->flags & DETECT_CONTENT_DISTANCE_BE) {
162  distance = det_ctx->bj_values[cd->distance];
163  }
164  if (distance < 0 && (uint32_t)(abs(distance)) > offset)
165  offset = 0;
166  else
167  offset += distance;
168 
169  SCLogDebug("cd->distance %"PRIi32", offset %"PRIu32", depth %"PRIu32,
170  distance, offset, depth);
171  }
172 
173  if (cd->flags & DETECT_CONTENT_WITHIN) {
174  if (cd->flags & DETECT_CONTENT_WITHIN_BE) {
175  if ((int32_t)depth > (int32_t)(prev_buffer_offset + det_ctx->bj_values[cd->within] + distance)) {
176  depth = prev_buffer_offset + det_ctx->bj_values[cd->within] + distance;
177  }
178  } else {
179  if ((int32_t)depth > (int32_t)(prev_buffer_offset + cd->within + distance)) {
180  depth = prev_buffer_offset + cd->within + distance;
181  }
182 
183  SCLogDebug("cd->within %"PRIi32", det_ctx->buffer_offset %"PRIu32", depth %"PRIu32,
184  cd->within, prev_buffer_offset, depth);
185  }
186 
187  if (stream_start_offset != 0 && prev_buffer_offset == 0) {
188  if (depth <= stream_start_offset) {
189  goto no_match;
190  } else if (depth >= (stream_start_offset + buffer_len)) {
191  ;
192  } else {
193  depth = depth - stream_start_offset;
194  }
195  }
196  }
197 
198  if (cd->flags & DETECT_CONTENT_DEPTH_BE) {
199  if ((det_ctx->bj_values[cd->depth] + prev_buffer_offset) < depth) {
200  depth = prev_buffer_offset + det_ctx->bj_values[cd->depth];
201  }
202  } else {
203  if (cd->depth != 0) {
204  if ((cd->depth + prev_buffer_offset) < depth) {
205  depth = prev_buffer_offset + cd->depth;
206  }
207 
208  SCLogDebug("cd->depth %"PRIu32", depth %"PRIu32, cd->depth, depth);
209  }
210  }
211 
212  if (cd->flags & DETECT_CONTENT_OFFSET_BE) {
213  if (det_ctx->bj_values[cd->offset] > offset)
214  offset = det_ctx->bj_values[cd->offset];
215  } else {
216  if (cd->offset > offset) {
217  offset = cd->offset;
218  SCLogDebug("setting offset %"PRIu32, offset);
219  }
220  }
221  } else { /* implied no relative matches */
222  /* set depth */
223  if (cd->flags & DETECT_CONTENT_DEPTH_BE) {
224  depth = det_ctx->bj_values[cd->depth];
225  } else {
226  if (cd->depth != 0) {
227  depth = cd->depth;
228  }
229  }
230 
231  if (stream_start_offset != 0 && cd->flags & DETECT_CONTENT_DEPTH) {
232  if (depth <= stream_start_offset) {
233  goto no_match;
234  } else if (depth >= (stream_start_offset + buffer_len)) {
235  ;
236  } else {
237  depth = depth - stream_start_offset;
238  }
239  }
240 
241  /* set offset */
243  offset = det_ctx->bj_values[cd->offset];
244  else
245  offset = cd->offset;
246  prev_buffer_offset = 0;
247  }
248 
249  /* update offset with prev_offset if we're searching for
250  * matches after the first occurence. */
251  SCLogDebug("offset %"PRIu32", prev_offset %"PRIu32, offset, prev_offset);
252  if (prev_offset != 0)
253  offset = prev_offset;
254 
255  SCLogDebug("offset %"PRIu32", depth %"PRIu32, offset, depth);
256 
257  if (depth > buffer_len)
258  depth = buffer_len;
259 
260  /* if offset is bigger than depth we can never match on a pattern.
261  * We can however, "match" on a negated pattern. */
262  if (offset > depth || depth == 0) {
263  if (cd->flags & DETECT_CONTENT_NEGATED) {
264  goto match;
265  } else {
266  goto no_match;
267  }
268  }
269 
270  uint8_t *sbuffer = buffer + offset;
271  uint32_t sbuffer_len = depth - offset;
272  uint32_t match_offset = 0;
273  SCLogDebug("sbuffer_len %"PRIu32, sbuffer_len);
274 #ifdef DEBUG
275  BUG_ON(sbuffer_len > buffer_len);
276 #endif
277  if (cd->flags & DETECT_CONTENT_ENDS_WITH && depth < buffer_len) {
278  SCLogDebug("depth < buffer_len while DETECT_CONTENT_ENDS_WITH is set. Can't possibly match.");
279  found = NULL;
280  } else if (cd->content_len > sbuffer_len) {
281  found = NULL;
282  } else {
283  /* do the actual search */
284  found = SpmScan(cd->spm_ctx, det_ctx->spm_thread_ctx, sbuffer,
285  sbuffer_len);
286  }
287 
288  /* next we evaluate the result in combination with the
289  * negation flag. */
290  SCLogDebug("found %p cd negated %s", found, cd->flags & DETECT_CONTENT_NEGATED ? "true" : "false");
291 
292  if (found == NULL && !(cd->flags & DETECT_CONTENT_NEGATED)) {
294  /* independent match from previous matches, so failure is fatal */
295  det_ctx->discontinue_matching = 1;
296  }
297 
298  goto no_match;
299  } else if (found == NULL && (cd->flags & DETECT_CONTENT_NEGATED)) {
300  goto match;
301  } else if (found != NULL && (cd->flags & DETECT_CONTENT_NEGATED)) {
302  SCLogDebug("content %"PRIu32" matched at offset %"PRIu32", but negated so no match", cd->id, match_offset);
303  /* don't bother carrying recursive matches now, for preceding
304  * relative keywords */
305  if (DETECT_CONTENT_IS_SINGLE(cd))
306  det_ctx->discontinue_matching = 1;
307  goto no_match;
308  } else {
309  match_offset = (uint32_t)((found - buffer) + cd->content_len);
310  SCLogDebug("content %"PRIu32" matched at offset %"PRIu32"", cd->id, match_offset);
311  det_ctx->buffer_offset = match_offset;
312 
313  if ((cd->flags & DETECT_CONTENT_ENDS_WITH) == 0 || match_offset == buffer_len) {
314  /* Match branch, add replace to the list if needed */
315  if (cd->flags & DETECT_CONTENT_REPLACE) {
316  if (inspection_mode == DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD) {
317  /* we will need to replace content if match is confirmed */
318  det_ctx->replist = DetectReplaceAddToList(det_ctx->replist, found, cd);
319  } else {
320  SCLogWarning(SC_ERR_INVALID_VALUE, "Can't modify payload without packet");
321  }
322  }
323 
324  /* if this is the last match we're done */
325  if (smd->is_last) {
326  goto match;
327  }
328 
329  SCLogDebug("content %"PRIu32, cd->id);
330  KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
331 
332  /* see if the next buffer keywords match. If not, we will
333  * search for another occurence of this content and see
334  * if the others match then until we run out of matches */
335  int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd+1,
336  f, buffer, buffer_len, stream_start_offset, flags,
337  inspection_mode, data);
338  if (r == 1) {
339  SCReturnInt(1);
340  }
341  SCLogDebug("no match for 'next sm'");
342 
343  if (det_ctx->discontinue_matching) {
344  SCLogDebug("'next sm' said to discontinue this right now");
345  goto no_match;
346  }
347 
348  /* no match and no reason to look for another instance */
349  if ((cd->flags & DETECT_CONTENT_WITHIN_NEXT) == 0) {
350  SCLogDebug("'next sm' does not depend on me, so we can give up");
351  det_ctx->discontinue_matching = 1;
352  goto no_match;
353  }
354 
355  SCLogDebug("'next sm' depends on me %p, lets see what we can do (flags %u)", cd, cd->flags);
356  }
357  /* set the previous match offset to the start of this match + 1 */
358  prev_offset = (match_offset - (cd->content_len - 1));
359  SCLogDebug("trying to see if there is another match after prev_offset %"PRIu32, prev_offset);
360  }
361 
362  } while(1);
363 
364  } else if (smd->type == DETECT_ISDATAAT) {
365  SCLogDebug("inspecting isdataat");
366 
367  const DetectIsdataatData *id = (DetectIsdataatData *)smd->ctx;
368  uint32_t dataat = id->dataat;
369  if (id->flags & ISDATAAT_OFFSET_BE) {
370  uint64_t be_value = det_ctx->bj_values[dataat];
371  if (be_value >= 100000000) {
372  if ((id->flags & ISDATAAT_NEGATED) == 0) {
373  SCLogDebug("extracted value %"PRIu64" very big: no match", be_value);
374  goto no_match;
375  }
376  SCLogDebug("extracted value way %"PRIu64" very big: match", be_value);
377  goto match;
378  }
379  dataat = (uint32_t)be_value;
380  SCLogDebug("isdataat: using value %u from byte_extract local_id %u", dataat, id->dataat);
381  }
382 
383  if (id->flags & ISDATAAT_RELATIVE) {
384  if (det_ctx->buffer_offset + dataat > buffer_len) {
385  SCLogDebug("det_ctx->buffer_offset + dataat %"PRIu32" > %"PRIu32, det_ctx->buffer_offset + dataat, buffer_len);
386  if (id->flags & ISDATAAT_NEGATED)
387  goto match;
388  goto no_match;
389  } else {
390  SCLogDebug("relative isdataat match");
391  if (id->flags & ISDATAAT_NEGATED)
392  goto no_match;
393  goto match;
394  }
395  } else {
396  if (dataat < buffer_len) {
397  SCLogDebug("absolute isdataat match");
398  if (id->flags & ISDATAAT_NEGATED)
399  goto no_match;
400  goto match;
401  } else {
402  SCLogDebug("absolute isdataat mismatch, id->isdataat %"PRIu32", buffer_len %"PRIu32"", dataat, buffer_len);
403  if (id->flags & ISDATAAT_NEGATED)
404  goto match;
405  goto no_match;
406  }
407  }
408 
409  } else if (smd->type == DETECT_PCRE) {
410  SCLogDebug("inspecting pcre");
411  DetectPcreData *pe = (DetectPcreData *)smd->ctx;
412  uint32_t prev_buffer_offset = det_ctx->buffer_offset;
413  uint32_t prev_offset = 0;
414  int r = 0;
415 
416  det_ctx->pcre_match_start_offset = 0;
417  do {
418  Packet *p = NULL;
419  if (inspection_mode == DETECT_ENGINE_CONTENT_INSPECTION_MODE_PAYLOAD)
420  p = (Packet *)data;
421  r = DetectPcrePayloadMatch(det_ctx, s, smd, p, f,
422  buffer, buffer_len);
423  if (r == 0) {
424  goto no_match;
425  }
426 
427  if (!(pe->flags & DETECT_PCRE_RELATIVE_NEXT)) {
428  SCLogDebug("no relative match coming up, so this is a match");
429  goto match;
430  }
431  KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
432 
433  /* save it, in case we need to do a pcre match once again */
434  prev_offset = det_ctx->pcre_match_start_offset;
435 
436  /* see if the next payload keywords match. If not, we will
437  * search for another occurence of this pcre and see
438  * if the others match, until we run out of matches */
439  r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd+1,
440  f, buffer, buffer_len, stream_start_offset, flags,
441  inspection_mode, data);
442  if (r == 1) {
443  SCReturnInt(1);
444  }
445 
446  if (det_ctx->discontinue_matching)
447  goto no_match;
448 
449  det_ctx->buffer_offset = prev_buffer_offset;
450  det_ctx->pcre_match_start_offset = prev_offset;
451  } while (1);
452 
453  } else if (smd->type == DETECT_BYTETEST) {
454  DetectBytetestData *btd = (DetectBytetestData *)smd->ctx;
455  uint8_t btflags = btd->flags;
456  int32_t offset = btd->offset;
457  uint64_t value = btd->value;
458  if (btflags & DETECT_BYTETEST_OFFSET_BE) {
459  offset = det_ctx->bj_values[offset];
460  }
461  if (btflags & DETECT_BYTETEST_VALUE_BE) {
462  value = det_ctx->bj_values[value];
463  }
464 
465  /* if we have dce enabled we will have to use the endianness
466  * specified by the dce header */
467  if (btflags & DETECT_BYTETEST_DCE && data != NULL) {
468  DCERPCState *dcerpc_state = (DCERPCState *)data;
469  /* enable the endianness flag temporarily. once we are done
470  * processing we reset the flags to the original value*/
471  btflags |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] & 0x10) ?
473  }
474 
475  if (DetectBytetestDoMatch(det_ctx, s, smd->ctx, buffer, buffer_len, btflags,
476  offset, value) != 1) {
477  goto no_match;
478  }
479 
480  goto match;
481 
482  } else if (smd->type == DETECT_BYTEJUMP) {
483  DetectBytejumpData *bjd = (DetectBytejumpData *)smd->ctx;
484  uint8_t bjflags = bjd->flags;
485  int32_t offset = bjd->offset;
486 
487  if (bjflags & DETECT_BYTEJUMP_OFFSET_BE) {
488  offset = det_ctx->bj_values[offset];
489  }
490 
491  /* if we have dce enabled we will have to use the endianness
492  * specified by the dce header */
493  if (bjflags & DETECT_BYTEJUMP_DCE && data != NULL) {
494  DCERPCState *dcerpc_state = (DCERPCState *)data;
495  /* enable the endianness flag temporarily. once we are done
496  * processing we reset the flags to the original value*/
497  bjflags |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] & 0x10) ?
499  }
500 
501  if (DetectBytejumpDoMatch(det_ctx, s, smd->ctx, buffer, buffer_len,
502  bjflags, offset) != 1) {
503  goto no_match;
504  }
505 
506  goto match;
507 
508  } else if (smd->type == DETECT_BYTE_EXTRACT) {
509 
510  DetectByteExtractData *bed = (DetectByteExtractData *)smd->ctx;
511  uint8_t endian = bed->endian;
512 
513  /* if we have dce enabled we will have to use the endianness
514  * specified by the dce header */
515  if ((bed->flags & DETECT_BYTE_EXTRACT_FLAG_ENDIAN) &&
516  endian == DETECT_BYTE_EXTRACT_ENDIAN_DCE && data != NULL) {
517 
518  DCERPCState *dcerpc_state = (DCERPCState *)data;
519  /* enable the endianness flag temporarily. once we are done
520  * processing we reset the flags to the original value*/
521  endian |= ((dcerpc_state->dcerpc.dcerpchdr.packed_drep[0] == 0x10) ?
523  }
524 
525  if (DetectByteExtractDoMatch(det_ctx, smd, s, buffer,
526  buffer_len,
527  &det_ctx->bj_values[bed->local_id],
528  endian) != 1) {
529  goto no_match;
530  }
531 
532  goto match;
533 
534  } else if (smd->type == DETECT_BSIZE) {
535 
536  bool eof = (flags & DETECT_CI_FLAGS_END);
537  const uint64_t data_size = buffer_len + stream_start_offset;
538  int r = DetectBsizeMatch(smd->ctx, data_size, eof);
539  if (r < 0) {
540  det_ctx->discontinue_matching = 1;
541  goto no_match;
542 
543  } else if (r == 0) {
544  goto no_match;
545  }
546  goto match;
547 
548  } else if (smd->type == DETECT_AL_URILEN) {
549  SCLogDebug("inspecting uri len");
550 
551  int r = 0;
552  DetectUrilenData *urilend = (DetectUrilenData *) smd->ctx;
553 
554  switch (urilend->mode) {
555  case DETECT_URILEN_EQ:
556  if (buffer_len == urilend->urilen1)
557  r = 1;
558  break;
559  case DETECT_URILEN_LT:
560  if (buffer_len < urilend->urilen1)
561  r = 1;
562  break;
563  case DETECT_URILEN_GT:
564  if (buffer_len > urilend->urilen1)
565  r = 1;
566  break;
567  case DETECT_URILEN_RA:
568  if (buffer_len > urilend->urilen1 &&
569  buffer_len < urilend->urilen2) {
570  r = 1;
571  }
572  break;
573  }
574 
575  if (r == 1) {
576  goto match;
577  }
578 
579  det_ctx->discontinue_matching = 0;
580 
581  goto no_match;
582 #ifdef HAVE_LUA
583  }
584  else if (smd->type == DETECT_LUA) {
585  SCLogDebug("lua starting");
586 
587  if (DetectLuaMatchBuffer(det_ctx, s, smd, buffer, buffer_len,
588  det_ctx->buffer_offset, f) != 1)
589  {
590  SCLogDebug("lua no_match");
591  goto no_match;
592  }
593  SCLogDebug("lua match");
594  goto match;
595 #endif /* HAVE_LUA */
596  } else if (smd->type == DETECT_BASE64_DECODE) {
597  if (DetectBase64DecodeDoMatch(det_ctx, s, smd, buffer, buffer_len)) {
598  if (s->sm_arrays[DETECT_SM_LIST_BASE64_DATA] != NULL) {
599  KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
600  if (DetectBase64DataDoMatch(de_ctx, det_ctx, s, f)) {
601  /* Base64 is a terminal list. */
602  goto final_match;
603  }
604  }
605  }
606  } else {
607  SCLogDebug("sm->type %u", smd->type);
608 #ifdef DEBUG
609  BUG_ON(1);
610 #endif
611  }
612 
613 no_match:
614  KEYWORD_PROFILING_END(det_ctx, smd->type, 0);
615  SCReturnInt(0);
616 
617 match:
618  /* this sigmatch matched, inspect the next one. If it was the last,
619  * the buffer portion of the signature matched. */
620  if (!smd->is_last) {
621  KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
622  int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd+1,
623  f, buffer, buffer_len, stream_start_offset, flags,
624  inspection_mode, data);
625  SCReturnInt(r);
626  }
627 final_match:
628  KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
629  SCReturnInt(1);
630 }
631 
632 #ifdef UNITTESTS
634 #endif
int DetectBase64DecodeDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, uint8_t *payload, uint32_t payload_len)
#define ISDATAAT_OFFSET_BE
uint16_t flags
#define SCLogDebug(...)
Definition: util-debug.h:335
int DetectPcrePayloadMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, uint8_t *payload, uint32_t payload_len)
Match a regex on a single payload.
Definition: detect-pcre.c:171
#define DETECT_BYTETEST_LITTLE
#define KEYWORD_PROFILING_END(ctx, type, m)
#define BUG_ON(x)
uint16_t discontinue_matching
Definition: detect.h:1029
uint64_t * bj_values
Definition: detect.h:1074
uint8_t is_last
Definition: detect.h:333
uint64_t offset
DetectReplaceList * replist
Definition: detect.h:1077
Data needed for Match()
Definition: detect.h:331
#define DETECT_CONTENT_DISTANCE_BE
#define ISDATAAT_RELATIVE
#define DETECT_BYTEJUMP_LITTLE
#define DETECT_CONTENT_DISTANCE
uint32_t buffer_offset
Definition: detect.h:994
Signature container.
Definition: detect.h:495
#define DETECT_CONTENT_DEPTH
#define DETECT_URILEN_EQ
Definition: detect-urilen.h:30
uint16_t flags
Definition: detect-pcre.h:42
#define DETECT_CONTENT_IS_SINGLE(c)
int DetectBase64DataDoMatch(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, Flow *f)
DetectReplaceList * DetectReplaceAddToList(DetectReplaceList *replist, uint8_t *found, DetectContentData *cd)
main detection engine ctx
Definition: detect.h:723
#define DETECT_CI_FLAGS_END
#define DETECT_CONTENT_WITHIN_BE
#define KEYWORD_PROFILING_START
#define DETECT_URILEN_GT
Definition: detect-urilen.h:28
#define ISDATAAT_NEGATED
#define DETECT_URILEN_LT
Definition: detect-urilen.h:27
int DetectByteExtractDoMatch(DetectEngineThreadCtx *det_ctx, const SigMatchData *smd, const Signature *s, uint8_t *payload, uint16_t payload_len, uint64_t *value, uint8_t endian)
#define SCEnter(...)
Definition: util-debug.h:337
#define DETECT_BYTETEST_VALUE_BE
#define DETECT_BYTE_EXTRACT_ENDIAN_BIG
int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchCtx *ctx, uint8_t *payload, uint32_t payload_len, uint8_t flags, int32_t offset, uint64_t value)
Bytetest detection code.
#define DETECT_CONTENT_WITHIN_NEXT
#define DETECT_URILEN_RA
Definition: detect-urilen.h:29
#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 SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:281
#define DETECT_CONTENT_ENDS_WITH
#define DETECT_BYTE_EXTRACT_ENDIAN_LITTLE
#define DETECT_CONTENT_OFFSET_BE
uint8_t type
Definition: detect.h:332
#define DETECT_CONTENT_NEGATED
#define DETECT_CONTENT_REPLACE
uint32_t pcre_match_start_offset
Definition: detect.h:996
int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Flow *f, uint8_t *buffer, uint32_t buffer_len, uint32_t stream_start_offset, uint8_t flags, uint8_t inspection_mode, void *data)
Run the actual payload match functions.
int DetectBsizeMatch(const SigMatchCtx *ctx, const uint64_t buffer_size, bool eof)
bsize match function
Definition: detect-bsize.c:84
#define DETECT_BYTETEST_DCE
#define DETECT_BYTETEST_OFFSET_BE
#define DETECT_CONTENT_WITHIN
int inspection_recursion_counter
Definition: detect.h:1041
#define DETECT_PCRE_RELATIVE_NEXT
Definition: detect-pcre.h:32
#define DETECT_BYTE_EXTRACT_FLAG_ENDIAN
Holds data related to byte_extract keyword.
int DetectLuaMatchBuffer(DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, uint8_t *buffer, uint32_t buffer_len, uint32_t offset, Flow *f)
#define DETECT_BYTEJUMP_OFFSET_BE
SpmThreadCtx * spm_thread_ctx
Definition: detect.h:1068
#define DETECT_CONTENT_DEPTH_BE
#define DETECT_BYTEJUMP_DCE
Flow data structure.
Definition: flow.h:324
SigMatchCtx * ctx
Definition: detect.h:334
int inspection_recursion_limit
Definition: detect.h:795
#define DETECT_BYTE_EXTRACT_ENDIAN_DCE
uint8_t * SpmScan(const SpmCtx *ctx, SpmThreadCtx *thread_ctx, const uint8_t *haystack, uint32_t haystack_len)
Definition: util-spm.c:186