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