bpf: indent one space for better visibility
[netsniff-ng.git] / src / proto_icmpv6.h
blob2ae5432adedbc52fc4b7e77a062e1be1cc62d2d2
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 void 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;
296 tprintf("\n\t Address: %s",
297 inet_ntop(AF_INET6, addr, address,
298 sizeof(address)));
302 static char *icmpv6_mcast_rec_types[] = {
303 "MODE_IS_INCLUDE",
304 "MODE_IS_EXCLUDE",
305 "CHANGE_TO_INCLUDE_MODE",
306 "CHANGE_TO_EXCLUDE_MODE",
307 "ALLOW_NEW_SOURCES",
308 "BLOCK_OLD_SOURCES",
311 static inline void dissect_icmpv6_mcast_rec(struct pkt_buff *pkt,
312 uint16_t nr_rec)
314 uint16_t nr_src, aux_data_len_bytes;
315 struct icmpv6_mldv2_addr_rec *addr_rec;
317 while (nr_rec--) {
318 addr_rec = (struct icmpv6_mldv2_addr_rec *)
319 pkt_pull(pkt,sizeof(*addr_rec));
320 if (addr_rec == NULL)
321 return;
322 aux_data_len_bytes = addr_rec->aux_data_len * 4;
323 nr_src = ntohs(addr_rec->nr_src);
325 tprintf(", Rec Type %s (%u)",
326 icmpv6_code_range_valid(addr_rec->rec_type - 1,
327 icmpv6_mcast_rec_types) ?
328 icmpv6_mcast_rec_types[addr_rec->rec_type - 1]
329 : "Unknown", addr_rec->rec_type);
330 tprintf(", Aux Data Len (%u, %u bytes)",addr_rec->aux_data_len,
331 aux_data_len_bytes);
332 tprintf(", Nr. of Sources (%u)",nr_src);
334 print_ipv6_addr_list(pkt, nr_src);
336 tprintf(", Aux Data: ");
337 while (aux_data_len_bytes--) {
338 tprintf("%x", *pkt_pull(pkt,1));
343 static inline void dissect_neighb_disc_ops_1(struct pkt_buff *pkt,
344 uint16_t len)
346 struct icmpv6_neighb_disc_ops_type_1_2 *icmp_neighb_disc_1;
348 icmp_neighb_disc_1 = (struct icmpv6_neighb_disc_ops_type_1_2 *)
349 pkt_pull(pkt,sizeof(*icmp_neighb_disc_1));
350 if (icmp_neighb_disc_1 == NULL)
351 return;
352 len -= sizeof(*icmp_neighb_disc_1);
354 tprintf("Address 0x");
356 while(len--){
357 tprintf("%x", *pkt_pull(pkt,1));
361 static inline void dissect_neighb_disc_ops_2(struct pkt_buff *pkt,
362 uint16_t len)
364 dissect_neighb_disc_ops_1(pkt, len);
367 static inline void dissect_neighb_disc_ops_3(struct pkt_buff *pkt,
368 uint16_t len)
370 char address[INET6_ADDRSTRLEN];
371 struct icmpv6_neighb_disc_ops_type_3 *icmp_neighb_disc_3;
373 icmp_neighb_disc_3 = (struct icmpv6_neighb_disc_ops_type_3 *)
374 pkt_pull(pkt,sizeof(*icmp_neighb_disc_3));
375 if (icmp_neighb_disc_3 == NULL)
376 return;
377 len -= sizeof(*icmp_neighb_disc_3);
379 tprintf("Prefix Len (%u) ",icmp_neighb_disc_3->prefix_len);
380 tprintf("L (%u) A (%u) Res1 (0x%x) ",icmp_neighb_disc_3->l_a_res1 >> 7,
381 (icmp_neighb_disc_3->l_a_res1 >> 7) & 0x1,
382 icmp_neighb_disc_3->l_a_res1 & 0x3F);
383 tprintf("Valid Lifetime (%us) ",
384 ntohl(icmp_neighb_disc_3->valid_lifetime));
385 tprintf("Preferred Lifetime (%us) ",
386 ntohl(icmp_neighb_disc_3->preferred_lifetime));
387 tprintf("Reserved2 (0x%x) ",
388 ntohl(icmp_neighb_disc_3->res2));
389 tprintf("Prefix: %s ",
390 inet_ntop(AF_INET6,&icmp_neighb_disc_3->prefix,
391 address, sizeof(address)));
394 static inline void dissect_neighb_disc_ops_4(struct pkt_buff *pkt,
395 uint16_t len)
397 struct icmpv6_neighb_disc_ops_type_4 *icmp_neighb_disc_4;
399 icmp_neighb_disc_4 = (struct icmpv6_neighb_disc_ops_type_4 *)
400 pkt_pull(pkt,sizeof(*icmp_neighb_disc_4));
401 if (icmp_neighb_disc_4 == NULL)
402 return;
403 len -= sizeof(*icmp_neighb_disc_4);
405 tprintf("Reserved 1 (0x%x) ", ntohs(icmp_neighb_disc_4->res1));
406 tprintf("Reserved 2 (0x%x) ", ntohl(icmp_neighb_disc_4->res2));
407 tprintf("IP header + data ");
409 while (len--) {
410 tprintf("%x", *pkt_pull(pkt,1));
414 static inline void dissect_neighb_disc_ops_5(struct pkt_buff *pkt,
415 uint16_t len)
417 struct icmpv6_neighb_disc_ops_type_5 *icmp_neighb_disc_5;
419 icmp_neighb_disc_5 = (struct icmpv6_neighb_disc_ops_type_5 *)
420 pkt_pull(pkt,sizeof(*icmp_neighb_disc_5));
421 if (icmp_neighb_disc_5 == NULL)
422 return;
423 len -= sizeof(*icmp_neighb_disc_5);
425 tprintf("Reserved (0x%x) ", ntohs(icmp_neighb_disc_5->res1));
426 tprintf("MTU (%u)", ntohl(icmp_neighb_disc_5->MTU));
429 static inline void dissect_neighb_disc_ops_9(struct pkt_buff *pkt,
430 uint16_t len)
432 struct icmpv6_neighb_disc_ops_type_9_10 *icmp_neighb_disc_9;
434 icmp_neighb_disc_9 = (struct icmpv6_neighb_disc_ops_type_9_10 *)
435 pkt_pull(pkt,sizeof(*icmp_neighb_disc_9));
436 if (icmp_neighb_disc_9 == NULL)
437 return;
438 len -= sizeof(*icmp_neighb_disc_9);
440 tprintf("Reserved 1 (0x%x) ", ntohs(icmp_neighb_disc_9->res1));
441 tprintf("Reserved 2 (0x%x) ", ntohl(icmp_neighb_disc_9->res2));
443 print_ipv6_addr_list(pkt, len / sizeof(struct in6_addr));
446 static inline void dissect_neighb_disc_ops_10(struct pkt_buff *pkt,
447 uint16_t len)
449 dissect_neighb_disc_ops_9(pkt, len);
452 static char *icmpv6_neighb_disc_ops_15_name[] = {
453 "DER Encoded X.501 Name",
454 "FQDN",
457 static inline void dissect_neighb_disc_ops_15(struct pkt_buff *pkt,
458 uint16_t len)
460 size_t pad_len;
461 uint16_t name_len;
462 struct icmpv6_neighb_disc_ops_type_15 *icmp_neighb_disc_15;
464 icmp_neighb_disc_15 = (struct icmpv6_neighb_disc_ops_type_15 *)
465 pkt_pull(pkt,sizeof(*icmp_neighb_disc_15));
466 if (icmp_neighb_disc_15 == NULL)
467 return;
468 len -= sizeof(*icmp_neighb_disc_15);
469 pad_len = icmp_neighb_disc_15->pad_len;
470 name_len = len - pad_len;
472 tprintf("Name Type %s (%u) ",
473 icmpv6_code_range_valid(icmp_neighb_disc_15->name_type - 1,
474 icmpv6_neighb_disc_ops_15_name) ?
475 icmpv6_neighb_disc_ops_15_name[
476 icmp_neighb_disc_15->name_type - 1] : "Unknown",
477 icmp_neighb_disc_15->name_type);
478 tprintf("Pad Len (0x%x) ", icmp_neighb_disc_15->pad_len);
480 tprintf("Name (");
481 while (name_len--) {
482 tprintf("%c", *pkt_pull(pkt,1));
484 tprintf(") ");
486 tprintf("Padding (");
488 while (pad_len--) {
489 tprintf("%x", *pkt_pull(pkt,1));
491 tprintf(")");
494 static char *icmpv6_neighb_disc_ops_16_cert[] = {
495 "X.509v3 Certificate",
498 static inline void dissect_neighb_disc_ops_16(struct pkt_buff *pkt,
499 uint16_t len)
501 struct icmpv6_neighb_disc_ops_type_16 *icmp_neighb_disc_16;
503 icmp_neighb_disc_16 = (struct icmpv6_neighb_disc_ops_type_16 *)
504 pkt_pull(pkt,sizeof(*icmp_neighb_disc_16));
505 if (icmp_neighb_disc_16 == NULL)
506 return;
507 len -= sizeof(*icmp_neighb_disc_16);
509 tprintf("Cert Type %s (%u) ",
510 icmpv6_code_range_valid(icmp_neighb_disc_16->cert_type - 1,
511 icmpv6_neighb_disc_ops_16_cert) ?
512 icmpv6_neighb_disc_ops_16_cert[
513 icmp_neighb_disc_16->cert_type - 1] : "Unknown",
514 icmp_neighb_disc_16->cert_type);
515 tprintf("Res (0x%x) ", icmp_neighb_disc_16->res);
517 tprintf("Certificate + Padding (");
518 while (len--) {
519 tprintf("%x", *pkt_pull(pkt,1));
521 tprintf(") ");
524 static char *icmpv6_neighb_disc_ops_17_codes[] = {
525 "Old Care-of Address",
526 "New Care-of Address",
527 "NAR's IP address",
528 "NAR's Prefix",
531 static inline void dissect_neighb_disc_ops_17(struct pkt_buff *pkt,
532 uint16_t len)
534 char address[INET6_ADDRSTRLEN];
535 struct icmpv6_neighb_disc_ops_type_17 *icmp_neighb_disc_17;
537 icmp_neighb_disc_17 = (struct icmpv6_neighb_disc_ops_type_17 *)
538 pkt_pull(pkt,sizeof(*icmp_neighb_disc_17));
539 if (icmp_neighb_disc_17 == NULL)
540 return;
541 len -= sizeof(*icmp_neighb_disc_17);
543 tprintf("Opt Code %s (%u) ",
544 icmpv6_code_range_valid(icmp_neighb_disc_17->opt_code - 1,
545 icmpv6_neighb_disc_ops_17_codes) ?
546 icmpv6_neighb_disc_ops_17_codes[
547 icmp_neighb_disc_17->opt_code - 1] : "Unknown",
548 icmp_neighb_disc_17->opt_code);
549 tprintf("Prefix Len (%u) ", icmp_neighb_disc_17->prefix_len);
551 if (len == sizeof(struct icmpv6_neighb_disc_ops_type_17_1)) {
552 struct icmpv6_neighb_disc_ops_type_17_1
553 *icmp_neighb_disc_17_1;
555 icmp_neighb_disc_17_1 =
556 (struct icmpv6_neighb_disc_ops_type_17_1 *)
557 pkt_pull(pkt,sizeof(*icmp_neighb_disc_17_1));
558 if (icmp_neighb_disc_17_1 == NULL)
559 return;
560 len -= sizeof(*icmp_neighb_disc_17_1);
562 tprintf("Res (0x%x) ",icmp_neighb_disc_17_1->res);
563 tprintf("Addr: %s ",
564 inet_ntop(AF_INET6,&icmp_neighb_disc_17_1->ipv6_addr,
565 address, sizeof(address)));
567 else if (len == sizeof(struct icmpv6_neighb_disc_ops_type_17_2)) {
568 struct icmpv6_neighb_disc_ops_type_17_2
569 *icmp_neighb_disc_17_2;
571 icmp_neighb_disc_17_2 =
572 (struct icmpv6_neighb_disc_ops_type_17_2 *)
573 pkt_pull(pkt,sizeof(*icmp_neighb_disc_17_2));
574 if (icmp_neighb_disc_17_2 == NULL)
575 return;
576 len -= sizeof(*icmp_neighb_disc_17_2);
578 tprintf("Addr: %s ",
579 inet_ntop(AF_INET6,&icmp_neighb_disc_17_2->ipv6_addr,
580 address, sizeof(address)));
582 else {
583 tprintf("Error Wrong Params (");
584 while (len--) {
585 tprintf("%x", *pkt_pull(pkt,1));
587 tprintf(") ");
591 static char *icmpv6_neighb_disc_ops_19_codes[] = {
592 "Wildcard requesting resolution for all nearby access points",
593 "Link-Layer Address of the New Access Point",
594 "Link-Layer Address of the MN",
595 "Link-Layer Address of the NAR",
596 "Link-Layer Address of the source of RtSolPr or PrRtAdv \
597 message",
598 "The access point identified by the LLA belongs to the \
599 current interface of the router",
600 "No prefix information available for the access point \
601 identified by the LLA",
602 "No fast handover support available for the access point \
603 identified by the LLA",
606 static inline void dissect_neighb_disc_ops_19(struct pkt_buff *pkt,
607 uint16_t len)
609 struct icmpv6_neighb_disc_ops_type_19 *icmp_neighb_disc_19;
611 icmp_neighb_disc_19 = (struct icmpv6_neighb_disc_ops_type_19 *)
612 pkt_pull(pkt,sizeof(*icmp_neighb_disc_19));
613 if (icmp_neighb_disc_19 == NULL)
614 return;
615 len -= sizeof(*icmp_neighb_disc_19);
617 tprintf("Opt Code %s (%u) ",
618 icmpv6_code_range_valid(icmp_neighb_disc_19->opt_code,
619 icmpv6_neighb_disc_ops_19_codes) ?
620 icmpv6_neighb_disc_ops_19_codes[
621 icmp_neighb_disc_19->opt_code] : "Unknown",
622 icmp_neighb_disc_19->opt_code);
624 tprintf("LLA (");
625 while(len--){
626 tprintf("%x", *pkt_pull(pkt,1));
628 tprintf(") ");
631 static inline char *icmpv6_neighb_disc_ops(uint8_t code) {
632 switch (code) {
633 case 1:
634 return "Source Link-Layer Address";
635 case 2:
636 return "Target Link-Layer Address";
637 case 3:
638 return "Prefix Information";
639 case 4:
640 return "Redirected Header";
641 case 5:
642 return "MTU";
643 case 6:
644 return "NBMA Shortcut Limit Option";
645 case 7:
646 return "Advertisement Interval Option";
647 case 8:
648 return "Home Agent Information Option";
649 case 9:
650 return "Source Address List";
651 case 10:
652 return "Target Address List";
653 case 11:
654 return "CGA option";
655 case 12:
656 return "RSA Signature option";
657 case 13:
658 return "Timestamp option";
659 case 14:
660 return "Nonce option";
661 case 15:
662 return "Trust Anchor option";
663 case 16:
664 return "Certificate option";
665 case 17:
666 return "IP Address/Prefix Option";
667 case 18:
668 return "New Router Prefix Information Option";
669 case 19:
670 return "Link-layer Address Option";
671 case 20:
672 return "Neighbor Advertisement Acknowledgment Option";
674 case 23:
675 return "Prefix Information";
676 case 24:
677 return "Redirected Header";
678 case 25:
679 return "MTU";
680 case 26:
681 return "NBMA Shortcut Limit Option";
682 case 27:
683 return "Advertisement Interval Option";
684 case 28:
685 return "Home Agent Information Option";
686 case 29:
687 return "Source Address List";
688 case 30:
689 return "Target Address List";
690 case 31:
691 return "DNS Search List Option";
692 case 32:
693 return "Proxy Signature (PS)";
695 case 138:
696 return "CARD Request option";
697 case 139:
698 return "CARD Reply option";
700 case 253:
701 return "RFC3692-style Experiment 1";
702 case 254:
703 return "RFC3692-style Experiment 2";
706 return NULL;
709 static inline void dissect_neighb_disc_ops(struct pkt_buff *pkt)
711 size_t pad_bytes;
712 uint16_t ops_total_len, ops_payl_len;
713 struct icmpv6_neighb_disc_ops_general *icmp_neighb_disc;
715 while(pkt_len(pkt)) {
716 icmp_neighb_disc = (struct icmpv6_neighb_disc_ops_general *)
717 pkt_pull(pkt,sizeof(*icmp_neighb_disc));
718 if (icmp_neighb_disc == NULL)
719 return;
721 ops_total_len = icmp_neighb_disc->len * 8;
722 pad_bytes = (size_t) (ops_total_len % 8);
723 ops_payl_len = ops_total_len - sizeof(*icmp_neighb_disc) -
724 pad_bytes;
726 tprintf("\n\tOption %s (%u) ",
727 icmpv6_neighb_disc_ops(icmp_neighb_disc->type) ?
728 icmpv6_neighb_disc_ops(icmp_neighb_disc->type)
729 : "Type Unknown", icmp_neighb_disc->type);
730 tprintf("Length (%u, %u bytes) ", icmp_neighb_disc->len,
731 ops_total_len);
733 switch (icmp_neighb_disc->type) {
734 case 1:
735 dissect_neighb_disc_ops_1(pkt, ops_payl_len);
736 break;
737 case 2:
738 dissect_neighb_disc_ops_2(pkt, ops_payl_len);
739 break;
740 case 3:
741 dissect_neighb_disc_ops_3(pkt, ops_payl_len);
742 break;
743 case 4:
744 dissect_neighb_disc_ops_4(pkt, ops_payl_len);
745 break;
746 case 5:
747 dissect_neighb_disc_ops_5(pkt, ops_payl_len);
748 break;
749 /* Type 9 and 10 defined in
750 * http://tools.ietf.org/html/rfc3122#section-3.1
752 case 9:
753 dissect_neighb_disc_ops_9(pkt, ops_payl_len);
754 break;
755 case 10:
756 dissect_neighb_disc_ops_10(pkt, ops_payl_len);
757 break;
758 /* Type 15 and 16 defined in
759 * http://tools.ietf.org/html/rfc3971#section-6.4.3
760 * http://tools.ietf.org/html/rfc3971#section-6.4.4
762 case 15:
763 dissect_neighb_disc_ops_15(pkt, ops_payl_len);
764 break;
765 case 16:
766 dissect_neighb_disc_ops_16(pkt, ops_payl_len);
767 break;
768 /* Type 17 and 19 defined in
769 * http://tools.ietf.org/html/rfc5568#section-6.4
771 case 17:
772 dissect_neighb_disc_ops_17(pkt, ops_payl_len);
773 break;
774 case 19:
775 dissect_neighb_disc_ops_19(pkt, ops_payl_len);
776 break;
777 default:
778 pkt_pull(pkt, ops_payl_len);
781 /* Skip Padding Bytes */
782 pkt_pull(pkt, pad_bytes);
786 static char *icmpv6_type_1_codes[] = {
787 "No route to destination",
788 "Communication with destination administratively prohibited",
789 "Beyond scope of source address",
790 "Address unreachable",
791 "Port unreachable",
792 "Source address failed ingress/egress policy",
793 "Reject route to destination",
794 "Error in Source Routing Header",
797 static inline void dissect_icmpv6_type1(struct pkt_buff *pkt)
799 struct icmpv6_type_1_3 *icmp_1;
801 icmp_1 = (struct icmpv6_type_1_3 *) pkt_pull(pkt,sizeof(*icmp_1));
802 if (icmp_1 == NULL)
803 return;
805 tprintf(", Unused (0x%x)",ntohl(icmp_1->unused));
806 tprintf(" Payload include as much of invoking packet");
809 static inline void dissect_icmpv6_type2(struct pkt_buff *pkt)
811 struct icmpv6_type_2 *icmp_2;
813 icmp_2 = (struct icmpv6_type_2 *) pkt_pull(pkt,sizeof(*icmp_2));
814 if (icmp_2 == NULL)
815 return;
817 tprintf(", MTU (0x%x)",ntohl(icmp_2->MTU));
818 tprintf(" Payload include as much of invoking packet");
821 static char *icmpv6_type_3_codes[] = {
822 "Hop limit exceeded in transit",
823 "Fragment reassembly time exceeded",
826 static inline void dissect_icmpv6_type3(struct pkt_buff *pkt)
828 struct icmpv6_type_1_3 *icmp_3;
830 icmp_3 = (struct icmpv6_type_1_3 *) pkt_pull(pkt,sizeof(*icmp_3));
831 if (icmp_3 == NULL)
832 return;
834 tprintf(", Unused (0x%x)",ntohl(icmp_3->unused));
835 tprintf(" Payload include as much of invoking packet");
838 static char *icmpv6_type_4_codes[] = {
839 "Erroneous header field encountered",
840 "Unrecognized Next Header type encountered",
841 "Unrecognized IPv6 option encountered",
844 static inline void dissect_icmpv6_type4(struct pkt_buff *pkt)
846 struct icmpv6_type_4 *icmp_4;
848 icmp_4 = (struct icmpv6_type_4 *) pkt_pull(pkt,sizeof(*icmp_4));
849 if (icmp_4 == NULL)
850 return;
852 tprintf(", Pointer (0x%x)",ntohl(icmp_4->pointer));
853 tprintf(" Payload include as much of invoking packet");
856 static inline void dissect_icmpv6_type128(struct pkt_buff *pkt)
858 struct icmpv6_type_128_129 *icmp_128;
860 icmp_128 = (struct icmpv6_type_128_129 *)
861 pkt_pull(pkt,sizeof(*icmp_128));
862 if (icmp_128 == NULL)
863 return;
865 tprintf(", ID (0x%x)",ntohs(icmp_128->id));
866 tprintf(", Seq. Nr. (%u)",ntohs(icmp_128->sn));
867 tprintf(" Payload include Data");
870 static inline void dissect_icmpv6_type129(struct pkt_buff *pkt)
872 struct icmpv6_type_128_129 *icmp_129;
874 icmp_129 = (struct icmpv6_type_128_129 *)
875 pkt_pull(pkt,sizeof(*icmp_129));
876 if (icmp_129 == NULL)
877 return;
879 tprintf(", ID (0x%x)",ntohs(icmp_129->id));
880 tprintf(", Seq. Nr. (%u)",ntohs(icmp_129->sn));
881 tprintf(" Payload include Data");
884 static inline void dissect_icmpv6_type130(struct pkt_buff *pkt)
886 char address[INET6_ADDRSTRLEN];
887 uint16_t nr_src, maxrespdel;
888 uint8_t switch_mldv2 = 0;
889 struct icmpv6_type_130_131_132 *icmp_130;
891 icmp_130 = (struct icmpv6_type_130_131_132 *)
892 pkt_pull(pkt,sizeof(*icmp_130));
893 if (icmp_130 == NULL)
894 return;
895 maxrespdel = ntohs(icmp_130->maxrespdel);
897 if(pkt_len(pkt) >= sizeof(struct icmpv6_type_130_mldv2))
898 switch_mldv2 = 1;
900 if(switch_mldv2)
901 tprintf(", MLDv2, Max Resp Delay (%ums)", maxrespdel >> 15 ?
902 (((maxrespdel & 0xFFF) | 0x1000) <<
903 (((maxrespdel >> 12) & 0x3) + 3)) : maxrespdel);
904 else
905 tprintf(", Max Resp Delay (%ums)",maxrespdel);
906 tprintf(", Res (0x%x)",ntohs(icmp_130->res));
907 tprintf(", Address: %s",
908 inet_ntop(AF_INET6, &icmp_130->ipv6_addr,
909 address, sizeof(address)));
911 if(switch_mldv2) {
912 struct icmpv6_type_130_mldv2 *icmp_130_mldv2;
914 icmp_130_mldv2 = (struct icmpv6_type_130_mldv2 *)
915 pkt_pull(pkt,sizeof(*icmp_130_mldv2));
916 if (icmp_130_mldv2 == NULL)
917 return;
919 nr_src = ntohs(icmp_130_mldv2->nr_src);
921 tprintf(", Resv (0x%x)",icmp_130_mldv2->resv_S_QRV >> 4);
922 tprintf(", S (%u)",(icmp_130_mldv2->resv_S_QRV >> 3) & 0x1);
923 tprintf(", QRV (0x%x)",icmp_130_mldv2->resv_S_QRV & 0x3);
924 tprintf(", QQIC (%u)",icmp_130_mldv2->QQIC);
925 tprintf(", Nr Src (0x%x)",nr_src);
927 print_ipv6_addr_list(pkt, nr_src);
931 static inline void dissect_icmpv6_type131(struct pkt_buff *pkt)
933 char address[INET6_ADDRSTRLEN];
934 struct icmpv6_type_130_131_132 *icmp_131;
936 icmp_131 = (struct icmpv6_type_130_131_132 *)
937 pkt_pull(pkt,sizeof(*icmp_131));
938 if (icmp_131 == NULL)
939 return;
941 tprintf(", Max Resp Delay (%ums)",ntohs(icmp_131->maxrespdel));
942 tprintf(", Res (0x%x)",ntohs(icmp_131->res));
943 tprintf(", Address: %s",
944 inet_ntop(AF_INET6, &icmp_131->ipv6_addr,
945 address, sizeof(address)));
948 static inline void dissect_icmpv6_type132(struct pkt_buff *pkt)
950 dissect_icmpv6_type131(pkt);
953 static inline void dissect_icmpv6_type133(struct pkt_buff *pkt)
955 struct icmpv6_type_133_141_142 *icmp_133;
957 icmp_133 = (struct icmpv6_type_133_141_142 *)
958 pkt_pull(pkt,sizeof(*icmp_133));
959 if (icmp_133 == NULL)
960 return;
962 tprintf(", Reserved (0x%x)",ntohl(icmp_133->res));
964 dissect_neighb_disc_ops(pkt);
967 static inline void dissect_icmpv6_type134(struct pkt_buff *pkt)
969 struct icmpv6_type_134 *icmp_134;
971 icmp_134 = (struct icmpv6_type_134 *)
972 pkt_pull(pkt,sizeof(*icmp_134));
973 if (icmp_134 == NULL)
974 return;
976 tprintf(", Cur Hop Limit (%u)",icmp_134->cur_hop_limit);
977 tprintf(", M (%u) O (%u)",icmp_134->m_o_res >> 7,
978 (icmp_134->m_o_res >> 6) & 0x1);
979 tprintf(", Router Lifetime (%us)",ntohs(icmp_134->router_lifetime));
980 tprintf(", Reachable Time (%ums)",ntohl(icmp_134->reachable_time));
981 tprintf(", Retrans Timer (%ums)",ntohl(icmp_134->retrans_timer));
983 dissect_neighb_disc_ops(pkt);
986 static inline void dissect_icmpv6_type135(struct pkt_buff *pkt)
988 char address[INET6_ADDRSTRLEN];
989 struct icmpv6_type_135 *icmp_135;
991 icmp_135 = (struct icmpv6_type_135 *)
992 pkt_pull(pkt,sizeof(*icmp_135));
993 if (icmp_135 == NULL)
994 return;
996 tprintf(", Reserved (0x%x)",ntohl(icmp_135->res));
997 tprintf(", Target Address: %s",
998 inet_ntop(AF_INET6, &icmp_135->ipv6_addr,
999 address, sizeof(address)));
1001 dissect_neighb_disc_ops(pkt);
1004 static inline void dissect_icmpv6_type136(struct pkt_buff *pkt)
1006 char address[INET6_ADDRSTRLEN];
1007 uint32_t r_s_o_res;
1008 struct icmpv6_type_136 *icmp_136;
1010 icmp_136 = (struct icmpv6_type_136 *)
1011 pkt_pull(pkt,sizeof(*icmp_136));
1012 if (icmp_136 == NULL)
1013 return;
1014 r_s_o_res = ntohl(icmp_136->r_s_o_res);
1016 tprintf(", R (%u) S (%u) O (%u) Reserved (0x%x)", r_s_o_res >> 31,
1017 (r_s_o_res >> 30) & 0x1, (r_s_o_res >> 29) & 0x1,
1018 r_s_o_res & 0x1FFFFFFF);
1019 tprintf(", Target Address: %s",
1020 inet_ntop(AF_INET6, &icmp_136->ipv6_addr,
1021 address, sizeof(address)));
1023 dissect_neighb_disc_ops(pkt);
1026 static inline void dissect_icmpv6_type137(struct pkt_buff *pkt)
1028 char address[INET6_ADDRSTRLEN];
1029 struct icmpv6_type_137 *icmp_137;
1031 icmp_137 = (struct icmpv6_type_137 *)
1032 pkt_pull(pkt,sizeof(*icmp_137));
1033 if (icmp_137 == NULL)
1034 return;
1036 tprintf(", Reserved (0x%x)",icmp_137->res);
1037 tprintf(", Target Address: %s",
1038 inet_ntop(AF_INET6, &icmp_137->ipv6_targ_addr,
1039 address, sizeof(address)));
1040 tprintf(", Dest Address: %s",
1041 inet_ntop(AF_INET6, &icmp_137->ipv6_dest_addr,
1042 address, sizeof(address)));
1044 dissect_neighb_disc_ops(pkt);
1047 static inline void dissect_icmpv6_rr_body(struct pkt_buff *pkt)
1050 * Upgrade Dissector for Message Body
1051 * from http://tools.ietf.org/html/rfc2894#section-3.2
1053 if(pkt_len(pkt))
1054 tprintf(" Message Body recognized");
1057 static inline char *icmpv6_type_138_codes(uint8_t code) {
1058 switch (code) {
1059 case 1:
1060 return "Router Renumbering Command";
1061 case 2:
1062 return "Router Renumbering Result";
1063 case 255:
1064 return "Sequence Number Reset";
1067 return NULL;
1070 static inline void dissect_icmpv6_type138(struct pkt_buff *pkt)
1072 struct icmpv6_type_138 *icmp_138;
1074 icmp_138 = (struct icmpv6_type_138 *)
1075 pkt_pull(pkt,sizeof(*icmp_138));
1076 if (icmp_138 == NULL)
1077 return;
1079 tprintf(", Sequence Nr. (%u)",ntohl(icmp_138->seq_nr));
1080 tprintf(", Segment Nr. (%u)",icmp_138->seg_nr);
1081 tprintf(", T (%u) R (%u) A (%u) S (%u) P (%u) Res \
1082 (0x%x) ",icmp_138->flags >> 7, (icmp_138->flags >> 6) & 1,
1083 (icmp_138->flags >> 5) & 1, (icmp_138->flags >> 4) & 1,
1084 (icmp_138->flags >> 3) & 1, icmp_138->flags & 7);
1085 tprintf(", Max Delay (%ums)", ntohs(icmp_138->maxdelay));
1086 tprintf(", Res (0x%x)", ntohl(icmp_138->res));
1088 dissect_icmpv6_rr_body(pkt);
1091 static inline void dissect_icmpv6_node_inf_data(struct pkt_buff *pkt)
1094 * Upgrade Dissector for Data field
1095 * http://tools.ietf.org/html/rfc4620#section-4
1097 if(pkt_len(pkt))
1098 tprintf(" Data recognized");
1101 static char *icmpv6_node_inf_qtypes[] = {
1102 "NOOP",
1103 "unused",
1104 "Node Name",
1105 "Node Addresses",
1106 "IPv4 Addresses ",
1109 static char *icmpv6_type_139_codes[] = {
1110 "Data contains IPv6 Address",
1111 "Data contains Name or nothing",
1112 "Data contains IPv4 Address",
1115 static inline void dissect_icmpv6_type139(struct pkt_buff *pkt)
1117 char *qtype_name = "Unknown";
1118 uint16_t qtype_nr;
1119 struct icmpv6_type_139_140 *icmp_139;
1121 icmp_139 = (struct icmpv6_type_139_140 *)
1122 pkt_pull(pkt,sizeof(*icmp_139));
1123 if (icmp_139 == NULL)
1124 return;
1126 qtype_nr = ntohs(icmp_139->qtype);
1127 if (icmpv6_code_range_valid(qtype_nr, icmpv6_node_inf_qtypes))
1128 qtype_name = icmpv6_node_inf_qtypes[qtype_nr];
1130 tprintf(", Qtype %s (%u)",qtype_name, qtype_nr);
1131 tprintf(", Flags (0x%x)",ntohs(icmp_139->flags));
1132 tprintf(", Nonce (0x%x)",ntohll(icmp_139->nonce));
1134 dissect_icmpv6_node_inf_data(pkt);
1137 static char *icmpv6_type_140_codes[] = {
1138 "Successfull reply",
1139 "Responder refuses answer",
1140 "Qtype is unknown to the Responder",
1143 static inline void dissect_icmpv6_type140(struct pkt_buff *pkt)
1145 dissect_icmpv6_type139(pkt);
1148 static inline void dissect_icmpv6_type141(struct pkt_buff *pkt)
1150 dissect_icmpv6_type133(pkt);
1153 static inline void dissect_icmpv6_type142(struct pkt_buff *pkt)
1155 dissect_icmpv6_type133(pkt);
1158 static inline void dissect_icmpv6_type143(struct pkt_buff *pkt)
1160 uint16_t nr_rec;
1161 struct icmpv6_type_143 *icmp_143;
1163 icmp_143 = (struct icmpv6_type_143 *)
1164 pkt_pull(pkt,sizeof(*icmp_143));
1165 if (icmp_143 == NULL)
1166 return;
1167 nr_rec = ntohs(icmp_143->nr_rec);
1169 tprintf(", Res (0x%x)",ntohs(icmp_143->res));
1170 tprintf(", Nr. Mcast Addr Records (%u)",nr_rec);
1172 dissect_icmpv6_mcast_rec(pkt, nr_rec);
1175 static inline void dissect_icmpv6_type144(struct pkt_buff *pkt)
1177 struct icmpv6_type_144_146 *icmp_144;
1179 icmp_144 = (struct icmpv6_type_144_146 *)
1180 pkt_pull(pkt,sizeof(*icmp_144));
1181 if (icmp_144 == NULL)
1182 return;
1184 tprintf(", ID (%u)",ntohs(icmp_144->id));
1185 tprintf(", Res (0x%x)",ntohs(icmp_144->res));
1188 static inline void dissect_icmpv6_type145(struct pkt_buff *pkt)
1190 struct icmpv6_type_145 *icmp_145;
1192 icmp_145 = (struct icmpv6_type_145 *)
1193 pkt_pull(pkt,sizeof(*icmp_145));
1194 if (icmp_145 == NULL)
1195 return;
1197 tprintf(", ID (%u)",ntohs(icmp_145->id));
1198 tprintf(", Res (0x%x)",ntohs(icmp_145->res));
1200 print_ipv6_addr_list(pkt, pkt_len(pkt) / sizeof(struct in6_addr));
1203 static inline void dissect_icmpv6_type146(struct pkt_buff *pkt)
1205 dissect_icmpv6_type144(pkt);
1208 static inline void dissect_icmpv6_type147(struct pkt_buff *pkt)
1210 uint16_t m_o_res;
1211 struct icmpv6_type_147 *icmp_147;
1213 icmp_147 = (struct icmpv6_type_147 *)
1214 pkt_pull(pkt,sizeof(*icmp_147));
1215 if (icmp_147 == NULL)
1216 return;
1217 m_o_res = ntohs(icmp_147->m_o_res);
1219 tprintf(", ID (%u)",ntohs(icmp_147->id));
1220 tprintf(", M (%u) O (%u) Res (0x%x)",m_o_res >> 15,
1221 (m_o_res >> 14) & 1, m_o_res & 0x3FFF);
1223 dissect_neighb_disc_ops(pkt);
1226 static inline void dissect_icmpv6_type148(struct pkt_buff *pkt)
1228 struct icmpv6_type_148 *icmp_148;
1230 icmp_148 = (struct icmpv6_type_148 *)
1231 pkt_pull(pkt,sizeof(*icmp_148));
1232 if (icmp_148 == NULL)
1233 return;
1235 tprintf(", ID (%u)",ntohs(icmp_148->id));
1236 tprintf(", Component (%u)",ntohs(icmp_148->comp));
1238 dissect_neighb_disc_ops(pkt);
1241 static inline void dissect_icmpv6_type149(struct pkt_buff *pkt)
1243 struct icmpv6_type_149 *icmp_149;
1245 icmp_149 = (struct icmpv6_type_149 *)
1246 pkt_pull(pkt,sizeof(*icmp_149));
1247 if (icmp_149 == NULL)
1248 return;
1250 tprintf(", ID (%u)",ntohs(icmp_149->id));
1251 tprintf(", All Components (%u)",ntohs(icmp_149->all_comp));
1252 tprintf(", Component (%u)",ntohs(icmp_149->comp));
1253 tprintf(", Res (0x%x)",ntohs(icmp_149->res));
1255 dissect_neighb_disc_ops(pkt);
1258 static inline void dissect_icmpv6_type150(struct pkt_buff *pkt)
1260 struct icmpv6_type_150 *icmp_150;
1262 icmp_150 = (struct icmpv6_type_150 *)
1263 pkt_pull(pkt,sizeof(*icmp_150));
1264 if (icmp_150 == NULL)
1265 return;
1267 tprintf(", Subtype (%u)",icmp_150->subtype);
1268 tprintf(", Res (0x%x)",icmp_150->res);
1269 tprintf(", Options in Payload");
1272 static inline void dissect_icmpv6_type151(struct pkt_buff *pkt)
1274 struct icmpv6_type_151 *icmp_151;
1276 icmp_151 = (struct icmpv6_type_151 *)
1277 pkt_pull(pkt,sizeof(*icmp_151));
1278 if (icmp_151 == NULL)
1279 return;
1281 tprintf(", Query Interval (%us)",ntohs(icmp_151->query_intv));
1282 tprintf(", Robustness Variable (%u)",ntohs(icmp_151->rob_var));
1285 static inline void dissect_icmpv6_type152(struct pkt_buff *pkt)
1287 struct icmpv6_type_152 *icmp_152;
1289 icmp_152 = (struct icmpv6_type_152 *)
1290 pkt_pull(pkt,sizeof(*icmp_152));
1291 if (icmp_152 == NULL)
1292 return;
1295 static inline void dissect_icmpv6_type153(struct pkt_buff *pkt)
1297 struct icmpv6_type_153 *icmp_153;
1299 icmp_153 = (struct icmpv6_type_153 *)
1300 pkt_pull(pkt,sizeof(*icmp_153));
1301 if (icmp_153 == NULL)
1302 return;
1305 static inline void dissect_icmpv6_type154(struct pkt_buff *pkt)
1307 struct icmpv6_type_154 *icmp_154;
1309 icmp_154 = (struct icmpv6_type_154 *)
1310 pkt_pull(pkt,sizeof(*icmp_154));
1311 if (icmp_154 == NULL)
1312 return;
1314 tprintf(", Subtype (%u)",icmp_154->subtype);
1315 tprintf(", Res (0x%x)",icmp_154->res);
1316 tprintf(", ID (%u)",ntohs(icmp_154->id));
1318 dissect_neighb_disc_ops(pkt);
1321 static inline char *icmpv6_type_155_codes(uint8_t code) {
1322 switch (code) {
1323 case 0x00:
1324 return "DODAG Information Solicitation";
1325 case 0x01:
1326 return "DODAG Information Object";
1327 case 0x02:
1328 return "Destination Advertisement Object";
1329 case 0x03:
1330 return "Destination Advertisement Object Acknowledgment";
1331 case 0x80:
1332 return "Secure DODAG Information Solicitation";
1333 case 0x81:
1334 return "Secure DODAG Information Object";
1335 case 0x82:
1336 return "Secure Destination Advertisement Object";
1337 case 0x83:
1338 return "Secure Destination Advertisement Object Acknowledgment";
1339 case 0x8A:
1340 return "Consistency Check";
1343 return NULL;
1346 static inline void icmpv6_process(struct icmpv6_general_hdr *icmp, char **type,
1347 char **code,
1348 void (**optional)(struct pkt_buff *pkt))
1350 *type = "Unknown Type";
1351 *code = "Unknown Code";
1353 switch (icmp->h_type) {
1354 case 1:
1355 *type = "Destination Unreachable";
1356 if (icmpv6_code_range_valid(icmp->h_code, icmpv6_type_1_codes))
1357 *code = icmpv6_type_1_codes[icmp->h_code];
1358 *optional = dissect_icmpv6_type1;
1359 return;
1360 case 2:
1361 *type = "Packet Too Big";
1362 *optional = dissect_icmpv6_type2;
1363 return;
1364 case 3:
1365 *type = "Time Exceeded";
1366 if (icmpv6_code_range_valid(icmp->h_code, icmpv6_type_3_codes))
1367 *code = icmpv6_type_3_codes[icmp->h_code];
1368 *optional = dissect_icmpv6_type3;
1369 return;
1370 case 4:
1371 *type = "Parameter Problem";
1372 if (icmpv6_code_range_valid(icmp->h_code, icmpv6_type_4_codes))
1373 *code = icmpv6_type_4_codes[icmp->h_code];
1374 *optional = dissect_icmpv6_type4;
1375 return;
1376 case 100:
1377 *type = "Private experimation";
1378 return;
1379 case 101:
1380 *type = "Private experimation";
1381 return;
1382 case 127:
1383 *type = "Reserved for expansion of ICMPv6 error messages";
1384 return;
1385 case 128:
1386 *type = "Echo Request";
1387 *optional = dissect_icmpv6_type128;
1388 return;
1389 case 129:
1390 *type = "Echo Reply";
1391 *optional = dissect_icmpv6_type129;
1392 return;
1393 case 130:
1394 *type = "Multicast Listener Query";
1395 *optional = dissect_icmpv6_type130;
1396 return;
1397 case 131:
1398 *type = "Multicast Listener Report";
1399 *optional = dissect_icmpv6_type131;
1400 return;
1401 case 132:
1402 *type = "Multicast Listener Done";
1403 *optional = dissect_icmpv6_type132;
1404 return;
1405 case 133:
1406 *type = "Router Solicitation";
1407 *optional = dissect_icmpv6_type133;
1408 return;
1409 case 134:
1410 *type = "Router Advertisement";
1411 *optional = dissect_icmpv6_type134;
1412 return;
1413 case 135:
1414 *type = "Neighbor Solicitation";
1415 *optional = dissect_icmpv6_type135;
1416 return;
1417 case 136:
1418 *type = "Neighbor Advertisement";
1419 *optional = dissect_icmpv6_type136;
1420 return;
1421 case 137:
1422 *type = "Redirect Message";
1423 *optional = dissect_icmpv6_type137;
1424 return;
1425 case 138:
1426 *type = "Router Renumbering";
1427 if(icmpv6_type_138_codes(icmp->h_code))
1428 *code = icmpv6_type_138_codes(icmp->h_code);
1429 *optional = dissect_icmpv6_type138;
1430 return;
1431 case 139:
1432 *type = "ICMP Node Information Query";
1433 if (icmpv6_code_range_valid(icmp->h_code,
1434 icmpv6_type_139_codes))
1435 *code = icmpv6_type_139_codes[icmp->h_code];
1436 *optional = dissect_icmpv6_type139;
1437 return;
1438 case 140:
1439 *type = "ICMP Node Information Response";
1440 if (icmpv6_code_range_valid(icmp->h_code,
1441 icmpv6_type_140_codes))
1442 *code = icmpv6_type_140_codes[icmp->h_code];
1443 *optional = dissect_icmpv6_type140;
1444 return;
1445 case 141:
1446 *type = "Inverse Neighbor Discovery Solicitation Message";
1447 *optional = dissect_icmpv6_type141;
1448 return;
1449 case 142:
1450 *type = "Inverse Neighbor Discovery Advertisement Message";
1451 *optional = dissect_icmpv6_type142;
1452 return;
1453 case 143:
1454 *type = "Multicast Listener Report v2";
1455 *optional = dissect_icmpv6_type143;
1456 return;
1457 case 144:
1458 *type = "Home Agent Address Discovery Request Message";
1459 *optional = dissect_icmpv6_type144;
1460 return;
1461 case 145:
1462 *type = "Home Agent Address Discovery Reply Message";
1463 *optional = dissect_icmpv6_type145;
1464 return;
1465 case 146:
1466 *type = "Mobile Prefix Solicitation";
1467 *optional = dissect_icmpv6_type146;
1468 return;
1469 case 147:
1470 *type = "Mobile Prefix Advertisement";
1471 *optional = dissect_icmpv6_type147;
1472 return;
1473 case 148:
1474 *type = "Certification Path Solicitation";
1475 *optional = dissect_icmpv6_type148;
1476 return;
1477 case 149:
1478 *type = "Certification Path Advertisement";
1479 *optional = dissect_icmpv6_type149;
1480 return;
1481 case 150:
1482 *type = "ICMP messages utilized by experimental mobility "
1483 "protocols such as Seamoby";
1484 *optional = dissect_icmpv6_type150;
1485 return;
1486 case 151:
1487 *type = "Multicast Router Advertisement";
1488 *code = "Ad. Interval";
1489 *optional = dissect_icmpv6_type151;
1490 return;
1491 case 152:
1492 *type = "Multicast Router Solicitation";
1493 *code = "Reserved";
1494 *optional = dissect_icmpv6_type152;
1495 return;
1496 case 153:
1497 *type = "Multicast Router Termination";
1498 *code = "Reserved";
1499 *optional = dissect_icmpv6_type153;
1500 return;
1501 case 154:
1502 *type = "FMIPv6 Messages";
1503 *optional = dissect_icmpv6_type154;
1504 return;
1505 case 155:
1506 *type = "RPL Control Message";
1507 if(icmpv6_type_155_codes(icmp->h_code))
1508 *code = icmpv6_type_155_codes(icmp->h_code);
1509 return;
1510 case 200:
1511 *type = "Private experimation";
1512 return;
1513 case 201:
1514 *type = "Private experimation";
1515 return;
1516 case 255:
1517 *type = "Reserved for expansion of ICMPv6 error messages";
1518 return;
1522 static inline void icmpv6(struct pkt_buff *pkt)
1524 char *type = NULL, *code = NULL;
1525 void (*optional)(struct pkt_buff *pkt) = NULL;
1526 struct icmpv6_general_hdr *icmp =
1527 (struct icmpv6_general_hdr *) pkt_pull(pkt, sizeof(*icmp));
1529 if (icmp == NULL)
1530 return;
1532 icmpv6_process(icmp, &type, &code, &optional);
1534 tprintf(" [ ICMPv6 ");
1535 tprintf("%s (%u), ", type, icmp->h_type);
1536 tprintf("%s (%u), ", code, icmp->h_code);
1537 tprintf("Chks (0x%x)", ntohs(icmp->h_chksum));
1538 if (optional)
1539 (*optional) (pkt);
1540 tprintf(" ]\n");
1543 static inline void icmpv6_less(struct pkt_buff *pkt)
1545 struct icmpv6_general_hdr *icmp =
1546 (struct icmpv6_general_hdr *) pkt_pull(pkt, sizeof(*icmp));
1548 if (icmp == NULL)
1549 return;
1551 tprintf(" ICMPv6 Type (%u) Code (%u)", icmp->h_type, icmp->h_code);
1554 struct protocol icmpv6_ops = {
1555 .key = 0x3A,
1556 .print_full = icmpv6,
1557 .print_less = icmpv6_less,
1560 #endif /* PROTO_ICMPV6_H */