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