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