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_ {
297 } 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  p->ip4h = NULL;
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  case IPPROTO_IPV6:
579  {
580  /* spawn off tunnel packet */
581  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
584  if (tp != NULL) {
587  }
588  FlowSetupPacket(p);
589  break;
590  }
591  case IPPROTO_IP:
592  /* check PPP VJ uncompressed packets and decode tcp dummy */
593  if(p->ppph != NULL && SCNtohs(p->ppph->protocol) == PPP_VJ_UCOMP) {
594  DecodeTCP(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
595  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p));
596  }
597  break;
598  case IPPROTO_ICMPV6:
600  break;
601  }
602 
603  return TM_ECODE_OK;
604 }
605 
606 /* UNITTESTS */
607 #ifdef UNITTESTS
608 
609 /** \test IPV4 with no options. */
610 static int DecodeIPV4OptionsNONETest01(void)
611 {
612  uint8_t raw_opts[] = { };
613  Packet *p = PacketGetFromAlloc();
614  FAIL_IF(unlikely(p == NULL));
615 
616  IPV4Options opts;
617  memset(&opts, 0x00, sizeof(opts));
618  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
620 
621  SCFree(p);
622  PASS;
623 }
624 
625 /** \test IPV4 with EOL option. */
626 static int DecodeIPV4OptionsEOLTest01(void)
627 {
628  uint8_t raw_opts[] = {
629  IPV4_OPT_EOL, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
630  };
631  Packet *p = PacketGetFromAlloc();
632  FAIL_IF(unlikely(p == NULL));
633  IPV4Options opts;
634  memset(&opts, 0x00, sizeof(opts));
635  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
637  SCFree(p);
638  PASS;
639 }
640 
641 /** \test IPV4 with NOP option. */
642 static int DecodeIPV4OptionsNOPTest01(void)
643 {
644  uint8_t raw_opts[] = {
645  IPV4_OPT_NOP, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
646  };
647  Packet *p = PacketGetFromAlloc();
648  FAIL_IF(unlikely(p == NULL));
649  IPV4Options opts;
650  memset(&opts, 0x00, sizeof(opts));
651  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
653  SCFree(p);
654  PASS;
655 }
656 
657 /** \test IPV4 with RR option. */
658 static int DecodeIPV4OptionsRRTest01(void)
659 {
660  uint8_t raw_opts[] = {
661  IPV4_OPT_RR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
662  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
663  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
664  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
665  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
666  };
667  Packet *p = PacketGetFromAlloc();
668  FAIL_IF(unlikely(p == NULL));
669 
670  IPV4Options opts;
671  memset(&opts, 0x00, sizeof(opts));
672  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
674  FAIL_IF(opts.o_rr.type != IPV4_OPT_RR);
675  SCFree(p);
676  PASS;
677 }
678 
679 /** \test IPV4 with RR option (len too large). */
680 static int DecodeIPV4OptionsRRTest02(void)
681 {
682  uint8_t raw_opts[] = {
683  IPV4_OPT_RR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
684  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
685  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
686  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
688  };
689  Packet *p = PacketGetFromAlloc();
690  FAIL_IF(unlikely(p == NULL));
691 
692  IPV4Options opts;
693  memset(&opts, 0x00, sizeof(opts));
694  FAIL_IF(DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts) != -1);
695  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
696  FAIL_IF(opts.o_rr.type != 0);
697  SCFree(p);
698  PASS;
699 }
700 
701 /** \test IPV4 with RR option (ptr too large). */
702 static int DecodeIPV4OptionsRRTest03(void)
703 {
704  uint8_t raw_opts[] = {
705  IPV4_OPT_RR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
706  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
707  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
708  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
709  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
710  };
711  Packet *p = PacketGetFromAlloc();
712  FAIL_IF(unlikely(p == NULL));
713 
714  IPV4Options opts;
715  memset(&opts, 0x00, sizeof(opts));
716  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
717  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
718  FAIL_IF(opts.o_rr.type != 0);
719  SCFree(p);
720  PASS;
721 }
722 
723 /** \test IPV4 with RR option (ptr not in 4 byte increment). */
724 static int DecodeIPV4OptionsRRTest04(void)
725 {
726  uint8_t raw_opts[] = {
727  IPV4_OPT_RR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
728  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
729  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
730  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
731  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
732  };
733  Packet *p = PacketGetFromAlloc();
734  FAIL_IF(unlikely(p == NULL));
735 
736  IPV4Options opts;
737  memset(&opts, 0x00, sizeof(opts));
738  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
739  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
740  FAIL_IF(opts.o_rr.type != 0);
741  SCFree(p);
742  PASS;
743 }
744 
745 /** \test IPV4 with QS option. */
746 static int DecodeIPV4OptionsQSTest01(void)
747 {
748  uint8_t raw_opts[] = {
749  IPV4_OPT_QS, 0x08, 0x0d, 0x00, 0xbe, 0xef, 0x00, 0x00
750  };
751  Packet *p = PacketGetFromAlloc();
752  FAIL_IF(unlikely(p == NULL));
753 
754  IPV4Options opts;
755  memset(&opts, 0x00, sizeof(opts));
756  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
758  FAIL_IF(opts.o_qs.type != IPV4_OPT_QS);
759  SCFree(p);
760  PASS;
761 }
762 
763 /** \test IPV4 with QS option (len too small) */
764 static int DecodeIPV4OptionsQSTest02(void)
765 {
766  uint8_t raw_opts[] = {
767  IPV4_OPT_QS, 0x07, 0x0d, 0x00, 0xbe, 0xef, 0x00, 0x00
768  };
769  Packet *p = PacketGetFromAlloc();
770  FAIL_IF(unlikely(p == NULL));
771 
772  IPV4Options opts;
773  memset(&opts, 0x00, sizeof(opts));
774  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
775  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
776  FAIL_IF(opts.o_qs.type != 0);
777  SCFree(p);
778  PASS;
779 }
780 
781 /** \test IPV4 with TS option. */
782 static int DecodeIPV4OptionsTSTest01(void)
783 {
784  uint8_t raw_opts[] = {
785  IPV4_OPT_TS, 0x24, 0x0d, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
786  0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
787  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
788  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
789  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
790  };
791  Packet *p = PacketGetFromAlloc();
792  FAIL_IF(unlikely(p == NULL));
793 
794  IPV4Options opts;
795  memset(&opts, 0x00, sizeof(opts));
796  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
798  FAIL_IF(opts.o_ts.type != IPV4_OPT_TS);
799  SCFree(p);
800  PASS;
801 }
802 
803 /** \test IPV4 with TS option (ptr too small). */
804 static int DecodeIPV4OptionsTSTest02(void)
805 {
806  uint8_t raw_opts[] = {
807  IPV4_OPT_TS, 0x24, 0x04, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
808  0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
809  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
810  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
811  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
812  };
813  Packet *p = PacketGetFromAlloc();
814  FAIL_IF(unlikely(p == NULL));
815 
816  IPV4Options opts;
817  memset(&opts, 0x00, sizeof(opts));
818  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
819  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
820  FAIL_IF(opts.o_ts.type != 0);
821  SCFree(p);
822  PASS;
823 }
824 
825 /** \test IPV4 with TS option (ptr too large). */
826 static int DecodeIPV4OptionsTSTest03(void)
827 {
828  uint8_t raw_opts[] = {
829  IPV4_OPT_TS, 0x24, 0xff, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
830  0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
831  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
832  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
833  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
834  };
835  Packet *p = PacketGetFromAlloc();
836  FAIL_IF(unlikely(p == NULL));
837 
838  IPV4Options opts;
839  memset(&opts, 0x00, sizeof(opts));
840  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
841  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
842  FAIL_IF(opts.o_ts.type != 0);
843  SCFree(p);
844  PASS;
845 }
846 
847 /** \test IPV4 with TS option (ptr not valid). */
848 static int DecodeIPV4OptionsTSTest04(void)
849 {
850  uint8_t raw_opts[] = {
851  IPV4_OPT_TS, 0x24, 0x0a, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
852  0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
853  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
854  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
855  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
856  };
857  Packet *p = PacketGetFromAlloc();
858  FAIL_IF(unlikely(p == NULL));
859 
860  IPV4Options opts;
861  memset(&opts, 0x00, sizeof(opts));
862  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
863  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
864  FAIL_IF(opts.o_ts.type != 0);
865  SCFree(p);
866  PASS;
867 }
868 
869 /** \test IPV4 with SEC option. */
870 static int DecodeIPV4OptionsSECTest01(void)
871 {
872  uint8_t raw_opts[] = {
873  IPV4_OPT_SEC, 0x0b, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00,
874  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
875  };
876  Packet *p = PacketGetFromAlloc();
877  FAIL_IF(unlikely(p == NULL));
878 
879  IPV4Options opts;
880  memset(&opts, 0x00, sizeof(opts));
881  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
883  FAIL_IF(opts.o_sec.type != IPV4_OPT_SEC);
884  SCFree(p);
885  PASS;
886 }
887 
888 /** \test IPV4 with SEC option (invalid length). */
889 static int DecodeIPV4OptionsSECTest02(void)
890 {
891  uint8_t raw_opts[] = {
892  IPV4_OPT_SEC, 0x0a, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00,
893  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
894  };
895  Packet *p = PacketGetFromAlloc();
896  FAIL_IF(unlikely(p == NULL));
897 
898  IPV4Options opts;
899  memset(&opts, 0x00, sizeof(opts));
900  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
901  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
902  FAIL_IF(opts.o_sec.type != 0);
903  SCFree(p);
904  PASS;
905 }
906 
907 /** \test IPV4 with LSRR option. */
908 static int DecodeIPV4OptionsLSRRTest01(void)
909 {
910  uint8_t raw_opts[] = {
911  IPV4_OPT_LSRR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
912  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
913  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
914  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
915  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
916  };
917  Packet *p = PacketGetFromAlloc();
918  FAIL_IF(unlikely(p == NULL));
919 
920  IPV4Options opts;
921  memset(&opts, 0x00, sizeof(opts));
922  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
924  FAIL_IF(opts.o_lsrr.type != IPV4_OPT_LSRR);
925  SCFree(p);
926  PASS;
927 }
928 
929 /** \test IPV4 with LSRR option (len too large). */
930 static int DecodeIPV4OptionsLSRRTest02(void)
931 {
932  uint8_t raw_opts[] = {
933  IPV4_OPT_LSRR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
934  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
935  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
936  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
937  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
938  };
939  Packet *p = PacketGetFromAlloc();
940  FAIL_IF(unlikely(p == NULL));
941 
942  IPV4Options opts;
943  memset(&opts, 0x00, sizeof(opts));
944  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
945  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
946  FAIL_IF(opts.o_lsrr.type != 0);
947  SCFree(p);
948  PASS;
949 }
950 
951 /** \test IPV4 with LSRR option (ptr too large). */
952 static int DecodeIPV4OptionsLSRRTest03(void)
953 {
954  uint8_t raw_opts[] = {
955  IPV4_OPT_LSRR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
956  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
957  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
958  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
959  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
960  };
961  Packet *p = PacketGetFromAlloc();
962  FAIL_IF(unlikely(p == NULL));
963 
964  IPV4Options opts;
965  memset(&opts, 0x00, sizeof(opts));
966  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
967  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
968  FAIL_IF(opts.o_lsrr.type != 0);
969  SCFree(p);
970  PASS;
971 }
972 
973 /** \test IPV4 with LSRR option (ptr not in 4 byte increment). */
974 static int DecodeIPV4OptionsLSRRTest04(void)
975 {
976  uint8_t raw_opts[] = {
977  IPV4_OPT_LSRR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
978  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
979  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
980  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
981  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
982  };
983  Packet *p = PacketGetFromAlloc();
984  FAIL_IF(unlikely(p == NULL));
985 
986  IPV4Options opts;
987  memset(&opts, 0x00, sizeof(opts));
988  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
989  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
990  FAIL_IF(opts.o_lsrr.type != 0);
991  SCFree(p);
992  PASS;
993 }
994 
995 /** \test IPV4 with CIPSO option. */
996 static int DecodeIPV4OptionsCIPSOTest01(void)
997 {
998  uint8_t raw_opts[] = {
999  IPV4_OPT_CIPSO, 0x18, 0x00, 0x00, 0x00, 0x05, 0x05, 0x12,
1000  0x00, 0x03, 0x00, 0xef, 0x00, 0xef, 0x00, 0x06,
1001  0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00
1002  };
1003  Packet *p = PacketGetFromAlloc();
1004  FAIL_IF(unlikely(p == NULL));
1005 
1006  IPV4Options opts;
1007  memset(&opts, 0x00, sizeof(opts));
1008  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1011  SCFree(p);
1012  PASS;
1013 }
1014 
1015 /** \test IPV4 with SID option. */
1016 static int DecodeIPV4OptionsSIDTest01(void)
1017 {
1018  uint8_t raw_opts[] = {
1019  IPV4_OPT_SID, 0x04, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1020  };
1021  Packet *p = PacketGetFromAlloc();
1022  FAIL_IF(unlikely(p == NULL));
1023 
1024  IPV4Options opts;
1025  memset(&opts, 0x00, sizeof(opts));
1026  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1028  FAIL_IF(opts.o_sid.type != IPV4_OPT_SID);
1029  SCFree(p);
1030  PASS;
1031 }
1032 
1033 /** \test IPV4 with SID option (len invalid. */
1034 static int DecodeIPV4OptionsSIDTest02(void)
1035 {
1036  uint8_t raw_opts[] = {
1037  IPV4_OPT_SID, 0x05, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1038  };
1039  Packet *p = PacketGetFromAlloc();
1040  FAIL_IF(unlikely(p == NULL));
1041 
1042  IPV4Options opts;
1043  memset(&opts, 0x00, sizeof(opts));
1044  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1045  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1046  FAIL_IF(opts.o_sid.type != 0);
1047  SCFree(p);
1048  PASS;
1049 }
1050 
1051 /** \test IPV4 with SSRR option. */
1052 static int DecodeIPV4OptionsSSRRTest01(void)
1053 {
1054  uint8_t raw_opts[] = {
1055  IPV4_OPT_SSRR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1056  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1057  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1058  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1059  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1060  };
1061  Packet *p = PacketGetFromAlloc();
1062  FAIL_IF(unlikely(p == NULL));
1063 
1064  IPV4Options opts;
1065  memset(&opts, 0x00, sizeof(opts));
1066  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1068  FAIL_IF(opts.o_ssrr.type != IPV4_OPT_SSRR);
1069  SCFree(p);
1070  PASS;
1071 }
1072 
1073 /** \test IPV4 with SSRR option (len too large). */
1074 static int DecodeIPV4OptionsSSRRTest02(void)
1075 {
1076  uint8_t raw_opts[] = {
1077  IPV4_OPT_SSRR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1078  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1079  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1080  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1081  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1082  };
1083  Packet *p = PacketGetFromAlloc();
1084  FAIL_IF(unlikely(p == NULL));
1085 
1086  IPV4Options opts;
1087  memset(&opts, 0x00, sizeof(opts));
1088  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1089  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1090  FAIL_IF(opts.o_ssrr.type != 0);
1091  SCFree(p);
1092  PASS;
1093 }
1094 
1095 /** \test IPV4 with SSRR option (ptr too large). */
1096 static int DecodeIPV4OptionsSSRRTest03(void)
1097 {
1098  uint8_t raw_opts[] = {
1099  IPV4_OPT_SSRR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1100  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1101  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1102  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1103  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1104  };
1105  Packet *p = PacketGetFromAlloc();
1106  FAIL_IF(unlikely(p == NULL));
1107 
1108  IPV4Options opts;
1109  memset(&opts, 0x00, sizeof(opts));
1110  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1111  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1112  FAIL_IF(opts.o_ssrr.type != 0);
1113  SCFree(p);
1114  PASS;
1115 }
1116 
1117 /** \test IPV4 with SSRR option (ptr not in 4 byte increment). */
1118 static int DecodeIPV4OptionsSSRRTest04(void)
1119 {
1120  uint8_t raw_opts[] = {
1121  IPV4_OPT_SSRR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1122  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1123  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1124  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1125  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1126  };
1127  Packet *p = PacketGetFromAlloc();
1128  FAIL_IF(unlikely(p == NULL));
1129 
1130  IPV4Options opts;
1131  memset(&opts, 0x00, sizeof(opts));
1132  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1133  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1134  FAIL_IF(opts.o_ssrr.type != 0);
1135  SCFree(p);
1136  PASS;
1137 }
1138 
1139 /** \test IPV4 with RTRALT option. */
1140 static int DecodeIPV4OptionsRTRALTTest01(void)
1141 {
1142  uint8_t raw_opts[] = {
1143  IPV4_OPT_RTRALT, 0x04, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1144  };
1145  Packet *p = PacketGetFromAlloc();
1146  FAIL_IF(unlikely(p == NULL));
1147 
1148  IPV4Options opts;
1149  memset(&opts, 0x00, sizeof(opts));
1150  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1153  SCFree(p);
1154  PASS;
1155 }
1156 
1157 /** \test IPV4 with RTRALT option (len invalid. */
1158 static int DecodeIPV4OptionsRTRALTTest02(void)
1159 {
1160  uint8_t raw_opts[] = {
1161  IPV4_OPT_RTRALT, 0x05, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1162  };
1163  Packet *p = PacketGetFromAlloc();
1164  FAIL_IF(unlikely(p == NULL));
1165 
1166  IPV4Options opts;
1167  memset(&opts, 0x00, sizeof(opts));
1168  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1169  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1170  FAIL_IF(opts.o_rtralt.type != 0);
1171  SCFree(p);
1172  PASS;
1173 }
1174 
1175 static int IPV4CalculateValidChecksumtest01(void)
1176 {
1177  uint16_t csum = 0;
1178 
1179  uint8_t raw_ipv4[] = {
1180  0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00,
1181  0x40, 0x01, 0xb7, 0x52, 0xc0, 0xa8, 0x01, 0x03,
1182  0xc0, 0xa8, 0x01, 0x03};
1183 
1184  csum = *( ((uint16_t *)raw_ipv4) + 5);
1185 
1186  FAIL_IF(IPV4Checksum((uint16_t *)raw_ipv4, sizeof(raw_ipv4), csum) != 0);
1187  PASS;
1188 }
1189 
1190 static int IPV4CalculateInvalidChecksumtest02(void)
1191 {
1192  uint16_t csum = 0;
1193 
1194  uint8_t raw_ipv4[] = {
1195  0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00,
1196  0x40, 0x01, 0xb7, 0x52, 0xc0, 0xa8, 0x01, 0x03,
1197  0xc0, 0xa8, 0x01, 0x07};
1198 
1199  csum = *( ((uint16_t *)raw_ipv4) + 5);
1200 
1201  FAIL_IF(IPV4Checksum((uint16_t *)raw_ipv4, sizeof(raw_ipv4), csum) == 0);
1202  PASS;
1203 }
1204 
1205 /**
1206  * \test IPV4 defrag and packet recursion level test
1207  */
1208 static int DecodeIPV4DefragTest01(void)
1209 {
1210  uint8_t pkt1[] = {
1211  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1212  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1213  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1214  0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1215  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1216  0x81, 0x5e
1217  };
1218  uint8_t pkt2[] = {
1219  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1220  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1221  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x01, 0x40, 0x06,
1222  0x9a, 0xc7, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1223  0xe1, 0x0c, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1224  0x80, 0x00
1225  };
1226  uint8_t pkt3[] = {
1227  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1228  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1229  0x00, 0x18, 0xe9, 0xef, 0x00, 0x02, 0x40, 0x06,
1230  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1231  0xe1, 0x0c, 0xb1, 0xa3, 0x00, 0x00
1232  };
1233  uint8_t tunnel_pkt[] = {
1234  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1235  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1236  0x00, 0x28, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1237  0xba, 0xbc, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1238  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1239  0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1240  0x80, 0x00, 0xb1, 0xa3, 0x00, 0x00
1241  };
1242 
1243  Packet *p = PacketGetFromAlloc();
1244  if (unlikely(p == NULL))
1245  return 0;
1246  ThreadVars tv;
1248  int result = 1;
1249 
1250  memset(&tv, 0, sizeof(ThreadVars));
1251  memset(&dtv, 0, sizeof(DecodeThreadVars));
1252 
1254  DefragInit();
1255 
1256  PacketCopyData(p, pkt1, sizeof(pkt1));
1259  if (p->tcph != NULL) {
1260  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1261  result = 0;
1262  goto end;
1263  }
1264  PACKET_RECYCLE(p);
1265 
1266  PacketCopyData(p, pkt2, sizeof(pkt2));
1269  if (p->tcph != NULL) {
1270  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1271  result = 0;
1272  goto end;
1273  }
1274  PACKET_RECYCLE(p);
1275 
1276  PacketCopyData(p, pkt3, sizeof(pkt3));
1279  if (p->tcph != NULL) {
1280  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1281  result = 0;
1282  goto end;
1283  }
1285  if (tp == NULL) {
1286  printf("Failed to get defragged pseudo packet\n");
1287  result = 0;
1288  goto end;
1289  }
1290  if (tp->recursion_level != p->recursion_level) {
1291  printf("defragged pseudo packet's and parent packet's recursion "
1292  "level don't match\n %d != %d",
1294  result = 0;
1295  goto end;
1296  }
1297  if (tp->ip4h == NULL || tp->tcph == NULL) {
1298  printf("pseudo packet's ip header and tcp header shouldn't be NULL, "
1299  "but it is\n");
1300  result = 0;
1301  goto end;
1302  }
1303  if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) {
1304  printf("defragged pseudo packet's and parent packet's pkt lens "
1305  "don't match\n %u != %"PRIuMAX,
1306  GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt));
1307  result = 0;
1308  goto end;
1309  }
1310  if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) {
1311  result = 0;
1312  goto end;
1313  }
1314 
1315  PACKET_RECYCLE(tp);
1316  SCFree(tp);
1317 
1318 end:
1319  DefragDestroy();
1320  PACKET_RECYCLE(p);
1321  FlowShutdown();
1322  SCFree(p);
1323  return result;
1324 }
1325 
1326 /**
1327  * \test Don't send IPv4 fragments to the upper layer decoder and
1328  * and packet recursion level test.
1329  */
1330 static int DecodeIPV4DefragTest02(void)
1331 {
1332  uint8_t pkt1[] = {
1333  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1334  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1335  0x00, 0x24, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1336  0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1337  0xe1, 0x0c,
1338  /* first frag */
1339  0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1340  0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1341  0x80, 0x00,
1342  };
1343  uint8_t pkt2[] = {
1344  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1345  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1346  0x00, 0x2c, 0xe9, 0xef, 0x20, 0x02, 0x40, 0x06,
1347  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1348  0xe1, 0x0c,
1349  /* second frag */
1350  0xb1, 0xa3, 0x00, 0x10, 0x5b, 0xa3, 0x81, 0x5e,
1351  0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1352  0xb1, 0xa3, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04
1353  };
1354  uint8_t pkt3[] = {
1355  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1356  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1357  0x00, 0x16, 0xe9, 0xef, 0x00, 0x05, 0x40, 0x06,
1358  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1359  0xe1, 0x0c,
1360  /* final frag */
1361  0xb1, 0xa3,
1362  };
1363 
1364  uint8_t tunnel_pkt[] = {
1365  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1366  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1367  0x00, 0x3e, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1368  0xba, 0xae, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1369  0xe1, 0x0c,
1370  0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3, 0x81, 0x5e,
1371  0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1372  0xb1, 0xa3, 0x00, 0x10, 0x5b, 0xa3, 0x81, 0x5e,
1373  0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1374  0xb1, 0xa3, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04,
1375  0xb1, 0xa3,
1376  };
1377 
1378  Packet *p = PacketGetFromAlloc();
1379  if (unlikely(p == NULL))
1380  return 0;
1381  ThreadVars tv;
1383  int result = 0;
1384 
1385  memset(&tv, 0, sizeof(ThreadVars));
1386  memset(&dtv, 0, sizeof(DecodeThreadVars));
1387 
1389  DefragInit();
1390 
1391  PacketCopyData(p, pkt1, sizeof(pkt1));
1394  if (p->tcph != NULL) {
1395  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1396  goto end;
1397  }
1398  PACKET_RECYCLE(p);
1399 
1400  PacketCopyData(p, pkt2, sizeof(pkt2));
1403  if (p->tcph != NULL) {
1404  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1405  goto end;
1406  }
1407  PACKET_RECYCLE(p);
1408 
1409  p->recursion_level = 3;
1410  PacketCopyData(p, pkt3, sizeof(pkt3));
1413  if (p->tcph != NULL) {
1414  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1415  goto end;
1416  }
1418  if (tp == NULL) {
1419  printf("Failed to get defragged pseudo packet\n");
1420  goto end;
1421  }
1422  if (tp->recursion_level != p->recursion_level) {
1423  printf("defragged pseudo packet's and parent packet's recursion "
1424  "level don't match %d != %d: ",
1426  goto end;
1427  }
1428  if (tp->ip4h == NULL || tp->tcph == NULL) {
1429  printf("pseudo packet's ip header and tcp header shouldn't be NULL, "
1430  "but it is\n");
1431  goto end;
1432  }
1433  if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) {
1434  printf("defragged pseudo packet's and parent packet's pkt lens "
1435  "don't match %u != %"PRIuMAX": ",
1436  GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt));
1437  goto end;
1438  }
1439 
1440  if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) {
1441  goto end;
1442  }
1443 
1444  result = 1;
1445  PACKET_RECYCLE(tp);
1446  SCFree(tp);
1447 
1448 end:
1449  DefragDestroy();
1450  PACKET_RECYCLE(p);
1451  FlowShutdown();
1452  SCFree(p);
1453  return result;
1454 }
1455 
1456 /**
1457  * \test IPV4 defrag and flow retrieval test.
1458  */
1459 static int DecodeIPV4DefragTest03(void)
1460 {
1461  uint8_t pkt[] = {
1462  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1463  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1464  0x00, 0x28, 0xe9, 0xee, 0x00, 0x00, 0x40, 0x06,
1465  0xba, 0xbd, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1466  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1467  0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02,
1468  0x80, 0x00, 0x0c, 0xee, 0x00, 0x00
1469  };
1470  uint8_t pkt1[] = {
1471  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1472  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1473  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1474  0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1475  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1476  0x81, 0x5e
1477  };
1478  uint8_t pkt2[] = {
1479  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1480  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1481  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x01, 0x40, 0x06,
1482  0x9a, 0xc7, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1483  0xe1, 0x0c, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1484  0x80, 0x00
1485  };
1486  uint8_t pkt3[] = {
1487  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1488  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1489  0x00, 0x18, 0xe9, 0xef, 0x00, 0x02, 0x40, 0x06,
1490  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1491  0xe1, 0x0c, 0xb1, 0xa3, 0x00, 0x00
1492  };
1493  uint8_t tunnel_pkt[] = {
1494  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1495  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1496  0x00, 0x28, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1497  0xba, 0xbc, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1498  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1499  0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1500  0x80, 0x00, 0xb1, 0xa3, 0x00, 0x00
1501  };
1502 
1503  Packet *p = PacketGetFromAlloc();
1504  if (unlikely(p == NULL))
1505  return 0;
1506  ThreadVars tv;
1508  int result = 1;
1509 
1510  memset(&tv, 0, sizeof(ThreadVars));
1511  memset(&dtv, 0, sizeof(DecodeThreadVars));
1512 
1514  DefragInit();
1515 
1516  PacketCopyData(p, pkt, sizeof(pkt));
1519  if (p->tcph == NULL) {
1520  printf("tcp header shouldn't be NULL, but it is\n");
1521  result = 0;
1522  goto end;
1523  }
1524  if (!(p->flags & PKT_WANTS_FLOW)) {
1525  printf("packet flow shouldn't be NULL\n");
1526  result = 0;
1527  goto end;
1528  }
1529  PACKET_RECYCLE(p);
1530 
1531  PacketCopyData(p, pkt1, sizeof(pkt1));
1534  if (p->tcph != NULL) {
1535  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1536  result = 0;
1537  goto end;
1538  }
1539  PACKET_RECYCLE(p);
1540 
1541  PacketCopyData(p, pkt2, sizeof(pkt2));
1544  if (p->tcph != NULL) {
1545  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1546  result = 0;
1547  goto end;
1548  }
1549  PACKET_RECYCLE(p);
1550 
1551  PacketCopyData(p, pkt3, sizeof(pkt3));
1554  if (p->tcph != NULL) {
1555  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1556  result = 0;
1557  goto end;
1558  }
1559 
1561  if (tp == NULL) {
1562  printf("Failed to get defragged pseudo packet\n");
1563  result = 0;
1564  goto end;
1565  }
1566  if (!(tp->flags & PKT_WANTS_FLOW)) {
1567  result = 0;
1568  goto end;
1569  }
1570  if (tp->flow_hash != p->flow_hash) {
1571  result = 0;
1572  goto end;
1573  }
1574  if (tp->recursion_level != p->recursion_level) {
1575  printf("defragged pseudo packet's and parent packet's recursion "
1576  "level don't match\n %d != %d",
1578  result = 0;
1579  goto end;
1580  }
1581  if (tp->ip4h == NULL || tp->tcph == NULL) {
1582  printf("pseudo packet's ip header and tcp header shouldn't be NULL, "
1583  "but it is\n");
1584  result = 0;
1585  goto end;
1586  }
1587  if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) {
1588  printf("defragged pseudo packet's and parent packet's pkt lens "
1589  "don't match\n %u != %"PRIuMAX,
1590  GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt));
1591  result = 0;
1592  goto end;
1593  }
1594 
1595  if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) {
1596  result = 0;
1597  goto end;
1598  }
1599 
1600  PACKET_RECYCLE(tp);
1601  SCFree(tp);
1602 
1603 end:
1604  DefragDestroy();
1605  PACKET_RECYCLE(p);
1606  FlowShutdown();
1607  SCFree(p);
1608  return result;
1609 }
1610 
1611 /**
1612  */
1613 static int DecodeEthernetTestIPv4Opt(void)
1614 {
1615  uint8_t raw_eth[] = {
1616  0xae, 0x71, 0x00, 0x00, 0x00, 0x4b, 0x06, 0x90, 0x61, 0x02, 0x00, 0xcd, 0x88, 0x64, 0x11, 0x00,
1617  0x15, 0x00, 0x80, 0x64, 0x00, 0x21, 0x4c, 0x00, 0x00, 0x30, 0x42, 0xd6, 0xff, 0xff, 0xbd, 0x2f,
1618  0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1619  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1620  0x01, 0x44, 0x05, 0x22, 0x02, 0x01
1621  };
1622 
1623  DefragInit();
1624 
1626  FAIL_IF_NULL(p);
1627  ThreadVars tv;
1629 
1630  memset(&dtv, 0, sizeof(DecodeThreadVars));
1631  memset(&tv, 0, sizeof(ThreadVars));
1632  memset(p, 0, SIZE_OF_PACKET);
1633 
1634  DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth));
1635 
1636  SCFree(p);
1637  DefragDestroy();
1638  PASS;
1639 }
1640 
1641 #endif /* UNITTESTS */
1642 
1644 {
1645 #ifdef UNITTESTS
1646  UtRegisterTest("DecodeIPV4OptionsNONETest01", DecodeIPV4OptionsNONETest01);
1647  UtRegisterTest("DecodeIPV4OptionsEOLTest01", DecodeIPV4OptionsEOLTest01);
1648  UtRegisterTest("DecodeIPV4OptionsNOPTest01", DecodeIPV4OptionsNOPTest01);
1649  UtRegisterTest("DecodeIPV4OptionsRRTest01", DecodeIPV4OptionsRRTest01);
1650  UtRegisterTest("DecodeIPV4OptionsRRTest02", DecodeIPV4OptionsRRTest02);
1651  UtRegisterTest("DecodeIPV4OptionsRRTest03", DecodeIPV4OptionsRRTest03);
1652  UtRegisterTest("DecodeIPV4OptionsRRTest04", DecodeIPV4OptionsRRTest04);
1653  UtRegisterTest("DecodeIPV4OptionsQSTest01", DecodeIPV4OptionsQSTest01);
1654  UtRegisterTest("DecodeIPV4OptionsQSTest02", DecodeIPV4OptionsQSTest02);
1655  UtRegisterTest("DecodeIPV4OptionsTSTest01", DecodeIPV4OptionsTSTest01);
1656  UtRegisterTest("DecodeIPV4OptionsTSTest02", DecodeIPV4OptionsTSTest02);
1657  UtRegisterTest("DecodeIPV4OptionsTSTest03", DecodeIPV4OptionsTSTest03);
1658  UtRegisterTest("DecodeIPV4OptionsTSTest04", DecodeIPV4OptionsTSTest04);
1659  UtRegisterTest("DecodeIPV4OptionsSECTest01", DecodeIPV4OptionsSECTest01);
1660  UtRegisterTest("DecodeIPV4OptionsSECTest02", DecodeIPV4OptionsSECTest02);
1661  UtRegisterTest("DecodeIPV4OptionsLSRRTest01", DecodeIPV4OptionsLSRRTest01);
1662  UtRegisterTest("DecodeIPV4OptionsLSRRTest02", DecodeIPV4OptionsLSRRTest02);
1663  UtRegisterTest("DecodeIPV4OptionsLSRRTest03", DecodeIPV4OptionsLSRRTest03);
1664  UtRegisterTest("DecodeIPV4OptionsLSRRTest04", DecodeIPV4OptionsLSRRTest04);
1665  UtRegisterTest("DecodeIPV4OptionsCIPSOTest01",
1666  DecodeIPV4OptionsCIPSOTest01);
1667  UtRegisterTest("DecodeIPV4OptionsSIDTest01", DecodeIPV4OptionsSIDTest01);
1668  UtRegisterTest("DecodeIPV4OptionsSIDTest02", DecodeIPV4OptionsSIDTest02);
1669  UtRegisterTest("DecodeIPV4OptionsSSRRTest01", DecodeIPV4OptionsSSRRTest01);
1670  UtRegisterTest("DecodeIPV4OptionsSSRRTest02", DecodeIPV4OptionsSSRRTest02);
1671  UtRegisterTest("DecodeIPV4OptionsSSRRTest03", DecodeIPV4OptionsSSRRTest03);
1672  UtRegisterTest("DecodeIPV4OptionsSSRRTest04", DecodeIPV4OptionsSSRRTest04);
1673  UtRegisterTest("DecodeIPV4OptionsRTRALTTest01",
1674  DecodeIPV4OptionsRTRALTTest01);
1675  UtRegisterTest("DecodeIPV4OptionsRTRALTTest02",
1676  DecodeIPV4OptionsRTRALTTest02);
1677  UtRegisterTest("IPV4CalculateValidChecksumtest01",
1678  IPV4CalculateValidChecksumtest01);
1679  UtRegisterTest("IPV4CalculateInvalidChecksumtest02",
1680  IPV4CalculateInvalidChecksumtest02);
1681  UtRegisterTest("DecodeIPV4DefragTest01", DecodeIPV4DefragTest01);
1682  UtRegisterTest("DecodeIPV4DefragTest02", DecodeIPV4DefragTest02);
1683  UtRegisterTest("DecodeIPV4DefragTest03", DecodeIPV4DefragTest03);
1684  UtRegisterTest("DecodeEthernetTestIPv4Opt", DecodeEthernetTestIPv4Opt);
1685 #endif /* UNITTESTS */
1686 }
1687 /**
1688  * @}
1689  */
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:976
DefragDestroy
void DefragDestroy(void)
Definition: defrag.c:1090
host.h
IPV4Options_::o_sid
IPV4Opt o_sid
Definition: decode-ipv4.c:294
Packet_::proto
uint8_t proto
Definition: decode.h:431
IPV4Options_::o_qs
IPV4Opt o_qs
Definition: decode-ipv4.c:289
len
uint8_t len
Definition: app-layer-dnp3.h:4
DECODE_TUNNEL_IPV6
@ DECODE_TUNNEL_IPV6
Definition: decode.h:885
IPV4_IPLEN_SMALLER_THAN_HLEN
@ IPV4_IPLEN_SMALLER_THAN_HLEN
Definition: decode-events.h:33
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:168
IPV4_OPT_QS_MIN
#define IPV4_OPT_QS_MIN
Definition: decode-ipv4.h:52
offset
uint64_t offset
Definition: util-streaming-buffer.h:2
DecodeUDP
int DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-udp.c:74
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:262
IPV4_GET_IPOFFSET
#define IPV4_GET_IPOFFSET(p)
Definition: decode-ipv4.h:135
SCFree
#define SCFree(a)
Definition: util-mem.h:322
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
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:335
PKT_SRC_DECODER_IPV4
@ PKT_SRC_DECODER_IPV4
Definition: decode.h:51
IPV4Options_::o_ts
IPV4Opt o_ts
Definition: decode-ipv4.c:290
Packet_::flags
uint32_t flags
Definition: decode.h:444
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:530
IPV4_OPT_LSRR
#define IPV4_OPT_LSRR
Definition: decode-ipv4.h:39
IPV4_OPT_MALFORMED
@ IPV4_OPT_MALFORMED
Definition: decode-events.h:39
PKT_WANTS_FLOW
#define PKT_WANTS_FLOW
Definition: decode.h:1098
IPV4Options_::o_sec
IPV4Opt o_sec
Definition: decode-ipv4.c:291
Packet_::ip4vars
IPV4Vars ip4vars
Definition: decode.h:507
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:250
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
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:79
IPV4Opt_::len
uint8_t len
Definition: decode-ipv4.h:66
IPV4_OPT_QS
#define IPV4_OPT_QS
Definition: decode-ipv4.h:36
util-unittest.h
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:78
SET_IPV4_SRC_ADDR
#define SET_IPV4_SRC_ADDR(p, a)
Definition: decode.h:139
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:1118
IPV4Vars_::opt_cnt
uint16_t opt_cnt
Definition: decode-ipv4.h:176
IPV4_OPT_UNKNOWN
@ IPV4_OPT_UNKNOWN
Definition: decode-events.h:43
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:216
IPV4_OPT_FLAG_SID
@ IPV4_OPT_FLAG_SID
Definition: decode-ipv4.h:165
PacketDequeueNoLock
Packet * PacketDequeueNoLock(PacketQueueNoLock *qnl)
Definition: packet-queue.c:206
PKT_IS_FRAGMENT
#define PKT_IS_FRAGMENT
Definition: decode.h:1092
IPV4_OPT_INVALID
@ IPV4_OPT_INVALID
Definition: decode-events.h:37
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:226
IPV4_OPT_FLAG_QS
@ IPV4_OPT_FLAG_QS
Definition: decode-ipv4.h:162
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
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:267
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_OPT_RR
#define IPV4_OPT_RR
Definition: decode-ipv4.h:35
SIZE_OF_PACKET
#define SIZE_OF_PACKET
Definition: decode.h:619
IPV4_GET_IPID
#define IPV4_GET_IPID(p)
Definition: decode-ipv4.h:129
SCMalloc
#define SCMalloc(a)
Definition: util-mem.h:222
util-profiling.h
IPV4_WITH_ICMPV6
@ IPV4_WITH_ICMPV6
Definition: decode-events.h:45
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:408
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:225
ETHERNET_HEADER_LEN
#define ETHERNET_HEADER_LEN
Definition: decode-ethernet.h:27
Packet_::ip4h
IPV4Hdr * ip4h
Definition: decode.h:501
IPV4_PKT_TOO_SMALL
@ IPV4_PKT_TOO_SMALL
Definition: decode-events.h:31
IPV4_OPT_RTRALT
#define IPV4_OPT_RTRALT
Definition: decode-ipv4.h:43
defrag.h
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:33
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:234
IPV4Hdr_
Definition: decode-ipv4.h:70
decode-ipv4.h
Packet_::ppph
PPPHdr * ppph
Definition: decode.h:533
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
IPV4_OPT_DUPLICATE
@ IPV4_OPT_DUPLICATE
Definition: decode-events.h:42
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:215
SCNtohs
#define SCNtohs(x)
Definition: suricata-common.h:375
suricata-common.h
IPV4_OPT_FLAG_RTRALT
@ IPV4_OPT_FLAG_RTRALT
Definition: decode-ipv4.h:168
Packet_::tcph
TCPHdr * tcph
Definition: decode.h:523
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:685
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:32
DecodeThreadVars_::counter_ipv4
uint16_t counter_ipv4
Definition: decode.h:636
util-optimize.h
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:144
Packet_::flow_hash
uint32_t flow_hash
Definition: decode.h:450
IPV4_OPT_PAD_REQUIRED
@ IPV4_OPT_PAD_REQUIRED
Definition: decode-events.h:40
IPV4_GET_HLEN
#define IPV4_GET_HLEN(p)
Definition: decode-ipv4.h:123
IPV4_HLEN_TOO_SMALL
@ IPV4_HLEN_TOO_SMALL
Definition: decode-events.h:32
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:622
Packet_::recursion_level
uint8_t recursion_level
Definition: decode.h:434
IPV4_GET_MF
#define IPV4_GET_MF(p)
Definition: decode-ipv4.h:144
IPV4Options_::o_lsrr
IPV4Opt o_lsrr
Definition: decode-ipv4.c:292
IPV4_TRUNC_PKT
@ IPV4_TRUNC_PKT
Definition: decode-events.h:34
IPV4_WRONG_IP_VER
@ IPV4_WRONG_IP_VER
Definition: decode-events.h:44
ThreadVars_::decode_pq
PacketQueueNoLock decode_pq
Definition: threadvars.h:109
IPV4_OPT_FLAG_SSRR
@ IPV4_OPT_FLAG_SSRR
Definition: decode-ipv4.h:164
DecodeIPV4RegisterTests
void DecodeIPV4RegisterTests(void)
Definition: decode-ipv4.c:1643
Packet_::dst
Address dst
Definition: decode.h:414
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:984
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:38
IPV4Vars_::opts_set
uint16_t opts_set
Definition: decode-ipv4.h:177
PPP_VJ_UCOMP
#define PPP_VJ_UCOMP
Definition: decode-ppp.h:30
IPV4_OPT_EOL_REQUIRED
@ IPV4_OPT_EOL_REQUIRED
Definition: decode-events.h:41
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:278
SET_IPV4_DST_ADDR
#define SET_IPV4_DST_ADDR(p, a)
Definition: decode.h:147
Defrag
Packet * Defrag(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
Entry point for IPv4 and IPv6 fragments.
Definition: defrag.c:1022
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:624
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:408
IPV4_OPT_FLAG_EOL
@ IPV4_OPT_FLAG_EOL
Definition: decode-ipv4.h:158
Packet_::src
Address src
Definition: decode.h:413
PKT_IS_INVALID
#define PKT_IS_INVALID
Definition: decode.h:1093
IPV4Options_::o_ssrr
IPV4Opt o_ssrr
Definition: decode-ipv4.c:295
IPV4_OPT_INVALID_LEN
@ IPV4_OPT_INVALID_LEN
Definition: decode-events.h:38
DefragInit
void DefragInit(void)
Definition: defrag.c:1068
PACKET_RECYCLE
#define PACKET_RECYCLE(p)
Definition: decode.h:804
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