suricata
detect-icode.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2016 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 Gerardo Iglesias <iglesiasg@gmail.com>
22  *
23  * Implements icode keyword support
24  */
25 
26 #include "suricata-common.h"
27 #include "debug.h"
28 #include "decode.h"
29 
30 #include "detect.h"
31 #include "detect-parse.h"
33 
34 #include "detect-icode.h"
35 
36 #include "util-byte.h"
37 #include "util-unittest.h"
38 #include "util-unittest-helper.h"
39 #include "util-debug.h"
40 
41 /**
42  *\brief Regex for parsing our icode options
43  */
44 #define PARSE_REGEX "^\\s*(<|>)?\\s*([0-9]+)\\s*(?:<>\\s*([0-9]+))?\\s*$"
45 
46 static pcre *parse_regex;
47 static pcre_extra *parse_regex_study;
48 
49 static int DetectICodeMatch(DetectEngineThreadCtx *, Packet *,
50  const Signature *, const SigMatchCtx *);
51 static int DetectICodeSetup(DetectEngineCtx *, Signature *, const char *);
52 void DetectICodeRegisterTests(void);
53 void DetectICodeFree(void *);
54 
55 static int PrefilterSetupICode(DetectEngineCtx *de_ctx, SigGroupHead *sgh);
56 static _Bool PrefilterICodeIsPrefilterable(const Signature *s);
57 
58 /**
59  * \brief Registration function for icode: keyword
60  */
62 {
63  sigmatch_table[DETECT_ICODE].name = "icode";
64  sigmatch_table[DETECT_ICODE].desc = "match on specific ICMP id-value";
65  sigmatch_table[DETECT_ICODE].url = DOC_URL DOC_VERSION "/rules/header-keywords.html#icode";
66  sigmatch_table[DETECT_ICODE].Match = DetectICodeMatch;
67  sigmatch_table[DETECT_ICODE].Setup = DetectICodeSetup;
70 
71  sigmatch_table[DETECT_ICODE].SupportsPrefilter = PrefilterICodeIsPrefilterable;
72  sigmatch_table[DETECT_ICODE].SetupPrefilter = PrefilterSetupICode;
73 
74  DetectSetupParseRegexes(PARSE_REGEX, &parse_regex, &parse_regex_study);
75 }
76 
77 #define DETECT_ICODE_EQ PREFILTER_U8HASH_MODE_EQ /**< "equal" operator */
78 #define DETECT_ICODE_LT PREFILTER_U8HASH_MODE_LT /**< "less than" operator */
79 #define DETECT_ICODE_GT PREFILTER_U8HASH_MODE_GT /**< "greater than" operator */
80 #define DETECT_ICODE_RN PREFILTER_U8HASH_MODE_RA /**< "range" operator */
81 
82 typedef struct DetectICodeData_ {
83  uint8_t code1;
84  uint8_t code2;
85 
86  uint8_t mode;
88 
89 static inline int ICodeMatch(const uint8_t pcode, const uint8_t mode,
90  const uint8_t dcode1, const uint8_t dcode2)
91 {
92  switch (mode) {
93  case DETECT_ICODE_EQ:
94  return (pcode == dcode1) ? 1 : 0;
95 
96  case DETECT_ICODE_LT:
97  return (pcode < dcode1) ? 1 : 0;
98 
99  case DETECT_ICODE_GT:
100  return (pcode > dcode1) ? 1 : 0;
101 
102  case DETECT_ICODE_RN:
103  return (pcode > dcode1 && pcode < dcode2) ? 1 : 0;
104  }
105  return 0;
106 }
107 
108 /**
109  * \brief This function is used to match icode rule option set on a packet with those passed via icode:
110  *
111  * \param t pointer to thread vars
112  * \param det_ctx pointer to the pattern matcher thread
113  * \param p pointer to the current packet
114  * \param m pointer to the sigmatch that we will cast into DetectICodeData
115  *
116  * \retval 0 no match
117  * \retval 1 match
118  */
119 static int DetectICodeMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
120  const Signature *s, const SigMatchCtx *ctx)
121 {
122  if (PKT_IS_PSEUDOPKT(p))
123  return 0;
124 
125  uint8_t picode;
126  if (PKT_IS_ICMPV4(p)) {
127  picode = ICMPV4_GET_CODE(p);
128  } else if (PKT_IS_ICMPV6(p)) {
129  picode = ICMPV6_GET_CODE(p);
130  } else {
131  /* Packet not ICMPv4 nor ICMPv6 */
132  return 0;
133  }
134 
135  const DetectICodeData *icd = (const DetectICodeData *)ctx;
136  return ICodeMatch(picode, icd->mode, icd->code1, icd->code2);
137 }
138 
139 /**
140  * \brief This function is used to parse icode options passed via icode: keyword
141  *
142  * \param icodestr Pointer to the user provided icode options
143  *
144  * \retval icd pointer to DetectICodeData on success
145  * \retval NULL on failure
146  */
147 static DetectICodeData *DetectICodeParse(const char *icodestr)
148 {
149  DetectICodeData *icd = NULL;
150  char *args[3] = {NULL, NULL, NULL};
151 #define MAX_SUBSTRINGS 30
152  int ret = 0, res = 0;
153  int ov[MAX_SUBSTRINGS];
154 
155  ret = pcre_exec(parse_regex, parse_regex_study, icodestr, strlen(icodestr), 0, 0, ov, MAX_SUBSTRINGS);
156  if (ret < 1 || ret > 4) {
157  SCLogError(SC_ERR_PCRE_MATCH, "pcre_exec parse error, ret %" PRId32 ", string %s", ret, icodestr);
158  goto error;
159  }
160 
161  int i;
162  const char *str_ptr;
163  for (i = 1; i < ret; i++) {
164  res = pcre_get_substring((char *)icodestr, ov, MAX_SUBSTRINGS, i, &str_ptr);
165  if (res < 0) {
166  SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
167  goto error;
168  }
169  args[i-1] = (char *)str_ptr;
170  }
171 
172  icd = SCMalloc(sizeof(DetectICodeData));
173  if (unlikely(icd == NULL))
174  goto error;
175  icd->code1 = 0;
176  icd->code2 = 0;
177  icd->mode = 0;
178 
179  /* we have either "<" or ">" */
180  if (args[0] != NULL && strlen(args[0]) != 0) {
181  /* we have a third part ("<> y"), therefore it's invalid */
182  if (args[2] != NULL) {
183  SCLogError(SC_ERR_INVALID_VALUE, "icode: invalid value");
184  goto error;
185  }
186  /* we have only a comparison ("<", ">") */
187  if (ByteExtractStringUint8(&icd->code1, 10, 0, args[1]) < 0) {
188  SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp code %s is not "
189  "valid", args[1]);
190  goto error;
191  }
192  if ((strcmp(args[0], ">")) == 0) icd->mode = DETECT_ICODE_GT;
193  else icd->mode = DETECT_ICODE_LT;
194  } else { /* no "<", ">" */
195  /* we have a range ("<>") */
196  if (args[2] != NULL) {
197  icd->mode = (uint8_t) DETECT_ICODE_RN;
198  if (ByteExtractStringUint8(&icd->code1, 10, 0, args[1]) < 0) {
199  SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp code %s is not "
200  "valid", args[1]);
201  goto error;
202  }
203  if (ByteExtractStringUint8(&icd->code2, 10, 0, args[2]) < 0) {
204  SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp code %s is not "
205  "valid", args[2]);
206  goto error;
207  }
208  /* we check that the first given value in the range is less than
209  the second, otherwise we swap them */
210  if (icd->code1 > icd->code2) {
211  uint8_t temp = icd->code1;
212  icd->code1 = icd->code2;
213  icd->code2 = temp;
214  }
215  } else { /* we have an equality */
216  icd->mode = DETECT_ICODE_EQ;
217  if (ByteExtractStringUint8(&icd->code1, 10, 0, args[1]) < 0) {
218  SCLogError(SC_ERR_INVALID_ARGUMENT, "specified icmp code %s is not "
219  "valid", args[1]);
220  goto error;
221  }
222  }
223  }
224 
225  for (i = 0; i < (ret-1); i++) {
226  if (args[i] != NULL)
227  SCFree(args[i]);
228  }
229  return icd;
230 
231 error:
232  for (i = 0; i < (ret-1) && i < 3; i++) {
233  if (args[i] != NULL)
234  SCFree(args[i]);
235  }
236  if (icd != NULL)
237  DetectICodeFree(icd);
238  return NULL;
239 }
240 
241 /**
242  * \brief this function is used to add the parsed icode data into the current signature
243  *
244  * \param de_ctx pointer to the Detection Engine Context
245  * \param s pointer to the Current Signature
246  * \param icodestr pointer to the user provided icode options
247  *
248  * \retval 0 on Success
249  * \retval -1 on Failure
250  */
251 static int DetectICodeSetup(DetectEngineCtx *de_ctx, Signature *s, const char *icodestr)
252 {
253 
254  DetectICodeData *icd = NULL;
255  SigMatch *sm = NULL;
256 
257  icd = DetectICodeParse(icodestr);
258  if (icd == NULL) goto error;
259 
260  sm = SigMatchAlloc();
261  if (sm == NULL) goto error;
262 
263  sm->type = DETECT_ICODE;
264  sm->ctx = (SigMatchCtx *)icd;
265 
268 
269  return 0;
270 
271 error:
272  if (icd != NULL) DetectICodeFree(icd);
273  if (sm != NULL) SCFree(sm);
274  return -1;
275 }
276 
277 /**
278  * \brief this function will free memory associated with DetectICodeData
279  *
280  * \param ptr pointer to DetectICodeData
281  */
282 void DetectICodeFree(void *ptr)
283 {
284  DetectICodeData *icd = (DetectICodeData *)ptr;
285  SCFree(icd);
286 }
287 
288 /* prefilter code */
289 
290 static void PrefilterPacketICodeMatch(DetectEngineThreadCtx *det_ctx,
291  Packet *p, const void *pectx)
292 {
293  if (PKT_IS_PSEUDOPKT(p)) {
294  SCReturn;
295  }
296 
297  uint8_t picode;
298  if (PKT_IS_ICMPV4(p)) {
299  picode = ICMPV4_GET_CODE(p);
300  } else if (PKT_IS_ICMPV6(p)) {
301  picode = ICMPV6_GET_CODE(p);
302  } else {
303  /* Packet not ICMPv4 nor ICMPv6 */
304  return;
305  }
306 
307  const PrefilterPacketU8HashCtx *h = pectx;
308  const SigsArray *sa = h->array[picode];
309  if (sa) {
310  PrefilterAddSids(&det_ctx->pmq, sa->sigs, sa->cnt);
311  }
312 }
313 
314 static void
315 PrefilterPacketICodeSet(PrefilterPacketHeaderValue *v, void *smctx)
316 {
317  const DetectICodeData *a = smctx;
318  v->u8[0] = a->mode;
319  v->u8[1] = a->code1;
320  v->u8[2] = a->code2;
321 }
322 
323 static _Bool
324 PrefilterPacketICodeCompare(PrefilterPacketHeaderValue v, void *smctx)
325 {
326  const DetectICodeData *a = smctx;
327  if (v.u8[0] == a->mode &&
328  v.u8[1] == a->code1 &&
329  v.u8[2] == a->code2)
330  return TRUE;
331  return FALSE;
332 }
333 
334 static int PrefilterSetupICode(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
335 {
337  PrefilterPacketICodeSet,
338  PrefilterPacketICodeCompare,
339  PrefilterPacketICodeMatch);
340 }
341 
342 static _Bool PrefilterICodeIsPrefilterable(const Signature *s)
343 {
344  const SigMatch *sm;
345  for (sm = s->init_data->smlists[DETECT_SM_LIST_MATCH] ; sm != NULL; sm = sm->next) {
346  switch (sm->type) {
347  case DETECT_ICODE:
348  return TRUE;
349  }
350  }
351  return FALSE;
352 }
353 
354 #ifdef UNITTESTS
355 #include "detect-engine.h"
356 #include "detect-engine-mpm.h"
357 
358 /**
359  * \test DetectICodeParseTest01 is a test for setting a valid icode value
360  */
361 static int DetectICodeParseTest01(void)
362 {
363  DetectICodeData *icd = NULL;
364  int result = 0;
365  icd = DetectICodeParse("8");
366  if (icd != NULL) {
367  if (icd->code1 == 8 && icd->mode == DETECT_ICODE_EQ)
368  result = 1;
369  DetectICodeFree(icd);
370  }
371  return result;
372 }
373 
374 /**
375  * \test DetectICodeParseTest02 is a test for setting a valid icode value
376  * with ">" operator
377  */
378 static int DetectICodeParseTest02(void)
379 {
380  DetectICodeData *icd = NULL;
381  int result = 0;
382  icd = DetectICodeParse(">8");
383  if (icd != NULL) {
384  if (icd->code1 == 8 && icd->mode == DETECT_ICODE_GT)
385  result = 1;
386  DetectICodeFree(icd);
387  }
388  return result;
389 }
390 
391 /**
392  * \test DetectICodeParseTest03 is a test for setting a valid icode value
393  * with "<" operator
394  */
395 static int DetectICodeParseTest03(void)
396 {
397  DetectICodeData *icd = NULL;
398  int result = 0;
399  icd = DetectICodeParse("<8");
400  if (icd != NULL) {
401  if (icd->code1 == 8 && icd->mode == DETECT_ICODE_LT)
402  result = 1;
403  DetectICodeFree(icd);
404  }
405  return result;
406 }
407 
408 /**
409  * \test DetectICodeParseTest04 is a test for setting a valid icode value
410  * with "<>" operator
411  */
412 static int DetectICodeParseTest04(void)
413 {
414  DetectICodeData *icd = NULL;
415  int result = 0;
416  icd = DetectICodeParse("8<>20");
417  if (icd != NULL) {
418  if (icd->code1 == 8 && icd->code2 == 20 && icd->mode == DETECT_ICODE_RN)
419  result = 1;
420  DetectICodeFree(icd);
421  }
422  return result;
423 }
424 
425 /**
426  * \test DetectICodeParseTest05 is a test for setting a valid icode value
427  * with spaces all around
428  */
429 static int DetectICodeParseTest05(void)
430 {
431  DetectICodeData *icd = NULL;
432  int result = 0;
433  icd = DetectICodeParse(" 8 ");
434  if (icd != NULL) {
435  if (icd->code1 == 8 && icd->mode == DETECT_ICODE_EQ)
436  result = 1;
437  DetectICodeFree(icd);
438  }
439  return result;
440 }
441 
442 /**
443  * \test DetectICodeParseTest06 is a test for setting a valid icode value
444  * with ">" operator and spaces all around
445  */
446 static int DetectICodeParseTest06(void)
447 {
448  DetectICodeData *icd = NULL;
449  int result = 0;
450  icd = DetectICodeParse(" > 8 ");
451  if (icd != NULL) {
452  if (icd->code1 == 8 && icd->mode == DETECT_ICODE_GT)
453  result = 1;
454  DetectICodeFree(icd);
455  }
456  return result;
457 }
458 
459 /**
460  * \test DetectICodeParseTest07 is a test for setting a valid icode value
461  * with "<>" operator and spaces all around
462  */
463 static int DetectICodeParseTest07(void)
464 {
465  DetectICodeData *icd = NULL;
466  int result = 0;
467  icd = DetectICodeParse(" 8 <> 20 ");
468  if (icd != NULL) {
469  if (icd->code1 == 8 && icd->code2 == 20 && icd->mode == DETECT_ICODE_RN)
470  result = 1;
471  DetectICodeFree(icd);
472  }
473  return result;
474 }
475 
476 /**
477  * \test DetectICodeParseTest08 is a test for setting an invalid icode value
478  */
479 static int DetectICodeParseTest08(void)
480 {
481  DetectICodeData *icd = NULL;
482  icd = DetectICodeParse("> 8 <> 20");
483  if (icd == NULL)
484  return 1;
485  DetectICodeFree(icd);
486  return 0;
487 }
488 
489 /**
490  * \test DetectICodeMatchTest01 is a test for checking the working of icode
491  * keyword by creating 5 rules and matching a crafted packet against
492  * them. 4 out of 5 rules shall trigger.
493  */
494 static int DetectICodeMatchTest01(void)
495 {
496 
497  Packet *p = NULL;
498  Signature *s = NULL;
499  ThreadVars th_v;
500  DetectEngineThreadCtx *det_ctx;
501  int result = 0;
502 
503  memset(&th_v, 0, sizeof(th_v));
504 
505  p = UTHBuildPacket(NULL, 0, IPPROTO_ICMP);
506 
507  p->icmpv4h->code = 10;
508 
510  if (de_ctx == NULL) {
511  goto end;
512  }
513 
514  de_ctx->flags |= DE_QUIET;
515 
516  s = de_ctx->sig_list = SigInit(de_ctx,"alert icmp any any -> any any (icode:10; sid:1;)");
517  if (s == NULL) {
518  goto end;
519  }
520 
521  s = s->next = SigInit(de_ctx,"alert icmp any any -> any any (icode:<15; sid:2;)");
522  if (s == NULL) {
523  goto end;
524  }
525 
526  s = s->next = SigInit(de_ctx,"alert icmp any any -> any any (icode:>20; sid:3;)");
527  if (s == NULL) {
528  goto end;
529  }
530 
531  s = s->next = SigInit(de_ctx,"alert icmp any any -> any any (icode:8<>20; sid:4;)");
532  if (s == NULL) {
533  goto end;
534  }
535 
536  s = s->next = SigInit(de_ctx,"alert icmp any any -> any any (icode:20<>8; sid:5;)");
537  if (s == NULL) {
538  goto end;
539  }
540 
541  SigGroupBuild(de_ctx);
542  DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
543 
544  SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
545  if (PacketAlertCheck(p, 1) == 0) {
546  SCLogDebug("sid 1 did not alert, but should have");
547  goto cleanup;
548  } else if (PacketAlertCheck(p, 2) == 0) {
549  SCLogDebug("sid 2 did not alert, but should have");
550  goto cleanup;
551  } else if (PacketAlertCheck(p, 3)) {
552  SCLogDebug("sid 3 alerted, but should not have");
553  goto cleanup;
554  } else if (PacketAlertCheck(p, 4) == 0) {
555  SCLogDebug("sid 4 did not alert, but should have");
556  goto cleanup;
557  } else if (PacketAlertCheck(p, 5) == 0) {
558  SCLogDebug("sid 5 did not alert, but should have");
559  goto cleanup;
560  }
561 
562  result = 1;
563 
564 cleanup:
565  SigGroupCleanup(de_ctx);
566  SigCleanSignatures(de_ctx);
567 
568  DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
569  DetectEngineCtxFree(de_ctx);
570 
571  UTHFreePackets(&p, 1);
572 end:
573  return result;
574 }
575 
576 #endif /* UNITTESTS */
577 
578 /**
579  * \brief this function registers unit tests for DetectICode
580  */
582 {
583 #ifdef UNITTESTS
584  UtRegisterTest("DetectICodeParseTest01", DetectICodeParseTest01);
585  UtRegisterTest("DetectICodeParseTest02", DetectICodeParseTest02);
586  UtRegisterTest("DetectICodeParseTest03", DetectICodeParseTest03);
587  UtRegisterTest("DetectICodeParseTest04", DetectICodeParseTest04);
588  UtRegisterTest("DetectICodeParseTest05", DetectICodeParseTest05);
589  UtRegisterTest("DetectICodeParseTest06", DetectICodeParseTest06);
590  UtRegisterTest("DetectICodeParseTest07", DetectICodeParseTest07);
591  UtRegisterTest("DetectICodeParseTest08", DetectICodeParseTest08);
592  UtRegisterTest("DetectICodeMatchTest01", DetectICodeMatchTest01);
593 #endif /* UNITTESTS */
594 }
#define MAX_SUBSTRINGS
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1448
SignatureInitData * init_data
Definition: detect.h:591
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1186
#define SCLogDebug(...)
Definition: util-debug.h:335
int(* SetupPrefilter)(DetectEngineCtx *de_ctx, struct SigGroupHead_ *sgh)
Definition: detect.h:1189
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
uint32_t flags
Definition: detect.h:523
_Bool(* SupportsPrefilter)(const Signature *s)
Definition: detect.h:1188
#define FALSE
#define unlikely(expr)
Definition: util-optimize.h:35
Signature * SigInit(DetectEngineCtx *, const char *)
Parses a signature and adds it to the Detection Engine Context.
ICMPV4Hdr * icmpv4h
Definition: decode.h:529
Signature * sig_list
Definition: detect.h:767
void SigCleanSignatures(DetectEngineCtx *de_ctx)
Container for matching data for a signature group.
Definition: detect.h:1336
void DetectICodeFree(void *)
this function will free memory associated with DetectICodeData
Definition: detect-icode.c:282
#define SIG_FLAG_REQUIRE_PACKET
Definition: detect.h:223
int ByteExtractStringUint8(uint8_t *res, int base, uint16_t len, const char *str)
Definition: util-byte.c:284
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
const char * name
Definition: detect.h:1200
Signature container.
Definition: detect.h:522
#define TRUE
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:313
struct SigMatch_ * next
Definition: detect.h:322
main detection engine ctx
Definition: detect.h:761
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
#define PARSE_REGEX
Regex for parsing our icode options.
Definition: detect-icode.c:44
#define DE_QUIET
Definition: detect.h:292
#define ICMPV6_GET_CODE(p)
#define DETECT_ICODE_EQ
Definition: detect-icode.c:77
uint8_t flags
Definition: detect.h:762
int PrefilterSetupPacketHeaderU8Hash(DetectEngineCtx *de_ctx, SigGroupHead *sgh, int sm_type, void(*Set)(PrefilterPacketHeaderValue *v, void *), _Bool(*Compare)(PrefilterPacketHeaderValue v, void *), void(*Match)(DetectEngineThreadCtx *det_ctx, Packet *p, const void *pectx))
void(* Free)(void *)
Definition: detect.h:1191
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
#define PKT_IS_ICMPV6(p)
Definition: decode.h:257
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1670
void DetectSetupParseRegexes(const char *parse_str, pcre **parse_regex, pcre_extra **parse_regex_study)
PrefilterRuleStore pmq
Definition: detect.h:1102
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.
struct DetectICodeData_ DetectICodeData
#define DETECT_ICODE_RN
Definition: detect-icode.c:80
int(* Match)(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1170
int SigGroupCleanup(DetectEngineCtx *de_ctx)
struct Signature_ * next
Definition: detect.h:594
uint8_t type
Definition: detect.h:319
const char * desc
Definition: detect.h:1202
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:346
struct SigMatch_ ** smlists
Definition: detect.h:516
SigMatchCtx * ctx
Definition: detect.h:321
#define SCMalloc(a)
Definition: util-mem.h:222
#define SCFree(a)
Definition: util-mem.h:322
PoolThreadReserved res
#define DETECT_ICODE_LT
Definition: detect-icode.c:78
#define PKT_IS_ICMPV4(p)
Definition: decode.h:256
const char * url
Definition: detect.h:1203
void DetectICodeRegister(void)
Registration function for icode: keyword.
Definition: detect-icode.c:61
#define DOC_URL
Definition: suricata.h:86
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1133
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:232
#define SCReturn
Definition: util-debug.h:339
Per thread variable structure.
Definition: threadvars.h:57
#define DETECT_ICODE_GT
Definition: detect-icode.c:79
#define DOC_VERSION
Definition: suricata.h:91
void DetectICodeRegisterTests(void)
this function registers unit tests for DetectICode
Definition: detect-icode.c:581
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
void UTHFreePackets(Packet **p, int numpkts)
UTHFreePackets: function to release the allocated data from UTHBuildPacket and the packet itself...
void(* RegisterTests)(void)
Definition: detect.h:1192
a single match condition for a signature
Definition: detect.h:318
DetectEngineCtx * DetectEngineCtxInit(void)
#define ICMPV4_GET_CODE(p)