PageRenderTime 58ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/src/decode-ipv6.c

https://github.com/gozzy/suricata
C | 1001 lines | 776 code | 118 blank | 107 comment | 126 complexity | cd8c9f1212453890d5d7e1d4b768d208 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 = 0; /* careful, 0 is actually a real type */
  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. /* No upper layer, but we do have data. Suspicious. */
  109. if (nh == IPPROTO_NONE && plen > 0) {
  110. ENGINE_SET_EVENT(p, IPV6_DATA_AFTER_NONE_HEADER);
  111. SCReturn;
  112. }
  113. if (plen < 2) { /* minimal needed in a hdr */
  114. SCReturn;
  115. }
  116. switch(nh)
  117. {
  118. case IPPROTO_TCP:
  119. IPV6_SET_L4PROTO(p,nh);
  120. DecodeTCP(tv, dtv, p, pkt, plen, pq);
  121. SCReturn;
  122. case IPPROTO_UDP:
  123. IPV6_SET_L4PROTO(p,nh);
  124. DecodeUDP(tv, dtv, p, pkt, plen, pq);
  125. SCReturn;
  126. case IPPROTO_ICMPV6:
  127. IPV6_SET_L4PROTO(p,nh);
  128. DecodeICMPV6(tv, dtv, p, pkt, plen, pq);
  129. SCReturn;
  130. case IPPROTO_SCTP:
  131. IPV6_SET_L4PROTO(p,nh);
  132. DecodeSCTP(tv, dtv, p, pkt, plen, pq);
  133. SCReturn;
  134. case IPPROTO_ROUTING:
  135. IPV6_SET_L4PROTO(p,nh);
  136. hdrextlen = 8 + (*(pkt+1) * 8); /* 8 bytes + length in 8 octet units */
  137. SCLogDebug("hdrextlen %"PRIu8, hdrextlen);
  138. if (hdrextlen > plen) {
  139. ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR);
  140. SCReturn;
  141. }
  142. if (p->IPV6_EH_CNT < IPV6_MAX_OPT)
  143. {
  144. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh;
  145. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = *pkt;
  146. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen;
  147. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2;
  148. p->IPV6_EH_CNT++;
  149. }
  150. if (IPV6_EXTHDR_ISSET_RH(p)) {
  151. ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_RH);
  152. /* skip past this extension so we can continue parsing the rest
  153. * of the packet */
  154. nh = *pkt;
  155. pkt += hdrextlen;
  156. plen -= hdrextlen;
  157. break;
  158. }
  159. IPV6_EXTHDR_SET_RH(p, pkt);
  160. /** \todo move into own function and load on demand */
  161. if (IPV6_EXTHDR_RH(p)->ip6rh_type == 0) {
  162. #if 0 // XXX usused and broken, original packet is modified in the memcpy
  163. uint8_t i;
  164. uint8_t n = hdrextlen / 2;
  165. /* because we devide the header len by 2 (as rfc 2460 tells us to)
  166. * we devide the result by 8 and not 16 as the header fields are
  167. * sized */
  168. for (i = 0; i < (n/8) && i < sizeof(IPV6_EXTHDR_RH(p)->ip6rh0_addr)/sizeof(struct in6_addr); ++i) {
  169. /* the address header fields are 16 bytes in size */
  170. /** \todo do this without memcpy since it's expensive */
  171. memcpy(&IPV6_EXTHDR_RH(p)->ip6rh0_addr[i], pkt+(i*16)+8, sizeof(IPV6_EXTHDR_RH(p)->ip6rh0_addr[i]));
  172. }
  173. IPV6_EXTHDR_RH(p)->ip6rh0_num_addrs = i;
  174. #endif
  175. ENGINE_SET_EVENT(p, IPV6_EXTHDR_RH_TYPE_0);
  176. }
  177. nh = *pkt;
  178. pkt += hdrextlen;
  179. plen -= hdrextlen;
  180. break;
  181. case IPPROTO_HOPOPTS:
  182. case IPPROTO_DSTOPTS:
  183. {
  184. IPV6OptHAO *hao = NULL;
  185. IPV6OptRA *ra = NULL;
  186. IPV6OptJumbo *jumbo = NULL;
  187. uint16_t optslen = 0;
  188. IPV6_SET_L4PROTO(p,nh);
  189. hdrextlen = (*(pkt+1) + 1) << 3;
  190. if (hdrextlen > plen) {
  191. ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR);
  192. SCReturn;
  193. }
  194. if (p->IPV6_EH_CNT < IPV6_MAX_OPT)
  195. {
  196. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh;
  197. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = *pkt;
  198. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen;
  199. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2;
  200. p->IPV6_EH_CNT++;
  201. }
  202. uint8_t *ptr = pkt + 2; /* +2 to go past nxthdr and len */
  203. /* point the pointers to right structures
  204. * in Packet. */
  205. if (nh == IPPROTO_HOPOPTS) {
  206. if (IPV6_EXTHDR_ISSET_HH(p)) {
  207. ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_HH);
  208. /* skip past this extension so we can continue parsing the rest
  209. * of the packet */
  210. nh = *pkt;
  211. pkt += hdrextlen;
  212. plen -= hdrextlen;
  213. break;
  214. }
  215. IPV6_EXTHDR_SET_HH(p, pkt);
  216. hao = &IPV6_EXTHDR_HH_HAO(p);
  217. ra = &IPV6_EXTHDR_HH_RA(p);
  218. jumbo = &IPV6_EXTHDR_HH_JUMBO(p);
  219. optslen = ((IPV6_EXTHDR_HH(p)->ip6hh_len+1)<<3)-2;
  220. }
  221. else if (nh == IPPROTO_DSTOPTS)
  222. {
  223. if (dstopts == 0) {
  224. IPV6_EXTHDR_SET_DH1(p, pkt);
  225. hao = &IPV6_EXTHDR_DH1_HAO(p);
  226. ra = &IPV6_EXTHDR_DH1_RA(p);
  227. jumbo = &IPV6_EXTHDR_DH2_JUMBO(p);
  228. optslen = ((IPV6_EXTHDR_DH1(p)->ip6dh_len+1)<<3)-2;
  229. dstopts = 1;
  230. } else if (dstopts == 1) {
  231. IPV6_EXTHDR_SET_DH2(p, pkt);
  232. hao = &IPV6_EXTHDR_DH2_HAO(p);
  233. ra = &IPV6_EXTHDR_DH2_RA(p);
  234. jumbo = &IPV6_EXTHDR_DH2_JUMBO(p);
  235. optslen = ((IPV6_EXTHDR_DH2(p)->ip6dh_len+1)<<3)-2;
  236. dstopts = 2;
  237. } else {
  238. ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_DH);
  239. /* skip past this extension so we can continue parsing the rest
  240. * of the packet */
  241. nh = *pkt;
  242. pkt += hdrextlen;
  243. plen -= hdrextlen;
  244. break;
  245. }
  246. }
  247. if (optslen > plen) {
  248. /* since the packet is long enough (we checked
  249. * plen against hdrlen, the optlen must be malformed. */
  250. ENGINE_SET_EVENT(p, IPV6_EXTHDR_INVALID_OPTLEN);
  251. /* skip past this extension so we can continue parsing the rest
  252. * of the packet */
  253. nh = *pkt;
  254. pkt += hdrextlen;
  255. plen -= hdrextlen;
  256. break;
  257. }
  258. /** \todo move into own function to loaded on demand */
  259. uint16_t padn_cnt = 0;
  260. uint16_t other_cnt = 0;
  261. uint16_t offset = 0;
  262. while(offset < optslen)
  263. {
  264. if (*ptr == IPV6OPT_PAD1)
  265. {
  266. padn_cnt++;
  267. offset++;
  268. ptr++;
  269. continue;
  270. }
  271. if (offset + 1 >= optslen) {
  272. ENGINE_SET_EVENT(p, IPV6_EXTHDR_INVALID_OPTLEN);
  273. break;
  274. }
  275. /* length field for each opt */
  276. uint8_t ip6_optlen = *(ptr + 1);
  277. /* see if the optlen from the packet fits the total optslen */
  278. if ((offset + 1 + ip6_optlen) > optslen) {
  279. ENGINE_SET_EVENT(p, IPV6_EXTHDR_INVALID_OPTLEN);
  280. break;
  281. }
  282. if (*ptr == IPV6OPT_PADN) /* PadN */
  283. {
  284. //printf("PadN option\n");
  285. padn_cnt++;
  286. /* a zero padN len would be weird */
  287. if (ip6_optlen == 0)
  288. ENGINE_SET_EVENT(p, IPV6_EXTHDR_ZERO_LEN_PADN);
  289. }
  290. else if (*ptr == IPV6OPT_RA) /* RA */
  291. {
  292. ra->ip6ra_type = *(ptr);
  293. ra->ip6ra_len = ip6_optlen;
  294. if (ip6_optlen < sizeof(ra->ip6ra_value)) {
  295. ENGINE_SET_EVENT(p, IPV6_EXTHDR_INVALID_OPTLEN);
  296. break;
  297. }
  298. memcpy(&ra->ip6ra_value, (ptr + 2), sizeof(ra->ip6ra_value));
  299. ra->ip6ra_value = ntohs(ra->ip6ra_value);
  300. //printf("RA option: type %" PRIu32 " len %" PRIu32 " value %" PRIu32 "\n",
  301. // ra->ip6ra_type, ra->ip6ra_len, ra->ip6ra_value);
  302. other_cnt++;
  303. }
  304. else if (*ptr == IPV6OPT_JUMBO) /* Jumbo */
  305. {
  306. jumbo->ip6j_type = *(ptr);
  307. jumbo->ip6j_len = ip6_optlen;
  308. if (ip6_optlen < sizeof(jumbo->ip6j_payload_len)) {
  309. ENGINE_SET_EVENT(p, IPV6_EXTHDR_INVALID_OPTLEN);
  310. break;
  311. }
  312. memcpy(&jumbo->ip6j_payload_len, (ptr+2), sizeof(jumbo->ip6j_payload_len));
  313. jumbo->ip6j_payload_len = ntohl(jumbo->ip6j_payload_len);
  314. //printf("Jumbo option: type %" PRIu32 " len %" PRIu32 " payload len %" PRIu32 "\n",
  315. // jumbo->ip6j_type, jumbo->ip6j_len, jumbo->ip6j_payload_len);
  316. }
  317. else if (*ptr == IPV6OPT_HAO) /* HAO */
  318. {
  319. hao->ip6hao_type = *(ptr);
  320. hao->ip6hao_len = ip6_optlen;
  321. if (ip6_optlen < sizeof(hao->ip6hao_hoa)) {
  322. ENGINE_SET_EVENT(p, IPV6_EXTHDR_INVALID_OPTLEN);
  323. break;
  324. }
  325. memcpy(&hao->ip6hao_hoa, (ptr+2), sizeof(hao->ip6hao_hoa));
  326. //printf("HAO option: type %" PRIu32 " len %" PRIu32 " ",
  327. // hao->ip6hao_type, hao->ip6hao_len);
  328. //char addr_buf[46];
  329. //PrintInet(AF_INET6, (char *)&(hao->ip6hao_hoa),
  330. // addr_buf,sizeof(addr_buf));
  331. //printf("home addr %s\n", addr_buf);
  332. other_cnt++;
  333. } else {
  334. if (nh == IPPROTO_HOPOPTS)
  335. ENGINE_SET_EVENT(p, IPV6_HOPOPTS_UNKNOWN_OPT);
  336. else
  337. ENGINE_SET_EVENT(p, IPV6_DSTOPTS_UNKNOWN_OPT);
  338. other_cnt++;
  339. }
  340. uint16_t optlen = (*(ptr + 1) + 2);
  341. ptr += optlen; /* +2 for opt type and opt len fields */
  342. offset += optlen;
  343. }
  344. /* flag packets that have only padding */
  345. if (padn_cnt > 0 && other_cnt == 0) {
  346. if (nh == IPPROTO_HOPOPTS)
  347. ENGINE_SET_EVENT(p, IPV6_HOPOPTS_ONLY_PADDING);
  348. else
  349. ENGINE_SET_EVENT(p, IPV6_DSTOPTS_ONLY_PADDING);
  350. }
  351. nh = *pkt;
  352. pkt += hdrextlen;
  353. plen -= hdrextlen;
  354. break;
  355. }
  356. case IPPROTO_FRAGMENT:
  357. IPV6_SET_L4PROTO(p,nh);
  358. /* store the offset of this extension into the packet
  359. * past the ipv6 header. We use it in defrag for creating
  360. * a defragmented packet without the frag header */
  361. if (exthdr_fh_done == 0) {
  362. p->ip6eh.fh_offset = pkt - orig_pkt;
  363. exthdr_fh_done = 1;
  364. }
  365. hdrextlen = sizeof(IPV6FragHdr);
  366. if (hdrextlen > plen) {
  367. ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR);
  368. SCReturn;
  369. }
  370. /* for the frag header, the length field is reserved */
  371. if (*(pkt + 1) != 0) {
  372. ENGINE_SET_EVENT(p, IPV6_FH_NON_ZERO_RES_FIELD);
  373. /* non fatal, lets try to continue */
  374. }
  375. if(p->IPV6_EH_CNT<IPV6_MAX_OPT)
  376. {
  377. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh;
  378. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = *pkt;
  379. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen;
  380. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2;
  381. p->IPV6_EH_CNT++;
  382. }
  383. if (IPV6_EXTHDR_ISSET_FH(p)) {
  384. ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_FH);
  385. nh = *pkt;
  386. pkt += hdrextlen;
  387. plen -= hdrextlen;
  388. break;
  389. }
  390. /* set the header ptr first */
  391. IPV6_EXTHDR_SET_FH(p, pkt);
  392. /* if FH has offset 0 and no more fragments are coming, we
  393. * parse this packet further right away, no defrag will be
  394. * needed. It is a useless FH then though, so we do set an
  395. * decoder event. */
  396. if (IPV6_EXTHDR_GET_FH_FLAG(p) == 0 && IPV6_EXTHDR_GET_FH_OFFSET(p) == 0) {
  397. ENGINE_SET_EVENT(p, IPV6_EXTHDR_USELESS_FH);
  398. nh = *pkt;
  399. pkt += hdrextlen;
  400. plen -= hdrextlen;
  401. break;
  402. }
  403. /* the rest is parsed upon reassembly */
  404. p->flags |= PKT_IS_FRAGMENT;
  405. SCReturn;
  406. case IPPROTO_ESP:
  407. {
  408. IPV6_SET_L4PROTO(p,nh);
  409. hdrextlen = sizeof(IPV6EspHdr);
  410. if (hdrextlen > plen) {
  411. ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR);
  412. SCReturn;
  413. }
  414. if(p->IPV6_EH_CNT<IPV6_MAX_OPT)
  415. {
  416. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh;
  417. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = IPPROTO_NONE;
  418. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen;
  419. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2;
  420. p->IPV6_EH_CNT++;
  421. }
  422. if (IPV6_EXTHDR_ISSET_EH(p)) {
  423. ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_EH);
  424. SCReturn;
  425. }
  426. IPV6_EXTHDR_SET_EH(p, pkt);
  427. nh = IPPROTO_NONE;
  428. pkt += hdrextlen;
  429. plen -= hdrextlen;
  430. break;
  431. }
  432. case IPPROTO_AH:
  433. {
  434. IPV6_SET_L4PROTO(p,nh);
  435. /* we need the header as a minimum */
  436. hdrextlen = sizeof(IPV6AuthHdr);
  437. /* the payload len field is the number of extra 4 byte fields,
  438. * IPV6AuthHdr already contains the first */
  439. if (*(pkt+1) > 0)
  440. hdrextlen += ((*(pkt+1) - 1) * 4);
  441. SCLogDebug("hdrextlen %"PRIu8, hdrextlen);
  442. if (hdrextlen > plen) {
  443. ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR);
  444. SCReturn;
  445. }
  446. IPV6AuthHdr *ahhdr = (IPV6AuthHdr *)pkt;
  447. if (ahhdr->ip6ah_reserved != 0x0000) {
  448. ENGINE_SET_EVENT(p, IPV6_EXTHDR_AH_RES_NOT_NULL);
  449. }
  450. if(p->IPV6_EH_CNT < IPV6_MAX_OPT)
  451. {
  452. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].type = nh;
  453. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].next = *pkt;
  454. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].len = hdrextlen;
  455. p->IPV6_EXTHDRS[p->IPV6_EH_CNT].data = pkt+2;
  456. p->IPV6_EH_CNT++;
  457. }
  458. if (IPV6_EXTHDR_ISSET_AH(p)) {
  459. ENGINE_SET_EVENT(p, IPV6_EXTHDR_DUPL_AH);
  460. nh = *pkt;
  461. pkt += hdrextlen;
  462. plen -= hdrextlen;
  463. break;
  464. }
  465. IPV6_EXTHDR_SET_AH(p, pkt);
  466. nh = *pkt;
  467. pkt += hdrextlen;
  468. plen -= hdrextlen;
  469. break;
  470. }
  471. case IPPROTO_IPIP:
  472. IPV6_SET_L4PROTO(p,nh);
  473. DecodeIPv4inIPv6(tv, dtv, p, pkt, plen, pq);
  474. SCReturn;
  475. /* none, last header */
  476. case IPPROTO_NONE:
  477. IPV6_SET_L4PROTO(p,nh);
  478. SCReturn;
  479. case IPPROTO_ICMP:
  480. ENGINE_SET_EVENT(p,IPV6_WITH_ICMPV4);
  481. SCReturn;
  482. /* no parsing yet, just skip it */
  483. case IPPROTO_MH:
  484. case IPPROTO_HIP:
  485. case IPPROTO_SHIM6:
  486. hdrextlen = 8 + (*(pkt+1) * 8); /* 8 bytes + length in 8 octet units */
  487. if (hdrextlen > plen) {
  488. ENGINE_SET_EVENT(p, IPV6_TRUNC_EXTHDR);
  489. SCReturn;
  490. }
  491. nh = *pkt;
  492. pkt += hdrextlen;
  493. plen -= hdrextlen;
  494. break;
  495. default:
  496. ENGINE_SET_EVENT(p, IPV6_UNKNOWN_NEXT_HEADER);
  497. IPV6_SET_L4PROTO(p,nh);
  498. SCReturn;
  499. }
  500. }
  501. SCReturn;
  502. }
  503. static int DecodeIPV6Packet (ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len)
  504. {
  505. if (unlikely(len < IPV6_HEADER_LEN)) {
  506. return -1;
  507. }
  508. if (unlikely(IP_GET_RAW_VER(pkt) != 6)) {
  509. SCLogDebug("wrong ip version %" PRIu8 "",IP_GET_RAW_VER(pkt));
  510. ENGINE_SET_INVALID_EVENT(p, IPV6_WRONG_IP_VER);
  511. return -1;
  512. }
  513. p->ip6h = (IPV6Hdr *)pkt;
  514. if (unlikely(len < (IPV6_HEADER_LEN + IPV6_GET_PLEN(p))))
  515. {
  516. ENGINE_SET_INVALID_EVENT(p, IPV6_TRUNC_PKT);
  517. return -1;
  518. }
  519. SET_IPV6_SRC_ADDR(p,&p->src);
  520. SET_IPV6_DST_ADDR(p,&p->dst);
  521. return 0;
  522. }
  523. int DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
  524. {
  525. int ret;
  526. SCPerfCounterIncr(dtv->counter_ipv6, tv->sc_perf_pca);
  527. /* do the actual decoding */
  528. ret = DecodeIPV6Packet (tv, dtv, p, pkt, len);
  529. if (unlikely(ret < 0)) {
  530. p->ip6h = NULL;
  531. return TM_ECODE_FAILED;
  532. }
  533. #ifdef DEBUG
  534. if (SCLogDebugEnabled()) { /* only convert the addresses if debug is really enabled */
  535. /* debug print */
  536. char s[46], d[46];
  537. PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), s, sizeof(s));
  538. PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), d, sizeof(d));
  539. SCLogDebug("IPV6 %s->%s - CLASS: %" PRIu32 " FLOW: %" PRIu32 " NH: %" PRIu32 " PLEN: %" PRIu32 " HLIM: %" PRIu32 "", s,d,
  540. IPV6_GET_CLASS(p), IPV6_GET_FLOW(p), IPV6_GET_NH(p), IPV6_GET_PLEN(p),
  541. IPV6_GET_HLIM(p));
  542. }
  543. #endif /* DEBUG */
  544. /* now process the Ext headers and/or the L4 Layer */
  545. switch(IPV6_GET_NH(p)) {
  546. case IPPROTO_TCP:
  547. IPV6_SET_L4PROTO (p, IPPROTO_TCP);
  548. DecodeTCP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
  549. return TM_ECODE_OK;
  550. case IPPROTO_UDP:
  551. IPV6_SET_L4PROTO (p, IPPROTO_UDP);
  552. DecodeUDP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
  553. return TM_ECODE_OK;
  554. case IPPROTO_ICMPV6:
  555. IPV6_SET_L4PROTO (p, IPPROTO_ICMPV6);
  556. DecodeICMPV6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
  557. return TM_ECODE_OK;
  558. case IPPROTO_SCTP:
  559. IPV6_SET_L4PROTO (p, IPPROTO_SCTP);
  560. DecodeSCTP(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
  561. return TM_ECODE_OK;
  562. case IPPROTO_IPIP:
  563. IPV6_SET_L4PROTO(p, IPPROTO_IPIP);
  564. DecodeIPv4inIPv6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
  565. return TM_ECODE_OK;
  566. case IPPROTO_IPV6:
  567. DecodeIP6inIP6(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
  568. return TM_ECODE_OK;
  569. case IPPROTO_FRAGMENT:
  570. case IPPROTO_HOPOPTS:
  571. case IPPROTO_ROUTING:
  572. case IPPROTO_NONE:
  573. case IPPROTO_DSTOPTS:
  574. case IPPROTO_AH:
  575. case IPPROTO_ESP:
  576. case IPPROTO_MH:
  577. case IPPROTO_HIP:
  578. case IPPROTO_SHIM6:
  579. DecodeIPV6ExtHdrs(tv, dtv, p, pkt + IPV6_HEADER_LEN, IPV6_GET_PLEN(p), pq);
  580. break;
  581. case IPPROTO_ICMP:
  582. ENGINE_SET_EVENT(p,IPV6_WITH_ICMPV4);
  583. break;
  584. default:
  585. ENGINE_SET_EVENT(p, IPV6_UNKNOWN_NEXT_HEADER);
  586. IPV6_SET_L4PROTO (p, IPV6_GET_NH(p));
  587. break;
  588. }
  589. p->proto = IPV6_GET_L4PROTO (p);
  590. /* Pass to defragger if a fragment. */
  591. if (IPV6_EXTHDR_ISSET_FH(p)) {
  592. Packet *rp = Defrag(tv, dtv, p, pq);
  593. if (rp != NULL) {
  594. PacketEnqueue(pq,rp);
  595. }
  596. }
  597. #ifdef DEBUG
  598. if (IPV6_EXTHDR_ISSET_FH(p)) {
  599. SCLogDebug("IPV6 FRAG - HDRLEN: %" PRIuMAX " NH: %" PRIu32 " OFFSET: %" PRIu32 " ID: %" PRIu32 "",
  600. (uintmax_t)IPV6_EXTHDR_GET_FH_HDRLEN(p), IPV6_EXTHDR_GET_FH_NH(p),
  601. IPV6_EXTHDR_GET_FH_OFFSET(p), IPV6_EXTHDR_GET_FH_ID(p));
  602. }
  603. if (IPV6_EXTHDR_ISSET_RH(p)) {
  604. SCLogDebug("IPV6 ROUTE - HDRLEN: %" PRIu32 " NH: %" PRIu32 " TYPE: %" PRIu32 "",
  605. IPV6_EXTHDR_GET_RH_HDRLEN(p), IPV6_EXTHDR_GET_RH_NH(p),
  606. IPV6_EXTHDR_GET_RH_TYPE(p));
  607. }
  608. if (IPV6_EXTHDR_ISSET_HH(p)) {
  609. SCLogDebug("IPV6 HOPOPT - HDRLEN: %" PRIu32 " NH: %" PRIu32 "",
  610. IPV6_EXTHDR_GET_HH_HDRLEN(p), IPV6_EXTHDR_GET_HH_NH(p));
  611. }
  612. if (IPV6_EXTHDR_ISSET_DH1(p)) {
  613. SCLogDebug("IPV6 DSTOPT1 - HDRLEN: %" PRIu32 " NH: %" PRIu32 "",
  614. IPV6_EXTHDR_GET_DH1_HDRLEN(p), IPV6_EXTHDR_GET_DH1_NH(p));
  615. }
  616. if (IPV6_EXTHDR_ISSET_DH2(p)) {
  617. SCLogDebug("IPV6 DSTOPT2 - HDRLEN: %" PRIu32 " NH: %" PRIu32 "",
  618. IPV6_EXTHDR_GET_DH2_HDRLEN(p), IPV6_EXTHDR_GET_DH2_NH(p));
  619. }
  620. #endif
  621. return TM_ECODE_OK;
  622. }
  623. #ifdef UNITTESTS
  624. /**
  625. * \test fragment decoding
  626. */
  627. static int DecodeIPV6FragTest01 (void)
  628. {
  629. uint8_t raw_frag1[] = {
  630. 0x60, 0x0f, 0x1a, 0xcf, 0x05, 0xa8, 0x2c, 0x36, 0x20, 0x01, 0x04, 0x70, 0x00, 0x01, 0x00, 0x18,
  631. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x09, 0x80, 0x32, 0xb2, 0x00, 0x01,
  632. 0x2e, 0x41, 0x38, 0xff, 0xfe, 0xa7, 0xea, 0xeb, 0x06, 0x00, 0x00, 0x01, 0xdf, 0xf8, 0x11, 0xd7,
  633. 0x00, 0x50, 0xa6, 0x5c, 0xcc, 0xd7, 0x28, 0x9f, 0xc3, 0x34, 0xc6, 0x58, 0x80, 0x10, 0x20, 0x13,
  634. 0x18, 0x1f, 0x00, 0x00, 0x01, 0x01, 0x08, 0x0a, 0xcd, 0xf9, 0x3a, 0x41, 0x00, 0x1a, 0x91, 0x8a,
  635. 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
  636. 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x30, 0x32, 0x20, 0x44,
  637. 0x65, 0x63, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20, 0x30, 0x38, 0x3a, 0x33, 0x32, 0x3a, 0x35, 0x37,
  638. 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
  639. 0x61, 0x63, 0x68, 0x65, 0x0d, 0x0a, 0x43, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x43, 0x6f, 0x6e, 0x74,
  640. 0x72, 0x6f, 0x6c, 0x3a, 0x20, 0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x0d, 0x0a, 0x50,
  641. 0x72, 0x61, 0x67, 0x6d, 0x61, 0x3a, 0x20, 0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, 0x0d,
  642. 0x0a, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30,
  643. 0x31, 0x20, 0x4a, 0x61, 0x6e, 0x20, 0x31, 0x39, 0x37, 0x31, 0x20, 0x30, 0x30, 0x3a, 0x30, 0x30,
  644. 0x3a, 0x30, 0x30, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,
  645. 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x35, 0x39, 0x39, 0x0d, 0x0a, 0x4b,
  646. 0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x3a, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x6f,
  647. 0x75, 0x74, 0x3d, 0x35, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x3d, 0x39, 0x39, 0x0d, 0x0a, 0x43, 0x6f,
  648. 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b, 0x65, 0x65, 0x70, 0x2d, 0x41,
  649. 0x6c, 0x69, 0x76, 0x65, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
  650. 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f,
  651. 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3b, 0x63, 0x68, 0x61, 0x72, 0x73,
  652. 0x65, 0x74, 0x3d, 0x61, 0x73, 0x63, 0x69, 0x69, 0x0d, 0x0a, 0x0d, 0x0a, 0x5f, 0x6a, 0x71, 0x6a,
  653. 0x73, 0x70, 0x28, 0x7b, 0x22, 0x69, 0x70, 0x22, 0x3a, 0x22, 0x32, 0x30, 0x30, 0x31, 0x3a, 0x39,
  654. 0x38, 0x30, 0x3a, 0x33, 0x32, 0x62, 0x32, 0x3a, 0x31, 0x3a, 0x32, 0x65, 0x34, 0x31, 0x3a, 0x33,
  655. 0x38, 0x66, 0x66, 0x3a, 0x66, 0x65, 0x61, 0x37, 0x3a, 0x65, 0x61, 0x65, 0x62, 0x22, 0x2c, 0x22,
  656. 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x69, 0x70, 0x76, 0x36, 0x22, 0x2c, 0x22, 0x73, 0x75,
  657. 0x62, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x76, 0x69, 0x61, 0x22, 0x3a,
  658. 0x22, 0x22, 0x2c, 0x22, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x22, 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. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  666. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  667. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  668. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  669. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  670. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  671. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  672. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  673. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  674. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  675. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  676. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  677. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  678. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  679. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  680. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 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. };
  724. uint8_t raw_frag2[] = {
  725. 0x60, 0x0f, 0x1a, 0xcf, 0x00, 0x1c, 0x2c, 0x36, 0x20, 0x01, 0x04, 0x70, 0x00, 0x01, 0x00, 0x18,
  726. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x09, 0x80, 0x32, 0xb2, 0x00, 0x01,
  727. 0x2e, 0x41, 0x38, 0xff, 0xfe, 0xa7, 0xea, 0xeb, 0x06, 0x00, 0x05, 0xa0, 0xdf, 0xf8, 0x11, 0xd7,
  728. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  729. 0x20, 0x20, 0x20, 0x20,
  730. };
  731. Packet *pkt;
  732. Packet *p1 = PacketGetFromAlloc();
  733. if (unlikely(p1 == NULL))
  734. return 0;
  735. Packet *p2 = PacketGetFromAlloc();
  736. if (unlikely(p2 == NULL)) {
  737. SCFree(p1);
  738. return 0;
  739. }
  740. ThreadVars tv;
  741. DecodeThreadVars dtv;
  742. int result = 0;
  743. PacketQueue pq;
  744. FlowInitConfig(FLOW_QUIET);
  745. DefragInit();
  746. memset(&pq, 0, sizeof(PacketQueue));
  747. memset(&tv, 0, sizeof(ThreadVars));
  748. memset(&dtv, 0, sizeof(DecodeThreadVars));
  749. PacketCopyData(p1, raw_frag1, sizeof(raw_frag1));
  750. PacketCopyData(p2, raw_frag2, sizeof(raw_frag2));
  751. DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq);
  752. if (!(IPV6_EXTHDR_ISSET_FH(p1))) {
  753. printf("ipv6 frag header not detected: ");
  754. goto end;
  755. }
  756. DecodeIPV6(&tv, &dtv, p2, GET_PKT_DATA(p2), GET_PKT_LEN(p2), &pq);
  757. if (!(IPV6_EXTHDR_ISSET_FH(p2))) {
  758. printf("ipv6 frag header not detected: ");
  759. goto end;
  760. }
  761. if (pq.len != 1) {
  762. printf("no reassembled packet: ");
  763. goto end;
  764. }
  765. result = 1;
  766. end:
  767. PACKET_RECYCLE(p1);
  768. PACKET_RECYCLE(p2);
  769. SCFree(p1);
  770. SCFree(p2);
  771. pkt = PacketDequeue(&pq);
  772. while (pkt != NULL) {
  773. PACKET_RECYCLE(pkt);
  774. SCFree(pkt);
  775. pkt = PacketDequeue(&pq);
  776. }
  777. DefragDestroy();
  778. FlowShutdown();
  779. return result;
  780. }
  781. /**
  782. * \test routing header decode
  783. */
  784. static int DecodeIPV6RouteTest01 (void)
  785. {
  786. uint8_t raw_pkt1[] = {
  787. 0x60, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x2b, 0x40,
  788. 0x20, 0x01, 0xaa, 0xaa, 0x00, 0x01, 0x00, 0x00,
  789. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
  790. 0x20, 0x01, 0xaa, 0xaa, 0x00, 0x01, 0x00, 0x00,
  791. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
  792. 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  793. 0xb2, 0xed, 0x00, 0x50, 0x1b, 0xc7, 0x6a, 0xdf,
  794. 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0x20, 0x00,
  795. 0xfa, 0x87, 0x00, 0x00,
  796. };
  797. Packet *p1 = PacketGetFromAlloc();
  798. if (unlikely(p1 == NULL))
  799. return 0;
  800. ThreadVars tv;
  801. DecodeThreadVars dtv;
  802. int result = 0;
  803. PacketQueue pq;
  804. FlowInitConfig(FLOW_QUIET);
  805. memset(&pq, 0, sizeof(PacketQueue));
  806. memset(&tv, 0, sizeof(ThreadVars));
  807. memset(&dtv, 0, sizeof(DecodeThreadVars));
  808. PacketCopyData(p1, raw_pkt1, sizeof(raw_pkt1));
  809. DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq);
  810. if (!(IPV6_EXTHDR_ISSET_RH(p1))) {
  811. printf("ipv6 routing header not detected: ");
  812. goto end;
  813. }
  814. if (p1->ip6eh.ip6_exthdrs[0].len != 8) {
  815. printf("ipv6 routing length incorrect: ");
  816. goto end;
  817. }
  818. result = 1;
  819. end:
  820. PACKET_RECYCLE(p1);
  821. SCFree(p1);
  822. FlowShutdown();
  823. return result;
  824. }
  825. /**
  826. * \test HOP header decode
  827. */
  828. static int DecodeIPV6HopTest01 (void)
  829. {
  830. uint8_t raw_pkt1[] = {
  831. 0x60,0x00,0x00,0x00,0x00,0x20,0x00,0x01,0xfe,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
  832. 0x02,0x0f,0xfe,0xff,0xfe,0x98,0x3d,0x01,0xff,0x02,0x00,0x00,0x00,0x00,0x00,0x00,
  833. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x3a,0x00,0x05,0x02,0x00,0x00,0x00,0x00,
  834. 0x82,0x00,0x1c,0x6f,0x27,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  835. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
  836. };
  837. Packet *p1 = PacketGetFromAlloc();
  838. if (unlikely(p1 == NULL))
  839. return 0;
  840. ThreadVars tv;
  841. DecodeThreadVars dtv;
  842. int result = 0;
  843. PacketQueue pq;
  844. FlowInitConfig(FLOW_QUIET);
  845. memset(&pq, 0, sizeof(PacketQueue));
  846. memset(&tv, 0, sizeof(ThreadVars));
  847. memset(&dtv, 0, sizeof(DecodeThreadVars));
  848. PacketCopyData(p1, raw_pkt1, sizeof(raw_pkt1));
  849. DecodeIPV6(&tv, &dtv, p1, GET_PKT_DATA(p1), GET_PKT_LEN(p1), &pq);
  850. if (!(IPV6_EXTHDR_ISSET_HH(p1))) {
  851. printf("ipv6 routing header not detected: ");
  852. goto end;
  853. }
  854. if (p1->ip6eh.ip6_exthdrs[0].len != 8) {
  855. printf("ipv6 routing length incorrect: ");
  856. goto end;
  857. }
  858. if (ENGINE_ISSET_EVENT(p1, IPV6_HOPOPTS_UNKNOWN_OPT)) {
  859. printf("engine event IPV6_HOPOPTS_UNKNOWN_OPT set: ");
  860. goto end;
  861. }
  862. result = 1;
  863. end:
  864. PACKET_RECYCLE(p1);
  865. SCFree(p1);
  866. FlowShutdown();
  867. return result;
  868. }
  869. #endif /* UNITTESTS */
  870. /**
  871. * \brief this function registers unit tests for IPV6 decoder
  872. */
  873. void DecodeIPV6RegisterTests(void)
  874. {
  875. #ifdef UNITTESTS
  876. UtRegisterTest("DecodeIPV6FragTest01", DecodeIPV6FragTest01, 1);
  877. UtRegisterTest("DecodeIPV6RouteTest01", DecodeIPV6RouteTest01, 1);
  878. UtRegisterTest("DecodeIPV6HopTest01", DecodeIPV6HopTest01, 1);
  879. #endif /* UNITTESTS */
  880. }
  881. /**
  882. * @}
  883. */