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