PageRenderTime 57ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/src/decode-ipv6.c

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