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 static u_char packet[512]; /* last inbound (icmp) packet */
298 static char *outpacket; /* last output packet */
300 int main(int, char *[]);
301 int wait_for_reply(int, struct msghdr *);
302 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
303 int setpolicy(int so, char *policy);
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, u_char *, u_char *);
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 *,
319 static int rcvsock; /* receive (icmp) socket file descriptor */
320 static int sndsock; /* send (raw/udp) socket file descriptor */
322 static struct msghdr rcvmhdr;
323 static struct iovec rcviov[2];
325 static struct in6_pktinfo *rcvpktinfo;
327 static struct sockaddr_in6 Src, Dst, Rcv;
328 static 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 static char rtbuf[2064];
332 static struct ip6_rthdr *rth;
333 static struct cmsghdr *cmsg;
335 static char *source = NULL;
336 static char *hostname;
338 static u_long nprobes = 3;
339 static u_long first_hop = 1;
340 static u_long max_hops = 30;
341 static u_int16_t srcport;
342 static u_int16_t port = 32768+666; /* start udp dest port # for probe packets */
343 static u_int16_t ident;
344 static int options; /* socket options */
346 static int waittime = 5; /* time to wait for response (in seconds) */
347 static int nflag; /* print addresses numerically */
348 static int useproto = IPPROTO_UDP; /* protocol to use to send packet */
349 static int lflag; /* print both numerical address & hostname */
350 static int as_path; /* print as numbers for each hop */
351 static char *as_server = NULL;
355 main(int argc, char *argv[])
357 int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM };
358 char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep;
359 int ch, i, on = 1, seq, rcvcmsglen, error;
360 struct addrinfo hints, *res;
361 static u_char *rcvcmsgbuf;
362 u_long probe, hops, lport;
367 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
368 char ipsec_inpolicy[] = "in bypass";
369 char ipsec_outpolicy[] = "out bypass";
375 if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
376 perror("socket(ICMPv6)");
381 (void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &i, &size, NULL, 0);
384 /* specify to tell receiving interface */
385 #ifdef IPV6_RECVPKTINFO
386 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
388 err(1, "setsockopt(IPV6_RECVPKTINFO)");
389 #else /* old adv. API */
390 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_PKTINFO, &on,
392 err(1, "setsockopt(IPV6_PKTINFO)");
395 /* specify to tell value of hoplimit field of received IP6 hdr */
396 #ifdef IPV6_RECVHOPLIMIT
397 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
399 err(1, "setsockopt(IPV6_RECVHOPLIMIT)");
400 #else /* old adv. API */
401 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on,
403 err(1, "setsockopt(IPV6_HOPLIMIT)");
407 ident = htons(getpid() & 0xffff); /* same as ping6 */
409 while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:STUvw:")) != -1)
424 first_hop = strtoul(optarg, &ep, 0);
425 if (errno || !*optarg || *ep || first_hop > 255) {
427 "traceroute6: invalid min hoplimit.\n");
432 hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno);
435 "traceroute6: unknown host %s\n", optarg);
440 * XXX: We can't detect the number of
441 * intermediate nodes yet.
443 if ((rth = inet6_rth_init((void *)rtbuf,
444 sizeof(rtbuf), IPV6_RTHDR_TYPE_0,
447 "inet6_rth_init failed.\n");
451 if (inet6_rth_add((void *)rth,
452 (struct in6_addr *)hp->h_addr)) {
454 "inet6_rth_add failed for %s\n",
461 useproto = IPPROTO_ICMPV6;
469 max_hops = strtoul(optarg, &ep, 0);
470 if (errno || !*optarg || *ep || max_hops > 255) {
472 "traceroute6: invalid max hoplimit.\n");
480 useproto = IPPROTO_NONE;
485 lport = strtoul(optarg, &ep, 0);
486 if (errno || !*optarg || *ep) {
487 fprintf(stderr, "traceroute6: invalid port.\n");
490 if (lport == 0 || lport != (lport & 0xffff)) {
492 "traceroute6: port out of range.\n");
495 port = lport & 0xffff;
500 nprobes = strtoul(optarg, &ep, 0);
501 if (errno || !*optarg || *ep) {
503 "traceroute6: invalid nprobes.\n");
508 "traceroute6: nprobes must be >0.\n");
513 options |= SO_DONTROUTE;
517 * set the ip source address of the outbound
518 * probe (e.g., on a multi-homed host).
523 useproto = IPPROTO_SCTP;
526 useproto = IPPROTO_TCP;
529 useproto = IPPROTO_UDP;
537 waittime = strtoul(optarg, &ep, 0);
538 if (errno || !*optarg || *ep) {
540 "traceroute6: invalid wait time.\n");
545 "traceroute6: wait must be >= 1 sec.\n");
556 * Open socket to send probe packets.
563 if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
564 perror("socket(SOCK_DGRAM)");
571 if ((sndsock = socket(AF_INET6, SOCK_RAW, useproto)) < 0) {
572 perror("socket(SOCK_RAW)");
577 fprintf(stderr, "traceroute6: unknown probe protocol %d\n",
581 if (max_hops < first_hop) {
583 "traceroute6: max hoplimit must be larger than first hoplimit.\n");
589 if (setresuid(uid, uid, uid) == -1) {
595 if (argc < 1 || argc > 2)
599 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
604 memset(&hints, 0, sizeof(hints));
605 hints.ai_family = PF_INET6;
606 hints.ai_socktype = SOCK_RAW;
607 hints.ai_protocol = IPPROTO_ICMPV6;
608 hints.ai_flags = AI_CANONNAME;
609 error = getaddrinfo(*argv, NULL, &hints, &res);
612 "traceroute6: %s\n", gai_strerror(error));
615 if (res->ai_addrlen != sizeof(Dst)) {
617 "traceroute6: size of sockaddr mismatch\n");
620 memcpy(&Dst, res->ai_addr, res->ai_addrlen);
621 hostname = res->ai_canonname ? strdup(res->ai_canonname) : *argv;
623 fprintf(stderr, "traceroute6: not enough core\n");
627 if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf,
628 sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
629 strlcpy(hbuf, "?", sizeof(hbuf));
630 fprintf(stderr, "traceroute6: Warning: %s has multiple "
631 "addresses; using %s\n", hostname, hbuf);
637 datalen = strtoul(*argv, &ep, 0);
640 "traceroute6: invalid packet length.\n");
646 minlen = ICMP6ECHOLEN;
649 minlen = sizeof(struct udphdr);
656 minlen = sizeof(struct sctphdr);
659 minlen = sizeof(struct tcphdr);
662 fprintf(stderr, "traceroute6: unknown probe protocol %d.\n",
666 if (datalen < minlen)
668 else if (datalen >= MAXPACKET) {
670 "traceroute6: packet size must be %zu <= s < %d.\n",
674 if (useproto == IPPROTO_UDP)
675 datalen -= sizeof(struct udphdr);
676 if ((useproto == IPPROTO_SCTP) && (datalen & 3)) {
678 "traceroute6: packet size must be a multiple of 4.\n");
681 outpacket = malloc(datalen);
686 (void) bzero((char *)outpacket, datalen);
688 /* initialize msghdr for receiving packets */
689 rcviov[0].iov_base = (caddr_t)packet;
690 rcviov[0].iov_len = sizeof(packet);
691 rcvmhdr.msg_name = (caddr_t)&Rcv;
692 rcvmhdr.msg_namelen = sizeof(Rcv);
693 rcvmhdr.msg_iov = rcviov;
694 rcvmhdr.msg_iovlen = 1;
695 rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
696 CMSG_SPACE(sizeof(int));
697 if ((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) {
698 fprintf(stderr, "traceroute6: malloc failed\n");
701 rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf;
702 rcvmhdr.msg_controllen = rcvcmsglen;
704 if (options & SO_DEBUG)
705 (void) setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG,
706 (char *)&on, sizeof(on));
707 if (options & SO_DONTROUTE)
708 (void) setsockopt(rcvsock, SOL_SOCKET, SO_DONTROUTE,
709 (char *)&on, sizeof(on));
710 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
712 * do not raise error even if setsockopt fails, kernel may have ipsec
715 if (setpolicy(rcvsock, ipsec_inpolicy) < 0)
716 errx(1, "%s", ipsec_strerror());
717 if (setpolicy(rcvsock, ipsec_outpolicy) < 0)
718 errx(1, "%s", ipsec_strerror());
721 int level = IPSEC_LEVEL_NONE;
723 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
725 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
727 #ifdef IP_AUTH_TRANS_LEVEL
728 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
731 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
734 #ifdef IP_AUTH_NETWORK_LEVEL
735 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
739 #endif /* !(IPSEC && 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",
766 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
768 * do not raise error even if setsockopt fails, kernel may have ipsec
771 if (setpolicy(sndsock, ipsec_inpolicy) < 0)
772 errx(1, "%s", ipsec_strerror());
773 if (setpolicy(sndsock, ipsec_outpolicy) < 0)
774 errx(1, "%s", ipsec_strerror());
777 int level = IPSEC_LEVEL_BYPASS;
779 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
781 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
783 #ifdef IP_AUTH_TRANS_LEVEL
784 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
787 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
790 #ifdef IP_AUTH_NETWORK_LEVEL
791 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
795 #endif /* !(IPSEC && IPSEC_POLICY_IPSEC) */
800 bzero(&Src, sizeof(Src));
802 memset(&hints, 0, sizeof(hints));
803 hints.ai_family = AF_INET6;
804 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
805 hints.ai_flags = AI_NUMERICHOST;
806 error = getaddrinfo(source, "0", &hints, &res);
808 printf("traceroute6: %s: %s\n", source,
809 gai_strerror(error));
812 if (res->ai_addrlen > sizeof(Src)) {
813 printf("traceroute6: %s: %s\n", source,
814 gai_strerror(error));
817 memcpy(&Src, res->ai_addr, res->ai_addrlen);
820 struct sockaddr_in6 Nxt;
825 Nxt.sin6_port = htons(DUMMY_PORT);
827 bcopy(inet6_rthdr_getaddr(cmsg, 1), &Nxt.sin6_addr,
828 sizeof(Nxt.sin6_addr));
829 if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
833 if (connect(dummy, (struct sockaddr *)&Nxt, Nxt.sin6_len) < 0) {
838 if (getsockname(dummy, (struct sockaddr *)&Src, &len) < 0) {
839 perror("getsockname");
842 if (getnameinfo((struct sockaddr *)&Src, Src.sin6_len,
843 src0, sizeof(src0), NULL, 0, NI_NUMERICHOST)) {
844 fprintf(stderr, "getnameinfo failed for source\n");
851 Src.sin6_port = htons(0);
852 if (bind(sndsock, (struct sockaddr *)&Src, Src.sin6_len) < 0) {
861 if (getsockname(sndsock, (struct sockaddr *)&Src, &len) < 0) {
862 perror("getsockname");
865 srcport = ntohs(Src.sin6_port);
869 asn = as_setup(as_server);
872 "traceroute6: as_setup failed, AS# lookups"
874 (void)fflush(stderr);
882 if (getnameinfo((struct sockaddr *)&Dst, Dst.sin6_len, hbuf,
883 sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
884 strlcpy(hbuf, "(invalid)", sizeof(hbuf));
885 fprintf(stderr, "traceroute6");
886 fprintf(stderr, " to %s (%s)", hostname, hbuf);
888 fprintf(stderr, " from %s", source);
889 fprintf(stderr, ", %lu hops max, %lu byte packets\n",
891 datalen + ((useproto == IPPROTO_UDP) ? sizeof(struct udphdr) : 0));
892 (void) fflush(stderr);
895 printf("Skipping %lu intermediate hops\n", first_hop - 1);
900 for (hops = first_hop; hops <= max_hops; ++hops) {
901 struct in6_addr lastaddr;
903 unsigned unreachable = 0;
905 printf("%2lu ", hops);
906 bzero(&lastaddr, sizeof(lastaddr));
907 for (probe = 0; probe < nprobes; ++probe) {
909 struct timeval t1, t2;
911 (void) gettimeofday(&t1, NULL);
912 send_probe(++seq, hops);
913 while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) {
914 (void) gettimeofday(&t2, NULL);
915 if (packet_ok(&rcvmhdr, cc, seq, &type, &code)) {
916 if (!IN6_ARE_ADDR_EQUAL(&Rcv.sin6_addr,
919 fputs("\n ", stdout);
921 lastaddr = Rcv.sin6_addr;
923 printf(" %.3f ms", deltaT(&t1, &t2));
924 if (type == ICMP6_DST_UNREACH) {
926 case ICMP6_DST_UNREACH_NOROUTE:
930 case ICMP6_DST_UNREACH_ADMIN:
934 case ICMP6_DST_UNREACH_NOTNEIGHBOR:
938 case ICMP6_DST_UNREACH_ADDR:
942 case ICMP6_DST_UNREACH_NOPORT:
949 } else if (type == ICMP6_PARAM_PROB &&
950 code == ICMP6_PARAMPROB_NEXTHEADER) {
953 } else if (type == ICMP6_ECHO_REPLY) {
960 } else if (deltaT(&t1, &t2) > waittime * 1000) {
967 (void) fflush(stdout);
971 (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) {
982 wait_for_reply(int sock, struct msghdr *mhdr)
985 struct pollfd pfd[1];
989 pfd[0].events = POLLIN;
992 if (poll(pfd, 1, waittime * 1000) > 0)
993 cc = recvmsg(rcvsock, mhdr, 0);
1001 fdsn = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
1002 if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
1004 memset(fdsp, 0, fdsn);
1006 wait.tv_sec = waittime; wait.tv_usec = 0;
1008 if (select(sock+1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0)
1009 cc = recvmsg(rcvsock, mhdr, 0);
1016 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
1018 setpolicy(int so, char *policy)
1022 buf = ipsec_set_policy(policy, strlen(policy));
1024 warnx("%s", ipsec_strerror());
1027 (void)setsockopt(so, IPPROTO_IPV6, IPV6_IPSEC_POLICY,
1028 buf, ipsec_get_policylen(buf));
1037 send_probe(int seq, u_long hops)
1039 struct icmp6_hdr *icp;
1040 struct sctphdr *sctp;
1041 struct sctp_chunkhdr *chk;
1042 struct sctp_init_chunk *init;
1043 struct sctp_paramhdr *param;
1048 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
1049 (char *)&i, sizeof(i)) < 0) {
1050 perror("setsockopt IPV6_UNICAST_HOPS");
1053 Dst.sin6_port = htons(port + seq);
1056 case IPPROTO_ICMPV6:
1057 icp = (struct icmp6_hdr *)outpacket;
1059 icp->icmp6_type = ICMP6_ECHO_REQUEST;
1060 icp->icmp6_code = 0;
1061 icp->icmp6_cksum = 0;
1062 icp->icmp6_id = ident;
1063 icp->icmp6_seq = htons(seq);
1068 /* No space for anything. No harm as seq/tv32 are decorative. */
1071 sctp = (struct sctphdr *)outpacket;
1073 sctp->src_port = htons(ident);
1074 sctp->dest_port = htons(port + seq);
1075 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1076 sizeof(struct sctp_init_chunk))) {
1079 sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port;
1081 sctp->checksum = htonl(0);
1082 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1083 sizeof(struct sctp_init_chunk))) {
1085 * Send a packet containing an INIT chunk. This works
1086 * better in case of firewalls on the path, but
1087 * results in a probe packet containing at least
1088 * 32 bytes of payload. For shorter payloads, use
1089 * SHUTDOWN-ACK chunks.
1091 init = (struct sctp_init_chunk *)(sctp + 1);
1092 init->ch.chunk_type = SCTP_INITIATION;
1093 init->ch.chunk_flags = 0;
1094 init->ch.chunk_length = htons((u_int16_t)(datalen -
1095 sizeof(struct sctphdr)));
1096 init->init.initiate_tag = (sctp->src_port << 16) |
1098 init->init.a_rwnd = htonl(1500);
1099 init->init.num_outbound_streams = htons(1);
1100 init->init.num_inbound_streams = htons(1);
1101 init->init.initial_tsn = htonl(0);
1102 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1103 sizeof(struct sctp_init_chunk) +
1104 sizeof(struct sctp_paramhdr))) {
1105 param = (struct sctp_paramhdr *)(init + 1);
1106 param->param_type = htons(SCTP_PAD);
1107 param->param_length =
1108 htons((u_int16_t)(datalen -
1109 sizeof(struct sctphdr) -
1110 sizeof(struct sctp_init_chunk)));
1114 * Send a packet containing a SHUTDOWN-ACK chunk,
1115 * possibly followed by a PAD chunk.
1117 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1118 sizeof(struct sctp_chunkhdr))) {
1119 chk = (struct sctp_chunkhdr *)(sctp + 1);
1120 chk->chunk_type = SCTP_SHUTDOWN_ACK;
1121 chk->chunk_flags = 0;
1122 chk->chunk_length = htons(4);
1124 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1125 2 * sizeof(struct sctp_chunkhdr))) {
1127 chk->chunk_type = SCTP_PAD_CHUNK;
1128 chk->chunk_flags = 0;
1129 chk->chunk_length = htons((u_int16_t)(datalen -
1130 sizeof(struct sctphdr) -
1131 sizeof(struct sctp_chunkhdr)));
1134 sctp->checksum = sctp_crc32c(outpacket, datalen);
1137 tcp = (struct tcphdr *)outpacket;
1139 tcp->th_sport = htons(ident);
1140 tcp->th_dport = htons(port + seq);
1141 tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
1144 tcp->th_flags = TH_SYN;
1146 tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen);
1149 fprintf(stderr, "Unknown probe protocol %d.\n", useproto);
1153 i = sendto(sndsock, (char *)outpacket, datalen, 0,
1154 (struct sockaddr *)&Dst, Dst.sin6_len);
1155 if (i < 0 || (u_long)i != datalen) {
1158 printf("traceroute6: wrote %s %lu chars, ret=%d\n",
1159 hostname, datalen, i);
1160 (void) fflush(stdout);
1165 get_hoplim(struct msghdr *mhdr)
1169 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1170 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1171 if (cm->cmsg_level == IPPROTO_IPV6 &&
1172 cm->cmsg_type == IPV6_HOPLIMIT &&
1173 cm->cmsg_len == CMSG_LEN(sizeof(int)))
1174 return (*(int *)CMSG_DATA(cm));
1181 deltaT(struct timeval *t1p, struct timeval *t2p)
1185 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1186 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1191 * Convert an ICMP "type" field to a printable string.
1196 u_char t = t0 & 0xff;
1200 case ICMP6_DST_UNREACH:
1201 cp = "Destination Unreachable";
1203 case ICMP6_PACKET_TOO_BIG:
1204 cp = "Packet Too Big";
1206 case ICMP6_TIME_EXCEEDED:
1207 cp = "Time Exceeded";
1209 case ICMP6_PARAM_PROB:
1210 cp = "Parameter Problem";
1212 case ICMP6_ECHO_REQUEST:
1213 cp = "Echo Request";
1215 case ICMP6_ECHO_REPLY:
1218 case ICMP6_MEMBERSHIP_QUERY:
1219 cp = "Group Membership Query";
1221 case ICMP6_MEMBERSHIP_REPORT:
1222 cp = "Group Membership Report";
1224 case ICMP6_MEMBERSHIP_REDUCTION:
1225 cp = "Group Membership Reduction";
1227 case ND_ROUTER_SOLICIT:
1228 cp = "Router Solicitation";
1230 case ND_ROUTER_ADVERT:
1231 cp = "Router Advertisement";
1233 case ND_NEIGHBOR_SOLICIT:
1234 cp = "Neighbor Solicitation";
1236 case ND_NEIGHBOR_ADVERT:
1237 cp = "Neighbor Advertisement";
1250 packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code)
1252 struct icmp6_hdr *icp;
1253 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1254 char *buf = (char *)mhdr->msg_iov[0].iov_base;
1257 char hbuf[NI_MAXHOST];
1265 ip = (struct ip6_hdr *) buf;
1266 hlen = sizeof(struct ip6_hdr);
1267 if (cc < hlen + sizeof(struct icmp6_hdr)) {
1269 if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1270 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1271 strlcpy(hbuf, "invalid", sizeof(hbuf));
1272 printf("packet too short (%d bytes) from %s\n", cc,
1278 icp = (struct icmp6_hdr *)(buf + hlen);
1280 if (cc < (int)sizeof(struct icmp6_hdr)) {
1282 if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1283 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1284 strlcpy(hbuf, "invalid", sizeof(hbuf));
1285 printf("data too short (%d bytes) from %s\n", cc, hbuf);
1289 icp = (struct icmp6_hdr *)buf;
1291 /* get optional information via advanced API */
1294 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1295 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1296 if (cm->cmsg_level == IPPROTO_IPV6 &&
1297 cm->cmsg_type == IPV6_PKTINFO &&
1299 CMSG_LEN(sizeof(struct in6_pktinfo)))
1300 rcvpktinfo = (struct in6_pktinfo *)(CMSG_DATA(cm));
1302 if (cm->cmsg_level == IPPROTO_IPV6 &&
1303 cm->cmsg_type == IPV6_HOPLIMIT &&
1304 cm->cmsg_len == CMSG_LEN(sizeof(int)))
1305 hlimp = (int *)CMSG_DATA(cm);
1307 if (rcvpktinfo == NULL || hlimp == NULL) {
1308 warnx("failed to get received hop limit or packet info");
1312 rcvhlim = 0; /*XXX*/
1318 *type = icp->icmp6_type;
1319 *code = icp->icmp6_code;
1320 if ((*type == ICMP6_TIME_EXCEEDED &&
1321 *code == ICMP6_TIME_EXCEED_TRANSIT) ||
1322 (*type == ICMP6_DST_UNREACH) ||
1323 (*type == ICMP6_PARAM_PROB &&
1324 *code == ICMP6_PARAMPROB_NEXTHEADER)) {
1325 struct ip6_hdr *hip;
1326 struct icmp6_hdr *icmp;
1327 struct sctp_init_chunk *init;
1328 struct sctphdr *sctp;
1333 hip = (struct ip6_hdr *)(icp + 1);
1334 if ((up = get_uphdr(hip, (u_char *)(buf + cc))) == NULL) {
1336 warnx("failed to get upper layer header");
1340 case IPPROTO_ICMPV6:
1341 icmp = (struct icmp6_hdr *)up;
1342 if (icmp->icmp6_id == ident &&
1343 icmp->icmp6_seq == htons(seq))
1347 udp = (struct udphdr *)up;
1348 if (udp->uh_sport == htons(srcport) &&
1349 udp->uh_dport == htons(port + seq))
1353 sctp = (struct sctphdr *)up;
1354 if (sctp->src_port != htons(ident) ||
1355 sctp->dest_port != htons(port + seq)) {
1358 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1359 sizeof(struct sctp_init_chunk))) {
1360 if (sctp->v_tag != 0) {
1363 init = (struct sctp_init_chunk *)(sctp + 1);
1364 /* Check the initiate tag, if available. */
1365 if ((char *)&init->init.a_rwnd > buf + cc) {
1368 if (init->init.initiate_tag == (u_int32_t)
1369 ((sctp->src_port << 16) | sctp->dest_port)) {
1374 (u_int32_t)((sctp->src_port << 16) |
1381 tcp = (struct tcphdr *)up;
1382 if (tcp->th_sport == htons(ident) &&
1383 tcp->th_dport == htons(port + seq) &&
1385 (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport))
1391 fprintf(stderr, "Unknown probe proto %d.\n", useproto);
1394 } else if (useproto == IPPROTO_ICMPV6 && *type == ICMP6_ECHO_REPLY) {
1395 if (icp->icmp6_id == ident &&
1396 icp->icmp6_seq == htons(seq))
1400 char sbuf[NI_MAXHOST+1], dbuf[INET6_ADDRSTRLEN];
1404 if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1405 sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0)
1406 strlcpy(sbuf, "invalid", sizeof(sbuf));
1407 printf("\n%d bytes from %s to %s", cc, sbuf,
1408 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1409 dbuf, sizeof(dbuf)) : "?");
1410 printf(": icmp type %d (%s) code %d\n", *type, pr_type(*type),
1412 p = (u_int8_t *)(icp + 1);
1414 for (i = 0; i < cc; i++) {
1419 printf("%02x", p[i]);
1420 if (i % WIDTH == WIDTH - 1)
1423 if (cc % WIDTH != 0)
1430 * Increment pointer until find the UDP or ICMP header.
1433 get_uphdr(struct ip6_hdr *ip6, u_char *lim)
1435 u_char *cp = (u_char *)ip6, nh;
1437 static u_char none_hdr[1]; /* Fake pointer for IPPROTO_NONE. */
1439 if (cp + sizeof(*ip6) > lim)
1443 cp += sizeof(struct ip6_hdr);
1445 while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) {
1449 case IPPROTO_ICMPV6:
1450 return (useproto == nh ? cp : NULL);
1454 return (useproto == nh ? cp : NULL);
1456 return (useproto == nh ? none_hdr : NULL);
1457 case IPPROTO_FRAGMENT:
1458 hlen = sizeof(struct ip6_frag);
1459 nh = ((struct ip6_frag *)cp)->ip6f_nxt;
1462 hlen = (((struct ip6_ext *)cp)->ip6e_len + 2) << 2;
1463 nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1466 hlen = (((struct ip6_ext *)cp)->ip6e_len + 1) << 3;
1467 nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1478 print(struct msghdr *mhdr, int cc)
1480 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1481 char hbuf[NI_MAXHOST];
1483 if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1484 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1485 strlcpy(hbuf, "invalid", sizeof(hbuf));
1487 printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6));
1489 printf(" %s", hbuf);
1491 printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf);
1493 printf(" %s", inetname((struct sockaddr *)from));
1497 printf(" %d bytes to %s", cc,
1498 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1499 hbuf, sizeof(hbuf)) : "?");
1501 printf(" %d bytes of data to %s", cc,
1502 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1503 hbuf, sizeof(hbuf)) : "?");
1509 * Construct an Internet address representation.
1510 * If the nflag has been supplied, give
1511 * numeric value, otherwise try for symbolic name.
1514 inetname(struct sockaddr *sa)
1516 static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1];
1517 static int first = 1;
1520 if (first && !nflag) {
1522 if (gethostname(domain, sizeof(domain)) == 0 &&
1523 (cp = strchr(domain, '.')))
1524 (void) strlcpy(domain, cp + 1, sizeof(domain));
1530 if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1531 NI_NAMEREQD) == 0) {
1532 if ((cp = strchr(line, '.')) &&
1533 !strcmp(cp + 1, domain))
1541 if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1542 NI_NUMERICHOST) != 0)
1543 strlcpy(line, "invalid", sizeof(line));
1548 * CRC32C routine for the Stream Control Transmission Protocol
1551 #define CRC32C(c, d) (c = (c>>8) ^ crc_c[(c^(d))&0xFF])
1553 static u_int32_t crc_c[256] = {
1554 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
1555 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
1556 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
1557 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
1558 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
1559 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
1560 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
1561 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
1562 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
1563 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
1564 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
1565 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
1566 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
1567 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
1568 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
1569 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
1570 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
1571 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
1572 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
1573 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
1574 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
1575 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
1576 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
1577 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
1578 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
1579 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
1580 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
1581 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
1582 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
1583 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
1584 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
1585 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
1586 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
1587 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
1588 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
1589 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
1590 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
1591 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
1592 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
1593 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
1594 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
1595 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
1596 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
1597 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
1598 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
1599 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
1600 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
1601 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
1602 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
1603 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
1604 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
1605 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
1606 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
1607 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
1608 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
1609 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
1610 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
1611 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
1612 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
1613 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
1614 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
1615 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
1616 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
1617 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
1621 sctp_crc32c(void *pack, u_int32_t len)
1623 u_int32_t i, crc32c;
1624 u_int8_t byte0, byte1, byte2, byte3;
1625 u_int8_t *buf = (u_int8_t *)pack;
1628 for (i = 0; i < len; i++)
1629 CRC32C(crc32c, buf[i]);
1631 byte0 = crc32c & 0xff;
1632 byte1 = (crc32c>>8) & 0xff;
1633 byte2 = (crc32c>>16) & 0xff;
1634 byte3 = (crc32c>>24) & 0xff;
1635 crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
1636 return htonl(crc32c);
1640 in_cksum(u_int16_t *addr, int len)
1643 u_int16_t *w = addr;
1648 * Our algorithm is simple, using a 32 bit accumulator (sum),
1649 * we add sequential 16 bit words to it, and at the end, fold
1650 * back all the carry bits from the top 16 bits into the lower
1658 /* mop up an odd byte, if necessary */
1660 sum += *(u_char *)w;
1663 * add back carry outs from top 16 bits to low 16 bits
1665 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
1666 sum += (sum >> 16); /* add carry */
1667 answer = ~sum; /* truncate to 16 bits */
1672 tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1673 void *payload, u_int32_t len)
1676 struct in6_addr src;
1677 struct in6_addr dst;
1684 pseudo_hdr.src = src->sin6_addr;
1685 pseudo_hdr.dst = dst->sin6_addr;
1686 pseudo_hdr.len = htonl(len);
1687 pseudo_hdr.zero[0] = 0;
1688 pseudo_hdr.zero[1] = 0;
1689 pseudo_hdr.zero[2] = 0;
1690 pseudo_hdr.next = IPPROTO_TCP;
1692 sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1693 sum[0] = in_cksum(payload, len);
1695 return (~in_cksum(sum, sizeof(sum)));
1703 "usage: traceroute6 [-adIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n"
1704 " [-m hoplimit] [-p port] [-q probes] [-s src] [-w waittime] target\n"