dissector_80211: start of 80211 collection
[netsniff-ng.git] / src / proto_icmpv6.h
blob30d142f96d831d15586470e36e76ba77a50836a7
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 #ifndef PROTO_ICMPV6_H
14 #define PROTO_ICMPV6_H
16 #include <stdio.h>
17 #include <stdint.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
20 #include <asm/byteorder.h>
22 #include "built_in.h"
23 #include "proto_struct.h"
24 #include "dissector_eth.h"
25 #include "pkt_buff.h"
26 #include "built_in.h"
28 #define icmpv6_code_range_valid(code, sarr) ((code) < array_size((sarr)))
30 struct icmpv6_general_hdr {
31 uint8_t h_type;
32 uint8_t h_code;
33 uint16_t h_chksum;
34 } __packed;
36 /* for type 0x01 and 0x03 */
37 struct icmpv6_type_1_3 {
38 uint32_t unused;
39 uint8_t invoking_pkt[0];
40 } __packed;
42 struct icmpv6_type_2 {
43 uint32_t MTU;
44 uint8_t invoking_pkt[0];
45 } __packed;
47 struct icmpv6_type_4 {
48 uint32_t pointer;
49 uint8_t invoking_pkt[0];
50 } __packed;
52 struct icmpv6_type_128_129 {
53 uint16_t id;
54 uint16_t sn;
55 uint8_t data[0];
56 } __packed;
58 /* MLDv1 msg */
59 struct icmpv6_type_130_131_132 {
60 uint16_t maxrespdel;
61 uint16_t res;
62 struct in6_addr ipv6_addr;
63 } __packed;
64 /* end MLDv1 msg */
66 struct icmpv6_type_130_mldv2 {
67 uint8_t resv_S_QRV;
68 uint8_t QQIC;
69 uint16_t nr_src;
70 struct in6_addr ipv6_addr[0];
71 } __packed;
73 /* Neighbor Discovery msg */
74 struct icmpv6_type_133_141_142 {
75 uint32_t res;
76 uint8_t ops[0];
77 } __packed;
79 struct icmpv6_type_134 {
80 uint8_t cur_hop_limit;
81 uint8_t m_o_res;
82 uint16_t router_lifetime;
83 uint32_t reachable_time;
84 uint32_t retrans_timer;
85 uint8_t ops[0];
86 } __packed;
88 struct icmpv6_type_135 {
89 uint32_t res;
90 struct in6_addr ipv6_addr;
91 uint8_t ops[0];
92 } __packed;
94 struct icmpv6_type_136 {
95 uint32_t r_s_o_res;
96 struct in6_addr ipv6_addr;
97 uint8_t ops[0];
98 } __packed;
100 struct icmpv6_type_137 {
101 uint32_t res;
102 struct in6_addr ipv6_targ_addr;
103 struct in6_addr ipv6_dest_addr;
104 uint8_t ops[0];
105 } __packed;
107 struct icmpv6_neighb_disc_ops_general {
108 uint8_t type;
109 uint8_t len;
110 uint8_t ops[0];
111 } __packed;
113 struct icmpv6_neighb_disc_ops_type_1_2 {
114 uint8_t link_lay_addr[0];
115 } __packed;
117 struct icmpv6_neighb_disc_ops_type_3 {
118 uint8_t prefix_len;
119 uint8_t l_a_res1;
120 uint32_t valid_lifetime;
121 uint32_t preferred_lifetime;
122 uint32_t res2;
123 struct in6_addr prefix;
124 } __packed;
126 struct icmpv6_neighb_disc_ops_type_4 {
127 uint16_t res1;
128 uint32_t res2;
129 uint8_t ip_hdr_data[0];
130 } __packed;
132 struct icmpv6_neighb_disc_ops_type_5 {
133 uint16_t res1;
134 uint32_t MTU;
135 } __packed;
137 struct icmpv6_neighb_disc_ops_type_9_10 {
138 uint16_t res1;
139 uint32_t res2;
140 uint8_t ip_hdr_data[0];
141 } __packed;
143 struct icmpv6_neighb_disc_ops_type_15 {
144 uint8_t name_type;
145 size_t pad_len;
146 char name[0];
147 uint8_t pad[0];
148 } __packed;
150 struct icmpv6_neighb_disc_ops_type_16 {
151 uint8_t cert_type;
152 uint8_t res;
153 uint8_t cert[0];
154 uint8_t pad[0];
155 } __packed;
157 struct icmpv6_neighb_disc_ops_type_17 {
158 uint8_t opt_code;
159 uint8_t prefix_len;
160 uint8_t data[0];
161 } __packed;
163 struct icmpv6_neighb_disc_ops_type_17_1 {
164 uint32_t res;
165 struct in6_addr ipv6_addr;
166 } __packed;
168 struct icmpv6_neighb_disc_ops_type_17_2 {
169 struct in6_addr ipv6_addr;
170 } __packed;
172 struct icmpv6_neighb_disc_ops_type_19 {
173 uint8_t opt_code;
174 uint8_t lla[0];
175 } __packed;
176 /* end Neighbor Discovery msg */
178 struct icmpv6_type_138 {
179 uint32_t seq_nr;
180 uint8_t seg_nr;
181 uint8_t flags;
182 uint16_t maxdelay;
183 uint32_t res;
184 } __packed;
186 /* Node Information Queries */
187 struct icmpv6_type_139_140 {
188 uint16_t qtype;
189 uint16_t flags;
190 uint64_t nonce;
191 uint8_t data[0];
192 } __packed;
193 /* end Node Information Queries */
195 /* MLDv2 report */
196 struct icmpv6_type_143 {
197 uint16_t res;
198 uint16_t nr_rec;
199 uint8_t addr_rec[0];
200 } __packed;
202 struct icmpv6_mldv2_addr_rec {
203 uint8_t rec_type;
204 uint8_t aux_data_len;
205 uint16_t nr_src;
206 struct in6_addr multic_addr;
207 struct in6_addr src_addr[0];
208 } __packed;
209 /* end MLDv2 report */
211 /* ICMP Mobility Support */
212 struct icmpv6_type_144_146 {
213 uint16_t id;
214 uint16_t res;
215 } __packed;
217 struct icmpv6_type_145 {
218 uint16_t id;
219 uint16_t res;
220 struct in6_addr home_agent_addr[0];
221 } __packed;
223 struct icmpv6_type_147 {
224 uint16_t id;
225 uint16_t m_o_res;
226 uint8_t ops[0];
227 } __packed;
228 /* end ICMP Mobility Support */
230 /* SEcure Neighbor Discovery */
231 struct icmpv6_type_148 {
232 uint16_t id;
233 uint16_t comp;
234 uint8_t ops[0];
235 } __packed;
237 struct icmpv6_type_149 {
238 uint16_t id;
239 uint16_t all_comp;
240 uint16_t comp;
241 uint16_t res;
242 uint8_t ops[0];
243 } __packed;
244 /* end SEcure Neighbor Discovery */
246 struct icmpv6_type_150 {
247 union {
248 uint32_t subtype_res;
249 struct {
250 #if defined(__LITTLE_ENDIAN_BITFIELD)
251 uint32_t res :24,
252 subtype :8;
253 #elif defined(__BIG_ENDIAN_BITFIELD)
254 uint32_t subtype :8,
255 res :24;
256 #else
257 # error "Please fix <asm/byteorder.h>"
258 #endif
261 uint8_t ops[0];
262 } __packed;
264 /* Multicast Router Discovery */
265 struct icmpv6_type_151 {
266 uint16_t query_intv;
267 uint16_t rob_var;
268 } __packed;
270 struct icmpv6_type_152 {
271 uint8_t null[0];
272 } __packed;
274 struct icmpv6_type_153 {
275 uint8_t null[0];
276 } __packed;
277 /* end Multicast Router Discovery */
279 struct icmpv6_type_154 {
280 uint8_t subtype;
281 uint8_t res;
282 uint16_t id;
283 uint8_t ops[0];
284 } __packed;
286 static inline int8_t print_ipv6_addr_list(struct pkt_buff *pkt, uint8_t nr_addr)
288 char address[INET6_ADDRSTRLEN];
289 struct in6_addr *addr;
291 while (nr_addr--) {
292 addr = (struct in6_addr *) pkt_pull(pkt, sizeof(*addr));
293 if (addr == NULL)
294 return 0;
296 tprintf("\n\t Address: %s",
297 inet_ntop(AF_INET6, addr, address,
298 sizeof(address)));
301 return 1;
304 static char *icmpv6_mcast_rec_types[] = {
305 "MODE_IS_INCLUDE",
306 "MODE_IS_EXCLUDE",
307 "CHANGE_TO_INCLUDE_MODE",
308 "CHANGE_TO_EXCLUDE_MODE",
309 "ALLOW_NEW_SOURCES",
310 "BLOCK_OLD_SOURCES",
313 static inline int8_t dissect_icmpv6_mcast_rec(struct pkt_buff *pkt,
314 uint16_t nr_rec)
316 uint16_t nr_src, aux_data_len_bytes;
317 struct icmpv6_mldv2_addr_rec *addr_rec;
319 while (nr_rec--) {
320 addr_rec = (struct icmpv6_mldv2_addr_rec *)
321 pkt_pull(pkt,sizeof(*addr_rec));
322 if (addr_rec == NULL)
323 return 0;
324 aux_data_len_bytes = addr_rec->aux_data_len * 4;
325 nr_src = ntohs(addr_rec->nr_src);
327 tprintf(", Rec Type %s (%u)",
328 icmpv6_code_range_valid(addr_rec->rec_type - 1,
329 icmpv6_mcast_rec_types) ?
330 icmpv6_mcast_rec_types[addr_rec->rec_type - 1]
331 : "Unknown", addr_rec->rec_type);
332 if (aux_data_len_bytes > pkt_len(pkt)) {
333 tprintf(", Aux Data Len (%u, %u bytes) %s",
334 addr_rec->aux_data_len,
335 aux_data_len_bytes,
336 colorize_start_full(black, red) "invalid"
337 colorize_end());
338 return 0;
340 tprintf(", Aux Data Len (%u, %u bytes)",addr_rec->aux_data_len,
341 aux_data_len_bytes);
342 tprintf(", Nr. of Sources (%u)",nr_src);
344 if(!print_ipv6_addr_list(pkt, nr_src))
345 return 0;
347 tprintf(", Aux Data: ");
348 while (aux_data_len_bytes--) {
349 tprintf("%x", *pkt_pull(pkt,1));
353 return 1;
356 static inline int8_t dissect_neighb_disc_ops_1(struct pkt_buff *pkt,
357 ssize_t len)
359 struct icmpv6_neighb_disc_ops_type_1_2 *icmp_neighb_disc_1;
361 icmp_neighb_disc_1 = (struct icmpv6_neighb_disc_ops_type_1_2 *)
362 pkt_pull(pkt,sizeof(*icmp_neighb_disc_1));
363 if (icmp_neighb_disc_1 == NULL)
364 return 0;
365 len -= sizeof(*icmp_neighb_disc_1);
366 if (len < 0)
367 return 0;
369 tprintf("Address 0x");
371 while(len--){
372 tprintf("%x", *pkt_pull(pkt,1));
375 return 1;
378 static inline int8_t dissect_neighb_disc_ops_2(struct pkt_buff *pkt,
379 ssize_t len)
381 return dissect_neighb_disc_ops_1(pkt, len);
384 static inline int8_t dissect_neighb_disc_ops_3(struct pkt_buff *pkt,
385 ssize_t len)
387 char address[INET6_ADDRSTRLEN];
388 struct icmpv6_neighb_disc_ops_type_3 *icmp_neighb_disc_3;
390 icmp_neighb_disc_3 = (struct icmpv6_neighb_disc_ops_type_3 *)
391 pkt_pull(pkt,sizeof(*icmp_neighb_disc_3));
392 if (icmp_neighb_disc_3 == NULL)
393 return 0;
394 len -= sizeof(*icmp_neighb_disc_3);
395 if (len < 0)
396 return 0;
398 tprintf("Prefix Len (%u) ",icmp_neighb_disc_3->prefix_len);
399 tprintf("L (%u) A (%u) Res1 (0x%x) ",icmp_neighb_disc_3->l_a_res1 >> 7,
400 (icmp_neighb_disc_3->l_a_res1 >> 7) & 0x1,
401 icmp_neighb_disc_3->l_a_res1 & 0x3F);
402 tprintf("Valid Lifetime (%us) ",
403 ntohl(icmp_neighb_disc_3->valid_lifetime));
404 tprintf("Preferred Lifetime (%us) ",
405 ntohl(icmp_neighb_disc_3->preferred_lifetime));
406 tprintf("Reserved2 (0x%x) ",
407 ntohl(icmp_neighb_disc_3->res2));
408 tprintf("Prefix: %s ",
409 inet_ntop(AF_INET6,&icmp_neighb_disc_3->prefix,
410 address, sizeof(address)));
412 return 1;
415 static inline int8_t dissect_neighb_disc_ops_4(struct pkt_buff *pkt,
416 ssize_t len)
418 struct icmpv6_neighb_disc_ops_type_4 *icmp_neighb_disc_4;
420 icmp_neighb_disc_4 = (struct icmpv6_neighb_disc_ops_type_4 *)
421 pkt_pull(pkt,sizeof(*icmp_neighb_disc_4));
422 if (icmp_neighb_disc_4 == NULL)
423 return 0;
424 len -= sizeof(*icmp_neighb_disc_4);
425 if (len < 0)
426 return 0;
428 tprintf("Reserved 1 (0x%x) ", ntohs(icmp_neighb_disc_4->res1));
429 tprintf("Reserved 2 (0x%x) ", ntohl(icmp_neighb_disc_4->res2));
430 tprintf("IP header + data ");
432 while (len--) {
433 tprintf("%x", *pkt_pull(pkt,1));
436 return 1;
439 static inline int8_t dissect_neighb_disc_ops_5(struct pkt_buff *pkt,
440 ssize_t len)
442 struct icmpv6_neighb_disc_ops_type_5 *icmp_neighb_disc_5;
444 icmp_neighb_disc_5 = (struct icmpv6_neighb_disc_ops_type_5 *)
445 pkt_pull(pkt,sizeof(*icmp_neighb_disc_5));
446 if (icmp_neighb_disc_5 == NULL)
447 return 0;
448 len -= sizeof(*icmp_neighb_disc_5);
449 if (len < 0)
450 return 0;
452 tprintf("Reserved (0x%x) ", ntohs(icmp_neighb_disc_5->res1));
453 tprintf("MTU (%u)", ntohl(icmp_neighb_disc_5->MTU));
455 return 1;
458 static inline int8_t dissect_neighb_disc_ops_9(struct pkt_buff *pkt,
459 ssize_t len)
461 struct icmpv6_neighb_disc_ops_type_9_10 *icmp_neighb_disc_9;
463 icmp_neighb_disc_9 = (struct icmpv6_neighb_disc_ops_type_9_10 *)
464 pkt_pull(pkt,sizeof(*icmp_neighb_disc_9));
465 if (icmp_neighb_disc_9 == NULL)
466 return 0;
467 len -= sizeof(*icmp_neighb_disc_9);
468 if (len < 0)
469 return 0;
471 tprintf("Reserved 1 (0x%x) ", ntohs(icmp_neighb_disc_9->res1));
472 tprintf("Reserved 2 (0x%x) ", ntohl(icmp_neighb_disc_9->res2));
474 return print_ipv6_addr_list(pkt, len / sizeof(struct in6_addr));
477 static inline int8_t dissect_neighb_disc_ops_10(struct pkt_buff *pkt,
478 ssize_t len)
480 return dissect_neighb_disc_ops_9(pkt, len);
483 static char *icmpv6_neighb_disc_ops_15_name[] = {
484 "DER Encoded X.501 Name",
485 "FQDN",
488 static inline int8_t dissect_neighb_disc_ops_15(struct pkt_buff *pkt,
489 ssize_t len)
491 size_t pad_len;
492 ssize_t name_len;
493 struct icmpv6_neighb_disc_ops_type_15 *icmp_neighb_disc_15;
495 icmp_neighb_disc_15 = (struct icmpv6_neighb_disc_ops_type_15 *)
496 pkt_pull(pkt,sizeof(*icmp_neighb_disc_15));
497 if (icmp_neighb_disc_15 == NULL)
498 return 0;
499 len -= sizeof(*icmp_neighb_disc_15);
500 if (len < 0)
501 return 0;
502 pad_len = icmp_neighb_disc_15->pad_len;
504 tprintf("Name Type %s (%u) ",
505 icmpv6_code_range_valid(icmp_neighb_disc_15->name_type - 1,
506 icmpv6_neighb_disc_ops_15_name) ?
507 icmpv6_neighb_disc_ops_15_name[
508 icmp_neighb_disc_15->name_type - 1] : "Unknown",
509 icmp_neighb_disc_15->name_type);
510 if (pad_len > len) {
511 tprintf("Pad Len (%u, invalid)\n%s", pad_len,
512 colorize_start_full(black, red)
513 "Skip Option" colorize_end());
514 pkt_pull(pkt, len);
515 return 1;
517 else
518 tprintf("Pad Len (%u) ", pad_len);
520 name_len = len - pad_len;
522 tprintf("Name (");
523 while (name_len--) {
524 tprintf("%c", *pkt_pull(pkt,1));
526 tprintf(") ");
528 tprintf("Padding (");
530 while (pad_len--) {
531 tprintf("%x", *pkt_pull(pkt,1));
533 tprintf(")");
535 return 1;
538 static char *icmpv6_neighb_disc_ops_16_cert[] = {
539 "X.509v3 Certificate",
542 static inline int8_t dissect_neighb_disc_ops_16(struct pkt_buff *pkt,
543 ssize_t len)
545 struct icmpv6_neighb_disc_ops_type_16 *icmp_neighb_disc_16;
547 icmp_neighb_disc_16 = (struct icmpv6_neighb_disc_ops_type_16 *)
548 pkt_pull(pkt,sizeof(*icmp_neighb_disc_16));
549 if (icmp_neighb_disc_16 == NULL)
550 return 0;
551 len -= sizeof(*icmp_neighb_disc_16);
552 if (len < 0)
553 return 0;
555 tprintf("Cert Type %s (%u) ",
556 icmpv6_code_range_valid(icmp_neighb_disc_16->cert_type - 1,
557 icmpv6_neighb_disc_ops_16_cert) ?
558 icmpv6_neighb_disc_ops_16_cert[
559 icmp_neighb_disc_16->cert_type - 1] : "Unknown",
560 icmp_neighb_disc_16->cert_type);
561 tprintf("Res (0x%x) ", icmp_neighb_disc_16->res);
563 tprintf("Certificate + Padding (");
564 while (len--) {
565 tprintf("%x", *pkt_pull(pkt,1));
567 tprintf(") ");
569 return 1;
572 static char *icmpv6_neighb_disc_ops_17_codes[] = {
573 "Old Care-of Address",
574 "New Care-of Address",
575 "NAR's IP address",
576 "NAR's Prefix",
579 static inline int8_t dissect_neighb_disc_ops_17(struct pkt_buff *pkt,
580 ssize_t len)
582 char address[INET6_ADDRSTRLEN];
583 struct icmpv6_neighb_disc_ops_type_17 *icmp_neighb_disc_17;
585 icmp_neighb_disc_17 = (struct icmpv6_neighb_disc_ops_type_17 *)
586 pkt_pull(pkt,sizeof(*icmp_neighb_disc_17));
587 if (icmp_neighb_disc_17 == NULL)
588 return 0;
589 len -= sizeof(*icmp_neighb_disc_17);
590 if (len < 0)
591 return 0;
593 tprintf("Opt Code %s (%u) ",
594 icmpv6_code_range_valid(icmp_neighb_disc_17->opt_code - 1,
595 icmpv6_neighb_disc_ops_17_codes) ?
596 icmpv6_neighb_disc_ops_17_codes[
597 icmp_neighb_disc_17->opt_code - 1] : "Unknown",
598 icmp_neighb_disc_17->opt_code);
599 tprintf("Prefix Len (%u) ", icmp_neighb_disc_17->prefix_len);
601 if (len == sizeof(struct icmpv6_neighb_disc_ops_type_17_1)) {
602 struct icmpv6_neighb_disc_ops_type_17_1
603 *icmp_neighb_disc_17_1;
605 icmp_neighb_disc_17_1 =
606 (struct icmpv6_neighb_disc_ops_type_17_1 *)
607 pkt_pull(pkt,sizeof(*icmp_neighb_disc_17_1));
608 if (icmp_neighb_disc_17_1 == NULL)
609 return 0;
610 len -= sizeof(*icmp_neighb_disc_17_1);
611 if (len < 0)
612 return 0;
614 tprintf("Res (0x%x) ",icmp_neighb_disc_17_1->res);
615 tprintf("Addr: %s ",
616 inet_ntop(AF_INET6,&icmp_neighb_disc_17_1->ipv6_addr,
617 address, sizeof(address)));
619 else if (len == sizeof(struct icmpv6_neighb_disc_ops_type_17_2)) {
620 struct icmpv6_neighb_disc_ops_type_17_2
621 *icmp_neighb_disc_17_2;
623 icmp_neighb_disc_17_2 =
624 (struct icmpv6_neighb_disc_ops_type_17_2 *)
625 pkt_pull(pkt,sizeof(*icmp_neighb_disc_17_2));
626 if (icmp_neighb_disc_17_2 == NULL)
627 return 0;
628 len -= sizeof(*icmp_neighb_disc_17_2);
629 if (len < 0)
630 return 0;
632 tprintf("Addr: %s ",
633 inet_ntop(AF_INET6,&icmp_neighb_disc_17_2->ipv6_addr,
634 address, sizeof(address)));
636 else {
637 tprintf("%s (", colorize_start_full(black, red)
638 "Error Wrong Length. Skip Option" colorize_end());
639 while (len--) {
640 tprintf("%x", *pkt_pull(pkt,1));
642 tprintf(") ");
645 return 1;
648 static char *icmpv6_neighb_disc_ops_19_codes[] = {
649 "Wildcard requesting resolution for all nearby access points",
650 "Link-Layer Address of the New Access Point",
651 "Link-Layer Address of the MN",
652 "Link-Layer Address of the NAR",
653 "Link-Layer Address of the source of RtSolPr or PrRtAdv \
654 message",
655 "The access point identified by the LLA belongs to the \
656 current interface of the router",
657 "No prefix information available for the access point \
658 identified by the LLA",
659 "No fast handover support available for the access point \
660 identified by the LLA",
663 static inline int8_t dissect_neighb_disc_ops_19(struct pkt_buff *pkt,
664 ssize_t len)
666 struct icmpv6_neighb_disc_ops_type_19 *icmp_neighb_disc_19;
668 icmp_neighb_disc_19 = (struct icmpv6_neighb_disc_ops_type_19 *)
669 pkt_pull(pkt,sizeof(*icmp_neighb_disc_19));
670 if (icmp_neighb_disc_19 == NULL)
671 return 0;
672 len -= sizeof(*icmp_neighb_disc_19);
673 if (len < 0)
674 return 0;
676 tprintf("Opt Code %s (%u) ",
677 icmpv6_code_range_valid(icmp_neighb_disc_19->opt_code,
678 icmpv6_neighb_disc_ops_19_codes) ?
679 icmpv6_neighb_disc_ops_19_codes[
680 icmp_neighb_disc_19->opt_code] : "Unknown",
681 icmp_neighb_disc_19->opt_code);
683 tprintf("LLA (");
684 while(len--){
685 tprintf("%x", *pkt_pull(pkt,1));
687 tprintf(") ");
689 return 1;
692 static inline char *icmpv6_neighb_disc_ops(uint8_t code) {
693 switch (code) {
694 case 1:
695 return "Source Link-Layer Address";
696 case 2:
697 return "Target Link-Layer Address";
698 case 3:
699 return "Prefix Information";
700 case 4:
701 return "Redirected Header";
702 case 5:
703 return "MTU";
704 case 6:
705 return "NBMA Shortcut Limit Option";
706 case 7:
707 return "Advertisement Interval Option";
708 case 8:
709 return "Home Agent Information Option";
710 case 9:
711 return "Source Address List";
712 case 10:
713 return "Target Address List";
714 case 11:
715 return "CGA option";
716 case 12:
717 return "RSA Signature option";
718 case 13:
719 return "Timestamp option";
720 case 14:
721 return "Nonce option";
722 case 15:
723 return "Trust Anchor option";
724 case 16:
725 return "Certificate option";
726 case 17:
727 return "IP Address/Prefix Option";
728 case 18:
729 return "New Router Prefix Information Option";
730 case 19:
731 return "Link-layer Address Option";
732 case 20:
733 return "Neighbor Advertisement Acknowledgment Option";
735 case 23:
736 return "Prefix Information";
737 case 24:
738 return "Redirected Header";
739 case 25:
740 return "MTU";
741 case 26:
742 return "NBMA Shortcut Limit Option";
743 case 27:
744 return "Advertisement Interval Option";
745 case 28:
746 return "Home Agent Information Option";
747 case 29:
748 return "Source Address List";
749 case 30:
750 return "Target Address List";
751 case 31:
752 return "DNS Search List Option";
753 case 32:
754 return "Proxy Signature (PS)";
756 case 138:
757 return "CARD Request option";
758 case 139:
759 return "CARD Reply option";
761 case 253:
762 return "RFC3692-style Experiment 1";
763 case 254:
764 return "RFC3692-style Experiment 2";
767 return NULL;
770 static inline int8_t dissect_neighb_disc_ops(struct pkt_buff *pkt)
772 size_t pad_bytes;
773 uint16_t ops_total_len;
774 ssize_t ops_payl_len;
775 struct icmpv6_neighb_disc_ops_general *icmp_neighb_disc;
777 while(pkt_len(pkt)) {
778 icmp_neighb_disc = (struct icmpv6_neighb_disc_ops_general *)
779 pkt_pull(pkt,sizeof(*icmp_neighb_disc));
780 if (icmp_neighb_disc == NULL)
781 return 0;
783 ops_total_len = icmp_neighb_disc->len * 8;
784 pad_bytes = (size_t) (ops_total_len % 8);
785 ops_payl_len = ops_total_len - sizeof(*icmp_neighb_disc) -
786 pad_bytes;
788 tprintf("\n\tOption %s (%u) ",
789 icmpv6_neighb_disc_ops(icmp_neighb_disc->type) ?
790 icmpv6_neighb_disc_ops(icmp_neighb_disc->type)
791 : "Type Unknown", icmp_neighb_disc->type);
792 if (ops_payl_len > pkt_len(pkt) || ops_payl_len < 0) {
793 tprintf("Length (%u, %u bytes, %s%s%s) ",
794 icmp_neighb_disc->len,
795 ops_total_len,
796 colorize_start_full(black, red),
797 "invalid", colorize_end());
798 return 0;
801 tprintf("Length (%u, %u bytes) ",icmp_neighb_disc->len,
802 ops_total_len);
804 switch (icmp_neighb_disc->type) {
805 case 1:
806 if (!dissect_neighb_disc_ops_1(pkt, ops_payl_len))
807 return 0;
808 break;
809 case 2:
810 if (!dissect_neighb_disc_ops_2(pkt, ops_payl_len))
811 return 0;
812 break;
813 case 3:
814 if (!dissect_neighb_disc_ops_3(pkt, ops_payl_len))
815 return 0;
816 break;
817 case 4:
818 if (!dissect_neighb_disc_ops_4(pkt, ops_payl_len))
819 return 0;
820 break;
821 case 5:
822 if (!dissect_neighb_disc_ops_5(pkt, ops_payl_len))
823 return 0;
824 break;
825 /* Type 9 and 10 defined in
826 * http://tools.ietf.org/html/rfc3122#section-3.1
828 case 9:
829 if (!dissect_neighb_disc_ops_9(pkt, ops_payl_len))
830 return 0;
831 break;
832 case 10:
833 if (!dissect_neighb_disc_ops_10(pkt, ops_payl_len))
834 return 0;
835 break;
836 /* Type 15 and 16 defined in
837 * http://tools.ietf.org/html/rfc3971#section-6.4.3
838 * http://tools.ietf.org/html/rfc3971#section-6.4.4
840 case 15:
841 if (!dissect_neighb_disc_ops_15(pkt, ops_payl_len))
842 return 0;
843 break;
844 case 16:
845 if (!dissect_neighb_disc_ops_16(pkt, ops_payl_len))
846 return 0;
847 break;
848 /* Type 17 and 19 defined in
849 * http://tools.ietf.org/html/rfc5568#section-6.4
851 case 17:
852 if (!dissect_neighb_disc_ops_17(pkt, ops_payl_len))
853 return 0;
854 break;
855 case 19:
856 if (!dissect_neighb_disc_ops_19(pkt, ops_payl_len))
857 return 0;
858 break;
859 default:
860 pkt_pull(pkt, ops_payl_len);
863 /* Skip Padding Bytes */
864 if (pad_bytes > pkt_len(pkt)) {
865 tprintf(" %s",colorize_start_full(black, red)
866 "Invalid Padding" colorize_end());
867 return 0;
869 pkt_pull(pkt, pad_bytes);
872 return 1;
875 static char *icmpv6_type_1_codes[] = {
876 "No route to destination",
877 "Communication with destination administratively prohibited",
878 "Beyond scope of source address",
879 "Address unreachable",
880 "Port unreachable",
881 "Source address failed ingress/egress policy",
882 "Reject route to destination",
883 "Error in Source Routing Header",
886 static inline int8_t dissect_icmpv6_type1(struct pkt_buff *pkt)
888 struct icmpv6_type_1_3 *icmp_1;
890 icmp_1 = (struct icmpv6_type_1_3 *) pkt_pull(pkt,sizeof(*icmp_1));
891 if (icmp_1 == NULL)
892 return 0;
894 tprintf(", Unused (0x%x)",ntohl(icmp_1->unused));
895 tprintf(" Payload include as much of invoking packet");
897 return 1;
900 static inline int8_t dissect_icmpv6_type2(struct pkt_buff *pkt)
902 struct icmpv6_type_2 *icmp_2;
904 icmp_2 = (struct icmpv6_type_2 *) pkt_pull(pkt,sizeof(*icmp_2));
905 if (icmp_2 == NULL)
906 return 0;
908 tprintf(", MTU (0x%x)",ntohl(icmp_2->MTU));
909 tprintf(" Payload include as much of invoking packet");
911 return 1;
914 static char *icmpv6_type_3_codes[] = {
915 "Hop limit exceeded in transit",
916 "Fragment reassembly time exceeded",
919 static inline int8_t dissect_icmpv6_type3(struct pkt_buff *pkt)
921 struct icmpv6_type_1_3 *icmp_3;
923 icmp_3 = (struct icmpv6_type_1_3 *) pkt_pull(pkt,sizeof(*icmp_3));
924 if (icmp_3 == NULL)
925 return 0;
927 tprintf(", Unused (0x%x)",ntohl(icmp_3->unused));
928 tprintf(" Payload include as much of invoking packet");
930 return 1;
933 static char *icmpv6_type_4_codes[] = {
934 "Erroneous header field encountered",
935 "Unrecognized Next Header type encountered",
936 "Unrecognized IPv6 option encountered",
939 static inline int8_t dissect_icmpv6_type4(struct pkt_buff *pkt)
941 struct icmpv6_type_4 *icmp_4;
943 icmp_4 = (struct icmpv6_type_4 *) pkt_pull(pkt,sizeof(*icmp_4));
944 if (icmp_4 == NULL)
945 return 0;
947 tprintf(", Pointer (0x%x)",ntohl(icmp_4->pointer));
948 tprintf(" Payload include as much of invoking packet");
950 return 1;
953 static inline int8_t dissect_icmpv6_type128(struct pkt_buff *pkt)
955 struct icmpv6_type_128_129 *icmp_128;
957 icmp_128 = (struct icmpv6_type_128_129 *)
958 pkt_pull(pkt,sizeof(*icmp_128));
959 if (icmp_128 == NULL)
960 return 0;
962 tprintf(", ID (0x%x)",ntohs(icmp_128->id));
963 tprintf(", Seq. Nr. (%u)",ntohs(icmp_128->sn));
964 tprintf(" Payload include Data");
966 return 1;
969 static inline int8_t dissect_icmpv6_type129(struct pkt_buff *pkt)
971 struct icmpv6_type_128_129 *icmp_129;
973 icmp_129 = (struct icmpv6_type_128_129 *)
974 pkt_pull(pkt,sizeof(*icmp_129));
975 if (icmp_129 == NULL)
976 return 0;
978 tprintf(", ID (0x%x)",ntohs(icmp_129->id));
979 tprintf(", Seq. Nr. (%u)",ntohs(icmp_129->sn));
980 tprintf(" Payload include Data");
982 return 1;
985 static inline int8_t dissect_icmpv6_type130(struct pkt_buff *pkt)
987 char address[INET6_ADDRSTRLEN];
988 uint16_t nr_src, maxrespdel;
989 uint8_t switch_mldv2 = 0;
990 struct icmpv6_type_130_131_132 *icmp_130;
992 icmp_130 = (struct icmpv6_type_130_131_132 *)
993 pkt_pull(pkt,sizeof(*icmp_130));
994 if (icmp_130 == NULL)
995 return 0;
996 maxrespdel = ntohs(icmp_130->maxrespdel);
998 if(pkt_len(pkt) >= sizeof(struct icmpv6_type_130_mldv2))
999 switch_mldv2 = 1;
1001 if(switch_mldv2)
1002 tprintf(", MLDv2, Max Resp Delay (%ums)", maxrespdel >> 15 ?
1003 (((maxrespdel & 0xFFF) | 0x1000) <<
1004 (((maxrespdel >> 12) & 0x3) + 3)) : maxrespdel);
1005 else
1006 tprintf(", Max Resp Delay (%ums)",maxrespdel);
1007 tprintf(", Res (0x%x)",ntohs(icmp_130->res));
1008 tprintf(", Address: %s",
1009 inet_ntop(AF_INET6, &icmp_130->ipv6_addr,
1010 address, sizeof(address)));
1012 if(switch_mldv2) {
1013 struct icmpv6_type_130_mldv2 *icmp_130_mldv2;
1015 icmp_130_mldv2 = (struct icmpv6_type_130_mldv2 *)
1016 pkt_pull(pkt,sizeof(*icmp_130_mldv2));
1017 if (icmp_130_mldv2 == NULL)
1018 return 0;
1020 nr_src = ntohs(icmp_130_mldv2->nr_src);
1022 tprintf(", Resv (0x%x)",icmp_130_mldv2->resv_S_QRV >> 4);
1023 tprintf(", S (%u)",(icmp_130_mldv2->resv_S_QRV >> 3) & 0x1);
1024 tprintf(", QRV (0x%x)",icmp_130_mldv2->resv_S_QRV & 0x3);
1025 tprintf(", QQIC (%u)",icmp_130_mldv2->QQIC);
1026 tprintf(", Nr Src (0x%x)",nr_src);
1028 return print_ipv6_addr_list(pkt, nr_src);
1031 return 1;
1034 static inline int8_t dissect_icmpv6_type131(struct pkt_buff *pkt)
1036 char address[INET6_ADDRSTRLEN];
1037 struct icmpv6_type_130_131_132 *icmp_131;
1039 icmp_131 = (struct icmpv6_type_130_131_132 *)
1040 pkt_pull(pkt,sizeof(*icmp_131));
1041 if (icmp_131 == NULL)
1042 return 0;
1044 tprintf(", Max Resp Delay (%ums)",ntohs(icmp_131->maxrespdel));
1045 tprintf(", Res (0x%x)",ntohs(icmp_131->res));
1046 tprintf(", Address: %s",
1047 inet_ntop(AF_INET6, &icmp_131->ipv6_addr,
1048 address, sizeof(address)));
1050 return 1;
1053 static inline int8_t dissect_icmpv6_type132(struct pkt_buff *pkt)
1055 return dissect_icmpv6_type131(pkt);
1058 static inline int8_t dissect_icmpv6_type133(struct pkt_buff *pkt)
1060 struct icmpv6_type_133_141_142 *icmp_133;
1062 icmp_133 = (struct icmpv6_type_133_141_142 *)
1063 pkt_pull(pkt,sizeof(*icmp_133));
1064 if (icmp_133 == NULL)
1065 return 0;
1067 tprintf(", Reserved (0x%x)",ntohl(icmp_133->res));
1069 return dissect_neighb_disc_ops(pkt);
1072 static inline int8_t dissect_icmpv6_type134(struct pkt_buff *pkt)
1074 struct icmpv6_type_134 *icmp_134;
1076 icmp_134 = (struct icmpv6_type_134 *)
1077 pkt_pull(pkt,sizeof(*icmp_134));
1078 if (icmp_134 == NULL)
1079 return 0;
1081 tprintf(", Cur Hop Limit (%u)",icmp_134->cur_hop_limit);
1082 tprintf(", M (%u) O (%u)",icmp_134->m_o_res >> 7,
1083 (icmp_134->m_o_res >> 6) & 0x1);
1084 tprintf(", Router Lifetime (%us)",ntohs(icmp_134->router_lifetime));
1085 tprintf(", Reachable Time (%ums)",ntohl(icmp_134->reachable_time));
1086 tprintf(", Retrans Timer (%ums)",ntohl(icmp_134->retrans_timer));
1088 return dissect_neighb_disc_ops(pkt);
1091 static inline int8_t dissect_icmpv6_type135(struct pkt_buff *pkt)
1093 char address[INET6_ADDRSTRLEN];
1094 struct icmpv6_type_135 *icmp_135;
1096 icmp_135 = (struct icmpv6_type_135 *)
1097 pkt_pull(pkt,sizeof(*icmp_135));
1098 if (icmp_135 == NULL)
1099 return 0;
1101 tprintf(", Reserved (0x%x)",ntohl(icmp_135->res));
1102 tprintf(", Target Address: %s",
1103 inet_ntop(AF_INET6, &icmp_135->ipv6_addr,
1104 address, sizeof(address)));
1106 return dissect_neighb_disc_ops(pkt);
1109 static inline int8_t dissect_icmpv6_type136(struct pkt_buff *pkt)
1111 char address[INET6_ADDRSTRLEN];
1112 uint32_t r_s_o_res;
1113 struct icmpv6_type_136 *icmp_136;
1115 icmp_136 = (struct icmpv6_type_136 *)
1116 pkt_pull(pkt,sizeof(*icmp_136));
1117 if (icmp_136 == NULL)
1118 return 0;
1119 r_s_o_res = ntohl(icmp_136->r_s_o_res);
1121 tprintf(", R (%u) S (%u) O (%u) Reserved (0x%x)", r_s_o_res >> 31,
1122 (r_s_o_res >> 30) & 0x1, (r_s_o_res >> 29) & 0x1,
1123 r_s_o_res & 0x1FFFFFFF);
1124 tprintf(", Target Address: %s",
1125 inet_ntop(AF_INET6, &icmp_136->ipv6_addr,
1126 address, sizeof(address)));
1128 return dissect_neighb_disc_ops(pkt);
1131 static inline int8_t dissect_icmpv6_type137(struct pkt_buff *pkt)
1133 char address[INET6_ADDRSTRLEN];
1134 struct icmpv6_type_137 *icmp_137;
1136 icmp_137 = (struct icmpv6_type_137 *)
1137 pkt_pull(pkt,sizeof(*icmp_137));
1138 if (icmp_137 == NULL)
1139 return 0;
1141 tprintf(", Reserved (0x%x)",icmp_137->res);
1142 tprintf(", Target Address: %s",
1143 inet_ntop(AF_INET6, &icmp_137->ipv6_targ_addr,
1144 address, sizeof(address)));
1145 tprintf(", Dest Address: %s",
1146 inet_ntop(AF_INET6, &icmp_137->ipv6_dest_addr,
1147 address, sizeof(address)));
1149 return dissect_neighb_disc_ops(pkt);
1152 static inline void dissect_icmpv6_rr_body(struct pkt_buff *pkt)
1155 * Upgrade Dissector for Message Body
1156 * from http://tools.ietf.org/html/rfc2894#section-3.2
1158 if(pkt_len(pkt))
1159 tprintf(" Message Body recognized");
1162 static inline char *icmpv6_type_138_codes(uint8_t code) {
1163 switch (code) {
1164 case 1:
1165 return "Router Renumbering Command";
1166 case 2:
1167 return "Router Renumbering Result";
1168 case 255:
1169 return "Sequence Number Reset";
1172 return NULL;
1175 static inline int8_t dissect_icmpv6_type138(struct pkt_buff *pkt)
1177 struct icmpv6_type_138 *icmp_138;
1179 icmp_138 = (struct icmpv6_type_138 *)
1180 pkt_pull(pkt,sizeof(*icmp_138));
1181 if (icmp_138 == NULL)
1182 return 0;
1184 tprintf(", Sequence Nr. (%u)",ntohl(icmp_138->seq_nr));
1185 tprintf(", Segment Nr. (%u)",icmp_138->seg_nr);
1186 tprintf(", T (%u) R (%u) A (%u) S (%u) P (%u) Res \
1187 (0x%x) ",icmp_138->flags >> 7, (icmp_138->flags >> 6) & 1,
1188 (icmp_138->flags >> 5) & 1, (icmp_138->flags >> 4) & 1,
1189 (icmp_138->flags >> 3) & 1, icmp_138->flags & 7);
1190 tprintf(", Max Delay (%ums)", ntohs(icmp_138->maxdelay));
1191 tprintf(", Res (0x%x)", ntohl(icmp_138->res));
1193 dissect_icmpv6_rr_body(pkt);
1195 return 1;
1198 static inline void dissect_icmpv6_node_inf_data(struct pkt_buff *pkt)
1201 * Upgrade Dissector for Data field
1202 * http://tools.ietf.org/html/rfc4620#section-4
1204 if(pkt_len(pkt))
1205 tprintf(" Data recognized");
1208 static char *icmpv6_node_inf_qtypes[] = {
1209 "NOOP",
1210 "unused",
1211 "Node Name",
1212 "Node Addresses",
1213 "IPv4 Addresses ",
1216 static char *icmpv6_type_139_codes[] = {
1217 "Data contains IPv6 Address",
1218 "Data contains Name or nothing",
1219 "Data contains IPv4 Address",
1222 static inline int8_t dissect_icmpv6_type139(struct pkt_buff *pkt)
1224 char *qtype_name = "Unknown";
1225 uint16_t qtype_nr;
1226 struct icmpv6_type_139_140 *icmp_139;
1228 icmp_139 = (struct icmpv6_type_139_140 *)
1229 pkt_pull(pkt,sizeof(*icmp_139));
1230 if (icmp_139 == NULL)
1231 return 0;
1233 qtype_nr = ntohs(icmp_139->qtype);
1234 if (icmpv6_code_range_valid(qtype_nr, icmpv6_node_inf_qtypes))
1235 qtype_name = icmpv6_node_inf_qtypes[qtype_nr];
1237 tprintf(", Qtype %s (%u)",qtype_name, qtype_nr);
1238 tprintf(", Flags (0x%x)",ntohs(icmp_139->flags));
1239 tprintf(", Nonce (0x%x)",ntohll(icmp_139->nonce));
1241 dissect_icmpv6_node_inf_data(pkt);
1243 return 1;
1246 static char *icmpv6_type_140_codes[] = {
1247 "Successfull reply",
1248 "Responder refuses answer",
1249 "Qtype is unknown to the Responder",
1252 static inline int8_t dissect_icmpv6_type140(struct pkt_buff *pkt)
1254 return dissect_icmpv6_type139(pkt);
1257 static inline int8_t dissect_icmpv6_type141(struct pkt_buff *pkt)
1259 return dissect_icmpv6_type133(pkt);
1262 static inline int8_t dissect_icmpv6_type142(struct pkt_buff *pkt)
1264 return dissect_icmpv6_type133(pkt);
1267 static inline int8_t dissect_icmpv6_type143(struct pkt_buff *pkt)
1269 uint16_t nr_rec;
1270 struct icmpv6_type_143 *icmp_143;
1272 icmp_143 = (struct icmpv6_type_143 *)
1273 pkt_pull(pkt,sizeof(*icmp_143));
1274 if (icmp_143 == NULL)
1275 return 0;
1276 nr_rec = ntohs(icmp_143->nr_rec);
1278 tprintf(", Res (0x%x)",ntohs(icmp_143->res));
1279 tprintf(", Nr. Mcast Addr Records (%u)",nr_rec);
1281 return dissect_icmpv6_mcast_rec(pkt, nr_rec);
1284 static inline int8_t dissect_icmpv6_type144(struct pkt_buff *pkt)
1286 struct icmpv6_type_144_146 *icmp_144;
1288 icmp_144 = (struct icmpv6_type_144_146 *)
1289 pkt_pull(pkt,sizeof(*icmp_144));
1290 if (icmp_144 == NULL)
1291 return 0;
1293 tprintf(", ID (%u)",ntohs(icmp_144->id));
1294 tprintf(", Res (0x%x)",ntohs(icmp_144->res));
1296 return 1;
1299 static inline int8_t dissect_icmpv6_type145(struct pkt_buff *pkt)
1301 struct icmpv6_type_145 *icmp_145;
1303 icmp_145 = (struct icmpv6_type_145 *)
1304 pkt_pull(pkt,sizeof(*icmp_145));
1305 if (icmp_145 == NULL)
1306 return 0;
1308 tprintf(", ID (%u)",ntohs(icmp_145->id));
1309 tprintf(", Res (0x%x)",ntohs(icmp_145->res));
1311 return print_ipv6_addr_list(pkt, pkt_len(pkt) /
1312 sizeof(struct in6_addr));
1315 static inline int8_t dissect_icmpv6_type146(struct pkt_buff *pkt)
1317 return dissect_icmpv6_type144(pkt);
1320 static inline int8_t dissect_icmpv6_type147(struct pkt_buff *pkt)
1322 uint16_t m_o_res;
1323 struct icmpv6_type_147 *icmp_147;
1325 icmp_147 = (struct icmpv6_type_147 *)
1326 pkt_pull(pkt,sizeof(*icmp_147));
1327 if (icmp_147 == NULL)
1328 return 0;
1329 m_o_res = ntohs(icmp_147->m_o_res);
1331 tprintf(", ID (%u)",ntohs(icmp_147->id));
1332 tprintf(", M (%u) O (%u) Res (0x%x)",m_o_res >> 15,
1333 (m_o_res >> 14) & 1, m_o_res & 0x3FFF);
1335 return dissect_neighb_disc_ops(pkt);
1338 static inline int8_t dissect_icmpv6_type148(struct pkt_buff *pkt)
1340 struct icmpv6_type_148 *icmp_148;
1342 icmp_148 = (struct icmpv6_type_148 *)
1343 pkt_pull(pkt,sizeof(*icmp_148));
1344 if (icmp_148 == NULL)
1345 return 0;
1347 tprintf(", ID (%u)",ntohs(icmp_148->id));
1348 tprintf(", Component (%u)",ntohs(icmp_148->comp));
1350 return dissect_neighb_disc_ops(pkt);
1353 static inline int8_t dissect_icmpv6_type149(struct pkt_buff *pkt)
1355 struct icmpv6_type_149 *icmp_149;
1357 icmp_149 = (struct icmpv6_type_149 *)
1358 pkt_pull(pkt,sizeof(*icmp_149));
1359 if (icmp_149 == NULL)
1360 return 0;
1362 tprintf(", ID (%u)",ntohs(icmp_149->id));
1363 tprintf(", All Components (%u)",ntohs(icmp_149->all_comp));
1364 tprintf(", Component (%u)",ntohs(icmp_149->comp));
1365 tprintf(", Res (0x%x)",ntohs(icmp_149->res));
1367 return dissect_neighb_disc_ops(pkt);
1370 static inline int8_t dissect_icmpv6_type150(struct pkt_buff *pkt)
1372 struct icmpv6_type_150 *icmp_150;
1374 icmp_150 = (struct icmpv6_type_150 *)
1375 pkt_pull(pkt,sizeof(*icmp_150));
1376 if (icmp_150 == NULL)
1377 return 0;
1379 tprintf(", Subtype (%u)",icmp_150->subtype);
1380 tprintf(", Res (0x%x)",icmp_150->res);
1381 tprintf(", Options in Payload");
1383 return 1;
1386 static inline int8_t dissect_icmpv6_type151(struct pkt_buff *pkt)
1388 struct icmpv6_type_151 *icmp_151;
1390 icmp_151 = (struct icmpv6_type_151 *)
1391 pkt_pull(pkt,sizeof(*icmp_151));
1392 if (icmp_151 == NULL)
1393 return 0;
1395 tprintf(", Query Interval (%us)",ntohs(icmp_151->query_intv));
1396 tprintf(", Robustness Variable (%u)",ntohs(icmp_151->rob_var));
1398 return 1;
1401 static inline int8_t dissect_icmpv6_type152(struct pkt_buff *pkt)
1403 struct icmpv6_type_152 *icmp_152;
1405 icmp_152 = (struct icmpv6_type_152 *)
1406 pkt_pull(pkt,sizeof(*icmp_152));
1407 if (icmp_152 == NULL)
1408 return 0;
1410 return 1;
1413 static inline int8_t dissect_icmpv6_type153(struct pkt_buff *pkt)
1415 struct icmpv6_type_153 *icmp_153;
1417 icmp_153 = (struct icmpv6_type_153 *)
1418 pkt_pull(pkt,sizeof(*icmp_153));
1419 if (icmp_153 == NULL)
1420 return 0;
1422 return 1;
1425 static inline int8_t dissect_icmpv6_type154(struct pkt_buff *pkt)
1427 struct icmpv6_type_154 *icmp_154;
1429 icmp_154 = (struct icmpv6_type_154 *)
1430 pkt_pull(pkt,sizeof(*icmp_154));
1431 if (icmp_154 == NULL)
1432 return 0;
1434 tprintf(", Subtype (%u)",icmp_154->subtype);
1435 tprintf(", Res (0x%x)",icmp_154->res);
1436 tprintf(", ID (%u)",ntohs(icmp_154->id));
1438 return dissect_neighb_disc_ops(pkt);
1441 static inline char *icmpv6_type_155_codes(uint8_t code) {
1442 switch (code) {
1443 case 0x00:
1444 return "DODAG Information Solicitation";
1445 case 0x01:
1446 return "DODAG Information Object";
1447 case 0x02:
1448 return "Destination Advertisement Object";
1449 case 0x03:
1450 return "Destination Advertisement Object Acknowledgment";
1451 case 0x80:
1452 return "Secure DODAG Information Solicitation";
1453 case 0x81:
1454 return "Secure DODAG Information Object";
1455 case 0x82:
1456 return "Secure Destination Advertisement Object";
1457 case 0x83:
1458 return "Secure Destination Advertisement Object Acknowledgment";
1459 case 0x8A:
1460 return "Consistency Check";
1463 return NULL;
1466 static inline void icmpv6_process(struct icmpv6_general_hdr *icmp, char **type,
1467 char **code,
1468 int8_t (**optional)(struct pkt_buff *pkt))
1470 *type = "Unknown Type";
1471 *code = "Unknown Code";
1473 switch (icmp->h_type) {
1474 case 1:
1475 *type = "Destination Unreachable";
1476 if (icmpv6_code_range_valid(icmp->h_code, icmpv6_type_1_codes))
1477 *code = icmpv6_type_1_codes[icmp->h_code];
1478 *optional = dissect_icmpv6_type1;
1479 return;
1480 case 2:
1481 *type = "Packet Too Big";
1482 *optional = dissect_icmpv6_type2;
1483 return;
1484 case 3:
1485 *type = "Time Exceeded";
1486 if (icmpv6_code_range_valid(icmp->h_code, icmpv6_type_3_codes))
1487 *code = icmpv6_type_3_codes[icmp->h_code];
1488 *optional = dissect_icmpv6_type3;
1489 return;
1490 case 4:
1491 *type = "Parameter Problem";
1492 if (icmpv6_code_range_valid(icmp->h_code, icmpv6_type_4_codes))
1493 *code = icmpv6_type_4_codes[icmp->h_code];
1494 *optional = dissect_icmpv6_type4;
1495 return;
1496 case 100:
1497 *type = "Private experimation";
1498 return;
1499 case 101:
1500 *type = "Private experimation";
1501 return;
1502 case 127:
1503 *type = "Reserved for expansion of ICMPv6 error messages";
1504 return;
1505 case 128:
1506 *type = "Echo Request";
1507 *optional = dissect_icmpv6_type128;
1508 return;
1509 case 129:
1510 *type = "Echo Reply";
1511 *optional = dissect_icmpv6_type129;
1512 return;
1513 case 130:
1514 *type = "Multicast Listener Query";
1515 *optional = dissect_icmpv6_type130;
1516 return;
1517 case 131:
1518 *type = "Multicast Listener Report";
1519 *optional = dissect_icmpv6_type131;
1520 return;
1521 case 132:
1522 *type = "Multicast Listener Done";
1523 *optional = dissect_icmpv6_type132;
1524 return;
1525 case 133:
1526 *type = "Router Solicitation";
1527 *optional = dissect_icmpv6_type133;
1528 return;
1529 case 134:
1530 *type = "Router Advertisement";
1531 *optional = dissect_icmpv6_type134;
1532 return;
1533 case 135:
1534 *type = "Neighbor Solicitation";
1535 *optional = dissect_icmpv6_type135;
1536 return;
1537 case 136:
1538 *type = "Neighbor Advertisement";
1539 *optional = dissect_icmpv6_type136;
1540 return;
1541 case 137:
1542 *type = "Redirect Message";
1543 *optional = dissect_icmpv6_type137;
1544 return;
1545 case 138:
1546 *type = "Router Renumbering";
1547 if(icmpv6_type_138_codes(icmp->h_code))
1548 *code = icmpv6_type_138_codes(icmp->h_code);
1549 *optional = dissect_icmpv6_type138;
1550 return;
1551 case 139:
1552 *type = "ICMP Node Information Query";
1553 if (icmpv6_code_range_valid(icmp->h_code,
1554 icmpv6_type_139_codes))
1555 *code = icmpv6_type_139_codes[icmp->h_code];
1556 *optional = dissect_icmpv6_type139;
1557 return;
1558 case 140:
1559 *type = "ICMP Node Information Response";
1560 if (icmpv6_code_range_valid(icmp->h_code,
1561 icmpv6_type_140_codes))
1562 *code = icmpv6_type_140_codes[icmp->h_code];
1563 *optional = dissect_icmpv6_type140;
1564 return;
1565 case 141:
1566 *type = "Inverse Neighbor Discovery Solicitation Message";
1567 *optional = dissect_icmpv6_type141;
1568 return;
1569 case 142:
1570 *type = "Inverse Neighbor Discovery Advertisement Message";
1571 *optional = dissect_icmpv6_type142;
1572 return;
1573 case 143:
1574 *type = "Multicast Listener Report v2";
1575 *optional = dissect_icmpv6_type143;
1576 return;
1577 case 144:
1578 *type = "Home Agent Address Discovery Request Message";
1579 *optional = dissect_icmpv6_type144;
1580 return;
1581 case 145:
1582 *type = "Home Agent Address Discovery Reply Message";
1583 *optional = dissect_icmpv6_type145;
1584 return;
1585 case 146:
1586 *type = "Mobile Prefix Solicitation";
1587 *optional = dissect_icmpv6_type146;
1588 return;
1589 case 147:
1590 *type = "Mobile Prefix Advertisement";
1591 *optional = dissect_icmpv6_type147;
1592 return;
1593 case 148:
1594 *type = "Certification Path Solicitation";
1595 *optional = dissect_icmpv6_type148;
1596 return;
1597 case 149:
1598 *type = "Certification Path Advertisement";
1599 *optional = dissect_icmpv6_type149;
1600 return;
1601 case 150:
1602 *type = "ICMP messages utilized by experimental mobility "
1603 "protocols such as Seamoby";
1604 *optional = dissect_icmpv6_type150;
1605 return;
1606 case 151:
1607 *type = "Multicast Router Advertisement";
1608 *code = "Ad. Interval";
1609 *optional = dissect_icmpv6_type151;
1610 return;
1611 case 152:
1612 *type = "Multicast Router Solicitation";
1613 *code = "Reserved";
1614 *optional = dissect_icmpv6_type152;
1615 return;
1616 case 153:
1617 *type = "Multicast Router Termination";
1618 *code = "Reserved";
1619 *optional = dissect_icmpv6_type153;
1620 return;
1621 case 154:
1622 *type = "FMIPv6 Messages";
1623 *optional = dissect_icmpv6_type154;
1624 return;
1625 case 155:
1626 *type = "RPL Control Message";
1627 if(icmpv6_type_155_codes(icmp->h_code))
1628 *code = icmpv6_type_155_codes(icmp->h_code);
1629 return;
1630 case 200:
1631 *type = "Private experimation";
1632 return;
1633 case 201:
1634 *type = "Private experimation";
1635 return;
1636 case 255:
1637 *type = "Reserved for expansion of ICMPv6 error messages";
1638 return;
1642 static inline void icmpv6(struct pkt_buff *pkt)
1644 char *type = NULL, *code = NULL;
1645 int8_t (*optional)(struct pkt_buff *pkt) = NULL;
1646 struct icmpv6_general_hdr *icmp =
1647 (struct icmpv6_general_hdr *) pkt_pull(pkt, sizeof(*icmp));
1649 if (icmp == NULL)
1650 return;
1652 icmpv6_process(icmp, &type, &code, &optional);
1654 tprintf(" [ ICMPv6 ");
1655 tprintf("%s (%u), ", type, icmp->h_type);
1656 tprintf("%s (%u), ", code, icmp->h_code);
1657 tprintf("Chks (0x%x)", ntohs(icmp->h_chksum));
1658 if (optional)
1659 if (!((*optional) (pkt)))
1660 tprintf("\n%s%s%s", colorize_start_full(black, red),
1661 "Failed to dissect Message", colorize_end());
1662 tprintf(" ]\n");
1665 static inline void icmpv6_less(struct pkt_buff *pkt)
1667 struct icmpv6_general_hdr *icmp =
1668 (struct icmpv6_general_hdr *) pkt_pull(pkt, sizeof(*icmp));
1670 if (icmp == NULL)
1671 return;
1673 tprintf(" ICMPv6 Type (%u) Code (%u)", icmp->h_type, icmp->h_code);
1676 struct protocol icmpv6_ops = {
1677 .key = 0x3A,
1678 .print_full = icmpv6,
1679 .print_less = icmpv6_less,
1682 #endif /* PROTO_ICMPV6_H */