suricata
decode-ipv4.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  * \ingroup decode
20  *
21  * @{
22  */
23 
24 
25 /**
26  * \file
27  *
28  * \author Victor Julien <victor@inliniac.net>
29  * \author Brian Rectanus <brectanu@gmail.com>
30  *
31  * Decode IPv4
32  */
33 
34 #include "suricata-common.h"
35 #include "packet-queue.h"
36 #include "decode.h"
37 #include "decode-ipv4.h"
38 #include "decode-events.h"
39 #include "defrag.h"
40 #include "pkt-var.h"
41 #include "host.h"
42 
43 #include "util-unittest.h"
44 #include "util-debug.h"
45 #include "util-optimize.h"
46 #include "util-print.h"
47 #include "util-profiling.h"
48 
49 /* Generic validation
50  *
51  * [--type--][--len---]
52  *
53  * \todo This function needs removed in favor of specific validation.
54  *
55  * See: RFC 791
56  */
57 static int IPV4OptValidateGeneric(Packet *p, const IPV4Opt *o)
58 {
59  switch (o->type) {
60  /* See: RFC 4782 */
61  case IPV4_OPT_QS:
62  if (o->len < IPV4_OPT_QS_MIN) {
64  return -1;
65  }
66  break;
67  /* See: RFC 1108 */
68  case IPV4_OPT_SEC:
69  if (o->len != IPV4_OPT_SEC_LEN) {
71  return -1;
72  }
73  break;
74  case IPV4_OPT_SID:
75  if (o->len != IPV4_OPT_SID_LEN) {
77  return -1;
78  }
79  break;
80  /* See: RFC 2113 */
81  case IPV4_OPT_RTRALT:
82  if (o->len != IPV4_OPT_RTRALT_LEN) {
84  return -1;
85  }
86  break;
87  default:
88  /* Should never get here unless there is a coding error */
90  return -1;
91  }
92 
93  return 0;
94 }
95 
96 /* Validate route type options
97  *
98  * [--type--][--len---][--ptr---][address1]...[addressN]
99  *
100  * See: RFC 791
101  */
102 static int IPV4OptValidateRoute(Packet *p, const IPV4Opt *o)
103 {
104  uint8_t ptr;
105 
106  /* Check length */
107  if (unlikely(o->len < IPV4_OPT_ROUTE_MIN)) {
109  return -1;
110  }
111 
112  /* Data is required */
113  if (unlikely(o->data == NULL)) {
115  return -1;
116  }
117  ptr = *o->data;
118 
119  /* Address pointer is 1 based and points at least after type+len+ptr,
120  * must be a incremented by 4 bytes (address size) and cannot extend
121  * past option length.
122  */
123  if (unlikely((ptr < 4) || (ptr % 4) || (ptr > o->len + 1))) {
125  return -1;
126  }
127 
128  return 0;
129 }
130 
131 /* Validate timestamp type options
132  *
133  * [--type--][--len---][--ptr---][ovfl][flag][rec1----...]...[recN----...]
134  * NOTE: rec could be 4 (ts only) or 8 (ip+ts) bytes in length.
135  *
136  * See: RFC 781
137  */
138 static int IPV4OptValidateTimestamp(Packet *p, const IPV4Opt *o)
139 {
140  uint8_t ptr;
141  uint8_t flag;
142  uint8_t rec_size;
143 
144  /* Check length */
145  if (unlikely(o->len < IPV4_OPT_TS_MIN)) {
147  return -1;
148  }
149 
150  /* Data is required */
151  if (unlikely(o->data == NULL)) {
153  return -1;
154  }
155  ptr = *o->data;
156 
157  /* We need the flag to determine what is in the option payload */
158  if (unlikely(ptr < 5)) {
160  return -1;
161  }
162  flag = *(o->data + 1) & 0x0f;
163 
164  /* A flag of 1|3 means we have both the ip+ts in each record */
165  rec_size = ((flag == 1) || (flag == 3)) ? 8 : 4;
166 
167  /* Address pointer is 1 based and points at least after
168  * type+len+ptr+ovfl+flag, must be incremented by by the rec_size
169  * and cannot extend past option length.
170  */
171  if (unlikely(((ptr - 5) % rec_size) || (ptr > o->len + 1))) {
173  return -1;
174  }
175 
176  return 0;
177 }
178 
179 /* Validate CIPSO option
180  *
181  * [--type--][--len---][--doi---][tags--...]
182  *
183  * See: draft-ietf-cipso-ipsecurity-01.txt
184  * See: FIPS 188 (tags 6 & 7)
185  */
186 static int IPV4OptValidateCIPSO(Packet *p, const IPV4Opt *o)
187 {
188 // uint32_t doi;
189  const uint8_t *tag;
190  uint16_t len;
191 
192  /* Check length */
193  if (unlikely(o->len < IPV4_OPT_CIPSO_MIN)) {
195  return -1;
196  }
197 
198  /* Data is required */
199  if (unlikely(o->data == NULL)) {
201  return -1;
202  }
203 // doi = *o->data;
204  tag = o->data + 4;
205  len = o->len - 1 - 1 - 4; /* Length of tags after header */
206 
207 
208 #if 0
209  /* Domain of Interest (DOI) of 0 is reserved and thus invalid */
210  /** \todo Aparently a DOI of zero is fine in practice - verify. */
211  if (doi == 0) {
213  return -1;
214  }
215 #endif
216 
217  /* NOTE: We know len has passed min tests prior to this call */
218 
219  /* Check that tags are formatted correctly
220  * [-ttype--][--tlen--][-tagdata-...]
221  */
222  while (len) {
223  uint8_t ttype;
224  uint8_t tlen;
225 
226  /* Tag header must fit within option length */
227  if (unlikely(len < 2)) {
228  //printf("CIPSO tag header too large %" PRIu16 " < 2\n", len);
230  return -1;
231  }
232 
233  /* Tag header is type+len */
234  ttype = *(tag++);
235  tlen = *(tag++);
236 
237  /* Tag length must fit within the option length */
238  if (unlikely(tlen > len)) {
239  //printf("CIPSO tag len too large %" PRIu8 " > %" PRIu16 "\n", tlen, len);
241  return -1;
242  }
243 
244  switch(ttype) {
245  case 1:
246  case 2:
247  case 5:
248  case 6:
249  case 7:
250  /* Tag is at least 4 and at most the remainder of option len */
251  if (unlikely((tlen < 4) || (tlen > len))) {
252  //printf("CIPSO tag %" PRIu8 " bad tlen=%" PRIu8 " len=%" PRIu8 "\n", ttype, tlen, len);
254  return -1;
255  }
256 
257  /* The alignment octet is always 0 except tag
258  * type 7, which has no such field.
259  */
260  if (unlikely((ttype != 7) && (*tag != 0))) {
261  //printf("CIPSO tag %" PRIu8 " ao=%" PRIu8 "\n", ttype, tlen);
263  return -1;
264  }
265 
266  /* Skip the rest of the tag payload */
267  tag += tlen - 2;
268  len -= tlen;
269 
270  continue;
271  case 0:
272  /* Tag type 0 is reserved and thus invalid */
273  /** \todo Wireshark marks this a padding, but spec says reserved. */
275  return -1;
276  default:
277  //printf("CIPSO tag %" PRIu8 " unknown tag\n", ttype);
279  /** \todo May not want to return error here on unknown tag type (at least not for 3|4) */
280  return -1;
281  }
282  }
283 
284  return 0;
285 }
286 
287 typedef struct IPV4Options_ {
298 
299 /**
300  * Decode/Validate IPv4 Options.
301  */
302 static int DecodeIPV4Options(Packet *p, const uint8_t *pkt, uint16_t len, IPV4Options *opts)
303 {
304  uint16_t plen = len;
305 
306 #ifdef DEBUG
307  if (SCLogDebugEnabled()) {
308  uint16_t i;
309  char buf[256] = "";
310  int offset = 0;
311 
312  for (i = 0; i < len; i++) {
313  offset += snprintf(buf + offset, (sizeof(buf) - offset), "%02" PRIx8 " ", pkt[i]);
314  }
315  SCLogDebug("IPV4OPTS: { %s}", buf);
316  }
317 #endif
318 
319  /* Options length must be padded to 8byte boundary */
320  if (plen % 8) {
322  /* Warn - we can keep going */
323  }
324 
325  while (plen)
326  {
327  p->ip4vars.opt_cnt++;
328 
329  /* single byte options */
330  if (*pkt == IPV4_OPT_EOL) {
331  /** \todo What if more data exist after EOL (possible covert channel or data leakage)? */
332  SCLogDebug("IPV4OPT %" PRIu8 " len 1 @ %d/%d",
333  *pkt, (len - plen), (len - 1));
335  break;
336  } else if (*pkt == IPV4_OPT_NOP) {
337  SCLogDebug("IPV4OPT %" PRIu8 " len 1 @ %d/%d",
338  *pkt, (len - plen), (len - 1));
339  pkt++;
340  plen--;
341 
343 
344  /* multibyte options */
345  } else {
346  if (unlikely(plen < 2)) {
347  /** \todo What if padding is non-zero (possible covert channel or data leakage)? */
348  /** \todo Spec seems to indicate EOL required if there is padding */
350  break;
351  }
352 
353  /* Option length is too big for packet */
354  if (unlikely(*(pkt+1) > plen)) {
356  return -1;
357  }
358 
359  IPV4Opt opt = {*pkt, *(pkt+1), plen > 2 ? (pkt + 2) : NULL };
360 
361  /* we already know that the total options len is valid,
362  * so here the len of the specific option must be bad.
363  * Also check for invalid lengths 0 and 1. */
364  if (unlikely(opt.len > plen || opt.len < 2)) {
366  return -1;
367  }
368  /* we are parsing the most commonly used opts to prevent
369  * us from having to walk the opts list for these all the
370  * time. */
371  /** \todo Figure out which IP options are more common and list them first */
372  switch (opt.type) {
373  case IPV4_OPT_TS:
374  if (opts->o_ts.type != 0) {
376  /* Warn - we can keep going */
377  } else if (IPV4OptValidateTimestamp(p, &opt) == 0) {
378  opts->o_ts = opt;
380  }
381  break;
382  case IPV4_OPT_RR:
383  if (opts->o_rr.type != 0) {
385  /* Warn - we can keep going */
386  } else if (IPV4OptValidateRoute(p, &opt) == 0) {
387  opts->o_rr = opt;
389  }
390  break;
391  case IPV4_OPT_QS:
392  if (opts->o_qs.type != 0) {
394  /* Warn - we can keep going */
395  } else if (IPV4OptValidateGeneric(p, &opt) == 0) {
396  opts->o_qs = opt;
398  }
399  break;
400  case IPV4_OPT_SEC:
401  if (opts->o_sec.type != 0) {
403  /* Warn - we can keep going */
404  } else if (IPV4OptValidateGeneric(p, &opt) == 0) {
405  opts->o_sec = opt;
407  }
408  break;
409  case IPV4_OPT_LSRR:
410  if (opts->o_lsrr.type != 0) {
412  /* Warn - we can keep going */
413  } else if (IPV4OptValidateRoute(p, &opt) == 0) {
414  opts->o_lsrr = opt;
416  }
417  break;
418  case IPV4_OPT_CIPSO:
419  if (opts->o_cipso.type != 0) {
421  /* Warn - we can keep going */
422  } else if (IPV4OptValidateCIPSO(p, &opt) == 0) {
423  opts->o_cipso = opt;
425  }
426  break;
427  case IPV4_OPT_SID:
428  if (opts->o_sid.type != 0) {
430  /* Warn - we can keep going */
431  } else if (IPV4OptValidateGeneric(p, &opt) == 0) {
432  opts->o_sid = opt;
434  }
435  break;
436  case IPV4_OPT_SSRR:
437  if (opts->o_ssrr.type != 0) {
439  /* Warn - we can keep going */
440  } else if (IPV4OptValidateRoute(p, &opt) == 0) {
441  opts->o_ssrr = opt;
443  }
444  break;
445  case IPV4_OPT_RTRALT:
446  if (opts->o_rtralt.type != 0) {
448  /* Warn - we can keep going */
449  } else if (IPV4OptValidateGeneric(p, &opt) == 0) {
450  opts->o_rtralt = opt;
452  }
453  break;
454  default:
455  SCLogDebug("IPV4OPT <unknown> (%" PRIu8 ") len %" PRIu8,
456  opt.type, opt.len);
458  /* Warn - we can keep going */
459  break;
460  }
461 
462  pkt += opt.len;
463  plen -= opt.len;
464  }
465  }
466 
467  return 0;
468 }
469 
470 static int DecodeIPV4Packet(Packet *p, const uint8_t *pkt, uint16_t len)
471 {
472  if (unlikely(len < IPV4_HEADER_LEN)) {
474  return -1;
475  }
476 
477  if (unlikely(IP_GET_RAW_VER(pkt) != 4)) {
478  SCLogDebug("wrong ip version %d",IP_GET_RAW_VER(pkt));
480  return -1;
481  }
482 
483  p->ip4h = (IPV4Hdr *)pkt;
484 
487  return -1;
488  }
489 
490  if (unlikely(IPV4_GET_IPLEN(p) < IPV4_GET_HLEN(p))) {
492  return -1;
493  }
494 
495  if (unlikely(len < IPV4_GET_IPLEN(p))) {
497  return -1;
498  }
499 
500  /* set the address struct */
501  SET_IPV4_SRC_ADDR(p,&p->src);
502  SET_IPV4_DST_ADDR(p,&p->dst);
503 
504  /* save the options len */
505  uint8_t ip_opt_len = IPV4_GET_HLEN(p) - IPV4_HEADER_LEN;
506  if (ip_opt_len > 0) {
507  IPV4Options opts;
508  memset(&opts, 0x00, sizeof(opts));
509  if (DecodeIPV4Options(p, pkt + IPV4_HEADER_LEN, ip_opt_len, &opts) < 0) {
510  return -1;
511  }
512  }
513 
514  return 0;
515 }
516 
518  const uint8_t *pkt, uint16_t len)
519 {
521 
522  SCLogDebug("pkt %p len %"PRIu16"", pkt, len);
523 
524  /* do the actual decoding */
525  if (unlikely(DecodeIPV4Packet (p, pkt, len) < 0)) {
526  SCLogDebug("decoding IPv4 packet failed");
527  CLEAR_IPV4_PACKET((p));
528  return TM_ECODE_FAILED;
529  }
530  p->proto = IPV4_GET_IPPROTO(p);
531 
532  /* If a fragment, pass off for re-assembly. */
533  if (unlikely(IPV4_GET_IPOFFSET(p) > 0 || IPV4_GET_MF(p) == 1)) {
534  Packet *rp = Defrag(tv, dtv, p);
535  if (rp != NULL) {
537  }
538  p->flags |= PKT_IS_FRAGMENT;
539  return TM_ECODE_OK;
540  }
541 
542  /* do hdr test, process hdr rules */
543 
544 #ifdef DEBUG
545  if (SCLogDebugEnabled()) { /* only convert the addresses if debug is really enabled */
546  /* debug print */
547  char s[16], d[16];
548  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), s, sizeof(s));
549  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), d, sizeof(d));
550  SCLogDebug("IPV4 %s->%s PROTO: %" PRIu32 " OFFSET: %" PRIu32 " RF: %" PRIu32 " DF: %" PRIu32 " MF: %" PRIu32 " ID: %" PRIu32 "", s,d,
553  }
554 #endif /* DEBUG */
555 
556  /* check what next decoder to invoke */
557  switch (IPV4_GET_IPPROTO(p)) {
558  case IPPROTO_TCP:
559  DecodeTCP(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
560  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p));
561  break;
562  case IPPROTO_UDP:
563  DecodeUDP(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
564  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p));
565  break;
566  case IPPROTO_ICMP:
567  DecodeICMPV4(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
568  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p));
569  break;
570  case IPPROTO_GRE:
571  DecodeGRE(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
572  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p));
573  break;
574  case IPPROTO_SCTP:
575  DecodeSCTP(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
576  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p));
577  break;
578 
579  case IPPROTO_ESP:
580  DecodeESP(tv, dtv, p, pkt + IPV4_GET_HLEN(p), IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p));
581  break;
582 
583  case IPPROTO_IPV6:
584  {
585  /* spawn off tunnel packet */
586  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
589  if (tp != NULL) {
592  }
593  FlowSetupPacket(p);
594  break;
595  }
596  case IPPROTO_IP:
597  /* check PPP VJ uncompressed packets and decode tcp dummy */
598  if(p->ppph != NULL && SCNtohs(p->ppph->protocol) == PPP_VJ_UCOMP) {
599  DecodeTCP(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
600  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p));
601  }
602  break;
603  case IPPROTO_ICMPV6:
605  break;
606  }
607 
608  return TM_ECODE_OK;
609 }
610 
611 /* UNITTESTS */
612 #ifdef UNITTESTS
613 
614 /** \test IPV4 with no options. */
615 static int DecodeIPV4OptionsNONETest01(void)
616 {
617  uint8_t raw_opts[] = { };
618  Packet *p = PacketGetFromAlloc();
619  FAIL_IF(unlikely(p == NULL));
620 
621  IPV4Options opts;
622  memset(&opts, 0x00, sizeof(opts));
623  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
625 
626  SCFree(p);
627  PASS;
628 }
629 
630 /** \test IPV4 with EOL option. */
631 static int DecodeIPV4OptionsEOLTest01(void)
632 {
633  uint8_t raw_opts[] = {
634  IPV4_OPT_EOL, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
635  };
636  Packet *p = PacketGetFromAlloc();
637  FAIL_IF(unlikely(p == NULL));
638  IPV4Options opts;
639  memset(&opts, 0x00, sizeof(opts));
640  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
642  SCFree(p);
643  PASS;
644 }
645 
646 /** \test IPV4 with NOP option. */
647 static int DecodeIPV4OptionsNOPTest01(void)
648 {
649  uint8_t raw_opts[] = {
650  IPV4_OPT_NOP, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
651  };
652  Packet *p = PacketGetFromAlloc();
653  FAIL_IF(unlikely(p == NULL));
654  IPV4Options opts;
655  memset(&opts, 0x00, sizeof(opts));
656  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
658  SCFree(p);
659  PASS;
660 }
661 
662 /** \test IPV4 with RR option. */
663 static int DecodeIPV4OptionsRRTest01(void)
664 {
665  uint8_t raw_opts[] = {
666  IPV4_OPT_RR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
667  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
668  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
671  };
672  Packet *p = PacketGetFromAlloc();
673  FAIL_IF(unlikely(p == NULL));
674 
675  IPV4Options opts;
676  memset(&opts, 0x00, sizeof(opts));
677  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
679  FAIL_IF(opts.o_rr.type != IPV4_OPT_RR);
680  SCFree(p);
681  PASS;
682 }
683 
684 /** \test IPV4 with RR option (len too large). */
685 static int DecodeIPV4OptionsRRTest02(void)
686 {
687  uint8_t raw_opts[] = {
688  IPV4_OPT_RR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
689  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
690  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
691  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
692  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
693  };
694  Packet *p = PacketGetFromAlloc();
695  FAIL_IF(unlikely(p == NULL));
696 
697  IPV4Options opts;
698  memset(&opts, 0x00, sizeof(opts));
699  FAIL_IF(DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts) != -1);
700  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
701  FAIL_IF(opts.o_rr.type != 0);
702  SCFree(p);
703  PASS;
704 }
705 
706 /** \test IPV4 with RR option (ptr too large). */
707 static int DecodeIPV4OptionsRRTest03(void)
708 {
709  uint8_t raw_opts[] = {
710  IPV4_OPT_RR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
711  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
712  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
713  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
714  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
715  };
716  Packet *p = PacketGetFromAlloc();
717  FAIL_IF(unlikely(p == NULL));
718 
719  IPV4Options opts;
720  memset(&opts, 0x00, sizeof(opts));
721  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
722  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
723  FAIL_IF(opts.o_rr.type != 0);
724  SCFree(p);
725  PASS;
726 }
727 
728 /** \test IPV4 with RR option (ptr not in 4 byte increment). */
729 static int DecodeIPV4OptionsRRTest04(void)
730 {
731  uint8_t raw_opts[] = {
732  IPV4_OPT_RR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
733  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
734  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
735  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
736  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
737  };
738  Packet *p = PacketGetFromAlloc();
739  FAIL_IF(unlikely(p == NULL));
740 
741  IPV4Options opts;
742  memset(&opts, 0x00, sizeof(opts));
743  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
744  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
745  FAIL_IF(opts.o_rr.type != 0);
746  SCFree(p);
747  PASS;
748 }
749 
750 /** \test IPV4 with QS option. */
751 static int DecodeIPV4OptionsQSTest01(void)
752 {
753  uint8_t raw_opts[] = {
754  IPV4_OPT_QS, 0x08, 0x0d, 0x00, 0xbe, 0xef, 0x00, 0x00
755  };
756  Packet *p = PacketGetFromAlloc();
757  FAIL_IF(unlikely(p == NULL));
758 
759  IPV4Options opts;
760  memset(&opts, 0x00, sizeof(opts));
761  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
763  FAIL_IF(opts.o_qs.type != IPV4_OPT_QS);
764  SCFree(p);
765  PASS;
766 }
767 
768 /** \test IPV4 with QS option (len too small) */
769 static int DecodeIPV4OptionsQSTest02(void)
770 {
771  uint8_t raw_opts[] = {
772  IPV4_OPT_QS, 0x07, 0x0d, 0x00, 0xbe, 0xef, 0x00, 0x00
773  };
774  Packet *p = PacketGetFromAlloc();
775  FAIL_IF(unlikely(p == NULL));
776 
777  IPV4Options opts;
778  memset(&opts, 0x00, sizeof(opts));
779  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
780  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
781  FAIL_IF(opts.o_qs.type != 0);
782  SCFree(p);
783  PASS;
784 }
785 
786 /** \test IPV4 with TS option. */
787 static int DecodeIPV4OptionsTSTest01(void)
788 {
789  uint8_t raw_opts[] = {
790  IPV4_OPT_TS, 0x24, 0x0d, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
791  0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
792  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
793  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
794  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
795  };
796  Packet *p = PacketGetFromAlloc();
797  FAIL_IF(unlikely(p == NULL));
798 
799  IPV4Options opts;
800  memset(&opts, 0x00, sizeof(opts));
801  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
803  FAIL_IF(opts.o_ts.type != IPV4_OPT_TS);
804  SCFree(p);
805  PASS;
806 }
807 
808 /** \test IPV4 with TS option (ptr too small). */
809 static int DecodeIPV4OptionsTSTest02(void)
810 {
811  uint8_t raw_opts[] = {
812  IPV4_OPT_TS, 0x24, 0x04, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
813  0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
814  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
815  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
816  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
817  };
818  Packet *p = PacketGetFromAlloc();
819  FAIL_IF(unlikely(p == NULL));
820 
821  IPV4Options opts;
822  memset(&opts, 0x00, sizeof(opts));
823  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
824  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
825  FAIL_IF(opts.o_ts.type != 0);
826  SCFree(p);
827  PASS;
828 }
829 
830 /** \test IPV4 with TS option (ptr too large). */
831 static int DecodeIPV4OptionsTSTest03(void)
832 {
833  uint8_t raw_opts[] = {
834  IPV4_OPT_TS, 0x24, 0xff, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
835  0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
836  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
837  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
838  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
839  };
840  Packet *p = PacketGetFromAlloc();
841  FAIL_IF(unlikely(p == NULL));
842 
843  IPV4Options opts;
844  memset(&opts, 0x00, sizeof(opts));
845  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
846  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
847  FAIL_IF(opts.o_ts.type != 0);
848  SCFree(p);
849  PASS;
850 }
851 
852 /** \test IPV4 with TS option (ptr not valid). */
853 static int DecodeIPV4OptionsTSTest04(void)
854 {
855  uint8_t raw_opts[] = {
856  IPV4_OPT_TS, 0x24, 0x0a, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
857  0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
858  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
859  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
860  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
861  };
862  Packet *p = PacketGetFromAlloc();
863  FAIL_IF(unlikely(p == NULL));
864 
865  IPV4Options opts;
866  memset(&opts, 0x00, sizeof(opts));
867  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
868  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
869  FAIL_IF(opts.o_ts.type != 0);
870  SCFree(p);
871  PASS;
872 }
873 
874 /** \test IPV4 with SEC option. */
875 static int DecodeIPV4OptionsSECTest01(void)
876 {
877  uint8_t raw_opts[] = {
878  IPV4_OPT_SEC, 0x0b, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00,
879  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
880  };
881  Packet *p = PacketGetFromAlloc();
882  FAIL_IF(unlikely(p == NULL));
883 
884  IPV4Options opts;
885  memset(&opts, 0x00, sizeof(opts));
886  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
888  FAIL_IF(opts.o_sec.type != IPV4_OPT_SEC);
889  SCFree(p);
890  PASS;
891 }
892 
893 /** \test IPV4 with SEC option (invalid length). */
894 static int DecodeIPV4OptionsSECTest02(void)
895 {
896  uint8_t raw_opts[] = {
897  IPV4_OPT_SEC, 0x0a, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00,
898  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
899  };
900  Packet *p = PacketGetFromAlloc();
901  FAIL_IF(unlikely(p == NULL));
902 
903  IPV4Options opts;
904  memset(&opts, 0x00, sizeof(opts));
905  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
906  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
907  FAIL_IF(opts.o_sec.type != 0);
908  SCFree(p);
909  PASS;
910 }
911 
912 /** \test IPV4 with LSRR option. */
913 static int DecodeIPV4OptionsLSRRTest01(void)
914 {
915  uint8_t raw_opts[] = {
916  IPV4_OPT_LSRR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
917  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
918  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
919  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
920  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
921  };
922  Packet *p = PacketGetFromAlloc();
923  FAIL_IF(unlikely(p == NULL));
924 
925  IPV4Options opts;
926  memset(&opts, 0x00, sizeof(opts));
927  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
929  FAIL_IF(opts.o_lsrr.type != IPV4_OPT_LSRR);
930  SCFree(p);
931  PASS;
932 }
933 
934 /** \test IPV4 with LSRR option (len too large). */
935 static int DecodeIPV4OptionsLSRRTest02(void)
936 {
937  uint8_t raw_opts[] = {
938  IPV4_OPT_LSRR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
939  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
940  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
941  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
942  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
943  };
944  Packet *p = PacketGetFromAlloc();
945  FAIL_IF(unlikely(p == NULL));
946 
947  IPV4Options opts;
948  memset(&opts, 0x00, sizeof(opts));
949  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
950  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
951  FAIL_IF(opts.o_lsrr.type != 0);
952  SCFree(p);
953  PASS;
954 }
955 
956 /** \test IPV4 with LSRR option (ptr too large). */
957 static int DecodeIPV4OptionsLSRRTest03(void)
958 {
959  uint8_t raw_opts[] = {
960  IPV4_OPT_LSRR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
961  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
962  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
963  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
964  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
965  };
966  Packet *p = PacketGetFromAlloc();
967  FAIL_IF(unlikely(p == NULL));
968 
969  IPV4Options opts;
970  memset(&opts, 0x00, sizeof(opts));
971  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
972  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
973  FAIL_IF(opts.o_lsrr.type != 0);
974  SCFree(p);
975  PASS;
976 }
977 
978 /** \test IPV4 with LSRR option (ptr not in 4 byte increment). */
979 static int DecodeIPV4OptionsLSRRTest04(void)
980 {
981  uint8_t raw_opts[] = {
982  IPV4_OPT_LSRR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
983  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
984  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
985  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
986  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
987  };
988  Packet *p = PacketGetFromAlloc();
989  FAIL_IF(unlikely(p == NULL));
990 
991  IPV4Options opts;
992  memset(&opts, 0x00, sizeof(opts));
993  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
994  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
995  FAIL_IF(opts.o_lsrr.type != 0);
996  SCFree(p);
997  PASS;
998 }
999 
1000 /** \test IPV4 with CIPSO option. */
1001 static int DecodeIPV4OptionsCIPSOTest01(void)
1002 {
1003  uint8_t raw_opts[] = {
1004  IPV4_OPT_CIPSO, 0x18, 0x00, 0x00, 0x00, 0x05, 0x05, 0x12,
1005  0x00, 0x03, 0x00, 0xef, 0x00, 0xef, 0x00, 0x06,
1006  0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00
1007  };
1008  Packet *p = PacketGetFromAlloc();
1009  FAIL_IF(unlikely(p == NULL));
1010 
1011  IPV4Options opts;
1012  memset(&opts, 0x00, sizeof(opts));
1013  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1016  SCFree(p);
1017  PASS;
1018 }
1019 
1020 /** \test IPV4 with SID option. */
1021 static int DecodeIPV4OptionsSIDTest01(void)
1022 {
1023  uint8_t raw_opts[] = {
1024  IPV4_OPT_SID, 0x04, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1025  };
1026  Packet *p = PacketGetFromAlloc();
1027  FAIL_IF(unlikely(p == NULL));
1028 
1029  IPV4Options opts;
1030  memset(&opts, 0x00, sizeof(opts));
1031  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1033  FAIL_IF(opts.o_sid.type != IPV4_OPT_SID);
1034  SCFree(p);
1035  PASS;
1036 }
1037 
1038 /** \test IPV4 with SID option (len invalid. */
1039 static int DecodeIPV4OptionsSIDTest02(void)
1040 {
1041  uint8_t raw_opts[] = {
1042  IPV4_OPT_SID, 0x05, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1043  };
1044  Packet *p = PacketGetFromAlloc();
1045  FAIL_IF(unlikely(p == NULL));
1046 
1047  IPV4Options opts;
1048  memset(&opts, 0x00, sizeof(opts));
1049  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1050  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1051  FAIL_IF(opts.o_sid.type != 0);
1052  SCFree(p);
1053  PASS;
1054 }
1055 
1056 /** \test IPV4 with SSRR option. */
1057 static int DecodeIPV4OptionsSSRRTest01(void)
1058 {
1059  uint8_t raw_opts[] = {
1060  IPV4_OPT_SSRR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1061  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1062  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1063  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1064  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1065  };
1066  Packet *p = PacketGetFromAlloc();
1067  FAIL_IF(unlikely(p == NULL));
1068 
1069  IPV4Options opts;
1070  memset(&opts, 0x00, sizeof(opts));
1071  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1073  FAIL_IF(opts.o_ssrr.type != IPV4_OPT_SSRR);
1074  SCFree(p);
1075  PASS;
1076 }
1077 
1078 /** \test IPV4 with SSRR option (len too large). */
1079 static int DecodeIPV4OptionsSSRRTest02(void)
1080 {
1081  uint8_t raw_opts[] = {
1082  IPV4_OPT_SSRR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1083  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1084  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1085  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1086  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1087  };
1088  Packet *p = PacketGetFromAlloc();
1089  FAIL_IF(unlikely(p == NULL));
1090 
1091  IPV4Options opts;
1092  memset(&opts, 0x00, sizeof(opts));
1093  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1094  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1095  FAIL_IF(opts.o_ssrr.type != 0);
1096  SCFree(p);
1097  PASS;
1098 }
1099 
1100 /** \test IPV4 with SSRR option (ptr too large). */
1101 static int DecodeIPV4OptionsSSRRTest03(void)
1102 {
1103  uint8_t raw_opts[] = {
1104  IPV4_OPT_SSRR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1105  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1106  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1107  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1108  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1109  };
1110  Packet *p = PacketGetFromAlloc();
1111  FAIL_IF(unlikely(p == NULL));
1112 
1113  IPV4Options opts;
1114  memset(&opts, 0x00, sizeof(opts));
1115  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1116  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1117  FAIL_IF(opts.o_ssrr.type != 0);
1118  SCFree(p);
1119  PASS;
1120 }
1121 
1122 /** \test IPV4 with SSRR option (ptr not in 4 byte increment). */
1123 static int DecodeIPV4OptionsSSRRTest04(void)
1124 {
1125  uint8_t raw_opts[] = {
1126  IPV4_OPT_SSRR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1127  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1128  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1129  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1130  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1131  };
1132  Packet *p = PacketGetFromAlloc();
1133  FAIL_IF(unlikely(p == NULL));
1134 
1135  IPV4Options opts;
1136  memset(&opts, 0x00, sizeof(opts));
1137  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1138  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1139  FAIL_IF(opts.o_ssrr.type != 0);
1140  SCFree(p);
1141  PASS;
1142 }
1143 
1144 /** \test IPV4 with RTRALT option. */
1145 static int DecodeIPV4OptionsRTRALTTest01(void)
1146 {
1147  uint8_t raw_opts[] = {
1148  IPV4_OPT_RTRALT, 0x04, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1149  };
1150  Packet *p = PacketGetFromAlloc();
1151  FAIL_IF(unlikely(p == NULL));
1152 
1153  IPV4Options opts;
1154  memset(&opts, 0x00, sizeof(opts));
1155  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1158  SCFree(p);
1159  PASS;
1160 }
1161 
1162 /** \test IPV4 with RTRALT option (len invalid. */
1163 static int DecodeIPV4OptionsRTRALTTest02(void)
1164 {
1165  uint8_t raw_opts[] = {
1166  IPV4_OPT_RTRALT, 0x05, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1167  };
1168  Packet *p = PacketGetFromAlloc();
1169  FAIL_IF(unlikely(p == NULL));
1170 
1171  IPV4Options opts;
1172  memset(&opts, 0x00, sizeof(opts));
1173  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1174  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1175  FAIL_IF(opts.o_rtralt.type != 0);
1176  SCFree(p);
1177  PASS;
1178 }
1179 
1180 static int IPV4CalculateValidChecksumtest01(void)
1181 {
1182  uint16_t csum = 0;
1183 
1184  uint8_t raw_ipv4[] = {
1185  0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00,
1186  0x40, 0x01, 0xb7, 0x52, 0xc0, 0xa8, 0x01, 0x03,
1187  0xc0, 0xa8, 0x01, 0x03};
1188 
1189  csum = *( ((uint16_t *)raw_ipv4) + 5);
1190 
1191  FAIL_IF(IPV4Checksum((uint16_t *)raw_ipv4, sizeof(raw_ipv4), csum) != 0);
1192  PASS;
1193 }
1194 
1195 static int IPV4CalculateInvalidChecksumtest02(void)
1196 {
1197  uint16_t csum = 0;
1198 
1199  uint8_t raw_ipv4[] = {
1200  0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00,
1201  0x40, 0x01, 0xb7, 0x52, 0xc0, 0xa8, 0x01, 0x03,
1202  0xc0, 0xa8, 0x01, 0x07};
1203 
1204  csum = *( ((uint16_t *)raw_ipv4) + 5);
1205 
1206  FAIL_IF(IPV4Checksum((uint16_t *)raw_ipv4, sizeof(raw_ipv4), csum) == 0);
1207  PASS;
1208 }
1209 
1210 /**
1211  * \test IPV4 defrag and packet recursion level test
1212  */
1213 static int DecodeIPV4DefragTest01(void)
1214 {
1215  uint8_t pkt1[] = {
1216  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1217  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1218  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1219  0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1220  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1221  0x81, 0x5e
1222  };
1223  uint8_t pkt2[] = {
1224  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1225  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1226  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x01, 0x40, 0x06,
1227  0x9a, 0xc7, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1228  0xe1, 0x0c, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1229  0x80, 0x00
1230  };
1231  uint8_t pkt3[] = {
1232  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1233  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1234  0x00, 0x18, 0xe9, 0xef, 0x00, 0x02, 0x40, 0x06,
1235  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1236  0xe1, 0x0c, 0xb1, 0xa3, 0x00, 0x00
1237  };
1238  uint8_t tunnel_pkt[] = {
1239  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1240  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1241  0x00, 0x28, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1242  0xba, 0xbc, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1243  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1244  0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1245  0x80, 0x00, 0xb1, 0xa3, 0x00, 0x00
1246  };
1247 
1248  Packet *p = PacketGetFromAlloc();
1249  if (unlikely(p == NULL))
1250  return 0;
1251  ThreadVars tv;
1253  int result = 1;
1254 
1255  memset(&tv, 0, sizeof(ThreadVars));
1256  memset(&dtv, 0, sizeof(DecodeThreadVars));
1257 
1259  DefragInit();
1260 
1261  PacketCopyData(p, pkt1, sizeof(pkt1));
1264  if (p->tcph != NULL) {
1265  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1266  result = 0;
1267  goto end;
1268  }
1269  PACKET_RECYCLE(p);
1270 
1271  PacketCopyData(p, pkt2, sizeof(pkt2));
1274  if (p->tcph != NULL) {
1275  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1276  result = 0;
1277  goto end;
1278  }
1279  PACKET_RECYCLE(p);
1280 
1281  PacketCopyData(p, pkt3, sizeof(pkt3));
1284  if (p->tcph != NULL) {
1285  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1286  result = 0;
1287  goto end;
1288  }
1290  if (tp == NULL) {
1291  printf("Failed to get defragged pseudo packet\n");
1292  result = 0;
1293  goto end;
1294  }
1295  if (tp->recursion_level != p->recursion_level) {
1296  printf("defragged pseudo packet's and parent packet's recursion "
1297  "level don't match\n %d != %d",
1299  result = 0;
1300  goto end;
1301  }
1302  if (tp->ip4h == NULL || tp->tcph == NULL) {
1303  printf("pseudo packet's ip header and tcp header shouldn't be NULL, "
1304  "but it is\n");
1305  result = 0;
1306  goto end;
1307  }
1308  if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) {
1309  printf("defragged pseudo packet's and parent packet's pkt lens "
1310  "don't match\n %u != %"PRIuMAX,
1311  GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt));
1312  result = 0;
1313  goto end;
1314  }
1315  if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) {
1316  result = 0;
1317  goto end;
1318  }
1319 
1320  PACKET_RECYCLE(tp);
1321  SCFree(tp);
1322 
1323 end:
1324  DefragDestroy();
1325  PACKET_RECYCLE(p);
1326  FlowShutdown();
1327  SCFree(p);
1328  return result;
1329 }
1330 
1331 /**
1332  * \test Don't send IPv4 fragments to the upper layer decoder and
1333  * and packet recursion level test.
1334  */
1335 static int DecodeIPV4DefragTest02(void)
1336 {
1337  uint8_t pkt1[] = {
1338  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1339  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1340  0x00, 0x24, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1341  0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1342  0xe1, 0x0c,
1343  /* first frag */
1344  0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1345  0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1346  0x80, 0x00,
1347  };
1348  uint8_t pkt2[] = {
1349  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1350  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1351  0x00, 0x2c, 0xe9, 0xef, 0x20, 0x02, 0x40, 0x06,
1352  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1353  0xe1, 0x0c,
1354  /* second frag */
1355  0xb1, 0xa3, 0x00, 0x10, 0x5b, 0xa3, 0x81, 0x5e,
1356  0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1357  0xb1, 0xa3, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04
1358  };
1359  uint8_t pkt3[] = {
1360  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1361  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1362  0x00, 0x16, 0xe9, 0xef, 0x00, 0x05, 0x40, 0x06,
1363  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1364  0xe1, 0x0c,
1365  /* final frag */
1366  0xb1, 0xa3,
1367  };
1368 
1369  uint8_t tunnel_pkt[] = {
1370  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1371  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1372  0x00, 0x3e, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1373  0xba, 0xae, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1374  0xe1, 0x0c,
1375  0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3, 0x81, 0x5e,
1376  0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1377  0xb1, 0xa3, 0x00, 0x10, 0x5b, 0xa3, 0x81, 0x5e,
1378  0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1379  0xb1, 0xa3, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04,
1380  0xb1, 0xa3,
1381  };
1382 
1383  Packet *p = PacketGetFromAlloc();
1384  if (unlikely(p == NULL))
1385  return 0;
1386  ThreadVars tv;
1388  int result = 0;
1389 
1390  memset(&tv, 0, sizeof(ThreadVars));
1391  memset(&dtv, 0, sizeof(DecodeThreadVars));
1392 
1394  DefragInit();
1395 
1396  PacketCopyData(p, pkt1, sizeof(pkt1));
1399  if (p->tcph != NULL) {
1400  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1401  goto end;
1402  }
1403  PACKET_RECYCLE(p);
1404 
1405  PacketCopyData(p, pkt2, sizeof(pkt2));
1408  if (p->tcph != NULL) {
1409  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1410  goto end;
1411  }
1412  PACKET_RECYCLE(p);
1413 
1414  p->recursion_level = 3;
1415  PacketCopyData(p, pkt3, sizeof(pkt3));
1418  if (p->tcph != NULL) {
1419  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1420  goto end;
1421  }
1423  if (tp == NULL) {
1424  printf("Failed to get defragged pseudo packet\n");
1425  goto end;
1426  }
1427  if (tp->recursion_level != p->recursion_level) {
1428  printf("defragged pseudo packet's and parent packet's recursion "
1429  "level don't match %d != %d: ",
1431  goto end;
1432  }
1433  if (tp->ip4h == NULL || tp->tcph == NULL) {
1434  printf("pseudo packet's ip header and tcp header shouldn't be NULL, "
1435  "but it is\n");
1436  goto end;
1437  }
1438  if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) {
1439  printf("defragged pseudo packet's and parent packet's pkt lens "
1440  "don't match %u != %"PRIuMAX": ",
1441  GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt));
1442  goto end;
1443  }
1444 
1445  if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) {
1446  goto end;
1447  }
1448 
1449  result = 1;
1450  PACKET_RECYCLE(tp);
1451  SCFree(tp);
1452 
1453 end:
1454  DefragDestroy();
1455  PACKET_RECYCLE(p);
1456  FlowShutdown();
1457  SCFree(p);
1458  return result;
1459 }
1460 
1461 /**
1462  * \test IPV4 defrag and flow retrieval test.
1463  */
1464 static int DecodeIPV4DefragTest03(void)
1465 {
1466  uint8_t pkt[] = {
1467  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1468  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1469  0x00, 0x28, 0xe9, 0xee, 0x00, 0x00, 0x40, 0x06,
1470  0xba, 0xbd, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1471  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1472  0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02,
1473  0x80, 0x00, 0x0c, 0xee, 0x00, 0x00
1474  };
1475  uint8_t pkt1[] = {
1476  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1477  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1478  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1479  0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1480  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1481  0x81, 0x5e
1482  };
1483  uint8_t pkt2[] = {
1484  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1485  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1486  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x01, 0x40, 0x06,
1487  0x9a, 0xc7, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1488  0xe1, 0x0c, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1489  0x80, 0x00
1490  };
1491  uint8_t pkt3[] = {
1492  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1493  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1494  0x00, 0x18, 0xe9, 0xef, 0x00, 0x02, 0x40, 0x06,
1495  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1496  0xe1, 0x0c, 0xb1, 0xa3, 0x00, 0x00
1497  };
1498  uint8_t tunnel_pkt[] = {
1499  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1500  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1501  0x00, 0x28, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1502  0xba, 0xbc, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1503  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1504  0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1505  0x80, 0x00, 0xb1, 0xa3, 0x00, 0x00
1506  };
1507 
1508  Packet *p = PacketGetFromAlloc();
1509  if (unlikely(p == NULL))
1510  return 0;
1511  ThreadVars tv;
1513  int result = 1;
1514 
1515  memset(&tv, 0, sizeof(ThreadVars));
1516  memset(&dtv, 0, sizeof(DecodeThreadVars));
1517 
1519  DefragInit();
1520 
1521  PacketCopyData(p, pkt, sizeof(pkt));
1524  if (p->tcph == NULL) {
1525  printf("tcp header shouldn't be NULL, but it is\n");
1526  result = 0;
1527  goto end;
1528  }
1529  if (!(p->flags & PKT_WANTS_FLOW)) {
1530  printf("packet flow shouldn't be NULL\n");
1531  result = 0;
1532  goto end;
1533  }
1534  PACKET_RECYCLE(p);
1535 
1536  PacketCopyData(p, pkt1, sizeof(pkt1));
1539  if (p->tcph != NULL) {
1540  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1541  result = 0;
1542  goto end;
1543  }
1544  PACKET_RECYCLE(p);
1545 
1546  PacketCopyData(p, pkt2, sizeof(pkt2));
1549  if (p->tcph != NULL) {
1550  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1551  result = 0;
1552  goto end;
1553  }
1554  PACKET_RECYCLE(p);
1555 
1556  PacketCopyData(p, pkt3, sizeof(pkt3));
1559  if (p->tcph != NULL) {
1560  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1561  result = 0;
1562  goto end;
1563  }
1564 
1566  if (tp == NULL) {
1567  printf("Failed to get defragged pseudo packet\n");
1568  result = 0;
1569  goto end;
1570  }
1571  if (!(tp->flags & PKT_WANTS_FLOW)) {
1572  result = 0;
1573  goto end;
1574  }
1575  if (tp->flow_hash != p->flow_hash) {
1576  result = 0;
1577  goto end;
1578  }
1579  if (tp->recursion_level != p->recursion_level) {
1580  printf("defragged pseudo packet's and parent packet's recursion "
1581  "level don't match\n %d != %d",
1583  result = 0;
1584  goto end;
1585  }
1586  if (tp->ip4h == NULL || tp->tcph == NULL) {
1587  printf("pseudo packet's ip header and tcp header shouldn't be NULL, "
1588  "but it is\n");
1589  result = 0;
1590  goto end;
1591  }
1592  if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) {
1593  printf("defragged pseudo packet's and parent packet's pkt lens "
1594  "don't match\n %u != %"PRIuMAX,
1595  GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt));
1596  result = 0;
1597  goto end;
1598  }
1599 
1600  if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) {
1601  result = 0;
1602  goto end;
1603  }
1604 
1605  PACKET_RECYCLE(tp);
1606  SCFree(tp);
1607 
1608 end:
1609  DefragDestroy();
1610  PACKET_RECYCLE(p);
1611  FlowShutdown();
1612  SCFree(p);
1613  return result;
1614 }
1615 
1616 /**
1617  */
1618 static int DecodeEthernetTestIPv4Opt(void)
1619 {
1620  uint8_t raw_eth[] = {
1621  0xae, 0x71, 0x00, 0x00, 0x00, 0x4b, 0x06, 0x90, 0x61, 0x02, 0x00, 0xcd, 0x88, 0x64, 0x11, 0x00,
1622  0x15, 0x00, 0x80, 0x64, 0x00, 0x21, 0x4c, 0x00, 0x00, 0x30, 0x42, 0xd6, 0xff, 0xff, 0xbd, 0x2f,
1623  0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1624  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1625  0x01, 0x44, 0x05, 0x22, 0x02, 0x01
1626  };
1627 
1628  DefragInit();
1629 
1631  FAIL_IF_NULL(p);
1632  ThreadVars tv;
1634 
1635  memset(&dtv, 0, sizeof(DecodeThreadVars));
1636  memset(&tv, 0, sizeof(ThreadVars));
1637  memset(p, 0, SIZE_OF_PACKET);
1638 
1639  DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth));
1640 
1641  SCFree(p);
1642  DefragDestroy();
1643  PASS;
1644 }
1645 
1646 #endif /* UNITTESTS */
1647 
1649 {
1650 #ifdef UNITTESTS
1651  UtRegisterTest("DecodeIPV4OptionsNONETest01", DecodeIPV4OptionsNONETest01);
1652  UtRegisterTest("DecodeIPV4OptionsEOLTest01", DecodeIPV4OptionsEOLTest01);
1653  UtRegisterTest("DecodeIPV4OptionsNOPTest01", DecodeIPV4OptionsNOPTest01);
1654  UtRegisterTest("DecodeIPV4OptionsRRTest01", DecodeIPV4OptionsRRTest01);
1655  UtRegisterTest("DecodeIPV4OptionsRRTest02", DecodeIPV4OptionsRRTest02);
1656  UtRegisterTest("DecodeIPV4OptionsRRTest03", DecodeIPV4OptionsRRTest03);
1657  UtRegisterTest("DecodeIPV4OptionsRRTest04", DecodeIPV4OptionsRRTest04);
1658  UtRegisterTest("DecodeIPV4OptionsQSTest01", DecodeIPV4OptionsQSTest01);
1659  UtRegisterTest("DecodeIPV4OptionsQSTest02", DecodeIPV4OptionsQSTest02);
1660  UtRegisterTest("DecodeIPV4OptionsTSTest01", DecodeIPV4OptionsTSTest01);
1661  UtRegisterTest("DecodeIPV4OptionsTSTest02", DecodeIPV4OptionsTSTest02);
1662  UtRegisterTest("DecodeIPV4OptionsTSTest03", DecodeIPV4OptionsTSTest03);
1663  UtRegisterTest("DecodeIPV4OptionsTSTest04", DecodeIPV4OptionsTSTest04);
1664  UtRegisterTest("DecodeIPV4OptionsSECTest01", DecodeIPV4OptionsSECTest01);
1665  UtRegisterTest("DecodeIPV4OptionsSECTest02", DecodeIPV4OptionsSECTest02);
1666  UtRegisterTest("DecodeIPV4OptionsLSRRTest01", DecodeIPV4OptionsLSRRTest01);
1667  UtRegisterTest("DecodeIPV4OptionsLSRRTest02", DecodeIPV4OptionsLSRRTest02);
1668  UtRegisterTest("DecodeIPV4OptionsLSRRTest03", DecodeIPV4OptionsLSRRTest03);
1669  UtRegisterTest("DecodeIPV4OptionsLSRRTest04", DecodeIPV4OptionsLSRRTest04);
1670  UtRegisterTest("DecodeIPV4OptionsCIPSOTest01",
1671  DecodeIPV4OptionsCIPSOTest01);
1672  UtRegisterTest("DecodeIPV4OptionsSIDTest01", DecodeIPV4OptionsSIDTest01);
1673  UtRegisterTest("DecodeIPV4OptionsSIDTest02", DecodeIPV4OptionsSIDTest02);
1674  UtRegisterTest("DecodeIPV4OptionsSSRRTest01", DecodeIPV4OptionsSSRRTest01);
1675  UtRegisterTest("DecodeIPV4OptionsSSRRTest02", DecodeIPV4OptionsSSRRTest02);
1676  UtRegisterTest("DecodeIPV4OptionsSSRRTest03", DecodeIPV4OptionsSSRRTest03);
1677  UtRegisterTest("DecodeIPV4OptionsSSRRTest04", DecodeIPV4OptionsSSRRTest04);
1678  UtRegisterTest("DecodeIPV4OptionsRTRALTTest01",
1679  DecodeIPV4OptionsRTRALTTest01);
1680  UtRegisterTest("DecodeIPV4OptionsRTRALTTest02",
1681  DecodeIPV4OptionsRTRALTTest02);
1682  UtRegisterTest("IPV4CalculateValidChecksumtest01",
1683  IPV4CalculateValidChecksumtest01);
1684  UtRegisterTest("IPV4CalculateInvalidChecksumtest02",
1685  IPV4CalculateInvalidChecksumtest02);
1686  UtRegisterTest("DecodeIPV4DefragTest01", DecodeIPV4DefragTest01);
1687  UtRegisterTest("DecodeIPV4DefragTest02", DecodeIPV4DefragTest02);
1688  UtRegisterTest("DecodeIPV4DefragTest03", DecodeIPV4DefragTest03);
1689  UtRegisterTest("DecodeEthernetTestIPv4Opt", DecodeEthernetTestIPv4Opt);
1690 #endif /* UNITTESTS */
1691 }
1692 /**
1693  * @}
1694  */
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:1015
DefragDestroy
void DefragDestroy(void)
Definition: defrag.c:1085
host.h
IPV4Options_::o_sid
IPV4Opt o_sid
Definition: decode-ipv4.c:294
Packet_::proto
uint8_t proto
Definition: decode.h:437
IPV4Options_::o_qs
IPV4Opt o_qs
Definition: decode-ipv4.c:289
IPV4_OPT_MALFORMED
@ IPV4_OPT_MALFORMED
Definition: decode-events.h:39
len
uint8_t len
Definition: app-layer-dnp3.h:2
DECODE_TUNNEL_IPV6
@ DECODE_TUNNEL_IPV6
Definition: decode.h:917
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
IPV4_WITH_ICMPV6
@ IPV4_WITH_ICMPV6
Definition: decode-events.h:45
IPV4_OPT_DUPLICATE
@ IPV4_OPT_DUPLICATE
Definition: decode-events.h:42
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:169
IPV4_OPT_QS_MIN
#define IPV4_OPT_QS_MIN
Definition: decode-ipv4.h:52
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
DecodeUDP
int DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-udp.c:75
IPV4_OPT_UNKNOWN
@ IPV4_OPT_UNKNOWN
Definition: decode-events.h:43
IPV4_OPT_TS_MIN
#define IPV4_OPT_TS_MIN
Definition: decode-ipv4.h:53
PacketCopyData
int PacketCopyData(Packet *p, const uint8_t *pktdata, uint32_t pktlen)
Copy data to Packet payload and set packet length.
Definition: decode.c:265
IPV4_GET_IPOFFSET
#define IPV4_GET_IPOFFSET(p)
Definition: decode-ipv4.h:135
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
IPV4_GET_DF
#define IPV4_GET_DF(p)
Definition: decode-ipv4.h:141
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
DecodeESP
int DecodeESP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Function to decode IPSEC-ESP packets.
Definition: decode-esp.c:60
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:298
IPV4_OPT_INVALID_LEN
@ IPV4_OPT_INVALID_LEN
Definition: decode-events.h:38
PKT_SRC_DECODER_IPV4
@ PKT_SRC_DECODER_IPV4
Definition: decode.h:53
IPV4_HLEN_TOO_SMALL
@ IPV4_HLEN_TOO_SMALL
Definition: decode-events.h:32
IPV4Options_::o_ts
IPV4Opt o_ts
Definition: decode-ipv4.c:290
Packet_::flags
uint32_t flags
Definition: decode.h:450
IPV4_OPT_SEC
#define IPV4_OPT_SEC
Definition: decode-ipv4.h:38
IPV4_OPT_CIPSO_MIN
#define IPV4_OPT_CIPSO_MIN
Definition: decode-ipv4.h:54
FlowInitConfig
void FlowInitConfig(char quiet)
initialize the configuration
Definition: flow.c:516
IPV4_OPT_LSRR
#define IPV4_OPT_LSRR
Definition: decode-ipv4.h:39
PKT_WANTS_FLOW
#define PKT_WANTS_FLOW
Definition: decode.h:1142
IPV4Options_::o_sec
IPV4Opt o_sec
Definition: decode-ipv4.c:291
Packet_::ip4vars
IPV4Vars ip4vars
Definition: decode.h:516
packet-queue.h
IPV4Options_::o_rr
IPV4Opt o_rr
Definition: decode-ipv4.c:288
IPV4_OPT_FLAG_SEC
@ IPV4_OPT_FLAG_SEC
Definition: decode-ipv4.h:166
IPPROTO_GRE
#define IPPROTO_GRE
Definition: decode-gre.h:30
IP_GET_RAW_VER
#define IP_GET_RAW_VER(pkt)
Definition: decode.h:256
IPV4_OPT_NOP
#define IPV4_OPT_NOP
Definition: decode-ipv4.h:34
IPV4_OPT_SID_LEN
#define IPV4_OPT_SID_LEN
Definition: decode-ipv4.h:47
IPV4_OPT_EOL_REQUIRED
@ IPV4_OPT_EOL_REQUIRED
Definition: decode-events.h:41
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:81
IPV4Opt_::len
uint8_t len
Definition: decode-ipv4.h:66
IPV4_OPT_QS
#define IPV4_OPT_QS
Definition: decode-ipv4.h:36
IPV4_TRUNC_PKT
@ IPV4_TRUNC_PKT
Definition: decode-events.h:34
util-unittest.h
IPV4_IPLEN_SMALLER_THAN_HLEN
@ IPV4_IPLEN_SMALLER_THAN_HLEN
Definition: decode-events.h:33
IPV4_GET_RF
#define IPV4_GET_RF(p)
Definition: decode-ipv4.h:138
DecodeSCTP
int DecodeSCTP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-sctp.c:62
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:80
SET_IPV4_SRC_ADDR
#define SET_IPV4_SRC_ADDR(p, a)
Definition: decode.h:146
IPV4_OPT_FLAG_NOP
@ IPV4_OPT_FLAG_NOP
Definition: decode-ipv4.h:159
PKT_SET_SRC
#define PKT_SET_SRC(p, src_val)
Definition: decode.h:1162
IPV4Vars_::opt_cnt
uint16_t opt_cnt
Definition: decode-ipv4.h:176
IPV4_GET_IPPROTO
#define IPV4_GET_IPPROTO(p)
Definition: decode-ipv4.h:148
decode.h
IPV4_OPT_EOL
#define IPV4_OPT_EOL
Definition: decode-ipv4.h:33
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
GET_IPV4_DST_ADDR_PTR
#define GET_IPV4_DST_ADDR_PTR(p)
Definition: decode.h:222
IPV4_OPT_FLAG_SID
@ IPV4_OPT_FLAG_SID
Definition: decode-ipv4.h:165
PacketDequeueNoLock
Packet * PacketDequeueNoLock(PacketQueueNoLock *qnl)
Definition: packet-queue.c:206
IPV4_WRONG_IP_VER
@ IPV4_WRONG_IP_VER
Definition: decode-events.h:44
PKT_IS_FRAGMENT
#define PKT_IS_FRAGMENT
Definition: decode.h:1136
IPV4_OPT_ROUTE_MIN
#define IPV4_OPT_ROUTE_MIN
Definition: decode-ipv4.h:51
util-print.h
GET_PKT_DATA
#define GET_PKT_DATA(p)
Definition: decode.h:232
IPV4_OPT_FLAG_QS
@ IPV4_OPT_FLAG_QS
Definition: decode-ipv4.h:162
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
IPV4_GET_IPLEN
#define IPV4_GET_IPLEN(p)
Definition: decode-ipv4.h:127
PrintInet
const char * PrintInet(int af, const void *src, char *dst, socklen_t size)
Definition: util-print.c:271
pkt-var.h
IPV4_OPT_FLAG_RR
@ IPV4_OPT_FLAG_RR
Definition: decode-ipv4.h:160
DecodeGRE
int DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Function to decode GRE packets.
Definition: decode-gre.c:46
IPV4_PKT_TOO_SMALL
@ IPV4_PKT_TOO_SMALL
Definition: decode-events.h:31
IPV4_OPT_RR
#define IPV4_OPT_RR
Definition: decode-ipv4.h:35
SIZE_OF_PACKET
#define SIZE_OF_PACKET
Definition: decode.h:630
IPV4_GET_IPID
#define IPV4_GET_IPID(p)
Definition: decode-ipv4.h:129
util-profiling.h
IPV4_OPT_RTRALT_LEN
#define IPV4_OPT_RTRALT_LEN
Definition: decode-ipv4.h:48
IPV4Options_::o_cipso
IPV4Opt o_cipso
Definition: decode-ipv4.c:293
Packet_
Definition: decode.h:415
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:231
ETHERNET_HEADER_LEN
#define ETHERNET_HEADER_LEN
Definition: decode-ethernet.h:27
Packet_::ip4h
IPV4Hdr * ip4h
Definition: decode.h:510
IPV4_OPT_RTRALT
#define IPV4_OPT_RTRALT
Definition: decode-ipv4.h:43
defrag.h
IPV4_OPT_PAD_REQUIRED
@ IPV4_OPT_PAD_REQUIRED
Definition: decode-events.h:40
IPV4_OPT_FLAG_CIPSO
@ IPV4_OPT_FLAG_CIPSO
Definition: decode-ipv4.h:167
IPV4Opt_::data
const uint8_t * data
Definition: decode-ipv4.h:67
decode-events.h
IPV4_OPT_SEC_LEN
#define IPV4_OPT_SEC_LEN
Definition: decode-ipv4.h:46
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:30
IPV4_OPT_TS
#define IPV4_OPT_TS
Definition: decode-ipv4.h:37
DecodeTCP
int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-tcp.c:231
IPV4Hdr_
Definition: decode-ipv4.h:71
decode-ipv4.h
Packet_::ppph
PPPHdr * ppph
Definition: decode.h:544
IPV4_OPT_CIPSO
#define IPV4_OPT_CIPSO
Definition: decode-ipv4.h:40
PacketEnqueueNoLock
void PacketEnqueueNoLock(PacketQueueNoLock *qnl, Packet *p)
Definition: packet-queue.c:167
IPV4Options_
Definition: decode-ipv4.c:287
IPV4_OPT_FLAG_TS
@ IPV4_OPT_FLAG_TS
Definition: decode-ipv4.h:161
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
GET_IPV4_SRC_ADDR_PTR
#define GET_IPV4_SRC_ADDR_PTR(p)
Definition: decode.h:221
SCNtohs
#define SCNtohs(x)
Definition: suricata-common.h:395
suricata-common.h
IPV4_OPT_FLAG_RTRALT
@ IPV4_OPT_FLAG_RTRALT
Definition: decode-ipv4.h:168
Packet_::tcph
TCPHdr * tcph
Definition: decode.h:532
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:644
IPV4_HEADER_LEN
#define IPV4_HEADER_LEN
Definition: decode-ipv4.h:28
IPV4Opt_::type
uint8_t type
Definition: decode-ipv4.h:65
IPV4Options
struct IPV4Options_ IPV4Options
IPV4Options_::o_rtralt
IPV4Opt o_rtralt
Definition: decode-ipv4.c:296
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:29
DecodeThreadVars_::counter_ipv4
uint16_t counter_ipv4
Definition: decode.h:650
util-optimize.h
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:146
SCMalloc
#define SCMalloc(sz)
Definition: util-mem.h:47
Packet_::flow_hash
uint32_t flow_hash
Definition: decode.h:456
IPV4_GET_HLEN
#define IPV4_GET_HLEN(p)
Definition: decode-ipv4.h:123
SCFree
#define SCFree(p)
Definition: util-mem.h:61
IPV4_OPT_INVALID
@ IPV4_OPT_INVALID
Definition: decode-events.h:37
IPV4_OPT_SSRR
#define IPV4_OPT_SSRR
Definition: decode-ipv4.h:42
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:634
Packet_::recursion_level
uint8_t recursion_level
Definition: decode.h:440
IPV4_GET_MF
#define IPV4_GET_MF(p)
Definition: decode-ipv4.h:144
IPV4Options_::o_lsrr
IPV4Opt o_lsrr
Definition: decode-ipv4.c:292
ThreadVars_::decode_pq
PacketQueueNoLock decode_pq
Definition: threadvars.h:110
IPV4_OPT_FLAG_SSRR
@ IPV4_OPT_FLAG_SSRR
Definition: decode-ipv4.h:164
DecodeIPV4RegisterTests
void DecodeIPV4RegisterTests(void)
Definition: decode-ipv4.c:1648
Packet_::dst
Address dst
Definition: decode.h:420
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1023
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:39
IPV4Vars_::opts_set
uint16_t opts_set
Definition: decode-ipv4.h:177
PPP_VJ_UCOMP
#define PPP_VJ_UCOMP
Definition: decode-ppp.h:30
PacketTunnelPktSetup
Packet * PacketTunnelPktSetup(ThreadVars *tv, DecodeThreadVars *dtv, Packet *parent, const uint8_t *pkt, uint32_t len, enum DecodeTunnelProto proto)
Setup a pseudo packet (tunnel)
Definition: decode.c:281
SET_IPV4_DST_ADDR
#define SET_IPV4_DST_ADDR(p, a)
Definition: decode.h:154
Defrag
Packet * Defrag(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
Entry point for IPv4 and IPv6 fragments.
Definition: defrag.c:1018
DecodeIPV4
int DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-ipv4.c:517
IPV4_OPT_SID
#define IPV4_OPT_SID
Definition: decode-ipv4.h:41
IPV4Opt_
Definition: decode-ipv4.h:60
IPV4_OPT_FLAG_LSRR
@ IPV4_OPT_FLAG_LSRR
Definition: decode-ipv4.h:163
SCLogDebugEnabled
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition: util-debug.c:662
DecodeEthernet
int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-ethernet.c:41
FlowSetupPacket
void FlowSetupPacket(Packet *p)
prepare packet for a life with flow Set PKT_WANTS_FLOW flag to incidate workers should do a flow look...
Definition: flow-hash.c:431
IPV4_OPT_FLAG_EOL
@ IPV4_OPT_FLAG_EOL
Definition: decode-ipv4.h:158
Packet_::src
Address src
Definition: decode.h:419
PKT_IS_INVALID
#define PKT_IS_INVALID
Definition: decode.h:1137
IPV4Options_::o_ssrr
IPV4Opt o_ssrr
Definition: decode-ipv4.c:295
DefragInit
void DefragInit(void)
Definition: defrag.c:1064
PACKET_RECYCLE
#define PACKET_RECYCLE(p)
Definition: decode.h:836
CLEAR_IPV4_PACKET
#define CLEAR_IPV4_PACKET(p)
Definition: decode-ipv4.h:151
DecodeICMPV4
int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Main ICMPv4 decoding function.
Definition: decode-icmpv4.c:155