]> git.ipfire.org Git - people/ms/suricata.git/blame - src/decode-icmpv6.c
core: Remove unneeded consts
[people/ms/suricata.git] / src / decode-icmpv6.c
CommitLineData
2eef905c 1/* Copyright (C) 2007-2010 Open Information Security Foundation
ce019275
WM
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
acf10525
EL
18/**
19 * \ingroup decode
20 *
21 * @{
22 */
23
24
ce019275
WM
25/**
26 * \file
27 *
28 * \author Victor Julien <victor@inliniac.net>
29 *
30 * Decode ICMPv6
31 */
bab4b623 32
ecf86f9c 33#include "suricata-common.h"
bab4b623 34#include "decode-icmpv6.h"
292a7e47
PR
35#include "decode.h"
36#include "decode-tcp.h"
8be92fdd 37#include "decode-sctp.h"
292a7e47
PR
38#include "decode-udp.h"
39#include "decode-events.h"
401a0313 40#include "util-unittest.h"
292a7e47 41#include "flow.h"
3a28171f 42#include "util-debug.h"
6b9d1012 43#include "util-print.h"
401a0313 44
c5bd04f1
EL
45#include "pkt-var.h"
46#include "util-profiling.h"
47#include "host.h"
48
292a7e47
PR
49
50/**
51 * \brief Get variables and do some checks of the embedded IPV6 packet
52 *
53 * \param p Pointer to the packet we are filling
54 * \param partial_packet Pointer to the raw packet buffer
55 * \param len the len of the rest of the packet not processed yet
56 *
57 * \retval void No return value
58 */
ab1200fb 59static void DecodePartialIPV6(Packet *p, uint8_t *partial_packet, uint16_t len )
292a7e47
PR
60{
61 /** Check the sizes, the header must fit at least */
62 if (len < IPV6_HEADER_LEN) {
06c382a4 63 SCLogDebug("ICMPV6_IPV6_TRUNC_PKT");
b2c58b8d 64 ENGINE_SET_INVALID_EVENT(p, ICMPV6_IPV6_TRUNC_PKT);
292a7e47
PR
65 return;
66 }
67
68 IPV6Hdr *icmp6_ip6h = (IPV6Hdr*)partial_packet;
69
70 /** Check the embedded version */
71 if(((icmp6_ip6h->s_ip6_vfc & 0xf0) >> 4) != 6)
32830ff4 72 {
06c382a4 73 SCLogDebug("ICMPv6 contains Unknown IPV6 version "
32830ff4 74 "ICMPV6_IPV6_UNKNOWN_VER");
b2c58b8d 75 ENGINE_SET_INVALID_EVENT(p, ICMPV6_IPV6_UNKNOWN_VER);
292a7e47
PR
76 return;
77 }
78
79 /** We need to fill icmpv6vars */
80 p->icmpv6vars.emb_ipv6h = icmp6_ip6h;
81
82 /** Get the IP6 address */
cdba2f50
VJ
83 p->icmpv6vars.emb_ip6_src[0] = icmp6_ip6h->s_ip6_src[0];
84 p->icmpv6vars.emb_ip6_src[1] = icmp6_ip6h->s_ip6_src[1];
85 p->icmpv6vars.emb_ip6_src[2] = icmp6_ip6h->s_ip6_src[2];
86 p->icmpv6vars.emb_ip6_src[3] = icmp6_ip6h->s_ip6_src[3];
292a7e47 87
cdba2f50
VJ
88 p->icmpv6vars.emb_ip6_dst[0] = icmp6_ip6h->s_ip6_dst[0];
89 p->icmpv6vars.emb_ip6_dst[1] = icmp6_ip6h->s_ip6_dst[1];
90 p->icmpv6vars.emb_ip6_dst[2] = icmp6_ip6h->s_ip6_dst[2];
91 p->icmpv6vars.emb_ip6_dst[3] = icmp6_ip6h->s_ip6_dst[3];
292a7e47
PR
92
93 /** Get protocol and ports inside the embedded ipv6 packet and set the pointers */
94 p->icmpv6vars.emb_ip6_proto_next = icmp6_ip6h->s_ip6_nxt;
95
96 switch (icmp6_ip6h->s_ip6_nxt) {
97 case IPPROTO_TCP:
98 if (len >= IPV6_HEADER_LEN + TCP_HEADER_LEN ) {
99 p->icmpv6vars.emb_tcph = (TCPHdr*)(partial_packet + IPV6_HEADER_LEN);
100 p->icmpv6vars.emb_sport = p->icmpv6vars.emb_tcph->th_sport;
101 p->icmpv6vars.emb_dport = p->icmpv6vars.emb_tcph->th_dport;
102
06c382a4 103 SCLogDebug("ICMPV6->IPV6->TCP header sport: "
248f9c66 104 "%"PRIu16" dport %"PRIu16"", p->icmpv6vars.emb_sport,
292a7e47
PR
105 p->icmpv6vars.emb_dport);
106 } else {
06c382a4 107 SCLogDebug("Warning, ICMPV6->IPV6->TCP "
292a7e47
PR
108 "header Didn't fit in the packet!");
109 p->icmpv6vars.emb_sport = 0;
110 p->icmpv6vars.emb_dport = 0;
111 }
112
113 break;
114 case IPPROTO_UDP:
115 if (len >= IPV6_HEADER_LEN + UDP_HEADER_LEN ) {
116 p->icmpv6vars.emb_udph = (UDPHdr*)(partial_packet + IPV6_HEADER_LEN);
117 p->icmpv6vars.emb_sport = p->icmpv6vars.emb_udph->uh_sport;
118 p->icmpv6vars.emb_dport = p->icmpv6vars.emb_udph->uh_dport;
119
06c382a4 120 SCLogDebug("ICMPV6->IPV6->UDP header sport: "
248f9c66 121 "%"PRIu16" dport %"PRIu16"", p->icmpv6vars.emb_sport,
292a7e47
PR
122 p->icmpv6vars.emb_dport);
123 } else {
06c382a4 124 SCLogDebug("Warning, ICMPV6->IPV6->UDP "
292a7e47
PR
125 "header Didn't fit in the packet!");
126 p->icmpv6vars.emb_sport = 0;
127 p->icmpv6vars.emb_dport = 0;
128 }
129
130 break;
131 case IPPROTO_ICMPV6:
132 p->icmpv6vars.emb_icmpv6h = (ICMPV6Hdr*)(partial_packet + IPV6_HEADER_LEN);
133 p->icmpv6vars.emb_sport = 0;
134 p->icmpv6vars.emb_dport = 0;
135
06c382a4 136 SCLogDebug("ICMPV6->IPV6->ICMP header");
292a7e47
PR
137
138 break;
139 }
140
141 /* debug print */
142#ifdef DEBUG
143 char s[46], d[46];
6b9d1012
EL
144 PrintInet(AF_INET6, (const void *)p->icmpv6vars.emb_ip6_src, s, sizeof(s));
145 PrintInet(AF_INET6, (const void *)p->icmpv6vars.emb_ip6_dst, d, sizeof(d));
292a7e47
PR
146 SCLogDebug("ICMPv6 embedding IPV6 %s->%s - CLASS: %" PRIu32 " FLOW: "
147 "%" PRIu32 " NH: %" PRIu32 " PLEN: %" PRIu32 " HLIM: %" PRIu32,
148 s, d, IPV6_GET_RAW_CLASS(icmp6_ip6h), IPV6_GET_RAW_FLOW(icmp6_ip6h),
149 IPV6_GET_RAW_NH(icmp6_ip6h), IPV6_GET_RAW_PLEN(icmp6_ip6h), IPV6_GET_RAW_HLIM(icmp6_ip6h));
150#endif
151
152 return;
153}
154
c662383b
VJ
155/** \retval type counterpart type or -1 */
156int ICMPv6GetCounterpart(uint8_t type)
157{
158#define CASE_CODE(t,r) case (t): return r; case (r): return t;
159 switch (type) {
160 CASE_CODE(ICMP6_ECHO_REQUEST, ICMP6_ECHO_REPLY);
161 CASE_CODE(ND_NEIGHBOR_SOLICIT, ND_NEIGHBOR_ADVERT);
162 CASE_CODE(ND_ROUTER_SOLICIT, ND_ROUTER_ADVERT);
163 CASE_CODE(MLD_LISTENER_QUERY, MLD_LISTENER_REPORT);
164 CASE_CODE(ICMP6_NI_QUERY, ICMP6_NI_REPLY);
165 CASE_CODE(HOME_AGENT_AD_REQUEST,HOME_AGENT_AD_REPLY);
166
167 CASE_CODE(MOBILE_PREFIX_SOLICIT,MOBILE_PREFIX_ADVERT);
168 CASE_CODE(CERT_PATH_SOLICIT, CERT_PATH_ADVERT);
169 CASE_CODE(MC_ROUTER_ADVERT, MC_ROUTER_SOLICIT);
170 CASE_CODE(DUPL_ADDR_REQUEST, DUPL_ADDR_CONFIRM);
171 default:
172 return -1;
173 }
174#undef CASE_CODE
175}
176
292a7e47
PR
177/**
178 * \brief Decode ICMPV6 packets and fill the Packet with the decoded info
179 *
180 * \param tv Pointer to the thread variables
181 * \param dtv Pointer to the decode thread variables
182 * \param p Pointer to the packet we are filling
183 * \param pkt Pointer to the raw packet buffer
184 * \param len the len of the rest of the packet not processed yet
292a7e47
PR
185 *
186 * \retval void No return value
187 */
d4b7ecfb 188int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
f8aed4ce 189 const uint8_t *pkt, uint32_t len)
bab4b623 190{
ba367dad 191 int full_hdr = 0;
1c0b4ee0 192 StatsIncr(tv, dtv->counter_icmpv6);
d0e70309 193
bab4b623 194 if (len < ICMPV6_HEADER_LEN) {
06c382a4 195 SCLogDebug("ICMPV6_PKT_TOO_SMALL");
b2c58b8d 196 ENGINE_SET_INVALID_EVENT(p, ICMPV6_PKT_TOO_SMALL);
d4b7ecfb 197 return TM_ECODE_FAILED;
bab4b623
VJ
198 }
199
57f71f7e 200 p->icmpv6h = (ICMPV6Hdr *)pkt;
292a7e47 201 p->proto = IPPROTO_ICMPV6;
c662383b
VJ
202 p->icmp_s.type = p->icmpv6h->type;
203 p->icmp_s.code = p->icmpv6h->code;
ad9ec4db 204 p->payload_len = len - ICMPV6_HEADER_LEN;
579cc9f0 205 p->payload = (uint8_t *)pkt + ICMPV6_HEADER_LEN;
57f71f7e 206
c662383b
VJ
207 int ctype = ICMPv6GetCounterpart(p->icmp_s.type);
208 if (ctype != -1) {
209 p->icmp_d.type = (uint8_t)ctype;
210 }
211
292a7e47
PR
212 SCLogDebug("ICMPV6 TYPE %" PRIu32 " CODE %" PRIu32 "", p->icmpv6h->type,
213 p->icmpv6h->code);
214
215 switch (ICMPV6_GET_TYPE(p)) {
216 case ICMP6_DST_UNREACH:
06c382a4 217 SCLogDebug("ICMP6_DST_UNREACH");
292a7e47
PR
218
219 if (ICMPV6_GET_CODE(p) > ICMP6_DST_UNREACH_REJECTROUTE) {
7425bf5c 220 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
292a7e47 221 } else {
55b14f37
MA
222 if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) {
223 return TM_ECODE_FAILED;
224 }
292a7e47
PR
225 DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN),
226 len - ICMPV6_HEADER_LEN );
ba367dad 227 full_hdr = 1;
292a7e47
PR
228 }
229
230 break;
231 case ICMP6_PACKET_TOO_BIG:
06c382a4 232 SCLogDebug("ICMP6_PACKET_TOO_BIG");
292a7e47
PR
233
234 if (ICMPV6_GET_CODE(p) != 0) {
7425bf5c 235 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
292a7e47 236 } else {
55b14f37
MA
237 if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) {
238 return TM_ECODE_FAILED;
239 }
292a7e47
PR
240 p->icmpv6vars.mtu = ICMPV6_GET_MTU(p);
241 DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN),
242 len - ICMPV6_HEADER_LEN );
ba367dad 243 full_hdr = 1;
292a7e47
PR
244 }
245
246 break;
247 case ICMP6_TIME_EXCEEDED:
06c382a4 248 SCLogDebug("ICMP6_TIME_EXCEEDED");
292a7e47
PR
249
250 if (ICMPV6_GET_CODE(p) > ICMP6_TIME_EXCEED_REASSEMBLY) {
7425bf5c 251 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
292a7e47 252 } else {
55b14f37
MA
253 if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) {
254 return TM_ECODE_FAILED;
255 }
292a7e47
PR
256 DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN),
257 len - ICMPV6_HEADER_LEN );
ba367dad 258 full_hdr = 1;
292a7e47
PR
259 }
260
261 break;
262 case ICMP6_PARAM_PROB:
06c382a4 263 SCLogDebug("ICMP6_PARAM_PROB");
292a7e47
PR
264
265 if (ICMPV6_GET_CODE(p) > ICMP6_PARAMPROB_OPTION) {
7425bf5c 266 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
292a7e47 267 } else {
55b14f37
MA
268 if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) {
269 return TM_ECODE_FAILED;
270 }
292a7e47
PR
271 p->icmpv6vars.error_ptr= ICMPV6_GET_ERROR_PTR(p);
272 DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN),
273 len - ICMPV6_HEADER_LEN );
ba367dad 274 full_hdr = 1;
292a7e47
PR
275 }
276
277 break;
278 case ICMP6_ECHO_REQUEST:
06c382a4 279 SCLogDebug("ICMP6_ECHO_REQUEST id: %u seq: %u",
7e87f373 280 p->icmpv6h->icmpv6b.icmpv6i.id, p->icmpv6h->icmpv6b.icmpv6i.seq);
292a7e47
PR
281
282 if (ICMPV6_GET_CODE(p) != 0) {
7425bf5c 283 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
292a7e47 284 } else {
7e87f373
GIG
285 p->icmpv6vars.id = p->icmpv6h->icmpv6b.icmpv6i.id;
286 p->icmpv6vars.seq = p->icmpv6h->icmpv6b.icmpv6i.seq;
ba367dad 287 full_hdr = 1;
292a7e47
PR
288 }
289
290 break;
291 case ICMP6_ECHO_REPLY:
06c382a4 292 SCLogDebug("ICMP6_ECHO_REPLY id: %u seq: %u",
7e87f373 293 p->icmpv6h->icmpv6b.icmpv6i.id, p->icmpv6h->icmpv6b.icmpv6i.seq);
292a7e47 294
98e8b13b 295 if (ICMPV6_GET_CODE(p) != 0) {
7425bf5c 296 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
292a7e47 297 } else {
7e87f373
GIG
298 p->icmpv6vars.id = p->icmpv6h->icmpv6b.icmpv6i.id;
299 p->icmpv6vars.seq = p->icmpv6h->icmpv6b.icmpv6i.seq;
ba367dad 300 full_hdr = 1;
292a7e47
PR
301 }
302
7a9da787
JI
303 break;
304 case ND_ROUTER_SOLICIT:
305 SCLogDebug("ND_ROUTER_SOLICIT");
98e8b13b 306 if (ICMPV6_GET_CODE(p) != 0) {
9f2ce16e
VJ
307 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
308 }
309 break;
7a9da787
JI
310 case ND_ROUTER_ADVERT:
311 SCLogDebug("ND_ROUTER_ADVERT");
98e8b13b 312 if (ICMPV6_GET_CODE(p) != 0) {
9f2ce16e
VJ
313 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
314 }
315 break;
7a9da787
JI
316 case ND_NEIGHBOR_SOLICIT:
317 SCLogDebug("ND_NEIGHBOR_SOLICIT");
98e8b13b 318 if (ICMPV6_GET_CODE(p) != 0) {
9f2ce16e
VJ
319 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
320 }
321 break;
7a9da787
JI
322 case ND_NEIGHBOR_ADVERT:
323 SCLogDebug("ND_NEIGHBOR_ADVERT");
98e8b13b 324 if (ICMPV6_GET_CODE(p) != 0) {
9f2ce16e
VJ
325 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
326 }
327 break;
7a9da787
JI
328 case ND_REDIRECT:
329 SCLogDebug("ND_REDIRECT");
98e8b13b 330 if (ICMPV6_GET_CODE(p) != 0) {
7a9da787
JI
331 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
332 }
292a7e47 333 break;
7539372d
VJ
334 case MLD_LISTENER_QUERY:
335 SCLogDebug("MLD_LISTENER_QUERY");
98e8b13b 336 if (ICMPV6_GET_CODE(p) != 0) {
7539372d
VJ
337 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
338 }
0bb2b154
VJ
339 if (IPV6_GET_HLIM(p) != 1) {
340 ENGINE_SET_EVENT(p, ICMPV6_MLD_MESSAGE_WITH_INVALID_HL);
341 }
7539372d
VJ
342 break;
343 case MLD_LISTENER_REPORT:
344 SCLogDebug("MLD_LISTENER_REPORT");
98e8b13b 345 if (ICMPV6_GET_CODE(p) != 0) {
7539372d
VJ
346 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
347 }
0bb2b154
VJ
348 if (IPV6_GET_HLIM(p) != 1) {
349 ENGINE_SET_EVENT(p, ICMPV6_MLD_MESSAGE_WITH_INVALID_HL);
350 }
7539372d
VJ
351 break;
352 case MLD_LISTENER_REDUCTION:
353 SCLogDebug("MLD_LISTENER_REDUCTION");
98e8b13b 354 if (ICMPV6_GET_CODE(p) != 0) {
7539372d
VJ
355 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
356 }
0bb2b154
VJ
357 if (IPV6_GET_HLIM(p) != 1) {
358 ENGINE_SET_EVENT(p, ICMPV6_MLD_MESSAGE_WITH_INVALID_HL);
359 }
7539372d 360 break;
98e8b13b
AH
361 case ICMP6_RR:
362 SCLogDebug("ICMP6_RR");
363 if (ICMPV6_GET_CODE(p) > 2 && ICMPV6_GET_CODE(p) != 255) {
364 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
365 }
366 break;
367 case ICMP6_NI_QUERY:
368 SCLogDebug("ICMP6_NI_QUERY");
369 if (ICMPV6_GET_CODE(p) > 2) {
370 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
371 }
372 break;
373 case ICMP6_NI_REPLY:
374 SCLogDebug("ICMP6_NI_REPLY");
375 if (ICMPV6_GET_CODE(p) > 2) {
376 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
377 }
378 break;
379 case ND_INVERSE_SOLICIT:
380 SCLogDebug("ND_INVERSE_SOLICIT");
381 if (ICMPV6_GET_CODE(p) != 0) {
382 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
383 }
384 break;
385 case ND_INVERSE_ADVERT:
386 SCLogDebug("ND_INVERSE_ADVERT");
387 if (ICMPV6_GET_CODE(p) != 0) {
388 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
389 }
390 break;
391 case MLD_V2_LIST_REPORT:
392 SCLogDebug("MLD_V2_LIST_REPORT");
393 if (ICMPV6_GET_CODE(p) != 0) {
394 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
395 }
396 break;
397 case HOME_AGENT_AD_REQUEST:
398 SCLogDebug("HOME_AGENT_AD_REQUEST");
399 if (ICMPV6_GET_CODE(p) != 0) {
400 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
401 }
402 break;
403 case HOME_AGENT_AD_REPLY:
404 SCLogDebug("HOME_AGENT_AD_REPLY");
405 if (ICMPV6_GET_CODE(p) != 0) {
406 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
407 }
408 break;
409 case MOBILE_PREFIX_SOLICIT:
410 SCLogDebug("MOBILE_PREFIX_SOLICIT");
411 if (ICMPV6_GET_CODE(p) != 0) {
412 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
413 }
414 break;
415 case MOBILE_PREFIX_ADVERT:
416 SCLogDebug("MOBILE_PREFIX_ADVERT");
417 if (ICMPV6_GET_CODE(p) != 0) {
418 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
419 }
420 break;
421 case CERT_PATH_SOLICIT:
422 SCLogDebug("CERT_PATH_SOLICIT");
423 if (ICMPV6_GET_CODE(p) != 0) {
424 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
425 }
426 break;
427 case CERT_PATH_ADVERT:
428 SCLogDebug("CERT_PATH_ADVERT");
429 if (ICMPV6_GET_CODE(p) != 0) {
430 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
431 }
432 break;
433 case ICMP6_MOBILE_EXPERIMENTAL:
434 SCLogDebug("ICMP6_MOBILE_EXPERIMENTAL");
435 break;
436 case MC_ROUTER_ADVERT:
437 SCLogDebug("MC_ROUTER_ADVERT");
438 break;
439 case MC_ROUTER_SOLICIT:
440 SCLogDebug("MC_ROUTER_SOLICIT");
441 break;
442 case MC_ROUTER_TERMINATE:
443 SCLogDebug("MC_ROUTER_TERMINATE");
444 break;
445 case FMIPV6_MSG:
446 SCLogDebug("FMIPV6_MSG");
447 if (ICMPV6_GET_CODE(p) != 0) {
448 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
449 }
450 break;
451 case RPL_CONTROL_MSG:
452 SCLogDebug("RPL_CONTROL_MSG");
453 if (ICMPV6_GET_CODE(p) > 3 && ICMPV6_GET_CODE(p) < 128) {
454 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
455 }
456 if (ICMPV6_GET_CODE(p) > 132) {
457 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
458 }
459 break;
460 case LOCATOR_UDATE_MSG:
461 SCLogDebug("LOCATOR_UDATE_MSG");
462 if (ICMPV6_GET_CODE(p) != 0) {
463 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
464 }
465 break;
466 case DUPL_ADDR_REQUEST:
467 SCLogDebug("DUPL_ADDR_REQUEST");
468 if (ICMPV6_GET_CODE(p) != 0) {
469 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
470 }
471 break;
472 case DUPL_ADDR_CONFIRM:
473 SCLogDebug("DUPL_ADDR_CONFIRM");
474 if (ICMPV6_GET_CODE(p) != 0) {
475 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
476 }
477 break;
478 case MPL_CONTROL_MSG:
479 SCLogDebug("MPL_CONTROL_MSG");
480 if (ICMPV6_GET_CODE(p) != 0) {
481 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
482 }
483 break;
292a7e47 484 default:
ab3aed7d
EL
485 /* Various range taken from:
486 * http://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml#icmpv6-parameters-2
487 */
488 if ((ICMPV6_GET_TYPE(p) > 4) && (ICMPV6_GET_TYPE(p) < 100)) {
489 ENGINE_SET_EVENT(p, ICMPV6_UNASSIGNED_TYPE);
490 } else if ((ICMPV6_GET_TYPE(p) >= 100) && (ICMPV6_GET_TYPE(p) < 102)) {
491 ENGINE_SET_EVENT(p, ICMPV6_EXPERIMENTATION_TYPE);
492 } else if ((ICMPV6_GET_TYPE(p) >= 102) && (ICMPV6_GET_TYPE(p) < 127)) {
493 ENGINE_SET_EVENT(p, ICMPV6_UNASSIGNED_TYPE);
494 } else if ((ICMPV6_GET_TYPE(p) >= 160) && (ICMPV6_GET_TYPE(p) < 200)) {
495 ENGINE_SET_EVENT(p, ICMPV6_UNASSIGNED_TYPE);
496 } else if ((ICMPV6_GET_TYPE(p) >= 200) && (ICMPV6_GET_TYPE(p) < 202)) {
497 ENGINE_SET_EVENT(p, ICMPV6_EXPERIMENTATION_TYPE);
498 } else if (ICMPV6_GET_TYPE(p) >= 202) {
499 ENGINE_SET_EVENT(p, ICMPV6_UNASSIGNED_TYPE);
500 } else {
501 SCLogDebug("ICMPV6 Message type %" PRIu8 " not "
502 "implemented yet", ICMPV6_GET_TYPE(p));
503 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_TYPE);
504 }
292a7e47
PR
505 }
506
a6471cdb 507 /* for a info message the header is just 4 bytes */
ba367dad 508 if (!full_hdr) {
a6471cdb
VJ
509 if (p->payload_len >= 4) {
510 p->payload_len -= 4;
579cc9f0 511 p->payload = (uint8_t *)pkt + 4;
a6471cdb
VJ
512 } else {
513 p->payload_len = 0;
514 p->payload = NULL;
515 }
516 }
292a7e47 517
a6471cdb 518#ifdef DEBUG
7425bf5c 519 if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE))
06c382a4 520 SCLogDebug("Unknown Code, ICMPV6_UNKNOWN_CODE");
292a7e47 521
7425bf5c 522 if (ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_TYPE))
06c382a4 523 SCLogDebug("Unknown Type, ICMPV6_UNKNOWN_TYPE");
a6471cdb 524#endif
bab4b623 525
2f0e0f17 526 FlowSetupPacket(p);
10cc9d5b 527
d4b7ecfb 528 return TM_ECODE_OK;
bab4b623
VJ
529}
530
c43319c3
BS
531#ifdef UNITTESTS
532
8f1d7503
KS
533static int ICMPV6CalculateValidChecksumtest01(void)
534{
401a0313
AS
535 uint16_t csum = 0;
536
537 uint8_t raw_ipv6[] = {
538 0x00, 0x00, 0x86, 0x05, 0x80, 0xda, 0x00, 0x60,
539 0x97, 0x07, 0x69, 0xea, 0x86, 0xdd, 0x60, 0x00,
540 0x00, 0x00, 0x00, 0x44, 0x3a, 0x40, 0x3f, 0xfe,
541 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x60,
542 0x97, 0xff, 0xfe, 0x07, 0x69, 0xea, 0x3f, 0xfe,
543 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
544 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x03, 0x00,
545 0xf7, 0x52, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
546 0x00, 0x00, 0x00, 0x14, 0x11, 0x01, 0x3f, 0xfe,
547 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
548 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
549 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
550 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75,
551 0x82, 0x9b, 0x00, 0x14, 0x82, 0x8b, 0x01, 0x01,
552 0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0xf5, 0xed,
553 0x08, 0x00};
554
555 csum = *( ((uint16_t *)(raw_ipv6 + 56)));
556
3cf8b462 557 FAIL_IF(csum != ICMPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8),
401a0313 558 (uint16_t *)(raw_ipv6 + 54), 68));
3cf8b462 559 PASS;
401a0313
AS
560}
561
8f1d7503
KS
562static int ICMPV6CalculateInvalidChecksumtest02(void)
563{
401a0313
AS
564 uint16_t csum = 0;
565
566 uint8_t raw_ipv6[] = {
567 0x00, 0x00, 0x86, 0x05, 0x80, 0xda, 0x00, 0x60,
568 0x97, 0x07, 0x69, 0xea, 0x86, 0xdd, 0x60, 0x00,
569 0x00, 0x00, 0x00, 0x44, 0x3a, 0x40, 0x3f, 0xfe,
570 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x60,
571 0x97, 0xff, 0xfe, 0x07, 0x69, 0xea, 0x3f, 0xfe,
572 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
573 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x03, 0x00,
574 0xf7, 0x52, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
575 0x00, 0x00, 0x00, 0x14, 0x11, 0x01, 0x3f, 0xfe,
576 0x05, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
577 0x86, 0xff, 0xfe, 0x05, 0x80, 0xda, 0x3f, 0xfe,
578 0x05, 0x01, 0x04, 0x10, 0x00, 0x00, 0x02, 0xc0,
579 0xdf, 0xff, 0xfe, 0x47, 0x03, 0x3e, 0xa0, 0x75,
580 0x82, 0x9b, 0x00, 0x14, 0x82, 0x8b, 0x01, 0x01,
581 0x00, 0x00, 0xf9, 0xc8, 0xe7, 0x36, 0xf5, 0xed,
582 0x08, 0x01};
583
584 csum = *( ((uint16_t *)(raw_ipv6 + 56)));
585
3cf8b462 586 FAIL_IF(csum == ICMPV6CalculateChecksum((uint16_t *)(raw_ipv6 + 14 + 8),
401a0313 587 (uint16_t *)(raw_ipv6 + 54), 68));
3cf8b462 588 PASS;
401a0313
AS
589}
590
292a7e47
PR
591/** \test icmpv6 message type: parameter problem, valid packet
592 *
593 * \retval retval 0 = Error ; 1 = ok
594 */
595static int ICMPV6ParamProbTest01(void)
596{
292a7e47
PR
597 static uint8_t raw_ipv6[] = {
598 0x60, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3a, 0xff,
599 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
601 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
603 0x04, 0x00, 0xcc, 0x2a, 0x6d, 0x93, 0x0b, 0xdf,
604 0x69, 0x70, 0x12, 0xb7, 0x00, 0x08, 0x3a, 0xff,
605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
609 0x80, 0x00, 0x08, 0xb5, 0x99, 0xc3, 0xde, 0x40 };
610
1db4aadd 611 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 612 FAIL_IF_NULL(p);
292a7e47
PR
613 IPV6Hdr ip6h;
614 ThreadVars tv;
615 DecodeThreadVars dtv;
616 uint32_t *ipv6src;
617 uint32_t *ipv6dst;
618 ipv6src = (uint32_t*) &raw_ipv6[8];
619 ipv6dst = (uint32_t*) &raw_ipv6[24];
620
621 memset(&tv, 0, sizeof(ThreadVars));
1db4aadd 622 memset(p, 0, SIZE_OF_PACKET);
292a7e47
PR
623 memset(&dtv, 0, sizeof(DecodeThreadVars));
624 memset(&ip6h, 0, sizeof(IPV6Hdr));
625
626 FlowInitConfig(FLOW_QUIET);
f8aed4ce 627 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
292a7e47 628
3cf8b462 629 FAIL_IF(p->icmpv6h == NULL);
292a7e47 630
3cf8b462
JI
631 /* ICMPv6 not processed at all? */
632 FAIL_IF(ICMPV6_GET_TYPE(p) != 4 || ICMPV6_GET_CODE(p) != 0 ||
633 ICMPV6_GET_EMB_PROTO(p) != IPPROTO_ICMPV6);
292a7e47
PR
634
635 /* Let's check if we retrieved the embedded ipv6 addresses correctly */
636 uint32_t i=0;
637 for (i = 0; i < 4; i++) {
3cf8b462
JI
638 FAIL_IF(p->icmpv6vars.emb_ip6_src[i] != ipv6src[i] ||
639 p->icmpv6vars.emb_ip6_dst[i] != ipv6dst[i]);
292a7e47
PR
640 }
641
c5bd04f1
EL
642 PACKET_RECYCLE(p);
643 FlowShutdown();
1db4aadd 644 SCFree(p);
3cf8b462 645 PASS;
292a7e47
PR
646}
647
648/** \test icmpv6 message type: packet too big, valid packet
649 *
650 * \retval retval 0 = Error ; 1 = ok
651 */
652static int ICMPV6PktTooBigTest01(void)
653{
292a7e47
PR
654 static uint8_t raw_ipv6[] = {
655 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff,
656 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
658 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
659 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
660 0x02, 0x00, 0x5c, 0x7a, 0x00, 0x00, 0x05, 0x00,
661 0x64, 0x14, 0xfd, 0xff, 0x00, 0x00, 0x3b, 0xff,
662 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
663 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
664 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
665 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
666
1db4aadd 667 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 668 FAIL_IF_NULL(p);
292a7e47
PR
669 IPV6Hdr ip6h;
670 ThreadVars tv;
671 DecodeThreadVars dtv;
672 uint32_t *ipv6src;
673 uint32_t *ipv6dst;
674 ipv6src = (uint32_t*) &raw_ipv6[8];
675 ipv6dst = (uint32_t*) &raw_ipv6[24];
676
677 memset(&tv, 0, sizeof(ThreadVars));
1db4aadd 678 memset(p, 0, SIZE_OF_PACKET);
292a7e47
PR
679 memset(&dtv, 0, sizeof(DecodeThreadVars));
680 memset(&ip6h, 0, sizeof(IPV6Hdr));
681
682 FlowInitConfig(FLOW_QUIET);
f8aed4ce 683 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
292a7e47 684
3cf8b462 685 FAIL_IF(p->icmpv6h == NULL);
292a7e47 686
3cf8b462
JI
687 /* Note: it has an embedded ipv6 packet but no protocol after ipv6
688 * (IPPROTO_NONE) */
689 /* Check if ICMPv6 header was processed at all. */
690 FAIL_IF(ICMPV6_GET_TYPE(p) != 2 || ICMPV6_GET_CODE(p) != 0 );
292a7e47
PR
691
692 /* Let's check if we retrieved the embedded ipv6 addresses correctly */
693 uint32_t i=0;
694 for (i = 0; i < 4; i++) {
3cf8b462
JI
695 FAIL_IF(p->icmpv6vars.emb_ip6_src[i] != ipv6src[i] ||
696 p->icmpv6vars.emb_ip6_dst[i] != ipv6dst[i]);
292a7e47
PR
697 }
698
699 SCLogDebug("ICMPV6 IPV6 src and dst properly set");
700
c5bd04f1
EL
701 PACKET_RECYCLE(p);
702 FlowShutdown();
1db4aadd 703 SCFree(p);
3cf8b462 704 PASS;
292a7e47
PR
705}
706
707/** \test icmpv6 message type: time exceed, valid packet
708 *
709 * \retval retval 0 = Error ; 1 = ok
710 */
711static int ICMPV6TimeExceedTest01(void)
712{
292a7e47
PR
713 static uint8_t raw_ipv6[] = {
714 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff,
715 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
716 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
717 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
718 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
719 0x03, 0x00, 0x56, 0x2d, 0x00, 0x00, 0x00, 0x00,
720 0x6d, 0x23, 0xff, 0x3d, 0x00, 0x00, 0x3b, 0xff,
721 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
722 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
723 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
725
1db4aadd 726 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 727 FAIL_IF_NULL(p);
292a7e47
PR
728 IPV6Hdr ip6h;
729 ThreadVars tv;
730 DecodeThreadVars dtv;
731 uint32_t *ipv6src;
732 uint32_t *ipv6dst;
733 ipv6src = (uint32_t*) &raw_ipv6[8];
734 ipv6dst = (uint32_t*) &raw_ipv6[24];
735
292a7e47 736 memset(&tv, 0, sizeof(ThreadVars));
1db4aadd 737 memset(p, 0, SIZE_OF_PACKET);
292a7e47
PR
738 memset(&dtv, 0, sizeof(DecodeThreadVars));
739 memset(&ip6h, 0, sizeof(IPV6Hdr));
740
741 FlowInitConfig(FLOW_QUIET);
f8aed4ce 742 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
292a7e47 743
3cf8b462 744 FAIL_IF_NULL(p->icmpv6h);
292a7e47
PR
745
746 /* Note: it has an embedded ipv6 packet but no protocol after ipv6 (IPPROTO_NONE) */
3cf8b462
JI
747 FAIL_IF(ICMPV6_GET_TYPE(p) != 3 || ICMPV6_GET_CODE(p) != 0 ||
748 ICMPV6_GET_EMB_IPV6(p) == NULL ||
749 ICMPV6_GET_EMB_PROTO(p) != IPPROTO_NONE);
292a7e47
PR
750
751 /* Let's check if we retrieved the embedded ipv6 addresses correctly */
752 uint32_t i=0;
753 for (i = 0; i < 4; i++) {
3cf8b462
JI
754 FAIL_IF(p->icmpv6vars.emb_ip6_src[i] != ipv6src[i] ||
755 p->icmpv6vars.emb_ip6_dst[i] != ipv6dst[i]);
292a7e47
PR
756 }
757
758 SCLogDebug("ICMPV6 IPV6 src and dst properly set");
759
c5bd04f1
EL
760 PACKET_RECYCLE(p);
761 FlowShutdown();
1db4aadd 762 SCFree(p);
3cf8b462 763 PASS;
292a7e47
PR
764}
765
766/** \test icmpv6 message type: destination unreach, valid packet
767 *
768 * \retval retval 0 = Error ; 1 = ok
769 */
770static int ICMPV6DestUnreachTest01(void)
771{
292a7e47
PR
772 static uint8_t raw_ipv6[] = {
773 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff,
774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
776 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
777 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
778 0x01, 0x00, 0x7b, 0x85, 0x00, 0x00, 0x00, 0x00,
779 0x60, 0x4b, 0xe8, 0xbd, 0x00, 0x00, 0x3b, 0xff,
780 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
781 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
782 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
783 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
784
1db4aadd 785 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 786 FAIL_IF_NULL(p);
292a7e47
PR
787 IPV6Hdr ip6h;
788 ThreadVars tv;
789 DecodeThreadVars dtv;
790 uint32_t *ipv6src;
791 uint32_t *ipv6dst;
792 ipv6src = (uint32_t*) &raw_ipv6[8];
793 ipv6dst = (uint32_t*) &raw_ipv6[24];
794
292a7e47 795 memset(&tv, 0, sizeof(ThreadVars));
1db4aadd 796 memset(p, 0, SIZE_OF_PACKET);
292a7e47
PR
797 memset(&dtv, 0, sizeof(DecodeThreadVars));
798 memset(&ip6h, 0, sizeof(IPV6Hdr));
799
800 FlowInitConfig(FLOW_QUIET);
f8aed4ce 801 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
292a7e47 802
3cf8b462 803 FAIL_IF_NULL(p->icmpv6h);
292a7e47
PR
804
805 /* Note: it has an embedded ipv6 packet but no protocol after ipv6 (IPPROTO_NONE) */
3cf8b462
JI
806 FAIL_IF(ICMPV6_GET_TYPE(p) != 1 || ICMPV6_GET_CODE(p) != 0 ||
807 ICMPV6_GET_EMB_IPV6(p) == NULL ||
808 ICMPV6_GET_EMB_PROTO(p) != IPPROTO_NONE);
292a7e47
PR
809
810 /* Let's check if we retrieved the embedded ipv6 addresses correctly */
811 uint32_t i=0;
812 for (i = 0; i < 4; i++) {
3cf8b462
JI
813 FAIL_IF(p->icmpv6vars.emb_ip6_src[i] != ipv6src[i] ||
814 p->icmpv6vars.emb_ip6_dst[i] != ipv6dst[i]);
292a7e47
PR
815 }
816
c5bd04f1
EL
817 PACKET_RECYCLE(p);
818 FlowShutdown();
1db4aadd 819 SCFree(p);
3cf8b462 820 PASS;
292a7e47
PR
821}
822
823/**\test icmpv6 message type: echo request, valid packet
824 * \retval retval 0 = Error ; 1 = ok
825 */
826static int ICMPV6EchoReqTest01(void)
827{
292a7e47
PR
828 static uint8_t raw_ipv6[] = {
829 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
830 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
831 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
832 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
833 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
834 0x80, 0x00, 0xe5, 0xa5, 0x25, 0xf0, 0x75, 0x23 };
835
1db4aadd 836 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 837 FAIL_IF_NULL(p);
292a7e47
PR
838 IPV6Hdr ip6h;
839 ThreadVars tv;
840 DecodeThreadVars dtv;
841
842 memset(&tv, 0, sizeof(ThreadVars));
1db4aadd 843 memset(p, 0, SIZE_OF_PACKET);
292a7e47
PR
844 memset(&dtv, 0, sizeof(DecodeThreadVars));
845 memset(&ip6h, 0, sizeof(IPV6Hdr));
846
847 FlowInitConfig(FLOW_QUIET);
f8aed4ce 848 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
292a7e47 849
3cf8b462 850 FAIL_IF_NULL(p->icmpv6h);
292a7e47 851
1db4aadd 852 SCLogDebug("ID: %u seq: %u", ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p));
292a7e47 853
1db4aadd 854 if (ICMPV6_GET_TYPE(p) != 128 || ICMPV6_GET_CODE(p) != 0 ||
11be9bd9 855 SCNtohs(ICMPV6_GET_ID(p)) != 9712 || SCNtohs(ICMPV6_GET_SEQ(p)) != 29987) {
4b4111e9 856 printf("ICMPv6 Echo reply decode failed TYPE %u CODE %u ID %04x(%u) SEQ %04x(%u): ",
11be9bd9
VJ
857 ICMPV6_GET_TYPE(p), ICMPV6_GET_CODE(p), ICMPV6_GET_ID(p), SCNtohs(ICMPV6_GET_ID(p)),
858 ICMPV6_GET_SEQ(p), SCNtohs(ICMPV6_GET_SEQ(p)));
3cf8b462 859 FAIL;
292a7e47
PR
860 }
861
c5bd04f1
EL
862 PACKET_RECYCLE(p);
863 FlowShutdown();
1db4aadd 864 SCFree(p);
3cf8b462 865 PASS;
292a7e47
PR
866}
867
868/**\test icmpv6 message type: echo reply, valid packet
869 * \retval retval 0 = Error ; 1 = ok
870 */
871static int ICMPV6EchoRepTest01(void)
872{
292a7e47
PR
873 static uint8_t raw_ipv6[] = {
874 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a,
875 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
876 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
877 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00,
878 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
879 0x00, 0x00, 0x00, 0x00, 0x01, 0x81, 0x00,
880 0xe5, 0xa5, 0x25, 0xf0, 0x75, 0x23 };
881
1db4aadd 882 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 883 FAIL_IF_NULL(p);
292a7e47
PR
884 IPV6Hdr ip6h;
885 ThreadVars tv;
886 DecodeThreadVars dtv;
887
888 memset(&tv, 0, sizeof(ThreadVars));
1db4aadd 889 memset(p, 0, SIZE_OF_PACKET);
292a7e47
PR
890 memset(&dtv, 0, sizeof(DecodeThreadVars));
891 memset(&ip6h, 0, sizeof(IPV6Hdr));
892
893 FlowInitConfig(FLOW_QUIET);
f8aed4ce 894 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
292a7e47 895
3cf8b462 896 FAIL_IF_NULL(p->icmpv6h);
292a7e47 897
1db4aadd
EL
898 SCLogDebug("type: %u code %u ID: %u seq: %u", ICMPV6_GET_TYPE(p),
899 ICMPV6_GET_CODE(p),ICMPV6_GET_ID(p), ICMPV6_GET_SEQ(p));
292a7e47 900
1db4aadd 901 if (ICMPV6_GET_TYPE(p) != 129 || ICMPV6_GET_CODE(p) != 0 ||
11be9bd9 902 SCNtohs(ICMPV6_GET_ID(p)) != 9712 || SCNtohs(ICMPV6_GET_SEQ(p)) != 29987) {
4b4111e9 903 printf("ICMPv6 Echo reply decode failed TYPE %u CODE %u ID %04x(%u) SEQ %04x(%u): ",
11be9bd9
VJ
904 ICMPV6_GET_TYPE(p), ICMPV6_GET_CODE(p), ICMPV6_GET_ID(p), SCNtohs(ICMPV6_GET_ID(p)),
905 ICMPV6_GET_SEQ(p), SCNtohs(ICMPV6_GET_SEQ(p)));
3cf8b462 906 FAIL;
292a7e47
PR
907 }
908
c5bd04f1
EL
909 PACKET_RECYCLE(p);
910 FlowShutdown();
1db4aadd 911 SCFree(p);
3cf8b462 912 PASS;
292a7e47
PR
913}
914
915/** \test icmpv6 message type: parameter problem, invalid packet
916 * \brief set the event ICMPV6_IPV6_UNKNOWN_VER properly when the embedded packet has an unknown version
917 * \retval retval 0 = Error ; 1 = ok
918 */
919static int ICMPV6ParamProbTest02(void)
920{
292a7e47
PR
921 static uint8_t raw_ipv6[] = {
922 0x60, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3a, 0xff,
923 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
924 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
925 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
926 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
927 0x04, 0x00, 0xcc, 0x2a, 0x6d, 0x93, 0x0b, 0xdf,
928 0x38, 0x70, 0x12, 0xb7, 0x00, 0x08, 0x3a, 0xff,
929 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
930 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
931 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
932 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
933 0x80, 0x00, 0x08, 0xb5, 0x99, 0xc3, 0xde, 0x40 };
934
1db4aadd 935 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 936 FAIL_IF_NULL(p);
292a7e47
PR
937 IPV6Hdr ip6h;
938 ThreadVars tv;
939 DecodeThreadVars dtv;
940
941 memset(&tv, 0, sizeof(ThreadVars));
1db4aadd 942 memset(p, 0, SIZE_OF_PACKET);
292a7e47
PR
943 memset(&dtv, 0, sizeof(DecodeThreadVars));
944 memset(&ip6h, 0, sizeof(IPV6Hdr));
945
946 FlowInitConfig(FLOW_QUIET);
f8aed4ce 947 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
292a7e47 948
3cf8b462
JI
949 FAIL_IF_NULL(p->icmpv6h);
950 FAIL_IF(ICMPV6_GET_TYPE(p) != 4 || ICMPV6_GET_CODE(p) != 0);
951 FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_IPV6_UNKNOWN_VER));
292a7e47 952
c5bd04f1
EL
953 PACKET_RECYCLE(p);
954 FlowShutdown();
1db4aadd 955 SCFree(p);
3cf8b462 956 PASS;
292a7e47
PR
957}
958
959/** \test icmpv6 message type: packet too big, invalid packet
960 * \brief Set the event ICMPV6_UNKNOWN_CODE if code is invalid for this type
961 * \retval retval 0 = Error ; 1 = ok
962 */
963static int ICMPV6PktTooBigTest02(void)
964{
292a7e47
PR
965 static uint8_t raw_ipv6[] = {
966 0x60, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3a, 0xff,
967 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
968 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
969 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
970 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
971 0x02, 0x10, 0x5c, 0x7a, 0x00, 0x00, 0x05, 0x00,
972 0x64, 0x14, 0xfd, 0xff, 0x00, 0x00, 0x3b, 0xff,
973 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
974 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
975 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
976 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };
977
1db4aadd 978 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 979 FAIL_IF_NULL(p);
292a7e47
PR
980 IPV6Hdr ip6h;
981 ThreadVars tv;
982 DecodeThreadVars dtv;
983
984 memset(&tv, 0, sizeof(ThreadVars));
1db4aadd 985 memset(p, 0, SIZE_OF_PACKET);
292a7e47
PR
986 memset(&dtv, 0, sizeof(DecodeThreadVars));
987 memset(&ip6h, 0, sizeof(IPV6Hdr));
988
989 FlowInitConfig(FLOW_QUIET);
f8aed4ce 990 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
292a7e47 991
3cf8b462
JI
992 FAIL_IF_NULL(p->icmpv6h);
993 FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE));
292a7e47 994
c5bd04f1
EL
995 PACKET_RECYCLE(p);
996 FlowShutdown();
1db4aadd 997 SCFree(p);
3cf8b462 998 PASS;
292a7e47
PR
999}
1000
1001/** \test icmpv6 message type: time exceed, invalid packet
1002 * \brief set the event ICMPV6_PKT_TOO_SMALL properly
1003 * \retval retval 0 = Error ; 1 = ok
1004 */
1005static int ICMPV6TimeExceedTest02(void)
1006{
292a7e47
PR
1007 static uint8_t raw_ipv6[] = {
1008 0x60, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3a, 0xff,
1009 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1010 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1011 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1012 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1013 0x02, 0x10, 0x5c };
1014
1015 /* The icmpv6 header is broken in the checksum (so we dont have a complete header) */
1016
1db4aadd 1017 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 1018 FAIL_IF_NULL(p);
292a7e47
PR
1019 IPV6Hdr ip6h;
1020 ThreadVars tv;
1021 DecodeThreadVars dtv;
1022
1023 memset(&tv, 0, sizeof(ThreadVars));
1db4aadd 1024 memset(p, 0, SIZE_OF_PACKET);
292a7e47
PR
1025 memset(&dtv, 0, sizeof(DecodeThreadVars));
1026 memset(&ip6h, 0, sizeof(IPV6Hdr));
1027
1028 FlowInitConfig(FLOW_QUIET);
f8aed4ce 1029 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
292a7e47 1030
3cf8b462 1031 FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_PKT_TOO_SMALL));
292a7e47 1032
c5bd04f1
EL
1033 PACKET_RECYCLE(p);
1034 FlowShutdown();
1db4aadd 1035 SCFree(p);
3cf8b462 1036 PASS;
292a7e47
PR
1037}
1038
1039/**\test icmpv6 message type: destination unreach, invalid packet
1040 * \brief The embedded packet header (ipv6) is truncated
1041 * \retval retval 0 = Error ; 1 = ok
1042 */
1043static int ICMPV6DestUnreachTest02(void)
1044{
292a7e47
PR
1045 static uint8_t raw_ipv6[] = {
1046 0x60, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x3a, 0xff,
1047 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1048 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1049 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1050 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1051 0x01, 0x00, 0x7b, 0x85, 0x00, 0x00, 0x00, 0x00,
1052 0x60, 0x4b, 0xe8, 0xbd, 0x00, 0x00, 0x3b, 0xff,
1053 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1054 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1055 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1056 0x00, 0x00, 0x00, 0x00, 0x00 };
1057
1db4aadd 1058 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 1059 FAIL_IF_NULL(p);
292a7e47
PR
1060 IPV6Hdr ip6h;
1061 ThreadVars tv;
1062 DecodeThreadVars dtv;
1063
1064 memset(&tv, 0, sizeof(ThreadVars));
1db4aadd 1065 memset(p, 0, SIZE_OF_PACKET);
292a7e47
PR
1066 memset(&dtv, 0, sizeof(DecodeThreadVars));
1067 memset(&ip6h, 0, sizeof(IPV6Hdr));
1068
1069 FlowInitConfig(FLOW_QUIET);
f8aed4ce 1070 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
292a7e47 1071
3cf8b462 1072 FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_IPV6_TRUNC_PKT));
292a7e47 1073
c5bd04f1
EL
1074 PACKET_RECYCLE(p);
1075 FlowShutdown();
1db4aadd 1076 SCFree(p);
3cf8b462 1077 PASS;
292a7e47
PR
1078}
1079
1080/**\test icmpv6 message type: echo request, invalid packet
1081 * \brief unknown code
1082 * \retval retval 0 = Error ; 1 = ok
1083 */
1084static int ICMPV6EchoReqTest02(void)
1085{
292a7e47
PR
1086 static uint8_t raw_ipv6[] = {
1087 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a,
1088 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1089 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1090 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00,
1091 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1092 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01,
1093 0xe5, 0xa5, 0x25, 0xf0, 0x75, 0x23 };
1094
1db4aadd 1095 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 1096 FAIL_IF_NULL(p);
292a7e47
PR
1097 IPV6Hdr ip6h;
1098 ThreadVars tv;
1099 DecodeThreadVars dtv;
1100
1101 memset(&tv, 0, sizeof(ThreadVars));
1db4aadd 1102 memset(p, 0, SIZE_OF_PACKET);
292a7e47
PR
1103 memset(&dtv, 0, sizeof(DecodeThreadVars));
1104 memset(&ip6h, 0, sizeof(IPV6Hdr));
1105
1106 FlowInitConfig(FLOW_QUIET);
f8aed4ce 1107 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
292a7e47 1108
3cf8b462 1109 FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE));
292a7e47 1110
c5bd04f1
EL
1111 PACKET_RECYCLE(p);
1112 FlowShutdown();
1db4aadd 1113 SCFree(p);
3cf8b462 1114 PASS;
292a7e47
PR
1115}
1116
1117/**\test icmpv6 message type: echo reply, invalid packet
1118 * \brief unknown code
1119 * \retval retval 0 = Error ; 1 = ok
1120 */
1121static int ICMPV6EchoRepTest02(void)
1122{
292a7e47
PR
1123 static uint8_t raw_ipv6[] = {
1124 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a,
1125 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1127 0x00, 0x00, 0x00, 0xff, 0x02, 0x00, 0x00,
1128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1129 0x00, 0x00, 0x00, 0x00, 0x01, 0x81, 0x01,
1130 0xe5, 0xa5, 0x25, 0xf0, 0x75, 0x23 };
1131
1db4aadd 1132 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 1133 FAIL_IF_NULL(p);
292a7e47
PR
1134 IPV6Hdr ip6h;
1135 ThreadVars tv;
1136 DecodeThreadVars dtv;
1137
1138 memset(&tv, 0, sizeof(ThreadVars));
1db4aadd 1139 memset(p, 0, SIZE_OF_PACKET);
292a7e47
PR
1140 memset(&dtv, 0, sizeof(DecodeThreadVars));
1141 memset(&ip6h, 0, sizeof(IPV6Hdr));
1142
1143 FlowInitConfig(FLOW_QUIET);
f8aed4ce 1144 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
292a7e47 1145
3cf8b462 1146 FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE));
292a7e47 1147
c5bd04f1
EL
1148 PACKET_RECYCLE(p);
1149 FlowShutdown();
1db4aadd 1150 SCFree(p);
3cf8b462 1151 PASS;
292a7e47
PR
1152}
1153
9a2bcb6a
GS
1154/**\test icmpv6 packet decoding and setting up of payload_len and payload buufer
1155 * \retval retval 0 = Error ; 1 = ok
1156 */
1157static int ICMPV6PayloadTest01(void)
1158{
9a2bcb6a
GS
1159 static uint8_t raw_ipv6[] = {
1160 0x60, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x3a, 0xff,
1161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1163 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1165 0x01, 0x00, 0x7b, 0x85, 0x00, 0x00, 0x00, 0x00,
1166 0x60, 0x4b, 0xe8, 0xbd, 0x00, 0x00, 0x3b, 0xff,
1167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1169 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1170 0x00, 0x00, 0x00, 0x00, 0x00 };
1171
1db4aadd 1172 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 1173 FAIL_IF_NULL(p);
9a2bcb6a
GS
1174 IPV6Hdr ip6h;
1175 ThreadVars tv;
1176 DecodeThreadVars dtv;
1177
1178 memset(&tv, 0, sizeof(ThreadVars));
1db4aadd 1179 memset(p, 0, SIZE_OF_PACKET);
9a2bcb6a
GS
1180 memset(&dtv, 0, sizeof(DecodeThreadVars));
1181 memset(&ip6h, 0, sizeof(IPV6Hdr));
1182
1183 FlowInitConfig(FLOW_QUIET);
f8aed4ce 1184 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
9a2bcb6a 1185
3cf8b462
JI
1186 FAIL_IF_NULL(p->payload);
1187 FAIL_IF(p->payload_len != 37);
8dceb278 1188
c5bd04f1
EL
1189 PACKET_RECYCLE(p);
1190 FlowShutdown();
1db4aadd 1191 SCFree(p);
3cf8b462 1192 PASS;
9a2bcb6a
GS
1193}
1194
7a9da787
JI
1195static int ICMPV6RouterSolicitTestKnownCode(void)
1196{
7a9da787
JI
1197 static uint8_t raw_ipv6[] = {
1198 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
1199 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1200 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
1201 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1203 0x85, 0x00, 0xbe, 0xb0, 0x00, 0x00, 0x00, 0x00
1204 };
1205
1206 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 1207 FAIL_IF_NULL(p);
7a9da787
JI
1208 IPV6Hdr ip6h;
1209 ThreadVars tv;
1210 DecodeThreadVars dtv;
1211
1212 memset(&tv, 0, sizeof(ThreadVars));
1213 memset(p, 0, SIZE_OF_PACKET);
1214 memset(&dtv, 0, sizeof(DecodeThreadVars));
1215 memset(&ip6h, 0, sizeof(IPV6Hdr));
1216
1217 FlowInitConfig(FLOW_QUIET);
f8aed4ce 1218 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
7a9da787 1219
3cf8b462 1220 FAIL_IF(ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE));
7a9da787 1221
7a9da787
JI
1222 PACKET_RECYCLE(p);
1223 FlowShutdown();
1224 SCFree(p);
3cf8b462 1225 PASS;
7a9da787
JI
1226}
1227
1228static int ICMPV6RouterSolicitTestUnknownCode(void)
1229{
7a9da787
JI
1230 static uint8_t raw_ipv6[] = {
1231 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
1232 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1233 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
1234 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1236 0x85, 0x01, 0xbe, 0xaf, 0x00, 0x00, 0x00, 0x00
1237 };
1238
1239 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 1240 FAIL_IF_NULL(p);
7a9da787
JI
1241 IPV6Hdr ip6h;
1242 ThreadVars tv;
1243 DecodeThreadVars dtv;
1244
1245 memset(&tv, 0, sizeof(ThreadVars));
1246 memset(p, 0, SIZE_OF_PACKET);
1247 memset(&dtv, 0, sizeof(DecodeThreadVars));
1248 memset(&ip6h, 0, sizeof(IPV6Hdr));
1249
1250 FlowInitConfig(FLOW_QUIET);
f8aed4ce 1251 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
7a9da787 1252
3cf8b462 1253 FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE));
7a9da787 1254
7a9da787
JI
1255 PACKET_RECYCLE(p);
1256 FlowShutdown();
1257 SCFree(p);
3cf8b462 1258 PASS;
7a9da787
JI
1259}
1260
1261static int ICMPV6RouterAdvertTestKnownCode(void)
1262{
7a9da787
JI
1263 static uint8_t raw_ipv6[] = {
1264 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
1265 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1266 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
1267 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1268 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1269 0x86, 0x00, 0xbd, 0xb0, 0x00, 0x00, 0x00, 0x00
1270 };
1271
1272 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 1273 FAIL_IF_NULL(p);
7a9da787
JI
1274 IPV6Hdr ip6h;
1275 ThreadVars tv;
1276 DecodeThreadVars dtv;
1277
1278 memset(&tv, 0, sizeof(ThreadVars));
1279 memset(p, 0, SIZE_OF_PACKET);
1280 memset(&dtv, 0, sizeof(DecodeThreadVars));
1281 memset(&ip6h, 0, sizeof(IPV6Hdr));
1282
1283 FlowInitConfig(FLOW_QUIET);
f8aed4ce 1284 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
7a9da787 1285
3cf8b462 1286 FAIL_IF(ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE));
7a9da787 1287
7a9da787
JI
1288 PACKET_RECYCLE(p);
1289 FlowShutdown();
1290 SCFree(p);
3cf8b462 1291 PASS;
7a9da787
JI
1292}
1293
1294static int ICMPV6RouterAdvertTestUnknownCode(void)
1295{
7a9da787
JI
1296 static uint8_t raw_ipv6[] = {
1297 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
1298 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1299 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
1300 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1302 0x86, 0x01, 0xbd, 0xaf, 0x00, 0x00, 0x00, 0x00
1303 };
1304
1305 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 1306 FAIL_IF_NULL(p);
7a9da787
JI
1307 IPV6Hdr ip6h;
1308 ThreadVars tv;
1309 DecodeThreadVars dtv;
1310
1311 memset(&tv, 0, sizeof(ThreadVars));
1312 memset(p, 0, SIZE_OF_PACKET);
1313 memset(&dtv, 0, sizeof(DecodeThreadVars));
1314 memset(&ip6h, 0, sizeof(IPV6Hdr));
1315
1316 FlowInitConfig(FLOW_QUIET);
f8aed4ce 1317 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
7a9da787 1318
3cf8b462 1319 FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE));
7a9da787 1320
7a9da787
JI
1321 PACKET_RECYCLE(p);
1322 FlowShutdown();
1323 SCFree(p);
3cf8b462 1324 PASS;
7a9da787
JI
1325}
1326
1327static int ICMPV6NeighbourSolicitTestKnownCode(void)
1328{
7a9da787
JI
1329 static uint8_t raw_ipv6[] = {
1330 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
1331 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1332 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
1333 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1335 0x87, 0x00, 0xbc, 0xb0, 0x00, 0x00, 0x00, 0x00
1336 };
1337
1338 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 1339 FAIL_IF_NULL(p);
7a9da787
JI
1340 IPV6Hdr ip6h;
1341 ThreadVars tv;
1342 DecodeThreadVars dtv;
1343
1344 memset(&tv, 0, sizeof(ThreadVars));
1345 memset(p, 0, SIZE_OF_PACKET);
1346 memset(&dtv, 0, sizeof(DecodeThreadVars));
1347 memset(&ip6h, 0, sizeof(IPV6Hdr));
1348
1349 FlowInitConfig(FLOW_QUIET);
f8aed4ce 1350 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
7a9da787 1351
3cf8b462 1352 FAIL_IF(ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE));
7a9da787 1353
7a9da787
JI
1354 PACKET_RECYCLE(p);
1355 FlowShutdown();
1356 SCFree(p);
3cf8b462 1357 PASS;
7a9da787
JI
1358}
1359
1360static int ICMPV6NeighbourSolicitTestUnknownCode(void)
1361{
7a9da787
JI
1362 static uint8_t raw_ipv6[] = {
1363 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
1364 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1365 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
1366 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1368 0x87, 0x01, 0xbc, 0xaf, 0x00, 0x00, 0x00, 0x00
1369 };
1370
1371 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 1372 FAIL_IF_NULL(p);
7a9da787
JI
1373 IPV6Hdr ip6h;
1374 ThreadVars tv;
1375 DecodeThreadVars dtv;
1376
1377 memset(&tv, 0, sizeof(ThreadVars));
1378 memset(p, 0, SIZE_OF_PACKET);
1379 memset(&dtv, 0, sizeof(DecodeThreadVars));
1380 memset(&ip6h, 0, sizeof(IPV6Hdr));
1381
1382 FlowInitConfig(FLOW_QUIET);
f8aed4ce 1383 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
7a9da787 1384
3cf8b462 1385 FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE));
7a9da787 1386
7a9da787
JI
1387 PACKET_RECYCLE(p);
1388 FlowShutdown();
1389 SCFree(p);
3cf8b462 1390 PASS;
7a9da787
JI
1391}
1392
1393static int ICMPV6NeighbourAdvertTestKnownCode(void)
1394{
7a9da787
JI
1395 static uint8_t raw_ipv6[] = {
1396 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
1397 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1398 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
1399 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1401 0x88, 0x00, 0xbb, 0xb0, 0x00, 0x00, 0x00, 0x00
1402 };
1403
1404 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 1405 FAIL_IF_NULL(p);
7a9da787
JI
1406 IPV6Hdr ip6h;
1407 ThreadVars tv;
1408 DecodeThreadVars dtv;
1409
1410 memset(&tv, 0, sizeof(ThreadVars));
1411 memset(p, 0, SIZE_OF_PACKET);
1412 memset(&dtv, 0, sizeof(DecodeThreadVars));
1413 memset(&ip6h, 0, sizeof(IPV6Hdr));
1414
1415 FlowInitConfig(FLOW_QUIET);
f8aed4ce 1416 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
7a9da787 1417
3cf8b462 1418 FAIL_IF(ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE));
7a9da787 1419
7a9da787
JI
1420 PACKET_RECYCLE(p);
1421 FlowShutdown();
1422 SCFree(p);
3cf8b462 1423 PASS;
7a9da787
JI
1424}
1425
1426static int ICMPV6NeighbourAdvertTestUnknownCode(void)
1427{
7a9da787
JI
1428 static uint8_t raw_ipv6[] = {
1429 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
1430 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1431 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
1432 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1434 0x88, 0x01, 0xbb, 0xaf, 0x00, 0x00, 0x00, 0x00
1435 };
1436
1437 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 1438 FAIL_IF_NULL(p);
7a9da787
JI
1439 IPV6Hdr ip6h;
1440 ThreadVars tv;
1441 DecodeThreadVars dtv;
1442
1443 memset(&tv, 0, sizeof(ThreadVars));
1444 memset(p, 0, SIZE_OF_PACKET);
1445 memset(&dtv, 0, sizeof(DecodeThreadVars));
1446 memset(&ip6h, 0, sizeof(IPV6Hdr));
1447
1448 FlowInitConfig(FLOW_QUIET);
f8aed4ce 1449 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
7a9da787 1450
3cf8b462 1451 FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE));
7a9da787 1452
7a9da787
JI
1453 PACKET_RECYCLE(p);
1454 FlowShutdown();
1455 SCFree(p);
3cf8b462 1456 PASS;
7a9da787
JI
1457}
1458
1459static int ICMPV6RedirectTestKnownCode(void)
1460{
7a9da787
JI
1461 static uint8_t raw_ipv6[] = {
1462 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
1463 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1464 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
1465 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1466 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1467 0x89, 0x00, 0xba, 0xb0, 0x00, 0x00, 0x00, 0x00
1468 };
1469
1470 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 1471 FAIL_IF_NULL(p);
7a9da787
JI
1472 IPV6Hdr ip6h;
1473 ThreadVars tv;
1474 DecodeThreadVars dtv;
1475
1476 memset(&tv, 0, sizeof(ThreadVars));
1477 memset(p, 0, SIZE_OF_PACKET);
1478 memset(&dtv, 0, sizeof(DecodeThreadVars));
1479 memset(&ip6h, 0, sizeof(IPV6Hdr));
1480
1481 FlowInitConfig(FLOW_QUIET);
f8aed4ce 1482 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
7a9da787 1483
3cf8b462 1484 FAIL_IF(ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE));
7a9da787 1485
7a9da787
JI
1486 PACKET_RECYCLE(p);
1487 FlowShutdown();
1488 SCFree(p);
3cf8b462 1489 PASS;
7a9da787
JI
1490}
1491
1492static int ICMPV6RedirectTestUnknownCode(void)
1493{
7a9da787
JI
1494 static uint8_t raw_ipv6[] = {
1495 0x60, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3a, 0xff,
1496 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1497 0x02, 0x24, 0x8c, 0xff, 0xfe, 0x0e, 0x31, 0x54,
1498 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1499 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
1500 0x89, 0x01, 0xba, 0xaf, 0x00, 0x00, 0x00, 0x00
1501 };
1502
1503 Packet *p = SCMalloc(SIZE_OF_PACKET);
3cf8b462 1504 FAIL_IF_NULL(p);
7a9da787
JI
1505 IPV6Hdr ip6h;
1506 ThreadVars tv;
1507 DecodeThreadVars dtv;
1508
1509 memset(&tv, 0, sizeof(ThreadVars));
1510 memset(p, 0, SIZE_OF_PACKET);
1511 memset(&dtv, 0, sizeof(DecodeThreadVars));
1512 memset(&ip6h, 0, sizeof(IPV6Hdr));
1513
1514 FlowInitConfig(FLOW_QUIET);
f8aed4ce 1515 DecodeIPV6(&tv, &dtv, p, raw_ipv6, sizeof(raw_ipv6));
7a9da787 1516
3cf8b462 1517 FAIL_IF(!ENGINE_ISSET_EVENT(p, ICMPV6_UNKNOWN_CODE));
7a9da787 1518
7a9da787
JI
1519 PACKET_RECYCLE(p);
1520 FlowShutdown();
1521 SCFree(p);
3cf8b462 1522 PASS;
7a9da787
JI
1523}
1524
af4085b7
JI
1525/**
1526 * \test Test for valid ICMPv6 checksum when the FCS is still attached.
1527 *
1528 * Tests that the packet is decoded with sufficient info to verify the
1529 * checksum even if the packet has some trailing data like an ethernet
1530 * FCS.
1531 */
1532static int ICMPV6CalculateValidChecksumWithFCS(void)
1533{
1534 /* IPV6/ICMPv6 packet with ethernet header.
1535 * - IPv6 payload length: 36
1536 */
1537 uint8_t raw_ipv6[] = {
1538 0x33, 0x33, 0x00, 0x00, 0x00, 0x16, 0x00, 0x50,
1539 0x56, 0xa6, 0x6a, 0x7d, 0x86, 0xdd, 0x60, 0x00,
1540 0x00, 0x00, 0x00, 0x24, 0x00, 0x01, 0xfe, 0x80,
1541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x09,
1542 0xad, 0x44, 0x49, 0x38, 0x5f, 0xa9, 0xff, 0x02,
1543 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1544 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x3a, 0x00,
1545 0x05, 0x02, 0x00, 0x00, 0x01, 0x00, 0x8f, 0x00,
1546 0x24, 0xe0, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, /* Checksum: 0x24e0. */
1547 0x00, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00,
1548 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1549 0x00, 0xfb, 0x1f, 0x34, 0xf6, 0xa4
1550 };
1551 uint16_t csum = *(((uint16_t *)(raw_ipv6 + 64)));
1552
1553 Packet *p = SCMalloc(SIZE_OF_PACKET);
1554 FAIL_IF_NULL(p);
1555 IPV6Hdr ip6h;
1556 ThreadVars tv;
1557 DecodeThreadVars dtv;
1558
1559 memset(&tv, 0, sizeof(ThreadVars));
1560 memset(p, 0, SIZE_OF_PACKET);
1561 memset(&dtv, 0, sizeof(DecodeThreadVars));
1562 memset(&ip6h, 0, sizeof(IPV6Hdr));
1563
1564 FlowInitConfig(FLOW_QUIET);
f8aed4ce 1565 DecodeIPV6(&tv, &dtv, p, raw_ipv6 + 14, sizeof(raw_ipv6) - 14);
af4085b7
JI
1566 FAIL_IF_NULL(p->icmpv6h);
1567
1568 uint16_t icmpv6_len = IPV6_GET_RAW_PLEN(p->ip6h) -
1569 ((uint8_t *)p->icmpv6h - (uint8_t *)p->ip6h - IPV6_HEADER_LEN);
1570 FAIL_IF(icmpv6_len != 28);
1571 FAIL_IF(ICMPV6CalculateChecksum(p->ip6h->s_ip6_addrs,
1572 (uint16_t *)p->icmpv6h, icmpv6_len) != csum);
1573
1574 PACKET_RECYCLE(p);
1575 FlowShutdown();
1576 SCFree(p);
1577 PASS;
1578}
1579
292a7e47 1580#endif /* UNITTESTS */
401a0313
AS
1581/**
1582 * \brief Registers ICMPV6 unit tests
1583 * \todo More ICMPv6 tests
1584 */
1585void DecodeICMPV6RegisterTests(void)
1586{
c43319c3 1587#ifdef UNITTESTS
796dd522
JI
1588 UtRegisterTest("ICMPV6CalculateValidChecksumtest01",
1589 ICMPV6CalculateValidChecksumtest01);
1590 UtRegisterTest("ICMPV6CalculateInValidChecksumtest02",
1591 ICMPV6CalculateInvalidChecksumtest02);
1592
1593 UtRegisterTest("ICMPV6ParamProbTest01 (Valid)", ICMPV6ParamProbTest01);
1594 UtRegisterTest("ICMPV6DestUnreachTest01 (Valid)", ICMPV6DestUnreachTest01);
1595 UtRegisterTest("ICMPV6PktTooBigTest01 (Valid)", ICMPV6PktTooBigTest01);
1596 UtRegisterTest("ICMPV6TimeExceedTest01 (Valid)", ICMPV6TimeExceedTest01);
1597 UtRegisterTest("ICMPV6EchoReqTest01 (Valid)", ICMPV6EchoReqTest01);
1598 UtRegisterTest("ICMPV6EchoRepTest01 (Valid)", ICMPV6EchoRepTest01);
1599
1600 UtRegisterTest("ICMPV6ParamProbTest02 (Invalid)", ICMPV6ParamProbTest02);
1601 UtRegisterTest("ICMPV6DestUnreachTest02 (Invalid)",
1602 ICMPV6DestUnreachTest02);
1603 UtRegisterTest("ICMPV6PktTooBigTest02 (Invalid)", ICMPV6PktTooBigTest02);
1604 UtRegisterTest("ICMPV6TimeExceedTest02 (Invalid)", ICMPV6TimeExceedTest02);
1605 UtRegisterTest("ICMPV6EchoReqTest02 (Invalid)", ICMPV6EchoReqTest02);
1606 UtRegisterTest("ICMPV6EchoRepTest02 (Invalid)", ICMPV6EchoRepTest02);
1607
1608 UtRegisterTest("ICMPV6PayloadTest01", ICMPV6PayloadTest01);
7a9da787
JI
1609
1610 UtRegisterTest("ICMPV6RouterSolicitTestKnownCode",
796dd522 1611 ICMPV6RouterSolicitTestKnownCode);
7a9da787 1612 UtRegisterTest("ICMPV6RouterSolicitTestUnknownCode",
796dd522 1613 ICMPV6RouterSolicitTestUnknownCode);
7a9da787 1614 UtRegisterTest("ICMPV6RouterAdvertTestKnownCode",
796dd522 1615 ICMPV6RouterAdvertTestKnownCode);
7a9da787 1616 UtRegisterTest("ICMPV6RouterAdvertTestUnknownCode",
796dd522 1617 ICMPV6RouterAdvertTestUnknownCode);
7a9da787
JI
1618
1619 UtRegisterTest("ICMPV6NeighbourSolicitTestKnownCode",
796dd522 1620 ICMPV6NeighbourSolicitTestKnownCode);
7a9da787 1621 UtRegisterTest("ICMPV6NeighbourSolicitTestUnknownCode",
796dd522 1622 ICMPV6NeighbourSolicitTestUnknownCode);
7a9da787 1623 UtRegisterTest("ICMPV6NeighbourAdvertTestKnownCode",
796dd522 1624 ICMPV6NeighbourAdvertTestKnownCode);
7a9da787 1625 UtRegisterTest("ICMPV6NeighbourAdvertTestUnknownCode",
796dd522 1626 ICMPV6NeighbourAdvertTestUnknownCode);
7a9da787 1627
796dd522 1628 UtRegisterTest("ICMPV6RedirectTestKnownCode", ICMPV6RedirectTestKnownCode);
7a9da787 1629 UtRegisterTest("ICMPV6RedirectTestUnknownCode",
796dd522 1630 ICMPV6RedirectTestUnknownCode);
af4085b7
JI
1631 UtRegisterTest("ICMPV6CalculateValidChecksumWithFCS",
1632 ICMPV6CalculateValidChecksumWithFCS);
c43319c3 1633#endif /* UNITTESTS */
401a0313 1634}
acf10525
EL
1635/**
1636 * @}
1637 */