]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/traceroute6/traceroute6.c
autofs: Remove stale comment
[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 #endif /* not lint */
77
78 /*
79  * traceroute host  - trace the route ip packets follow going to "host".
80  *
81  * Attempt to trace the route an ip packet would follow to some
82  * internet host.  We find out intermediate hops by launching probe
83  * packets with a small ttl (time to live) then listening for an
84  * icmp "time exceeded" reply from a gateway.  We start our probes
85  * with a ttl of one and increase by one until we get an icmp "port
86  * unreachable" (which means we got to "host") or hit a max (which
87  * defaults to 30 hops & can be changed with the -m flag).  Three
88  * probes (change with -q flag) are sent at each ttl setting and a
89  * line is printed showing the ttl, address of the gateway and
90  * round trip time of each probe.  If the probe answers come from
91  * different gateways, the address of each responding system will
92  * be printed.  If there is no response within a 5 sec. timeout
93  * interval (changed with the -w flag), a "*" is printed for that
94  * probe.
95  *
96  * Probe packets are UDP format.  We don't want the destination
97  * host to process them so the destination port is set to an
98  * unlikely value (if some clod on the destination is using that
99  * value, it can be changed with the -p flag).
100  *
101  * A sample use might be:
102  *
103  *     [yak 71]% traceroute nis.nsf.net.
104  *     traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 56 byte packet
105  *      1  helios.ee.lbl.gov (128.3.112.1)  19 ms  19 ms  0 ms
106  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
107  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
108  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  39 ms
109  *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  39 ms  39 ms  39 ms
110  *      6  128.32.197.4 (128.32.197.4)  40 ms  59 ms  59 ms
111  *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  59 ms
112  *      8  129.140.70.13 (129.140.70.13)  99 ms  99 ms  80 ms
113  *      9  129.140.71.6 (129.140.71.6)  139 ms  239 ms  319 ms
114  *     10  129.140.81.7 (129.140.81.7)  220 ms  199 ms  199 ms
115  *     11  nic.merit.edu (35.1.1.48)  239 ms  239 ms  239 ms
116  *
117  * Note that lines 2 & 3 are the same.  This is due to a buggy
118  * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
119  * packets with a zero ttl.
120  *
121  * A more interesting example is:
122  *
123  *     [yak 72]% traceroute allspice.lcs.mit.edu.
124  *     traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max
125  *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
126  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  19 ms  19 ms
127  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  19 ms
128  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  19 ms  39 ms  39 ms
129  *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  20 ms  39 ms  39 ms
130  *      6  128.32.197.4 (128.32.197.4)  59 ms  119 ms  39 ms
131  *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  39 ms
132  *      8  129.140.70.13 (129.140.70.13)  80 ms  79 ms  99 ms
133  *      9  129.140.71.6 (129.140.71.6)  139 ms  139 ms  159 ms
134  *     10  129.140.81.7 (129.140.81.7)  199 ms  180 ms  300 ms
135  *     11  129.140.72.17 (129.140.72.17)  300 ms  239 ms  239 ms
136  *     12  * * *
137  *     13  128.121.54.72 (128.121.54.72)  259 ms  499 ms  279 ms
138  *     14  * * *
139  *     15  * * *
140  *     16  * * *
141  *     17  * * *
142  *     18  ALLSPICE.LCS.MIT.EDU (18.26.0.115)  339 ms  279 ms  279 ms
143  *
144  * (I start to see why I'm having so much trouble with mail to
145  * MIT.)  Note that the gateways 12, 14, 15, 16 & 17 hops away
146  * either don't send ICMP "time exceeded" messages or send them
147  * with a ttl too small to reach us.  14 - 17 are running the
148  * MIT C Gateway code that doesn't send "time exceeded"s.  God
149  * only knows what's going on with 12.
150  *
151  * The silent gateway 12 in the above may be the result of a bug in
152  * the 4.[23]BSD network code (and its derivatives):  4.x (x <= 3)
153  * sends an unreachable message using whatever ttl remains in the
154  * original datagram.  Since, for gateways, the remaining ttl is
155  * zero, the icmp "time exceeded" is guaranteed to not make it back
156  * to us.  The behavior of this bug is slightly more interesting
157  * when it appears on the destination system:
158  *
159  *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
160  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  39 ms
161  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  39 ms  19 ms
162  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  19 ms
163  *      5  ccn-nerif35.Berkeley.EDU (128.32.168.35)  39 ms  39 ms  39 ms
164  *      6  csgw.Berkeley.EDU (128.32.133.254)  39 ms  59 ms  39 ms
165  *      7  * * *
166  *      8  * * *
167  *      9  * * *
168  *     10  * * *
169  *     11  * * *
170  *     12  * * *
171  *     13  rip.Berkeley.EDU (128.32.131.22)  59 ms !  39 ms !  39 ms !
172  *
173  * Notice that there are 12 "gateways" (13 is the final
174  * destination) and exactly the last half of them are "missing".
175  * What's really happening is that rip (a Sun-3 running Sun OS3.5)
176  * is using the ttl from our arriving datagram as the ttl in its
177  * icmp reply.  So, the reply will time out on the return path
178  * (with no notice sent to anyone since icmp's aren't sent for
179  * icmp's) until we probe with a ttl that's at least twice the path
180  * length.  I.e., rip is really only 7 hops away.  A reply that
181  * returns with a ttl of 1 is a clue this problem exists.
182  * Traceroute prints a "!" after the time if the ttl is <= 1.
183  * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
184  * non-standard (HPUX) software, expect to see this problem
185  * frequently and/or take care picking the target host of your
186  * probes.
187  *
188  * Other possible annotations after the time are !H, !N, !P (got a host,
189  * network or protocol unreachable, respectively), !S or !F (source
190  * route failed or fragmentation needed -- neither of these should
191  * ever occur and the associated gateway is busted if you see one).  If
192  * almost all the probes result in some kind of unreachable, traceroute
193  * will give up and exit.
194  *
195  * Notes
196  * -----
197  * This program must be run by root or be setuid.  (I suggest that
198  * you *don't* make it setuid -- casual use could result in a lot
199  * of unnecessary traffic on our poor, congested nets.)
200  *
201  * This program requires a kernel mod that does not appear in any
202  * system available from Berkeley:  A raw ip socket using proto
203  * IPPROTO_RAW must interpret the data sent as an ip datagram (as
204  * opposed to data to be wrapped in an ip datagram).  See the README
205  * file that came with the source to this program for a description
206  * of the mods I made to /sys/netinet/raw_ip.c.  Your mileage may
207  * vary.  But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
208  * MODIFIED TO RUN THIS PROGRAM.
209  *
210  * The udp port usage may appear bizarre (well, ok, it is bizarre).
211  * The problem is that an icmp message only contains 8 bytes of
212  * data from the original datagram.  8 bytes is the size of a udp
213  * header so, if we want to associate replies with the original
214  * datagram, the necessary information must be encoded into the
215  * udp header (the ip id could be used but there's no way to
216  * interlock with the kernel's assignment of ip id's and, anyway,
217  * it would have taken a lot more kernel hacking to allow this
218  * code to set the ip id).  So, to allow two or more users to
219  * use traceroute simultaneously, we use this task's pid as the
220  * source port (the high bit is set to move the port number out
221  * of the "likely" range).  To keep track of which probe is being
222  * replied to (so times and/or hop counts don't get confused by a
223  * reply that was delayed in transit), we increment the destination
224  * port number before each probe.
225  *
226  * Don't use this as a coding example.  I was trying to find a
227  * routing problem and this code sort-of popped out after 48 hours
228  * without sleep.  I was amazed it ever compiled, much less ran.
229  *
230  * I stole the idea for this program from Steve Deering.  Since
231  * the first release, I've learned that had I attended the right
232  * IETF working group meetings, I also could have stolen it from Guy
233  * Almes or Matt Mathis.  I don't know (or care) who came up with
234  * the idea first.  I envy the originators' perspicacity and I'm
235  * glad they didn't keep the idea a secret.
236  *
237  * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
238  * enhancements to the original distribution.
239  *
240  * I've hacked up a round-trip-route version of this that works by
241  * sending a loose-source-routed udp datagram through the destination
242  * back to yourself.  Unfortunately, SO many gateways botch source
243  * routing, the thing is almost worthless.  Maybe one day...
244  *
245  *  -- Van Jacobson (van@helios.ee.lbl.gov)
246  *     Tue Dec 20 03:50:13 PST 1988
247  */
248
249 #include <sys/param.h>
250 #include <sys/capsicum.h>
251 #include <sys/time.h>
252 #include <sys/socket.h>
253 #include <sys/uio.h>
254 #include <sys/file.h>
255 #include <sys/ioctl.h>
256 #include <sys/sysctl.h>
257
258 #include <netinet/in.h>
259
260 #include <arpa/inet.h>
261
262 #include <libcasper.h>
263 #include <casper/cap_dns.h>
264 #include <capsicum_helpers.h>
265
266 #include <netdb.h>
267 #include <stdio.h>
268 #include <err.h>
269 #ifdef HAVE_POLL
270 #include <poll.h>
271 #endif
272 #include <errno.h>
273 #include <stdlib.h>
274 #include <string.h>
275 #include <unistd.h>
276
277 #include <netinet/ip6.h>
278 #include <netinet/icmp6.h>
279 #include <netinet/sctp.h>
280 #include <netinet/sctp_header.h>
281 #include <netinet/tcp.h>
282 #include <netinet/udp.h>
283
284 #ifdef IPSEC
285 #include <net/route.h>
286 #include <netipsec/ipsec.h>
287 #endif
288
289 #include "as.h"
290
291 #define DUMMY_PORT 10010
292
293 #define MAXPACKET       65535   /* max ip packet size */
294
295 static u_char   packet[512];            /* last inbound (icmp) packet */
296 static char     *outpacket;             /* last output packet */
297
298 int     main(int, char *[]);
299 int     wait_for_reply(int, struct msghdr *);
300 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
301 int     setpolicy(int so, char *policy);
302 #endif
303 void    send_probe(int, u_long);
304 void    *get_uphdr(struct ip6_hdr *, u_char *);
305 void    capdns_open(void);
306 int     get_hoplim(struct msghdr *);
307 double  deltaT(struct timeval *, struct timeval *);
308 const char *pr_type(int);
309 int     packet_ok(struct msghdr *, int, int, u_char *, u_char *);
310 void    print(struct msghdr *, int);
311 const char *inetname(struct sockaddr *);
312 u_int32_t sctp_crc32c(void *, u_int32_t);
313 u_int16_t in_cksum(u_int16_t *addr, int);
314 u_int16_t udp_cksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
315     void *, u_int32_t);
316 u_int16_t tcp_chksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
317     void *, u_int32_t);
318 void    usage(void);
319
320 static int rcvsock;                     /* receive (icmp) socket file descriptor */
321 static int sndsock;                     /* send (raw/udp) socket file descriptor */
322
323 static struct msghdr rcvmhdr;
324 static struct iovec rcviov[2];
325 static int rcvhlim;
326 static struct in6_pktinfo *rcvpktinfo;
327
328 static struct sockaddr_in6 Src, Dst, Rcv;
329 static u_long datalen = 20;                     /* How much data */
330 #define ICMP6ECHOLEN    8
331 /* XXX: 2064 = 127(max hops in type 0 rthdr) * sizeof(ip6_hdr) + 16(margin) */
332 static char rtbuf[2064];
333 static struct ip6_rthdr *rth;
334 static struct cmsghdr *cmsg;
335
336 static char *source = NULL;
337 static char *hostname;
338
339 static cap_channel_t *capdns;
340
341 static u_long nprobes = 3;
342 static u_long first_hop = 1;
343 static u_long max_hops = 30;
344 static u_int16_t srcport;
345 static u_int16_t port = 32768+666;      /* start udp dest port # for probe packets */
346 static u_int16_t ident;
347 static int tclass = -1;
348 static int options;                     /* socket options */
349 static int verbose;
350 static int waittime = 5;                /* time to wait for response (in seconds) */
351 static int nflag;                       /* print addresses numerically */
352 static int useproto = IPPROTO_UDP;      /* protocol to use to send packet */
353 static int lflag;                       /* print both numerical address & hostname */
354 static int as_path;                     /* print as numbers for each hop */
355 static char *as_server = NULL;
356 static 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, ltclass;
367         struct hostent *hp;
368         size_t size, minlen;
369         uid_t uid;
370         u_char type, code;
371 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
372         char ipsec_inpolicy[] = "in bypass";
373         char ipsec_outpolicy[] = "out bypass";
374 #endif
375         cap_rights_t rights;
376
377         capdns_open();
378
379         /*
380          * Receive ICMP
381          */
382         if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
383                 perror("socket(ICMPv6)");
384                 exit(5);
385         }
386
387         size = sizeof(i);
388         (void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &i, &size, NULL, 0);
389         max_hops = i;
390
391         /* specify to tell receiving interface */
392 #ifdef IPV6_RECVPKTINFO
393         if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
394             sizeof(on)) < 0)
395                 err(1, "setsockopt(IPV6_RECVPKTINFO)");
396 #else  /* old adv. API */
397         if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_PKTINFO, &on,
398             sizeof(on)) < 0)
399                 err(1, "setsockopt(IPV6_PKTINFO)");
400 #endif
401
402         /* specify to tell value of hoplimit field of received IP6 hdr */
403 #ifdef IPV6_RECVHOPLIMIT
404         if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
405             sizeof(on)) < 0)
406                 err(1, "setsockopt(IPV6_RECVHOPLIMIT)");
407 #else  /* old adv. API */
408         if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on,
409             sizeof(on)) < 0)
410                 err(1, "setsockopt(IPV6_HOPLIMIT)");
411 #endif
412
413         seq = 0;
414         ident = htons(getpid() & 0xffff); /* same as ping6 */
415
416         while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:St:TUvw:")) != -1)
417                 switch (ch) {
418                 case 'a':
419                         as_path = 1;
420                         break;
421                 case 'A':
422                         as_path = 1;
423                         as_server = optarg;
424                         break;
425                 case 'd':
426                         options |= SO_DEBUG;
427                         break;
428                 case 'f':
429                         ep = NULL;
430                         errno = 0;
431                         first_hop = strtoul(optarg, &ep, 0);
432                         if (errno || !*optarg || *ep || first_hop > 255) {
433                                 fprintf(stderr,
434                                     "traceroute6: invalid min hoplimit.\n");
435                                 exit(1);
436                         }
437                         break;
438                 case 'g':
439                         /* XXX use after capability mode is entered */
440                         hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno);
441                         if (hp == NULL) {
442                                 fprintf(stderr,
443                                     "traceroute6: unknown host %s\n", optarg);
444                                 exit(1);
445                         }
446                         if (rth == NULL) {
447                                 /*
448                                  * XXX: We can't detect the number of
449                                  * intermediate nodes yet.
450                                  */
451                                 if ((rth = inet6_rth_init((void *)rtbuf,
452                                     sizeof(rtbuf), IPV6_RTHDR_TYPE_0,
453                                     0)) == NULL) {
454                                         fprintf(stderr,
455                                             "inet6_rth_init failed.\n");
456                                         exit(1);
457                                 }
458                         }
459                         if (inet6_rth_add((void *)rth,
460                             (struct in6_addr *)hp->h_addr)) {
461                                 fprintf(stderr,
462                                     "inet6_rth_add failed for %s\n",
463                                     optarg);
464                                 exit(1);
465                         }
466                         freehostent(hp);
467                         break;
468                 case 'I':
469                         useproto = IPPROTO_ICMPV6;
470                         break;
471                 case 'l':
472                         lflag++;
473                         break;
474                 case 'm':
475                         ep = NULL;
476                         errno = 0;
477                         max_hops = strtoul(optarg, &ep, 0);
478                         if (errno || !*optarg || *ep || max_hops > 255) {
479                                 fprintf(stderr,
480                                     "traceroute6: invalid max hoplimit.\n");
481                                 exit(1);
482                         }
483                         break;
484                 case 'n':
485                         nflag++;
486                         break;
487                 case 'N':
488                         useproto = IPPROTO_NONE;
489                         break;
490                 case 'p':
491                         ep = NULL;
492                         errno = 0;
493                         lport = strtoul(optarg, &ep, 0);
494                         if (errno || !*optarg || *ep) {
495                                 fprintf(stderr, "traceroute6: invalid port.\n");
496                                 exit(1);
497                         }
498                         if (lport == 0 || lport != (lport & 0xffff)) {
499                                 fprintf(stderr,
500                                     "traceroute6: port out of range.\n");
501                                 exit(1);
502                         }
503                         port = lport & 0xffff;
504                         break;
505                 case 'q':
506                         ep = NULL;
507                         errno = 0;
508                         nprobes = strtoul(optarg, &ep, 0);
509                         if (errno || !*optarg || *ep) {
510                                 fprintf(stderr,
511                                     "traceroute6: invalid nprobes.\n");
512                                 exit(1);
513                         }
514                         if (nprobes < 1) {
515                                 fprintf(stderr,
516                                     "traceroute6: nprobes must be >0.\n");
517                                 exit(1);
518                         }
519                         break;
520                 case 'r':
521                         options |= SO_DONTROUTE;
522                         break;
523                 case 's':
524                         /*
525                          * set the ip source address of the outbound
526                          * probe (e.g., on a multi-homed host).
527                          */
528                         source = optarg;
529                         break;
530                 case 'S':
531                         useproto = IPPROTO_SCTP;
532                         break;
533                 case 't':
534                         ep = NULL;
535                         errno = 0;
536                         ltclass = strtoul(optarg, &ep, 0);
537                         if (errno || !*optarg || *ep || ltclass > 255) {
538                                 fprintf(stderr,
539                                     "traceroute6: invalid traffic class.\n");
540                                 exit(1);
541                         }
542                         tclass = (int)ltclass;
543                         break;
544                 case 'T':
545                         useproto = IPPROTO_TCP;
546                         break;
547                 case 'U':
548                         useproto = IPPROTO_UDP;
549                         break;
550                 case 'v':
551                         verbose++;
552                         break;
553                 case 'w':
554                         ep = NULL;
555                         errno = 0;
556                         waittime = strtoul(optarg, &ep, 0);
557                         if (errno || !*optarg || *ep) {
558                                 fprintf(stderr,
559                                     "traceroute6: invalid wait time.\n");
560                                 exit(1);
561                         }
562                         if (waittime < 1) {
563                                 fprintf(stderr,
564                                     "traceroute6: wait must be >= 1 sec.\n");
565                                 exit(1);
566                         }
567                         break;
568                 default:
569                         usage();
570                 }
571         argc -= optind;
572         argv += optind;
573
574         /*
575          * Open socket to send probe packets.
576          */
577         switch (useproto) {
578         case IPPROTO_ICMPV6:
579         case IPPROTO_NONE:
580         case IPPROTO_SCTP:
581         case IPPROTO_TCP:
582         case IPPROTO_UDP:
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
629         error = cap_getaddrinfo(capdns, *argv, NULL, &hints, &res);
630
631         if (error) {
632                 fprintf(stderr,
633                     "traceroute6: %s\n", gai_strerror(error));
634                 exit(1);
635         }
636         if (res->ai_addrlen != sizeof(Dst)) {
637                 fprintf(stderr,
638                     "traceroute6: size of sockaddr mismatch\n");
639                 exit(1);
640         }
641         memcpy(&Dst, res->ai_addr, res->ai_addrlen);
642         hostname = res->ai_canonname ? strdup(res->ai_canonname) : *argv;
643         if (!hostname) {
644                 fprintf(stderr, "traceroute6: not enough core\n");
645                 exit(1);
646         }
647         if (res->ai_next) {
648                 if (cap_getnameinfo(capdns, res->ai_addr, res->ai_addrlen, hbuf,
649                     sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
650                         strlcpy(hbuf, "?", sizeof(hbuf));
651                 fprintf(stderr, "traceroute6: Warning: %s has multiple "
652                     "addresses; using %s\n", hostname, hbuf);
653         }
654         freeaddrinfo(res);
655         if (*++argv) {
656                 ep = NULL;
657                 errno = 0;
658                 datalen = strtoul(*argv, &ep, 0);
659                 if (errno || *ep) {
660                         fprintf(stderr,
661                             "traceroute6: invalid packet length.\n");
662                         exit(1);
663                 }
664         }
665         switch (useproto) {
666         case IPPROTO_ICMPV6:
667                 minlen = ICMP6ECHOLEN;
668                 break;
669         case IPPROTO_UDP:
670                 minlen = sizeof(struct udphdr);
671                 break;
672         case IPPROTO_NONE:
673                 minlen = 0;
674                 datalen = 0;
675                 break;
676         case IPPROTO_SCTP:
677                 minlen = sizeof(struct sctphdr);
678                 break;
679         case IPPROTO_TCP:
680                 minlen = sizeof(struct tcphdr);
681                 break;
682         default:
683                 fprintf(stderr, "traceroute6: unknown probe protocol %d.\n",
684                     useproto);
685                 exit(1);
686         }
687         if (datalen < minlen)
688                 datalen = minlen;
689         else if (datalen >= MAXPACKET) {
690                 fprintf(stderr,
691                     "traceroute6: packet size must be %zu <= s < %d.\n",
692                     minlen, MAXPACKET);
693                 exit(1);
694         }
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 = cap_getaddrinfo(capdns, 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 (cap_getnameinfo(capdns, (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 (cap_getnameinfo(capdns, (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         if (connect(sndsock, (struct sockaddr *)&Dst,
917             sizeof(Dst)) != 0) {
918                 fprintf(stderr, "connect: %s\n", strerror(errno));
919                 exit(1);
920         }
921
922         /*
923          * Here we enter capability mode. Further down access to global
924          * namespaces (e.g filesystem) is restricted (see capsicum(4)).
925          * We must connect(2) our socket before this point.
926          */
927         if (caph_enter_casper() < 0) {
928                 fprintf(stderr, "caph_enter_casper: %s\n", strerror(errno));
929                 exit(1);
930         }
931
932         cap_rights_init(&rights, CAP_SEND, CAP_SETSOCKOPT);
933         if (caph_rights_limit(sndsock, &rights) < 0) {
934                 fprintf(stderr, "caph_rights_limit sndsock: %s\n",
935                     strerror(errno));
936                 exit(1);
937         }
938         cap_rights_init(&rights, CAP_RECV, CAP_EVENT);
939         if (caph_rights_limit(rcvsock, &rights) < 0) {
940                 fprintf(stderr, "caph_rights_limit rcvsock: %s\n",
941                     strerror(errno));
942                 exit(1);
943         }
944
945         /*
946          * Main loop
947          */
948         for (hops = first_hop; hops <= max_hops; ++hops) {
949                 struct in6_addr lastaddr;
950                 int got_there = 0;
951                 unsigned unreachable = 0;
952
953                 printf("%2lu ", hops);
954                 bzero(&lastaddr, sizeof(lastaddr));
955                 for (probe = 0; probe < nprobes; ++probe) {
956                         int cc;
957                         struct timeval t1, t2;
958
959                         (void) gettimeofday(&t1, NULL);
960                         send_probe(++seq, hops);
961                         while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) {
962                                 (void) gettimeofday(&t2, NULL);
963                                 if (packet_ok(&rcvmhdr, cc, seq, &type, &code)) {
964                                         if (!IN6_ARE_ADDR_EQUAL(&Rcv.sin6_addr,
965                                             &lastaddr)) {
966                                                 if (probe > 0)
967                                                         fputs("\n   ", stdout);
968                                                 print(&rcvmhdr, cc);
969                                                 lastaddr = Rcv.sin6_addr;
970                                         }
971                                         printf("  %.3f ms", deltaT(&t1, &t2));
972                                         if (type == ICMP6_DST_UNREACH) {
973                                                 switch (code) {
974                                                 case ICMP6_DST_UNREACH_NOROUTE:
975                                                         ++unreachable;
976                                                         printf(" !N");
977                                                         break;
978                                                 case ICMP6_DST_UNREACH_ADMIN:
979                                                         ++unreachable;
980                                                         printf(" !P");
981                                                         break;
982                                                 case ICMP6_DST_UNREACH_NOTNEIGHBOR:
983                                                         ++unreachable;
984                                                         printf(" !S");
985                                                         break;
986                                                 case ICMP6_DST_UNREACH_ADDR:
987                                                         ++unreachable;
988                                                         printf(" !A");
989                                                         break;
990                                                 case ICMP6_DST_UNREACH_NOPORT:
991                                                         if (rcvhlim >= 0 &&
992                                                             rcvhlim <= 1)
993                                                                 printf(" !");
994                                                         ++got_there;
995                                                         break;
996                                                 }
997                                         } else if (type == ICMP6_PARAM_PROB &&
998                                             code == ICMP6_PARAMPROB_NEXTHEADER) {
999                                                 printf(" !H");
1000                                                 ++got_there;
1001                                         } else if (type == ICMP6_ECHO_REPLY) {
1002                                                 if (rcvhlim >= 0 &&
1003                                                     rcvhlim <= 1)
1004                                                         printf(" !");
1005                                                 ++got_there;
1006                                         }
1007                                         break;
1008                                 } else if (deltaT(&t1, &t2) > waittime * 1000) {
1009                                         cc = 0;
1010                                         break;
1011                                 }
1012                         }
1013                         if (cc == 0)
1014                                 printf(" *");
1015                         (void) fflush(stdout);
1016                 }
1017                 putchar('\n');
1018                 if (got_there ||
1019                     (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) {
1020                         exit(0);
1021                 }
1022         }
1023         if (as_path)
1024                 as_shutdown(asn);
1025
1026         exit(0);
1027 }
1028
1029 int
1030 wait_for_reply(int sock, struct msghdr *mhdr)
1031 {
1032 #ifdef HAVE_POLL
1033         struct pollfd pfd[1];
1034         int cc = 0;
1035
1036         pfd[0].fd = sock;
1037         pfd[0].events = POLLIN;
1038         pfd[0].revents = 0;
1039
1040         if (poll(pfd, 1, waittime * 1000) > 0 &&
1041             pfd[0].revents & POLLIN)
1042                 cc = recvmsg(rcvsock, mhdr, 0);
1043
1044         return (cc);
1045 #else
1046         fd_set *fdsp;
1047         struct timeval wait;
1048         int cc = 0, fdsn;
1049
1050         fdsn = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
1051         if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
1052                 err(1, "malloc");
1053         memset(fdsp, 0, fdsn);
1054         FD_SET(sock, fdsp);
1055         wait.tv_sec = waittime; wait.tv_usec = 0;
1056
1057         if (select(sock+1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0)
1058                 cc = recvmsg(rcvsock, mhdr, 0);
1059
1060         free(fdsp);
1061         return (cc);
1062 #endif
1063 }
1064
1065 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
1066 int
1067 setpolicy(int so, char *policy)
1068 {
1069         char *buf;
1070
1071         buf = ipsec_set_policy(policy, strlen(policy));
1072         if (buf == NULL) {
1073                 warnx("%s", ipsec_strerror());
1074                 return -1;
1075         }
1076         (void)setsockopt(so, IPPROTO_IPV6, IPV6_IPSEC_POLICY,
1077             buf, ipsec_get_policylen(buf));
1078
1079         free(buf);
1080
1081         return 0;
1082 }
1083 #endif
1084
1085 void
1086 send_probe(int seq, u_long hops)
1087 {
1088         struct icmp6_hdr *icp;
1089         struct sctphdr *sctp;
1090         struct udphdr *outudp;
1091         struct sctp_chunkhdr *chk;
1092         struct sctp_init_chunk *init;
1093         struct sctp_paramhdr *param;
1094         struct tcphdr *tcp;
1095         int i;
1096
1097         i = hops;
1098         if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
1099             (char *)&i, sizeof(i)) < 0) {
1100                 perror("setsockopt IPV6_UNICAST_HOPS");
1101         }
1102
1103         Dst.sin6_port = htons(port + seq);
1104
1105         switch (useproto) {
1106         case IPPROTO_ICMPV6:
1107                 icp = (struct icmp6_hdr *)outpacket;
1108
1109                 icp->icmp6_type = ICMP6_ECHO_REQUEST;
1110                 icp->icmp6_code = 0;
1111                 icp->icmp6_cksum = 0;
1112                 icp->icmp6_id = ident;
1113                 icp->icmp6_seq = htons(seq);
1114                 break;
1115         case IPPROTO_UDP:
1116                 outudp = (struct udphdr *) outpacket;
1117                 outudp->uh_sport = htons(ident);
1118                 outudp->uh_dport = htons(port+seq);
1119                 outudp->uh_ulen = htons(datalen);
1120                 outudp->uh_sum = 0;
1121                 outudp->uh_sum = udp_cksum(&Src, &Dst, outpacket, datalen);
1122                 break;
1123         case IPPROTO_NONE:
1124                 /* No space for anything. No harm as seq/tv32 are decorative. */
1125                 break;
1126         case IPPROTO_SCTP:
1127                 sctp = (struct sctphdr *)outpacket;
1128
1129                 sctp->src_port = htons(ident);
1130                 sctp->dest_port = htons(port + seq);
1131                 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1132                     sizeof(struct sctp_init_chunk))) {
1133                         sctp->v_tag = 0;
1134                 } else {
1135                         sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port;
1136                 }
1137                 sctp->checksum = htonl(0);
1138                 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1139                     sizeof(struct sctp_init_chunk))) {
1140                         /*
1141                          * Send a packet containing an INIT chunk. This works
1142                          * better in case of firewalls on the path, but
1143                          * results in a probe packet containing at least
1144                          * 32 bytes of payload. For shorter payloads, use
1145                          * SHUTDOWN-ACK chunks.
1146                          */
1147                         init = (struct sctp_init_chunk *)(sctp + 1);
1148                         init->ch.chunk_type = SCTP_INITIATION;
1149                         init->ch.chunk_flags = 0;
1150                         init->ch.chunk_length = htons((u_int16_t)(datalen -
1151                             sizeof(struct sctphdr)));
1152                         init->init.initiate_tag = (sctp->src_port << 16) |
1153                             sctp->dest_port;
1154                         init->init.a_rwnd = htonl(1500);
1155                         init->init.num_outbound_streams = htons(1);
1156                         init->init.num_inbound_streams = htons(1);
1157                         init->init.initial_tsn = htonl(0);
1158                         if (datalen >= (u_long)(sizeof(struct sctphdr) +
1159                             sizeof(struct sctp_init_chunk) +
1160                             sizeof(struct sctp_paramhdr))) {
1161                                 param = (struct sctp_paramhdr *)(init + 1);
1162                                 param->param_type = htons(SCTP_PAD);
1163                                 param->param_length =
1164                                     htons((u_int16_t)(datalen -
1165                                     sizeof(struct sctphdr) -
1166                                     sizeof(struct sctp_init_chunk)));
1167                         }
1168                 } else {
1169                         /*
1170                          * Send a packet containing a SHUTDOWN-ACK chunk,
1171                          * possibly followed by a PAD chunk.
1172                          */
1173                         if (datalen >= (u_long)(sizeof(struct sctphdr) +
1174                             sizeof(struct sctp_chunkhdr))) {
1175                                 chk = (struct sctp_chunkhdr *)(sctp + 1);
1176                                 chk->chunk_type = SCTP_SHUTDOWN_ACK;
1177                                 chk->chunk_flags = 0;
1178                                 chk->chunk_length = htons(4);
1179                         }
1180                         if (datalen >= (u_long)(sizeof(struct sctphdr) +
1181                             2 * sizeof(struct sctp_chunkhdr))) {
1182                                 chk = chk + 1;
1183                                 chk->chunk_type = SCTP_PAD_CHUNK;
1184                                 chk->chunk_flags = 0;
1185                                 chk->chunk_length = htons((u_int16_t)(datalen -
1186                                     sizeof(struct sctphdr) -
1187                                     sizeof(struct sctp_chunkhdr)));
1188                         }
1189                 }
1190                 sctp->checksum = sctp_crc32c(outpacket, datalen);
1191                 break;
1192         case IPPROTO_TCP:
1193                 tcp = (struct tcphdr *)outpacket;
1194
1195                 tcp->th_sport = htons(ident);
1196                 tcp->th_dport = htons(port + seq);
1197                 tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
1198                 tcp->th_ack = 0;
1199                 tcp->th_off = 5;
1200                 tcp->th_flags = TH_SYN;
1201                 tcp->th_sum = 0;
1202                 tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen);
1203                 break;
1204         default:
1205                 fprintf(stderr, "Unknown probe protocol %d.\n", useproto);
1206                 exit(1);
1207         }
1208         
1209         i = send(sndsock, (char *)outpacket, datalen, 0);
1210         if (i < 0 || (u_long)i != datalen)  {
1211                 if (i < 0)
1212                         perror("send");
1213                 printf("traceroute6: wrote %s %lu chars, ret=%d\n",
1214                     hostname, datalen, i);
1215                 (void) fflush(stdout);
1216         }
1217 }
1218
1219 int
1220 get_hoplim(struct msghdr *mhdr)
1221 {
1222         struct cmsghdr *cm;
1223
1224         for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1225             cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1226                 if (cm->cmsg_level == IPPROTO_IPV6 &&
1227                     cm->cmsg_type == IPV6_HOPLIMIT &&
1228                     cm->cmsg_len == CMSG_LEN(sizeof(int)))
1229                         return (*(int *)CMSG_DATA(cm));
1230         }
1231
1232         return (-1);
1233 }
1234
1235 double
1236 deltaT(struct timeval *t1p, struct timeval *t2p)
1237 {
1238         double dt;
1239
1240         dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1241             (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1242         return (dt);
1243 }
1244
1245 /*
1246  * Convert an ICMP "type" field to a printable string.
1247  */
1248 const char *
1249 pr_type(int t0)
1250 {
1251         u_char t = t0 & 0xff;
1252         const char *cp;
1253
1254         switch (t) {
1255         case ICMP6_DST_UNREACH:
1256                 cp = "Destination Unreachable";
1257                 break;
1258         case ICMP6_PACKET_TOO_BIG:
1259                 cp = "Packet Too Big";
1260                 break;
1261         case ICMP6_TIME_EXCEEDED:
1262                 cp = "Time Exceeded";
1263                 break;
1264         case ICMP6_PARAM_PROB:
1265                 cp = "Parameter Problem";
1266                 break;
1267         case ICMP6_ECHO_REQUEST:
1268                 cp = "Echo Request";
1269                 break;
1270         case ICMP6_ECHO_REPLY:
1271                 cp = "Echo Reply";
1272                 break;
1273         case ICMP6_MEMBERSHIP_QUERY:
1274                 cp = "Group Membership Query";
1275                 break;
1276         case ICMP6_MEMBERSHIP_REPORT:
1277                 cp = "Group Membership Report";
1278                 break;
1279         case ICMP6_MEMBERSHIP_REDUCTION:
1280                 cp = "Group Membership Reduction";
1281                 break;
1282         case ND_ROUTER_SOLICIT:
1283                 cp = "Router Solicitation";
1284                 break;
1285         case ND_ROUTER_ADVERT:
1286                 cp = "Router Advertisement";
1287                 break;
1288         case ND_NEIGHBOR_SOLICIT:
1289                 cp = "Neighbor Solicitation";
1290                 break;
1291         case ND_NEIGHBOR_ADVERT:
1292                 cp = "Neighbor Advertisement";
1293                 break;
1294         case ND_REDIRECT:
1295                 cp = "Redirect";
1296                 break;
1297         default:
1298                 cp = "Unknown";
1299                 break;
1300         }
1301         return cp;
1302 }
1303
1304 int
1305 packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code)
1306 {
1307         struct icmp6_hdr *icp;
1308         struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1309         char *buf = (char *)mhdr->msg_iov[0].iov_base;
1310         struct cmsghdr *cm;
1311         int *hlimp;
1312         char hbuf[NI_MAXHOST];
1313
1314 #ifdef OLDRAWSOCKET
1315         int hlen;
1316         struct ip6_hdr *ip;
1317 #endif
1318
1319 #ifdef OLDRAWSOCKET
1320         ip = (struct ip6_hdr *) buf;
1321         hlen = sizeof(struct ip6_hdr);
1322         if (cc < hlen + sizeof(struct icmp6_hdr)) {
1323                 if (verbose) {
1324                         if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1325                             hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1326                                 strlcpy(hbuf, "invalid", sizeof(hbuf));
1327                         printf("packet too short (%d bytes) from %s\n", cc,
1328                             hbuf);
1329                 }
1330                 return (0);
1331         }
1332         cc -= hlen;
1333         icp = (struct icmp6_hdr *)(buf + hlen);
1334 #else
1335         if (cc < (int)sizeof(struct icmp6_hdr)) {
1336                 if (verbose) {
1337                         if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1338                             hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1339                                 strlcpy(hbuf, "invalid", sizeof(hbuf));
1340                         printf("data too short (%d bytes) from %s\n", cc, hbuf);
1341                 }
1342                 return (0);
1343         }
1344         icp = (struct icmp6_hdr *)buf;
1345 #endif
1346         /* get optional information via advanced API */
1347         rcvpktinfo = NULL;
1348         hlimp = NULL;
1349         for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1350             cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1351                 if (cm->cmsg_level == IPPROTO_IPV6 &&
1352                     cm->cmsg_type == IPV6_PKTINFO &&
1353                     cm->cmsg_len ==
1354                     CMSG_LEN(sizeof(struct in6_pktinfo)))
1355                         rcvpktinfo = (struct in6_pktinfo *)(CMSG_DATA(cm));
1356
1357                 if (cm->cmsg_level == IPPROTO_IPV6 &&
1358                     cm->cmsg_type == IPV6_HOPLIMIT &&
1359                     cm->cmsg_len == CMSG_LEN(sizeof(int)))
1360                         hlimp = (int *)CMSG_DATA(cm);
1361         }
1362         if (rcvpktinfo == NULL || hlimp == NULL) {
1363                 warnx("failed to get received hop limit or packet info");
1364 #if 0
1365                 return (0);
1366 #else
1367                 rcvhlim = 0;    /*XXX*/
1368 #endif
1369         }
1370         else
1371                 rcvhlim = *hlimp;
1372
1373         *type = icp->icmp6_type;
1374         *code = icp->icmp6_code;
1375         if ((*type == ICMP6_TIME_EXCEEDED &&
1376             *code == ICMP6_TIME_EXCEED_TRANSIT) ||
1377             (*type == ICMP6_DST_UNREACH) ||
1378             (*type == ICMP6_PARAM_PROB &&
1379             *code == ICMP6_PARAMPROB_NEXTHEADER)) {
1380                 struct ip6_hdr *hip;
1381                 struct icmp6_hdr *icmp;
1382                 struct sctp_init_chunk *init;
1383                 struct sctphdr *sctp;
1384                 struct tcphdr *tcp;
1385                 struct udphdr *udp;
1386                 void *up;
1387
1388                 hip = (struct ip6_hdr *)(icp + 1);
1389                 if ((up = get_uphdr(hip, (u_char *)(buf + cc))) == NULL) {
1390                         if (verbose)
1391                                 warnx("failed to get upper layer header");
1392                         return (0);
1393                 }
1394                 switch (useproto) {
1395                 case IPPROTO_ICMPV6:
1396                         icmp = (struct icmp6_hdr *)up;
1397                         if (icmp->icmp6_id == ident &&
1398                             icmp->icmp6_seq == htons(seq))
1399                                 return (1);
1400                         break;
1401                 case IPPROTO_UDP:
1402                         udp = (struct udphdr *)up;
1403                         if (udp->uh_sport == htons(ident) &&
1404                             udp->uh_dport == htons(port + seq))
1405                                 return (1);
1406                         break;
1407                 case IPPROTO_SCTP:
1408                         sctp = (struct sctphdr *)up;
1409                         if (sctp->src_port != htons(ident) ||
1410                             sctp->dest_port != htons(port + seq)) {
1411                                 break;
1412                         }
1413                         if (datalen >= (u_long)(sizeof(struct sctphdr) +
1414                             sizeof(struct sctp_init_chunk))) {
1415                                 if (sctp->v_tag != 0) {
1416                                         break;
1417                                 }
1418                                 init = (struct sctp_init_chunk *)(sctp + 1);
1419                                 /* Check the initiate tag, if available. */
1420                                 if ((char *)&init->init.a_rwnd > buf + cc) {
1421                                         return (1);
1422                                 }
1423                                 if (init->init.initiate_tag == (u_int32_t)
1424                                     ((sctp->src_port << 16) | sctp->dest_port)) {
1425                                         return (1);
1426                                 }
1427                         } else {
1428                                 if (sctp->v_tag ==
1429                                     (u_int32_t)((sctp->src_port << 16) |
1430                                     sctp->dest_port)) {
1431                                         return (1);
1432                                 }
1433                         }
1434                         break;
1435                 case IPPROTO_TCP:
1436                         tcp = (struct tcphdr *)up;
1437                         if (tcp->th_sport == htons(ident) &&
1438                             tcp->th_dport == htons(port + seq) &&
1439                             tcp->th_seq ==
1440                             (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport))
1441                                 return (1);
1442                         break;
1443                 case IPPROTO_NONE:
1444                         return (1);
1445                 default:
1446                         fprintf(stderr, "Unknown probe proto %d.\n", useproto);
1447                         break;
1448                 }
1449         } else if (useproto == IPPROTO_ICMPV6 && *type == ICMP6_ECHO_REPLY) {
1450                 if (icp->icmp6_id == ident &&
1451                     icp->icmp6_seq == htons(seq))
1452                         return (1);
1453         }
1454         if (verbose) {
1455                 char sbuf[NI_MAXHOST+1], dbuf[INET6_ADDRSTRLEN];
1456                 u_int8_t *p;
1457                 int i;
1458
1459                 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1460                     sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0)
1461                         strlcpy(sbuf, "invalid", sizeof(sbuf));
1462                 printf("\n%d bytes from %s to %s", cc, sbuf,
1463                     rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1464                     dbuf, sizeof(dbuf)) : "?");
1465                 printf(": icmp type %d (%s) code %d\n", *type, pr_type(*type),
1466                     *code);
1467                 p = (u_int8_t *)(icp + 1);
1468 #define WIDTH   16
1469                 for (i = 0; i < cc; i++) {
1470                         if (i % WIDTH == 0)
1471                                 printf("%04x:", i);
1472                         if (i % 4 == 0)
1473                                 printf(" ");
1474                         printf("%02x", p[i]);
1475                         if (i % WIDTH == WIDTH - 1)
1476                                 printf("\n");
1477                 }
1478                 if (cc % WIDTH != 0)
1479                         printf("\n");
1480         }
1481         return (0);
1482 }
1483
1484 /*
1485  * Increment pointer until find the UDP or ICMP header.
1486  */
1487 void *
1488 get_uphdr(struct ip6_hdr *ip6, u_char *lim)
1489 {
1490         u_char *cp = (u_char *)ip6, nh;
1491         int hlen;
1492         static u_char none_hdr[1]; /* Fake pointer for IPPROTO_NONE. */
1493
1494         if (cp + sizeof(*ip6) > lim)
1495                 return (NULL);
1496
1497         nh = ip6->ip6_nxt;
1498         cp += sizeof(struct ip6_hdr);
1499
1500         while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) {
1501                 switch (nh) {
1502                 case IPPROTO_ESP:
1503                         return (NULL);
1504                 case IPPROTO_ICMPV6:
1505                         return (useproto == nh ? cp : NULL);
1506                 case IPPROTO_SCTP:
1507                 case IPPROTO_TCP:
1508                 case IPPROTO_UDP:
1509                         return (useproto == nh ? cp : NULL);
1510                 case IPPROTO_NONE:
1511                         return (useproto == nh ? none_hdr : NULL);
1512                 case IPPROTO_FRAGMENT:
1513                         hlen = sizeof(struct ip6_frag);
1514                         nh = ((struct ip6_frag *)cp)->ip6f_nxt;
1515                         break;
1516                 case IPPROTO_AH:
1517                         hlen = (((struct ip6_ext *)cp)->ip6e_len + 2) << 2;
1518                         nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1519                         break;
1520                 default:
1521                         hlen = (((struct ip6_ext *)cp)->ip6e_len + 1) << 3;
1522                         nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1523                         break;
1524                 }
1525
1526                 cp += hlen;
1527         }
1528
1529         return (NULL);
1530 }
1531
1532 void
1533 capdns_open(void)
1534 {
1535 #ifdef  WITH_CASPER
1536         const char *types[] = { "NAME", "ADDR" };
1537         int families[1];
1538         cap_channel_t *casper;
1539
1540         casper = cap_init();
1541         if (casper == NULL)
1542                 errx(1, "unable to create casper process");
1543         capdns = cap_service_open(casper, "system.dns");
1544         if (capdns == NULL)
1545                 errx(1, "unable to open system.dns service");
1546         if (cap_dns_type_limit(capdns, types, nitems(types)) < 0)
1547                 errx(1, "unable to limit access to system.dns service");
1548         families[0] = AF_INET6;
1549         if (cap_dns_family_limit(capdns, families, nitems(families)) < 0)
1550                 errx(1, "unable to limit access to system.dns service");
1551         cap_close(casper);
1552 #endif  /* WITH_CASPER */
1553 }
1554
1555 void
1556 print(struct msghdr *mhdr, int cc)
1557 {
1558         struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1559         char hbuf[NI_MAXHOST];
1560
1561         if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1562             hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1563                 strlcpy(hbuf, "invalid", sizeof(hbuf));
1564         if (as_path)
1565                 printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6));
1566         if (nflag)
1567                 printf(" %s", hbuf);
1568         else if (lflag)
1569                 printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf);
1570         else
1571                 printf(" %s", inetname((struct sockaddr *)from));
1572
1573         if (verbose) {
1574 #ifdef OLDRAWSOCKET
1575                 printf(" %d bytes to %s", cc,
1576                     rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1577                     hbuf, sizeof(hbuf)) : "?");
1578 #else
1579                 printf(" %d bytes of data to %s", cc,
1580                     rcvpktinfo ?  inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1581                     hbuf, sizeof(hbuf)) : "?");
1582 #endif
1583         }
1584 }
1585
1586 /*
1587  * Construct an Internet address representation.
1588  * If the nflag has been supplied, give
1589  * numeric value, otherwise try for symbolic name.
1590  */
1591 const char *
1592 inetname(struct sockaddr *sa)
1593 {
1594         static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1];
1595         static int first = 1;
1596         char *cp;
1597
1598         if (first && !nflag) {
1599                 first = 0;
1600                 if (gethostname(domain, sizeof(domain)) == 0 &&
1601                     (cp = strchr(domain, '.')))
1602                         (void) strlcpy(domain, cp + 1, sizeof(domain));
1603                 else
1604                         domain[0] = 0;
1605         }
1606         cp = NULL;
1607         if (!nflag) {
1608                 if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0,
1609                     NI_NAMEREQD) == 0) {
1610                         if ((cp = strchr(line, '.')) &&
1611                             !strcmp(cp + 1, domain))
1612                                 *cp = 0;
1613                         cp = line;
1614                 }
1615         }
1616         if (cp)
1617                 return cp;
1618
1619         if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0,
1620             NI_NUMERICHOST) != 0)
1621                 strlcpy(line, "invalid", sizeof(line));
1622         return line;
1623 }
1624
1625 /*
1626  * CRC32C routine for the Stream Control Transmission Protocol
1627  */
1628
1629 #define CRC32C(c, d) (c = (c>>8) ^ crc_c[(c^(d))&0xFF])
1630
1631 static u_int32_t crc_c[256] = {
1632         0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
1633         0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
1634         0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
1635         0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
1636         0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
1637         0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
1638         0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
1639         0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
1640         0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
1641         0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
1642         0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
1643         0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
1644         0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
1645         0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
1646         0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
1647         0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
1648         0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
1649         0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
1650         0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
1651         0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
1652         0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
1653         0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
1654         0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
1655         0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
1656         0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
1657         0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
1658         0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
1659         0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
1660         0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
1661         0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
1662         0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
1663         0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
1664         0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
1665         0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
1666         0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
1667         0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
1668         0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
1669         0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
1670         0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
1671         0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
1672         0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
1673         0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
1674         0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
1675         0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
1676         0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
1677         0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
1678         0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
1679         0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
1680         0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
1681         0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
1682         0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
1683         0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
1684         0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
1685         0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
1686         0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
1687         0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
1688         0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
1689         0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
1690         0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
1691         0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
1692         0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
1693         0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
1694         0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
1695         0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
1696 };
1697
1698 u_int32_t
1699 sctp_crc32c(void *pack, u_int32_t len)
1700 {
1701         u_int32_t i, crc32c;
1702         u_int8_t byte0, byte1, byte2, byte3;
1703         u_int8_t *buf = (u_int8_t *)pack;
1704
1705         crc32c = ~0;
1706         for (i = 0; i < len; i++)
1707                 CRC32C(crc32c, buf[i]);
1708         crc32c = ~crc32c;
1709         byte0  = crc32c & 0xff;
1710         byte1  = (crc32c>>8) & 0xff;
1711         byte2  = (crc32c>>16) & 0xff;
1712         byte3  = (crc32c>>24) & 0xff;
1713         crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
1714         return htonl(crc32c);
1715 }
1716
1717 u_int16_t
1718 in_cksum(u_int16_t *addr, int len)
1719 {
1720         int nleft = len;
1721         u_int16_t *w = addr;
1722         u_int16_t answer;
1723         int sum = 0;
1724
1725         /*
1726          *  Our algorithm is simple, using a 32 bit accumulator (sum),
1727          *  we add sequential 16 bit words to it, and at the end, fold
1728          *  back all the carry bits from the top 16 bits into the lower
1729          *  16 bits.
1730          */
1731         while (nleft > 1)  {
1732                 sum += *w++;
1733                 nleft -= 2;
1734         }
1735
1736         /* mop up an odd byte, if necessary */
1737         if (nleft == 1)
1738                 sum += *(u_char *)w;
1739
1740         /*
1741          * add back carry outs from top 16 bits to low 16 bits
1742          */
1743         sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */
1744         sum += (sum >> 16);                     /* add carry */
1745         answer = ~sum;                          /* truncate to 16 bits */
1746         return (answer);
1747 }
1748
1749 u_int16_t
1750 udp_cksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1751     void *payload, u_int32_t len)
1752 {
1753         struct {
1754                 struct in6_addr src;
1755                 struct in6_addr dst;
1756                 u_int32_t len;
1757                 u_int8_t zero[3];
1758                 u_int8_t next;
1759         } pseudo_hdr;
1760         u_int16_t sum[2];
1761
1762         pseudo_hdr.src = src->sin6_addr;
1763         pseudo_hdr.dst = dst->sin6_addr;
1764         pseudo_hdr.len = htonl(len);
1765         pseudo_hdr.zero[0] = 0;
1766         pseudo_hdr.zero[1] = 0;
1767         pseudo_hdr.zero[2] = 0;
1768         pseudo_hdr.next = IPPROTO_UDP;
1769
1770         sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1771         sum[0] = in_cksum(payload, len);
1772
1773         return (~in_cksum(sum, sizeof(sum)));
1774 }
1775
1776 u_int16_t
1777 tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1778     void *payload, u_int32_t len)
1779 {
1780         struct {
1781                 struct in6_addr src;
1782                 struct in6_addr dst;
1783                 u_int32_t len;
1784                 u_int8_t zero[3];
1785                 u_int8_t next;
1786         } pseudo_hdr;
1787         u_int16_t sum[2];
1788
1789         pseudo_hdr.src = src->sin6_addr;
1790         pseudo_hdr.dst = dst->sin6_addr;
1791         pseudo_hdr.len = htonl(len);
1792         pseudo_hdr.zero[0] = 0;
1793         pseudo_hdr.zero[1] = 0;
1794         pseudo_hdr.zero[2] = 0;
1795         pseudo_hdr.next = IPPROTO_TCP;
1796
1797         sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1798         sum[0] = in_cksum(payload, len);
1799
1800         return (~in_cksum(sum, sizeof(sum)));
1801 }
1802
1803 void
1804 usage(void)
1805 {
1806
1807         fprintf(stderr,
1808 "usage: traceroute6 [-adIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n"
1809 "       [-m hoplimit] [-p port] [-q probes] [-s src] [-w waittime] target\n"
1810 "       [datalen]\n");
1811         exit(1);
1812 }