tcpdump  4.99.1
About: tcpdump is a tool for network monitoring and data acquisition.
  Fossies Dox: tcpdump-4.99.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

print-icmp6.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994
3  * The Regents of the University of California. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that: (1) source code distributions
7  * retain the above copyright notice and this paragraph in its entirety, (2)
8  * distributions including binary code include the above copyright notice and
9  * this paragraph in its entirety in the documentation or other materials
10  * provided with the distribution, and (3) all advertising materials mentioning
11  * features or use of this software display the following acknowledgement:
12  * ``This product includes software developed by the University of California,
13  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14  * the University nor the names of its contributors may be used to endorse
15  * or promote products derived from this software without specific prior
16  * written permission.
17  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20  */
21 
22 /* \summary: IPv6 Internet Control Message Protocol (ICMPv6) printer */
23 
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 
28 #include "netdissect-stdinc.h"
29 
30 #include <stdio.h>
31 #include <string.h>
32 
33 #include "netdissect.h"
34 #include "addrtoname.h"
35 #include "addrtostr.h"
36 #include "extract.h"
37 
38 #include "ip6.h"
39 #include "ipproto.h"
40 
41 #include "udp.h"
42 #include "ah.h"
43 
44 /* NetBSD: icmp6.h,v 1.13 2000/08/03 16:30:37 itojun Exp */
45 /* $KAME: icmp6.h,v 1.22 2000/08/03 15:25:16 jinmei Exp $ */
46 
47 /*
48  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
49  * All rights reserved.
50  *
51  * Redistribution and use in source and binary forms, with or without
52  * modification, are permitted provided that the following conditions
53  * are met:
54  * 1. Redistributions of source code must retain the above copyright
55  * notice, this list of conditions and the following disclaimer.
56  * 2. Redistributions in binary form must reproduce the above copyright
57  * notice, this list of conditions and the following disclaimer in the
58  * documentation and/or other materials provided with the distribution.
59  * 3. Neither the name of the project nor the names of its contributors
60  * may be used to endorse or promote products derived from this software
61  * without specific prior written permission.
62  *
63  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
64  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
66  * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
67  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
68  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
69  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
70  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
71  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
72  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
73  * SUCH DAMAGE.
74  */
75 
76 struct icmp6_hdr {
77  nd_uint8_t icmp6_type; /* type field */
78  nd_uint8_t icmp6_code; /* code field */
79  nd_uint16_t icmp6_cksum; /* checksum field */
80  union {
81  nd_uint32_t icmp6_un_data32[1]; /* type-specific field */
82  nd_uint16_t icmp6_un_data16[2]; /* type-specific field */
83  nd_uint8_t icmp6_un_data8[4]; /* type-specific field */
84  nd_byte icmp6_un_data[1]; /* type-specific field */
86 };
87 
88 #define icmp6_data32 icmp6_dataun.icmp6_un_data32
89 #define icmp6_data16 icmp6_dataun.icmp6_un_data16
90 #define icmp6_data8 icmp6_dataun.icmp6_un_data8
91 #define icmp6_data icmp6_dataun.icmp6_un_data
92 #define icmp6_pptr icmp6_data32[0] /* parameter prob */
93 #define icmp6_mtu icmp6_data32[0] /* packet too big */
94 #define icmp6_id icmp6_data16[0] /* echo request/reply */
95 #define icmp6_seq icmp6_data16[1] /* echo request/reply */
96 #define icmp6_maxdelay icmp6_data16[0] /* mcast group membership */
97 
98 #define ICMP6_DST_UNREACH 1 /* dest unreachable, codes: */
99 #define ICMP6_PACKET_TOO_BIG 2 /* packet too big */
100 #define ICMP6_TIME_EXCEEDED 3 /* time exceeded, code: */
101 #define ICMP6_PARAM_PROB 4 /* ip6 header bad */
102 
103 #define ICMP6_ECHO_REQUEST 128 /* echo service */
104 #define ICMP6_ECHO_REPLY 129 /* echo reply */
105 #define ICMP6_MEMBERSHIP_QUERY 130 /* group membership query */
106 #define MLD6_LISTENER_QUERY 130 /* multicast listener query */
107 #define ICMP6_MEMBERSHIP_REPORT 131 /* group membership report */
108 #define MLD6_LISTENER_REPORT 131 /* multicast listener report */
109 #define ICMP6_MEMBERSHIP_REDUCTION 132 /* group membership termination */
110 #define MLD6_LISTENER_DONE 132 /* multicast listener done */
111 
112 #define ND_ROUTER_SOLICIT 133 /* router solicitation */
113 #define ND_ROUTER_ADVERT 134 /* router advertisement */
114 #define ND_NEIGHBOR_SOLICIT 135 /* neighbor solicitation */
115 #define ND_NEIGHBOR_ADVERT 136 /* neighbor advertisement */
116 #define ND_REDIRECT 137 /* redirect */
117 
118 #define ICMP6_ROUTER_RENUMBERING 138 /* router renumbering */
119 
120 #define ICMP6_WRUREQUEST 139 /* who are you request */
121 #define ICMP6_WRUREPLY 140 /* who are you reply */
122 #define ICMP6_FQDN_QUERY 139 /* FQDN query */
123 #define ICMP6_FQDN_REPLY 140 /* FQDN reply */
124 #define ICMP6_NI_QUERY 139 /* node information request - RFC 4620 */
125 #define ICMP6_NI_REPLY 140 /* node information reply - RFC 4620 */
126 #define IND_SOLICIT 141 /* inverse neighbor solicitation */
127 #define IND_ADVERT 142 /* inverse neighbor advertisement */
128 
129 #define ICMP6_V2_MEMBERSHIP_REPORT 143 /* v2 membership report */
130 #define MLDV2_LISTENER_REPORT 143 /* v2 multicast listener report */
131 #define ICMP6_HADISCOV_REQUEST 144
132 #define ICMP6_HADISCOV_REPLY 145
133 #define ICMP6_MOBILEPREFIX_SOLICIT 146
134 #define ICMP6_MOBILEPREFIX_ADVERT 147
135 
136 #define MLD6_MTRACE_RESP 200 /* mtrace response(to sender) */
137 #define MLD6_MTRACE 201 /* mtrace messages */
138 
139 #define ICMP6_MAXTYPE 201
140 
141 #define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */
142 #define ICMP6_DST_UNREACH_ADMIN 1 /* administratively prohibited */
143 #define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor(obsolete) */
144 #define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */
145 #define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */
146 #define ICMP6_DST_UNREACH_NOPORT 4 /* port unreachable */
147 
148 #define ICMP6_TIME_EXCEED_TRANSIT 0 /* ttl==0 in transit */
149 #define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* ttl==0 in reass */
150 
151 #define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */
152 #define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized next header */
153 #define ICMP6_PARAMPROB_OPTION 2 /* unrecognized option */
154 #define ICMP6_PARAMPROB_FRAGHDRCHAIN 3 /* incomplete header chain */
155 
156 #define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */
157 
158 #define ICMP6_NI_SUBJ_IPV6 0 /* Query Subject is an IPv6 address */
159 #define ICMP6_NI_SUBJ_FQDN 1 /* Query Subject is a Domain name */
160 #define ICMP6_NI_SUBJ_IPV4 2 /* Query Subject is an IPv4 address */
161 
162 #define ICMP6_NI_SUCCESS 0 /* node information successful reply */
163 #define ICMP6_NI_REFUSED 1 /* node information request is refused */
164 #define ICMP6_NI_UNKNOWN 2 /* unknown Qtype */
165 
166 #define ICMP6_ROUTER_RENUMBERING_COMMAND 0 /* rr command */
167 #define ICMP6_ROUTER_RENUMBERING_RESULT 1 /* rr result */
168 #define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET 255 /* rr seq num reset */
169 
170 /* Used in kernel only */
171 #define ND_REDIRECT_ONLINK 0 /* redirect to an on-link node */
172 #define ND_REDIRECT_ROUTER 1 /* redirect to a better router */
173 
174 /*
175  * Multicast Listener Discovery
176  */
177 struct mld6_hdr {
178  struct icmp6_hdr mld6_hdr;
179  nd_ipv6 mld6_addr; /* multicast address */
180 };
181 
182 #define mld6_type mld6_hdr.icmp6_type
183 #define mld6_code mld6_hdr.icmp6_code
184 #define mld6_cksum mld6_hdr.icmp6_cksum
185 #define mld6_maxdelay mld6_hdr.icmp6_data16[0]
186 #define mld6_reserved mld6_hdr.icmp6_data16[1]
187 
188 #define MLD_MINLEN 24
189 #define MLDV2_MINLEN 28
190 
191 /*
192  * Neighbor Discovery
193  */
194 
195 struct nd_router_solicit { /* router solicitation */
196  struct icmp6_hdr nd_rs_hdr;
197  /* could be followed by options */
198 };
199 
200 #define nd_rs_type nd_rs_hdr.icmp6_type
201 #define nd_rs_code nd_rs_hdr.icmp6_code
202 #define nd_rs_cksum nd_rs_hdr.icmp6_cksum
203 #define nd_rs_reserved nd_rs_hdr.icmp6_data32[0]
204 
205 struct nd_router_advert { /* router advertisement */
206  struct icmp6_hdr nd_ra_hdr;
207  nd_uint32_t nd_ra_reachable; /* reachable time */
208  nd_uint32_t nd_ra_retransmit; /* retransmit timer */
209  /* could be followed by options */
210 };
211 
212 #define nd_ra_type nd_ra_hdr.icmp6_type
213 #define nd_ra_code nd_ra_hdr.icmp6_code
214 #define nd_ra_cksum nd_ra_hdr.icmp6_cksum
215 #define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0]
216 #define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1]
217 #define ND_RA_FLAG_MANAGED 0x80
218 #define ND_RA_FLAG_OTHER 0x40
219 #define ND_RA_FLAG_HOME_AGENT 0x20
220 #define ND_RA_FLAG_IPV6ONLY 0x02
221 
222 /*
223  * Router preference values based on draft-draves-ipngwg-router-selection-01.
224  * These are non-standard definitions.
225  */
226 #define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */
227 
228 #define ND_RA_FLAG_RTPREF_HIGH 0x08 /* 00001000 */
229 #define ND_RA_FLAG_RTPREF_MEDIUM 0x00 /* 00000000 */
230 #define ND_RA_FLAG_RTPREF_LOW 0x18 /* 00011000 */
231 #define ND_RA_FLAG_RTPREF_RSV 0x10 /* 00010000 */
232 
233 #define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1]
234 
235 struct nd_neighbor_solicit { /* neighbor solicitation */
236  struct icmp6_hdr nd_ns_hdr;
237  nd_ipv6 nd_ns_target; /*target address */
238  /* could be followed by options */
239 };
240 
241 #define nd_ns_type nd_ns_hdr.icmp6_type
242 #define nd_ns_code nd_ns_hdr.icmp6_code
243 #define nd_ns_cksum nd_ns_hdr.icmp6_cksum
244 #define nd_ns_reserved nd_ns_hdr.icmp6_data32[0]
245 
246 struct nd_neighbor_advert { /* neighbor advertisement */
247  struct icmp6_hdr nd_na_hdr;
248  nd_ipv6 nd_na_target; /* target address */
249  /* could be followed by options */
250 };
251 
252 #define nd_na_type nd_na_hdr.icmp6_type
253 #define nd_na_code nd_na_hdr.icmp6_code
254 #define nd_na_cksum nd_na_hdr.icmp6_cksum
255 #define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0]
256 
257 #define ND_NA_FLAG_ROUTER 0x80000000
258 #define ND_NA_FLAG_SOLICITED 0x40000000
259 #define ND_NA_FLAG_OVERRIDE 0x20000000
260 
261 struct nd_redirect { /* redirect */
262  struct icmp6_hdr nd_rd_hdr;
263  nd_ipv6 nd_rd_target; /* target address */
264  nd_ipv6 nd_rd_dst; /* destination address */
265  /* could be followed by options */
266 };
267 
268 #define nd_rd_type nd_rd_hdr.icmp6_type
269 #define nd_rd_code nd_rd_hdr.icmp6_code
270 #define nd_rd_cksum nd_rd_hdr.icmp6_cksum
271 #define nd_rd_reserved nd_rd_hdr.icmp6_data32[0]
272 
273 struct nd_opt_hdr { /* Neighbor discovery option header */
276  /* followed by option specific data*/
277 };
278 
279 #define ND_OPT_SOURCE_LINKADDR 1
280 #define ND_OPT_TARGET_LINKADDR 2
281 #define ND_OPT_PREFIX_INFORMATION 3
282 #define ND_OPT_REDIRECTED_HEADER 4
283 #define ND_OPT_MTU 5
284 #define ND_OPT_ADVINTERVAL 7
285 #define ND_OPT_HOMEAGENT_INFO 8
286 #define ND_OPT_ROUTE_INFO 24 /* RFC4191 */
287 #define ND_OPT_RDNSS 25
288 #define ND_OPT_DNSSL 31
289 
290 struct nd_opt_prefix_info { /* prefix information */
299 };
300 
301 #define ND_OPT_PI_FLAG_ONLINK 0x80
302 #define ND_OPT_PI_FLAG_AUTO 0x40
303 #define ND_OPT_PI_FLAG_ROUTER 0x20 /*2292bis*/
304 
305 struct nd_opt_rd_hdr { /* redirected header */
310  /* followed by IP header and data */
311 };
312 
313 struct nd_opt_mtu { /* MTU option */
318 };
319 
320 struct nd_opt_rdnss { /* RDNSS RFC 6106 5.1 */
325  nd_ipv6 nd_opt_rdnss_addr[1]; /* variable-length */
326 };
327 
328 struct nd_opt_dnssl { /* DNSSL RFC 6106 5.2 */
333  /* followed by list of DNS search domains, variable-length */
334 };
335 
336 struct nd_opt_advinterval { /* Advertisement interval option */
341 };
342 
343 struct nd_opt_homeagent_info { /* Home Agent info */
349 };
350 
351 struct nd_opt_route_info { /* route info */
357  /* prefix follows */
358 };
359 
360 /*
361  * icmp6 namelookup
362  */
363 
365  struct icmp6_hdr icmp6_nl_hdr;
368 #if 0
369  nd_uint8_t icmp6_nl_len;
370  nd_byte icmp6_nl_name[3];
371 #endif
372  /* could be followed by options */
373 };
374 
375 /*
376  * icmp6 node information
377  */
379  struct icmp6_hdr icmp6_ni_hdr;
381  /* could be followed by reply data */
382 };
383 
384 #define ni_type icmp6_ni_hdr.icmp6_type
385 #define ni_code icmp6_ni_hdr.icmp6_code
386 #define ni_cksum icmp6_ni_hdr.icmp6_cksum
387 #define ni_qtype icmp6_ni_hdr.icmp6_data16[0]
388 #define ni_flags icmp6_ni_hdr.icmp6_data16[1]
389 
390 #define NI_QTYPE_NOOP 0 /* NOOP */
391 #define NI_QTYPE_SUPTYPES 1 /* Supported Qtypes (drafts up to 09) */
392 #define NI_QTYPE_FQDN 2 /* FQDN (draft 04) */
393 #define NI_QTYPE_DNSNAME 2 /* DNS Name */
394 #define NI_QTYPE_NODEADDR 3 /* Node Addresses */
395 #define NI_QTYPE_IPV4ADDR 4 /* IPv4 Addresses */
396 
397 /* network endian */
398 #define NI_SUPTYPE_FLAG_COMPRESS ((uint16_t)htons(0x1))
399 #define NI_FQDN_FLAG_VALIDTTL ((uint16_t)htons(0x1))
400 
401 /* network endian */
402 #define NI_NODEADDR_FLAG_TRUNCATE ((uint16_t)htons(0x1))
403 #define NI_NODEADDR_FLAG_ALL ((uint16_t)htons(0x2))
404 #define NI_NODEADDR_FLAG_COMPAT ((uint16_t)htons(0x4))
405 #define NI_NODEADDR_FLAG_LINKLOCAL ((uint16_t)htons(0x8))
406 #define NI_NODEADDR_FLAG_SITELOCAL ((uint16_t)htons(0x10))
407 #define NI_NODEADDR_FLAG_GLOBAL ((uint16_t)htons(0x20))
408 #define NI_NODEADDR_FLAG_ANYCAST ((uint16_t)htons(0x40)) /* just experimental. not in spec */
409 
412  nd_uint8_t ni_fqdn_namelen; /* length in octets of the FQDN */
413  nd_byte ni_fqdn_name[3]; /* XXX: alignment */
414 };
415 
416 /*
417  * Router Renumbering. as router-renum-08.txt
418  */
419 struct icmp6_router_renum { /* router renumbering header */
420  struct icmp6_hdr rr_hdr;
425 };
426 #define ICMP6_RR_FLAGS_TEST 0x80
427 #define ICMP6_RR_FLAGS_REQRESULT 0x40
428 #define ICMP6_RR_FLAGS_FORCEAPPLY 0x20
429 #define ICMP6_RR_FLAGS_SPECSITE 0x10
430 #define ICMP6_RR_FLAGS_PREVDONE 0x08
431 
432 #define rr_type rr_hdr.icmp6_type
433 #define rr_code rr_hdr.icmp6_code
434 #define rr_cksum rr_hdr.icmp6_cksum
435 #define rr_seqnum rr_hdr.icmp6_data32[0]
436 
437 struct rr_pco_match { /* match prefix part */
446 };
447 
448 #define RPM_PCO_ADD 1
449 #define RPM_PCO_CHANGE 2
450 #define RPM_PCO_SETGLOBAL 3
451 #define RPM_PCO_MAX 4
452 
453 struct rr_pco_use { /* use prefix part */
462 };
463 #define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x80
464 #define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x40
465 
466 /* network endian */
467 #define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME ((uint32_t)htonl(0x80000000))
468 #define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME ((uint32_t)htonl(0x40000000))
469 
470 struct rr_result { /* router renumbering result message */
476 };
477 /* network endian */
478 #define ICMP6_RR_RESULT_FLAGS_OOB ((uint16_t)htons(0x0002))
479 #define ICMP6_RR_RESULT_FLAGS_FORBIDDEN ((uint16_t)htons(0x0001))
480 
481 static const char *get_rtpref(u_int);
482 static const char *get_lifetime(uint32_t);
483 static void print_lladdr(netdissect_options *ndo, const u_char *, size_t);
484 static int icmp6_opt_print(netdissect_options *ndo, const u_char *, int);
485 static void mld6_print(netdissect_options *ndo, const u_char *);
486 static void mldv2_report_print(netdissect_options *ndo, const u_char *, u_int);
487 static void mldv2_query_print(netdissect_options *ndo, const u_char *, u_int);
488 static const struct udphdr *get_upperlayer(netdissect_options *ndo, const u_char *, u_int *);
489 static void dnsname_print(netdissect_options *ndo, const u_char *, const u_char *);
490 static void icmp6_nodeinfo_print(netdissect_options *ndo, u_int, const u_char *, const u_char *);
491 static void icmp6_rrenum_print(netdissect_options *ndo, const u_char *, const u_char *);
492 
493 #ifndef abs
494 #define abs(a) ((0 < (a)) ? (a) : -(a))
495 #endif
496 
497 /*
498  * DIO: Updated to RFC6550, as published in 2012: section 6. (page 30)
499  */
500 
501 #define ND_RPL_MESSAGE 155 /* 0x9B */
502 
506  ND_RPL_DAO =0x02,
512  ND_RPL_SEC_CONSIST= 0x8A
513 };
514 
521  ND_RPL_DIO_PRF_MASK = 0x07 /* 3-bit preference */
522 };
523 
524 #define DAGID_LEN 16
525 
526 /* section 6 of draft-ietf-roll-rpl-19 */
528  nd_uint8_t rpl_sec_t_reserved; /* bit 7 is T-bit */
530  nd_uint16_t rpl_sec_kim_lvl_flags; /* bit 15/14, KIM */
531  /* bit 10-8, LVL, bit 7-0 flags */
533 #if 0
534  nd_byte rpl_sec_ki[0]; /* depends upon kim */
535 #endif
536 };
537 
538 /* section 6.2.1, DODAG Information Solication (DIS_IS) */
542 #if 0
543  nd_byte rpl_dis_options[0];
544 #endif
545 };
546 
547 /* section 6.3.1, DODAG Information Object (DIO) */
548 struct nd_rpl_dio {
552  nd_uint8_t rpl_mopprf; /* bit 7=G, 5-3=MOP, 2-0=PRF */
553  nd_uint8_t rpl_dtsn; /* Dest. Advertisement Trigger Sequence Number */
554  nd_uint8_t rpl_flags; /* no flags defined yet */
557 };
558 #define RPL_DIO_GROUND_FLAG 0x80
559 #define RPL_DIO_MOP_SHIFT 3
560 #define RPL_DIO_MOP_MASK (7 << RPL_DIO_MOP_SHIFT)
561 #define RPL_DIO_PRF_SHIFT 0
562 #define RPL_DIO_PRF_MASK (7 << RPL_DIO_PRF_SHIFT)
563 #define RPL_DIO_GROUNDED(X) ((X)&RPL_DIO_GROUND_FLAG)
564 #define RPL_DIO_MOP(X) (enum RPL_DIO_MOP)(((X)&RPL_DIO_MOP_MASK) >> RPL_DIO_MOP_SHIFT)
565 #define RPL_DIO_PRF(X) (((X)&RPL_DIO_PRF_MASK) >> RPL_DIO_PRF_SHIFT)
566 
572 };
573 
584 };
585 
588  nd_uint8_t rpl_dio_len; /* suboption length, not including type/len */
589 };
590 #define RPL_GENOPTION_LEN 2
591 
592 #define RPL_DIO_LIFETIME_INFINITE 0xffffffff
593 #define RPL_DIO_LIFETIME_DISCONNECT 0
594 
599  nd_uint8_t rpl_dio_prf; /* flags, including Route Preference */
601 #if 0
602  nd_byte rpl_dio_prefix[0]; /* variable number of bytes */
603 #endif
604 };
605 
606 /* section 6.4.1, DODAG Information Object (DIO) */
607 struct nd_rpl_dao {
609  nd_uint8_t rpl_flags; /* bit 7=K, 6=D */
612  nd_byte rpl_dagid[DAGID_LEN]; /* present when D set. */
613 };
614 #define ND_RPL_DAO_MIN_LEN 4 /* length without DAGID */
615 
616 /* indicates if this DAO is to be acK'ed */
617 #define RPL_DAO_K_SHIFT 7
618 #define RPL_DAO_K_MASK (1 << RPL_DAO_K_SHIFT)
619 #define RPL_DAO_K(X) (((X)&RPL_DAO_K_MASK) >> RPL_DAO_K_SHIFT)
620 
621 /* indicates if the DAGID is present */
622 #define RPL_DAO_D_SHIFT 6
623 #define RPL_DAO_D_MASK (1 << RPL_DAO_D_SHIFT)
624 #define RPL_DAO_D(X) (((X)&RPL_DAO_D_MASK) >> RPL_DAO_D_SHIFT)
625 
629  nd_uint8_t rpl_dao_flags; /* unused */
631 #if 0
632  nd_byte rpl_dao_prefix[0]; /* variable number of bytes */
633 #endif
634 };
635 
636 /* section 6.5.1, Destination Advertisement Object Acknowledgement (DAO-ACK) */
639  nd_uint8_t rpl_flags; /* bit 7=D */
642  nd_byte rpl_dagid[DAGID_LEN]; /* present when D set. */
643 };
644 #define ND_RPL_DAOACK_MIN_LEN 4 /* length without DAGID */
645 /* indicates if the DAGID is present */
646 #define RPL_DAOACK_D_SHIFT 7
647 #define RPL_DAOACK_D_MASK (1 << RPL_DAOACK_D_SHIFT)
648 #define RPL_DAOACK_D(X) (((X)&RPL_DAOACK_D_MASK) >> RPL_DAOACK_D_SHIFT)
649 
650 static const struct tok icmp6_type_values[] = {
651  { ICMP6_DST_UNREACH, "destination unreachable"},
652  { ICMP6_PACKET_TOO_BIG, "packet too big"},
653  { ICMP6_TIME_EXCEEDED, "time exceeded in-transit"},
654  { ICMP6_PARAM_PROB, "parameter problem"},
655  { ICMP6_ECHO_REQUEST, "echo request"},
656  { ICMP6_ECHO_REPLY, "echo reply"},
657  { MLD6_LISTENER_QUERY, "multicast listener query"},
658  { MLD6_LISTENER_REPORT, "multicast listener report"},
659  { MLD6_LISTENER_DONE, "multicast listener done"},
660  { ND_ROUTER_SOLICIT, "router solicitation"},
661  { ND_ROUTER_ADVERT, "router advertisement"},
662  { ND_NEIGHBOR_SOLICIT, "neighbor solicitation"},
663  { ND_NEIGHBOR_ADVERT, "neighbor advertisement"},
664  { ND_REDIRECT, "redirect"},
665  { ICMP6_ROUTER_RENUMBERING, "router renumbering"},
666  { IND_SOLICIT, "inverse neighbor solicitation"},
667  { IND_ADVERT, "inverse neighbor advertisement"},
668  { MLDV2_LISTENER_REPORT, "multicast listener report v2"},
669  { ICMP6_HADISCOV_REQUEST, "ha discovery request"},
670  { ICMP6_HADISCOV_REPLY, "ha discovery reply"},
671  { ICMP6_MOBILEPREFIX_SOLICIT, "mobile router solicitation"},
672  { ICMP6_MOBILEPREFIX_ADVERT, "mobile router advertisement"},
673  { ICMP6_WRUREQUEST, "who-are-you request"},
674  { ICMP6_WRUREPLY, "who-are-you reply"},
675  { ICMP6_NI_QUERY, "node information query"},
676  { ICMP6_NI_REPLY, "node information reply"},
677  { MLD6_MTRACE, "mtrace message"},
678  { MLD6_MTRACE_RESP, "mtrace response"},
679  { ND_RPL_MESSAGE, "RPL"},
680  { 0, NULL }
681 };
682 
683 static const struct tok icmp6_dst_unreach_code_values[] = {
684  { ICMP6_DST_UNREACH_NOROUTE, "unreachable route" },
685  { ICMP6_DST_UNREACH_ADMIN, " unreachable prohibited"},
686  { ICMP6_DST_UNREACH_BEYONDSCOPE, "beyond scope"},
687  { ICMP6_DST_UNREACH_ADDR, "unreachable address"},
688  { ICMP6_DST_UNREACH_NOPORT, "unreachable port"},
689  { 0, NULL }
690 };
691 
692 static const struct tok icmp6_opt_pi_flag_values[] = {
693  { ND_OPT_PI_FLAG_ONLINK, "onlink" },
694  { ND_OPT_PI_FLAG_AUTO, "auto" },
695  { ND_OPT_PI_FLAG_ROUTER, "router" },
696  { 0, NULL }
697 };
698 
699 static const struct tok icmp6_opt_ra_flag_values[] = {
700  { ND_RA_FLAG_MANAGED, "managed" },
701  { ND_RA_FLAG_OTHER, "other stateful"},
702  { ND_RA_FLAG_HOME_AGENT, "home agent"},
703  { ND_RA_FLAG_IPV6ONLY, "ipv6 only"},
704  { 0, NULL }
705 };
706 
707 static const struct tok icmp6_nd_na_flag_values[] = {
708  { ND_NA_FLAG_ROUTER, "router" },
709  { ND_NA_FLAG_SOLICITED, "solicited" },
710  { ND_NA_FLAG_OVERRIDE, "override" },
711  { 0, NULL }
712 };
713 
714 
715 static const struct tok icmp6_opt_values[] = {
716  { ND_OPT_SOURCE_LINKADDR, "source link-address"},
717  { ND_OPT_TARGET_LINKADDR, "destination link-address"},
718  { ND_OPT_PREFIX_INFORMATION, "prefix info"},
719  { ND_OPT_REDIRECTED_HEADER, "redirected header"},
720  { ND_OPT_MTU, "mtu"},
721  { ND_OPT_RDNSS, "rdnss"},
722  { ND_OPT_DNSSL, "dnssl"},
723  { ND_OPT_ADVINTERVAL, "advertisement interval"},
724  { ND_OPT_HOMEAGENT_INFO, "homeagent information"},
725  { ND_OPT_ROUTE_INFO, "route info"},
726  { 0, NULL }
727 };
728 
729 /* mldv2 report types */
730 static const struct tok mldv2report2str[] = {
731  { 1, "is_in" },
732  { 2, "is_ex" },
733  { 3, "to_in" },
734  { 4, "to_ex" },
735  { 5, "allow" },
736  { 6, "block" },
737  { 0, NULL }
738 };
739 
740 static const char *
741 get_rtpref(u_int v)
742 {
743  static const char *rtpref_str[] = {
744  "medium", /* 00 */
745  "high", /* 01 */
746  "rsv", /* 10 */
747  "low" /* 11 */
748  };
749 
750  return rtpref_str[((v & ND_RA_FLAG_RTPREF_MASK) >> 3) & 0xff];
751 }
752 
753 static const char *
754 get_lifetime(uint32_t v)
755 {
756  static char buf[20];
757 
758  if (v == (uint32_t)~0UL)
759  return "infinity";
760  else {
761  snprintf(buf, sizeof(buf), "%us", v);
762  return buf;
763  }
764 }
765 
766 static void
767 print_lladdr(netdissect_options *ndo, const uint8_t *p, size_t l)
768 {
769  const uint8_t *ep, *q;
770 
771  q = p;
772  ep = p + l;
773  while (l > 0 && q < ep) {
774  if (q > p)
775  ND_PRINT(":");
776  ND_PRINT("%02x", GET_U_1(q));
777  q++;
778  l--;
779  }
780 }
781 
782 static uint16_t icmp6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6,
783  const struct icmp6_hdr *icp, u_int len)
784 {
785  return nextproto6_cksum(ndo, ip6, (const uint8_t *)(const void *)icp, len, len,
787 }
788 
789 static const struct tok rpl_mop_values[] = {
790  { RPL_DIO_NONSTORING, "nonstoring"},
791  { RPL_DIO_STORING, "storing"},
792  { RPL_DIO_NONSTORING_MULTICAST, "nonstoring-multicast"},
793  { RPL_DIO_STORING_MULTICAST, "storing-multicast"},
794  { 0, NULL},
795 };
796 
797 static const struct tok rpl_subopt_values[] = {
798  { RPL_OPT_PAD1, "pad1"},
799  { RPL_OPT_PADN, "padN"},
800  { RPL_DIO_METRICS, "metrics"},
801  { RPL_DIO_ROUTINGINFO, "routinginfo"},
802  { RPL_DIO_CONFIG, "config"},
803  { RPL_DAO_RPLTARGET, "rpltarget"},
804  { RPL_DAO_TRANSITINFO, "transitinfo"},
805  { RPL_DIO_DESTPREFIX, "destprefix"},
806  { RPL_DAO_RPLTARGET_DESC, "rpltargetdesc"},
807  { 0, NULL},
808 };
809 
810 static void
811 rpl_printopts(netdissect_options *ndo, const uint8_t *opts, u_int length)
812 {
813  const struct rpl_genoption *opt;
814  uint8_t dio_type;
815  u_int optlen;
816 
817  while (length != 0) {
818  opt = (const struct rpl_genoption *)opts;
819  dio_type = GET_U_1(opt->rpl_dio_type);
820  if (dio_type == RPL_OPT_PAD1) {
821  optlen = 1;
822  ND_PRINT(" opt:pad1");
823  } else {
824  if (length < RPL_GENOPTION_LEN)
825  goto trunc;
826  optlen = GET_U_1(opt->rpl_dio_len)+RPL_GENOPTION_LEN;
827  ND_PRINT(" opt:%s len:%u ",
828  tok2str(rpl_subopt_values, "subopt:%u", dio_type),
829  optlen);
830  ND_TCHECK_LEN(opt, optlen);
831  if (length < optlen)
832  goto trunc;
833  if (ndo->ndo_vflag > 2) {
834  hex_print(ndo,
835  " ",
836  opts + RPL_GENOPTION_LEN, /* content of DIO option */
837  optlen - RPL_GENOPTION_LEN);
838  }
839  }
840  opts += optlen;
841  length -= optlen;
842  }
843  return;
844 trunc:
845  nd_print_trunc(ndo);
846 }
847 
848 static void
850  const u_char *bp, u_int length)
851 {
852  const struct nd_rpl_dio *dio = (const struct nd_rpl_dio *)bp;
853  const char *dagid_str;
854 
855  ND_TCHECK_SIZE(dio);
856  dagid_str = ip6addr_string (ndo, dio->rpl_dagid);
857 
858  ND_PRINT(" [dagid:%s,seq:%u,instance:%u,rank:%u,%smop:%s,prf:%u]",
859  dagid_str,
860  GET_U_1(dio->rpl_dtsn),
861  GET_U_1(dio->rpl_instanceid),
862  GET_BE_U_2(dio->rpl_dagrank),
863  RPL_DIO_GROUNDED(GET_U_1(dio->rpl_mopprf)) ? "grounded,":"",
866 
867  if(ndo->ndo_vflag > 1) {
868  rpl_printopts(ndo, bp + sizeof(struct nd_rpl_dio),
869  length - sizeof(struct nd_rpl_dio));
870  }
871  return;
872 trunc:
873  nd_print_trunc(ndo);
874 }
875 
876 static void
878  const u_char *bp, u_int length)
879 {
880  const struct nd_rpl_dao *dao = (const struct nd_rpl_dao *)bp;
881  const char *dagid_str = "<elided>";
882  uint8_t rpl_flags;
883 
884  ND_TCHECK_SIZE(dao);
885  if (length < ND_RPL_DAO_MIN_LEN)
886  goto tooshort;
887 
888  bp += ND_RPL_DAO_MIN_LEN;
889  length -= ND_RPL_DAO_MIN_LEN;
890  rpl_flags = GET_U_1(dao->rpl_flags);
891  if(RPL_DAO_D(rpl_flags)) {
893  if (length < DAGID_LEN)
894  goto tooshort;
895  dagid_str = ip6addr_string (ndo, dao->rpl_dagid);
896  bp += DAGID_LEN;
897  length -= DAGID_LEN;
898  }
899 
900  ND_PRINT(" [dagid:%s,seq:%u,instance:%u%s%s,%02x]",
901  dagid_str,
902  GET_U_1(dao->rpl_daoseq),
903  GET_U_1(dao->rpl_instanceid),
904  RPL_DAO_K(rpl_flags) ? ",acK":"",
905  RPL_DAO_D(rpl_flags) ? ",Dagid":"",
906  rpl_flags);
907 
908  if(ndo->ndo_vflag > 1) {
909  rpl_printopts(ndo, bp, length);
910  }
911  return;
912 
913 trunc:
914  nd_print_trunc(ndo);
915  return;
916 
917 tooshort:
918  ND_PRINT(" [|length too short]");
919 }
920 
921 static void
923  const u_char *bp, u_int length)
924 {
925  const struct nd_rpl_daoack *daoack = (const struct nd_rpl_daoack *)bp;
926  const char *dagid_str = "<elided>";
927 
929  if (length < ND_RPL_DAOACK_MIN_LEN)
930  goto tooshort;
931 
932  bp += ND_RPL_DAOACK_MIN_LEN;
933  length -= ND_RPL_DAOACK_MIN_LEN;
934  if(RPL_DAOACK_D(GET_U_1(daoack->rpl_flags))) {
936  if (length < DAGID_LEN)
937  goto tooshort;
938  dagid_str = ip6addr_string (ndo, daoack->rpl_dagid);
939  bp += DAGID_LEN;
940  length -= DAGID_LEN;
941  }
942 
943  ND_PRINT(" [dagid:%s,seq:%u,instance:%u,status:%u]",
944  dagid_str,
945  GET_U_1(daoack->rpl_daoseq),
946  GET_U_1(daoack->rpl_instanceid),
947  GET_U_1(daoack->rpl_status));
948 
949  /* no officially defined options for DAOACK, but print any we find */
950  if(ndo->ndo_vflag > 1) {
951  rpl_printopts(ndo, bp, length);
952  }
953  return;
954 
955 trunc:
956  nd_print_trunc(ndo);
957  return;
958 
959 tooshort:
960  ND_PRINT(" [|dao-length too short]");
961 }
962 
963 static void
965  uint8_t icmp6_code,
966  const u_char *bp, u_int length)
967 {
968  int secured = icmp6_code & 0x80;
969  int basecode= icmp6_code & 0x7f;
970 
971  if(secured) {
972  ND_PRINT(", (SEC) [worktodo]");
973  /* XXX
974  * the next header pointer needs to move forward to
975  * skip the secure part.
976  */
977  return;
978  } else {
979  ND_PRINT(", (CLR)");
980  }
981 
982  switch(basecode) {
983  case ND_RPL_DAG_IS:
984  ND_PRINT("DODAG Information Solicitation");
985  if(ndo->ndo_vflag) {
986  }
987  break;
988  case ND_RPL_DAG_IO:
989  ND_PRINT("DODAG Information Object");
990  if(ndo->ndo_vflag) {
991  rpl_dio_print(ndo, bp, length);
992  }
993  break;
994  case ND_RPL_DAO:
995  ND_PRINT("Destination Advertisement Object");
996  if(ndo->ndo_vflag) {
997  rpl_dao_print(ndo, bp, length);
998  }
999  break;
1000  case ND_RPL_DAO_ACK:
1001  ND_PRINT("Destination Advertisement Object Ack");
1002  if(ndo->ndo_vflag) {
1003  rpl_daoack_print(ndo, bp, length);
1004  }
1005  break;
1006  default:
1007  ND_PRINT("RPL message, unknown code %u",icmp6_code);
1008  break;
1009  }
1010  return;
1011 
1012 #if 0
1013 trunc:
1014  nd_print_trunc(ndo);
1015  return;
1016 #endif
1017 
1018 }
1019 
1020 
1021 void
1023  const u_char *bp, u_int length, const u_char *bp2, int fragmented)
1024 {
1025  const struct icmp6_hdr *dp;
1026  uint8_t icmp6_type, icmp6_code;
1027  const struct ip6_hdr *ip;
1028  const struct ip6_hdr *oip;
1029  const struct udphdr *ouh;
1030  uint16_t dport;
1031  const u_char *ep;
1032  u_int prot;
1033 
1034  ndo->ndo_protocol = "icmp6";
1035  dp = (const struct icmp6_hdr *)bp;
1036  ip = (const struct ip6_hdr *)bp2;
1037  oip = (const struct ip6_hdr *)(dp + 1);
1038  /* 'ep' points to the end of available data. */
1039  ep = ndo->ndo_snapend;
1040  if (length == 0) {
1041  ND_PRINT("ICMP6, length 0");
1042  nd_print_invalid(ndo);
1043  return;
1044  }
1045 
1046  if (ndo->ndo_vflag && !fragmented) {
1047  uint16_t sum, udp_sum;
1048 
1049  if (ND_TTEST_LEN(bp, length)) {
1050  udp_sum = GET_BE_U_2(dp->icmp6_cksum);
1051  sum = icmp6_cksum(ndo, ip, dp, length);
1052  if (sum != 0)
1053  ND_PRINT("[bad icmp6 cksum 0x%04x -> 0x%04x!] ",
1054  udp_sum,
1055  in_cksum_shouldbe(udp_sum, sum));
1056  else
1057  ND_PRINT("[icmp6 sum ok] ");
1058  }
1059  }
1060 
1061  icmp6_type = GET_U_1(dp->icmp6_type);
1062  ND_PRINT("ICMP6, %s", tok2str(icmp6_type_values,"unknown icmp6 type (%u)",icmp6_type));
1063 
1064  /* display cosmetics: print the packet length for printer that use the vflag now */
1065  if (ndo->ndo_vflag && (icmp6_type == ND_ROUTER_SOLICIT ||
1066  icmp6_type == ND_ROUTER_ADVERT ||
1067  icmp6_type == ND_NEIGHBOR_ADVERT ||
1068  icmp6_type == ND_NEIGHBOR_SOLICIT ||
1069  icmp6_type == ND_REDIRECT ||
1070  icmp6_type == ICMP6_HADISCOV_REPLY ||
1071  icmp6_type == ICMP6_MOBILEPREFIX_ADVERT ))
1072  ND_PRINT(", length %u", length);
1073 
1074  icmp6_code = GET_U_1(dp->icmp6_code);
1075 
1076  switch (icmp6_type) {
1077  case ICMP6_DST_UNREACH:
1078  ND_PRINT(", %s", tok2str(icmp6_dst_unreach_code_values,"unknown unreach code (%u)",icmp6_code));
1079  switch (icmp6_code) {
1080 
1081  case ICMP6_DST_UNREACH_NOROUTE: /* fall through */
1084  ND_PRINT(" %s",GET_IP6ADDR_STRING(oip->ip6_dst));
1085  break;
1087  ND_PRINT(" %s, source address %s",
1089  GET_IP6ADDR_STRING(oip->ip6_src));
1090  break;
1092  if ((ouh = get_upperlayer(ndo, (const u_char *)oip, &prot))
1093  == NULL)
1094  goto trunc;
1095 
1096  dport = GET_BE_U_2(ouh->uh_dport);
1097  switch (prot) {
1098  case IPPROTO_TCP:
1099  ND_PRINT(", %s tcp port %s",
1100  GET_IP6ADDR_STRING(oip->ip6_dst),
1101  tcpport_string(ndo, dport));
1102  break;
1103  case IPPROTO_UDP:
1104  ND_PRINT(", %s udp port %s",
1105  GET_IP6ADDR_STRING(oip->ip6_dst),
1106  udpport_string(ndo, dport));
1107  break;
1108  default:
1109  ND_PRINT(", %s protocol %u port %u unreachable",
1110  GET_IP6ADDR_STRING(oip->ip6_dst),
1111  prot, dport);
1112  break;
1113  }
1114  break;
1115  default:
1116  if (ndo->ndo_vflag <= 1) {
1117  print_unknown_data(ndo, bp,"\n\t",length);
1118  return;
1119  }
1120  break;
1121  }
1122  break;
1123  case ICMP6_PACKET_TOO_BIG:
1124  ND_PRINT(", mtu %u", GET_BE_U_4(dp->icmp6_mtu));
1125  break;
1126  case ICMP6_TIME_EXCEEDED:
1127  switch (icmp6_code) {
1129  ND_PRINT(" for %s",
1130  GET_IP6ADDR_STRING(oip->ip6_dst));
1131  break;
1133  ND_PRINT(" (reassembly)");
1134  break;
1135  default:
1136  ND_PRINT(", unknown code (%u)", icmp6_code);
1137  break;
1138  }
1139  break;
1140  case ICMP6_PARAM_PROB:
1141  ND_TCHECK_16(oip->ip6_dst);
1142  switch (icmp6_code) {
1144  ND_PRINT(", erroneous - octet %u",
1145  GET_BE_U_4(dp->icmp6_pptr));
1146  break;
1148  ND_PRINT(", next header - octet %u",
1149  GET_BE_U_4(dp->icmp6_pptr));
1150  break;
1152  ND_PRINT(", option - octet %u",
1153  GET_BE_U_4(dp->icmp6_pptr));
1154  break;
1156  ND_PRINT(", incomplete header chain - octet %u",
1157  GET_BE_U_4(dp->icmp6_pptr));
1158  break;
1159  default:
1160  ND_PRINT(", code-#%u",
1161  icmp6_code);
1162  break;
1163  }
1164  break;
1165  case ICMP6_ECHO_REQUEST:
1166  case ICMP6_ECHO_REPLY:
1167  ND_PRINT(", id %u, seq %u", GET_BE_U_2(dp->icmp6_id),
1168  GET_BE_U_2(dp->icmp6_seq));
1169  break;
1171  if (length == MLD_MINLEN) {
1172  mld6_print(ndo, (const u_char *)dp);
1173  } else if (length >= MLDV2_MINLEN) {
1174  ND_PRINT(" v2");
1175  mldv2_query_print(ndo, (const u_char *)dp, length);
1176  } else {
1177  ND_PRINT(" unknown-version (len %u) ", length);
1178  }
1179  break;
1181  mld6_print(ndo, (const u_char *)dp);
1182  break;
1184  mld6_print(ndo, (const u_char *)dp);
1185  break;
1186  case ND_ROUTER_SOLICIT:
1187 #define RTSOLLEN 8
1188  if (ndo->ndo_vflag) {
1189  if (icmp6_opt_print(ndo, (const u_char *)dp + RTSOLLEN,
1190  length - RTSOLLEN) == -1)
1191  goto trunc;
1192  }
1193  break;
1194  case ND_ROUTER_ADVERT:
1195 #define RTADVLEN 16
1196  if (ndo->ndo_vflag) {
1197  const struct nd_router_advert *p;
1198 
1199  p = (const struct nd_router_advert *)dp;
1200  ND_PRINT("\n\thop limit %u, Flags [%s]"
1201  ", pref %s, router lifetime %us, reachable time %ums, retrans timer %ums",
1202  GET_U_1(p->nd_ra_curhoplimit),
1203  bittok2str(icmp6_opt_ra_flag_values,"none",GET_U_1(p->nd_ra_flags_reserved)),
1204  get_rtpref(GET_U_1(p->nd_ra_flags_reserved)),
1205  GET_BE_U_2(p->nd_ra_router_lifetime),
1208 
1209  if (icmp6_opt_print(ndo, (const u_char *)dp + RTADVLEN,
1210  length - RTADVLEN) == -1)
1211  goto trunc;
1212  }
1213  break;
1214  case ND_NEIGHBOR_SOLICIT:
1215  {
1216  const struct nd_neighbor_solicit *p;
1217  p = (const struct nd_neighbor_solicit *)dp;
1218  ND_PRINT(", who has %s", GET_IP6ADDR_STRING(p->nd_ns_target));
1219  if (ndo->ndo_vflag) {
1220 #define NDSOLLEN 24
1221  if (icmp6_opt_print(ndo, (const u_char *)dp + NDSOLLEN,
1222  length - NDSOLLEN) == -1)
1223  goto trunc;
1224  }
1225  }
1226  break;
1227  case ND_NEIGHBOR_ADVERT:
1228  {
1229  const struct nd_neighbor_advert *p;
1230 
1231  p = (const struct nd_neighbor_advert *)dp;
1232  ND_PRINT(", tgt is %s",
1234  if (ndo->ndo_vflag) {
1235  ND_PRINT(", Flags [%s]",
1237  "none",
1238  GET_BE_U_4(p->nd_na_flags_reserved)));
1239 #define NDADVLEN 24
1240  if (icmp6_opt_print(ndo, (const u_char *)dp + NDADVLEN,
1241  length - NDADVLEN) == -1)
1242  goto trunc;
1243 #undef NDADVLEN
1244  }
1245  }
1246  break;
1247  case ND_REDIRECT:
1248  {
1249  const struct nd_redirect *p;
1250 
1251  p = (const struct nd_redirect *)dp;
1252  ND_PRINT(", %s", GET_IP6ADDR_STRING(p->nd_rd_dst));
1253  ND_PRINT(" to %s", GET_IP6ADDR_STRING(p->nd_rd_target));
1254 #define REDIRECTLEN 40
1255  if (ndo->ndo_vflag) {
1256  if (icmp6_opt_print(ndo, (const u_char *)dp + REDIRECTLEN,
1257  length - REDIRECTLEN) == -1)
1258  goto trunc;
1259 #undef REDIRECTLEN
1260  }
1261  }
1262  break;
1264  icmp6_rrenum_print(ndo, bp, ep);
1265  break;
1266  case ICMP6_NI_QUERY:
1267  case ICMP6_NI_REPLY:
1268  icmp6_nodeinfo_print(ndo, length, bp, ep);
1269  break;
1270  case IND_SOLICIT:
1271  case IND_ADVERT:
1272  break;
1274  mldv2_report_print(ndo, (const u_char *) dp, length);
1275  break;
1276  case ICMP6_MOBILEPREFIX_SOLICIT: /* fall through */
1278  ND_PRINT(", id 0x%04x", GET_BE_U_2(dp->icmp6_data16[0]));
1279  break;
1280  case ICMP6_HADISCOV_REPLY:
1281  if (ndo->ndo_vflag) {
1282  const u_char *cp;
1283  const u_char *p;
1284 
1285  ND_PRINT(", id 0x%04x",
1286  GET_BE_U_2(dp->icmp6_data16[0]));
1287  cp = (const u_char *)dp + length;
1288  p = (const u_char *)(dp + 1);
1289  while (p < cp) {
1290  ND_PRINT(", %s", GET_IP6ADDR_STRING(p));
1291  p += 16;
1292  }
1293  }
1294  break;
1296  if (ndo->ndo_vflag) {
1297  uint16_t flags;
1298 
1299  ND_PRINT(", id 0x%04x",
1300  GET_BE_U_2(dp->icmp6_data16[0]));
1301  flags = GET_BE_U_2(dp->icmp6_data16[1]);
1302  if (flags & 0xc000)
1303  ND_PRINT(" ");
1304  if (flags & 0x8000)
1305  ND_PRINT("M");
1306  if (flags & 0x4000)
1307  ND_PRINT("O");
1308 #define MPADVLEN 8
1309  if (icmp6_opt_print(ndo, (const u_char *)dp + MPADVLEN,
1310  length - MPADVLEN) == -1)
1311  goto trunc;
1312  }
1313  break;
1314  case ND_RPL_MESSAGE:
1315  /* plus 4, because struct icmp6_hdr contains 4 bytes of icmp payload */
1316  rpl_print(ndo, icmp6_code, dp->icmp6_data, length-sizeof(struct icmp6_hdr)+4);
1317  break;
1318  default:
1319  ND_PRINT(", length %u", length);
1320  if (ndo->ndo_vflag <= 1)
1321  print_unknown_data(ndo, bp,"\n\t", length);
1322  return;
1323  }
1324  if (!ndo->ndo_vflag)
1325  ND_PRINT(", length %u", length);
1326  return;
1327 trunc:
1328  nd_print_trunc(ndo);
1329 }
1330 
1331 static const struct udphdr *
1332 get_upperlayer(netdissect_options *ndo, const u_char *bp, u_int *prot)
1333 {
1334  const u_char *ep;
1335  const struct ip6_hdr *ip6 = (const struct ip6_hdr *)bp;
1336  const struct udphdr *uh;
1337  const struct ip6_hbh *hbh;
1338  const struct ip6_frag *fragh;
1339  const struct ah *ah;
1340  u_int nh;
1341  int hlen;
1342 
1343  /* 'ep' points to the end of available data. */
1344  ep = ndo->ndo_snapend;
1345 
1346  if (!ND_TTEST_1(ip6->ip6_nxt))
1347  return NULL;
1348 
1349  nh = GET_U_1(ip6->ip6_nxt);
1350  hlen = sizeof(struct ip6_hdr);
1351 
1352  while (bp < ep) {
1353  bp += hlen;
1354 
1355  switch(nh) {
1356  case IPPROTO_UDP:
1357  case IPPROTO_TCP:
1358  uh = (const struct udphdr *)bp;
1359  if (ND_TTEST_2(uh->uh_dport)) {
1360  *prot = nh;
1361  return(uh);
1362  }
1363  else
1364  return(NULL);
1365  /* NOTREACHED */
1366 
1367  case IPPROTO_HOPOPTS:
1368  case IPPROTO_DSTOPTS:
1369  case IPPROTO_ROUTING:
1370  hbh = (const struct ip6_hbh *)bp;
1371  if (!ND_TTEST_1(hbh->ip6h_len))
1372  return(NULL);
1373  nh = GET_U_1(hbh->ip6h_nxt);
1374  hlen = (GET_U_1(hbh->ip6h_len) + 1) << 3;
1375  break;
1376 
1377  case IPPROTO_FRAGMENT: /* this should be odd, but try anyway */
1378  fragh = (const struct ip6_frag *)bp;
1379  if (!ND_TTEST_2(fragh->ip6f_offlg))
1380  return(NULL);
1381  /* fragments with non-zero offset are meaningless */
1382  if ((GET_BE_U_2(fragh->ip6f_offlg) & IP6F_OFF_MASK) != 0)
1383  return(NULL);
1384  nh = GET_U_1(fragh->ip6f_nxt);
1385  hlen = sizeof(struct ip6_frag);
1386  break;
1387 
1388  case IPPROTO_AH:
1389  ah = (const struct ah *)bp;
1390  if (!ND_TTEST_1(ah->ah_len))
1391  return(NULL);
1392  nh = GET_U_1(ah->ah_nxt);
1393  hlen = (GET_U_1(ah->ah_len) + 2) << 2;
1394  break;
1395 
1396  default: /* unknown or undecodable header */
1397  *prot = nh; /* meaningless, but set here anyway */
1398  return(NULL);
1399  }
1400  }
1401 
1402  return(NULL); /* should be notreached, though */
1403 }
1404 
1405 static int
1406 icmp6_opt_print(netdissect_options *ndo, const u_char *bp, int resid)
1407 {
1408  const struct nd_opt_hdr *op;
1409  uint8_t opt_type;
1410  u_int opt_len;
1411  const struct nd_opt_prefix_info *opp;
1412  const struct nd_opt_mtu *opm;
1413  const struct nd_opt_rdnss *oprd;
1414  const struct nd_opt_dnssl *opds;
1415  const struct nd_opt_advinterval *opa;
1416  const struct nd_opt_homeagent_info *oph;
1417  const struct nd_opt_route_info *opri;
1418  const u_char *cp, *ep, *domp;
1419  nd_ipv6 in6;
1420  size_t l;
1421  u_int i;
1422 
1423  cp = bp;
1424  /* 'ep' points to the end of available data. */
1425  ep = ndo->ndo_snapend;
1426 
1427  while (cp < ep) {
1428  op = (const struct nd_opt_hdr *)cp;
1429 
1430  ND_TCHECK_1(op->nd_opt_len);
1431  if (resid <= 0)
1432  return 0;
1433  opt_type = GET_U_1(op->nd_opt_type);
1434  opt_len = GET_U_1(op->nd_opt_len);
1435  if (opt_len == 0)
1436  goto trunc;
1437  if (cp + (opt_len << 3) > ep)
1438  goto trunc;
1439 
1440  ND_PRINT("\n\t %s option (%u), length %u (%u): ",
1441  tok2str(icmp6_opt_values, "unknown", opt_type),
1442  opt_type,
1443  opt_len << 3,
1444  opt_len);
1445 
1446  switch (opt_type) {
1448  l = (opt_len << 3) - 2;
1449  print_lladdr(ndo, cp + 2, l);
1450  break;
1452  l = (opt_len << 3) - 2;
1453  print_lladdr(ndo, cp + 2, l);
1454  break;
1456  opp = (const struct nd_opt_prefix_info *)op;
1457  ND_PRINT("%s/%u%s, Flags [%s], valid time %s",
1460  (opt_len != 4) ? "badlen" : "",
1463  ND_PRINT(", pref. time %s",
1465  break;
1467  print_unknown_data(ndo, bp,"\n\t ",opt_len<<3);
1468  /* xxx */
1469  break;
1470  case ND_OPT_MTU:
1471  opm = (const struct nd_opt_mtu *)op;
1472  ND_PRINT(" %u%s",
1473  GET_BE_U_4(opm->nd_opt_mtu_mtu),
1474  (opt_len != 1) ? "bad option length" : "" );
1475  break;
1476  case ND_OPT_RDNSS:
1477  oprd = (const struct nd_opt_rdnss *)op;
1478  l = (opt_len - 1) / 2;
1479  ND_PRINT(" lifetime %us,",
1481  for (i = 0; i < l; i++) {
1482  ND_PRINT(" addr: %s",
1484  }
1485  break;
1486  case ND_OPT_DNSSL:
1487  opds = (const struct nd_opt_dnssl *)op;
1488  ND_PRINT(" lifetime %us, domain(s):",
1490  domp = cp + 8; /* domain names, variable-sized, RFC1035-encoded */
1491  while (domp < cp + (opt_len << 3) && GET_U_1(domp) != '\0')
1492  {
1493  ND_PRINT(" ");
1494  if ((domp = fqdn_print(ndo, domp, bp)) == NULL)
1495  goto trunc;
1496  }
1497  break;
1498  case ND_OPT_ADVINTERVAL:
1499  opa = (const struct nd_opt_advinterval *)op;
1500  ND_PRINT(" %ums",
1502  break;
1503  case ND_OPT_HOMEAGENT_INFO:
1504  oph = (const struct nd_opt_homeagent_info *)op;
1505  ND_PRINT(" preference %u, lifetime %u",
1508  break;
1509  case ND_OPT_ROUTE_INFO:
1510  opri = (const struct nd_opt_route_info *)op;
1512  memset(&in6, 0, sizeof(in6));
1513  switch (opt_len) {
1514  case 1:
1515  break;
1516  case 2:
1517  GET_CPY_BYTES(&in6, opri + 1, 8);
1518  break;
1519  case 3:
1520  GET_CPY_BYTES(&in6, opri + 1, 16);
1521  break;
1522  default:
1523  goto trunc;
1524  }
1525  ND_PRINT(" %s/%u", ip6addr_string(ndo, (const u_char *)&in6),
1526  GET_U_1(opri->nd_opt_rti_prefixlen));
1527  ND_PRINT(", pref=%s",
1529  ND_PRINT(", lifetime=%s",
1531  break;
1532  default:
1533  if (ndo->ndo_vflag <= 1) {
1534  print_unknown_data(ndo,cp+2,"\n\t ", (opt_len << 3) - 2); /* skip option header */
1535  return 0;
1536  }
1537  break;
1538  }
1539  /* do we want to see an additional hexdump ? */
1540  if (ndo->ndo_vflag> 1)
1541  print_unknown_data(ndo, cp+2,"\n\t ", (opt_len << 3) - 2); /* skip option header */
1542 
1543  cp += opt_len << 3;
1544  resid -= opt_len << 3;
1545  }
1546  return 0;
1547 
1548 trunc:
1549  return -1;
1550 }
1551 
1552 static void
1553 mld6_print(netdissect_options *ndo, const u_char *bp)
1554 {
1555  const struct mld6_hdr *mp = (const struct mld6_hdr *)bp;
1556  const u_char *ep;
1557 
1558  /* 'ep' points to the end of available data. */
1559  ep = ndo->ndo_snapend;
1560 
1561  if ((const u_char *)mp + sizeof(*mp) > ep)
1562  return;
1563 
1564  ND_PRINT("max resp delay: %u ", GET_BE_U_2(mp->mld6_maxdelay));
1565  ND_PRINT("addr: %s", GET_IP6ADDR_STRING(mp->mld6_addr));
1566 }
1567 
1568 static void
1569 mldv2_report_print(netdissect_options *ndo, const u_char *bp, u_int len)
1570 {
1571  const struct icmp6_hdr *icp = (const struct icmp6_hdr *) bp;
1572  u_int group, nsrcs, ngroups;
1573  u_int i, j;
1574 
1575  /* Minimum len is 8 */
1576  if (len < 8) {
1577  ND_PRINT(" [invalid len %u]", len);
1578  return;
1579  }
1580 
1581  ngroups = GET_BE_U_2(icp->icmp6_data16[1]);
1582  ND_PRINT(", %u group record(s)", ngroups);
1583  if (ndo->ndo_vflag > 0) {
1584  /* Print the group records */
1585  group = 8;
1586  for (i = 0; i < ngroups; i++) {
1587  /* type(1) + auxlen(1) + numsrc(2) + grp(16) */
1588  if (len < group + 20) {
1589  ND_PRINT(" [invalid number of groups]");
1590  return;
1591  }
1592  ND_PRINT(" [gaddr %s", GET_IP6ADDR_STRING(bp + group + 4));
1593  ND_PRINT(" %s", tok2str(mldv2report2str, " [v2-report-#%u]",
1594  GET_U_1(bp + group)));
1595  nsrcs = GET_BE_U_2(bp + group + 2);
1596  /* Check the number of sources and print them */
1597  if (len < group + 20 + (nsrcs * sizeof(nd_ipv6))) {
1598  ND_PRINT(" [invalid number of sources %u]", nsrcs);
1599  return;
1600  }
1601  if (ndo->ndo_vflag == 1)
1602  ND_PRINT(", %u source(s)", nsrcs);
1603  else {
1604  /* Print the sources */
1605  ND_PRINT(" {");
1606  for (j = 0; j < nsrcs; j++) {
1607  ND_PRINT(" %s", GET_IP6ADDR_STRING(bp + group + 20 + (j * sizeof(nd_ipv6))));
1608  }
1609  ND_PRINT(" }");
1610  }
1611  /* Next group record */
1612  group += 20 + nsrcs * sizeof(nd_ipv6);
1613  ND_PRINT("]");
1614  }
1615  }
1616 }
1617 
1618 static void
1619 mldv2_query_print(netdissect_options *ndo, const u_char *bp, u_int len)
1620 {
1621  const struct icmp6_hdr *icp = (const struct icmp6_hdr *) bp;
1622  u_int mrc;
1623  u_int mrt, qqi;
1624  u_int nsrcs;
1625  u_int i;
1626 
1627  /* Minimum len is 28 */
1628  if (len < 28) {
1629  ND_PRINT(" [invalid len %u]", len);
1630  return;
1631  }
1632  mrc = GET_BE_U_2(icp->icmp6_data16[0]);
1633  if (mrc < 32768) {
1634  mrt = mrc;
1635  } else {
1636  mrt = ((mrc & 0x0fff) | 0x1000) << (((mrc & 0x7000) >> 12) + 3);
1637  }
1638  if (ndo->ndo_vflag) {
1639  ND_PRINT(" [max resp delay=%u]", mrt);
1640  }
1641  ND_PRINT(" [gaddr %s", GET_IP6ADDR_STRING(bp + 8));
1642 
1643  if (ndo->ndo_vflag) {
1644  if (GET_U_1(bp + 24) & 0x08) {
1645  ND_PRINT(" sflag");
1646  }
1647  if (GET_U_1(bp + 24) & 0x07) {
1648  ND_PRINT(" robustness=%u", GET_U_1(bp + 24) & 0x07);
1649  }
1650  if (GET_U_1(bp + 25) < 128) {
1651  qqi = GET_U_1(bp + 25);
1652  } else {
1653  qqi = ((GET_U_1(bp + 25) & 0x0f) | 0x10) <<
1654  (((GET_U_1(bp + 25) & 0x70) >> 4) + 3);
1655  }
1656  ND_PRINT(" qqi=%u", qqi);
1657  }
1658 
1659  nsrcs = GET_BE_U_2(bp + 26);
1660  if (nsrcs > 0) {
1661  if (len < 28 + nsrcs * sizeof(nd_ipv6))
1662  ND_PRINT(" [invalid number of sources]");
1663  else if (ndo->ndo_vflag > 1) {
1664  ND_PRINT(" {");
1665  for (i = 0; i < nsrcs; i++) {
1666  ND_PRINT(" %s", GET_IP6ADDR_STRING(bp + 28 + (i * sizeof(nd_ipv6))));
1667  }
1668  ND_PRINT(" }");
1669  } else
1670  ND_PRINT(", %u source(s)", nsrcs);
1671  }
1672  ND_PRINT("]");
1673 }
1674 
1675 static void
1676 dnsname_print(netdissect_options *ndo, const u_char *cp, const u_char *ep)
1677 {
1678  int i;
1679 
1680  /* DNS name decoding - no decompression */
1681  ND_PRINT(", \"");
1682  while (cp < ep) {
1683  i = GET_U_1(cp);
1684  cp++;
1685  if (i) {
1686  if (i > ep - cp) {
1687  ND_PRINT("???");
1688  break;
1689  }
1690  while (i-- && cp < ep) {
1691  fn_print_char(ndo, GET_U_1(cp));
1692  cp++;
1693  }
1694  if (cp + 1 < ep && GET_U_1(cp))
1695  ND_PRINT(".");
1696  } else {
1697  if (cp == ep) {
1698  /* FQDN */
1699  ND_PRINT(".");
1700  } else if (cp + 1 == ep && GET_U_1(cp) == '\0') {
1701  /* truncated */
1702  } else {
1703  /* invalid */
1704  ND_PRINT("???");
1705  }
1706  break;
1707  }
1708  }
1709  ND_PRINT("\"");
1710 }
1711 
1712 static void
1713 icmp6_nodeinfo_print(netdissect_options *ndo, u_int icmp6len, const u_char *bp, const u_char *ep)
1714 {
1715  const struct icmp6_nodeinfo *ni6;
1716  const struct icmp6_hdr *dp;
1717  const u_char *cp;
1718  size_t siz, i;
1719  int needcomma;
1720 
1721  if (ep < bp)
1722  return;
1723  dp = (const struct icmp6_hdr *)bp;
1724  ni6 = (const struct icmp6_nodeinfo *)bp;
1725  siz = ep - bp;
1726 
1727  switch (GET_U_1(ni6->ni_type)) {
1728  case ICMP6_NI_QUERY:
1729  if (siz == sizeof(*dp) + 4) {
1730  /* KAME who-are-you */
1731  ND_PRINT(" who-are-you request");
1732  break;
1733  }
1734  ND_PRINT(" node information query");
1735 
1736  ND_TCHECK_LEN(dp, sizeof(*ni6));
1737  ni6 = (const struct icmp6_nodeinfo *)dp;
1738  ND_PRINT(" ("); /*)*/
1739  switch (GET_BE_U_2(ni6->ni_qtype)) {
1740  case NI_QTYPE_NOOP:
1741  ND_PRINT("noop");
1742  break;
1743  case NI_QTYPE_SUPTYPES:
1744  ND_PRINT("supported qtypes");
1745  i = GET_BE_U_2(ni6->ni_flags);
1746  if (i)
1747  ND_PRINT(" [%s]", (i & 0x01) ? "C" : "");
1748  break;
1749  case NI_QTYPE_FQDN:
1750  ND_PRINT("DNS name");
1751  break;
1752  case NI_QTYPE_NODEADDR:
1753  ND_PRINT("node addresses");
1754  i = GET_BE_U_2(ni6->ni_flags);
1755  if (!i)
1756  break;
1757  /* NI_NODEADDR_FLAG_TRUNCATE undefined for query */
1758  ND_PRINT(" [%s%s%s%s%s%s]",
1759  (i & NI_NODEADDR_FLAG_ANYCAST) ? "a" : "",
1760  (i & NI_NODEADDR_FLAG_GLOBAL) ? "G" : "",
1761  (i & NI_NODEADDR_FLAG_SITELOCAL) ? "S" : "",
1762  (i & NI_NODEADDR_FLAG_LINKLOCAL) ? "L" : "",
1763  (i & NI_NODEADDR_FLAG_COMPAT) ? "C" : "",
1764  (i & NI_NODEADDR_FLAG_ALL) ? "A" : "");
1765  break;
1766  default:
1767  ND_PRINT("unknown");
1768  break;
1769  }
1770 
1771  if (GET_BE_U_2(ni6->ni_qtype) == NI_QTYPE_NOOP ||
1772  GET_BE_U_2(ni6->ni_qtype) == NI_QTYPE_SUPTYPES) {
1773  if (siz != sizeof(*ni6))
1774  if (ndo->ndo_vflag)
1775  ND_PRINT(", invalid len");
1776  /*(*/
1777  ND_PRINT(")");
1778  break;
1779  }
1780 
1781 
1782  /* XXX backward compat, icmp-name-lookup-03 */
1783  if (siz == sizeof(*ni6)) {
1784  ND_PRINT(", 03 draft");
1785  /*(*/
1786  ND_PRINT(")");
1787  break;
1788  }
1789 
1790  cp = (const u_char *)(ni6 + 1);
1791  switch (GET_U_1(ni6->ni_code)) {
1792  case ICMP6_NI_SUBJ_IPV6:
1793  if (!ND_TTEST_LEN(dp, sizeof(*ni6) + sizeof(nd_ipv6)))
1794  break;
1795  if (siz != sizeof(*ni6) + sizeof(nd_ipv6)) {
1796  if (ndo->ndo_vflag)
1797  ND_PRINT(", invalid subject len");
1798  break;
1799  }
1800  ND_PRINT(", subject=%s",
1801  GET_IP6ADDR_STRING(cp));
1802  break;
1803  case ICMP6_NI_SUBJ_FQDN:
1804  ND_PRINT(", subject=DNS name");
1805  if (GET_U_1(cp) == ep - cp - 1) {
1806  /* icmp-name-lookup-03, pascal string */
1807  if (ndo->ndo_vflag)
1808  ND_PRINT(", 03 draft");
1809  cp++;
1810  ND_PRINT(", \"");
1811  while (cp < ep) {
1812  fn_print_char(ndo, GET_U_1(cp));
1813  cp++;
1814  }
1815  ND_PRINT("\"");
1816  } else
1817  dnsname_print(ndo, cp, ep);
1818  break;
1819  case ICMP6_NI_SUBJ_IPV4:
1820  if (!ND_TTEST_LEN(dp, sizeof(*ni6) + sizeof(nd_ipv4)))
1821  break;
1822  if (siz != sizeof(*ni6) + sizeof(nd_ipv4)) {
1823  if (ndo->ndo_vflag)
1824  ND_PRINT(", invalid subject len");
1825  break;
1826  }
1827  ND_PRINT(", subject=%s",
1828  GET_IPADDR_STRING(cp));
1829  break;
1830  default:
1831  ND_PRINT(", unknown subject");
1832  break;
1833  }
1834 
1835  /*(*/
1836  ND_PRINT(")");
1837  break;
1838 
1839  case ICMP6_NI_REPLY:
1840  if (icmp6len > siz)
1841  goto trunc;
1842 
1843  needcomma = 0;
1844 
1845  ND_TCHECK_LEN(dp, sizeof(*ni6));
1846  ni6 = (const struct icmp6_nodeinfo *)dp;
1847  ND_PRINT(" node information reply");
1848  ND_PRINT(" ("); /*)*/
1849  switch (GET_U_1(ni6->ni_code)) {
1850  case ICMP6_NI_SUCCESS:
1851  if (ndo->ndo_vflag) {
1852  ND_PRINT("success");
1853  needcomma++;
1854  }
1855  break;
1856  case ICMP6_NI_REFUSED:
1857  ND_PRINT("refused");
1858  needcomma++;
1859  if (siz != sizeof(*ni6))
1860  if (ndo->ndo_vflag)
1861  ND_PRINT(", invalid length");
1862  break;
1863  case ICMP6_NI_UNKNOWN:
1864  ND_PRINT("unknown");
1865  needcomma++;
1866  if (siz != sizeof(*ni6))
1867  if (ndo->ndo_vflag)
1868  ND_PRINT(", invalid length");
1869  break;
1870  }
1871 
1872  if (GET_U_1(ni6->ni_code) != ICMP6_NI_SUCCESS) {
1873  /*(*/
1874  ND_PRINT(")");
1875  break;
1876  }
1877 
1878  switch (GET_BE_U_2(ni6->ni_qtype)) {
1879  case NI_QTYPE_NOOP:
1880  if (needcomma)
1881  ND_PRINT(", ");
1882  ND_PRINT("noop");
1883  if (siz != sizeof(*ni6))
1884  if (ndo->ndo_vflag)
1885  ND_PRINT(", invalid length");
1886  break;
1887  case NI_QTYPE_SUPTYPES:
1888  if (needcomma)
1889  ND_PRINT(", ");
1890  ND_PRINT("supported qtypes");
1891  i = GET_BE_U_2(ni6->ni_flags);
1892  if (i)
1893  ND_PRINT(" [%s]", (i & 0x01) ? "C" : "");
1894  break;
1895  case NI_QTYPE_FQDN:
1896  if (needcomma)
1897  ND_PRINT(", ");
1898  ND_PRINT("DNS name");
1899  cp = (const u_char *)(ni6 + 1) + 4;
1900  if (GET_U_1(cp) == ep - cp - 1) {
1901  /* icmp-name-lookup-03, pascal string */
1902  if (ndo->ndo_vflag)
1903  ND_PRINT(", 03 draft");
1904  cp++;
1905  ND_PRINT(", \"");
1906  while (cp < ep) {
1907  fn_print_char(ndo, GET_U_1(cp));
1908  cp++;
1909  }
1910  ND_PRINT("\"");
1911  } else
1912  dnsname_print(ndo, cp, ep);
1913  if ((GET_BE_U_2(ni6->ni_flags) & 0x01) != 0)
1914  ND_PRINT(" [TTL=%u]", GET_BE_U_4(ni6 + 1));
1915  break;
1916  case NI_QTYPE_NODEADDR:
1917  if (needcomma)
1918  ND_PRINT(", ");
1919  ND_PRINT("node addresses");
1920  i = sizeof(*ni6);
1921  while (i < siz) {
1922  if (i + sizeof(uint32_t) + sizeof(nd_ipv6) > siz)
1923  break;
1924  ND_PRINT(" %s(%u)",
1925  GET_IP6ADDR_STRING(bp + i + sizeof(uint32_t)),
1926  GET_BE_U_4(bp + i));
1927  i += sizeof(uint32_t) + sizeof(nd_ipv6);
1928  }
1929  i = GET_BE_U_2(ni6->ni_flags);
1930  if (!i)
1931  break;
1932  ND_PRINT(" [%s%s%s%s%s%s%s]",
1933  (i & NI_NODEADDR_FLAG_ANYCAST) ? "a" : "",
1934  (i & NI_NODEADDR_FLAG_GLOBAL) ? "G" : "",
1935  (i & NI_NODEADDR_FLAG_SITELOCAL) ? "S" : "",
1936  (i & NI_NODEADDR_FLAG_LINKLOCAL) ? "L" : "",
1937  (i & NI_NODEADDR_FLAG_COMPAT) ? "C" : "",
1938  (i & NI_NODEADDR_FLAG_ALL) ? "A" : "",
1939  (i & NI_NODEADDR_FLAG_TRUNCATE) ? "T" : "");
1940  break;
1941  default:
1942  if (needcomma)
1943  ND_PRINT(", ");
1944  ND_PRINT("unknown");
1945  break;
1946  }
1947 
1948  /*(*/
1949  ND_PRINT(")");
1950  break;
1951  }
1952  return;
1953 
1954 trunc:
1955  nd_print_trunc(ndo);
1956 }
1957 
1958 static void
1959 icmp6_rrenum_print(netdissect_options *ndo, const u_char *bp, const u_char *ep)
1960 {
1961  const struct icmp6_router_renum *rr6;
1962  const char *cp;
1963  const struct rr_pco_match *match;
1964  const struct rr_pco_use *use;
1965  char hbuf[NI_MAXHOST];
1966  int n;
1967 
1968  if (ep < bp)
1969  return;
1970  rr6 = (const struct icmp6_router_renum *)bp;
1971  cp = (const char *)(rr6 + 1);
1972 
1973  ND_TCHECK_4(rr6->rr_reserved);
1974  switch (GET_U_1(rr6->rr_code)) {
1976  ND_PRINT("router renum: command");
1977  break;
1979  ND_PRINT("router renum: result");
1980  break;
1982  ND_PRINT("router renum: sequence number reset");
1983  break;
1984  default:
1985  ND_PRINT("router renum: code-#%u", GET_U_1(rr6->rr_code));
1986  break;
1987  }
1988 
1989  ND_PRINT(", seq=%u", GET_BE_U_4(rr6->rr_seqnum));
1990 
1991  if (ndo->ndo_vflag) {
1992  uint8_t rr_flags = GET_U_1(rr6->rr_flags);
1993 #define F(x, y) (rr_flags & (x) ? (y) : "")
1994  ND_PRINT("["); /*]*/
1995  if (rr_flags) {
1996  ND_PRINT("%s%s%s%s%s,", F(ICMP6_RR_FLAGS_TEST, "T"),
1999  F(ICMP6_RR_FLAGS_SPECSITE, "S"),
2000  F(ICMP6_RR_FLAGS_PREVDONE, "P"));
2001  }
2002  ND_PRINT("seg=%u,", GET_U_1(rr6->rr_segnum));
2003  ND_PRINT("maxdelay=%u", GET_BE_U_2(rr6->rr_maxdelay));
2004  if (GET_BE_U_4(rr6->rr_reserved))
2005  ND_PRINT("rsvd=0x%x", GET_BE_U_4(rr6->rr_reserved));
2006  /*[*/
2007  ND_PRINT("]");
2008 #undef F
2009  }
2010 
2011  if (GET_U_1(rr6->rr_code) == ICMP6_ROUTER_RENUMBERING_COMMAND) {
2012  match = (const struct rr_pco_match *)cp;
2013  cp = (const char *)(match + 1);
2014 
2015  ND_TCHECK_16(match->rpm_prefix);
2016 
2017  if (ndo->ndo_vflag > 1)
2018  ND_PRINT("\n\t");
2019  else
2020  ND_PRINT(" ");
2021  ND_PRINT("match("); /*)*/
2022  switch (GET_U_1(match->rpm_code)) {
2023  case RPM_PCO_ADD: ND_PRINT("add"); break;
2024  case RPM_PCO_CHANGE: ND_PRINT("change"); break;
2025  case RPM_PCO_SETGLOBAL: ND_PRINT("setglobal"); break;
2026  default: ND_PRINT("#%u",
2027  GET_U_1(match->rpm_code)); break;
2028  }
2029 
2030  if (ndo->ndo_vflag) {
2031  ND_PRINT(",ord=%u", GET_U_1(match->rpm_ordinal));
2032  ND_PRINT(",min=%u", GET_U_1(match->rpm_minlen));
2033  ND_PRINT(",max=%u", GET_U_1(match->rpm_maxlen));
2034  }
2035  if (addrtostr6(match->rpm_prefix, hbuf, sizeof(hbuf)))
2036  ND_PRINT(",%s/%u", hbuf, GET_U_1(match->rpm_matchlen));
2037  else
2038  ND_PRINT(",?/%u", GET_U_1(match->rpm_matchlen));
2039  /*(*/
2040  ND_PRINT(")");
2041 
2042  n = GET_U_1(match->rpm_len) - 3;
2043  if (n % 4)
2044  goto trunc;
2045  n /= 4;
2046  while (n-- > 0) {
2047  use = (const struct rr_pco_use *)cp;
2048  cp = (const char *)(use + 1);
2049 
2050  ND_TCHECK_16(use->rpu_prefix);
2051 
2052  if (ndo->ndo_vflag > 1)
2053  ND_PRINT("\n\t");
2054  else
2055  ND_PRINT(" ");
2056  ND_PRINT("use("); /*)*/
2057  if (GET_U_1(use->rpu_flags)) {
2058 #define F(x, y) (GET_U_1(use->rpu_flags) & (x) ? (y) : "")
2059  ND_PRINT("%s%s,",
2062 #undef F
2063  }
2064  if (ndo->ndo_vflag) {
2065  ND_PRINT("mask=0x%x,",
2066  GET_U_1(use->rpu_ramask));
2067  ND_PRINT("raflags=0x%x,",
2068  GET_U_1(use->rpu_raflags));
2069  if (GET_BE_U_4(use->rpu_vltime) == 0xffffffff)
2070  ND_PRINT("vltime=infty,");
2071  else
2072  ND_PRINT("vltime=%u,",
2073  GET_BE_U_4(use->rpu_vltime));
2074  if (GET_BE_U_4(use->rpu_pltime) == 0xffffffff)
2075  ND_PRINT("pltime=infty,");
2076  else
2077  ND_PRINT("pltime=%u,",
2078  GET_BE_U_4(use->rpu_pltime));
2079  }
2080  if (addrtostr6(use->rpu_prefix, hbuf, sizeof(hbuf)))
2081  ND_PRINT("%s/%u/%u", hbuf,
2082  GET_U_1(use->rpu_uselen),
2083  GET_U_1(use->rpu_keeplen));
2084  else
2085  ND_PRINT("?/%u/%u", GET_U_1(use->rpu_uselen),
2086  GET_U_1(use->rpu_keeplen));
2087  /*(*/
2088  ND_PRINT(")");
2089  }
2090  }
2091 
2092  return;
2093 
2094 trunc:
2095  nd_print_trunc(ndo);
2096 }
const char * tcpport_string(netdissect_options *ndo, u_short port)
Definition: addrtoname.c:739
const char * ip6addr_string(netdissect_options *ndo, const u_char *ap)
Definition: addrtoname.c:338
const char * udpport_string(netdissect_options *ndo, u_short port)
Definition: addrtoname.c:761
#define GET_IPADDR_STRING(p)
Definition: addrtoname.h:120
#define GET_IP6ADDR_STRING(p)
Definition: addrtoname.h:121
const char * addrtostr6(const void *src, char *dst, size_t size)
Definition: addrtostr.c:99
#define GET_BE_U_4(p)
Definition: extract.h:877
#define GET_BE_U_2(p)
Definition: extract.h:875
#define ND_TTEST_2(p)
Definition: extract.h:554
#define GET_U_1(p)
Definition: extract.h:872
#define ND_TCHECK_4(p)
Definition: extract.h:561
#define ND_TTEST_1(p)
Definition: extract.h:551
#define GET_CPY_BYTES(dst, p, len)
Definition: extract.h:913
#define ND_TCHECK_16(p)
Definition: extract.h:576
#define ND_TCHECK_1(p)
Definition: extract.h:552
uint16_t in_cksum_shouldbe(uint16_t sum, uint16_t computed_sum)
Definition: in_cksum.c:157
#define IP6F_OFF_MASK
Definition: ip6.h:208
#define IPPROTO_ICMPV6
Definition: ipproto.h:96
#define IPPROTO_AH
Definition: ipproto.h:90
#define IPPROTO_TCP
Definition: ipproto.h:57
#define IPPROTO_DSTOPTS
Definition: ipproto.h:102
#define IPPROTO_FRAGMENT
Definition: ipproto.h:78
#define IPPROTO_UDP
Definition: ipproto.h:66
#define IPPROTO_ROUTING
Definition: ipproto.h:75
#define IPPROTO_HOPOPTS
Definition: ipproto.h:45
#define NI_MAXHOST
unsigned char nd_uint16_t[2]
Definition: netdissect.h:47
uint16_t nextproto6_cksum(netdissect_options *, const struct ip6_hdr *, const uint8_t *, u_int, u_int, uint8_t)
Definition: print-ip6.c:173
void fn_print_char(netdissect_options *, u_char)
Definition: util-print.c:70
int print_unknown_data(netdissect_options *, const u_char *, const char *, u_int)
Definition: util-print.c:441
#define ND_TCHECK_LEN(p, l)
Definition: netdissect.h:368
const char * tok2str(const struct tok *, const char *, u_int)
Definition: util-print.c:485
#define ND_TTEST_LEN(p, l)
Definition: netdissect.h:356
#define ND_TCHECK_SIZE(p)
Definition: netdissect.h:372
char * bittok2str(const struct tok *, const char *, u_int)
Definition: util-print.c:558
void nd_print_invalid(netdissect_options *)
Definition: util-print.c:429
unsigned char nd_byte
Definition: netdissect.h:108
void hex_print(netdissect_options *, const char *ident, const u_char *cp, u_int)
Definition: print-ascii.c:212
const u_char * fqdn_print(netdissect_options *, const u_char *, const u_char *)
Definition: print-domain.c:185
void nd_print_trunc(netdissect_options *)
Definition: util-print.c:409
unsigned char nd_int32_t[4]
Definition: netdissect.h:61
unsigned char nd_ipv4[4]
Definition: netdissect.h:92
#define ND_PRINT(...)
Definition: netdissect.h:385
unsigned char nd_uint32_t[4]
Definition: netdissect.h:49
unsigned char nd_uint8_t[1]
Definition: netdissect.h:46
unsigned char nd_ipv6[16]
Definition: netdissect.h:97
int snprintf(char *, size_t, const char *,...)
#define RPL_DIO_GROUNDED(X)
Definition: print-icmp6.c:563
static void mldv2_query_print(netdissect_options *ndo, const u_char *, u_int)
Definition: print-icmp6.c:1619
#define ND_RPL_DAO_MIN_LEN
Definition: print-icmp6.c:614
#define ICMP6_TIME_EXCEEDED
Definition: print-icmp6.c:100
#define ICMP6_NI_SUCCESS
Definition: print-icmp6.c:162
#define ICMP6_NI_REFUSED
Definition: print-icmp6.c:163
static const struct tok icmp6_type_values[]
Definition: print-icmp6.c:650
#define ICMP6_NI_REPLY
Definition: print-icmp6.c:125
#define ICMP6_V2_MEMBERSHIP_REPORT
Definition: print-icmp6.c:129
static void rpl_daoack_print(netdissect_options *ndo, const u_char *bp, u_int length)
Definition: print-icmp6.c:922
RPL_DIO_MOP
Definition: print-icmp6.c:567
@ RPL_DIO_STORING_MULTICAST
Definition: print-icmp6.c:571
@ RPL_DIO_STORING
Definition: print-icmp6.c:569
@ RPL_DIO_NONSTORING
Definition: print-icmp6.c:568
@ RPL_DIO_NONSTORING_MULTICAST
Definition: print-icmp6.c:570
#define ICMP6_DST_UNREACH_ADMIN
Definition: print-icmp6.c:142
#define RPL_GENOPTION_LEN
Definition: print-icmp6.c:590
#define MPADVLEN
#define ND_NA_FLAG_ROUTER
Definition: print-icmp6.c:257
#define ND_RA_FLAG_MANAGED
Definition: print-icmp6.c:217
#define ND_OPT_PI_FLAG_ROUTER
Definition: print-icmp6.c:303
#define NDSOLLEN
#define ICMP6_ECHO_REPLY
Definition: print-icmp6.c:104
static const struct tok rpl_subopt_values[]
Definition: print-icmp6.c:797
#define ICMP6_RR_FLAGS_REQRESULT
Definition: print-icmp6.c:427
#define ND_RPL_MESSAGE
Definition: print-icmp6.c:501
#define ICMP6_DST_UNREACH
Definition: print-icmp6.c:98
#define NDADVLEN
#define ICMP6_NI_SUBJ_IPV6
Definition: print-icmp6.c:158
#define ND_RA_FLAG_IPV6ONLY
Definition: print-icmp6.c:220
#define ND_NEIGHBOR_ADVERT
Definition: print-icmp6.c:115
void icmp6_print(netdissect_options *ndo, const u_char *bp, u_int length, const u_char *bp2, int fragmented)
Definition: print-icmp6.c:1022
static const char * get_rtpref(u_int)
Definition: print-icmp6.c:741
#define NI_NODEADDR_FLAG_ANYCAST
Definition: print-icmp6.c:408
#define NI_QTYPE_SUPTYPES
Definition: print-icmp6.c:391
#define ND_OPT_PREFIX_INFORMATION
Definition: print-icmp6.c:281
#define NI_QTYPE_NOOP
Definition: print-icmp6.c:390
#define NI_QTYPE_FQDN
Definition: print-icmp6.c:392
#define ND_OPT_PI_FLAG_AUTO
Definition: print-icmp6.c:302
#define MLDV2_MINLEN
Definition: print-icmp6.c:189
static void print_lladdr(netdissect_options *ndo, const u_char *, size_t)
#define ND_ROUTER_ADVERT
Definition: print-icmp6.c:113
static void rpl_printopts(netdissect_options *ndo, const uint8_t *opts, u_int length)
Definition: print-icmp6.c:811
static int icmp6_opt_print(netdissect_options *ndo, const u_char *, int)
Definition: print-icmp6.c:1406
#define F(x, y)
#define ICMP6_TIME_EXCEED_REASSEMBLY
Definition: print-icmp6.c:149
#define ND_RPL_DAOACK_MIN_LEN
Definition: print-icmp6.c:644
#define ND_OPT_ROUTE_INFO
Definition: print-icmp6.c:286
#define NI_NODEADDR_FLAG_COMPAT
Definition: print-icmp6.c:404
static const struct tok icmp6_dst_unreach_code_values[]
Definition: print-icmp6.c:683
static void dnsname_print(netdissect_options *ndo, const u_char *, const u_char *)
Definition: print-icmp6.c:1676
#define RPL_DAO_D(X)
Definition: print-icmp6.c:624
#define ICMP6_NI_QUERY
Definition: print-icmp6.c:124
#define ND_OPT_MTU
Definition: print-icmp6.c:283
static const struct tok mldv2report2str[]
Definition: print-icmp6.c:730
#define ND_OPT_PI_FLAG_ONLINK
Definition: print-icmp6.c:301
#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME
Definition: print-icmp6.c:468
#define ND_RA_FLAG_OTHER
Definition: print-icmp6.c:218
#define NI_NODEADDR_FLAG_ALL
Definition: print-icmp6.c:403
#define ICMP6_WRUREQUEST
Definition: print-icmp6.c:120
#define NI_NODEADDR_FLAG_TRUNCATE
Definition: print-icmp6.c:402
#define ICMP6_PACKET_TOO_BIG
Definition: print-icmp6.c:99
#define ND_REDIRECT
Definition: print-icmp6.c:116
static const struct udphdr * get_upperlayer(netdissect_options *ndo, const u_char *, u_int *)
Definition: print-icmp6.c:1332
#define ICMP6_DST_UNREACH_ADDR
Definition: print-icmp6.c:145
#define RTSOLLEN
#define RPL_DAOACK_D(X)
Definition: print-icmp6.c:648
#define RPL_DAO_K(X)
Definition: print-icmp6.c:619
#define NI_QTYPE_NODEADDR
Definition: print-icmp6.c:394
#define ICMP6_RR_FLAGS_SPECSITE
Definition: print-icmp6.c:429
#define ND_NA_FLAG_SOLICITED
Definition: print-icmp6.c:258
#define NI_NODEADDR_FLAG_GLOBAL
Definition: print-icmp6.c:407
#define ND_OPT_HOMEAGENT_INFO
Definition: print-icmp6.c:285
#define ICMP6_ROUTER_RENUMBERING_COMMAND
Definition: print-icmp6.c:166
static const struct tok icmp6_opt_ra_flag_values[]
Definition: print-icmp6.c:699
static void rpl_print(netdissect_options *ndo, uint8_t icmp6_code, const u_char *bp, u_int length)
Definition: print-icmp6.c:964
#define ICMP6_NI_SUBJ_FQDN
Definition: print-icmp6.c:159
#define ICMP6_ROUTER_RENUMBERING_RESULT
Definition: print-icmp6.c:167
#define REDIRECTLEN
static void rpl_dio_print(netdissect_options *ndo, const u_char *bp, u_int length)
Definition: print-icmp6.c:849
static void icmp6_rrenum_print(netdissect_options *ndo, const u_char *, const u_char *)
Definition: print-icmp6.c:1959
#define ICMP6_HADISCOV_REPLY
Definition: print-icmp6.c:132
static const struct tok icmp6_nd_na_flag_values[]
Definition: print-icmp6.c:707
#define ND_OPT_ADVINTERVAL
Definition: print-icmp6.c:284
ND_RPL_DIO_FLAGS
Definition: print-icmp6.c:515
@ ND_RPL_DIO_RES4
Definition: print-icmp6.c:519
@ ND_RPL_DIO_GROUNDED
Definition: print-icmp6.c:516
@ ND_RPL_DIO_PRF_MASK
Definition: print-icmp6.c:521
@ ND_RPL_DIO_RES3
Definition: print-icmp6.c:520
@ ND_RPL_DIO_DATRIG
Definition: print-icmp6.c:517
@ ND_RPL_DIO_DASUPPORT
Definition: print-icmp6.c:518
static void icmp6_nodeinfo_print(netdissect_options *ndo, u_int, const u_char *, const u_char *)
Definition: print-icmp6.c:1713
#define MLD6_MTRACE
Definition: print-icmp6.c:137
#define ICMP6_PARAM_PROB
Definition: print-icmp6.c:101
#define MLD6_LISTENER_REPORT
Definition: print-icmp6.c:108
#define MLD6_MTRACE_RESP
Definition: print-icmp6.c:136
static void mld6_print(netdissect_options *ndo, const u_char *)
Definition: print-icmp6.c:1553
#define ICMP6_DST_UNREACH_NOPORT
Definition: print-icmp6.c:146
#define ND_OPT_SOURCE_LINKADDR
Definition: print-icmp6.c:279
#define ICMP6_MEMBERSHIP_QUERY
Definition: print-icmp6.c:105
#define NI_NODEADDR_FLAG_LINKLOCAL
Definition: print-icmp6.c:405
#define DAGID_LEN
Definition: print-icmp6.c:524
#define MLDV2_LISTENER_REPORT
Definition: print-icmp6.c:130
ND_RPL_CODE
Definition: print-icmp6.c:503
@ ND_RPL_SEC_DAG_IS
Definition: print-icmp6.c:508
@ ND_RPL_DAO
Definition: print-icmp6.c:506
@ ND_RPL_SEC_DAG
Definition: print-icmp6.c:510
@ ND_RPL_DAO_ACK
Definition: print-icmp6.c:507
@ ND_RPL_SEC_DAG_ACK
Definition: print-icmp6.c:511
@ ND_RPL_DAG_IO
Definition: print-icmp6.c:505
@ ND_RPL_DAG_IS
Definition: print-icmp6.c:504
@ ND_RPL_SEC_CONSIST
Definition: print-icmp6.c:512
@ ND_RPL_SEC_DAG_IO
Definition: print-icmp6.c:509
static const struct tok icmp6_opt_pi_flag_values[]
Definition: print-icmp6.c:692
#define ICMP6_ROUTER_RENUMBERING
Definition: print-icmp6.c:118
#define IND_ADVERT
Definition: print-icmp6.c:127
#define ND_RA_FLAG_HOME_AGENT
Definition: print-icmp6.c:219
#define MLD6_LISTENER_DONE
Definition: print-icmp6.c:110
#define ICMP6_PARAMPROB_FRAGHDRCHAIN
Definition: print-icmp6.c:154
#define ND_ROUTER_SOLICIT
Definition: print-icmp6.c:112
#define ND_OPT_TARGET_LINKADDR
Definition: print-icmp6.c:280
#define ICMP6_MEMBERSHIP_REDUCTION
Definition: print-icmp6.c:109
#define ND_NA_FLAG_OVERRIDE
Definition: print-icmp6.c:259
#define RPM_PCO_ADD
Definition: print-icmp6.c:448
#define RTADVLEN
#define ICMP6_NI_SUBJ_IPV4
Definition: print-icmp6.c:160
#define ICMP6_DST_UNREACH_BEYONDSCOPE
Definition: print-icmp6.c:144
#define ICMP6_NI_UNKNOWN
Definition: print-icmp6.c:164
#define RPM_PCO_SETGLOBAL
Definition: print-icmp6.c:450
#define ICMP6_MEMBERSHIP_REPORT
Definition: print-icmp6.c:107
#define MLD6_LISTENER_QUERY
Definition: print-icmp6.c:106
#define NI_NODEADDR_FLAG_SITELOCAL
Definition: print-icmp6.c:406
static const struct tok icmp6_opt_values[]
Definition: print-icmp6.c:715
#define RPL_DIO_PRF(X)
Definition: print-icmp6.c:565
#define ICMP6_RR_FLAGS_TEST
Definition: print-icmp6.c:426
#define ND_OPT_RDNSS
Definition: print-icmp6.c:287
#define MLD_MINLEN
Definition: print-icmp6.c:188
#define ICMP6_RR_FLAGS_PREVDONE
Definition: print-icmp6.c:430
#define ICMP6_HADISCOV_REQUEST
Definition: print-icmp6.c:131
#define ND_OPT_REDIRECTED_HEADER
Definition: print-icmp6.c:282
#define RPM_PCO_CHANGE
Definition: print-icmp6.c:449
#define ND_OPT_DNSSL
Definition: print-icmp6.c:288
static void rpl_dao_print(netdissect_options *ndo, const u_char *bp, u_int length)
Definition: print-icmp6.c:877
#define ICMP6_PARAMPROB_NEXTHEADER
Definition: print-icmp6.c:152
static const char * get_lifetime(uint32_t)
Definition: print-icmp6.c:754
#define RPL_DIO_MOP(X)
Definition: print-icmp6.c:564
#define ICMP6_PARAMPROB_HEADER
Definition: print-icmp6.c:151
static const struct tok rpl_mop_values[]
Definition: print-icmp6.c:789
#define ICMP6_MOBILEPREFIX_SOLICIT
Definition: print-icmp6.c:133
#define ICMP6_RR_FLAGS_FORCEAPPLY
Definition: print-icmp6.c:428
#define IND_SOLICIT
Definition: print-icmp6.c:126
#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME
Definition: print-icmp6.c:467
static void mldv2_report_print(netdissect_options *ndo, const u_char *, u_int)
Definition: print-icmp6.c:1569
static uint16_t icmp6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6, const struct icmp6_hdr *icp, u_int len)
Definition: print-icmp6.c:782
#define ICMP6_PARAMPROB_OPTION
Definition: print-icmp6.c:153
#define ICMP6_MOBILEPREFIX_ADVERT
Definition: print-icmp6.c:134
#define ICMP6_WRUREPLY
Definition: print-icmp6.c:121
#define ICMP6_ECHO_REQUEST
Definition: print-icmp6.c:103
#define ICMP6_DST_UNREACH_NOROUTE
Definition: print-icmp6.c:141
#define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET
Definition: print-icmp6.c:168
#define ND_NEIGHBOR_SOLICIT
Definition: print-icmp6.c:114
#define ND_RA_FLAG_RTPREF_MASK
Definition: print-icmp6.c:226
RPL_SUBOPT
Definition: print-icmp6.c:574
@ RPL_DIO_CONFIG
Definition: print-icmp6.c:579
@ RPL_DIO_METRICS
Definition: print-icmp6.c:577
@ RPL_DAO_RPLTARGET
Definition: print-icmp6.c:580
@ RPL_DAO_RPLTARGET_DESC
Definition: print-icmp6.c:583
@ RPL_OPT_PADN
Definition: print-icmp6.c:576
@ RPL_OPT_PAD1
Definition: print-icmp6.c:575
@ RPL_DIO_ROUTINGINFO
Definition: print-icmp6.c:578
@ RPL_DAO_TRANSITINFO
Definition: print-icmp6.c:581
@ RPL_DIO_DESTPREFIX
Definition: print-icmp6.c:582
#define ICMP6_TIME_EXCEED_TRANSIT
Definition: print-icmp6.c:148
Definition: ah.h:58
nd_uint8_t ah_nxt
Definition: ah.h:59
nd_uint8_t ah_len
Definition: ah.h:60
nd_byte icmp6_un_data[1]
Definition: print-icmp6.c:84
nd_uint8_t icmp6_code
Definition: print-icmp6.c:78
nd_uint8_t icmp6_type
Definition: print-icmp6.c:77
nd_uint8_t icmp6_un_data8[4]
Definition: print-icmp6.c:83
nd_uint16_t icmp6_un_data16[2]
Definition: print-icmp6.c:82
union icmp6_hdr::@41 icmp6_dataun
nd_uint32_t icmp6_un_data32[1]
Definition: print-icmp6.c:81
nd_uint16_t icmp6_cksum
Definition: print-icmp6.c:79
struct icmp6_hdr icmp6_nl_hdr
Definition: print-icmp6.c:365
nd_int32_t icmp6_nl_ttl
Definition: print-icmp6.c:367
nd_byte icmp6_nl_nonce[8]
Definition: print-icmp6.c:366
nd_byte icmp6_ni_nonce[8]
Definition: print-icmp6.c:380
struct icmp6_hdr icmp6_ni_hdr
Definition: print-icmp6.c:379
nd_uint16_t rr_maxdelay
Definition: print-icmp6.c:423
nd_uint8_t rr_flags
Definition: print-icmp6.c:422
nd_uint8_t rr_segnum
Definition: print-icmp6.c:421
nd_uint32_t rr_reserved
Definition: print-icmp6.c:424
struct icmp6_hdr rr_hdr
Definition: print-icmp6.c:420
Definition: ip6.h:201
nd_uint16_t ip6f_offlg
Definition: ip6.h:204
nd_uint8_t ip6f_nxt
Definition: ip6.h:202
Definition: ip6.h:112
nd_uint8_t ip6h_nxt
Definition: ip6.h:113
nd_uint8_t ip6h_len
Definition: ip6.h:114
Definition: ip6.h:76
nd_ipv6 ip6_dst
Definition: ip6.h:87
nd_ipv6 ip6_src
Definition: ip6.h:86
Definition: ip.h:52
nd_ipv6 mld6_addr
Definition: print-icmp6.c:179
struct icmp6_hdr nd_na_hdr
Definition: print-icmp6.c:247
struct icmp6_hdr nd_ns_hdr
Definition: print-icmp6.c:236
nd_uint8_t nd_opt_adv_type
Definition: print-icmp6.c:337
nd_uint8_t nd_opt_adv_len
Definition: print-icmp6.c:338
nd_uint16_t nd_opt_adv_reserved
Definition: print-icmp6.c:339
nd_uint32_t nd_opt_adv_interval
Definition: print-icmp6.c:340
nd_uint32_t nd_opt_dnssl_lifetime
Definition: print-icmp6.c:332
nd_uint8_t nd_opt_dnssl_len
Definition: print-icmp6.c:330
nd_uint16_t nd_opt_dnssl_reserved
Definition: print-icmp6.c:331
nd_uint8_t nd_opt_dnssl_type
Definition: print-icmp6.c:329
nd_uint8_t nd_opt_len
Definition: print-icmp6.c:275
nd_uint8_t nd_opt_type
Definition: print-icmp6.c:274
nd_uint16_t nd_opt_hai_reserved
Definition: print-icmp6.c:346
nd_uint8_t nd_opt_hai_type
Definition: print-icmp6.c:344
nd_uint8_t nd_opt_hai_len
Definition: print-icmp6.c:345
nd_uint16_t nd_opt_hai_lifetime
Definition: print-icmp6.c:348
nd_uint16_t nd_opt_hai_preference
Definition: print-icmp6.c:347
nd_uint32_t nd_opt_mtu_mtu
Definition: print-icmp6.c:317
nd_uint8_t nd_opt_mtu_type
Definition: print-icmp6.c:314
nd_uint16_t nd_opt_mtu_reserved
Definition: print-icmp6.c:316
nd_uint8_t nd_opt_mtu_len
Definition: print-icmp6.c:315
nd_uint32_t nd_opt_pi_preferred_time
Definition: print-icmp6.c:296
nd_uint8_t nd_opt_pi_flags_reserved
Definition: print-icmp6.c:294
nd_uint32_t nd_opt_pi_reserved2
Definition: print-icmp6.c:297
nd_uint8_t nd_opt_pi_prefix_len
Definition: print-icmp6.c:293
nd_uint8_t nd_opt_pi_len
Definition: print-icmp6.c:292
nd_uint32_t nd_opt_pi_valid_time
Definition: print-icmp6.c:295
nd_ipv6 nd_opt_pi_prefix
Definition: print-icmp6.c:298
nd_uint8_t nd_opt_pi_type
Definition: print-icmp6.c:291
nd_uint8_t nd_opt_rh_type
Definition: print-icmp6.c:306
nd_uint32_t nd_opt_rh_reserved2
Definition: print-icmp6.c:309
nd_uint16_t nd_opt_rh_reserved1
Definition: print-icmp6.c:308
nd_uint8_t nd_opt_rh_len
Definition: print-icmp6.c:307
nd_uint16_t nd_opt_rdnss_reserved
Definition: print-icmp6.c:323
nd_ipv6 nd_opt_rdnss_addr[1]
Definition: print-icmp6.c:325
nd_uint8_t nd_opt_rdnss_len
Definition: print-icmp6.c:322
nd_uint8_t nd_opt_rdnss_type
Definition: print-icmp6.c:321
nd_uint32_t nd_opt_rdnss_lifetime
Definition: print-icmp6.c:324
nd_uint8_t nd_opt_rti_len
Definition: print-icmp6.c:353
nd_uint8_t nd_opt_rti_prefixlen
Definition: print-icmp6.c:354
nd_uint8_t nd_opt_rti_type
Definition: print-icmp6.c:352
nd_uint8_t nd_opt_rti_flags
Definition: print-icmp6.c:355
nd_uint32_t nd_opt_rti_lifetime
Definition: print-icmp6.c:356
nd_ipv6 nd_rd_target
Definition: print-icmp6.c:263
struct icmp6_hdr nd_rd_hdr
Definition: print-icmp6.c:262
nd_ipv6 nd_rd_dst
Definition: print-icmp6.c:264
struct icmp6_hdr nd_ra_hdr
Definition: print-icmp6.c:206
nd_uint32_t nd_ra_retransmit
Definition: print-icmp6.c:208
nd_uint32_t nd_ra_reachable
Definition: print-icmp6.c:207
struct icmp6_hdr nd_rs_hdr
Definition: print-icmp6.c:196
nd_uint8_t rpl_instanceid
Definition: print-icmp6.c:608
nd_byte rpl_dagid[16]
Definition: print-icmp6.c:612
nd_uint8_t rpl_daoseq
Definition: print-icmp6.c:611
nd_uint8_t rpl_flags
Definition: print-icmp6.c:609
nd_uint8_t rpl_resv
Definition: print-icmp6.c:610
nd_uint8_t rpl_instanceid
Definition: print-icmp6.c:638
nd_uint8_t rpl_daoseq
Definition: print-icmp6.c:640
nd_uint8_t rpl_status
Definition: print-icmp6.c:641
nd_byte rpl_dagid[16]
Definition: print-icmp6.c:642
nd_uint8_t rpl_flags
Definition: print-icmp6.c:639
nd_uint8_t rpl_mopprf
Definition: print-icmp6.c:552
nd_uint16_t rpl_dagrank
Definition: print-icmp6.c:551
nd_uint8_t rpl_dtsn
Definition: print-icmp6.c:553
nd_uint8_t rpl_flags
Definition: print-icmp6.c:554
nd_uint8_t rpl_resv1
Definition: print-icmp6.c:555
nd_byte rpl_dagid[16]
Definition: print-icmp6.c:556
nd_uint8_t rpl_instanceid
Definition: print-icmp6.c:549
nd_uint8_t rpl_version
Definition: print-icmp6.c:550
nd_uint8_t rpl_dis_flags
Definition: print-icmp6.c:540
nd_uint8_t rpl_dis_reserved
Definition: print-icmp6.c:541
nd_uint16_t rpl_sec_kim_lvl_flags
Definition: print-icmp6.c:530
nd_uint32_t rpl_sec_counter
Definition: print-icmp6.c:532
nd_uint8_t rpl_sec_t_reserved
Definition: print-icmp6.c:528
nd_uint8_t rpl_sec_algo
Definition: print-icmp6.c:529
const u_char * ndo_snapend
Definition: netdissect.h:239
const char * ndo_protocol
Definition: netdissect.h:218
nd_byte ni_fqdn_name[3]
Definition: print-icmp6.c:413
nd_uint8_t ni_fqdn_namelen
Definition: print-icmp6.c:412
nd_uint32_t ni_fqdn_ttl
Definition: print-icmp6.c:411
nd_uint8_t rpl_dao_flags
Definition: print-icmp6.c:629
nd_uint8_t rpl_dao_prefixlen
Definition: print-icmp6.c:630
nd_uint8_t rpl_dao_len
Definition: print-icmp6.c:628
nd_uint8_t rpl_dao_type
Definition: print-icmp6.c:627
nd_uint8_t rpl_dio_prefixlen
Definition: print-icmp6.c:598
nd_uint8_t rpl_dio_prf
Definition: print-icmp6.c:599
nd_uint8_t rpl_dio_len
Definition: print-icmp6.c:597
nd_uint32_t rpl_dio_prefixlifetime
Definition: print-icmp6.c:600
nd_uint8_t rpl_dio_type
Definition: print-icmp6.c:596
nd_uint8_t rpl_dio_type
Definition: print-icmp6.c:587
nd_uint8_t rpl_dio_len
Definition: print-icmp6.c:588
nd_uint8_t rpm_len
Definition: print-icmp6.c:439
nd_uint8_t rpm_matchlen
Definition: print-icmp6.c:441
nd_uint8_t rpm_maxlen
Definition: print-icmp6.c:443
nd_ipv6 rpm_prefix
Definition: print-icmp6.c:445
nd_uint8_t rpm_minlen
Definition: print-icmp6.c:442
nd_uint8_t rpm_code
Definition: print-icmp6.c:438
nd_uint16_t rpm_reserved
Definition: print-icmp6.c:444
nd_uint8_t rpm_ordinal
Definition: print-icmp6.c:440
nd_uint32_t rpu_pltime
Definition: print-icmp6.c:459
nd_uint32_t rpu_flags
Definition: print-icmp6.c:460
nd_ipv6 rpu_prefix
Definition: print-icmp6.c:461
nd_uint8_t rpu_keeplen
Definition: print-icmp6.c:455
nd_uint8_t rpu_uselen
Definition: print-icmp6.c:454
nd_uint8_t rpu_raflags
Definition: print-icmp6.c:457
nd_uint8_t rpu_ramask
Definition: print-icmp6.c:456
nd_uint32_t rpu_vltime
Definition: print-icmp6.c:458
nd_uint8_t rrr_matchedlen
Definition: print-icmp6.c:473
nd_uint8_t rrr_ordinal
Definition: print-icmp6.c:472
nd_uint32_t rrr_ifid
Definition: print-icmp6.c:474
nd_ipv6 rrr_prefix
Definition: print-icmp6.c:475
nd_uint16_t rrr_flags
Definition: print-icmp6.c:471
u_int v
Definition: netdissect.h:139
Definition: udp.h:40
nd_uint16_t uh_dport
Definition: udp.h:42