1 /* $KAME: traceroute6.c,v 1.68 2004/01/25 11:16:12 suz Exp $ */
4 * SPDX-License-Identifier: BSD-3-Clause
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
35 * Copyright (c) 1990, 1993
36 * The Regents of the University of California. All rights reserved.
38 * This code is derived from software contributed to Berkeley by
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
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.
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
67 static const char copyright[] =
68 "@(#) Copyright (c) 1990, 1993\n\
69 The Regents of the University of California. All rights reserved.\n";
74 static char sccsid[] = "@(#)traceroute.c 8.1 (Berkeley) 6/6/93";
76 static const char rcsid[] =
81 * traceroute host - trace the route ip packets follow going to "host".
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
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).
103 * A sample use might be:
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
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.
123 * A more interesting example is:
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
139 * 13 128.121.54.72 (128.121.54.72) 259 ms 499 ms 279 ms
144 * 18 ALLSPICE.LCS.MIT.EDU (18.26.0.115) 339 ms 279 ms 279 ms
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.
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:
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
173 * 13 rip.Berkeley.EDU (128.32.131.22) 59 ms ! 39 ms ! 39 ms !
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
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.
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.)
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.
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.
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.
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.
239 * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
240 * enhancements to the original distribution.
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...
247 * -- Van Jacobson (van@helios.ee.lbl.gov)
248 * Tue Dec 20 03:50:13 PST 1988
251 #include <sys/param.h>
252 #include <sys/time.h>
253 #include <sys/socket.h>
255 #include <sys/file.h>
256 #include <sys/ioctl.h>
257 #include <sys/sysctl.h>
259 #include <netinet/in.h>
261 #include <arpa/inet.h>
274 #include <netinet/ip6.h>
275 #include <netinet/icmp6.h>
276 #include <netinet/sctp.h>
277 #include <netinet/sctp_header.h>
278 #include <netinet/tcp.h>
279 #include <netinet/udp.h>
282 #include <net/route.h>
283 #include <netipsec/ipsec.h>
288 #define DUMMY_PORT 10010
290 #define MAXPACKET 65535 /* max ip packet size */
292 #ifndef HAVE_GETIPNODEBYNAME
293 #define getipnodebyname(x, y, z, u) gethostbyname2((x), (y))
294 #define freehostent(x)
297 u_char packet[512]; /* last inbound (icmp) packet */
298 char *outpacket; /* last output packet */
300 int main(int, char *[]);
301 int wait_for_reply(int, struct msghdr *);
303 #ifdef IPSEC_POLICY_IPSEC
304 int setpolicy(int so, char *policy);
307 void send_probe(int, u_long);
308 void *get_uphdr(struct ip6_hdr *, u_char *);
309 int get_hoplim(struct msghdr *);
310 double deltaT(struct timeval *, struct timeval *);
311 const char *pr_type(int);
312 int packet_ok(struct msghdr *, int, int, u_char *, u_char *);
313 void print(struct msghdr *, int);
314 const char *inetname(struct sockaddr *);
315 u_int32_t sctp_crc32c(void *, u_int32_t);
316 u_int16_t in_cksum(u_int16_t *addr, int);
317 u_int16_t tcp_chksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
321 int rcvsock; /* receive (icmp) socket file descriptor */
322 int sndsock; /* send (raw/udp) socket file descriptor */
324 struct msghdr rcvmhdr;
325 struct iovec rcviov[2];
327 struct in6_pktinfo *rcvpktinfo;
329 struct sockaddr_in6 Src, Dst, Rcv;
330 u_long datalen = 20; /* How much data */
331 #define ICMP6ECHOLEN 8
332 /* XXX: 2064 = 127(max hops in type 0 rthdr) * sizeof(ip6_hdr) + 16(margin) */
334 struct ip6_rthdr *rth;
335 struct cmsghdr *cmsg;
341 u_long first_hop = 1;
342 u_long max_hops = 30;
344 u_int16_t port = 32768+666; /* start udp dest port # for probe packets */
346 int options; /* socket options */
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;
357 main(int argc, char *argv[])
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;
373 if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
374 perror("socket(ICMPv6)");
379 (void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &i, &size, NULL, 0);
382 /* specify to tell receiving interface */
383 #ifdef IPV6_RECVPKTINFO
384 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
386 err(1, "setsockopt(IPV6_RECVPKTINFO)");
387 #else /* old adv. API */
388 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_PKTINFO, &on,
390 err(1, "setsockopt(IPV6_PKTINFO)");
393 /* specify to tell value of hoplimit field of received IP6 hdr */
394 #ifdef IPV6_RECVHOPLIMIT
395 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
397 err(1, "setsockopt(IPV6_RECVHOPLIMIT)");
398 #else /* old adv. API */
399 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on,
401 err(1, "setsockopt(IPV6_HOPLIMIT)");
405 ident = htons(getpid() & 0xffff); /* same as ping6 */
407 while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:STUvw:")) != -1)
422 first_hop = strtoul(optarg, &ep, 0);
423 if (errno || !*optarg || *ep || first_hop > 255) {
425 "traceroute6: invalid min hoplimit.\n");
430 hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno);
433 "traceroute6: unknown host %s\n", optarg);
438 * XXX: We can't detect the number of
439 * intermediate nodes yet.
441 if ((rth = inet6_rth_init((void *)rtbuf,
442 sizeof(rtbuf), IPV6_RTHDR_TYPE_0,
445 "inet6_rth_init failed.\n");
449 if (inet6_rth_add((void *)rth,
450 (struct in6_addr *)hp->h_addr)) {
452 "inet6_rth_add failed for %s\n",
459 useproto = IPPROTO_ICMPV6;
467 max_hops = strtoul(optarg, &ep, 0);
468 if (errno || !*optarg || *ep || max_hops > 255) {
470 "traceroute6: invalid max hoplimit.\n");
478 useproto = IPPROTO_NONE;
483 lport = strtoul(optarg, &ep, 0);
484 if (errno || !*optarg || *ep) {
485 fprintf(stderr, "traceroute6: invalid port.\n");
488 if (lport == 0 || lport != (lport & 0xffff)) {
490 "traceroute6: port out of range.\n");
493 port = lport & 0xffff;
498 nprobes = strtoul(optarg, &ep, 0);
499 if (errno || !*optarg || *ep) {
501 "traceroute6: invalid nprobes.\n");
506 "traceroute6: nprobes must be >0.\n");
511 options |= SO_DONTROUTE;
515 * set the ip source address of the outbound
516 * probe (e.g., on a multi-homed host).
521 useproto = IPPROTO_SCTP;
524 useproto = IPPROTO_TCP;
527 useproto = IPPROTO_UDP;
535 waittime = strtoul(optarg, &ep, 0);
536 if (errno || !*optarg || *ep) {
538 "traceroute6: invalid wait time.\n");
543 "traceroute6: wait must be >= 1 sec.\n");
554 * Open socket to send probe packets.
561 if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
562 perror("socket(SOCK_DGRAM)");
569 if ((sndsock = socket(AF_INET6, SOCK_RAW, useproto)) < 0) {
570 perror("socket(SOCK_RAW)");
575 fprintf(stderr, "traceroute6: unknown probe protocol %d\n",
579 if (max_hops < first_hop) {
581 "traceroute6: max hoplimit must be larger than first hoplimit.\n");
587 if (setresuid(uid, uid, uid) == -1) {
593 if (argc < 1 || argc > 2)
597 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
602 memset(&hints, 0, sizeof(hints));
603 hints.ai_family = PF_INET6;
604 hints.ai_socktype = SOCK_RAW;
605 hints.ai_protocol = IPPROTO_ICMPV6;
606 hints.ai_flags = AI_CANONNAME;
607 error = getaddrinfo(*argv, NULL, &hints, &res);
610 "traceroute6: %s\n", gai_strerror(error));
613 if (res->ai_addrlen != sizeof(Dst)) {
615 "traceroute6: size of sockaddr mismatch\n");
618 memcpy(&Dst, res->ai_addr, res->ai_addrlen);
619 hostname = res->ai_canonname ? strdup(res->ai_canonname) : *argv;
621 fprintf(stderr, "traceroute6: not enough core\n");
625 if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf,
626 sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
627 strlcpy(hbuf, "?", sizeof(hbuf));
628 fprintf(stderr, "traceroute6: Warning: %s has multiple "
629 "addresses; using %s\n", hostname, hbuf);
635 datalen = strtoul(*argv, &ep, 0);
638 "traceroute6: invalid packet length.\n");
644 minlen = ICMP6ECHOLEN;
647 minlen = sizeof(struct udphdr);
654 minlen = sizeof(struct sctphdr);
657 minlen = sizeof(struct tcphdr);
660 fprintf(stderr, "traceroute6: unknown probe protocol %d.\n",
664 if (datalen < minlen)
666 else if (datalen >= MAXPACKET) {
668 "traceroute6: packet size must be %zu <= s < %d.\n",
672 if (useproto == IPPROTO_UDP)
673 datalen -= sizeof(struct udphdr);
674 if ((useproto == IPPROTO_SCTP) && (datalen & 3)) {
676 "traceroute6: packet size must be a multiple of 4.\n");
679 outpacket = malloc(datalen);
684 (void) bzero((char *)outpacket, datalen);
686 /* initialize msghdr for receiving packets */
687 rcviov[0].iov_base = (caddr_t)packet;
688 rcviov[0].iov_len = sizeof(packet);
689 rcvmhdr.msg_name = (caddr_t)&Rcv;
690 rcvmhdr.msg_namelen = sizeof(Rcv);
691 rcvmhdr.msg_iov = rcviov;
692 rcvmhdr.msg_iovlen = 1;
693 rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
694 CMSG_SPACE(sizeof(int));
695 if ((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) {
696 fprintf(stderr, "traceroute6: malloc failed\n");
699 rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf;
700 rcvmhdr.msg_controllen = rcvcmsglen;
702 if (options & SO_DEBUG)
703 (void) setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG,
704 (char *)&on, sizeof(on));
705 if (options & SO_DONTROUTE)
706 (void) setsockopt(rcvsock, SOL_SOCKET, SO_DONTROUTE,
707 (char *)&on, sizeof(on));
709 #ifdef IPSEC_POLICY_IPSEC
711 * do not raise error even if setsockopt fails, kernel may have ipsec
714 if (setpolicy(rcvsock, "in bypass") < 0)
715 errx(1, "%s", ipsec_strerror());
716 if (setpolicy(rcvsock, "out bypass") < 0)
717 errx(1, "%s", ipsec_strerror());
720 int level = IPSEC_LEVEL_NONE;
722 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
724 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
726 #ifdef IP_AUTH_TRANS_LEVEL
727 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
730 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
733 #ifdef IP_AUTH_NETWORK_LEVEL
734 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
738 #endif /*IPSEC_POLICY_IPSEC*/
745 if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&i,
747 perror("setsockopt(SO_SNDBUF)");
750 #endif /* SO_SNDBUF */
751 if (options & SO_DEBUG)
752 (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
753 (char *)&on, sizeof(on));
754 if (options & SO_DONTROUTE)
755 (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
756 (char *)&on, sizeof(on));
757 if (rth) {/* XXX: there is no library to finalize the header... */
758 rth->ip6r_len = rth->ip6r_segleft * 2;
759 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_RTHDR,
760 (void *)rth, (rth->ip6r_len + 1) << 3)) {
761 fprintf(stderr, "setsockopt(IPV6_RTHDR): %s\n",
767 #ifdef IPSEC_POLICY_IPSEC
769 * do not raise error even if setsockopt fails, kernel may have ipsec
772 if (setpolicy(sndsock, "in bypass") < 0)
773 errx(1, "%s", ipsec_strerror());
774 if (setpolicy(sndsock, "out bypass") < 0)
775 errx(1, "%s", ipsec_strerror());
778 int level = IPSEC_LEVEL_BYPASS;
780 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
782 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
784 #ifdef IP_AUTH_TRANS_LEVEL
785 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
788 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
791 #ifdef IP_AUTH_NETWORK_LEVEL
792 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
796 #endif /*IPSEC_POLICY_IPSEC*/
802 bzero(&Src, sizeof(Src));
804 struct addrinfo hints, *res;
807 memset(&hints, 0, sizeof(hints));
808 hints.ai_family = AF_INET6;
809 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
810 hints.ai_flags = AI_NUMERICHOST;
811 error = getaddrinfo(source, "0", &hints, &res);
813 printf("traceroute6: %s: %s\n", source,
814 gai_strerror(error));
817 if (res->ai_addrlen > sizeof(Src)) {
818 printf("traceroute6: %s: %s\n", source,
819 gai_strerror(error));
822 memcpy(&Src, res->ai_addr, res->ai_addrlen);
825 struct sockaddr_in6 Nxt;
830 Nxt.sin6_port = htons(DUMMY_PORT);
832 bcopy(inet6_rthdr_getaddr(cmsg, 1), &Nxt.sin6_addr,
833 sizeof(Nxt.sin6_addr));
834 if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
838 if (connect(dummy, (struct sockaddr *)&Nxt, Nxt.sin6_len) < 0) {
843 if (getsockname(dummy, (struct sockaddr *)&Src, &len) < 0) {
844 perror("getsockname");
847 if (getnameinfo((struct sockaddr *)&Src, Src.sin6_len,
848 src0, sizeof(src0), NULL, 0, NI_NUMERICHOST)) {
849 fprintf(stderr, "getnameinfo failed for source\n");
856 Src.sin6_port = htons(0);
857 if (bind(sndsock, (struct sockaddr *)&Src, Src.sin6_len) < 0) {
866 if (getsockname(sndsock, (struct sockaddr *)&Src, &len) < 0) {
867 perror("getsockname");
870 srcport = ntohs(Src.sin6_port);
874 asn = as_setup(as_server);
877 "traceroute6: as_setup failed, AS# lookups"
879 (void)fflush(stderr);
887 if (getnameinfo((struct sockaddr *)&Dst, Dst.sin6_len, hbuf,
888 sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
889 strlcpy(hbuf, "(invalid)", sizeof(hbuf));
890 fprintf(stderr, "traceroute6");
891 fprintf(stderr, " to %s (%s)", hostname, hbuf);
893 fprintf(stderr, " from %s", source);
894 fprintf(stderr, ", %lu hops max, %lu byte packets\n",
896 datalen + ((useproto == IPPROTO_UDP) ? sizeof(struct udphdr) : 0));
897 (void) fflush(stderr);
900 printf("Skipping %lu intermediate hops\n", first_hop - 1);
905 for (hops = first_hop; hops <= max_hops; ++hops) {
906 struct in6_addr lastaddr;
908 unsigned unreachable = 0;
910 printf("%2lu ", hops);
911 bzero(&lastaddr, sizeof(lastaddr));
912 for (probe = 0; probe < nprobes; ++probe) {
914 struct timeval t1, t2;
916 (void) gettimeofday(&t1, NULL);
917 send_probe(++seq, hops);
918 while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) {
919 (void) gettimeofday(&t2, NULL);
920 if (packet_ok(&rcvmhdr, cc, seq, &type, &code)) {
921 if (!IN6_ARE_ADDR_EQUAL(&Rcv.sin6_addr,
924 fputs("\n ", stdout);
926 lastaddr = Rcv.sin6_addr;
928 printf(" %.3f ms", deltaT(&t1, &t2));
929 if (type == ICMP6_DST_UNREACH) {
931 case ICMP6_DST_UNREACH_NOROUTE:
935 case ICMP6_DST_UNREACH_ADMIN:
939 case ICMP6_DST_UNREACH_NOTNEIGHBOR:
943 case ICMP6_DST_UNREACH_ADDR:
947 case ICMP6_DST_UNREACH_NOPORT:
954 } else if (type == ICMP6_PARAM_PROB &&
955 code == ICMP6_PARAMPROB_NEXTHEADER) {
958 } else if (type == ICMP6_ECHO_REPLY) {
965 } else if (deltaT(&t1, &t2) > waittime * 1000) {
972 (void) fflush(stdout);
976 (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) {
987 wait_for_reply(int sock, struct msghdr *mhdr)
990 struct pollfd pfd[1];
994 pfd[0].events = POLLIN;
997 if (poll(pfd, 1, waittime * 1000) > 0)
998 cc = recvmsg(rcvsock, mhdr, 0);
1003 struct timeval wait;
1006 fdsn = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
1007 if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
1009 memset(fdsp, 0, fdsn);
1011 wait.tv_sec = waittime; wait.tv_usec = 0;
1013 if (select(sock+1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0)
1014 cc = recvmsg(rcvsock, mhdr, 0);
1022 #ifdef IPSEC_POLICY_IPSEC
1024 setpolicy(so, policy)
1030 buf = ipsec_set_policy(policy, strlen(policy));
1032 warnx("%s", ipsec_strerror());
1035 (void)setsockopt(so, IPPROTO_IPV6, IPV6_IPSEC_POLICY,
1036 buf, ipsec_get_policylen(buf));
1046 send_probe(int seq, u_long hops)
1048 struct icmp6_hdr *icp;
1049 struct sctphdr *sctp;
1050 struct sctp_chunkhdr *chk;
1051 struct sctp_init_chunk *init;
1052 struct sctp_paramhdr *param;
1057 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
1058 (char *)&i, sizeof(i)) < 0) {
1059 perror("setsockopt IPV6_UNICAST_HOPS");
1062 Dst.sin6_port = htons(port + seq);
1065 case IPPROTO_ICMPV6:
1066 icp = (struct icmp6_hdr *)outpacket;
1068 icp->icmp6_type = ICMP6_ECHO_REQUEST;
1069 icp->icmp6_code = 0;
1070 icp->icmp6_cksum = 0;
1071 icp->icmp6_id = ident;
1072 icp->icmp6_seq = htons(seq);
1077 /* No space for anything. No harm as seq/tv32 are decorative. */
1080 sctp = (struct sctphdr *)outpacket;
1082 sctp->src_port = htons(ident);
1083 sctp->dest_port = htons(port + seq);
1084 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1085 sizeof(struct sctp_init_chunk))) {
1088 sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port;
1090 sctp->checksum = htonl(0);
1091 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1092 sizeof(struct sctp_init_chunk))) {
1094 * Send a packet containing an INIT chunk. This works
1095 * better in case of firewalls on the path, but
1096 * results in a probe packet containing at least
1097 * 32 bytes of payload. For shorter payloads, use
1098 * SHUTDOWN-ACK chunks.
1100 init = (struct sctp_init_chunk *)(sctp + 1);
1101 init->ch.chunk_type = SCTP_INITIATION;
1102 init->ch.chunk_flags = 0;
1103 init->ch.chunk_length = htons((u_int16_t)(datalen -
1104 sizeof(struct sctphdr)));
1105 init->init.initiate_tag = (sctp->src_port << 16) |
1107 init->init.a_rwnd = htonl(1500);
1108 init->init.num_outbound_streams = htons(1);
1109 init->init.num_inbound_streams = htons(1);
1110 init->init.initial_tsn = htonl(0);
1111 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1112 sizeof(struct sctp_init_chunk) +
1113 sizeof(struct sctp_paramhdr))) {
1114 param = (struct sctp_paramhdr *)(init + 1);
1115 param->param_type = htons(SCTP_PAD);
1116 param->param_length =
1117 htons((u_int16_t)(datalen -
1118 sizeof(struct sctphdr) -
1119 sizeof(struct sctp_init_chunk)));
1123 * Send a packet containing a SHUTDOWN-ACK chunk,
1124 * possibly followed by a PAD chunk.
1126 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1127 sizeof(struct sctp_chunkhdr))) {
1128 chk = (struct sctp_chunkhdr *)(sctp + 1);
1129 chk->chunk_type = SCTP_SHUTDOWN_ACK;
1130 chk->chunk_flags = 0;
1131 chk->chunk_length = htons(4);
1133 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1134 2 * sizeof(struct sctp_chunkhdr))) {
1136 chk->chunk_type = SCTP_PAD_CHUNK;
1137 chk->chunk_flags = 0;
1138 chk->chunk_length = htons((u_int16_t)(datalen -
1139 sizeof(struct sctphdr) -
1140 sizeof(struct sctp_chunkhdr)));
1143 sctp->checksum = sctp_crc32c(outpacket, datalen);
1146 tcp = (struct tcphdr *)outpacket;
1148 tcp->th_sport = htons(ident);
1149 tcp->th_dport = htons(port + seq);
1150 tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
1153 tcp->th_flags = TH_SYN;
1155 tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen);
1158 fprintf(stderr, "Unknown probe protocol %d.\n", useproto);
1162 i = sendto(sndsock, (char *)outpacket, datalen, 0,
1163 (struct sockaddr *)&Dst, Dst.sin6_len);
1164 if (i < 0 || (u_long)i != datalen) {
1167 printf("traceroute6: wrote %s %lu chars, ret=%d\n",
1168 hostname, datalen, i);
1169 (void) fflush(stdout);
1174 get_hoplim(struct msghdr *mhdr)
1178 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1179 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1180 if (cm->cmsg_level == IPPROTO_IPV6 &&
1181 cm->cmsg_type == IPV6_HOPLIMIT &&
1182 cm->cmsg_len == CMSG_LEN(sizeof(int)))
1183 return (*(int *)CMSG_DATA(cm));
1190 deltaT(struct timeval *t1p, struct timeval *t2p)
1194 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1195 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1200 * Convert an ICMP "type" field to a printable string.
1205 u_char t = t0 & 0xff;
1209 case ICMP6_DST_UNREACH:
1210 cp = "Destination Unreachable";
1212 case ICMP6_PACKET_TOO_BIG:
1213 cp = "Packet Too Big";
1215 case ICMP6_TIME_EXCEEDED:
1216 cp = "Time Exceeded";
1218 case ICMP6_PARAM_PROB:
1219 cp = "Parameter Problem";
1221 case ICMP6_ECHO_REQUEST:
1222 cp = "Echo Request";
1224 case ICMP6_ECHO_REPLY:
1227 case ICMP6_MEMBERSHIP_QUERY:
1228 cp = "Group Membership Query";
1230 case ICMP6_MEMBERSHIP_REPORT:
1231 cp = "Group Membership Report";
1233 case ICMP6_MEMBERSHIP_REDUCTION:
1234 cp = "Group Membership Reduction";
1236 case ND_ROUTER_SOLICIT:
1237 cp = "Router Solicitation";
1239 case ND_ROUTER_ADVERT:
1240 cp = "Router Advertisement";
1242 case ND_NEIGHBOR_SOLICIT:
1243 cp = "Neighbor Solicitation";
1245 case ND_NEIGHBOR_ADVERT:
1246 cp = "Neighbor Advertisement";
1259 packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code)
1261 struct icmp6_hdr *icp;
1262 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1263 char *buf = (char *)mhdr->msg_iov[0].iov_base;
1266 char hbuf[NI_MAXHOST];
1274 ip = (struct ip6_hdr *) buf;
1275 hlen = sizeof(struct ip6_hdr);
1276 if (cc < hlen + sizeof(struct icmp6_hdr)) {
1278 if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1279 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1280 strlcpy(hbuf, "invalid", sizeof(hbuf));
1281 printf("packet too short (%d bytes) from %s\n", cc,
1287 icp = (struct icmp6_hdr *)(buf + hlen);
1289 if (cc < (int)sizeof(struct icmp6_hdr)) {
1291 if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1292 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1293 strlcpy(hbuf, "invalid", sizeof(hbuf));
1294 printf("data too short (%d bytes) from %s\n", cc, hbuf);
1298 icp = (struct icmp6_hdr *)buf;
1300 /* get optional information via advanced API */
1303 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1304 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1305 if (cm->cmsg_level == IPPROTO_IPV6 &&
1306 cm->cmsg_type == IPV6_PKTINFO &&
1308 CMSG_LEN(sizeof(struct in6_pktinfo)))
1309 rcvpktinfo = (struct in6_pktinfo *)(CMSG_DATA(cm));
1311 if (cm->cmsg_level == IPPROTO_IPV6 &&
1312 cm->cmsg_type == IPV6_HOPLIMIT &&
1313 cm->cmsg_len == CMSG_LEN(sizeof(int)))
1314 hlimp = (int *)CMSG_DATA(cm);
1316 if (rcvpktinfo == NULL || hlimp == NULL) {
1317 warnx("failed to get received hop limit or packet info");
1321 rcvhlim = 0; /*XXX*/
1327 *type = icp->icmp6_type;
1328 *code = icp->icmp6_code;
1329 if ((*type == ICMP6_TIME_EXCEEDED &&
1330 *code == ICMP6_TIME_EXCEED_TRANSIT) ||
1331 (*type == ICMP6_DST_UNREACH) ||
1332 (*type == ICMP6_PARAM_PROB &&
1333 *code == ICMP6_PARAMPROB_NEXTHEADER)) {
1334 struct ip6_hdr *hip;
1335 struct icmp6_hdr *icmp;
1336 struct sctp_init_chunk *init;
1337 struct sctphdr *sctp;
1342 hip = (struct ip6_hdr *)(icp + 1);
1343 if ((up = get_uphdr(hip, (u_char *)(buf + cc))) == NULL) {
1345 warnx("failed to get upper layer header");
1349 case IPPROTO_ICMPV6:
1350 icmp = (struct icmp6_hdr *)up;
1351 if (icmp->icmp6_id == ident &&
1352 icmp->icmp6_seq == htons(seq))
1356 udp = (struct udphdr *)up;
1357 if (udp->uh_sport == htons(srcport) &&
1358 udp->uh_dport == htons(port + seq))
1362 sctp = (struct sctphdr *)up;
1363 if (sctp->src_port != htons(ident) ||
1364 sctp->dest_port != htons(port + seq)) {
1367 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1368 sizeof(struct sctp_init_chunk))) {
1369 if (sctp->v_tag != 0) {
1372 init = (struct sctp_init_chunk *)(sctp + 1);
1373 /* Check the initiate tag, if available. */
1374 if ((char *)&init->init.a_rwnd > buf + cc) {
1377 if (init->init.initiate_tag == (u_int32_t)
1378 ((sctp->src_port << 16) | sctp->dest_port)) {
1383 (u_int32_t)((sctp->src_port << 16) |
1390 tcp = (struct tcphdr *)up;
1391 if (tcp->th_sport == htons(ident) &&
1392 tcp->th_dport == htons(port + seq) &&
1394 (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport))
1400 fprintf(stderr, "Unknown probe proto %d.\n", useproto);
1403 } else if (useproto == IPPROTO_ICMPV6 && *type == ICMP6_ECHO_REPLY) {
1404 if (icp->icmp6_id == ident &&
1405 icp->icmp6_seq == htons(seq))
1409 char sbuf[NI_MAXHOST+1], dbuf[INET6_ADDRSTRLEN];
1413 if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1414 sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0)
1415 strlcpy(sbuf, "invalid", sizeof(sbuf));
1416 printf("\n%d bytes from %s to %s", cc, sbuf,
1417 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1418 dbuf, sizeof(dbuf)) : "?");
1419 printf(": icmp type %d (%s) code %d\n", *type, pr_type(*type),
1421 p = (u_int8_t *)(icp + 1);
1423 for (i = 0; i < cc; i++) {
1428 printf("%02x", p[i]);
1429 if (i % WIDTH == WIDTH - 1)
1432 if (cc % WIDTH != 0)
1439 * Increment pointer until find the UDP or ICMP header.
1442 get_uphdr(struct ip6_hdr *ip6, u_char *lim)
1444 u_char *cp = (u_char *)ip6, nh;
1446 static u_char none_hdr[1]; /* Fake pointer for IPPROTO_NONE. */
1448 if (cp + sizeof(*ip6) > lim)
1452 cp += sizeof(struct ip6_hdr);
1454 while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) {
1458 case IPPROTO_ICMPV6:
1459 return (useproto == nh ? cp : NULL);
1463 return (useproto == nh ? cp : NULL);
1465 return (useproto == nh ? none_hdr : NULL);
1466 case IPPROTO_FRAGMENT:
1467 hlen = sizeof(struct ip6_frag);
1468 nh = ((struct ip6_frag *)cp)->ip6f_nxt;
1471 hlen = (((struct ip6_ext *)cp)->ip6e_len + 2) << 2;
1472 nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1475 hlen = (((struct ip6_ext *)cp)->ip6e_len + 1) << 3;
1476 nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1487 print(struct msghdr *mhdr, int cc)
1489 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1490 char hbuf[NI_MAXHOST];
1492 if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1493 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1494 strlcpy(hbuf, "invalid", sizeof(hbuf));
1496 printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6));
1498 printf(" %s", hbuf);
1500 printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf);
1502 printf(" %s", inetname((struct sockaddr *)from));
1506 printf(" %d bytes to %s", cc,
1507 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1508 hbuf, sizeof(hbuf)) : "?");
1510 printf(" %d bytes of data to %s", cc,
1511 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1512 hbuf, sizeof(hbuf)) : "?");
1518 * Construct an Internet address representation.
1519 * If the nflag has been supplied, give
1520 * numeric value, otherwise try for symbolic name.
1523 inetname(struct sockaddr *sa)
1525 static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1];
1526 static int first = 1;
1529 if (first && !nflag) {
1531 if (gethostname(domain, sizeof(domain)) == 0 &&
1532 (cp = strchr(domain, '.')))
1533 (void) strlcpy(domain, cp + 1, sizeof(domain));
1539 if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1540 NI_NAMEREQD) == 0) {
1541 if ((cp = strchr(line, '.')) &&
1542 !strcmp(cp + 1, domain))
1550 if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1551 NI_NUMERICHOST) != 0)
1552 strlcpy(line, "invalid", sizeof(line));
1557 * CRC32C routine for the Stream Control Transmission Protocol
1560 #define CRC32C(c, d) (c = (c>>8) ^ crc_c[(c^(d))&0xFF])
1562 static u_int32_t crc_c[256] = {
1563 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
1564 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
1565 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
1566 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
1567 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
1568 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
1569 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
1570 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
1571 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
1572 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
1573 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
1574 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
1575 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
1576 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
1577 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
1578 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
1579 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
1580 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
1581 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
1582 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
1583 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
1584 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
1585 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
1586 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
1587 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
1588 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
1589 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
1590 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
1591 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
1592 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
1593 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
1594 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
1595 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
1596 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
1597 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
1598 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
1599 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
1600 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
1601 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
1602 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
1603 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
1604 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
1605 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
1606 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
1607 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
1608 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
1609 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
1610 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
1611 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
1612 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
1613 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
1614 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
1615 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
1616 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
1617 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
1618 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
1619 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
1620 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
1621 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
1622 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
1623 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
1624 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
1625 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
1626 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
1630 sctp_crc32c(void *packet, u_int32_t len)
1632 u_int32_t i, crc32c;
1633 u_int8_t byte0, byte1, byte2, byte3;
1634 u_int8_t *buf = (u_int8_t *)packet;
1637 for (i = 0; i < len; i++)
1638 CRC32C(crc32c, buf[i]);
1640 byte0 = crc32c & 0xff;
1641 byte1 = (crc32c>>8) & 0xff;
1642 byte2 = (crc32c>>16) & 0xff;
1643 byte3 = (crc32c>>24) & 0xff;
1644 crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
1645 return htonl(crc32c);
1649 in_cksum(u_int16_t *addr, int len)
1652 u_int16_t *w = addr;
1657 * Our algorithm is simple, using a 32 bit accumulator (sum),
1658 * we add sequential 16 bit words to it, and at the end, fold
1659 * back all the carry bits from the top 16 bits into the lower
1667 /* mop up an odd byte, if necessary */
1669 sum += *(u_char *)w;
1672 * add back carry outs from top 16 bits to low 16 bits
1674 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
1675 sum += (sum >> 16); /* add carry */
1676 answer = ~sum; /* truncate to 16 bits */
1681 tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1682 void *payload, u_int32_t len)
1685 struct in6_addr src;
1686 struct in6_addr dst;
1693 pseudo_hdr.src = src->sin6_addr;
1694 pseudo_hdr.dst = dst->sin6_addr;
1695 pseudo_hdr.len = htonl(len);
1696 pseudo_hdr.zero[0] = 0;
1697 pseudo_hdr.zero[1] = 0;
1698 pseudo_hdr.zero[2] = 0;
1699 pseudo_hdr.next = IPPROTO_TCP;
1701 sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1702 sum[0] = in_cksum(payload, len);
1704 return (~in_cksum(sum, sizeof(sum)));
1712 "usage: traceroute6 [-adIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n"
1713 " [-m hoplimit] [-p port] [-q probes] [-s src] [-w waittime] target\n"