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