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