xref: /freebsd/usr.sbin/traceroute6/traceroute6.c (revision 4f52dfbb8d6c4d446500c5b097e3806ec219fbd4)
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 u_char	packet[512];		/* last inbound (icmp) packet */
298 char 	*outpacket;		/* last output packet */
299 
300 int	main(int, char *[]);
301 int	wait_for_reply(int, struct msghdr *);
302 #ifdef IPSEC
303 #ifdef IPSEC_POLICY_IPSEC
304 int	setpolicy(int so, char *policy);
305 #endif
306 #endif
307 void	send_probe(int, u_long);
308 void	*get_uphdr(struct ip6_hdr *, u_char *);
309 int	get_hoplim(struct msghdr *);
310 double	deltaT(struct timeval *, struct timeval *);
311 const char *pr_type(int);
312 int	packet_ok(struct msghdr *, int, int);
313 void	print(struct msghdr *, int);
314 const char *inetname(struct sockaddr *);
315 u_int32_t sctp_crc32c(void *, u_int32_t);
316 u_int16_t in_cksum(u_int16_t *addr, int);
317 u_int16_t tcp_chksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
318     void *, u_int32_t);
319 void	usage(void);
320 
321 int rcvsock;			/* receive (icmp) socket file descriptor */
322 int sndsock;			/* send (raw/udp) socket file descriptor */
323 
324 struct msghdr rcvmhdr;
325 struct iovec rcviov[2];
326 int rcvhlim;
327 struct in6_pktinfo *rcvpktinfo;
328 
329 struct sockaddr_in6 Src, Dst, Rcv;
330 u_long datalen = 20;			/* How much data */
331 #define	ICMP6ECHOLEN	8
332 /* XXX: 2064 = 127(max hops in type 0 rthdr) * sizeof(ip6_hdr) + 16(margin) */
333 char rtbuf[2064];
334 #ifdef USE_RFC2292BIS
335 struct ip6_rthdr *rth;
336 #endif
337 struct cmsghdr *cmsg;
338 
339 char *source = NULL;
340 char *hostname;
341 
342 u_long nprobes = 3;
343 u_long first_hop = 1;
344 u_long max_hops = 30;
345 u_int16_t srcport;
346 u_int16_t port = 32768+666;	/* start udp dest port # for probe packets */
347 u_int16_t ident;
348 int options;			/* socket options */
349 int verbose;
350 int waittime = 5;		/* time to wait for response (in seconds) */
351 int nflag;			/* print addresses numerically */
352 int useproto = IPPROTO_UDP;	/* protocol to use to send packet */
353 int lflag;			/* print both numerical address & hostname */
354 int as_path;			/* print as numbers for each hop */
355 char *as_server = NULL;
356 void *asn;
357 
358 int
359 main(int argc, char *argv[])
360 {
361 	int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM };
362 	char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep;
363 	int ch, i, on = 1, seq, rcvcmsglen, error;
364 	struct addrinfo hints, *res;
365 	static u_char *rcvcmsgbuf;
366 	u_long probe, hops, lport;
367 	struct hostent *hp;
368 	size_t size, minlen;
369 	uid_t uid;
370 
371 	/*
372 	 * Receive ICMP
373 	 */
374 	if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
375 		perror("socket(ICMPv6)");
376 		exit(5);
377 	}
378 
379 	size = sizeof(i);
380 	(void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &i, &size, NULL, 0);
381 	max_hops = i;
382 
383 	/* specify to tell receiving interface */
384 #ifdef IPV6_RECVPKTINFO
385 	if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
386 	    sizeof(on)) < 0)
387 		err(1, "setsockopt(IPV6_RECVPKTINFO)");
388 #else  /* old adv. API */
389 	if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_PKTINFO, &on,
390 	    sizeof(on)) < 0)
391 		err(1, "setsockopt(IPV6_PKTINFO)");
392 #endif
393 
394 	/* specify to tell value of hoplimit field of received IP6 hdr */
395 #ifdef IPV6_RECVHOPLIMIT
396 	if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
397 	    sizeof(on)) < 0)
398 		err(1, "setsockopt(IPV6_RECVHOPLIMIT)");
399 #else  /* old adv. API */
400 	if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on,
401 	    sizeof(on)) < 0)
402 		err(1, "setsockopt(IPV6_HOPLIMIT)");
403 #endif
404 
405 	seq = 0;
406 	ident = htons(getpid() & 0xffff); /* same as ping6 */
407 
408 	while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:STUvw:")) != -1)
409 		switch (ch) {
410 		case 'a':
411 			as_path = 1;
412 			break;
413 		case 'A':
414 			as_path = 1;
415 			as_server = optarg;
416 			break;
417 		case 'd':
418 			options |= SO_DEBUG;
419 			break;
420 		case 'f':
421 			ep = NULL;
422 			errno = 0;
423 			first_hop = strtoul(optarg, &ep, 0);
424 			if (errno || !*optarg || *ep || first_hop > 255) {
425 				fprintf(stderr,
426 				    "traceroute6: invalid min hoplimit.\n");
427 				exit(1);
428 			}
429 			break;
430 		case 'g':
431 			hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno);
432 			if (hp == NULL) {
433 				fprintf(stderr,
434 				    "traceroute6: unknown host %s\n", optarg);
435 				exit(1);
436 			}
437 #ifdef USE_RFC2292BIS
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 #else  /* old advanced API */
459 			if (cmsg == NULL)
460 				cmsg = inet6_rthdr_init(rtbuf, IPV6_RTHDR_TYPE_0);
461 			inet6_rthdr_add(cmsg, (struct in6_addr *)hp->h_addr,
462 			    IPV6_RTHDR_LOOSE);
463 #endif
464 			freehostent(hp);
465 			break;
466 		case 'I':
467 			useproto = IPPROTO_ICMPV6;
468 			break;
469 		case 'l':
470 			lflag++;
471 			break;
472 		case 'm':
473 			ep = NULL;
474 			errno = 0;
475 			max_hops = strtoul(optarg, &ep, 0);
476 			if (errno || !*optarg || *ep || max_hops > 255) {
477 				fprintf(stderr,
478 				    "traceroute6: invalid max hoplimit.\n");
479 				exit(1);
480 			}
481 			break;
482 		case 'n':
483 			nflag++;
484 			break;
485 		case 'N':
486 			useproto = IPPROTO_NONE;
487 			break;
488 		case 'p':
489 			ep = NULL;
490 			errno = 0;
491 			lport = strtoul(optarg, &ep, 0);
492 			if (errno || !*optarg || *ep) {
493 				fprintf(stderr, "traceroute6: invalid port.\n");
494 				exit(1);
495 			}
496 			if (lport == 0 || lport != (lport & 0xffff)) {
497 				fprintf(stderr,
498 				    "traceroute6: port out of range.\n");
499 				exit(1);
500 			}
501 			port = lport & 0xffff;
502 			break;
503 		case 'q':
504 			ep = NULL;
505 			errno = 0;
506 			nprobes = strtoul(optarg, &ep, 0);
507 			if (errno || !*optarg || *ep) {
508 				fprintf(stderr,
509 				    "traceroute6: invalid nprobes.\n");
510 				exit(1);
511 			}
512 			if (nprobes < 1) {
513 				fprintf(stderr,
514 				    "traceroute6: nprobes must be >0.\n");
515 				exit(1);
516 			}
517 			break;
518 		case 'r':
519 			options |= SO_DONTROUTE;
520 			break;
521 		case 's':
522 			/*
523 			 * set the ip source address of the outbound
524 			 * probe (e.g., on a multi-homed host).
525 			 */
526 			source = optarg;
527 			break;
528 		case 'S':
529 			useproto = IPPROTO_SCTP;
530 			break;
531 		case 'T':
532 			useproto = IPPROTO_TCP;
533 			break;
534 		case 'U':
535 			useproto = IPPROTO_UDP;
536 			break;
537 		case 'v':
538 			verbose++;
539 			break;
540 		case 'w':
541 			ep = NULL;
542 			errno = 0;
543 			waittime = strtoul(optarg, &ep, 0);
544 			if (errno || !*optarg || *ep) {
545 				fprintf(stderr,
546 				    "traceroute6: invalid wait time.\n");
547 				exit(1);
548 			}
549 			if (waittime < 1) {
550 				fprintf(stderr,
551 				    "traceroute6: wait must be >= 1 sec.\n");
552 				exit(1);
553 			}
554 			break;
555 		default:
556 			usage();
557 		}
558 	argc -= optind;
559 	argv += optind;
560 
561 	/*
562 	 * Open socket to send probe packets.
563 	 */
564 	switch (useproto) {
565 	case IPPROTO_ICMPV6:
566 		sndsock = rcvsock;
567 		break;
568 	case IPPROTO_UDP:
569 		if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
570 			perror("socket(SOCK_DGRAM)");
571 			exit(5);
572 		}
573 		break;
574 	case IPPROTO_NONE:
575 	case IPPROTO_SCTP:
576 	case IPPROTO_TCP:
577 		if ((sndsock = socket(AF_INET6, SOCK_RAW, useproto)) < 0) {
578 			perror("socket(SOCK_RAW)");
579 			exit(5);
580 		}
581 		break;
582 	default:
583 		fprintf(stderr, "traceroute6: unknown probe protocol %d\n",
584 		    useproto);
585 		exit(5);
586 	}
587 	if (max_hops < first_hop) {
588 		fprintf(stderr,
589 		    "traceroute6: max hoplimit must be larger than first hoplimit.\n");
590 		exit(1);
591 	}
592 
593 	/* revoke privs */
594 	uid = getuid();
595 	if (setresuid(uid, uid, uid) == -1) {
596 		perror("setresuid");
597 		exit(1);
598 	}
599 
600 
601 	if (argc < 1 || argc > 2)
602 		usage();
603 
604 #if 1
605 	setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
606 #else
607 	setlinebuf(stdout);
608 #endif
609 
610 	memset(&hints, 0, sizeof(hints));
611 	hints.ai_family = PF_INET6;
612 	hints.ai_socktype = SOCK_RAW;
613 	hints.ai_protocol = IPPROTO_ICMPV6;
614 	hints.ai_flags = AI_CANONNAME;
615 	error = getaddrinfo(*argv, NULL, &hints, &res);
616 	if (error) {
617 		fprintf(stderr,
618 		    "traceroute6: %s\n", gai_strerror(error));
619 		exit(1);
620 	}
621 	if (res->ai_addrlen != sizeof(Dst)) {
622 		fprintf(stderr,
623 		    "traceroute6: size of sockaddr mismatch\n");
624 		exit(1);
625 	}
626 	memcpy(&Dst, res->ai_addr, res->ai_addrlen);
627 	hostname = res->ai_canonname ? strdup(res->ai_canonname) : *argv;
628 	if (!hostname) {
629 		fprintf(stderr, "traceroute6: not enough core\n");
630 		exit(1);
631 	}
632 	if (res->ai_next) {
633 		if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf,
634 		    sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
635 			strlcpy(hbuf, "?", sizeof(hbuf));
636 		fprintf(stderr, "traceroute6: Warning: %s has multiple "
637 		    "addresses; using %s\n", hostname, hbuf);
638 	}
639 
640 	if (*++argv) {
641 		ep = NULL;
642 		errno = 0;
643 		datalen = strtoul(*argv, &ep, 0);
644 		if (errno || *ep) {
645 			fprintf(stderr,
646 			    "traceroute6: invalid packet length.\n");
647 			exit(1);
648 		}
649 	}
650 	switch (useproto) {
651 	case IPPROTO_ICMPV6:
652 		minlen = ICMP6ECHOLEN;
653 		break;
654 	case IPPROTO_UDP:
655 		minlen = sizeof(struct udphdr);
656 		break;
657 	case IPPROTO_NONE:
658 		minlen = 0;
659 		datalen = 0;
660 		break;
661 	case IPPROTO_SCTP:
662 		minlen = sizeof(struct sctphdr);
663 		break;
664 	case IPPROTO_TCP:
665 		minlen = sizeof(struct tcphdr);
666 		break;
667 	default:
668 		fprintf(stderr, "traceroute6: unknown probe protocol %d.\n",
669 		    useproto);
670 		exit(1);
671 	}
672 	if (datalen < minlen)
673 		datalen = minlen;
674 	else if (datalen >= MAXPACKET) {
675 		fprintf(stderr,
676 		    "traceroute6: packet size must be %zu <= s < %d.\n",
677 		    minlen, MAXPACKET);
678 		exit(1);
679 	}
680 	if (useproto == IPPROTO_UDP)
681 		datalen -= sizeof(struct udphdr);
682 	if ((useproto == IPPROTO_SCTP) && (datalen & 3)) {
683 		fprintf(stderr,
684 		    "traceroute6: packet size must be a multiple of 4.\n");
685 		exit(1);
686 	}
687 	outpacket = malloc(datalen);
688 	if (!outpacket) {
689 		perror("malloc");
690 		exit(1);
691 	}
692 	(void) bzero((char *)outpacket, datalen);
693 
694 	/* initialize msghdr for receiving packets */
695 	rcviov[0].iov_base = (caddr_t)packet;
696 	rcviov[0].iov_len = sizeof(packet);
697 	rcvmhdr.msg_name = (caddr_t)&Rcv;
698 	rcvmhdr.msg_namelen = sizeof(Rcv);
699 	rcvmhdr.msg_iov = rcviov;
700 	rcvmhdr.msg_iovlen = 1;
701 	rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
702 	    CMSG_SPACE(sizeof(int));
703 	if ((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) {
704 		fprintf(stderr, "traceroute6: malloc failed\n");
705 		exit(1);
706 	}
707 	rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf;
708 	rcvmhdr.msg_controllen = rcvcmsglen;
709 
710 	if (options & SO_DEBUG)
711 		(void) setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG,
712 		    (char *)&on, sizeof(on));
713 	if (options & SO_DONTROUTE)
714 		(void) setsockopt(rcvsock, SOL_SOCKET, SO_DONTROUTE,
715 		    (char *)&on, sizeof(on));
716 #ifdef IPSEC
717 #ifdef IPSEC_POLICY_IPSEC
718 	/*
719 	 * do not raise error even if setsockopt fails, kernel may have ipsec
720 	 * turned off.
721 	 */
722 	if (setpolicy(rcvsock, "in bypass") < 0)
723 		errx(1, "%s", ipsec_strerror());
724 	if (setpolicy(rcvsock, "out bypass") < 0)
725 		errx(1, "%s", ipsec_strerror());
726 #else
727     {
728 	int level = IPSEC_LEVEL_NONE;
729 
730 	(void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
731 	    sizeof(level));
732 	(void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
733 	    sizeof(level));
734 #ifdef IP_AUTH_TRANS_LEVEL
735 	(void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
736 	    sizeof(level));
737 #else
738 	(void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
739 	    sizeof(level));
740 #endif
741 #ifdef IP_AUTH_NETWORK_LEVEL
742 	(void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
743 	    sizeof(level));
744 #endif
745     }
746 #endif /*IPSEC_POLICY_IPSEC*/
747 #endif /*IPSEC*/
748 
749 #ifdef SO_SNDBUF
750 	i = datalen;
751 	if (i == 0)
752 		i = 1;
753 	if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&i,
754 	    sizeof(i)) < 0) {
755 		perror("setsockopt(SO_SNDBUF)");
756 		exit(6);
757 	}
758 #endif /* SO_SNDBUF */
759 	if (options & SO_DEBUG)
760 		(void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
761 		    (char *)&on, sizeof(on));
762 	if (options & SO_DONTROUTE)
763 		(void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
764 		    (char *)&on, sizeof(on));
765 #ifdef USE_RFC2292BIS
766 	if (rth) {/* XXX: there is no library to finalize the header... */
767 		rth->ip6r_len = rth->ip6r_segleft * 2;
768 		if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_RTHDR,
769 		    (void *)rth, (rth->ip6r_len + 1) << 3)) {
770 			fprintf(stderr, "setsockopt(IPV6_RTHDR): %s\n",
771 			    strerror(errno));
772 			exit(1);
773 		}
774 	}
775 #else  /* old advanced API */
776 	if (cmsg != NULL) {
777 		inet6_rthdr_lasthop(cmsg, IPV6_RTHDR_LOOSE);
778 		if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_PKTOPTIONS,
779 		    rtbuf, cmsg->cmsg_len) < 0) {
780 			fprintf(stderr, "setsockopt(IPV6_PKTOPTIONS): %s\n",
781 			    strerror(errno));
782 			exit(1);
783 		}
784 	}
785 #endif /* USE_RFC2292BIS */
786 #ifdef IPSEC
787 #ifdef IPSEC_POLICY_IPSEC
788 	/*
789 	 * do not raise error even if setsockopt fails, kernel may have ipsec
790 	 * turned off.
791 	 */
792 	if (setpolicy(sndsock, "in bypass") < 0)
793 		errx(1, "%s", ipsec_strerror());
794 	if (setpolicy(sndsock, "out bypass") < 0)
795 		errx(1, "%s", ipsec_strerror());
796 #else
797     {
798 	int level = IPSEC_LEVEL_BYPASS;
799 
800 	(void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
801 	    sizeof(level));
802 	(void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
803 	    sizeof(level));
804 #ifdef IP_AUTH_TRANS_LEVEL
805 	(void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
806 	    sizeof(level));
807 #else
808 	(void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
809 	    sizeof(level));
810 #endif
811 #ifdef IP_AUTH_NETWORK_LEVEL
812 	(void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
813 	    sizeof(level));
814 #endif
815     }
816 #endif /*IPSEC_POLICY_IPSEC*/
817 #endif /*IPSEC*/
818 
819 	/*
820 	 * Source selection
821 	 */
822 	bzero(&Src, sizeof(Src));
823 	if (source) {
824 		struct addrinfo hints, *res;
825 		int error;
826 
827 		memset(&hints, 0, sizeof(hints));
828 		hints.ai_family = AF_INET6;
829 		hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
830 		hints.ai_flags = AI_NUMERICHOST;
831 		error = getaddrinfo(source, "0", &hints, &res);
832 		if (error) {
833 			printf("traceroute6: %s: %s\n", source,
834 			    gai_strerror(error));
835 			exit(1);
836 		}
837 		if (res->ai_addrlen > sizeof(Src)) {
838 			printf("traceroute6: %s: %s\n", source,
839 			    gai_strerror(error));
840 			exit(1);
841 		}
842 		memcpy(&Src, res->ai_addr, res->ai_addrlen);
843 		freeaddrinfo(res);
844 	} else {
845 		struct sockaddr_in6 Nxt;
846 		int dummy;
847 		socklen_t len;
848 
849 		Nxt = Dst;
850 		Nxt.sin6_port = htons(DUMMY_PORT);
851 		if (cmsg != NULL)
852 			bcopy(inet6_rthdr_getaddr(cmsg, 1), &Nxt.sin6_addr,
853 			    sizeof(Nxt.sin6_addr));
854 		if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
855 			perror("socket");
856 			exit(1);
857 		}
858 		if (connect(dummy, (struct sockaddr *)&Nxt, Nxt.sin6_len) < 0) {
859 			perror("connect");
860 			exit(1);
861 		}
862 		len = sizeof(Src);
863 		if (getsockname(dummy, (struct sockaddr *)&Src, &len) < 0) {
864 			perror("getsockname");
865 			exit(1);
866 		}
867 		if (getnameinfo((struct sockaddr *)&Src, Src.sin6_len,
868 		    src0, sizeof(src0), NULL, 0, NI_NUMERICHOST)) {
869 			fprintf(stderr, "getnameinfo failed for source\n");
870 			exit(1);
871 		}
872 		source = src0;
873 		close(dummy);
874 	}
875 
876 	Src.sin6_port = htons(0);
877 	if (bind(sndsock, (struct sockaddr *)&Src, Src.sin6_len) < 0) {
878 		perror("bind");
879 		exit(1);
880 	}
881 
882 	{
883 		socklen_t len;
884 
885 		len = sizeof(Src);
886 		if (getsockname(sndsock, (struct sockaddr *)&Src, &len) < 0) {
887 			perror("getsockname");
888 			exit(1);
889 		}
890 		srcport = ntohs(Src.sin6_port);
891 	}
892 
893 	if (as_path) {
894 		asn = as_setup(as_server);
895 		if (asn == NULL) {
896 			fprintf(stderr,
897 			    "traceroute6: as_setup failed, AS# lookups"
898 			    " disabled\n");
899 			(void)fflush(stderr);
900 			as_path = 0;
901 		}
902 	}
903 
904 	/*
905 	 * Message to users
906 	 */
907 	if (getnameinfo((struct sockaddr *)&Dst, Dst.sin6_len, hbuf,
908 	    sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
909 		strlcpy(hbuf, "(invalid)", sizeof(hbuf));
910 	fprintf(stderr, "traceroute6");
911 	fprintf(stderr, " to %s (%s)", hostname, hbuf);
912 	if (source)
913 		fprintf(stderr, " from %s", source);
914 	fprintf(stderr, ", %lu hops max, %lu byte packets\n",
915 	    max_hops,
916 	    datalen + ((useproto == IPPROTO_UDP) ? sizeof(struct udphdr) : 0));
917 	(void) fflush(stderr);
918 
919 	if (first_hop > 1)
920 		printf("Skipping %lu intermediate hops\n", first_hop - 1);
921 
922 	/*
923 	 * Main loop
924 	 */
925 	for (hops = first_hop; hops <= max_hops; ++hops) {
926 		struct in6_addr lastaddr;
927 		int got_there = 0;
928 		unsigned unreachable = 0;
929 
930 		printf("%2lu ", hops);
931 		bzero(&lastaddr, sizeof(lastaddr));
932 		for (probe = 0; probe < nprobes; ++probe) {
933 			int cc;
934 			struct timeval t1, t2;
935 
936 			(void) gettimeofday(&t1, NULL);
937 			send_probe(++seq, hops);
938 			while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) {
939 				(void) gettimeofday(&t2, NULL);
940 				if ((i = packet_ok(&rcvmhdr, cc, seq))) {
941 					if (!IN6_ARE_ADDR_EQUAL(&Rcv.sin6_addr,
942 					    &lastaddr)) {
943 						if (probe > 0)
944 							fputs("\n   ", stdout);
945 						print(&rcvmhdr, cc);
946 						lastaddr = Rcv.sin6_addr;
947 					}
948 					printf("  %.3f ms", deltaT(&t1, &t2));
949 					switch (i - 1) {
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 					break;
974 				} else if (deltaT(&t1, &t2) > waittime * 1000) {
975 					cc = 0;
976 					break;
977 				}
978 			}
979 			if (cc == 0)
980 				printf(" *");
981 			(void) fflush(stdout);
982 		}
983 		putchar('\n');
984 		if (got_there ||
985 		    (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) {
986 			exit(0);
987 		}
988 	}
989 	if (as_path)
990 		as_shutdown(asn);
991 
992 	exit(0);
993 }
994 
995 int
996 wait_for_reply(int sock, struct msghdr *mhdr)
997 {
998 #ifdef HAVE_POLL
999 	struct pollfd pfd[1];
1000 	int cc = 0;
1001 
1002 	pfd[0].fd = sock;
1003 	pfd[0].events = POLLIN;
1004 	pfd[0].revents = 0;
1005 
1006 	if (poll(pfd, 1, waittime * 1000) > 0)
1007 		cc = recvmsg(rcvsock, mhdr, 0);
1008 
1009 	return(cc);
1010 #else
1011 	fd_set *fdsp;
1012 	struct timeval wait;
1013 	int cc = 0, fdsn;
1014 
1015 	fdsn = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
1016 	if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
1017 		err(1, "malloc");
1018 	memset(fdsp, 0, fdsn);
1019 	FD_SET(sock, fdsp);
1020 	wait.tv_sec = waittime; wait.tv_usec = 0;
1021 
1022 	if (select(sock+1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0)
1023 		cc = recvmsg(rcvsock, mhdr, 0);
1024 
1025 	free(fdsp);
1026 	return(cc);
1027 #endif
1028 }
1029 
1030 #ifdef IPSEC
1031 #ifdef IPSEC_POLICY_IPSEC
1032 int
1033 setpolicy(so, policy)
1034 	int so;
1035 	char *policy;
1036 {
1037 	char *buf;
1038 
1039 	buf = ipsec_set_policy(policy, strlen(policy));
1040 	if (buf == NULL) {
1041 		warnx("%s", ipsec_strerror());
1042 		return -1;
1043 	}
1044 	(void)setsockopt(so, IPPROTO_IPV6, IPV6_IPSEC_POLICY,
1045 	    buf, ipsec_get_policylen(buf));
1046 
1047 	free(buf);
1048 
1049 	return 0;
1050 }
1051 #endif
1052 #endif
1053 
1054 void
1055 send_probe(int seq, u_long hops)
1056 {
1057 	struct icmp6_hdr *icp;
1058 	struct sctphdr *sctp;
1059 	struct sctp_chunkhdr *chk;
1060 	struct sctp_init_chunk *init;
1061 	struct sctp_paramhdr *param;
1062 	struct tcphdr *tcp;
1063 	int i;
1064 
1065 	i = hops;
1066 	if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
1067 	    (char *)&i, sizeof(i)) < 0) {
1068 		perror("setsockopt IPV6_UNICAST_HOPS");
1069 	}
1070 
1071 	Dst.sin6_port = htons(port + seq);
1072 
1073 	switch (useproto) {
1074 	case IPPROTO_ICMPV6:
1075 		icp = (struct icmp6_hdr *)outpacket;
1076 
1077 		icp->icmp6_type = ICMP6_ECHO_REQUEST;
1078 		icp->icmp6_code = 0;
1079 		icp->icmp6_cksum = 0;
1080 		icp->icmp6_id = ident;
1081 		icp->icmp6_seq = htons(seq);
1082 		break;
1083 	case IPPROTO_UDP:
1084 		break;
1085 	case IPPROTO_NONE:
1086 		/* No space for anything. No harm as seq/tv32 are decorative. */
1087 		break;
1088 	case IPPROTO_SCTP:
1089 		sctp = (struct sctphdr *)outpacket;
1090 
1091 		sctp->src_port = htons(ident);
1092 		sctp->dest_port = htons(port + seq);
1093 		if (datalen >= (u_long)(sizeof(struct sctphdr) +
1094 		    sizeof(struct sctp_init_chunk))) {
1095 			sctp->v_tag = 0;
1096 		} else {
1097 			sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port;
1098 		}
1099 		sctp->checksum = htonl(0);
1100 		if (datalen >= (u_long)(sizeof(struct sctphdr) +
1101 		    sizeof(struct sctp_init_chunk))) {
1102 			/*
1103 			 * Send a packet containing an INIT chunk. This works
1104 			 * better in case of firewalls on the path, but
1105 			 * results in a probe packet containing at least
1106 			 * 32 bytes of payload. For shorter payloads, use
1107 			 * SHUTDOWN-ACK chunks.
1108 			 */
1109 			init = (struct sctp_init_chunk *)(sctp + 1);
1110 			init->ch.chunk_type = SCTP_INITIATION;
1111 			init->ch.chunk_flags = 0;
1112 			init->ch.chunk_length = htons((u_int16_t)(datalen -
1113 			    sizeof(struct sctphdr)));
1114 			init->init.initiate_tag = (sctp->src_port << 16) |
1115 			    sctp->dest_port;
1116 			init->init.a_rwnd = htonl(1500);
1117 			init->init.num_outbound_streams = htons(1);
1118 			init->init.num_inbound_streams = htons(1);
1119 			init->init.initial_tsn = htonl(0);
1120 			if (datalen >= (u_long)(sizeof(struct sctphdr) +
1121 			    sizeof(struct sctp_init_chunk) +
1122 			    sizeof(struct sctp_paramhdr))) {
1123 				param = (struct sctp_paramhdr *)(init + 1);
1124 				param->param_type = htons(SCTP_PAD);
1125 				param->param_length =
1126 				    htons((u_int16_t)(datalen -
1127 				    sizeof(struct sctphdr) -
1128 				    sizeof(struct sctp_init_chunk)));
1129 			}
1130 		} else {
1131 			/*
1132 			 * Send a packet containing a SHUTDOWN-ACK chunk,
1133 			 * possibly followed by a PAD chunk.
1134 			 */
1135 			if (datalen >= (u_long)(sizeof(struct sctphdr) +
1136 			    sizeof(struct sctp_chunkhdr))) {
1137 				chk = (struct sctp_chunkhdr *)(sctp + 1);
1138 				chk->chunk_type = SCTP_SHUTDOWN_ACK;
1139 				chk->chunk_flags = 0;
1140 				chk->chunk_length = htons(4);
1141 			}
1142 			if (datalen >= (u_long)(sizeof(struct sctphdr) +
1143 			    2 * sizeof(struct sctp_chunkhdr))) {
1144 				chk = chk + 1;
1145 				chk->chunk_type = SCTP_PAD_CHUNK;
1146 				chk->chunk_flags = 0;
1147 				chk->chunk_length = htons((u_int16_t)(datalen -
1148 				    sizeof(struct sctphdr) -
1149 				    sizeof(struct sctp_chunkhdr)));
1150 			}
1151 		}
1152 		sctp->checksum = sctp_crc32c(outpacket, datalen);
1153 		break;
1154 	case IPPROTO_TCP:
1155 		tcp = (struct tcphdr *)outpacket;
1156 
1157 		tcp->th_sport = htons(ident);
1158 		tcp->th_dport = htons(port + seq);
1159 		tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
1160 		tcp->th_ack = 0;
1161 		tcp->th_off = 5;
1162 		tcp->th_flags = TH_SYN;
1163 		tcp->th_sum = 0;
1164 		tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen);
1165 		break;
1166 	default:
1167 		fprintf(stderr, "Unknown probe protocol %d.\n", useproto);
1168 		exit(1);
1169 	}
1170 
1171 	i = sendto(sndsock, (char *)outpacket, datalen, 0,
1172 	    (struct sockaddr *)&Dst, Dst.sin6_len);
1173 	if (i < 0 || (u_long)i != datalen)  {
1174 		if (i < 0)
1175 			perror("sendto");
1176 		printf("traceroute6: wrote %s %lu chars, ret=%d\n",
1177 		    hostname, datalen, i);
1178 		(void) fflush(stdout);
1179 	}
1180 }
1181 
1182 int
1183 get_hoplim(struct msghdr *mhdr)
1184 {
1185 	struct cmsghdr *cm;
1186 
1187 	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1188 	    cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1189 		if (cm->cmsg_level == IPPROTO_IPV6 &&
1190 		    cm->cmsg_type == IPV6_HOPLIMIT &&
1191 		    cm->cmsg_len == CMSG_LEN(sizeof(int)))
1192 			return(*(int *)CMSG_DATA(cm));
1193 	}
1194 
1195 	return(-1);
1196 }
1197 
1198 double
1199 deltaT(struct timeval *t1p, struct timeval *t2p)
1200 {
1201 	double dt;
1202 
1203 	dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1204 	    (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1205 	return (dt);
1206 }
1207 
1208 /*
1209  * Convert an ICMP "type" field to a printable string.
1210  */
1211 const char *
1212 pr_type(int t0)
1213 {
1214 	u_char t = t0 & 0xff;
1215 	const char *cp;
1216 
1217 	switch (t) {
1218 	case ICMP6_DST_UNREACH:
1219 		cp = "Destination Unreachable";
1220 		break;
1221 	case ICMP6_PACKET_TOO_BIG:
1222 		cp = "Packet Too Big";
1223 		break;
1224 	case ICMP6_TIME_EXCEEDED:
1225 		cp = "Time Exceeded";
1226 		break;
1227 	case ICMP6_PARAM_PROB:
1228 		cp = "Parameter Problem";
1229 		break;
1230 	case ICMP6_ECHO_REQUEST:
1231 		cp = "Echo Request";
1232 		break;
1233 	case ICMP6_ECHO_REPLY:
1234 		cp = "Echo Reply";
1235 		break;
1236 	case ICMP6_MEMBERSHIP_QUERY:
1237 		cp = "Group Membership Query";
1238 		break;
1239 	case ICMP6_MEMBERSHIP_REPORT:
1240 		cp = "Group Membership Report";
1241 		break;
1242 	case ICMP6_MEMBERSHIP_REDUCTION:
1243 		cp = "Group Membership Reduction";
1244 		break;
1245 	case ND_ROUTER_SOLICIT:
1246 		cp = "Router Solicitation";
1247 		break;
1248 	case ND_ROUTER_ADVERT:
1249 		cp = "Router Advertisement";
1250 		break;
1251 	case ND_NEIGHBOR_SOLICIT:
1252 		cp = "Neighbor Solicitation";
1253 		break;
1254 	case ND_NEIGHBOR_ADVERT:
1255 		cp = "Neighbor Advertisement";
1256 		break;
1257 	case ND_REDIRECT:
1258 		cp = "Redirect";
1259 		break;
1260 	default:
1261 		cp = "Unknown";
1262 		break;
1263 	}
1264 	return cp;
1265 }
1266 
1267 int
1268 packet_ok(struct msghdr *mhdr, int cc, int seq)
1269 {
1270 	struct icmp6_hdr *icp;
1271 	struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1272 	u_char type, code;
1273 	char *buf = (char *)mhdr->msg_iov[0].iov_base;
1274 	struct cmsghdr *cm;
1275 	int *hlimp;
1276 	char hbuf[NI_MAXHOST];
1277 
1278 #ifdef OLDRAWSOCKET
1279 	int hlen;
1280 	struct ip6_hdr *ip;
1281 #endif
1282 
1283 #ifdef OLDRAWSOCKET
1284 	ip = (struct ip6_hdr *) buf;
1285 	hlen = sizeof(struct ip6_hdr);
1286 	if (cc < hlen + sizeof(struct icmp6_hdr)) {
1287 		if (verbose) {
1288 			if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1289 			    hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1290 				strlcpy(hbuf, "invalid", sizeof(hbuf));
1291 			printf("packet too short (%d bytes) from %s\n", cc,
1292 			    hbuf);
1293 		}
1294 		return (0);
1295 	}
1296 	cc -= hlen;
1297 	icp = (struct icmp6_hdr *)(buf + hlen);
1298 #else
1299 	if (cc < (int)sizeof(struct icmp6_hdr)) {
1300 		if (verbose) {
1301 			if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1302 			    hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1303 				strlcpy(hbuf, "invalid", sizeof(hbuf));
1304 			printf("data too short (%d bytes) from %s\n", cc, hbuf);
1305 		}
1306 		return(0);
1307 	}
1308 	icp = (struct icmp6_hdr *)buf;
1309 #endif
1310 	/* get optional information via advanced API */
1311 	rcvpktinfo = NULL;
1312 	hlimp = NULL;
1313 	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1314 	    cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1315 		if (cm->cmsg_level == IPPROTO_IPV6 &&
1316 		    cm->cmsg_type == IPV6_PKTINFO &&
1317 		    cm->cmsg_len ==
1318 		    CMSG_LEN(sizeof(struct in6_pktinfo)))
1319 			rcvpktinfo = (struct in6_pktinfo *)(CMSG_DATA(cm));
1320 
1321 		if (cm->cmsg_level == IPPROTO_IPV6 &&
1322 		    cm->cmsg_type == IPV6_HOPLIMIT &&
1323 		    cm->cmsg_len == CMSG_LEN(sizeof(int)))
1324 			hlimp = (int *)CMSG_DATA(cm);
1325 	}
1326 	if (rcvpktinfo == NULL || hlimp == NULL) {
1327 		warnx("failed to get received hop limit or packet info");
1328 #if 0
1329 		return(0);
1330 #else
1331 		rcvhlim = 0;	/*XXX*/
1332 #endif
1333 	}
1334 	else
1335 		rcvhlim = *hlimp;
1336 
1337 	type = icp->icmp6_type;
1338 	code = icp->icmp6_code;
1339 	if ((type == ICMP6_TIME_EXCEEDED && code == ICMP6_TIME_EXCEED_TRANSIT)
1340 	    || type == ICMP6_DST_UNREACH) {
1341 		struct ip6_hdr *hip;
1342 		struct icmp6_hdr *icmp;
1343 		struct sctp_init_chunk *init;
1344 		struct sctphdr *sctp;
1345 		struct tcphdr *tcp;
1346 		struct udphdr *udp;
1347 		void *up;
1348 
1349 		hip = (struct ip6_hdr *)(icp + 1);
1350 		if ((up = get_uphdr(hip, (u_char *)(buf + cc))) == NULL) {
1351 			if (verbose)
1352 				warnx("failed to get upper layer header");
1353 			return(0);
1354 		}
1355 		switch (useproto) {
1356 		case IPPROTO_ICMPV6:
1357 			icmp = (struct icmp6_hdr *)up;
1358 			if (icmp->icmp6_id == ident &&
1359 			    icmp->icmp6_seq == htons(seq))
1360 				return (type == ICMP6_TIME_EXCEEDED ?
1361 				    -1 : code + 1);
1362 			break;
1363 		case IPPROTO_UDP:
1364 			udp = (struct udphdr *)up;
1365 			if (udp->uh_sport == htons(srcport) &&
1366 			    udp->uh_dport == htons(port + seq))
1367 				return (type == ICMP6_TIME_EXCEEDED ?
1368 				    -1 : code + 1);
1369 			break;
1370 		case IPPROTO_SCTP:
1371 			sctp = (struct sctphdr *)up;
1372 			if (sctp->src_port != htons(ident) ||
1373 			    sctp->dest_port != htons(port + seq)) {
1374 				break;
1375 			}
1376 			if (datalen >= (u_long)(sizeof(struct sctphdr) +
1377 			    sizeof(struct sctp_init_chunk))) {
1378 				if (sctp->v_tag != 0) {
1379 					break;
1380 				}
1381 				init = (struct sctp_init_chunk *)(sctp + 1);
1382 				/* Check the initiate tag, if available. */
1383 				if ((char *)&init->init.a_rwnd > buf + cc) {
1384 					return (type == ICMP6_TIME_EXCEEDED ?
1385 					    -1 : code + 1);
1386 				}
1387 				if (init->init.initiate_tag == (u_int32_t)
1388 				    ((sctp->src_port << 16) | sctp->dest_port)) {
1389 					return (type == ICMP6_TIME_EXCEEDED ?
1390 					    -1 : code + 1);
1391 				}
1392 			} else {
1393 				if (sctp->v_tag ==
1394 				    (u_int32_t)((sctp->src_port << 16) |
1395 				    sctp->dest_port)) {
1396 					return (type == ICMP6_TIME_EXCEEDED ?
1397 					    -1 : code + 1);
1398 				}
1399 			}
1400 			break;
1401 		case IPPROTO_TCP:
1402 			tcp = (struct tcphdr *)up;
1403 			if (tcp->th_sport == htons(ident) &&
1404 			    tcp->th_dport == htons(port + seq) &&
1405 			    tcp->th_seq ==
1406 			    (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport))
1407 				return (type == ICMP6_TIME_EXCEEDED ?
1408 				    -1 : code + 1);
1409 			break;
1410 		case IPPROTO_NONE:
1411 			return (type == ICMP6_TIME_EXCEEDED ?  -1 : code + 1);
1412 		default:
1413 			fprintf(stderr, "Unknown probe proto %d.\n", useproto);
1414 			break;
1415 		}
1416 	} else if (useproto == IPPROTO_ICMPV6 && type == ICMP6_ECHO_REPLY) {
1417 		if (icp->icmp6_id == ident &&
1418 		    icp->icmp6_seq == htons(seq))
1419 			return (ICMP6_DST_UNREACH_NOPORT + 1);
1420 	}
1421 	if (verbose) {
1422 		char sbuf[NI_MAXHOST+1], dbuf[INET6_ADDRSTRLEN];
1423 		u_int8_t *p;
1424 		int i;
1425 
1426 		if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1427 		    sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0)
1428 			strlcpy(sbuf, "invalid", sizeof(sbuf));
1429 		printf("\n%d bytes from %s to %s", cc, sbuf,
1430 		    rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1431 		    dbuf, sizeof(dbuf)) : "?");
1432 		printf(": icmp type %d (%s) code %d\n", type, pr_type(type),
1433 		    icp->icmp6_code);
1434 		p = (u_int8_t *)(icp + 1);
1435 #define WIDTH	16
1436 		for (i = 0; i < cc; i++) {
1437 			if (i % WIDTH == 0)
1438 				printf("%04x:", i);
1439 			if (i % 4 == 0)
1440 				printf(" ");
1441 			printf("%02x", p[i]);
1442 			if (i % WIDTH == WIDTH - 1)
1443 				printf("\n");
1444 		}
1445 		if (cc % WIDTH != 0)
1446 			printf("\n");
1447 	}
1448 	return(0);
1449 }
1450 
1451 /*
1452  * Increment pointer until find the UDP or ICMP header.
1453  */
1454 void *
1455 get_uphdr(struct ip6_hdr *ip6, u_char *lim)
1456 {
1457 	u_char *cp = (u_char *)ip6, nh;
1458 	int hlen;
1459 	static u_char none_hdr[1]; /* Fake pointer for IPPROTO_NONE. */
1460 
1461 	if (cp + sizeof(*ip6) > lim)
1462 		return(NULL);
1463 
1464 	nh = ip6->ip6_nxt;
1465 	cp += sizeof(struct ip6_hdr);
1466 
1467 	while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) {
1468 		switch (nh) {
1469 		case IPPROTO_ESP:
1470 			return(NULL);
1471 		case IPPROTO_ICMPV6:
1472 			return(useproto == nh ? cp : NULL);
1473 		case IPPROTO_SCTP:
1474 		case IPPROTO_TCP:
1475 		case IPPROTO_UDP:
1476 			return(useproto == nh ? cp : NULL);
1477 		case IPPROTO_NONE:
1478 			return(useproto == nh ? none_hdr : NULL);
1479 		case IPPROTO_FRAGMENT:
1480 			hlen = sizeof(struct ip6_frag);
1481 			nh = ((struct ip6_frag *)cp)->ip6f_nxt;
1482 			break;
1483 		case IPPROTO_AH:
1484 			hlen = (((struct ip6_ext *)cp)->ip6e_len + 2) << 2;
1485 			nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1486 			break;
1487 		default:
1488 			hlen = (((struct ip6_ext *)cp)->ip6e_len + 1) << 3;
1489 			nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1490 			break;
1491 		}
1492 
1493 		cp += hlen;
1494 	}
1495 
1496 	return(NULL);
1497 }
1498 
1499 void
1500 print(struct msghdr *mhdr, int cc)
1501 {
1502 	struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1503 	char hbuf[NI_MAXHOST];
1504 
1505 	if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1506 	    hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1507 		strlcpy(hbuf, "invalid", sizeof(hbuf));
1508 	if (as_path)
1509 		printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6));
1510 	if (nflag)
1511 		printf(" %s", hbuf);
1512 	else if (lflag)
1513 		printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf);
1514 	else
1515 		printf(" %s", inetname((struct sockaddr *)from));
1516 
1517 	if (verbose) {
1518 #ifdef OLDRAWSOCKET
1519 		printf(" %d bytes to %s", cc,
1520 		    rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1521 		    hbuf, sizeof(hbuf)) : "?");
1522 #else
1523 		printf(" %d bytes of data to %s", cc,
1524 		    rcvpktinfo ?  inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1525 		    hbuf, sizeof(hbuf)) : "?");
1526 #endif
1527 	}
1528 }
1529 
1530 /*
1531  * Construct an Internet address representation.
1532  * If the nflag has been supplied, give
1533  * numeric value, otherwise try for symbolic name.
1534  */
1535 const char *
1536 inetname(struct sockaddr *sa)
1537 {
1538 	static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1];
1539 	static int first = 1;
1540 	char *cp;
1541 
1542 	if (first && !nflag) {
1543 		first = 0;
1544 		if (gethostname(domain, sizeof(domain)) == 0 &&
1545 		    (cp = strchr(domain, '.')))
1546 			(void) strlcpy(domain, cp + 1, sizeof(domain));
1547 		else
1548 			domain[0] = 0;
1549 	}
1550 	cp = NULL;
1551 	if (!nflag) {
1552 		if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1553 		    NI_NAMEREQD) == 0) {
1554 			if ((cp = strchr(line, '.')) &&
1555 			    !strcmp(cp + 1, domain))
1556 				*cp = 0;
1557 			cp = line;
1558 		}
1559 	}
1560 	if (cp)
1561 		return cp;
1562 
1563 	if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1564 	    NI_NUMERICHOST) != 0)
1565 		strlcpy(line, "invalid", sizeof(line));
1566 	return line;
1567 }
1568 
1569 /*
1570  * CRC32C routine for the Stream Control Transmission Protocol
1571  */
1572 
1573 #define CRC32C(c, d) (c = (c>>8) ^ crc_c[(c^(d))&0xFF])
1574 
1575 static u_int32_t crc_c[256] = {
1576 	0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
1577 	0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
1578 	0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
1579 	0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
1580 	0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
1581 	0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
1582 	0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
1583 	0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
1584 	0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
1585 	0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
1586 	0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
1587 	0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
1588 	0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
1589 	0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
1590 	0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
1591 	0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
1592 	0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
1593 	0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
1594 	0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
1595 	0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
1596 	0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
1597 	0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
1598 	0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
1599 	0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
1600 	0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
1601 	0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
1602 	0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
1603 	0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
1604 	0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
1605 	0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
1606 	0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
1607 	0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
1608 	0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
1609 	0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
1610 	0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
1611 	0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
1612 	0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
1613 	0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
1614 	0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
1615 	0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
1616 	0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
1617 	0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
1618 	0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
1619 	0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
1620 	0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
1621 	0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
1622 	0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
1623 	0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
1624 	0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
1625 	0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
1626 	0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
1627 	0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
1628 	0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
1629 	0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
1630 	0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
1631 	0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
1632 	0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
1633 	0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
1634 	0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
1635 	0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
1636 	0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
1637 	0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
1638 	0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
1639 	0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
1640 };
1641 
1642 u_int32_t
1643 sctp_crc32c(void *packet, u_int32_t len)
1644 {
1645 	u_int32_t i, crc32c;
1646 	u_int8_t byte0, byte1, byte2, byte3;
1647 	u_int8_t *buf = (u_int8_t *)packet;
1648 
1649 	crc32c = ~0;
1650 	for (i = 0; i < len; i++)
1651 		CRC32C(crc32c, buf[i]);
1652 	crc32c = ~crc32c;
1653 	byte0  = crc32c & 0xff;
1654 	byte1  = (crc32c>>8) & 0xff;
1655 	byte2  = (crc32c>>16) & 0xff;
1656 	byte3  = (crc32c>>24) & 0xff;
1657 	crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
1658 	return htonl(crc32c);
1659 }
1660 
1661 u_int16_t
1662 in_cksum(u_int16_t *addr, int len)
1663 {
1664 	int nleft = len;
1665 	u_int16_t *w = addr;
1666 	u_int16_t answer;
1667 	int sum = 0;
1668 
1669 	/*
1670 	 *  Our algorithm is simple, using a 32 bit accumulator (sum),
1671 	 *  we add sequential 16 bit words to it, and at the end, fold
1672 	 *  back all the carry bits from the top 16 bits into the lower
1673 	 *  16 bits.
1674 	 */
1675 	while (nleft > 1)  {
1676 		sum += *w++;
1677 		nleft -= 2;
1678 	}
1679 
1680 	/* mop up an odd byte, if necessary */
1681 	if (nleft == 1)
1682 		sum += *(u_char *)w;
1683 
1684 	/*
1685 	 * add back carry outs from top 16 bits to low 16 bits
1686 	 */
1687 	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
1688 	sum += (sum >> 16);			/* add carry */
1689 	answer = ~sum;				/* truncate to 16 bits */
1690 	return (answer);
1691 }
1692 
1693 u_int16_t
1694 tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1695     void *payload, u_int32_t len)
1696 {
1697 	struct {
1698 		struct in6_addr src;
1699 		struct in6_addr dst;
1700 		u_int32_t len;
1701 		u_int8_t zero[3];
1702 		u_int8_t next;
1703 	} pseudo_hdr;
1704 	u_int16_t sum[2];
1705 
1706 	pseudo_hdr.src = src->sin6_addr;
1707 	pseudo_hdr.dst = dst->sin6_addr;
1708 	pseudo_hdr.len = htonl(len);
1709 	pseudo_hdr.zero[0] = 0;
1710 	pseudo_hdr.zero[1] = 0;
1711 	pseudo_hdr.zero[2] = 0;
1712 	pseudo_hdr.next = IPPROTO_TCP;
1713 
1714 	sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1715 	sum[0] = in_cksum(payload, len);
1716 
1717 	return (~in_cksum(sum, sizeof(sum)));
1718 }
1719 
1720 void
1721 usage(void)
1722 {
1723 
1724 	fprintf(stderr,
1725 "usage: traceroute6 [-adIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n"
1726 "       [-m hoplimit] [-p port] [-q probes] [-s src] [-w waittime] target\n"
1727 "       [datalen]\n");
1728 	exit(1);
1729 }
1730