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