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
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
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
20 #include <asm/byteorder.h>
23 #include "proto_struct.h"
24 #include "dissector_eth.h"
28 #define icmpv6_code_range_valid(code, sarr) ((code) < array_size((sarr)))
30 struct icmpv6_general_hdr
{
36 /* for type 0x01 and 0x03 */
37 struct icmpv6_type_1_3
{
39 uint8_t invoking_pkt
[0];
42 struct icmpv6_type_2
{
44 uint8_t invoking_pkt
[0];
47 struct icmpv6_type_4
{
49 uint8_t invoking_pkt
[0];
52 struct icmpv6_type_128_129
{
59 struct icmpv6_type_130_131_132
{
62 struct in6_addr ipv6_addr
;
66 struct icmpv6_type_130_mldv2
{
70 struct in6_addr ipv6_addr
[0];
73 /* Neighbor Discovery msg */
74 struct icmpv6_type_133_141_142
{
79 struct icmpv6_type_134
{
80 uint8_t cur_hop_limit
;
82 uint16_t router_lifetime
;
83 uint32_t reachable_time
;
84 uint32_t retrans_timer
;
88 struct icmpv6_type_135
{
90 struct in6_addr ipv6_addr
;
94 struct icmpv6_type_136
{
96 struct in6_addr ipv6_addr
;
100 struct icmpv6_type_137
{
102 struct in6_addr ipv6_targ_addr
;
103 struct in6_addr ipv6_dest_addr
;
107 struct icmpv6_neighb_disc_ops_general
{
113 struct icmpv6_neighb_disc_ops_type_1_2
{
114 uint8_t link_lay_addr
[0];
117 struct icmpv6_neighb_disc_ops_type_3
{
120 uint32_t valid_lifetime
;
121 uint32_t preferred_lifetime
;
123 struct in6_addr prefix
;
126 struct icmpv6_neighb_disc_ops_type_4
{
129 uint8_t ip_hdr_data
[0];
132 struct icmpv6_neighb_disc_ops_type_5
{
137 struct icmpv6_neighb_disc_ops_type_9_10
{
140 uint8_t ip_hdr_data
[0];
143 struct icmpv6_neighb_disc_ops_type_15
{
150 struct icmpv6_neighb_disc_ops_type_16
{
157 struct icmpv6_neighb_disc_ops_type_17
{
163 struct icmpv6_neighb_disc_ops_type_17_1
{
165 struct in6_addr ipv6_addr
;
168 struct icmpv6_neighb_disc_ops_type_17_2
{
169 struct in6_addr ipv6_addr
;
172 struct icmpv6_neighb_disc_ops_type_19
{
176 /* end Neighbor Discovery msg */
178 struct icmpv6_type_138
{
186 /* Node Information Queries */
187 struct icmpv6_type_139_140
{
193 /* end Node Information Queries */
196 struct icmpv6_type_143
{
202 struct icmpv6_mldv2_addr_rec
{
204 uint8_t aux_data_len
;
206 struct in6_addr multic_addr
;
207 struct in6_addr src_addr
[0];
209 /* end MLDv2 report */
211 /* ICMP Mobility Support */
212 struct icmpv6_type_144_146
{
217 struct icmpv6_type_145
{
220 struct in6_addr home_agent_addr
[0];
223 struct icmpv6_type_147
{
228 /* end ICMP Mobility Support */
230 /* SEcure Neighbor Discovery */
231 struct icmpv6_type_148
{
237 struct icmpv6_type_149
{
244 /* end SEcure Neighbor Discovery */
246 struct icmpv6_type_150
{
248 uint32_t subtype_res
;
250 #if defined(__LITTLE_ENDIAN_BITFIELD)
253 #elif defined(__BIG_ENDIAN_BITFIELD)
257 # error "Please fix <asm/byteorder.h>"
264 /* Multicast Router Discovery */
265 struct icmpv6_type_151
{
270 struct icmpv6_type_152
{
274 struct icmpv6_type_153
{
277 /* end Multicast Router Discovery */
279 struct icmpv6_type_154
{
286 static inline int8_t print_ipv6_addr_list(struct pkt_buff
*pkt
, uint8_t nr_addr
)
288 char address
[INET6_ADDRSTRLEN
];
289 struct in6_addr
*addr
;
292 addr
= (struct in6_addr
*) pkt_pull(pkt
, sizeof(*addr
));
296 tprintf("\n\t Address: %s",
297 inet_ntop(AF_INET6
, addr
, address
,
304 static char *icmpv6_mcast_rec_types
[] = {
307 "CHANGE_TO_INCLUDE_MODE",
308 "CHANGE_TO_EXCLUDE_MODE",
313 static inline int8_t dissect_icmpv6_mcast_rec(struct pkt_buff
*pkt
,
316 uint16_t nr_src
, aux_data_len_bytes
;
317 struct icmpv6_mldv2_addr_rec
*addr_rec
;
320 addr_rec
= (struct icmpv6_mldv2_addr_rec
*)
321 pkt_pull(pkt
,sizeof(*addr_rec
));
322 if (addr_rec
== NULL
)
324 aux_data_len_bytes
= addr_rec
->aux_data_len
* 4;
325 nr_src
= ntohs(addr_rec
->nr_src
);
327 tprintf(", Rec Type %s (%u)",
328 icmpv6_code_range_valid(addr_rec
->rec_type
- 1,
329 icmpv6_mcast_rec_types
) ?
330 icmpv6_mcast_rec_types
[addr_rec
->rec_type
- 1]
331 : "Unknown", addr_rec
->rec_type
);
332 if (aux_data_len_bytes
> pkt_len(pkt
)) {
333 tprintf(", Aux Data Len (%u, %u bytes) %s",
334 addr_rec
->aux_data_len
,
336 colorize_start_full(black
, red
) "invalid"
340 tprintf(", Aux Data Len (%u, %u bytes)",addr_rec
->aux_data_len
,
342 tprintf(", Nr. of Sources (%u)",nr_src
);
344 if(!print_ipv6_addr_list(pkt
, nr_src
))
347 tprintf(", Aux Data: ");
348 while (aux_data_len_bytes
--) {
349 tprintf("%x", *pkt_pull(pkt
,1));
356 static inline int8_t dissect_neighb_disc_ops_1(struct pkt_buff
*pkt
,
359 struct icmpv6_neighb_disc_ops_type_1_2
*icmp_neighb_disc_1
;
361 icmp_neighb_disc_1
= (struct icmpv6_neighb_disc_ops_type_1_2
*)
362 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_1
));
363 if (icmp_neighb_disc_1
== NULL
)
365 len
-= sizeof(*icmp_neighb_disc_1
);
369 tprintf("Address 0x");
372 tprintf("%x", *pkt_pull(pkt
,1));
378 static inline int8_t dissect_neighb_disc_ops_2(struct pkt_buff
*pkt
,
381 return dissect_neighb_disc_ops_1(pkt
, len
);
384 static inline int8_t dissect_neighb_disc_ops_3(struct pkt_buff
*pkt
,
387 char address
[INET6_ADDRSTRLEN
];
388 struct icmpv6_neighb_disc_ops_type_3
*icmp_neighb_disc_3
;
390 icmp_neighb_disc_3
= (struct icmpv6_neighb_disc_ops_type_3
*)
391 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_3
));
392 if (icmp_neighb_disc_3
== NULL
)
394 len
-= sizeof(*icmp_neighb_disc_3
);
398 tprintf("Prefix Len (%u) ",icmp_neighb_disc_3
->prefix_len
);
399 tprintf("L (%u) A (%u) Res1 (0x%x) ",icmp_neighb_disc_3
->l_a_res1
>> 7,
400 (icmp_neighb_disc_3
->l_a_res1
>> 7) & 0x1,
401 icmp_neighb_disc_3
->l_a_res1
& 0x3F);
402 tprintf("Valid Lifetime (%us) ",
403 ntohl(icmp_neighb_disc_3
->valid_lifetime
));
404 tprintf("Preferred Lifetime (%us) ",
405 ntohl(icmp_neighb_disc_3
->preferred_lifetime
));
406 tprintf("Reserved2 (0x%x) ",
407 ntohl(icmp_neighb_disc_3
->res2
));
408 tprintf("Prefix: %s ",
409 inet_ntop(AF_INET6
,&icmp_neighb_disc_3
->prefix
,
410 address
, sizeof(address
)));
415 static inline int8_t dissect_neighb_disc_ops_4(struct pkt_buff
*pkt
,
418 struct icmpv6_neighb_disc_ops_type_4
*icmp_neighb_disc_4
;
420 icmp_neighb_disc_4
= (struct icmpv6_neighb_disc_ops_type_4
*)
421 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_4
));
422 if (icmp_neighb_disc_4
== NULL
)
424 len
-= sizeof(*icmp_neighb_disc_4
);
428 tprintf("Reserved 1 (0x%x) ", ntohs(icmp_neighb_disc_4
->res1
));
429 tprintf("Reserved 2 (0x%x) ", ntohl(icmp_neighb_disc_4
->res2
));
430 tprintf("IP header + data ");
433 tprintf("%x", *pkt_pull(pkt
,1));
439 static inline int8_t dissect_neighb_disc_ops_5(struct pkt_buff
*pkt
,
442 struct icmpv6_neighb_disc_ops_type_5
*icmp_neighb_disc_5
;
444 icmp_neighb_disc_5
= (struct icmpv6_neighb_disc_ops_type_5
*)
445 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_5
));
446 if (icmp_neighb_disc_5
== NULL
)
448 len
-= sizeof(*icmp_neighb_disc_5
);
452 tprintf("Reserved (0x%x) ", ntohs(icmp_neighb_disc_5
->res1
));
453 tprintf("MTU (%u)", ntohl(icmp_neighb_disc_5
->MTU
));
458 static inline int8_t dissect_neighb_disc_ops_9(struct pkt_buff
*pkt
,
461 struct icmpv6_neighb_disc_ops_type_9_10
*icmp_neighb_disc_9
;
463 icmp_neighb_disc_9
= (struct icmpv6_neighb_disc_ops_type_9_10
*)
464 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_9
));
465 if (icmp_neighb_disc_9
== NULL
)
467 len
-= sizeof(*icmp_neighb_disc_9
);
471 tprintf("Reserved 1 (0x%x) ", ntohs(icmp_neighb_disc_9
->res1
));
472 tprintf("Reserved 2 (0x%x) ", ntohl(icmp_neighb_disc_9
->res2
));
474 return print_ipv6_addr_list(pkt
, len
/ sizeof(struct in6_addr
));
477 static inline int8_t dissect_neighb_disc_ops_10(struct pkt_buff
*pkt
,
480 return dissect_neighb_disc_ops_9(pkt
, len
);
483 static char *icmpv6_neighb_disc_ops_15_name
[] = {
484 "DER Encoded X.501 Name",
488 static inline int8_t dissect_neighb_disc_ops_15(struct pkt_buff
*pkt
,
493 struct icmpv6_neighb_disc_ops_type_15
*icmp_neighb_disc_15
;
495 icmp_neighb_disc_15
= (struct icmpv6_neighb_disc_ops_type_15
*)
496 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_15
));
497 if (icmp_neighb_disc_15
== NULL
)
499 len
-= sizeof(*icmp_neighb_disc_15
);
502 pad_len
= icmp_neighb_disc_15
->pad_len
;
504 tprintf("Name Type %s (%u) ",
505 icmpv6_code_range_valid(icmp_neighb_disc_15
->name_type
- 1,
506 icmpv6_neighb_disc_ops_15_name
) ?
507 icmpv6_neighb_disc_ops_15_name
[
508 icmp_neighb_disc_15
->name_type
- 1] : "Unknown",
509 icmp_neighb_disc_15
->name_type
);
511 tprintf("Pad Len (%u, invalid)\n%s", pad_len
,
512 colorize_start_full(black
, red
)
513 "Skip Option" colorize_end());
518 tprintf("Pad Len (%u) ", pad_len
);
520 name_len
= len
- pad_len
;
524 tprintf("%c", *pkt_pull(pkt
,1));
528 tprintf("Padding (");
531 tprintf("%x", *pkt_pull(pkt
,1));
538 static char *icmpv6_neighb_disc_ops_16_cert
[] = {
539 "X.509v3 Certificate",
542 static inline int8_t dissect_neighb_disc_ops_16(struct pkt_buff
*pkt
,
545 struct icmpv6_neighb_disc_ops_type_16
*icmp_neighb_disc_16
;
547 icmp_neighb_disc_16
= (struct icmpv6_neighb_disc_ops_type_16
*)
548 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_16
));
549 if (icmp_neighb_disc_16
== NULL
)
551 len
-= sizeof(*icmp_neighb_disc_16
);
555 tprintf("Cert Type %s (%u) ",
556 icmpv6_code_range_valid(icmp_neighb_disc_16
->cert_type
- 1,
557 icmpv6_neighb_disc_ops_16_cert
) ?
558 icmpv6_neighb_disc_ops_16_cert
[
559 icmp_neighb_disc_16
->cert_type
- 1] : "Unknown",
560 icmp_neighb_disc_16
->cert_type
);
561 tprintf("Res (0x%x) ", icmp_neighb_disc_16
->res
);
563 tprintf("Certificate + Padding (");
565 tprintf("%x", *pkt_pull(pkt
,1));
572 static char *icmpv6_neighb_disc_ops_17_codes
[] = {
573 "Old Care-of Address",
574 "New Care-of Address",
579 static inline int8_t dissect_neighb_disc_ops_17(struct pkt_buff
*pkt
,
582 char address
[INET6_ADDRSTRLEN
];
583 struct icmpv6_neighb_disc_ops_type_17
*icmp_neighb_disc_17
;
585 icmp_neighb_disc_17
= (struct icmpv6_neighb_disc_ops_type_17
*)
586 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_17
));
587 if (icmp_neighb_disc_17
== NULL
)
589 len
-= sizeof(*icmp_neighb_disc_17
);
593 tprintf("Opt Code %s (%u) ",
594 icmpv6_code_range_valid(icmp_neighb_disc_17
->opt_code
- 1,
595 icmpv6_neighb_disc_ops_17_codes
) ?
596 icmpv6_neighb_disc_ops_17_codes
[
597 icmp_neighb_disc_17
->opt_code
- 1] : "Unknown",
598 icmp_neighb_disc_17
->opt_code
);
599 tprintf("Prefix Len (%u) ", icmp_neighb_disc_17
->prefix_len
);
601 if (len
== sizeof(struct icmpv6_neighb_disc_ops_type_17_1
)) {
602 struct icmpv6_neighb_disc_ops_type_17_1
603 *icmp_neighb_disc_17_1
;
605 icmp_neighb_disc_17_1
=
606 (struct icmpv6_neighb_disc_ops_type_17_1
*)
607 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_17_1
));
608 if (icmp_neighb_disc_17_1
== NULL
)
610 len
-= sizeof(*icmp_neighb_disc_17_1
);
614 tprintf("Res (0x%x) ",icmp_neighb_disc_17_1
->res
);
616 inet_ntop(AF_INET6
,&icmp_neighb_disc_17_1
->ipv6_addr
,
617 address
, sizeof(address
)));
619 else if (len
== sizeof(struct icmpv6_neighb_disc_ops_type_17_2
)) {
620 struct icmpv6_neighb_disc_ops_type_17_2
621 *icmp_neighb_disc_17_2
;
623 icmp_neighb_disc_17_2
=
624 (struct icmpv6_neighb_disc_ops_type_17_2
*)
625 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_17_2
));
626 if (icmp_neighb_disc_17_2
== NULL
)
628 len
-= sizeof(*icmp_neighb_disc_17_2
);
633 inet_ntop(AF_INET6
,&icmp_neighb_disc_17_2
->ipv6_addr
,
634 address
, sizeof(address
)));
637 tprintf("%s (", colorize_start_full(black
, red
)
638 "Error Wrong Length. Skip Option" colorize_end());
640 tprintf("%x", *pkt_pull(pkt
,1));
648 static char *icmpv6_neighb_disc_ops_19_codes
[] = {
649 "Wildcard requesting resolution for all nearby access points",
650 "Link-Layer Address of the New Access Point",
651 "Link-Layer Address of the MN",
652 "Link-Layer Address of the NAR",
653 "Link-Layer Address of the source of RtSolPr or PrRtAdv \
655 "The access point identified by the LLA belongs to the \
656 current interface of the router",
657 "No prefix information available for the access point \
658 identified by the LLA",
659 "No fast handover support available for the access point \
660 identified by the LLA",
663 static inline int8_t dissect_neighb_disc_ops_19(struct pkt_buff
*pkt
,
666 struct icmpv6_neighb_disc_ops_type_19
*icmp_neighb_disc_19
;
668 icmp_neighb_disc_19
= (struct icmpv6_neighb_disc_ops_type_19
*)
669 pkt_pull(pkt
,sizeof(*icmp_neighb_disc_19
));
670 if (icmp_neighb_disc_19
== NULL
)
672 len
-= sizeof(*icmp_neighb_disc_19
);
676 tprintf("Opt Code %s (%u) ",
677 icmpv6_code_range_valid(icmp_neighb_disc_19
->opt_code
,
678 icmpv6_neighb_disc_ops_19_codes
) ?
679 icmpv6_neighb_disc_ops_19_codes
[
680 icmp_neighb_disc_19
->opt_code
] : "Unknown",
681 icmp_neighb_disc_19
->opt_code
);
685 tprintf("%x", *pkt_pull(pkt
,1));
692 static inline char *icmpv6_neighb_disc_ops(uint8_t code
) {
695 return "Source Link-Layer Address";
697 return "Target Link-Layer Address";
699 return "Prefix Information";
701 return "Redirected Header";
705 return "NBMA Shortcut Limit Option";
707 return "Advertisement Interval Option";
709 return "Home Agent Information Option";
711 return "Source Address List";
713 return "Target Address List";
717 return "RSA Signature option";
719 return "Timestamp option";
721 return "Nonce option";
723 return "Trust Anchor option";
725 return "Certificate option";
727 return "IP Address/Prefix Option";
729 return "New Router Prefix Information Option";
731 return "Link-layer Address Option";
733 return "Neighbor Advertisement Acknowledgment Option";
736 return "Prefix Information";
738 return "Redirected Header";
742 return "NBMA Shortcut Limit Option";
744 return "Advertisement Interval Option";
746 return "Home Agent Information Option";
748 return "Source Address List";
750 return "Target Address List";
752 return "DNS Search List Option";
754 return "Proxy Signature (PS)";
757 return "CARD Request option";
759 return "CARD Reply option";
762 return "RFC3692-style Experiment 1";
764 return "RFC3692-style Experiment 2";
770 static inline int8_t dissect_neighb_disc_ops(struct pkt_buff
*pkt
)
773 uint16_t ops_total_len
;
774 ssize_t ops_payl_len
;
775 struct icmpv6_neighb_disc_ops_general
*icmp_neighb_disc
;
777 while(pkt_len(pkt
)) {
778 icmp_neighb_disc
= (struct icmpv6_neighb_disc_ops_general
*)
779 pkt_pull(pkt
,sizeof(*icmp_neighb_disc
));
780 if (icmp_neighb_disc
== NULL
)
783 ops_total_len
= icmp_neighb_disc
->len
* 8;
784 pad_bytes
= (size_t) (ops_total_len
% 8);
785 ops_payl_len
= ops_total_len
- sizeof(*icmp_neighb_disc
) -
788 tprintf("\n\tOption %s (%u) ",
789 icmpv6_neighb_disc_ops(icmp_neighb_disc
->type
) ?
790 icmpv6_neighb_disc_ops(icmp_neighb_disc
->type
)
791 : "Type Unknown", icmp_neighb_disc
->type
);
792 if (ops_payl_len
> pkt_len(pkt
) || ops_payl_len
< 0) {
793 tprintf("Length (%u, %u bytes, %s%s%s) ",
794 icmp_neighb_disc
->len
,
796 colorize_start_full(black
, red
),
797 "invalid", colorize_end());
801 tprintf("Length (%u, %u bytes) ",icmp_neighb_disc
->len
,
804 switch (icmp_neighb_disc
->type
) {
806 if (!dissect_neighb_disc_ops_1(pkt
, ops_payl_len
))
810 if (!dissect_neighb_disc_ops_2(pkt
, ops_payl_len
))
814 if (!dissect_neighb_disc_ops_3(pkt
, ops_payl_len
))
818 if (!dissect_neighb_disc_ops_4(pkt
, ops_payl_len
))
822 if (!dissect_neighb_disc_ops_5(pkt
, ops_payl_len
))
825 /* Type 9 and 10 defined in
826 * http://tools.ietf.org/html/rfc3122#section-3.1
829 if (!dissect_neighb_disc_ops_9(pkt
, ops_payl_len
))
833 if (!dissect_neighb_disc_ops_10(pkt
, ops_payl_len
))
836 /* Type 15 and 16 defined in
837 * http://tools.ietf.org/html/rfc3971#section-6.4.3
838 * http://tools.ietf.org/html/rfc3971#section-6.4.4
841 if (!dissect_neighb_disc_ops_15(pkt
, ops_payl_len
))
845 if (!dissect_neighb_disc_ops_16(pkt
, ops_payl_len
))
848 /* Type 17 and 19 defined in
849 * http://tools.ietf.org/html/rfc5568#section-6.4
852 if (!dissect_neighb_disc_ops_17(pkt
, ops_payl_len
))
856 if (!dissect_neighb_disc_ops_19(pkt
, ops_payl_len
))
860 pkt_pull(pkt
, ops_payl_len
);
863 /* Skip Padding Bytes */
864 if (pad_bytes
> pkt_len(pkt
)) {
865 tprintf(" %s",colorize_start_full(black
, red
)
866 "Invalid Padding" colorize_end());
869 pkt_pull(pkt
, pad_bytes
);
875 static char *icmpv6_type_1_codes
[] = {
876 "No route to destination",
877 "Communication with destination administratively prohibited",
878 "Beyond scope of source address",
879 "Address unreachable",
881 "Source address failed ingress/egress policy",
882 "Reject route to destination",
883 "Error in Source Routing Header",
886 static inline int8_t dissect_icmpv6_type1(struct pkt_buff
*pkt
)
888 struct icmpv6_type_1_3
*icmp_1
;
890 icmp_1
= (struct icmpv6_type_1_3
*) pkt_pull(pkt
,sizeof(*icmp_1
));
894 tprintf(", Unused (0x%x)",ntohl(icmp_1
->unused
));
895 tprintf(" Payload include as much of invoking packet");
900 static inline int8_t dissect_icmpv6_type2(struct pkt_buff
*pkt
)
902 struct icmpv6_type_2
*icmp_2
;
904 icmp_2
= (struct icmpv6_type_2
*) pkt_pull(pkt
,sizeof(*icmp_2
));
908 tprintf(", MTU (0x%x)",ntohl(icmp_2
->MTU
));
909 tprintf(" Payload include as much of invoking packet");
914 static char *icmpv6_type_3_codes
[] = {
915 "Hop limit exceeded in transit",
916 "Fragment reassembly time exceeded",
919 static inline int8_t dissect_icmpv6_type3(struct pkt_buff
*pkt
)
921 struct icmpv6_type_1_3
*icmp_3
;
923 icmp_3
= (struct icmpv6_type_1_3
*) pkt_pull(pkt
,sizeof(*icmp_3
));
927 tprintf(", Unused (0x%x)",ntohl(icmp_3
->unused
));
928 tprintf(" Payload include as much of invoking packet");
933 static char *icmpv6_type_4_codes
[] = {
934 "Erroneous header field encountered",
935 "Unrecognized Next Header type encountered",
936 "Unrecognized IPv6 option encountered",
939 static inline int8_t dissect_icmpv6_type4(struct pkt_buff
*pkt
)
941 struct icmpv6_type_4
*icmp_4
;
943 icmp_4
= (struct icmpv6_type_4
*) pkt_pull(pkt
,sizeof(*icmp_4
));
947 tprintf(", Pointer (0x%x)",ntohl(icmp_4
->pointer
));
948 tprintf(" Payload include as much of invoking packet");
953 static inline int8_t dissect_icmpv6_type128(struct pkt_buff
*pkt
)
955 struct icmpv6_type_128_129
*icmp_128
;
957 icmp_128
= (struct icmpv6_type_128_129
*)
958 pkt_pull(pkt
,sizeof(*icmp_128
));
959 if (icmp_128
== NULL
)
962 tprintf(", ID (0x%x)",ntohs(icmp_128
->id
));
963 tprintf(", Seq. Nr. (%u)",ntohs(icmp_128
->sn
));
964 tprintf(" Payload include Data");
969 static inline int8_t dissect_icmpv6_type129(struct pkt_buff
*pkt
)
971 struct icmpv6_type_128_129
*icmp_129
;
973 icmp_129
= (struct icmpv6_type_128_129
*)
974 pkt_pull(pkt
,sizeof(*icmp_129
));
975 if (icmp_129
== NULL
)
978 tprintf(", ID (0x%x)",ntohs(icmp_129
->id
));
979 tprintf(", Seq. Nr. (%u)",ntohs(icmp_129
->sn
));
980 tprintf(" Payload include Data");
985 static inline int8_t dissect_icmpv6_type130(struct pkt_buff
*pkt
)
987 char address
[INET6_ADDRSTRLEN
];
988 uint16_t nr_src
, maxrespdel
;
989 uint8_t switch_mldv2
= 0;
990 struct icmpv6_type_130_131_132
*icmp_130
;
992 icmp_130
= (struct icmpv6_type_130_131_132
*)
993 pkt_pull(pkt
,sizeof(*icmp_130
));
994 if (icmp_130
== NULL
)
996 maxrespdel
= ntohs(icmp_130
->maxrespdel
);
998 if(pkt_len(pkt
) >= sizeof(struct icmpv6_type_130_mldv2
))
1002 tprintf(", MLDv2, Max Resp Delay (%ums)", maxrespdel
>> 15 ?
1003 (((maxrespdel
& 0xFFF) | 0x1000) <<
1004 (((maxrespdel
>> 12) & 0x3) + 3)) : maxrespdel
);
1006 tprintf(", Max Resp Delay (%ums)",maxrespdel
);
1007 tprintf(", Res (0x%x)",ntohs(icmp_130
->res
));
1008 tprintf(", Address: %s",
1009 inet_ntop(AF_INET6
, &icmp_130
->ipv6_addr
,
1010 address
, sizeof(address
)));
1013 struct icmpv6_type_130_mldv2
*icmp_130_mldv2
;
1015 icmp_130_mldv2
= (struct icmpv6_type_130_mldv2
*)
1016 pkt_pull(pkt
,sizeof(*icmp_130_mldv2
));
1017 if (icmp_130_mldv2
== NULL
)
1020 nr_src
= ntohs(icmp_130_mldv2
->nr_src
);
1022 tprintf(", Resv (0x%x)",icmp_130_mldv2
->resv_S_QRV
>> 4);
1023 tprintf(", S (%u)",(icmp_130_mldv2
->resv_S_QRV
>> 3) & 0x1);
1024 tprintf(", QRV (0x%x)",icmp_130_mldv2
->resv_S_QRV
& 0x3);
1025 tprintf(", QQIC (%u)",icmp_130_mldv2
->QQIC
);
1026 tprintf(", Nr Src (0x%x)",nr_src
);
1028 return print_ipv6_addr_list(pkt
, nr_src
);
1034 static inline int8_t dissect_icmpv6_type131(struct pkt_buff
*pkt
)
1036 char address
[INET6_ADDRSTRLEN
];
1037 struct icmpv6_type_130_131_132
*icmp_131
;
1039 icmp_131
= (struct icmpv6_type_130_131_132
*)
1040 pkt_pull(pkt
,sizeof(*icmp_131
));
1041 if (icmp_131
== NULL
)
1044 tprintf(", Max Resp Delay (%ums)",ntohs(icmp_131
->maxrespdel
));
1045 tprintf(", Res (0x%x)",ntohs(icmp_131
->res
));
1046 tprintf(", Address: %s",
1047 inet_ntop(AF_INET6
, &icmp_131
->ipv6_addr
,
1048 address
, sizeof(address
)));
1053 static inline int8_t dissect_icmpv6_type132(struct pkt_buff
*pkt
)
1055 return dissect_icmpv6_type131(pkt
);
1058 static inline int8_t dissect_icmpv6_type133(struct pkt_buff
*pkt
)
1060 struct icmpv6_type_133_141_142
*icmp_133
;
1062 icmp_133
= (struct icmpv6_type_133_141_142
*)
1063 pkt_pull(pkt
,sizeof(*icmp_133
));
1064 if (icmp_133
== NULL
)
1067 tprintf(", Reserved (0x%x)",ntohl(icmp_133
->res
));
1069 return dissect_neighb_disc_ops(pkt
);
1072 static inline int8_t dissect_icmpv6_type134(struct pkt_buff
*pkt
)
1074 struct icmpv6_type_134
*icmp_134
;
1076 icmp_134
= (struct icmpv6_type_134
*)
1077 pkt_pull(pkt
,sizeof(*icmp_134
));
1078 if (icmp_134
== NULL
)
1081 tprintf(", Cur Hop Limit (%u)",icmp_134
->cur_hop_limit
);
1082 tprintf(", M (%u) O (%u)",icmp_134
->m_o_res
>> 7,
1083 (icmp_134
->m_o_res
>> 6) & 0x1);
1084 tprintf(", Router Lifetime (%us)",ntohs(icmp_134
->router_lifetime
));
1085 tprintf(", Reachable Time (%ums)",ntohl(icmp_134
->reachable_time
));
1086 tprintf(", Retrans Timer (%ums)",ntohl(icmp_134
->retrans_timer
));
1088 return dissect_neighb_disc_ops(pkt
);
1091 static inline int8_t dissect_icmpv6_type135(struct pkt_buff
*pkt
)
1093 char address
[INET6_ADDRSTRLEN
];
1094 struct icmpv6_type_135
*icmp_135
;
1096 icmp_135
= (struct icmpv6_type_135
*)
1097 pkt_pull(pkt
,sizeof(*icmp_135
));
1098 if (icmp_135
== NULL
)
1101 tprintf(", Reserved (0x%x)",ntohl(icmp_135
->res
));
1102 tprintf(", Target Address: %s",
1103 inet_ntop(AF_INET6
, &icmp_135
->ipv6_addr
,
1104 address
, sizeof(address
)));
1106 return dissect_neighb_disc_ops(pkt
);
1109 static inline int8_t dissect_icmpv6_type136(struct pkt_buff
*pkt
)
1111 char address
[INET6_ADDRSTRLEN
];
1113 struct icmpv6_type_136
*icmp_136
;
1115 icmp_136
= (struct icmpv6_type_136
*)
1116 pkt_pull(pkt
,sizeof(*icmp_136
));
1117 if (icmp_136
== NULL
)
1119 r_s_o_res
= ntohl(icmp_136
->r_s_o_res
);
1121 tprintf(", R (%u) S (%u) O (%u) Reserved (0x%x)", r_s_o_res
>> 31,
1122 (r_s_o_res
>> 30) & 0x1, (r_s_o_res
>> 29) & 0x1,
1123 r_s_o_res
& 0x1FFFFFFF);
1124 tprintf(", Target Address: %s",
1125 inet_ntop(AF_INET6
, &icmp_136
->ipv6_addr
,
1126 address
, sizeof(address
)));
1128 return dissect_neighb_disc_ops(pkt
);
1131 static inline int8_t dissect_icmpv6_type137(struct pkt_buff
*pkt
)
1133 char address
[INET6_ADDRSTRLEN
];
1134 struct icmpv6_type_137
*icmp_137
;
1136 icmp_137
= (struct icmpv6_type_137
*)
1137 pkt_pull(pkt
,sizeof(*icmp_137
));
1138 if (icmp_137
== NULL
)
1141 tprintf(", Reserved (0x%x)",icmp_137
->res
);
1142 tprintf(", Target Address: %s",
1143 inet_ntop(AF_INET6
, &icmp_137
->ipv6_targ_addr
,
1144 address
, sizeof(address
)));
1145 tprintf(", Dest Address: %s",
1146 inet_ntop(AF_INET6
, &icmp_137
->ipv6_dest_addr
,
1147 address
, sizeof(address
)));
1149 return dissect_neighb_disc_ops(pkt
);
1152 static inline void dissect_icmpv6_rr_body(struct pkt_buff
*pkt
)
1155 * Upgrade Dissector for Message Body
1156 * from http://tools.ietf.org/html/rfc2894#section-3.2
1159 tprintf(" Message Body recognized");
1162 static inline char *icmpv6_type_138_codes(uint8_t code
) {
1165 return "Router Renumbering Command";
1167 return "Router Renumbering Result";
1169 return "Sequence Number Reset";
1175 static inline int8_t dissect_icmpv6_type138(struct pkt_buff
*pkt
)
1177 struct icmpv6_type_138
*icmp_138
;
1179 icmp_138
= (struct icmpv6_type_138
*)
1180 pkt_pull(pkt
,sizeof(*icmp_138
));
1181 if (icmp_138
== NULL
)
1184 tprintf(", Sequence Nr. (%u)",ntohl(icmp_138
->seq_nr
));
1185 tprintf(", Segment Nr. (%u)",icmp_138
->seg_nr
);
1186 tprintf(", T (%u) R (%u) A (%u) S (%u) P (%u) Res \
1187 (0x%x) ",icmp_138
->flags
>> 7, (icmp_138
->flags
>> 6) & 1,
1188 (icmp_138
->flags
>> 5) & 1, (icmp_138
->flags
>> 4) & 1,
1189 (icmp_138
->flags
>> 3) & 1, icmp_138
->flags
& 7);
1190 tprintf(", Max Delay (%ums)", ntohs(icmp_138
->maxdelay
));
1191 tprintf(", Res (0x%x)", ntohl(icmp_138
->res
));
1193 dissect_icmpv6_rr_body(pkt
);
1198 static inline void dissect_icmpv6_node_inf_data(struct pkt_buff
*pkt
)
1201 * Upgrade Dissector for Data field
1202 * http://tools.ietf.org/html/rfc4620#section-4
1205 tprintf(" Data recognized");
1208 static char *icmpv6_node_inf_qtypes
[] = {
1216 static char *icmpv6_type_139_codes
[] = {
1217 "Data contains IPv6 Address",
1218 "Data contains Name or nothing",
1219 "Data contains IPv4 Address",
1222 static inline int8_t dissect_icmpv6_type139(struct pkt_buff
*pkt
)
1224 char *qtype_name
= "Unknown";
1226 struct icmpv6_type_139_140
*icmp_139
;
1228 icmp_139
= (struct icmpv6_type_139_140
*)
1229 pkt_pull(pkt
,sizeof(*icmp_139
));
1230 if (icmp_139
== NULL
)
1233 qtype_nr
= ntohs(icmp_139
->qtype
);
1234 if (icmpv6_code_range_valid(qtype_nr
, icmpv6_node_inf_qtypes
))
1235 qtype_name
= icmpv6_node_inf_qtypes
[qtype_nr
];
1237 tprintf(", Qtype %s (%u)",qtype_name
, qtype_nr
);
1238 tprintf(", Flags (0x%x)",ntohs(icmp_139
->flags
));
1239 tprintf(", Nonce (0x%x)",ntohll(icmp_139
->nonce
));
1241 dissect_icmpv6_node_inf_data(pkt
);
1246 static char *icmpv6_type_140_codes
[] = {
1247 "Successfull reply",
1248 "Responder refuses answer",
1249 "Qtype is unknown to the Responder",
1252 static inline int8_t dissect_icmpv6_type140(struct pkt_buff
*pkt
)
1254 return dissect_icmpv6_type139(pkt
);
1257 static inline int8_t dissect_icmpv6_type141(struct pkt_buff
*pkt
)
1259 return dissect_icmpv6_type133(pkt
);
1262 static inline int8_t dissect_icmpv6_type142(struct pkt_buff
*pkt
)
1264 return dissect_icmpv6_type133(pkt
);
1267 static inline int8_t dissect_icmpv6_type143(struct pkt_buff
*pkt
)
1270 struct icmpv6_type_143
*icmp_143
;
1272 icmp_143
= (struct icmpv6_type_143
*)
1273 pkt_pull(pkt
,sizeof(*icmp_143
));
1274 if (icmp_143
== NULL
)
1276 nr_rec
= ntohs(icmp_143
->nr_rec
);
1278 tprintf(", Res (0x%x)",ntohs(icmp_143
->res
));
1279 tprintf(", Nr. Mcast Addr Records (%u)",nr_rec
);
1281 return dissect_icmpv6_mcast_rec(pkt
, nr_rec
);
1284 static inline int8_t dissect_icmpv6_type144(struct pkt_buff
*pkt
)
1286 struct icmpv6_type_144_146
*icmp_144
;
1288 icmp_144
= (struct icmpv6_type_144_146
*)
1289 pkt_pull(pkt
,sizeof(*icmp_144
));
1290 if (icmp_144
== NULL
)
1293 tprintf(", ID (%u)",ntohs(icmp_144
->id
));
1294 tprintf(", Res (0x%x)",ntohs(icmp_144
->res
));
1299 static inline int8_t dissect_icmpv6_type145(struct pkt_buff
*pkt
)
1301 struct icmpv6_type_145
*icmp_145
;
1303 icmp_145
= (struct icmpv6_type_145
*)
1304 pkt_pull(pkt
,sizeof(*icmp_145
));
1305 if (icmp_145
== NULL
)
1308 tprintf(", ID (%u)",ntohs(icmp_145
->id
));
1309 tprintf(", Res (0x%x)",ntohs(icmp_145
->res
));
1311 return print_ipv6_addr_list(pkt
, pkt_len(pkt
) /
1312 sizeof(struct in6_addr
));
1315 static inline int8_t dissect_icmpv6_type146(struct pkt_buff
*pkt
)
1317 return dissect_icmpv6_type144(pkt
);
1320 static inline int8_t dissect_icmpv6_type147(struct pkt_buff
*pkt
)
1323 struct icmpv6_type_147
*icmp_147
;
1325 icmp_147
= (struct icmpv6_type_147
*)
1326 pkt_pull(pkt
,sizeof(*icmp_147
));
1327 if (icmp_147
== NULL
)
1329 m_o_res
= ntohs(icmp_147
->m_o_res
);
1331 tprintf(", ID (%u)",ntohs(icmp_147
->id
));
1332 tprintf(", M (%u) O (%u) Res (0x%x)",m_o_res
>> 15,
1333 (m_o_res
>> 14) & 1, m_o_res
& 0x3FFF);
1335 return dissect_neighb_disc_ops(pkt
);
1338 static inline int8_t dissect_icmpv6_type148(struct pkt_buff
*pkt
)
1340 struct icmpv6_type_148
*icmp_148
;
1342 icmp_148
= (struct icmpv6_type_148
*)
1343 pkt_pull(pkt
,sizeof(*icmp_148
));
1344 if (icmp_148
== NULL
)
1347 tprintf(", ID (%u)",ntohs(icmp_148
->id
));
1348 tprintf(", Component (%u)",ntohs(icmp_148
->comp
));
1350 return dissect_neighb_disc_ops(pkt
);
1353 static inline int8_t dissect_icmpv6_type149(struct pkt_buff
*pkt
)
1355 struct icmpv6_type_149
*icmp_149
;
1357 icmp_149
= (struct icmpv6_type_149
*)
1358 pkt_pull(pkt
,sizeof(*icmp_149
));
1359 if (icmp_149
== NULL
)
1362 tprintf(", ID (%u)",ntohs(icmp_149
->id
));
1363 tprintf(", All Components (%u)",ntohs(icmp_149
->all_comp
));
1364 tprintf(", Component (%u)",ntohs(icmp_149
->comp
));
1365 tprintf(", Res (0x%x)",ntohs(icmp_149
->res
));
1367 return dissect_neighb_disc_ops(pkt
);
1370 static inline int8_t dissect_icmpv6_type150(struct pkt_buff
*pkt
)
1372 struct icmpv6_type_150
*icmp_150
;
1374 icmp_150
= (struct icmpv6_type_150
*)
1375 pkt_pull(pkt
,sizeof(*icmp_150
));
1376 if (icmp_150
== NULL
)
1379 tprintf(", Subtype (%u)",icmp_150
->subtype
);
1380 tprintf(", Res (0x%x)",icmp_150
->res
);
1381 tprintf(", Options in Payload");
1386 static inline int8_t dissect_icmpv6_type151(struct pkt_buff
*pkt
)
1388 struct icmpv6_type_151
*icmp_151
;
1390 icmp_151
= (struct icmpv6_type_151
*)
1391 pkt_pull(pkt
,sizeof(*icmp_151
));
1392 if (icmp_151
== NULL
)
1395 tprintf(", Query Interval (%us)",ntohs(icmp_151
->query_intv
));
1396 tprintf(", Robustness Variable (%u)",ntohs(icmp_151
->rob_var
));
1401 static inline int8_t dissect_icmpv6_type152(struct pkt_buff
*pkt
)
1403 struct icmpv6_type_152
*icmp_152
;
1405 icmp_152
= (struct icmpv6_type_152
*)
1406 pkt_pull(pkt
,sizeof(*icmp_152
));
1407 if (icmp_152
== NULL
)
1413 static inline int8_t dissect_icmpv6_type153(struct pkt_buff
*pkt
)
1415 struct icmpv6_type_153
*icmp_153
;
1417 icmp_153
= (struct icmpv6_type_153
*)
1418 pkt_pull(pkt
,sizeof(*icmp_153
));
1419 if (icmp_153
== NULL
)
1425 static inline int8_t dissect_icmpv6_type154(struct pkt_buff
*pkt
)
1427 struct icmpv6_type_154
*icmp_154
;
1429 icmp_154
= (struct icmpv6_type_154
*)
1430 pkt_pull(pkt
,sizeof(*icmp_154
));
1431 if (icmp_154
== NULL
)
1434 tprintf(", Subtype (%u)",icmp_154
->subtype
);
1435 tprintf(", Res (0x%x)",icmp_154
->res
);
1436 tprintf(", ID (%u)",ntohs(icmp_154
->id
));
1438 return dissect_neighb_disc_ops(pkt
);
1441 static inline char *icmpv6_type_155_codes(uint8_t code
) {
1444 return "DODAG Information Solicitation";
1446 return "DODAG Information Object";
1448 return "Destination Advertisement Object";
1450 return "Destination Advertisement Object Acknowledgment";
1452 return "Secure DODAG Information Solicitation";
1454 return "Secure DODAG Information Object";
1456 return "Secure Destination Advertisement Object";
1458 return "Secure Destination Advertisement Object Acknowledgment";
1460 return "Consistency Check";
1466 static inline void icmpv6_process(struct icmpv6_general_hdr
*icmp
, char **type
,
1468 int8_t (**optional
)(struct pkt_buff
*pkt
))
1470 *type
= "Unknown Type";
1471 *code
= "Unknown Code";
1473 switch (icmp
->h_type
) {
1475 *type
= "Destination Unreachable";
1476 if (icmpv6_code_range_valid(icmp
->h_code
, icmpv6_type_1_codes
))
1477 *code
= icmpv6_type_1_codes
[icmp
->h_code
];
1478 *optional
= dissect_icmpv6_type1
;
1481 *type
= "Packet Too Big";
1482 *optional
= dissect_icmpv6_type2
;
1485 *type
= "Time Exceeded";
1486 if (icmpv6_code_range_valid(icmp
->h_code
, icmpv6_type_3_codes
))
1487 *code
= icmpv6_type_3_codes
[icmp
->h_code
];
1488 *optional
= dissect_icmpv6_type3
;
1491 *type
= "Parameter Problem";
1492 if (icmpv6_code_range_valid(icmp
->h_code
, icmpv6_type_4_codes
))
1493 *code
= icmpv6_type_4_codes
[icmp
->h_code
];
1494 *optional
= dissect_icmpv6_type4
;
1497 *type
= "Private experimation";
1500 *type
= "Private experimation";
1503 *type
= "Reserved for expansion of ICMPv6 error messages";
1506 *type
= "Echo Request";
1507 *optional
= dissect_icmpv6_type128
;
1510 *type
= "Echo Reply";
1511 *optional
= dissect_icmpv6_type129
;
1514 *type
= "Multicast Listener Query";
1515 *optional
= dissect_icmpv6_type130
;
1518 *type
= "Multicast Listener Report";
1519 *optional
= dissect_icmpv6_type131
;
1522 *type
= "Multicast Listener Done";
1523 *optional
= dissect_icmpv6_type132
;
1526 *type
= "Router Solicitation";
1527 *optional
= dissect_icmpv6_type133
;
1530 *type
= "Router Advertisement";
1531 *optional
= dissect_icmpv6_type134
;
1534 *type
= "Neighbor Solicitation";
1535 *optional
= dissect_icmpv6_type135
;
1538 *type
= "Neighbor Advertisement";
1539 *optional
= dissect_icmpv6_type136
;
1542 *type
= "Redirect Message";
1543 *optional
= dissect_icmpv6_type137
;
1546 *type
= "Router Renumbering";
1547 if(icmpv6_type_138_codes(icmp
->h_code
))
1548 *code
= icmpv6_type_138_codes(icmp
->h_code
);
1549 *optional
= dissect_icmpv6_type138
;
1552 *type
= "ICMP Node Information Query";
1553 if (icmpv6_code_range_valid(icmp
->h_code
,
1554 icmpv6_type_139_codes
))
1555 *code
= icmpv6_type_139_codes
[icmp
->h_code
];
1556 *optional
= dissect_icmpv6_type139
;
1559 *type
= "ICMP Node Information Response";
1560 if (icmpv6_code_range_valid(icmp
->h_code
,
1561 icmpv6_type_140_codes
))
1562 *code
= icmpv6_type_140_codes
[icmp
->h_code
];
1563 *optional
= dissect_icmpv6_type140
;
1566 *type
= "Inverse Neighbor Discovery Solicitation Message";
1567 *optional
= dissect_icmpv6_type141
;
1570 *type
= "Inverse Neighbor Discovery Advertisement Message";
1571 *optional
= dissect_icmpv6_type142
;
1574 *type
= "Multicast Listener Report v2";
1575 *optional
= dissect_icmpv6_type143
;
1578 *type
= "Home Agent Address Discovery Request Message";
1579 *optional
= dissect_icmpv6_type144
;
1582 *type
= "Home Agent Address Discovery Reply Message";
1583 *optional
= dissect_icmpv6_type145
;
1586 *type
= "Mobile Prefix Solicitation";
1587 *optional
= dissect_icmpv6_type146
;
1590 *type
= "Mobile Prefix Advertisement";
1591 *optional
= dissect_icmpv6_type147
;
1594 *type
= "Certification Path Solicitation";
1595 *optional
= dissect_icmpv6_type148
;
1598 *type
= "Certification Path Advertisement";
1599 *optional
= dissect_icmpv6_type149
;
1602 *type
= "ICMP messages utilized by experimental mobility "
1603 "protocols such as Seamoby";
1604 *optional
= dissect_icmpv6_type150
;
1607 *type
= "Multicast Router Advertisement";
1608 *code
= "Ad. Interval";
1609 *optional
= dissect_icmpv6_type151
;
1612 *type
= "Multicast Router Solicitation";
1614 *optional
= dissect_icmpv6_type152
;
1617 *type
= "Multicast Router Termination";
1619 *optional
= dissect_icmpv6_type153
;
1622 *type
= "FMIPv6 Messages";
1623 *optional
= dissect_icmpv6_type154
;
1626 *type
= "RPL Control Message";
1627 if(icmpv6_type_155_codes(icmp
->h_code
))
1628 *code
= icmpv6_type_155_codes(icmp
->h_code
);
1631 *type
= "Private experimation";
1634 *type
= "Private experimation";
1637 *type
= "Reserved for expansion of ICMPv6 error messages";
1642 static inline void icmpv6(struct pkt_buff
*pkt
)
1644 char *type
= NULL
, *code
= NULL
;
1645 int8_t (*optional
)(struct pkt_buff
*pkt
) = NULL
;
1646 struct icmpv6_general_hdr
*icmp
=
1647 (struct icmpv6_general_hdr
*) pkt_pull(pkt
, sizeof(*icmp
));
1652 icmpv6_process(icmp
, &type
, &code
, &optional
);
1654 tprintf(" [ ICMPv6 ");
1655 tprintf("%s (%u), ", type
, icmp
->h_type
);
1656 tprintf("%s (%u), ", code
, icmp
->h_code
);
1657 tprintf("Chks (0x%x)", ntohs(icmp
->h_chksum
));
1659 if (!((*optional
) (pkt
)))
1660 tprintf("\n%s%s%s", colorize_start_full(black
, red
),
1661 "Failed to dissect Message", colorize_end());
1665 static inline void icmpv6_less(struct pkt_buff
*pkt
)
1667 struct icmpv6_general_hdr
*icmp
=
1668 (struct icmpv6_general_hdr
*) pkt_pull(pkt
, sizeof(*icmp
));
1673 tprintf(" ICMPv6 Type (%u) Code (%u)", icmp
->h_type
, icmp
->h_code
);
1676 struct protocol icmpv6_ops
= {
1678 .print_full
= icmpv6
,
1679 .print_less
= icmpv6_less
,
1682 #endif /* PROTO_ICMPV6_H */