PageRenderTime 54ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/src/decode-ipv6.c

https://github.com/chamaillard/suricata
C | 871 lines | 675 code | 99 blank | 97 comment | 103 complexity | 2c2af963cd5d4cd21fe82565da68b2e3 MD5 | raw file
Possible License(s): GPL-2.0, Unlicense, AGPL-1.0
  1. /* Copyright (C) 2007-2010 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. * \ingroup decode
  19. *
  20. * @{
  21. */
  22. /**
  23. * \file
  24. *
  25. * \author Victor Julien <victor@inliniac.net>
  26. *
  27. * Decode IPv6
  28. */
  29. #include "suricata-common.h"
  30. #include "packet-queue.h"
  31. #include "decode.h"
  32. #include "decode-ipv6.h"
  33. #include "decode-icmpv6.h"
  34. #include "decode-events.h"
  35. #include "defrag.h"
  36. #include "pkt-var.h"
  37. #include "util-debug.h"
  38. #include "util-print.h"
  39. #include "util-unittest.h"
  40. #define IPV6_EXTHDRS ip6eh.ip6_exthdrs
  41. #define IPV6_EH_CNT ip6eh.ip6_exthdrs_cnt
  42. /**
  43. * \brief Function to decode IPv4 in IPv6 packets
  44. *
  45. */
  46. static void DecodeIPv4inIPv6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t plen, PacketQueue *pq)
  47. {
  48. if (unlikely(plen < IPV4_HEADER_LEN)) {
  49. ENGINE_SET_EVENT(p, IPV4_IN_IPV6_PKT_TOO_SMALL);
  50. return;
  51. }
  52. if (IP_GET_RAW_VER(pkt) == 4) {
  53. if (pq != NULL) {
  54. Packet *tp = PacketPseudoPktSetup(p, pkt, plen, IPPROTO_IP);
  55. if (tp != NULL) {
  56. PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV6);
  57. DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
  58. GET_PKT_LEN(tp), pq, IPPROTO_IP);
  59. PacketEnqueue(pq,tp);
  60. SCPerfCounterIncr(dtv->counter_ipv4inipv6, tv->sc_perf_pca);
  61. return;
  62. }
  63. }
  64. } else {
  65. ENGINE_SET_EVENT(p, IPV4_IN_IPV6_WRONG_IP_VER);
  66. }
  67. return;
  68. }
  69. /**
  70. * \brief Function to decode IPv4 in IPv6 packets
  71. *
  72. */
  73. static void DecodeIP6inIP6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t plen, PacketQueue *pq)
  74. {
  75. if (unlikely(plen < IPV6_HEADER_LEN)) {
  76. ENGINE_SET_EVENT(p, IPV6_IN_IPV6_PKT_TOO_SMALL);
  77. return;
  78. }
  79. if (IP_GET_RAW_VER(pkt) == 6) {
  80. if (pq != NULL) {
  81. Packet *tp = PacketPseudoPktSetup(p, pkt, plen, IPPROTO_IPV6);
  82. if (tp != NULL) {
  83. PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV6);
  84. DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
  85. GET_PKT_LEN(tp), pq, IPPROTO_IP);
  86. PacketEnqueue(pq,tp);
  87. SCPerfCounterIncr(dtv->counter_ipv6inipv6, tv->sc_perf_pca);
  88. return;
  89. }
  90. }
  91. } else {
  92. ENGINE_SET_EVENT(p, IPV6_IN_IPV6_WRONG_IP_VER);
  93. }
  94. return;
  95. }
  96. static void
  97. DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
  98. {
  99. SCEnter();
  100. uint8_t *orig_pkt = pkt;
  101. uint8_t nh;
  102. uint16_t hdrextlen;
  103. uint16_t plen;
  104. char dstopts = 0;
  105. char exthdr_fh_done = 0;
  106. nh = IPV6_GET_NH(p);
  107. plen = len;
  108. while(1)
  109. {
  110. if (plen < 2) { /* minimal needed in a hdr */
  111. SCReturn;
  112. }
  113. switch(nh)
  114. {
  115. case IPPROTO_TCP:
  116. IPV6_SET_L4PROTO(p,nh);
  117. DecodeTCP(tv, dtv, p, pkt, plen, pq);
  118. SCReturn;
  119. case IPPROTO_UDP:
  120. IPV6_SET_L4PROTO(p,nh);
  121. DecodeUDP(tv, dtv, p, pkt, plen, pq);
  122. SCReturn;
  123. case IPPROTO_ICMPV6:
  124. IPV6_SET_L4PROTO(p,nh);
  125. DecodeICMPV6(tv, dtv, p, pkt, plen, pq);
  126. SCReturn;
  127. case IPPROTO_SCTP:
  128. IPV6_SET_L4PROTO(p,nh);
  129. DecodeSCTP(tv, dtv, p, pkt, plen, pq);
  130. SCReturn;
  131. case IPPROTO_ROUTING:
  132. IPV6_SET_L4PROTO(p,nh);
  133. hdrextlen = 8 + (*(pkt+1) * 8); /* 8 bytes + length in 8 octet units */
  134. SCLogDebug("hdrextlen %"PRIu8, hdrextlen);
  135. if (hdrextlen > plen) {
  136. ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR);
  137. SCReturn;
  138. }
  139. if (p->IPV6_EH_CNT < IPV6_MAX_OPT)
  140. {
  141. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh;
  142. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = *pkt;
  143. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen;
  144. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2;
  145. p->IPV6_EH_CNT++;
  146. }
  147. if (IPV6_EXTHDR_ISSET_RH(p)) {
  148. ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_RH);
  149. /* skip past this extension so we can continue parsing the rest
  150. * of the packet */
  151. nh = *pkt;
  152. pkt += hdrextlen;
  153. plen -= hdrextlen;
  154. break;
  155. }
  156. IPV6_EXTHDR_SET_RH(p, pkt);
  157. IPV6_EXTHDR_RH(p)->ip6rh_len = hdrextlen;
  158. /** \todo move into own function and load on demand */
  159. if (IPV6_EXTHDR_RH(p)->ip6rh_type == 0) {
  160. uint8_t i;
  161. uint8_t n = IPV6_EXTHDR_RH(p)->ip6rh_len / 2;
  162. /* because we devide the header len by 2 (as rfc 2460 tells us to)
  163. * we devide the result by 8 and not 16 as the header fields are
  164. * sized */
  165. for (i = 0; i < (n/8) && i < sizeof(IPV6_EXTHDR_RH(p)->ip6rh0_addr)/sizeof(struct in6_addr); ++i) {
  166. /* the address header fields are 16 bytes in size */
  167. /** \todo do this without memcpy since it's expensive */
  168. memcpy(&IPV6_EXTHDR_RH(p)->ip6rh0_addr[i], pkt+(i*16)+8, sizeof(IPV6_EXTHDR_RH(p)->ip6rh0_addr[i]));
  169. }
  170. IPV6_EXTHDR_RH(p)->ip6rh0_num_addrs = i;
  171. }
  172. nh = *pkt;
  173. pkt += hdrextlen;
  174. plen -= hdrextlen;
  175. break;
  176. case IPPROTO_HOPOPTS:
  177. case IPPROTO_DSTOPTS:
  178. {
  179. IPV6OptHAO *hao = NULL;
  180. IPV6OptRA *ra = NULL;
  181. IPV6OptJumbo *jumbo = NULL;
  182. uint8_t optslen = 0;
  183. IPV6_SET_L4PROTO(p,nh);
  184. hdrextlen = (*(pkt+1) + 1) << 3;
  185. if (hdrextlen > plen) {
  186. ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR);
  187. SCReturn;
  188. }
  189. if (p->IPV6_EH_CNT < IPV6_MAX_OPT)
  190. {
  191. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh;
  192. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = *pkt;
  193. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen;
  194. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2;
  195. p->IPV6_EH_CNT++;
  196. }
  197. uint8_t *ptr = pkt + 2; /* +2 to go past nxthdr and len */
  198. /* point the pointers to right structures
  199. * in Packet. */
  200. if (nh == IPPROTO_HOPOPTS) {
  201. if (IPV6_EXTHDR_ISSET_HH(p)) {
  202. ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_HH);
  203. /* skip past this extension so we can continue parsing the rest
  204. * of the packet */
  205. nh = *pkt;
  206. pkt += hdrextlen;
  207. plen -= hdrextlen;
  208. break;
  209. }
  210. IPV6_EXTHDR_SET_HH(p, pkt);
  211. hao = &IPV6_EXTHDR_HH_HAO(p);
  212. ra = &IPV6_EXTHDR_HH_RA(p);
  213. jumbo = &IPV6_EXTHDR_HH_JUMBO(p);
  214. optslen = ((IPV6_EXTHDR_HH(p)->ip6hh_len+1)<<3)-2;
  215. }
  216. else if (nh == IPPROTO_DSTOPTS)
  217. {
  218. if (dstopts == 0) {
  219. IPV6_EXTHDR_SET_DH1(p, pkt);
  220. hao = &IPV6_EXTHDR_DH1_HAO(p);
  221. ra = &IPV6_EXTHDR_DH1_RA(p);
  222. jumbo = &IPV6_EXTHDR_DH2_JUMBO(p);
  223. optslen = ((IPV6_EXTHDR_DH1(p)->ip6dh_len+1)<<3)-2;
  224. dstopts = 1;
  225. } else if (dstopts == 1) {
  226. IPV6_EXTHDR_SET_DH2(p, pkt);
  227. hao = &IPV6_EXTHDR_DH2_HAO(p);
  228. ra = &IPV6_EXTHDR_DH2_RA(p);
  229. jumbo = &IPV6_EXTHDR_DH2_JUMBO(p);
  230. optslen = ((IPV6_EXTHDR_DH2(p)->ip6dh_len+1)<<3)-2;
  231. dstopts = 2;
  232. } else {
  233. ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_DH);
  234. /* skip past this extension so we can continue parsing the rest
  235. * of the packet */
  236. nh = *pkt;
  237. pkt += hdrextlen;
  238. plen -= hdrextlen;
  239. break;
  240. }
  241. }
  242. if (optslen > plen) {
  243. /* since the packet is long enough (we checked
  244. * plen against hdrlen, the optlen must be malformed. */
  245. ENGINE_SET_EVENT(p, IPV6_EXTHDR_INVALID_OPTLEN);
  246. /* skip past this extension so we can continue parsing the rest
  247. * of the packet */
  248. nh = *pkt;
  249. pkt += hdrextlen;
  250. plen -= hdrextlen;
  251. break;
  252. }
  253. /** \todo move into own function to loaded on demand */
  254. uint16_t padn_cnt = 0;
  255. uint16_t other_cnt = 0;
  256. uint16_t offset = 0;
  257. while(offset < optslen)
  258. {
  259. if (*ptr == IPV6OPT_PADN) /* PadN */
  260. {
  261. //printf("PadN option\n");
  262. padn_cnt++;
  263. }
  264. else if (*ptr == IPV6OPT_RA) /* RA */
  265. {
  266. ra->ip6ra_type = *(ptr);
  267. ra->ip6ra_len = *(ptr + 1);
  268. memcpy(&ra->ip6ra_value, (ptr + 2), sizeof(ra->ip6ra_value));
  269. ra->ip6ra_value = ntohs(ra->ip6ra_value);
  270. //printf("RA option: type %" PRIu32 " len %" PRIu32 " value %" PRIu32 "\n",
  271. // ra->ip6ra_type, ra->ip6ra_len, ra->ip6ra_value);
  272. other_cnt++;
  273. }
  274. else if (*ptr == IPV6OPT_JUMBO) /* Jumbo */
  275. {
  276. jumbo->ip6j_type = *(ptr);
  277. jumbo->ip6j_len = *(ptr+1);
  278. memcpy(&jumbo->ip6j_payload_len, (ptr+2), sizeof(jumbo->ip6j_payload_len));
  279. jumbo->ip6j_payload_len = ntohl(jumbo->ip6j_payload_len);
  280. //printf("Jumbo option: type %" PRIu32 " len %" PRIu32 " payload len %" PRIu32 "\n",
  281. // jumbo->ip6j_type, jumbo->ip6j_len, jumbo->ip6j_payload_len);
  282. }
  283. else if (*ptr == IPV6OPT_HAO) /* HAO */
  284. {
  285. hao->ip6hao_type = *(ptr);
  286. hao->ip6hao_len = *(ptr+1);
  287. memcpy(&hao->ip6hao_hoa, (ptr+2), sizeof(hao->ip6hao_hoa));
  288. //printf("HAO option: type %" PRIu32 " len %" PRIu32 " ",
  289. // hao->ip6hao_type, hao->ip6hao_len);
  290. //char addr_buf[46];
  291. //PrintInet(AF_INET6, (char *)&(hao->ip6hao_hoa),
  292. // addr_buf,sizeof(addr_buf));
  293. //printf("home addr %s\n", addr_buf);
  294. other_cnt++;
  295. } else {
  296. if (nh == IPPROTO_HOPOPTS)
  297. ENGINE_SET_EVENT(p, IPV6_HOPOPTS_UNKNOWN_OPT);
  298. else
  299. ENGINE_SET_EVENT(p, IPV6_DSTOPTS_UNKNOWN_OPT);
  300. other_cnt++;
  301. }
  302. uint16_t optlen = (*(ptr + 1) + 2);
  303. ptr += optlen; /* +2 for opt type and opt len fields */
  304. offset += optlen;
  305. }
  306. /* flag packets that have only padding */
  307. if (padn_cnt > 0 && other_cnt == 0) {
  308. if (nh == IPPROTO_HOPOPTS)
  309. ENGINE_SET_EVENT(p, IPV6_HOPOPTS_ONLY_PADDING);
  310. else
  311. ENGINE_SET_EVENT(p, IPV6_DSTOPTS_ONLY_PADDING);
  312. }
  313. nh = *pkt;
  314. pkt += hdrextlen;
  315. plen -= hdrextlen;
  316. break;
  317. }
  318. case IPPROTO_FRAGMENT:
  319. IPV6_SET_L4PROTO(p,nh);
  320. /* store the offset of this extension into the packet
  321. * past the ipv6 header. We use it in defrag for creating
  322. * a defragmented packet without the frag header */
  323. if (exthdr_fh_done == 0) {
  324. p->ip6eh.fh_offset = pkt - orig_pkt;
  325. exthdr_fh_done = 1;
  326. }
  327. hdrextlen = sizeof(IPV6FragHdr);
  328. if (hdrextlen > plen) {
  329. ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR);
  330. SCReturn;
  331. }
  332. if(p->IPV6_EH_CNT<IPV6_MAX_OPT)
  333. {
  334. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh;
  335. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = *pkt;
  336. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen;
  337. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2;
  338. p->IPV6_EH_CNT++;
  339. }
  340. if (IPV6_EXTHDR_ISSET_FH(p)) {
  341. ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_FH);
  342. nh = *pkt;
  343. pkt += hdrextlen;
  344. plen -= hdrextlen;
  345. break;
  346. }
  347. /* set the header ptr first */
  348. IPV6_EXTHDR_SET_FH(p, pkt);
  349. /* if FH has offset 0 and no more fragments are coming, we
  350. * parse this packet further right away, no defrag will be
  351. * needed. It is a useless FH then though, so we do set an
  352. * decoder event. */
  353. if (IPV6_EXTHDR_GET_FH_FLAG(p) == 0 && IPV6_EXTHDR_GET_FH_OFFSET(p) == 0) {
  354. ENGINE_SET_EVENT(p, IPV6_EXTHDR_USELESS_FH);
  355. nh = *pkt;
  356. pkt += hdrextlen;
  357. plen -= hdrextlen;
  358. break;
  359. }
  360. /* the rest is parsed upon reassembly */
  361. SCReturn;
  362. case IPPROTO_ESP:
  363. {
  364. IPV6_SET_L4PROTO(p,nh);
  365. hdrextlen = sizeof(IPV6EspHdr);
  366. if (hdrextlen > plen) {
  367. ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR);
  368. SCReturn;
  369. }
  370. if(p->IPV6_EH_CNT<IPV6_MAX_OPT)
  371. {
  372. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh;
  373. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = IPPROTO_NONE;
  374. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen;
  375. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2;
  376. p->IPV6_EH_CNT++;
  377. }
  378. if (IPV6_EXTHDR_ISSET_EH(p)) {
  379. ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_EH);
  380. SCReturn;
  381. }
  382. IPV6_EXTHDR_SET_EH(p, pkt);
  383. nh = IPPROTO_NONE;
  384. pkt += hdrextlen;
  385. plen -= hdrextlen;
  386. break;
  387. }
  388. case IPPROTO_AH:
  389. {
  390. IPV6_SET_L4PROTO(p,nh);
  391. /* we need the header as a minimum */
  392. hdrextlen = sizeof(IPV6AuthHdr);
  393. /* the payload len field is the number of extra 4 byte fields,
  394. * IPV6AuthHdr already contains the first */
  395. if (*(pkt+1) > 0)
  396. hdrextlen += ((*(pkt+1) - 1) * 4);
  397. SCLogDebug("hdrextlen %"PRIu8, hdrextlen);
  398. if (hdrextlen > plen) {
  399. ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR);
  400. SCReturn;
  401. }
  402. IPV6AuthHdr *ahhdr = (IPV6AuthHdr *)pkt;
  403. if (ahhdr->ip6ah_reserved != 0x0000) {
  404. ENGINE_SET_EVENT(p, IPV6_EXTHDR_AH_RES_NOT_NULL);
  405. }
  406. if(p->IPV6_EH_CNT < IPV6_MAX_OPT)
  407. {
  408. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh;
  409. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = *pkt;
  410. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen;
  411. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2;
  412. p->IPV6_EH_CNT++;
  413. }
  414. if (IPV6_EXTHDR_ISSET_AH(p)) {
  415. ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_AH);
  416. nh = *pkt;
  417. pkt += hdrextlen;
  418. plen -= hdrextlen;
  419. break;
  420. }
  421. IPV6_EXTHDR_SET_AH(p, pkt);
  422. nh = *pkt;
  423. pkt += hdrextlen;
  424. plen -= hdrextlen;
  425. break;
  426. }
  427. case IPPROTO_IPIP:
  428. IPV6_SET_L4PROTO(p,nh);
  429. DecodeIPv4inIPv6(tv, dtv, p, pkt, plen, pq);
  430. SCReturn;
  431. case IPPROTO_NONE:
  432. IPV6_SET_L4PROTO(p,nh);
  433. SCReturn;
  434. case IPPROTO_ICMP:
  435. ENGINE_SET_EVENT(p,IPV6_WITH_ICMPV4);
  436. break;
  437. default:
  438. IPV6_SET_L4PROTO(p,nh);
  439. SCReturn;
  440. }
  441. }
  442. SCReturn;
  443. }
  444. static int DecodeIPV6Packet (ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len)
  445. {
  446. if (len < IPV6_HEADER_LEN) {
  447. return -1;
  448. }
  449. if (IP_GET_RAW_VER(pkt) != 6) {
  450. SCLogDebug("wrong ip version %" PRIu8 "",IP_GET_RAW_VER(pkt));
  451. ENGINE_SET_EVENT(p,IPV6_WRONG_IP_VER);
  452. return -1;
  453. }
  454. p->ip6h = (IPV6Hdr *)pkt;
  455. if (len < (IPV6_HEADER_LEN + IPV6_GET_PLEN(p)))
  456. {
  457. ENGINE_SET_EVENT(p,IPV6_TRUNC_PKT);
  458. return -1;
  459. }
  460. SET_IPV6_SRC_ADDR(p,&p->src);
  461. SET_IPV6_DST_ADDR(p,&p->dst);
  462. return 0;
  463. }
  464. void DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
  465. {
  466. int ret;
  467. SCPerfCounterIncr(dtv->counter_ipv6, tv->sc_perf_pca);
  468. /* do the actual decoding */
  469. ret = DecodeIPV6Packet (tv, dtv, p, pkt, len);
  470. if (ret < 0) {
  471. p->ip6h = NULL;
  472. return;
  473. }
  474. #ifdef DEBUG
  475. if (SCLogDebugEnabled()) { /* only convert the addresses if debug is really enabled */
  476. /* debug print */
  477. char s[46], d[46];
  478. PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), s, sizeof(s));
  479. PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), d, sizeof(d));
  480. SCLogDebug("IPV6 %s->%s - CLASS: %" PRIu32 " FLOW: %" PRIu32 " NH: %" PRIu32 " PLEN: %" PRIu32 " HLIM: %" PRIu32 "", s,d,
  481. IPV6_GET_CLASS(p), IPV6_GET_FLOW(p), IPV6_GET_NH(p), IPV6_GET_PLEN(p),
  482. IPV6_GET_HLIM(p));
  483. }
  484. #endif /* DEBUG */
  485. /* now process the Ext headers and/or the L4 Layer */
  486. switch(IPV6_GET_NH(p)) {
  487. case IPPROTO_TCP:
  488. IPV6_SET_L4PROTO (p, IPPROTO_TCP);
  489. return DecodeTCP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
  490. case IPPROTO_UDP:
  491. IPV6_SET_L4PROTO (p, IPPROTO_UDP);
  492. return DecodeUDP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
  493. break;
  494. case IPPROTO_ICMPV6:
  495. IPV6_SET_L4PROTO (p, IPPROTO_ICMPV6);
  496. return DecodeICMPV6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
  497. case IPPROTO_SCTP:
  498. IPV6_SET_L4PROTO (p, IPPROTO_SCTP);
  499. return DecodeSCTP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
  500. case IPPROTO_IPIP:
  501. IPV6_SET_L4PROTO(p, IPPROTO_IPIP);
  502. return DecodeIPv4inIPv6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
  503. case IPPROTO_IPV6:
  504. return DecodeIP6inIP6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
  505. case IPPROTO_FRAGMENT:
  506. case IPPROTO_HOPOPTS:
  507. case IPPROTO_ROUTING:
  508. case IPPROTO_NONE:
  509. case IPPROTO_DSTOPTS:
  510. case IPPROTO_AH:
  511. case IPPROTO_ESP:
  512. DecodeIPV6ExtHdrs(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
  513. break;
  514. case IPPROTO_ICMP:
  515. ENGINE_SET_EVENT(p,IPV6_WITH_ICMPV4);
  516. break;
  517. default:
  518. p->proto = IPV6_GET_NH(p);
  519. break;
  520. }
  521. /* Pass to defragger if a fragment. */
  522. if (IPV6_EXTHDR_ISSET_FH(p)) {
  523. Packet *rp = Defrag(tv, dtv, p);
  524. if (rp != NULL) {
  525. DecodeIPV6(tv, dtv, rp, (uint8_t *)rp->ip6h, IPV6_GET_PLEN(rp) + IPV6_HEADER_LEN, pq);
  526. PacketEnqueue(pq, rp);
  527. /* Not really a tunnel packet, but we're piggybacking that
  528. * functionality for now. */
  529. SET_TUNNEL_PKT(p);
  530. }
  531. }
  532. #ifdef DEBUG
  533. if (IPV6_EXTHDR_ISSET_FH(p)) {
  534. SCLogDebug("IPV6 FRAG - HDRLEN: %" PRIuMAX " NH: %" PRIu32 " OFFSET: %" PRIu32 " ID: %" PRIu32 "",
  535. (uintmax_t)IPV6_EXTHDR_GET_FH_HDRLEN(p), IPV6_EXTHDR_GET_FH_NH(p),
  536. IPV6_EXTHDR_GET_FH_OFFSET(p), IPV6_EXTHDR_GET_FH_ID(p));
  537. }
  538. if (IPV6_EXTHDR_ISSET_RH(p)) {
  539. SCLogDebug("IPV6 ROUTE - HDRLEN: %" PRIu32 " NH: %" PRIu32 " TYPE: %" PRIu32 "",
  540. IPV6_EXTHDR_GET_RH_HDRLEN(p), IPV6_EXTHDR_GET_RH_NH(p),
  541. IPV6_EXTHDR_GET_RH_TYPE(p));
  542. }
  543. if (IPV6_EXTHDR_ISSET_HH(p)) {
  544. SCLogDebug("IPV6 HOPOPT - HDRLEN: %" PRIu32 " NH: %" PRIu32 "",
  545. IPV6_EXTHDR_GET_HH_HDRLEN(p), IPV6_EXTHDR_GET_HH_NH(p));
  546. }
  547. if (IPV6_EXTHDR_ISSET_DH1(p)) {
  548. SCLogDebug("IPV6 DSTOPT1 - HDRLEN: %" PRIu32 " NH: %" PRIu32 "",
  549. IPV6_EXTHDR_GET_DH1_HDRLEN(p), IPV6_EXTHDR_GET_DH1_NH(p));
  550. }
  551. if (IPV6_EXTHDR_ISSET_DH2(p)) {
  552. SCLogDebug("IPV6 DSTOPT2 - HDRLEN: %" PRIu32 " NH: %" PRIu32 "",
  553. IPV6_EXTHDR_GET_DH2_HDRLEN(p), IPV6_EXTHDR_GET_DH2_NH(p));
  554. }
  555. #endif
  556. return;
  557. }
  558. #ifdef UNITTESTS
  559. /**
  560. * \test fragment decoding
  561. */
  562. static int DecodeIPV6FragTest01 (void) {
  563. uint8_t raw_frag1[] = {
  564. 0x60, 0x0f, 0x1a, 0xcf, 0x05, 0xa8, 0x2c, 0x36, 0x20, 0x01, 0x04, 0x70, 0x00, 0x01, 0x00, 0x18,
  565. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x09, 0x80, 0x32, 0xb2, 0x00, 0x01,
  566. 0x2e, 0x41, 0x38, 0xff, 0xfe, 0xa7, 0xea, 0xeb, 0x06, 0x00, 0x00, 0x01, 0xdf, 0xf8, 0x11, 0xd7,
  567. 0x00, 0x50, 0xa6, 0x5c, 0xcc, 0xd7, 0x28, 0x9f, 0xc3, 0x34, 0xc6, 0x58, 0x80, 0x10, 0x20, 0x13,
  568. 0x18, 0x1f, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0xcd, 0xf9, 0x3a, 0x41, 0x00, 0x1a, 0x91, 0x8a,
  569. 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
  570. 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x30, 0x32, 0x20, 0x44,
  571. 0x65, 0x63, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, 0x30, 0x38, 0x3a, 0x33, 0x32, 0x3a, 0x35, 0x37,
  572. 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
  573. 0x61, 0x63, 0x68, 0x65, 0x0d, 0x0a, 0x43, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x43, 0x6f, 0x6e, 0x74,
  574. 0x72, 0x6f, 0x6c, 0x3a, 0x20, 0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x0d, 0x0a, 0x50,
  575. 0x72, 0x61, 0x67, 0x6d, 0x61, 0x3a, 0x20, 0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x0d,
  576. 0x0a, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30,
  577. 0x31, 0x20, 0x4a, 0x61, 0x6e, 0x20, 0x31, 0x39, 0x37, 0x31, 0x20, 0x30, 0x30, 0x3a, 0x30, 0x30,
  578. 0x3a, 0x30, 0x30, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
  579. 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x35, 0x39, 0x39, 0x0d, 0x0a, 0x4b,
  580. 0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x3a, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x6f,
  581. 0x75, 0x74, 0x3d, 0x35, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x3d, 0x39, 0x39, 0x0d, 0x0a, 0x43, 0x6f,
  582. 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b, 0x65, 0x65, 0x70, 0x2d, 0x41,
  583. 0x6c, 0x69, 0x76, 0x65, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
  584. 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f,
  585. 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3b, 0x63, 0x68, 0x61, 0x72, 0x73,
  586. 0x65, 0x74, 0x3d, 0x61, 0x73, 0x63, 0x69, 0x69, 0x0d, 0x0a, 0x0d, 0x0a, 0x5f, 0x6a, 0x71, 0x6a,
  587. 0x73, 0x70, 0x28, 0x7b, 0x22, 0x69, 0x70, 0x22, 0x3a, 0x22, 0x32, 0x30, 0x30, 0x31, 0x3a, 0x39,
  588. 0x38, 0x30, 0x3a, 0x33, 0x32, 0x62, 0x32, 0x3a, 0x31, 0x3a, 0x32, 0x65, 0x34, 0x31, 0x3a, 0x33,
  589. 0x38, 0x66, 0x66, 0x3a, 0x66, 0x65, 0x61, 0x37, 0x3a, 0x65, 0x61, 0x65, 0x62, 0x22, 0x2c, 0x22,
  590. 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x69, 0x70, 0x76, 0x36, 0x22, 0x2c, 0x22, 0x73, 0x75,
  591. 0x62, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x76, 0x69, 0x61, 0x22, 0x3a,
  592. 0x22, 0x22, 0x2c, 0x22, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x22, 0x20, 0x20,
  593. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  594. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  595. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  596. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  597. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  598. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  599. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  600. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  601. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  602. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  603. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  604. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  605. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  606. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  607. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  608. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  609. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  610. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  611. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  612. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  613. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  614. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  615. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  616. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  617. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  618. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  619. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  620. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  621. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  622. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  623. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  624. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  625. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  626. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  627. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  628. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  629. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  630. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  631. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  632. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  633. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  634. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  635. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  636. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  637. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  638. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  639. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  640. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  641. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  642. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  643. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  644. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  645. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  646. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  647. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  648. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  649. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  650. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  651. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  652. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  653. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  654. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  655. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  656. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  657. };
  658. uint8_t raw_frag2[] = {
  659. 0x60, 0x0f, 0x1a, 0xcf, 0x00, 0x1c, 0x2c, 0x36, 0x20, 0x01, 0x04, 0x70, 0x00, 0x01, 0x00, 0x18,
  660. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x09, 0x80, 0x32, 0xb2, 0x00, 0x01,
  661. 0x2e, 0x41, 0x38, 0xff, 0xfe, 0xa7, 0xea, 0xeb, 0x06, 0x00, 0x05, 0xa0, 0xdf, 0xf8, 0x11, 0xd7,
  662. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  663. 0x20, 0x20, 0x20, 0x20,
  664. };
  665. Packet *p1 = SCMalloc(SIZE_OF_PACKET);
  666. if (unlikely(p1 == NULL))
  667. return 0;
  668. Packet *p2 = SCMalloc(SIZE_OF_PACKET);
  669. if (unlikely(p2 == NULL)) {
  670. SCFree(p1);
  671. return 0;
  672. }
  673. ThreadVars tv;
  674. DecodeThreadVars dtv;
  675. int result = 0;
  676. PacketQueue pq;
  677. FlowInitConfig(FLOW_QUIET);
  678. DefragInit();
  679. memset(&pq, 0, sizeof(PacketQueue));
  680. memset(&tv, 0, sizeof(ThreadVars));
  681. memset(p1, 0, SIZE_OF_PACKET);
  682. p1->pkt = (uint8_t *)(p1 + 1);
  683. memset(p2, 0, SIZE_OF_PACKET);
  684. p2->pkt = (uint8_t *)(p2 + 1);
  685. memset(&dtv, 0, sizeof(DecodeThreadVars));
  686. PACKET_INITIALIZE(p1);
  687. PACKET_INITIALIZE(p2);
  688. PacketCopyData(p1, raw_frag1, sizeof(raw_frag1));
  689. PacketCopyData(p2, raw_frag2, sizeof(raw_frag2));
  690. DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq);
  691. if (!(IPV6_EXTHDR_ISSET_FH(p1))) {
  692. printf("ipv6 frag header not detected: ");
  693. goto end;
  694. }
  695. DecodeIPV6(&tv, &dtv, p2, GET_PKT_DATA(p2), GET_PKT_LEN(p2), &pq);
  696. if (!(IPV6_EXTHDR_ISSET_FH(p2))) {
  697. printf("ipv6 frag header not detected: ");
  698. goto end;
  699. }
  700. if (pq.len != 1) {
  701. printf("no reassembled packet: ");
  702. goto end;
  703. }
  704. result = 1;
  705. end:
  706. PACKET_CLEANUP(p1);
  707. PACKET_CLEANUP(p2);
  708. SCFree(p1);
  709. SCFree(p2);
  710. DefragDestroy();
  711. FlowShutdown();
  712. return result;
  713. }
  714. /**
  715. * \test routing header decode
  716. */
  717. static int DecodeIPV6RouteTest01 (void) {
  718. uint8_t raw_pkt1[] = {
  719. 0x60, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x2b, 0x40,
  720. 0x20, 0x01, 0xaa, 0xaa, 0x00, 0x01, 0x00, 0x00,
  721. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
  722. 0x20, 0x01, 0xaa, 0xaa, 0x00, 0x01, 0x00, 0x00,
  723. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
  724. 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  725. 0xb2, 0xed, 0x00, 0x50, 0x1b, 0xc7, 0x6a, 0xdf,
  726. 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0x20, 0x00,
  727. 0xfa, 0x87, 0x00, 0x00,
  728. };
  729. Packet *p1 = SCMalloc(SIZE_OF_PACKET);
  730. if (unlikely(p1 == NULL))
  731. return 0;
  732. ThreadVars tv;
  733. DecodeThreadVars dtv;
  734. int result = 0;
  735. PacketQueue pq;
  736. FlowInitConfig(FLOW_QUIET);
  737. memset(&pq, 0, sizeof(PacketQueue));
  738. memset(&tv, 0, sizeof(ThreadVars));
  739. memset(p1, 0, SIZE_OF_PACKET);
  740. p1->pkt = (uint8_t *)(p1 + 1);
  741. memset(&dtv, 0, sizeof(DecodeThreadVars));
  742. PACKET_INITIALIZE(p1);
  743. PacketCopyData(p1, raw_pkt1, sizeof(raw_pkt1));
  744. DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq);
  745. if (!(IPV6_EXTHDR_ISSET_RH(p1))) {
  746. printf("ipv6 routing header not detected: ");
  747. goto end;
  748. }
  749. if (p1->ip6eh.ip6_exthdrs[0].len != 8) {
  750. printf("ipv6 routing length incorrect: ");
  751. goto end;
  752. }
  753. result = 1;
  754. end:
  755. PACKET_CLEANUP(p1);
  756. SCFree(p1);
  757. FlowShutdown();
  758. return result;
  759. }
  760. #endif /* UNITTESTS */
  761. /**
  762. * \brief this function registers unit tests for IPV6 decoder
  763. */
  764. void DecodeIPV6RegisterTests(void) {
  765. #ifdef UNITTESTS
  766. UtRegisterTest("DecodeIPV6FragTest01", DecodeIPV6FragTest01, 1);
  767. UtRegisterTest("DecodeIPV6RouteTest01", DecodeIPV6RouteTest01, 1);
  768. #endif /* UNITTESTS */
  769. }
  770. /**
  771. * @}
  772. */