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