1/*	$KAME: traceroute6.c,v 1.68 2004/01/25 11:16:12 suz Exp $	*/
2
3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*-
33 * Copyright (c) 1990, 1993
34 *	The Regents of the University of California.  All rights reserved.
35 *
36 * This code is derived from software contributed to Berkeley by
37 * Van Jacobson.
38 *
39 * Redistribution and use in source and binary forms, with or without
40 * modification, are permitted provided that the following conditions
41 * are met:
42 * 1. Redistributions of source code must retain the above copyright
43 *    notice, this list of conditions and the following disclaimer.
44 * 2. Redistributions in binary form must reproduce the above copyright
45 *    notice, this list of conditions and the following disclaimer in the
46 *    documentation and/or other materials provided with the distribution.
47 * 4. Neither the name of the University nor the names of its contributors
48 *    may be used to endorse or promote products derived from this software
49 *    without specific prior written permission.
50 *
51 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 * SUCH DAMAGE.
62 */
63
64#ifndef lint
65static const char copyright[] =
66"@(#) Copyright (c) 1990, 1993\n\
67	The Regents of the University of California.  All rights reserved.\n";
68#endif /* not lint */
69
70#ifndef lint
71#if 0
72static char sccsid[] = "@(#)traceroute.c	8.1 (Berkeley) 6/6/93";
73#endif
74static const char rcsid[] =
75  "$FreeBSD: stable/11/usr.sbin/traceroute6/traceroute6.c 360709 2020-05-06 22:13:08Z tuexen $";
76#endif /* not lint */
77
78/*
79 * traceroute host  - trace the route ip packets follow going to "host".
80 *
81 * Attempt to trace the route an ip packet would follow to some
82 * internet host.  We find out intermediate hops by launching probe
83 * packets with a small ttl (time to live) then listening for an
84 * icmp "time exceeded" reply from a gateway.  We start our probes
85 * with a ttl of one and increase by one until we get an icmp "port
86 * unreachable" (which means we got to "host") or hit a max (which
87 * defaults to 30 hops & can be changed with the -m flag).  Three
88 * probes (change with -q flag) are sent at each ttl setting and a
89 * line is printed showing the ttl, address of the gateway and
90 * round trip time of each probe.  If the probe answers come from
91 * different gateways, the address of each responding system will
92 * be printed.  If there is no response within a 5 sec. timeout
93 * interval (changed with the -w flag), a "*" is printed for that
94 * probe.
95 *
96 * Probe packets are UDP format.  We don't want the destination
97 * host to process them so the destination port is set to an
98 * unlikely value (if some clod on the destination is using that
99 * value, it can be changed with the -p flag).
100 *
101 * A sample use might be:
102 *
103 *     [yak 71]% traceroute nis.nsf.net.
104 *     traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 56 byte packet
105 *      1  helios.ee.lbl.gov (128.3.112.1)  19 ms  19 ms  0 ms
106 *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
107 *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
108 *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  39 ms
109 *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  39 ms  39 ms  39 ms
110 *      6  128.32.197.4 (128.32.197.4)  40 ms  59 ms  59 ms
111 *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  59 ms
112 *      8  129.140.70.13 (129.140.70.13)  99 ms  99 ms  80 ms
113 *      9  129.140.71.6 (129.140.71.6)  139 ms  239 ms  319 ms
114 *     10  129.140.81.7 (129.140.81.7)  220 ms  199 ms  199 ms
115 *     11  nic.merit.edu (35.1.1.48)  239 ms  239 ms  239 ms
116 *
117 * Note that lines 2 & 3 are the same.  This is due to a buggy
118 * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
119 * packets with a zero ttl.
120 *
121 * A more interesting example is:
122 *
123 *     [yak 72]% traceroute allspice.lcs.mit.edu.
124 *     traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max
125 *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
126 *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  19 ms  19 ms
127 *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  19 ms
128 *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  19 ms  39 ms  39 ms
129 *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  20 ms  39 ms  39 ms
130 *      6  128.32.197.4 (128.32.197.4)  59 ms  119 ms  39 ms
131 *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  39 ms
132 *      8  129.140.70.13 (129.140.70.13)  80 ms  79 ms  99 ms
133 *      9  129.140.71.6 (129.140.71.6)  139 ms  139 ms  159 ms
134 *     10  129.140.81.7 (129.140.81.7)  199 ms  180 ms  300 ms
135 *     11  129.140.72.17 (129.140.72.17)  300 ms  239 ms  239 ms
136 *     12  * * *
137 *     13  128.121.54.72 (128.121.54.72)  259 ms  499 ms  279 ms
138 *     14  * * *
139 *     15  * * *
140 *     16  * * *
141 *     17  * * *
142 *     18  ALLSPICE.LCS.MIT.EDU (18.26.0.115)  339 ms  279 ms  279 ms
143 *
144 * (I start to see why I'm having so much trouble with mail to
145 * MIT.)  Note that the gateways 12, 14, 15, 16 & 17 hops away
146 * either don't send ICMP "time exceeded" messages or send them
147 * with a ttl too small to reach us.  14 - 17 are running the
148 * MIT C Gateway code that doesn't send "time exceeded"s.  God
149 * only knows what's going on with 12.
150 *
151 * The silent gateway 12 in the above may be the result of a bug in
152 * the 4.[23]BSD network code (and its derivatives):  4.x (x <= 3)
153 * sends an unreachable message using whatever ttl remains in the
154 * original datagram.  Since, for gateways, the remaining ttl is
155 * zero, the icmp "time exceeded" is guaranteed to not make it back
156 * to us.  The behavior of this bug is slightly more interesting
157 * when it appears on the destination system:
158 *
159 *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
160 *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  39 ms
161 *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  39 ms  19 ms
162 *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  19 ms
163 *      5  ccn-nerif35.Berkeley.EDU (128.32.168.35)  39 ms  39 ms  39 ms
164 *      6  csgw.Berkeley.EDU (128.32.133.254)  39 ms  59 ms  39 ms
165 *      7  * * *
166 *      8  * * *
167 *      9  * * *
168 *     10  * * *
169 *     11  * * *
170 *     12  * * *
171 *     13  rip.Berkeley.EDU (128.32.131.22)  59 ms !  39 ms !  39 ms !
172 *
173 * Notice that there are 12 "gateways" (13 is the final
174 * destination) and exactly the last half of them are "missing".
175 * What's really happening is that rip (a Sun-3 running Sun OS3.5)
176 * is using the ttl from our arriving datagram as the ttl in its
177 * icmp reply.  So, the reply will time out on the return path
178 * (with no notice sent to anyone since icmp's aren't sent for
179 * icmp's) until we probe with a ttl that's at least twice the path
180 * length.  I.e., rip is really only 7 hops away.  A reply that
181 * returns with a ttl of 1 is a clue this problem exists.
182 * Traceroute prints a "!" after the time if the ttl is <= 1.
183 * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
184 * non-standard (HPUX) software, expect to see this problem
185 * frequently and/or take care picking the target host of your
186 * probes.
187 *
188 * Other possible annotations after the time are !H, !N, !P (got a host,
189 * network or protocol unreachable, respectively), !S or !F (source
190 * route failed or fragmentation needed -- neither of these should
191 * ever occur and the associated gateway is busted if you see one).  If
192 * almost all the probes result in some kind of unreachable, traceroute
193 * will give up and exit.
194 *
195 * Notes
196 * -----
197 * This program must be run by root or be setuid.  (I suggest that
198 * you *don't* make it setuid -- casual use could result in a lot
199 * of unnecessary traffic on our poor, congested nets.)
200 *
201 * This program requires a kernel mod that does not appear in any
202 * system available from Berkeley:  A raw ip socket using proto
203 * IPPROTO_RAW must interpret the data sent as an ip datagram (as
204 * opposed to data to be wrapped in an ip datagram).  See the README
205 * file that came with the source to this program for a description
206 * of the mods I made to /sys/netinet/raw_ip.c.  Your mileage may
207 * vary.  But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
208 * MODIFIED TO RUN THIS PROGRAM.
209 *
210 * The udp port usage may appear bizarre (well, ok, it is bizarre).
211 * The problem is that an icmp message only contains 8 bytes of
212 * data from the original datagram.  8 bytes is the size of a udp
213 * header so, if we want to associate replies with the original
214 * datagram, the necessary information must be encoded into the
215 * udp header (the ip id could be used but there's no way to
216 * interlock with the kernel's assignment of ip id's and, anyway,
217 * it would have taken a lot more kernel hacking to allow this
218 * code to set the ip id).  So, to allow two or more users to
219 * use traceroute simultaneously, we use this task's pid as the
220 * source port (the high bit is set to move the port number out
221 * of the "likely" range).  To keep track of which probe is being
222 * replied to (so times and/or hop counts don't get confused by a
223 * reply that was delayed in transit), we increment the destination
224 * port number before each probe.
225 *
226 * Don't use this as a coding example.  I was trying to find a
227 * routing problem and this code sort-of popped out after 48 hours
228 * without sleep.  I was amazed it ever compiled, much less ran.
229 *
230 * I stole the idea for this program from Steve Deering.  Since
231 * the first release, I've learned that had I attended the right
232 * IETF working group meetings, I also could have stolen it from Guy
233 * Almes or Matt Mathis.  I don't know (or care) who came up with
234 * the idea first.  I envy the originators' perspicacity and I'm
235 * glad they didn't keep the idea a secret.
236 *
237 * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
238 * enhancements to the original distribution.
239 *
240 * I've hacked up a round-trip-route version of this that works by
241 * sending a loose-source-routed udp datagram through the destination
242 * back to yourself.  Unfortunately, SO many gateways botch source
243 * routing, the thing is almost worthless.  Maybe one day...
244 *
245 *  -- Van Jacobson (van@helios.ee.lbl.gov)
246 *     Tue Dec 20 03:50:13 PST 1988
247 */
248
249#include <sys/param.h>
250#include <sys/time.h>
251#include <sys/socket.h>
252#include <sys/uio.h>
253#include <sys/file.h>
254#include <sys/ioctl.h>
255#include <sys/sysctl.h>
256
257#include <netinet/in.h>
258
259#include <arpa/inet.h>
260
261#include <netdb.h>
262#include <stdio.h>
263#include <err.h>
264#ifdef HAVE_POLL
265#include <poll.h>
266#endif
267#include <errno.h>
268#include <stdlib.h>
269#include <string.h>
270#include <unistd.h>
271
272#include <netinet/ip6.h>
273#include <netinet/icmp6.h>
274#include <netinet/sctp.h>
275#include <netinet/sctp_header.h>
276#include <netinet/tcp.h>
277#include <netinet/udp.h>
278
279#ifdef IPSEC
280#include <net/route.h>
281#include <netipsec/ipsec.h>
282#endif
283
284#include "as.h"
285
286#define DUMMY_PORT 10010
287
288#define	MAXPACKET	65535	/* max ip packet size */
289
290#ifndef HAVE_GETIPNODEBYNAME
291#define getipnodebyname(x, y, z, u)	gethostbyname2((x), (y))
292#define freehostent(x)
293#endif
294
295u_char	packet[512];		/* last inbound (icmp) packet */
296char 	*outpacket;		/* last output packet */
297
298int	main(int, char *[]);
299int	wait_for_reply(int, struct msghdr *);
300#ifdef IPSEC
301#ifdef IPSEC_POLICY_IPSEC
302int	setpolicy(int so, char *policy);
303#endif
304#endif
305void	send_probe(int, u_long);
306void	*get_uphdr(struct ip6_hdr *, u_char *);
307int	get_hoplim(struct msghdr *);
308double	deltaT(struct timeval *, struct timeval *);
309const char *pr_type(int);
310int	packet_ok(struct msghdr *, int, int, u_char *, u_char *);
311void	print(struct msghdr *, int);
312const char *inetname(struct sockaddr *);
313u_int32_t sctp_crc32c(void *, u_int32_t);
314u_int16_t in_cksum(u_int16_t *addr, int);
315u_int16_t tcp_chksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
316    void *, u_int32_t);
317void	usage(void);
318
319int rcvsock;			/* receive (icmp) socket file descriptor */
320int sndsock;			/* send (raw/udp) socket file descriptor */
321
322struct msghdr rcvmhdr;
323struct iovec rcviov[2];
324int rcvhlim;
325struct in6_pktinfo *rcvpktinfo;
326
327struct sockaddr_in6 Src, Dst, Rcv;
328u_long datalen = 20;			/* How much data */
329#define	ICMP6ECHOLEN	8
330/* XXX: 2064 = 127(max hops in type 0 rthdr) * sizeof(ip6_hdr) + 16(margin) */
331char rtbuf[2064];
332#ifdef USE_RFC2292BIS
333struct ip6_rthdr *rth;
334#endif
335struct cmsghdr *cmsg;
336
337char *source = NULL;
338char *hostname;
339
340u_long nprobes = 3;
341u_long first_hop = 1;
342u_long max_hops = 30;
343u_int16_t srcport;
344u_int16_t port = 32768+666;	/* start udp dest port # for probe packets */
345u_int16_t ident;
346int options;			/* socket options */
347int verbose;
348int waittime = 5;		/* time to wait for response (in seconds) */
349int nflag;			/* print addresses numerically */
350int useproto = IPPROTO_UDP;	/* protocol to use to send packet */
351int lflag;			/* print both numerical address & hostname */
352int as_path;			/* print as numbers for each hop */
353char *as_server = NULL;
354void *asn;
355
356int
357main(int argc, char *argv[])
358{
359	int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM };
360	char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep;
361	int ch, i, on = 1, seq, rcvcmsglen, error;
362	struct addrinfo hints, *res;
363	static u_char *rcvcmsgbuf;
364	u_long probe, hops, lport;
365	struct hostent *hp;
366	size_t size, minlen;
367	uid_t uid;
368	u_char type, code;
369
370	/*
371	 * Receive ICMP
372	 */
373	if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
374		perror("socket(ICMPv6)");
375		exit(5);
376	}
377
378	size = sizeof(i);
379	(void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &i, &size, NULL, 0);
380	max_hops = i;
381
382	/* specify to tell receiving interface */
383#ifdef IPV6_RECVPKTINFO
384	if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
385	    sizeof(on)) < 0)
386		err(1, "setsockopt(IPV6_RECVPKTINFO)");
387#else  /* old adv. API */
388	if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_PKTINFO, &on,
389	    sizeof(on)) < 0)
390		err(1, "setsockopt(IPV6_PKTINFO)");
391#endif
392
393	/* specify to tell value of hoplimit field of received IP6 hdr */
394#ifdef IPV6_RECVHOPLIMIT
395	if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
396	    sizeof(on)) < 0)
397		err(1, "setsockopt(IPV6_RECVHOPLIMIT)");
398#else  /* old adv. API */
399	if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on,
400	    sizeof(on)) < 0)
401		err(1, "setsockopt(IPV6_HOPLIMIT)");
402#endif
403
404	seq = 0;
405	ident = htons(getpid() & 0xffff); /* same as ping6 */
406
407	while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:STUvw:")) != -1)
408		switch (ch) {
409		case 'a':
410			as_path = 1;
411			break;
412		case 'A':
413			as_path = 1;
414			as_server = optarg;
415			break;
416		case 'd':
417			options |= SO_DEBUG;
418			break;
419		case 'f':
420			ep = NULL;
421			errno = 0;
422			first_hop = strtoul(optarg, &ep, 0);
423			if (errno || !*optarg || *ep || first_hop > 255) {
424				fprintf(stderr,
425				    "traceroute6: invalid min hoplimit.\n");
426				exit(1);
427			}
428			break;
429		case 'g':
430			hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno);
431			if (hp == NULL) {
432				fprintf(stderr,
433				    "traceroute6: unknown host %s\n", optarg);
434				exit(1);
435			}
436#ifdef USE_RFC2292BIS
437			if (rth == NULL) {
438				/*
439				 * XXX: We can't detect the number of
440				 * intermediate nodes yet.
441				 */
442				if ((rth = inet6_rth_init((void *)rtbuf,
443				    sizeof(rtbuf), IPV6_RTHDR_TYPE_0,
444				    0)) == NULL) {
445					fprintf(stderr,
446					    "inet6_rth_init failed.\n");
447					exit(1);
448				}
449			}
450			if (inet6_rth_add((void *)rth,
451			    (struct in6_addr *)hp->h_addr)) {
452				fprintf(stderr,
453				    "inet6_rth_add failed for %s\n",
454				    optarg);
455				exit(1);
456			}
457#else  /* old advanced API */
458			if (cmsg == NULL)
459				cmsg = inet6_rthdr_init(rtbuf, IPV6_RTHDR_TYPE_0);
460			inet6_rthdr_add(cmsg, (struct in6_addr *)hp->h_addr,
461			    IPV6_RTHDR_LOOSE);
462#endif
463			freehostent(hp);
464			break;
465		case 'I':
466			useproto = IPPROTO_ICMPV6;
467			break;
468		case 'l':
469			lflag++;
470			break;
471		case 'm':
472			ep = NULL;
473			errno = 0;
474			max_hops = strtoul(optarg, &ep, 0);
475			if (errno || !*optarg || *ep || max_hops > 255) {
476				fprintf(stderr,
477				    "traceroute6: invalid max hoplimit.\n");
478				exit(1);
479			}
480			break;
481		case 'n':
482			nflag++;
483			break;
484		case 'N':
485			useproto = IPPROTO_NONE;
486			break;
487		case 'p':
488			ep = NULL;
489			errno = 0;
490			lport = strtoul(optarg, &ep, 0);
491			if (errno || !*optarg || *ep) {
492				fprintf(stderr, "traceroute6: invalid port.\n");
493				exit(1);
494			}
495			if (lport == 0 || lport != (lport & 0xffff)) {
496				fprintf(stderr,
497				    "traceroute6: port out of range.\n");
498				exit(1);
499			}
500			port = lport & 0xffff;
501			break;
502		case 'q':
503			ep = NULL;
504			errno = 0;
505			nprobes = strtoul(optarg, &ep, 0);
506			if (errno || !*optarg || *ep) {
507				fprintf(stderr,
508				    "traceroute6: invalid nprobes.\n");
509				exit(1);
510			}
511			if (nprobes < 1) {
512				fprintf(stderr,
513				    "traceroute6: nprobes must be >0.\n");
514				exit(1);
515			}
516			break;
517		case 'r':
518			options |= SO_DONTROUTE;
519			break;
520		case 's':
521			/*
522			 * set the ip source address of the outbound
523			 * probe (e.g., on a multi-homed host).
524			 */
525			source = optarg;
526			break;
527		case 'S':
528			useproto = IPPROTO_SCTP;
529			break;
530		case 'T':
531			useproto = IPPROTO_TCP;
532			break;
533		case 'U':
534			useproto = IPPROTO_UDP;
535			break;
536		case 'v':
537			verbose++;
538			break;
539		case 'w':
540			ep = NULL;
541			errno = 0;
542			waittime = strtoul(optarg, &ep, 0);
543			if (errno || !*optarg || *ep) {
544				fprintf(stderr,
545				    "traceroute6: invalid wait time.\n");
546				exit(1);
547			}
548			if (waittime < 1) {
549				fprintf(stderr,
550				    "traceroute6: wait must be >= 1 sec.\n");
551				exit(1);
552			}
553			break;
554		default:
555			usage();
556		}
557	argc -= optind;
558	argv += optind;
559
560	/*
561	 * Open socket to send probe packets.
562	 */
563	switch (useproto) {
564	case IPPROTO_ICMPV6:
565		sndsock = rcvsock;
566		break;
567	case IPPROTO_UDP:
568		if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
569			perror("socket(SOCK_DGRAM)");
570			exit(5);
571		}
572		break;
573	case IPPROTO_NONE:
574	case IPPROTO_SCTP:
575	case IPPROTO_TCP:
576		if ((sndsock = socket(AF_INET6, SOCK_RAW, useproto)) < 0) {
577			perror("socket(SOCK_RAW)");
578			exit(5);
579		}
580		break;
581	default:
582		fprintf(stderr, "traceroute6: unknown probe protocol %d\n",
583		    useproto);
584		exit(5);
585	}
586	if (max_hops < first_hop) {
587		fprintf(stderr,
588		    "traceroute6: max hoplimit must be larger than first hoplimit.\n");
589		exit(1);
590	}
591
592	/* revoke privs */
593	uid = getuid();
594	if (setresuid(uid, uid, uid) == -1) {
595		perror("setresuid");
596		exit(1);
597	}
598
599
600	if (argc < 1 || argc > 2)
601		usage();
602
603#if 1
604	setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
605#else
606	setlinebuf(stdout);
607#endif
608
609	memset(&hints, 0, sizeof(hints));
610	hints.ai_family = PF_INET6;
611	hints.ai_socktype = SOCK_RAW;
612	hints.ai_protocol = IPPROTO_ICMPV6;
613	hints.ai_flags = AI_CANONNAME;
614	error = getaddrinfo(*argv, NULL, &hints, &res);
615	if (error) {
616		fprintf(stderr,
617		    "traceroute6: %s\n", gai_strerror(error));
618		exit(1);
619	}
620	if (res->ai_addrlen != sizeof(Dst)) {
621		fprintf(stderr,
622		    "traceroute6: size of sockaddr mismatch\n");
623		exit(1);
624	}
625	memcpy(&Dst, res->ai_addr, res->ai_addrlen);
626	hostname = res->ai_canonname ? strdup(res->ai_canonname) : *argv;
627	if (!hostname) {
628		fprintf(stderr, "traceroute6: not enough core\n");
629		exit(1);
630	}
631	if (res->ai_next) {
632		if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf,
633		    sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
634			strlcpy(hbuf, "?", sizeof(hbuf));
635		fprintf(stderr, "traceroute6: Warning: %s has multiple "
636		    "addresses; using %s\n", hostname, hbuf);
637	}
638
639	if (*++argv) {
640		ep = NULL;
641		errno = 0;
642		datalen = strtoul(*argv, &ep, 0);
643		if (errno || *ep) {
644			fprintf(stderr,
645			    "traceroute6: invalid packet length.\n");
646			exit(1);
647		}
648	}
649	switch (useproto) {
650	case IPPROTO_ICMPV6:
651		minlen = ICMP6ECHOLEN;
652		break;
653	case IPPROTO_UDP:
654		minlen = sizeof(struct udphdr);
655		break;
656	case IPPROTO_NONE:
657		minlen = 0;
658		datalen = 0;
659		break;
660	case IPPROTO_SCTP:
661		minlen = sizeof(struct sctphdr);
662		break;
663	case IPPROTO_TCP:
664		minlen = sizeof(struct tcphdr);
665		break;
666	default:
667		fprintf(stderr, "traceroute6: unknown probe protocol %d.\n",
668		    useproto);
669		exit(1);
670	}
671	if (datalen < minlen)
672		datalen = minlen;
673	else if (datalen >= MAXPACKET) {
674		fprintf(stderr,
675		    "traceroute6: packet size must be %zu <= s < %d.\n",
676		    minlen, MAXPACKET);
677		exit(1);
678	}
679	if (useproto == IPPROTO_UDP)
680		datalen -= sizeof(struct udphdr);
681	if ((useproto == IPPROTO_SCTP) && (datalen & 3)) {
682		fprintf(stderr,
683		    "traceroute6: packet size must be a multiple of 4.\n");
684		exit(1);
685	}
686	outpacket = malloc(datalen);
687	if (!outpacket) {
688		perror("malloc");
689		exit(1);
690	}
691	(void) bzero((char *)outpacket, datalen);
692
693	/* initialize msghdr for receiving packets */
694	rcviov[0].iov_base = (caddr_t)packet;
695	rcviov[0].iov_len = sizeof(packet);
696	rcvmhdr.msg_name = (caddr_t)&Rcv;
697	rcvmhdr.msg_namelen = sizeof(Rcv);
698	rcvmhdr.msg_iov = rcviov;
699	rcvmhdr.msg_iovlen = 1;
700	rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
701	    CMSG_SPACE(sizeof(int));
702	if ((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) {
703		fprintf(stderr, "traceroute6: malloc failed\n");
704		exit(1);
705	}
706	rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf;
707	rcvmhdr.msg_controllen = rcvcmsglen;
708
709	if (options & SO_DEBUG)
710		(void) setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG,
711		    (char *)&on, sizeof(on));
712	if (options & SO_DONTROUTE)
713		(void) setsockopt(rcvsock, SOL_SOCKET, SO_DONTROUTE,
714		    (char *)&on, sizeof(on));
715#ifdef IPSEC
716#ifdef IPSEC_POLICY_IPSEC
717	/*
718	 * do not raise error even if setsockopt fails, kernel may have ipsec
719	 * turned off.
720	 */
721	if (setpolicy(rcvsock, "in bypass") < 0)
722		errx(1, "%s", ipsec_strerror());
723	if (setpolicy(rcvsock, "out bypass") < 0)
724		errx(1, "%s", ipsec_strerror());
725#else
726    {
727	int level = IPSEC_LEVEL_NONE;
728
729	(void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
730	    sizeof(level));
731	(void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
732	    sizeof(level));
733#ifdef IP_AUTH_TRANS_LEVEL
734	(void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
735	    sizeof(level));
736#else
737	(void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
738	    sizeof(level));
739#endif
740#ifdef IP_AUTH_NETWORK_LEVEL
741	(void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
742	    sizeof(level));
743#endif
744    }
745#endif /*IPSEC_POLICY_IPSEC*/
746#endif /*IPSEC*/
747
748#ifdef SO_SNDBUF
749	i = datalen;
750	if (i == 0)
751		i = 1;
752	if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&i,
753	    sizeof(i)) < 0) {
754		perror("setsockopt(SO_SNDBUF)");
755		exit(6);
756	}
757#endif /* SO_SNDBUF */
758	if (options & SO_DEBUG)
759		(void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
760		    (char *)&on, sizeof(on));
761	if (options & SO_DONTROUTE)
762		(void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
763		    (char *)&on, sizeof(on));
764#ifdef USE_RFC2292BIS
765	if (rth) {/* XXX: there is no library to finalize the header... */
766		rth->ip6r_len = rth->ip6r_segleft * 2;
767		if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_RTHDR,
768		    (void *)rth, (rth->ip6r_len + 1) << 3)) {
769			fprintf(stderr, "setsockopt(IPV6_RTHDR): %s\n",
770			    strerror(errno));
771			exit(1);
772		}
773	}
774#else  /* old advanced API */
775	if (cmsg != NULL) {
776		inet6_rthdr_lasthop(cmsg, IPV6_RTHDR_LOOSE);
777		if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_PKTOPTIONS,
778		    rtbuf, cmsg->cmsg_len) < 0) {
779			fprintf(stderr, "setsockopt(IPV6_PKTOPTIONS): %s\n",
780			    strerror(errno));
781			exit(1);
782		}
783	}
784#endif /* USE_RFC2292BIS */
785#ifdef IPSEC
786#ifdef IPSEC_POLICY_IPSEC
787	/*
788	 * do not raise error even if setsockopt fails, kernel may have ipsec
789	 * turned off.
790	 */
791	if (setpolicy(sndsock, "in bypass") < 0)
792		errx(1, "%s", ipsec_strerror());
793	if (setpolicy(sndsock, "out bypass") < 0)
794		errx(1, "%s", ipsec_strerror());
795#else
796    {
797	int level = IPSEC_LEVEL_BYPASS;
798
799	(void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
800	    sizeof(level));
801	(void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
802	    sizeof(level));
803#ifdef IP_AUTH_TRANS_LEVEL
804	(void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
805	    sizeof(level));
806#else
807	(void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
808	    sizeof(level));
809#endif
810#ifdef IP_AUTH_NETWORK_LEVEL
811	(void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
812	    sizeof(level));
813#endif
814    }
815#endif /*IPSEC_POLICY_IPSEC*/
816#endif /*IPSEC*/
817
818	/*
819	 * Source selection
820	 */
821	bzero(&Src, sizeof(Src));
822	if (source) {
823		struct addrinfo hints, *res;
824		int error;
825
826		memset(&hints, 0, sizeof(hints));
827		hints.ai_family = AF_INET6;
828		hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
829		hints.ai_flags = AI_NUMERICHOST;
830		error = getaddrinfo(source, "0", &hints, &res);
831		if (error) {
832			printf("traceroute6: %s: %s\n", source,
833			    gai_strerror(error));
834			exit(1);
835		}
836		if (res->ai_addrlen > sizeof(Src)) {
837			printf("traceroute6: %s: %s\n", source,
838			    gai_strerror(error));
839			exit(1);
840		}
841		memcpy(&Src, res->ai_addr, res->ai_addrlen);
842		freeaddrinfo(res);
843	} else {
844		struct sockaddr_in6 Nxt;
845		int dummy;
846		socklen_t len;
847
848		Nxt = Dst;
849		Nxt.sin6_port = htons(DUMMY_PORT);
850		if (cmsg != NULL)
851			bcopy(inet6_rthdr_getaddr(cmsg, 1), &Nxt.sin6_addr,
852			    sizeof(Nxt.sin6_addr));
853		if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
854			perror("socket");
855			exit(1);
856		}
857		if (connect(dummy, (struct sockaddr *)&Nxt, Nxt.sin6_len) < 0) {
858			perror("connect");
859			exit(1);
860		}
861		len = sizeof(Src);
862		if (getsockname(dummy, (struct sockaddr *)&Src, &len) < 0) {
863			perror("getsockname");
864			exit(1);
865		}
866		if (getnameinfo((struct sockaddr *)&Src, Src.sin6_len,
867		    src0, sizeof(src0), NULL, 0, NI_NUMERICHOST)) {
868			fprintf(stderr, "getnameinfo failed for source\n");
869			exit(1);
870		}
871		source = src0;
872		close(dummy);
873	}
874
875	Src.sin6_port = htons(0);
876	if (bind(sndsock, (struct sockaddr *)&Src, Src.sin6_len) < 0) {
877		perror("bind");
878		exit(1);
879	}
880
881	{
882		socklen_t len;
883
884		len = sizeof(Src);
885		if (getsockname(sndsock, (struct sockaddr *)&Src, &len) < 0) {
886			perror("getsockname");
887			exit(1);
888		}
889		srcport = ntohs(Src.sin6_port);
890	}
891
892	if (as_path) {
893		asn = as_setup(as_server);
894		if (asn == NULL) {
895			fprintf(stderr,
896			    "traceroute6: as_setup failed, AS# lookups"
897			    " disabled\n");
898			(void)fflush(stderr);
899			as_path = 0;
900		}
901	}
902
903	/*
904	 * Message to users
905	 */
906	if (getnameinfo((struct sockaddr *)&Dst, Dst.sin6_len, hbuf,
907	    sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
908		strlcpy(hbuf, "(invalid)", sizeof(hbuf));
909	fprintf(stderr, "traceroute6");
910	fprintf(stderr, " to %s (%s)", hostname, hbuf);
911	if (source)
912		fprintf(stderr, " from %s", source);
913	fprintf(stderr, ", %lu hops max, %lu byte packets\n",
914	    max_hops,
915	    datalen + ((useproto == IPPROTO_UDP) ? sizeof(struct udphdr) : 0));
916	(void) fflush(stderr);
917
918	if (first_hop > 1)
919		printf("Skipping %lu intermediate hops\n", first_hop - 1);
920
921	/*
922	 * Main loop
923	 */
924	for (hops = first_hop; hops <= max_hops; ++hops) {
925		struct in6_addr lastaddr;
926		int got_there = 0;
927		unsigned unreachable = 0;
928
929		printf("%2lu ", hops);
930		bzero(&lastaddr, sizeof(lastaddr));
931		for (probe = 0; probe < nprobes; ++probe) {
932			int cc;
933			struct timeval t1, t2;
934
935			(void) gettimeofday(&t1, NULL);
936			send_probe(++seq, hops);
937			while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) {
938				(void) gettimeofday(&t2, NULL);
939				if (packet_ok(&rcvmhdr, cc, seq, &type, &code)) {
940					if (!IN6_ARE_ADDR_EQUAL(&Rcv.sin6_addr,
941					    &lastaddr)) {
942						if (probe > 0)
943							fputs("\n   ", stdout);
944						print(&rcvmhdr, cc);
945						lastaddr = Rcv.sin6_addr;
946					}
947					printf("  %.3f ms", deltaT(&t1, &t2));
948					if (type == ICMP6_DST_UNREACH) {
949						switch (code) {
950						case ICMP6_DST_UNREACH_NOROUTE:
951							++unreachable;
952							printf(" !N");
953							break;
954						case ICMP6_DST_UNREACH_ADMIN:
955							++unreachable;
956							printf(" !P");
957							break;
958						case ICMP6_DST_UNREACH_NOTNEIGHBOR:
959							++unreachable;
960							printf(" !S");
961							break;
962						case ICMP6_DST_UNREACH_ADDR:
963							++unreachable;
964							printf(" !A");
965							break;
966						case ICMP6_DST_UNREACH_NOPORT:
967							if (rcvhlim >= 0 &&
968							    rcvhlim <= 1)
969								printf(" !");
970							++got_there;
971							break;
972						}
973					} else if (type == ICMP6_PARAM_PROB &&
974					    code == ICMP6_PARAMPROB_NEXTHEADER) {
975						printf(" !H");
976						++got_there;
977					} else if (type == ICMP6_ECHO_REPLY) {
978						if (rcvhlim >= 0 &&
979						    rcvhlim <= 1)
980							printf(" !");
981						++got_there;
982					}
983					break;
984				} else if (deltaT(&t1, &t2) > waittime * 1000) {
985					cc = 0;
986					break;
987				}
988			}
989			if (cc == 0)
990				printf(" *");
991			(void) fflush(stdout);
992		}
993		putchar('\n');
994		if (got_there ||
995		    (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) {
996			exit(0);
997		}
998	}
999	if (as_path)
1000		as_shutdown(asn);
1001
1002	exit(0);
1003}
1004
1005int
1006wait_for_reply(int sock, struct msghdr *mhdr)
1007{
1008#ifdef HAVE_POLL
1009	struct pollfd pfd[1];
1010	int cc = 0;
1011
1012	pfd[0].fd = sock;
1013	pfd[0].events = POLLIN;
1014	pfd[0].revents = 0;
1015
1016	if (poll(pfd, 1, waittime * 1000) > 0)
1017		cc = recvmsg(rcvsock, mhdr, 0);
1018
1019	return (cc);
1020#else
1021	fd_set *fdsp;
1022	struct timeval wait;
1023	int cc = 0, fdsn;
1024
1025	fdsn = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
1026	if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
1027		err(1, "malloc");
1028	memset(fdsp, 0, fdsn);
1029	FD_SET(sock, fdsp);
1030	wait.tv_sec = waittime; wait.tv_usec = 0;
1031
1032	if (select(sock+1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0)
1033		cc = recvmsg(rcvsock, mhdr, 0);
1034
1035	free(fdsp);
1036	return (cc);
1037#endif
1038}
1039
1040#ifdef IPSEC
1041#ifdef IPSEC_POLICY_IPSEC
1042int
1043setpolicy(so, policy)
1044	int so;
1045	char *policy;
1046{
1047	char *buf;
1048
1049	buf = ipsec_set_policy(policy, strlen(policy));
1050	if (buf == NULL) {
1051		warnx("%s", ipsec_strerror());
1052		return -1;
1053	}
1054	(void)setsockopt(so, IPPROTO_IPV6, IPV6_IPSEC_POLICY,
1055	    buf, ipsec_get_policylen(buf));
1056
1057	free(buf);
1058
1059	return 0;
1060}
1061#endif
1062#endif
1063
1064void
1065send_probe(int seq, u_long hops)
1066{
1067	struct icmp6_hdr *icp;
1068	struct sctphdr *sctp;
1069	struct sctp_chunkhdr *chk;
1070	struct sctp_init_chunk *init;
1071	struct sctp_paramhdr *param;
1072	struct tcphdr *tcp;
1073	int i;
1074
1075	i = hops;
1076	if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
1077	    (char *)&i, sizeof(i)) < 0) {
1078		perror("setsockopt IPV6_UNICAST_HOPS");
1079	}
1080
1081	Dst.sin6_port = htons(port + seq);
1082
1083	switch (useproto) {
1084	case IPPROTO_ICMPV6:
1085		icp = (struct icmp6_hdr *)outpacket;
1086
1087		icp->icmp6_type = ICMP6_ECHO_REQUEST;
1088		icp->icmp6_code = 0;
1089		icp->icmp6_cksum = 0;
1090		icp->icmp6_id = ident;
1091		icp->icmp6_seq = htons(seq);
1092		break;
1093	case IPPROTO_UDP:
1094		break;
1095	case IPPROTO_NONE:
1096		/* No space for anything. No harm as seq/tv32 are decorative. */
1097		break;
1098	case IPPROTO_SCTP:
1099		sctp = (struct sctphdr *)outpacket;
1100
1101		sctp->src_port = htons(ident);
1102		sctp->dest_port = htons(port + seq);
1103		if (datalen >= (u_long)(sizeof(struct sctphdr) +
1104		    sizeof(struct sctp_init_chunk))) {
1105			sctp->v_tag = 0;
1106		} else {
1107			sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port;
1108		}
1109		sctp->checksum = htonl(0);
1110		if (datalen >= (u_long)(sizeof(struct sctphdr) +
1111		    sizeof(struct sctp_init_chunk))) {
1112			/*
1113			 * Send a packet containing an INIT chunk. This works
1114			 * better in case of firewalls on the path, but
1115			 * results in a probe packet containing at least
1116			 * 32 bytes of payload. For shorter payloads, use
1117			 * SHUTDOWN-ACK chunks.
1118			 */
1119			init = (struct sctp_init_chunk *)(sctp + 1);
1120			init->ch.chunk_type = SCTP_INITIATION;
1121			init->ch.chunk_flags = 0;
1122			init->ch.chunk_length = htons((u_int16_t)(datalen -
1123			    sizeof(struct sctphdr)));
1124			init->init.initiate_tag = (sctp->src_port << 16) |
1125			    sctp->dest_port;
1126			init->init.a_rwnd = htonl(1500);
1127			init->init.num_outbound_streams = htons(1);
1128			init->init.num_inbound_streams = htons(1);
1129			init->init.initial_tsn = htonl(0);
1130			if (datalen >= (u_long)(sizeof(struct sctphdr) +
1131			    sizeof(struct sctp_init_chunk) +
1132			    sizeof(struct sctp_paramhdr))) {
1133				param = (struct sctp_paramhdr *)(init + 1);
1134				param->param_type = htons(SCTP_PAD);
1135				param->param_length =
1136				    htons((u_int16_t)(datalen -
1137				    sizeof(struct sctphdr) -
1138				    sizeof(struct sctp_init_chunk)));
1139			}
1140		} else {
1141			/*
1142			 * Send a packet containing a SHUTDOWN-ACK chunk,
1143			 * possibly followed by a PAD chunk.
1144			 */
1145			if (datalen >= (u_long)(sizeof(struct sctphdr) +
1146			    sizeof(struct sctp_chunkhdr))) {
1147				chk = (struct sctp_chunkhdr *)(sctp + 1);
1148				chk->chunk_type = SCTP_SHUTDOWN_ACK;
1149				chk->chunk_flags = 0;
1150				chk->chunk_length = htons(4);
1151			}
1152			if (datalen >= (u_long)(sizeof(struct sctphdr) +
1153			    2 * sizeof(struct sctp_chunkhdr))) {
1154				chk = chk + 1;
1155				chk->chunk_type = SCTP_PAD_CHUNK;
1156				chk->chunk_flags = 0;
1157				chk->chunk_length = htons((u_int16_t)(datalen -
1158				    sizeof(struct sctphdr) -
1159				    sizeof(struct sctp_chunkhdr)));
1160			}
1161		}
1162		sctp->checksum = sctp_crc32c(outpacket, datalen);
1163		break;
1164	case IPPROTO_TCP:
1165		tcp = (struct tcphdr *)outpacket;
1166
1167		tcp->th_sport = htons(ident);
1168		tcp->th_dport = htons(port + seq);
1169		tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
1170		tcp->th_ack = 0;
1171		tcp->th_off = 5;
1172		tcp->th_flags = TH_SYN;
1173		tcp->th_sum = 0;
1174		tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen);
1175		break;
1176	default:
1177		fprintf(stderr, "Unknown probe protocol %d.\n", useproto);
1178		exit(1);
1179	}
1180
1181	i = sendto(sndsock, (char *)outpacket, datalen, 0,
1182	    (struct sockaddr *)&Dst, Dst.sin6_len);
1183	if (i < 0 || (u_long)i != datalen)  {
1184		if (i < 0)
1185			perror("sendto");
1186		printf("traceroute6: wrote %s %lu chars, ret=%d\n",
1187		    hostname, datalen, i);
1188		(void) fflush(stdout);
1189	}
1190}
1191
1192int
1193get_hoplim(struct msghdr *mhdr)
1194{
1195	struct cmsghdr *cm;
1196
1197	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1198	    cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1199		if (cm->cmsg_level == IPPROTO_IPV6 &&
1200		    cm->cmsg_type == IPV6_HOPLIMIT &&
1201		    cm->cmsg_len == CMSG_LEN(sizeof(int)))
1202			return (*(int *)CMSG_DATA(cm));
1203	}
1204
1205	return (-1);
1206}
1207
1208double
1209deltaT(struct timeval *t1p, struct timeval *t2p)
1210{
1211	double dt;
1212
1213	dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1214	    (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1215	return (dt);
1216}
1217
1218/*
1219 * Convert an ICMP "type" field to a printable string.
1220 */
1221const char *
1222pr_type(int t0)
1223{
1224	u_char t = t0 & 0xff;
1225	const char *cp;
1226
1227	switch (t) {
1228	case ICMP6_DST_UNREACH:
1229		cp = "Destination Unreachable";
1230		break;
1231	case ICMP6_PACKET_TOO_BIG:
1232		cp = "Packet Too Big";
1233		break;
1234	case ICMP6_TIME_EXCEEDED:
1235		cp = "Time Exceeded";
1236		break;
1237	case ICMP6_PARAM_PROB:
1238		cp = "Parameter Problem";
1239		break;
1240	case ICMP6_ECHO_REQUEST:
1241		cp = "Echo Request";
1242		break;
1243	case ICMP6_ECHO_REPLY:
1244		cp = "Echo Reply";
1245		break;
1246	case ICMP6_MEMBERSHIP_QUERY:
1247		cp = "Group Membership Query";
1248		break;
1249	case ICMP6_MEMBERSHIP_REPORT:
1250		cp = "Group Membership Report";
1251		break;
1252	case ICMP6_MEMBERSHIP_REDUCTION:
1253		cp = "Group Membership Reduction";
1254		break;
1255	case ND_ROUTER_SOLICIT:
1256		cp = "Router Solicitation";
1257		break;
1258	case ND_ROUTER_ADVERT:
1259		cp = "Router Advertisement";
1260		break;
1261	case ND_NEIGHBOR_SOLICIT:
1262		cp = "Neighbor Solicitation";
1263		break;
1264	case ND_NEIGHBOR_ADVERT:
1265		cp = "Neighbor Advertisement";
1266		break;
1267	case ND_REDIRECT:
1268		cp = "Redirect";
1269		break;
1270	default:
1271		cp = "Unknown";
1272		break;
1273	}
1274	return cp;
1275}
1276
1277int
1278packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code)
1279{
1280	struct icmp6_hdr *icp;
1281	struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1282	char *buf = (char *)mhdr->msg_iov[0].iov_base;
1283	struct cmsghdr *cm;
1284	int *hlimp;
1285	char hbuf[NI_MAXHOST];
1286
1287#ifdef OLDRAWSOCKET
1288	int hlen;
1289	struct ip6_hdr *ip;
1290#endif
1291
1292#ifdef OLDRAWSOCKET
1293	ip = (struct ip6_hdr *) buf;
1294	hlen = sizeof(struct ip6_hdr);
1295	if (cc < hlen + sizeof(struct icmp6_hdr)) {
1296		if (verbose) {
1297			if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1298			    hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1299				strlcpy(hbuf, "invalid", sizeof(hbuf));
1300			printf("packet too short (%d bytes) from %s\n", cc,
1301			    hbuf);
1302		}
1303		return (0);
1304	}
1305	cc -= hlen;
1306	icp = (struct icmp6_hdr *)(buf + hlen);
1307#else
1308	if (cc < (int)sizeof(struct icmp6_hdr)) {
1309		if (verbose) {
1310			if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1311			    hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1312				strlcpy(hbuf, "invalid", sizeof(hbuf));
1313			printf("data too short (%d bytes) from %s\n", cc, hbuf);
1314		}
1315		return (0);
1316	}
1317	icp = (struct icmp6_hdr *)buf;
1318#endif
1319	/* get optional information via advanced API */
1320	rcvpktinfo = NULL;
1321	hlimp = NULL;
1322	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1323	    cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1324		if (cm->cmsg_level == IPPROTO_IPV6 &&
1325		    cm->cmsg_type == IPV6_PKTINFO &&
1326		    cm->cmsg_len ==
1327		    CMSG_LEN(sizeof(struct in6_pktinfo)))
1328			rcvpktinfo = (struct in6_pktinfo *)(CMSG_DATA(cm));
1329
1330		if (cm->cmsg_level == IPPROTO_IPV6 &&
1331		    cm->cmsg_type == IPV6_HOPLIMIT &&
1332		    cm->cmsg_len == CMSG_LEN(sizeof(int)))
1333			hlimp = (int *)CMSG_DATA(cm);
1334	}
1335	if (rcvpktinfo == NULL || hlimp == NULL) {
1336		warnx("failed to get received hop limit or packet info");
1337#if 0
1338		return (0);
1339#else
1340		rcvhlim = 0;	/*XXX*/
1341#endif
1342	}
1343	else
1344		rcvhlim = *hlimp;
1345
1346	*type = icp->icmp6_type;
1347	*code = icp->icmp6_code;
1348	if ((*type == ICMP6_TIME_EXCEEDED &&
1349	    *code == ICMP6_TIME_EXCEED_TRANSIT) ||
1350	    (*type == ICMP6_DST_UNREACH) ||
1351	    (*type == ICMP6_PARAM_PROB &&
1352	    *code == ICMP6_PARAMPROB_NEXTHEADER)) {
1353		struct ip6_hdr *hip;
1354		struct icmp6_hdr *icmp;
1355		struct sctp_init_chunk *init;
1356		struct sctphdr *sctp;
1357		struct tcphdr *tcp;
1358		struct udphdr *udp;
1359		void *up;
1360
1361		hip = (struct ip6_hdr *)(icp + 1);
1362		if ((up = get_uphdr(hip, (u_char *)(buf + cc))) == NULL) {
1363			if (verbose)
1364				warnx("failed to get upper layer header");
1365			return (0);
1366		}
1367		switch (useproto) {
1368		case IPPROTO_ICMPV6:
1369			icmp = (struct icmp6_hdr *)up;
1370			if (icmp->icmp6_id == ident &&
1371			    icmp->icmp6_seq == htons(seq))
1372				return (1);
1373			break;
1374		case IPPROTO_UDP:
1375			udp = (struct udphdr *)up;
1376			if (udp->uh_sport == htons(srcport) &&
1377			    udp->uh_dport == htons(port + seq))
1378				return (1);
1379			break;
1380		case IPPROTO_SCTP:
1381			sctp = (struct sctphdr *)up;
1382			if (sctp->src_port != htons(ident) ||
1383			    sctp->dest_port != htons(port + seq)) {
1384				break;
1385			}
1386			if (datalen >= (u_long)(sizeof(struct sctphdr) +
1387			    sizeof(struct sctp_init_chunk))) {
1388				if (sctp->v_tag != 0) {
1389					break;
1390				}
1391				init = (struct sctp_init_chunk *)(sctp + 1);
1392				/* Check the initiate tag, if available. */
1393				if ((char *)&init->init.a_rwnd > buf + cc) {
1394					return (1);
1395				}
1396				if (init->init.initiate_tag == (u_int32_t)
1397				    ((sctp->src_port << 16) | sctp->dest_port)) {
1398					return (1);
1399				}
1400			} else {
1401				if (sctp->v_tag ==
1402				    (u_int32_t)((sctp->src_port << 16) |
1403				    sctp->dest_port)) {
1404					return (1);
1405				}
1406			}
1407			break;
1408		case IPPROTO_TCP:
1409			tcp = (struct tcphdr *)up;
1410			if (tcp->th_sport == htons(ident) &&
1411			    tcp->th_dport == htons(port + seq) &&
1412			    tcp->th_seq ==
1413			    (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport))
1414				return (1);
1415			break;
1416		case IPPROTO_NONE:
1417			return (1);
1418		default:
1419			fprintf(stderr, "Unknown probe proto %d.\n", useproto);
1420			break;
1421		}
1422	} else if (useproto == IPPROTO_ICMPV6 && *type == ICMP6_ECHO_REPLY) {
1423		if (icp->icmp6_id == ident &&
1424		    icp->icmp6_seq == htons(seq))
1425			return (1);
1426	}
1427	if (verbose) {
1428		char sbuf[NI_MAXHOST+1], dbuf[INET6_ADDRSTRLEN];
1429		u_int8_t *p;
1430		int i;
1431
1432		if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1433		    sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0)
1434			strlcpy(sbuf, "invalid", sizeof(sbuf));
1435		printf("\n%d bytes from %s to %s", cc, sbuf,
1436		    rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1437		    dbuf, sizeof(dbuf)) : "?");
1438		printf(": icmp type %d (%s) code %d\n", *type, pr_type(*type),
1439		    *code);
1440		p = (u_int8_t *)(icp + 1);
1441#define WIDTH	16
1442		for (i = 0; i < cc; i++) {
1443			if (i % WIDTH == 0)
1444				printf("%04x:", i);
1445			if (i % 4 == 0)
1446				printf(" ");
1447			printf("%02x", p[i]);
1448			if (i % WIDTH == WIDTH - 1)
1449				printf("\n");
1450		}
1451		if (cc % WIDTH != 0)
1452			printf("\n");
1453	}
1454	return (0);
1455}
1456
1457/*
1458 * Increment pointer until find the UDP or ICMP header.
1459 */
1460void *
1461get_uphdr(struct ip6_hdr *ip6, u_char *lim)
1462{
1463	u_char *cp = (u_char *)ip6, nh;
1464	int hlen;
1465	static u_char none_hdr[1]; /* Fake pointer for IPPROTO_NONE. */
1466
1467	if (cp + sizeof(*ip6) > lim)
1468		return (NULL);
1469
1470	nh = ip6->ip6_nxt;
1471	cp += sizeof(struct ip6_hdr);
1472
1473	while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) {
1474		switch (nh) {
1475		case IPPROTO_ESP:
1476			return (NULL);
1477		case IPPROTO_ICMPV6:
1478			return (useproto == nh ? cp : NULL);
1479		case IPPROTO_SCTP:
1480		case IPPROTO_TCP:
1481		case IPPROTO_UDP:
1482			return (useproto == nh ? cp : NULL);
1483		case IPPROTO_NONE:
1484			return (useproto == nh ? none_hdr : NULL);
1485		case IPPROTO_FRAGMENT:
1486			hlen = sizeof(struct ip6_frag);
1487			nh = ((struct ip6_frag *)cp)->ip6f_nxt;
1488			break;
1489		case IPPROTO_AH:
1490			hlen = (((struct ip6_ext *)cp)->ip6e_len + 2) << 2;
1491			nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1492			break;
1493		default:
1494			hlen = (((struct ip6_ext *)cp)->ip6e_len + 1) << 3;
1495			nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1496			break;
1497		}
1498
1499		cp += hlen;
1500	}
1501
1502	return (NULL);
1503}
1504
1505void
1506print(struct msghdr *mhdr, int cc)
1507{
1508	struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1509	char hbuf[NI_MAXHOST];
1510
1511	if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1512	    hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1513		strlcpy(hbuf, "invalid", sizeof(hbuf));
1514	if (as_path)
1515		printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6));
1516	if (nflag)
1517		printf(" %s", hbuf);
1518	else if (lflag)
1519		printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf);
1520	else
1521		printf(" %s", inetname((struct sockaddr *)from));
1522
1523	if (verbose) {
1524#ifdef OLDRAWSOCKET
1525		printf(" %d bytes to %s", cc,
1526		    rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1527		    hbuf, sizeof(hbuf)) : "?");
1528#else
1529		printf(" %d bytes of data to %s", cc,
1530		    rcvpktinfo ?  inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1531		    hbuf, sizeof(hbuf)) : "?");
1532#endif
1533	}
1534}
1535
1536/*
1537 * Construct an Internet address representation.
1538 * If the nflag has been supplied, give
1539 * numeric value, otherwise try for symbolic name.
1540 */
1541const char *
1542inetname(struct sockaddr *sa)
1543{
1544	static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1];
1545	static int first = 1;
1546	char *cp;
1547
1548	if (first && !nflag) {
1549		first = 0;
1550		if (gethostname(domain, sizeof(domain)) == 0 &&
1551		    (cp = strchr(domain, '.')))
1552			(void) strlcpy(domain, cp + 1, sizeof(domain));
1553		else
1554			domain[0] = 0;
1555	}
1556	cp = NULL;
1557	if (!nflag) {
1558		if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1559		    NI_NAMEREQD) == 0) {
1560			if ((cp = strchr(line, '.')) &&
1561			    !strcmp(cp + 1, domain))
1562				*cp = 0;
1563			cp = line;
1564		}
1565	}
1566	if (cp)
1567		return cp;
1568
1569	if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1570	    NI_NUMERICHOST) != 0)
1571		strlcpy(line, "invalid", sizeof(line));
1572	return line;
1573}
1574
1575/*
1576 * CRC32C routine for the Stream Control Transmission Protocol
1577 */
1578
1579#define CRC32C(c, d) (c = (c>>8) ^ crc_c[(c^(d))&0xFF])
1580
1581static u_int32_t crc_c[256] = {
1582	0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
1583	0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
1584	0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
1585	0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
1586	0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
1587	0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
1588	0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
1589	0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
1590	0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
1591	0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
1592	0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
1593	0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
1594	0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
1595	0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
1596	0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
1597	0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
1598	0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
1599	0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
1600	0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
1601	0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
1602	0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
1603	0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
1604	0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
1605	0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
1606	0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
1607	0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
1608	0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
1609	0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
1610	0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
1611	0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
1612	0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
1613	0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
1614	0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
1615	0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
1616	0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
1617	0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
1618	0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
1619	0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
1620	0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
1621	0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
1622	0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
1623	0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
1624	0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
1625	0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
1626	0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
1627	0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
1628	0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
1629	0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
1630	0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
1631	0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
1632	0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
1633	0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
1634	0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
1635	0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
1636	0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
1637	0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
1638	0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
1639	0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
1640	0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
1641	0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
1642	0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
1643	0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
1644	0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
1645	0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
1646};
1647
1648u_int32_t
1649sctp_crc32c(void *packet, u_int32_t len)
1650{
1651	u_int32_t i, crc32c;
1652	u_int8_t byte0, byte1, byte2, byte3;
1653	u_int8_t *buf = (u_int8_t *)packet;
1654
1655	crc32c = ~0;
1656	for (i = 0; i < len; i++)
1657		CRC32C(crc32c, buf[i]);
1658	crc32c = ~crc32c;
1659	byte0  = crc32c & 0xff;
1660	byte1  = (crc32c>>8) & 0xff;
1661	byte2  = (crc32c>>16) & 0xff;
1662	byte3  = (crc32c>>24) & 0xff;
1663	crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
1664	return htonl(crc32c);
1665}
1666
1667u_int16_t
1668in_cksum(u_int16_t *addr, int len)
1669{
1670	int nleft = len;
1671	u_int16_t *w = addr;
1672	u_int16_t answer;
1673	int sum = 0;
1674
1675	/*
1676	 *  Our algorithm is simple, using a 32 bit accumulator (sum),
1677	 *  we add sequential 16 bit words to it, and at the end, fold
1678	 *  back all the carry bits from the top 16 bits into the lower
1679	 *  16 bits.
1680	 */
1681	while (nleft > 1)  {
1682		sum += *w++;
1683		nleft -= 2;
1684	}
1685
1686	/* mop up an odd byte, if necessary */
1687	if (nleft == 1)
1688		sum += *(u_char *)w;
1689
1690	/*
1691	 * add back carry outs from top 16 bits to low 16 bits
1692	 */
1693	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
1694	sum += (sum >> 16);			/* add carry */
1695	answer = ~sum;				/* truncate to 16 bits */
1696	return (answer);
1697}
1698
1699u_int16_t
1700tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1701    void *payload, u_int32_t len)
1702{
1703	struct {
1704		struct in6_addr src;
1705		struct in6_addr dst;
1706		u_int32_t len;
1707		u_int8_t zero[3];
1708		u_int8_t next;
1709	} pseudo_hdr;
1710	u_int16_t sum[2];
1711
1712	pseudo_hdr.src = src->sin6_addr;
1713	pseudo_hdr.dst = dst->sin6_addr;
1714	pseudo_hdr.len = htonl(len);
1715	pseudo_hdr.zero[0] = 0;
1716	pseudo_hdr.zero[1] = 0;
1717	pseudo_hdr.zero[2] = 0;
1718	pseudo_hdr.next = IPPROTO_TCP;
1719
1720	sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1721	sum[0] = in_cksum(payload, len);
1722
1723	return (~in_cksum(sum, sizeof(sum)));
1724}
1725
1726void
1727usage(void)
1728{
1729
1730	fprintf(stderr,
1731"usage: traceroute6 [-adIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n"
1732"       [-m hoplimit] [-p port] [-q probes] [-s src] [-w waittime] target\n"
1733"       [datalen]\n");
1734	exit(1);
1735}
1736