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 #ifdef USE_RFC2292BIS
335 struct ip6_rthdr *rth;
337 struct cmsghdr *cmsg;
343 u_long first_hop = 1;
344 u_long max_hops = 30;
346 u_int16_t port = 32768+666; /* start udp dest port # for probe packets */
348 int options; /* socket options */
350 int waittime = 5; /* time to wait for response (in seconds) */
351 int nflag; /* print addresses numerically */
352 int useproto = IPPROTO_UDP; /* protocol to use to send packet */
353 int lflag; /* print both numerical address & hostname */
354 int as_path; /* print as numbers for each hop */
355 char *as_server = NULL;
359 main(int argc, char *argv[])
361 int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM };
362 char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep;
363 int ch, i, on = 1, seq, rcvcmsglen, error;
364 struct addrinfo hints, *res;
365 static u_char *rcvcmsgbuf;
366 u_long probe, hops, lport;
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);
438 #ifdef USE_RFC2292BIS
441 * XXX: We can't detect the number of
442 * intermediate nodes yet.
444 if ((rth = inet6_rth_init((void *)rtbuf,
445 sizeof(rtbuf), IPV6_RTHDR_TYPE_0,
448 "inet6_rth_init failed.\n");
452 if (inet6_rth_add((void *)rth,
453 (struct in6_addr *)hp->h_addr)) {
455 "inet6_rth_add failed for %s\n",
459 #else /* old advanced API */
461 cmsg = inet6_rthdr_init(rtbuf, IPV6_RTHDR_TYPE_0);
462 inet6_rthdr_add(cmsg, (struct in6_addr *)hp->h_addr,
468 useproto = IPPROTO_ICMPV6;
476 max_hops = strtoul(optarg, &ep, 0);
477 if (errno || !*optarg || *ep || max_hops > 255) {
479 "traceroute6: invalid max hoplimit.\n");
487 useproto = IPPROTO_NONE;
492 lport = strtoul(optarg, &ep, 0);
493 if (errno || !*optarg || *ep) {
494 fprintf(stderr, "traceroute6: invalid port.\n");
497 if (lport == 0 || lport != (lport & 0xffff)) {
499 "traceroute6: port out of range.\n");
502 port = lport & 0xffff;
507 nprobes = strtoul(optarg, &ep, 0);
508 if (errno || !*optarg || *ep) {
510 "traceroute6: invalid nprobes.\n");
515 "traceroute6: nprobes must be >0.\n");
520 options |= SO_DONTROUTE;
524 * set the ip source address of the outbound
525 * probe (e.g., on a multi-homed host).
530 useproto = IPPROTO_SCTP;
533 useproto = IPPROTO_TCP;
536 useproto = IPPROTO_UDP;
544 waittime = strtoul(optarg, &ep, 0);
545 if (errno || !*optarg || *ep) {
547 "traceroute6: invalid wait time.\n");
552 "traceroute6: wait must be >= 1 sec.\n");
563 * Open socket to send probe packets.
570 if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
571 perror("socket(SOCK_DGRAM)");
578 if ((sndsock = socket(AF_INET6, SOCK_RAW, useproto)) < 0) {
579 perror("socket(SOCK_RAW)");
584 fprintf(stderr, "traceroute6: unknown probe protocol %d\n",
588 if (max_hops < first_hop) {
590 "traceroute6: max hoplimit must be larger than first hoplimit.\n");
596 if (setresuid(uid, uid, uid) == -1) {
602 if (argc < 1 || argc > 2)
606 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
611 memset(&hints, 0, sizeof(hints));
612 hints.ai_family = PF_INET6;
613 hints.ai_socktype = SOCK_RAW;
614 hints.ai_protocol = IPPROTO_ICMPV6;
615 hints.ai_flags = AI_CANONNAME;
616 error = getaddrinfo(*argv, NULL, &hints, &res);
619 "traceroute6: %s\n", gai_strerror(error));
622 if (res->ai_addrlen != sizeof(Dst)) {
624 "traceroute6: size of sockaddr mismatch\n");
627 memcpy(&Dst, res->ai_addr, res->ai_addrlen);
628 hostname = res->ai_canonname ? strdup(res->ai_canonname) : *argv;
630 fprintf(stderr, "traceroute6: not enough core\n");
634 if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf,
635 sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
636 strlcpy(hbuf, "?", sizeof(hbuf));
637 fprintf(stderr, "traceroute6: Warning: %s has multiple "
638 "addresses; using %s\n", hostname, hbuf);
644 datalen = strtoul(*argv, &ep, 0);
647 "traceroute6: invalid packet length.\n");
653 minlen = ICMP6ECHOLEN;
656 minlen = sizeof(struct udphdr);
663 minlen = sizeof(struct sctphdr);
666 minlen = sizeof(struct tcphdr);
669 fprintf(stderr, "traceroute6: unknown probe protocol %d.\n",
673 if (datalen < minlen)
675 else if (datalen >= MAXPACKET) {
677 "traceroute6: packet size must be %zu <= s < %d.\n",
681 if (useproto == IPPROTO_UDP)
682 datalen -= sizeof(struct udphdr);
683 if ((useproto == IPPROTO_SCTP) && (datalen & 3)) {
685 "traceroute6: packet size must be a multiple of 4.\n");
688 outpacket = malloc(datalen);
693 (void) bzero((char *)outpacket, datalen);
695 /* initialize msghdr for receiving packets */
696 rcviov[0].iov_base = (caddr_t)packet;
697 rcviov[0].iov_len = sizeof(packet);
698 rcvmhdr.msg_name = (caddr_t)&Rcv;
699 rcvmhdr.msg_namelen = sizeof(Rcv);
700 rcvmhdr.msg_iov = rcviov;
701 rcvmhdr.msg_iovlen = 1;
702 rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
703 CMSG_SPACE(sizeof(int));
704 if ((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) {
705 fprintf(stderr, "traceroute6: malloc failed\n");
708 rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf;
709 rcvmhdr.msg_controllen = rcvcmsglen;
711 if (options & SO_DEBUG)
712 (void) setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG,
713 (char *)&on, sizeof(on));
714 if (options & SO_DONTROUTE)
715 (void) setsockopt(rcvsock, SOL_SOCKET, SO_DONTROUTE,
716 (char *)&on, sizeof(on));
718 #ifdef IPSEC_POLICY_IPSEC
720 * do not raise error even if setsockopt fails, kernel may have ipsec
723 if (setpolicy(rcvsock, "in bypass") < 0)
724 errx(1, "%s", ipsec_strerror());
725 if (setpolicy(rcvsock, "out bypass") < 0)
726 errx(1, "%s", ipsec_strerror());
729 int level = IPSEC_LEVEL_NONE;
731 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
733 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
735 #ifdef IP_AUTH_TRANS_LEVEL
736 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
739 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
742 #ifdef IP_AUTH_NETWORK_LEVEL
743 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
747 #endif /*IPSEC_POLICY_IPSEC*/
754 if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&i,
756 perror("setsockopt(SO_SNDBUF)");
759 #endif /* SO_SNDBUF */
760 if (options & SO_DEBUG)
761 (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
762 (char *)&on, sizeof(on));
763 if (options & SO_DONTROUTE)
764 (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
765 (char *)&on, sizeof(on));
766 #ifdef USE_RFC2292BIS
767 if (rth) {/* XXX: there is no library to finalize the header... */
768 rth->ip6r_len = rth->ip6r_segleft * 2;
769 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_RTHDR,
770 (void *)rth, (rth->ip6r_len + 1) << 3)) {
771 fprintf(stderr, "setsockopt(IPV6_RTHDR): %s\n",
776 #else /* old advanced API */
778 inet6_rthdr_lasthop(cmsg, IPV6_RTHDR_LOOSE);
779 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_PKTOPTIONS,
780 rtbuf, cmsg->cmsg_len) < 0) {
781 fprintf(stderr, "setsockopt(IPV6_PKTOPTIONS): %s\n",
786 #endif /* USE_RFC2292BIS */
788 #ifdef IPSEC_POLICY_IPSEC
790 * do not raise error even if setsockopt fails, kernel may have ipsec
793 if (setpolicy(sndsock, "in bypass") < 0)
794 errx(1, "%s", ipsec_strerror());
795 if (setpolicy(sndsock, "out bypass") < 0)
796 errx(1, "%s", ipsec_strerror());
799 int level = IPSEC_LEVEL_BYPASS;
801 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
803 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
805 #ifdef IP_AUTH_TRANS_LEVEL
806 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
809 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
812 #ifdef IP_AUTH_NETWORK_LEVEL
813 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
817 #endif /*IPSEC_POLICY_IPSEC*/
823 bzero(&Src, sizeof(Src));
825 struct addrinfo hints, *res;
828 memset(&hints, 0, sizeof(hints));
829 hints.ai_family = AF_INET6;
830 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
831 hints.ai_flags = AI_NUMERICHOST;
832 error = getaddrinfo(source, "0", &hints, &res);
834 printf("traceroute6: %s: %s\n", source,
835 gai_strerror(error));
838 if (res->ai_addrlen > sizeof(Src)) {
839 printf("traceroute6: %s: %s\n", source,
840 gai_strerror(error));
843 memcpy(&Src, res->ai_addr, res->ai_addrlen);
846 struct sockaddr_in6 Nxt;
851 Nxt.sin6_port = htons(DUMMY_PORT);
853 bcopy(inet6_rthdr_getaddr(cmsg, 1), &Nxt.sin6_addr,
854 sizeof(Nxt.sin6_addr));
855 if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
859 if (connect(dummy, (struct sockaddr *)&Nxt, Nxt.sin6_len) < 0) {
864 if (getsockname(dummy, (struct sockaddr *)&Src, &len) < 0) {
865 perror("getsockname");
868 if (getnameinfo((struct sockaddr *)&Src, Src.sin6_len,
869 src0, sizeof(src0), NULL, 0, NI_NUMERICHOST)) {
870 fprintf(stderr, "getnameinfo failed for source\n");
877 Src.sin6_port = htons(0);
878 if (bind(sndsock, (struct sockaddr *)&Src, Src.sin6_len) < 0) {
887 if (getsockname(sndsock, (struct sockaddr *)&Src, &len) < 0) {
888 perror("getsockname");
891 srcport = ntohs(Src.sin6_port);
895 asn = as_setup(as_server);
898 "traceroute6: as_setup failed, AS# lookups"
900 (void)fflush(stderr);
908 if (getnameinfo((struct sockaddr *)&Dst, Dst.sin6_len, hbuf,
909 sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
910 strlcpy(hbuf, "(invalid)", sizeof(hbuf));
911 fprintf(stderr, "traceroute6");
912 fprintf(stderr, " to %s (%s)", hostname, hbuf);
914 fprintf(stderr, " from %s", source);
915 fprintf(stderr, ", %lu hops max, %lu byte packets\n",
917 datalen + ((useproto == IPPROTO_UDP) ? sizeof(struct udphdr) : 0));
918 (void) fflush(stderr);
921 printf("Skipping %lu intermediate hops\n", first_hop - 1);
926 for (hops = first_hop; hops <= max_hops; ++hops) {
927 struct in6_addr lastaddr;
929 unsigned unreachable = 0;
931 printf("%2lu ", hops);
932 bzero(&lastaddr, sizeof(lastaddr));
933 for (probe = 0; probe < nprobes; ++probe) {
935 struct timeval t1, t2;
937 (void) gettimeofday(&t1, NULL);
938 send_probe(++seq, hops);
939 while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) {
940 (void) gettimeofday(&t2, NULL);
941 if (packet_ok(&rcvmhdr, cc, seq, &type, &code)) {
942 if (!IN6_ARE_ADDR_EQUAL(&Rcv.sin6_addr,
945 fputs("\n ", stdout);
947 lastaddr = Rcv.sin6_addr;
949 printf(" %.3f ms", deltaT(&t1, &t2));
950 if (type == ICMP6_DST_UNREACH) {
952 case ICMP6_DST_UNREACH_NOROUTE:
956 case ICMP6_DST_UNREACH_ADMIN:
960 case ICMP6_DST_UNREACH_NOTNEIGHBOR:
964 case ICMP6_DST_UNREACH_ADDR:
968 case ICMP6_DST_UNREACH_NOPORT:
975 } else if (type == ICMP6_PARAM_PROB &&
976 code == ICMP6_PARAMPROB_NEXTHEADER) {
979 } else if (type == ICMP6_ECHO_REPLY) {
986 } else if (deltaT(&t1, &t2) > waittime * 1000) {
993 (void) fflush(stdout);
997 (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) {
1008 wait_for_reply(int sock, struct msghdr *mhdr)
1011 struct pollfd pfd[1];
1015 pfd[0].events = POLLIN;
1018 if (poll(pfd, 1, waittime * 1000) > 0)
1019 cc = recvmsg(rcvsock, mhdr, 0);
1024 struct timeval wait;
1027 fdsn = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
1028 if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
1030 memset(fdsp, 0, fdsn);
1032 wait.tv_sec = waittime; wait.tv_usec = 0;
1034 if (select(sock+1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0)
1035 cc = recvmsg(rcvsock, mhdr, 0);
1043 #ifdef IPSEC_POLICY_IPSEC
1045 setpolicy(so, policy)
1051 buf = ipsec_set_policy(policy, strlen(policy));
1053 warnx("%s", ipsec_strerror());
1056 (void)setsockopt(so, IPPROTO_IPV6, IPV6_IPSEC_POLICY,
1057 buf, ipsec_get_policylen(buf));
1067 send_probe(int seq, u_long hops)
1069 struct icmp6_hdr *icp;
1070 struct sctphdr *sctp;
1071 struct sctp_chunkhdr *chk;
1072 struct sctp_init_chunk *init;
1073 struct sctp_paramhdr *param;
1078 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
1079 (char *)&i, sizeof(i)) < 0) {
1080 perror("setsockopt IPV6_UNICAST_HOPS");
1083 Dst.sin6_port = htons(port + seq);
1086 case IPPROTO_ICMPV6:
1087 icp = (struct icmp6_hdr *)outpacket;
1089 icp->icmp6_type = ICMP6_ECHO_REQUEST;
1090 icp->icmp6_code = 0;
1091 icp->icmp6_cksum = 0;
1092 icp->icmp6_id = ident;
1093 icp->icmp6_seq = htons(seq);
1098 /* No space for anything. No harm as seq/tv32 are decorative. */
1101 sctp = (struct sctphdr *)outpacket;
1103 sctp->src_port = htons(ident);
1104 sctp->dest_port = htons(port + seq);
1105 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1106 sizeof(struct sctp_init_chunk))) {
1109 sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port;
1111 sctp->checksum = htonl(0);
1112 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1113 sizeof(struct sctp_init_chunk))) {
1115 * Send a packet containing an INIT chunk. This works
1116 * better in case of firewalls on the path, but
1117 * results in a probe packet containing at least
1118 * 32 bytes of payload. For shorter payloads, use
1119 * SHUTDOWN-ACK chunks.
1121 init = (struct sctp_init_chunk *)(sctp + 1);
1122 init->ch.chunk_type = SCTP_INITIATION;
1123 init->ch.chunk_flags = 0;
1124 init->ch.chunk_length = htons((u_int16_t)(datalen -
1125 sizeof(struct sctphdr)));
1126 init->init.initiate_tag = (sctp->src_port << 16) |
1128 init->init.a_rwnd = htonl(1500);
1129 init->init.num_outbound_streams = htons(1);
1130 init->init.num_inbound_streams = htons(1);
1131 init->init.initial_tsn = htonl(0);
1132 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1133 sizeof(struct sctp_init_chunk) +
1134 sizeof(struct sctp_paramhdr))) {
1135 param = (struct sctp_paramhdr *)(init + 1);
1136 param->param_type = htons(SCTP_PAD);
1137 param->param_length =
1138 htons((u_int16_t)(datalen -
1139 sizeof(struct sctphdr) -
1140 sizeof(struct sctp_init_chunk)));
1144 * Send a packet containing a SHUTDOWN-ACK chunk,
1145 * possibly followed by a PAD chunk.
1147 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1148 sizeof(struct sctp_chunkhdr))) {
1149 chk = (struct sctp_chunkhdr *)(sctp + 1);
1150 chk->chunk_type = SCTP_SHUTDOWN_ACK;
1151 chk->chunk_flags = 0;
1152 chk->chunk_length = htons(4);
1154 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1155 2 * sizeof(struct sctp_chunkhdr))) {
1157 chk->chunk_type = SCTP_PAD_CHUNK;
1158 chk->chunk_flags = 0;
1159 chk->chunk_length = htons((u_int16_t)(datalen -
1160 sizeof(struct sctphdr) -
1161 sizeof(struct sctp_chunkhdr)));
1164 sctp->checksum = sctp_crc32c(outpacket, datalen);
1167 tcp = (struct tcphdr *)outpacket;
1169 tcp->th_sport = htons(ident);
1170 tcp->th_dport = htons(port + seq);
1171 tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
1174 tcp->th_flags = TH_SYN;
1176 tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen);
1179 fprintf(stderr, "Unknown probe protocol %d.\n", useproto);
1183 i = sendto(sndsock, (char *)outpacket, datalen, 0,
1184 (struct sockaddr *)&Dst, Dst.sin6_len);
1185 if (i < 0 || (u_long)i != datalen) {
1188 printf("traceroute6: wrote %s %lu chars, ret=%d\n",
1189 hostname, datalen, i);
1190 (void) fflush(stdout);
1195 get_hoplim(struct msghdr *mhdr)
1199 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1200 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1201 if (cm->cmsg_level == IPPROTO_IPV6 &&
1202 cm->cmsg_type == IPV6_HOPLIMIT &&
1203 cm->cmsg_len == CMSG_LEN(sizeof(int)))
1204 return (*(int *)CMSG_DATA(cm));
1211 deltaT(struct timeval *t1p, struct timeval *t2p)
1215 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1216 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1221 * Convert an ICMP "type" field to a printable string.
1226 u_char t = t0 & 0xff;
1230 case ICMP6_DST_UNREACH:
1231 cp = "Destination Unreachable";
1233 case ICMP6_PACKET_TOO_BIG:
1234 cp = "Packet Too Big";
1236 case ICMP6_TIME_EXCEEDED:
1237 cp = "Time Exceeded";
1239 case ICMP6_PARAM_PROB:
1240 cp = "Parameter Problem";
1242 case ICMP6_ECHO_REQUEST:
1243 cp = "Echo Request";
1245 case ICMP6_ECHO_REPLY:
1248 case ICMP6_MEMBERSHIP_QUERY:
1249 cp = "Group Membership Query";
1251 case ICMP6_MEMBERSHIP_REPORT:
1252 cp = "Group Membership Report";
1254 case ICMP6_MEMBERSHIP_REDUCTION:
1255 cp = "Group Membership Reduction";
1257 case ND_ROUTER_SOLICIT:
1258 cp = "Router Solicitation";
1260 case ND_ROUTER_ADVERT:
1261 cp = "Router Advertisement";
1263 case ND_NEIGHBOR_SOLICIT:
1264 cp = "Neighbor Solicitation";
1266 case ND_NEIGHBOR_ADVERT:
1267 cp = "Neighbor Advertisement";
1280 packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code)
1282 struct icmp6_hdr *icp;
1283 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1284 char *buf = (char *)mhdr->msg_iov[0].iov_base;
1287 char hbuf[NI_MAXHOST];
1295 ip = (struct ip6_hdr *) buf;
1296 hlen = sizeof(struct ip6_hdr);
1297 if (cc < hlen + sizeof(struct icmp6_hdr)) {
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("packet too short (%d bytes) from %s\n", cc,
1308 icp = (struct icmp6_hdr *)(buf + hlen);
1310 if (cc < (int)sizeof(struct icmp6_hdr)) {
1312 if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1313 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1314 strlcpy(hbuf, "invalid", sizeof(hbuf));
1315 printf("data too short (%d bytes) from %s\n", cc, hbuf);
1319 icp = (struct icmp6_hdr *)buf;
1321 /* get optional information via advanced API */
1324 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1325 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1326 if (cm->cmsg_level == IPPROTO_IPV6 &&
1327 cm->cmsg_type == IPV6_PKTINFO &&
1329 CMSG_LEN(sizeof(struct in6_pktinfo)))
1330 rcvpktinfo = (struct in6_pktinfo *)(CMSG_DATA(cm));
1332 if (cm->cmsg_level == IPPROTO_IPV6 &&
1333 cm->cmsg_type == IPV6_HOPLIMIT &&
1334 cm->cmsg_len == CMSG_LEN(sizeof(int)))
1335 hlimp = (int *)CMSG_DATA(cm);
1337 if (rcvpktinfo == NULL || hlimp == NULL) {
1338 warnx("failed to get received hop limit or packet info");
1342 rcvhlim = 0; /*XXX*/
1348 *type = icp->icmp6_type;
1349 *code = icp->icmp6_code;
1350 if ((*type == ICMP6_TIME_EXCEEDED &&
1351 *code == ICMP6_TIME_EXCEED_TRANSIT) ||
1352 (*type == ICMP6_DST_UNREACH) ||
1353 (*type == ICMP6_PARAM_PROB &&
1354 *code == ICMP6_PARAMPROB_NEXTHEADER)) {
1355 struct ip6_hdr *hip;
1356 struct icmp6_hdr *icmp;
1357 struct sctp_init_chunk *init;
1358 struct sctphdr *sctp;
1363 hip = (struct ip6_hdr *)(icp + 1);
1364 if ((up = get_uphdr(hip, (u_char *)(buf + cc))) == NULL) {
1366 warnx("failed to get upper layer header");
1370 case IPPROTO_ICMPV6:
1371 icmp = (struct icmp6_hdr *)up;
1372 if (icmp->icmp6_id == ident &&
1373 icmp->icmp6_seq == htons(seq))
1377 udp = (struct udphdr *)up;
1378 if (udp->uh_sport == htons(srcport) &&
1379 udp->uh_dport == htons(port + seq))
1383 sctp = (struct sctphdr *)up;
1384 if (sctp->src_port != htons(ident) ||
1385 sctp->dest_port != htons(port + seq)) {
1388 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1389 sizeof(struct sctp_init_chunk))) {
1390 if (sctp->v_tag != 0) {
1393 init = (struct sctp_init_chunk *)(sctp + 1);
1394 /* Check the initiate tag, if available. */
1395 if ((char *)&init->init.a_rwnd > buf + cc) {
1398 if (init->init.initiate_tag == (u_int32_t)
1399 ((sctp->src_port << 16) | sctp->dest_port)) {
1404 (u_int32_t)((sctp->src_port << 16) |
1411 tcp = (struct tcphdr *)up;
1412 if (tcp->th_sport == htons(ident) &&
1413 tcp->th_dport == htons(port + seq) &&
1415 (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport))
1421 fprintf(stderr, "Unknown probe proto %d.\n", useproto);
1424 } else if (useproto == IPPROTO_ICMPV6 && *type == ICMP6_ECHO_REPLY) {
1425 if (icp->icmp6_id == ident &&
1426 icp->icmp6_seq == htons(seq))
1430 char sbuf[NI_MAXHOST+1], dbuf[INET6_ADDRSTRLEN];
1434 if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1435 sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0)
1436 strlcpy(sbuf, "invalid", sizeof(sbuf));
1437 printf("\n%d bytes from %s to %s", cc, sbuf,
1438 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1439 dbuf, sizeof(dbuf)) : "?");
1440 printf(": icmp type %d (%s) code %d\n", *type, pr_type(*type),
1442 p = (u_int8_t *)(icp + 1);
1444 for (i = 0; i < cc; i++) {
1449 printf("%02x", p[i]);
1450 if (i % WIDTH == WIDTH - 1)
1453 if (cc % WIDTH != 0)
1460 * Increment pointer until find the UDP or ICMP header.
1463 get_uphdr(struct ip6_hdr *ip6, u_char *lim)
1465 u_char *cp = (u_char *)ip6, nh;
1467 static u_char none_hdr[1]; /* Fake pointer for IPPROTO_NONE. */
1469 if (cp + sizeof(*ip6) > lim)
1473 cp += sizeof(struct ip6_hdr);
1475 while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) {
1479 case IPPROTO_ICMPV6:
1480 return (useproto == nh ? cp : NULL);
1484 return (useproto == nh ? cp : NULL);
1486 return (useproto == nh ? none_hdr : NULL);
1487 case IPPROTO_FRAGMENT:
1488 hlen = sizeof(struct ip6_frag);
1489 nh = ((struct ip6_frag *)cp)->ip6f_nxt;
1492 hlen = (((struct ip6_ext *)cp)->ip6e_len + 2) << 2;
1493 nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1496 hlen = (((struct ip6_ext *)cp)->ip6e_len + 1) << 3;
1497 nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1508 print(struct msghdr *mhdr, int cc)
1510 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1511 char hbuf[NI_MAXHOST];
1513 if (getnameinfo((struct sockaddr *)from, from->sin6_len,
1514 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1515 strlcpy(hbuf, "invalid", sizeof(hbuf));
1517 printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6));
1519 printf(" %s", hbuf);
1521 printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf);
1523 printf(" %s", inetname((struct sockaddr *)from));
1527 printf(" %d bytes to %s", cc,
1528 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1529 hbuf, sizeof(hbuf)) : "?");
1531 printf(" %d bytes of data to %s", cc,
1532 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1533 hbuf, sizeof(hbuf)) : "?");
1539 * Construct an Internet address representation.
1540 * If the nflag has been supplied, give
1541 * numeric value, otherwise try for symbolic name.
1544 inetname(struct sockaddr *sa)
1546 static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1];
1547 static int first = 1;
1550 if (first && !nflag) {
1552 if (gethostname(domain, sizeof(domain)) == 0 &&
1553 (cp = strchr(domain, '.')))
1554 (void) strlcpy(domain, cp + 1, sizeof(domain));
1560 if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1561 NI_NAMEREQD) == 0) {
1562 if ((cp = strchr(line, '.')) &&
1563 !strcmp(cp + 1, domain))
1571 if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
1572 NI_NUMERICHOST) != 0)
1573 strlcpy(line, "invalid", sizeof(line));
1578 * CRC32C routine for the Stream Control Transmission Protocol
1581 #define CRC32C(c, d) (c = (c>>8) ^ crc_c[(c^(d))&0xFF])
1583 static u_int32_t crc_c[256] = {
1584 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
1585 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
1586 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
1587 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
1588 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
1589 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
1590 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
1591 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
1592 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
1593 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
1594 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
1595 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
1596 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
1597 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
1598 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
1599 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
1600 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
1601 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
1602 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
1603 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
1604 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
1605 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
1606 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
1607 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
1608 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
1609 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
1610 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
1611 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
1612 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
1613 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
1614 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
1615 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
1616 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
1617 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
1618 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
1619 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
1620 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
1621 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
1622 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
1623 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
1624 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
1625 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
1626 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
1627 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
1628 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
1629 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
1630 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
1631 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
1632 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
1633 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
1634 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
1635 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
1636 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
1637 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
1638 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
1639 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
1640 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
1641 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
1642 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
1643 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
1644 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
1645 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
1646 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
1647 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
1651 sctp_crc32c(void *packet, u_int32_t len)
1653 u_int32_t i, crc32c;
1654 u_int8_t byte0, byte1, byte2, byte3;
1655 u_int8_t *buf = (u_int8_t *)packet;
1658 for (i = 0; i < len; i++)
1659 CRC32C(crc32c, buf[i]);
1661 byte0 = crc32c & 0xff;
1662 byte1 = (crc32c>>8) & 0xff;
1663 byte2 = (crc32c>>16) & 0xff;
1664 byte3 = (crc32c>>24) & 0xff;
1665 crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
1666 return htonl(crc32c);
1670 in_cksum(u_int16_t *addr, int len)
1673 u_int16_t *w = addr;
1678 * Our algorithm is simple, using a 32 bit accumulator (sum),
1679 * we add sequential 16 bit words to it, and at the end, fold
1680 * back all the carry bits from the top 16 bits into the lower
1688 /* mop up an odd byte, if necessary */
1690 sum += *(u_char *)w;
1693 * add back carry outs from top 16 bits to low 16 bits
1695 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
1696 sum += (sum >> 16); /* add carry */
1697 answer = ~sum; /* truncate to 16 bits */
1702 tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1703 void *payload, u_int32_t len)
1706 struct in6_addr src;
1707 struct in6_addr dst;
1714 pseudo_hdr.src = src->sin6_addr;
1715 pseudo_hdr.dst = dst->sin6_addr;
1716 pseudo_hdr.len = htonl(len);
1717 pseudo_hdr.zero[0] = 0;
1718 pseudo_hdr.zero[1] = 0;
1719 pseudo_hdr.zero[2] = 0;
1720 pseudo_hdr.next = IPPROTO_TCP;
1722 sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1723 sum[0] = in_cksum(payload, len);
1725 return (~in_cksum(sum, sizeof(sum)));
1733 "usage: traceroute6 [-adIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n"
1734 " [-m hoplimit] [-p port] [-q probes] [-s src] [-w waittime] target\n"