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