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