xref: /freebsd/sbin/ping/ping6.c (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
1 /*	$KAME: ping6.c,v 1.169 2003/07/25 06:01:47 itojun Exp $	*/
2 
3 /*-
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the project nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 /*	BSDI	ping.c,v 2.3 1996/01/21 17:56:50 jch Exp	*/
35 
36 /*
37  * Copyright (c) 1989, 1993
38  *	The Regents of the University of California.  All rights reserved.
39  *
40  * This code is derived from software contributed to Berkeley by
41  * Mike Muuss.
42  *
43  * Redistribution and use in source and binary forms, with or without
44  * modification, are permitted provided that the following conditions
45  * are met:
46  * 1. Redistributions of source code must retain the above copyright
47  *    notice, this list of conditions and the following disclaimer.
48  * 2. Redistributions in binary form must reproduce the above copyright
49  *    notice, this list of conditions and the following disclaimer in the
50  *    documentation and/or other materials provided with the distribution.
51  * 3. Neither the name of the University nor the names of its contributors
52  *    may be used to endorse or promote products derived from this software
53  *    without specific prior written permission.
54  *
55  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
56  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
58  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
59  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
60  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
61  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
62  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
63  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65  * SUCH DAMAGE.
66  */
67 
68 #if 0
69 #ifndef lint
70 static const char copyright[] =
71 "@(#) Copyright (c) 1989, 1993\n\
72 	The Regents of the University of California.  All rights reserved.\n";
73 #endif /* not lint */
74 
75 #ifndef lint
76 static char sccsid[] = "@(#)ping.c	8.1 (Berkeley) 6/5/93";
77 #endif /* not lint */
78 #endif
79 
80 #include <sys/cdefs.h>
81 __FBSDID("$FreeBSD$");
82 
83 /*
84  * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility,
85  * measure round-trip-delays and packet loss across network paths.
86  *
87  * Author -
88  *	Mike Muuss
89  *	U. S. Army Ballistic Research Laboratory
90  *	December, 1983
91  *
92  * Status -
93  *	Public Domain.  Distribution Unlimited.
94  * Bugs -
95  *	More statistics could always be gathered.
96  *	This program has to run SUID to ROOT to access the ICMP socket.
97  */
98 /*
99  * NOTE:
100  * USE_SIN6_SCOPE_ID assumes that sin6_scope_id has the same semantics
101  * as IPV6_PKTINFO.  Some people object it (sin6_scope_id specifies *link*
102  * while IPV6_PKTINFO specifies *interface*.  Link is defined as collection of
103  * network attached to 1 or more interfaces)
104  */
105 
106 #include <sys/param.h>
107 #include <sys/capsicum.h>
108 #include <sys/uio.h>
109 #include <sys/socket.h>
110 
111 #include <net/if.h>
112 #include <net/route.h>
113 
114 #include <netinet/in.h>
115 #include <netinet/ip6.h>
116 #include <netinet/icmp6.h>
117 #include <arpa/inet.h>
118 #include <arpa/nameser.h>
119 #include <netdb.h>
120 
121 #include <capsicum_helpers.h>
122 #include <casper/cap_dns.h>
123 #include <libcasper.h>
124 
125 #include <ctype.h>
126 #include <err.h>
127 #include <errno.h>
128 #include <fcntl.h>
129 #include <math.h>
130 #include <signal.h>
131 #include <stdio.h>
132 #include <stdlib.h>
133 #include <string.h>
134 #include <sysexits.h>
135 #include <time.h>
136 #include <unistd.h>
137 
138 #ifdef IPSEC
139 #include <netipsec/ah.h>
140 #include <netipsec/ipsec.h>
141 #endif
142 
143 #include <md5.h>
144 
145 #include "main.h"
146 #include "ping6.h"
147 
148 struct tv32 {
149 	u_int32_t tv32_sec;
150 	u_int32_t tv32_nsec;
151 };
152 
153 #define MAXPACKETLEN	131072
154 #define	IP6LEN		40
155 #define ICMP6ECHOLEN	8	/* icmp echo header len excluding time */
156 #define ICMP6ECHOTMLEN sizeof(struct tv32)
157 #define ICMP6_NIQLEN	(ICMP6ECHOLEN + 8)
158 # define CONTROLLEN	10240	/* ancillary data buffer size RFC3542 20.1 */
159 /* FQDN case, 64 bits of nonce + 32 bits ttl */
160 #define ICMP6_NIRLEN	(ICMP6ECHOLEN + 12)
161 #define	EXTRA		256	/* for AH and various other headers. weird. */
162 #define	DEFDATALEN	ICMP6ECHOTMLEN
163 #define MAXDATALEN	MAXPACKETLEN - IP6LEN - ICMP6ECHOLEN
164 #define	NROUTES		9		/* number of record route slots */
165 #define	MAXWAIT		10000		/* max ms to wait for response */
166 #define	MAXALARM	(60 * 60)	/* max seconds for alarm timeout */
167 
168 #define	A(bit)		rcvd_tbl[(bit)>>3]	/* identify byte in array */
169 #define	B(bit)		(1 << ((bit) & 0x07))	/* identify bit in byte */
170 #define	SET(bit)	(A(bit) |= B(bit))
171 #define	CLR(bit)	(A(bit) &= (~B(bit)))
172 #define	TST(bit)	(A(bit) & B(bit))
173 
174 #define	F_FLOOD		0x0001
175 #define	F_INTERVAL	0x0002
176 #define	F_PINGFILLED	0x0008
177 #define	F_QUIET		0x0010
178 #define	F_RROUTE	0x0020
179 #define	F_SO_DEBUG	0x0040
180 #define	F_VERBOSE	0x0100
181 #ifdef IPSEC
182 #ifdef IPSEC_POLICY_IPSEC
183 #define	F_POLICY	0x0400
184 #else
185 #define F_AUTHHDR	0x0200
186 #define F_ENCRYPT	0x0400
187 #endif /*IPSEC_POLICY_IPSEC*/
188 #endif /*IPSEC*/
189 #define F_NODEADDR	0x0800
190 #define F_FQDN		0x1000
191 #define F_INTERFACE	0x2000
192 #define F_SRCADDR	0x4000
193 #define F_HOSTNAME	0x10000
194 #define F_FQDNOLD	0x20000
195 #define F_NIGROUP	0x40000
196 #define F_SUPTYPES	0x80000
197 #define F_NOMINMTU	0x100000
198 #define F_ONCE		0x200000
199 #define F_AUDIBLE	0x400000
200 #define F_MISSED	0x800000
201 #define F_DONTFRAG	0x1000000
202 #define F_NOUSERDATA	(F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES)
203 #define	F_WAITTIME	0x2000000
204 #define	F_DOT		0x4000000
205 static u_int options;
206 
207 #define IN6LEN		sizeof(struct in6_addr)
208 #define SA6LEN		sizeof(struct sockaddr_in6)
209 #define DUMMY_PORT	10101
210 
211 #define SIN6(s)	((struct sockaddr_in6 *)(s))
212 
213 /*
214  * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum
215  * number of received sequence numbers we can keep track of.  Change 128
216  * to 8192 for complete accuracy...
217  */
218 #define	MAX_DUP_CHK	(8 * 8192)
219 static int mx_dup_ck = MAX_DUP_CHK;
220 static char rcvd_tbl[MAX_DUP_CHK / 8];
221 
222 static struct sockaddr_in6 dst;	/* who to ping6 */
223 static struct sockaddr_in6 src;	/* src addr of this packet */
224 static socklen_t srclen;
225 static size_t datalen = DEFDATALEN;
226 static int ssend;		/* send socket file descriptor */
227 static int srecv;		/* receive socket file descriptor */
228 static u_char outpack[MAXPACKETLEN];
229 static char BSPACE = '\b';	/* characters written for flood */
230 static char BBELL = '\a';	/* characters written for AUDIBLE */
231 static const char *DOT = ".";
232 static size_t DOTlen = 1;
233 static size_t DOTidx = 0;
234 static char *hostname;
235 static int ident;		/* process id to identify our packets */
236 static u_int8_t nonce[8];	/* nonce field for node information */
237 static int hoplimit = -1;	/* hoplimit */
238 static int tclass = -1;		/* traffic class */
239 static int pcp = -2;		/* vlan priority code point */
240 static u_char *packet = NULL;
241 static cap_channel_t *capdns;
242 
243 /* counters */
244 static long nmissedmax;		/* max value of ntransmitted - nreceived - 1 */
245 static long npackets;		/* max packets to transmit */
246 static long nreceived;		/* # of packets we got back */
247 static long nrepeats;		/* number of duplicates */
248 static long ntransmitted;	/* sequence # for outbound packets = #sent */
249 static long ntransmitfailures;	/* number of transmit failures */
250 static int interval = 1000;	/* interval between packets in ms */
251 static int waittime = MAXWAIT;	/* timeout for each packet */
252 static long nrcvtimeout = 0;	/* # of packets we got back after waittime */
253 
254 /* timing */
255 static int timing;		/* flag to do timing */
256 static double tmin = 999999999.0;	/* minimum round trip time */
257 static double tmax = 0.0;	/* maximum round trip time */
258 static double tsum = 0.0;	/* sum of all times, for doing average */
259 static double tsumsq = 0.0;	/* sum of all times squared, for std. dev. */
260 
261 /* for node addresses */
262 static u_short naflags;
263 
264 /* for ancillary data(advanced API) */
265 static struct msghdr smsghdr;
266 static struct iovec smsgiov;
267 static char *scmsg = 0;
268 
269 static volatile sig_atomic_t seenint;
270 #ifdef SIGINFO
271 static volatile sig_atomic_t seeninfo;
272 #endif
273 
274 static cap_channel_t *capdns_setup(void);
275 static void	 fill(char *, char *);
276 static int	 get_hoplim(struct msghdr *);
277 static int	 get_pathmtu(struct msghdr *);
278 static struct in6_pktinfo *get_rcvpktinfo(struct msghdr *);
279 static void	 onsignal(int);
280 static void	 onint(int);
281 static size_t	 pingerlen(void);
282 static int	 pinger(void);
283 static const char *pr_addr(struct sockaddr *, int);
284 static void	 pr_icmph(struct icmp6_hdr *, u_char *);
285 static void	 pr_iph(struct ip6_hdr *);
286 static void	 pr_suptypes(struct icmp6_nodeinfo *, size_t);
287 static void	 pr_nodeaddr(struct icmp6_nodeinfo *, int);
288 static int	 myechoreply(const struct icmp6_hdr *);
289 static int	 mynireply(const struct icmp6_nodeinfo *);
290 static const char *dnsdecode(const u_char *, const u_char *, const u_char *,
291     char *, size_t);
292 static void	 pr_pack(u_char *, int, struct msghdr *);
293 static void	 pr_exthdrs(struct msghdr *);
294 static void	 pr_ip6opt(void *, size_t);
295 static void	 pr_rthdr(void *, size_t);
296 static int	 pr_bitrange(u_int32_t, int, int);
297 static void	 pr_retip(struct ip6_hdr *, u_char *);
298 static void	 summary(void);
299 #ifdef IPSEC
300 #ifdef IPSEC_POLICY_IPSEC
301 static int	 setpolicy(int, char *);
302 #endif
303 #endif
304 static char	*nigroup(char *, int);
305 
306 int
307 ping6(int argc, char *argv[])
308 {
309 	struct timespec last, intvl;
310 	struct sockaddr_in6 from, *sin6;
311 	struct addrinfo hints, *res;
312 	struct sigaction si_sa;
313 	int cc, i;
314 	int almost_done, ch, hold, packlen, preload, optval, error;
315 	int nig_oldmcprefix = -1;
316 	u_char *datap;
317 	char *e, *target, *ifname = NULL, *gateway = NULL;
318 	int ip6optlen = 0;
319 	struct cmsghdr *scmsgp = NULL;
320 	/* For control (ancillary) data received from recvmsg() */
321 	u_char cm[CONTROLLEN];
322 #if defined(SO_SNDBUF) && defined(SO_RCVBUF)
323 	u_long lsockbufsize;
324 	int sockbufsize = 0;
325 #endif
326 	int usepktinfo = 0;
327 	struct in6_pktinfo pktinfo;
328 	char *cmsg_pktinfo = NULL;
329 	struct ip6_rthdr *rthdr = NULL;
330 #ifdef IPSEC_POLICY_IPSEC
331 	char *policy_in = NULL;
332 	char *policy_out = NULL;
333 #endif
334 	double t;
335 	u_long alarmtimeout;
336 	size_t rthlen;
337 #ifdef IPV6_USE_MIN_MTU
338 	int mflag = 0;
339 #endif
340 	cap_rights_t rights_srecv;
341 	cap_rights_t rights_ssend;
342 	cap_rights_t rights_stdin;
343 
344 	/* just to be sure */
345 	memset(&smsghdr, 0, sizeof(smsghdr));
346 	memset(&smsgiov, 0, sizeof(smsgiov));
347 	memset(&pktinfo, 0, sizeof(pktinfo));
348 
349 	intvl.tv_sec = interval / 1000;
350 	intvl.tv_nsec = interval % 1000 * 1000000;
351 
352 	alarmtimeout = preload = 0;
353 	datap = &outpack[ICMP6ECHOLEN + ICMP6ECHOTMLEN];
354 	capdns = capdns_setup();
355 
356 	while ((ch = getopt(argc, argv, PING6OPTS)) != -1) {
357 		switch (ch) {
358 		case '.':
359 			options |= F_DOT;
360 			if (optarg != NULL) {
361 				DOT = optarg;
362 				DOTlen = strlen(optarg);
363 			}
364 			break;
365 		case '6':
366 			/* This option is processed in main(). */
367 			break;
368 		case 'k':
369 		{
370 			char *cp;
371 
372 			options &= ~F_NOUSERDATA;
373 			options |= F_NODEADDR;
374 			for (cp = optarg; *cp != '\0'; cp++) {
375 				switch (*cp) {
376 				case 'a':
377 					naflags |= NI_NODEADDR_FLAG_ALL;
378 					break;
379 				case 'c':
380 				case 'C':
381 					naflags |= NI_NODEADDR_FLAG_COMPAT;
382 					break;
383 				case 'l':
384 				case 'L':
385 					naflags |= NI_NODEADDR_FLAG_LINKLOCAL;
386 					break;
387 				case 's':
388 				case 'S':
389 					naflags |= NI_NODEADDR_FLAG_SITELOCAL;
390 					break;
391 				case 'g':
392 				case 'G':
393 					naflags |= NI_NODEADDR_FLAG_GLOBAL;
394 					break;
395 				case 'A': /* experimental. not in the spec */
396 #ifdef NI_NODEADDR_FLAG_ANYCAST
397 					naflags |= NI_NODEADDR_FLAG_ANYCAST;
398 					break;
399 #else
400 					errx(1,
401 "-a A is not supported on the platform");
402 					/*NOTREACHED*/
403 #endif
404 				default:
405 					usage();
406 					/*NOTREACHED*/
407 				}
408 			}
409 			break;
410 		}
411 		case 'b':
412 #if defined(SO_SNDBUF) && defined(SO_RCVBUF)
413 			errno = 0;
414 			e = NULL;
415 			lsockbufsize = strtoul(optarg, &e, 10);
416 			sockbufsize = (int)lsockbufsize;
417 			if (errno || !*optarg || *e ||
418 			    lsockbufsize > INT_MAX)
419 				errx(1, "invalid socket buffer size");
420 #else
421 			errx(1,
422 "-b option ignored: SO_SNDBUF/SO_RCVBUF socket options not supported");
423 #endif
424 			break;
425 		case 'C':		/* vlan priority code point */
426 			pcp = strtol(optarg, &e, 10);
427 			if (*optarg == '\0' || *e != '\0')
428 				errx(1, "illegal vlan pcp %s", optarg);
429 			if (7 < pcp || pcp < -1)
430 				errx(1, "illegal vlan pcp -- %s", optarg);
431 			break;
432 		case 'c':
433 			npackets = strtol(optarg, &e, 10);
434 			if (npackets <= 0 || *optarg == '\0' || *e != '\0')
435 				errx(1,
436 				    "illegal number of packets -- %s", optarg);
437 			break;
438 		case 'D':
439 			options |= F_DONTFRAG;
440 			break;
441 		case 'd':
442 			options |= F_SO_DEBUG;
443 			break;
444 		case 'f':
445 			if (getuid()) {
446 				errno = EPERM;
447 				errx(1, "Must be superuser to flood ping");
448 			}
449 			options |= F_FLOOD;
450 			options |= F_DOT;
451 			setbuf(stdout, (char *)NULL);
452 			break;
453 		case 'e':
454 			gateway = optarg;
455 			break;
456 		case 'H':
457 			options |= F_HOSTNAME;
458 			break;
459 		case 'm':		/* hoplimit */
460 			hoplimit = strtol(optarg, &e, 10);
461 			if (*optarg == '\0' || *e != '\0')
462 				errx(1, "illegal hoplimit %s", optarg);
463 			if (255 < hoplimit || hoplimit < -1)
464 				errx(1,
465 				    "illegal hoplimit -- %s", optarg);
466 			break;
467 		case 'I':
468 			ifname = optarg;
469 			options |= F_INTERFACE;
470 #ifndef USE_SIN6_SCOPE_ID
471 			usepktinfo++;
472 #endif
473 			break;
474 		case 'i':		/* wait between sending packets */
475 			t = strtod(optarg, &e);
476 			if (*optarg == '\0' || *e != '\0')
477 				errx(1, "illegal timing interval %s", optarg);
478 			if (t < 1 && getuid()) {
479 				errx(1, "%s: only root may use interval < 1s",
480 				    strerror(EPERM));
481 			}
482 			intvl.tv_sec = (time_t)t;
483 			intvl.tv_nsec =
484 			    (long)((t - intvl.tv_sec) * 1000000000);
485 			if (intvl.tv_sec < 0)
486 				errx(1, "illegal timing interval %s", optarg);
487 			/* less than 1/hz does not make sense */
488 			if (intvl.tv_sec == 0 && intvl.tv_nsec < 1000) {
489 				warnx("too small interval, raised to .000001");
490 				intvl.tv_nsec = 1000;
491 			}
492 			options |= F_INTERVAL;
493 			break;
494 		case 'l':
495 			if (getuid()) {
496 				errno = EPERM;
497 				errx(1, "Must be superuser to preload");
498 			}
499 			preload = strtol(optarg, &e, 10);
500 			if (preload < 0 || *optarg == '\0' || *e != '\0')
501 				errx(1, "illegal preload value -- %s", optarg);
502 			break;
503 		case 'u':
504 #ifdef IPV6_USE_MIN_MTU
505 			mflag++;
506 			break;
507 #else
508 			errx(1, "-%c is not supported on this platform", ch);
509 			/*NOTREACHED*/
510 #endif
511 		case 'n':
512 			options &= ~F_HOSTNAME;
513 			break;
514 		case 'N':
515 			options |= F_NIGROUP;
516 			nig_oldmcprefix++;
517 			break;
518 		case 'o':
519 			options |= F_ONCE;
520 			break;
521 		case 'p':		/* fill buffer with user pattern */
522 			options |= F_PINGFILLED;
523 			fill((char *)datap, optarg);
524 				break;
525 		case 'q':
526 			options |= F_QUIET;
527 			break;
528 		case 'a':
529 			options |= F_AUDIBLE;
530 			break;
531 		case 'A':
532 			options |= F_MISSED;
533 			break;
534 		case 'S':
535 			memset(&hints, 0, sizeof(struct addrinfo));
536 			hints.ai_flags = AI_NUMERICHOST; /* allow hostname? */
537 			hints.ai_family = AF_INET6;
538 			hints.ai_socktype = SOCK_RAW;
539 			hints.ai_protocol = IPPROTO_ICMPV6;
540 
541 			error = cap_getaddrinfo(capdns, optarg, NULL, &hints, &res);
542 			if (error) {
543 				errx(1, "invalid source address: %s",
544 				     gai_strerror(error));
545 			}
546 			/*
547 			 * res->ai_family must be AF_INET6 and res->ai_addrlen
548 			 * must be sizeof(src).
549 			 */
550 			memcpy(&src, res->ai_addr, res->ai_addrlen);
551 			srclen = res->ai_addrlen;
552 			freeaddrinfo(res);
553 			options |= F_SRCADDR;
554 			break;
555 		case 's':		/* size of packet to send */
556 			datalen = strtol(optarg, &e, 10);
557 			if (datalen <= 0 || *optarg == '\0' || *e != '\0')
558 				errx(1, "illegal datalen value -- %s", optarg);
559 			if (datalen > MAXDATALEN) {
560 				errx(1,
561 				    "datalen value too large, maximum is %d",
562 				    MAXDATALEN);
563 			}
564 			break;
565 		case 'O':
566 			options &= ~F_NOUSERDATA;
567 			options |= F_SUPTYPES;
568 			break;
569 		case 'v':
570 			options |= F_VERBOSE;
571 			break;
572 		case 'y':
573 			options &= ~F_NOUSERDATA;
574 			options |= F_FQDN;
575 			break;
576 		case 'Y':
577 			options &= ~F_NOUSERDATA;
578 			options |= F_FQDNOLD;
579 			break;
580 		case 'W':
581 			t = strtod(optarg, &e);
582 			if (*e || e == optarg || t > (double)INT_MAX)
583 				err(EX_USAGE, "invalid timing interval: `%s'",
584 				    optarg);
585 			options |= F_WAITTIME;
586 			waittime = (int)t;
587 			break;
588 		case 't':
589 			alarmtimeout = strtoul(optarg, &e, 0);
590 			if ((alarmtimeout < 1) || (alarmtimeout == ULONG_MAX))
591 				errx(EX_USAGE, "invalid timeout: `%s'",
592 				    optarg);
593 			if (alarmtimeout > MAXALARM)
594 				errx(EX_USAGE, "invalid timeout: `%s' > %d",
595 				    optarg, MAXALARM);
596 			{
597 				struct itimerval itv;
598 
599 				timerclear(&itv.it_interval);
600 				timerclear(&itv.it_value);
601 				itv.it_value.tv_sec = (time_t)alarmtimeout;
602 				if (setitimer(ITIMER_REAL, &itv, NULL) != 0)
603 					err(1, "setitimer");
604 			}
605 			break;
606 		case 'z':		/* traffic class */
607 			tclass = strtol(optarg, &e, 10);
608 			if (*optarg == '\0' || *e != '\0')
609 				errx(1, "illegal traffic class %s", optarg);
610 			if (255 < tclass || tclass < -1)
611 				errx(1,
612 				    "illegal traffic class -- %s", optarg);
613 			break;
614 #ifdef IPSEC
615 #ifdef IPSEC_POLICY_IPSEC
616 		case 'P':
617 			options |= F_POLICY;
618 			if (!strncmp("in", optarg, 2)) {
619 				if ((policy_in = strdup(optarg)) == NULL)
620 					errx(1, "strdup");
621 			} else if (!strncmp("out", optarg, 3)) {
622 				if ((policy_out = strdup(optarg)) == NULL)
623 					errx(1, "strdup");
624 			} else
625 				errx(1, "invalid security policy");
626 			break;
627 #else
628 		case 'Z':
629 			options |= F_AUTHHDR;
630 			break;
631 		case 'E':
632 			options |= F_ENCRYPT;
633 			break;
634 #endif /*IPSEC_POLICY_IPSEC*/
635 #endif /*IPSEC*/
636 		default:
637 			usage();
638 			/*NOTREACHED*/
639 		}
640 	}
641 
642 	argc -= optind;
643 	argv += optind;
644 
645 	if (argc < 1) {
646 		usage();
647 		/*NOTREACHED*/
648 	}
649 
650 	if (argc > 1) {
651 #ifdef IPV6_RECVRTHDR	/* 2292bis */
652 		rthlen = CMSG_SPACE(inet6_rth_space(IPV6_RTHDR_TYPE_0,
653 		    argc - 1));
654 #else  /* RFC2292 */
655 		rthlen = inet6_rthdr_space(IPV6_RTHDR_TYPE_0, argc - 1);
656 #endif
657 		if (rthlen == 0) {
658 			errx(1, "too many intermediate hops");
659 			/*NOTREACHED*/
660 		}
661 		ip6optlen += rthlen;
662 	}
663 
664 	if (options & F_NIGROUP) {
665 		target = nigroup(argv[argc - 1], nig_oldmcprefix);
666 		if (target == NULL) {
667 			usage();
668 			/*NOTREACHED*/
669 		}
670 	} else
671 		target = argv[argc - 1];
672 
673 	/* cap_getaddrinfo */
674 	memset(&hints, 0, sizeof(struct addrinfo));
675 	hints.ai_flags = AI_CANONNAME;
676 	hints.ai_family = AF_INET6;
677 	hints.ai_socktype = SOCK_RAW;
678 	hints.ai_protocol = IPPROTO_ICMPV6;
679 
680 	error = cap_getaddrinfo(capdns, target, NULL, &hints, &res);
681 	if (error)
682 		errx(1, "%s", gai_strerror(error));
683 	if (res->ai_canonname)
684 		hostname = strdup(res->ai_canonname);
685 	else
686 		hostname = target;
687 
688 	if (!res->ai_addr)
689 		errx(1, "cap_getaddrinfo failed");
690 
691 	(void)memcpy(&dst, res->ai_addr, res->ai_addrlen);
692 
693 	if ((ssend = socket(res->ai_family, res->ai_socktype,
694 	    res->ai_protocol)) < 0)
695 		err(1, "socket ssend");
696 	if ((srecv = socket(res->ai_family, res->ai_socktype,
697 	    res->ai_protocol)) < 0)
698 		err(1, "socket srecv");
699 	freeaddrinfo(res);
700 
701 	/* set the source address if specified. */
702 	if ((options & F_SRCADDR) != 0) {
703 		/* properly fill sin6_scope_id */
704 		if (IN6_IS_ADDR_LINKLOCAL(&src.sin6_addr) && (
705 		    IN6_IS_ADDR_LINKLOCAL(&dst.sin6_addr) ||
706 		    IN6_IS_ADDR_MC_LINKLOCAL(&dst.sin6_addr) ||
707 		    IN6_IS_ADDR_MC_NODELOCAL(&dst.sin6_addr))) {
708 			if (src.sin6_scope_id == 0)
709 				src.sin6_scope_id = dst.sin6_scope_id;
710 			if (dst.sin6_scope_id == 0)
711 				dst.sin6_scope_id = src.sin6_scope_id;
712 		}
713 		if (bind(ssend, (struct sockaddr *)&src, srclen) != 0)
714 			err(1, "bind");
715 	}
716 	/* set the gateway (next hop) if specified */
717 	if (gateway) {
718 		memset(&hints, 0, sizeof(hints));
719 		hints.ai_family = AF_INET6;
720 		hints.ai_socktype = SOCK_RAW;
721 		hints.ai_protocol = IPPROTO_ICMPV6;
722 
723 		error = cap_getaddrinfo(capdns, gateway, NULL, &hints, &res);
724 		if (error) {
725 			errx(1, "cap_getaddrinfo for the gateway %s: %s",
726 			     gateway, gai_strerror(error));
727 		}
728 		if (res->ai_next && (options & F_VERBOSE))
729 			warnx("gateway resolves to multiple addresses");
730 
731 		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_NEXTHOP,
732 		    res->ai_addr, res->ai_addrlen)) {
733 			err(1, "setsockopt(IPV6_NEXTHOP)");
734 		}
735 
736 		freeaddrinfo(res);
737 	}
738 
739 	/*
740 	 * let the kerel pass extension headers of incoming packets,
741 	 * for privileged socket options
742 	 */
743 	if ((options & F_VERBOSE) != 0) {
744 		int opton = 1;
745 
746 #ifdef IPV6_RECVHOPOPTS
747 		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &opton,
748 		    sizeof(opton)))
749 			err(1, "setsockopt(IPV6_RECVHOPOPTS)");
750 #else  /* old adv. API */
751 		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_HOPOPTS, &opton,
752 		    sizeof(opton)))
753 			err(1, "setsockopt(IPV6_HOPOPTS)");
754 #endif
755 #ifdef IPV6_RECVDSTOPTS
756 		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &opton,
757 		    sizeof(opton)))
758 			err(1, "setsockopt(IPV6_RECVDSTOPTS)");
759 #else  /* old adv. API */
760 		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_DSTOPTS, &opton,
761 		    sizeof(opton)))
762 			err(1, "setsockopt(IPV6_DSTOPTS)");
763 #endif
764 #ifdef IPV6_RECVRTHDRDSTOPTS
765 		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, &opton,
766 		    sizeof(opton)))
767 			err(1, "setsockopt(IPV6_RECVRTHDRDSTOPTS)");
768 #endif
769 	}
770 
771 	/* revoke root privilege */
772 	if (seteuid(getuid()) != 0)
773 		err(1, "seteuid() failed");
774 	if (setuid(getuid()) != 0)
775 		err(1, "setuid() failed");
776 
777 	if ((options & F_FLOOD) && (options & F_INTERVAL))
778 		errx(1, "-f and -i incompatible options");
779 
780 	if ((options & F_NOUSERDATA) == 0) {
781 		if (datalen >= sizeof(struct tv32)) {
782 			/* we can time transfer */
783 			timing = 1;
784 		} else
785 			timing = 0;
786 		/* in F_VERBOSE case, we may get non-echoreply packets*/
787 		if (options & F_VERBOSE)
788 			packlen = 2048 + IP6LEN + ICMP6ECHOLEN + EXTRA;
789 		else
790 			packlen = datalen + IP6LEN + ICMP6ECHOLEN + EXTRA;
791 	} else {
792 		/* suppress timing for node information query */
793 		timing = 0;
794 		datalen = 2048;
795 		packlen = 2048 + IP6LEN + ICMP6ECHOLEN + EXTRA;
796 	}
797 
798 	if (!(packet = (u_char *)malloc((u_int)packlen)))
799 		err(1, "Unable to allocate packet");
800 	if (!(options & F_PINGFILLED))
801 		for (i = ICMP6ECHOLEN; i < packlen; ++i)
802 			*datap++ = i;
803 
804 	ident = getpid() & 0xFFFF;
805 	arc4random_buf(nonce, sizeof(nonce));
806 	optval = 1;
807 	if (options & F_DONTFRAG)
808 		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_DONTFRAG,
809 		    &optval, sizeof(optval)) == -1)
810 			err(1, "IPV6_DONTFRAG");
811 	hold = 1;
812 
813 	if (options & F_SO_DEBUG) {
814 		(void)setsockopt(ssend, SOL_SOCKET, SO_DEBUG, (char *)&hold,
815 		    sizeof(hold));
816 		(void)setsockopt(srecv, SOL_SOCKET, SO_DEBUG, (char *)&hold,
817 		    sizeof(hold));
818 	}
819 	optval = IPV6_DEFHLIM;
820 	if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr))
821 		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
822 		    &optval, sizeof(optval)) == -1)
823 			err(1, "IPV6_MULTICAST_HOPS");
824 #ifdef IPV6_USE_MIN_MTU
825 	if (mflag != 1) {
826 		optval = mflag > 1 ? 0 : 1;
827 
828 		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
829 		    &optval, sizeof(optval)) == -1)
830 			err(1, "setsockopt(IPV6_USE_MIN_MTU)");
831 	}
832 #ifdef IPV6_RECVPATHMTU
833 	else {
834 		optval = 1;
835 		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVPATHMTU,
836 		    &optval, sizeof(optval)) == -1)
837 			err(1, "setsockopt(IPV6_RECVPATHMTU)");
838 	}
839 #endif /* IPV6_RECVPATHMTU */
840 #endif /* IPV6_USE_MIN_MTU */
841 
842 #ifdef IPSEC
843 #ifdef IPSEC_POLICY_IPSEC
844 	if (options & F_POLICY) {
845 		if (setpolicy(srecv, policy_in) < 0)
846 			errx(1, "%s", ipsec_strerror());
847 		if (setpolicy(ssend, policy_out) < 0)
848 			errx(1, "%s", ipsec_strerror());
849 	}
850 #else
851 	if (options & F_AUTHHDR) {
852 		optval = IPSEC_LEVEL_REQUIRE;
853 #ifdef IPV6_AUTH_TRANS_LEVEL
854 		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL,
855 		    &optval, sizeof(optval)) == -1)
856 			err(1, "setsockopt(IPV6_AUTH_TRANS_LEVEL)");
857 		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL,
858 		     &optval, sizeof(optval)) == -1)
859 			err(1, "setsockopt(IPV6_AUTH_TRANS_LEVEL)");
860 #else /* old def */
861 		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_AUTH_LEVEL,
862 		    &optval, sizeof(optval)) == -1)
863 			err(1, "setsockopt(IPV6_AUTH_LEVEL)");
864 		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_AUTH_LEVEL,
865 		    &optval, sizeof(optval)) == -1)
866 			err(1, "setsockopt(IPV6_AUTH_LEVEL)");
867 #endif
868 	}
869 	if (options & F_ENCRYPT) {
870 		optval = IPSEC_LEVEL_REQUIRE;
871 		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL,
872 		    &optval, sizeof(optval)) == -1)
873 			err(1, "setsockopt(IPV6_ESP_TRANS_LEVEL)");
874 		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL,
875 		    &optval, sizeof(optval)) == -1)
876 			err(1, "setsockopt(IPV6_ESP_TRANS_LEVEL)");
877 	}
878 #endif /*IPSEC_POLICY_IPSEC*/
879 #endif
880 
881 #ifdef ICMP6_FILTER
882     {
883 	struct icmp6_filter filt;
884 	if (!(options & F_VERBOSE)) {
885 		ICMP6_FILTER_SETBLOCKALL(&filt);
886 		if ((options & F_FQDN) || (options & F_FQDNOLD) ||
887 		    (options & F_NODEADDR) || (options & F_SUPTYPES))
888 			ICMP6_FILTER_SETPASS(ICMP6_NI_REPLY, &filt);
889 		else
890 			ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filt);
891 	} else {
892 		ICMP6_FILTER_SETPASSALL(&filt);
893 	}
894 	if (setsockopt(srecv, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
895 	    sizeof(filt)) < 0)
896 		err(1, "setsockopt(ICMP6_FILTER)");
897     }
898 #endif /*ICMP6_FILTER*/
899 
900 	/* let the kerel pass extension headers of incoming packets */
901 	if ((options & F_VERBOSE) != 0) {
902 		int opton = 1;
903 
904 #ifdef IPV6_RECVRTHDR
905 		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVRTHDR, &opton,
906 		    sizeof(opton)))
907 			err(1, "setsockopt(IPV6_RECVRTHDR)");
908 #else  /* old adv. API */
909 		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RTHDR, &opton,
910 		    sizeof(opton)))
911 			err(1, "setsockopt(IPV6_RTHDR)");
912 #endif
913 	}
914 
915 /*
916 	optval = 1;
917 	if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr))
918 		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
919 		    &optval, sizeof(optval)) == -1)
920 			err(1, "IPV6_MULTICAST_LOOP");
921 */
922 
923 	/* Specify the outgoing interface and/or the source address */
924 	if (usepktinfo)
925 		ip6optlen += CMSG_SPACE(sizeof(struct in6_pktinfo));
926 
927 	if (hoplimit != -1)
928 		ip6optlen += CMSG_SPACE(sizeof(int));
929 
930 	/* set IP6 packet options */
931 	if (ip6optlen) {
932 		if ((scmsg = (char *)malloc(ip6optlen)) == NULL)
933 			errx(1, "can't allocate enough memory");
934 		smsghdr.msg_control = (caddr_t)scmsg;
935 		smsghdr.msg_controllen = ip6optlen;
936 		scmsgp = CMSG_FIRSTHDR(&smsghdr);
937 	}
938 	if (usepktinfo) {
939 		cmsg_pktinfo = CMSG_DATA(scmsgp);
940 		scmsgp->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
941 		scmsgp->cmsg_level = IPPROTO_IPV6;
942 		scmsgp->cmsg_type = IPV6_PKTINFO;
943 		scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp);
944 	}
945 
946 	/* set the outgoing interface */
947 	if (ifname) {
948 #ifndef USE_SIN6_SCOPE_ID
949 		/* pktinfo must have already been allocated */
950 		if ((pktinfo.ipi6_ifindex = if_nametoindex(ifname)) == 0)
951 			errx(1, "%s: invalid interface name", ifname);
952 #else
953 		if ((dst.sin6_scope_id = if_nametoindex(ifname)) == 0)
954 			errx(1, "%s: invalid interface name", ifname);
955 #endif
956 	}
957 	if (hoplimit != -1) {
958 		scmsgp->cmsg_len = CMSG_LEN(sizeof(int));
959 		scmsgp->cmsg_level = IPPROTO_IPV6;
960 		scmsgp->cmsg_type = IPV6_HOPLIMIT;
961 		memcpy(CMSG_DATA(scmsgp), &hoplimit, sizeof(hoplimit));
962 
963 		scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp);
964 	}
965 
966 	if (tclass != -1) {
967 		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_TCLASS,
968 		    &tclass, sizeof(tclass)) == -1)
969 			err(1, "setsockopt(IPV6_TCLASS)");
970 	}
971 
972 	if (pcp != -2) {
973 		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_VLAN_PCP,
974 		    &pcp, sizeof(pcp)) == -1)
975 			err(1, "setsockopt(IPV6_VLAN_PCP)");
976 	}
977 
978 	if (argc > 1) {	/* some intermediate addrs are specified */
979 		int hops;
980 		int rthdrlen;
981 
982 		rthdrlen = inet6_rth_space(IPV6_RTHDR_TYPE_0, argc - 1);
983 		scmsgp->cmsg_len = CMSG_LEN(rthdrlen);
984 		scmsgp->cmsg_level = IPPROTO_IPV6;
985 		scmsgp->cmsg_type = IPV6_RTHDR;
986 		rthdr = (struct ip6_rthdr *)CMSG_DATA(scmsgp);
987 		rthdr = inet6_rth_init((void *)rthdr, rthdrlen,
988 		    IPV6_RTHDR_TYPE_0, argc - 1);
989 		if (rthdr == NULL)
990 			errx(1, "can't initialize rthdr");
991 
992 		for (hops = 0; hops < argc - 1; hops++) {
993 			memset(&hints, 0, sizeof(hints));
994 			hints.ai_family = AF_INET6;
995 
996 			if ((error = cap_getaddrinfo(capdns, argv[hops], NULL, &hints,
997 			    &res)))
998 				errx(1, "%s", gai_strerror(error));
999 			if (res->ai_addr->sa_family != AF_INET6)
1000 				errx(1,
1001 				    "bad addr family of an intermediate addr");
1002 			sin6 = (struct sockaddr_in6 *)(void *)res->ai_addr;
1003 			if (inet6_rth_add(rthdr, &sin6->sin6_addr))
1004 				errx(1, "can't add an intermediate node");
1005 			freeaddrinfo(res);
1006 		}
1007 
1008 		scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp);
1009 	}
1010 
1011 	/* From now on we will use only reverse DNS lookups. */
1012 #ifdef WITH_CASPER
1013 	if (capdns != NULL) {
1014 		const char *types[1];
1015 
1016 		types[0] = "ADDR2NAME";
1017 		if (cap_dns_type_limit(capdns, types, nitems(types)) < 0)
1018 			err(1, "unable to limit access to system.dns service");
1019 	}
1020 #endif
1021 	if (!(options & F_SRCADDR)) {
1022 		/*
1023 		 * get the source address. XXX since we revoked the root
1024 		 * privilege, we cannot use a raw socket for this.
1025 		 */
1026 		int dummy;
1027 		socklen_t len = sizeof(src);
1028 
1029 		if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
1030 			err(1, "UDP socket");
1031 
1032 		src.sin6_family = AF_INET6;
1033 		src.sin6_addr = dst.sin6_addr;
1034 		src.sin6_port = ntohs(DUMMY_PORT);
1035 		src.sin6_scope_id = dst.sin6_scope_id;
1036 
1037 		if (usepktinfo &&
1038 		    setsockopt(dummy, IPPROTO_IPV6, IPV6_PKTINFO,
1039 		    (void *)&pktinfo, sizeof(pktinfo)))
1040 			err(1, "UDP setsockopt(IPV6_PKTINFO)");
1041 
1042 		if (hoplimit != -1 &&
1043 		    setsockopt(dummy, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
1044 		    (void *)&hoplimit, sizeof(hoplimit)))
1045 			err(1, "UDP setsockopt(IPV6_UNICAST_HOPS)");
1046 
1047 		if (hoplimit != -1 &&
1048 		    setsockopt(dummy, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
1049 		    (void *)&hoplimit, sizeof(hoplimit)))
1050 			err(1, "UDP setsockopt(IPV6_MULTICAST_HOPS)");
1051 
1052 		if (rthdr &&
1053 		    setsockopt(dummy, IPPROTO_IPV6, IPV6_RTHDR,
1054 		    (void *)rthdr, (rthdr->ip6r_len + 1) << 3))
1055 			err(1, "UDP setsockopt(IPV6_RTHDR)");
1056 
1057 		if (connect(dummy, (struct sockaddr *)&src, len) < 0)
1058 			err(1, "UDP connect");
1059 
1060 		if (getsockname(dummy, (struct sockaddr *)&src, &len) < 0)
1061 			err(1, "getsockname");
1062 
1063 		close(dummy);
1064 	}
1065 
1066 	/* Save pktinfo in the ancillary data. */
1067 	if (usepktinfo)
1068 		memcpy(cmsg_pktinfo, &pktinfo, sizeof(pktinfo));
1069 
1070 	if (connect(ssend, (struct sockaddr *)&dst, sizeof(dst)) != 0)
1071 		err(1, "connect() ssend");
1072 
1073 	caph_cache_catpages();
1074 	if (caph_enter_casper() < 0)
1075 		err(1, "caph_enter_casper");
1076 
1077 	cap_rights_init(&rights_stdin);
1078 	if (caph_rights_limit(STDIN_FILENO, &rights_stdin) < 0)
1079 		err(1, "caph_rights_limit stdin");
1080 	if (caph_limit_stdout() < 0)
1081 		err(1, "caph_limit_stdout");
1082 	if (caph_limit_stderr() < 0)
1083 		err(1, "caph_limit_stderr");
1084 
1085 	cap_rights_init(&rights_srecv, CAP_RECV, CAP_EVENT, CAP_SETSOCKOPT);
1086 	if (caph_rights_limit(srecv, &rights_srecv) < 0)
1087 		err(1, "caph_rights_limit srecv");
1088 	cap_rights_init(&rights_ssend, CAP_SEND, CAP_SETSOCKOPT);
1089 	if (caph_rights_limit(ssend, &rights_ssend) < 0)
1090 		err(1, "caph_rights_limit ssend");
1091 
1092 #if defined(SO_SNDBUF) && defined(SO_RCVBUF)
1093 	if (sockbufsize) {
1094 		if (datalen > (size_t)sockbufsize)
1095 			warnx("you need -b to increase socket buffer size");
1096 		if (setsockopt(ssend, SOL_SOCKET, SO_SNDBUF, &sockbufsize,
1097 		    sizeof(sockbufsize)) < 0)
1098 			err(1, "setsockopt(SO_SNDBUF)");
1099 		if (setsockopt(srecv, SOL_SOCKET, SO_RCVBUF, &sockbufsize,
1100 		    sizeof(sockbufsize)) < 0)
1101 			err(1, "setsockopt(SO_RCVBUF)");
1102 	}
1103 	else {
1104 		if (datalen > 8 * 1024)	/*XXX*/
1105 			warnx("you need -b to increase socket buffer size");
1106 		/*
1107 		 * When pinging the broadcast address, you can get a lot of
1108 		 * answers. Doing something so evil is useful if you are trying
1109 		 * to stress the ethernet, or just want to fill the arp cache
1110 		 * to get some stuff for /etc/ethers.
1111 		 */
1112 		hold = 48 * 1024;
1113 		setsockopt(srecv, SOL_SOCKET, SO_RCVBUF, (char *)&hold,
1114 		    sizeof(hold));
1115 	}
1116 #endif
1117 
1118 	optval = 1;
1119 #ifndef USE_SIN6_SCOPE_ID
1120 #ifdef IPV6_RECVPKTINFO
1121 	if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval,
1122 	    sizeof(optval)) < 0)
1123 		warn("setsockopt(IPV6_RECVPKTINFO)"); /* XXX err? */
1124 #else  /* old adv. API */
1125 	if (setsockopt(srecv, IPPROTO_IPV6, IPV6_PKTINFO, &optval,
1126 	    sizeof(optval)) < 0)
1127 		warn("setsockopt(IPV6_PKTINFO)"); /* XXX err? */
1128 #endif
1129 #endif /* USE_SIN6_SCOPE_ID */
1130 #ifdef IPV6_RECVHOPLIMIT
1131 	if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &optval,
1132 	    sizeof(optval)) < 0)
1133 		warn("setsockopt(IPV6_RECVHOPLIMIT)"); /* XXX err? */
1134 #else  /* old adv. API */
1135 	if (setsockopt(srecv, IPPROTO_IPV6, IPV6_HOPLIMIT, &optval,
1136 	    sizeof(optval)) < 0)
1137 		warn("setsockopt(IPV6_HOPLIMIT)"); /* XXX err? */
1138 #endif
1139 
1140 	cap_rights_clear(&rights_srecv, CAP_SETSOCKOPT);
1141 	if (caph_rights_limit(srecv, &rights_srecv) < 0)
1142 		err(1, "caph_rights_limit srecv setsockopt");
1143 	cap_rights_clear(&rights_ssend, CAP_SETSOCKOPT);
1144 	if (caph_rights_limit(ssend, &rights_ssend) < 0)
1145 		err(1, "caph_rights_limit ssend setsockopt");
1146 
1147 	printf("PING6(%lu=40+8+%lu bytes) ", (unsigned long)(40 + pingerlen()),
1148 	    (unsigned long)(pingerlen() - 8));
1149 	printf("%s --> ", pr_addr((struct sockaddr *)&src, sizeof(src)));
1150 	printf("%s\n", pr_addr((struct sockaddr *)&dst, sizeof(dst)));
1151 
1152 	if (preload == 0)
1153 		pinger();
1154 	else {
1155 		if (npackets != 0 && preload > npackets)
1156 			preload = npackets;
1157 		while (preload--)
1158 			pinger();
1159 	}
1160 	clock_gettime(CLOCK_MONOTONIC, &last);
1161 
1162 	sigemptyset(&si_sa.sa_mask);
1163 	si_sa.sa_flags = 0;
1164 	si_sa.sa_handler = onsignal;
1165 	if (sigaction(SIGINT, &si_sa, 0) == -1)
1166 		err(EX_OSERR, "sigaction SIGINT");
1167 	seenint = 0;
1168 #ifdef SIGINFO
1169 	if (sigaction(SIGINFO, &si_sa, 0) == -1)
1170 		err(EX_OSERR, "sigaction SIGINFO");
1171 	seeninfo = 0;
1172 #endif
1173 	if (alarmtimeout > 0) {
1174 		if (sigaction(SIGALRM, &si_sa, 0) == -1)
1175 			err(EX_OSERR, "sigaction SIGALRM");
1176 	}
1177 	if (options & F_FLOOD) {
1178 		intvl.tv_sec = 0;
1179 		intvl.tv_nsec = 10000000;
1180 	}
1181 
1182 	almost_done = 0;
1183 	while (seenint == 0) {
1184 		struct timespec now, timeout;
1185 		struct msghdr m;
1186 		struct iovec iov[2];
1187 		fd_set rfds;
1188 		int n;
1189 
1190 		/* signal handling */
1191 		if (seenint)
1192 			onint(SIGINT);
1193 #ifdef SIGINFO
1194 		if (seeninfo) {
1195 			summary();
1196 			seeninfo = 0;
1197 			continue;
1198 		}
1199 #endif
1200 		FD_ZERO(&rfds);
1201 		FD_SET(srecv, &rfds);
1202 		clock_gettime(CLOCK_MONOTONIC, &now);
1203 		timespecadd(&last, &intvl, &timeout);
1204 		timespecsub(&timeout, &now, &timeout);
1205 		if (timeout.tv_sec < 0)
1206 			timespecclear(&timeout);
1207 
1208 		n = pselect(srecv + 1, &rfds, NULL, NULL, &timeout, NULL);
1209 		if (n < 0)
1210 			continue;	/* EINTR */
1211 		if (n == 1) {
1212 			m.msg_name = (caddr_t)&from;
1213 			m.msg_namelen = sizeof(from);
1214 			memset(&iov, 0, sizeof(iov));
1215 			iov[0].iov_base = (caddr_t)packet;
1216 			iov[0].iov_len = packlen;
1217 			m.msg_iov = iov;
1218 			m.msg_iovlen = 1;
1219 			memset(cm, 0, CONTROLLEN);
1220 			m.msg_control = (void *)cm;
1221 			m.msg_controllen = CONTROLLEN;
1222 
1223 			cc = recvmsg(srecv, &m, 0);
1224 			if (cc < 0) {
1225 				if (errno != EINTR) {
1226 					warn("recvmsg");
1227 					sleep(1);
1228 				}
1229 				continue;
1230 			} else if (cc == 0) {
1231 				int mtu;
1232 
1233 				/*
1234 				 * receive control messages only. Process the
1235 				 * exceptions (currently the only possibility is
1236 				 * a path MTU notification.)
1237 				 */
1238 				if ((mtu = get_pathmtu(&m)) > 0) {
1239 					if ((options & F_VERBOSE) != 0) {
1240 						printf("new path MTU (%d) is "
1241 						    "notified\n", mtu);
1242 					}
1243 				}
1244 				continue;
1245 			} else {
1246 				/*
1247 				 * an ICMPv6 message (probably an echoreply)
1248 				 * arrived.
1249 				 */
1250 				pr_pack(packet, cc, &m);
1251 			}
1252 			if (((options & F_ONCE) != 0 && nreceived > 0) ||
1253 			    (npackets > 0 && nreceived >= npackets))
1254 				break;
1255 		}
1256 		if (n == 0 || (options & F_FLOOD)) {
1257 			if (npackets == 0 || ntransmitted < npackets)
1258 				pinger();
1259 			else {
1260 				if (almost_done)
1261 					break;
1262 				almost_done = 1;
1263 			/*
1264 			 * If we're not transmitting any more packets,
1265 			 * change the timer to wait two round-trip times
1266 			 * if we've received any packets or (waittime)
1267 			 * milliseconds if we haven't.
1268 			 */
1269 				intvl.tv_nsec = 0;
1270 				if (nreceived) {
1271 					intvl.tv_sec = 2 * tmax / 1000;
1272 					if (intvl.tv_sec == 0)
1273 						intvl.tv_sec = 1;
1274 				} else {
1275 					intvl.tv_sec = waittime / 1000;
1276 					intvl.tv_nsec =
1277 						waittime % 1000 * 1000000;
1278 				}
1279 			}
1280 			clock_gettime(CLOCK_MONOTONIC, &last);
1281 			if (ntransmitted - nreceived - 1 > nmissedmax) {
1282 				nmissedmax = ntransmitted - nreceived - 1;
1283 				if (options & F_MISSED)
1284 					(void)write(STDOUT_FILENO, &BBELL, 1);
1285 			}
1286 		}
1287 	}
1288 	sigemptyset(&si_sa.sa_mask);
1289 	si_sa.sa_flags = 0;
1290 	si_sa.sa_handler = SIG_IGN;
1291 	sigaction(SIGINT, &si_sa, 0);
1292 	sigaction(SIGALRM, &si_sa, 0);
1293 	summary();
1294 
1295         if(packet != NULL)
1296                 free(packet);
1297 
1298 	if (nreceived > 0)
1299 		exit(0);
1300 	else if (ntransmitted > ntransmitfailures)
1301 		exit(2);
1302 	else
1303 		exit(EX_OSERR);
1304 }
1305 
1306 static void
1307 onsignal(int sig)
1308 {
1309 
1310 	switch (sig) {
1311 	case SIGINT:
1312 	case SIGALRM:
1313 		seenint++;
1314 		break;
1315 #ifdef SIGINFO
1316 	case SIGINFO:
1317 		seeninfo++;
1318 		break;
1319 #endif
1320 	}
1321 }
1322 
1323 /*
1324  * pinger --
1325  *	Compose and transmit an ICMP ECHO REQUEST packet.  The IP packet
1326  * will be added on by the kernel.  The ID field is our UNIX process ID,
1327  * and the sequence number is an ascending integer.  The first 8 bytes
1328  * of the data portion are used to hold a UNIX "timespec" struct in VAX
1329  * byte-order, to compute the round-trip time.
1330  */
1331 static size_t
1332 pingerlen(void)
1333 {
1334 	size_t l;
1335 
1336 	if (options & F_FQDN)
1337 		l = ICMP6_NIQLEN + sizeof(dst.sin6_addr);
1338 	else if (options & F_FQDNOLD)
1339 		l = ICMP6_NIQLEN;
1340 	else if (options & F_NODEADDR)
1341 		l = ICMP6_NIQLEN + sizeof(dst.sin6_addr);
1342 	else if (options & F_SUPTYPES)
1343 		l = ICMP6_NIQLEN;
1344 	else
1345 		l = ICMP6ECHOLEN + datalen;
1346 
1347 	return l;
1348 }
1349 
1350 static int
1351 pinger(void)
1352 {
1353 	struct icmp6_hdr *icp;
1354 	struct iovec iov[2];
1355 	int i, cc;
1356 	struct icmp6_nodeinfo *nip;
1357 	uint16_t seq;
1358 
1359 	if (npackets && ntransmitted >= npackets)
1360 		return(-1);	/* no more transmission */
1361 
1362 	icp = (struct icmp6_hdr *)outpack;
1363 	nip = (struct icmp6_nodeinfo *)outpack;
1364 	memset(icp, 0, sizeof(*icp));
1365 	icp->icmp6_cksum = 0;
1366 	seq = ntransmitted++;
1367 	CLR(seq % mx_dup_ck);
1368 
1369 	if (options & F_FQDN) {
1370 		uint16_t s;
1371 
1372 		icp->icmp6_type = ICMP6_NI_QUERY;
1373 		icp->icmp6_code = ICMP6_NI_SUBJ_IPV6;
1374 		nip->ni_qtype = htons(NI_QTYPE_FQDN);
1375 		nip->ni_flags = htons(0);
1376 
1377 		memcpy(nip->icmp6_ni_nonce, nonce,
1378 		    sizeof(nip->icmp6_ni_nonce));
1379 		s = htons(seq);
1380 		memcpy(nip->icmp6_ni_nonce, &s, sizeof(s));
1381 
1382 		memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr,
1383 		    sizeof(dst.sin6_addr));
1384 		cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr);
1385 		datalen = 0;
1386 	} else if (options & F_FQDNOLD) {
1387 		uint16_t s;
1388 		/* packet format in 03 draft - no Subject data on queries */
1389 		icp->icmp6_type = ICMP6_NI_QUERY;
1390 		icp->icmp6_code = 0;	/* code field is always 0 */
1391 		nip->ni_qtype = htons(NI_QTYPE_FQDN);
1392 		nip->ni_flags = htons(0);
1393 
1394 		memcpy(nip->icmp6_ni_nonce, nonce,
1395 		    sizeof(nip->icmp6_ni_nonce));
1396 		s = htons(seq);
1397 		memcpy(nip->icmp6_ni_nonce, &s, sizeof(s));
1398 
1399 		cc = ICMP6_NIQLEN;
1400 		datalen = 0;
1401 	} else if (options & F_NODEADDR) {
1402 		uint16_t s;
1403 
1404 		icp->icmp6_type = ICMP6_NI_QUERY;
1405 		icp->icmp6_code = ICMP6_NI_SUBJ_IPV6;
1406 		nip->ni_qtype = htons(NI_QTYPE_NODEADDR);
1407 		nip->ni_flags = naflags;
1408 
1409 		memcpy(nip->icmp6_ni_nonce, nonce,
1410 		    sizeof(nip->icmp6_ni_nonce));
1411 		s = htons(seq);
1412 		memcpy(nip->icmp6_ni_nonce, &s, sizeof(s));
1413 
1414 		memcpy(&outpack[ICMP6_NIQLEN], &dst.sin6_addr,
1415 		    sizeof(dst.sin6_addr));
1416 		cc = ICMP6_NIQLEN + sizeof(dst.sin6_addr);
1417 		datalen = 0;
1418 	} else if (options & F_SUPTYPES) {
1419 		uint16_t s;
1420 
1421 		icp->icmp6_type = ICMP6_NI_QUERY;
1422 		icp->icmp6_code = ICMP6_NI_SUBJ_FQDN;	/*empty*/
1423 		nip->ni_qtype = htons(NI_QTYPE_SUPTYPES);
1424 		/* we support compressed bitmap */
1425 		nip->ni_flags = NI_SUPTYPE_FLAG_COMPRESS;
1426 
1427 		memcpy(nip->icmp6_ni_nonce, nonce,
1428 		    sizeof(nip->icmp6_ni_nonce));
1429 		s = htons(seq);
1430 		memcpy(nip->icmp6_ni_nonce, &s, sizeof(s));
1431 
1432 		cc = ICMP6_NIQLEN;
1433 		datalen = 0;
1434 	} else {
1435 		icp->icmp6_type = ICMP6_ECHO_REQUEST;
1436 		icp->icmp6_code = 0;
1437 		icp->icmp6_id = htons(ident);
1438 		icp->icmp6_seq = htons(seq);
1439 		if (timing) {
1440 			struct timespec tv;
1441 			struct tv32 tv32;
1442 			(void)clock_gettime(CLOCK_MONOTONIC, &tv);
1443 			/*
1444 			 * Truncate seconds down to 32 bits in order
1445 			 * to fit the timestamp within 8 bytes of the
1446 			 * packet. We're only concerned with
1447 			 * durations, not absolute times.
1448 			 */
1449 			tv32.tv32_sec = (uint32_t)htonl(tv.tv_sec);
1450 			tv32.tv32_nsec = (uint32_t)htonl(tv.tv_nsec);
1451 			memcpy(&outpack[ICMP6ECHOLEN], &tv32, sizeof(tv32));
1452 		}
1453 		cc = ICMP6ECHOLEN + datalen;
1454 	}
1455 
1456 #ifdef DIAGNOSTIC
1457 	if (pingerlen() != cc)
1458 		errx(1, "internal error; length mismatch");
1459 #endif
1460 
1461 	memset(&iov, 0, sizeof(iov));
1462 	iov[0].iov_base = (caddr_t)outpack;
1463 	iov[0].iov_len = cc;
1464 	smsghdr.msg_iov = iov;
1465 	smsghdr.msg_iovlen = 1;
1466 
1467 	i = sendmsg(ssend, &smsghdr, 0);
1468 
1469 	if (i < 0 || i != cc)  {
1470 		if (i < 0) {
1471 			ntransmitfailures++;
1472 			warn("sendmsg");
1473 		}
1474 		(void)printf("ping6: wrote %s %d chars, ret=%d\n",
1475 		    hostname, cc, i);
1476 	}
1477 	if (!(options & F_QUIET) && options & F_DOT)
1478 		(void)write(STDOUT_FILENO, &DOT[DOTidx++ % DOTlen], 1);
1479 
1480 	return(0);
1481 }
1482 
1483 static int
1484 myechoreply(const struct icmp6_hdr *icp)
1485 {
1486 	if (ntohs(icp->icmp6_id) == ident)
1487 		return 1;
1488 	else
1489 		return 0;
1490 }
1491 
1492 static int
1493 mynireply(const struct icmp6_nodeinfo *nip)
1494 {
1495 	if (memcmp(nip->icmp6_ni_nonce + sizeof(u_int16_t),
1496 	    nonce + sizeof(u_int16_t),
1497 	    sizeof(nonce) - sizeof(u_int16_t)) == 0)
1498 		return 1;
1499 	else
1500 		return 0;
1501 }
1502 
1503 /*
1504  * Decode a name from a DNS message.
1505  *
1506  * Format of the message is described in RFC 1035 subsection 4.1.4.
1507  *
1508  * Arguments:
1509  *   sp     - Pointer to a DNS pointer octet or to the first octet of a label
1510  *            in the message.
1511  *   ep     - Pointer to the end of the message (one step past the last octet).
1512  *   base   - Pointer to the beginning of the message.
1513  *   buf    - Buffer into which the decoded name will be saved.
1514  *   bufsiz - Size of the buffer 'buf'.
1515  *
1516  * Return value:
1517  *   Pointer to an octet immediately following the ending zero octet
1518  *   of the decoded label, or NULL if an error occured.
1519  */
1520 static const char *
1521 dnsdecode(const u_char *sp, const u_char *ep, const u_char *base, char *buf,
1522 	size_t bufsiz)
1523 {
1524 	int i;
1525 	const u_char *cp;
1526 	char cresult[MAXDNAME + 1];
1527 	const u_char *comp;
1528 	int l;
1529 
1530 	cp = sp;
1531 	*buf = '\0';
1532 
1533 	if (cp >= ep)
1534 		return NULL;
1535 	while (cp < ep) {
1536 		i = *cp;
1537 		if (i == 0 || cp != sp) {
1538 			if (strlcat((char *)buf, ".", bufsiz) >= bufsiz)
1539 				return NULL;	/*result overrun*/
1540 		}
1541 		if (i == 0)
1542 			break;
1543 		cp++;
1544 
1545 		if ((i & 0xc0) == 0xc0 && cp - base > (i & 0x3f)) {
1546 			/* DNS compression */
1547 			if (!base)
1548 				return NULL;
1549 
1550 			comp = base + (i & 0x3f);
1551 			if (dnsdecode(comp, cp, base, cresult,
1552 			    sizeof(cresult)) == NULL)
1553 				return NULL;
1554 			if (strlcat(buf, cresult, bufsiz) >= bufsiz)
1555 				return NULL;	/*result overrun*/
1556 			break;
1557 		} else if ((i & 0x3f) == i) {
1558 			if (i > ep - cp)
1559 				return NULL;	/*source overrun*/
1560 			while (i-- > 0 && cp < ep) {
1561 				l = snprintf(cresult, sizeof(cresult),
1562 				    isprint(*cp) ? "%c" : "\\%03o", *cp & 0xff);
1563 				if ((size_t)l >= sizeof(cresult) || l < 0)
1564 					return NULL;
1565 				if (strlcat(buf, cresult, bufsiz) >= bufsiz)
1566 					return NULL;	/*result overrun*/
1567 				cp++;
1568 			}
1569 		} else
1570 			return NULL;	/*invalid label*/
1571 	}
1572 	if (i != 0)
1573 		return NULL;	/*not terminated*/
1574 	cp++;
1575 	return cp;
1576 }
1577 
1578 /*
1579  * pr_pack --
1580  *	Print out the packet, if it came from us.  This logic is necessary
1581  * because ALL readers of the ICMP socket get a copy of ALL ICMP packets
1582  * which arrive ('tis only fair).  This permits multiple copies of this
1583  * program to be run without having intermingled output (or statistics!).
1584  */
1585 static void
1586 pr_pack(u_char *buf, int cc, struct msghdr *mhdr)
1587 {
1588 #define safeputc(c)	printf((isprint((c)) ? "%c" : "\\%03o"), c)
1589 	struct icmp6_hdr *icp;
1590 	struct icmp6_nodeinfo *ni;
1591 	int i;
1592 	int hoplim;
1593 	struct sockaddr *from;
1594 	int fromlen;
1595 	const u_char *cp = NULL;
1596 	u_char *dp, *end = buf + cc;
1597 	struct in6_pktinfo *pktinfo = NULL;
1598 	struct timespec tv, tp;
1599 	struct tv32 tpp;
1600 	double triptime = 0;
1601 	int dupflag;
1602 	size_t off;
1603 	int oldfqdn;
1604 	u_int16_t seq;
1605 	char dnsname[MAXDNAME + 1];
1606 
1607 	(void)clock_gettime(CLOCK_MONOTONIC, &tv);
1608 
1609 	if (!mhdr || !mhdr->msg_name ||
1610 	    mhdr->msg_namelen != sizeof(struct sockaddr_in6) ||
1611 	    ((struct sockaddr *)mhdr->msg_name)->sa_family != AF_INET6) {
1612 		if (options & F_VERBOSE)
1613 			warnx("invalid peername");
1614 		return;
1615 	}
1616 	from = (struct sockaddr *)mhdr->msg_name;
1617 	fromlen = mhdr->msg_namelen;
1618 	if (cc < (int)sizeof(struct icmp6_hdr)) {
1619 		if (options & F_VERBOSE)
1620 			warnx("packet too short (%d bytes) from %s", cc,
1621 			    pr_addr(from, fromlen));
1622 		return;
1623 	}
1624 	if (((mhdr->msg_flags & MSG_CTRUNC) != 0) &&
1625 	    (options & F_VERBOSE) != 0)
1626 		warnx("some control data discarded, insufficient buffer size");
1627 	icp = (struct icmp6_hdr *)buf;
1628 	ni = (struct icmp6_nodeinfo *)buf;
1629 	off = 0;
1630 
1631 	if ((hoplim = get_hoplim(mhdr)) == -1) {
1632 		warnx("failed to get receiving hop limit");
1633 		return;
1634 	}
1635 	if ((pktinfo = get_rcvpktinfo(mhdr)) == NULL) {
1636 		warnx("failed to get receiving packet information");
1637 		return;
1638 	}
1639 
1640 	if (icp->icmp6_type == ICMP6_ECHO_REPLY && myechoreply(icp)) {
1641 		seq = ntohs(icp->icmp6_seq);
1642 		++nreceived;
1643 		if (timing) {
1644 			memcpy(&tpp, icp + 1, sizeof(tpp));
1645 			tp.tv_sec = ntohl(tpp.tv32_sec);
1646 			tp.tv_nsec = ntohl(tpp.tv32_nsec);
1647 			timespecsub(&tv, &tp, &tv);
1648 			triptime = ((double)tv.tv_sec) * 1000.0 +
1649 			    ((double)tv.tv_nsec) / 1000000.0;
1650 			tsum += triptime;
1651 			tsumsq += triptime * triptime;
1652 			if (triptime < tmin)
1653 				tmin = triptime;
1654 			if (triptime > tmax)
1655 				tmax = triptime;
1656 		}
1657 
1658 		if (TST(seq % mx_dup_ck)) {
1659 			++nrepeats;
1660 			--nreceived;
1661 			dupflag = 1;
1662 		} else {
1663 			SET(seq % mx_dup_ck);
1664 			dupflag = 0;
1665 		}
1666 
1667 		if (options & F_QUIET)
1668 			return;
1669 
1670 		if (options & F_WAITTIME && triptime > waittime) {
1671 			++nrcvtimeout;
1672 			return;
1673 		}
1674 
1675 		if (options & F_DOT)
1676 			(void)write(STDOUT_FILENO, &BSPACE, 1);
1677 		else {
1678 			if (options & F_AUDIBLE)
1679 				(void)write(STDOUT_FILENO, &BBELL, 1);
1680 			(void)printf("%d bytes from %s, icmp_seq=%u", cc,
1681 			    pr_addr(from, fromlen), seq);
1682 			(void)printf(" hlim=%d", hoplim);
1683 			if ((options & F_VERBOSE) != 0) {
1684 				struct sockaddr_in6 dstsa;
1685 
1686 				memset(&dstsa, 0, sizeof(dstsa));
1687 				dstsa.sin6_family = AF_INET6;
1688 				dstsa.sin6_len = sizeof(dstsa);
1689 				dstsa.sin6_scope_id = pktinfo->ipi6_ifindex;
1690 				dstsa.sin6_addr = pktinfo->ipi6_addr;
1691 				(void)printf(" dst=%s",
1692 				    pr_addr((struct sockaddr *)&dstsa,
1693 				    sizeof(dstsa)));
1694 			}
1695 			if (timing)
1696 				(void)printf(" time=%.3f ms", triptime);
1697 			if (dupflag)
1698 				(void)printf("(DUP!)");
1699 			/* check the data */
1700 			cp = buf + off + ICMP6ECHOLEN + ICMP6ECHOTMLEN;
1701 			dp = outpack + ICMP6ECHOLEN + ICMP6ECHOTMLEN;
1702 			for (i = 8; cp < end; ++i, ++cp, ++dp) {
1703 				if (*cp != *dp) {
1704 					(void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x", i, *dp, *cp);
1705 					break;
1706 				}
1707 			}
1708 		}
1709 	} else if (icp->icmp6_type == ICMP6_NI_REPLY && mynireply(ni)) {
1710 		memcpy(&seq, ni->icmp6_ni_nonce, sizeof(seq));
1711 		seq = ntohs(seq);
1712 		++nreceived;
1713 		if (TST(seq % mx_dup_ck)) {
1714 			++nrepeats;
1715 			--nreceived;
1716 			dupflag = 1;
1717 		} else {
1718 			SET(seq % mx_dup_ck);
1719 			dupflag = 0;
1720 		}
1721 
1722 		if (options & F_QUIET)
1723 			return;
1724 
1725 		(void)printf("%d bytes from %s: ", cc, pr_addr(from, fromlen));
1726 
1727 		switch (ntohs(ni->ni_code)) {
1728 		case ICMP6_NI_SUCCESS:
1729 			break;
1730 		case ICMP6_NI_REFUSED:
1731 			printf("refused, type 0x%x", ntohs(ni->ni_type));
1732 			goto fqdnend;
1733 		case ICMP6_NI_UNKNOWN:
1734 			printf("unknown, type 0x%x", ntohs(ni->ni_type));
1735 			goto fqdnend;
1736 		default:
1737 			printf("unknown code 0x%x, type 0x%x",
1738 			    ntohs(ni->ni_code), ntohs(ni->ni_type));
1739 			goto fqdnend;
1740 		}
1741 
1742 		switch (ntohs(ni->ni_qtype)) {
1743 		case NI_QTYPE_NOOP:
1744 			printf("NodeInfo NOOP");
1745 			break;
1746 		case NI_QTYPE_SUPTYPES:
1747 			pr_suptypes(ni, end - (u_char *)ni);
1748 			break;
1749 		case NI_QTYPE_NODEADDR:
1750 			pr_nodeaddr(ni, end - (u_char *)ni);
1751 			break;
1752 		case NI_QTYPE_FQDN:
1753 		default:	/* XXX: for backward compatibility */
1754 			cp = (u_char *)ni + ICMP6_NIRLEN;
1755 			if (buf[off + ICMP6_NIRLEN] ==
1756 			    cc - off - ICMP6_NIRLEN - 1)
1757 				oldfqdn = 1;
1758 			else
1759 				oldfqdn = 0;
1760 			if (oldfqdn) {
1761 				cp++;	/* skip length */
1762 				while (cp < end) {
1763 					safeputc(*cp & 0xff);
1764 					cp++;
1765 				}
1766 			} else {
1767 				i = 0;
1768 				while (cp < end) {
1769 					cp = dnsdecode((const u_char *)cp, end,
1770 					    (const u_char *)(ni + 1), dnsname,
1771 					    sizeof(dnsname));
1772 					if (cp == NULL) {
1773 						printf("???");
1774 						break;
1775 					}
1776 					/*
1777 					 * name-lookup special handling for
1778 					 * truncated name
1779 					 */
1780 					if (cp + 1 <= end && !*cp &&
1781 					    strlen(dnsname) > 0) {
1782 						dnsname[strlen(dnsname) - 1] = '\0';
1783 						cp++;
1784 					}
1785 					printf("%s%s", i > 0 ? "," : "",
1786 					    dnsname);
1787 				}
1788 			}
1789 			if (options & F_VERBOSE) {
1790 				u_long t;
1791 				int32_t ttl;
1792 				int comma = 0;
1793 
1794 				(void)printf(" (");	/*)*/
1795 
1796 				switch (ni->ni_code) {
1797 				case ICMP6_NI_REFUSED:
1798 					(void)printf("refused");
1799 					comma++;
1800 					break;
1801 				case ICMP6_NI_UNKNOWN:
1802 					(void)printf("unknown qtype");
1803 					comma++;
1804 					break;
1805 				}
1806 
1807 				if ((end - (u_char *)ni) < ICMP6_NIRLEN) {
1808 					/* case of refusion, unknown */
1809 					/*(*/
1810 					putchar(')');
1811 					goto fqdnend;
1812 				}
1813 				memcpy(&t, &buf[off+ICMP6ECHOLEN+8], sizeof(t));
1814 				ttl = (int32_t)ntohl(t);
1815 				if (comma)
1816 					printf(",");
1817 				if (!(ni->ni_flags & NI_FQDN_FLAG_VALIDTTL)) {
1818 					(void)printf("TTL=%d:meaningless",
1819 					    (int)ttl);
1820 				} else {
1821 					if (ttl < 0) {
1822 						(void)printf("TTL=%d:invalid",
1823 						   ttl);
1824 					} else
1825 						(void)printf("TTL=%d", ttl);
1826 				}
1827 				comma++;
1828 
1829 				if (oldfqdn) {
1830 					if (comma)
1831 						printf(",");
1832 					printf("03 draft");
1833 					comma++;
1834 				} else {
1835 					cp = (u_char *)ni + ICMP6_NIRLEN;
1836 					if (cp == end) {
1837 						if (comma)
1838 							printf(",");
1839 						printf("no name");
1840 						comma++;
1841 					}
1842 				}
1843 
1844 				if (buf[off + ICMP6_NIRLEN] !=
1845 				    cc - off - ICMP6_NIRLEN - 1 && oldfqdn) {
1846 					if (comma)
1847 						printf(",");
1848 					(void)printf("invalid namelen:%d/%lu",
1849 					    buf[off + ICMP6_NIRLEN],
1850 					    (u_long)cc - off - ICMP6_NIRLEN - 1);
1851 					comma++;
1852 				}
1853 				/*(*/
1854 				putchar(')');
1855 			}
1856 		fqdnend:
1857 			;
1858 		}
1859 	} else {
1860 		/* We've got something other than an ECHOREPLY */
1861 		if (!(options & F_VERBOSE))
1862 			return;
1863 		(void)printf("%d bytes from %s: ", cc, pr_addr(from, fromlen));
1864 		pr_icmph(icp, end);
1865 	}
1866 
1867 	if (!(options & F_DOT)) {
1868 		(void)putchar('\n');
1869 		if (options & F_VERBOSE)
1870 			pr_exthdrs(mhdr);
1871 		(void)fflush(stdout);
1872 	}
1873 #undef safeputc
1874 }
1875 
1876 static void
1877 pr_exthdrs(struct msghdr *mhdr)
1878 {
1879 	ssize_t	bufsize;
1880 	void	*bufp;
1881 	struct cmsghdr *cm;
1882 
1883 	bufsize = 0;
1884 	bufp = mhdr->msg_control;
1885 	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1886 	     cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1887 		if (cm->cmsg_level != IPPROTO_IPV6)
1888 			continue;
1889 
1890 		bufsize = CONTROLLEN - ((caddr_t)CMSG_DATA(cm) - (caddr_t)bufp);
1891 		if (bufsize <= 0)
1892 			continue;
1893 		switch (cm->cmsg_type) {
1894 		case IPV6_HOPOPTS:
1895 			printf("  HbH Options: ");
1896 			pr_ip6opt(CMSG_DATA(cm), (size_t)bufsize);
1897 			break;
1898 		case IPV6_DSTOPTS:
1899 #ifdef IPV6_RTHDRDSTOPTS
1900 		case IPV6_RTHDRDSTOPTS:
1901 #endif
1902 			printf("  Dst Options: ");
1903 			pr_ip6opt(CMSG_DATA(cm), (size_t)bufsize);
1904 			break;
1905 		case IPV6_RTHDR:
1906 			printf("  Routing: ");
1907 			pr_rthdr(CMSG_DATA(cm), (size_t)bufsize);
1908 			break;
1909 		}
1910 	}
1911 }
1912 
1913 static void
1914 pr_ip6opt(void *extbuf, size_t bufsize)
1915 {
1916 	struct ip6_hbh *ext;
1917 	int currentlen;
1918 	u_int8_t type;
1919 	socklen_t extlen, len;
1920 	void *databuf;
1921 	size_t offset;
1922 	u_int16_t value2;
1923 	u_int32_t value4;
1924 
1925 	ext = (struct ip6_hbh *)extbuf;
1926 	extlen = (ext->ip6h_len + 1) * 8;
1927 	printf("nxt %u, len %u (%lu bytes)\n", ext->ip6h_nxt,
1928 	    (unsigned int)ext->ip6h_len, (unsigned long)extlen);
1929 
1930 	/*
1931 	 * Bounds checking on the ancillary data buffer:
1932 	 *     subtract the size of a cmsg structure from the buffer size.
1933 	 */
1934 	if (bufsize < (extlen  + CMSG_SPACE(0))) {
1935 		extlen = bufsize - CMSG_SPACE(0);
1936 		warnx("options truncated, showing only %u (total=%u)",
1937 		    (unsigned int)(extlen / 8 - 1),
1938 		    (unsigned int)(ext->ip6h_len));
1939 	}
1940 
1941 	currentlen = 0;
1942 	while (1) {
1943 		currentlen = inet6_opt_next(extbuf, extlen, currentlen,
1944 		    &type, &len, &databuf);
1945 		if (currentlen == -1)
1946 			break;
1947 		switch (type) {
1948 		/*
1949 		 * Note that inet6_opt_next automatically skips any padding
1950 		 * optins.
1951 		 */
1952 		case IP6OPT_JUMBO:
1953 			offset = 0;
1954 			offset = inet6_opt_get_val(databuf, offset,
1955 			    &value4, sizeof(value4));
1956 			printf("    Jumbo Payload Opt: Length %u\n",
1957 			    (u_int32_t)ntohl(value4));
1958 			break;
1959 		case IP6OPT_ROUTER_ALERT:
1960 			offset = 0;
1961 			offset = inet6_opt_get_val(databuf, offset,
1962 						   &value2, sizeof(value2));
1963 			printf("    Router Alert Opt: Type %u\n",
1964 			    ntohs(value2));
1965 			break;
1966 		default:
1967 			printf("    Received Opt %u len %lu\n",
1968 			    type, (unsigned long)len);
1969 			break;
1970 		}
1971 	}
1972 	return;
1973 }
1974 
1975 static void
1976 pr_rthdr(void *extbuf, size_t bufsize)
1977 {
1978 	struct in6_addr *in6;
1979 	char ntopbuf[INET6_ADDRSTRLEN];
1980 	struct ip6_rthdr *rh = (struct ip6_rthdr *)extbuf;
1981 	int i, segments, origsegs, rthsize, size0, size1;
1982 
1983 	/* print fixed part of the header */
1984 	printf("nxt %u, len %u (%d bytes), type %u, ", rh->ip6r_nxt,
1985 	    rh->ip6r_len, (rh->ip6r_len + 1) << 3, rh->ip6r_type);
1986 	if ((segments = inet6_rth_segments(extbuf)) >= 0) {
1987 		printf("%d segments, ", segments);
1988 		printf("%d left\n", rh->ip6r_segleft);
1989 	} else {
1990 		printf("segments unknown, ");
1991 		printf("%d left\n", rh->ip6r_segleft);
1992 		return;
1993 	}
1994 
1995 	/*
1996 	 * Bounds checking on the ancillary data buffer. When calculating
1997 	 * the number of items to show keep in mind:
1998 	 *	- The size of the cmsg structure
1999 	 *	- The size of one segment (the size of a Type 0 routing header)
2000 	 *	- When dividing add a fudge factor of one in case the
2001 	 *	  dividend is not evenly divisible by the divisor
2002 	 */
2003 	rthsize = (rh->ip6r_len + 1) * 8;
2004 	if (bufsize < (rthsize + CMSG_SPACE(0))) {
2005 		origsegs = segments;
2006 		size0 = inet6_rth_space(IPV6_RTHDR_TYPE_0, 0);
2007 		size1 = inet6_rth_space(IPV6_RTHDR_TYPE_0, 1);
2008 		segments -= (rthsize - (bufsize - CMSG_SPACE(0))) /
2009 		    (size1 - size0) + 1;
2010 		warnx("segments truncated, showing only %d (total=%d)",
2011 		    segments, origsegs);
2012 	}
2013 
2014 	for (i = 0; i < segments; i++) {
2015 		in6 = inet6_rth_getaddr(extbuf, i);
2016 		if (in6 == NULL)
2017 			printf("   [%d]<NULL>\n", i);
2018 		else {
2019 			if (!inet_ntop(AF_INET6, in6, ntopbuf,
2020 			    sizeof(ntopbuf)))
2021 				strlcpy(ntopbuf, "?", sizeof(ntopbuf));
2022 			printf("   [%d]%s\n", i, ntopbuf);
2023 		}
2024 	}
2025 
2026 	return;
2027 
2028 }
2029 
2030 static int
2031 pr_bitrange(u_int32_t v, int soff, int ii)
2032 {
2033 	int off;
2034 	int i;
2035 
2036 	off = 0;
2037 	while (off < 32) {
2038 		/* shift till we have 0x01 */
2039 		if ((v & 0x01) == 0) {
2040 			if (ii > 1)
2041 				printf("-%u", soff + off - 1);
2042 			ii = 0;
2043 			switch (v & 0x0f) {
2044 			case 0x00:
2045 				v >>= 4;
2046 				off += 4;
2047 				continue;
2048 			case 0x08:
2049 				v >>= 3;
2050 				off += 3;
2051 				continue;
2052 			case 0x04: case 0x0c:
2053 				v >>= 2;
2054 				off += 2;
2055 				continue;
2056 			default:
2057 				v >>= 1;
2058 				off += 1;
2059 				continue;
2060 			}
2061 		}
2062 
2063 		/* we have 0x01 with us */
2064 		for (i = 0; i < 32 - off; i++) {
2065 			if ((v & (0x01 << i)) == 0)
2066 				break;
2067 		}
2068 		if (!ii)
2069 			printf(" %u", soff + off);
2070 		ii += i;
2071 		v >>= i; off += i;
2072 	}
2073 	return ii;
2074 }
2075 
2076 static void
2077 pr_suptypes(struct icmp6_nodeinfo *ni, size_t nilen)
2078 	/* ni->qtype must be SUPTYPES */
2079 {
2080 	size_t clen;
2081 	u_int32_t v;
2082 	const u_char *cp, *end;
2083 	u_int16_t cur;
2084 	struct cbit {
2085 		u_int16_t words;	/*32bit count*/
2086 		u_int16_t skip;
2087 	} cbit;
2088 #define MAXQTYPES	(1 << 16)
2089 	size_t off;
2090 	int b;
2091 
2092 	cp = (u_char *)(ni + 1);
2093 	end = ((u_char *)ni) + nilen;
2094 	cur = 0;
2095 	b = 0;
2096 
2097 	printf("NodeInfo Supported Qtypes");
2098 	if (options & F_VERBOSE) {
2099 		if (ni->ni_flags & NI_SUPTYPE_FLAG_COMPRESS)
2100 			printf(", compressed bitmap");
2101 		else
2102 			printf(", raw bitmap");
2103 	}
2104 
2105 	while (cp < end) {
2106 		clen = (size_t)(end - cp);
2107 		if ((ni->ni_flags & NI_SUPTYPE_FLAG_COMPRESS) == 0) {
2108 			if (clen == 0 || clen > MAXQTYPES / 8 ||
2109 			    clen % sizeof(v)) {
2110 				printf("???");
2111 				return;
2112 			}
2113 		} else {
2114 			if (clen < sizeof(cbit) || clen % sizeof(v))
2115 				return;
2116 			memcpy(&cbit, cp, sizeof(cbit));
2117 			if (sizeof(cbit) + ntohs(cbit.words) * sizeof(v) >
2118 			    clen)
2119 				return;
2120 			cp += sizeof(cbit);
2121 			clen = ntohs(cbit.words) * sizeof(v);
2122 			if (cur + clen * 8 + (u_long)ntohs(cbit.skip) * 32 >
2123 			    MAXQTYPES)
2124 				return;
2125 		}
2126 
2127 		for (off = 0; off < clen; off += sizeof(v)) {
2128 			memcpy(&v, cp + off, sizeof(v));
2129 			v = (u_int32_t)ntohl(v);
2130 			b = pr_bitrange(v, (int)(cur + off * 8), b);
2131 		}
2132 		/* flush the remaining bits */
2133 		b = pr_bitrange(0, (int)(cur + off * 8), b);
2134 
2135 		cp += clen;
2136 		cur += clen * 8;
2137 		if ((ni->ni_flags & NI_SUPTYPE_FLAG_COMPRESS) != 0)
2138 			cur += ntohs(cbit.skip) * 32;
2139 	}
2140 }
2141 
2142 static void
2143 pr_nodeaddr(struct icmp6_nodeinfo *ni, int nilen)
2144 	/* ni->qtype must be NODEADDR */
2145 {
2146 	u_char *cp = (u_char *)(ni + 1);
2147 	char ntop_buf[INET6_ADDRSTRLEN];
2148 	int withttl = 0;
2149 
2150 	nilen -= sizeof(struct icmp6_nodeinfo);
2151 
2152 	if (options & F_VERBOSE) {
2153 		switch (ni->ni_code) {
2154 		case ICMP6_NI_REFUSED:
2155 			(void)printf("refused");
2156 			break;
2157 		case ICMP6_NI_UNKNOWN:
2158 			(void)printf("unknown qtype");
2159 			break;
2160 		}
2161 		if (ni->ni_flags & NI_NODEADDR_FLAG_TRUNCATE)
2162 			(void)printf(" truncated");
2163 	}
2164 	putchar('\n');
2165 	if (nilen <= 0)
2166 		printf("  no address\n");
2167 
2168 	/*
2169 	 * In icmp-name-lookups 05 and later, TTL of each returned address
2170 	 * is contained in the resposne. We try to detect the version
2171 	 * by the length of the data, but note that the detection algorithm
2172 	 * is incomplete. We assume the latest draft by default.
2173 	 */
2174 	if (nilen % (sizeof(u_int32_t) + sizeof(struct in6_addr)) == 0)
2175 		withttl = 1;
2176 	while (nilen > 0) {
2177 		u_int32_t ttl = 0;
2178 
2179 		if (withttl) {
2180 			uint32_t t;
2181 
2182 			memcpy(&t, cp, sizeof(t));
2183 			ttl = (u_int32_t)ntohl(t);
2184 			cp += sizeof(u_int32_t);
2185 			nilen -= sizeof(u_int32_t);
2186 		}
2187 
2188 		if (inet_ntop(AF_INET6, cp, ntop_buf, sizeof(ntop_buf)) ==
2189 		    NULL)
2190 			strlcpy(ntop_buf, "?", sizeof(ntop_buf));
2191 		printf("  %s", ntop_buf);
2192 		if (withttl) {
2193 			if (ttl == 0xffffffff) {
2194 				/*
2195 				 * XXX: can this convention be applied to all
2196 				 * type of TTL (i.e. non-ND TTL)?
2197 				 */
2198 				printf("(TTL=infty)");
2199 			}
2200 			else
2201 				printf("(TTL=%u)", ttl);
2202 		}
2203 		putchar('\n');
2204 
2205 		nilen -= sizeof(struct in6_addr);
2206 		cp += sizeof(struct in6_addr);
2207 	}
2208 }
2209 
2210 static int
2211 get_hoplim(struct msghdr *mhdr)
2212 {
2213 	struct cmsghdr *cm;
2214 
2215 	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
2216 	     cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
2217 		if (cm->cmsg_len == 0)
2218 			return(-1);
2219 
2220 		if (cm->cmsg_level == IPPROTO_IPV6 &&
2221 		    cm->cmsg_type == IPV6_HOPLIMIT &&
2222 		    cm->cmsg_len == CMSG_LEN(sizeof(int))) {
2223 			int r;
2224 
2225 			memcpy(&r, CMSG_DATA(cm), sizeof(r));
2226 			return(r);
2227 		}
2228 	}
2229 
2230 	return(-1);
2231 }
2232 
2233 static struct in6_pktinfo *
2234 get_rcvpktinfo(struct msghdr *mhdr)
2235 {
2236 	static struct in6_pktinfo pi;
2237 	struct cmsghdr *cm;
2238 
2239 	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
2240 	     cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
2241 		if (cm->cmsg_len == 0)
2242 			return(NULL);
2243 
2244 		if (cm->cmsg_level == IPPROTO_IPV6 &&
2245 		    cm->cmsg_type == IPV6_PKTINFO &&
2246 		    cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo))) {
2247 			memcpy(&pi, CMSG_DATA(cm), sizeof(pi));
2248 			return(&pi);
2249 		}
2250 	}
2251 
2252 	return(NULL);
2253 }
2254 
2255 static int
2256 get_pathmtu(struct msghdr *mhdr)
2257 {
2258 #ifdef IPV6_RECVPATHMTU
2259 	struct cmsghdr *cm;
2260 	struct ip6_mtuinfo mtuctl;
2261 
2262 	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
2263 	     cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
2264 		if (cm->cmsg_len == 0)
2265 			return(0);
2266 
2267 		if (cm->cmsg_level == IPPROTO_IPV6 &&
2268 		    cm->cmsg_type == IPV6_PATHMTU &&
2269 		    cm->cmsg_len == CMSG_LEN(sizeof(struct ip6_mtuinfo))) {
2270 			memcpy(&mtuctl, CMSG_DATA(cm), sizeof(mtuctl));
2271 
2272 			/*
2273 			 * If the notified destination is different from
2274 			 * the one we are pinging, just ignore the info.
2275 			 * We check the scope ID only when both notified value
2276 			 * and our own value have non-0 values, because we may
2277 			 * have used the default scope zone ID for sending,
2278 			 * in which case the scope ID value is 0.
2279 			 */
2280 			if (!IN6_ARE_ADDR_EQUAL(&mtuctl.ip6m_addr.sin6_addr,
2281 						&dst.sin6_addr) ||
2282 			    (mtuctl.ip6m_addr.sin6_scope_id &&
2283 			     dst.sin6_scope_id &&
2284 			     mtuctl.ip6m_addr.sin6_scope_id !=
2285 			     dst.sin6_scope_id)) {
2286 				if ((options & F_VERBOSE) != 0) {
2287 					printf("path MTU for %s is notified. "
2288 					       "(ignored)\n",
2289 					   pr_addr((struct sockaddr *)&mtuctl.ip6m_addr,
2290 					   sizeof(mtuctl.ip6m_addr)));
2291 				}
2292 				return(0);
2293 			}
2294 
2295 			/*
2296 			 * Ignore an invalid MTU. XXX: can we just believe
2297 			 * the kernel check?
2298 			 */
2299 			if (mtuctl.ip6m_mtu < IPV6_MMTU)
2300 				return(0);
2301 
2302 			/* notification for our destination. return the MTU. */
2303 			return((int)mtuctl.ip6m_mtu);
2304 		}
2305 	}
2306 #endif
2307 	return(0);
2308 }
2309 
2310 /*
2311  * onint --
2312  *	SIGINT handler.
2313  */
2314 /* ARGSUSED */
2315 static void
2316 onint(int notused __unused)
2317 {
2318 	/*
2319 	 * When doing reverse DNS lookups, the seenint flag might not
2320 	 * be noticed for a while.  Just exit if we get a second SIGINT.
2321 	 */
2322 	if ((options & F_HOSTNAME) && seenint != 0)
2323 		_exit(nreceived ? 0 : 2);
2324 }
2325 
2326 /*
2327  * summary --
2328  *	Print out statistics.
2329  */
2330 static void
2331 summary(void)
2332 {
2333 
2334 	(void)printf("\n--- %s ping6 statistics ---\n", hostname);
2335 	(void)printf("%ld packets transmitted, ", ntransmitted);
2336 	(void)printf("%ld packets received, ", nreceived);
2337 	if (nrepeats)
2338 		(void)printf("+%ld duplicates, ", nrepeats);
2339 	if (ntransmitted) {
2340 		if (nreceived > ntransmitted)
2341 			(void)printf("-- somebody's duplicating packets!");
2342 		else
2343 			(void)printf("%.1f%% packet loss",
2344 			    ((((double)ntransmitted - nreceived) * 100.0) /
2345 			    ntransmitted));
2346 	}
2347 	if (nrcvtimeout)
2348 		printf(", %ld packets out of wait time", nrcvtimeout);
2349 	(void)putchar('\n');
2350 	if (nreceived && timing) {
2351 		/* Only display average to microseconds */
2352 		double num = nreceived + nrepeats;
2353 		double avg = tsum / num;
2354 		double dev = sqrt(tsumsq / num - avg * avg);
2355 		(void)printf(
2356 		    "round-trip min/avg/max/std-dev = %.3f/%.3f/%.3f/%.3f ms\n",
2357 		    tmin, avg, tmax, dev);
2358 		(void)fflush(stdout);
2359 	}
2360 	(void)fflush(stdout);
2361 }
2362 
2363 /*subject type*/
2364 static const char *niqcode[] = {
2365 	"IPv6 address",
2366 	"DNS label",	/*or empty*/
2367 	"IPv4 address",
2368 };
2369 
2370 /*result code*/
2371 static const char *nircode[] = {
2372 	"Success", "Refused", "Unknown",
2373 };
2374 
2375 
2376 /*
2377  * pr_icmph --
2378  *	Print a descriptive string about an ICMP header.
2379  */
2380 static void
2381 pr_icmph(struct icmp6_hdr *icp, u_char *end)
2382 {
2383 	char ntop_buf[INET6_ADDRSTRLEN];
2384 	struct nd_redirect *red;
2385 	struct icmp6_nodeinfo *ni;
2386 	char dnsname[MAXDNAME + 1];
2387 	const u_char *cp;
2388 	size_t l;
2389 
2390 	switch (icp->icmp6_type) {
2391 	case ICMP6_DST_UNREACH:
2392 		switch (icp->icmp6_code) {
2393 		case ICMP6_DST_UNREACH_NOROUTE:
2394 			(void)printf("No Route to Destination\n");
2395 			break;
2396 		case ICMP6_DST_UNREACH_ADMIN:
2397 			(void)printf("Destination Administratively "
2398 			    "Unreachable\n");
2399 			break;
2400 		case ICMP6_DST_UNREACH_BEYONDSCOPE:
2401 			(void)printf("Destination Unreachable Beyond Scope\n");
2402 			break;
2403 		case ICMP6_DST_UNREACH_ADDR:
2404 			(void)printf("Destination Host Unreachable\n");
2405 			break;
2406 		case ICMP6_DST_UNREACH_NOPORT:
2407 			(void)printf("Destination Port Unreachable\n");
2408 			break;
2409 		default:
2410 			(void)printf("Destination Unreachable, Bad Code: %d\n",
2411 			    icp->icmp6_code);
2412 			break;
2413 		}
2414 		/* Print returned IP header information */
2415 		pr_retip((struct ip6_hdr *)(icp + 1), end);
2416 		break;
2417 	case ICMP6_PACKET_TOO_BIG:
2418 		(void)printf("Packet too big mtu = %d\n",
2419 		    (int)ntohl(icp->icmp6_mtu));
2420 		pr_retip((struct ip6_hdr *)(icp + 1), end);
2421 		break;
2422 	case ICMP6_TIME_EXCEEDED:
2423 		switch (icp->icmp6_code) {
2424 		case ICMP6_TIME_EXCEED_TRANSIT:
2425 			(void)printf("Time to live exceeded\n");
2426 			break;
2427 		case ICMP6_TIME_EXCEED_REASSEMBLY:
2428 			(void)printf("Frag reassembly time exceeded\n");
2429 			break;
2430 		default:
2431 			(void)printf("Time exceeded, Bad Code: %d\n",
2432 			    icp->icmp6_code);
2433 			break;
2434 		}
2435 		pr_retip((struct ip6_hdr *)(icp + 1), end);
2436 		break;
2437 	case ICMP6_PARAM_PROB:
2438 		(void)printf("Parameter problem: ");
2439 		switch (icp->icmp6_code) {
2440 		case ICMP6_PARAMPROB_HEADER:
2441 			(void)printf("Erroneous Header ");
2442 			break;
2443 		case ICMP6_PARAMPROB_NEXTHEADER:
2444 			(void)printf("Unknown Nextheader ");
2445 			break;
2446 		case ICMP6_PARAMPROB_OPTION:
2447 			(void)printf("Unrecognized Option ");
2448 			break;
2449 		default:
2450 			(void)printf("Bad code(%d) ", icp->icmp6_code);
2451 			break;
2452 		}
2453 		(void)printf("pointer = 0x%02x\n",
2454 		    (u_int32_t)ntohl(icp->icmp6_pptr));
2455 		pr_retip((struct ip6_hdr *)(icp + 1), end);
2456 		break;
2457 	case ICMP6_ECHO_REQUEST:
2458 		(void)printf("Echo Request");
2459 		/* XXX ID + Seq + Data */
2460 		break;
2461 	case ICMP6_ECHO_REPLY:
2462 		(void)printf("Echo Reply");
2463 		/* XXX ID + Seq + Data */
2464 		break;
2465 	case ICMP6_MEMBERSHIP_QUERY:
2466 		(void)printf("Listener Query");
2467 		break;
2468 	case ICMP6_MEMBERSHIP_REPORT:
2469 		(void)printf("Listener Report");
2470 		break;
2471 	case ICMP6_MEMBERSHIP_REDUCTION:
2472 		(void)printf("Listener Done");
2473 		break;
2474 	case ND_ROUTER_SOLICIT:
2475 		(void)printf("Router Solicitation");
2476 		break;
2477 	case ND_ROUTER_ADVERT:
2478 		(void)printf("Router Advertisement");
2479 		break;
2480 	case ND_NEIGHBOR_SOLICIT:
2481 		(void)printf("Neighbor Solicitation");
2482 		break;
2483 	case ND_NEIGHBOR_ADVERT:
2484 		(void)printf("Neighbor Advertisement");
2485 		break;
2486 	case ND_REDIRECT:
2487 		red = (struct nd_redirect *)icp;
2488 		(void)printf("Redirect\n");
2489 		if (!inet_ntop(AF_INET6, &red->nd_rd_dst, ntop_buf,
2490 		    sizeof(ntop_buf)))
2491 			strlcpy(ntop_buf, "?", sizeof(ntop_buf));
2492 		(void)printf("Destination: %s", ntop_buf);
2493 		if (!inet_ntop(AF_INET6, &red->nd_rd_target, ntop_buf,
2494 		    sizeof(ntop_buf)))
2495 			strlcpy(ntop_buf, "?", sizeof(ntop_buf));
2496 		(void)printf(" New Target: %s", ntop_buf);
2497 		break;
2498 	case ICMP6_NI_QUERY:
2499 		(void)printf("Node Information Query");
2500 		/* XXX ID + Seq + Data */
2501 		ni = (struct icmp6_nodeinfo *)icp;
2502 		l = end - (u_char *)(ni + 1);
2503 		printf(", ");
2504 		switch (ntohs(ni->ni_qtype)) {
2505 		case NI_QTYPE_NOOP:
2506 			(void)printf("NOOP");
2507 			break;
2508 		case NI_QTYPE_SUPTYPES:
2509 			(void)printf("Supported qtypes");
2510 			break;
2511 		case NI_QTYPE_FQDN:
2512 			(void)printf("DNS name");
2513 			break;
2514 		case NI_QTYPE_NODEADDR:
2515 			(void)printf("nodeaddr");
2516 			break;
2517 		case NI_QTYPE_IPV4ADDR:
2518 			(void)printf("IPv4 nodeaddr");
2519 			break;
2520 		default:
2521 			(void)printf("unknown qtype");
2522 			break;
2523 		}
2524 		if (options & F_VERBOSE) {
2525 			switch (ni->ni_code) {
2526 			case ICMP6_NI_SUBJ_IPV6:
2527 				if (l == sizeof(struct in6_addr) &&
2528 				    inet_ntop(AF_INET6, ni + 1, ntop_buf,
2529 				    sizeof(ntop_buf)) != NULL) {
2530 					(void)printf(", subject=%s(%s)",
2531 					    niqcode[ni->ni_code], ntop_buf);
2532 				} else {
2533 #if 1
2534 					/* backward compat to -W */
2535 					(void)printf(", oldfqdn");
2536 #else
2537 					(void)printf(", invalid");
2538 #endif
2539 				}
2540 				break;
2541 			case ICMP6_NI_SUBJ_FQDN:
2542 				if (end == (u_char *)(ni + 1)) {
2543 					(void)printf(", no subject");
2544 					break;
2545 				}
2546 				printf(", subject=%s", niqcode[ni->ni_code]);
2547 				cp = (const u_char *)(ni + 1);
2548 				cp = dnsdecode(cp, end, NULL, dnsname,
2549 				    sizeof(dnsname));
2550 				if (cp != NULL)
2551 					printf("(%s)", dnsname);
2552 				else
2553 					printf("(invalid)");
2554 				break;
2555 			case ICMP6_NI_SUBJ_IPV4:
2556 				if (l == sizeof(struct in_addr) &&
2557 				    inet_ntop(AF_INET, ni + 1, ntop_buf,
2558 				    sizeof(ntop_buf)) != NULL) {
2559 					(void)printf(", subject=%s(%s)",
2560 					    niqcode[ni->ni_code], ntop_buf);
2561 				} else
2562 					(void)printf(", invalid");
2563 				break;
2564 			default:
2565 				(void)printf(", invalid");
2566 				break;
2567 			}
2568 		}
2569 		break;
2570 	case ICMP6_NI_REPLY:
2571 		(void)printf("Node Information Reply");
2572 		/* XXX ID + Seq + Data */
2573 		ni = (struct icmp6_nodeinfo *)icp;
2574 		printf(", ");
2575 		switch (ntohs(ni->ni_qtype)) {
2576 		case NI_QTYPE_NOOP:
2577 			(void)printf("NOOP");
2578 			break;
2579 		case NI_QTYPE_SUPTYPES:
2580 			(void)printf("Supported qtypes");
2581 			break;
2582 		case NI_QTYPE_FQDN:
2583 			(void)printf("DNS name");
2584 			break;
2585 		case NI_QTYPE_NODEADDR:
2586 			(void)printf("nodeaddr");
2587 			break;
2588 		case NI_QTYPE_IPV4ADDR:
2589 			(void)printf("IPv4 nodeaddr");
2590 			break;
2591 		default:
2592 			(void)printf("unknown qtype");
2593 			break;
2594 		}
2595 		if (options & F_VERBOSE) {
2596 			if (ni->ni_code > nitems(nircode))
2597 				printf(", invalid");
2598 			else
2599 				printf(", %s", nircode[ni->ni_code]);
2600 		}
2601 		break;
2602 	default:
2603 		(void)printf("Bad ICMP type: %d", icp->icmp6_type);
2604 	}
2605 }
2606 
2607 /*
2608  * pr_iph --
2609  *	Print an IP6 header.
2610  */
2611 static void
2612 pr_iph(struct ip6_hdr *ip6)
2613 {
2614 	u_int32_t flow = ip6->ip6_flow & IPV6_FLOWLABEL_MASK;
2615 	u_int8_t tc;
2616 	char ntop_buf[INET6_ADDRSTRLEN];
2617 
2618 	tc = *(&ip6->ip6_vfc + 1); /* XXX */
2619 	tc = (tc >> 4) & 0x0f;
2620 	tc |= (ip6->ip6_vfc << 4);
2621 
2622 	printf("Vr TC  Flow Plen Nxt Hlim\n");
2623 	printf(" %1x %02x %05x %04x  %02x   %02x\n",
2624 	    (ip6->ip6_vfc & IPV6_VERSION_MASK) >> 4, tc, (u_int32_t)ntohl(flow),
2625 	    ntohs(ip6->ip6_plen), ip6->ip6_nxt, ip6->ip6_hlim);
2626 	if (!inet_ntop(AF_INET6, &ip6->ip6_src, ntop_buf, sizeof(ntop_buf)))
2627 		strlcpy(ntop_buf, "?", sizeof(ntop_buf));
2628 	printf("%s->", ntop_buf);
2629 	if (!inet_ntop(AF_INET6, &ip6->ip6_dst, ntop_buf, sizeof(ntop_buf)))
2630 		strlcpy(ntop_buf, "?", sizeof(ntop_buf));
2631 	printf("%s\n", ntop_buf);
2632 }
2633 
2634 /*
2635  * pr_addr --
2636  *	Return an ascii host address as a dotted quad and optionally with
2637  * a hostname.
2638  */
2639 static const char *
2640 pr_addr(struct sockaddr *addr, int addrlen)
2641 {
2642 	static char buf[NI_MAXHOST];
2643 	int flag = 0;
2644 
2645 	if ((options & F_HOSTNAME) == 0)
2646 		flag |= NI_NUMERICHOST;
2647 
2648 	if (cap_getnameinfo(capdns, addr, addrlen, buf, sizeof(buf), NULL, 0,
2649 		flag) == 0)
2650 		return (buf);
2651 	else
2652 		return "?";
2653 }
2654 
2655 /*
2656  * pr_retip --
2657  *	Dump some info on a returned (via ICMPv6) IPv6 packet.
2658  */
2659 static void
2660 pr_retip(struct ip6_hdr *ip6, u_char *end)
2661 {
2662 	u_char *cp = (u_char *)ip6, nh;
2663 	int hlen;
2664 
2665 	if ((size_t)(end - (u_char *)ip6) < sizeof(*ip6)) {
2666 		printf("IP6");
2667 		goto trunc;
2668 	}
2669 	pr_iph(ip6);
2670 	hlen = sizeof(*ip6);
2671 
2672 	nh = ip6->ip6_nxt;
2673 	cp += hlen;
2674 	while (end - cp >= 8) {
2675 #ifdef IPSEC
2676 		struct ah ah;
2677 #endif
2678 
2679 		switch (nh) {
2680 		case IPPROTO_HOPOPTS:
2681 			printf("HBH ");
2682 			hlen = (((struct ip6_hbh *)cp)->ip6h_len+1) << 3;
2683 			nh = ((struct ip6_hbh *)cp)->ip6h_nxt;
2684 			break;
2685 		case IPPROTO_DSTOPTS:
2686 			printf("DSTOPT ");
2687 			hlen = (((struct ip6_dest *)cp)->ip6d_len+1) << 3;
2688 			nh = ((struct ip6_dest *)cp)->ip6d_nxt;
2689 			break;
2690 		case IPPROTO_FRAGMENT:
2691 			printf("FRAG ");
2692 			hlen = sizeof(struct ip6_frag);
2693 			nh = ((struct ip6_frag *)cp)->ip6f_nxt;
2694 			break;
2695 		case IPPROTO_ROUTING:
2696 			printf("RTHDR ");
2697 			hlen = (((struct ip6_rthdr *)cp)->ip6r_len+1) << 3;
2698 			nh = ((struct ip6_rthdr *)cp)->ip6r_nxt;
2699 			break;
2700 #ifdef IPSEC
2701 		case IPPROTO_AH:
2702 			printf("AH ");
2703 			memcpy(&ah, cp, sizeof(ah));
2704 			hlen = (ah.ah_len+2) << 2;
2705 			nh = ah.ah_nxt;
2706 			break;
2707 #endif
2708 		case IPPROTO_ICMPV6:
2709 			printf("ICMP6: type = %d, code = %d\n",
2710 			    *cp, *(cp + 1));
2711 			return;
2712 		case IPPROTO_ESP:
2713 			printf("ESP\n");
2714 			return;
2715 		case IPPROTO_TCP:
2716 			printf("TCP: from port %u, to port %u (decimal)\n",
2717 			    (*cp * 256 + *(cp + 1)),
2718 			    (*(cp + 2) * 256 + *(cp + 3)));
2719 			return;
2720 		case IPPROTO_UDP:
2721 			printf("UDP: from port %u, to port %u (decimal)\n",
2722 			    (*cp * 256 + *(cp + 1)),
2723 			    (*(cp + 2) * 256 + *(cp + 3)));
2724 			return;
2725 		default:
2726 			printf("Unknown Header(%d)\n", nh);
2727 			return;
2728 		}
2729 
2730 		if ((cp += hlen) >= end)
2731 			goto trunc;
2732 	}
2733 	if (end - cp < 8)
2734 		goto trunc;
2735 
2736 	putchar('\n');
2737 	return;
2738 
2739   trunc:
2740 	printf("...\n");
2741 	return;
2742 }
2743 
2744 static void
2745 fill(char *bp, char *patp)
2746 {
2747 	int ii, jj, kk;
2748 	int pat[16];
2749 	char *cp;
2750 
2751 	for (cp = patp; *cp; cp++)
2752 		if (!isxdigit(*cp))
2753 			errx(1, "patterns must be specified as hex digits");
2754 	ii = sscanf(patp,
2755 	    "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
2756 	    &pat[0], &pat[1], &pat[2], &pat[3], &pat[4], &pat[5], &pat[6],
2757 	    &pat[7], &pat[8], &pat[9], &pat[10], &pat[11], &pat[12],
2758 	    &pat[13], &pat[14], &pat[15]);
2759 
2760 /* xxx */
2761 	if (ii > 0)
2762 		for (kk = 0;
2763 		    (size_t)kk <= MAXDATALEN - 8 + sizeof(struct tv32) + ii;
2764 		    kk += ii)
2765 			for (jj = 0; jj < ii; ++jj)
2766 				bp[jj + kk] = pat[jj];
2767 	if (!(options & F_QUIET)) {
2768 		(void)printf("PATTERN: 0x");
2769 		for (jj = 0; jj < ii; ++jj)
2770 			(void)printf("%02x", bp[jj] & 0xFF);
2771 		(void)printf("\n");
2772 	}
2773 }
2774 
2775 #ifdef IPSEC
2776 #ifdef IPSEC_POLICY_IPSEC
2777 static int
2778 setpolicy(int so __unused, char *policy)
2779 {
2780 	char *buf;
2781 
2782 	if (policy == NULL)
2783 		return 0;	/* ignore */
2784 
2785 	buf = ipsec_set_policy(policy, strlen(policy));
2786 	if (buf == NULL)
2787 		errx(1, "%s", ipsec_strerror());
2788 	if (setsockopt(ssend, IPPROTO_IPV6, IPV6_IPSEC_POLICY, buf,
2789 	    ipsec_get_policylen(buf)) < 0)
2790 		warnx("Unable to set IPsec policy");
2791 	free(buf);
2792 
2793 	return 0;
2794 }
2795 #endif
2796 #endif
2797 
2798 static char *
2799 nigroup(char *name, int nig_oldmcprefix)
2800 {
2801 	char *p;
2802 	char *q;
2803 	MD5_CTX ctxt;
2804 	u_int8_t digest[16];
2805 	u_int8_t c;
2806 	size_t l;
2807 	char hbuf[NI_MAXHOST];
2808 	struct in6_addr in6;
2809 	int valid;
2810 
2811 	p = strchr(name, '.');
2812 	if (!p)
2813 		p = name + strlen(name);
2814 	l = p - name;
2815 	if (l > 63 || l > sizeof(hbuf) - 1)
2816 		return NULL;	/*label too long*/
2817 	strncpy(hbuf, name, l);
2818 	hbuf[(int)l] = '\0';
2819 
2820 	for (q = name; *q; q++) {
2821 		if (isupper(*(unsigned char *)q))
2822 			*q = tolower(*(unsigned char *)q);
2823 	}
2824 
2825 	/* generate 16 bytes of pseudo-random value. */
2826 	memset(&ctxt, 0, sizeof(ctxt));
2827 	MD5Init(&ctxt);
2828 	c = l & 0xff;
2829 	MD5Update(&ctxt, &c, sizeof(c));
2830 	MD5Update(&ctxt, (unsigned char *)name, l);
2831 	MD5Final(digest, &ctxt);
2832 
2833 	if (nig_oldmcprefix) {
2834 		/* draft-ietf-ipngwg-icmp-name-lookup */
2835 		valid = inet_pton(AF_INET6, "ff02::2:0000:0000", &in6);
2836 	} else {
2837 		/* RFC 4620 */
2838 		valid = inet_pton(AF_INET6, "ff02::2:ff00:0000", &in6);
2839 	}
2840 	if (valid != 1)
2841 		return NULL;	/*XXX*/
2842 
2843 	if (nig_oldmcprefix) {
2844 		/* draft-ietf-ipngwg-icmp-name-lookup */
2845 		bcopy(digest, &in6.s6_addr[12], 4);
2846 	} else {
2847 		/* RFC 4620 */
2848 		bcopy(digest, &in6.s6_addr[13], 3);
2849 	}
2850 
2851 	if (inet_ntop(AF_INET6, &in6, hbuf, sizeof(hbuf)) == NULL)
2852 		return NULL;
2853 
2854 	return strdup(hbuf);
2855 }
2856 
2857 static cap_channel_t *
2858 capdns_setup(void)
2859 {
2860 	cap_channel_t *capcas, *capdnsloc;
2861 #ifdef WITH_CASPER
2862 	const char *types[2];
2863 	int families[1];
2864 #endif
2865 	capcas = cap_init();
2866 	if (capcas == NULL)
2867 		err(1, "unable to create casper process");
2868 	capdnsloc = cap_service_open(capcas, "system.dns");
2869 	/* Casper capability no longer needed. */
2870 	cap_close(capcas);
2871 	if (capdnsloc == NULL)
2872 		err(1, "unable to open system.dns service");
2873 #ifdef WITH_CASPER
2874 	types[0] = "NAME2ADDR";
2875 	types[1] = "ADDR2NAME";
2876 	if (cap_dns_type_limit(capdnsloc, types, nitems(types)) < 0)
2877 		err(1, "unable to limit access to system.dns service");
2878 	families[0] = AF_INET6;
2879 	if (cap_dns_family_limit(capdnsloc, families, nitems(families)) < 0)
2880 		err(1, "unable to limit access to system.dns service");
2881 #endif
2882 	return (capdnsloc);
2883 }
2884