suricata
detect-csum.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2013 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  * Implements checksum keyword.
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"
32 
33 #include "detect-csum.h"
34 
35 #include "util-unittest.h"
36 #include "util-debug.h"
37 
38 #include "pkt-var.h"
39 #include "host.h"
40 #include "util-profiling.h"
41 
42 /* prototypes for the "ipv4-csum" rule keyword */
43 static int DetectIPV4CsumMatch(ThreadVars *, DetectEngineThreadCtx *,
44  Packet *, const Signature *, const SigMatchCtx *);
45 static int DetectIPV4CsumSetup(DetectEngineCtx *, Signature *, const char *);
46 static void DetectIPV4CsumFree(void *);
47 
48 /* prototypes for the "tcpv4-csum" rule keyword */
49 static int DetectTCPV4CsumMatch(ThreadVars *, DetectEngineThreadCtx *,
50  Packet *, const Signature *, const SigMatchCtx *);
51 static int DetectTCPV4CsumSetup(DetectEngineCtx *, Signature *, const char *);
52 static void DetectTCPV4CsumFree(void *);
53 
54 /* prototypes for the "tcpv6-csum" rule keyword */
55 static int DetectTCPV6CsumMatch(ThreadVars *, DetectEngineThreadCtx *,
56  Packet *, const Signature *, const SigMatchCtx *);
57 static int DetectTCPV6CsumSetup(DetectEngineCtx *, Signature *, const char *);
58 static void DetectTCPV6CsumFree(void *);
59 
60 /* prototypes for the "udpv4-csum" rule keyword */
61 static int DetectUDPV4CsumMatch(ThreadVars *, DetectEngineThreadCtx *,
62  Packet *, const Signature *, const SigMatchCtx *);
63 static int DetectUDPV4CsumSetup(DetectEngineCtx *, Signature *, const char *);
64 static void DetectUDPV4CsumFree(void *);
65 
66 /* prototypes for the "udpv6-csum" rule keyword */
67 static int DetectUDPV6CsumMatch(ThreadVars *, DetectEngineThreadCtx *,
68  Packet *, const Signature *, const SigMatchCtx *);
69 static int DetectUDPV6CsumSetup(DetectEngineCtx *, Signature *, const char *);
70 static void DetectUDPV6CsumFree(void *);
71 
72 /* prototypes for the "icmpv4-csum" rule keyword */
73 static int DetectICMPV4CsumMatch(ThreadVars *, DetectEngineThreadCtx *,
74  Packet *, const Signature *, const SigMatchCtx *);
75 static int DetectICMPV4CsumSetup(DetectEngineCtx *, Signature *, const char *);
76 static void DetectICMPV4CsumFree(void *);
77 
78 /* prototypes for the "icmpv6-csum" rule keyword */
79 static int DetectICMPV6CsumMatch(ThreadVars *, DetectEngineThreadCtx *,
80  Packet *, const Signature *, const SigMatchCtx *);
81 static int DetectICMPV6CsumSetup(DetectEngineCtx *, Signature *, const char *);
82 static void DetectICMPV6CsumFree(void *);
83 
84 static void DetectCsumRegisterTests(void);
85 
86 /**
87  * \brief Registers handlers for all the checksum keywords. The checksum
88  * keywords that are registered are ipv4-sum, tcpv4-csum, tcpv6-csum,
89  * udpv4-csum, udpv6-csum, icmpv4-csum and icmpv6-csum.
90  *
91  * Each of the checksum keywords implemented here takes 2 arguments -
92  * "valid" or "invalid". If the rule keyword in the signature is
93  * specified as "valid", the Match function would return TRUE if the
94  * checksum for that particular packet and protocol is valid. Similarly
95  * for "invalid".
96  *
97  * The Setup functions takes 4 arguments -
98  *
99  * DetectEngineCtx * (de_ctx) - A pointer to the detection engine context
100  * Signature *(s) - Pointer to signature for the current Signature being
101  * parsed from the rules
102  * SigMatchCtx * (m) - Pointer to the head of the SigMatchs added to the
103  * current Signature being parsed
104  * char * (csum_str) - Pointer to a string holding the keyword value
105  *
106  * The Setup function returns 0 if it successfully parses the keyword
107  * value, and -1 otherwise.
108  *
109  * The Match function takes 5 arguments -
110  *
111  * ThreadVars * (t) - Pointer to the tv for the detection module instance
112  * DetectEngineThreadCtx * (det_ctx) - Pointer to the detection engine
113  * thread context
114  * Packet * (p) - Pointer to the Packet currently being handled
115  * Signature * (s) - Pointer to the Signature, the packet is being
116  * currently matched with
117  * SigMatchCtx * (m) - Pointer to the keyword structure from the above
118  * Signature, the Packet is being currently matched
119  * with
120  *
121  * The Match function returns 1 if the Packet contents match the keyword,
122  * and 0 otherwise
123  *
124  * The Free function takes a single argument -
125  *
126  * void * (ptr) - Pointer to the DetectCsumData for a keyword
127  */
129 {
130  sigmatch_table[DETECT_IPV4_CSUM].name = "ipv4-csum";
131  sigmatch_table[DETECT_IPV4_CSUM].Match = DetectIPV4CsumMatch;
132  sigmatch_table[DETECT_IPV4_CSUM].Setup = DetectIPV4CsumSetup;
133  sigmatch_table[DETECT_IPV4_CSUM].Free = DetectIPV4CsumFree;
134  sigmatch_table[DETECT_IPV4_CSUM].RegisterTests = DetectCsumRegisterTests;
135 
136  sigmatch_table[DETECT_TCPV4_CSUM].name = "tcpv4-csum";
137  sigmatch_table[DETECT_TCPV4_CSUM].Match = DetectTCPV4CsumMatch;
138  sigmatch_table[DETECT_TCPV4_CSUM].Setup = DetectTCPV4CsumSetup;
139  sigmatch_table[DETECT_TCPV4_CSUM].Free = DetectTCPV4CsumFree;
141 
142  sigmatch_table[DETECT_TCPV6_CSUM].name = "tcpv6-csum";
143  sigmatch_table[DETECT_TCPV6_CSUM].Match = DetectTCPV6CsumMatch;
144  sigmatch_table[DETECT_TCPV6_CSUM].Setup = DetectTCPV6CsumSetup;
145  sigmatch_table[DETECT_TCPV6_CSUM].Free = DetectTCPV6CsumFree;
147 
148  sigmatch_table[DETECT_UDPV4_CSUM].name = "udpv4-csum";
149  sigmatch_table[DETECT_UDPV4_CSUM].Match = DetectUDPV4CsumMatch;
150  sigmatch_table[DETECT_UDPV4_CSUM].Setup = DetectUDPV4CsumSetup;
151  sigmatch_table[DETECT_UDPV4_CSUM].Free = DetectUDPV4CsumFree;
153 
154  sigmatch_table[DETECT_UDPV6_CSUM].name = "udpv6-csum";
155  sigmatch_table[DETECT_UDPV6_CSUM].Match = DetectUDPV6CsumMatch;
156  sigmatch_table[DETECT_UDPV6_CSUM].Setup = DetectUDPV6CsumSetup;
157  sigmatch_table[DETECT_UDPV6_CSUM].Free = DetectUDPV6CsumFree;
159 
160  sigmatch_table[DETECT_ICMPV4_CSUM].name = "icmpv4-csum";
161  sigmatch_table[DETECT_ICMPV4_CSUM].Match = DetectICMPV4CsumMatch;
162  sigmatch_table[DETECT_ICMPV4_CSUM].Setup = DetectICMPV4CsumSetup;
163  sigmatch_table[DETECT_ICMPV4_CSUM].Free = DetectICMPV4CsumFree;
165 
166  sigmatch_table[DETECT_ICMPV6_CSUM].name = "icmpv6-csum";
167  sigmatch_table[DETECT_ICMPV6_CSUM].Match = DetectICMPV6CsumMatch;
168  sigmatch_table[DETECT_ICMPV6_CSUM].Setup = DetectICMPV6CsumSetup;
169  sigmatch_table[DETECT_ICMPV6_CSUM].Free = DetectICMPV6CsumFree;
171 
172  return;
173 }
174 
175 /**
176  * \brief Validates and parses the argument supplied with the checksum keyword.
177  * Accepts strings both with and without quotes, i.e. valid, \"valid\",
178  * invalid and \"invalid\"
179  *
180  * \param key Pointer to a const character string holding the csum keyword value
181  * \param cd Pointer to the DetectCsumData structure that holds the keyword
182  * value sent as argument
183  *
184  * \retval 1 the keyvalue has been parsed successfully
185  * \retval 0 error
186  */
187 static int DetectCsumParseArg(const char *key, DetectCsumData *cd)
188 {
189  char *str;
190 
191  if (key[0] == '\"' && key[strlen(key) - 1] == '\"') {
192  str = SCStrdup(key + 1);
193  if (unlikely(str == NULL)) {
194  goto error;
195  }
196  str[strlen(key) - 2] = '\0';
197  } else {
198  str = SCStrdup(key);
199  if (unlikely(str == NULL)) {
200  goto error;
201  }
202  }
203 
204  if (strcasecmp(str, DETECT_CSUM_VALID) == 0 ||
205  strcasecmp(str, DETECT_CSUM_INVALID) == 0) {
206  cd->valid = (strcasecmp(key, DETECT_CSUM_VALID) == 0);
207  SCFree(str);
208  return 1;
209  }
210 
211 error:
212  if (str != NULL)
213  SCFree(str);
214  return 0;
215 }
216 
217 /**
218  * \brief Checks if the packet sent as the argument, has a valid or invalid
219  * ipv4 checksum, based on whether ipv4-csum option for this rule
220  * has been supplied with "valid" or "invalid" argument
221  *
222  * \param t Pointer to the tv for this detection module instance
223  * \param det_ctx Pointer to the detection engine thread context
224  * \param p Pointer to the Packet currently being matched
225  * \param s Pointer to the Signature, the packet is being currently
226  * matched with
227  * \param m Pointer to the keyword_structure(SigMatch) from the above
228  * Signature, the Packet is being currently matched with
229  *
230  * \retval 1 if the Packet contents match the keyword option; 0 otherwise
231  */
232 static int DetectIPV4CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
233  Packet *p, const Signature *s, const SigMatchCtx *ctx)
234 {
235  const DetectCsumData *cd = (const DetectCsumData *)ctx;
236 
237  if (p->ip4h == NULL || PKT_IS_PSEUDOPKT(p))
238  return 0;
239 
240  if (p->flags & PKT_IGNORE_CHECKSUM) {
241  return cd->valid;
242  }
243 
244  if (p->level3_comp_csum == -1)
245  p->level3_comp_csum = IPV4Checksum((uint16_t *)p->ip4h,
246  IPV4_GET_HLEN(p),
247  p->ip4h->ip_csum);
248 
249  if (p->level3_comp_csum == 0 && cd->valid == 1)
250  return 1;
251  else if (p->level3_comp_csum != 0 && cd->valid == 0)
252  return 1;
253  else
254  return 0;
255 }
256 
257 /**
258  * \brief Creates a SigMatch for the ipv4-csum keyword being sent as argument,
259  * and appends it to the Signature(s). Accepts 2 values for the
260  * keyword - "valid" and "invalid", both with and without quotes
261  *
262  * \param de_ctx Pointer to the detection engine context
263  * \param s Pointer to signature for the current Signature being parsed
264  * from the rules
265  * \param csum_str Pointer to the string holding the keyword value
266  *
267  * \retval 0 on success, -1 on failure
268  */
269 static int DetectIPV4CsumSetup(DetectEngineCtx *de_ctx, Signature *s, const char *csum_str)
270 {
271  DetectCsumData *cd = NULL;
272  SigMatch *sm = NULL;
273 
274  //printf("DetectCsumSetup: \'%s\'\n", csum_str);
275 
276  sm = SigMatchAlloc();
277  if (sm == NULL)
278  goto error;
279 
280  sm->type = DETECT_IPV4_CSUM;
281 
282  if ( (cd = SCMalloc(sizeof(DetectCsumData))) == NULL)
283  goto error;
284  memset(cd, 0, sizeof(DetectCsumData));
285 
286  if (DetectCsumParseArg(csum_str, cd) == 0)
287  goto error;
288 
289  sm->ctx = (SigMatchCtx *)cd;
290 
292 
293  return 0;
294 
295 error:
296  if (cd != NULL) DetectIPV4CsumFree(cd);
297  if (sm != NULL) SCFree(sm);
298 
299  return -1;
300 }
301 
302 static void DetectIPV4CsumFree(void *ptr)
303 {
304  DetectCsumData *cd = (DetectCsumData *)ptr;
305 
306  if (cd != NULL)
307  SCFree(cd);
308 
309  return;
310 }
311 
312 /**
313  * \brief Checks if the packet sent as the argument, has a valid or invalid
314  * tcpv4 checksum, based on whether tcpv4-csum option for this rule
315  * has been supplied with "valid" or "invalid" argument
316  *
317  * \param t Pointer to the tv for this detection module instance
318  * \param det_ctx Pointer to the detection engine thread context
319  * \param p Pointer to the Packet currently being matched
320  * \param s Pointer to the Signature, the packet is being currently
321  * matched with
322  * \param m Pointer to the keyword_structure(SigMatch) from the above
323  * Signature, the Packet is being currently matched with
324  *
325  * \retval 1 if the Packet contents match the keyword option; 0 otherwise
326  */
327 static int DetectTCPV4CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
328  Packet *p, const Signature *s, const SigMatchCtx *ctx)
329 {
330  const DetectCsumData *cd = (const DetectCsumData *)ctx;
331 
332  if (p->ip4h == NULL || p->tcph == NULL || p->proto != IPPROTO_TCP || PKT_IS_PSEUDOPKT(p))
333  return 0;
334 
335  if (p->flags & PKT_IGNORE_CHECKSUM) {
336  return cd->valid;
337  }
338 
339  if (p->level4_comp_csum == -1)
340  p->level4_comp_csum = TCPChecksum(p->ip4h->s_ip_addrs,
341  (uint16_t *)p->tcph,
342  (p->payload_len +
343  TCP_GET_HLEN(p)),
344  p->tcph->th_sum);
345 
346  if (p->level4_comp_csum == 0 && cd->valid == 1)
347  return 1;
348  else if (p->level4_comp_csum != 0 && cd->valid == 0)
349  return 1;
350  else
351  return 0;
352 }
353 
354 /**
355  * \brief Creates a SigMatch for the tcpv4-csum keyword being sent as argument,
356  * and appends it to the Signature(s). Accepts 2 values for the
357  * keyword - "valid" and "invalid", both with and without quotes
358  *
359  * \param de_ctx Pointer to the detection engine context
360  * \param s Pointer to signature for the current Signature being parsed
361  * from the rules
362  * \param csum_str Pointer to the string holding the keyword value
363  *
364  * \retval 0 on success, -1 on failure
365  */
366 static int DetectTCPV4CsumSetup(DetectEngineCtx *de_ctx, Signature *s, const char *csum_str)
367 {
368  DetectCsumData *cd = NULL;
369  SigMatch *sm = NULL;
370 
371  //printf("DetectCsumSetup: \'%s\'\n", csum_str);
372 
373  sm = SigMatchAlloc();
374  if (sm == NULL)
375  goto error;
376 
377  sm->type = DETECT_TCPV4_CSUM;
378 
379  if ( (cd = SCMalloc(sizeof(DetectCsumData))) == NULL)
380  goto error;
381  memset(cd, 0, sizeof(DetectCsumData));
382 
383  if (DetectCsumParseArg(csum_str, cd) == 0)
384  goto error;
385 
386  sm->ctx = (SigMatchCtx *)cd;
387 
389 
390  return 0;
391 
392 error:
393  if (cd != NULL) DetectTCPV4CsumFree(cd);
394  if (sm != NULL) SCFree(sm);
395 
396  return -1;
397 }
398 
399 static void DetectTCPV4CsumFree(void *ptr)
400 {
401  DetectCsumData *cd = (DetectCsumData *)ptr;
402 
403  if (cd != NULL)
404  SCFree(cd);
405 
406  return;
407 }
408 
409 /**
410  * \brief Checks if the packet sent as the argument, has a valid or invalid
411  * tcpv6 checksum, based on whether tcpv6-csum option for this rule
412  * has been supplied with "valid" or "invalid" argument
413  *
414  * \param t Pointer to the tv for this detection module instance
415  * \param det_ctx Pointer to the detection engine thread context
416  * \param p Pointer to the Packet currently being matched
417  * \param s Pointer to the Signature, the packet is being currently
418  * matched with
419  * \param m Pointer to the keyword_structure(SigMatch) from the above
420  * Signature, the Packet is being currently matched with
421  *
422  * \retval 1 if the Packet contents match the keyword option; 0 otherwise
423  */
424 static int DetectTCPV6CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
425  Packet *p, const Signature *s, const SigMatchCtx *ctx)
426 {
427  const DetectCsumData *cd = (const DetectCsumData *)ctx;
428 
429  if (p->ip6h == NULL || p->tcph == NULL || p->proto != IPPROTO_TCP || PKT_IS_PSEUDOPKT(p))
430  return 0;
431 
432  if (p->flags & PKT_IGNORE_CHECKSUM) {
433  return cd->valid;
434  }
435 
436  if (p->level4_comp_csum == -1)
437  p->level4_comp_csum = TCPV6Checksum(p->ip6h->s_ip6_addrs,
438  (uint16_t *)p->tcph,
439  (p->payload_len +
440  TCP_GET_HLEN(p)),
441  p->tcph->th_sum);
442 
443  if (p->level4_comp_csum == 0 && cd->valid == 1)
444  return 1;
445  else if (p->level4_comp_csum != 0 && cd->valid == 0)
446  return 1;
447  else
448  return 0;
449 }
450 
451 /**
452  * \brief Creates a SigMatch for the tcpv6-csum keyword being sent as argument,
453  * and appends it to the Signature(s). Accepts 2 values for the
454  * keyword - "valid" and "invalid", both with and without quotes
455  *
456  * \param de_ctx Pointer to the detection engine context
457  * \param s Pointer to signature for the current Signature being parsed
458  * from the rules
459  * \param csum_str Pointer to the string holding the keyword value
460  *
461  * \retval 0 on success, -1 on failure
462  */
463 static int DetectTCPV6CsumSetup(DetectEngineCtx *de_ctx, Signature *s, const char *csum_str)
464 {
465  DetectCsumData *cd = NULL;
466  SigMatch *sm = NULL;
467 
468  //printf("DetectCsumSetup: \'%s\'\n", csum_str);
469 
470  sm = SigMatchAlloc();
471  if (sm == NULL)
472  goto error;
473 
474  sm->type = DETECT_TCPV6_CSUM;
475 
476  if ( (cd = SCMalloc(sizeof(DetectCsumData))) == NULL)
477  goto error;
478  memset(cd, 0, sizeof(DetectCsumData));
479 
480  if (DetectCsumParseArg(csum_str, cd) == 0)
481  goto error;
482 
483  sm->ctx = (SigMatchCtx *)cd;
484 
486 
487  return 0;
488 
489 error:
490  if (cd != NULL) DetectTCPV6CsumFree(cd);
491  if (sm != NULL) SCFree(sm);
492 
493  return -1;
494 }
495 
496 static void DetectTCPV6CsumFree(void *ptr)
497 {
498  DetectCsumData *cd = (DetectCsumData *)ptr;
499 
500  if (cd != NULL)
501  SCFree(cd);
502 
503  return;
504 }
505 
506 /**
507  * \brief Checks if the packet sent as the argument, has a valid or invalid
508  * udpv4 checksum, based on whether udpv4-csum option for this rule
509  * has been supplied with "valid" or "invalid" argument
510  *
511  * \param t Pointer to the tv for this detection module instance
512  * \param det_ctx Pointer to the detection engine thread context
513  * \param p Pointer to the Packet currently being matched
514  * \param s Pointer to the Signature, the packet is being currently
515  * matched with
516  * \param m Pointer to the keyword_structure(SigMatch) from the above
517  * Signature, the Packet is being currently matched with
518  *
519  * \retval 1 if the Packet contents match the keyword option; 0 otherwise
520  */
521 static int DetectUDPV4CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
522  Packet *p, const Signature *s, const SigMatchCtx *ctx)
523 {
524  const DetectCsumData *cd = (const DetectCsumData *)ctx;
525 
526  if (p->ip4h == NULL || p->udph == NULL || p->proto != IPPROTO_UDP || PKT_IS_PSEUDOPKT(p) || p->udph->uh_sum == 0)
527  return 0;
528 
529  if (p->flags & PKT_IGNORE_CHECKSUM) {
530  return cd->valid;
531  }
532 
533  if (p->level4_comp_csum == -1)
534  p->level4_comp_csum = UDPV4Checksum(p->ip4h->s_ip_addrs,
535  (uint16_t *)p->udph,
536  (p->payload_len +
538  p->udph->uh_sum);
539 
540  if (p->level4_comp_csum == 0 && cd->valid == 1)
541  return 1;
542  else if (p->level4_comp_csum != 0 && cd->valid == 0)
543  return 1;
544  else
545  return 0;
546 }
547 
548 /**
549  * \brief Creates a SigMatch for the udpv4-csum keyword being sent as argument,
550  * and appends it to the Signature(s). Accepts 2 values for the
551  * keyword - "valid" and "invalid", both with and without quotes
552  *
553  * \param de_ctx Pointer to the detection engine context
554  * \param s Pointer to signature for the current Signature being parsed
555  * from the rules
556  * \param csum_str Pointer to the string holding the keyword value
557  *
558  * \retval 0 on success, -1 on failure
559  */
560 static int DetectUDPV4CsumSetup(DetectEngineCtx *de_ctx, Signature *s, const char *csum_str)
561 {
562  DetectCsumData *cd = NULL;
563  SigMatch *sm = NULL;
564 
565  //printf("DetectCsumSetup: \'%s\'\n", csum_str);
566 
567  sm = SigMatchAlloc();
568  if (sm == NULL)
569  goto error;
570 
571  sm->type = DETECT_UDPV4_CSUM;
572 
573  if ( (cd = SCMalloc(sizeof(DetectCsumData))) == NULL)
574  goto error;
575  memset(cd, 0, sizeof(DetectCsumData));
576 
577  if (DetectCsumParseArg(csum_str, cd) == 0)
578  goto error;
579 
580  sm->ctx = (SigMatchCtx *)cd;
581 
583 
584  return 0;
585 
586 error:
587  if (cd != NULL) DetectUDPV4CsumFree(cd);
588  if (sm != NULL) SCFree(sm);
589 
590  return -1;
591 }
592 
593 static void DetectUDPV4CsumFree(void *ptr)
594 {
595  DetectCsumData *cd = (DetectCsumData *)ptr;
596 
597  if (cd != NULL)
598  SCFree(cd);
599 
600  return;
601 }
602 
603 /**
604  * \brief Checks if the packet sent as the argument, has a valid or invalid
605  * udpv6 checksum, based on whether udpv6-csum option for this rule
606  * has been supplied with "valid" or "invalid" argument
607  *
608  * \param t Pointer to the tv for this detection module instance
609  * \param det_ctx Pointer to the detection engine thread context
610  * \param p Pointer to the Packet currently being matched
611  * \param s Pointer to the Signature, the packet is being currently
612  * matched with
613  * \param m Pointer to the keyword_structure(SigMatch) from the above
614  * Signature, the Packet is being currently matched with
615  *
616  * \retval 1 if the Packet contents match the keyword option; 0 otherwise
617  */
618 static int DetectUDPV6CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
619  Packet *p, const Signature *s, const SigMatchCtx *ctx)
620 {
621  const DetectCsumData *cd = (const DetectCsumData *)ctx;
622 
623  if (p->ip6h == NULL || p->udph == NULL || p->proto != IPPROTO_UDP || PKT_IS_PSEUDOPKT(p))
624  return 0;
625 
626  if (p->flags & PKT_IGNORE_CHECKSUM) {
627  return cd->valid;
628  }
629 
630  if (p->level4_comp_csum == -1)
631  p->level4_comp_csum = UDPV6Checksum(p->ip6h->s_ip6_addrs,
632  (uint16_t *)p->udph,
633  (p->payload_len +
635  p->udph->uh_sum);
636 
637  if (p->level4_comp_csum == 0 && cd->valid == 1)
638  return 1;
639  else if (p->level4_comp_csum != 0 && cd->valid == 0)
640  return 1;
641  else
642  return 0;
643 }
644 
645 /**
646  * \brief Creates a SigMatch for the udpv6-csum keyword being sent as argument,
647  * and appends it to the Signature(s). Accepts 2 values for the
648  * keyword - "valid" and "invalid", both with and without quotes
649  *
650  * \param de_ctx Pointer to the detection engine context
651  * \param s Pointer to signature for the current Signature being parsed
652  * from the rules
653  * \param csum_str Pointer to the string holding the keyword value
654  *
655  * \retval 0 on success, -1 on failure
656  */
657 static int DetectUDPV6CsumSetup(DetectEngineCtx *de_ctx, Signature *s, const char *csum_str)
658 {
659  DetectCsumData *cd = NULL;
660  SigMatch *sm = NULL;
661 
662  //printf("DetectCsumSetup: \'%s\'\n", csum_str);
663 
664  sm = SigMatchAlloc();
665  if (sm == NULL)
666  goto error;
667 
668  sm->type = DETECT_UDPV6_CSUM;
669 
670  if ( (cd = SCMalloc(sizeof(DetectCsumData))) == NULL)
671  goto error;
672  memset(cd, 0, sizeof(DetectCsumData));
673 
674  if (DetectCsumParseArg(csum_str, cd) == 0)
675  goto error;
676 
677  sm->ctx = (void *)cd;
678 
680 
681  return 0;
682 
683 error:
684  if (cd != NULL) DetectUDPV6CsumFree(cd);
685  if (sm != NULL) SCFree(sm);
686 
687  return -1;
688 }
689 
690 static void DetectUDPV6CsumFree(void *ptr)
691 {
692  DetectCsumData *cd = (DetectCsumData *)ptr;
693 
694  if (cd != NULL)
695  SCFree(cd);
696 
697  return;
698 }
699 
700 /**
701  * \brief Checks if the packet sent as the argument, has a valid or invalid
702  * icmpv4 checksum, based on whether icmpv4-csum option for this rule
703  * has been supplied with "valid" or "invalid" argument
704  *
705  * \param t Pointer to the tv for this detection module instance
706  * \param det_ctx Pointer to the detection engine thread context
707  * \param p Pointer to the Packet currently being matched
708  * \param s Pointer to the Signature, the packet is being currently
709  * matched with
710  * \param m Pointer to the keyword_structure(SigMatch) from the above
711  * Signature, the Packet is being currently matched with
712  *
713  * \retval 1 if the Packet contents match the keyword option; 0 otherwise
714  */
715 static int DetectICMPV4CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
716  Packet *p, const Signature *s, const SigMatchCtx *ctx)
717 {
718  const DetectCsumData *cd = (const DetectCsumData *)ctx;
719 
720  if (p->ip4h == NULL || p->icmpv4h == NULL || p->proto != IPPROTO_ICMP || PKT_IS_PSEUDOPKT(p))
721  return 0;
722 
723  if (p->flags & PKT_IGNORE_CHECKSUM) {
724  return cd->valid;
725  }
726 
727  if (p->level4_comp_csum == -1)
728  p->level4_comp_csum = ICMPV4CalculateChecksum((uint16_t *)p->icmpv4h,
730  IPV4_GET_RAW_HLEN(p->ip4h) * 4);
731 
732  if (p->level4_comp_csum == p->icmpv4h->checksum && cd->valid == 1)
733  return 1;
734  else if (p->level4_comp_csum != p->icmpv4h->checksum && cd->valid == 0)
735  return 1;
736  else
737  return 0;
738 }
739 
740 /**
741  * \brief Creates a SigMatch for the icmpv4-csum keyword being sent as argument,
742  * and appends it to the Signature(s). Accepts 2 values for the
743  * keyword - "valid" and "invalid", both with and without quotes
744  *
745  * \param de_ctx Pointer to the detection engine context
746  * \param s Pointer to signature for the current Signature being parsed
747  * from the rules
748  * \param csum_str Pointer to the string holding the keyword value
749  *
750  * \retval 0 on success, -1 on failure
751  */
752 static int DetectICMPV4CsumSetup(DetectEngineCtx *de_ctx, Signature *s, const char *csum_str)
753 {
754  DetectCsumData *cd = NULL;
755  SigMatch *sm = NULL;
756 
757  //printf("DetectCsumSetup: \'%s\'\n", csum_str);
758 
759  sm = SigMatchAlloc();
760  if (sm == NULL)
761  goto error;
762 
763  sm->type = DETECT_ICMPV4_CSUM;
764 
765  if ( (cd = SCMalloc(sizeof(DetectCsumData))) == NULL)
766  goto error;
767  memset(cd, 0, sizeof(DetectCsumData));
768 
769  if (DetectCsumParseArg(csum_str, cd) == 0)
770  goto error;
771 
772  sm->ctx = (SigMatchCtx *)cd;
773 
775 
776  return 0;
777 
778 error:
779  if (cd != NULL) DetectICMPV4CsumFree(cd);
780  if (sm != NULL) SCFree(sm);
781 
782  return -1;
783 }
784 
785 static void DetectICMPV4CsumFree(void *ptr)
786 {
787  DetectCsumData *cd = (DetectCsumData *)ptr;
788 
789  if (cd != NULL)
790  SCFree(cd);
791 
792  return;
793 }
794 
795 /**
796  * \brief Checks if the packet sent as the argument, has a valid or invalid
797  * icmpv6 checksum, based on whether icmpv6-csum option for this rule
798  * has been supplied with "valid" or "invalid" argument
799  *
800  * \param t Pointer to the tv for this detection module instance
801  * \param det_ctx Pointer to the detection engine thread context
802  * \param p Pointer to the Packet currently being matched
803  * \param s Pointer to the Signature, the packet is being currently
804  * matched with
805  * \param m Pointer to the keyword_structure(SigMatch) from the above
806  * Signature, the Packet is being currently matched with
807  *
808  * \retval 1 if the Packet contents match the keyword option; 0 otherwise
809  */
810 static int DetectICMPV6CsumMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx,
811  Packet *p, const Signature *s, const SigMatchCtx *ctx)
812 {
813  const DetectCsumData *cd = (const DetectCsumData *)ctx;
814 
815  if (p->ip6h == NULL || p->icmpv6h == NULL || p->proto != IPPROTO_ICMPV6 || PKT_IS_PSEUDOPKT(p) ||
816  (GET_PKT_LEN(p) - ((uint8_t *)p->icmpv6h - GET_PKT_DATA(p))) <= 0) {
817  return 0;
818  }
819 
820  if (p->flags & PKT_IGNORE_CHECKSUM) {
821  return cd->valid;
822  }
823 
824  if (p->level4_comp_csum == -1) {
825  uint16_t len = IPV6_GET_RAW_PLEN(p->ip6h) -
826  ((uint8_t *)p->icmpv6h - (uint8_t *)p->ip6h - IPV6_HEADER_LEN);
827  p->level4_comp_csum = ICMPV6CalculateChecksum(p->ip6h->s_ip6_addrs,
828  (uint16_t *)p->icmpv6h,
829  len);
830  }
831 
832  if (p->level4_comp_csum == p->icmpv6h->csum && cd->valid == 1)
833  return 1;
834  else if (p->level4_comp_csum != p->icmpv6h->csum && cd->valid == 0)
835  return 1;
836  else
837  return 0;
838 }
839 
840 /**
841  * \brief Creates a SigMatch for the icmpv6-csum keyword being sent as argument,
842  * and appends it to the Signature(s). Accepts 2 values for the
843  * keyword - "valid" and "invalid", both with and without quotes
844  *
845  * \param de_ctx Pointer to the detection engine context
846  * \param s Pointer to signature for the current Signature being parsed
847  * from the rules
848  * \param csum_str Pointer to the string holding the keyword value
849  *
850  * \retval 0 on success, -1 on failure
851  */
852 static int DetectICMPV6CsumSetup(DetectEngineCtx *de_ctx, Signature *s, const char *csum_str)
853 {
854  DetectCsumData *cd = NULL;
855  SigMatch *sm = NULL;
856 
857  sm = SigMatchAlloc();
858  if (sm == NULL)
859  goto error;
860 
861  sm->type = DETECT_ICMPV6_CSUM;
862 
863  if ( (cd = SCMalloc(sizeof(DetectCsumData))) == NULL)
864  goto error;
865  memset(cd, 0, sizeof(DetectCsumData));
866 
867  if (DetectCsumParseArg(csum_str, cd) == 0)
868  goto error;
869 
870  sm->ctx = (SigMatchCtx *)cd;
871 
873 
874  return 0;
875 
876 error:
877  if (cd != NULL) DetectICMPV6CsumFree(cd);
878  if (sm != NULL) SCFree(sm);
879 
880  return -1;
881 }
882 
883 static void DetectICMPV6CsumFree(void *ptr)
884 {
885  DetectCsumData *cd = (DetectCsumData *)ptr;
886 
887  if (cd != NULL)
888  SCFree(cd);
889 
890  return;
891 }
892 
893 /* ---------------------------------- Unit Tests --------------------------- */
894 
895 #ifdef UNITTESTS
896 #include "detect-engine.h"
897 
898 #define mystr(s) #s
899 #define TEST1(kwstr) {\
900  DetectEngineCtx *de_ctx = DetectEngineCtxInit();\
901  FAIL_IF_NULL(de_ctx);\
902  de_ctx->flags = DE_QUIET;\
903  \
904  Signature *s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any ("mystr(kwstr)"-csum:valid; sid:1;)");\
905  FAIL_IF_NULL(s);\
906  s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any ("mystr(kwstr)"-csum:invalid; sid:2;)");\
907  FAIL_IF_NULL(s);\
908  s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any ("mystr(kwstr)"-csum:vaLid; sid:3;)");\
909  FAIL_IF_NULL(s);\
910  s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any ("mystr(kwstr)"-csum:VALID; sid:4;)");\
911  FAIL_IF_NULL(s);\
912  s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any ("mystr(kwstr)"-csum:iNvaLid; sid:5;)");\
913  FAIL_IF_NULL(s);\
914  DetectEngineCtxFree(de_ctx);\
915 }
916 
917 
918 static int DetectCsumValidArgsTestParse01(void)
919 {
920  TEST1(ipv4);
921  TEST1(tcpv4);
922  TEST1(tcpv6);
923  TEST1(udpv4);
924  TEST1(udpv6);
925  TEST1(icmpv4);
926  TEST1(icmpv6);
927  PASS;
928 }
929 #undef TEST1
930 
931 #define TEST2(kwstr) { \
932  DetectEngineCtx *de_ctx = DetectEngineCtxInit();\
933  FAIL_IF_NULL(de_ctx);\
934  Signature *s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any ("mystr(kwstr)"-csum:vaid; sid:1;)");\
935  FAIL_IF(s);\
936  s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any ("mystr(kwstr)"-csum:invaalid; sid:2;)");\
937  FAIL_IF(s);\
938  s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any ("mystr(kwstr)"-csum:vaLiid; sid:3;)");\
939  FAIL_IF(s);\
940  s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any ("mystr(kwstr)"-csum:VALieD; sid:4;)");\
941  FAIL_IF(s);\
942  s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any ("mystr(kwstr)"-csum:iNvamid; sid:5;)");\
943  FAIL_IF(s);\
944  DetectEngineCtxFree(de_ctx);\
945 }
946 
947 static int DetectCsumInvalidArgsTestParse02(void)
948 {
949  TEST2(ipv4);
950  TEST2(tcpv4);
951  TEST2(tcpv6);
952  TEST2(udpv4);
953  TEST2(udpv6);
954  TEST2(icmpv4);
955  TEST2(icmpv6);
956  PASS;
957 }
958 #undef TEST2
959 
960 #define TEST3(kwstr, kwtype) { \
961  DetectEngineCtx *de_ctx = DetectEngineCtxInit();\
962  FAIL_IF_NULL(de_ctx);\
963  Signature *s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any ("mystr(kwstr)"-csum:valid; sid:1;)");\
964  FAIL_IF_NULL(s);\
965  SigMatch *sm = DetectGetLastSMFromLists(s, (kwtype), -1);\
966  FAIL_IF_NULL(sm);\
967  FAIL_IF_NULL(sm->ctx);\
968  FAIL_IF_NOT(((DetectCsumData *)sm->ctx)->valid == 1);\
969  s = DetectEngineAppendSig(de_ctx, "alert ip any any -> any any ("mystr(kwstr)"-csum:INVALID; sid:2;)");\
970  FAIL_IF_NULL(s);\
971  sm = DetectGetLastSMFromLists(s, (kwtype), -1);\
972  FAIL_IF_NULL(sm);\
973  FAIL_IF_NULL(sm->ctx);\
974  FAIL_IF_NOT(((DetectCsumData *)sm->ctx)->valid == 0);\
975  DetectEngineCtxFree(de_ctx);\
976 }
977 
978 static int DetectCsumValidArgsTestParse03(void)
979 {
980  TEST3(ipv4, DETECT_IPV4_CSUM);
981  TEST3(tcpv4, DETECT_TCPV4_CSUM);
982  TEST3(tcpv6, DETECT_TCPV6_CSUM);
983  TEST3(udpv4, DETECT_UDPV4_CSUM);
984  TEST3(udpv6, DETECT_UDPV6_CSUM);
985  TEST3(icmpv4, DETECT_ICMPV4_CSUM);
986  TEST3(icmpv6, DETECT_ICMPV6_CSUM);
987  PASS;
988 }
989 #undef TEST3
990 #undef mystr
991 
992 #include "detect-engine.h"
993 #include "stream-tcp.h"
994 
995 static int DetectCsumICMPV6Test01(void)
996 {
997  DetectEngineCtx *de_ctx = NULL;
998  Signature *s = NULL;
999  ThreadVars tv;
1000  DetectEngineThreadCtx *det_ctx = NULL;
1001  DecodeThreadVars dtv;
1002 
1003  Packet *p = PacketGetFromAlloc();
1004  FAIL_IF_NULL(p);
1005 
1006  uint8_t pkt[] = {
1007  0x00, 0x30, 0x18, 0xa8, 0x7c, 0x23, 0x2c, 0x41,
1008  0x38, 0xa7, 0xea, 0xeb, 0x86, 0xdd, 0x60, 0x00,
1009  0x00, 0x00, 0x00, 0x40, 0x3c, 0x40, 0xad, 0xa1,
1010  0x09, 0x80, 0x00, 0x01, 0xd6, 0xf3, 0x20, 0x01,
1011  0xf4, 0xbe, 0xea, 0x3c, 0x00, 0x01, 0x00, 0x00,
1012  0x00, 0x00, 0x32, 0xb2, 0x00, 0x01, 0x32, 0xb2,
1013  0x09, 0x80, 0x20, 0x01, 0x00, 0x00, 0x3c, 0x00,
1014  0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00,
1015  0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00,
1016  0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00,
1017  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00,
1018  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00,
1019  0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00,
1020  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
1021  0x63, 0xc2, 0x00, 0x00, 0x00, 0x00 };
1022 
1023  PacketCopyData(p, pkt, sizeof(pkt));
1024 
1025  memset(&tv, 0, sizeof(tv));
1026  memset(&dtv, 0, sizeof(dtv));
1027 
1030 
1031  de_ctx = DetectEngineCtxInit();
1032  FAIL_IF_NULL(de_ctx);
1033  de_ctx->mpm_matcher = mpm_default_matcher;
1034  de_ctx->flags |= DE_QUIET;
1035 
1036  s = de_ctx->sig_list = SigInit(de_ctx, "alert ip any any -> any any "
1037  "(icmpv6-csum:valid; sid:1;)");
1038  FAIL_IF_NULL(s);
1039  SigGroupBuild(de_ctx);
1040 
1041  DecodeEthernet(&tv, &dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), NULL);
1042 
1043  DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
1044 
1045  SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1046 
1047  FAIL_IF(!PacketAlertCheck(p, 1));
1048 
1049  DetectEngineThreadCtxDeinit(&tv, det_ctx);
1050  DetectEngineCtxFree(de_ctx);
1051 
1053  PACKET_RECYCLE(p);
1054  FlowShutdown();
1055  SCFree(p);
1056  PASS;
1057 }
1058 
1059 #endif /* UNITTESTS */
1060 
1061 static void DetectCsumRegisterTests(void)
1062 {
1063 #ifdef UNITTESTS
1064 
1065  UtRegisterTest("DetectCsumValidArgsTestParse01",
1066  DetectCsumValidArgsTestParse01);
1067  UtRegisterTest("DetectCsumInvalidArgsTestParse02",
1068  DetectCsumInvalidArgsTestParse02);
1069  UtRegisterTest("DetectCsumValidArgsTestParse03",
1070  DetectCsumValidArgsTestParse03);
1071 
1072  UtRegisterTest("DetectCsumICMPV6Test01",
1073  DetectCsumICMPV6Test01);
1074 
1075 #endif /* UNITTESTS */
1076 }
uint16_t csum
#define TEST3(kwstr, kwtype)
Definition: detect-csum.c:960
SigTableElmt sigmatch_table[DETECT_TBLSIZE]
Definition: detect.h:1406
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1149
UDPHdr * udph
Definition: decode.h:522
int32_t level4_comp_csum
Definition: decode.h:496
int PacketAlertCheck(Packet *p, uint32_t sid)
Check if a certain sid alerted, this is used in the test functions.
#define PASS
Pass the test.
#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:526
Signature * sig_list
Definition: detect.h:729
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
#define FLOW_QUIET
Definition: flow.h:37
#define PACKET_RECYCLE(p)
Definition: decode.h:817
void StreamTcpFreeConfig(char quiet)
Definition: stream-tcp.c:669
TmEcode DetectEngineThreadCtxInit(ThreadVars *, void *, void **)
initialize thread specific detection engine context
const char * name
Definition: detect.h:1163
TCPHdr * tcph
Definition: decode.h:520
Signature container.
Definition: detect.h:495
#define TRUE
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:317
#define IPV4_GET_RAW_IPLEN(ip4h)
Definition: decode-ipv4.h:97
main detection engine ctx
Definition: detect.h:723
TmEcode DetectEngineThreadCtxDeinit(ThreadVars *, void *)
#define DE_QUIET
Definition: detect.h:296
#define str(s)
IPV6Hdr * ip6h
Definition: decode.h:500
ICMPV6Hdr * icmpv6h
Definition: decode.h:528
#define TEST2(kwstr)
Definition: detect-csum.c:931
#define IPV6_GET_RAW_PLEN(ip6h)
Definition: decode-ipv6.h:66
uint8_t proto
Definition: decode.h:428
uint8_t flags
Definition: detect.h:724
void(* Free)(void *)
Definition: detect.h:1154
int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
int SigGroupBuild(DetectEngineCtx *de_ctx)
Convert the signature list into the runtime match structure.
uint16_t mpm_matcher
Definition: detect.h:772
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Structure to hold thread specific data for all decode modules.
Definition: decode.h:632
void SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, Packet *p)
wrapper for old tests
Definition: detect.c:1743
void StreamTcpInitConfig(char)
To initialize the stream global configuration data.
Definition: stream-tcp.c:365
#define PKT_IGNORE_CHECKSUM
Definition: decode.h:1101
uint8_t type
Definition: detect.h:323
#define IPV4_GET_HLEN(p)
Definition: decode-ipv4.h:123
void SigMatchAppendSMToList(Signature *s, SigMatch *new, int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:288
IPV4Hdr * ip4h
Definition: decode.h:498
#define IPV4_GET_RAW_HLEN(ip4h)
Definition: decode-ipv4.h:95
SigMatchCtx * ctx
Definition: detect.h:325
#define SCMalloc(a)
Definition: util-mem.h:166
int mpm_default_matcher
Definition: util-mpm.h:170
#define IPV6_HEADER_LEN
Definition: decode-ipv6.h:27
#define DETECT_CSUM_INVALID
Definition: detect-csum.h:28
#define SCFree(a)
Definition: util-mem.h:228
#define SCNtohs(x)
int32_t level3_comp_csum
Definition: decode.h:494
void DetectCsumRegister(void)
Registers handlers for all the checksum keywords. The checksum keywords that are registered are ipv4-...
Definition: detect-csum.c:128
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:667
int(* Match)(ThreadVars *, DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *)
Definition: detect.h:1132
#define GET_PKT_DATA(p)
Definition: decode.h:223
#define SCStrdup(a)
Definition: util-mem.h:212
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
#define PKT_IS_PSEUDOPKT(p)
return 1 if the packet is a pseudo packet
Definition: decode.h:1131
uint16_t ip_csum
Definition: decode-ipv4.h:79
#define TCP_GET_HLEN(p)
Definition: decode-tcp.h:103
SigMatch * SigMatchAlloc(void)
Definition: detect-parse.c:232
uint8_t len
Per thread variable structure.
Definition: threadvars.h:57
#define GET_PKT_LEN(p)
Definition: decode.h:222
uint32_t flags
Definition: decode.h:441
uint16_t payload_len
Definition: decode.h:541
#define DETECT_CSUM_VALID
Definition: detect-csum.h:27
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
int PacketCopyData(Packet *p, uint8_t *pktdata, uint32_t pktlen)
Copy data to Packet payload and set packet length.
Definition: decode.c:258
void(* RegisterTests)(void)
Definition: detect.h:1155
a single match condition for a signature
Definition: detect.h:322
#define UDP_HEADER_LEN
Definition: decode-udp.h:27
#define TEST1(kwstr)
Definition: detect-csum.c:899
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:140
DetectEngineCtx * DetectEngineCtxInit(void)
void FlowInitConfig(char quiet)
initialize the configuration
Definition: flow.c:512