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 void 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;
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;
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  break;
378  } else if (IPV4OptValidateTimestamp(p, &opt)) {
379  return;
380  }
381  opts->o_ts = opt;
383  break;
384  case IPV4_OPT_RR:
385  if (opts->o_rr.type != 0) {
387  /* Warn - we can keep going */
388  break;
389  } else if (IPV4OptValidateRoute(p, &opt) != 0) {
390  return;
391  }
392  opts->o_rr = opt;
394  break;
395  case IPV4_OPT_QS:
396  if (opts->o_qs.type != 0) {
398  /* Warn - we can keep going */
399  break;
400  } else if (IPV4OptValidateGeneric(p, &opt)) {
401  return;
402  }
403  opts->o_qs = opt;
405  break;
406  case IPV4_OPT_SEC:
407  if (opts->o_sec.type != 0) {
409  /* Warn - we can keep going */
410  break;
411  } else if (IPV4OptValidateGeneric(p, &opt)) {
412  return;
413  }
414  opts->o_sec = opt;
416  break;
417  case IPV4_OPT_LSRR:
418  if (opts->o_lsrr.type != 0) {
420  /* Warn - we can keep going */
421  break;
422  } else if (IPV4OptValidateRoute(p, &opt) != 0) {
423  return;
424  }
425  opts->o_lsrr = opt;
427  break;
428  case IPV4_OPT_CIPSO:
429  if (opts->o_cipso.type != 0) {
431  /* Warn - we can keep going */
432  break;
433  } else if (IPV4OptValidateCIPSO(p, &opt) != 0) {
434  return;
435  }
436  opts->o_cipso = opt;
438  break;
439  case IPV4_OPT_SID:
440  if (opts->o_sid.type != 0) {
442  /* Warn - we can keep going */
443  break;
444  } else if (IPV4OptValidateGeneric(p, &opt)) {
445  return;
446  }
447  opts->o_sid = opt;
449  break;
450  case IPV4_OPT_SSRR:
451  if (opts->o_ssrr.type != 0) {
453  /* Warn - we can keep going */
454  break;
455  } else if (IPV4OptValidateRoute(p, &opt) != 0) {
456  return;
457  }
458  opts->o_ssrr = opt;
460  break;
461  case IPV4_OPT_RTRALT:
462  if (opts->o_rtralt.type != 0) {
464  /* Warn - we can keep going */
465  break;
466  } else if (IPV4OptValidateGeneric(p, &opt)) {
467  return;
468  }
469  opts->o_rtralt = opt;
471  break;
472  default:
473  SCLogDebug("IPV4OPT <unknown> (%" PRIu8 ") len %" PRIu8,
474  opt.type, opt.len);
476  /* Warn - we can keep going */
477  break;
478  }
479 
480  pkt += opt.len;
481  plen -= opt.len;
482  }
483  }
484 
485 }
486 
487 static int DecodeIPV4Packet(Packet *p, const uint8_t *pkt, uint16_t len)
488 {
489  if (unlikely(len < IPV4_HEADER_LEN)) {
491  return -1;
492  }
493 
494  if (unlikely(IP_GET_RAW_VER(pkt) != 4)) {
495  SCLogDebug("wrong ip version %d",IP_GET_RAW_VER(pkt));
497  return -1;
498  }
499 
500  p->ip4h = (IPV4Hdr *)pkt;
501 
504  return -1;
505  }
506 
507  if (unlikely(IPV4_GET_IPLEN(p) < IPV4_GET_HLEN(p))) {
509  return -1;
510  }
511 
512  if (unlikely(len < IPV4_GET_IPLEN(p))) {
514  return -1;
515  }
516 
517  /* set the address struct */
518  SET_IPV4_SRC_ADDR(p,&p->src);
519  SET_IPV4_DST_ADDR(p,&p->dst);
520 
521  /* save the options len */
522  uint8_t ip_opt_len = IPV4_GET_HLEN(p) - IPV4_HEADER_LEN;
523  if (ip_opt_len > 0) {
524  IPV4Options opts;
525  memset(&opts, 0x00, sizeof(opts));
526  DecodeIPV4Options(p, pkt + IPV4_HEADER_LEN, ip_opt_len, &opts);
527  }
528 
529  return 0;
530 }
531 
533  const uint8_t *pkt, uint16_t len, PacketQueue *pq)
534 {
535  StatsIncr(tv, dtv->counter_ipv4);
536 
537  SCLogDebug("pkt %p len %"PRIu16"", pkt, len);
538 
539  /* do the actual decoding */
540  if (unlikely(DecodeIPV4Packet (p, pkt, len) < 0)) {
541  SCLogDebug("decoding IPv4 packet failed");
542  p->ip4h = NULL;
543  return TM_ECODE_FAILED;
544  }
545  p->proto = IPV4_GET_IPPROTO(p);
546 
547  /* If a fragment, pass off for re-assembly. */
548  if (unlikely(IPV4_GET_IPOFFSET(p) > 0 || IPV4_GET_MF(p) == 1)) {
549  Packet *rp = Defrag(tv, dtv, p, pq);
550  if (rp != NULL) {
551  PacketEnqueue(pq, rp);
552  }
553  p->flags |= PKT_IS_FRAGMENT;
554  return TM_ECODE_OK;
555  }
556 
557  /* do hdr test, process hdr rules */
558 
559 #ifdef DEBUG
560  if (SCLogDebugEnabled()) { /* only convert the addresses if debug is really enabled */
561  /* debug print */
562  char s[16], d[16];
563  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), s, sizeof(s));
564  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), d, sizeof(d));
565  SCLogDebug("IPV4 %s->%s PROTO: %" PRIu32 " OFFSET: %" PRIu32 " RF: %" PRIu32 " DF: %" PRIu32 " MF: %" PRIu32 " ID: %" PRIu32 "", s,d,
568  }
569 #endif /* DEBUG */
570 
571  /* check what next decoder to invoke */
572  switch (IPV4_GET_IPPROTO(p)) {
573  case IPPROTO_TCP:
574  DecodeTCP(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
575  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq);
576  break;
577  case IPPROTO_UDP:
578  DecodeUDP(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
579  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq);
580  break;
581  case IPPROTO_ICMP:
582  DecodeICMPV4(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
583  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq);
584  break;
585  case IPPROTO_GRE:
586  DecodeGRE(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
587  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq);
588  break;
589  case IPPROTO_SCTP:
590  DecodeSCTP(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
591  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq);
592  break;
593  case IPPROTO_IPV6:
594  {
595  if (pq != NULL) {
596  /* spawn off tunnel packet */
597  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
599  DECODE_TUNNEL_IPV6, pq);
600  if (tp != NULL) {
602  PacketEnqueue(pq,tp);
603  }
604  FlowSetupPacket(p);
605  }
606  break;
607  }
608  case IPPROTO_IP:
609  /* check PPP VJ uncompressed packets and decode tcp dummy */
610  if(p->ppph != NULL && SCNtohs(p->ppph->protocol) == PPP_VJ_UCOMP) {
611  DecodeTCP(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
612  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq);
613  }
614  break;
615  case IPPROTO_ICMPV6:
617  break;
618  }
619 
620  return TM_ECODE_OK;
621 }
622 
623 /* UNITTESTS */
624 #ifdef UNITTESTS
625 
626 /** \test IPV4 with no options. */
627 static int DecodeIPV4OptionsNONETest01(void)
628 {
629  uint8_t raw_opts[] = { };
630  Packet *p = PacketGetFromAlloc();
631  FAIL_IF(unlikely(p == NULL));
632 
633  IPV4Options opts;
634  memset(&opts, 0x00, sizeof(opts));
635  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
637 
638  SCFree(p);
639  PASS;
640 }
641 
642 /** \test IPV4 with EOL option. */
643 static int DecodeIPV4OptionsEOLTest01(void)
644 {
645  uint8_t raw_opts[] = {
646  IPV4_OPT_EOL, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
647  };
648  Packet *p = PacketGetFromAlloc();
649  FAIL_IF(unlikely(p == NULL));
650  IPV4Options opts;
651  memset(&opts, 0x00, sizeof(opts));
652  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
654  SCFree(p);
655  PASS;
656 }
657 
658 /** \test IPV4 with NOP option. */
659 static int DecodeIPV4OptionsNOPTest01(void)
660 {
661  uint8_t raw_opts[] = {
662  IPV4_OPT_NOP, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
663  };
664  Packet *p = PacketGetFromAlloc();
665  FAIL_IF(unlikely(p == NULL));
666  IPV4Options opts;
667  memset(&opts, 0x00, sizeof(opts));
668  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
670  SCFree(p);
671  PASS;
672 }
673 
674 /** \test IPV4 with RR option. */
675 static int DecodeIPV4OptionsRRTest01(void)
676 {
677  uint8_t raw_opts[] = {
678  IPV4_OPT_RR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
679  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
680  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
681  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
682  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
683  };
684  Packet *p = PacketGetFromAlloc();
685  FAIL_IF(unlikely(p == NULL));
686 
687  IPV4Options opts;
688  memset(&opts, 0x00, sizeof(opts));
689  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
691  FAIL_IF(opts.o_rr.type != IPV4_OPT_RR);
692  SCFree(p);
693  PASS;
694 }
695 
696 /** \test IPV4 with RR option (len too large). */
697 static int DecodeIPV4OptionsRRTest02(void)
698 {
699  uint8_t raw_opts[] = {
700  IPV4_OPT_RR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
701  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
702  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
703  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
704  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
705  };
706  Packet *p = PacketGetFromAlloc();
707  FAIL_IF(unlikely(p == NULL));
708 
709  IPV4Options opts;
710  memset(&opts, 0x00, sizeof(opts));
711  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
712  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
713  FAIL_IF(opts.o_rr.type != 0);
714  SCFree(p);
715  PASS;
716 }
717 
718 /** \test IPV4 with RR option (ptr too large). */
719 static int DecodeIPV4OptionsRRTest03(void)
720 {
721  uint8_t raw_opts[] = {
722  IPV4_OPT_RR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
723  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
725  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
726  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
727  };
728  Packet *p = PacketGetFromAlloc();
729  FAIL_IF(unlikely(p == NULL));
730 
731  IPV4Options opts;
732  memset(&opts, 0x00, sizeof(opts));
733  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
734  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
735  FAIL_IF(opts.o_rr.type != 0);
736  SCFree(p);
737  PASS;
738 }
739 
740 /** \test IPV4 with RR option (ptr not in 4 byte increment). */
741 static int DecodeIPV4OptionsRRTest04(void)
742 {
743  uint8_t raw_opts[] = {
744  IPV4_OPT_RR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
745  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
746  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
747  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
748  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
749  };
750  Packet *p = PacketGetFromAlloc();
751  FAIL_IF(unlikely(p == NULL));
752 
753  IPV4Options opts;
754  memset(&opts, 0x00, sizeof(opts));
755  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
756  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
757  FAIL_IF(opts.o_rr.type != 0);
758  SCFree(p);
759  PASS;
760 }
761 
762 /** \test IPV4 with QS option. */
763 static int DecodeIPV4OptionsQSTest01(void)
764 {
765  uint8_t raw_opts[] = {
766  IPV4_OPT_QS, 0x08, 0x0d, 0x00, 0xbe, 0xef, 0x00, 0x00
767  };
768  Packet *p = PacketGetFromAlloc();
769  FAIL_IF(unlikely(p == NULL));
770 
771  IPV4Options opts;
772  memset(&opts, 0x00, sizeof(opts));
773  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
775  FAIL_IF(opts.o_qs.type != IPV4_OPT_QS);
776  SCFree(p);
777  PASS;
778 }
779 
780 /** \test IPV4 with QS option (len too small) */
781 static int DecodeIPV4OptionsQSTest02(void)
782 {
783  uint8_t raw_opts[] = {
784  IPV4_OPT_QS, 0x07, 0x0d, 0x00, 0xbe, 0xef, 0x00, 0x00
785  };
786  Packet *p = PacketGetFromAlloc();
787  FAIL_IF(unlikely(p == NULL));
788 
789  IPV4Options opts;
790  memset(&opts, 0x00, sizeof(opts));
791  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
792  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
793  FAIL_IF(opts.o_qs.type != 0);
794  SCFree(p);
795  PASS;
796 }
797 
798 /** \test IPV4 with TS option. */
799 static int DecodeIPV4OptionsTSTest01(void)
800 {
801  uint8_t raw_opts[] = {
802  IPV4_OPT_TS, 0x24, 0x0d, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
803  0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
804  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
805  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
806  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
807  };
808  Packet *p = PacketGetFromAlloc();
809  FAIL_IF(unlikely(p == NULL));
810 
811  IPV4Options opts;
812  memset(&opts, 0x00, sizeof(opts));
813  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
815  FAIL_IF(opts.o_ts.type != IPV4_OPT_TS);
816  SCFree(p);
817  PASS;
818 }
819 
820 /** \test IPV4 with TS option (ptr too small). */
821 static int DecodeIPV4OptionsTSTest02(void)
822 {
823  uint8_t raw_opts[] = {
824  IPV4_OPT_TS, 0x24, 0x04, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
825  0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
826  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
827  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
828  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
829  };
830  Packet *p = PacketGetFromAlloc();
831  FAIL_IF(unlikely(p == NULL));
832 
833  IPV4Options opts;
834  memset(&opts, 0x00, sizeof(opts));
835  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
836  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
837  FAIL_IF(opts.o_ts.type != 0);
838  SCFree(p);
839  PASS;
840 }
841 
842 /** \test IPV4 with TS option (ptr too large). */
843 static int DecodeIPV4OptionsTSTest03(void)
844 {
845  uint8_t raw_opts[] = {
846  IPV4_OPT_TS, 0x24, 0xff, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
847  0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
848  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
849  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
850  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
851  };
852  Packet *p = PacketGetFromAlloc();
853  FAIL_IF(unlikely(p == NULL));
854 
855  IPV4Options opts;
856  memset(&opts, 0x00, sizeof(opts));
857  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
858  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
859  FAIL_IF(opts.o_ts.type != 0);
860  SCFree(p);
861  PASS;
862 }
863 
864 /** \test IPV4 with TS option (ptr not valid). */
865 static int DecodeIPV4OptionsTSTest04(void)
866 {
867  uint8_t raw_opts[] = {
868  IPV4_OPT_TS, 0x24, 0x0a, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
869  0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
870  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
871  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
872  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
873  };
874  Packet *p = PacketGetFromAlloc();
875  FAIL_IF(unlikely(p == NULL));
876 
877  IPV4Options opts;
878  memset(&opts, 0x00, sizeof(opts));
879  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
880  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
881  FAIL_IF(opts.o_ts.type != 0);
882  SCFree(p);
883  PASS;
884 }
885 
886 /** \test IPV4 with SEC option. */
887 static int DecodeIPV4OptionsSECTest01(void)
888 {
889  uint8_t raw_opts[] = {
890  IPV4_OPT_SEC, 0x0b, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00,
891  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
892  };
893  Packet *p = PacketGetFromAlloc();
894  FAIL_IF(unlikely(p == NULL));
895 
896  IPV4Options opts;
897  memset(&opts, 0x00, sizeof(opts));
898  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
900  FAIL_IF(opts.o_sec.type != IPV4_OPT_SEC);
901  SCFree(p);
902  PASS;
903 }
904 
905 /** \test IPV4 with SEC option (invalid length). */
906 static int DecodeIPV4OptionsSECTest02(void)
907 {
908  uint8_t raw_opts[] = {
909  IPV4_OPT_SEC, 0x0a, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00,
910  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
911  };
912  Packet *p = PacketGetFromAlloc();
913  FAIL_IF(unlikely(p == NULL));
914 
915  IPV4Options opts;
916  memset(&opts, 0x00, sizeof(opts));
917  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
918  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
919  FAIL_IF(opts.o_sec.type != 0);
920  SCFree(p);
921  PASS;
922 }
923 
924 /** \test IPV4 with LSRR option. */
925 static int DecodeIPV4OptionsLSRRTest01(void)
926 {
927  uint8_t raw_opts[] = {
928  IPV4_OPT_LSRR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
929  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
930  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
931  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
932  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
933  };
934  Packet *p = PacketGetFromAlloc();
935  FAIL_IF(unlikely(p == NULL));
936 
937  IPV4Options opts;
938  memset(&opts, 0x00, sizeof(opts));
939  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
941  FAIL_IF(opts.o_lsrr.type != IPV4_OPT_LSRR);
942  SCFree(p);
943  PASS;
944 }
945 
946 /** \test IPV4 with LSRR option (len too large). */
947 static int DecodeIPV4OptionsLSRRTest02(void)
948 {
949  uint8_t raw_opts[] = {
950  IPV4_OPT_LSRR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
951  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
952  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
953  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
954  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
955  };
956  Packet *p = PacketGetFromAlloc();
957  FAIL_IF(unlikely(p == NULL));
958 
959  IPV4Options opts;
960  memset(&opts, 0x00, sizeof(opts));
961  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
962  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
963  FAIL_IF(opts.o_lsrr.type != 0);
964  SCFree(p);
965  PASS;
966 }
967 
968 /** \test IPV4 with LSRR option (ptr too large). */
969 static int DecodeIPV4OptionsLSRRTest03(void)
970 {
971  uint8_t raw_opts[] = {
972  IPV4_OPT_LSRR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
973  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
974  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
975  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
976  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
977  };
978  Packet *p = PacketGetFromAlloc();
979  FAIL_IF(unlikely(p == NULL));
980 
981  IPV4Options opts;
982  memset(&opts, 0x00, sizeof(opts));
983  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
984  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
985  FAIL_IF(opts.o_lsrr.type != 0);
986  SCFree(p);
987  PASS;
988 }
989 
990 /** \test IPV4 with LSRR option (ptr not in 4 byte increment). */
991 static int DecodeIPV4OptionsLSRRTest04(void)
992 {
993  uint8_t raw_opts[] = {
994  IPV4_OPT_LSRR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
995  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
996  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
997  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
998  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
999  };
1000  Packet *p = PacketGetFromAlloc();
1001  FAIL_IF(unlikely(p == NULL));
1002 
1003  IPV4Options opts;
1004  memset(&opts, 0x00, sizeof(opts));
1005  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1006  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1007  FAIL_IF(opts.o_lsrr.type != 0);
1008  SCFree(p);
1009  PASS;
1010 }
1011 
1012 /** \test IPV4 with CIPSO option. */
1013 static int DecodeIPV4OptionsCIPSOTest01(void)
1014 {
1015  uint8_t raw_opts[] = {
1016  IPV4_OPT_CIPSO, 0x18, 0x00, 0x00, 0x00, 0x05, 0x05, 0x12,
1017  0x00, 0x03, 0x00, 0xef, 0x00, 0xef, 0x00, 0x06,
1018  0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00
1019  };
1020  Packet *p = PacketGetFromAlloc();
1021  FAIL_IF(unlikely(p == NULL));
1022 
1023  IPV4Options opts;
1024  memset(&opts, 0x00, sizeof(opts));
1025  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1028  SCFree(p);
1029  PASS;
1030 }
1031 
1032 /** \test IPV4 with SID option. */
1033 static int DecodeIPV4OptionsSIDTest01(void)
1034 {
1035  uint8_t raw_opts[] = {
1036  IPV4_OPT_SID, 0x04, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1037  };
1038  Packet *p = PacketGetFromAlloc();
1039  FAIL_IF(unlikely(p == NULL));
1040 
1041  IPV4Options opts;
1042  memset(&opts, 0x00, sizeof(opts));
1043  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1045  FAIL_IF(opts.o_sid.type != IPV4_OPT_SID);
1046  SCFree(p);
1047  PASS;
1048 }
1049 
1050 /** \test IPV4 with SID option (len invalid. */
1051 static int DecodeIPV4OptionsSIDTest02(void)
1052 {
1053  uint8_t raw_opts[] = {
1054  IPV4_OPT_SID, 0x05, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1055  };
1056  Packet *p = PacketGetFromAlloc();
1057  FAIL_IF(unlikely(p == NULL));
1058 
1059  IPV4Options opts;
1060  memset(&opts, 0x00, sizeof(opts));
1061  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1062  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1063  FAIL_IF(opts.o_sid.type != 0);
1064  SCFree(p);
1065  PASS;
1066 }
1067 
1068 /** \test IPV4 with SSRR option. */
1069 static int DecodeIPV4OptionsSSRRTest01(void)
1070 {
1071  uint8_t raw_opts[] = {
1072  IPV4_OPT_SSRR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1073  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1074  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1075  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1076  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1077  };
1078  Packet *p = PacketGetFromAlloc();
1079  FAIL_IF(unlikely(p == NULL));
1080 
1081  IPV4Options opts;
1082  memset(&opts, 0x00, sizeof(opts));
1083  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1085  FAIL_IF(opts.o_ssrr.type != IPV4_OPT_SSRR);
1086  SCFree(p);
1087  PASS;
1088 }
1089 
1090 /** \test IPV4 with SSRR option (len too large). */
1091 static int DecodeIPV4OptionsSSRRTest02(void)
1092 {
1093  uint8_t raw_opts[] = {
1094  IPV4_OPT_SSRR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1095  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1096  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1097  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1098  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1099  };
1100  Packet *p = PacketGetFromAlloc();
1101  FAIL_IF(unlikely(p == NULL));
1102 
1103  IPV4Options opts;
1104  memset(&opts, 0x00, sizeof(opts));
1105  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1106  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1107  FAIL_IF(opts.o_ssrr.type != 0);
1108  SCFree(p);
1109  PASS;
1110 }
1111 
1112 /** \test IPV4 with SSRR option (ptr too large). */
1113 static int DecodeIPV4OptionsSSRRTest03(void)
1114 {
1115  uint8_t raw_opts[] = {
1116  IPV4_OPT_SSRR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1117  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1118  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1119  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1120  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1121  };
1122  Packet *p = PacketGetFromAlloc();
1123  FAIL_IF(unlikely(p == NULL));
1124 
1125  IPV4Options opts;
1126  memset(&opts, 0x00, sizeof(opts));
1127  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1128  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1129  FAIL_IF(opts.o_ssrr.type != 0);
1130  SCFree(p);
1131  PASS;
1132 }
1133 
1134 /** \test IPV4 with SSRR option (ptr not in 4 byte increment). */
1135 static int DecodeIPV4OptionsSSRRTest04(void)
1136 {
1137  uint8_t raw_opts[] = {
1138  IPV4_OPT_SSRR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1139  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1140  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1141  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1142  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1143  };
1144  Packet *p = PacketGetFromAlloc();
1145  FAIL_IF(unlikely(p == NULL));
1146 
1147  IPV4Options opts;
1148  memset(&opts, 0x00, sizeof(opts));
1149  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1150  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1151  FAIL_IF(opts.o_ssrr.type != 0);
1152  SCFree(p);
1153  PASS;
1154 }
1155 
1156 /** \test IPV4 with RTRALT option. */
1157 static int DecodeIPV4OptionsRTRALTTest01(void)
1158 {
1159  uint8_t raw_opts[] = {
1160  IPV4_OPT_RTRALT, 0x04, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1161  };
1162  Packet *p = PacketGetFromAlloc();
1163  FAIL_IF(unlikely(p == NULL));
1164 
1165  IPV4Options opts;
1166  memset(&opts, 0x00, sizeof(opts));
1167  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1170  SCFree(p);
1171  PASS;
1172 }
1173 
1174 /** \test IPV4 with RTRALT option (len invalid. */
1175 static int DecodeIPV4OptionsRTRALTTest02(void)
1176 {
1177  uint8_t raw_opts[] = {
1178  IPV4_OPT_RTRALT, 0x05, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1179  };
1180  Packet *p = PacketGetFromAlloc();
1181  FAIL_IF(unlikely(p == NULL));
1182 
1183  IPV4Options opts;
1184  memset(&opts, 0x00, sizeof(opts));
1185  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1186  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1187  FAIL_IF(opts.o_rtralt.type != 0);
1188  SCFree(p);
1189  PASS;
1190 }
1191 
1192 static int IPV4CalculateValidChecksumtest01(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, 0x03};
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 static int IPV4CalculateInvalidChecksumtest02(void)
1208 {
1209  uint16_t csum = 0;
1210 
1211  uint8_t raw_ipv4[] = {
1212  0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00,
1213  0x40, 0x01, 0xb7, 0x52, 0xc0, 0xa8, 0x01, 0x03,
1214  0xc0, 0xa8, 0x01, 0x07};
1215 
1216  csum = *( ((uint16_t *)raw_ipv4) + 5);
1217 
1218  FAIL_IF(IPV4Checksum((uint16_t *)raw_ipv4, sizeof(raw_ipv4), csum) == 0);
1219  PASS;
1220 }
1221 
1222 /**
1223  * \test IPV4 defrag and packet recursion level test
1224  */
1225 static int DecodeIPV4DefragTest01(void)
1226 {
1227  uint8_t pkt1[] = {
1228  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1229  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1230  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1231  0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1232  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1233  0x81, 0x5e
1234  };
1235  uint8_t pkt2[] = {
1236  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1237  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1238  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x01, 0x40, 0x06,
1239  0x9a, 0xc7, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1240  0xe1, 0x0c, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1241  0x80, 0x00
1242  };
1243  uint8_t pkt3[] = {
1244  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1245  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1246  0x00, 0x18, 0xe9, 0xef, 0x00, 0x02, 0x40, 0x06,
1247  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1248  0xe1, 0x0c, 0xb1, 0xa3, 0x00, 0x00
1249  };
1250  uint8_t tunnel_pkt[] = {
1251  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1252  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1253  0x00, 0x28, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1254  0xba, 0xbc, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1255  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1256  0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1257  0x80, 0x00, 0xb1, 0xa3, 0x00, 0x00
1258  };
1259 
1260  Packet *p = PacketGetFromAlloc();
1261  if (unlikely(p == NULL))
1262  return 0;
1263  ThreadVars tv;
1264  DecodeThreadVars dtv;
1265  PacketQueue pq;
1266  int result = 1;
1267 
1268  memset(&tv, 0, sizeof(ThreadVars));
1269  memset(&dtv, 0, sizeof(DecodeThreadVars));
1270  memset(&pq, 0, sizeof(PacketQueue));
1271 
1273  DefragInit();
1274 
1275  PacketCopyData(p, pkt1, sizeof(pkt1));
1276  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1277  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
1278  if (p->tcph != NULL) {
1279  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1280  result = 0;
1281  goto end;
1282  }
1283  PACKET_RECYCLE(p);
1284 
1285  PacketCopyData(p, pkt2, sizeof(pkt2));
1286  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1287  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
1288  if (p->tcph != NULL) {
1289  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1290  result = 0;
1291  goto end;
1292  }
1293  PACKET_RECYCLE(p);
1294 
1295  PacketCopyData(p, pkt3, sizeof(pkt3));
1296  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1297  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
1298  if (p->tcph != NULL) {
1299  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1300  result = 0;
1301  goto end;
1302  }
1303  Packet *tp = PacketDequeue(&pq);
1304  if (tp == NULL) {
1305  printf("Failed to get defragged pseudo packet\n");
1306  result = 0;
1307  goto end;
1308  }
1309  if (tp->recursion_level != p->recursion_level) {
1310  printf("defragged pseudo packet's and parent packet's recursion "
1311  "level don't match\n %d != %d",
1313  result = 0;
1314  goto end;
1315  }
1316  if (tp->ip4h == NULL || tp->tcph == NULL) {
1317  printf("pseudo packet's ip header and tcp header shouldn't be NULL, "
1318  "but it is\n");
1319  result = 0;
1320  goto end;
1321  }
1322  if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) {
1323  printf("defragged pseudo packet's and parent packet's pkt lens "
1324  "don't match\n %u != %"PRIuMAX,
1325  GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt));
1326  result = 0;
1327  goto end;
1328  }
1329  if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) {
1330  result = 0;
1331  goto end;
1332  }
1333 
1334  PACKET_RECYCLE(tp);
1335  SCFree(tp);
1336 
1337 end:
1338  DefragDestroy();
1339  PACKET_RECYCLE(p);
1340  FlowShutdown();
1341  SCFree(p);
1342  return result;
1343 }
1344 
1345 /**
1346  * \test Don't send IPv4 fragments to the upper layer decoder and
1347  * and packet recursion level test.
1348  */
1349 static int DecodeIPV4DefragTest02(void)
1350 {
1351  uint8_t pkt1[] = {
1352  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1353  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1354  0x00, 0x24, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1355  0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1356  0xe1, 0x0c,
1357  /* first frag */
1358  0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1359  0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1360  0x80, 0x00,
1361  };
1362  uint8_t pkt2[] = {
1363  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1364  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1365  0x00, 0x2c, 0xe9, 0xef, 0x20, 0x02, 0x40, 0x06,
1366  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1367  0xe1, 0x0c,
1368  /* second frag */
1369  0xb1, 0xa3, 0x00, 0x10, 0x5b, 0xa3, 0x81, 0x5e,
1370  0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1371  0xb1, 0xa3, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04
1372  };
1373  uint8_t pkt3[] = {
1374  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1375  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1376  0x00, 0x16, 0xe9, 0xef, 0x00, 0x05, 0x40, 0x06,
1377  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1378  0xe1, 0x0c,
1379  /* final frag */
1380  0xb1, 0xa3,
1381  };
1382 
1383  uint8_t tunnel_pkt[] = {
1384  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1385  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1386  0x00, 0x3e, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1387  0xba, 0xae, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1388  0xe1, 0x0c,
1389  0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3, 0x81, 0x5e,
1390  0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1391  0xb1, 0xa3, 0x00, 0x10, 0x5b, 0xa3, 0x81, 0x5e,
1392  0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1393  0xb1, 0xa3, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04,
1394  0xb1, 0xa3,
1395  };
1396 
1397  Packet *p = PacketGetFromAlloc();
1398  if (unlikely(p == NULL))
1399  return 0;
1400  ThreadVars tv;
1401  DecodeThreadVars dtv;
1402  PacketQueue pq;
1403  int result = 0;
1404 
1405  memset(&tv, 0, sizeof(ThreadVars));
1406  memset(&dtv, 0, sizeof(DecodeThreadVars));
1407  memset(&pq, 0, sizeof(PacketQueue));
1408 
1410  DefragInit();
1411 
1412  PacketCopyData(p, pkt1, sizeof(pkt1));
1413  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1414  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
1415  if (p->tcph != NULL) {
1416  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1417  goto end;
1418  }
1419  PACKET_RECYCLE(p);
1420 
1421  PacketCopyData(p, pkt2, sizeof(pkt2));
1422  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1423  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
1424  if (p->tcph != NULL) {
1425  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1426  goto end;
1427  }
1428  PACKET_RECYCLE(p);
1429 
1430  p->recursion_level = 3;
1431  PacketCopyData(p, pkt3, sizeof(pkt3));
1432  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1433  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
1434  if (p->tcph != NULL) {
1435  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1436  goto end;
1437  }
1438  Packet *tp = PacketDequeue(&pq);
1439  if (tp == NULL) {
1440  printf("Failed to get defragged pseudo packet\n");
1441  goto end;
1442  }
1443  if (tp->recursion_level != p->recursion_level) {
1444  printf("defragged pseudo packet's and parent packet's recursion "
1445  "level don't match %d != %d: ",
1447  goto end;
1448  }
1449  if (tp->ip4h == NULL || tp->tcph == NULL) {
1450  printf("pseudo packet's ip header and tcp header shouldn't be NULL, "
1451  "but it is\n");
1452  goto end;
1453  }
1454  if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) {
1455  printf("defragged pseudo packet's and parent packet's pkt lens "
1456  "don't match %u != %"PRIuMAX": ",
1457  GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt));
1458  goto end;
1459  }
1460 
1461  if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) {
1462  goto end;
1463  }
1464 
1465  result = 1;
1466  PACKET_RECYCLE(tp);
1467  SCFree(tp);
1468 
1469 end:
1470  DefragDestroy();
1471  PACKET_RECYCLE(p);
1472  FlowShutdown();
1473  SCFree(p);
1474  return result;
1475 }
1476 
1477 /**
1478  * \test IPV4 defrag and flow retrieval test.
1479  */
1480 static int DecodeIPV4DefragTest03(void)
1481 {
1482  uint8_t pkt[] = {
1483  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1484  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1485  0x00, 0x28, 0xe9, 0xee, 0x00, 0x00, 0x40, 0x06,
1486  0xba, 0xbd, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1487  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1488  0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02,
1489  0x80, 0x00, 0x0c, 0xee, 0x00, 0x00
1490  };
1491  uint8_t pkt1[] = {
1492  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1493  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1494  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1495  0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1496  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1497  0x81, 0x5e
1498  };
1499  uint8_t pkt2[] = {
1500  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1501  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1502  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x01, 0x40, 0x06,
1503  0x9a, 0xc7, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1504  0xe1, 0x0c, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1505  0x80, 0x00
1506  };
1507  uint8_t pkt3[] = {
1508  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1509  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1510  0x00, 0x18, 0xe9, 0xef, 0x00, 0x02, 0x40, 0x06,
1511  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1512  0xe1, 0x0c, 0xb1, 0xa3, 0x00, 0x00
1513  };
1514  uint8_t tunnel_pkt[] = {
1515  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1516  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1517  0x00, 0x28, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1518  0xba, 0xbc, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1519  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1520  0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1521  0x80, 0x00, 0xb1, 0xa3, 0x00, 0x00
1522  };
1523 
1524  Packet *p = PacketGetFromAlloc();
1525  if (unlikely(p == NULL))
1526  return 0;
1527  ThreadVars tv;
1528  DecodeThreadVars dtv;
1529  PacketQueue pq;
1530  int result = 1;
1531 
1532  memset(&tv, 0, sizeof(ThreadVars));
1533  memset(&dtv, 0, sizeof(DecodeThreadVars));
1534  memset(&pq, 0, sizeof(PacketQueue));
1535 
1537  DefragInit();
1538 
1539  PacketCopyData(p, pkt, sizeof(pkt));
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 shouldn't be NULL, but it is\n");
1544  result = 0;
1545  goto end;
1546  }
1547  if (!(p->flags & PKT_WANTS_FLOW)) {
1548  printf("packet flow shouldn't be NULL\n");
1549  result = 0;
1550  goto end;
1551  }
1552  PACKET_RECYCLE(p);
1553 
1554  PacketCopyData(p, pkt1, sizeof(pkt1));
1555  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1556  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
1557  if (p->tcph != NULL) {
1558  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1559  result = 0;
1560  goto end;
1561  }
1562  PACKET_RECYCLE(p);
1563 
1564  PacketCopyData(p, pkt2, sizeof(pkt2));
1565  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1566  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
1567  if (p->tcph != NULL) {
1568  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1569  result = 0;
1570  goto end;
1571  }
1572  PACKET_RECYCLE(p);
1573 
1574  PacketCopyData(p, pkt3, sizeof(pkt3));
1575  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1576  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
1577  if (p->tcph != NULL) {
1578  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1579  result = 0;
1580  goto end;
1581  }
1582 
1583  Packet *tp = PacketDequeue(&pq);
1584  if (tp == NULL) {
1585  printf("Failed to get defragged pseudo packet\n");
1586  result = 0;
1587  goto end;
1588  }
1589  if (!(tp->flags & PKT_WANTS_FLOW)) {
1590  result = 0;
1591  goto end;
1592  }
1593  if (tp->flow_hash != p->flow_hash) {
1594  result = 0;
1595  goto end;
1596  }
1597  if (tp->recursion_level != p->recursion_level) {
1598  printf("defragged pseudo packet's and parent packet's recursion "
1599  "level don't match\n %d != %d",
1601  result = 0;
1602  goto end;
1603  }
1604  if (tp->ip4h == NULL || tp->tcph == NULL) {
1605  printf("pseudo packet's ip header and tcp header shouldn't be NULL, "
1606  "but it is\n");
1607  result = 0;
1608  goto end;
1609  }
1610  if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) {
1611  printf("defragged pseudo packet's and parent packet's pkt lens "
1612  "don't match\n %u != %"PRIuMAX,
1613  GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt));
1614  result = 0;
1615  goto end;
1616  }
1617 
1618  if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) {
1619  result = 0;
1620  goto end;
1621  }
1622 
1623  PACKET_RECYCLE(tp);
1624  SCFree(tp);
1625 
1626 end:
1627  DefragDestroy();
1628  PACKET_RECYCLE(p);
1629  FlowShutdown();
1630  SCFree(p);
1631  return result;
1632 }
1633 
1634 /**
1635  */
1636 static int DecodeEthernetTestIPv4Opt(void)
1637 {
1638  uint8_t raw_eth[] = {
1639  0xae, 0x71, 0x00, 0x00, 0x00, 0x4b, 0x06, 0x90, 0x61, 0x02, 0x00, 0xcd, 0x88, 0x64, 0x11, 0x00,
1640  0x15, 0x00, 0x80, 0x64, 0x00, 0x21, 0x4c, 0x00, 0x00, 0x30, 0x42, 0xd6, 0xff, 0xff, 0xbd, 0x2f,
1641  0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1642  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1643  0x01, 0x44, 0x05, 0x22, 0x02, 0x01
1644  };
1645 
1646  DefragInit();
1647 
1649  FAIL_IF_NULL(p);
1650  ThreadVars tv;
1651  DecodeThreadVars dtv;
1652 
1653  memset(&dtv, 0, sizeof(DecodeThreadVars));
1654  memset(&tv, 0, sizeof(ThreadVars));
1655  memset(p, 0, SIZE_OF_PACKET);
1656 
1657  DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth), NULL);
1658 
1659  SCFree(p);
1660  DefragDestroy();
1661  PASS;
1662 }
1663 
1664 #endif /* UNITTESTS */
1665 
1667 {
1668 #ifdef UNITTESTS
1669  UtRegisterTest("DecodeIPV4OptionsNONETest01", DecodeIPV4OptionsNONETest01);
1670  UtRegisterTest("DecodeIPV4OptionsEOLTest01", DecodeIPV4OptionsEOLTest01);
1671  UtRegisterTest("DecodeIPV4OptionsNOPTest01", DecodeIPV4OptionsNOPTest01);
1672  UtRegisterTest("DecodeIPV4OptionsRRTest01", DecodeIPV4OptionsRRTest01);
1673  UtRegisterTest("DecodeIPV4OptionsRRTest02", DecodeIPV4OptionsRRTest02);
1674  UtRegisterTest("DecodeIPV4OptionsRRTest03", DecodeIPV4OptionsRRTest03);
1675  UtRegisterTest("DecodeIPV4OptionsRRTest04", DecodeIPV4OptionsRRTest04);
1676  UtRegisterTest("DecodeIPV4OptionsQSTest01", DecodeIPV4OptionsQSTest01);
1677  UtRegisterTest("DecodeIPV4OptionsQSTest02", DecodeIPV4OptionsQSTest02);
1678  UtRegisterTest("DecodeIPV4OptionsTSTest01", DecodeIPV4OptionsTSTest01);
1679  UtRegisterTest("DecodeIPV4OptionsTSTest02", DecodeIPV4OptionsTSTest02);
1680  UtRegisterTest("DecodeIPV4OptionsTSTest03", DecodeIPV4OptionsTSTest03);
1681  UtRegisterTest("DecodeIPV4OptionsTSTest04", DecodeIPV4OptionsTSTest04);
1682  UtRegisterTest("DecodeIPV4OptionsSECTest01", DecodeIPV4OptionsSECTest01);
1683  UtRegisterTest("DecodeIPV4OptionsSECTest02", DecodeIPV4OptionsSECTest02);
1684  UtRegisterTest("DecodeIPV4OptionsLSRRTest01", DecodeIPV4OptionsLSRRTest01);
1685  UtRegisterTest("DecodeIPV4OptionsLSRRTest02", DecodeIPV4OptionsLSRRTest02);
1686  UtRegisterTest("DecodeIPV4OptionsLSRRTest03", DecodeIPV4OptionsLSRRTest03);
1687  UtRegisterTest("DecodeIPV4OptionsLSRRTest04", DecodeIPV4OptionsLSRRTest04);
1688  UtRegisterTest("DecodeIPV4OptionsCIPSOTest01",
1689  DecodeIPV4OptionsCIPSOTest01);
1690  UtRegisterTest("DecodeIPV4OptionsSIDTest01", DecodeIPV4OptionsSIDTest01);
1691  UtRegisterTest("DecodeIPV4OptionsSIDTest02", DecodeIPV4OptionsSIDTest02);
1692  UtRegisterTest("DecodeIPV4OptionsSSRRTest01", DecodeIPV4OptionsSSRRTest01);
1693  UtRegisterTest("DecodeIPV4OptionsSSRRTest02", DecodeIPV4OptionsSSRRTest02);
1694  UtRegisterTest("DecodeIPV4OptionsSSRRTest03", DecodeIPV4OptionsSSRRTest03);
1695  UtRegisterTest("DecodeIPV4OptionsSSRRTest04", DecodeIPV4OptionsSSRRTest04);
1696  UtRegisterTest("DecodeIPV4OptionsRTRALTTest01",
1697  DecodeIPV4OptionsRTRALTTest01);
1698  UtRegisterTest("DecodeIPV4OptionsRTRALTTest02",
1699  DecodeIPV4OptionsRTRALTTest02);
1700  UtRegisterTest("IPV4CalculateValidChecksumtest01",
1701  IPV4CalculateValidChecksumtest01);
1702  UtRegisterTest("IPV4CalculateInvalidChecksumtest02",
1703  IPV4CalculateInvalidChecksumtest02);
1704  UtRegisterTest("DecodeIPV4DefragTest01", DecodeIPV4DefragTest01);
1705  UtRegisterTest("DecodeIPV4DefragTest02", DecodeIPV4DefragTest02);
1706  UtRegisterTest("DecodeIPV4DefragTest03", DecodeIPV4DefragTest03);
1707  UtRegisterTest("DecodeEthernetTestIPv4Opt", DecodeEthernetTestIPv4Opt);
1708 #endif /* UNITTESTS */
1709 }
1710 /**
1711  * @}
1712  */
#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:1666
#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:233
#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:532
#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