xref: /freebsd/usr.sbin/traceroute6/traceroute6.c (revision 99ec65e7fe61e3148dde543ed7d6566fe589a565)
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 
284 static u_char	packet[512];		/* last inbound (icmp) packet */
285 static char 	*outpacket;		/* last output packet */
286 
287 int	main(int, char *[]);
288 int	wait_for_reply(int, struct msghdr *);
289 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
290 int	setpolicy(int so, char *policy);
291 #endif
292 void	send_probe(int, u_long);
293 void	*get_uphdr(struct ip6_hdr *, u_char *);
294 void	capdns_open(void);
295 int	get_hoplim(struct msghdr *);
296 double	deltaT(struct timeval *, struct timeval *);
297 const char *pr_type(int);
298 int	packet_ok(struct msghdr *, int, int, u_char *, u_char *, u_char *);
299 void	print(struct msghdr *, int);
300 const char *inetname(struct sockaddr *);
301 u_int32_t sctp_crc32c(void *, u_int32_t);
302 u_int16_t in_cksum(u_int16_t *addr, int);
303 u_int16_t udp_cksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
304     void *, u_int32_t);
305 u_int16_t tcp_chksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
306     void *, u_int32_t);
307 void	usage(void);
308 
309 static int rcvsock;			/* receive (icmp) socket file descriptor */
310 static int sndsock;			/* send (raw/udp) socket file descriptor */
311 
312 static struct msghdr rcvmhdr;
313 static struct iovec rcviov[2];
314 static int rcvhlim;
315 static struct in6_pktinfo *rcvpktinfo;
316 
317 static struct sockaddr_in6 Src, Dst, Rcv;
318 static 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) */
321 static char rtbuf[2064];
322 static struct ip6_rthdr *rth;
323 static struct cmsghdr *cmsg;
324 
325 static char *source = NULL;
326 static char *hostname;
327 
328 static cap_channel_t *capdns;
329 
330 static u_long nprobes = 3;
331 static u_long first_hop = 1;
332 static u_long max_hops = 30;
333 static u_int16_t srcport;
334 static u_int16_t port = 32768 + 666;	/* start udp dest port # for probe packets */
335 static u_int16_t ident;
336 static int tclass = -1;
337 static int options;			/* socket options */
338 static int verbose;
339 static int waittime = 5;		/* time to wait for response (in seconds) */
340 static int nflag;			/* print addresses numerically */
341 static int useproto = IPPROTO_UDP;	/* protocol to use to send packet */
342 static int as_path;			/* print as numbers for each hop */
343 static int ecnflag;			/* ECN bleaching detection flag */
344 static char *as_server = NULL;
345 static void *asn;
346 
347 int
main(int argc,char * argv[])348 main(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 						default:
1013 							++unreachable;
1014 							printf(" !<%d>", code & 0xff);
1015 							break;
1016 						}
1017 					} else if (type == ICMP6_PARAM_PROB &&
1018 					    code == ICMP6_PARAMPROB_NEXTHEADER) {
1019 						printf(" !H");
1020 						++got_there;
1021 					} else if (type == ICMP6_ECHO_REPLY) {
1022 						if (rcvhlim >= 0 &&
1023 						    rcvhlim <= 1)
1024 							printf(" !");
1025 						++got_there;
1026 					}
1027 					break;
1028 				} else if (deltaT(&t1, &t2) > waittime * 1000) {
1029 					cc = 0;
1030 					break;
1031 				}
1032 			}
1033 			if (cc == 0)
1034 				printf(" *");
1035 			(void) fflush(stdout);
1036 		}
1037 		putchar('\n');
1038 		if (got_there ||
1039 		    (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) {
1040 			exit(0);
1041 		}
1042 	}
1043 	if (as_path)
1044 		as_shutdown(asn);
1045 
1046 	exit(0);
1047 }
1048 
1049 int
wait_for_reply(int sock,struct msghdr * mhdr)1050 wait_for_reply(int sock, struct msghdr *mhdr)
1051 {
1052 #ifdef HAVE_POLL
1053 	struct pollfd pfd[1];
1054 	int cc = 0;
1055 
1056 	pfd[0].fd = sock;
1057 	pfd[0].events = POLLIN;
1058 	pfd[0].revents = 0;
1059 
1060 	if (poll(pfd, 1, waittime * 1000) > 0 &&
1061 	    pfd[0].revents & POLLIN)
1062 		cc = recvmsg(rcvsock, mhdr, 0);
1063 
1064 	return (cc);
1065 #else
1066 	fd_set *fdsp;
1067 	struct timeval wait;
1068 	int cc = 0, fdsn;
1069 
1070 	fdsn = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
1071 	if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
1072 		err(1, "malloc");
1073 	memset(fdsp, 0, fdsn);
1074 	FD_SET(sock, fdsp);
1075 	wait.tv_sec = waittime; wait.tv_usec = 0;
1076 
1077 	if (select(sock + 1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0)
1078 		cc = recvmsg(rcvsock, mhdr, 0);
1079 
1080 	free(fdsp);
1081 	return (cc);
1082 #endif
1083 }
1084 
1085 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
1086 int
setpolicy(int so,char * policy)1087 setpolicy(int so, char *policy)
1088 {
1089 	char *buf;
1090 
1091 	buf = ipsec_set_policy(policy, strlen(policy));
1092 	if (buf == NULL) {
1093 		warnx("%s", ipsec_strerror());
1094 		return (-1);
1095 	}
1096 	(void)setsockopt(so, IPPROTO_IPV6, IPV6_IPSEC_POLICY,
1097 	    buf, ipsec_get_policylen(buf));
1098 
1099 	free(buf);
1100 
1101 	return (0);
1102 }
1103 #endif
1104 
1105 void
send_probe(int seq,u_long hops)1106 send_probe(int seq, u_long hops)
1107 {
1108 	struct icmp6_hdr *icp;
1109 	struct sctphdr *sctp;
1110 	struct udphdr *outudp;
1111 	struct sctp_chunkhdr *chk;
1112 	struct sctp_init_chunk *init;
1113 	struct sctp_paramhdr *param;
1114 	struct tcphdr *tcp;
1115 	int i;
1116 
1117 	i = hops;
1118 	if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
1119 	    (char *)&i, sizeof(i)) < 0) {
1120 		perror("setsockopt IPV6_UNICAST_HOPS");
1121 	}
1122 
1123 	Dst.sin6_port = htons(port + seq);
1124 
1125 	switch (useproto) {
1126 	case IPPROTO_ICMPV6:
1127 		icp = (struct icmp6_hdr *)outpacket;
1128 
1129 		icp->icmp6_type = ICMP6_ECHO_REQUEST;
1130 		icp->icmp6_code = 0;
1131 		icp->icmp6_cksum = 0;
1132 		icp->icmp6_id = ident;
1133 		icp->icmp6_seq = htons(seq);
1134 		break;
1135 	case IPPROTO_UDP:
1136 		outudp = (struct udphdr *) outpacket;
1137 		outudp->uh_sport = htons(ident);
1138 		outudp->uh_dport = htons(port + seq);
1139 		outudp->uh_ulen = htons(datalen);
1140 		outudp->uh_sum = 0;
1141 		outudp->uh_sum = udp_cksum(&Src, &Dst, outpacket, datalen);
1142 		break;
1143 	case IPPROTO_NONE:
1144 		/* No space for anything. No harm as seq/tv32 are decorative. */
1145 		break;
1146 	case IPPROTO_SCTP:
1147 		sctp = (struct sctphdr *)outpacket;
1148 
1149 		sctp->src_port = htons(ident);
1150 		sctp->dest_port = htons(port + seq);
1151 		if (datalen >= (u_long)(sizeof(struct sctphdr) +
1152 		    sizeof(struct sctp_init_chunk))) {
1153 			sctp->v_tag = 0;
1154 		} else {
1155 			sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port;
1156 		}
1157 		sctp->checksum = htonl(0);
1158 		if (datalen >= (u_long)(sizeof(struct sctphdr) +
1159 		    sizeof(struct sctp_init_chunk))) {
1160 			/*
1161 			 * Send a packet containing an INIT chunk. This works
1162 			 * better in case of firewalls on the path, but
1163 			 * results in a probe packet containing at least
1164 			 * 32 bytes of payload. For shorter payloads, use
1165 			 * SHUTDOWN-ACK chunks.
1166 			 */
1167 			init = (struct sctp_init_chunk *)(sctp + 1);
1168 			init->ch.chunk_type = SCTP_INITIATION;
1169 			init->ch.chunk_flags = 0;
1170 			init->ch.chunk_length = htons((u_int16_t)(datalen -
1171 			    sizeof(struct sctphdr)));
1172 			init->init.initiate_tag = (sctp->src_port << 16) |
1173 			    sctp->dest_port;
1174 			init->init.a_rwnd = htonl(1500);
1175 			init->init.num_outbound_streams = htons(1);
1176 			init->init.num_inbound_streams = htons(1);
1177 			init->init.initial_tsn = htonl(0);
1178 			if (datalen >= (u_long)(sizeof(struct sctphdr) +
1179 			    sizeof(struct sctp_init_chunk) +
1180 			    sizeof(struct sctp_paramhdr))) {
1181 				param = (struct sctp_paramhdr *)(init + 1);
1182 				param->param_type = htons(SCTP_PAD);
1183 				param->param_length =
1184 				    htons((u_int16_t)(datalen -
1185 				    sizeof(struct sctphdr) -
1186 				    sizeof(struct sctp_init_chunk)));
1187 			}
1188 		} else {
1189 			/*
1190 			 * Send a packet containing a SHUTDOWN-ACK chunk,
1191 			 * possibly followed by a PAD chunk.
1192 			 */
1193 			if (datalen >= (u_long)(sizeof(struct sctphdr) +
1194 			    sizeof(struct sctp_chunkhdr))) {
1195 				chk = (struct sctp_chunkhdr *)(sctp + 1);
1196 				chk->chunk_type = SCTP_SHUTDOWN_ACK;
1197 				chk->chunk_flags = 0;
1198 				chk->chunk_length = htons(4);
1199 			}
1200 			if (datalen >= (u_long)(sizeof(struct sctphdr) +
1201 			    2 * sizeof(struct sctp_chunkhdr))) {
1202 				chk = chk + 1;
1203 				chk->chunk_type = SCTP_PAD_CHUNK;
1204 				chk->chunk_flags = 0;
1205 				chk->chunk_length = htons((u_int16_t)(datalen -
1206 				    sizeof(struct sctphdr) -
1207 				    sizeof(struct sctp_chunkhdr)));
1208 			}
1209 		}
1210 		sctp->checksum = sctp_crc32c(outpacket, datalen);
1211 		break;
1212 	case IPPROTO_TCP:
1213 		tcp = (struct tcphdr *)outpacket;
1214 
1215 		tcp->th_sport = htons(ident);
1216 		tcp->th_dport = htons(port + seq);
1217 		tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
1218 		tcp->th_ack = 0;
1219 		tcp->th_off = 5;
1220 		__tcp_set_flags(tcp, TH_SYN);
1221 		tcp->th_sum = 0;
1222 		tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen);
1223 		break;
1224 	default:
1225 		fprintf(stderr, "Unknown probe protocol %d.\n", useproto);
1226 		exit(1);
1227 	}
1228 
1229 	i = send(sndsock, (char *)outpacket, datalen, 0);
1230 	if (i < 0 || (u_long)i != datalen)  {
1231 		if (i < 0)
1232 			perror("send");
1233 		printf("traceroute6: wrote %s %lu chars, ret=%d\n",
1234 		    hostname, datalen, i);
1235 		(void) fflush(stdout);
1236 	}
1237 }
1238 
1239 int
get_hoplim(struct msghdr * mhdr)1240 get_hoplim(struct msghdr *mhdr)
1241 {
1242 	struct cmsghdr *cm;
1243 
1244 	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1245 	    cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1246 		if (cm->cmsg_level == IPPROTO_IPV6 &&
1247 		    cm->cmsg_type == IPV6_HOPLIMIT &&
1248 		    cm->cmsg_len == CMSG_LEN(sizeof(int)))
1249 			return (*(int *)CMSG_DATA(cm));
1250 	}
1251 
1252 	return (-1);
1253 }
1254 
1255 double
deltaT(struct timeval * t1p,struct timeval * t2p)1256 deltaT(struct timeval *t1p, struct timeval *t2p)
1257 {
1258 	double dt;
1259 
1260 	dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1261 	    (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1262 	return (dt);
1263 }
1264 
1265 /*
1266  * Convert an ICMP "type" field to a printable string.
1267  */
1268 const char *
pr_type(int t0)1269 pr_type(int t0)
1270 {
1271 	u_char t = t0 & 0xff;
1272 	const char *cp;
1273 
1274 	switch (t) {
1275 	case ICMP6_DST_UNREACH:
1276 		cp = "Destination Unreachable";
1277 		break;
1278 	case ICMP6_PACKET_TOO_BIG:
1279 		cp = "Packet Too Big";
1280 		break;
1281 	case ICMP6_TIME_EXCEEDED:
1282 		cp = "Time Exceeded";
1283 		break;
1284 	case ICMP6_PARAM_PROB:
1285 		cp = "Parameter Problem";
1286 		break;
1287 	case ICMP6_ECHO_REQUEST:
1288 		cp = "Echo Request";
1289 		break;
1290 	case ICMP6_ECHO_REPLY:
1291 		cp = "Echo Reply";
1292 		break;
1293 	case ICMP6_MEMBERSHIP_QUERY:
1294 		cp = "Group Membership Query";
1295 		break;
1296 	case ICMP6_MEMBERSHIP_REPORT:
1297 		cp = "Group Membership Report";
1298 		break;
1299 	case ICMP6_MEMBERSHIP_REDUCTION:
1300 		cp = "Group Membership Reduction";
1301 		break;
1302 	case ND_ROUTER_SOLICIT:
1303 		cp = "Router Solicitation";
1304 		break;
1305 	case ND_ROUTER_ADVERT:
1306 		cp = "Router Advertisement";
1307 		break;
1308 	case ND_NEIGHBOR_SOLICIT:
1309 		cp = "Neighbor Solicitation";
1310 		break;
1311 	case ND_NEIGHBOR_ADVERT:
1312 		cp = "Neighbor Advertisement";
1313 		break;
1314 	case ND_REDIRECT:
1315 		cp = "Redirect";
1316 		break;
1317 	default:
1318 		cp = "Unknown";
1319 		break;
1320 	}
1321 	return (cp);
1322 }
1323 
1324 int
packet_ok(struct msghdr * mhdr,int cc,int seq,u_char * type,u_char * code,u_char * ecn)1325 packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code,
1326     u_char *ecn)
1327 {
1328 	struct icmp6_hdr *icp;
1329 	struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1330 	char *buf = (char *)mhdr->msg_iov[0].iov_base;
1331 	struct cmsghdr *cm;
1332 	int *hlimp;
1333 	char hbuf[NI_MAXHOST];
1334 
1335 #ifdef OLDRAWSOCKET
1336 	int hlen;
1337 	struct ip6_hdr *ip;
1338 #endif
1339 
1340 #ifdef OLDRAWSOCKET
1341 	ip = (struct ip6_hdr *) buf;
1342 	hlen = sizeof(struct ip6_hdr);
1343 	if (cc < hlen + sizeof(struct icmp6_hdr)) {
1344 		if (verbose) {
1345 			if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1346 			    hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1347 				strlcpy(hbuf, "invalid", sizeof(hbuf));
1348 			printf("packet too short (%d bytes) from %s\n", cc,
1349 			    hbuf);
1350 		}
1351 		return (0);
1352 	}
1353 	cc -= hlen;
1354 	icp = (struct icmp6_hdr *)(buf + hlen);
1355 #else
1356 	if (cc < (int)sizeof(struct icmp6_hdr)) {
1357 		if (verbose) {
1358 			if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1359 			    hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1360 				strlcpy(hbuf, "invalid", sizeof(hbuf));
1361 			printf("data too short (%d bytes) from %s\n", cc, hbuf);
1362 		}
1363 		return (0);
1364 	}
1365 	icp = (struct icmp6_hdr *)buf;
1366 #endif
1367 	/* get optional information via advanced API */
1368 	rcvpktinfo = NULL;
1369 	hlimp = NULL;
1370 	for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1371 	    cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1372 		if (cm->cmsg_level == IPPROTO_IPV6 &&
1373 		    cm->cmsg_type == IPV6_PKTINFO &&
1374 		    cm->cmsg_len ==
1375 		    CMSG_LEN(sizeof(struct in6_pktinfo)))
1376 			rcvpktinfo = (struct in6_pktinfo *)(CMSG_DATA(cm));
1377 
1378 		if (cm->cmsg_level == IPPROTO_IPV6 &&
1379 		    cm->cmsg_type == IPV6_HOPLIMIT &&
1380 		    cm->cmsg_len == CMSG_LEN(sizeof(int)))
1381 			hlimp = (int *)CMSG_DATA(cm);
1382 	}
1383 	if (rcvpktinfo == NULL || hlimp == NULL) {
1384 		warnx("failed to get received hop limit or packet info");
1385 #if 0
1386 		return (0);
1387 #else
1388 		rcvhlim = 0;	/*XXX*/
1389 #endif
1390 	} else
1391 		rcvhlim = *hlimp;
1392 
1393 	*type = icp->icmp6_type;
1394 	*code = icp->icmp6_code;
1395 	if ((*type == ICMP6_TIME_EXCEEDED &&
1396 	    *code == ICMP6_TIME_EXCEED_TRANSIT) ||
1397 	    (*type == ICMP6_DST_UNREACH) ||
1398 	    (*type == ICMP6_PARAM_PROB &&
1399 	    *code == ICMP6_PARAMPROB_NEXTHEADER)) {
1400 		struct ip6_hdr *hip;
1401 		struct icmp6_hdr *icmp;
1402 		struct sctp_init_chunk *init;
1403 		struct sctphdr *sctp;
1404 		struct tcphdr *tcp;
1405 		struct udphdr *udp;
1406 		void *up;
1407 
1408 		hip = (struct ip6_hdr *)(icp + 1);
1409 		*ecn = ntohl(hip->ip6_flow & IPV6_ECN_MASK) >> 20;
1410 		if ((up = get_uphdr(hip, (u_char *)(buf + cc))) == NULL) {
1411 			if (verbose)
1412 				warnx("failed to get upper layer header");
1413 			return (0);
1414 		}
1415 		switch (useproto) {
1416 		case IPPROTO_ICMPV6:
1417 			icmp = (struct icmp6_hdr *)up;
1418 			if (icmp->icmp6_id == ident &&
1419 			    icmp->icmp6_seq == htons(seq))
1420 				return (1);
1421 			break;
1422 		case IPPROTO_UDP:
1423 			udp = (struct udphdr *)up;
1424 			if (udp->uh_sport == htons(ident) &&
1425 			    udp->uh_dport == htons(port + seq))
1426 				return (1);
1427 			break;
1428 		case IPPROTO_SCTP:
1429 			sctp = (struct sctphdr *)up;
1430 			if (sctp->src_port != htons(ident) ||
1431 			    sctp->dest_port != htons(port + seq)) {
1432 				break;
1433 			}
1434 			if (datalen >= (u_long)(sizeof(struct sctphdr) +
1435 			    sizeof(struct sctp_init_chunk))) {
1436 				if (sctp->v_tag != 0) {
1437 					break;
1438 				}
1439 				init = (struct sctp_init_chunk *)(sctp + 1);
1440 				/* Check the initiate tag, if available. */
1441 				if ((char *)&init->init.a_rwnd > buf + cc) {
1442 					return (1);
1443 				}
1444 				if (init->init.initiate_tag == (u_int32_t)
1445 				    ((sctp->src_port << 16) | sctp->dest_port)) {
1446 					return (1);
1447 				}
1448 			} else {
1449 				if (sctp->v_tag ==
1450 				    (u_int32_t)((sctp->src_port << 16) |
1451 				    sctp->dest_port)) {
1452 					return (1);
1453 				}
1454 			}
1455 			break;
1456 		case IPPROTO_TCP:
1457 			tcp = (struct tcphdr *)up;
1458 			if (tcp->th_sport == htons(ident) &&
1459 			    tcp->th_dport == htons(port + seq) &&
1460 			    tcp->th_seq ==
1461 			    (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport))
1462 				return (1);
1463 			break;
1464 		case IPPROTO_NONE:
1465 			return (1);
1466 		default:
1467 			fprintf(stderr, "Unknown probe proto %d.\n", useproto);
1468 			break;
1469 		}
1470 	} else if (useproto == IPPROTO_ICMPV6 && *type == ICMP6_ECHO_REPLY) {
1471 		if (icp->icmp6_id == ident &&
1472 		    icp->icmp6_seq == htons(seq))
1473 			return (1);
1474 	}
1475 	if (verbose) {
1476 		char sbuf[NI_MAXHOST + 1], dbuf[INET6_ADDRSTRLEN];
1477 		u_int8_t *p;
1478 		int i;
1479 
1480 		if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1481 		    sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0)
1482 			strlcpy(sbuf, "invalid", sizeof(sbuf));
1483 		printf("\n%d bytes from %s to %s", cc, sbuf,
1484 		    rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1485 		    dbuf, sizeof(dbuf)) : "?");
1486 		printf(": icmp type %d (%s) code %d\n", *type, pr_type(*type),
1487 		    *code);
1488 		p = (u_int8_t *)(icp + 1);
1489 #define WIDTH	16
1490 		for (i = 0; i < cc; i++) {
1491 			if (i % WIDTH == 0)
1492 				printf("%04x:", i);
1493 			if (i % 4 == 0)
1494 				printf(" ");
1495 			printf("%02x", p[i]);
1496 			if (i % WIDTH == WIDTH - 1)
1497 				printf("\n");
1498 		}
1499 		if (cc % WIDTH != 0)
1500 			printf("\n");
1501 	}
1502 	return (0);
1503 }
1504 
1505 /*
1506  * Increment pointer until find the UDP or ICMP header.
1507  */
1508 void *
get_uphdr(struct ip6_hdr * ip6,u_char * lim)1509 get_uphdr(struct ip6_hdr *ip6, u_char *lim)
1510 {
1511 	u_char *cp = (u_char *)ip6, nh;
1512 	int hlen;
1513 	static u_char none_hdr[1]; /* Fake pointer for IPPROTO_NONE. */
1514 
1515 	if (cp + sizeof(*ip6) > lim)
1516 		return (NULL);
1517 
1518 	nh = ip6->ip6_nxt;
1519 	cp += sizeof(struct ip6_hdr);
1520 
1521 	while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) {
1522 		switch (nh) {
1523 		case IPPROTO_ESP:
1524 			return (NULL);
1525 		case IPPROTO_ICMPV6:
1526 			return (useproto == nh ? cp : NULL);
1527 		case IPPROTO_SCTP:
1528 		case IPPROTO_TCP:
1529 		case IPPROTO_UDP:
1530 			return (useproto == nh ? cp : NULL);
1531 		case IPPROTO_NONE:
1532 			return (useproto == nh ? none_hdr : NULL);
1533 		case IPPROTO_FRAGMENT:
1534 			hlen = sizeof(struct ip6_frag);
1535 			nh = ((struct ip6_frag *)cp)->ip6f_nxt;
1536 			break;
1537 		case IPPROTO_AH:
1538 			hlen = (((struct ip6_ext *)cp)->ip6e_len + 2) << 2;
1539 			nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1540 			break;
1541 		default:
1542 			hlen = (((struct ip6_ext *)cp)->ip6e_len + 1) << 3;
1543 			nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1544 			break;
1545 		}
1546 
1547 		cp += hlen;
1548 	}
1549 
1550 	return (NULL);
1551 }
1552 
1553 void
capdns_open(void)1554 capdns_open(void)
1555 {
1556 #ifdef	WITH_CASPER
1557 	const char *types[] = { "NAME", "ADDR" };
1558 	int families[1];
1559 	cap_channel_t *casper;
1560 
1561 	casper = cap_init();
1562 	if (casper == NULL)
1563 		errx(1, "unable to create casper process");
1564 	capdns = cap_service_open(casper, "system.dns");
1565 	if (capdns == NULL)
1566 		errx(1, "unable to open system.dns service");
1567 	if (cap_dns_type_limit(capdns, types, nitems(types)) < 0)
1568 		errx(1, "unable to limit access to system.dns service");
1569 	families[0] = AF_INET6;
1570 	if (cap_dns_family_limit(capdns, families, nitems(families)) < 0)
1571 		errx(1, "unable to limit access to system.dns service");
1572 	cap_close(casper);
1573 #endif	/* WITH_CASPER */
1574 }
1575 
1576 void
print(struct msghdr * mhdr,int cc)1577 print(struct msghdr *mhdr, int cc)
1578 {
1579 	struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1580 	char hbuf[NI_MAXHOST];
1581 
1582 	if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1583 	    hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1584 		strlcpy(hbuf, "invalid", sizeof(hbuf));
1585 	if (as_path)
1586 		printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6));
1587 	if (nflag)
1588 		printf(" %s", hbuf);
1589 	else
1590 		printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf);
1591 
1592 	if (verbose) {
1593 #ifdef OLDRAWSOCKET
1594 		printf(" %d bytes to %s", cc,
1595 		    rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1596 		    hbuf, sizeof(hbuf)) : "?");
1597 #else
1598 		printf(" %d bytes of data to %s", cc,
1599 		    rcvpktinfo ?  inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1600 		    hbuf, sizeof(hbuf)) : "?");
1601 #endif
1602 	}
1603 }
1604 
1605 /*
1606  * Construct an Internet address representation.
1607  * If the nflag has been supplied, give
1608  * numeric value, otherwise try for symbolic name.
1609  */
1610 const char *
inetname(struct sockaddr * sa)1611 inetname(struct sockaddr *sa)
1612 {
1613 	static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1];
1614 	static int first = 1;
1615 	char *cp;
1616 
1617 	if (first && !nflag) {
1618 		first = 0;
1619 		if (gethostname(domain, sizeof(domain)) == 0 &&
1620 		    (cp = strchr(domain, '.')))
1621 			(void) strlcpy(domain, cp + 1, sizeof(domain));
1622 		else
1623 			domain[0] = 0;
1624 	}
1625 	cp = NULL;
1626 	if (!nflag) {
1627 		if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0,
1628 		    NI_NAMEREQD) == 0) {
1629 			if ((cp = strchr(line, '.')) &&
1630 			    !strcmp(cp + 1, domain))
1631 				*cp = 0;
1632 			cp = line;
1633 		}
1634 	}
1635 	if (cp)
1636 		return (cp);
1637 
1638 	if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0,
1639 	    NI_NUMERICHOST) != 0)
1640 		strlcpy(line, "invalid", sizeof(line));
1641 	return (line);
1642 }
1643 
1644 /*
1645  * CRC32C routine for the Stream Control Transmission Protocol
1646  */
1647 
1648 #define CRC32C(c, d) (c = (c >> 8) ^ crc_c[(c ^ (d)) & 0xFF])
1649 
1650 static u_int32_t crc_c[256] = {
1651 	0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
1652 	0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
1653 	0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
1654 	0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
1655 	0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
1656 	0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
1657 	0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
1658 	0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
1659 	0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
1660 	0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
1661 	0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
1662 	0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
1663 	0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
1664 	0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
1665 	0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
1666 	0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
1667 	0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
1668 	0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
1669 	0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
1670 	0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
1671 	0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
1672 	0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
1673 	0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
1674 	0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
1675 	0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
1676 	0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
1677 	0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
1678 	0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
1679 	0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
1680 	0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
1681 	0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
1682 	0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
1683 	0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
1684 	0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
1685 	0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
1686 	0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
1687 	0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
1688 	0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
1689 	0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
1690 	0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
1691 	0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
1692 	0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
1693 	0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
1694 	0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
1695 	0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
1696 	0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
1697 	0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
1698 	0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
1699 	0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
1700 	0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
1701 	0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
1702 	0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
1703 	0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
1704 	0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
1705 	0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
1706 	0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
1707 	0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
1708 	0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
1709 	0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
1710 	0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
1711 	0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
1712 	0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
1713 	0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
1714 	0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
1715 };
1716 
1717 u_int32_t
sctp_crc32c(void * pack,u_int32_t len)1718 sctp_crc32c(void *pack, u_int32_t len)
1719 {
1720 	u_int32_t i, crc32c;
1721 	u_int8_t byte0, byte1, byte2, byte3;
1722 	u_int8_t *buf = (u_int8_t *)pack;
1723 
1724 	crc32c = ~0;
1725 	for (i = 0; i < len; i++)
1726 		CRC32C(crc32c, buf[i]);
1727 	crc32c = ~crc32c;
1728 	byte0  = crc32c & 0xff;
1729 	byte1  = (crc32c >> 8) & 0xff;
1730 	byte2  = (crc32c >> 16) & 0xff;
1731 	byte3  = (crc32c >> 24) & 0xff;
1732 	crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
1733 	return (htonl(crc32c));
1734 }
1735 
1736 u_int16_t
in_cksum(u_int16_t * addr,int len)1737 in_cksum(u_int16_t *addr, int len)
1738 {
1739 	int nleft = len;
1740 	u_int16_t *w = addr;
1741 	u_int16_t answer;
1742 	int sum = 0;
1743 
1744 	/*
1745 	 *  Our algorithm is simple, using a 32 bit accumulator (sum),
1746 	 *  we add sequential 16 bit words to it, and at the end, fold
1747 	 *  back all the carry bits from the top 16 bits into the lower
1748 	 *  16 bits.
1749 	 */
1750 	while (nleft > 1)  {
1751 		sum += *w++;
1752 		nleft -= 2;
1753 	}
1754 
1755 	/* mop up an odd byte, if necessary */
1756 	if (nleft == 1)
1757 		sum += *(u_char *)w;
1758 
1759 	/*
1760 	 * add back carry outs from top 16 bits to low 16 bits
1761 	 */
1762 	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
1763 	sum += (sum >> 16);			/* add carry */
1764 	answer = ~sum;				/* truncate to 16 bits */
1765 	return (answer);
1766 }
1767 
1768 u_int16_t
udp_cksum(struct sockaddr_in6 * src,struct sockaddr_in6 * dst,void * payload,u_int32_t len)1769 udp_cksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1770     void *payload, u_int32_t len)
1771 {
1772 	struct {
1773 		struct in6_addr src;
1774 		struct in6_addr dst;
1775 		u_int32_t len;
1776 		u_int8_t zero[3];
1777 		u_int8_t next;
1778 	} pseudo_hdr;
1779 	u_int16_t sum[2];
1780 
1781 	pseudo_hdr.src = src->sin6_addr;
1782 	pseudo_hdr.dst = dst->sin6_addr;
1783 	pseudo_hdr.len = htonl(len);
1784 	pseudo_hdr.zero[0] = 0;
1785 	pseudo_hdr.zero[1] = 0;
1786 	pseudo_hdr.zero[2] = 0;
1787 	pseudo_hdr.next = IPPROTO_UDP;
1788 
1789 	sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1790 	sum[0] = in_cksum(payload, len);
1791 
1792 	return (~in_cksum(sum, sizeof(sum)));
1793 }
1794 
1795 u_int16_t
tcp_chksum(struct sockaddr_in6 * src,struct sockaddr_in6 * dst,void * payload,u_int32_t len)1796 tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1797     void *payload, u_int32_t len)
1798 {
1799 	struct {
1800 		struct in6_addr src;
1801 		struct in6_addr dst;
1802 		u_int32_t len;
1803 		u_int8_t zero[3];
1804 		u_int8_t next;
1805 	} pseudo_hdr;
1806 	u_int16_t sum[2];
1807 
1808 	pseudo_hdr.src = src->sin6_addr;
1809 	pseudo_hdr.dst = dst->sin6_addr;
1810 	pseudo_hdr.len = htonl(len);
1811 	pseudo_hdr.zero[0] = 0;
1812 	pseudo_hdr.zero[1] = 0;
1813 	pseudo_hdr.zero[2] = 0;
1814 	pseudo_hdr.next = IPPROTO_TCP;
1815 
1816 	sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1817 	sum[0] = in_cksum(payload, len);
1818 
1819 	return (~in_cksum(sum, sizeof(sum)));
1820 }
1821 
1822 void
usage(void)1823 usage(void)
1824 {
1825 	fprintf(stderr,
1826 "Usage: traceroute6 [-adEIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n"
1827 "\t[-m hoplimit] [-p port] [-q probes] [-s src] [-t tclass]\n"
1828 "\t[-w waittime] target [datalen]\n");
1829 	exit(1);
1830 }
1831