]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/traceroute6/traceroute6.c
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / usr.sbin / traceroute6 / traceroute6.c
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/sctp_header.h>
278 #include <netinet/tcp.h>
279 #include <netinet/udp.h>
280
281 #ifdef IPSEC
282 #include <net/route.h>
283 #include <netipsec/ipsec.h>
284 #endif
285
286 #include "as.h"
287
288 #define DUMMY_PORT 10010
289
290 #define MAXPACKET       65535   /* max ip packet size */
291
292 #ifndef HAVE_GETIPNODEBYNAME
293 #define getipnodebyname(x, y, z, u)     gethostbyname2((x), (y))
294 #define freehostent(x)
295 #endif
296
297 static u_char   packet[512];            /* last inbound (icmp) packet */
298 static char     *outpacket;             /* last output packet */
299
300 int     main(int, char *[]);
301 int     wait_for_reply(int, struct msghdr *);
302 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
303 int     setpolicy(int so, char *policy);
304 #endif
305 void    send_probe(int, u_long);
306 void    *get_uphdr(struct ip6_hdr *, u_char *);
307 int     get_hoplim(struct msghdr *);
308 double  deltaT(struct timeval *, struct timeval *);
309 const char *pr_type(int);
310 int     packet_ok(struct msghdr *, int, int, u_char *, u_char *);
311 void    print(struct msghdr *, int);
312 const char *inetname(struct sockaddr *);
313 u_int32_t sctp_crc32c(void *, u_int32_t);
314 u_int16_t in_cksum(u_int16_t *addr, int);
315 u_int16_t tcp_chksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
316     void *, u_int32_t);
317 void    usage(void);
318
319 static int rcvsock;                     /* receive (icmp) socket file descriptor */
320 static int sndsock;                     /* send (raw/udp) socket file descriptor */
321
322 static struct msghdr rcvmhdr;
323 static struct iovec rcviov[2];
324 static int rcvhlim;
325 static struct in6_pktinfo *rcvpktinfo;
326
327 static struct sockaddr_in6 Src, Dst, Rcv;
328 static u_long datalen = 20;                     /* How much data */
329 #define ICMP6ECHOLEN    8
330 /* XXX: 2064 = 127(max hops in type 0 rthdr) * sizeof(ip6_hdr) + 16(margin) */
331 static char rtbuf[2064];
332 static struct ip6_rthdr *rth;
333 static struct cmsghdr *cmsg;
334
335 static char *source = NULL;
336 static char *hostname;
337
338 static u_long nprobes = 3;
339 static u_long first_hop = 1;
340 static u_long max_hops = 30;
341 static u_int16_t srcport;
342 static u_int16_t port = 32768+666;      /* start udp dest port # for probe packets */
343 static u_int16_t ident;
344 static int options;                     /* socket options */
345 static int verbose;
346 static int waittime = 5;                /* time to wait for response (in seconds) */
347 static int nflag;                       /* print addresses numerically */
348 static int useproto = IPPROTO_UDP;      /* protocol to use to send packet */
349 static int lflag;                       /* print both numerical address & hostname */
350 static int as_path;                     /* print as numbers for each hop */
351 static char *as_server = NULL;
352 static void *asn;
353
354 int
355 main(int argc, char *argv[])
356 {
357         int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM };
358         char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep;
359         int ch, i, on = 1, seq, rcvcmsglen, error;
360         struct addrinfo hints, *res;
361         static u_char *rcvcmsgbuf;
362         u_long probe, hops, lport;
363         struct hostent *hp;
364         size_t size, minlen;
365         uid_t uid;
366         u_char type, code;
367 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
368         char ipsec_inpolicy[] = "in bypass";
369         char ipsec_outpolicy[] = "out bypass";
370 #endif
371
372         /*
373          * Receive ICMP
374          */
375         if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
376                 perror("socket(ICMPv6)");
377                 exit(5);
378         }
379
380         size = sizeof(i);
381         (void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &i, &size, NULL, 0);
382         max_hops = i;
383
384         /* specify to tell receiving interface */
385 #ifdef IPV6_RECVPKTINFO
386         if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
387             sizeof(on)) < 0)
388                 err(1, "setsockopt(IPV6_RECVPKTINFO)");
389 #else  /* old adv. API */
390         if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_PKTINFO, &on,
391             sizeof(on)) < 0)
392                 err(1, "setsockopt(IPV6_PKTINFO)");
393 #endif
394
395         /* specify to tell value of hoplimit field of received IP6 hdr */
396 #ifdef IPV6_RECVHOPLIMIT
397         if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
398             sizeof(on)) < 0)
399                 err(1, "setsockopt(IPV6_RECVHOPLIMIT)");
400 #else  /* old adv. API */
401         if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on,
402             sizeof(on)) < 0)
403                 err(1, "setsockopt(IPV6_HOPLIMIT)");
404 #endif
405
406         seq = 0;
407         ident = htons(getpid() & 0xffff); /* same as ping6 */
408
409         while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:STUvw:")) != -1)
410                 switch (ch) {
411                 case 'a':
412                         as_path = 1;
413                         break;
414                 case 'A':
415                         as_path = 1;
416                         as_server = optarg;
417                         break;
418                 case 'd':
419                         options |= SO_DEBUG;
420                         break;
421                 case 'f':
422                         ep = NULL;
423                         errno = 0;
424                         first_hop = strtoul(optarg, &ep, 0);
425                         if (errno || !*optarg || *ep || first_hop > 255) {
426                                 fprintf(stderr,
427                                     "traceroute6: invalid min hoplimit.\n");
428                                 exit(1);
429                         }
430                         break;
431                 case 'g':
432                         hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno);
433                         if (hp == NULL) {
434                                 fprintf(stderr,
435                                     "traceroute6: unknown host %s\n", optarg);
436                                 exit(1);
437                         }
438                         if (rth == NULL) {
439                                 /*
440                                  * XXX: We can't detect the number of
441                                  * intermediate nodes yet.
442                                  */
443                                 if ((rth = inet6_rth_init((void *)rtbuf,
444                                     sizeof(rtbuf), IPV6_RTHDR_TYPE_0,
445                                     0)) == NULL) {
446                                         fprintf(stderr,
447                                             "inet6_rth_init failed.\n");
448                                         exit(1);
449                                 }
450                         }
451                         if (inet6_rth_add((void *)rth,
452                             (struct in6_addr *)hp->h_addr)) {
453                                 fprintf(stderr,
454                                     "inet6_rth_add failed for %s\n",
455                                     optarg);
456                                 exit(1);
457                         }
458                         freehostent(hp);
459                         break;
460                 case 'I':
461                         useproto = IPPROTO_ICMPV6;
462                         break;
463                 case 'l':
464                         lflag++;
465                         break;
466                 case 'm':
467                         ep = NULL;
468                         errno = 0;
469                         max_hops = strtoul(optarg, &ep, 0);
470                         if (errno || !*optarg || *ep || max_hops > 255) {
471                                 fprintf(stderr,
472                                     "traceroute6: invalid max hoplimit.\n");
473                                 exit(1);
474                         }
475                         break;
476                 case 'n':
477                         nflag++;
478                         break;
479                 case 'N':
480                         useproto = IPPROTO_NONE;
481                         break;
482                 case 'p':
483                         ep = NULL;
484                         errno = 0;
485                         lport = strtoul(optarg, &ep, 0);
486                         if (errno || !*optarg || *ep) {
487                                 fprintf(stderr, "traceroute6: invalid port.\n");
488                                 exit(1);
489                         }
490                         if (lport == 0 || lport != (lport & 0xffff)) {
491                                 fprintf(stderr,
492                                     "traceroute6: port out of range.\n");
493                                 exit(1);
494                         }
495                         port = lport & 0xffff;
496                         break;
497                 case 'q':
498                         ep = NULL;
499                         errno = 0;
500                         nprobes = strtoul(optarg, &ep, 0);
501                         if (errno || !*optarg || *ep) {
502                                 fprintf(stderr,
503                                     "traceroute6: invalid nprobes.\n");
504                                 exit(1);
505                         }
506                         if (nprobes < 1) {
507                                 fprintf(stderr,
508                                     "traceroute6: nprobes must be >0.\n");
509                                 exit(1);
510                         }
511                         break;
512                 case 'r':
513                         options |= SO_DONTROUTE;
514                         break;
515                 case 's':
516                         /*
517                          * set the ip source address of the outbound
518                          * probe (e.g., on a multi-homed host).
519                          */
520                         source = optarg;
521                         break;
522                 case 'S':
523                         useproto = IPPROTO_SCTP;
524                         break;
525                 case 'T':
526                         useproto = IPPROTO_TCP;
527                         break;
528                 case 'U':
529                         useproto = IPPROTO_UDP;
530                         break;
531                 case 'v':
532                         verbose++;
533                         break;
534                 case 'w':
535                         ep = NULL;
536                         errno = 0;
537                         waittime = strtoul(optarg, &ep, 0);
538                         if (errno || !*optarg || *ep) {
539                                 fprintf(stderr,
540                                     "traceroute6: invalid wait time.\n");
541                                 exit(1);
542                         }
543                         if (waittime < 1) {
544                                 fprintf(stderr,
545                                     "traceroute6: wait must be >= 1 sec.\n");
546                                 exit(1);
547                         }
548                         break;
549                 default:
550                         usage();
551                 }
552         argc -= optind;
553         argv += optind;
554
555         /*
556          * Open socket to send probe packets.
557          */
558         switch (useproto) {
559         case IPPROTO_ICMPV6:
560                 sndsock = rcvsock;
561                 break;
562         case IPPROTO_UDP:
563                 if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
564                         perror("socket(SOCK_DGRAM)");
565                         exit(5);
566                 }
567                 break;
568         case IPPROTO_NONE:
569         case IPPROTO_SCTP:
570         case IPPROTO_TCP:
571                 if ((sndsock = socket(AF_INET6, SOCK_RAW, useproto)) < 0) {
572                         perror("socket(SOCK_RAW)");
573                         exit(5);
574                 }
575                 break;
576         default:
577                 fprintf(stderr, "traceroute6: unknown probe protocol %d\n",
578                     useproto);
579                 exit(5);
580         }
581         if (max_hops < first_hop) {
582                 fprintf(stderr,
583                     "traceroute6: max hoplimit must be larger than first hoplimit.\n");
584                 exit(1);
585         }
586
587         /* revoke privs */
588         uid = getuid();
589         if (setresuid(uid, uid, uid) == -1) {
590                 perror("setresuid");
591                 exit(1);
592         }
593
594
595         if (argc < 1 || argc > 2)
596                 usage();
597
598 #if 1
599         setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
600 #else
601         setlinebuf(stdout);
602 #endif
603
604         memset(&hints, 0, sizeof(hints));
605         hints.ai_family = PF_INET6;
606         hints.ai_socktype = SOCK_RAW;
607         hints.ai_protocol = IPPROTO_ICMPV6;
608         hints.ai_flags = AI_CANONNAME;
609         error = getaddrinfo(*argv, NULL, &hints, &res);
610         if (error) {
611                 fprintf(stderr,
612                     "traceroute6: %s\n", gai_strerror(error));
613                 exit(1);
614         }
615         if (res->ai_addrlen != sizeof(Dst)) {
616                 fprintf(stderr,
617                     "traceroute6: size of sockaddr mismatch\n");
618                 exit(1);
619         }
620         memcpy(&Dst, res->ai_addr, res->ai_addrlen);
621         hostname = res->ai_canonname ? strdup(res->ai_canonname) : *argv;
622         if (!hostname) {
623                 fprintf(stderr, "traceroute6: not enough core\n");
624                 exit(1);
625         }
626         if (res->ai_next) {
627                 if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf,
628                     sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
629                         strlcpy(hbuf, "?", sizeof(hbuf));
630                 fprintf(stderr, "traceroute6: Warning: %s has multiple "
631                     "addresses; using %s\n", hostname, hbuf);
632         }
633         freeaddrinfo(res);
634         if (*++argv) {
635                 ep = NULL;
636                 errno = 0;
637                 datalen = strtoul(*argv, &ep, 0);
638                 if (errno || *ep) {
639                         fprintf(stderr,
640                             "traceroute6: invalid packet length.\n");
641                         exit(1);
642                 }
643         }
644         switch (useproto) {
645         case IPPROTO_ICMPV6:
646                 minlen = ICMP6ECHOLEN;
647                 break;
648         case IPPROTO_UDP:
649                 minlen = sizeof(struct udphdr);
650                 break;
651         case IPPROTO_NONE:
652                 minlen = 0;
653                 datalen = 0;
654                 break;
655         case IPPROTO_SCTP:
656                 minlen = sizeof(struct sctphdr);
657                 break;
658         case IPPROTO_TCP:
659                 minlen = sizeof(struct tcphdr);
660                 break;
661         default:
662                 fprintf(stderr, "traceroute6: unknown probe protocol %d.\n",
663                     useproto);
664                 exit(1);
665         }
666         if (datalen < minlen)
667                 datalen = minlen;
668         else if (datalen >= MAXPACKET) {
669                 fprintf(stderr,
670                     "traceroute6: packet size must be %zu <= s < %d.\n",
671                     minlen, MAXPACKET);
672                 exit(1);
673         }
674         if (useproto == IPPROTO_UDP)
675                 datalen -= sizeof(struct udphdr);
676         if ((useproto == IPPROTO_SCTP) && (datalen & 3)) {
677                 fprintf(stderr, 
678                     "traceroute6: packet size must be a multiple of 4.\n");
679                 exit(1);
680         }
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 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
711         /*
712          * do not raise error even if setsockopt fails, kernel may have ipsec
713          * turned off.
714          */
715         if (setpolicy(rcvsock, ipsec_inpolicy) < 0)
716                 errx(1, "%s", ipsec_strerror());
717         if (setpolicy(rcvsock, ipsec_outpolicy) < 0)
718                 errx(1, "%s", ipsec_strerror());
719 #else
720     {
721         int level = IPSEC_LEVEL_NONE;
722
723         (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
724             sizeof(level));
725         (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
726             sizeof(level));
727 #ifdef IP_AUTH_TRANS_LEVEL
728         (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
729             sizeof(level));
730 #else
731         (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
732             sizeof(level));
733 #endif
734 #ifdef IP_AUTH_NETWORK_LEVEL
735         (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
736             sizeof(level));
737 #endif
738     }
739 #endif /* !(IPSEC && IPSEC_POLICY_IPSEC) */
740
741 #ifdef SO_SNDBUF
742         i = datalen;
743         if (i == 0)
744                 i = 1;
745         if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&i,
746             sizeof(i)) < 0) {
747                 perror("setsockopt(SO_SNDBUF)");
748                 exit(6);
749         }
750 #endif /* SO_SNDBUF */
751         if (options & SO_DEBUG)
752                 (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
753                     (char *)&on, sizeof(on));
754         if (options & SO_DONTROUTE)
755                 (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
756                     (char *)&on, sizeof(on));
757         if (rth) {/* XXX: there is no library to finalize the header... */
758                 rth->ip6r_len = rth->ip6r_segleft * 2;
759                 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_RTHDR,
760                     (void *)rth, (rth->ip6r_len + 1) << 3)) {
761                         fprintf(stderr, "setsockopt(IPV6_RTHDR): %s\n",
762                             strerror(errno));
763                         exit(1);
764                 }
765         }
766 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
767         /*
768          * do not raise error even if setsockopt fails, kernel may have ipsec
769          * turned off.
770          */
771         if (setpolicy(sndsock, ipsec_inpolicy) < 0)
772                 errx(1, "%s", ipsec_strerror());
773         if (setpolicy(sndsock, ipsec_outpolicy) < 0)
774                 errx(1, "%s", ipsec_strerror());
775 #else
776     {
777         int level = IPSEC_LEVEL_BYPASS;
778
779         (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
780             sizeof(level));
781         (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
782             sizeof(level));
783 #ifdef IP_AUTH_TRANS_LEVEL
784         (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
785             sizeof(level));
786 #else
787         (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
788             sizeof(level));
789 #endif
790 #ifdef IP_AUTH_NETWORK_LEVEL
791         (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
792             sizeof(level));
793 #endif
794     }
795 #endif /* !(IPSEC && IPSEC_POLICY_IPSEC) */
796
797         /*
798          * Source selection
799          */
800         bzero(&Src, sizeof(Src));
801         if (source) {
802                 memset(&hints, 0, sizeof(hints));
803                 hints.ai_family = AF_INET6;
804                 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
805                 hints.ai_flags = AI_NUMERICHOST;
806                 error = getaddrinfo(source, "0", &hints, &res);
807                 if (error) {
808                         printf("traceroute6: %s: %s\n", source,
809                             gai_strerror(error));
810                         exit(1);
811                 }
812                 if (res->ai_addrlen > sizeof(Src)) {
813                         printf("traceroute6: %s: %s\n", source,
814                             gai_strerror(error));
815                         exit(1);
816                 }
817                 memcpy(&Src, res->ai_addr, res->ai_addrlen);
818                 freeaddrinfo(res);
819         } else {
820                 struct sockaddr_in6 Nxt;
821                 int dummy;
822                 socklen_t len;
823
824                 Nxt = Dst;
825                 Nxt.sin6_port = htons(DUMMY_PORT);
826                 if (cmsg != NULL)
827                         bcopy(inet6_rthdr_getaddr(cmsg, 1), &Nxt.sin6_addr,
828                             sizeof(Nxt.sin6_addr));
829                 if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
830                         perror("socket");
831                         exit(1);
832                 }
833                 if (connect(dummy, (struct sockaddr *)&Nxt, Nxt.sin6_len) < 0) {
834                         perror("connect");
835                         exit(1);
836                 }
837                 len = sizeof(Src);
838                 if (getsockname(dummy, (struct sockaddr *)&Src, &len) < 0) {
839                         perror("getsockname");
840                         exit(1);
841                 }
842                 if (getnameinfo((struct sockaddr *)&Src, Src.sin6_len,
843                     src0, sizeof(src0), NULL, 0, NI_NUMERICHOST)) {
844                         fprintf(stderr, "getnameinfo failed for source\n");
845                         exit(1);
846                 }
847                 source = src0;
848                 close(dummy);
849         }
850
851         Src.sin6_port = htons(0);
852         if (bind(sndsock, (struct sockaddr *)&Src, Src.sin6_len) < 0) {
853                 perror("bind");
854                 exit(1);
855         }
856
857         {
858                 socklen_t len;
859
860                 len = sizeof(Src);
861                 if (getsockname(sndsock, (struct sockaddr *)&Src, &len) < 0) {
862                         perror("getsockname");
863                         exit(1);
864                 }
865                 srcport = ntohs(Src.sin6_port);
866         }
867
868         if (as_path) {
869                 asn = as_setup(as_server);
870                 if (asn == NULL) {
871                         fprintf(stderr,
872                             "traceroute6: as_setup failed, AS# lookups"
873                             " disabled\n");
874                         (void)fflush(stderr);
875                         as_path = 0;
876                 }
877         }
878
879         /*
880          * Message to users
881          */
882         if (getnameinfo((struct sockaddr *)&Dst, Dst.sin6_len, hbuf,
883             sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
884                 strlcpy(hbuf, "(invalid)", sizeof(hbuf));
885         fprintf(stderr, "traceroute6");
886         fprintf(stderr, " to %s (%s)", hostname, hbuf);
887         if (source)
888                 fprintf(stderr, " from %s", source);
889         fprintf(stderr, ", %lu hops max, %lu byte packets\n",
890             max_hops,
891             datalen + ((useproto == IPPROTO_UDP) ? sizeof(struct udphdr) : 0));
892         (void) fflush(stderr);
893
894         if (first_hop > 1)
895                 printf("Skipping %lu intermediate hops\n", first_hop - 1);
896
897         /*
898          * Main loop
899          */
900         for (hops = first_hop; hops <= max_hops; ++hops) {
901                 struct in6_addr lastaddr;
902                 int got_there = 0;
903                 unsigned unreachable = 0;
904
905                 printf("%2lu ", hops);
906                 bzero(&lastaddr, sizeof(lastaddr));
907                 for (probe = 0; probe < nprobes; ++probe) {
908                         int cc;
909                         struct timeval t1, t2;
910
911                         (void) gettimeofday(&t1, NULL);
912                         send_probe(++seq, hops);
913                         while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) {
914                                 (void) gettimeofday(&t2, NULL);
915                                 if (packet_ok(&rcvmhdr, cc, seq, &type, &code)) {
916                                         if (!IN6_ARE_ADDR_EQUAL(&Rcv.sin6_addr,
917                                             &lastaddr)) {
918                                                 if (probe > 0)
919                                                         fputs("\n   ", stdout);
920                                                 print(&rcvmhdr, cc);
921                                                 lastaddr = Rcv.sin6_addr;
922                                         }
923                                         printf("  %.3f ms", deltaT(&t1, &t2));
924                                         if (type == ICMP6_DST_UNREACH) {
925                                                 switch (code) {
926                                                 case ICMP6_DST_UNREACH_NOROUTE:
927                                                         ++unreachable;
928                                                         printf(" !N");
929                                                         break;
930                                                 case ICMP6_DST_UNREACH_ADMIN:
931                                                         ++unreachable;
932                                                         printf(" !P");
933                                                         break;
934                                                 case ICMP6_DST_UNREACH_NOTNEIGHBOR:
935                                                         ++unreachable;
936                                                         printf(" !S");
937                                                         break;
938                                                 case ICMP6_DST_UNREACH_ADDR:
939                                                         ++unreachable;
940                                                         printf(" !A");
941                                                         break;
942                                                 case ICMP6_DST_UNREACH_NOPORT:
943                                                         if (rcvhlim >= 0 &&
944                                                             rcvhlim <= 1)
945                                                                 printf(" !");
946                                                         ++got_there;
947                                                         break;
948                                                 }
949                                         } else if (type == ICMP6_PARAM_PROB &&
950                                             code == ICMP6_PARAMPROB_NEXTHEADER) {
951                                                 printf(" !H");
952                                                 ++got_there;
953                                         } else if (type == ICMP6_ECHO_REPLY) {
954                                                 if (rcvhlim >= 0 &&
955                                                     rcvhlim <= 1)
956                                                         printf(" !");
957                                                 ++got_there;
958                                         }
959                                         break;
960                                 } else if (deltaT(&t1, &t2) > waittime * 1000) {
961                                         cc = 0;
962                                         break;
963                                 }
964                         }
965                         if (cc == 0)
966                                 printf(" *");
967                         (void) fflush(stdout);
968                 }
969                 putchar('\n');
970                 if (got_there ||
971                     (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) {
972                         exit(0);
973                 }
974         }
975         if (as_path)
976                 as_shutdown(asn);
977
978         exit(0);
979 }
980
981 int
982 wait_for_reply(int sock, struct msghdr *mhdr)
983 {
984 #ifdef HAVE_POLL
985         struct pollfd pfd[1];
986         int cc = 0;
987
988         pfd[0].fd = sock;
989         pfd[0].events = POLLIN;
990         pfd[0].revents = 0;
991
992         if (poll(pfd, 1, waittime * 1000) > 0)
993                 cc = recvmsg(rcvsock, mhdr, 0);
994
995         return (cc);
996 #else
997         fd_set *fdsp;
998         struct timeval wait;
999         int cc = 0, fdsn;
1000
1001         fdsn = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
1002         if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
1003                 err(1, "malloc");
1004         memset(fdsp, 0, fdsn);
1005         FD_SET(sock, fdsp);
1006         wait.tv_sec = waittime; wait.tv_usec = 0;
1007
1008         if (select(sock+1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0)
1009                 cc = recvmsg(rcvsock, mhdr, 0);
1010
1011         free(fdsp);
1012         return (cc);
1013 #endif
1014 }
1015
1016 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
1017 int
1018 setpolicy(int so, char *policy)
1019 {
1020         char *buf;
1021
1022         buf = ipsec_set_policy(policy, strlen(policy));
1023         if (buf == NULL) {
1024                 warnx("%s", ipsec_strerror());
1025                 return -1;
1026         }
1027         (void)setsockopt(so, IPPROTO_IPV6, IPV6_IPSEC_POLICY,
1028             buf, ipsec_get_policylen(buf));
1029
1030         free(buf);
1031
1032         return 0;
1033 }
1034 #endif
1035
1036 void
1037 send_probe(int seq, u_long hops)
1038 {
1039         struct icmp6_hdr *icp;
1040         struct sctphdr *sctp;
1041         struct sctp_chunkhdr *chk;
1042         struct sctp_init_chunk *init;
1043         struct sctp_paramhdr *param;
1044         struct tcphdr *tcp;
1045         int i;
1046
1047         i = hops;
1048         if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
1049             (char *)&i, sizeof(i)) < 0) {
1050                 perror("setsockopt IPV6_UNICAST_HOPS");
1051         }
1052
1053         Dst.sin6_port = htons(port + seq);
1054
1055         switch (useproto) {
1056         case IPPROTO_ICMPV6:
1057                 icp = (struct icmp6_hdr *)outpacket;
1058
1059                 icp->icmp6_type = ICMP6_ECHO_REQUEST;
1060                 icp->icmp6_code = 0;
1061                 icp->icmp6_cksum = 0;
1062                 icp->icmp6_id = ident;
1063                 icp->icmp6_seq = htons(seq);
1064                 break;
1065         case IPPROTO_UDP:
1066                 break;
1067         case IPPROTO_NONE:
1068                 /* No space for anything. No harm as seq/tv32 are decorative. */
1069                 break;
1070         case IPPROTO_SCTP:
1071                 sctp = (struct sctphdr *)outpacket;
1072
1073                 sctp->src_port = htons(ident);
1074                 sctp->dest_port = htons(port + seq);
1075                 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1076                     sizeof(struct sctp_init_chunk))) {
1077                         sctp->v_tag = 0;
1078                 } else {
1079                         sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port;
1080                 }
1081                 sctp->checksum = htonl(0);
1082                 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1083                     sizeof(struct sctp_init_chunk))) {
1084                         /*
1085                          * Send a packet containing an INIT chunk. This works
1086                          * better in case of firewalls on the path, but
1087                          * results in a probe packet containing at least
1088                          * 32 bytes of payload. For shorter payloads, use
1089                          * SHUTDOWN-ACK chunks.
1090                          */
1091                         init = (struct sctp_init_chunk *)(sctp + 1);
1092                         init->ch.chunk_type = SCTP_INITIATION;
1093                         init->ch.chunk_flags = 0;
1094                         init->ch.chunk_length = htons((u_int16_t)(datalen -
1095                             sizeof(struct sctphdr)));
1096                         init->init.initiate_tag = (sctp->src_port << 16) |
1097                             sctp->dest_port;
1098                         init->init.a_rwnd = htonl(1500);
1099                         init->init.num_outbound_streams = htons(1);
1100                         init->init.num_inbound_streams = htons(1);
1101                         init->init.initial_tsn = htonl(0);
1102                         if (datalen >= (u_long)(sizeof(struct sctphdr) +
1103                             sizeof(struct sctp_init_chunk) +
1104                             sizeof(struct sctp_paramhdr))) {
1105                                 param = (struct sctp_paramhdr *)(init + 1);
1106                                 param->param_type = htons(SCTP_PAD);
1107                                 param->param_length =
1108                                     htons((u_int16_t)(datalen -
1109                                     sizeof(struct sctphdr) -
1110                                     sizeof(struct sctp_init_chunk)));
1111                         }
1112                 } else {
1113                         /*
1114                          * Send a packet containing a SHUTDOWN-ACK chunk,
1115                          * possibly followed by a PAD chunk.
1116                          */
1117                         if (datalen >= (u_long)(sizeof(struct sctphdr) +
1118                             sizeof(struct sctp_chunkhdr))) {
1119                                 chk = (struct sctp_chunkhdr *)(sctp + 1);
1120                                 chk->chunk_type = SCTP_SHUTDOWN_ACK;
1121                                 chk->chunk_flags = 0;
1122                                 chk->chunk_length = htons(4);
1123                         }
1124                         if (datalen >= (u_long)(sizeof(struct sctphdr) +
1125                             2 * sizeof(struct sctp_chunkhdr))) {
1126                                 chk = chk + 1;
1127                                 chk->chunk_type = SCTP_PAD_CHUNK;
1128                                 chk->chunk_flags = 0;
1129                                 chk->chunk_length = htons((u_int16_t)(datalen -
1130                                     sizeof(struct sctphdr) -
1131                                     sizeof(struct sctp_chunkhdr)));
1132                         }
1133                 }
1134                 sctp->checksum = sctp_crc32c(outpacket, datalen);
1135                 break;
1136         case IPPROTO_TCP:
1137                 tcp = (struct tcphdr *)outpacket;
1138
1139                 tcp->th_sport = htons(ident);
1140                 tcp->th_dport = htons(port + seq);
1141                 tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
1142                 tcp->th_ack = 0;
1143                 tcp->th_off = 5;
1144                 tcp->th_flags = TH_SYN;
1145                 tcp->th_sum = 0;
1146                 tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen);
1147                 break;
1148         default:
1149                 fprintf(stderr, "Unknown probe protocol %d.\n", useproto);
1150                 exit(1);
1151         }
1152
1153         i = sendto(sndsock, (char *)outpacket, datalen, 0,
1154             (struct sockaddr *)&Dst, Dst.sin6_len);
1155         if (i < 0 || (u_long)i != datalen)  {
1156                 if (i < 0)
1157                         perror("sendto");
1158                 printf("traceroute6: wrote %s %lu chars, ret=%d\n",
1159                     hostname, datalen, i);
1160                 (void) fflush(stdout);
1161         }
1162 }
1163
1164 int
1165 get_hoplim(struct msghdr *mhdr)
1166 {
1167         struct cmsghdr *cm;
1168
1169         for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1170             cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1171                 if (cm->cmsg_level == IPPROTO_IPV6 &&
1172                     cm->cmsg_type == IPV6_HOPLIMIT &&
1173                     cm->cmsg_len == CMSG_LEN(sizeof(int)))
1174                         return (*(int *)CMSG_DATA(cm));
1175         }
1176
1177         return (-1);
1178 }
1179
1180 double
1181 deltaT(struct timeval *t1p, struct timeval *t2p)
1182 {
1183         double dt;
1184
1185         dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1186             (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1187         return (dt);
1188 }
1189
1190 /*
1191  * Convert an ICMP "type" field to a printable string.
1192  */
1193 const char *
1194 pr_type(int t0)
1195 {
1196         u_char t = t0 & 0xff;
1197         const char *cp;
1198
1199         switch (t) {
1200         case ICMP6_DST_UNREACH:
1201                 cp = "Destination Unreachable";
1202                 break;
1203         case ICMP6_PACKET_TOO_BIG:
1204                 cp = "Packet Too Big";
1205                 break;
1206         case ICMP6_TIME_EXCEEDED:
1207                 cp = "Time Exceeded";
1208                 break;
1209         case ICMP6_PARAM_PROB:
1210                 cp = "Parameter Problem";
1211                 break;
1212         case ICMP6_ECHO_REQUEST:
1213                 cp = "Echo Request";
1214                 break;
1215         case ICMP6_ECHO_REPLY:
1216                 cp = "Echo Reply";
1217                 break;
1218         case ICMP6_MEMBERSHIP_QUERY:
1219                 cp = "Group Membership Query";
1220                 break;
1221         case ICMP6_MEMBERSHIP_REPORT:
1222                 cp = "Group Membership Report";
1223                 break;
1224         case ICMP6_MEMBERSHIP_REDUCTION:
1225                 cp = "Group Membership Reduction";
1226                 break;
1227         case ND_ROUTER_SOLICIT:
1228                 cp = "Router Solicitation";
1229                 break;
1230         case ND_ROUTER_ADVERT:
1231                 cp = "Router Advertisement";
1232                 break;
1233         case ND_NEIGHBOR_SOLICIT:
1234                 cp = "Neighbor Solicitation";
1235                 break;
1236         case ND_NEIGHBOR_ADVERT:
1237                 cp = "Neighbor Advertisement";
1238                 break;
1239         case ND_REDIRECT:
1240                 cp = "Redirect";
1241                 break;
1242         default:
1243                 cp = "Unknown";
1244                 break;
1245         }
1246         return cp;
1247 }
1248
1249 int
1250 packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code)
1251 {
1252         struct icmp6_hdr *icp;
1253         struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1254         char *buf = (char *)mhdr->msg_iov[0].iov_base;
1255         struct cmsghdr *cm;
1256         int *hlimp;
1257         char hbuf[NI_MAXHOST];
1258
1259 #ifdef OLDRAWSOCKET
1260         int hlen;
1261         struct ip6_hdr *ip;
1262 #endif
1263
1264 #ifdef OLDRAWSOCKET
1265         ip = (struct ip6_hdr *) buf;
1266         hlen = sizeof(struct ip6_hdr);
1267         if (cc < hlen + sizeof(struct icmp6_hdr)) {
1268                 if (verbose) {
1269                         if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1270                             hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1271                                 strlcpy(hbuf, "invalid", sizeof(hbuf));
1272                         printf("packet too short (%d bytes) from %s\n", cc,
1273                             hbuf);
1274                 }
1275                 return (0);
1276         }
1277         cc -= hlen;
1278         icp = (struct icmp6_hdr *)(buf + hlen);
1279 #else
1280         if (cc < (int)sizeof(struct icmp6_hdr)) {
1281                 if (verbose) {
1282                         if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1283                             hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1284                                 strlcpy(hbuf, "invalid", sizeof(hbuf));
1285                         printf("data too short (%d bytes) from %s\n", cc, hbuf);
1286                 }
1287                 return (0);
1288         }
1289         icp = (struct icmp6_hdr *)buf;
1290 #endif
1291         /* get optional information via advanced API */
1292         rcvpktinfo = NULL;
1293         hlimp = NULL;
1294         for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1295             cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1296                 if (cm->cmsg_level == IPPROTO_IPV6 &&
1297                     cm->cmsg_type == IPV6_PKTINFO &&
1298                     cm->cmsg_len ==
1299                     CMSG_LEN(sizeof(struct in6_pktinfo)))
1300                         rcvpktinfo = (struct in6_pktinfo *)(CMSG_DATA(cm));
1301
1302                 if (cm->cmsg_level == IPPROTO_IPV6 &&
1303                     cm->cmsg_type == IPV6_HOPLIMIT &&
1304                     cm->cmsg_len == CMSG_LEN(sizeof(int)))
1305                         hlimp = (int *)CMSG_DATA(cm);
1306         }
1307         if (rcvpktinfo == NULL || hlimp == NULL) {
1308                 warnx("failed to get received hop limit or packet info");
1309 #if 0
1310                 return (0);
1311 #else
1312                 rcvhlim = 0;    /*XXX*/
1313 #endif
1314         }
1315         else
1316                 rcvhlim = *hlimp;
1317
1318         *type = icp->icmp6_type;
1319         *code = icp->icmp6_code;
1320         if ((*type == ICMP6_TIME_EXCEEDED &&
1321             *code == ICMP6_TIME_EXCEED_TRANSIT) ||
1322             (*type == ICMP6_DST_UNREACH) ||
1323             (*type == ICMP6_PARAM_PROB &&
1324             *code == ICMP6_PARAMPROB_NEXTHEADER)) {
1325                 struct ip6_hdr *hip;
1326                 struct icmp6_hdr *icmp;
1327                 struct sctp_init_chunk *init;
1328                 struct sctphdr *sctp;
1329                 struct tcphdr *tcp;
1330                 struct udphdr *udp;
1331                 void *up;
1332
1333                 hip = (struct ip6_hdr *)(icp + 1);
1334                 if ((up = get_uphdr(hip, (u_char *)(buf + cc))) == NULL) {
1335                         if (verbose)
1336                                 warnx("failed to get upper layer header");
1337                         return (0);
1338                 }
1339                 switch (useproto) {
1340                 case IPPROTO_ICMPV6:
1341                         icmp = (struct icmp6_hdr *)up;
1342                         if (icmp->icmp6_id == ident &&
1343                             icmp->icmp6_seq == htons(seq))
1344                                 return (1);
1345                         break;
1346                 case IPPROTO_UDP:
1347                         udp = (struct udphdr *)up;
1348                         if (udp->uh_sport == htons(srcport) &&
1349                             udp->uh_dport == htons(port + seq))
1350                                 return (1);
1351                         break;
1352                 case IPPROTO_SCTP:
1353                         sctp = (struct sctphdr *)up;
1354                         if (sctp->src_port != htons(ident) ||
1355                             sctp->dest_port != htons(port + seq)) {
1356                                 break;
1357                         }
1358                         if (datalen >= (u_long)(sizeof(struct sctphdr) +
1359                             sizeof(struct sctp_init_chunk))) {
1360                                 if (sctp->v_tag != 0) {
1361                                         break;
1362                                 }
1363                                 init = (struct sctp_init_chunk *)(sctp + 1);
1364                                 /* Check the initiate tag, if available. */
1365                                 if ((char *)&init->init.a_rwnd > buf + cc) {
1366                                         return (1);
1367                                 }
1368                                 if (init->init.initiate_tag == (u_int32_t)
1369                                     ((sctp->src_port << 16) | sctp->dest_port)) {
1370                                         return (1);
1371                                 }
1372                         } else {
1373                                 if (sctp->v_tag ==
1374                                     (u_int32_t)((sctp->src_port << 16) |
1375                                     sctp->dest_port)) {
1376                                         return (1);
1377                                 }
1378                         }
1379                         break;
1380                 case IPPROTO_TCP:
1381                         tcp = (struct tcphdr *)up;
1382                         if (tcp->th_sport == htons(ident) &&
1383                             tcp->th_dport == htons(port + seq) &&
1384                             tcp->th_seq ==
1385                             (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport))
1386                                 return (1);
1387                         break;
1388                 case IPPROTO_NONE:
1389                         return (1);
1390                 default:
1391                         fprintf(stderr, "Unknown probe proto %d.\n", useproto);
1392                         break;
1393                 }
1394         } else if (useproto == IPPROTO_ICMPV6 && *type == ICMP6_ECHO_REPLY) {
1395                 if (icp->icmp6_id == ident &&
1396                     icp->icmp6_seq == htons(seq))
1397                         return (1);
1398         }
1399         if (verbose) {
1400                 char sbuf[NI_MAXHOST+1], dbuf[INET6_ADDRSTRLEN];
1401                 u_int8_t *p;
1402                 int i;
1403
1404                 if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1405                     sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0)
1406                         strlcpy(sbuf, "invalid", sizeof(sbuf));
1407                 printf("\n%d bytes from %s to %s", cc, sbuf,
1408                     rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1409                     dbuf, sizeof(dbuf)) : "?");
1410                 printf(": icmp type %d (%s) code %d\n", *type, pr_type(*type),
1411                     *code);
1412                 p = (u_int8_t *)(icp + 1);
1413 #define WIDTH   16
1414                 for (i = 0; i < cc; i++) {
1415                         if (i % WIDTH == 0)
1416                                 printf("%04x:", i);
1417                         if (i % 4 == 0)
1418                                 printf(" ");
1419                         printf("%02x", p[i]);
1420                         if (i % WIDTH == WIDTH - 1)
1421                                 printf("\n");
1422                 }
1423                 if (cc % WIDTH != 0)
1424                         printf("\n");
1425         }
1426         return (0);
1427 }
1428
1429 /*
1430  * Increment pointer until find the UDP or ICMP header.
1431  */
1432 void *
1433 get_uphdr(struct ip6_hdr *ip6, u_char *lim)
1434 {
1435         u_char *cp = (u_char *)ip6, nh;
1436         int hlen;
1437         static u_char none_hdr[1]; /* Fake pointer for IPPROTO_NONE. */
1438
1439         if (cp + sizeof(*ip6) > lim)
1440                 return (NULL);
1441
1442         nh = ip6->ip6_nxt;
1443         cp += sizeof(struct ip6_hdr);
1444
1445         while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) {
1446                 switch (nh) {
1447                 case IPPROTO_ESP:
1448                         return (NULL);
1449                 case IPPROTO_ICMPV6:
1450                         return (useproto == nh ? cp : NULL);
1451                 case IPPROTO_SCTP:
1452                 case IPPROTO_TCP:
1453                 case IPPROTO_UDP:
1454                         return (useproto == nh ? cp : NULL);
1455                 case IPPROTO_NONE:
1456                         return (useproto == nh ? none_hdr : NULL);
1457                 case IPPROTO_FRAGMENT:
1458                         hlen = sizeof(struct ip6_frag);
1459                         nh = ((struct ip6_frag *)cp)->ip6f_nxt;
1460                         break;
1461                 case IPPROTO_AH:
1462                         hlen = (((struct ip6_ext *)cp)->ip6e_len + 2) << 2;
1463                         nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1464                         break;
1465                 default:
1466                         hlen = (((struct ip6_ext *)cp)->ip6e_len + 1) << 3;
1467                         nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1468                         break;
1469                 }
1470
1471                 cp += hlen;
1472         }
1473
1474         return (NULL);
1475 }
1476
1477 void
1478 print(struct msghdr *mhdr, int cc)
1479 {
1480         struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1481         char hbuf[NI_MAXHOST];
1482
1483         if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1484             hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1485                 strlcpy(hbuf, "invalid", sizeof(hbuf));
1486         if (as_path)
1487                 printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6));
1488         if (nflag)
1489                 printf(" %s", hbuf);
1490         else if (lflag)
1491                 printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf);
1492         else
1493                 printf(" %s", inetname((struct sockaddr *)from));
1494
1495         if (verbose) {
1496 #ifdef OLDRAWSOCKET
1497                 printf(" %d bytes to %s", cc,
1498                     rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1499                     hbuf, sizeof(hbuf)) : "?");
1500 #else
1501                 printf(" %d bytes of data to %s", cc,
1502                     rcvpktinfo ?  inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1503                     hbuf, sizeof(hbuf)) : "?");
1504 #endif
1505         }
1506 }
1507
1508 /*
1509  * Construct an Internet address representation.
1510  * If the nflag has been supplied, give
1511  * numeric value, otherwise try for symbolic name.
1512  */
1513 const char *
1514 inetname(struct sockaddr *sa)
1515 {
1516         static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1];
1517         static int first = 1;
1518         char *cp;
1519
1520         if (first && !nflag) {
1521                 first = 0;
1522                 if (gethostname(domain, sizeof(domain)) == 0 &&
1523                     (cp = strchr(domain, '.')))
1524                         (void) strlcpy(domain, cp + 1, sizeof(domain));
1525                 else
1526                         domain[0] = 0;
1527         }
1528         cp = NULL;
1529         if (!nflag) {
1530                 if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1531                     NI_NAMEREQD) == 0) {
1532                         if ((cp = strchr(line, '.')) &&
1533                             !strcmp(cp + 1, domain))
1534                                 *cp = 0;
1535                         cp = line;
1536                 }
1537         }
1538         if (cp)
1539                 return cp;
1540
1541         if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1542             NI_NUMERICHOST) != 0)
1543                 strlcpy(line, "invalid", sizeof(line));
1544         return line;
1545 }
1546
1547 /*
1548  * CRC32C routine for the Stream Control Transmission Protocol
1549  */
1550
1551 #define CRC32C(c, d) (c = (c>>8) ^ crc_c[(c^(d))&0xFF])
1552
1553 static u_int32_t crc_c[256] = {
1554         0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
1555         0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
1556         0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
1557         0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
1558         0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
1559         0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
1560         0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
1561         0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
1562         0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
1563         0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
1564         0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
1565         0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
1566         0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
1567         0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
1568         0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
1569         0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
1570         0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
1571         0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
1572         0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
1573         0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
1574         0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
1575         0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
1576         0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
1577         0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
1578         0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
1579         0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
1580         0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
1581         0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
1582         0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
1583         0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
1584         0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
1585         0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
1586         0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
1587         0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
1588         0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
1589         0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
1590         0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
1591         0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
1592         0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
1593         0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
1594         0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
1595         0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
1596         0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
1597         0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
1598         0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
1599         0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
1600         0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
1601         0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
1602         0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
1603         0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
1604         0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
1605         0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
1606         0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
1607         0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
1608         0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
1609         0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
1610         0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
1611         0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
1612         0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
1613         0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
1614         0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
1615         0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
1616         0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
1617         0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
1618 };
1619
1620 u_int32_t
1621 sctp_crc32c(void *pack, u_int32_t len)
1622 {
1623         u_int32_t i, crc32c;
1624         u_int8_t byte0, byte1, byte2, byte3;
1625         u_int8_t *buf = (u_int8_t *)pack;
1626
1627         crc32c = ~0;
1628         for (i = 0; i < len; i++)
1629                 CRC32C(crc32c, buf[i]);
1630         crc32c = ~crc32c;
1631         byte0  = crc32c & 0xff;
1632         byte1  = (crc32c>>8) & 0xff;
1633         byte2  = (crc32c>>16) & 0xff;
1634         byte3  = (crc32c>>24) & 0xff;
1635         crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
1636         return htonl(crc32c);
1637 }
1638
1639 u_int16_t
1640 in_cksum(u_int16_t *addr, int len)
1641 {
1642         int nleft = len;
1643         u_int16_t *w = addr;
1644         u_int16_t answer;
1645         int sum = 0;
1646
1647         /*
1648          *  Our algorithm is simple, using a 32 bit accumulator (sum),
1649          *  we add sequential 16 bit words to it, and at the end, fold
1650          *  back all the carry bits from the top 16 bits into the lower
1651          *  16 bits.
1652          */
1653         while (nleft > 1)  {
1654                 sum += *w++;
1655                 nleft -= 2;
1656         }
1657
1658         /* mop up an odd byte, if necessary */
1659         if (nleft == 1)
1660                 sum += *(u_char *)w;
1661
1662         /*
1663          * add back carry outs from top 16 bits to low 16 bits
1664          */
1665         sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */
1666         sum += (sum >> 16);                     /* add carry */
1667         answer = ~sum;                          /* truncate to 16 bits */
1668         return (answer);
1669 }
1670
1671 u_int16_t
1672 tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1673     void *payload, u_int32_t len)
1674 {
1675         struct {
1676                 struct in6_addr src;
1677                 struct in6_addr dst;
1678                 u_int32_t len;
1679                 u_int8_t zero[3];
1680                 u_int8_t next;
1681         } pseudo_hdr;
1682         u_int16_t sum[2];
1683
1684         pseudo_hdr.src = src->sin6_addr;
1685         pseudo_hdr.dst = dst->sin6_addr;
1686         pseudo_hdr.len = htonl(len);
1687         pseudo_hdr.zero[0] = 0;
1688         pseudo_hdr.zero[1] = 0;
1689         pseudo_hdr.zero[2] = 0;
1690         pseudo_hdr.next = IPPROTO_TCP;
1691
1692         sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1693         sum[0] = in_cksum(payload, len);
1694
1695         return (~in_cksum(sum, sizeof(sum)));
1696 }
1697
1698 void
1699 usage(void)
1700 {
1701
1702         fprintf(stderr,
1703 "usage: traceroute6 [-adIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n"
1704 "       [-m hoplimit] [-p port] [-q probes] [-s src] [-w waittime] target\n"
1705 "       [datalen]\n");
1706         exit(1);
1707 }