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