suricata
decode-ipv6.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2025 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  *
30  * Decode IPv6
31  */
32 
33 #include "suricata-common.h"
34 #include "decode-ipv6.h"
35 #include "decode.h"
36 #include "defrag.h"
37 #include "flow-hash.h"
38 #include "util-print.h"
39 #include "util-validate.h"
40 
41 /**
42  * \brief Function to decode IPv4 in IPv6 packets
43  *
44  */
45 static void DecodeIPv4inIPv6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t plen)
46 {
47 
48  if (unlikely(plen < IPV4_HEADER_LEN)) {
50  return;
51  }
52  if (IP_GET_RAW_VER(pkt) == 4) {
53  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt, plen, DECODE_TUNNEL_IPV4);
54  if (tp != NULL) {
58  }
59  FlowSetupPacket(p);
60  } else {
62  }
63 }
64 
65 /**
66  * \brief Function to decode IPv6 in IPv6 packets
67  *
68  */
69 static int DecodeIP6inIP6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
70  const uint8_t *pkt, uint16_t plen)
71 {
72 
73  if (unlikely(plen < IPV6_HEADER_LEN)) {
75  return TM_ECODE_FAILED;
76  }
77  if (IP_GET_RAW_VER(pkt) == 6) {
78  Packet *tp = PacketTunnelPktSetup(tv, dtv, p, pkt, plen, DECODE_TUNNEL_IPV6);
79  if (tp != NULL) {
83  }
84  FlowSetupPacket(p);
85  } else {
87  }
88  return TM_ECODE_OK;
89 }
90 
91 #ifndef UNITTESTS // ugly, but we need this in defrag tests
92 static inline
93 #endif
94 void DecodeIPV6FragHeader(Packet *p, const uint8_t *pkt,
95  uint16_t hdrextlen, uint16_t plen,
96  uint16_t prev_hdrextlen)
97 {
98  uint16_t frag_offset = (*(pkt + 2) << 8 | *(pkt + 3)) & 0xFFF8;
99  int frag_morefrags = (*(pkt + 2) << 8 | *(pkt + 3)) & 0x0001;
100 
101  p->l3.vars.ip6.eh.fh_offset = frag_offset;
102  p->l3.vars.ip6.eh.fh_more_frags_set = frag_morefrags ? true : false;
103  p->l3.vars.ip6.eh.fh_nh = *pkt;
104 
105  uint32_t fh_id;
106  memcpy(&fh_id, pkt+4, 4);
107  p->l3.vars.ip6.eh.fh_id = SCNtohl(fh_id);
108 
109  SCLogDebug("IPV6 FH: offset %u, mf %s, nh %u, id %u/%x", p->l3.vars.ip6.eh.fh_offset,
110  p->l3.vars.ip6.eh.fh_more_frags_set ? "true" : "false", p->l3.vars.ip6.eh.fh_nh,
111  p->l3.vars.ip6.eh.fh_id, p->l3.vars.ip6.eh.fh_id);
112 
113  // store header offset, data offset
114  uint16_t frag_hdr_offset = (uint16_t)(pkt - GET_PKT_DATA(p));
115  uint16_t data_offset = (uint16_t)(frag_hdr_offset + hdrextlen);
116  uint16_t data_len = plen - hdrextlen;
117 
118  p->l3.vars.ip6.eh.fh_header_offset = frag_hdr_offset;
119  p->l3.vars.ip6.eh.fh_data_offset = data_offset;
120  p->l3.vars.ip6.eh.fh_data_len = data_len;
121 
122  /* if we have a prev hdr, store the type and offset of it */
123  if (prev_hdrextlen) {
124  p->l3.vars.ip6.eh.fh_prev_hdr_offset = frag_hdr_offset - prev_hdrextlen;
125  }
126 
127  SCLogDebug("IPV6 FH: frag_hdr_offset %u, data_offset %u, data_len %u",
128  p->l3.vars.ip6.eh.fh_header_offset, p->l3.vars.ip6.eh.fh_data_offset,
129  p->l3.vars.ip6.eh.fh_data_len);
130 }
131 
132 static void DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const IPV6Hdr *ip6h,
133  const uint8_t *pkt, uint16_t len)
134 {
135  SCEnter();
136 
137  const uint8_t *orig_pkt = pkt;
138  uint8_t nh = IPV6_GET_RAW_NH(ip6h); /* careful, 0 is actually a real type */
139  uint16_t hdrextlen = 0;
140  uint16_t plen = len;
141  char dstopts = 0;
142  char exthdr_fh_done = 0;
143  int hh = 0;
144  int rh = 0;
145  int ah = 0;
146 
147  while(1)
148  {
149  IPV6_SET_EXTHDRS_LEN(p, (len - plen));
150 
151  if (nh == IPPROTO_NONE) {
152  if (plen > 0) {
153  /* No upper layer, but we do have data. Suspicious. */
155  }
156  SCReturn;
157  }
158 
159  if (plen < 2) { /* minimal needed in a hdr */
161  SCReturn;
162  }
163 
164  switch(nh)
165  {
166  case IPPROTO_TCP:
167  IPV6_SET_L4PROTO(p,nh);
168  DecodeTCP(tv, dtv, p, pkt, plen);
169  SCReturn;
170 
171  case IPPROTO_UDP:
172  IPV6_SET_L4PROTO(p,nh);
173  DecodeUDP(tv, dtv, p, pkt, plen);
174  SCReturn;
175 
176  case IPPROTO_ICMPV6:
177  IPV6_SET_L4PROTO(p,nh);
178  DecodeICMPV6(tv, dtv, p, pkt, plen);
179  SCReturn;
180 
181  case IPPROTO_SCTP:
182  IPV6_SET_L4PROTO(p,nh);
183  DecodeSCTP(tv, dtv, p, pkt, plen);
184  SCReturn;
185 
186  case IPPROTO_ROUTING:
187  IPV6_SET_L4PROTO(p,nh);
188  hdrextlen = 8 + (*(pkt+1) * 8); /* 8 bytes + length in 8 octet units */
189 
190  SCLogDebug("hdrextlen %"PRIu16, hdrextlen);
191 
192  if (hdrextlen > plen) {
194  SCReturn;
195  }
196 
197  if (rh) {
199  /* skip past this extension so we can continue parsing the rest
200  * of the packet */
201  nh = *pkt;
202  pkt += hdrextlen;
203  plen -= hdrextlen;
204  break;
205  }
206 
207  rh = 1;
209 
210  uint8_t ip6rh_type = *(pkt + 2);
211  if (ip6rh_type == 0) {
213  }
214  p->l3.vars.ip6.eh.rh_type = ip6rh_type;
215 
216  nh = *pkt;
217  pkt += hdrextlen;
218  plen -= hdrextlen;
219  break;
220 
221  case IPPROTO_HOPOPTS:
222  case IPPROTO_DSTOPTS:
223  {
224  IPV6OptHAO hao_s, *hao = &hao_s;
225  IPV6OptRA ra_s, *ra = &ra_s;
226  IPV6OptJumbo jumbo_s, *jumbo = &jumbo_s;
227  uint16_t optslen = 0;
228 
229  IPV6_SET_L4PROTO(p,nh);
230  hdrextlen = (uint16_t)((*(pkt + 1) + 1) << 3);
231  if (hdrextlen > plen) {
233  SCReturn;
234  }
235 
236  const uint8_t *ptr = pkt + 2; /* +2 to go past nxthdr and len */
237 
238  /* point the pointers to right structures
239  * in Packet. */
240  if (nh == IPPROTO_HOPOPTS) {
241  if (hh) {
243  /* skip past this extension so we can continue parsing the rest
244  * of the packet */
245  nh = *pkt;
246  pkt += hdrextlen;
247  plen -= hdrextlen;
248  break;
249  }
250 
251  hh = 1;
252 
253  optslen = (uint16_t)((*(pkt + 1) + 1) << 3) - 2;
254  }
255  else if (nh == IPPROTO_DSTOPTS)
256  {
257  if (dstopts == 0) {
258  optslen = (uint16_t)((*(pkt + 1) + 1) << 3) - 2;
259  dstopts = 1;
260  } else if (dstopts == 1) {
261  optslen = (uint16_t)((*(pkt + 1) + 1) << 3) - 2;
262  dstopts = 2;
263  } else {
265  /* skip past this extension so we can continue parsing the rest
266  * of the packet */
267  nh = *pkt;
268  pkt += hdrextlen;
269  plen -= hdrextlen;
270  break;
271  }
272  }
273 
274  if (optslen > plen) {
275  /* since the packet is long enough (we checked
276  * plen against hdrlen, the optlen must be malformed. */
278  /* skip past this extension so we can continue parsing the rest
279  * of the packet */
280  nh = *pkt;
281  pkt += hdrextlen;
282  plen -= hdrextlen;
283  break;
284  }
285 /** \todo move into own function to loaded on demand */
286  uint16_t padn_cnt = 0;
287  uint16_t other_cnt = 0;
288  uint16_t offset = 0;
289  while(offset < optslen)
290  {
291  if (*ptr == IPV6OPT_PAD1)
292  {
293  padn_cnt++;
294  offset++;
295  ptr++;
296  continue;
297  }
298 
299  if (offset + 1 >= optslen) {
301  break;
302  }
303 
304  /* length field for each opt */
305  uint8_t ip6_optlen = *(ptr + 1);
306 
307  /* see if the optlen from the packet fits the total optslen */
308  if ((offset + 1 + ip6_optlen) > optslen) {
310  break;
311  }
312 
313  if (*ptr == IPV6OPT_PADN) /* PadN */
314  {
315  padn_cnt++;
316 
317  /* a zero padN len would be weird */
318  if (ip6_optlen == 0)
320  } else if (*ptr == IPV6OPT_RA) /* RA */
321  {
322  ra->ip6ra_type = *(ptr);
323  ra->ip6ra_len = ip6_optlen;
324 
325  if (ip6_optlen < sizeof(ra->ip6ra_value)) {
327  break;
328  }
329 
330  memcpy(&ra->ip6ra_value, (ptr + 2), sizeof(ra->ip6ra_value));
331  ra->ip6ra_value = SCNtohs(ra->ip6ra_value);
332  other_cnt++;
333  } else if (*ptr == IPV6OPT_JUMBO) /* Jumbo */
334  {
335  jumbo->ip6j_type = *(ptr);
336  jumbo->ip6j_len = ip6_optlen;
337 
338  if (ip6_optlen < sizeof(jumbo->ip6j_payload_len)) {
340  break;
341  }
342 
343  memcpy(&jumbo->ip6j_payload_len, (ptr+2), sizeof(jumbo->ip6j_payload_len));
344  jumbo->ip6j_payload_len = SCNtohl(jumbo->ip6j_payload_len);
345  } else if (*ptr == IPV6OPT_HAO) /* HAO */
346  {
347  hao->ip6hao_type = *(ptr);
348  hao->ip6hao_len = ip6_optlen;
349 
350  if (ip6_optlen < sizeof(hao->ip6hao_hoa)) {
352  break;
353  }
354 
355  memcpy(&hao->ip6hao_hoa, (ptr + 2), sizeof(hao->ip6hao_hoa));
356  other_cnt++;
357  } else {
358  if (nh == IPPROTO_HOPOPTS)
360  else
362 
363  other_cnt++;
364  }
365  uint16_t optlen = (*(ptr + 1) + 2);
366  ptr += optlen; /* +2 for opt type and opt len fields */
367  offset += optlen;
368  }
369  /* flag packets that have only padding */
370  if (padn_cnt > 0 && other_cnt == 0) {
371  if (nh == IPPROTO_HOPOPTS)
373  else
375  }
376 
377  nh = *pkt;
378  pkt += hdrextlen;
379  plen -= hdrextlen;
380  break;
381  }
382 
383  case IPPROTO_FRAGMENT:
384  {
385  IPV6_SET_L4PROTO(p,nh);
386  /* store the offset of this extension into the packet
387  * past the ipv6 header. We use it in defrag for creating
388  * a defragmented packet without the frag header */
389  if (exthdr_fh_done == 0) {
390  DEBUG_VALIDATE_BUG_ON(pkt - orig_pkt > UINT16_MAX);
391  p->l3.vars.ip6.eh.fh_offset = (uint16_t)(pkt - orig_pkt);
392  exthdr_fh_done = 1;
393  }
394 
395  uint16_t prev_hdrextlen = hdrextlen;
396  hdrextlen = sizeof(IPV6FragHdr);
397  if (hdrextlen > plen) {
399  SCReturn;
400  }
401 
402  /* for the frag header, the length field is reserved */
403  if (*(pkt + 1) != 0) {
405  /* non fatal, lets try to continue */
406  }
407 
408  if (IPV6_EXTHDR_ISSET_FH(p)) {
410  nh = *pkt;
411  pkt += hdrextlen;
412  plen -= hdrextlen;
413  break;
414  }
415 
416  /* set the header flag first */
418 
419  /* parse the header and setup the vars */
420  DecodeIPV6FragHeader(p, pkt, hdrextlen, plen, prev_hdrextlen);
421 
422  /* if FH has offset 0 and no more fragments are coming, we
423  * parse this packet further right away, no defrag will be
424  * needed. It is a useless FH then though, so we do set an
425  * decoder event. */
426  if (p->l3.vars.ip6.eh.fh_more_frags_set == 0 && p->l3.vars.ip6.eh.fh_offset == 0) {
428 
429  nh = *pkt;
430  pkt += hdrextlen;
431  plen -= hdrextlen;
432  break;
433  }
434  if (p->l3.vars.ip6.eh.fh_more_frags_set != 0 && plen % 8 != 0) {
435  // cf https://datatracker.ietf.org/doc/html/rfc2460#section-4.5
436  // each, except possibly the last ("rightmost") one,
437  // being an integer multiple of 8 octets long.
439  }
440 
441  /* the rest is parsed upon reassembly */
442  p->flags |= PKT_IS_FRAGMENT;
443  SCReturn;
444  }
445  case IPPROTO_ESP:
446  {
447  IPV6_SET_L4PROTO(p,nh);
448  DecodeESP(tv, dtv, p, pkt, plen);
449  SCReturn;
450  }
451  case IPPROTO_AH:
452  {
453  IPV6_SET_L4PROTO(p,nh);
454  /* we need the header as a minimum */
455  hdrextlen = sizeof(IPV6AuthHdr);
456  /* the payload len field is the number of extra 4 byte fields,
457  * IPV6AuthHdr already contains the first */
458  if (*(pkt+1) > 0)
459  hdrextlen += ((*(pkt+1) - 1) * 4);
460 
461  SCLogDebug("hdrextlen %"PRIu16, hdrextlen);
462 
463  if (hdrextlen > plen) {
465  SCReturn;
466  }
467 
468  IPV6AuthHdr *ahhdr = (IPV6AuthHdr *)pkt;
469  if (ahhdr->ip6ah_reserved != 0x0000) {
471  }
472 
473  if (ah) {
475  nh = *pkt;
476  pkt += hdrextlen;
477  plen -= hdrextlen;
478  break;
479  }
480 
481  ah = 1;
482 
483  nh = *pkt;
484  pkt += hdrextlen;
485  plen -= hdrextlen;
486  break;
487  }
488  case IPPROTO_IPIP:
489  IPV6_SET_L4PROTO(p,nh);
490  DecodeIPv4inIPv6(tv, dtv, p, pkt, plen);
491  SCReturn;
492  /* none, last header */
493  case IPPROTO_NONE:
494  IPV6_SET_L4PROTO(p,nh);
495  SCReturn;
496  case IPPROTO_ICMP:
498  SCReturn;
499  /* no parsing yet, just skip it */
500  case IPPROTO_MH:
501  case IPPROTO_HIP:
502  case IPPROTO_SHIM6:
503  hdrextlen = 8 + (*(pkt+1) * 8); /* 8 bytes + length in 8 octet units */
504  if (hdrextlen > plen) {
506  SCReturn;
507  }
508  nh = *pkt;
509  pkt += hdrextlen;
510  plen -= hdrextlen;
511  break;
512  default:
514  IPV6_SET_L4PROTO(p,nh);
515  SCReturn;
516  }
517  }
518 
519  SCReturn;
520 }
521 
522 static const IPV6Hdr *DecodeIPV6Packet(
523  ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
524 {
525  if (unlikely(len < IPV6_HEADER_LEN)) {
527  return NULL;
528  }
529 
530  if (unlikely(IP_GET_RAW_VER(pkt) != 6)) {
531  SCLogDebug("wrong ip version %d",IP_GET_RAW_VER(pkt));
533  return NULL;
534  }
535 
536  const IPV6Hdr *ip6h = PacketSetIPV6(p, pkt);
537 
538  if (unlikely(len < (IPV6_HEADER_LEN + IPV6_GET_RAW_PLEN(ip6h)))) {
540  return NULL;
541  }
542 
543  SET_IPV6_SRC_ADDR(ip6h, &p->src);
544  SET_IPV6_DST_ADDR(ip6h, &p->dst);
545 
546  return ip6h;
547 }
548 
549 int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
550 {
552 
553  if (!PacketIncreaseCheckLayers(p)) {
554  return TM_ECODE_FAILED;
555  }
556  /* do the actual decoding */
557  const IPV6Hdr *ip6h = DecodeIPV6Packet(tv, dtv, p, pkt, len);
558  if (unlikely(ip6h == NULL)) {
559  PacketClearL3(p);
560  return TM_ECODE_FAILED;
561  }
562  p->proto = IPV6_GET_RAW_NH(ip6h);
563 
564 #ifdef DEBUG
565  if (SCLogDebugEnabled()) { /* only convert the addresses if debug is really enabled */
566  /* debug print */
567  char s[46], d[46];
568  PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), s, sizeof(s));
569  PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), d, sizeof(d));
570  SCLogDebug("IPV6 %s->%s - CLASS: %" PRIu32 " FLOW: %" PRIu32 " NH: %" PRIu32
571  " PLEN: %" PRIu32 " HLIM: %" PRIu32 "",
572  s, d, IPV6_GET_RAW_CLASS(ip6h), IPV6_GET_RAW_FLOW(ip6h), IPV6_GET_RAW_NH(ip6h),
573  IPV6_GET_RAW_PLEN(ip6h), IPV6_GET_RAW_HLIM(ip6h));
574  }
575 #endif /* DEBUG */
576  const uint8_t *data = pkt + IPV6_HEADER_LEN;
577  const uint16_t data_len = IPV6_GET_RAW_PLEN(ip6h);
578 
579  /* now process the Ext headers and/or the L4 Layer */
580  switch (IPV6_GET_RAW_NH(ip6h)) {
581  case IPPROTO_TCP:
582  IPV6_SET_L4PROTO (p, IPPROTO_TCP);
583  DecodeTCP(tv, dtv, p, data, data_len);
584  return TM_ECODE_OK;
585  case IPPROTO_UDP:
586  IPV6_SET_L4PROTO (p, IPPROTO_UDP);
587  DecodeUDP(tv, dtv, p, data, data_len);
588  return TM_ECODE_OK;
589  case IPPROTO_ICMPV6:
590  IPV6_SET_L4PROTO (p, IPPROTO_ICMPV6);
591  DecodeICMPV6(tv, dtv, p, data, data_len);
592  return TM_ECODE_OK;
593  case IPPROTO_SCTP:
595  DecodeSCTP(tv, dtv, p, data, data_len);
596  return TM_ECODE_OK;
597  case IPPROTO_IPIP:
599  DecodeIPv4inIPv6(tv, dtv, p, data, data_len);
600  return TM_ECODE_OK;
601  case IPPROTO_IPV6:
602  DecodeIP6inIP6(tv, dtv, p, data, data_len);
603  return TM_ECODE_OK;
604  case IPPROTO_GRE:
606  DecodeGRE(tv, dtv, p, data, data_len);
607  break;
608  case IPPROTO_FRAGMENT:
609  case IPPROTO_HOPOPTS:
610  case IPPROTO_ROUTING:
611  case IPPROTO_NONE:
612  case IPPROTO_DSTOPTS:
613  case IPPROTO_AH:
614  case IPPROTO_ESP:
615  case IPPROTO_MH:
616  case IPPROTO_HIP:
617  case IPPROTO_SHIM6:
618  DecodeIPV6ExtHdrs(tv, dtv, p, ip6h, data, data_len);
619  break;
620  case IPPROTO_ICMP:
622  break;
623  default:
626  break;
627  }
628  p->proto = IPV6_GET_L4PROTO (p);
629 
630  /* Pass to defragger if a fragment. */
631  if (IPV6_EXTHDR_ISSET_FH(p)) {
632  Packet *rp = Defrag(tv, dtv, p);
633  if (rp != NULL) {
635  }
636  }
637 
638  return TM_ECODE_OK;
639 }
640 
641 #ifdef UNITTESTS
642 #include "util-unittest-helper.h"
643 #include "packet.h"
644 
645 /**
646  * \test fragment decoding
647  */
648 static int DecodeIPV6FragTest01 (void)
649 {
650 
651  uint8_t raw_frag1[] = {
652  0x60, 0x0f, 0x1a, 0xcf, 0x05, 0xa8, 0x2c, 0x36, 0x20, 0x01, 0x04, 0x70, 0x00, 0x01, 0x00, 0x18,
653  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x09, 0x80, 0x32, 0xb2, 0x00, 0x01,
654  0x2e, 0x41, 0x38, 0xff, 0xfe, 0xa7, 0xea, 0xeb, 0x06, 0x00, 0x00, 0x01, 0xdf, 0xf8, 0x11, 0xd7,
655  0x00, 0x50, 0xa6, 0x5c, 0xcc, 0xd7, 0x28, 0x9f, 0xc3, 0x34, 0xc6, 0x58, 0x80, 0x10, 0x20, 0x13,
656  0x18, 0x1f, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0xcd, 0xf9, 0x3a, 0x41, 0x00, 0x1a, 0x91, 0x8a,
657  0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
658  0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x30, 0x32, 0x20, 0x44,
659  0x65, 0x63, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, 0x30, 0x38, 0x3a, 0x33, 0x32, 0x3a, 0x35, 0x37,
660  0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
661  0x61, 0x63, 0x68, 0x65, 0x0d, 0x0a, 0x43, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x43, 0x6f, 0x6e, 0x74,
662  0x72, 0x6f, 0x6c, 0x3a, 0x20, 0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x0d, 0x0a, 0x50,
663  0x72, 0x61, 0x67, 0x6d, 0x61, 0x3a, 0x20, 0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x0d,
664  0x0a, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30,
665  0x31, 0x20, 0x4a, 0x61, 0x6e, 0x20, 0x31, 0x39, 0x37, 0x31, 0x20, 0x30, 0x30, 0x3a, 0x30, 0x30,
666  0x3a, 0x30, 0x30, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
667  0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x35, 0x39, 0x39, 0x0d, 0x0a, 0x4b,
668  0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x3a, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x6f,
669  0x75, 0x74, 0x3d, 0x35, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x3d, 0x39, 0x39, 0x0d, 0x0a, 0x43, 0x6f,
670  0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b, 0x65, 0x65, 0x70, 0x2d, 0x41,
671  0x6c, 0x69, 0x76, 0x65, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
672  0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f,
673  0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3b, 0x63, 0x68, 0x61, 0x72, 0x73,
674  0x65, 0x74, 0x3d, 0x61, 0x73, 0x63, 0x69, 0x69, 0x0d, 0x0a, 0x0d, 0x0a, 0x5f, 0x6a, 0x71, 0x6a,
675  0x73, 0x70, 0x28, 0x7b, 0x22, 0x69, 0x70, 0x22, 0x3a, 0x22, 0x32, 0x30, 0x30, 0x31, 0x3a, 0x39,
676  0x38, 0x30, 0x3a, 0x33, 0x32, 0x62, 0x32, 0x3a, 0x31, 0x3a, 0x32, 0x65, 0x34, 0x31, 0x3a, 0x33,
677  0x38, 0x66, 0x66, 0x3a, 0x66, 0x65, 0x61, 0x37, 0x3a, 0x65, 0x61, 0x65, 0x62, 0x22, 0x2c, 0x22,
678  0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x69, 0x70, 0x76, 0x36, 0x22, 0x2c, 0x22, 0x73, 0x75,
679  0x62, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x76, 0x69, 0x61, 0x22, 0x3a,
680  0x22, 0x22, 0x2c, 0x22, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x22, 0x20, 0x20,
681  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
682  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
683  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
684  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
685  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
686  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
687  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
688  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
689  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
690  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
691  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
692  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
693  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
694  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
695  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
696  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
697  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
698  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
699  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
700  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
701  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
702  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
703  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
704  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
705  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
706  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
707  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
708  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
709  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
710  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
711  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
712  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
713  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
714  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
715  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
716  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
717  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
718  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
719  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
720  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
721  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
722  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
723  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
724  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
725  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
726  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
727  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
728  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
729  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
730  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
731  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
732  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
733  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
734  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
735  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
736  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
737  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
738  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
739  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
740  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
741  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
742  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
743  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
744  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
745  };
746  uint8_t raw_frag2[] = {
747  0x60, 0x0f, 0x1a, 0xcf, 0x00, 0x1c, 0x2c, 0x36, 0x20, 0x01, 0x04, 0x70, 0x00, 0x01, 0x00, 0x18,
748  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x09, 0x80, 0x32, 0xb2, 0x00, 0x01,
749  0x2e, 0x41, 0x38, 0xff, 0xfe, 0xa7, 0xea, 0xeb, 0x06, 0x00, 0x05, 0xa0, 0xdf, 0xf8, 0x11, 0xd7,
750  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
751  0x20, 0x20, 0x20, 0x20,
752  };
753  Packet *pkt;
754  Packet *p1 = PacketGetFromAlloc();
755  if (unlikely(p1 == NULL))
756  return 0;
757  Packet *p2 = PacketGetFromAlloc();
758  if (unlikely(p2 == NULL)) {
759  SCFree(p1);
760  return 0;
761  }
762  ThreadVars tv;
764  int result = 0;
765 
767  DefragInit();
768 
769  memset(&tv, 0, sizeof(ThreadVars));
770  memset(&dtv, 0, sizeof(DecodeThreadVars));
771 
772  PacketCopyData(p1, raw_frag1, sizeof(raw_frag1));
773  PacketCopyData(p2, raw_frag2, sizeof(raw_frag2));
774 
775  DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1));
776 
777  if (!(IPV6_EXTHDR_ISSET_FH(p1))) {
778  printf("ipv6 frag header not detected: ");
779  goto end;
780  }
781 
782  DecodeIPV6(&tv, &dtv, p2, GET_PKT_DATA(p2), GET_PKT_LEN(p2));
783 
784  if (!(IPV6_EXTHDR_ISSET_FH(p2))) {
785  printf("ipv6 frag header not detected: ");
786  goto end;
787  }
788 
789  if (tv.decode_pq.len != 1) {
790  printf("no reassembled packet: ");
791  goto end;
792  }
793 
794  result = 1;
795 end:
796  PacketRecycle(p1);
797  PacketRecycle(p2);
798  SCFree(p1);
799  SCFree(p2);
801  while (pkt != NULL) {
802  PacketRecycle(pkt);
803  SCFree(pkt);
805  }
806  DefragDestroy();
807  FlowShutdown();
808  return result;
809 }
810 
811 /**
812  * \test routing header decode
813  */
814 static int DecodeIPV6RouteTest01 (void)
815 {
816  uint8_t raw_pkt1[] = {
817  0x60, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x2b, 0x40,
818  0x20, 0x01, 0xaa, 0xaa, 0x00, 0x01, 0x00, 0x00,
819  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
820  0x20, 0x01, 0xaa, 0xaa, 0x00, 0x01, 0x00, 0x00,
821  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
822  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
823 
824  0xb2, 0xed, 0x00, 0x50, 0x1b, 0xc7, 0x6a, 0xdf,
825  0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0x20, 0x00,
826  0xfa, 0x87, 0x00, 0x00,
827  };
828  Packet *p1 = PacketGetFromAlloc();
829  FAIL_IF(unlikely(p1 == NULL));
830  ThreadVars tv;
832 
834 
835  memset(&tv, 0, sizeof(ThreadVars));
836  memset(&dtv, 0, sizeof(DecodeThreadVars));
837 
838  PacketCopyData(p1, raw_pkt1, sizeof(raw_pkt1));
839 
840  DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1));
841 
842  FAIL_IF (!(IPV6_EXTHDR_ISSET_RH(p1)));
843  FAIL_IF(p1->l3.vars.ip6.eh.rh_type != 0);
844  PacketRecycle(p1);
845  SCFree(p1);
846  FlowShutdown();
847  PASS;
848 }
849 
850 /**
851  * \test HOP header decode
852  */
853 static int DecodeIPV6HopTest01 (void)
854 {
855  uint8_t raw_pkt1[] = { 0x60, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0xfe, 0x80, 0x00, 0x00,
856  0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0xfe, 0xff, 0xfe, 0x98, 0x3d, 0x01, 0xff, 0x02, 0x00,
857  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3a, 0x00,
858  0xff, /* 0xff is a nonsense opt */
859  0x02, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x1c, 0x6f, 0x27, 0x10, 0x00, 0x00, 0x00, 0x00,
860  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
861  Packet *p1 = PacketGetFromAlloc();
862  FAIL_IF(unlikely(p1 == NULL));
863  ThreadVars tv;
865 
867 
868  memset(&tv, 0, sizeof(ThreadVars));
869  memset(&dtv, 0, sizeof(DecodeThreadVars));
870 
871  PacketCopyData(p1, raw_pkt1, sizeof(raw_pkt1));
872 
873  DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1));
874 
876 
877  PacketRecycle(p1);
878  SCFree(p1);
879  FlowShutdown();
880  PASS;
881 }
882 
883 /**
884  * \test pkt too small event setting
885  */
886 static int DecodeIPV6PktTooSmallTest01(void)
887 {
888  uint8_t raw_pkt1[] = { 0x60, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0xfe, 0x80, 0x00, 0x00,
889  0x00, 0x00, 0x00, 0x00, 0x02, 0x0f, 0xfe, 0xff, 0xfe, 0x98, 0x3d, 0x01, 0xff, 0x02, 0x00,
890  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3a, 0x00,
891  0xff, /* 0xff is a nonsense opt */
892  0x02, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x1c, 0x6f, 0x27, 0x10, 0x00, 0x00, 0x00, 0x00,
893  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
894  Packet *p1 = PacketGetFromAlloc();
895  FAIL_IF(unlikely(p1 == NULL));
896  ThreadVars tv;
898 
900 
901  memset(&tv, 0, sizeof(ThreadVars));
902  memset(&dtv, 0, sizeof(DecodeThreadVars));
903 
904  PacketCopyData(p1, raw_pkt1, sizeof(raw_pkt1));
905 
906  /* force pkt length to be shorter than headers length */
907  DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1) - 33);
908 
910  PacketRecycle(p1);
911  SCFree(p1);
912  FlowShutdown();
913  PASS;
914 }
915 
916 #endif /* UNITTESTS */
917 
918 /**
919  * \brief this function registers unit tests for IPV6 decoder
920  */
921 
923 {
924 #ifdef UNITTESTS
925  UtRegisterTest("DecodeIPV6FragTest01", DecodeIPV6FragTest01);
926  UtRegisterTest("DecodeIPV6RouteTest01", DecodeIPV6RouteTest01);
927  UtRegisterTest("DecodeIPV6HopTest01", DecodeIPV6HopTest01);
928  UtRegisterTest("DecodeIPV6PktTooSmallTest01", DecodeIPV6PktTooSmallTest01);
929 #endif /* UNITTESTS */
930 }
931 
932 /**
933  * @}
934  */
IPV6_FRAG_INVALID_LENGTH
@ IPV6_FRAG_INVALID_LENGTH
Definition: decode-events.h:184
ENGINE_SET_EVENT
#define ENGINE_SET_EVENT(p, e)
Definition: decode.h:1188
IPV4_IN_IPV6_WRONG_IP_VER
@ IPV4_IN_IPV6_WRONG_IP_VER
Definition: decode-events.h:192
DefragDestroy
void DefragDestroy(void)
Definition: defrag.c:1129
PacketL3::ip6
struct PacketL3::@31::@32 ip6
Packet_::proto
uint8_t proto
Definition: decode.h:523
len
uint8_t len
Definition: app-layer-dnp3.h:2
DECODE_TUNNEL_IPV6
@ DECODE_TUNNEL_IPV6
Definition: decode.h:1108
IPV6_PKT_TOO_SMALL
@ IPV6_PKT_TOO_SMALL
Definition: decode-events.h:68
IPV6_GET_RAW_PLEN
#define IPV6_GET_RAW_PLEN(ip6h)
Definition: decode-ipv6.h:66
IPV4_IN_IPV6_PKT_TOO_SMALL
@ IPV4_IN_IPV6_PKT_TOO_SMALL
Definition: decode-events.h:191
StatsIncr
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
Definition: counters.c:166
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
IPV6_GET_RAW_HLIM
#define IPV6_GET_RAW_HLIM(ip6h)
Definition: decode-ipv6.h:67
IPV6_GET_RAW_NH
#define IPV6_GET_RAW_NH(ip6h)
Definition: decode-ipv6.h:65
PacketCopyData
int PacketCopyData(Packet *p, const uint8_t *pktdata, uint32_t pktlen)
Copy data to Packet payload and set packet length.
Definition: decode.c:377
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
ENGINE_ISSET_EVENT
#define ENGINE_ISSET_EVENT(p, e)
Definition: decode.h:1201
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:279
IPV6_DSTOPTS_UNKNOWN_OPT
@ IPV6_DSTOPTS_UNKNOWN_OPT
Definition: decode-events.h:85
IPV6OptRA_::ip6ra_value
uint16_t ip6ra_value
Definition: decode-ipv6.h:138
IPV6OptHAO_::ip6hao_hoa
struct in6_addr ip6hao_hoa
Definition: decode-ipv6.h:130
IPV6_EXTHDR_ISSET_FH
#define IPV6_EXTHDR_ISSET_FH(p)
Definition: decode-ipv6.h:174
IPV6OPT_HAO
#define IPV6OPT_HAO
Definition: decode-ipv6.h:123
Packet_::flags
uint32_t flags
Definition: decode.h:544
PacketRecycle
void PacketRecycle(Packet *p)
Definition: packet.c:151
IPV6_GET_RAW_CLASS
#define IPV6_GET_RAW_CLASS(ip6h)
Definition: decode-ipv6.h:63
IPV6OPT_PADN
#define IPV6OPT_PADN
Definition: decode-ipv6.h:120
IPV6_EXTHDR_USELESS_FH
@ IPV6_EXTHDR_USELESS_FH
Definition: decode-events.h:72
flow-hash.h
IPV6OPT_RA
#define IPV6OPT_RA
Definition: decode-ipv6.h:121
IPV6_EXTHDR_SET_FH
#define IPV6_EXTHDR_SET_FH(p)
Definition: decode-ipv6.h:173
IPV6_GET_L4PROTO
#define IPV6_GET_L4PROTO(p)
Definition: decode-ipv6.h:75
IPPROTO_GRE
#define IPPROTO_GRE
Definition: decode-gre.h:30
IP_GET_RAW_VER
#define IP_GET_RAW_VER(pkt)
Definition: decode.h:232
IPV6_SET_L4PROTO
#define IPV6_SET_L4PROTO(p, proto)
Definition: decode-ipv6.h:72
TM_ECODE_FAILED
@ TM_ECODE_FAILED
Definition: tm-threads-common.h:82
IPV6_EXTHDR_DUPL_HH
@ IPV6_EXTHDR_DUPL_HH
Definition: decode-events.h:74
GET_IPV6_DST_ADDR
#define GET_IPV6_DST_ADDR(p)
Definition: decode.h:204
IPV6_IN_IPV6_PKT_TOO_SMALL
@ IPV6_IN_IPV6_PKT_TOO_SMALL
Definition: decode-events.h:195
IPV6_IN_IPV6_WRONG_IP_VER
@ IPV6_IN_IPV6_WRONG_IP_VER
Definition: decode-events.h:196
DecodeSCTP
int DecodeSCTP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-sctp.c:62
util-unittest-helper.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
IPV6_HOPOPTS_ONLY_PADDING
@ IPV6_HOPOPTS_ONLY_PADDING
Definition: decode-events.h:84
TM_ECODE_OK
@ TM_ECODE_OK
Definition: tm-threads-common.h:81
IPV6OptHAO_::ip6hao_len
uint8_t ip6hao_len
Definition: decode-ipv6.h:129
IPV6OPT_JUMBO
#define IPV6OPT_JUMBO
Definition: decode-ipv6.h:122
IPV6_DATA_AFTER_NONE_HEADER
@ IPV6_DATA_AFTER_NONE_HEADER
Definition: decode-events.h:91
PKT_SET_SRC
#define PKT_SET_SRC(p, src_val)
Definition: decode.h:1327
FlowInitConfig
void FlowInitConfig(bool quiet)
initialize the configuration
Definition: flow.c:547
DecodeThreadVars_::counter_ipv6inipv6
uint16_t counter_ipv6inipv6
Definition: decode.h:1014
IPV6_FH_NON_ZERO_RES_FIELD
@ IPV6_FH_NON_ZERO_RES_FIELD
Definition: decode-events.h:90
decode-ipv6.h
IPV6_UNKNOWN_NEXT_HEADER
@ IPV6_UNKNOWN_NEXT_HEADER
Definition: decode-events.h:93
decode.h
IPPROTO_SHIM6
#define IPPROTO_SHIM6
Definition: decode.h:1243
IPV6_TRUNC_EXTHDR
@ IPV6_TRUNC_EXTHDR
Definition: decode-events.h:70
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
IPV6_TRUNC_PKT
@ IPV6_TRUNC_PKT
Definition: decode-events.h:69
IPV6_EXTHDR_DUPL_FH
@ IPV6_EXTHDR_DUPL_FH
Definition: decode-events.h:71
PacketDequeueNoLock
Packet * PacketDequeueNoLock(PacketQueueNoLock *qnl)
Definition: packet-queue.c:208
PKT_IS_FRAGMENT
#define PKT_IS_FRAGMENT
Definition: decode.h:1292
DecodeIPV6FragHeader
void DecodeIPV6FragHeader(Packet *p, const uint8_t *pkt, uint16_t hdrextlen, uint16_t plen, uint16_t prev_hdrextlen)
Definition: decode-ipv6.c:94
util-print.h
SCEnter
#define SCEnter(...)
Definition: util-debug.h:281
GET_PKT_DATA
#define GET_PKT_DATA(p)
Definition: decode.h:209
ThreadVars_
Per thread variable structure.
Definition: threadvars.h:58
PrintInet
const char * PrintInet(int af, const void *src, char *dst, socklen_t size)
Definition: util-print.c:231
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
IPV6_EXTHDR_DUPL_RH
@ IPV6_EXTHDR_DUPL_RH
Definition: decode-events.h:73
IPV6_EXTHDR_AH_RES_NOT_NULL
@ IPV6_EXTHDR_AH_RES_NOT_NULL
Definition: decode-events.h:81
SET_IPV6_SRC_ADDR
#define SET_IPV6_SRC_ADDR(ip6h, a)
Definition: decode.h:159
SCReturn
#define SCReturn
Definition: util-debug.h:283
IPV6_EXTHDR_RH_TYPE_0
@ IPV6_EXTHDR_RH_TYPE_0
Definition: decode-events.h:88
PKT_SRC_DECODER_IPV6
@ PKT_SRC_DECODER_IPV6
Definition: decode.h:55
IPV6Hdr_
Definition: decode-ipv6.h:32
Packet_
Definition: decode.h:501
DecodeIPV6
int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-ipv6.c:549
DECODE_TUNNEL_IPV4
@ DECODE_TUNNEL_IPV4
Definition: decode.h:1107
GET_PKT_LEN
#define GET_PKT_LEN(p)
Definition: decode.h:208
PacketL3::vars
union PacketL3::@31 vars
DecodeThreadVars_::counter_ipv4inipv6
uint16_t counter_ipv4inipv6
Definition: decode.h:1013
IPPROTO_HIP
#define IPPROTO_HIP
Definition: decode.h:1239
IPV6_EXTHDR_DUPL_DH
@ IPV6_EXTHDR_DUPL_DH
Definition: decode-events.h:75
defrag.h
IPV6_EXTHDR_ISSET_RH
#define IPV6_EXTHDR_ISSET_RH(p)
Definition: decode-ipv6.h:176
IPV6OptRA_
Definition: decode-ipv6.h:135
IPV6OptJumbo_::ip6j_payload_len
uint32_t ip6j_payload_len
Definition: decode-ipv6.h:146
dtv
DecodeThreadVars * dtv
Definition: fuzz_decodepcapfile.c:33
DecodeTCP
int DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint16_t len)
Definition: decode-tcp.c:273
IPV6_DSTOPTS_ONLY_PADDING
@ IPV6_DSTOPTS_ONLY_PADDING
Definition: decode-events.h:86
IPV6_EXTHDR_ZERO_LEN_PADN
@ IPV6_EXTHDR_ZERO_LEN_PADN
Definition: decode-events.h:89
PacketEnqueueNoLock
void PacketEnqueueNoLock(PacketQueueNoLock *qnl, Packet *p)
Definition: packet-queue.c:168
IPPROTO_IPIP
#define IPPROTO_IPIP
Definition: decode.h:1214
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
SCNtohs
#define SCNtohs(x)
Definition: suricata-common.h:431
DecodeICMPV6
int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, const uint8_t *pkt, uint32_t len)
Decode ICMPV6 packets and fill the Packet with the decoded info.
Definition: decode-icmpv6.c:177
suricata-common.h
IPV6_WRONG_IP_VER
@ IPV6_WRONG_IP_VER
Definition: decode-events.h:80
DecodeThreadVars_::counter_ipv6
uint16_t counter_ipv6
Definition: decode.h:980
FlowShutdown
void FlowShutdown(void)
shutdown the flow engine
Definition: flow.c:691
IPV4_HEADER_LEN
#define IPV4_HEADER_LEN
Definition: decode-ipv4.h:28
IPV6OptHAO_::ip6hao_type
uint8_t ip6hao_type
Definition: decode-ipv6.h:128
packet.h
IPV6_GET_RAW_FLOW
#define IPV6_GET_RAW_FLOW(ip6h)
Definition: decode-ipv6.h:64
tv
ThreadVars * tv
Definition: fuzz_decodepcapfile.c:32
util-validate.h
PacketGetFromAlloc
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
Definition: decode.c:258
PacketQueueNoLock_::len
uint32_t len
Definition: packet-queue.h:37
IPV6_SET_EXTHDRS_LEN
#define IPV6_SET_EXTHDRS_LEN(p, len)
Definition: decode-ipv6.h:73
Packet_::l3
struct PacketL3 l3
Definition: decode.h:600
IPV6OptRA_::ip6ra_len
uint8_t ip6ra_len
Definition: decode-ipv6.h:137
GET_IPV6_SRC_ADDR
#define GET_IPV6_SRC_ADDR(p)
Definition: decode.h:203
SCFree
#define SCFree(p)
Definition: util-mem.h:61
SCNtohl
#define SCNtohl(x)
Definition: suricata-common.h:430
DecodeThreadVars_
Structure to hold thread specific data for all decode modules.
Definition: decode.h:963
IPV6_EXTHDR_DUPL_AH
@ IPV6_EXTHDR_DUPL_AH
Definition: decode-events.h:76
IPV6_WITH_ICMPV4
@ IPV6_WITH_ICMPV4
Definition: decode-events.h:94
IPPROTO_MH
#define IPPROTO_MH
Definition: decode.h:1234
ThreadVars_::decode_pq
PacketQueueNoLock decode_pq
Definition: threadvars.h:112
IPV6OptJumbo_
Definition: decode-ipv6.h:143
IPV6OptRA_::ip6ra_type
uint8_t ip6ra_type
Definition: decode-ipv6.h:136
IPV6OptJumbo_::ip6j_len
uint8_t ip6j_len
Definition: decode-ipv6.h:145
Packet_::dst
Address dst
Definition: decode.h:506
ENGINE_SET_INVALID_EVENT
#define ENGINE_SET_INVALID_EVENT(p, e)
Definition: decode.h:1196
FLOW_QUIET
#define FLOW_QUIET
Definition: flow.h:43
IPV6OptJumbo_::ip6j_type
uint8_t ip6j_type
Definition: decode-ipv6.h:144
IPV6_HEADER_LEN
#define IPV6_HEADER_LEN
Definition: decode-ipv6.h:27
IPPROTO_SCTP
#define IPPROTO_SCTP
Definition: decode.h:1230
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:393
Defrag
Packet * Defrag(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p)
Entry point for IPv4 and IPv6 fragments.
Definition: defrag.c:1063
SET_IPV6_DST_ADDR
#define SET_IPV6_DST_ADDR(ip6h, a)
Definition: decode.h:168
IPV6_EXTHDR_INVALID_OPTLEN
@ IPV6_EXTHDR_INVALID_OPTLEN
Definition: decode-events.h:79
SCLogDebugEnabled
int SCLogDebugEnabled(void)
Returns whether debug messages are enabled to be logged or not.
Definition: util-debug.c:767
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:102
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:533
DecodeIPV6RegisterTests
void DecodeIPV6RegisterTests(void)
this function registers unit tests for IPV6 decoder
Definition: decode-ipv6.c:922
IPV6OptHAO_
Definition: decode-ipv6.h:127
Packet_::src
Address src
Definition: decode.h:505
DefragInit
void DefragInit(void)
Definition: defrag.c:1109
IPV6_EXTHDR_SET_RH
#define IPV6_EXTHDR_SET_RH(p)
Definition: decode-ipv6.h:175
IPV6_HOPOPTS_UNKNOWN_OPT
@ IPV6_HOPOPTS_UNKNOWN_OPT
Definition: decode-events.h:83
IPV6OPT_PAD1
#define IPV6OPT_PAD1
Definition: decode-ipv6.h:119