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