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