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