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