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