proto_icmpv6.c: make safer
[netsniff-ng.git] / src / proto_icmpv6.c
blobf1c638fdc03f954b47b3cfac22880372d208d5e5
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2012 Markus Amend <markus@netsniff-ng.org>
4 * Subject to the GPL, version 2.
6 * ICMPv6 described in RFC4443, RFC2710, RFC4861, RFC2894,
7 * RFC4620, RFC3122, RFC3810, RFC3775, RFC3971, RFC4065
8 * RFC4286
9 * Look also for an good overview:
10 * http://www.iana.org/assignments/icmpv6-parameters
13 #include <stdio.h>
14 #include <stdint.h>
15 #include <netinet/in.h>
16 #include <arpa/inet.h>
17 #include <asm/byteorder.h>
19 #include "proto.h"
20 #include "protos.h"
21 #include "dissector_eth.h"
22 #include "pkt_buff.h"
23 #include "built_in.h"
25 #define icmpv6_code_range_valid(code, sarr) ((code) < array_size((sarr)))
27 struct icmpv6_general_hdr {
28 uint8_t h_type;
29 uint8_t h_code;
30 uint16_t h_chksum;
31 } __packed;
33 /* for type 0x01 and 0x03 */
34 struct icmpv6_type_1_3 {
35 uint32_t unused;
36 uint8_t invoking_pkt[0];
37 } __packed;
39 struct icmpv6_type_2 {
40 uint32_t MTU;
41 uint8_t invoking_pkt[0];
42 } __packed;
44 struct icmpv6_type_4 {
45 uint32_t pointer;
46 uint8_t invoking_pkt[0];
47 } __packed;
49 struct icmpv6_type_128_129 {
50 uint16_t id;
51 uint16_t sn;
52 uint8_t data[0];
53 } __packed;
55 /* MLDv1 msg */
56 struct icmpv6_type_130_131_132 {
57 uint16_t maxrespdel;
58 uint16_t res;
59 struct in6_addr ipv6_addr;
60 } __packed;
61 /* end MLDv1 msg */
63 struct icmpv6_type_130_mldv2 {
64 uint8_t resv_S_QRV;
65 uint8_t QQIC;
66 uint16_t nr_src;
67 struct in6_addr ipv6_addr[0];
68 } __packed;
70 /* Neighbor Discovery msg */
71 struct icmpv6_type_133_141_142 {
72 uint32_t res;
73 uint8_t ops[0];
74 } __packed;
76 struct icmpv6_type_134 {
77 uint8_t cur_hop_limit;
78 uint8_t m_o_res;
79 uint16_t router_lifetime;
80 uint32_t reachable_time;
81 uint32_t retrans_timer;
82 uint8_t ops[0];
83 } __packed;
85 struct icmpv6_type_135 {
86 uint32_t res;
87 struct in6_addr ipv6_addr;
88 uint8_t ops[0];
89 } __packed;
91 struct icmpv6_type_136 {
92 uint32_t r_s_o_res;
93 struct in6_addr ipv6_addr;
94 uint8_t ops[0];
95 } __packed;
97 struct icmpv6_type_137 {
98 uint32_t res;
99 struct in6_addr ipv6_targ_addr;
100 struct in6_addr ipv6_dest_addr;
101 uint8_t ops[0];
102 } __packed;
104 struct icmpv6_neighb_disc_ops_general {
105 uint8_t type;
106 uint8_t len;
107 uint8_t ops[0];
108 } __packed;
110 struct icmpv6_neighb_disc_ops_type_1_2 {
111 uint8_t link_lay_addr[0];
112 } __packed;
114 struct icmpv6_neighb_disc_ops_type_3 {
115 uint8_t prefix_len;
116 uint8_t l_a_res1;
117 uint32_t valid_lifetime;
118 uint32_t preferred_lifetime;
119 uint32_t res2;
120 struct in6_addr prefix;
121 } __packed;
123 struct icmpv6_neighb_disc_ops_type_4 {
124 uint16_t res1;
125 uint32_t res2;
126 uint8_t ip_hdr_data[0];
127 } __packed;
129 struct icmpv6_neighb_disc_ops_type_5 {
130 uint16_t res1;
131 uint32_t MTU;
132 } __packed;
134 struct icmpv6_neighb_disc_ops_type_9_10 {
135 uint16_t res1;
136 uint32_t res2;
137 uint8_t ip_hdr_data[0];
138 } __packed;
140 struct icmpv6_neighb_disc_ops_type_15 {
141 uint8_t name_type;
142 size_t pad_len;
143 char name[0];
144 uint8_t pad[0];
145 } __packed;
147 struct icmpv6_neighb_disc_ops_type_16 {
148 uint8_t cert_type;
149 uint8_t res;
150 uint8_t cert[0];
151 uint8_t pad[0];
152 } __packed;
154 struct icmpv6_neighb_disc_ops_type_17 {
155 uint8_t opt_code;
156 uint8_t prefix_len;
157 uint8_t data[0];
158 } __packed;
160 struct icmpv6_neighb_disc_ops_type_17_1 {
161 uint32_t res;
162 struct in6_addr ipv6_addr;
163 } __packed;
165 struct icmpv6_neighb_disc_ops_type_17_2 {
166 struct in6_addr ipv6_addr;
167 } __packed;
169 struct icmpv6_neighb_disc_ops_type_19 {
170 uint8_t opt_code;
171 uint8_t lla[0];
172 } __packed;
173 /* end Neighbor Discovery msg */
175 struct icmpv6_type_138 {
176 uint32_t seq_nr;
177 uint8_t seg_nr;
178 uint8_t flags;
179 uint16_t maxdelay;
180 uint32_t res;
181 } __packed;
183 /* Node Information Queries */
184 struct icmpv6_type_139_140 {
185 uint16_t qtype;
186 uint16_t flags;
187 uint64_t nonce;
188 uint8_t data[0];
189 } __packed;
190 /* end Node Information Queries */
192 /* MLDv2 report */
193 struct icmpv6_type_143 {
194 uint16_t res;
195 uint16_t nr_rec;
196 uint8_t addr_rec[0];
197 } __packed;
199 struct icmpv6_mldv2_addr_rec {
200 uint8_t rec_type;
201 uint8_t aux_data_len;
202 uint16_t nr_src;
203 struct in6_addr multic_addr;
204 struct in6_addr src_addr[0];
205 } __packed;
206 /* end MLDv2 report */
208 /* ICMP Mobility Support */
209 struct icmpv6_type_144_146 {
210 uint16_t id;
211 uint16_t res;
212 } __packed;
214 struct icmpv6_type_145 {
215 uint16_t id;
216 uint16_t res;
217 struct in6_addr home_agent_addr[0];
218 } __packed;
220 struct icmpv6_type_147 {
221 uint16_t id;
222 uint16_t m_o_res;
223 uint8_t ops[0];
224 } __packed;
225 /* end ICMP Mobility Support */
227 /* SEcure Neighbor Discovery */
228 struct icmpv6_type_148 {
229 uint16_t id;
230 uint16_t comp;
231 uint8_t ops[0];
232 } __packed;
234 struct icmpv6_type_149 {
235 uint16_t id;
236 uint16_t all_comp;
237 uint16_t comp;
238 uint16_t res;
239 uint8_t ops[0];
240 } __packed;
241 /* end SEcure Neighbor Discovery */
243 struct icmpv6_type_150 {
244 union {
245 uint32_t subtype_res;
246 struct {
247 #if defined(__LITTLE_ENDIAN_BITFIELD)
248 uint32_t res :24,
249 subtype :8;
250 #elif defined(__BIG_ENDIAN_BITFIELD)
251 uint32_t subtype :8,
252 res :24;
253 #else
254 # error "Please fix <asm/byteorder.h>"
255 #endif
258 uint8_t ops[0];
259 } __packed;
261 /* Multicast Router Discovery */
262 struct icmpv6_type_151 {
263 uint16_t query_intv;
264 uint16_t rob_var;
265 } __packed;
267 struct icmpv6_type_152 {
268 uint8_t null[0];
269 } __packed;
271 struct icmpv6_type_153 {
272 uint8_t null[0];
273 } __packed;
274 /* end Multicast Router Discovery */
276 struct icmpv6_type_154 {
277 uint8_t subtype;
278 uint8_t res;
279 uint16_t id;
280 uint8_t ops[0];
281 } __packed;
283 static int8_t print_ipv6_addr_list(struct pkt_buff *pkt, uint8_t nr_addr)
285 char address[INET6_ADDRSTRLEN];
286 struct in6_addr *addr;
288 while (nr_addr--) {
289 addr = (struct in6_addr *) pkt_pull(pkt, sizeof(*addr));
290 if (addr == NULL)
291 return 0;
293 tprintf("\n\t Address: %s",
294 inet_ntop(AF_INET6, addr, address,
295 sizeof(address)));
298 return 1;
301 static char *icmpv6_mcast_rec_types[] = {
302 "MODE_IS_INCLUDE",
303 "MODE_IS_EXCLUDE",
304 "CHANGE_TO_INCLUDE_MODE",
305 "CHANGE_TO_EXCLUDE_MODE",
306 "ALLOW_NEW_SOURCES",
307 "BLOCK_OLD_SOURCES",
310 static int8_t dissect_icmpv6_mcast_rec(struct pkt_buff *pkt,
311 uint16_t nr_rec)
313 uint16_t nr_src, aux_data_len_bytes;
314 struct icmpv6_mldv2_addr_rec *addr_rec;
316 while (nr_rec--) {
317 addr_rec = (struct icmpv6_mldv2_addr_rec *)
318 pkt_pull(pkt,sizeof(*addr_rec));
319 if (addr_rec == NULL)
320 return 0;
321 aux_data_len_bytes = addr_rec->aux_data_len * 4;
322 nr_src = ntohs(addr_rec->nr_src);
324 tprintf(", Rec Type %s (%u)",
325 icmpv6_code_range_valid(addr_rec->rec_type - 1,
326 icmpv6_mcast_rec_types) ?
327 icmpv6_mcast_rec_types[addr_rec->rec_type - 1]
328 : "Unknown", addr_rec->rec_type);
329 if (aux_data_len_bytes > pkt_len(pkt)) {
330 tprintf(", Aux Data Len (%u, %u bytes) %s",
331 addr_rec->aux_data_len,
332 aux_data_len_bytes,
333 colorize_start_full(black, red) "invalid"
334 colorize_end());
335 return 0;
337 tprintf(", Aux Data Len (%u, %u bytes)",addr_rec->aux_data_len,
338 aux_data_len_bytes);
339 tprintf(", Nr. of Sources (%u)",nr_src);
341 if(!print_ipv6_addr_list(pkt, nr_src))
342 return 0;
344 if (aux_data_len_bytes > pkt_len(pkt)) {
345 tprintf("\nAux Data Len %s",
346 colorize_start_full(black, red) "invalid"
347 colorize_end());
348 return 0;
351 tprintf(", Aux Data: ");
352 while (aux_data_len_bytes--) {
353 tprintf("%x", *pkt_pull(pkt,1));
357 return 1;
360 static int8_t dissect_neighb_disc_ops_1(struct pkt_buff *pkt,
361 ssize_t len)
363 struct icmpv6_neighb_disc_ops_type_1_2 *icmp_neighb_disc_1;
365 icmp_neighb_disc_1 = (struct icmpv6_neighb_disc_ops_type_1_2 *)
366 pkt_pull(pkt,sizeof(*icmp_neighb_disc_1));
367 if (icmp_neighb_disc_1 == NULL)
368 return 0;
369 len -= sizeof(*icmp_neighb_disc_1);
370 if (len < 0)
371 return 0;
373 tprintf("Address 0x");
375 while(len--){
376 tprintf("%x", *pkt_pull(pkt,1));
379 return 1;
382 static int8_t dissect_neighb_disc_ops_2(struct pkt_buff *pkt,
383 ssize_t len)
385 return dissect_neighb_disc_ops_1(pkt, len);
388 static int8_t dissect_neighb_disc_ops_3(struct pkt_buff *pkt,
389 ssize_t len)
391 char address[INET6_ADDRSTRLEN];
392 struct icmpv6_neighb_disc_ops_type_3 *icmp_neighb_disc_3;
394 icmp_neighb_disc_3 = (struct icmpv6_neighb_disc_ops_type_3 *)
395 pkt_pull(pkt,sizeof(*icmp_neighb_disc_3));
396 if (icmp_neighb_disc_3 == NULL)
397 return 0;
398 len -= sizeof(*icmp_neighb_disc_3);
399 if (len < 0)
400 return 0;
402 tprintf("Prefix Len (%u) ",icmp_neighb_disc_3->prefix_len);
403 tprintf("L (%u) A (%u) Res1 (0x%x) ",icmp_neighb_disc_3->l_a_res1 >> 7,
404 (icmp_neighb_disc_3->l_a_res1 >> 7) & 0x1,
405 icmp_neighb_disc_3->l_a_res1 & 0x3F);
406 tprintf("Valid Lifetime (%us) ",
407 ntohl(icmp_neighb_disc_3->valid_lifetime));
408 tprintf("Preferred Lifetime (%us) ",
409 ntohl(icmp_neighb_disc_3->preferred_lifetime));
410 tprintf("Reserved2 (0x%x) ",
411 ntohl(icmp_neighb_disc_3->res2));
412 tprintf("Prefix: %s ",
413 inet_ntop(AF_INET6,&icmp_neighb_disc_3->prefix,
414 address, sizeof(address)));
416 return 1;
419 static int8_t dissect_neighb_disc_ops_4(struct pkt_buff *pkt,
420 ssize_t len)
422 struct icmpv6_neighb_disc_ops_type_4 *icmp_neighb_disc_4;
424 icmp_neighb_disc_4 = (struct icmpv6_neighb_disc_ops_type_4 *)
425 pkt_pull(pkt,sizeof(*icmp_neighb_disc_4));
426 if (icmp_neighb_disc_4 == NULL)
427 return 0;
428 len -= sizeof(*icmp_neighb_disc_4);
429 if (len < 0)
430 return 0;
432 tprintf("Reserved 1 (0x%x) ", ntohs(icmp_neighb_disc_4->res1));
433 tprintf("Reserved 2 (0x%x) ", ntohl(icmp_neighb_disc_4->res2));
434 tprintf("IP header + data ");
436 while (len--) {
437 tprintf("%x", *pkt_pull(pkt,1));
440 return 1;
443 static int8_t dissect_neighb_disc_ops_5(struct pkt_buff *pkt,
444 ssize_t len)
446 struct icmpv6_neighb_disc_ops_type_5 *icmp_neighb_disc_5;
448 icmp_neighb_disc_5 = (struct icmpv6_neighb_disc_ops_type_5 *)
449 pkt_pull(pkt,sizeof(*icmp_neighb_disc_5));
450 if (icmp_neighb_disc_5 == NULL)
451 return 0;
452 len -= sizeof(*icmp_neighb_disc_5);
453 if (len < 0)
454 return 0;
456 tprintf("Reserved (0x%x) ", ntohs(icmp_neighb_disc_5->res1));
457 tprintf("MTU (%u)", ntohl(icmp_neighb_disc_5->MTU));
459 return 1;
462 static int8_t dissect_neighb_disc_ops_9(struct pkt_buff *pkt,
463 ssize_t len)
465 struct icmpv6_neighb_disc_ops_type_9_10 *icmp_neighb_disc_9;
467 icmp_neighb_disc_9 = (struct icmpv6_neighb_disc_ops_type_9_10 *)
468 pkt_pull(pkt,sizeof(*icmp_neighb_disc_9));
469 if (icmp_neighb_disc_9 == NULL)
470 return 0;
471 len -= sizeof(*icmp_neighb_disc_9);
472 if (len < 0)
473 return 0;
475 tprintf("Reserved 1 (0x%x) ", ntohs(icmp_neighb_disc_9->res1));
476 tprintf("Reserved 2 (0x%x) ", ntohl(icmp_neighb_disc_9->res2));
478 return print_ipv6_addr_list(pkt, len / sizeof(struct in6_addr));
481 static int8_t dissect_neighb_disc_ops_10(struct pkt_buff *pkt,
482 ssize_t len)
484 return dissect_neighb_disc_ops_9(pkt, len);
487 static char *icmpv6_neighb_disc_ops_15_name[] = {
488 "DER Encoded X.501 Name",
489 "FQDN",
492 static int8_t dissect_neighb_disc_ops_15(struct pkt_buff *pkt,
493 ssize_t len)
495 size_t pad_len;
496 ssize_t name_len;
497 struct icmpv6_neighb_disc_ops_type_15 *icmp_neighb_disc_15;
499 icmp_neighb_disc_15 = (struct icmpv6_neighb_disc_ops_type_15 *)
500 pkt_pull(pkt,sizeof(*icmp_neighb_disc_15));
501 if (icmp_neighb_disc_15 == NULL)
502 return 0;
503 len -= sizeof(*icmp_neighb_disc_15);
504 if (len < 0)
505 return 0;
506 pad_len = icmp_neighb_disc_15->pad_len;
508 tprintf("Name Type %s (%u) ",
509 icmpv6_code_range_valid(icmp_neighb_disc_15->name_type - 1,
510 icmpv6_neighb_disc_ops_15_name) ?
511 icmpv6_neighb_disc_ops_15_name[
512 icmp_neighb_disc_15->name_type - 1] : "Unknown",
513 icmp_neighb_disc_15->name_type);
514 if (pad_len > len) {
515 tprintf("Pad Len (%u, invalid)\n%s", pad_len,
516 colorize_start_full(black, red)
517 "Skip Option" colorize_end());
518 pkt_pull(pkt, len);
519 return 1;
521 else
522 tprintf("Pad Len (%u) ", pad_len);
524 name_len = len - pad_len;
526 tprintf("Name (");
527 while (name_len--) {
528 tprintf("%c", *pkt_pull(pkt,1));
530 tprintf(") ");
532 tprintf("Padding (");
534 while (pad_len--) {
535 tprintf("%x", *pkt_pull(pkt,1));
537 tprintf(")");
539 return 1;
542 static char *icmpv6_neighb_disc_ops_16_cert[] = {
543 "X.509v3 Certificate",
546 static int8_t dissect_neighb_disc_ops_16(struct pkt_buff *pkt,
547 ssize_t len)
549 struct icmpv6_neighb_disc_ops_type_16 *icmp_neighb_disc_16;
551 icmp_neighb_disc_16 = (struct icmpv6_neighb_disc_ops_type_16 *)
552 pkt_pull(pkt,sizeof(*icmp_neighb_disc_16));
553 if (icmp_neighb_disc_16 == NULL)
554 return 0;
555 len -= sizeof(*icmp_neighb_disc_16);
556 if (len < 0)
557 return 0;
559 tprintf("Cert Type %s (%u) ",
560 icmpv6_code_range_valid(icmp_neighb_disc_16->cert_type - 1,
561 icmpv6_neighb_disc_ops_16_cert) ?
562 icmpv6_neighb_disc_ops_16_cert[
563 icmp_neighb_disc_16->cert_type - 1] : "Unknown",
564 icmp_neighb_disc_16->cert_type);
565 tprintf("Res (0x%x) ", icmp_neighb_disc_16->res);
567 tprintf("Certificate + Padding (");
568 while (len--) {
569 tprintf("%x", *pkt_pull(pkt,1));
571 tprintf(") ");
573 return 1;
576 static char *icmpv6_neighb_disc_ops_17_codes[] = {
577 "Old Care-of Address",
578 "New Care-of Address",
579 "NAR's IP address",
580 "NAR's Prefix",
583 static int8_t dissect_neighb_disc_ops_17(struct pkt_buff *pkt,
584 ssize_t len)
586 char address[INET6_ADDRSTRLEN];
587 struct icmpv6_neighb_disc_ops_type_17 *icmp_neighb_disc_17;
589 icmp_neighb_disc_17 = (struct icmpv6_neighb_disc_ops_type_17 *)
590 pkt_pull(pkt,sizeof(*icmp_neighb_disc_17));
591 if (icmp_neighb_disc_17 == NULL)
592 return 0;
593 len -= sizeof(*icmp_neighb_disc_17);
594 if (len < 0)
595 return 0;
597 tprintf("Opt Code %s (%u) ",
598 icmpv6_code_range_valid(icmp_neighb_disc_17->opt_code - 1,
599 icmpv6_neighb_disc_ops_17_codes) ?
600 icmpv6_neighb_disc_ops_17_codes[
601 icmp_neighb_disc_17->opt_code - 1] : "Unknown",
602 icmp_neighb_disc_17->opt_code);
603 tprintf("Prefix Len (%u) ", icmp_neighb_disc_17->prefix_len);
605 if (len == sizeof(struct icmpv6_neighb_disc_ops_type_17_1)) {
606 struct icmpv6_neighb_disc_ops_type_17_1
607 *icmp_neighb_disc_17_1;
609 icmp_neighb_disc_17_1 =
610 (struct icmpv6_neighb_disc_ops_type_17_1 *)
611 pkt_pull(pkt,sizeof(*icmp_neighb_disc_17_1));
612 if (icmp_neighb_disc_17_1 == NULL)
613 return 0;
614 len -= sizeof(*icmp_neighb_disc_17_1);
615 if (len < 0)
616 return 0;
618 tprintf("Res (0x%x) ",icmp_neighb_disc_17_1->res);
619 tprintf("Addr: %s ",
620 inet_ntop(AF_INET6,&icmp_neighb_disc_17_1->ipv6_addr,
621 address, sizeof(address)));
623 else if (len == sizeof(struct icmpv6_neighb_disc_ops_type_17_2)) {
624 struct icmpv6_neighb_disc_ops_type_17_2
625 *icmp_neighb_disc_17_2;
627 icmp_neighb_disc_17_2 =
628 (struct icmpv6_neighb_disc_ops_type_17_2 *)
629 pkt_pull(pkt,sizeof(*icmp_neighb_disc_17_2));
630 if (icmp_neighb_disc_17_2 == NULL)
631 return 0;
632 len -= sizeof(*icmp_neighb_disc_17_2);
633 if (len < 0)
634 return 0;
636 tprintf("Addr: %s ",
637 inet_ntop(AF_INET6,&icmp_neighb_disc_17_2->ipv6_addr,
638 address, sizeof(address)));
640 else {
641 tprintf("%s (", colorize_start_full(black, red)
642 "Error Wrong Length. Skip Option" colorize_end());
643 while (len--) {
644 tprintf("%x", *pkt_pull(pkt,1));
646 tprintf(") ");
649 return 1;
652 static char *icmpv6_neighb_disc_ops_19_codes[] = {
653 "Wildcard requesting resolution for all nearby access points",
654 "Link-Layer Address of the New Access Point",
655 "Link-Layer Address of the MN",
656 "Link-Layer Address of the NAR",
657 "Link-Layer Address of the source of RtSolPr or PrRtAdv \
658 message",
659 "The access point identified by the LLA belongs to the \
660 current interface of the router",
661 "No prefix information available for the access point \
662 identified by the LLA",
663 "No fast handover support available for the access point \
664 identified by the LLA",
667 static int8_t dissect_neighb_disc_ops_19(struct pkt_buff *pkt,
668 ssize_t len)
670 struct icmpv6_neighb_disc_ops_type_19 *icmp_neighb_disc_19;
672 icmp_neighb_disc_19 = (struct icmpv6_neighb_disc_ops_type_19 *)
673 pkt_pull(pkt,sizeof(*icmp_neighb_disc_19));
674 if (icmp_neighb_disc_19 == NULL)
675 return 0;
676 len -= sizeof(*icmp_neighb_disc_19);
677 if (len < 0)
678 return 0;
680 tprintf("Opt Code %s (%u) ",
681 icmpv6_code_range_valid(icmp_neighb_disc_19->opt_code,
682 icmpv6_neighb_disc_ops_19_codes) ?
683 icmpv6_neighb_disc_ops_19_codes[
684 icmp_neighb_disc_19->opt_code] : "Unknown",
685 icmp_neighb_disc_19->opt_code);
687 tprintf("LLA (");
688 while(len--){
689 tprintf("%x", *pkt_pull(pkt,1));
691 tprintf(") ");
693 return 1;
696 static inline char *icmpv6_neighb_disc_ops(uint8_t code) {
697 switch (code) {
698 case 1:
699 return "Source Link-Layer Address";
700 case 2:
701 return "Target Link-Layer Address";
702 case 3:
703 return "Prefix Information";
704 case 4:
705 return "Redirected Header";
706 case 5:
707 return "MTU";
708 case 6:
709 return "NBMA Shortcut Limit Option";
710 case 7:
711 return "Advertisement Interval Option";
712 case 8:
713 return "Home Agent Information Option";
714 case 9:
715 return "Source Address List";
716 case 10:
717 return "Target Address List";
718 case 11:
719 return "CGA option";
720 case 12:
721 return "RSA Signature option";
722 case 13:
723 return "Timestamp option";
724 case 14:
725 return "Nonce option";
726 case 15:
727 return "Trust Anchor option";
728 case 16:
729 return "Certificate option";
730 case 17:
731 return "IP Address/Prefix Option";
732 case 18:
733 return "New Router Prefix Information Option";
734 case 19:
735 return "Link-layer Address Option";
736 case 20:
737 return "Neighbor Advertisement Acknowledgment Option";
739 case 23:
740 return "Prefix Information";
741 case 24:
742 return "Redirected Header";
743 case 25:
744 return "MTU";
745 case 26:
746 return "NBMA Shortcut Limit Option";
747 case 27:
748 return "Advertisement Interval Option";
749 case 28:
750 return "Home Agent Information Option";
751 case 29:
752 return "Source Address List";
753 case 30:
754 return "Target Address List";
755 case 31:
756 return "DNS Search List Option";
757 case 32:
758 return "Proxy Signature (PS)";
760 case 138:
761 return "CARD Request option";
762 case 139:
763 return "CARD Reply option";
765 case 253:
766 return "RFC3692-style Experiment 1";
767 case 254:
768 return "RFC3692-style Experiment 2";
771 return NULL;
774 static int8_t dissect_neighb_disc_ops(struct pkt_buff *pkt)
776 size_t pad_bytes;
777 uint16_t ops_total_len;
778 ssize_t ops_payl_len;
779 struct icmpv6_neighb_disc_ops_general *icmp_neighb_disc;
781 while(pkt_len(pkt)) {
782 icmp_neighb_disc = (struct icmpv6_neighb_disc_ops_general *)
783 pkt_pull(pkt,sizeof(*icmp_neighb_disc));
784 if (icmp_neighb_disc == NULL)
785 return 0;
787 ops_total_len = icmp_neighb_disc->len * 8;
788 pad_bytes = (size_t) (ops_total_len % 8);
789 ops_payl_len = ops_total_len - sizeof(*icmp_neighb_disc) -
790 pad_bytes;
792 tprintf("\n\tOption %s (%u) ",
793 icmpv6_neighb_disc_ops(icmp_neighb_disc->type) ?
794 icmpv6_neighb_disc_ops(icmp_neighb_disc->type)
795 : "Type Unknown", icmp_neighb_disc->type);
796 if (ops_payl_len > pkt_len(pkt) || ops_payl_len < 0) {
797 tprintf("Length (%u, %u bytes, %s%s%s) ",
798 icmp_neighb_disc->len,
799 ops_total_len,
800 colorize_start_full(black, red),
801 "invalid", colorize_end());
802 return 0;
805 tprintf("Length (%u, %u bytes) ",icmp_neighb_disc->len,
806 ops_total_len);
808 switch (icmp_neighb_disc->type) {
809 case 1:
810 if (!dissect_neighb_disc_ops_1(pkt, ops_payl_len))
811 return 0;
812 break;
813 case 2:
814 if (!dissect_neighb_disc_ops_2(pkt, ops_payl_len))
815 return 0;
816 break;
817 case 3:
818 if (!dissect_neighb_disc_ops_3(pkt, ops_payl_len))
819 return 0;
820 break;
821 case 4:
822 if (!dissect_neighb_disc_ops_4(pkt, ops_payl_len))
823 return 0;
824 break;
825 case 5:
826 if (!dissect_neighb_disc_ops_5(pkt, ops_payl_len))
827 return 0;
828 break;
829 /* Type 9 and 10 defined in
830 * http://tools.ietf.org/html/rfc3122#section-3.1
832 case 9:
833 if (!dissect_neighb_disc_ops_9(pkt, ops_payl_len))
834 return 0;
835 break;
836 case 10:
837 if (!dissect_neighb_disc_ops_10(pkt, ops_payl_len))
838 return 0;
839 break;
840 /* Type 15 and 16 defined in
841 * http://tools.ietf.org/html/rfc3971#section-6.4.3
842 * http://tools.ietf.org/html/rfc3971#section-6.4.4
844 case 15:
845 if (!dissect_neighb_disc_ops_15(pkt, ops_payl_len))
846 return 0;
847 break;
848 case 16:
849 if (!dissect_neighb_disc_ops_16(pkt, ops_payl_len))
850 return 0;
851 break;
852 /* Type 17 and 19 defined in
853 * http://tools.ietf.org/html/rfc5568#section-6.4
855 case 17:
856 if (!dissect_neighb_disc_ops_17(pkt, ops_payl_len))
857 return 0;
858 break;
859 case 19:
860 if (!dissect_neighb_disc_ops_19(pkt, ops_payl_len))
861 return 0;
862 break;
863 default:
864 pkt_pull(pkt, ops_payl_len);
867 /* Skip Padding Bytes */
868 if (pad_bytes > pkt_len(pkt)) {
869 tprintf(" %s",colorize_start_full(black, red)
870 "Invalid Padding" colorize_end());
871 return 0;
873 pkt_pull(pkt, pad_bytes);
876 return 1;
879 static char *icmpv6_type_1_codes[] = {
880 "No route to destination",
881 "Communication with destination administratively prohibited",
882 "Beyond scope of source address",
883 "Address unreachable",
884 "Port unreachable",
885 "Source address failed ingress/egress policy",
886 "Reject route to destination",
887 "Error in Source Routing Header",
890 static int8_t dissect_icmpv6_type1(struct pkt_buff *pkt)
892 struct icmpv6_type_1_3 *icmp_1;
894 icmp_1 = (struct icmpv6_type_1_3 *) pkt_pull(pkt,sizeof(*icmp_1));
895 if (icmp_1 == NULL)
896 return 0;
898 tprintf(", Unused (0x%x)",ntohl(icmp_1->unused));
899 tprintf(" Payload include as much of invoking packet");
901 return 1;
904 static int8_t dissect_icmpv6_type2(struct pkt_buff *pkt)
906 struct icmpv6_type_2 *icmp_2;
908 icmp_2 = (struct icmpv6_type_2 *) pkt_pull(pkt,sizeof(*icmp_2));
909 if (icmp_2 == NULL)
910 return 0;
912 tprintf(", MTU (0x%x)",ntohl(icmp_2->MTU));
913 tprintf(" Payload include as much of invoking packet");
915 return 1;
918 static char *icmpv6_type_3_codes[] = {
919 "Hop limit exceeded in transit",
920 "Fragment reassembly time exceeded",
923 static int8_t dissect_icmpv6_type3(struct pkt_buff *pkt)
925 struct icmpv6_type_1_3 *icmp_3;
927 icmp_3 = (struct icmpv6_type_1_3 *) pkt_pull(pkt,sizeof(*icmp_3));
928 if (icmp_3 == NULL)
929 return 0;
931 tprintf(", Unused (0x%x)",ntohl(icmp_3->unused));
932 tprintf(" Payload include as much of invoking packet");
934 return 1;
937 static char *icmpv6_type_4_codes[] = {
938 "Erroneous header field encountered",
939 "Unrecognized Next Header type encountered",
940 "Unrecognized IPv6 option encountered",
943 static int8_t dissect_icmpv6_type4(struct pkt_buff *pkt)
945 struct icmpv6_type_4 *icmp_4;
947 icmp_4 = (struct icmpv6_type_4 *) pkt_pull(pkt,sizeof(*icmp_4));
948 if (icmp_4 == NULL)
949 return 0;
951 tprintf(", Pointer (0x%x)",ntohl(icmp_4->pointer));
952 tprintf(" Payload include as much of invoking packet");
954 return 1;
957 static int8_t dissect_icmpv6_type128(struct pkt_buff *pkt)
959 struct icmpv6_type_128_129 *icmp_128;
961 icmp_128 = (struct icmpv6_type_128_129 *)
962 pkt_pull(pkt,sizeof(*icmp_128));
963 if (icmp_128 == NULL)
964 return 0;
966 tprintf(", ID (0x%x)",ntohs(icmp_128->id));
967 tprintf(", Seq. Nr. (%u)",ntohs(icmp_128->sn));
968 tprintf(" Payload include Data");
970 return 1;
973 static int8_t dissect_icmpv6_type129(struct pkt_buff *pkt)
975 struct icmpv6_type_128_129 *icmp_129;
977 icmp_129 = (struct icmpv6_type_128_129 *)
978 pkt_pull(pkt,sizeof(*icmp_129));
979 if (icmp_129 == NULL)
980 return 0;
982 tprintf(", ID (0x%x)",ntohs(icmp_129->id));
983 tprintf(", Seq. Nr. (%u)",ntohs(icmp_129->sn));
984 tprintf(" Payload include Data");
986 return 1;
989 static int8_t dissect_icmpv6_type130(struct pkt_buff *pkt)
991 char address[INET6_ADDRSTRLEN];
992 uint16_t nr_src, maxrespdel;
993 uint8_t switch_mldv2 = 0;
994 struct icmpv6_type_130_131_132 *icmp_130;
996 icmp_130 = (struct icmpv6_type_130_131_132 *)
997 pkt_pull(pkt,sizeof(*icmp_130));
998 if (icmp_130 == NULL)
999 return 0;
1000 maxrespdel = ntohs(icmp_130->maxrespdel);
1002 if(pkt_len(pkt) >= sizeof(struct icmpv6_type_130_mldv2))
1003 switch_mldv2 = 1;
1005 if(switch_mldv2)
1006 tprintf(", MLDv2, Max Resp Delay (%ums)", maxrespdel >> 15 ?
1007 (((maxrespdel & 0xFFF) | 0x1000) <<
1008 (((maxrespdel >> 12) & 0x3) + 3)) : maxrespdel);
1009 else
1010 tprintf(", Max Resp Delay (%ums)",maxrespdel);
1011 tprintf(", Res (0x%x)",ntohs(icmp_130->res));
1012 tprintf(", Address: %s",
1013 inet_ntop(AF_INET6, &icmp_130->ipv6_addr,
1014 address, sizeof(address)));
1016 if(switch_mldv2) {
1017 struct icmpv6_type_130_mldv2 *icmp_130_mldv2;
1019 icmp_130_mldv2 = (struct icmpv6_type_130_mldv2 *)
1020 pkt_pull(pkt,sizeof(*icmp_130_mldv2));
1021 if (icmp_130_mldv2 == NULL)
1022 return 0;
1024 nr_src = ntohs(icmp_130_mldv2->nr_src);
1026 tprintf(", Resv (0x%x)",icmp_130_mldv2->resv_S_QRV >> 4);
1027 tprintf(", S (%u)",(icmp_130_mldv2->resv_S_QRV >> 3) & 0x1);
1028 tprintf(", QRV (0x%x)",icmp_130_mldv2->resv_S_QRV & 0x3);
1029 tprintf(", QQIC (%u)",icmp_130_mldv2->QQIC);
1030 tprintf(", Nr Src (0x%x)",nr_src);
1032 return print_ipv6_addr_list(pkt, nr_src);
1035 return 1;
1038 static int8_t dissect_icmpv6_type131(struct pkt_buff *pkt)
1040 char address[INET6_ADDRSTRLEN];
1041 struct icmpv6_type_130_131_132 *icmp_131;
1043 icmp_131 = (struct icmpv6_type_130_131_132 *)
1044 pkt_pull(pkt,sizeof(*icmp_131));
1045 if (icmp_131 == NULL)
1046 return 0;
1048 tprintf(", Max Resp Delay (%ums)",ntohs(icmp_131->maxrespdel));
1049 tprintf(", Res (0x%x)",ntohs(icmp_131->res));
1050 tprintf(", Address: %s",
1051 inet_ntop(AF_INET6, &icmp_131->ipv6_addr,
1052 address, sizeof(address)));
1054 return 1;
1057 static inline int8_t dissect_icmpv6_type132(struct pkt_buff *pkt)
1059 return dissect_icmpv6_type131(pkt);
1062 static int8_t dissect_icmpv6_type133(struct pkt_buff *pkt)
1064 struct icmpv6_type_133_141_142 *icmp_133;
1066 icmp_133 = (struct icmpv6_type_133_141_142 *)
1067 pkt_pull(pkt,sizeof(*icmp_133));
1068 if (icmp_133 == NULL)
1069 return 0;
1071 tprintf(", Reserved (0x%x)",ntohl(icmp_133->res));
1073 return dissect_neighb_disc_ops(pkt);
1076 static int8_t dissect_icmpv6_type134(struct pkt_buff *pkt)
1078 struct icmpv6_type_134 *icmp_134;
1080 icmp_134 = (struct icmpv6_type_134 *)
1081 pkt_pull(pkt,sizeof(*icmp_134));
1082 if (icmp_134 == NULL)
1083 return 0;
1085 tprintf(", Cur Hop Limit (%u)",icmp_134->cur_hop_limit);
1086 tprintf(", M (%u) O (%u)",icmp_134->m_o_res >> 7,
1087 (icmp_134->m_o_res >> 6) & 0x1);
1088 tprintf(", Router Lifetime (%us)",ntohs(icmp_134->router_lifetime));
1089 tprintf(", Reachable Time (%ums)",ntohl(icmp_134->reachable_time));
1090 tprintf(", Retrans Timer (%ums)",ntohl(icmp_134->retrans_timer));
1092 return dissect_neighb_disc_ops(pkt);
1095 static int8_t dissect_icmpv6_type135(struct pkt_buff *pkt)
1097 char address[INET6_ADDRSTRLEN];
1098 struct icmpv6_type_135 *icmp_135;
1100 icmp_135 = (struct icmpv6_type_135 *)
1101 pkt_pull(pkt,sizeof(*icmp_135));
1102 if (icmp_135 == NULL)
1103 return 0;
1105 tprintf(", Reserved (0x%x)",ntohl(icmp_135->res));
1106 tprintf(", Target Address: %s",
1107 inet_ntop(AF_INET6, &icmp_135->ipv6_addr,
1108 address, sizeof(address)));
1110 return dissect_neighb_disc_ops(pkt);
1113 static int8_t dissect_icmpv6_type136(struct pkt_buff *pkt)
1115 char address[INET6_ADDRSTRLEN];
1116 uint32_t r_s_o_res;
1117 struct icmpv6_type_136 *icmp_136;
1119 icmp_136 = (struct icmpv6_type_136 *)
1120 pkt_pull(pkt,sizeof(*icmp_136));
1121 if (icmp_136 == NULL)
1122 return 0;
1123 r_s_o_res = ntohl(icmp_136->r_s_o_res);
1125 tprintf(", R (%u) S (%u) O (%u) Reserved (0x%x)", r_s_o_res >> 31,
1126 (r_s_o_res >> 30) & 0x1, (r_s_o_res >> 29) & 0x1,
1127 r_s_o_res & 0x1FFFFFFF);
1128 tprintf(", Target Address: %s",
1129 inet_ntop(AF_INET6, &icmp_136->ipv6_addr,
1130 address, sizeof(address)));
1132 return dissect_neighb_disc_ops(pkt);
1135 static int8_t dissect_icmpv6_type137(struct pkt_buff *pkt)
1137 char address[INET6_ADDRSTRLEN];
1138 struct icmpv6_type_137 *icmp_137;
1140 icmp_137 = (struct icmpv6_type_137 *)
1141 pkt_pull(pkt,sizeof(*icmp_137));
1142 if (icmp_137 == NULL)
1143 return 0;
1145 tprintf(", Reserved (0x%x)",icmp_137->res);
1146 tprintf(", Target Address: %s",
1147 inet_ntop(AF_INET6, &icmp_137->ipv6_targ_addr,
1148 address, sizeof(address)));
1149 tprintf(", Dest Address: %s",
1150 inet_ntop(AF_INET6, &icmp_137->ipv6_dest_addr,
1151 address, sizeof(address)));
1153 return dissect_neighb_disc_ops(pkt);
1156 static void dissect_icmpv6_rr_body(struct pkt_buff *pkt)
1159 * Upgrade Dissector for Message Body
1160 * from http://tools.ietf.org/html/rfc2894#section-3.2
1162 if(pkt_len(pkt))
1163 tprintf(" Message Body recognized");
1166 static inline char *icmpv6_type_138_codes(uint8_t code) {
1167 switch (code) {
1168 case 1:
1169 return "Router Renumbering Command";
1170 case 2:
1171 return "Router Renumbering Result";
1172 case 255:
1173 return "Sequence Number Reset";
1176 return NULL;
1179 static int8_t dissect_icmpv6_type138(struct pkt_buff *pkt)
1181 struct icmpv6_type_138 *icmp_138;
1183 icmp_138 = (struct icmpv6_type_138 *)
1184 pkt_pull(pkt,sizeof(*icmp_138));
1185 if (icmp_138 == NULL)
1186 return 0;
1188 tprintf(", Sequence Nr. (%u)",ntohl(icmp_138->seq_nr));
1189 tprintf(", Segment Nr. (%u)",icmp_138->seg_nr);
1190 tprintf(", T (%u) R (%u) A (%u) S (%u) P (%u) Res \
1191 (0x%x) ",icmp_138->flags >> 7, (icmp_138->flags >> 6) & 1,
1192 (icmp_138->flags >> 5) & 1, (icmp_138->flags >> 4) & 1,
1193 (icmp_138->flags >> 3) & 1, icmp_138->flags & 7);
1194 tprintf(", Max Delay (%ums)", ntohs(icmp_138->maxdelay));
1195 tprintf(", Res (0x%x)", ntohl(icmp_138->res));
1197 dissect_icmpv6_rr_body(pkt);
1199 return 1;
1202 static void dissect_icmpv6_node_inf_data(struct pkt_buff *pkt)
1205 * Upgrade Dissector for Data field
1206 * http://tools.ietf.org/html/rfc4620#section-4
1208 if(pkt_len(pkt))
1209 tprintf(" Data recognized");
1212 static char *icmpv6_node_inf_qtypes[] = {
1213 "NOOP",
1214 "unused",
1215 "Node Name",
1216 "Node Addresses",
1217 "IPv4 Addresses ",
1220 static char *icmpv6_type_139_codes[] = {
1221 "Data contains IPv6 Address",
1222 "Data contains Name or nothing",
1223 "Data contains IPv4 Address",
1226 static int8_t dissect_icmpv6_type139(struct pkt_buff *pkt)
1228 char *qtype_name = "Unknown";
1229 uint16_t qtype_nr;
1230 struct icmpv6_type_139_140 *icmp_139;
1232 icmp_139 = (struct icmpv6_type_139_140 *)
1233 pkt_pull(pkt,sizeof(*icmp_139));
1234 if (icmp_139 == NULL)
1235 return 0;
1237 qtype_nr = ntohs(icmp_139->qtype);
1238 if (icmpv6_code_range_valid(qtype_nr, icmpv6_node_inf_qtypes))
1239 qtype_name = icmpv6_node_inf_qtypes[qtype_nr];
1241 tprintf(", Qtype %s (%u)",qtype_name, qtype_nr);
1242 tprintf(", Flags (0x%x)",ntohs(icmp_139->flags));
1243 tprintf(", Nonce (0x%x)",ntohll(icmp_139->nonce));
1245 dissect_icmpv6_node_inf_data(pkt);
1247 return 1;
1250 static char *icmpv6_type_140_codes[] = {
1251 "Successfull reply",
1252 "Responder refuses answer",
1253 "Qtype is unknown to the Responder",
1256 static inline int8_t dissect_icmpv6_type140(struct pkt_buff *pkt)
1258 return dissect_icmpv6_type139(pkt);
1261 static inline int8_t dissect_icmpv6_type141(struct pkt_buff *pkt)
1263 return dissect_icmpv6_type133(pkt);
1266 static inline int8_t dissect_icmpv6_type142(struct pkt_buff *pkt)
1268 return dissect_icmpv6_type133(pkt);
1271 static int8_t dissect_icmpv6_type143(struct pkt_buff *pkt)
1273 uint16_t nr_rec;
1274 struct icmpv6_type_143 *icmp_143;
1276 icmp_143 = (struct icmpv6_type_143 *)
1277 pkt_pull(pkt,sizeof(*icmp_143));
1278 if (icmp_143 == NULL)
1279 return 0;
1280 nr_rec = ntohs(icmp_143->nr_rec);
1282 tprintf(", Res (0x%x)",ntohs(icmp_143->res));
1283 tprintf(", Nr. Mcast Addr Records (%u)",nr_rec);
1285 return dissect_icmpv6_mcast_rec(pkt, nr_rec);
1288 static int8_t dissect_icmpv6_type144(struct pkt_buff *pkt)
1290 struct icmpv6_type_144_146 *icmp_144;
1292 icmp_144 = (struct icmpv6_type_144_146 *)
1293 pkt_pull(pkt,sizeof(*icmp_144));
1294 if (icmp_144 == NULL)
1295 return 0;
1297 tprintf(", ID (%u)",ntohs(icmp_144->id));
1298 tprintf(", Res (0x%x)",ntohs(icmp_144->res));
1300 return 1;
1303 static int8_t dissect_icmpv6_type145(struct pkt_buff *pkt)
1305 struct icmpv6_type_145 *icmp_145;
1307 icmp_145 = (struct icmpv6_type_145 *)
1308 pkt_pull(pkt,sizeof(*icmp_145));
1309 if (icmp_145 == NULL)
1310 return 0;
1312 tprintf(", ID (%u)",ntohs(icmp_145->id));
1313 tprintf(", Res (0x%x)",ntohs(icmp_145->res));
1315 return print_ipv6_addr_list(pkt, pkt_len(pkt) /
1316 sizeof(struct in6_addr));
1319 static inline int8_t dissect_icmpv6_type146(struct pkt_buff *pkt)
1321 return dissect_icmpv6_type144(pkt);
1324 static int8_t dissect_icmpv6_type147(struct pkt_buff *pkt)
1326 uint16_t m_o_res;
1327 struct icmpv6_type_147 *icmp_147;
1329 icmp_147 = (struct icmpv6_type_147 *)
1330 pkt_pull(pkt,sizeof(*icmp_147));
1331 if (icmp_147 == NULL)
1332 return 0;
1333 m_o_res = ntohs(icmp_147->m_o_res);
1335 tprintf(", ID (%u)",ntohs(icmp_147->id));
1336 tprintf(", M (%u) O (%u) Res (0x%x)",m_o_res >> 15,
1337 (m_o_res >> 14) & 1, m_o_res & 0x3FFF);
1339 return dissect_neighb_disc_ops(pkt);
1342 static int8_t dissect_icmpv6_type148(struct pkt_buff *pkt)
1344 struct icmpv6_type_148 *icmp_148;
1346 icmp_148 = (struct icmpv6_type_148 *)
1347 pkt_pull(pkt,sizeof(*icmp_148));
1348 if (icmp_148 == NULL)
1349 return 0;
1351 tprintf(", ID (%u)",ntohs(icmp_148->id));
1352 tprintf(", Component (%u)",ntohs(icmp_148->comp));
1354 return dissect_neighb_disc_ops(pkt);
1357 static int8_t dissect_icmpv6_type149(struct pkt_buff *pkt)
1359 struct icmpv6_type_149 *icmp_149;
1361 icmp_149 = (struct icmpv6_type_149 *)
1362 pkt_pull(pkt,sizeof(*icmp_149));
1363 if (icmp_149 == NULL)
1364 return 0;
1366 tprintf(", ID (%u)",ntohs(icmp_149->id));
1367 tprintf(", All Components (%u)",ntohs(icmp_149->all_comp));
1368 tprintf(", Component (%u)",ntohs(icmp_149->comp));
1369 tprintf(", Res (0x%x)",ntohs(icmp_149->res));
1371 return dissect_neighb_disc_ops(pkt);
1374 static int8_t dissect_icmpv6_type150(struct pkt_buff *pkt)
1376 struct icmpv6_type_150 *icmp_150;
1378 icmp_150 = (struct icmpv6_type_150 *)
1379 pkt_pull(pkt,sizeof(*icmp_150));
1380 if (icmp_150 == NULL)
1381 return 0;
1383 tprintf(", Subtype (%u)",icmp_150->subtype);
1384 tprintf(", Res (0x%x)",icmp_150->res);
1385 tprintf(", Options in Payload");
1387 return 1;
1390 static int8_t dissect_icmpv6_type151(struct pkt_buff *pkt)
1392 struct icmpv6_type_151 *icmp_151;
1394 icmp_151 = (struct icmpv6_type_151 *)
1395 pkt_pull(pkt,sizeof(*icmp_151));
1396 if (icmp_151 == NULL)
1397 return 0;
1399 tprintf(", Query Interval (%us)",ntohs(icmp_151->query_intv));
1400 tprintf(", Robustness Variable (%u)",ntohs(icmp_151->rob_var));
1402 return 1;
1405 static int8_t dissect_icmpv6_type152(struct pkt_buff *pkt)
1407 struct icmpv6_type_152 *icmp_152;
1409 icmp_152 = (struct icmpv6_type_152 *)
1410 pkt_pull(pkt,sizeof(*icmp_152));
1411 if (icmp_152 == NULL)
1412 return 0;
1414 return 1;
1417 static int8_t dissect_icmpv6_type153(struct pkt_buff *pkt)
1419 struct icmpv6_type_153 *icmp_153;
1421 icmp_153 = (struct icmpv6_type_153 *)
1422 pkt_pull(pkt,sizeof(*icmp_153));
1423 if (icmp_153 == NULL)
1424 return 0;
1426 return 1;
1429 static int8_t dissect_icmpv6_type154(struct pkt_buff *pkt)
1431 struct icmpv6_type_154 *icmp_154;
1433 icmp_154 = (struct icmpv6_type_154 *)
1434 pkt_pull(pkt,sizeof(*icmp_154));
1435 if (icmp_154 == NULL)
1436 return 0;
1438 tprintf(", Subtype (%u)",icmp_154->subtype);
1439 tprintf(", Res (0x%x)",icmp_154->res);
1440 tprintf(", ID (%u)",ntohs(icmp_154->id));
1442 return dissect_neighb_disc_ops(pkt);
1445 static inline char *icmpv6_type_155_codes(uint8_t code) {
1446 switch (code) {
1447 case 0x00:
1448 return "DODAG Information Solicitation";
1449 case 0x01:
1450 return "DODAG Information Object";
1451 case 0x02:
1452 return "Destination Advertisement Object";
1453 case 0x03:
1454 return "Destination Advertisement Object Acknowledgment";
1455 case 0x80:
1456 return "Secure DODAG Information Solicitation";
1457 case 0x81:
1458 return "Secure DODAG Information Object";
1459 case 0x82:
1460 return "Secure Destination Advertisement Object";
1461 case 0x83:
1462 return "Secure Destination Advertisement Object Acknowledgment";
1463 case 0x8A:
1464 return "Consistency Check";
1467 return NULL;
1470 static void icmpv6_process(struct icmpv6_general_hdr *icmp, char **type,
1471 char **code, int8_t (**optional)(struct pkt_buff *pkt))
1473 *type = "Unknown Type";
1474 *code = "Unknown Code";
1476 switch (icmp->h_type) {
1477 case 1:
1478 *type = "Destination Unreachable";
1479 if (icmpv6_code_range_valid(icmp->h_code, icmpv6_type_1_codes))
1480 *code = icmpv6_type_1_codes[icmp->h_code];
1481 *optional = dissect_icmpv6_type1;
1482 return;
1483 case 2:
1484 *type = "Packet Too Big";
1485 *optional = dissect_icmpv6_type2;
1486 return;
1487 case 3:
1488 *type = "Time Exceeded";
1489 if (icmpv6_code_range_valid(icmp->h_code, icmpv6_type_3_codes))
1490 *code = icmpv6_type_3_codes[icmp->h_code];
1491 *optional = dissect_icmpv6_type3;
1492 return;
1493 case 4:
1494 *type = "Parameter Problem";
1495 if (icmpv6_code_range_valid(icmp->h_code, icmpv6_type_4_codes))
1496 *code = icmpv6_type_4_codes[icmp->h_code];
1497 *optional = dissect_icmpv6_type4;
1498 return;
1499 case 100:
1500 *type = "Private experimation";
1501 return;
1502 case 101:
1503 *type = "Private experimation";
1504 return;
1505 case 127:
1506 *type = "Reserved for expansion of ICMPv6 error messages";
1507 return;
1508 case 128:
1509 *type = "Echo Request";
1510 *optional = dissect_icmpv6_type128;
1511 return;
1512 case 129:
1513 *type = "Echo Reply";
1514 *optional = dissect_icmpv6_type129;
1515 return;
1516 case 130:
1517 *type = "Multicast Listener Query";
1518 *optional = dissect_icmpv6_type130;
1519 return;
1520 case 131:
1521 *type = "Multicast Listener Report";
1522 *optional = dissect_icmpv6_type131;
1523 return;
1524 case 132:
1525 *type = "Multicast Listener Done";
1526 *optional = dissect_icmpv6_type132;
1527 return;
1528 case 133:
1529 *type = "Router Solicitation";
1530 *optional = dissect_icmpv6_type133;
1531 return;
1532 case 134:
1533 *type = "Router Advertisement";
1534 *optional = dissect_icmpv6_type134;
1535 return;
1536 case 135:
1537 *type = "Neighbor Solicitation";
1538 *optional = dissect_icmpv6_type135;
1539 return;
1540 case 136:
1541 *type = "Neighbor Advertisement";
1542 *optional = dissect_icmpv6_type136;
1543 return;
1544 case 137:
1545 *type = "Redirect Message";
1546 *optional = dissect_icmpv6_type137;
1547 return;
1548 case 138:
1549 *type = "Router Renumbering";
1550 if(icmpv6_type_138_codes(icmp->h_code))
1551 *code = icmpv6_type_138_codes(icmp->h_code);
1552 *optional = dissect_icmpv6_type138;
1553 return;
1554 case 139:
1555 *type = "ICMP Node Information Query";
1556 if (icmpv6_code_range_valid(icmp->h_code,
1557 icmpv6_type_139_codes))
1558 *code = icmpv6_type_139_codes[icmp->h_code];
1559 *optional = dissect_icmpv6_type139;
1560 return;
1561 case 140:
1562 *type = "ICMP Node Information Response";
1563 if (icmpv6_code_range_valid(icmp->h_code,
1564 icmpv6_type_140_codes))
1565 *code = icmpv6_type_140_codes[icmp->h_code];
1566 *optional = dissect_icmpv6_type140;
1567 return;
1568 case 141:
1569 *type = "Inverse Neighbor Discovery Solicitation Message";
1570 *optional = dissect_icmpv6_type141;
1571 return;
1572 case 142:
1573 *type = "Inverse Neighbor Discovery Advertisement Message";
1574 *optional = dissect_icmpv6_type142;
1575 return;
1576 case 143:
1577 *type = "Multicast Listener Report v2";
1578 *optional = dissect_icmpv6_type143;
1579 return;
1580 case 144:
1581 *type = "Home Agent Address Discovery Request Message";
1582 *optional = dissect_icmpv6_type144;
1583 return;
1584 case 145:
1585 *type = "Home Agent Address Discovery Reply Message";
1586 *optional = dissect_icmpv6_type145;
1587 return;
1588 case 146:
1589 *type = "Mobile Prefix Solicitation";
1590 *optional = dissect_icmpv6_type146;
1591 return;
1592 case 147:
1593 *type = "Mobile Prefix Advertisement";
1594 *optional = dissect_icmpv6_type147;
1595 return;
1596 case 148:
1597 *type = "Certification Path Solicitation";
1598 *optional = dissect_icmpv6_type148;
1599 return;
1600 case 149:
1601 *type = "Certification Path Advertisement";
1602 *optional = dissect_icmpv6_type149;
1603 return;
1604 case 150:
1605 *type = "ICMP messages utilized by experimental mobility "
1606 "protocols such as Seamoby";
1607 *optional = dissect_icmpv6_type150;
1608 return;
1609 case 151:
1610 *type = "Multicast Router Advertisement";
1611 *code = "Ad. Interval";
1612 *optional = dissect_icmpv6_type151;
1613 return;
1614 case 152:
1615 *type = "Multicast Router Solicitation";
1616 *code = "Reserved";
1617 *optional = dissect_icmpv6_type152;
1618 return;
1619 case 153:
1620 *type = "Multicast Router Termination";
1621 *code = "Reserved";
1622 *optional = dissect_icmpv6_type153;
1623 return;
1624 case 154:
1625 *type = "FMIPv6 Messages";
1626 *optional = dissect_icmpv6_type154;
1627 return;
1628 case 155:
1629 *type = "RPL Control Message";
1630 if(icmpv6_type_155_codes(icmp->h_code))
1631 *code = icmpv6_type_155_codes(icmp->h_code);
1632 return;
1633 case 200:
1634 *type = "Private experimation";
1635 return;
1636 case 201:
1637 *type = "Private experimation";
1638 return;
1639 case 255:
1640 *type = "Reserved for expansion of ICMPv6 error messages";
1641 return;
1645 static void icmpv6(struct pkt_buff *pkt)
1647 char *type = NULL, *code = NULL;
1648 int8_t (*optional)(struct pkt_buff *pkt) = NULL;
1649 struct icmpv6_general_hdr *icmp =
1650 (struct icmpv6_general_hdr *) pkt_pull(pkt, sizeof(*icmp));
1652 if (icmp == NULL)
1653 return;
1655 icmpv6_process(icmp, &type, &code, &optional);
1657 tprintf(" [ ICMPv6 ");
1658 tprintf("%s (%u), ", type, icmp->h_type);
1659 tprintf("%s (%u), ", code, icmp->h_code);
1660 tprintf("Chks (0x%x)", ntohs(icmp->h_chksum));
1661 if (optional)
1662 if (!((*optional) (pkt)))
1663 tprintf("\n%s%s%s", colorize_start_full(black, red),
1664 "Failed to dissect Message", colorize_end());
1665 tprintf(" ]\n");
1668 static void icmpv6_less(struct pkt_buff *pkt)
1670 struct icmpv6_general_hdr *icmp =
1671 (struct icmpv6_general_hdr *) pkt_pull(pkt, sizeof(*icmp));
1673 if (icmp == NULL)
1674 return;
1676 tprintf(" ICMPv6 Type (%u) Code (%u)", icmp->h_type, icmp->h_code);
1679 struct protocol icmpv6_ops = {
1680 .key = 0x3A,
1681 .print_full = icmpv6,
1682 .print_less = icmpv6_less,
1685 EXPORT_SYMBOL(icmpv6_ops);