suricata
decode-ipv4.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2024 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \ingroup decode
20  *
21  * @{
22  */
23 
24 
25 /**
26  * \file
27  *
28  * \author Victor Julien <victor@inliniac.net>
29  * \author Brian Rectanus <brectanu@gmail.com>
30  *
31  * Decode IPv4
32  */
33 
34 #include "suricata-common.h"
35 #include "decode-ipv4.h"
36 #include "decode.h"
37 #include "defrag.h"
38 #include "flow.h"
39 #include "util-print.h"
40 
41 /* Generic validation
42  *
43  * [--type--][--len---]
44  *
45  * \todo This function needs removed in favor of specific validation.
46  *
47  * See: RFC 791
48  */
49 static int IPV4OptValidateGeneric(Packet *p, const IPV4Opt *o)
50 {
51  switch (o->type) {
52  /* See: RFC 4782 */
53  case IPV4_OPT_QS:
54  if (o->len < IPV4_OPT_QS_MIN) {
56  return -1;
57  }
58  break;
59  /* See: RFC 1108 */
60  case IPV4_OPT_SEC:
61  case IPV4_OPT_ESEC:
62  if (unlikely(o->len < IPV4_OPT_SEC_MIN)) {
64  return -1;
65  }
66  break;
67  case IPV4_OPT_SID:
68  if (o->len != IPV4_OPT_SID_LEN) {
70  return -1;
71  }
72  break;
73  /* See: RFC 2113 */
74  case IPV4_OPT_RTRALT:
75  if (o->len != IPV4_OPT_RTRALT_LEN) {
77  return -1;
78  }
79  break;
80  default:
81  /* Should never get here unless there is a coding error */
83  return -1;
84  }
85 
86  return 0;
87 }
88 
89 /* Validate route type options
90  *
91  * [--type--][--len---][--ptr---][address1]...[addressN]
92  *
93  * See: RFC 791
94  */
95 static int IPV4OptValidateRoute(Packet *p, const IPV4Opt *o)
96 {
97  uint8_t ptr;
98 
99  /* Check length */
100  if (unlikely(o->len < IPV4_OPT_ROUTE_MIN)) {
102  return -1;
103  }
104 
105  /* Data is required */
106  if (unlikely(o->data == NULL)) {
108  return -1;
109  }
110  ptr = *o->data;
111 
112  /* Address pointer is 1 based and points at least after type+len+ptr,
113  * must be a incremented by 4 bytes (address size) and cannot extend
114  * past option length.
115  */
116  if (unlikely((ptr < 4) || (ptr % 4) || (ptr > o->len + 1))) {
118  return -1;
119  }
120 
121  return 0;
122 }
123 
124 /* Validate timestamp type options
125  *
126  * [--type--][--len---][--ptr---][ovfl][flag][rec1----...]...[recN----...]
127  * NOTE: rec could be 4 (ts only) or 8 (ip+ts) bytes in length.
128  *
129  * See: RFC 781
130  */
131 static int IPV4OptValidateTimestamp(Packet *p, const IPV4Opt *o)
132 {
133  uint8_t ptr;
134  uint8_t flag;
135  uint8_t rec_size;
136 
137  /* Check length */
138  if (unlikely(o->len < IPV4_OPT_TS_MIN)) {
140  return -1;
141  }
142 
143  /* Data is required */
144  if (unlikely(o->data == NULL)) {
146  return -1;
147  }
148  ptr = *o->data;
149 
150  /* We need the flag to determine what is in the option payload */
151  if (unlikely(ptr < 5)) {
153  return -1;
154  }
155  flag = *(o->data + 1) & 0x0f;
156 
157  /* A flag of 1|3 means we have both the ip+ts in each record */
158  rec_size = ((flag == 1) || (flag == 3)) ? 8 : 4;
159 
160  /* Address pointer is 1 based and points at least after
161  * type+len+ptr+ovfl+flag, must be incremented by by the rec_size
162  * and cannot extend past option length.
163  */
164  if (unlikely(((ptr - 5) % rec_size) || (ptr > o->len + 1))) {
166  return -1;
167  }
168 
169  return 0;
170 }
171 
172 /* Validate CIPSO option
173  *
174  * [--type--][--len---][--doi---][tags--...]
175  *
176  * See: draft-ietf-cipso-ipsecurity-01.txt
177  * See: FIPS 188 (tags 6 & 7)
178  */
179 static int IPV4OptValidateCIPSO(Packet *p, const IPV4Opt *o)
180 {
181 // uint32_t doi;
182  const uint8_t *tag;
183  uint16_t len;
184 
185  /* Check length */
186  if (unlikely(o->len < IPV4_OPT_CIPSO_MIN)) {
188  return -1;
189  }
190 
191  /* Data is required */
192  if (unlikely(o->data == NULL)) {
194  return -1;
195  }
196 // doi = *o->data;
197  tag = o->data + 4;
198  len = o->len - 1 - 1 - 4; /* Length of tags after header */
199 
200 
201 #if 0
202  /* Domain of Interest (DOI) of 0 is reserved and thus invalid */
203  /** \todo Apparently a DOI of zero is fine in practice - verify. */
204  if (doi == 0) {
206  return -1;
207  }
208 #endif
209 
210  /* NOTE: We know len has passed min tests prior to this call */
211 
212  /* Check that tags are formatted correctly
213  * [-ttype--][--tlen--][-tagdata-...]
214  */
215  while (len) {
216  uint8_t ttype;
217  uint8_t tlen;
218 
219  /* Tag header must fit within option length */
220  if (unlikely(len < 2)) {
221  //printf("CIPSO tag header too large %" PRIu16 " < 2\n", len);
223  return -1;
224  }
225 
226  /* Tag header is type+len */
227  ttype = *(tag++);
228  tlen = *(tag++);
229 
230  /* Tag length must fit within the option length */
231  if (unlikely(tlen > len)) {
232  //printf("CIPSO tag len too large %" PRIu8 " > %" PRIu16 "\n", tlen, len);
234  return -1;
235  }
236 
237  switch(ttype) {
238  case 1:
239  case 2:
240  case 5:
241  case 6:
242  case 7:
243  /* Tag is at least 4 and at most the remainder of option len */
244  if (unlikely((tlen < 4) || (tlen > len))) {
245  //printf("CIPSO tag %" PRIu8 " bad tlen=%" PRIu8 " len=%" PRIu8 "\n", ttype, tlen, len);
247  return -1;
248  }
249 
250  /* The alignment octet is always 0 except tag
251  * type 7, which has no such field.
252  */
253  if (unlikely((ttype != 7) && (*tag != 0))) {
254  //printf("CIPSO tag %" PRIu8 " ao=%" PRIu8 "\n", ttype, tlen);
256  return -1;
257  }
258 
259  /* Skip the rest of the tag payload */
260  tag += tlen - 2;
261  len -= tlen;
262 
263  continue;
264  case 0:
265  /* Tag type 0 is reserved and thus invalid */
266  /** \todo Wireshark marks this a padding, but spec says reserved. */
268  return -1;
269  default:
270  //printf("CIPSO tag %" PRIu8 " unknown tag\n", ttype);
272  /** \todo May not want to return error here on unknown tag type (at least not for 3|4) */
273  return -1;
274  }
275  }
276 
277  return 0;
278 }
279 
280 typedef struct IPV4Options_ {
292 
293 /**
294  * Decode/Validate IPv4 Options.
295  */
296 static int DecodeIPV4Options(Packet *p, const uint8_t *pkt, uint16_t len, IPV4Options *opts)
297 {
298  uint16_t plen = len;
299 
300 #ifdef DEBUG
301  if (SCLogDebugEnabled()) {
302  uint16_t i;
303  char buf[256] = "";
304  int offset = 0;
305 
306  for (i = 0; i < len; i++) {
307  offset += snprintf(buf + offset, (sizeof(buf) - offset), "%02" PRIx8 " ", pkt[i]);
308  }
309  SCLogDebug("IPV4OPTS: { %s}", buf);
310  }
311 #endif
312 
313  /* Options length must be padded to 8byte boundary */
314  if (plen % 8) {
316  /* Warn - we can keep going */
317  }
318 
319  while (plen)
320  {
321  p->l3.vars.ip4.opt_cnt++;
322 
323  /* single byte options */
324  if (*pkt == IPV4_OPT_EOL) {
325  /** \todo What if more data exist after EOL (possible covert channel or data leakage)? */
326  SCLogDebug("IPV4OPT %" PRIu8 " len 1 @ %d/%d",
327  *pkt, (len - plen), (len - 1));
329  break;
330  } else if (*pkt == IPV4_OPT_NOP) {
331  SCLogDebug("IPV4OPT %" PRIu8 " len 1 @ %d/%d",
332  *pkt, (len - plen), (len - 1));
333  pkt++;
334  plen--;
335 
337 
338  /* multibyte options */
339  } else {
340  if (unlikely(plen < 2)) {
341  /** \todo What if padding is non-zero (possible covert channel or data leakage)? */
342  /** \todo Spec seems to indicate EOL required if there is padding */
344  break;
345  }
346 
347  /* Option length is too big for packet */
348  if (unlikely(*(pkt+1) > plen)) {
350  return -1;
351  }
352 
353  IPV4Opt opt = {*pkt, *(pkt+1), plen > 2 ? (pkt + 2) : NULL };
354 
355  /* we already know that the total options len is valid,
356  * so here the len of the specific option must be bad.
357  * Also check for invalid lengths 0 and 1. */
358  if (unlikely(opt.len > plen || opt.len < 2)) {
360  return -1;
361  }
362  /* we are parsing the most commonly used opts to prevent
363  * us from having to walk the opts list for these all the
364  * time. */
365  /** \todo Figure out which IP options are more common and list them first */
366  switch (opt.type) {
367  case IPV4_OPT_TS:
368  if (opts->o_ts.type != 0) {
370  /* Warn - we can keep going */
371  } else if (IPV4OptValidateTimestamp(p, &opt) == 0) {
372  opts->o_ts = opt;
374  }
375  break;
376  case IPV4_OPT_RR:
377  if (opts->o_rr.type != 0) {
379  /* Warn - we can keep going */
380  } else if (IPV4OptValidateRoute(p, &opt) == 0) {
381  opts->o_rr = opt;
383  }
384  break;
385  case IPV4_OPT_QS:
386  if (opts->o_qs.type != 0) {
388  /* Warn - we can keep going */
389  } else if (IPV4OptValidateGeneric(p, &opt) == 0) {
390  opts->o_qs = opt;
392  }
393  break;
394  case IPV4_OPT_SEC:
395  if (opts->o_sec.type != 0) {
397  /* Warn - we can keep going */
398  } else if (IPV4OptValidateGeneric(p, &opt) == 0) {
399  opts->o_sec = opt;
401  }
402  break;
403  case IPV4_OPT_LSRR:
404  if (opts->o_lsrr.type != 0) {
406  /* Warn - we can keep going */
407  } else if (IPV4OptValidateRoute(p, &opt) == 0) {
408  opts->o_lsrr = opt;
410  }
411  break;
412  case IPV4_OPT_ESEC:
413  if (opts->o_esec.type != 0) {
415  /* Warn - we can keep going */
416  } else if (IPV4OptValidateGeneric(p, &opt) == 0) {
417  opts->o_esec = opt;
419  }
420  break;
421  case IPV4_OPT_CIPSO:
422  if (opts->o_cipso.type != 0) {
424  /* Warn - we can keep going */
425  } else if (IPV4OptValidateCIPSO(p, &opt) == 0) {
426  opts->o_cipso = opt;
428  }
429  break;
430  case IPV4_OPT_SID:
431  if (opts->o_sid.type != 0) {
433  /* Warn - we can keep going */
434  } else if (IPV4OptValidateGeneric(p, &opt) == 0) {
435  opts->o_sid = opt;
437  }
438  break;
439  case IPV4_OPT_SSRR:
440  if (opts->o_ssrr.type != 0) {
442  /* Warn - we can keep going */
443  } else if (IPV4OptValidateRoute(p, &opt) == 0) {
444  opts->o_ssrr = opt;
446  }
447  break;
448  case IPV4_OPT_RTRALT:
449  if (opts->o_rtralt.type != 0) {
451  /* Warn - we can keep going */
452  } else if (IPV4OptValidateGeneric(p, &opt) == 0) {
453  opts->o_rtralt = opt;
455  }
456  break;
457  default:
458  SCLogDebug("IPV4OPT <unknown> (%" PRIu8 ") len %" PRIu8,
459  opt.type, opt.len);
461  /* Warn - we can keep going */
462  break;
463  }
464 
465  pkt += opt.len;
466  plen -= opt.len;
467  }
468  }
469 
470  return 0;
471 }
472 
473 static const IPV4Hdr *DecodeIPV4Packet(Packet *p, const uint8_t *pkt, uint16_t len)
474 {
475  if (unlikely(len < IPV4_HEADER_LEN)) {
477  return NULL;
478  }
479 
480  if (unlikely(IP_GET_RAW_VER(pkt) != 4)) {
481  SCLogDebug("wrong ip version %d",IP_GET_RAW_VER(pkt));
483  return NULL;
484  }
485 
486  const IPV4Hdr *ip4h = PacketSetIPV4(p, pkt);
487 
490  return NULL;
491  }
492 
493  if (unlikely(IPV4_GET_RAW_IPLEN(ip4h) < IPV4_GET_RAW_HLEN(ip4h))) {
495  return NULL;
496  }
497 
498  if (unlikely(len < IPV4_GET_RAW_IPLEN(ip4h))) {
500  return NULL;
501  }
502 
503  /* set the address struct */
504  SET_IPV4_SRC_ADDR(ip4h, &p->src);
505  SET_IPV4_DST_ADDR(ip4h, &p->dst);
506 
507  /* save the options len */
508  uint8_t ip_opt_len = IPV4_GET_RAW_HLEN(ip4h) - IPV4_HEADER_LEN;
509  if (ip_opt_len > 0) {
510  IPV4Options opts;
511  memset(&opts, 0x00, sizeof(opts));
512  if (DecodeIPV4Options(p, pkt + IPV4_HEADER_LEN, ip_opt_len, &opts) < 0) {
513  return NULL;
514  }
515  }
516 
517  return ip4h;
518 }
519 
521  const uint8_t *pkt, uint16_t len)
522 {
524 
525  SCLogDebug("pkt %p len %"PRIu16"", pkt, len);
526 
527  if (!PacketIncreaseCheckLayers(p)) {
528  return TM_ECODE_FAILED;
529  }
530  /* do the actual decoding */
531  const IPV4Hdr *ip4h = DecodeIPV4Packet(p, pkt, len);
532  if (unlikely(ip4h == NULL)) {
533  SCLogDebug("decoding IPv4 packet failed");
534  PacketClearL3(p);
535  return TM_ECODE_FAILED;
536  }
537  p->proto = IPV4_GET_RAW_IPPROTO(ip4h);
538 
539  /* If a fragment, pass off for re-assembly. */
540  if (unlikely(IPV4_GET_RAW_FRAGOFFSET(ip4h) > 0 || IPV4_GET_RAW_FLAG_MF(ip4h))) {
541  Packet *rp = Defrag(tv, dtv, p);
542  if (rp != NULL) {
544  }
545  p->flags |= PKT_IS_FRAGMENT;
546  return TM_ECODE_OK;
547  }
548 
549  /* do hdr test, process hdr rules */
550 
551 #ifdef DEBUG
552  if (SCLogDebugEnabled()) { /* only convert the addresses if debug is really enabled */
553  /* debug print */
554  char s[16], d[16];
555  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), s, sizeof(s));
556  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), d, sizeof(d));
557  SCLogDebug("IPV4 %s->%s PROTO: %" PRIu32 " OFFSET: %" PRIu32 " RF: %" PRIu8 " DF: %" PRIu8
558  " MF: %" PRIu8 " ID: %" PRIu32 "",
559  s, d, IPV4_GET_RAW_IPPROTO(ip4h), IPV4_GET_RAW_IPOFFSET(ip4h),
561  IPV4_GET_RAW_IPID(ip4h));
562  }
563 #endif /* DEBUG */
564 
565  const uint8_t *data = pkt + IPV4_GET_RAW_HLEN(ip4h);
566  const uint16_t data_len = IPV4_GET_RAW_IPLEN(ip4h) - IPV4_GET_RAW_HLEN(ip4h);
567 
568  /* check what next decoder to invoke */
569  switch (p->proto) {
570  case IPPROTO_TCP:
571  DecodeTCP(tv, dtv, p, data, data_len);
572  break;
573  case IPPROTO_UDP:
574  DecodeUDP(tv, dtv, p, data, data_len);
575  break;
576  case IPPROTO_ICMP:
577  DecodeICMPV4(tv, dtv, p, data, data_len);
578  break;
579  case IPPROTO_GRE:
580  DecodeGRE(tv, dtv, p, data, data_len);
581  break;
582  case IPPROTO_SCTP:
583  DecodeSCTP(tv, dtv, p, data, data_len);
584  break;
585  case IPPROTO_ESP:
586  DecodeESP(tv, dtv, p, data, data_len);
587  break;
588  case IPPROTO_IPV6:
589  {
590  /* spawn off tunnel packet */
591  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, data, data_len, DECODE_TUNNEL_IPV6);
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->flags & PKT_PPP_VJ_UCOMP) {
602  DecodeTCP(tv, dtv, p, data, data_len);
603  }
604  break;
605  case IPPROTO_ICMPV6:
607  break;
608  }
609 
610  return TM_ECODE_OK;
611 }
612 
613 /* UNITTESTS */
614 #ifdef UNITTESTS
615 #include "packet.h"
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[] = { IPV4_OPT_SEC, 0x02, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
900  0x00, 0x00, 0x00, 0x00, 0x00 };
901  Packet *p = PacketGetFromAlloc();
902  FAIL_IF(unlikely(p == NULL));
903 
904  IPV4Options opts;
905  memset(&opts, 0x00, sizeof(opts));
906  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
907  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
908  FAIL_IF(opts.o_sec.type != 0);
909  SCFree(p);
910  PASS;
911 }
912 
913 /** \test IPV4 with ESEC option. */
914 static int DecodeIPV4OptionsESECTest01(void)
915 {
916  uint8_t raw_opts[] = { IPV4_OPT_ESEC, 0x0b, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
917  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
918  Packet *p = PacketGetFromAlloc();
919  FAIL_IF(unlikely(p == NULL));
920 
921  IPV4Options opts;
922  memset(&opts, 0x00, sizeof(opts));
923  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
925  FAIL_IF(opts.o_esec.type != IPV4_OPT_ESEC);
926  SCFree(p);
927  PASS;
928 }
929 
930 /** \test IPV4 with ESEC option (invalid length). */
931 static int DecodeIPV4OptionsESECTest02(void)
932 {
933  uint8_t raw_opts[] = { IPV4_OPT_ESEC, 0x02, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
934  0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
935  Packet *p = PacketGetFromAlloc();
936  FAIL_IF(unlikely(p == NULL));
937 
938  IPV4Options opts;
939  memset(&opts, 0x00, sizeof(opts));
940  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
941  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
942  FAIL_IF(opts.o_esec.type != 0);
943  SCFree(p);
944  PASS;
945 }
946 
947 /** \test IPV4 with LSRR option. */
948 static int DecodeIPV4OptionsLSRRTest01(void)
949 {
950  uint8_t raw_opts[] = {
951  IPV4_OPT_LSRR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 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  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
956  };
957  Packet *p = PacketGetFromAlloc();
958  FAIL_IF(unlikely(p == NULL));
959 
960  IPV4Options opts;
961  memset(&opts, 0x00, sizeof(opts));
962  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
964  FAIL_IF(opts.o_lsrr.type != IPV4_OPT_LSRR);
965  SCFree(p);
966  PASS;
967 }
968 
969 /** \test IPV4 with LSRR option (len too large). */
970 static int DecodeIPV4OptionsLSRRTest02(void)
971 {
972  uint8_t raw_opts[] = {
973  IPV4_OPT_LSRR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 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  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
978  };
979  Packet *p = PacketGetFromAlloc();
980  FAIL_IF(unlikely(p == NULL));
981 
982  IPV4Options opts;
983  memset(&opts, 0x00, sizeof(opts));
984  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
985  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
986  FAIL_IF(opts.o_lsrr.type != 0);
987  SCFree(p);
988  PASS;
989 }
990 
991 /** \test IPV4 with LSRR option (ptr too large). */
992 static int DecodeIPV4OptionsLSRRTest03(void)
993 {
994  uint8_t raw_opts[] = {
995  IPV4_OPT_LSRR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 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  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1000  };
1001  Packet *p = PacketGetFromAlloc();
1002  FAIL_IF(unlikely(p == NULL));
1003 
1004  IPV4Options opts;
1005  memset(&opts, 0x00, sizeof(opts));
1006  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1007  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1008  FAIL_IF(opts.o_lsrr.type != 0);
1009  SCFree(p);
1010  PASS;
1011 }
1012 
1013 /** \test IPV4 with LSRR option (ptr not in 4 byte increment). */
1014 static int DecodeIPV4OptionsLSRRTest04(void)
1015 {
1016  uint8_t raw_opts[] = {
1017  IPV4_OPT_LSRR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1018  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1019  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1020  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1021  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1022  };
1023  Packet *p = PacketGetFromAlloc();
1024  FAIL_IF(unlikely(p == NULL));
1025 
1026  IPV4Options opts;
1027  memset(&opts, 0x00, sizeof(opts));
1028  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1029  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1030  FAIL_IF(opts.o_lsrr.type != 0);
1031  SCFree(p);
1032  PASS;
1033 }
1034 
1035 /** \test IPV4 with CIPSO option. */
1036 static int DecodeIPV4OptionsCIPSOTest01(void)
1037 {
1038  uint8_t raw_opts[] = {
1039  IPV4_OPT_CIPSO, 0x18, 0x00, 0x00, 0x00, 0x05, 0x05, 0x12,
1040  0x00, 0x03, 0x00, 0xef, 0x00, 0xef, 0x00, 0x06,
1041  0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00
1042  };
1043  Packet *p = PacketGetFromAlloc();
1044  FAIL_IF(unlikely(p == NULL));
1045 
1046  IPV4Options opts;
1047  memset(&opts, 0x00, sizeof(opts));
1048  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1051  SCFree(p);
1052  PASS;
1053 }
1054 
1055 /** \test IPV4 with SID option. */
1056 static int DecodeIPV4OptionsSIDTest01(void)
1057 {
1058  uint8_t raw_opts[] = {
1059  IPV4_OPT_SID, 0x04, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1060  };
1061  Packet *p = PacketGetFromAlloc();
1062  FAIL_IF(unlikely(p == NULL));
1063 
1064  IPV4Options opts;
1065  memset(&opts, 0x00, sizeof(opts));
1066  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1068  FAIL_IF(opts.o_sid.type != IPV4_OPT_SID);
1069  SCFree(p);
1070  PASS;
1071 }
1072 
1073 /** \test IPV4 with SID option (len invalid. */
1074 static int DecodeIPV4OptionsSIDTest02(void)
1075 {
1076  uint8_t raw_opts[] = {
1077  IPV4_OPT_SID, 0x05, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1078  };
1079  Packet *p = PacketGetFromAlloc();
1080  FAIL_IF(unlikely(p == NULL));
1081 
1082  IPV4Options opts;
1083  memset(&opts, 0x00, sizeof(opts));
1084  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1085  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1086  FAIL_IF(opts.o_sid.type != 0);
1087  SCFree(p);
1088  PASS;
1089 }
1090 
1091 /** \test IPV4 with SSRR option. */
1092 static int DecodeIPV4OptionsSSRRTest01(void)
1093 {
1094  uint8_t raw_opts[] = {
1095  IPV4_OPT_SSRR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 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  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1100  };
1101  Packet *p = PacketGetFromAlloc();
1102  FAIL_IF(unlikely(p == NULL));
1103 
1104  IPV4Options opts;
1105  memset(&opts, 0x00, sizeof(opts));
1106  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1108  FAIL_IF(opts.o_ssrr.type != IPV4_OPT_SSRR);
1109  SCFree(p);
1110  PASS;
1111 }
1112 
1113 /** \test IPV4 with SSRR option (len too large). */
1114 static int DecodeIPV4OptionsSSRRTest02(void)
1115 {
1116  uint8_t raw_opts[] = {
1117  IPV4_OPT_SSRR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 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  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1122  };
1123  Packet *p = PacketGetFromAlloc();
1124  FAIL_IF(unlikely(p == NULL));
1125 
1126  IPV4Options opts;
1127  memset(&opts, 0x00, sizeof(opts));
1128  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1129  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1130  FAIL_IF(opts.o_ssrr.type != 0);
1131  SCFree(p);
1132  PASS;
1133 }
1134 
1135 /** \test IPV4 with SSRR option (ptr too large). */
1136 static int DecodeIPV4OptionsSSRRTest03(void)
1137 {
1138  uint8_t raw_opts[] = {
1139  IPV4_OPT_SSRR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 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  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1144  };
1145  Packet *p = PacketGetFromAlloc();
1146  FAIL_IF(unlikely(p == NULL));
1147 
1148  IPV4Options opts;
1149  memset(&opts, 0x00, sizeof(opts));
1150  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1151  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1152  FAIL_IF(opts.o_ssrr.type != 0);
1153  SCFree(p);
1154  PASS;
1155 }
1156 
1157 /** \test IPV4 with SSRR option (ptr not in 4 byte increment). */
1158 static int DecodeIPV4OptionsSSRRTest04(void)
1159 {
1160  uint8_t raw_opts[] = {
1161  IPV4_OPT_SSRR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1162  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1163  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1164  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1165  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1166  };
1167  Packet *p = PacketGetFromAlloc();
1168  FAIL_IF(unlikely(p == NULL));
1169 
1170  IPV4Options opts;
1171  memset(&opts, 0x00, sizeof(opts));
1172  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1173  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1174  FAIL_IF(opts.o_ssrr.type != 0);
1175  SCFree(p);
1176  PASS;
1177 }
1178 
1179 /** \test IPV4 with RTRALT option. */
1180 static int DecodeIPV4OptionsRTRALTTest01(void)
1181 {
1182  uint8_t raw_opts[] = {
1183  IPV4_OPT_RTRALT, 0x04, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1184  };
1185  Packet *p = PacketGetFromAlloc();
1186  FAIL_IF(unlikely(p == NULL));
1187 
1188  IPV4Options opts;
1189  memset(&opts, 0x00, sizeof(opts));
1190  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1193  SCFree(p);
1194  PASS;
1195 }
1196 
1197 /** \test IPV4 with RTRALT option (len invalid. */
1198 static int DecodeIPV4OptionsRTRALTTest02(void)
1199 {
1200  uint8_t raw_opts[] = {
1201  IPV4_OPT_RTRALT, 0x05, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1202  };
1203  Packet *p = PacketGetFromAlloc();
1204  FAIL_IF(unlikely(p == NULL));
1205 
1206  IPV4Options opts;
1207  memset(&opts, 0x00, sizeof(opts));
1208  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1209  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1210  FAIL_IF(opts.o_rtralt.type != 0);
1211  SCFree(p);
1212  PASS;
1213 }
1214 
1215 static int IPV4CalculateValidChecksumtest01(void)
1216 {
1217  uint16_t csum = 0;
1218 
1219  uint8_t raw_ipv4[] = {
1220  0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00,
1221  0x40, 0x01, 0xb7, 0x52, 0xc0, 0xa8, 0x01, 0x03,
1222  0xc0, 0xa8, 0x01, 0x03};
1223 
1224  csum = *( ((uint16_t *)raw_ipv4) + 5);
1225 
1226  FAIL_IF(IPV4Checksum((uint16_t *)raw_ipv4, sizeof(raw_ipv4), csum) != 0);
1227  PASS;
1228 }
1229 
1230 static int IPV4CalculateInvalidChecksumtest02(void)
1231 {
1232  uint16_t csum = 0;
1233 
1234  uint8_t raw_ipv4[] = {
1235  0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00,
1236  0x40, 0x01, 0xb7, 0x52, 0xc0, 0xa8, 0x01, 0x03,
1237  0xc0, 0xa8, 0x01, 0x07};
1238 
1239  csum = *( ((uint16_t *)raw_ipv4) + 5);
1240 
1241  FAIL_IF(IPV4Checksum((uint16_t *)raw_ipv4, sizeof(raw_ipv4), csum) == 0);
1242  PASS;
1243 }
1244 
1245 /**
1246  * \test IPV4 defrag and packet recursion level test
1247  */
1248 static int DecodeIPV4DefragTest01(void)
1249 {
1250  uint8_t pkt1[] = {
1251  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1252  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1253  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1254  0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1255  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1256  0x81, 0x5e
1257  };
1258  uint8_t pkt2[] = {
1259  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1260  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1261  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x01, 0x40, 0x06,
1262  0x9a, 0xc7, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1263  0xe1, 0x0c, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1264  0x80, 0x00
1265  };
1266  uint8_t pkt3[] = {
1267  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1268  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1269  0x00, 0x18, 0xe9, 0xef, 0x00, 0x02, 0x40, 0x06,
1270  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1271  0xe1, 0x0c, 0xb1, 0xa3, 0x00, 0x00
1272  };
1273  uint8_t tunnel_pkt[] = {
1274  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1275  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1276  0x00, 0x28, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1277  0xba, 0xbc, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1278  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1279  0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1280  0x80, 0x00, 0xb1, 0xa3, 0x00, 0x00
1281  };
1282 
1283  Packet *p = PacketGetFromAlloc();
1284  FAIL_IF_NULL(p);
1285  ThreadVars tv;
1287 
1288  memset(&tv, 0, sizeof(ThreadVars));
1289  memset(&dtv, 0, sizeof(DecodeThreadVars));
1290 
1292  DefragInit();
1293 
1294  PacketCopyData(p, pkt1, sizeof(pkt1));
1297  FAIL_IF(PacketIsTCP(p));
1298  PacketRecycle(p);
1299 
1300  PacketCopyData(p, pkt2, sizeof(pkt2));
1303  FAIL_IF(PacketIsTCP(p));
1304  PacketRecycle(p);
1305 
1306  PacketCopyData(p, pkt3, sizeof(pkt3));
1309  FAIL_IF(PacketIsTCP(p));
1311  FAIL_IF_NULL(tp);
1313  FAIL_IF_NOT(PacketIsIPv4(tp));
1314  FAIL_IF_NOT(PacketIsTCP(tp));
1315  FAIL_IF(GET_PKT_LEN(tp) != sizeof(tunnel_pkt));
1316  FAIL_IF(memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0);
1317  PacketRecycle(tp);
1318  SCFree(tp);
1319 
1320  DefragDestroy();
1321  PacketRecycle(p);
1322  FlowShutdown();
1323  SCFree(p);
1324  PASS;
1325 }
1326 
1327 /**
1328  * \test Don't send IPv4 fragments to the upper layer decoder and
1329  * and packet recursion level test.
1330  */
1331 static int DecodeIPV4DefragTest02(void)
1332 {
1333  uint8_t pkt1[] = {
1334  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1335  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1336  0x00, 0x24, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1337  0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1338  0xe1, 0x0c,
1339  /* first frag */
1340  0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1341  0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1342  0x80, 0x00,
1343  };
1344  uint8_t pkt2[] = {
1345  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1346  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1347  0x00, 0x2c, 0xe9, 0xef, 0x20, 0x02, 0x40, 0x06,
1348  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1349  0xe1, 0x0c,
1350  /* second frag */
1351  0xb1, 0xa3, 0x00, 0x10, 0x5b, 0xa3, 0x81, 0x5e,
1352  0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1353  0xb1, 0xa3, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04
1354  };
1355  uint8_t pkt3[] = {
1356  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1357  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1358  0x00, 0x16, 0xe9, 0xef, 0x00, 0x05, 0x40, 0x06,
1359  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1360  0xe1, 0x0c,
1361  /* final frag */
1362  0xb1, 0xa3,
1363  };
1364 
1365  uint8_t tunnel_pkt[] = {
1366  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1367  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1368  0x00, 0x3e, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1369  0xba, 0xae, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1370  0xe1, 0x0c,
1371  0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3, 0x81, 0x5e,
1372  0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1373  0xb1, 0xa3, 0x00, 0x10, 0x5b, 0xa3, 0x81, 0x5e,
1374  0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1375  0xb1, 0xa3, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04,
1376  0xb1, 0xa3,
1377  };
1378 
1379  Packet *p = PacketGetFromAlloc();
1380  FAIL_IF_NULL(p);
1381  ThreadVars tv;
1383 
1384  memset(&tv, 0, sizeof(ThreadVars));
1385  memset(&dtv, 0, sizeof(DecodeThreadVars));
1386 
1388  DefragInit();
1389 
1390  PacketCopyData(p, pkt1, sizeof(pkt1));
1393  FAIL_IF(PacketIsTCP(p));
1394  PacketRecycle(p);
1395 
1396  PacketCopyData(p, pkt2, sizeof(pkt2));
1399  FAIL_IF(PacketIsTCP(p));
1400  PacketRecycle(p);
1401 
1402  p->recursion_level = 3;
1403  PacketCopyData(p, pkt3, sizeof(pkt3));
1406  FAIL_IF(PacketIsTCP(p));
1408  FAIL_IF_NULL(tp);
1410  FAIL_IF_NOT(PacketIsIPv4(tp));
1411  FAIL_IF_NOT(PacketIsTCP(tp));
1412  FAIL_IF(GET_PKT_LEN(tp) != sizeof(tunnel_pkt));
1413  FAIL_IF(memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0);
1414  PacketRecycle(tp);
1415  SCFree(tp);
1416 
1417  DefragDestroy();
1418  PacketRecycle(p);
1419  FlowShutdown();
1420  SCFree(p);
1421  PASS;
1422 }
1423 
1424 /**
1425  * \test IPV4 defrag and flow retrieval test.
1426  */
1427 static int DecodeIPV4DefragTest03(void)
1428 {
1429  uint8_t pkt[] = {
1430  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1431  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1432  0x00, 0x28, 0xe9, 0xee, 0x00, 0x00, 0x40, 0x06,
1433  0xba, 0xbd, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1434  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1435  0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02,
1436  0x80, 0x00, 0x0c, 0xee, 0x00, 0x00
1437  };
1438  uint8_t pkt1[] = {
1439  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1440  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1441  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1442  0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1443  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1444  0x81, 0x5e
1445  };
1446  uint8_t pkt2[] = {
1447  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1448  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1449  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x01, 0x40, 0x06,
1450  0x9a, 0xc7, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1451  0xe1, 0x0c, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1452  0x80, 0x00
1453  };
1454  uint8_t pkt3[] = {
1455  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1456  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1457  0x00, 0x18, 0xe9, 0xef, 0x00, 0x02, 0x40, 0x06,
1458  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1459  0xe1, 0x0c, 0xb1, 0xa3, 0x00, 0x00
1460  };
1461  uint8_t tunnel_pkt[] = {
1462  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1463  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1464  0x00, 0x28, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1465  0xba, 0xbc, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1466  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1467  0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1468  0x80, 0x00, 0xb1, 0xa3, 0x00, 0x00
1469  };
1470 
1471  Packet *p = PacketGetFromAlloc();
1472  FAIL_IF_NULL(p);
1473  ThreadVars tv;
1475  memset(&tv, 0, sizeof(ThreadVars));
1476  memset(&dtv, 0, sizeof(DecodeThreadVars));
1477 
1479  DefragInit();
1480 
1481  PacketCopyData(p, pkt, sizeof(pkt));
1484  FAIL_IF_NOT(PacketIsTCP(p));
1485  FAIL_IF(!(p->flags & PKT_WANTS_FLOW));
1486  PacketRecycle(p);
1487 
1488  PacketCopyData(p, pkt1, sizeof(pkt1));
1491  FAIL_IF(PacketIsTCP(p));
1492  PacketRecycle(p);
1493 
1494  PacketCopyData(p, pkt2, sizeof(pkt2));
1497  FAIL_IF(PacketIsTCP(p));
1498  PacketRecycle(p);
1499 
1500  PacketCopyData(p, pkt3, sizeof(pkt3));
1503  FAIL_IF(PacketIsTCP(p));
1504 
1506  FAIL_IF_NULL(tp);
1507  FAIL_IF(!(tp->flags & PKT_WANTS_FLOW));
1508  FAIL_IF(tp->flow_hash != p->flow_hash);
1510  FAIL_IF_NOT(PacketIsIPv4(tp));
1511  FAIL_IF_NOT(PacketIsTCP(tp));
1512  FAIL_IF(GET_PKT_LEN(tp) != sizeof(tunnel_pkt));
1513  FAIL_IF(memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0);
1514  PacketRecycle(tp);
1515  SCFree(tp);
1516 
1517  DefragDestroy();
1518  PacketRecycle(p);
1519  FlowShutdown();
1520  SCFree(p);
1521  PASS;
1522 }
1523 
1524 /**
1525  */
1526 static int DecodeEthernetTestIPv4Opt(void)
1527 {
1528  uint8_t raw_eth[] = {
1529  0xae, 0x71, 0x00, 0x00, 0x00, 0x4b, 0x06, 0x90, 0x61, 0x02, 0x00, 0xcd, 0x88, 0x64, 0x11, 0x00,
1530  0x15, 0x00, 0x80, 0x64, 0x00, 0x21, 0x4c, 0x00, 0x00, 0x30, 0x42, 0xd6, 0xff, 0xff, 0xbd, 0x2f,
1531  0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1532  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
1533  0x01, 0x44, 0x05, 0x22, 0x02, 0x01
1534  };
1535 
1536  DefragInit();
1537 
1538  Packet *p = PacketGetFromAlloc();
1539  FAIL_IF_NULL(p);
1540  ThreadVars tv;
1542 
1543  memset(&dtv, 0, sizeof(DecodeThreadVars));
1544  memset(&tv, 0, sizeof(ThreadVars));
1545 
1546  DecodeEthernet(&tv, &dtv, p, raw_eth, sizeof(raw_eth));
1547 
1548  SCFree(p);
1549  DefragDestroy();
1550  PASS;
1551 }
1552 
1553 #endif /* UNITTESTS */
1554 
1556 {
1557 #ifdef UNITTESTS
1558  UtRegisterTest("DecodeIPV4OptionsNONETest01", DecodeIPV4OptionsNONETest01);
1559  UtRegisterTest("DecodeIPV4OptionsEOLTest01", DecodeIPV4OptionsEOLTest01);
1560  UtRegisterTest("DecodeIPV4OptionsNOPTest01", DecodeIPV4OptionsNOPTest01);
1561  UtRegisterTest("DecodeIPV4OptionsRRTest01", DecodeIPV4OptionsRRTest01);
1562  UtRegisterTest("DecodeIPV4OptionsRRTest02", DecodeIPV4OptionsRRTest02);
1563  UtRegisterTest("DecodeIPV4OptionsRRTest03", DecodeIPV4OptionsRRTest03);
1564  UtRegisterTest("DecodeIPV4OptionsRRTest04", DecodeIPV4OptionsRRTest04);
1565  UtRegisterTest("DecodeIPV4OptionsQSTest01", DecodeIPV4OptionsQSTest01);
1566  UtRegisterTest("DecodeIPV4OptionsQSTest02", DecodeIPV4OptionsQSTest02);
1567  UtRegisterTest("DecodeIPV4OptionsTSTest01", DecodeIPV4OptionsTSTest01);
1568  UtRegisterTest("DecodeIPV4OptionsTSTest02", DecodeIPV4OptionsTSTest02);
1569  UtRegisterTest("DecodeIPV4OptionsTSTest03", DecodeIPV4OptionsTSTest03);
1570  UtRegisterTest("DecodeIPV4OptionsTSTest04", DecodeIPV4OptionsTSTest04);
1571  UtRegisterTest("DecodeIPV4OptionsSECTest01", DecodeIPV4OptionsSECTest01);
1572  UtRegisterTest("DecodeIPV4OptionsSECTest02", DecodeIPV4OptionsSECTest02);
1573  UtRegisterTest("DecodeIPV4OptionsESECTest01", DecodeIPV4OptionsESECTest01);
1574  UtRegisterTest("DecodeIPV4OptionsESECTest02", DecodeIPV4OptionsESECTest02);
1575  UtRegisterTest("DecodeIPV4OptionsLSRRTest01", DecodeIPV4OptionsLSRRTest01);
1576  UtRegisterTest("DecodeIPV4OptionsLSRRTest02", DecodeIPV4OptionsLSRRTest02);
1577  UtRegisterTest("DecodeIPV4OptionsLSRRTest03", DecodeIPV4OptionsLSRRTest03);
1578  UtRegisterTest("DecodeIPV4OptionsLSRRTest04", DecodeIPV4OptionsLSRRTest04);
1579  UtRegisterTest("DecodeIPV4OptionsCIPSOTest01",
1580  DecodeIPV4OptionsCIPSOTest01);
1581  UtRegisterTest("DecodeIPV4OptionsSIDTest01", DecodeIPV4OptionsSIDTest01);
1582  UtRegisterTest("DecodeIPV4OptionsSIDTest02", DecodeIPV4OptionsSIDTest02);
1583  UtRegisterTest("DecodeIPV4OptionsSSRRTest01", DecodeIPV4OptionsSSRRTest01);
1584  UtRegisterTest("DecodeIPV4OptionsSSRRTest02", DecodeIPV4OptionsSSRRTest02);
1585  UtRegisterTest("DecodeIPV4OptionsSSRRTest03", DecodeIPV4OptionsSSRRTest03);
1586  UtRegisterTest("DecodeIPV4OptionsSSRRTest04", DecodeIPV4OptionsSSRRTest04);
1587  UtRegisterTest("DecodeIPV4OptionsRTRALTTest01",
1588  DecodeIPV4OptionsRTRALTTest01);
1589  UtRegisterTest("DecodeIPV4OptionsRTRALTTest02",
1590  DecodeIPV4OptionsRTRALTTest02);
1591  UtRegisterTest("IPV4CalculateValidChecksumtest01",
1592  IPV4CalculateValidChecksumtest01);
1593  UtRegisterTest("IPV4CalculateInvalidChecksumtest02",
1594  IPV4CalculateInvalidChecksumtest02);
1595  UtRegisterTest("DecodeIPV4DefragTest01", DecodeIPV4DefragTest01);
1596  UtRegisterTest("DecodeIPV4DefragTest02", DecodeIPV4DefragTest02);
1597  UtRegisterTest("DecodeIPV4DefragTest03", DecodeIPV4DefragTest03);
1598  UtRegisterTest("DecodeEthernetTestIPv4Opt", DecodeEthernetTestIPv4Opt);
1599 #endif /* UNITTESTS */
1600 }
1601 /**
1602  * @}
1603  */
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:1168
DefragDestroy
void DefragDestroy(void)
Definition: defrag.c:1127
IPV4Options_::o_sid
IPV4Opt o_sid
Definition: decode-ipv4.c:288
Packet_::proto
uint8_t proto
Definition: decode.h:513
IPV4_GET_RAW_IPID
#define IPV4_GET_RAW_IPID(ip4h)
Definition: decode-ipv4.h:99
IPV4Options_::o_qs
IPV4Opt o_qs
Definition: decode-ipv4.c:282
IPV4_OPT_FLAG_NOP
#define IPV4_OPT_FLAG_NOP
Definition: decode-ipv4.h:117
len
uint8_t len
Definition: app-layer-dnp3.h:2
DECODE_TUNNEL_IPV6
@ DECODE_TUNNEL_IPV6
Definition: decode.h:1090
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:167
IPV4_OPT_QS_MIN
#define IPV4_OPT_QS_MIN
Definition: decode-ipv4.h:53
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
DecodeUDP
int DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-udp.c:75
IPV4_GET_RAW_IPPROTO
#define IPV4_GET_RAW_IPPROTO(ip4h)
Definition: decode-ipv4.h:103
IPV4_OPT_TS_MIN
#define IPV4_OPT_TS_MIN
Definition: decode-ipv4.h:54
PacketCopyData
int PacketCopyData(Packet *p, const uint8_t *pktdata, uint32_t pktlen)
Copy data to Packet payload and set packet length.
Definition: decode.c:351
IPV4_GET_RAW_FLAG_DF
#define IPV4_GET_RAW_FLAG_DF(ip4h)
Definition: decode-ipv4.h:113
IPV4_GET_RAW_FLAG_MF
#define IPV4_GET_RAW_FLAG_MF(ip4h)
Definition: decode-ipv4.h:112
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
DecodeESP
int DecodeESP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Function to decode IPSEC-ESP packets.
Definition: decode-esp.c:64
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
IPV4_OPT_FLAG_SSRR
#define IPV4_OPT_FLAG_SSRR
Definition: decode-ipv4.h:122
PKT_SRC_DECODER_IPV4
@ PKT_SRC_DECODER_IPV4
Definition: decode.h:57
IPV4Options_::o_ts
IPV4Opt o_ts
Definition: decode-ipv4.c:283
Packet_::flags
uint32_t flags
Definition: decode.h:528
PacketRecycle
void PacketRecycle(Packet *p)
Definition: packet.c:142
IPV4_OPT_SEC
#define IPV4_OPT_SEC
Definition: decode-ipv4.h:38
IPV4_OPT_CIPSO_MIN
#define IPV4_OPT_CIPSO_MIN
Definition: decode-ipv4.h:55
IPV4_OPT_FLAG_TS
#define IPV4_OPT_FLAG_TS
Definition: decode-ipv4.h:119
IPV4_OPT_LSRR
#define IPV4_OPT_LSRR
Definition: decode-ipv4.h:39
PKT_WANTS_FLOW
#define PKT_WANTS_FLOW
Definition: decode.h:1316
IPV4Options_::o_sec
IPV4Opt o_sec
Definition: decode-ipv4.c:284
IPV4_OPT_DUPLICATE
@ IPV4_OPT_DUPLICATE
Definition: decode-events.h:42
IPV4Options_::o_rr
IPV4Opt o_rr
Definition: decode-ipv4.c:281
IPV4_GET_RAW_IPOFFSET
#define IPV4_GET_RAW_IPOFFSET(ip4h)
Definition: decode-ipv4.h:100
IPV4_OPT_FLAG_SEC
#define IPV4_OPT_FLAG_SEC
Definition: decode-ipv4.h:124
IPPROTO_GRE
#define IPPROTO_GRE
Definition: decode-gre.h:30
IP_GET_RAW_VER
#define IP_GET_RAW_VER(pkt)
Definition: decode.h:237
IPV4_OPT_NOP
#define IPV4_OPT_NOP
Definition: decode-ipv4.h:34
IPV4_OPT_FLAG_QS
#define IPV4_OPT_FLAG_QS
Definition: decode-ipv4.h:120
IPV4_OPT_SID_LEN
#define IPV4_OPT_SID_LEN
Definition: decode-ipv4.h:47
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:85
IPV4Opt_::len
uint8_t len
Definition: decode-ipv4.h:67
IPV4_OPT_QS
#define IPV4_OPT_QS
Definition: decode-ipv4.h:36
IPV4_OPT_FLAG_ESEC
#define IPV4_OPT_FLAG_ESEC
Definition: decode-ipv4.h:127
DecodeSCTP
int DecodeSCTP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-sctp.c:62
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:84
IPV4_PKT_TOO_SMALL
@ IPV4_PKT_TOO_SMALL
Definition: decode-events.h:31
tag
uint32_t tag
Definition: decode-vntag.h:0
IPV4_OPT_FLAG_LSRR
#define IPV4_OPT_FLAG_LSRR
Definition: decode-ipv4.h:121
PKT_SET_SRC
#define PKT_SET_SRC(p, src_val)
Definition: decode.h:1342
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:527
IPV4Vars_::opt_cnt
uint16_t opt_cnt
Definition: decode-ipv4.h:131
decode.h
IPV4_OPT_EOL
#define IPV4_OPT_EOL
Definition: decode-ipv4.h:33
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
GET_IPV4_DST_ADDR_PTR
#define GET_IPV4_DST_ADDR_PTR(p)
Definition: decode.h:204
IPV4_WRONG_IP_VER
@ IPV4_WRONG_IP_VER
Definition: decode-events.h:44
IPV4_OPT_EOL_REQUIRED
@ IPV4_OPT_EOL_REQUIRED
Definition: decode-events.h:41
IPV4_GET_RAW_FRAGOFFSET
#define IPV4_GET_RAW_FRAGOFFSET(ip4h)
Definition: decode-ipv4.h:101
PacketDequeueNoLock
Packet * PacketDequeueNoLock(PacketQueueNoLock *qnl)
Definition: packet-queue.c:208
PKT_IS_FRAGMENT
#define PKT_IS_FRAGMENT
Definition: decode.h:1310
IPV4_OPT_ROUTE_MIN
#define IPV4_OPT_ROUTE_MIN
Definition: decode-ipv4.h:52
util-print.h
GET_PKT_DATA
#define GET_PKT_DATA(p)
Definition: decode.h:214
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:57
PrintInet
const char * PrintInet(int af, const void *src, char *dst, socklen_t size)
Definition: util-print.c:241
IPV4_GET_RAW_HLEN
#define IPV4_GET_RAW_HLEN(ip4h)
Definition: decode-ipv4.h:96
IPV4_WITH_ICMPV6
@ IPV4_WITH_ICMPV6
Definition: decode-events.h:45
DecodeGRE
int DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Function to decode GRE packets.
Definition: decode-gre.c:47
IPV4_OPT_RR
#define IPV4_OPT_RR
Definition: decode-ipv4.h:35
IPV4_OPT_FLAG_CIPSO
#define IPV4_OPT_FLAG_CIPSO
Definition: decode-ipv4.h:125
SET_IPV4_SRC_ADDR
#define SET_IPV4_SRC_ADDR(ip4h, a)
Definition: decode.h:145
IPV4_OPT_ESEC
#define IPV4_OPT_ESEC
Definition: decode-ipv4.h:40
IPV4_OPT_FLAG_RTRALT
#define IPV4_OPT_FLAG_RTRALT
Definition: decode-ipv4.h:126
IPV4_OPT_RTRALT_LEN
#define IPV4_OPT_RTRALT_LEN
Definition: decode-ipv4.h:48
IPV4Options_::o_cipso
IPV4Opt o_cipso
Definition: decode-ipv4.c:287
Packet_
Definition: decode.h:491
IPV4_HLEN_TOO_SMALL
@ IPV4_HLEN_TOO_SMALL
Definition: decode-events.h:32
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:213
IPV4_OPT_FLAG_RR
#define IPV4_OPT_FLAG_RR
Definition: decode-ipv4.h:118
ETHERNET_HEADER_LEN
#define ETHERNET_HEADER_LEN
Definition: decode-ethernet.h:27
PacketL3::ip4
IPV4Vars ip4
Definition: decode.h:435
IPV4_OPT_RTRALT
#define IPV4_OPT_RTRALT
Definition: decode-ipv4.h:44
PacketL3::vars
union PacketL3::@31 vars
IPV4_IPLEN_SMALLER_THAN_HLEN
@ IPV4_IPLEN_SMALLER_THAN_HLEN
Definition: decode-events.h:33
defrag.h
IPV4Opt_::data
const uint8_t * data
Definition: decode-ipv4.h:68
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:33
IPV4_OPT_TS
#define IPV4_OPT_TS
Definition: decode-ipv4.h:37
DecodeTCP
int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-tcp.c:270
IPV4Hdr_
Definition: decode-ipv4.h:72
decode-ipv4.h
IPV4_OPT_CIPSO
#define IPV4_OPT_CIPSO
Definition: decode-ipv4.h:41
PacketEnqueueNoLock
void PacketEnqueueNoLock(PacketQueueNoLock *qnl, Packet *p)
Definition: packet-queue.c:168
IPV4Options_
Definition: decode-ipv4.c:280
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
GET_IPV4_SRC_ADDR_PTR
#define GET_IPV4_SRC_ADDR_PTR(p)
Definition: decode.h:203
suricata-common.h
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:675
IPV4_HEADER_LEN
#define IPV4_HEADER_LEN
Definition: decode-ipv4.h:28
packet.h
IPV4Opt_::type
uint8_t type
Definition: decode-ipv4.h:66
IPV4Options
struct IPV4Options_ IPV4Options
IPV4_OPT_PAD_REQUIRED
@ IPV4_OPT_PAD_REQUIRED
Definition: decode-events.h:40
IPV4_OPT_INVALID_LEN
@ IPV4_OPT_INVALID_LEN
Definition: decode-events.h:38
IPV4_GET_RAW_FLAG_RF
#define IPV4_GET_RAW_FLAG_RF(ip4h)
Definition: decode-ipv4.h:114
IPV4Options_::o_rtralt
IPV4Opt o_rtralt
Definition: decode-ipv4.c:290
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
IPV4_TRUNC_PKT
@ IPV4_TRUNC_PKT
Definition: decode-events.h:34
PKT_PPP_VJ_UCOMP
#define PKT_PPP_VJ_UCOMP
Definition: decode.h:1272
DecodeThreadVars_::counter_ipv4
uint16_t counter_ipv4
Definition: decode.h:971
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:232
Packet_::flow_hash
uint32_t flow_hash
Definition: decode.h:534
Packet_::l3
struct PacketL3 l3
Definition: decode.h:592
IPV4_OPT_MALFORMED
@ IPV4_OPT_MALFORMED
Definition: decode-events.h:39
IPV4_OPT_SEC_MIN
#define IPV4_OPT_SEC_MIN
Definition: decode-ipv4.h:51
SCFree
#define SCFree(p)
Definition: util-mem.h:61
IPV4_OPT_SSRR
#define IPV4_OPT_SSRR
Definition: decode-ipv4.h:43
IPV4_OPT_FLAG_EOL
#define IPV4_OPT_FLAG_EOL
Definition: decode-ipv4.h:116
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:955
Packet_::recursion_level
uint8_t recursion_level
Definition: decode.h:516
IPV4Options_::o_lsrr
IPV4Opt o_lsrr
Definition: decode-ipv4.c:285
IPV4_OPT_INVALID
@ IPV4_OPT_INVALID
Definition: decode-events.h:37
ThreadVars_::decode_pq
PacketQueueNoLock decode_pq
Definition: threadvars.h:111
IPV4_OPT_FLAG_SID
#define IPV4_OPT_FLAG_SID
Definition: decode-ipv4.h:123
DecodeIPV4RegisterTests
void DecodeIPV4RegisterTests(void)
Definition: decode-ipv4.c:1555
Packet_::dst
Address dst
Definition: decode.h:496
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1176
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:42
IPV4_OPT_UNKNOWN
@ IPV4_OPT_UNKNOWN
Definition: decode-events.h:43
IPV4Vars_::opts_set
uint16_t opts_set
Definition: decode-ipv4.h:132
IPV4_GET_RAW_IPLEN
#define IPV4_GET_RAW_IPLEN(ip4h)
Definition: decode-ipv4.h:98
IPPROTO_SCTP
#define IPPROTO_SCTP
Definition: decode.h:1212
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:367
Defrag
Packet * Defrag(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
Entry point for IPv4 and IPv6 fragments.
Definition: defrag.c:1058
flow.h
SET_IPV4_DST_ADDR
#define SET_IPV4_DST_ADDR(ip4h, a)
Definition: decode.h:154
DecodeIPV4
int DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-ipv4.c:520
IPV4_OPT_SID
#define IPV4_OPT_SID
Definition: decode-ipv4.h:42
IPV4Opt_
Definition: decode-ipv4.h:61
SCLogDebugEnabled
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition: util-debug.c:771
DecodeEthernet
int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Definition: decode-ethernet.c:42
FlowSetupPacket
void FlowSetupPacket(Packet *p)
prepare packet for a life with flow Set PKT_WANTS_FLOW flag to indicate workers should do a flow look...
Definition: flow-hash.c:521
Packet_::src
Address src
Definition: decode.h:495
PKT_IS_INVALID
#define PKT_IS_INVALID
Definition: decode.h:1311
IPV4Options_::o_ssrr
IPV4Opt o_ssrr
Definition: decode-ipv4.c:289
DefragInit
void DefragInit(void)
Definition: defrag.c:1107
DecodeICMPV4
int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Main ICMPv4 decoding function.
Definition: decode-icmpv4.c:143
IPV4Options_::o_esec
IPV4Opt o_esec
Definition: decode-ipv4.c:286