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/capsicum.h>
253 #include <sys/time.h>
254 #include <sys/socket.h>
256 #include <sys/file.h>
257 #include <sys/ioctl.h>
258 #include <sys/sysctl.h>
260 #include <netinet/in.h>
262 #include <arpa/inet.h>
264 #include <libcasper.h>
265 #include <casper/cap_dns.h>
266 #include <capsicum_helpers.h>
279 #include <netinet/ip6.h>
280 #include <netinet/icmp6.h>
281 #include <netinet/sctp.h>
282 #include <netinet/sctp_header.h>
283 #include <netinet/tcp.h>
284 #include <netinet/udp.h>
287 #include <net/route.h>
288 #include <netipsec/ipsec.h>
293 #define DUMMY_PORT 10010
295 #define MAXPACKET 65535 /* max ip packet size */
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 void capdns_open(void);
308 int get_hoplim(struct msghdr *);
309 double deltaT(struct timeval *, struct timeval *);
310 const char *pr_type(int);
311 int packet_ok(struct msghdr *, int, int, u_char *, u_char *);
312 void print(struct msghdr *, int);
313 const char *inetname(struct sockaddr *);
314 u_int32_t sctp_crc32c(void *, u_int32_t);
315 u_int16_t in_cksum(u_int16_t *addr, int);
316 u_int16_t udp_cksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
318 u_int16_t tcp_chksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
322 static int rcvsock; /* receive (icmp) socket file descriptor */
323 static int sndsock; /* send (raw/udp) socket file descriptor */
325 static struct msghdr rcvmhdr;
326 static struct iovec rcviov[2];
328 static struct in6_pktinfo *rcvpktinfo;
330 static struct sockaddr_in6 Src, Dst, Rcv;
331 static u_long datalen = 20; /* How much data */
332 #define ICMP6ECHOLEN 8
333 /* XXX: 2064 = 127(max hops in type 0 rthdr) * sizeof(ip6_hdr) + 16(margin) */
334 static char rtbuf[2064];
335 static struct ip6_rthdr *rth;
336 static struct cmsghdr *cmsg;
338 static char *source = NULL;
339 static char *hostname;
341 static cap_channel_t *capdns;
343 static u_long nprobes = 3;
344 static u_long first_hop = 1;
345 static u_long max_hops = 30;
346 static u_int16_t srcport;
347 static u_int16_t port = 32768+666; /* start udp dest port # for probe packets */
348 static u_int16_t ident;
349 static int options; /* socket options */
351 static int waittime = 5; /* time to wait for response (in seconds) */
352 static int nflag; /* print addresses numerically */
353 static int useproto = IPPROTO_UDP; /* protocol to use to send packet */
354 static int lflag; /* print both numerical address & hostname */
355 static int as_path; /* print as numbers for each hop */
356 static char *as_server = NULL;
360 main(int argc, char *argv[])
362 int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM };
363 char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep;
364 int ch, i, on = 1, seq, rcvcmsglen, error;
365 struct addrinfo hints, *res;
366 static u_char *rcvcmsgbuf;
367 u_long probe, hops, lport;
372 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
373 char ipsec_inpolicy[] = "in bypass";
374 char ipsec_outpolicy[] = "out bypass";
383 if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
384 perror("socket(ICMPv6)");
389 (void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &i, &size, NULL, 0);
392 /* specify to tell receiving interface */
393 #ifdef IPV6_RECVPKTINFO
394 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
396 err(1, "setsockopt(IPV6_RECVPKTINFO)");
397 #else /* old adv. API */
398 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_PKTINFO, &on,
400 err(1, "setsockopt(IPV6_PKTINFO)");
403 /* specify to tell value of hoplimit field of received IP6 hdr */
404 #ifdef IPV6_RECVHOPLIMIT
405 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
407 err(1, "setsockopt(IPV6_RECVHOPLIMIT)");
408 #else /* old adv. API */
409 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on,
411 err(1, "setsockopt(IPV6_HOPLIMIT)");
415 ident = htons(getpid() & 0xffff); /* same as ping6 */
417 while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:STUvw:")) != -1)
432 first_hop = strtoul(optarg, &ep, 0);
433 if (errno || !*optarg || *ep || first_hop > 255) {
435 "traceroute6: invalid min hoplimit.\n");
440 /* XXX use after capability mode is entered */
441 hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno);
444 "traceroute6: unknown host %s\n", optarg);
449 * XXX: We can't detect the number of
450 * intermediate nodes yet.
452 if ((rth = inet6_rth_init((void *)rtbuf,
453 sizeof(rtbuf), IPV6_RTHDR_TYPE_0,
456 "inet6_rth_init failed.\n");
460 if (inet6_rth_add((void *)rth,
461 (struct in6_addr *)hp->h_addr)) {
463 "inet6_rth_add failed for %s\n",
470 useproto = IPPROTO_ICMPV6;
478 max_hops = strtoul(optarg, &ep, 0);
479 if (errno || !*optarg || *ep || max_hops > 255) {
481 "traceroute6: invalid max hoplimit.\n");
489 useproto = IPPROTO_NONE;
494 lport = strtoul(optarg, &ep, 0);
495 if (errno || !*optarg || *ep) {
496 fprintf(stderr, "traceroute6: invalid port.\n");
499 if (lport == 0 || lport != (lport & 0xffff)) {
501 "traceroute6: port out of range.\n");
504 port = lport & 0xffff;
509 nprobes = strtoul(optarg, &ep, 0);
510 if (errno || !*optarg || *ep) {
512 "traceroute6: invalid nprobes.\n");
517 "traceroute6: nprobes must be >0.\n");
522 options |= SO_DONTROUTE;
526 * set the ip source address of the outbound
527 * probe (e.g., on a multi-homed host).
532 useproto = IPPROTO_SCTP;
535 useproto = IPPROTO_TCP;
538 useproto = IPPROTO_UDP;
546 waittime = strtoul(optarg, &ep, 0);
547 if (errno || !*optarg || *ep) {
549 "traceroute6: invalid wait time.\n");
554 "traceroute6: wait must be >= 1 sec.\n");
565 * Open socket to send probe packets.
572 if ((sndsock = socket(AF_INET6, SOCK_RAW, IPPROTO_UDP)) < 0) {
573 perror("socket(SOCK_RAW)");
580 if ((sndsock = socket(AF_INET6, SOCK_RAW, useproto)) < 0) {
581 perror("socket(SOCK_RAW)");
586 fprintf(stderr, "traceroute6: unknown probe protocol %d\n",
590 if (max_hops < first_hop) {
592 "traceroute6: max hoplimit must be larger than first hoplimit.\n");
598 if (setresuid(uid, uid, uid) == -1) {
604 if (argc < 1 || argc > 2)
608 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
613 memset(&hints, 0, sizeof(hints));
614 hints.ai_family = PF_INET6;
615 hints.ai_socktype = SOCK_RAW;
616 hints.ai_protocol = IPPROTO_ICMPV6;
617 hints.ai_flags = AI_CANONNAME;
619 error = cap_getaddrinfo(capdns, *argv, NULL, &hints, &res);
623 "traceroute6: %s\n", gai_strerror(error));
626 if (res->ai_addrlen != sizeof(Dst)) {
628 "traceroute6: size of sockaddr mismatch\n");
631 memcpy(&Dst, res->ai_addr, res->ai_addrlen);
632 hostname = res->ai_canonname ? strdup(res->ai_canonname) : *argv;
634 fprintf(stderr, "traceroute6: not enough core\n");
638 if (cap_getnameinfo(capdns, res->ai_addr, res->ai_addrlen, hbuf,
639 sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
640 strlcpy(hbuf, "?", sizeof(hbuf));
641 fprintf(stderr, "traceroute6: Warning: %s has multiple "
642 "addresses; using %s\n", hostname, hbuf);
648 datalen = strtoul(*argv, &ep, 0);
651 "traceroute6: invalid packet length.\n");
657 minlen = ICMP6ECHOLEN;
660 minlen = sizeof(struct udphdr);
667 minlen = sizeof(struct sctphdr);
670 minlen = sizeof(struct tcphdr);
673 fprintf(stderr, "traceroute6: unknown probe protocol %d.\n",
677 if (datalen < minlen)
679 else if (datalen >= MAXPACKET) {
681 "traceroute6: packet size must be %zu <= s < %d.\n",
685 if (useproto == IPPROTO_UDP)
686 datalen -= sizeof(struct udphdr);
687 if ((useproto == IPPROTO_SCTP) && (datalen & 3)) {
689 "traceroute6: packet size must be a multiple of 4.\n");
692 outpacket = malloc(datalen);
697 (void) bzero((char *)outpacket, datalen);
699 /* initialize msghdr for receiving packets */
700 rcviov[0].iov_base = (caddr_t)packet;
701 rcviov[0].iov_len = sizeof(packet);
702 rcvmhdr.msg_name = (caddr_t)&Rcv;
703 rcvmhdr.msg_namelen = sizeof(Rcv);
704 rcvmhdr.msg_iov = rcviov;
705 rcvmhdr.msg_iovlen = 1;
706 rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
707 CMSG_SPACE(sizeof(int));
708 if ((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) {
709 fprintf(stderr, "traceroute6: malloc failed\n");
712 rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf;
713 rcvmhdr.msg_controllen = rcvcmsglen;
715 if (options & SO_DEBUG)
716 (void) setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG,
717 (char *)&on, sizeof(on));
718 if (options & SO_DONTROUTE)
719 (void) setsockopt(rcvsock, SOL_SOCKET, SO_DONTROUTE,
720 (char *)&on, sizeof(on));
721 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
723 * do not raise error even if setsockopt fails, kernel may have ipsec
726 if (setpolicy(rcvsock, ipsec_inpolicy) < 0)
727 errx(1, "%s", ipsec_strerror());
728 if (setpolicy(rcvsock, ipsec_outpolicy) < 0)
729 errx(1, "%s", ipsec_strerror());
732 int level = IPSEC_LEVEL_NONE;
734 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
736 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
738 #ifdef IP_AUTH_TRANS_LEVEL
739 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
742 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
745 #ifdef IP_AUTH_NETWORK_LEVEL
746 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
750 #endif /* !(IPSEC && IPSEC_POLICY_IPSEC) */
756 if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&i,
758 perror("setsockopt(SO_SNDBUF)");
761 #endif /* SO_SNDBUF */
762 if (options & SO_DEBUG)
763 (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
764 (char *)&on, sizeof(on));
765 if (options & SO_DONTROUTE)
766 (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
767 (char *)&on, sizeof(on));
768 if (rth) {/* XXX: there is no library to finalize the header... */
769 rth->ip6r_len = rth->ip6r_segleft * 2;
770 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_RTHDR,
771 (void *)rth, (rth->ip6r_len + 1) << 3)) {
772 fprintf(stderr, "setsockopt(IPV6_RTHDR): %s\n",
777 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
779 * do not raise error even if setsockopt fails, kernel may have ipsec
782 if (setpolicy(sndsock, ipsec_inpolicy) < 0)
783 errx(1, "%s", ipsec_strerror());
784 if (setpolicy(sndsock, ipsec_outpolicy) < 0)
785 errx(1, "%s", ipsec_strerror());
788 int level = IPSEC_LEVEL_BYPASS;
790 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
792 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
794 #ifdef IP_AUTH_TRANS_LEVEL
795 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
798 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
801 #ifdef IP_AUTH_NETWORK_LEVEL
802 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
806 #endif /* !(IPSEC && IPSEC_POLICY_IPSEC) */
811 bzero(&Src, sizeof(Src));
813 memset(&hints, 0, sizeof(hints));
814 hints.ai_family = AF_INET6;
815 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
816 hints.ai_flags = AI_NUMERICHOST;
817 error = cap_getaddrinfo(capdns, source, "0", &hints, &res);
819 printf("traceroute6: %s: %s\n", source,
820 gai_strerror(error));
823 if (res->ai_addrlen > sizeof(Src)) {
824 printf("traceroute6: %s: %s\n", source,
825 gai_strerror(error));
828 memcpy(&Src, res->ai_addr, res->ai_addrlen);
831 struct sockaddr_in6 Nxt;
836 Nxt.sin6_port = htons(DUMMY_PORT);
838 bcopy(inet6_rthdr_getaddr(cmsg, 1), &Nxt.sin6_addr,
839 sizeof(Nxt.sin6_addr));
840 if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
844 if (connect(dummy, (struct sockaddr *)&Nxt, Nxt.sin6_len) < 0) {
849 if (getsockname(dummy, (struct sockaddr *)&Src, &len) < 0) {
850 perror("getsockname");
853 if (cap_getnameinfo(capdns, (struct sockaddr *)&Src, Src.sin6_len,
854 src0, sizeof(src0), NULL, 0, NI_NUMERICHOST)) {
855 fprintf(stderr, "getnameinfo failed for source\n");
862 Src.sin6_port = htons(0);
863 if (bind(sndsock, (struct sockaddr *)&Src, Src.sin6_len) < 0) {
872 if (getsockname(sndsock, (struct sockaddr *)&Src, &len) < 0) {
873 perror("getsockname");
876 srcport = ntohs(Src.sin6_port);
880 asn = as_setup(as_server);
883 "traceroute6: as_setup failed, AS# lookups"
885 (void)fflush(stderr);
893 if (cap_getnameinfo(capdns, (struct sockaddr *)&Dst, Dst.sin6_len, hbuf,
894 sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
895 strlcpy(hbuf, "(invalid)", sizeof(hbuf));
896 fprintf(stderr, "traceroute6");
897 fprintf(stderr, " to %s (%s)", hostname, hbuf);
899 fprintf(stderr, " from %s", source);
900 fprintf(stderr, ", %lu hops max, %lu byte packets\n",
902 datalen + ((useproto == IPPROTO_UDP) ? sizeof(struct udphdr) : 0));
903 (void) fflush(stderr);
906 printf("Skipping %lu intermediate hops\n", first_hop - 1);
908 if (connect(sndsock, (struct sockaddr *)&Dst,
910 fprintf(stderr, "connect: %s\n", strerror(errno));
915 * Here we enter capability mode. Further down access to global
916 * namespaces (e.g filesystem) is restricted (see capsicum(4)).
917 * We must connect(2) our socket before this point.
920 if (caph_enter_casper() < 0) {
921 fprintf(stderr, "caph_enter_casper: %s\n", strerror(errno));
925 cap_rights_init(&rights, CAP_SEND, CAP_SETSOCKOPT);
926 if (caph_rights_limit(sndsock, &rights) < 0) {
927 fprintf(stderr, "caph_rights_limit sndsock: %s\n",
935 for (hops = first_hop; hops <= max_hops; ++hops) {
936 struct in6_addr lastaddr;
938 unsigned unreachable = 0;
940 printf("%2lu ", hops);
941 bzero(&lastaddr, sizeof(lastaddr));
942 for (probe = 0; probe < nprobes; ++probe) {
944 struct timeval t1, t2;
946 (void) gettimeofday(&t1, NULL);
947 send_probe(++seq, hops);
948 while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) {
949 (void) gettimeofday(&t2, NULL);
950 if (packet_ok(&rcvmhdr, cc, seq, &type, &code)) {
951 if (!IN6_ARE_ADDR_EQUAL(&Rcv.sin6_addr,
954 fputs("\n ", stdout);
956 lastaddr = Rcv.sin6_addr;
958 printf(" %.3f ms", deltaT(&t1, &t2));
959 if (type == ICMP6_DST_UNREACH) {
961 case ICMP6_DST_UNREACH_NOROUTE:
965 case ICMP6_DST_UNREACH_ADMIN:
969 case ICMP6_DST_UNREACH_NOTNEIGHBOR:
973 case ICMP6_DST_UNREACH_ADDR:
977 case ICMP6_DST_UNREACH_NOPORT:
984 } else if (type == ICMP6_PARAM_PROB &&
985 code == ICMP6_PARAMPROB_NEXTHEADER) {
988 } else if (type == ICMP6_ECHO_REPLY) {
995 } else if (deltaT(&t1, &t2) > waittime * 1000) {
1002 (void) fflush(stdout);
1006 (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) {
1017 wait_for_reply(int sock, struct msghdr *mhdr)
1020 struct pollfd pfd[1];
1024 pfd[0].events = POLLIN;
1027 if (poll(pfd, 1, waittime * 1000) > 0)
1028 cc = recvmsg(rcvsock, mhdr, 0);
1033 struct timeval wait;
1036 fdsn = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
1037 if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
1039 memset(fdsp, 0, fdsn);
1041 wait.tv_sec = waittime; wait.tv_usec = 0;
1043 if (select(sock+1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0)
1044 cc = recvmsg(rcvsock, mhdr, 0);
1051 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
1053 setpolicy(int so, char *policy)
1057 buf = ipsec_set_policy(policy, strlen(policy));
1059 warnx("%s", ipsec_strerror());
1062 (void)setsockopt(so, IPPROTO_IPV6, IPV6_IPSEC_POLICY,
1063 buf, ipsec_get_policylen(buf));
1072 send_probe(int seq, u_long hops)
1074 struct icmp6_hdr *icp;
1075 struct sctphdr *sctp;
1076 struct udphdr *outudp;
1077 struct sctp_chunkhdr *chk;
1078 struct sctp_init_chunk *init;
1079 struct sctp_paramhdr *param;
1084 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
1085 (char *)&i, sizeof(i)) < 0) {
1086 perror("setsockopt IPV6_UNICAST_HOPS");
1089 Dst.sin6_port = htons(port + seq);
1092 case IPPROTO_ICMPV6:
1093 icp = (struct icmp6_hdr *)outpacket;
1095 icp->icmp6_type = ICMP6_ECHO_REQUEST;
1096 icp->icmp6_code = 0;
1097 icp->icmp6_cksum = 0;
1098 icp->icmp6_id = ident;
1099 icp->icmp6_seq = htons(seq);
1102 outudp = (struct udphdr *) outpacket;
1103 outudp->uh_sport = htons(ident);
1104 outudp->uh_dport = htons(port+seq);
1105 outudp->uh_ulen = htons(datalen);
1106 outudp->uh_sum = udp_cksum(&Src, &Dst, outpacket, datalen);
1109 /* No space for anything. No harm as seq/tv32 are decorative. */
1112 sctp = (struct sctphdr *)outpacket;
1114 sctp->src_port = htons(ident);
1115 sctp->dest_port = htons(port + seq);
1116 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1117 sizeof(struct sctp_init_chunk))) {
1120 sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port;
1122 sctp->checksum = htonl(0);
1123 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1124 sizeof(struct sctp_init_chunk))) {
1126 * Send a packet containing an INIT chunk. This works
1127 * better in case of firewalls on the path, but
1128 * results in a probe packet containing at least
1129 * 32 bytes of payload. For shorter payloads, use
1130 * SHUTDOWN-ACK chunks.
1132 init = (struct sctp_init_chunk *)(sctp + 1);
1133 init->ch.chunk_type = SCTP_INITIATION;
1134 init->ch.chunk_flags = 0;
1135 init->ch.chunk_length = htons((u_int16_t)(datalen -
1136 sizeof(struct sctphdr)));
1137 init->init.initiate_tag = (sctp->src_port << 16) |
1139 init->init.a_rwnd = htonl(1500);
1140 init->init.num_outbound_streams = htons(1);
1141 init->init.num_inbound_streams = htons(1);
1142 init->init.initial_tsn = htonl(0);
1143 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1144 sizeof(struct sctp_init_chunk) +
1145 sizeof(struct sctp_paramhdr))) {
1146 param = (struct sctp_paramhdr *)(init + 1);
1147 param->param_type = htons(SCTP_PAD);
1148 param->param_length =
1149 htons((u_int16_t)(datalen -
1150 sizeof(struct sctphdr) -
1151 sizeof(struct sctp_init_chunk)));
1155 * Send a packet containing a SHUTDOWN-ACK chunk,
1156 * possibly followed by a PAD chunk.
1158 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1159 sizeof(struct sctp_chunkhdr))) {
1160 chk = (struct sctp_chunkhdr *)(sctp + 1);
1161 chk->chunk_type = SCTP_SHUTDOWN_ACK;
1162 chk->chunk_flags = 0;
1163 chk->chunk_length = htons(4);
1165 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1166 2 * sizeof(struct sctp_chunkhdr))) {
1168 chk->chunk_type = SCTP_PAD_CHUNK;
1169 chk->chunk_flags = 0;
1170 chk->chunk_length = htons((u_int16_t)(datalen -
1171 sizeof(struct sctphdr) -
1172 sizeof(struct sctp_chunkhdr)));
1175 sctp->checksum = sctp_crc32c(outpacket, datalen);
1178 tcp = (struct tcphdr *)outpacket;
1180 tcp->th_sport = htons(ident);
1181 tcp->th_dport = htons(port + seq);
1182 tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
1185 tcp->th_flags = TH_SYN;
1187 tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen);
1190 fprintf(stderr, "Unknown probe protocol %d.\n", useproto);
1194 i = send(sndsock, (char *)outpacket, datalen, 0);
1195 if (i < 0 || (u_long)i != datalen) {
1198 printf("traceroute6: wrote %s %lu chars, ret=%d\n",
1199 hostname, datalen, i);
1200 (void) fflush(stdout);
1205 get_hoplim(struct msghdr *mhdr)
1209 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1210 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1211 if (cm->cmsg_level == IPPROTO_IPV6 &&
1212 cm->cmsg_type == IPV6_HOPLIMIT &&
1213 cm->cmsg_len == CMSG_LEN(sizeof(int)))
1214 return (*(int *)CMSG_DATA(cm));
1221 deltaT(struct timeval *t1p, struct timeval *t2p)
1225 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1226 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1231 * Convert an ICMP "type" field to a printable string.
1236 u_char t = t0 & 0xff;
1240 case ICMP6_DST_UNREACH:
1241 cp = "Destination Unreachable";
1243 case ICMP6_PACKET_TOO_BIG:
1244 cp = "Packet Too Big";
1246 case ICMP6_TIME_EXCEEDED:
1247 cp = "Time Exceeded";
1249 case ICMP6_PARAM_PROB:
1250 cp = "Parameter Problem";
1252 case ICMP6_ECHO_REQUEST:
1253 cp = "Echo Request";
1255 case ICMP6_ECHO_REPLY:
1258 case ICMP6_MEMBERSHIP_QUERY:
1259 cp = "Group Membership Query";
1261 case ICMP6_MEMBERSHIP_REPORT:
1262 cp = "Group Membership Report";
1264 case ICMP6_MEMBERSHIP_REDUCTION:
1265 cp = "Group Membership Reduction";
1267 case ND_ROUTER_SOLICIT:
1268 cp = "Router Solicitation";
1270 case ND_ROUTER_ADVERT:
1271 cp = "Router Advertisement";
1273 case ND_NEIGHBOR_SOLICIT:
1274 cp = "Neighbor Solicitation";
1276 case ND_NEIGHBOR_ADVERT:
1277 cp = "Neighbor Advertisement";
1290 packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code)
1292 struct icmp6_hdr *icp;
1293 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1294 char *buf = (char *)mhdr->msg_iov[0].iov_base;
1297 char hbuf[NI_MAXHOST];
1305 ip = (struct ip6_hdr *) buf;
1306 hlen = sizeof(struct ip6_hdr);
1307 if (cc < hlen + sizeof(struct icmp6_hdr)) {
1309 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1310 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1311 strlcpy(hbuf, "invalid", sizeof(hbuf));
1312 printf("packet too short (%d bytes) from %s\n", cc,
1318 icp = (struct icmp6_hdr *)(buf + hlen);
1320 if (cc < (int)sizeof(struct icmp6_hdr)) {
1322 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1323 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1324 strlcpy(hbuf, "invalid", sizeof(hbuf));
1325 printf("data too short (%d bytes) from %s\n", cc, hbuf);
1329 icp = (struct icmp6_hdr *)buf;
1331 /* get optional information via advanced API */
1334 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1335 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1336 if (cm->cmsg_level == IPPROTO_IPV6 &&
1337 cm->cmsg_type == IPV6_PKTINFO &&
1339 CMSG_LEN(sizeof(struct in6_pktinfo)))
1340 rcvpktinfo = (struct in6_pktinfo *)(CMSG_DATA(cm));
1342 if (cm->cmsg_level == IPPROTO_IPV6 &&
1343 cm->cmsg_type == IPV6_HOPLIMIT &&
1344 cm->cmsg_len == CMSG_LEN(sizeof(int)))
1345 hlimp = (int *)CMSG_DATA(cm);
1347 if (rcvpktinfo == NULL || hlimp == NULL) {
1348 warnx("failed to get received hop limit or packet info");
1352 rcvhlim = 0; /*XXX*/
1358 *type = icp->icmp6_type;
1359 *code = icp->icmp6_code;
1360 if ((*type == ICMP6_TIME_EXCEEDED &&
1361 *code == ICMP6_TIME_EXCEED_TRANSIT) ||
1362 (*type == ICMP6_DST_UNREACH) ||
1363 (*type == ICMP6_PARAM_PROB &&
1364 *code == ICMP6_PARAMPROB_NEXTHEADER)) {
1365 struct ip6_hdr *hip;
1366 struct icmp6_hdr *icmp;
1367 struct sctp_init_chunk *init;
1368 struct sctphdr *sctp;
1373 hip = (struct ip6_hdr *)(icp + 1);
1374 if ((up = get_uphdr(hip, (u_char *)(buf + cc))) == NULL) {
1376 warnx("failed to get upper layer header");
1380 case IPPROTO_ICMPV6:
1381 icmp = (struct icmp6_hdr *)up;
1382 if (icmp->icmp6_id == ident &&
1383 icmp->icmp6_seq == htons(seq))
1387 udp = (struct udphdr *)up;
1388 if (udp->uh_sport == htons(ident) &&
1389 udp->uh_dport == htons(port + seq))
1393 sctp = (struct sctphdr *)up;
1394 if (sctp->src_port != htons(ident) ||
1395 sctp->dest_port != htons(port + seq)) {
1398 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1399 sizeof(struct sctp_init_chunk))) {
1400 if (sctp->v_tag != 0) {
1403 init = (struct sctp_init_chunk *)(sctp + 1);
1404 /* Check the initiate tag, if available. */
1405 if ((char *)&init->init.a_rwnd > buf + cc) {
1408 if (init->init.initiate_tag == (u_int32_t)
1409 ((sctp->src_port << 16) | sctp->dest_port)) {
1414 (u_int32_t)((sctp->src_port << 16) |
1421 tcp = (struct tcphdr *)up;
1422 if (tcp->th_sport == htons(ident) &&
1423 tcp->th_dport == htons(port + seq) &&
1425 (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport))
1431 fprintf(stderr, "Unknown probe proto %d.\n", useproto);
1434 } else if (useproto == IPPROTO_ICMPV6 && *type == ICMP6_ECHO_REPLY) {
1435 if (icp->icmp6_id == ident &&
1436 icp->icmp6_seq == htons(seq))
1440 char sbuf[NI_MAXHOST+1], dbuf[INET6_ADDRSTRLEN];
1444 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1445 sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0)
1446 strlcpy(sbuf, "invalid", sizeof(sbuf));
1447 printf("\n%d bytes from %s to %s", cc, sbuf,
1448 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1449 dbuf, sizeof(dbuf)) : "?");
1450 printf(": icmp type %d (%s) code %d\n", *type, pr_type(*type),
1452 p = (u_int8_t *)(icp + 1);
1454 for (i = 0; i < cc; i++) {
1459 printf("%02x", p[i]);
1460 if (i % WIDTH == WIDTH - 1)
1463 if (cc % WIDTH != 0)
1470 * Increment pointer until find the UDP or ICMP header.
1473 get_uphdr(struct ip6_hdr *ip6, u_char *lim)
1475 u_char *cp = (u_char *)ip6, nh;
1477 static u_char none_hdr[1]; /* Fake pointer for IPPROTO_NONE. */
1479 if (cp + sizeof(*ip6) > lim)
1483 cp += sizeof(struct ip6_hdr);
1485 while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) {
1489 case IPPROTO_ICMPV6:
1490 return (useproto == nh ? cp : NULL);
1494 return (useproto == nh ? cp : NULL);
1496 return (useproto == nh ? none_hdr : NULL);
1497 case IPPROTO_FRAGMENT:
1498 hlen = sizeof(struct ip6_frag);
1499 nh = ((struct ip6_frag *)cp)->ip6f_nxt;
1502 hlen = (((struct ip6_ext *)cp)->ip6e_len + 2) << 2;
1503 nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1506 hlen = (((struct ip6_ext *)cp)->ip6e_len + 1) << 3;
1507 nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1520 const char *types[] = { "NAME", "ADDR" };
1522 cap_channel_t *casper;
1524 casper = cap_init();
1526 errx(1, "unable to create casper process");
1527 capdns = cap_service_open(casper, "system.dns");
1529 errx(1, "unable to open system.dns service");
1530 if (cap_dns_type_limit(capdns, types, nitems(types)) < 0)
1531 errx(1, "unable to limit access to system.dns service");
1532 families[0] = AF_INET6;
1533 if (cap_dns_family_limit(capdns, families, nitems(families)) < 0)
1534 errx(1, "unable to limit access to system.dns service");
1539 print(struct msghdr *mhdr, int cc)
1541 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1542 char hbuf[NI_MAXHOST];
1544 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1545 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1546 strlcpy(hbuf, "invalid", sizeof(hbuf));
1548 printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6));
1550 printf(" %s", hbuf);
1552 printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf);
1554 printf(" %s", inetname((struct sockaddr *)from));
1558 printf(" %d bytes to %s", cc,
1559 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1560 hbuf, sizeof(hbuf)) : "?");
1562 printf(" %d bytes of data to %s", cc,
1563 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1564 hbuf, sizeof(hbuf)) : "?");
1570 * Construct an Internet address representation.
1571 * If the nflag has been supplied, give
1572 * numeric value, otherwise try for symbolic name.
1575 inetname(struct sockaddr *sa)
1577 static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1];
1578 static int first = 1;
1581 if (first && !nflag) {
1583 if (gethostname(domain, sizeof(domain)) == 0 &&
1584 (cp = strchr(domain, '.')))
1585 (void) strlcpy(domain, cp + 1, sizeof(domain));
1591 if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0,
1592 NI_NAMEREQD) == 0) {
1593 if ((cp = strchr(line, '.')) &&
1594 !strcmp(cp + 1, domain))
1602 if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0,
1603 NI_NUMERICHOST) != 0)
1604 strlcpy(line, "invalid", sizeof(line));
1609 * CRC32C routine for the Stream Control Transmission Protocol
1612 #define CRC32C(c, d) (c = (c>>8) ^ crc_c[(c^(d))&0xFF])
1614 static u_int32_t crc_c[256] = {
1615 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
1616 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
1617 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
1618 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
1619 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
1620 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
1621 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
1622 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
1623 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
1624 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
1625 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
1626 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
1627 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
1628 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
1629 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
1630 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
1631 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
1632 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
1633 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
1634 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
1635 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
1636 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
1637 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
1638 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
1639 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
1640 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
1641 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
1642 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
1643 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
1644 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
1645 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
1646 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
1647 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
1648 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
1649 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
1650 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
1651 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
1652 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
1653 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
1654 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
1655 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
1656 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
1657 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
1658 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
1659 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
1660 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
1661 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
1662 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
1663 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
1664 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
1665 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
1666 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
1667 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
1668 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
1669 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
1670 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
1671 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
1672 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
1673 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
1674 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
1675 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
1676 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
1677 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
1678 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
1682 sctp_crc32c(void *pack, u_int32_t len)
1684 u_int32_t i, crc32c;
1685 u_int8_t byte0, byte1, byte2, byte3;
1686 u_int8_t *buf = (u_int8_t *)pack;
1689 for (i = 0; i < len; i++)
1690 CRC32C(crc32c, buf[i]);
1692 byte0 = crc32c & 0xff;
1693 byte1 = (crc32c>>8) & 0xff;
1694 byte2 = (crc32c>>16) & 0xff;
1695 byte3 = (crc32c>>24) & 0xff;
1696 crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
1697 return htonl(crc32c);
1701 in_cksum(u_int16_t *addr, int len)
1704 u_int16_t *w = addr;
1709 * Our algorithm is simple, using a 32 bit accumulator (sum),
1710 * we add sequential 16 bit words to it, and at the end, fold
1711 * back all the carry bits from the top 16 bits into the lower
1719 /* mop up an odd byte, if necessary */
1721 sum += *(u_char *)w;
1724 * add back carry outs from top 16 bits to low 16 bits
1726 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
1727 sum += (sum >> 16); /* add carry */
1728 answer = ~sum; /* truncate to 16 bits */
1733 udp_cksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1734 void *payload, u_int32_t len)
1737 struct in6_addr src;
1738 struct in6_addr dst;
1745 pseudo_hdr.src = src->sin6_addr;
1746 pseudo_hdr.dst = dst->sin6_addr;
1747 pseudo_hdr.len = htonl(len);
1748 pseudo_hdr.zero[0] = 0;
1749 pseudo_hdr.zero[1] = 0;
1750 pseudo_hdr.zero[2] = 0;
1751 pseudo_hdr.next = IPPROTO_UDP;
1753 sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1754 sum[0] = in_cksum(payload, len);
1756 return (~in_cksum(sum, sizeof(sum)));
1760 tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1761 void *payload, u_int32_t len)
1764 struct in6_addr src;
1765 struct in6_addr dst;
1772 pseudo_hdr.src = src->sin6_addr;
1773 pseudo_hdr.dst = dst->sin6_addr;
1774 pseudo_hdr.len = htonl(len);
1775 pseudo_hdr.zero[0] = 0;
1776 pseudo_hdr.zero[1] = 0;
1777 pseudo_hdr.zero[2] = 0;
1778 pseudo_hdr.next = IPPROTO_TCP;
1780 sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1781 sum[0] = in_cksum(payload, len);
1783 return (~in_cksum(sum, sizeof(sum)));
1791 "usage: traceroute6 [-adIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n"
1792 " [-m hoplimit] [-p port] [-q probes] [-s src] [-w waittime] target\n"