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 + 3) & 0x00ff;
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  uint8_t *tag;
190  uint16_t len;
191 
192  /* Check length */
193  if (unlikely(o->len < IPV4_OPT_CIPSO_MIN)) {
195  return -1;
196  }
197 
198  /* Data is required */
199  if (unlikely(o->data == NULL)) {
201  return -1;
202  }
203 // doi = *o->data;
204  tag = o->data + 4;
205  len = o->len - 1 - 1 - 4; /* Length of tags after header */
206 
207 
208 #if 0
209  /* Domain of Interest (DOI) of 0 is reserved and thus invalid */
210  /** \todo Aparently a DOI of zero is fine in practice - verify. */
211  if (doi == 0) {
213  return -1;
214  }
215 #endif
216 
217  /* NOTE: We know len has passed min tests prior to this call */
218 
219  /* Check that tags are formatted correctly
220  * [-ttype--][--tlen--][-tagdata-...]
221  */
222  while (len) {
223  uint8_t ttype;
224  uint8_t tlen;
225 
226  /* Tag header must fit within option length */
227  if (unlikely(len < 2)) {
228  //printf("CIPSO tag header too large %" PRIu16 " < 2\n", len);
230  return -1;
231  }
232 
233  /* Tag header is type+len */
234  ttype = *(tag++);
235  tlen = *(tag++);
236 
237  /* Tag length must fit within the option length */
238  if (unlikely(tlen > len)) {
239  //printf("CIPSO tag len too large %" PRIu8 " > %" PRIu16 "\n", tlen, len);
241  return -1;
242  }
243 
244  switch(ttype) {
245  case 1:
246  case 2:
247  case 5:
248  case 6:
249  case 7:
250  /* Tag is at least 4 and at most the remainder of option len */
251  if (unlikely((tlen < 4) || (tlen > len))) {
252  //printf("CIPSO tag %" PRIu8 " bad tlen=%" PRIu8 " len=%" PRIu8 "\n", ttype, tlen, len);
254  return -1;
255  }
256 
257  /* The alignment octet is always 0 except tag
258  * type 7, which has no such field.
259  */
260  if (unlikely((ttype != 7) && (*tag != 0))) {
261  //printf("CIPSO tag %" PRIu8 " ao=%" PRIu8 "\n", ttype, tlen);
263  return -1;
264  }
265 
266  /* Skip the rest of the tag payload */
267  tag += tlen - 2;
268  len -= tlen;
269 
270  continue;
271  case 0:
272  /* Tag type 0 is reserved and thus invalid */
273  /** \todo Wireshark marks this a padding, but spec says reserved. */
275  return -1;
276  default:
277  //printf("CIPSO tag %" PRIu8 " unknown tag\n", ttype);
279  /** \todo May not want to return error here on unknown tag type (at least not for 3|4) */
280  return -1;
281  }
282  }
283 
284  return 0;
285 }
286 
287 typedef struct IPV4Options_ {
297 } IPV4Options;
298 
299 /**
300  * Decode/Validate IPv4 Options.
301  */
302 static void DecodeIPV4Options(Packet *p, uint8_t *pkt, uint16_t len, IPV4Options *opts)
303 {
304  uint16_t plen = len;
305 
306 #ifdef DEBUG
307  if (SCLogDebugEnabled()) {
308  uint16_t i;
309  char buf[256] = "";
310  int offset = 0;
311 
312  for (i = 0; i < len; i++) {
313  offset += snprintf(buf + offset, (sizeof(buf) - offset), "%02" PRIx8 " ", pkt[i]);
314  }
315  SCLogDebug("IPV4OPTS: { %s}", buf);
316  }
317 #endif
318 
319  /* Options length must be padded to 8byte boundary */
320  if (plen % 8) {
322  /* Warn - we can keep going */
323  }
324 
325  while (plen)
326  {
327  p->ip4vars.opt_cnt++;
328 
329  /* single byte options */
330  if (*pkt == IPV4_OPT_EOL) {
331  /** \todo What if more data exist after EOL (possible covert channel or data leakage)? */
332  SCLogDebug("IPV4OPT %" PRIu8 " len 1 @ %d/%d",
333  *pkt, (len - plen), (len - 1));
335  break;
336  } else if (*pkt == IPV4_OPT_NOP) {
337  SCLogDebug("IPV4OPT %" PRIu8 " len 1 @ %d/%d",
338  *pkt, (len - plen), (len - 1));
339  pkt++;
340  plen--;
341 
343 
344  /* multibyte options */
345  } else {
346  if (unlikely(plen < 2)) {
347  /** \todo What if padding is non-zero (possible covert channel or data leakage)? */
348  /** \todo Spec seems to indicate EOL required if there is padding */
350  break;
351  }
352 
353  /* Option length is too big for packet */
354  if (unlikely(*(pkt+1) > plen)) {
356  return;
357  }
358 
359  IPV4Opt opt = {*pkt, *(pkt+1), plen > 2 ? (pkt + 2) : NULL };
360 
361  /* we already know that the total options len is valid,
362  * so here the len of the specific option must be bad.
363  * Also check for invalid lengths 0 and 1. */
364  if (unlikely(opt.len > plen || opt.len < 2)) {
366  return;
367  }
368  /* we are parsing the most commonly used opts to prevent
369  * us from having to walk the opts list for these all the
370  * time. */
371  /** \todo Figure out which IP options are more common and list them first */
372  switch (opt.type) {
373  case IPV4_OPT_TS:
374  if (opts->o_ts.type != 0) {
376  /* Warn - we can keep going */
377  break;
378  } else if (IPV4OptValidateTimestamp(p, &opt)) {
379  return;
380  }
381  opts->o_ts = opt;
383  break;
384  case IPV4_OPT_RR:
385  if (opts->o_rr.type != 0) {
387  /* Warn - we can keep going */
388  break;
389  } else if (IPV4OptValidateRoute(p, &opt) != 0) {
390  return;
391  }
392  opts->o_rr = opt;
394  break;
395  case IPV4_OPT_QS:
396  if (opts->o_qs.type != 0) {
398  /* Warn - we can keep going */
399  break;
400  } else if (IPV4OptValidateGeneric(p, &opt)) {
401  return;
402  }
403  opts->o_qs = opt;
405  break;
406  case IPV4_OPT_SEC:
407  if (opts->o_sec.type != 0) {
409  /* Warn - we can keep going */
410  break;
411  } else if (IPV4OptValidateGeneric(p, &opt)) {
412  return;
413  }
414  opts->o_sec = opt;
416  break;
417  case IPV4_OPT_LSRR:
418  if (opts->o_lsrr.type != 0) {
420  /* Warn - we can keep going */
421  break;
422  } else if (IPV4OptValidateRoute(p, &opt) != 0) {
423  return;
424  }
425  opts->o_lsrr = opt;
427  break;
428  case IPV4_OPT_CIPSO:
429  if (opts->o_cipso.type != 0) {
431  /* Warn - we can keep going */
432  break;
433  } else if (IPV4OptValidateCIPSO(p, &opt) != 0) {
434  return;
435  }
436  opts->o_cipso = opt;
438  break;
439  case IPV4_OPT_SID:
440  if (opts->o_sid.type != 0) {
442  /* Warn - we can keep going */
443  break;
444  } else if (IPV4OptValidateGeneric(p, &opt)) {
445  return;
446  }
447  opts->o_sid = opt;
449  break;
450  case IPV4_OPT_SSRR:
451  if (opts->o_ssrr.type != 0) {
453  /* Warn - we can keep going */
454  break;
455  } else if (IPV4OptValidateRoute(p, &opt) != 0) {
456  return;
457  }
458  opts->o_ssrr = opt;
460  break;
461  case IPV4_OPT_RTRALT:
462  if (opts->o_rtralt.type != 0) {
464  /* Warn - we can keep going */
465  break;
466  } else if (IPV4OptValidateGeneric(p, &opt)) {
467  return;
468  }
469  opts->o_rtralt = opt;
471  break;
472  default:
473  SCLogDebug("IPV4OPT <unknown> (%" PRIu8 ") len %" PRIu8,
474  opt.type, opt.len);
476  /* Warn - we can keep going */
477  break;
478  }
479 
480  pkt += opt.len;
481  plen -= opt.len;
482  }
483  }
484 
485 }
486 
487 static int DecodeIPV4Packet(Packet *p, uint8_t *pkt, uint16_t len)
488 {
489  if (unlikely(len < IPV4_HEADER_LEN)) {
491  return -1;
492  }
493 
494  if (unlikely(IP_GET_RAW_VER(pkt) != 4)) {
495  SCLogDebug("wrong ip version %d",IP_GET_RAW_VER(pkt));
497  return -1;
498  }
499 
500  p->ip4h = (IPV4Hdr *)pkt;
501 
504  return -1;
505  }
506 
507  if (unlikely(IPV4_GET_IPLEN(p) < IPV4_GET_HLEN(p))) {
509  return -1;
510  }
511 
512  if (unlikely(len < IPV4_GET_IPLEN(p))) {
514  return -1;
515  }
516 
517  /* set the address struct */
518  SET_IPV4_SRC_ADDR(p,&p->src);
519  SET_IPV4_DST_ADDR(p,&p->dst);
520 
521  /* save the options len */
522  uint8_t ip_opt_len = IPV4_GET_HLEN(p) - IPV4_HEADER_LEN;
523  if (ip_opt_len > 0) {
524  IPV4Options opts;
525  memset(&opts, 0x00, sizeof(opts));
526  DecodeIPV4Options(p, pkt + IPV4_HEADER_LEN, ip_opt_len, &opts);
527  }
528 
529  return 0;
530 }
531 
532 int DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
533 {
534  StatsIncr(tv, dtv->counter_ipv4);
535 
536  SCLogDebug("pkt %p len %"PRIu16"", pkt, len);
537 
538  /* do the actual decoding */
539  if (unlikely(DecodeIPV4Packet (p, pkt, len) < 0)) {
540  SCLogDebug("decoding IPv4 packet failed");
541  p->ip4h = NULL;
542  return TM_ECODE_FAILED;
543  }
544  p->proto = IPV4_GET_IPPROTO(p);
545 
546  /* If a fragment, pass off for re-assembly. */
547  if (unlikely(IPV4_GET_IPOFFSET(p) > 0 || IPV4_GET_MF(p) == 1)) {
548  Packet *rp = Defrag(tv, dtv, p, pq);
549  if (rp != NULL) {
550  PacketEnqueue(pq, rp);
551  }
552  p->flags |= PKT_IS_FRAGMENT;
553  return TM_ECODE_OK;
554  }
555 
556  /* do hdr test, process hdr rules */
557 
558 #ifdef DEBUG
559  if (SCLogDebugEnabled()) { /* only convert the addresses if debug is really enabled */
560  /* debug print */
561  char s[16], d[16];
562  PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), s, sizeof(s));
563  PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), d, sizeof(d));
564  SCLogDebug("IPV4 %s->%s PROTO: %" PRIu32 " OFFSET: %" PRIu32 " RF: %" PRIu32 " DF: %" PRIu32 " MF: %" PRIu32 " ID: %" PRIu32 "", s,d,
567  }
568 #endif /* DEBUG */
569 
570  /* check what next decoder to invoke */
571  switch (IPV4_GET_IPPROTO(p)) {
572  case IPPROTO_TCP:
573  DecodeTCP(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
574  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq);
575  break;
576  case IPPROTO_UDP:
577  DecodeUDP(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
578  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq);
579  break;
580  case IPPROTO_ICMP:
581  DecodeICMPV4(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
582  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq);
583  break;
584  case IPPROTO_GRE:
585  DecodeGRE(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
586  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq);
587  break;
588  case IPPROTO_SCTP:
589  DecodeSCTP(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
590  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq);
591  break;
592  case IPPROTO_IPV6:
593  {
594  if (pq != NULL) {
595  /* spawn off tunnel packet */
596  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
598  DECODE_TUNNEL_IPV6, pq);
599  if (tp != NULL) {
601  PacketEnqueue(pq,tp);
602  }
603  FlowSetupPacket(p);
604  }
605  break;
606  }
607  case IPPROTO_IP:
608  /* check PPP VJ uncompressed packets and decode tcp dummy */
609  if(p->ppph != NULL && SCNtohs(p->ppph->protocol) == PPP_VJ_UCOMP) {
610  DecodeTCP(tv, dtv, p, pkt + IPV4_GET_HLEN(p),
611  IPV4_GET_IPLEN(p) - IPV4_GET_HLEN(p), pq);
612  }
613  break;
614  case IPPROTO_ICMPV6:
616  break;
617  }
618 
619  return TM_ECODE_OK;
620 }
621 
622 /* UNITTESTS */
623 #ifdef UNITTESTS
624 
625 /** \test IPV4 with no options. */
626 static int DecodeIPV4OptionsNONETest01(void)
627 {
628  uint8_t raw_opts[] = { };
629  Packet *p = PacketGetFromAlloc();
630  FAIL_IF(unlikely(p == NULL));
631 
632  IPV4Options opts;
633  memset(&opts, 0x00, sizeof(opts));
634  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
636 
637  SCFree(p);
638  PASS;
639 }
640 
641 /** \test IPV4 with EOL option. */
642 static int DecodeIPV4OptionsEOLTest01(void)
643 {
644  uint8_t raw_opts[] = {
645  IPV4_OPT_EOL, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
646  };
647  Packet *p = PacketGetFromAlloc();
648  FAIL_IF(unlikely(p == NULL));
649  IPV4Options opts;
650  memset(&opts, 0x00, sizeof(opts));
651  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
653  SCFree(p);
654  PASS;
655 }
656 
657 /** \test IPV4 with NOP option. */
658 static int DecodeIPV4OptionsNOPTest01(void)
659 {
660  uint8_t raw_opts[] = {
661  IPV4_OPT_NOP, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
662  };
663  Packet *p = PacketGetFromAlloc();
664  FAIL_IF(unlikely(p == NULL));
665  IPV4Options opts;
666  memset(&opts, 0x00, sizeof(opts));
667  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
669  SCFree(p);
670  PASS;
671 }
672 
673 /** \test IPV4 with RR option. */
674 static int DecodeIPV4OptionsRRTest01(void)
675 {
676  uint8_t raw_opts[] = {
677  IPV4_OPT_RR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
678  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
679  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
680  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
681  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
682  };
683  Packet *p = PacketGetFromAlloc();
684  FAIL_IF(unlikely(p == NULL));
685 
686  IPV4Options opts;
687  memset(&opts, 0x00, sizeof(opts));
688  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
690  FAIL_IF(opts.o_rr.type != IPV4_OPT_RR);
691  SCFree(p);
692  PASS;
693 }
694 
695 /** \test IPV4 with RR option (len too large). */
696 static int DecodeIPV4OptionsRRTest02(void)
697 {
698  uint8_t raw_opts[] = {
699  IPV4_OPT_RR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
700  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
701  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
702  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
703  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
704  };
705  Packet *p = PacketGetFromAlloc();
706  FAIL_IF(unlikely(p == NULL));
707 
708  IPV4Options opts;
709  memset(&opts, 0x00, sizeof(opts));
710  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
711  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
712  FAIL_IF(opts.o_rr.type != 0);
713  SCFree(p);
714  PASS;
715 }
716 
717 /** \test IPV4 with RR option (ptr too large). */
718 static int DecodeIPV4OptionsRRTest03(void)
719 {
720  uint8_t raw_opts[] = {
721  IPV4_OPT_RR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
722  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
723  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
725  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
726  };
727  Packet *p = PacketGetFromAlloc();
728  FAIL_IF(unlikely(p == NULL));
729 
730  IPV4Options opts;
731  memset(&opts, 0x00, sizeof(opts));
732  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
733  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
734  FAIL_IF(opts.o_rr.type != 0);
735  SCFree(p);
736  PASS;
737 }
738 
739 /** \test IPV4 with RR option (ptr not in 4 byte increment). */
740 static int DecodeIPV4OptionsRRTest04(void)
741 {
742  uint8_t raw_opts[] = {
743  IPV4_OPT_RR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
744  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
745  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
746  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
747  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
748  };
749  Packet *p = PacketGetFromAlloc();
750  FAIL_IF(unlikely(p == NULL));
751 
752  IPV4Options opts;
753  memset(&opts, 0x00, sizeof(opts));
754  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
755  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
756  FAIL_IF(opts.o_rr.type != 0);
757  SCFree(p);
758  PASS;
759 }
760 
761 /** \test IPV4 with QS option. */
762 static int DecodeIPV4OptionsQSTest01(void)
763 {
764  uint8_t raw_opts[] = {
765  IPV4_OPT_QS, 0x08, 0x0d, 0x00, 0xbe, 0xef, 0x00, 0x00
766  };
767  Packet *p = PacketGetFromAlloc();
768  FAIL_IF(unlikely(p == NULL));
769 
770  IPV4Options opts;
771  memset(&opts, 0x00, sizeof(opts));
772  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
774  FAIL_IF(opts.o_qs.type != IPV4_OPT_QS);
775  SCFree(p);
776  PASS;
777 }
778 
779 /** \test IPV4 with QS option (len too small) */
780 static int DecodeIPV4OptionsQSTest02(void)
781 {
782  uint8_t raw_opts[] = {
783  IPV4_OPT_QS, 0x07, 0x0d, 0x00, 0xbe, 0xef, 0x00, 0x00
784  };
785  Packet *p = PacketGetFromAlloc();
786  FAIL_IF(unlikely(p == NULL));
787 
788  IPV4Options opts;
789  memset(&opts, 0x00, sizeof(opts));
790  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
791  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
792  FAIL_IF(opts.o_qs.type != 0);
793  SCFree(p);
794  PASS;
795 }
796 
797 /** \test IPV4 with TS option. */
798 static int DecodeIPV4OptionsTSTest01(void)
799 {
800  uint8_t raw_opts[] = {
801  IPV4_OPT_TS, 0x24, 0x0d, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
802  0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
803  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
804  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
805  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
806  };
807  Packet *p = PacketGetFromAlloc();
808  FAIL_IF(unlikely(p == NULL));
809 
810  IPV4Options opts;
811  memset(&opts, 0x00, sizeof(opts));
812  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
814  FAIL_IF(opts.o_ts.type != IPV4_OPT_TS);
815  SCFree(p);
816  PASS;
817 }
818 
819 /** \test IPV4 with TS option (ptr too small). */
820 static int DecodeIPV4OptionsTSTest02(void)
821 {
822  uint8_t raw_opts[] = {
823  IPV4_OPT_TS, 0x24, 0x04, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
824  0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
825  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
826  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
827  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
828  };
829  Packet *p = PacketGetFromAlloc();
830  FAIL_IF(unlikely(p == NULL));
831 
832  IPV4Options opts;
833  memset(&opts, 0x00, sizeof(opts));
834  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
835  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
836  FAIL_IF(opts.o_ts.type != 0);
837  SCFree(p);
838  PASS;
839 }
840 
841 /** \test IPV4 with TS option (ptr too large). */
842 static int DecodeIPV4OptionsTSTest03(void)
843 {
844  uint8_t raw_opts[] = {
845  IPV4_OPT_TS, 0x24, 0xff, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
846  0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
847  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
848  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
849  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
850  };
851  Packet *p = PacketGetFromAlloc();
852  FAIL_IF(unlikely(p == NULL));
853 
854  IPV4Options opts;
855  memset(&opts, 0x00, sizeof(opts));
856  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
857  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
858  FAIL_IF(opts.o_ts.type != 0);
859  SCFree(p);
860  PASS;
861 }
862 
863 /** \test IPV4 with TS option (ptr not valid). */
864 static int DecodeIPV4OptionsTSTest04(void)
865 {
866  uint8_t raw_opts[] = {
867  IPV4_OPT_TS, 0x24, 0x0a, 0x01, 0x0a, 0x0a, 0x0a, 0x69,
868  0x04, 0xce, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
869  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
870  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
871  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
872  };
873  Packet *p = PacketGetFromAlloc();
874  FAIL_IF(unlikely(p == NULL));
875 
876  IPV4Options opts;
877  memset(&opts, 0x00, sizeof(opts));
878  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
879  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
880  FAIL_IF(opts.o_ts.type != 0);
881  SCFree(p);
882  PASS;
883 }
884 
885 /** \test IPV4 with SEC option. */
886 static int DecodeIPV4OptionsSECTest01(void)
887 {
888  uint8_t raw_opts[] = {
889  IPV4_OPT_SEC, 0x0b, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00,
890  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
891  };
892  Packet *p = PacketGetFromAlloc();
893  FAIL_IF(unlikely(p == NULL));
894 
895  IPV4Options opts;
896  memset(&opts, 0x00, sizeof(opts));
897  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
899  FAIL_IF(opts.o_sec.type != IPV4_OPT_SEC);
900  SCFree(p);
901  PASS;
902 }
903 
904 /** \test IPV4 with SEC option (invalid length). */
905 static int DecodeIPV4OptionsSECTest02(void)
906 {
907  uint8_t raw_opts[] = {
908  IPV4_OPT_SEC, 0x0a, 0xf1, 0x35, 0x00, 0x00, 0x00, 0x00,
909  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
910  };
911  Packet *p = PacketGetFromAlloc();
912  FAIL_IF(unlikely(p == NULL));
913 
914  IPV4Options opts;
915  memset(&opts, 0x00, sizeof(opts));
916  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
917  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
918  FAIL_IF(opts.o_sec.type != 0);
919  SCFree(p);
920  PASS;
921 }
922 
923 /** \test IPV4 with LSRR option. */
924 static int DecodeIPV4OptionsLSRRTest01(void)
925 {
926  uint8_t raw_opts[] = {
927  IPV4_OPT_LSRR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
928  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
929  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
930  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
931  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
932  };
933  Packet *p = PacketGetFromAlloc();
934  FAIL_IF(unlikely(p == NULL));
935 
936  IPV4Options opts;
937  memset(&opts, 0x00, sizeof(opts));
938  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
940  FAIL_IF(opts.o_lsrr.type != IPV4_OPT_LSRR);
941  SCFree(p);
942  PASS;
943 }
944 
945 /** \test IPV4 with LSRR option (len too large). */
946 static int DecodeIPV4OptionsLSRRTest02(void)
947 {
948  uint8_t raw_opts[] = {
949  IPV4_OPT_LSRR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
950  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
951  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
952  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
953  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
954  };
955  Packet *p = PacketGetFromAlloc();
956  FAIL_IF(unlikely(p == NULL));
957 
958  IPV4Options opts;
959  memset(&opts, 0x00, sizeof(opts));
960  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
961  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
962  FAIL_IF(opts.o_lsrr.type != 0);
963  SCFree(p);
964  PASS;
965 }
966 
967 /** \test IPV4 with LSRR option (ptr too large). */
968 static int DecodeIPV4OptionsLSRRTest03(void)
969 {
970  uint8_t raw_opts[] = {
971  IPV4_OPT_LSRR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
972  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
973  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
974  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
975  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
976  };
977  Packet *p = PacketGetFromAlloc();
978  FAIL_IF(unlikely(p == NULL));
979 
980  IPV4Options opts;
981  memset(&opts, 0x00, sizeof(opts));
982  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
983  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
984  FAIL_IF(opts.o_lsrr.type != 0);
985  SCFree(p);
986  PASS;
987 }
988 
989 /** \test IPV4 with LSRR option (ptr not in 4 byte increment). */
990 static int DecodeIPV4OptionsLSRRTest04(void)
991 {
992  uint8_t raw_opts[] = {
993  IPV4_OPT_LSRR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
994  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
995  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
996  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
997  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
998  };
999  Packet *p = PacketGetFromAlloc();
1000  FAIL_IF(unlikely(p == NULL));
1001 
1002  IPV4Options opts;
1003  memset(&opts, 0x00, sizeof(opts));
1004  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1005  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1006  FAIL_IF(opts.o_lsrr.type != 0);
1007  SCFree(p);
1008  PASS;
1009 }
1010 
1011 /** \test IPV4 with CIPSO option. */
1012 static int DecodeIPV4OptionsCIPSOTest01(void)
1013 {
1014  uint8_t raw_opts[] = {
1015  IPV4_OPT_CIPSO, 0x18, 0x00, 0x00, 0x00, 0x05, 0x05, 0x12,
1016  0x00, 0x03, 0x00, 0xef, 0x00, 0xef, 0x00, 0x06,
1017  0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00
1018  };
1019  Packet *p = PacketGetFromAlloc();
1020  FAIL_IF(unlikely(p == NULL));
1021 
1022  IPV4Options opts;
1023  memset(&opts, 0x00, sizeof(opts));
1024  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1027  SCFree(p);
1028  PASS;
1029 }
1030 
1031 /** \test IPV4 with SID option. */
1032 static int DecodeIPV4OptionsSIDTest01(void)
1033 {
1034  uint8_t raw_opts[] = {
1035  IPV4_OPT_SID, 0x04, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1036  };
1037  Packet *p = PacketGetFromAlloc();
1038  FAIL_IF(unlikely(p == NULL));
1039 
1040  IPV4Options opts;
1041  memset(&opts, 0x00, sizeof(opts));
1042  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1044  FAIL_IF(opts.o_sid.type != IPV4_OPT_SID);
1045  SCFree(p);
1046  PASS;
1047 }
1048 
1049 /** \test IPV4 with SID option (len invalid. */
1050 static int DecodeIPV4OptionsSIDTest02(void)
1051 {
1052  uint8_t raw_opts[] = {
1053  IPV4_OPT_SID, 0x05, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1054  };
1055  Packet *p = PacketGetFromAlloc();
1056  FAIL_IF(unlikely(p == NULL));
1057 
1058  IPV4Options opts;
1059  memset(&opts, 0x00, sizeof(opts));
1060  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1061  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1062  FAIL_IF(opts.o_sid.type != 0);
1063  SCFree(p);
1064  PASS;
1065 }
1066 
1067 /** \test IPV4 with SSRR option. */
1068 static int DecodeIPV4OptionsSSRRTest01(void)
1069 {
1070  uint8_t raw_opts[] = {
1071  IPV4_OPT_SSRR, 0x27, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1072  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1073  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1074  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1075  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1076  };
1077  Packet *p = PacketGetFromAlloc();
1078  FAIL_IF(unlikely(p == NULL));
1079 
1080  IPV4Options opts;
1081  memset(&opts, 0x00, sizeof(opts));
1082  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1084  FAIL_IF(opts.o_ssrr.type != IPV4_OPT_SSRR);
1085  SCFree(p);
1086  PASS;
1087 }
1088 
1089 /** \test IPV4 with SSRR option (len too large). */
1090 static int DecodeIPV4OptionsSSRRTest02(void)
1091 {
1092  uint8_t raw_opts[] = {
1093  IPV4_OPT_SSRR, 0xff, 0x08, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1094  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1095  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1096  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1097  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1098  };
1099  Packet *p = PacketGetFromAlloc();
1100  FAIL_IF(unlikely(p == NULL));
1101 
1102  IPV4Options opts;
1103  memset(&opts, 0x00, sizeof(opts));
1104  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1105  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1106  FAIL_IF(opts.o_ssrr.type != 0);
1107  SCFree(p);
1108  PASS;
1109 }
1110 
1111 /** \test IPV4 with SSRR option (ptr too large). */
1112 static int DecodeIPV4OptionsSSRRTest03(void)
1113 {
1114  uint8_t raw_opts[] = {
1115  IPV4_OPT_SSRR, 0x27, 0xff, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1116  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1117  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1118  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1119  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1120  };
1121  Packet *p = PacketGetFromAlloc();
1122  FAIL_IF(unlikely(p == NULL));
1123 
1124  IPV4Options opts;
1125  memset(&opts, 0x00, sizeof(opts));
1126  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1127  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1128  FAIL_IF(opts.o_ssrr.type != 0);
1129  SCFree(p);
1130  PASS;
1131 }
1132 
1133 /** \test IPV4 with SSRR option (ptr not in 4 byte increment). */
1134 static int DecodeIPV4OptionsSSRRTest04(void)
1135 {
1136  uint8_t raw_opts[] = {
1137  IPV4_OPT_SSRR, 0x27, 0x05, 0xc0, 0xa8, 0x2a, 0x64, 0x00,
1138  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1139  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1140  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1141  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1142  };
1143  Packet *p = PacketGetFromAlloc();
1144  FAIL_IF(unlikely(p == NULL));
1145 
1146  IPV4Options opts;
1147  memset(&opts, 0x00, sizeof(opts));
1148  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1149  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1150  FAIL_IF(opts.o_ssrr.type != 0);
1151  SCFree(p);
1152  PASS;
1153 }
1154 
1155 /** \test IPV4 with RTRALT option. */
1156 static int DecodeIPV4OptionsRTRALTTest01(void)
1157 {
1158  uint8_t raw_opts[] = {
1159  IPV4_OPT_RTRALT, 0x04, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1160  };
1161  Packet *p = PacketGetFromAlloc();
1162  FAIL_IF(unlikely(p == NULL));
1163 
1164  IPV4Options opts;
1165  memset(&opts, 0x00, sizeof(opts));
1166  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1169  SCFree(p);
1170  PASS;
1171 }
1172 
1173 /** \test IPV4 with RTRALT option (len invalid. */
1174 static int DecodeIPV4OptionsRTRALTTest02(void)
1175 {
1176  uint8_t raw_opts[] = {
1177  IPV4_OPT_RTRALT, 0x05, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x00
1178  };
1179  Packet *p = PacketGetFromAlloc();
1180  FAIL_IF(unlikely(p == NULL));
1181 
1182  IPV4Options opts;
1183  memset(&opts, 0x00, sizeof(opts));
1184  DecodeIPV4Options(p, raw_opts, sizeof(raw_opts), &opts);
1185  FAIL_IF((p->flags & PKT_IS_INVALID) == 0);
1186  FAIL_IF(opts.o_rtralt.type != 0);
1187  SCFree(p);
1188  PASS;
1189 }
1190 
1191 static int IPV4CalculateValidChecksumtest01(void)
1192 {
1193  uint16_t csum = 0;
1194 
1195  uint8_t raw_ipv4[] = {
1196  0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00,
1197  0x40, 0x01, 0xb7, 0x52, 0xc0, 0xa8, 0x01, 0x03,
1198  0xc0, 0xa8, 0x01, 0x03};
1199 
1200  csum = *( ((uint16_t *)raw_ipv4) + 5);
1201 
1202  FAIL_IF(IPV4Checksum((uint16_t *)raw_ipv4, sizeof(raw_ipv4), csum) != 0);
1203  PASS;
1204 }
1205 
1206 static int IPV4CalculateInvalidChecksumtest02(void)
1207 {
1208  uint16_t csum = 0;
1209 
1210  uint8_t raw_ipv4[] = {
1211  0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00,
1212  0x40, 0x01, 0xb7, 0x52, 0xc0, 0xa8, 0x01, 0x03,
1213  0xc0, 0xa8, 0x01, 0x07};
1214 
1215  csum = *( ((uint16_t *)raw_ipv4) + 5);
1216 
1217  FAIL_IF(IPV4Checksum((uint16_t *)raw_ipv4, sizeof(raw_ipv4), csum) == 0);
1218  PASS;
1219 }
1220 
1221 /**
1222  * \test IPV4 defrag and packet recursion level test
1223  */
1224 static int DecodeIPV4DefragTest01(void)
1225 {
1226  uint8_t pkt1[] = {
1227  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1228  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1229  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1230  0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1231  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1232  0x81, 0x5e
1233  };
1234  uint8_t pkt2[] = {
1235  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1236  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1237  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x01, 0x40, 0x06,
1238  0x9a, 0xc7, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1239  0xe1, 0x0c, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1240  0x80, 0x00
1241  };
1242  uint8_t pkt3[] = {
1243  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1244  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1245  0x00, 0x18, 0xe9, 0xef, 0x00, 0x02, 0x40, 0x06,
1246  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1247  0xe1, 0x0c, 0xb1, 0xa3, 0x00, 0x00
1248  };
1249  uint8_t tunnel_pkt[] = {
1250  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1251  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1252  0x00, 0x28, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1253  0xba, 0xbc, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1254  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1255  0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1256  0x80, 0x00, 0xb1, 0xa3, 0x00, 0x00
1257  };
1258 
1259  Packet *p = PacketGetFromAlloc();
1260  if (unlikely(p == NULL))
1261  return 0;
1262  ThreadVars tv;
1263  DecodeThreadVars dtv;
1264  PacketQueue pq;
1265  int result = 1;
1266 
1267  memset(&tv, 0, sizeof(ThreadVars));
1268  memset(&dtv, 0, sizeof(DecodeThreadVars));
1269  memset(&pq, 0, sizeof(PacketQueue));
1270 
1272  DefragInit();
1273 
1274  PacketCopyData(p, pkt1, sizeof(pkt1));
1275  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1276  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
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, pkt2, sizeof(pkt2));
1285  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1286  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
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  }
1292  PACKET_RECYCLE(p);
1293 
1294  PacketCopyData(p, pkt3, sizeof(pkt3));
1295  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1296  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
1297  if (p->tcph != NULL) {
1298  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1299  result = 0;
1300  goto end;
1301  }
1302  Packet *tp = PacketDequeue(&pq);
1303  if (tp == NULL) {
1304  printf("Failed to get defragged pseudo packet\n");
1305  result = 0;
1306  goto end;
1307  }
1308  if (tp->recursion_level != p->recursion_level) {
1309  printf("defragged pseudo packet's and parent packet's recursion "
1310  "level don't match\n %d != %d",
1312  result = 0;
1313  goto end;
1314  }
1315  if (tp->ip4h == NULL || tp->tcph == NULL) {
1316  printf("pseudo packet's ip header and tcp header shouldn't be NULL, "
1317  "but it is\n");
1318  result = 0;
1319  goto end;
1320  }
1321  if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) {
1322  printf("defragged pseudo packet's and parent packet's pkt lens "
1323  "don't match\n %u != %"PRIuMAX,
1324  GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt));
1325  result = 0;
1326  goto end;
1327  }
1328  if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) {
1329  result = 0;
1330  goto end;
1331  }
1332 
1333  PACKET_RECYCLE(tp);
1334  SCFree(tp);
1335 
1336 end:
1337  DefragDestroy();
1338  PACKET_RECYCLE(p);
1339  FlowShutdown();
1340  SCFree(p);
1341  return result;
1342 }
1343 
1344 /**
1345  * \test Don't send IPv4 fragments to the upper layer decoder and
1346  * and packet recursion level test.
1347  */
1348 static int DecodeIPV4DefragTest02(void)
1349 {
1350  uint8_t pkt1[] = {
1351  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1352  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1353  0x00, 0x24, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1354  0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1355  0xe1, 0x0c,
1356  /* first frag */
1357  0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1358  0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1359  0x80, 0x00,
1360  };
1361  uint8_t pkt2[] = {
1362  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1363  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1364  0x00, 0x2c, 0xe9, 0xef, 0x20, 0x02, 0x40, 0x06,
1365  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1366  0xe1, 0x0c,
1367  /* second frag */
1368  0xb1, 0xa3, 0x00, 0x10, 0x5b, 0xa3, 0x81, 0x5e,
1369  0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1370  0xb1, 0xa3, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04
1371  };
1372  uint8_t pkt3[] = {
1373  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1374  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1375  0x00, 0x16, 0xe9, 0xef, 0x00, 0x05, 0x40, 0x06,
1376  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1377  0xe1, 0x0c,
1378  /* final frag */
1379  0xb1, 0xa3,
1380  };
1381 
1382  uint8_t tunnel_pkt[] = {
1383  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1384  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1385  0x00, 0x3e, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1386  0xba, 0xae, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1387  0xe1, 0x0c,
1388  0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3, 0x81, 0x5e,
1389  0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1390  0xb1, 0xa3, 0x00, 0x10, 0x5b, 0xa3, 0x81, 0x5e,
1391  0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10, 0x80, 0x00,
1392  0xb1, 0xa3, 0x00, 0x10, 0x01, 0x02, 0x03, 0x04,
1393  0xb1, 0xa3,
1394  };
1395 
1396  Packet *p = PacketGetFromAlloc();
1397  if (unlikely(p == NULL))
1398  return 0;
1399  ThreadVars tv;
1400  DecodeThreadVars dtv;
1401  PacketQueue pq;
1402  int result = 0;
1403 
1404  memset(&tv, 0, sizeof(ThreadVars));
1405  memset(&dtv, 0, sizeof(DecodeThreadVars));
1406  memset(&pq, 0, sizeof(PacketQueue));
1407 
1409  DefragInit();
1410 
1411  PacketCopyData(p, pkt1, sizeof(pkt1));
1412  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1413  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
1414  if (p->tcph != NULL) {
1415  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1416  goto end;
1417  }
1418  PACKET_RECYCLE(p);
1419 
1420  PacketCopyData(p, pkt2, sizeof(pkt2));
1421  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1422  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
1423  if (p->tcph != NULL) {
1424  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1425  goto end;
1426  }
1427  PACKET_RECYCLE(p);
1428 
1429  p->recursion_level = 3;
1430  PacketCopyData(p, pkt3, sizeof(pkt3));
1431  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1432  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
1433  if (p->tcph != NULL) {
1434  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1435  goto end;
1436  }
1437  Packet *tp = PacketDequeue(&pq);
1438  if (tp == NULL) {
1439  printf("Failed to get defragged pseudo packet\n");
1440  goto end;
1441  }
1442  if (tp->recursion_level != p->recursion_level) {
1443  printf("defragged pseudo packet's and parent packet's recursion "
1444  "level don't match %d != %d: ",
1446  goto end;
1447  }
1448  if (tp->ip4h == NULL || tp->tcph == NULL) {
1449  printf("pseudo packet's ip header and tcp header shouldn't be NULL, "
1450  "but it is\n");
1451  goto end;
1452  }
1453  if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) {
1454  printf("defragged pseudo packet's and parent packet's pkt lens "
1455  "don't match %u != %"PRIuMAX": ",
1456  GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt));
1457  goto end;
1458  }
1459 
1460  if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) {
1461  goto end;
1462  }
1463 
1464  result = 1;
1465  PACKET_RECYCLE(tp);
1466  SCFree(tp);
1467 
1468 end:
1469  DefragDestroy();
1470  PACKET_RECYCLE(p);
1471  FlowShutdown();
1472  SCFree(p);
1473  return result;
1474 }
1475 
1476 /**
1477  * \test IPV4 defrag and flow retrieval test.
1478  */
1479 static int DecodeIPV4DefragTest03(void)
1480 {
1481  uint8_t pkt[] = {
1482  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1483  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1484  0x00, 0x28, 0xe9, 0xee, 0x00, 0x00, 0x40, 0x06,
1485  0xba, 0xbd, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1486  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1487  0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02,
1488  0x80, 0x00, 0x0c, 0xee, 0x00, 0x00
1489  };
1490  uint8_t pkt1[] = {
1491  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1492  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1493  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x00, 0x40, 0x06,
1494  0x9a, 0xc8, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1495  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1496  0x81, 0x5e
1497  };
1498  uint8_t pkt2[] = {
1499  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1500  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1501  0x00, 0x1c, 0xe9, 0xef, 0x20, 0x01, 0x40, 0x06,
1502  0x9a, 0xc7, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1503  0xe1, 0x0c, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1504  0x80, 0x00
1505  };
1506  uint8_t pkt3[] = {
1507  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1508  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1509  0x00, 0x18, 0xe9, 0xef, 0x00, 0x02, 0x40, 0x06,
1510  0xba, 0xca, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1511  0xe1, 0x0c, 0xb1, 0xa3, 0x00, 0x00
1512  };
1513  uint8_t tunnel_pkt[] = {
1514  0x00, 0x50, 0x56, 0x00, 0x03, 0x05, 0xde, 0xad,
1515  0x01, 0xa3, 0xa2, 0x2f, 0x08, 0x00, 0x45, 0x00,
1516  0x00, 0x28, 0xe9, 0xef, 0x00, 0x00, 0x40, 0x06,
1517  0xba, 0xbc, 0x0a, 0x00, 0xe1, 0x17, 0x0a, 0x00,
1518  0xe1, 0x0c, 0x6e, 0x12, 0x01, 0xbd, 0x5b, 0xa3,
1519  0x81, 0x5e, 0xac, 0xb0, 0xae, 0x8a, 0x50, 0x10,
1520  0x80, 0x00, 0xb1, 0xa3, 0x00, 0x00
1521  };
1522 
1523  Packet *p = PacketGetFromAlloc();
1524  if (unlikely(p == NULL))
1525  return 0;
1526  ThreadVars tv;
1527  DecodeThreadVars dtv;
1528  PacketQueue pq;
1529  int result = 1;
1530 
1531  memset(&tv, 0, sizeof(ThreadVars));
1532  memset(&dtv, 0, sizeof(DecodeThreadVars));
1533  memset(&pq, 0, sizeof(PacketQueue));
1534 
1536  DefragInit();
1537 
1538  PacketCopyData(p, pkt, sizeof(pkt));
1539  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1540  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
1541  if (p->tcph == NULL) {
1542  printf("tcp header shouldn't be NULL, but it is\n");
1543  result = 0;
1544  goto end;
1545  }
1546  if (!(p->flags & PKT_WANTS_FLOW)) {
1547  printf("packet flow shouldn't be NULL\n");
1548  result = 0;
1549  goto end;
1550  }
1551  PACKET_RECYCLE(p);
1552 
1553  PacketCopyData(p, pkt1, sizeof(pkt1));
1554  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1555  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
1556  if (p->tcph != NULL) {
1557  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1558  result = 0;
1559  goto end;
1560  }
1561  PACKET_RECYCLE(p);
1562 
1563  PacketCopyData(p, pkt2, sizeof(pkt2));
1564  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1565  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
1566  if (p->tcph != NULL) {
1567  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1568  result = 0;
1569  goto end;
1570  }
1571  PACKET_RECYCLE(p);
1572 
1573  PacketCopyData(p, pkt3, sizeof(pkt3));
1574  DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
1575  GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
1576  if (p->tcph != NULL) {
1577  printf("tcp header should be NULL for ip fragment, but it isn't\n");
1578  result = 0;
1579  goto end;
1580  }
1581 
1582  Packet *tp = PacketDequeue(&pq);
1583  if (tp == NULL) {
1584  printf("Failed to get defragged pseudo packet\n");
1585  result = 0;
1586  goto end;
1587  }
1588  if (!(tp->flags & PKT_WANTS_FLOW)) {
1589  result = 0;
1590  goto end;
1591  }
1592  if (tp->flow_hash != p->flow_hash) {
1593  result = 0;
1594  goto end;
1595  }
1596  if (tp->recursion_level != p->recursion_level) {
1597  printf("defragged pseudo packet's and parent packet's recursion "
1598  "level don't match\n %d != %d",
1600  result = 0;
1601  goto end;
1602  }
1603  if (tp->ip4h == NULL || tp->tcph == NULL) {
1604  printf("pseudo packet's ip header and tcp header shouldn't be NULL, "
1605  "but it is\n");
1606  result = 0;
1607  goto end;
1608  }
1609  if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) {
1610  printf("defragged pseudo packet's and parent packet's pkt lens "
1611  "don't match\n %u != %"PRIuMAX,
1612  GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt));
1613  result = 0;
1614  goto end;
1615  }
1616 
1617  if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) {
1618  result = 0;
1619  goto end;
1620  }
1621 
1622  PACKET_RECYCLE(tp);
1623  SCFree(tp);
1624 
1625 end:
1626  DefragDestroy();
1627  PACKET_RECYCLE(p);
1628  FlowShutdown();
1629  SCFree(p);
1630  return result;
1631 }
1632 
1633 #endif /* UNITTESTS */
1634 
1636 {
1637 #ifdef UNITTESTS
1638  UtRegisterTest("DecodeIPV4OptionsNONETest01", DecodeIPV4OptionsNONETest01);
1639  UtRegisterTest("DecodeIPV4OptionsEOLTest01", DecodeIPV4OptionsEOLTest01);
1640  UtRegisterTest("DecodeIPV4OptionsNOPTest01", DecodeIPV4OptionsNOPTest01);
1641  UtRegisterTest("DecodeIPV4OptionsRRTest01", DecodeIPV4OptionsRRTest01);
1642  UtRegisterTest("DecodeIPV4OptionsRRTest02", DecodeIPV4OptionsRRTest02);
1643  UtRegisterTest("DecodeIPV4OptionsRRTest03", DecodeIPV4OptionsRRTest03);
1644  UtRegisterTest("DecodeIPV4OptionsRRTest04", DecodeIPV4OptionsRRTest04);
1645  UtRegisterTest("DecodeIPV4OptionsQSTest01", DecodeIPV4OptionsQSTest01);
1646  UtRegisterTest("DecodeIPV4OptionsQSTest02", DecodeIPV4OptionsQSTest02);
1647  UtRegisterTest("DecodeIPV4OptionsTSTest01", DecodeIPV4OptionsTSTest01);
1648  UtRegisterTest("DecodeIPV4OptionsTSTest02", DecodeIPV4OptionsTSTest02);
1649  UtRegisterTest("DecodeIPV4OptionsTSTest03", DecodeIPV4OptionsTSTest03);
1650  UtRegisterTest("DecodeIPV4OptionsTSTest04", DecodeIPV4OptionsTSTest04);
1651  UtRegisterTest("DecodeIPV4OptionsSECTest01", DecodeIPV4OptionsSECTest01);
1652  UtRegisterTest("DecodeIPV4OptionsSECTest02", DecodeIPV4OptionsSECTest02);
1653  UtRegisterTest("DecodeIPV4OptionsLSRRTest01", DecodeIPV4OptionsLSRRTest01);
1654  UtRegisterTest("DecodeIPV4OptionsLSRRTest02", DecodeIPV4OptionsLSRRTest02);
1655  UtRegisterTest("DecodeIPV4OptionsLSRRTest03", DecodeIPV4OptionsLSRRTest03);
1656  UtRegisterTest("DecodeIPV4OptionsLSRRTest04", DecodeIPV4OptionsLSRRTest04);
1657  UtRegisterTest("DecodeIPV4OptionsCIPSOTest01",
1658  DecodeIPV4OptionsCIPSOTest01);
1659  UtRegisterTest("DecodeIPV4OptionsSIDTest01", DecodeIPV4OptionsSIDTest01);
1660  UtRegisterTest("DecodeIPV4OptionsSIDTest02", DecodeIPV4OptionsSIDTest02);
1661  UtRegisterTest("DecodeIPV4OptionsSSRRTest01", DecodeIPV4OptionsSSRRTest01);
1662  UtRegisterTest("DecodeIPV4OptionsSSRRTest02", DecodeIPV4OptionsSSRRTest02);
1663  UtRegisterTest("DecodeIPV4OptionsSSRRTest03", DecodeIPV4OptionsSSRRTest03);
1664  UtRegisterTest("DecodeIPV4OptionsSSRRTest04", DecodeIPV4OptionsSSRRTest04);
1665  UtRegisterTest("DecodeIPV4OptionsRTRALTTest01",
1666  DecodeIPV4OptionsRTRALTTest01);
1667  UtRegisterTest("DecodeIPV4OptionsRTRALTTest02",
1668  DecodeIPV4OptionsRTRALTTest02);
1669  UtRegisterTest("IPV4CalculateValidChecksumtest01",
1670  IPV4CalculateValidChecksumtest01);
1671  UtRegisterTest("IPV4CalculateInvalidChecksumtest02",
1672  IPV4CalculateInvalidChecksumtest02);
1673  UtRegisterTest("DecodeIPV4DefragTest01", DecodeIPV4DefragTest01);
1674  UtRegisterTest("DecodeIPV4DefragTest02", DecodeIPV4DefragTest02);
1675  UtRegisterTest("DecodeIPV4DefragTest03", DecodeIPV4DefragTest03);
1676 #endif /* UNITTESTS */
1677 }
1678 /**
1679  * @}
1680  */
#define PPP_VJ_UCOMP
Definition: decode-ppp.h:30
#define GET_IPV4_SRC_ADDR_PTR(p)
Definition: decode.h:214
void FlowSetupPacket(Packet *p)
prepare packet for a life with flow Set PKT_WANTS_FLOW flag to incidate workers should do a flow look...
Definition: flow-hash.c:407
IPV4Vars ip4vars
Definition: decode.h:506
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:989
#define SCLogDebug(...)
Definition: util-debug.h:335
#define IPV4_GET_MF(p)
Definition: decode-ipv4.h:144
#define SET_IPV4_SRC_ADDR(p, a)
Definition: decode.h:138
IPV4Opt o_rr
Definition: decode-ipv4.c:288
#define IPV4_OPT_SID_LEN
Definition: decode-ipv4.h:47
#define IPV4_GET_IPPROTO(p)
Definition: decode-ipv4.h:148
int DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
Function to decode GRE packets.
Definition: decode-gre.c:46
#define PASS
Pass the test.
#define unlikely(expr)
Definition: util-optimize.h:35
#define GET_IPV4_DST_ADDR_PTR(p)
Definition: decode.h:215
#define IPV4_OPT_SEC_LEN
Definition: decode-ipv4.h:46
uint8_t len
Definition: decode-ipv4.h:66
#define IPV4_OPT_LSRR
Definition: decode-ipv4.h:39
#define PKT_IS_FRAGMENT
Definition: decode.h:1105
int DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
Definition: decode-udp.c:74
#define IPV4_OPT_SEC
Definition: decode-ipv4.h:38
#define IPV4_OPT_ROUTE_MIN
Definition: decode-ipv4.h:51
IPV4Opt o_lsrr
Definition: decode-ipv4.c:292
uint64_t offset
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
#define FLOW_QUIET
Definition: flow.h:38
Address dst
Definition: decode.h:413
IPV4Opt o_cipso
Definition: decode-ipv4.c:293
#define PACKET_RECYCLE(p)
Definition: decode.h:814
int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
Definition: decode-tcp.c:199
uint16_t counter_ipv4
Definition: decode.h:646
void DefragDestroy(void)
Definition: defrag.c:1067
TCPHdr * tcph
Definition: decode.h:522
#define IPV4_GET_IPOFFSET(p)
Definition: decode-ipv4.h:135
IPV4Opt o_sid
Definition: decode-ipv4.c:294
int DecodeSCTP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
Definition: decode-sctp.c:62
#define IPV4_OPT_QS
Definition: decode-ipv4.h:36
#define IPV4_GET_DF(p)
Definition: decode-ipv4.h:141
void DecodeIPV4RegisterTests(void)
Definition: decode-ipv4.c:1635
#define IPV4_OPT_QS_MIN
Definition: decode-ipv4.h:52
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition: util-debug.c:631
#define PKT_SET_SRC(p, src_val)
Definition: decode.h:1132
int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
Main ICMPv4 decoding function.
#define IPPROTO_GRE
Definition: decode-gre.h:30
IPV4Opt o_ssrr
Definition: decode-ipv4.c:295
int DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
Definition: decode-ipv4.c:532
#define IPV4_OPT_TS
Definition: decode-ipv4.h:37
#define IPV4_OPT_SID
Definition: decode-ipv4.h:41
IPV4Opt o_sec
Definition: decode-ipv4.c:291
#define IPV4_OPT_CIPSO
Definition: decode-ipv4.h:40
uint8_t proto
Definition: decode.h:430
PPPHdr * ppph
Definition: decode.h:532
uint8_t recursion_level
Definition: decode.h:433
IPV4Opt o_rtralt
Definition: decode-ipv4.c:296
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Structure to hold thread specific data for all decode modules.
Definition: decode.h:632
#define IPV4_OPT_RTRALT_LEN
Definition: decode-ipv4.h:48
#define IP_GET_RAW_VER(pkt)
Definition: decode.h:249
uint16_t opt_cnt
Definition: decode-ipv4.h:176
struct IPV4Options_ IPV4Options
uint8_t * data
Definition: decode-ipv4.h:67
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:163
const char * PrintInet(int af, const void *src, char *dst, socklen_t size)
Definition: util-print.c:267
#define IPV4_GET_RF(p)
Definition: decode-ipv4.h:138
#define IPV4_OPT_RTRALT
Definition: decode-ipv4.h:43
#define IPV4_GET_HLEN(p)
Definition: decode-ipv4.h:123
void DefragInit(void)
Definition: defrag.c:1045
#define ETHERNET_HEADER_LEN
IPV4Hdr * ip4h
Definition: decode.h:500
#define IPV4_GET_IPLEN(p)
Definition: decode-ipv4.h:127
#define IPV4_OPT_EOL
Definition: decode-ipv4.h:33
uint8_t tag
#define SCFree(a)
Definition: util-mem.h:322
#define SCNtohs(x)
#define IPV4_OPT_NOP
Definition: decode-ipv4.h:34
IPV4Opt o_qs
Definition: decode-ipv4.c:289
Packet * Defrag(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, PacketQueue *pq)
Entry point for IPv4 and IPv6 fragments.
Definition: defrag.c:999
#define IPV4_OPT_CIPSO_MIN
Definition: decode-ipv4.h:54
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:667
#define SET_IPV4_DST_ADDR(p, a)
Definition: decode.h:146
#define GET_PKT_DATA(p)
Definition: decode.h:225
Packet * PacketDequeue(PacketQueue *q)
Definition: packet-queue.c:167
#define IPV4_OPT_TS_MIN
Definition: decode-ipv4.h:53
uint16_t opts_set
Definition: decode-ipv4.h:177
#define PKT_WANTS_FLOW
Definition: decode.h:1111
uint32_t flow_hash
Definition: decode.h:449
uint8_t len
Per thread variable structure.
Definition: threadvars.h:57
#define GET_PKT_LEN(p)
Definition: decode.h:224
uint32_t flags
Definition: decode.h:443
Packet * PacketTunnelPktSetup(ThreadVars *tv, DecodeThreadVars *dtv, Packet *parent, uint8_t *pkt, uint32_t len, enum DecodeTunnelProto proto, PacketQueue *pq)
Setup a pseudo packet (tunnel)
Definition: decode.c:275
IPV4Opt o_ts
Definition: decode-ipv4.c:290
#define IPV4_OPT_RR
Definition: decode-ipv4.h:35
#define IPV4_HEADER_LEN
Definition: decode-ipv4.h:28
#define IPV4_GET_IPID(p)
Definition: decode-ipv4.h:129
uint8_t type
Definition: decode-ipv4.h:65
#define PKT_IS_INVALID
Definition: decode.h:1106
int PacketCopyData(Packet *p, uint8_t *pktdata, uint32_t pktlen)
Copy data to Packet payload and set packet length.
Definition: decode.c:259
#define IPV4_OPT_SSRR
Definition: decode-ipv4.h:42
void PacketEnqueue(PacketQueue *q, Packet *p)
Definition: packet-queue.c:139
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:997
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:141
Address src
Definition: decode.h:412
void FlowInitConfig(char quiet)
initialize the configuration
Definition: flow.c:512