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
67static 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
74static char sccsid[] = "@(#)traceroute.c	8.1 (Berkeley) 6/6/93";
75#endif
76static 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
297u_char	packet[512];		/* last inbound (icmp) packet */
298char 	*outpacket;		/* last output packet */
299
300int	main(int, char *[]);
301int	wait_for_reply(int, struct msghdr *);
302#ifdef IPSEC
303#ifdef IPSEC_POLICY_IPSEC
304int	setpolicy(int so, char *policy);
305#endif
306#endif
307void	send_probe(int, u_long);
308void	*get_uphdr(struct ip6_hdr *, u_char *);
309int	get_hoplim(struct msghdr *);
310double	deltaT(struct timeval *, struct timeval *);
311const char *pr_type(int);
312int	packet_ok(struct msghdr *, int, int, u_char *, u_char *);
313void	print(struct msghdr *, int);
314const char *inetname(struct sockaddr *);
315u_int32_t sctp_crc32c(void *, u_int32_t);
316u_int16_t in_cksum(u_int16_t *addr, int);
317u_int16_t tcp_chksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
318    void *, u_int32_t);
319void	usage(void);
320
321int rcvsock;			/* receive (icmp) socket file descriptor */
322int sndsock;			/* send (raw/udp) socket file descriptor */
323
324struct msghdr rcvmhdr;
325struct iovec rcviov[2];
326int rcvhlim;
327struct in6_pktinfo *rcvpktinfo;
328
329struct sockaddr_in6 Src, Dst, Rcv;
330u_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) */
333char rtbuf[2064];
334struct ip6_rthdr *rth;
335struct cmsghdr *cmsg;
336
337char *source = NULL;
338char *hostname;
339
340u_long nprobes = 3;
341u_long first_hop = 1;
342u_long max_hops = 30;
343u_int16_t srcport;
344u_int16_t port = 32768+666;	/* start udp dest port # for probe packets */
345u_int16_t ident;
346int options;			/* socket options */
347int verbose;
348int waittime = 5;		/* time to wait for response (in seconds) */
349int nflag;			/* print addresses numerically */
350int useproto = IPPROTO_UDP;	/* protocol to use to send packet */
351int lflag;			/* print both numerical address & hostname */
352int as_path;			/* print as numbers for each hop */
353char *as_server = NULL;
354void *asn;
355
356int
357main(int argc, char *argv[])
358{
359	int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM };
360	char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep;
361	int ch, i, on = 1, seq, rcvcmsglen, error;
362	struct addrinfo hints, *res;
363	static u_char *rcvcmsgbuf;
364	u_long probe, hops, lport;
365	struct hostent *hp;
366	size_t size, minlen;
367	uid_t uid;
368	u_char type, code;
369
370	/*
371	 * Receive ICMP
372	 */
373	if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
374		perror("socket(ICMPv6)");
375		exit(5);
376	}
377
378	size = sizeof(i);
379	(void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &i, &size, NULL, 0);
380	max_hops = i;
381
382	/* specify to tell receiving interface */
383#ifdef IPV6_RECVPKTINFO
384	if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
385	    sizeof(on)) < 0)
386		err(1, "setsockopt(IPV6_RECVPKTINFO)");
387#else  /* old adv. API */
388	if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_PKTINFO, &on,
389	    sizeof(on)) < 0)
390		err(1, "setsockopt(IPV6_PKTINFO)");
391#endif
392
393	/* specify to tell value of hoplimit field of received IP6 hdr */
394#ifdef IPV6_RECVHOPLIMIT
395	if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
396	    sizeof(on)) < 0)
397		err(1, "setsockopt(IPV6_RECVHOPLIMIT)");
398#else  /* old adv. API */
399	if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on,
400	    sizeof(on)) < 0)
401		err(1, "setsockopt(IPV6_HOPLIMIT)");
402#endif
403
404	seq = 0;
405	ident = htons(getpid() & 0xffff); /* same as ping6 */
406
407	while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:STUvw:")) != -1)
408		switch (ch) {
409		case 'a':
410			as_path = 1;
411			break;
412		case 'A':
413			as_path = 1;
414			as_server = optarg;
415			break;
416		case 'd':
417			options |= SO_DEBUG;
418			break;
419		case 'f':
420			ep = NULL;
421			errno = 0;
422			first_hop = strtoul(optarg, &ep, 0);
423			if (errno || !*optarg || *ep || first_hop > 255) {
424				fprintf(stderr,
425				    "traceroute6: invalid min hoplimit.\n");
426				exit(1);
427			}
428			break;
429		case 'g':
430			hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno);
431			if (hp == NULL) {
432				fprintf(stderr,
433				    "traceroute6: unknown host %s\n", optarg);
434				exit(1);
435			}
436			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
986int
987wait_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
1023int
1024setpolicy(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
1045void
1046send_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
1173int
1174get_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
1189double
1190deltaT(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 */
1202const char *
1203pr_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
1258int
1259packet_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 */
1441void *
1442get_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
1486void
1487print(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 */
1522const char *
1523inetname(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
1562static 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
1629u_int32_t
1630sctp_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
1648u_int16_t
1649in_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
1680u_int16_t
1681tcp_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
1707void
1708usage(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