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>
21 #include "dissector_eth.h"
25 #define icmpv6_code_range_valid(code, sarr) ((code) < array_size((sarr)))
27 struct icmpv6_general_hdr
{
33 /* for type 0x01 and 0x03 */
34 struct icmpv6_type_1_3
{
36 uint8_t invoking_pkt
[0];
39 struct icmpv6_type_2
{
41 uint8_t invoking_pkt
[0];
44 struct icmpv6_type_4
{
46 uint8_t invoking_pkt
[0];
49 struct icmpv6_type_128_129
{
56 struct icmpv6_type_130_131_132
{
59 struct in6_addr ipv6_addr
;
63 struct icmpv6_type_130_mldv2
{
67 struct in6_addr ipv6_addr
[0];
70 /* Neighbor Discovery msg */
71 struct icmpv6_type_133_141_142
{
76 struct icmpv6_type_134
{
77 uint8_t cur_hop_limit
;
79 uint16_t router_lifetime
;
80 uint32_t reachable_time
;
81 uint32_t retrans_timer
;
85 struct icmpv6_type_135
{
87 struct in6_addr ipv6_addr
;
91 struct icmpv6_type_136
{
93 struct in6_addr ipv6_addr
;
97 struct icmpv6_type_137
{
99 struct in6_addr ipv6_targ_addr
;
100 struct in6_addr ipv6_dest_addr
;
104 struct icmpv6_neighb_disc_ops_general
{
110 struct icmpv6_neighb_disc_ops_type_1_2
{
111 uint8_t link_lay_addr
[0];
114 struct icmpv6_neighb_disc_ops_type_3
{
117 uint32_t valid_lifetime
;
118 uint32_t preferred_lifetime
;
120 struct in6_addr prefix
;
123 struct icmpv6_neighb_disc_ops_type_4
{
126 uint8_t ip_hdr_data
[0];
129 struct icmpv6_neighb_disc_ops_type_5
{
134 struct icmpv6_neighb_disc_ops_type_9_10
{
137 uint8_t ip_hdr_data
[0];
140 struct icmpv6_neighb_disc_ops_type_15
{
147 struct icmpv6_neighb_disc_ops_type_16
{
154 struct icmpv6_neighb_disc_ops_type_17
{
160 struct icmpv6_neighb_disc_ops_type_17_1
{
162 struct in6_addr ipv6_addr
;
165 struct icmpv6_neighb_disc_ops_type_17_2
{
166 struct in6_addr ipv6_addr
;
169 struct icmpv6_neighb_disc_ops_type_19
{
173 /* end Neighbor Discovery msg */
175 struct icmpv6_type_138
{
183 /* Node Information Queries */
184 struct icmpv6_type_139_140
{
190 /* end Node Information Queries */
193 struct icmpv6_type_143
{
199 struct icmpv6_mldv2_addr_rec
{
201 uint8_t aux_data_len
;
203 struct in6_addr multic_addr
;
204 struct in6_addr src_addr
[0];
206 /* end MLDv2 report */
208 /* ICMP Mobility Support */
209 struct icmpv6_type_144_146
{
214 struct icmpv6_type_145
{
217 struct in6_addr home_agent_addr
[0];
220 struct icmpv6_type_147
{
225 /* end ICMP Mobility Support */
227 /* SEcure Neighbor Discovery */
228 struct icmpv6_type_148
{
234 struct icmpv6_type_149
{
241 /* end SEcure Neighbor Discovery */
243 struct icmpv6_type_150
{
245 uint32_t subtype_res
;
247 #if defined(__LITTLE_ENDIAN_BITFIELD)
250 #elif defined(__BIG_ENDIAN_BITFIELD)
254 # error "Please fix <asm/byteorder.h>"
261 /* Multicast Router Discovery */
262 struct icmpv6_type_151
{
267 struct icmpv6_type_152
{
271 struct icmpv6_type_153
{
274 /* end Multicast Router Discovery */
276 struct icmpv6_type_154
{
283 static int8_t print_ipv6_addr_list(struct pkt_buff
*pkt
, uint8_t nr_addr
)
285 char address
[INET6_ADDRSTRLEN
];
286 struct in6_addr
*addr
;
289 addr
= (struct in6_addr
*) pkt_pull(pkt
, sizeof(*addr
));
293 tprintf("\n\t Address: %s",
294 inet_ntop(AF_INET6
, addr
, address
,
301 static const char *icmpv6_mcast_rec_types
[] = {
304 "CHANGE_TO_INCLUDE_MODE",
305 "CHANGE_TO_EXCLUDE_MODE",
310 static int8_t dissect_icmpv6_mcast_rec(struct pkt_buff
*pkt
,
313 uint16_t nr_src
, aux_data_len_bytes
;
314 char address
[INET6_ADDRSTRLEN
];
315 struct icmpv6_mldv2_addr_rec
*addr_rec
;
318 addr_rec
= (struct icmpv6_mldv2_addr_rec
*)
319 pkt_pull(pkt
,sizeof(*addr_rec
));
320 if (addr_rec
== NULL
)
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 if (aux_data_len_bytes
> pkt_len(pkt
)) {
331 tprintf(", Aux Data Len (%u, %u bytes) %s",
332 addr_rec
->aux_data_len
,
334 colorize_start_full(black
, red
) "invalid"
338 tprintf(", Aux Data Len (%u, %u bytes)",addr_rec
->aux_data_len
,
340 tprintf(", Nr. of Sources (%u)",nr_src
);
341 tprintf(", Address: %s",
342 inet_ntop(AF_INET6
, &addr_rec
->multic_addr
,
343 address
, sizeof(address
)));
345 if(!print_ipv6_addr_list(pkt
, nr_src
))
348 if (aux_data_len_bytes
> pkt_len(pkt
)) {
349 tprintf("\nAux Data Len %s",
350 colorize_start_full(black
, red
) "invalid"
355 tprintf(", Aux Data: ");
356 while (aux_data_len_bytes
--) {
357 tprintf("%x", *pkt_pull(pkt
,1));
364 static int8_t dissect_neighb_disc_ops_1(struct pkt_buff
*pkt
,
367 struct icmpv6_neighb_disc_ops_type_1_2
*icmp_neighb_disc_1
;
369 icmp_neighb_disc_1
= (struct icmpv6_neighb_disc_ops_type_1_2
*)
370 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_1
));
371 if (icmp_neighb_disc_1
== NULL
)
373 len
-= sizeof(*icmp_neighb_disc_1
);
377 tprintf("Address 0x");
380 tprintf("%x", *pkt_pull(pkt
,1));
386 static int8_t dissect_neighb_disc_ops_2(struct pkt_buff
*pkt
,
389 return dissect_neighb_disc_ops_1(pkt
, len
);
392 static int8_t dissect_neighb_disc_ops_3(struct pkt_buff
*pkt
,
395 char address
[INET6_ADDRSTRLEN
];
396 struct icmpv6_neighb_disc_ops_type_3
*icmp_neighb_disc_3
;
398 icmp_neighb_disc_3
= (struct icmpv6_neighb_disc_ops_type_3
*)
399 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_3
));
400 if (icmp_neighb_disc_3
== NULL
)
402 len
-= sizeof(*icmp_neighb_disc_3
);
406 tprintf("Prefix Len (%u) ",icmp_neighb_disc_3
->prefix_len
);
407 tprintf("L (%u) A (%u) Res1 (0x%x) ",icmp_neighb_disc_3
->l_a_res1
>> 7,
408 (icmp_neighb_disc_3
->l_a_res1
>> 7) & 0x1,
409 icmp_neighb_disc_3
->l_a_res1
& 0x3F);
410 tprintf("Valid Lifetime (%us) ",
411 ntohl(icmp_neighb_disc_3
->valid_lifetime
));
412 tprintf("Preferred Lifetime (%us) ",
413 ntohl(icmp_neighb_disc_3
->preferred_lifetime
));
414 tprintf("Reserved2 (0x%x) ",
415 ntohl(icmp_neighb_disc_3
->res2
));
416 tprintf("Prefix: %s ",
417 inet_ntop(AF_INET6
,&icmp_neighb_disc_3
->prefix
,
418 address
, sizeof(address
)));
423 static int8_t dissect_neighb_disc_ops_4(struct pkt_buff
*pkt
,
426 struct icmpv6_neighb_disc_ops_type_4
*icmp_neighb_disc_4
;
428 icmp_neighb_disc_4
= (struct icmpv6_neighb_disc_ops_type_4
*)
429 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_4
));
430 if (icmp_neighb_disc_4
== NULL
)
432 len
-= sizeof(*icmp_neighb_disc_4
);
436 tprintf("Reserved 1 (0x%x) ", ntohs(icmp_neighb_disc_4
->res1
));
437 tprintf("Reserved 2 (0x%x) ", ntohl(icmp_neighb_disc_4
->res2
));
438 tprintf("IP header + data ");
441 tprintf("%x", *pkt_pull(pkt
,1));
447 static int8_t dissect_neighb_disc_ops_5(struct pkt_buff
*pkt
,
450 struct icmpv6_neighb_disc_ops_type_5
*icmp_neighb_disc_5
;
452 icmp_neighb_disc_5
= (struct icmpv6_neighb_disc_ops_type_5
*)
453 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_5
));
454 if (icmp_neighb_disc_5
== NULL
)
456 len
-= sizeof(*icmp_neighb_disc_5
);
460 tprintf("Reserved (0x%x) ", ntohs(icmp_neighb_disc_5
->res1
));
461 tprintf("MTU (%u)", ntohl(icmp_neighb_disc_5
->MTU
));
466 static int8_t dissect_neighb_disc_ops_9(struct pkt_buff
*pkt
,
469 struct icmpv6_neighb_disc_ops_type_9_10
*icmp_neighb_disc_9
;
471 icmp_neighb_disc_9
= (struct icmpv6_neighb_disc_ops_type_9_10
*)
472 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_9
));
473 if (icmp_neighb_disc_9
== NULL
)
475 len
-= sizeof(*icmp_neighb_disc_9
);
479 tprintf("Reserved 1 (0x%x) ", ntohs(icmp_neighb_disc_9
->res1
));
480 tprintf("Reserved 2 (0x%x) ", ntohl(icmp_neighb_disc_9
->res2
));
482 return print_ipv6_addr_list(pkt
, len
/ sizeof(struct in6_addr
));
485 static int8_t dissect_neighb_disc_ops_10(struct pkt_buff
*pkt
,
488 return dissect_neighb_disc_ops_9(pkt
, len
);
491 static const char *icmpv6_neighb_disc_ops_15_name
[] = {
492 "DER Encoded X.501 Name",
496 static int8_t dissect_neighb_disc_ops_15(struct pkt_buff
*pkt
,
501 struct icmpv6_neighb_disc_ops_type_15
*icmp_neighb_disc_15
;
503 icmp_neighb_disc_15
= (struct icmpv6_neighb_disc_ops_type_15
*)
504 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_15
));
505 if (icmp_neighb_disc_15
== NULL
)
507 len
-= sizeof(*icmp_neighb_disc_15
);
510 pad_len
= icmp_neighb_disc_15
->pad_len
;
512 tprintf("Name Type %s (%u) ",
513 icmpv6_code_range_valid(icmp_neighb_disc_15
->name_type
- 1,
514 icmpv6_neighb_disc_ops_15_name
) ?
515 icmpv6_neighb_disc_ops_15_name
[
516 icmp_neighb_disc_15
->name_type
- 1] : "Unknown",
517 icmp_neighb_disc_15
->name_type
);
519 tprintf("Pad Len (%u, invalid)\n%s", pad_len
,
520 colorize_start_full(black
, red
)
521 "Skip Option" colorize_end());
526 tprintf("Pad Len (%u) ", pad_len
);
528 name_len
= len
- pad_len
;
532 tprintf("%c", *pkt_pull(pkt
,1));
536 tprintf("Padding (");
539 tprintf("%x", *pkt_pull(pkt
,1));
546 static const char *icmpv6_neighb_disc_ops_16_cert
[] = {
547 "X.509v3 Certificate",
550 static int8_t dissect_neighb_disc_ops_16(struct pkt_buff
*pkt
,
553 struct icmpv6_neighb_disc_ops_type_16
*icmp_neighb_disc_16
;
555 icmp_neighb_disc_16
= (struct icmpv6_neighb_disc_ops_type_16
*)
556 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_16
));
557 if (icmp_neighb_disc_16
== NULL
)
559 len
-= sizeof(*icmp_neighb_disc_16
);
563 tprintf("Cert Type %s (%u) ",
564 icmpv6_code_range_valid(icmp_neighb_disc_16
->cert_type
- 1,
565 icmpv6_neighb_disc_ops_16_cert
) ?
566 icmpv6_neighb_disc_ops_16_cert
[
567 icmp_neighb_disc_16
->cert_type
- 1] : "Unknown",
568 icmp_neighb_disc_16
->cert_type
);
569 tprintf("Res (0x%x) ", icmp_neighb_disc_16
->res
);
571 tprintf("Certificate + Padding (");
573 tprintf("%x", *pkt_pull(pkt
,1));
580 static const char *icmpv6_neighb_disc_ops_17_codes
[] = {
581 "Old Care-of Address",
582 "New Care-of Address",
587 static int8_t dissect_neighb_disc_ops_17(struct pkt_buff
*pkt
,
590 char address
[INET6_ADDRSTRLEN
];
591 struct icmpv6_neighb_disc_ops_type_17
*icmp_neighb_disc_17
;
593 icmp_neighb_disc_17
= (struct icmpv6_neighb_disc_ops_type_17
*)
594 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_17
));
595 if (icmp_neighb_disc_17
== NULL
)
597 len
-= sizeof(*icmp_neighb_disc_17
);
601 tprintf("Opt Code %s (%u) ",
602 icmpv6_code_range_valid(icmp_neighb_disc_17
->opt_code
- 1,
603 icmpv6_neighb_disc_ops_17_codes
) ?
604 icmpv6_neighb_disc_ops_17_codes
[
605 icmp_neighb_disc_17
->opt_code
- 1] : "Unknown",
606 icmp_neighb_disc_17
->opt_code
);
607 tprintf("Prefix Len (%u) ", icmp_neighb_disc_17
->prefix_len
);
609 if (len
== sizeof(struct icmpv6_neighb_disc_ops_type_17_1
)) {
610 struct icmpv6_neighb_disc_ops_type_17_1
611 *icmp_neighb_disc_17_1
;
613 icmp_neighb_disc_17_1
=
614 (struct icmpv6_neighb_disc_ops_type_17_1
*)
615 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_17_1
));
616 if (icmp_neighb_disc_17_1
== NULL
)
618 len
-= sizeof(*icmp_neighb_disc_17_1
);
622 tprintf("Res (0x%x) ",icmp_neighb_disc_17_1
->res
);
624 inet_ntop(AF_INET6
,&icmp_neighb_disc_17_1
->ipv6_addr
,
625 address
, sizeof(address
)));
627 else if (len
== sizeof(struct icmpv6_neighb_disc_ops_type_17_2
)) {
628 struct icmpv6_neighb_disc_ops_type_17_2
629 *icmp_neighb_disc_17_2
;
631 icmp_neighb_disc_17_2
=
632 (struct icmpv6_neighb_disc_ops_type_17_2
*)
633 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_17_2
));
634 if (icmp_neighb_disc_17_2
== NULL
)
636 len
-= sizeof(*icmp_neighb_disc_17_2
);
641 inet_ntop(AF_INET6
,&icmp_neighb_disc_17_2
->ipv6_addr
,
642 address
, sizeof(address
)));
645 tprintf("%s (", colorize_start_full(black
, red
)
646 "Error Wrong Length. Skip Option" colorize_end());
648 tprintf("%x", *pkt_pull(pkt
,1));
656 static const char *icmpv6_neighb_disc_ops_19_codes
[] = {
657 "Wildcard requesting resolution for all nearby access points",
658 "Link-Layer Address of the New Access Point",
659 "Link-Layer Address of the MN",
660 "Link-Layer Address of the NAR",
661 "Link-Layer Address of the source of RtSolPr or PrRtAdv \
663 "The access point identified by the LLA belongs to the \
664 current interface of the router",
665 "No prefix information available for the access point \
666 identified by the LLA",
667 "No fast handover support available for the access point \
668 identified by the LLA",
671 static int8_t dissect_neighb_disc_ops_19(struct pkt_buff
*pkt
,
674 struct icmpv6_neighb_disc_ops_type_19
*icmp_neighb_disc_19
;
676 icmp_neighb_disc_19
= (struct icmpv6_neighb_disc_ops_type_19
*)
677 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_19
));
678 if (icmp_neighb_disc_19
== NULL
)
680 len
-= sizeof(*icmp_neighb_disc_19
);
684 tprintf("Opt Code %s (%u) ",
685 icmpv6_code_range_valid(icmp_neighb_disc_19
->opt_code
,
686 icmpv6_neighb_disc_ops_19_codes
) ?
687 icmpv6_neighb_disc_ops_19_codes
[
688 icmp_neighb_disc_19
->opt_code
] : "Unknown",
689 icmp_neighb_disc_19
->opt_code
);
693 tprintf("%x", *pkt_pull(pkt
,1));
700 static inline char *icmpv6_neighb_disc_ops(uint8_t code
) {
702 case 1: return "Source Link-Layer Address";
703 case 2: return "Target Link-Layer Address";
704 case 3: return "Prefix Information";
705 case 4: return "Redirected Header";
706 case 5: return "MTU";
707 case 6: return "NBMA Shortcut Limit Option";
708 case 7: return "Advertisement Interval Option";
709 case 8: return "Home Agent Information Option";
710 case 9: return "Source Address List";
711 case 10: return "Target Address List";
712 case 11: return "CGA option";
713 case 12: return "RSA Signature option";
714 case 13: return "Timestamp option";
715 case 14: return "Nonce option";
716 case 15: return "Trust Anchor option";
717 case 16: return "Certificate option";
718 case 17: return "IP Address/Prefix Option";
719 case 18: return "New Router Prefix Information Option";
720 case 19: return "Link-layer Address Option";
721 case 20: return "Neighbor Advertisement Acknowledgment Option";
723 case 23: return "Prefix Information";
724 case 24: return "Redirected Header";
725 case 25: return "MTU";
726 case 26: return "NBMA Shortcut Limit Option";
727 case 27: return "Advertisement Interval Option";
728 case 28: return "Home Agent Information Option";
729 case 29: return "Source Address List";
730 case 30: return "Target Address List";
731 case 31: return "DNS Search List Option";
732 case 32: return "Proxy Signature (PS)";
734 case 138: return "CARD Request option";
735 case 139: return "CARD Reply option";
737 case 253: return "RFC3692-style Experiment 1";
738 case 254: return "RFC3692-style Experiment 2";
744 static int8_t dissect_neighb_disc_ops(struct pkt_buff
*pkt
)
747 uint16_t ops_total_len
;
748 ssize_t ops_payl_len
;
749 struct icmpv6_neighb_disc_ops_general
*icmp_neighb_disc
;
751 while(pkt_len(pkt
)) {
752 icmp_neighb_disc
= (struct icmpv6_neighb_disc_ops_general
*)
753 pkt_pull(pkt
,sizeof(*icmp_neighb_disc
));
754 if (icmp_neighb_disc
== NULL
)
757 ops_total_len
= icmp_neighb_disc
->len
* 8;
758 pad_bytes
= (size_t) (ops_total_len
% 8);
759 ops_payl_len
= ops_total_len
- sizeof(*icmp_neighb_disc
) -
762 tprintf("\n\tOption %s (%u) ",
763 icmpv6_neighb_disc_ops(icmp_neighb_disc
->type
) ?
764 icmpv6_neighb_disc_ops(icmp_neighb_disc
->type
)
765 : "Type Unknown", icmp_neighb_disc
->type
);
766 if (ops_payl_len
> pkt_len(pkt
) || ops_payl_len
< 0) {
767 tprintf("Length (%u, %u bytes, %s%s%s) ",
768 icmp_neighb_disc
->len
,
770 colorize_start_full(black
, red
),
771 "invalid", colorize_end());
775 tprintf("Length (%u, %u bytes) ",icmp_neighb_disc
->len
,
778 switch (icmp_neighb_disc
->type
) {
780 if (!dissect_neighb_disc_ops_1(pkt
, ops_payl_len
))
784 if (!dissect_neighb_disc_ops_2(pkt
, ops_payl_len
))
788 if (!dissect_neighb_disc_ops_3(pkt
, ops_payl_len
))
792 if (!dissect_neighb_disc_ops_4(pkt
, ops_payl_len
))
796 if (!dissect_neighb_disc_ops_5(pkt
, ops_payl_len
))
799 /* Type 9 and 10 defined in
800 * http://tools.ietf.org/html/rfc3122#section-3.1
803 if (!dissect_neighb_disc_ops_9(pkt
, ops_payl_len
))
807 if (!dissect_neighb_disc_ops_10(pkt
, ops_payl_len
))
810 /* Type 15 and 16 defined in
811 * http://tools.ietf.org/html/rfc3971#section-6.4.3
812 * http://tools.ietf.org/html/rfc3971#section-6.4.4
815 if (!dissect_neighb_disc_ops_15(pkt
, ops_payl_len
))
819 if (!dissect_neighb_disc_ops_16(pkt
, ops_payl_len
))
822 /* Type 17 and 19 defined in
823 * http://tools.ietf.org/html/rfc5568#section-6.4
826 if (!dissect_neighb_disc_ops_17(pkt
, ops_payl_len
))
830 if (!dissect_neighb_disc_ops_19(pkt
, ops_payl_len
))
834 pkt_pull(pkt
, ops_payl_len
);
837 /* Skip Padding Bytes */
838 if (pad_bytes
> pkt_len(pkt
)) {
839 tprintf(" %s",colorize_start_full(black
, red
)
840 "Invalid Padding" colorize_end());
843 pkt_pull(pkt
, pad_bytes
);
849 static const char *icmpv6_type_1_codes
[] = {
850 "No route to destination",
851 "Communication with destination administratively prohibited",
852 "Beyond scope of source address",
853 "Address unreachable",
855 "Source address failed ingress/egress policy",
856 "Reject route to destination",
857 "Error in Source Routing Header",
860 static int8_t dissect_icmpv6_type1(struct pkt_buff
*pkt
)
862 struct icmpv6_type_1_3
*icmp_1
;
864 icmp_1
= (struct icmpv6_type_1_3
*) pkt_pull(pkt
,sizeof(*icmp_1
));
868 tprintf(", Unused (0x%x)",ntohl(icmp_1
->unused
));
869 tprintf(" Payload include as much of invoking packet");
874 static int8_t dissect_icmpv6_type2(struct pkt_buff
*pkt
)
876 struct icmpv6_type_2
*icmp_2
;
878 icmp_2
= (struct icmpv6_type_2
*) pkt_pull(pkt
,sizeof(*icmp_2
));
882 tprintf(", MTU (0x%x)",ntohl(icmp_2
->MTU
));
883 tprintf(" Payload include as much of invoking packet");
888 static const char *icmpv6_type_3_codes
[] = {
889 "Hop limit exceeded in transit",
890 "Fragment reassembly time exceeded",
893 static int8_t dissect_icmpv6_type3(struct pkt_buff
*pkt
)
895 struct icmpv6_type_1_3
*icmp_3
;
897 icmp_3
= (struct icmpv6_type_1_3
*) pkt_pull(pkt
,sizeof(*icmp_3
));
901 tprintf(", Unused (0x%x)",ntohl(icmp_3
->unused
));
902 tprintf(" Payload include as much of invoking packet");
907 static const char *icmpv6_type_4_codes
[] = {
908 "Erroneous header field encountered",
909 "Unrecognized Next Header type encountered",
910 "Unrecognized IPv6 option encountered",
913 static int8_t dissect_icmpv6_type4(struct pkt_buff
*pkt
)
915 struct icmpv6_type_4
*icmp_4
;
917 icmp_4
= (struct icmpv6_type_4
*) pkt_pull(pkt
,sizeof(*icmp_4
));
921 tprintf(", Pointer (0x%x)",ntohl(icmp_4
->pointer
));
922 tprintf(" Payload include as much of invoking packet");
927 static int8_t dissect_icmpv6_type128(struct pkt_buff
*pkt
)
929 struct icmpv6_type_128_129
*icmp_128
;
931 icmp_128
= (struct icmpv6_type_128_129
*)
932 pkt_pull(pkt
,sizeof(*icmp_128
));
933 if (icmp_128
== NULL
)
936 tprintf(", ID (0x%x)",ntohs(icmp_128
->id
));
937 tprintf(", Seq. Nr. (%u)",ntohs(icmp_128
->sn
));
938 tprintf(" Payload include Data");
943 static int8_t dissect_icmpv6_type129(struct pkt_buff
*pkt
)
945 struct icmpv6_type_128_129
*icmp_129
;
947 icmp_129
= (struct icmpv6_type_128_129
*)
948 pkt_pull(pkt
,sizeof(*icmp_129
));
949 if (icmp_129
== NULL
)
952 tprintf(", ID (0x%x)",ntohs(icmp_129
->id
));
953 tprintf(", Seq. Nr. (%u)",ntohs(icmp_129
->sn
));
954 tprintf(" Payload include Data");
959 static int8_t dissect_icmpv6_type130(struct pkt_buff
*pkt
)
961 char address
[INET6_ADDRSTRLEN
];
962 uint16_t nr_src
, maxrespdel
;
963 uint8_t switch_mldv2
= 0;
964 struct icmpv6_type_130_131_132
*icmp_130
;
966 icmp_130
= (struct icmpv6_type_130_131_132
*)
967 pkt_pull(pkt
,sizeof(*icmp_130
));
968 if (icmp_130
== NULL
)
970 maxrespdel
= ntohs(icmp_130
->maxrespdel
);
972 if(pkt_len(pkt
) >= sizeof(struct icmpv6_type_130_mldv2
))
976 tprintf(", MLDv2, Max Resp Delay (%ums)", maxrespdel
>> 15 ?
977 (((maxrespdel
& 0xFFF) | 0x1000) <<
978 (((maxrespdel
>> 12) & 0x3) + 3)) : maxrespdel
);
980 tprintf(", Max Resp Delay (%ums)",maxrespdel
);
981 tprintf(", Res (0x%x)",ntohs(icmp_130
->res
));
982 tprintf(", Address: %s",
983 inet_ntop(AF_INET6
, &icmp_130
->ipv6_addr
,
984 address
, sizeof(address
)));
987 struct icmpv6_type_130_mldv2
*icmp_130_mldv2
;
989 icmp_130_mldv2
= (struct icmpv6_type_130_mldv2
*)
990 pkt_pull(pkt
,sizeof(*icmp_130_mldv2
));
991 if (icmp_130_mldv2
== NULL
)
994 nr_src
= ntohs(icmp_130_mldv2
->nr_src
);
996 tprintf(", Resv (0x%x)",icmp_130_mldv2
->resv_S_QRV
>> 4);
997 tprintf(", S (%u)",(icmp_130_mldv2
->resv_S_QRV
>> 3) & 0x1);
998 tprintf(", QRV (0x%x)",icmp_130_mldv2
->resv_S_QRV
& 0x3);
999 tprintf(", QQIC (%u)",icmp_130_mldv2
->QQIC
);
1000 tprintf(", Nr Src (%u)",nr_src
);
1002 return print_ipv6_addr_list(pkt
, nr_src
);
1008 static int8_t dissect_icmpv6_type131(struct pkt_buff
*pkt
)
1010 char address
[INET6_ADDRSTRLEN
];
1011 struct icmpv6_type_130_131_132
*icmp_131
;
1013 icmp_131
= (struct icmpv6_type_130_131_132
*)
1014 pkt_pull(pkt
,sizeof(*icmp_131
));
1015 if (icmp_131
== NULL
)
1018 tprintf(", Max Resp Delay (%ums)",ntohs(icmp_131
->maxrespdel
));
1019 tprintf(", Res (0x%x)",ntohs(icmp_131
->res
));
1020 tprintf(", Address: %s",
1021 inet_ntop(AF_INET6
, &icmp_131
->ipv6_addr
,
1022 address
, sizeof(address
)));
1027 static inline int8_t dissect_icmpv6_type132(struct pkt_buff
*pkt
)
1029 return dissect_icmpv6_type131(pkt
);
1032 static int8_t dissect_icmpv6_type133(struct pkt_buff
*pkt
)
1034 struct icmpv6_type_133_141_142
*icmp_133
;
1036 icmp_133
= (struct icmpv6_type_133_141_142
*)
1037 pkt_pull(pkt
,sizeof(*icmp_133
));
1038 if (icmp_133
== NULL
)
1041 tprintf(", Reserved (0x%x)",ntohl(icmp_133
->res
));
1043 return dissect_neighb_disc_ops(pkt
);
1046 static int8_t dissect_icmpv6_type134(struct pkt_buff
*pkt
)
1048 struct icmpv6_type_134
*icmp_134
;
1050 icmp_134
= (struct icmpv6_type_134
*)
1051 pkt_pull(pkt
,sizeof(*icmp_134
));
1052 if (icmp_134
== NULL
)
1055 tprintf(", Cur Hop Limit (%u)",icmp_134
->cur_hop_limit
);
1056 tprintf(", M (%u) O (%u)",icmp_134
->m_o_res
>> 7,
1057 (icmp_134
->m_o_res
>> 6) & 0x1);
1058 tprintf(", Router Lifetime (%us)",ntohs(icmp_134
->router_lifetime
));
1059 tprintf(", Reachable Time (%ums)",ntohl(icmp_134
->reachable_time
));
1060 tprintf(", Retrans Timer (%ums)",ntohl(icmp_134
->retrans_timer
));
1062 return dissect_neighb_disc_ops(pkt
);
1065 static int8_t dissect_icmpv6_type135(struct pkt_buff
*pkt
)
1067 char address
[INET6_ADDRSTRLEN
];
1068 struct icmpv6_type_135
*icmp_135
;
1070 icmp_135
= (struct icmpv6_type_135
*)
1071 pkt_pull(pkt
,sizeof(*icmp_135
));
1072 if (icmp_135
== NULL
)
1075 tprintf(", Reserved (0x%x)",ntohl(icmp_135
->res
));
1076 tprintf(", Target Address: %s",
1077 inet_ntop(AF_INET6
, &icmp_135
->ipv6_addr
,
1078 address
, sizeof(address
)));
1080 return dissect_neighb_disc_ops(pkt
);
1083 static int8_t dissect_icmpv6_type136(struct pkt_buff
*pkt
)
1085 char address
[INET6_ADDRSTRLEN
];
1087 struct icmpv6_type_136
*icmp_136
;
1089 icmp_136
= (struct icmpv6_type_136
*)
1090 pkt_pull(pkt
,sizeof(*icmp_136
));
1091 if (icmp_136
== NULL
)
1093 r_s_o_res
= ntohl(icmp_136
->r_s_o_res
);
1095 tprintf(", R (%u) S (%u) O (%u) Reserved (0x%x)", r_s_o_res
>> 31,
1096 (r_s_o_res
>> 30) & 0x1, (r_s_o_res
>> 29) & 0x1,
1097 r_s_o_res
& 0x1FFFFFFF);
1098 tprintf(", Target Address: %s",
1099 inet_ntop(AF_INET6
, &icmp_136
->ipv6_addr
,
1100 address
, sizeof(address
)));
1102 return dissect_neighb_disc_ops(pkt
);
1105 static int8_t dissect_icmpv6_type137(struct pkt_buff
*pkt
)
1107 char address
[INET6_ADDRSTRLEN
];
1108 struct icmpv6_type_137
*icmp_137
;
1110 icmp_137
= (struct icmpv6_type_137
*)
1111 pkt_pull(pkt
,sizeof(*icmp_137
));
1112 if (icmp_137
== NULL
)
1115 tprintf(", Reserved (0x%x)",icmp_137
->res
);
1116 tprintf(", Target Address: %s",
1117 inet_ntop(AF_INET6
, &icmp_137
->ipv6_targ_addr
,
1118 address
, sizeof(address
)));
1119 tprintf(", Dest Address: %s",
1120 inet_ntop(AF_INET6
, &icmp_137
->ipv6_dest_addr
,
1121 address
, sizeof(address
)));
1123 return dissect_neighb_disc_ops(pkt
);
1126 static void dissect_icmpv6_rr_body(struct pkt_buff
*pkt
)
1129 * Upgrade Dissector for Message Body
1130 * from http://tools.ietf.org/html/rfc2894#section-3.2
1133 tprintf(" Message Body recognized");
1136 static inline char *icmpv6_type_138_codes(uint8_t code
) {
1138 case 1: return "Router Renumbering Command";
1139 case 2: return "Router Renumbering Result";
1140 case 255: return "Sequence Number Reset";
1146 static int8_t dissect_icmpv6_type138(struct pkt_buff
*pkt
)
1148 struct icmpv6_type_138
*icmp_138
;
1150 icmp_138
= (struct icmpv6_type_138
*)
1151 pkt_pull(pkt
,sizeof(*icmp_138
));
1152 if (icmp_138
== NULL
)
1155 tprintf(", Sequence Nr. (%u)",ntohl(icmp_138
->seq_nr
));
1156 tprintf(", Segment Nr. (%u)",icmp_138
->seg_nr
);
1157 tprintf(", T (%u) R (%u) A (%u) S (%u) P (%u) Res \
1158 (0x%x) ",icmp_138
->flags
>> 7, (icmp_138
->flags
>> 6) & 1,
1159 (icmp_138
->flags
>> 5) & 1, (icmp_138
->flags
>> 4) & 1,
1160 (icmp_138
->flags
>> 3) & 1, icmp_138
->flags
& 7);
1161 tprintf(", Max Delay (%ums)", ntohs(icmp_138
->maxdelay
));
1162 tprintf(", Res (0x%x)", ntohl(icmp_138
->res
));
1164 dissect_icmpv6_rr_body(pkt
);
1169 static void dissect_icmpv6_node_inf_data(struct pkt_buff
*pkt
)
1172 * Upgrade Dissector for Data field
1173 * http://tools.ietf.org/html/rfc4620#section-4
1176 tprintf(" Data recognized");
1179 static const char *icmpv6_node_inf_qtypes
[] = {
1187 static const char *icmpv6_type_139_codes
[] = {
1188 "Data contains IPv6 Address",
1189 "Data contains Name or nothing",
1190 "Data contains IPv4 Address",
1193 static int8_t dissect_icmpv6_type139(struct pkt_buff
*pkt
)
1195 const char *qtype_name
= "Unknown";
1197 struct icmpv6_type_139_140
*icmp_139
;
1199 icmp_139
= (struct icmpv6_type_139_140
*)
1200 pkt_pull(pkt
,sizeof(*icmp_139
));
1201 if (icmp_139
== NULL
)
1204 qtype_nr
= ntohs(icmp_139
->qtype
);
1205 if (icmpv6_code_range_valid(qtype_nr
, icmpv6_node_inf_qtypes
))
1206 qtype_name
= icmpv6_node_inf_qtypes
[qtype_nr
];
1208 tprintf(", Qtype %s (%u)", qtype_name
, qtype_nr
);
1209 tprintf(", Flags (0x%x)", ntohs(icmp_139
->flags
));
1210 tprintf(", Nonce (0x%x)", ntohll(icmp_139
->nonce
));
1212 dissect_icmpv6_node_inf_data(pkt
);
1217 static char *icmpv6_type_140_codes
[] = {
1218 "Successfull reply",
1219 "Responder refuses answer",
1220 "Qtype is unknown to the Responder",
1223 static inline int8_t dissect_icmpv6_type140(struct pkt_buff
*pkt
)
1225 return dissect_icmpv6_type139(pkt
);
1228 static inline int8_t dissect_icmpv6_type141(struct pkt_buff
*pkt
)
1230 return dissect_icmpv6_type133(pkt
);
1233 static inline int8_t dissect_icmpv6_type142(struct pkt_buff
*pkt
)
1235 return dissect_icmpv6_type133(pkt
);
1238 static int8_t dissect_icmpv6_type143(struct pkt_buff
*pkt
)
1241 struct icmpv6_type_143
*icmp_143
;
1243 icmp_143
= (struct icmpv6_type_143
*)
1244 pkt_pull(pkt
,sizeof(*icmp_143
));
1245 if (icmp_143
== NULL
)
1247 nr_rec
= ntohs(icmp_143
->nr_rec
);
1249 tprintf(", Res (0x%x)",ntohs(icmp_143
->res
));
1250 tprintf(", Nr. Mcast Addr Records (%u)",nr_rec
);
1252 return dissect_icmpv6_mcast_rec(pkt
, nr_rec
);
1255 static int8_t dissect_icmpv6_type144(struct pkt_buff
*pkt
)
1257 struct icmpv6_type_144_146
*icmp_144
;
1259 icmp_144
= (struct icmpv6_type_144_146
*)
1260 pkt_pull(pkt
,sizeof(*icmp_144
));
1261 if (icmp_144
== NULL
)
1264 tprintf(", ID (%u)",ntohs(icmp_144
->id
));
1265 tprintf(", Res (0x%x)",ntohs(icmp_144
->res
));
1270 static int8_t dissect_icmpv6_type145(struct pkt_buff
*pkt
)
1272 struct icmpv6_type_145
*icmp_145
;
1274 icmp_145
= (struct icmpv6_type_145
*)
1275 pkt_pull(pkt
,sizeof(*icmp_145
));
1276 if (icmp_145
== NULL
)
1279 tprintf(", ID (%u)",ntohs(icmp_145
->id
));
1280 tprintf(", Res (0x%x)",ntohs(icmp_145
->res
));
1282 return print_ipv6_addr_list(pkt
, pkt_len(pkt
) /
1283 sizeof(struct in6_addr
));
1286 static inline int8_t dissect_icmpv6_type146(struct pkt_buff
*pkt
)
1288 return dissect_icmpv6_type144(pkt
);
1291 static int8_t dissect_icmpv6_type147(struct pkt_buff
*pkt
)
1294 struct icmpv6_type_147
*icmp_147
;
1296 icmp_147
= (struct icmpv6_type_147
*)
1297 pkt_pull(pkt
,sizeof(*icmp_147
));
1298 if (icmp_147
== NULL
)
1300 m_o_res
= ntohs(icmp_147
->m_o_res
);
1302 tprintf(", ID (%u)",ntohs(icmp_147
->id
));
1303 tprintf(", M (%u) O (%u) Res (0x%x)",m_o_res
>> 15,
1304 (m_o_res
>> 14) & 1, m_o_res
& 0x3FFF);
1306 return dissect_neighb_disc_ops(pkt
);
1309 static int8_t dissect_icmpv6_type148(struct pkt_buff
*pkt
)
1311 struct icmpv6_type_148
*icmp_148
;
1313 icmp_148
= (struct icmpv6_type_148
*)
1314 pkt_pull(pkt
,sizeof(*icmp_148
));
1315 if (icmp_148
== NULL
)
1318 tprintf(", ID (%u)",ntohs(icmp_148
->id
));
1319 tprintf(", Component (%u)",ntohs(icmp_148
->comp
));
1321 return dissect_neighb_disc_ops(pkt
);
1324 static int8_t dissect_icmpv6_type149(struct pkt_buff
*pkt
)
1326 struct icmpv6_type_149
*icmp_149
;
1328 icmp_149
= (struct icmpv6_type_149
*)
1329 pkt_pull(pkt
,sizeof(*icmp_149
));
1330 if (icmp_149
== NULL
)
1333 tprintf(", ID (%u)",ntohs(icmp_149
->id
));
1334 tprintf(", All Components (%u)",ntohs(icmp_149
->all_comp
));
1335 tprintf(", Component (%u)",ntohs(icmp_149
->comp
));
1336 tprintf(", Res (0x%x)",ntohs(icmp_149
->res
));
1338 return dissect_neighb_disc_ops(pkt
);
1341 static int8_t dissect_icmpv6_type150(struct pkt_buff
*pkt
)
1343 struct icmpv6_type_150
*icmp_150
;
1345 icmp_150
= (struct icmpv6_type_150
*)
1346 pkt_pull(pkt
,sizeof(*icmp_150
));
1347 if (icmp_150
== NULL
)
1350 tprintf(", Subtype (%u)",icmp_150
->subtype
);
1351 tprintf(", Res (0x%x)",icmp_150
->res
);
1352 tprintf(", Options in Payload");
1357 static int8_t dissect_icmpv6_type151(struct pkt_buff
*pkt
)
1359 struct icmpv6_type_151
*icmp_151
;
1361 icmp_151
= (struct icmpv6_type_151
*)
1362 pkt_pull(pkt
,sizeof(*icmp_151
));
1363 if (icmp_151
== NULL
)
1366 tprintf(", Query Interval (%us)",ntohs(icmp_151
->query_intv
));
1367 tprintf(", Robustness Variable (%u)",ntohs(icmp_151
->rob_var
));
1372 static int8_t dissect_icmpv6_type152(struct pkt_buff
*pkt
)
1374 struct icmpv6_type_152
*icmp_152
;
1376 icmp_152
= (struct icmpv6_type_152
*)
1377 pkt_pull(pkt
,sizeof(*icmp_152
));
1378 if (icmp_152
== NULL
)
1384 static int8_t dissect_icmpv6_type153(struct pkt_buff
*pkt
)
1386 struct icmpv6_type_153
*icmp_153
;
1388 icmp_153
= (struct icmpv6_type_153
*)
1389 pkt_pull(pkt
,sizeof(*icmp_153
));
1390 if (icmp_153
== NULL
)
1396 static int8_t dissect_icmpv6_type154(struct pkt_buff
*pkt
)
1398 struct icmpv6_type_154
*icmp_154
;
1400 icmp_154
= (struct icmpv6_type_154
*)
1401 pkt_pull(pkt
,sizeof(*icmp_154
));
1402 if (icmp_154
== NULL
)
1405 tprintf(", Subtype (%u)",icmp_154
->subtype
);
1406 tprintf(", Res (0x%x)",icmp_154
->res
);
1407 tprintf(", ID (%u)",ntohs(icmp_154
->id
));
1409 return dissect_neighb_disc_ops(pkt
);
1412 static inline char *icmpv6_type_155_codes(uint8_t code
) {
1414 case 0x00: return "DODAG Information Solicitation";
1415 case 0x01: return "DODAG Information Object";
1416 case 0x02: return "Destination Advertisement Object";
1417 case 0x03: return "Destination Advertisement Object Acknowledgment";
1418 case 0x80: return "Secure DODAG Information Solicitation";
1419 case 0x81: return "Secure DODAG Information Object";
1420 case 0x82: return "Secure Destination Advertisement Object";
1421 case 0x83: return "Secure Destination Advertisement Object Acknowledgment";
1422 case 0x8A: return "Consistency Check";
1428 static void icmpv6_process(struct icmpv6_general_hdr
*icmp
, const char **type
,
1429 const char **code
, int8_t (**optional
)(struct pkt_buff
*pkt
))
1431 *type
= "Unknown Type";
1432 *code
= "Unknown Code";
1434 switch (icmp
->h_type
) {
1436 *type
= "Destination Unreachable";
1437 if (icmpv6_code_range_valid(icmp
->h_code
, icmpv6_type_1_codes
))
1438 *code
= icmpv6_type_1_codes
[icmp
->h_code
];
1439 *optional
= dissect_icmpv6_type1
;
1442 *type
= "Packet Too Big";
1443 *optional
= dissect_icmpv6_type2
;
1446 *type
= "Time Exceeded";
1447 if (icmpv6_code_range_valid(icmp
->h_code
, icmpv6_type_3_codes
))
1448 *code
= icmpv6_type_3_codes
[icmp
->h_code
];
1449 *optional
= dissect_icmpv6_type3
;
1452 *type
= "Parameter Problem";
1453 if (icmpv6_code_range_valid(icmp
->h_code
, icmpv6_type_4_codes
))
1454 *code
= icmpv6_type_4_codes
[icmp
->h_code
];
1455 *optional
= dissect_icmpv6_type4
;
1458 *type
= "Private experimation";
1461 *type
= "Private experimation";
1464 *type
= "Reserved for expansion of ICMPv6 error messages";
1467 *type
= "Echo Request";
1468 *optional
= dissect_icmpv6_type128
;
1471 *type
= "Echo Reply";
1472 *optional
= dissect_icmpv6_type129
;
1475 *type
= "Multicast Listener Query";
1476 *optional
= dissect_icmpv6_type130
;
1479 *type
= "Multicast Listener Report";
1480 *optional
= dissect_icmpv6_type131
;
1483 *type
= "Multicast Listener Done";
1484 *optional
= dissect_icmpv6_type132
;
1487 *type
= "Router Solicitation";
1488 *optional
= dissect_icmpv6_type133
;
1491 *type
= "Router Advertisement";
1492 *optional
= dissect_icmpv6_type134
;
1495 *type
= "Neighbor Solicitation";
1496 *optional
= dissect_icmpv6_type135
;
1499 *type
= "Neighbor Advertisement";
1500 *optional
= dissect_icmpv6_type136
;
1503 *type
= "Redirect Message";
1504 *optional
= dissect_icmpv6_type137
;
1507 *type
= "Router Renumbering";
1508 if(icmpv6_type_138_codes(icmp
->h_code
))
1509 *code
= icmpv6_type_138_codes(icmp
->h_code
);
1510 *optional
= dissect_icmpv6_type138
;
1513 *type
= "ICMP Node Information Query";
1514 if (icmpv6_code_range_valid(icmp
->h_code
,
1515 icmpv6_type_139_codes
))
1516 *code
= icmpv6_type_139_codes
[icmp
->h_code
];
1517 *optional
= dissect_icmpv6_type139
;
1520 *type
= "ICMP Node Information Response";
1521 if (icmpv6_code_range_valid(icmp
->h_code
,
1522 icmpv6_type_140_codes
))
1523 *code
= icmpv6_type_140_codes
[icmp
->h_code
];
1524 *optional
= dissect_icmpv6_type140
;
1527 *type
= "Inverse Neighbor Discovery Solicitation Message";
1528 *optional
= dissect_icmpv6_type141
;
1531 *type
= "Inverse Neighbor Discovery Advertisement Message";
1532 *optional
= dissect_icmpv6_type142
;
1535 *type
= "Multicast Listener Report v2";
1536 *optional
= dissect_icmpv6_type143
;
1539 *type
= "Home Agent Address Discovery Request Message";
1540 *optional
= dissect_icmpv6_type144
;
1543 *type
= "Home Agent Address Discovery Reply Message";
1544 *optional
= dissect_icmpv6_type145
;
1547 *type
= "Mobile Prefix Solicitation";
1548 *optional
= dissect_icmpv6_type146
;
1551 *type
= "Mobile Prefix Advertisement";
1552 *optional
= dissect_icmpv6_type147
;
1555 *type
= "Certification Path Solicitation";
1556 *optional
= dissect_icmpv6_type148
;
1559 *type
= "Certification Path Advertisement";
1560 *optional
= dissect_icmpv6_type149
;
1563 *type
= "ICMP messages utilized by experimental mobility "
1564 "protocols such as Seamoby";
1565 *optional
= dissect_icmpv6_type150
;
1568 *type
= "Multicast Router Advertisement";
1569 *code
= "Ad. Interval";
1570 *optional
= dissect_icmpv6_type151
;
1573 *type
= "Multicast Router Solicitation";
1575 *optional
= dissect_icmpv6_type152
;
1578 *type
= "Multicast Router Termination";
1580 *optional
= dissect_icmpv6_type153
;
1583 *type
= "FMIPv6 Messages";
1584 *optional
= dissect_icmpv6_type154
;
1587 *type
= "RPL Control Message";
1588 if(icmpv6_type_155_codes(icmp
->h_code
))
1589 *code
= icmpv6_type_155_codes(icmp
->h_code
);
1592 *type
= "Private experimation";
1595 *type
= "Private experimation";
1598 *type
= "Reserved for expansion of ICMPv6 error messages";
1603 static void icmpv6(struct pkt_buff
*pkt
)
1605 const char *type
= NULL
, *code
= NULL
;
1606 int8_t (*optional
)(struct pkt_buff
*pkt
) = NULL
;
1607 struct icmpv6_general_hdr
*icmp
=
1608 (struct icmpv6_general_hdr
*) pkt_pull(pkt
, sizeof(*icmp
));
1613 icmpv6_process(icmp
, &type
, &code
, &optional
);
1615 tprintf(" [ ICMPv6 ");
1616 tprintf("%s (%u), ", type
, icmp
->h_type
);
1617 tprintf("%s (%u), ", code
, icmp
->h_code
);
1618 tprintf("Chks (0x%x)", ntohs(icmp
->h_chksum
));
1620 if (!((*optional
) (pkt
)))
1621 tprintf("\n%s%s%s", colorize_start_full(black
, red
),
1622 "Failed to dissect Message", colorize_end());
1626 static void icmpv6_less(struct pkt_buff
*pkt
)
1628 struct icmpv6_general_hdr
*icmp
=
1629 (struct icmpv6_general_hdr
*) pkt_pull(pkt
, sizeof(*icmp
));
1634 tprintf(" ICMPv6 Type (%u) Code (%u)", icmp
->h_type
, icmp
->h_code
);
1637 struct protocol icmpv6_ops
= {
1639 .print_full
= icmpv6
,
1640 .print_less
= icmpv6_less
,
1643 EXPORT_SYMBOL(icmpv6_ops
);