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