2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2012 Markus Amend <markus@netsniff-ng.org>, Deutsche Flugsicherung GmbH
4 * Subject to the GPL, version 2.
6 * ICMPv6 described in RFC4443, RFC2710, RFC4861, RFC2894,
7 * RFC4620, RFC3122, RFC3810, RFC3775, RFC3971, RFC4065
9 * Look also for an good overview:
10 * http://www.iana.org/assignments/icmpv6-parameters
15 #include <netinet/in.h>
16 #include <arpa/inet.h>
17 #include <asm/byteorder.h>
20 #include "dissector_eth.h"
24 #define icmpv6_code_range_valid(code, sarr) ((size_t) (code) < array_size((sarr)))
26 struct icmpv6_general_hdr
{
32 /* for type 0x01 and 0x03 */
33 struct icmpv6_type_1_3
{
35 uint8_t invoking_pkt
[0];
38 struct icmpv6_type_2
{
40 uint8_t invoking_pkt
[0];
43 struct icmpv6_type_4
{
45 uint8_t invoking_pkt
[0];
48 struct icmpv6_type_128_129
{
55 struct icmpv6_type_130_131_132
{
58 struct in6_addr ipv6_addr
;
62 struct icmpv6_type_130_mldv2
{
66 struct in6_addr ipv6_addr
[0];
69 /* Neighbor Discovery msg */
70 struct icmpv6_type_133_141_142
{
75 struct icmpv6_type_134
{
76 uint8_t cur_hop_limit
;
78 uint16_t router_lifetime
;
79 uint32_t reachable_time
;
80 uint32_t retrans_timer
;
84 struct icmpv6_type_135
{
86 struct in6_addr ipv6_addr
;
90 struct icmpv6_type_136
{
92 struct in6_addr ipv6_addr
;
96 struct icmpv6_type_137
{
98 struct in6_addr ipv6_targ_addr
;
99 struct in6_addr ipv6_dest_addr
;
103 struct icmpv6_neighb_disc_ops_general
{
109 struct icmpv6_neighb_disc_ops_type_1_2
{
110 uint8_t link_lay_addr
[0];
113 struct icmpv6_neighb_disc_ops_type_3
{
116 uint32_t valid_lifetime
;
117 uint32_t preferred_lifetime
;
119 struct in6_addr prefix
;
122 struct icmpv6_neighb_disc_ops_type_4
{
125 uint8_t ip_hdr_data
[0];
128 struct icmpv6_neighb_disc_ops_type_5
{
133 struct icmpv6_neighb_disc_ops_type_9_10
{
136 uint8_t ip_hdr_data
[0];
139 struct icmpv6_neighb_disc_ops_type_15
{
146 struct icmpv6_neighb_disc_ops_type_16
{
153 struct icmpv6_neighb_disc_ops_type_17
{
159 struct icmpv6_neighb_disc_ops_type_17_1
{
161 struct in6_addr ipv6_addr
;
164 struct icmpv6_neighb_disc_ops_type_17_2
{
165 struct in6_addr ipv6_addr
;
168 struct icmpv6_neighb_disc_ops_type_19
{
172 /* end Neighbor Discovery msg */
174 struct icmpv6_type_138
{
182 /* Node Information Queries */
183 struct icmpv6_type_139_140
{
189 /* end Node Information Queries */
192 struct icmpv6_type_143
{
198 struct icmpv6_mldv2_addr_rec
{
200 uint8_t aux_data_len
;
202 struct in6_addr multic_addr
;
203 struct in6_addr src_addr
[0];
205 /* end MLDv2 report */
207 /* ICMP Mobility Support */
208 struct icmpv6_type_144_146
{
213 struct icmpv6_type_145
{
216 struct in6_addr home_agent_addr
[0];
219 struct icmpv6_type_147
{
224 /* end ICMP Mobility Support */
226 /* SEcure Neighbor Discovery */
227 struct icmpv6_type_148
{
233 struct icmpv6_type_149
{
240 /* end SEcure Neighbor Discovery */
242 struct icmpv6_type_150
{
244 uint32_t subtype_res
;
246 #if defined(__LITTLE_ENDIAN_BITFIELD)
249 #elif defined(__BIG_ENDIAN_BITFIELD)
253 # error "Please fix <asm/byteorder.h>"
260 /* Multicast Router Discovery */
261 struct icmpv6_type_151
{
266 struct icmpv6_type_152
{
270 struct icmpv6_type_153
{
273 /* end Multicast Router Discovery */
275 struct icmpv6_type_154
{
282 static int8_t print_ipv6_addr_list(struct pkt_buff
*pkt
, uint8_t nr_addr
)
284 char address
[INET6_ADDRSTRLEN
];
285 struct in6_addr
*addr
;
288 addr
= (struct in6_addr
*) pkt_pull(pkt
, sizeof(*addr
));
292 tprintf("\n\t Address: %s",
293 inet_ntop(AF_INET6
, addr
, address
,
300 static const char *icmpv6_mcast_rec_types
[] = {
303 "CHANGE_TO_INCLUDE_MODE",
304 "CHANGE_TO_EXCLUDE_MODE",
309 static int8_t dissect_icmpv6_mcast_rec(struct pkt_buff
*pkt
,
312 uint16_t nr_src
, aux_data_len_bytes
;
313 char address
[INET6_ADDRSTRLEN
];
314 struct icmpv6_mldv2_addr_rec
*addr_rec
;
317 addr_rec
= (struct icmpv6_mldv2_addr_rec
*)
318 pkt_pull(pkt
,sizeof(*addr_rec
));
319 if (addr_rec
== NULL
)
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
,
333 colorize_start_full(black
, red
) "invalid"
337 tprintf(", Aux Data Len (%u, %u bytes)",addr_rec
->aux_data_len
,
339 tprintf(", Nr. of Sources (%u)",nr_src
);
340 tprintf(", Address: %s",
341 inet_ntop(AF_INET6
, &addr_rec
->multic_addr
,
342 address
, sizeof(address
)));
344 if(!print_ipv6_addr_list(pkt
, nr_src
))
347 if (aux_data_len_bytes
> pkt_len(pkt
)) {
348 tprintf("\nAux Data Len %s",
349 colorize_start_full(black
, red
) "invalid"
354 tprintf(", Aux Data: ");
355 while (aux_data_len_bytes
--) {
356 uint8_t *data
= pkt_pull(pkt
, 1);
359 tprintf("%sINVALID%s", colorize_start_full(black
, red
),
364 tprintf("%x", *data
);
371 static int8_t dissect_neighb_disc_ops_1(struct pkt_buff
*pkt
,
374 struct icmpv6_neighb_disc_ops_type_1_2
*icmp_neighb_disc_1
;
376 icmp_neighb_disc_1
= (struct icmpv6_neighb_disc_ops_type_1_2
*)
377 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_1
));
378 if (icmp_neighb_disc_1
== NULL
)
380 len
-= sizeof(*icmp_neighb_disc_1
);
384 tprintf("Address 0x");
387 uint8_t *data
= pkt_pull(pkt
, 1);
390 tprintf("%sINVALID%s", colorize_start_full(black
, red
),
395 tprintf("%x", *data
);
401 static int8_t dissect_neighb_disc_ops_2(struct pkt_buff
*pkt
,
404 return dissect_neighb_disc_ops_1(pkt
, len
);
407 static int8_t dissect_neighb_disc_ops_3(struct pkt_buff
*pkt
,
410 char address
[INET6_ADDRSTRLEN
];
411 struct icmpv6_neighb_disc_ops_type_3
*icmp_neighb_disc_3
;
413 icmp_neighb_disc_3
= (struct icmpv6_neighb_disc_ops_type_3
*)
414 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_3
));
415 if (icmp_neighb_disc_3
== NULL
)
417 len
-= sizeof(*icmp_neighb_disc_3
);
421 tprintf("Prefix Len (%u) ",icmp_neighb_disc_3
->prefix_len
);
422 tprintf("L (%u) A (%u) Res1 (0x%x) ",icmp_neighb_disc_3
->l_a_res1
>> 7,
423 (icmp_neighb_disc_3
->l_a_res1
>> 7) & 0x1,
424 icmp_neighb_disc_3
->l_a_res1
& 0x3F);
425 tprintf("Valid Lifetime (%us) ",
426 ntohl(icmp_neighb_disc_3
->valid_lifetime
));
427 tprintf("Preferred Lifetime (%us) ",
428 ntohl(icmp_neighb_disc_3
->preferred_lifetime
));
429 tprintf("Reserved2 (0x%x) ",
430 ntohl(icmp_neighb_disc_3
->res2
));
431 tprintf("Prefix: %s ",
432 inet_ntop(AF_INET6
,&icmp_neighb_disc_3
->prefix
,
433 address
, sizeof(address
)));
438 static int8_t dissect_neighb_disc_ops_4(struct pkt_buff
*pkt
,
441 struct icmpv6_neighb_disc_ops_type_4
*icmp_neighb_disc_4
;
443 icmp_neighb_disc_4
= (struct icmpv6_neighb_disc_ops_type_4
*)
444 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_4
));
445 if (icmp_neighb_disc_4
== NULL
)
447 len
-= sizeof(*icmp_neighb_disc_4
);
451 tprintf("Reserved 1 (0x%x) ", ntohs(icmp_neighb_disc_4
->res1
));
452 tprintf("Reserved 2 (0x%x) ", ntohl(icmp_neighb_disc_4
->res2
));
453 tprintf("IP header + data ");
456 uint8_t *data
= pkt_pull(pkt
, 1);
459 tprintf("%sINVALID%s", colorize_start_full(black
, red
),
464 tprintf("%x", *data
);
470 static int8_t dissect_neighb_disc_ops_5(struct pkt_buff
*pkt
,
473 struct icmpv6_neighb_disc_ops_type_5
*icmp_neighb_disc_5
;
475 icmp_neighb_disc_5
= (struct icmpv6_neighb_disc_ops_type_5
*)
476 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_5
));
477 if (icmp_neighb_disc_5
== NULL
)
479 len
-= sizeof(*icmp_neighb_disc_5
);
483 tprintf("Reserved (0x%x) ", ntohs(icmp_neighb_disc_5
->res1
));
484 tprintf("MTU (%u)", ntohl(icmp_neighb_disc_5
->MTU
));
489 static int8_t dissect_neighb_disc_ops_9(struct pkt_buff
*pkt
,
492 struct icmpv6_neighb_disc_ops_type_9_10
*icmp_neighb_disc_9
;
494 icmp_neighb_disc_9
= (struct icmpv6_neighb_disc_ops_type_9_10
*)
495 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_9
));
496 if (icmp_neighb_disc_9
== NULL
)
498 len
-= sizeof(*icmp_neighb_disc_9
);
502 tprintf("Reserved 1 (0x%x) ", ntohs(icmp_neighb_disc_9
->res1
));
503 tprintf("Reserved 2 (0x%x) ", ntohl(icmp_neighb_disc_9
->res2
));
505 return print_ipv6_addr_list(pkt
, len
/ sizeof(struct in6_addr
));
508 static int8_t dissect_neighb_disc_ops_10(struct pkt_buff
*pkt
,
511 return dissect_neighb_disc_ops_9(pkt
, len
);
514 static const char *icmpv6_neighb_disc_ops_15_name
[] = {
515 "DER Encoded X.501 Name",
519 static int8_t dissect_neighb_disc_ops_15(struct pkt_buff
*pkt
,
524 struct icmpv6_neighb_disc_ops_type_15
*icmp_neighb_disc_15
;
526 icmp_neighb_disc_15
= (struct icmpv6_neighb_disc_ops_type_15
*)
527 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_15
));
528 if (icmp_neighb_disc_15
== NULL
)
530 len
-= sizeof(*icmp_neighb_disc_15
);
533 pad_len
= icmp_neighb_disc_15
->pad_len
;
535 tprintf("Name Type %s (%u) ",
536 icmpv6_code_range_valid(icmp_neighb_disc_15
->name_type
- 1,
537 icmpv6_neighb_disc_ops_15_name
) ?
538 icmpv6_neighb_disc_ops_15_name
[
539 icmp_neighb_disc_15
->name_type
- 1] : "Unknown",
540 icmp_neighb_disc_15
->name_type
);
541 if (pad_len
> (size_t) len
) {
542 tprintf("Pad Len (%zu, invalid)\n%s", pad_len
,
543 colorize_start_full(black
, red
)
544 "Skip Option" colorize_end());
549 tprintf("Pad Len (%zu) ", pad_len
);
551 name_len
= len
- pad_len
;
555 uint8_t *data
= pkt_pull(pkt
, 1);
558 tprintf("%sINVALID%s", colorize_start_full(black
, red
),
563 tprintf("%c", *data
);
567 tprintf("Padding (");
570 uint8_t *data
= pkt_pull(pkt
, 1);
573 tprintf("%sINVALID%s", colorize_start_full(black
, red
),
578 tprintf("%x", *data
);
585 static const char *icmpv6_neighb_disc_ops_16_cert
[] = {
586 "X.509v3 Certificate",
589 static int8_t dissect_neighb_disc_ops_16(struct pkt_buff
*pkt
,
592 struct icmpv6_neighb_disc_ops_type_16
*icmp_neighb_disc_16
;
594 icmp_neighb_disc_16
= (struct icmpv6_neighb_disc_ops_type_16
*)
595 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_16
));
596 if (icmp_neighb_disc_16
== NULL
)
598 len
-= sizeof(*icmp_neighb_disc_16
);
602 tprintf("Cert Type %s (%u) ",
603 icmpv6_code_range_valid(icmp_neighb_disc_16
->cert_type
- 1,
604 icmpv6_neighb_disc_ops_16_cert
) ?
605 icmpv6_neighb_disc_ops_16_cert
[
606 icmp_neighb_disc_16
->cert_type
- 1] : "Unknown",
607 icmp_neighb_disc_16
->cert_type
);
608 tprintf("Res (0x%x) ", icmp_neighb_disc_16
->res
);
610 tprintf("Certificate + Padding (");
612 uint8_t *data
= pkt_pull(pkt
, 1);
615 tprintf("%sINVALID%s", colorize_start_full(black
, red
),
620 tprintf("%x", *data
);
627 static const char *icmpv6_neighb_disc_ops_17_codes
[] = {
628 "Old Care-of Address",
629 "New Care-of Address",
634 static int8_t dissect_neighb_disc_ops_17(struct pkt_buff
*pkt
,
637 char address
[INET6_ADDRSTRLEN
];
638 struct icmpv6_neighb_disc_ops_type_17
*icmp_neighb_disc_17
;
640 icmp_neighb_disc_17
= (struct icmpv6_neighb_disc_ops_type_17
*)
641 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_17
));
642 if (icmp_neighb_disc_17
== NULL
)
644 len
-= sizeof(*icmp_neighb_disc_17
);
648 tprintf("Opt Code %s (%u) ",
649 icmpv6_code_range_valid(icmp_neighb_disc_17
->opt_code
- 1,
650 icmpv6_neighb_disc_ops_17_codes
) ?
651 icmpv6_neighb_disc_ops_17_codes
[
652 icmp_neighb_disc_17
->opt_code
- 1] : "Unknown",
653 icmp_neighb_disc_17
->opt_code
);
654 tprintf("Prefix Len (%u) ", icmp_neighb_disc_17
->prefix_len
);
656 if (len
== sizeof(struct icmpv6_neighb_disc_ops_type_17_1
)) {
657 struct icmpv6_neighb_disc_ops_type_17_1
658 *icmp_neighb_disc_17_1
;
660 icmp_neighb_disc_17_1
=
661 (struct icmpv6_neighb_disc_ops_type_17_1
*)
662 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_17_1
));
663 if (icmp_neighb_disc_17_1
== NULL
)
665 len
-= sizeof(*icmp_neighb_disc_17_1
);
669 tprintf("Res (0x%x) ",icmp_neighb_disc_17_1
->res
);
671 inet_ntop(AF_INET6
,&icmp_neighb_disc_17_1
->ipv6_addr
,
672 address
, sizeof(address
)));
674 else if (len
== sizeof(struct icmpv6_neighb_disc_ops_type_17_2
)) {
675 struct icmpv6_neighb_disc_ops_type_17_2
676 *icmp_neighb_disc_17_2
;
678 icmp_neighb_disc_17_2
=
679 (struct icmpv6_neighb_disc_ops_type_17_2
*)
680 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_17_2
));
681 if (icmp_neighb_disc_17_2
== NULL
)
683 len
-= sizeof(*icmp_neighb_disc_17_2
);
688 inet_ntop(AF_INET6
,&icmp_neighb_disc_17_2
->ipv6_addr
,
689 address
, sizeof(address
)));
692 tprintf("%s (", colorize_start_full(black
, red
)
693 "Error Wrong Length. Skip Option" colorize_end());
695 uint8_t *data
= pkt_pull(pkt
, 1);
698 tprintf("%sINVALID%s", colorize_start_full(black
, red
),
703 tprintf("%x", *data
);
711 static const char *icmpv6_neighb_disc_ops_19_codes
[] = {
712 "Wildcard requesting resolution for all nearby access points",
713 "Link-Layer Address of the New Access Point",
714 "Link-Layer Address of the MN",
715 "Link-Layer Address of the NAR",
716 "Link-Layer Address of the source of RtSolPr or PrRtAdv \
718 "The access point identified by the LLA belongs to the \
719 current interface of the router",
720 "No prefix information available for the access point \
721 identified by the LLA",
722 "No fast handover support available for the access point \
723 identified by the LLA",
726 static int8_t dissect_neighb_disc_ops_19(struct pkt_buff
*pkt
,
729 struct icmpv6_neighb_disc_ops_type_19
*icmp_neighb_disc_19
;
731 icmp_neighb_disc_19
= (struct icmpv6_neighb_disc_ops_type_19
*)
732 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_19
));
733 if (icmp_neighb_disc_19
== NULL
)
735 len
-= sizeof(*icmp_neighb_disc_19
);
739 tprintf("Opt Code %s (%u) ",
740 icmpv6_code_range_valid(icmp_neighb_disc_19
->opt_code
,
741 icmpv6_neighb_disc_ops_19_codes
) ?
742 icmpv6_neighb_disc_ops_19_codes
[
743 icmp_neighb_disc_19
->opt_code
] : "Unknown",
744 icmp_neighb_disc_19
->opt_code
);
748 uint8_t *data
= pkt_pull(pkt
, 1);
751 tprintf("%sINVALID%s", colorize_start_full(black
, red
),
756 tprintf("%x", *data
);
763 static inline char *icmpv6_neighb_disc_ops(uint8_t code
) {
765 case 1: return "Source Link-Layer Address";
766 case 2: return "Target Link-Layer Address";
767 case 3: return "Prefix Information";
768 case 4: return "Redirected Header";
769 case 5: return "MTU";
770 case 6: return "NBMA Shortcut Limit Option";
771 case 7: return "Advertisement Interval Option";
772 case 8: return "Home Agent Information Option";
773 case 9: return "Source Address List";
774 case 10: return "Target Address List";
775 case 11: return "CGA option";
776 case 12: return "RSA Signature option";
777 case 13: return "Timestamp option";
778 case 14: return "Nonce option";
779 case 15: return "Trust Anchor option";
780 case 16: return "Certificate option";
781 case 17: return "IP Address/Prefix Option";
782 case 18: return "New Router Prefix Information Option";
783 case 19: return "Link-layer Address Option";
784 case 20: return "Neighbor Advertisement Acknowledgment Option";
786 case 23: return "Prefix Information";
787 case 24: return "Redirected Header";
788 case 25: return "MTU";
789 case 26: return "NBMA Shortcut Limit Option";
790 case 27: return "Advertisement Interval Option";
791 case 28: return "Home Agent Information Option";
792 case 29: return "Source Address List";
793 case 30: return "Target Address List";
794 case 31: return "DNS Search List Option";
795 case 32: return "Proxy Signature (PS)";
797 case 138: return "CARD Request option";
798 case 139: return "CARD Reply option";
800 case 253: return "RFC3692-style Experiment 1";
801 case 254: return "RFC3692-style Experiment 2";
807 static int8_t dissect_neighb_disc_ops(struct pkt_buff
*pkt
)
810 uint16_t ops_total_len
;
811 ssize_t ops_payl_len
;
812 struct icmpv6_neighb_disc_ops_general
*icmp_neighb_disc
;
814 while(pkt_len(pkt
)) {
815 icmp_neighb_disc
= (struct icmpv6_neighb_disc_ops_general
*)
816 pkt_pull(pkt
,sizeof(*icmp_neighb_disc
));
817 if (icmp_neighb_disc
== NULL
)
820 ops_total_len
= icmp_neighb_disc
->len
* 8;
821 pad_bytes
= (size_t) (ops_total_len
% 8);
822 ops_payl_len
= ops_total_len
- sizeof(*icmp_neighb_disc
) -
825 tprintf("\n\tOption %s (%u) ",
826 icmpv6_neighb_disc_ops(icmp_neighb_disc
->type
) ?
827 icmpv6_neighb_disc_ops(icmp_neighb_disc
->type
)
828 : "Type Unknown", icmp_neighb_disc
->type
);
829 if (ops_payl_len
> pkt_len(pkt
) || ops_payl_len
< 0) {
830 tprintf("Length (%u, %u bytes, %s%s%s) ",
831 icmp_neighb_disc
->len
,
833 colorize_start_full(black
, red
),
834 "invalid", colorize_end());
838 tprintf("Length (%u, %u bytes) ",icmp_neighb_disc
->len
,
841 switch (icmp_neighb_disc
->type
) {
843 if (!dissect_neighb_disc_ops_1(pkt
, ops_payl_len
))
847 if (!dissect_neighb_disc_ops_2(pkt
, ops_payl_len
))
851 if (!dissect_neighb_disc_ops_3(pkt
, ops_payl_len
))
855 if (!dissect_neighb_disc_ops_4(pkt
, ops_payl_len
))
859 if (!dissect_neighb_disc_ops_5(pkt
, ops_payl_len
))
862 /* Type 9 and 10 defined in
863 * http://tools.ietf.org/html/rfc3122#section-3.1
866 if (!dissect_neighb_disc_ops_9(pkt
, ops_payl_len
))
870 if (!dissect_neighb_disc_ops_10(pkt
, ops_payl_len
))
873 /* Type 15 and 16 defined in
874 * http://tools.ietf.org/html/rfc3971#section-6.4.3
875 * http://tools.ietf.org/html/rfc3971#section-6.4.4
878 if (!dissect_neighb_disc_ops_15(pkt
, ops_payl_len
))
882 if (!dissect_neighb_disc_ops_16(pkt
, ops_payl_len
))
885 /* Type 17 and 19 defined in
886 * http://tools.ietf.org/html/rfc5568#section-6.4
889 if (!dissect_neighb_disc_ops_17(pkt
, ops_payl_len
))
893 if (!dissect_neighb_disc_ops_19(pkt
, ops_payl_len
))
897 pkt_pull(pkt
, ops_payl_len
);
900 /* Skip Padding Bytes */
901 if (pad_bytes
> pkt_len(pkt
)) {
902 tprintf(" %s",colorize_start_full(black
, red
)
903 "Invalid Padding" colorize_end());
906 pkt_pull(pkt
, pad_bytes
);
912 static const char *icmpv6_type_1_codes
[] = {
913 "No route to destination",
914 "Communication with destination administratively prohibited",
915 "Beyond scope of source address",
916 "Address unreachable",
918 "Source address failed ingress/egress policy",
919 "Reject route to destination",
920 "Error in Source Routing Header",
923 static int8_t dissect_icmpv6_type1(struct pkt_buff
*pkt
)
925 struct icmpv6_type_1_3
*icmp_1
;
927 icmp_1
= (struct icmpv6_type_1_3
*) pkt_pull(pkt
,sizeof(*icmp_1
));
931 tprintf(", Unused (0x%x)",ntohl(icmp_1
->unused
));
932 tprintf(" Payload include as much of invoking packet");
937 static int8_t dissect_icmpv6_type2(struct pkt_buff
*pkt
)
939 struct icmpv6_type_2
*icmp_2
;
941 icmp_2
= (struct icmpv6_type_2
*) pkt_pull(pkt
,sizeof(*icmp_2
));
945 tprintf(", MTU (0x%x)",ntohl(icmp_2
->MTU
));
946 tprintf(" Payload include as much of invoking packet");
951 static const char *icmpv6_type_3_codes
[] = {
952 "Hop limit exceeded in transit",
953 "Fragment reassembly time exceeded",
956 static int8_t dissect_icmpv6_type3(struct pkt_buff
*pkt
)
958 struct icmpv6_type_1_3
*icmp_3
;
960 icmp_3
= (struct icmpv6_type_1_3
*) pkt_pull(pkt
,sizeof(*icmp_3
));
964 tprintf(", Unused (0x%x)",ntohl(icmp_3
->unused
));
965 tprintf(" Payload include as much of invoking packet");
970 static const char *icmpv6_type_4_codes
[] = {
971 "Erroneous header field encountered",
972 "Unrecognized Next Header type encountered",
973 "Unrecognized IPv6 option encountered",
976 static int8_t dissect_icmpv6_type4(struct pkt_buff
*pkt
)
978 struct icmpv6_type_4
*icmp_4
;
980 icmp_4
= (struct icmpv6_type_4
*) pkt_pull(pkt
,sizeof(*icmp_4
));
984 tprintf(", Pointer (0x%x)",ntohl(icmp_4
->pointer
));
985 tprintf(" Payload include as much of invoking packet");
990 static int8_t dissect_icmpv6_type128(struct pkt_buff
*pkt
)
992 struct icmpv6_type_128_129
*icmp_128
;
994 icmp_128
= (struct icmpv6_type_128_129
*)
995 pkt_pull(pkt
,sizeof(*icmp_128
));
996 if (icmp_128
== NULL
)
999 tprintf(", ID (0x%x)",ntohs(icmp_128
->id
));
1000 tprintf(", Seq. Nr. (%u)",ntohs(icmp_128
->sn
));
1001 tprintf(" Payload include Data");
1006 static int8_t dissect_icmpv6_type129(struct pkt_buff
*pkt
)
1008 struct icmpv6_type_128_129
*icmp_129
;
1010 icmp_129
= (struct icmpv6_type_128_129
*)
1011 pkt_pull(pkt
,sizeof(*icmp_129
));
1012 if (icmp_129
== NULL
)
1015 tprintf(", ID (0x%x)",ntohs(icmp_129
->id
));
1016 tprintf(", Seq. Nr. (%u)",ntohs(icmp_129
->sn
));
1017 tprintf(" Payload include Data");
1022 static int8_t dissect_icmpv6_type130(struct pkt_buff
*pkt
)
1024 char address
[INET6_ADDRSTRLEN
];
1025 uint16_t nr_src
, maxrespdel
;
1026 uint8_t switch_mldv2
= 0;
1027 struct icmpv6_type_130_131_132
*icmp_130
;
1029 icmp_130
= (struct icmpv6_type_130_131_132
*)
1030 pkt_pull(pkt
,sizeof(*icmp_130
));
1031 if (icmp_130
== NULL
)
1033 maxrespdel
= ntohs(icmp_130
->maxrespdel
);
1035 if(pkt_len(pkt
) >= sizeof(struct icmpv6_type_130_mldv2
))
1039 tprintf(", MLDv2, Max Resp Delay (%ums)", maxrespdel
>> 15 ?
1040 (((maxrespdel
& 0xFFF) | 0x1000) <<
1041 (((maxrespdel
>> 12) & 0x3) + 3)) : maxrespdel
);
1043 tprintf(", Max Resp Delay (%ums)",maxrespdel
);
1044 tprintf(", Res (0x%x)",ntohs(icmp_130
->res
));
1045 tprintf(", Address: %s",
1046 inet_ntop(AF_INET6
, &icmp_130
->ipv6_addr
,
1047 address
, sizeof(address
)));
1050 struct icmpv6_type_130_mldv2
*icmp_130_mldv2
;
1052 icmp_130_mldv2
= (struct icmpv6_type_130_mldv2
*)
1053 pkt_pull(pkt
,sizeof(*icmp_130_mldv2
));
1054 if (icmp_130_mldv2
== NULL
)
1057 nr_src
= ntohs(icmp_130_mldv2
->nr_src
);
1059 tprintf(", Resv (0x%x)",icmp_130_mldv2
->resv_S_QRV
>> 4);
1060 tprintf(", S (%u)",(icmp_130_mldv2
->resv_S_QRV
>> 3) & 0x1);
1061 tprintf(", QRV (0x%x)",icmp_130_mldv2
->resv_S_QRV
& 0x3);
1062 tprintf(", QQIC (%u)",icmp_130_mldv2
->QQIC
);
1063 tprintf(", Nr Src (%u)",nr_src
);
1065 return print_ipv6_addr_list(pkt
, nr_src
);
1071 static int8_t dissect_icmpv6_type131(struct pkt_buff
*pkt
)
1073 char address
[INET6_ADDRSTRLEN
];
1074 struct icmpv6_type_130_131_132
*icmp_131
;
1076 icmp_131
= (struct icmpv6_type_130_131_132
*)
1077 pkt_pull(pkt
,sizeof(*icmp_131
));
1078 if (icmp_131
== NULL
)
1081 tprintf(", Max Resp Delay (%ums)",ntohs(icmp_131
->maxrespdel
));
1082 tprintf(", Res (0x%x)",ntohs(icmp_131
->res
));
1083 tprintf(", Address: %s",
1084 inet_ntop(AF_INET6
, &icmp_131
->ipv6_addr
,
1085 address
, sizeof(address
)));
1090 static inline int8_t dissect_icmpv6_type132(struct pkt_buff
*pkt
)
1092 return dissect_icmpv6_type131(pkt
);
1095 static int8_t dissect_icmpv6_type133(struct pkt_buff
*pkt
)
1097 struct icmpv6_type_133_141_142
*icmp_133
;
1099 icmp_133
= (struct icmpv6_type_133_141_142
*)
1100 pkt_pull(pkt
,sizeof(*icmp_133
));
1101 if (icmp_133
== NULL
)
1104 tprintf(", Reserved (0x%x)",ntohl(icmp_133
->res
));
1106 return dissect_neighb_disc_ops(pkt
);
1109 static int8_t dissect_icmpv6_type134(struct pkt_buff
*pkt
)
1111 struct icmpv6_type_134
*icmp_134
;
1113 icmp_134
= (struct icmpv6_type_134
*)
1114 pkt_pull(pkt
,sizeof(*icmp_134
));
1115 if (icmp_134
== NULL
)
1118 tprintf(", Cur Hop Limit (%u)",icmp_134
->cur_hop_limit
);
1119 tprintf(", M (%u) O (%u)",icmp_134
->m_o_res
>> 7,
1120 (icmp_134
->m_o_res
>> 6) & 0x1);
1121 tprintf(", Router Lifetime (%us)",ntohs(icmp_134
->router_lifetime
));
1122 tprintf(", Reachable Time (%ums)",ntohl(icmp_134
->reachable_time
));
1123 tprintf(", Retrans Timer (%ums)",ntohl(icmp_134
->retrans_timer
));
1125 return dissect_neighb_disc_ops(pkt
);
1128 static int8_t dissect_icmpv6_type135(struct pkt_buff
*pkt
)
1130 char address
[INET6_ADDRSTRLEN
];
1131 struct icmpv6_type_135
*icmp_135
;
1133 icmp_135
= (struct icmpv6_type_135
*)
1134 pkt_pull(pkt
,sizeof(*icmp_135
));
1135 if (icmp_135
== NULL
)
1138 tprintf(", Reserved (0x%x)",ntohl(icmp_135
->res
));
1139 tprintf(", Target Address: %s",
1140 inet_ntop(AF_INET6
, &icmp_135
->ipv6_addr
,
1141 address
, sizeof(address
)));
1143 return dissect_neighb_disc_ops(pkt
);
1146 static int8_t dissect_icmpv6_type136(struct pkt_buff
*pkt
)
1148 char address
[INET6_ADDRSTRLEN
];
1150 struct icmpv6_type_136
*icmp_136
;
1152 icmp_136
= (struct icmpv6_type_136
*)
1153 pkt_pull(pkt
,sizeof(*icmp_136
));
1154 if (icmp_136
== NULL
)
1156 r_s_o_res
= ntohl(icmp_136
->r_s_o_res
);
1158 tprintf(", R (%u) S (%u) O (%u) Reserved (0x%x)", r_s_o_res
>> 31,
1159 (r_s_o_res
>> 30) & 0x1, (r_s_o_res
>> 29) & 0x1,
1160 r_s_o_res
& 0x1FFFFFFF);
1161 tprintf(", Target Address: %s",
1162 inet_ntop(AF_INET6
, &icmp_136
->ipv6_addr
,
1163 address
, sizeof(address
)));
1165 return dissect_neighb_disc_ops(pkt
);
1168 static int8_t dissect_icmpv6_type137(struct pkt_buff
*pkt
)
1170 char address
[INET6_ADDRSTRLEN
];
1171 struct icmpv6_type_137
*icmp_137
;
1173 icmp_137
= (struct icmpv6_type_137
*)
1174 pkt_pull(pkt
,sizeof(*icmp_137
));
1175 if (icmp_137
== NULL
)
1178 tprintf(", Reserved (0x%x)",icmp_137
->res
);
1179 tprintf(", Target Address: %s",
1180 inet_ntop(AF_INET6
, &icmp_137
->ipv6_targ_addr
,
1181 address
, sizeof(address
)));
1182 tprintf(", Dest Address: %s",
1183 inet_ntop(AF_INET6
, &icmp_137
->ipv6_dest_addr
,
1184 address
, sizeof(address
)));
1186 return dissect_neighb_disc_ops(pkt
);
1189 static void dissect_icmpv6_rr_body(struct pkt_buff
*pkt
)
1192 * Upgrade Dissector for Message Body
1193 * from http://tools.ietf.org/html/rfc2894#section-3.2
1196 tprintf(" Message Body recognized");
1199 static inline char *icmpv6_type_138_codes(uint8_t code
) {
1201 case 1: return "Router Renumbering Command";
1202 case 2: return "Router Renumbering Result";
1203 case 255: return "Sequence Number Reset";
1209 static int8_t dissect_icmpv6_type138(struct pkt_buff
*pkt
)
1211 struct icmpv6_type_138
*icmp_138
;
1213 icmp_138
= (struct icmpv6_type_138
*)
1214 pkt_pull(pkt
,sizeof(*icmp_138
));
1215 if (icmp_138
== NULL
)
1218 tprintf(", Sequence Nr. (%u)",ntohl(icmp_138
->seq_nr
));
1219 tprintf(", Segment Nr. (%u)",icmp_138
->seg_nr
);
1220 tprintf(", T (%u) R (%u) A (%u) S (%u) P (%u) Res \
1221 (0x%x) ",icmp_138
->flags
>> 7, (icmp_138
->flags
>> 6) & 1,
1222 (icmp_138
->flags
>> 5) & 1, (icmp_138
->flags
>> 4) & 1,
1223 (icmp_138
->flags
>> 3) & 1, icmp_138
->flags
& 7);
1224 tprintf(", Max Delay (%ums)", ntohs(icmp_138
->maxdelay
));
1225 tprintf(", Res (0x%x)", ntohl(icmp_138
->res
));
1227 dissect_icmpv6_rr_body(pkt
);
1232 static void dissect_icmpv6_node_inf_data(struct pkt_buff
*pkt
)
1235 * Upgrade Dissector for Data field
1236 * http://tools.ietf.org/html/rfc4620#section-4
1239 tprintf(" Data recognized");
1242 static const char *icmpv6_node_inf_qtypes
[] = {
1250 static const char *icmpv6_type_139_codes
[] = {
1251 "Data contains IPv6 Address",
1252 "Data contains Name or nothing",
1253 "Data contains IPv4 Address",
1256 static int8_t dissect_icmpv6_type139(struct pkt_buff
*pkt
)
1258 const char *qtype_name
= "Unknown";
1260 struct icmpv6_type_139_140
*icmp_139
;
1262 icmp_139
= (struct icmpv6_type_139_140
*)
1263 pkt_pull(pkt
,sizeof(*icmp_139
));
1264 if (icmp_139
== NULL
)
1267 qtype_nr
= ntohs(icmp_139
->qtype
);
1268 if (icmpv6_code_range_valid(qtype_nr
, icmpv6_node_inf_qtypes
))
1269 qtype_name
= icmpv6_node_inf_qtypes
[qtype_nr
];
1271 tprintf(", Qtype %s (%u)", qtype_name
, qtype_nr
);
1272 tprintf(", Flags (0x%x)", ntohs(icmp_139
->flags
));
1273 tprintf(", Nonce (0x%lx)", ntohll(icmp_139
->nonce
));
1275 dissect_icmpv6_node_inf_data(pkt
);
1280 static char *icmpv6_type_140_codes
[] = {
1281 "Successfull reply",
1282 "Responder refuses answer",
1283 "Qtype is unknown to the Responder",
1286 static inline int8_t dissect_icmpv6_type140(struct pkt_buff
*pkt
)
1288 return dissect_icmpv6_type139(pkt
);
1291 static inline int8_t dissect_icmpv6_type141(struct pkt_buff
*pkt
)
1293 return dissect_icmpv6_type133(pkt
);
1296 static inline int8_t dissect_icmpv6_type142(struct pkt_buff
*pkt
)
1298 return dissect_icmpv6_type133(pkt
);
1301 static int8_t dissect_icmpv6_type143(struct pkt_buff
*pkt
)
1304 struct icmpv6_type_143
*icmp_143
;
1306 icmp_143
= (struct icmpv6_type_143
*)
1307 pkt_pull(pkt
,sizeof(*icmp_143
));
1308 if (icmp_143
== NULL
)
1310 nr_rec
= ntohs(icmp_143
->nr_rec
);
1312 tprintf(", Res (0x%x)",ntohs(icmp_143
->res
));
1313 tprintf(", Nr. Mcast Addr Records (%u)",nr_rec
);
1315 return dissect_icmpv6_mcast_rec(pkt
, nr_rec
);
1318 static int8_t dissect_icmpv6_type144(struct pkt_buff
*pkt
)
1320 struct icmpv6_type_144_146
*icmp_144
;
1322 icmp_144
= (struct icmpv6_type_144_146
*)
1323 pkt_pull(pkt
,sizeof(*icmp_144
));
1324 if (icmp_144
== NULL
)
1327 tprintf(", ID (%u)",ntohs(icmp_144
->id
));
1328 tprintf(", Res (0x%x)",ntohs(icmp_144
->res
));
1333 static int8_t dissect_icmpv6_type145(struct pkt_buff
*pkt
)
1335 struct icmpv6_type_145
*icmp_145
;
1337 icmp_145
= (struct icmpv6_type_145
*)
1338 pkt_pull(pkt
,sizeof(*icmp_145
));
1339 if (icmp_145
== NULL
)
1342 tprintf(", ID (%u)",ntohs(icmp_145
->id
));
1343 tprintf(", Res (0x%x)",ntohs(icmp_145
->res
));
1345 return print_ipv6_addr_list(pkt
, pkt_len(pkt
) /
1346 sizeof(struct in6_addr
));
1349 static inline int8_t dissect_icmpv6_type146(struct pkt_buff
*pkt
)
1351 return dissect_icmpv6_type144(pkt
);
1354 static int8_t dissect_icmpv6_type147(struct pkt_buff
*pkt
)
1357 struct icmpv6_type_147
*icmp_147
;
1359 icmp_147
= (struct icmpv6_type_147
*)
1360 pkt_pull(pkt
,sizeof(*icmp_147
));
1361 if (icmp_147
== NULL
)
1363 m_o_res
= ntohs(icmp_147
->m_o_res
);
1365 tprintf(", ID (%u)",ntohs(icmp_147
->id
));
1366 tprintf(", M (%u) O (%u) Res (0x%x)",m_o_res
>> 15,
1367 (m_o_res
>> 14) & 1, m_o_res
& 0x3FFF);
1369 return dissect_neighb_disc_ops(pkt
);
1372 static int8_t dissect_icmpv6_type148(struct pkt_buff
*pkt
)
1374 struct icmpv6_type_148
*icmp_148
;
1376 icmp_148
= (struct icmpv6_type_148
*)
1377 pkt_pull(pkt
,sizeof(*icmp_148
));
1378 if (icmp_148
== NULL
)
1381 tprintf(", ID (%u)",ntohs(icmp_148
->id
));
1382 tprintf(", Component (%u)",ntohs(icmp_148
->comp
));
1384 return dissect_neighb_disc_ops(pkt
);
1387 static int8_t dissect_icmpv6_type149(struct pkt_buff
*pkt
)
1389 struct icmpv6_type_149
*icmp_149
;
1391 icmp_149
= (struct icmpv6_type_149
*)
1392 pkt_pull(pkt
,sizeof(*icmp_149
));
1393 if (icmp_149
== NULL
)
1396 tprintf(", ID (%u)",ntohs(icmp_149
->id
));
1397 tprintf(", All Components (%u)",ntohs(icmp_149
->all_comp
));
1398 tprintf(", Component (%u)",ntohs(icmp_149
->comp
));
1399 tprintf(", Res (0x%x)",ntohs(icmp_149
->res
));
1401 return dissect_neighb_disc_ops(pkt
);
1404 static int8_t dissect_icmpv6_type150(struct pkt_buff
*pkt
)
1406 struct icmpv6_type_150
*icmp_150
;
1408 icmp_150
= (struct icmpv6_type_150
*)
1409 pkt_pull(pkt
,sizeof(*icmp_150
));
1410 if (icmp_150
== NULL
)
1413 tprintf(", Subtype (%u)",icmp_150
->subtype
);
1414 tprintf(", Res (0x%x)",icmp_150
->res
);
1415 tprintf(", Options in Payload");
1420 static int8_t dissect_icmpv6_type151(struct pkt_buff
*pkt
)
1422 struct icmpv6_type_151
*icmp_151
;
1424 icmp_151
= (struct icmpv6_type_151
*)
1425 pkt_pull(pkt
,sizeof(*icmp_151
));
1426 if (icmp_151
== NULL
)
1429 tprintf(", Query Interval (%us)",ntohs(icmp_151
->query_intv
));
1430 tprintf(", Robustness Variable (%u)",ntohs(icmp_151
->rob_var
));
1435 static int8_t dissect_icmpv6_type152(struct pkt_buff
*pkt
)
1437 struct icmpv6_type_152
*icmp_152
;
1439 icmp_152
= (struct icmpv6_type_152
*)
1440 pkt_pull(pkt
,sizeof(*icmp_152
));
1441 if (icmp_152
== NULL
)
1447 static int8_t dissect_icmpv6_type153(struct pkt_buff
*pkt
)
1449 struct icmpv6_type_153
*icmp_153
;
1451 icmp_153
= (struct icmpv6_type_153
*)
1452 pkt_pull(pkt
,sizeof(*icmp_153
));
1453 if (icmp_153
== NULL
)
1459 static int8_t dissect_icmpv6_type154(struct pkt_buff
*pkt
)
1461 struct icmpv6_type_154
*icmp_154
;
1463 icmp_154
= (struct icmpv6_type_154
*)
1464 pkt_pull(pkt
,sizeof(*icmp_154
));
1465 if (icmp_154
== NULL
)
1468 tprintf(", Subtype (%u)",icmp_154
->subtype
);
1469 tprintf(", Res (0x%x)",icmp_154
->res
);
1470 tprintf(", ID (%u)",ntohs(icmp_154
->id
));
1472 return dissect_neighb_disc_ops(pkt
);
1475 static inline char *icmpv6_type_155_codes(uint8_t code
) {
1477 case 0x00: return "DODAG Information Solicitation";
1478 case 0x01: return "DODAG Information Object";
1479 case 0x02: return "Destination Advertisement Object";
1480 case 0x03: return "Destination Advertisement Object Acknowledgment";
1481 case 0x80: return "Secure DODAG Information Solicitation";
1482 case 0x81: return "Secure DODAG Information Object";
1483 case 0x82: return "Secure Destination Advertisement Object";
1484 case 0x83: return "Secure Destination Advertisement Object Acknowledgment";
1485 case 0x8A: return "Consistency Check";
1491 static void icmpv6_process(struct icmpv6_general_hdr
*icmp
, const char **type
,
1492 const char **code
, int8_t (**optional
)(struct pkt_buff
*pkt
))
1494 *type
= "Unknown Type";
1495 *code
= "Unknown Code";
1497 switch (icmp
->h_type
) {
1499 *type
= "Destination Unreachable";
1500 if (icmpv6_code_range_valid(icmp
->h_code
, icmpv6_type_1_codes
))
1501 *code
= icmpv6_type_1_codes
[icmp
->h_code
];
1502 *optional
= dissect_icmpv6_type1
;
1505 *type
= "Packet Too Big";
1506 *optional
= dissect_icmpv6_type2
;
1509 *type
= "Time Exceeded";
1510 if (icmpv6_code_range_valid(icmp
->h_code
, icmpv6_type_3_codes
))
1511 *code
= icmpv6_type_3_codes
[icmp
->h_code
];
1512 *optional
= dissect_icmpv6_type3
;
1515 *type
= "Parameter Problem";
1516 if (icmpv6_code_range_valid(icmp
->h_code
, icmpv6_type_4_codes
))
1517 *code
= icmpv6_type_4_codes
[icmp
->h_code
];
1518 *optional
= dissect_icmpv6_type4
;
1521 *type
= "Private experimation";
1524 *type
= "Private experimation";
1527 *type
= "Reserved for expansion of ICMPv6 error messages";
1530 *type
= "Echo Request";
1531 *optional
= dissect_icmpv6_type128
;
1534 *type
= "Echo Reply";
1535 *optional
= dissect_icmpv6_type129
;
1538 *type
= "Multicast Listener Query";
1539 *optional
= dissect_icmpv6_type130
;
1542 *type
= "Multicast Listener Report";
1543 *optional
= dissect_icmpv6_type131
;
1546 *type
= "Multicast Listener Done";
1547 *optional
= dissect_icmpv6_type132
;
1550 *type
= "Router Solicitation";
1551 *optional
= dissect_icmpv6_type133
;
1554 *type
= "Router Advertisement";
1555 *optional
= dissect_icmpv6_type134
;
1558 *type
= "Neighbor Solicitation";
1559 *optional
= dissect_icmpv6_type135
;
1562 *type
= "Neighbor Advertisement";
1563 *optional
= dissect_icmpv6_type136
;
1566 *type
= "Redirect Message";
1567 *optional
= dissect_icmpv6_type137
;
1570 *type
= "Router Renumbering";
1571 if(icmpv6_type_138_codes(icmp
->h_code
))
1572 *code
= icmpv6_type_138_codes(icmp
->h_code
);
1573 *optional
= dissect_icmpv6_type138
;
1576 *type
= "ICMP Node Information Query";
1577 if (icmpv6_code_range_valid(icmp
->h_code
,
1578 icmpv6_type_139_codes
))
1579 *code
= icmpv6_type_139_codes
[icmp
->h_code
];
1580 *optional
= dissect_icmpv6_type139
;
1583 *type
= "ICMP Node Information Response";
1584 if (icmpv6_code_range_valid(icmp
->h_code
,
1585 icmpv6_type_140_codes
))
1586 *code
= icmpv6_type_140_codes
[icmp
->h_code
];
1587 *optional
= dissect_icmpv6_type140
;
1590 *type
= "Inverse Neighbor Discovery Solicitation Message";
1591 *optional
= dissect_icmpv6_type141
;
1594 *type
= "Inverse Neighbor Discovery Advertisement Message";
1595 *optional
= dissect_icmpv6_type142
;
1598 *type
= "Multicast Listener Report v2";
1599 *optional
= dissect_icmpv6_type143
;
1602 *type
= "Home Agent Address Discovery Request Message";
1603 *optional
= dissect_icmpv6_type144
;
1606 *type
= "Home Agent Address Discovery Reply Message";
1607 *optional
= dissect_icmpv6_type145
;
1610 *type
= "Mobile Prefix Solicitation";
1611 *optional
= dissect_icmpv6_type146
;
1614 *type
= "Mobile Prefix Advertisement";
1615 *optional
= dissect_icmpv6_type147
;
1618 *type
= "Certification Path Solicitation";
1619 *optional
= dissect_icmpv6_type148
;
1622 *type
= "Certification Path Advertisement";
1623 *optional
= dissect_icmpv6_type149
;
1626 *type
= "ICMP messages utilized by experimental mobility "
1627 "protocols such as Seamoby";
1628 *optional
= dissect_icmpv6_type150
;
1631 *type
= "Multicast Router Advertisement";
1632 *code
= "Ad. Interval";
1633 *optional
= dissect_icmpv6_type151
;
1636 *type
= "Multicast Router Solicitation";
1638 *optional
= dissect_icmpv6_type152
;
1641 *type
= "Multicast Router Termination";
1643 *optional
= dissect_icmpv6_type153
;
1646 *type
= "FMIPv6 Messages";
1647 *optional
= dissect_icmpv6_type154
;
1650 *type
= "RPL Control Message";
1651 if(icmpv6_type_155_codes(icmp
->h_code
))
1652 *code
= icmpv6_type_155_codes(icmp
->h_code
);
1655 *type
= "Private experimation";
1658 *type
= "Private experimation";
1661 *type
= "Reserved for expansion of ICMPv6 error messages";
1666 static void icmpv6(struct pkt_buff
*pkt
)
1668 const char *type
= NULL
, *code
= NULL
;
1669 int8_t (*optional
)(struct pkt_buff
*pkt
) = NULL
;
1670 struct icmpv6_general_hdr
*icmp
=
1671 (struct icmpv6_general_hdr
*) pkt_pull(pkt
, sizeof(*icmp
));
1676 icmpv6_process(icmp
, &type
, &code
, &optional
);
1678 tprintf(" [ ICMPv6 ");
1679 tprintf("%s (%u), ", type
, icmp
->h_type
);
1680 tprintf("%s (%u), ", code
, icmp
->h_code
);
1681 tprintf("Chks (0x%x)", ntohs(icmp
->h_chksum
));
1683 if (!((*optional
) (pkt
)))
1684 tprintf("\n%s%s%s", colorize_start_full(black
, red
),
1685 "Failed to dissect Message", colorize_end());
1689 static void icmpv6_less(struct pkt_buff
*pkt
)
1691 struct icmpv6_general_hdr
*icmp
=
1692 (struct icmpv6_general_hdr
*) pkt_pull(pkt
, sizeof(*icmp
));
1697 tprintf(" ICMPv6 Type (%u) Code (%u)", icmp
->h_type
, icmp
->h_code
);
1700 struct protocol icmpv6_ops
= {
1702 .print_full
= icmpv6
,
1703 .print_less
= icmpv6_less
,