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