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 * traceroute host - trace the route ip packets follow going to "host".
69 * Attempt to trace the route an ip packet would follow to some
70 * internet host. We find out intermediate hops by launching probe
71 * packets with a small ttl (time to live) then listening for an
72 * icmp "time exceeded" reply from a gateway. We start our probes
73 * with a ttl of one and increase by one until we get an icmp "port
74 * unreachable" (which means we got to "host") or hit a max (which
75 * defaults to 30 hops & can be changed with the -m flag). Three
76 * probes (change with -q flag) are sent at each ttl setting and a
77 * line is printed showing the ttl, address of the gateway and
78 * round trip time of each probe. If the probe answers come from
79 * different gateways, the address of each responding system will
80 * be printed. If there is no response within a 5 sec. timeout
81 * interval (changed with the -w flag), a "*" is printed for that
84 * Probe packets are UDP format. We don't want the destination
85 * host to process them so the destination port is set to an
86 * unlikely value (if some clod on the destination is using that
87 * value, it can be changed with the -p flag).
89 * A sample use might be:
91 * [yak 71]% traceroute nis.nsf.net.
92 * traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 56 byte packet
93 * 1 helios.ee.lbl.gov (128.3.112.1) 19 ms 19 ms 0 ms
94 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
95 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
96 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 39 ms
97 * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 39 ms 39 ms 39 ms
98 * 6 128.32.197.4 (128.32.197.4) 40 ms 59 ms 59 ms
99 * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 59 ms
100 * 8 129.140.70.13 (129.140.70.13) 99 ms 99 ms 80 ms
101 * 9 129.140.71.6 (129.140.71.6) 139 ms 239 ms 319 ms
102 * 10 129.140.81.7 (129.140.81.7) 220 ms 199 ms 199 ms
103 * 11 nic.merit.edu (35.1.1.48) 239 ms 239 ms 239 ms
105 * Note that lines 2 & 3 are the same. This is due to a buggy
106 * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
107 * packets with a zero ttl.
109 * A more interesting example is:
111 * [yak 72]% traceroute allspice.lcs.mit.edu.
112 * traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max
113 * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms
114 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 19 ms 19 ms
115 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 19 ms
116 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 19 ms 39 ms 39 ms
117 * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 20 ms 39 ms 39 ms
118 * 6 128.32.197.4 (128.32.197.4) 59 ms 119 ms 39 ms
119 * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 39 ms
120 * 8 129.140.70.13 (129.140.70.13) 80 ms 79 ms 99 ms
121 * 9 129.140.71.6 (129.140.71.6) 139 ms 139 ms 159 ms
122 * 10 129.140.81.7 (129.140.81.7) 199 ms 180 ms 300 ms
123 * 11 129.140.72.17 (129.140.72.17) 300 ms 239 ms 239 ms
125 * 13 128.121.54.72 (128.121.54.72) 259 ms 499 ms 279 ms
130 * 18 ALLSPICE.LCS.MIT.EDU (18.26.0.115) 339 ms 279 ms 279 ms
132 * (I start to see why I'm having so much trouble with mail to
133 * MIT.) Note that the gateways 12, 14, 15, 16 & 17 hops away
134 * either don't send ICMP "time exceeded" messages or send them
135 * with a ttl too small to reach us. 14 - 17 are running the
136 * MIT C Gateway code that doesn't send "time exceeded"s. God
137 * only knows what's going on with 12.
139 * The silent gateway 12 in the above may be the result of a bug in
140 * the 4.[23]BSD network code (and its derivatives): 4.x (x <= 3)
141 * sends an unreachable message using whatever ttl remains in the
142 * original datagram. Since, for gateways, the remaining ttl is
143 * zero, the icmp "time exceeded" is guaranteed to not make it back
144 * to us. The behavior of this bug is slightly more interesting
145 * when it appears on the destination system:
147 * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms
148 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 39 ms
149 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 39 ms 19 ms
150 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 19 ms
151 * 5 ccn-nerif35.Berkeley.EDU (128.32.168.35) 39 ms 39 ms 39 ms
152 * 6 csgw.Berkeley.EDU (128.32.133.254) 39 ms 59 ms 39 ms
159 * 13 rip.Berkeley.EDU (128.32.131.22) 59 ms ! 39 ms ! 39 ms !
161 * Notice that there are 12 "gateways" (13 is the final
162 * destination) and exactly the last half of them are "missing".
163 * What's really happening is that rip (a Sun-3 running Sun OS3.5)
164 * is using the ttl from our arriving datagram as the ttl in its
165 * icmp reply. So, the reply will time out on the return path
166 * (with no notice sent to anyone since icmp's aren't sent for
167 * icmp's) until we probe with a ttl that's at least twice the path
168 * length. I.e., rip is really only 7 hops away. A reply that
169 * returns with a ttl of 1 is a clue this problem exists.
170 * Traceroute prints a "!" after the time if the ttl is <= 1.
171 * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
172 * non-standard (HPUX) software, expect to see this problem
173 * frequently and/or take care picking the target host of your
176 * Other possible annotations after the time are !H, !N, !P (got a host,
177 * network or protocol unreachable, respectively), !S or !F (source
178 * route failed or fragmentation needed -- neither of these should
179 * ever occur and the associated gateway is busted if you see one). If
180 * almost all the probes result in some kind of unreachable, traceroute
181 * will give up and exit.
185 * This program must be run by root or be setuid. (I suggest that
186 * you *don't* make it setuid -- casual use could result in a lot
187 * of unnecessary traffic on our poor, congested nets.)
189 * This program requires a kernel mod that does not appear in any
190 * system available from Berkeley: A raw ip socket using proto
191 * IPPROTO_RAW must interpret the data sent as an ip datagram (as
192 * opposed to data to be wrapped in an ip datagram). See the README
193 * file that came with the source to this program for a description
194 * of the mods I made to /sys/netinet/raw_ip.c. Your mileage may
195 * vary. But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
196 * MODIFIED TO RUN THIS PROGRAM.
198 * The udp port usage may appear bizarre (well, ok, it is bizarre).
199 * The problem is that an icmp message only contains 8 bytes of
200 * data from the original datagram. 8 bytes is the size of a udp
201 * header so, if we want to associate replies with the original
202 * datagram, the necessary information must be encoded into the
203 * udp header (the ip id could be used but there's no way to
204 * interlock with the kernel's assignment of ip id's and, anyway,
205 * it would have taken a lot more kernel hacking to allow this
206 * code to set the ip id). So, to allow two or more users to
207 * use traceroute simultaneously, we use this task's pid as the
208 * source port (the high bit is set to move the port number out
209 * of the "likely" range). To keep track of which probe is being
210 * replied to (so times and/or hop counts don't get confused by a
211 * reply that was delayed in transit), we increment the destination
212 * port number before each probe.
214 * Don't use this as a coding example. I was trying to find a
215 * routing problem and this code sort-of popped out after 48 hours
216 * without sleep. I was amazed it ever compiled, much less ran.
218 * I stole the idea for this program from Steve Deering. Since
219 * the first release, I've learned that had I attended the right
220 * IETF working group meetings, I also could have stolen it from Guy
221 * Almes or Matt Mathis. I don't know (or care) who came up with
222 * the idea first. I envy the originators' perspicacity and I'm
223 * glad they didn't keep the idea a secret.
225 * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
226 * enhancements to the original distribution.
228 * I've hacked up a round-trip-route version of this that works by
229 * sending a loose-source-routed udp datagram through the destination
230 * back to yourself. Unfortunately, SO many gateways botch source
231 * routing, the thing is almost worthless. Maybe one day...
233 * -- Van Jacobson (van@helios.ee.lbl.gov)
234 * Tue Dec 20 03:50:13 PST 1988
237 #include <sys/param.h>
238 #include <sys/capsicum.h>
239 #include <sys/time.h>
240 #include <sys/socket.h>
242 #include <sys/file.h>
243 #include <sys/ioctl.h>
244 #include <sys/sysctl.h>
246 #include <netinet/in.h>
248 #include <arpa/inet.h>
250 #include <libcasper.h>
251 #include <casper/cap_dns.h>
252 #include <capsicum_helpers.h>
265 #include <netinet/ip6.h>
266 #include <netinet/icmp6.h>
267 #include <netinet/sctp.h>
268 #include <netinet/sctp_header.h>
269 #include <netinet/tcp.h>
270 #include <netinet/udp.h>
273 #include <net/route.h>
274 #include <netipsec/ipsec.h>
279 #define DUMMY_PORT 10010
281 #define MAXPACKET 65535 /* max ip packet size */
283 static u_char packet[512]; /* last inbound (icmp) packet */
284 static char *outpacket; /* last output packet */
286 int main(int, char *[]);
287 int wait_for_reply(int, struct msghdr *);
288 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
289 int setpolicy(int so, char *policy);
291 void send_probe(int, u_long);
292 void *get_uphdr(struct ip6_hdr *, u_char *);
293 void capdns_open(void);
294 int get_hoplim(struct msghdr *);
295 double deltaT(struct timeval *, struct timeval *);
296 const char *pr_type(int);
297 int packet_ok(struct msghdr *, int, int, u_char *, u_char *);
298 void print(struct msghdr *, int);
299 const char *inetname(struct sockaddr *);
300 u_int32_t sctp_crc32c(void *, u_int32_t);
301 u_int16_t in_cksum(u_int16_t *addr, int);
302 u_int16_t udp_cksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
304 u_int16_t tcp_chksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
308 static int rcvsock; /* receive (icmp) socket file descriptor */
309 static int sndsock; /* send (raw/udp) socket file descriptor */
311 static struct msghdr rcvmhdr;
312 static struct iovec rcviov[2];
314 static struct in6_pktinfo *rcvpktinfo;
316 static struct sockaddr_in6 Src, Dst, Rcv;
317 static u_long datalen = 20; /* How much data */
318 #define ICMP6ECHOLEN 8
319 /* XXX: 2064 = 127(max hops in type 0 rthdr) * sizeof(ip6_hdr) + 16(margin) */
320 static char rtbuf[2064];
321 static struct ip6_rthdr *rth;
322 static struct cmsghdr *cmsg;
324 static char *source = NULL;
325 static char *hostname;
327 static cap_channel_t *capdns;
329 static u_long nprobes = 3;
330 static u_long first_hop = 1;
331 static u_long max_hops = 30;
332 static u_int16_t srcport;
333 static u_int16_t port = 32768+666; /* start udp dest port # for probe packets */
334 static u_int16_t ident;
335 static int tclass = -1;
336 static int options; /* socket options */
338 static int waittime = 5; /* time to wait for response (in seconds) */
339 static int nflag; /* print addresses numerically */
340 static int useproto = IPPROTO_UDP; /* protocol to use to send packet */
341 static int lflag; /* print both numerical address & hostname */
342 static int as_path; /* print as numbers for each hop */
343 static char *as_server = NULL;
347 main(int argc, char *argv[])
349 int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM };
350 char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep;
351 int ch, i, on = 1, seq, rcvcmsglen, error;
352 struct addrinfo hints, *res;
353 static u_char *rcvcmsgbuf;
354 u_long probe, hops, lport, ltclass;
359 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
360 char ipsec_inpolicy[] = "in bypass";
361 char ipsec_outpolicy[] = "out bypass";
370 if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
371 perror("socket(ICMPv6)");
376 (void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &i, &size, NULL, 0);
379 /* specify to tell receiving interface */
380 #ifdef IPV6_RECVPKTINFO
381 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
383 err(1, "setsockopt(IPV6_RECVPKTINFO)");
384 #else /* old adv. API */
385 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_PKTINFO, &on,
387 err(1, "setsockopt(IPV6_PKTINFO)");
390 /* specify to tell value of hoplimit field of received IP6 hdr */
391 #ifdef IPV6_RECVHOPLIMIT
392 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
394 err(1, "setsockopt(IPV6_RECVHOPLIMIT)");
395 #else /* old adv. API */
396 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on,
398 err(1, "setsockopt(IPV6_HOPLIMIT)");
402 ident = htons(getpid() & 0xffff); /* same as ping6 */
404 while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:St:TUvw:")) != -1)
419 first_hop = strtoul(optarg, &ep, 0);
420 if (errno || !*optarg || *ep || first_hop > 255) {
422 "traceroute6: invalid min hoplimit.\n");
427 /* XXX use after capability mode is entered */
428 hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno);
431 "traceroute6: unknown host %s\n", optarg);
436 * XXX: We can't detect the number of
437 * intermediate nodes yet.
439 if ((rth = inet6_rth_init((void *)rtbuf,
440 sizeof(rtbuf), IPV6_RTHDR_TYPE_0,
443 "inet6_rth_init failed.\n");
447 if (inet6_rth_add((void *)rth,
448 (struct in6_addr *)hp->h_addr)) {
450 "inet6_rth_add failed for %s\n",
457 useproto = IPPROTO_ICMPV6;
465 max_hops = strtoul(optarg, &ep, 0);
466 if (errno || !*optarg || *ep || max_hops > 255) {
468 "traceroute6: invalid max hoplimit.\n");
476 useproto = IPPROTO_NONE;
481 lport = strtoul(optarg, &ep, 0);
482 if (errno || !*optarg || *ep) {
483 fprintf(stderr, "traceroute6: invalid port.\n");
486 if (lport == 0 || lport != (lport & 0xffff)) {
488 "traceroute6: port out of range.\n");
491 port = lport & 0xffff;
496 nprobes = strtoul(optarg, &ep, 0);
497 if (errno || !*optarg || *ep) {
499 "traceroute6: invalid nprobes.\n");
504 "traceroute6: nprobes must be >0.\n");
509 options |= SO_DONTROUTE;
513 * set the ip source address of the outbound
514 * probe (e.g., on a multi-homed host).
519 useproto = IPPROTO_SCTP;
524 ltclass = strtoul(optarg, &ep, 0);
525 if (errno || !*optarg || *ep || ltclass > 255) {
527 "traceroute6: invalid traffic class.\n");
530 tclass = (int)ltclass;
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.
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 (setsockopt(sndsock, IPPROTO_IPV6, IPV6_TCLASS, &tclass,
596 sizeof(int)) == -1) {
597 perror("setsockopt(IPV6_TCLASS)");
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;
617 error = cap_getaddrinfo(capdns, *argv, NULL, &hints, &res);
621 "traceroute6: %s\n", gai_strerror(error));
624 if (res->ai_addrlen != sizeof(Dst)) {
626 "traceroute6: size of sockaddr mismatch\n");
629 memcpy(&Dst, res->ai_addr, res->ai_addrlen);
630 hostname = res->ai_canonname ? strdup(res->ai_canonname) : *argv;
632 fprintf(stderr, "traceroute6: not enough core\n");
636 if (cap_getnameinfo(capdns, res->ai_addr, res->ai_addrlen, hbuf,
637 sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
638 strlcpy(hbuf, "?", sizeof(hbuf));
639 fprintf(stderr, "traceroute6: Warning: %s has multiple "
640 "addresses; using %s\n", hostname, hbuf);
646 datalen = strtoul(*argv, &ep, 0);
649 "traceroute6: invalid packet length.\n");
655 minlen = ICMP6ECHOLEN;
658 minlen = sizeof(struct udphdr);
665 minlen = sizeof(struct sctphdr);
668 minlen = sizeof(struct tcphdr);
671 fprintf(stderr, "traceroute6: unknown probe protocol %d.\n",
675 if (datalen < minlen)
677 else if (datalen >= MAXPACKET) {
679 "traceroute6: packet size must be %zu <= s < %d.\n",
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));
717 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
719 * do not raise error even if setsockopt fails, kernel may have ipsec
722 if (setpolicy(rcvsock, ipsec_inpolicy) < 0)
723 errx(1, "%s", ipsec_strerror());
724 if (setpolicy(rcvsock, ipsec_outpolicy) < 0)
725 errx(1, "%s", ipsec_strerror());
728 int level = IPSEC_LEVEL_NONE;
730 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
732 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
734 #ifdef IP_AUTH_TRANS_LEVEL
735 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
738 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
741 #ifdef IP_AUTH_NETWORK_LEVEL
742 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
746 #endif /* !(IPSEC && IPSEC_POLICY_IPSEC) */
752 if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&i,
754 perror("setsockopt(SO_SNDBUF)");
757 #endif /* SO_SNDBUF */
758 if (options & SO_DEBUG)
759 (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
760 (char *)&on, sizeof(on));
761 if (options & SO_DONTROUTE)
762 (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
763 (char *)&on, sizeof(on));
764 if (rth) {/* XXX: there is no library to finalize the header... */
765 rth->ip6r_len = rth->ip6r_segleft * 2;
766 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_RTHDR,
767 (void *)rth, (rth->ip6r_len + 1) << 3)) {
768 fprintf(stderr, "setsockopt(IPV6_RTHDR): %s\n",
773 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
775 * do not raise error even if setsockopt fails, kernel may have ipsec
778 if (setpolicy(sndsock, ipsec_inpolicy) < 0)
779 errx(1, "%s", ipsec_strerror());
780 if (setpolicy(sndsock, ipsec_outpolicy) < 0)
781 errx(1, "%s", ipsec_strerror());
784 int level = IPSEC_LEVEL_BYPASS;
786 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
788 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
790 #ifdef IP_AUTH_TRANS_LEVEL
791 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
794 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
797 #ifdef IP_AUTH_NETWORK_LEVEL
798 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
802 #endif /* !(IPSEC && IPSEC_POLICY_IPSEC) */
807 bzero(&Src, sizeof(Src));
809 memset(&hints, 0, sizeof(hints));
810 hints.ai_family = AF_INET6;
811 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
812 hints.ai_flags = AI_NUMERICHOST;
813 error = cap_getaddrinfo(capdns, source, "0", &hints, &res);
815 printf("traceroute6: %s: %s\n", source,
816 gai_strerror(error));
819 if (res->ai_addrlen > sizeof(Src)) {
820 printf("traceroute6: %s: %s\n", source,
821 gai_strerror(error));
824 memcpy(&Src, res->ai_addr, res->ai_addrlen);
827 struct sockaddr_in6 Nxt;
832 Nxt.sin6_port = htons(DUMMY_PORT);
834 bcopy(inet6_rthdr_getaddr(cmsg, 1), &Nxt.sin6_addr,
835 sizeof(Nxt.sin6_addr));
836 if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
840 if (connect(dummy, (struct sockaddr *)&Nxt, Nxt.sin6_len) < 0) {
845 if (getsockname(dummy, (struct sockaddr *)&Src, &len) < 0) {
846 perror("getsockname");
849 if (cap_getnameinfo(capdns, (struct sockaddr *)&Src, Src.sin6_len,
850 src0, sizeof(src0), NULL, 0, NI_NUMERICHOST)) {
851 fprintf(stderr, "getnameinfo failed for source\n");
858 Src.sin6_port = htons(0);
859 if (bind(sndsock, (struct sockaddr *)&Src, Src.sin6_len) < 0) {
868 if (getsockname(sndsock, (struct sockaddr *)&Src, &len) < 0) {
869 perror("getsockname");
872 srcport = ntohs(Src.sin6_port);
876 asn = as_setup(as_server);
879 "traceroute6: as_setup failed, AS# lookups"
881 (void)fflush(stderr);
889 if (cap_getnameinfo(capdns, (struct sockaddr *)&Dst, Dst.sin6_len, hbuf,
890 sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
891 strlcpy(hbuf, "(invalid)", sizeof(hbuf));
892 fprintf(stderr, "traceroute6");
893 fprintf(stderr, " to %s (%s)", hostname, hbuf);
895 fprintf(stderr, " from %s", source);
896 fprintf(stderr, ", %lu hops max, %lu byte packets\n",
898 datalen + ((useproto == IPPROTO_UDP) ? sizeof(struct udphdr) : 0));
899 (void) fflush(stderr);
902 printf("Skipping %lu intermediate hops\n", first_hop - 1);
904 if (connect(sndsock, (struct sockaddr *)&Dst,
906 fprintf(stderr, "connect: %s\n", strerror(errno));
911 * Here we enter capability mode. Further down access to global
912 * namespaces (e.g filesystem) is restricted (see capsicum(4)).
913 * We must connect(2) our socket before this point.
915 if (caph_enter_casper() < 0) {
916 fprintf(stderr, "caph_enter_casper: %s\n", strerror(errno));
920 cap_rights_init(&rights, CAP_SEND, CAP_SETSOCKOPT);
921 if (caph_rights_limit(sndsock, &rights) < 0) {
922 fprintf(stderr, "caph_rights_limit sndsock: %s\n",
926 cap_rights_init(&rights, CAP_RECV, CAP_EVENT);
927 if (caph_rights_limit(rcvsock, &rights) < 0) {
928 fprintf(stderr, "caph_rights_limit rcvsock: %s\n",
936 for (hops = first_hop; hops <= max_hops; ++hops) {
937 struct in6_addr lastaddr;
939 unsigned unreachable = 0;
941 printf("%2lu ", hops);
942 bzero(&lastaddr, sizeof(lastaddr));
943 for (probe = 0; probe < nprobes; ++probe) {
945 struct timeval t1, t2;
947 (void) gettimeofday(&t1, NULL);
948 send_probe(++seq, hops);
949 while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) {
950 (void) gettimeofday(&t2, NULL);
951 if (packet_ok(&rcvmhdr, cc, seq, &type, &code)) {
952 if (!IN6_ARE_ADDR_EQUAL(&Rcv.sin6_addr,
955 fputs("\n ", stdout);
957 lastaddr = Rcv.sin6_addr;
959 printf(" %.3f ms", deltaT(&t1, &t2));
960 if (type == ICMP6_DST_UNREACH) {
962 case ICMP6_DST_UNREACH_NOROUTE:
966 case ICMP6_DST_UNREACH_ADMIN:
970 case ICMP6_DST_UNREACH_NOTNEIGHBOR:
974 case ICMP6_DST_UNREACH_ADDR:
978 case ICMP6_DST_UNREACH_NOPORT:
985 } else if (type == ICMP6_PARAM_PROB &&
986 code == ICMP6_PARAMPROB_NEXTHEADER) {
989 } else if (type == ICMP6_ECHO_REPLY) {
996 } else if (deltaT(&t1, &t2) > waittime * 1000) {
1003 (void) fflush(stdout);
1007 (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) {
1018 wait_for_reply(int sock, struct msghdr *mhdr)
1021 struct pollfd pfd[1];
1025 pfd[0].events = POLLIN;
1028 if (poll(pfd, 1, waittime * 1000) > 0 &&
1029 pfd[0].revents & POLLIN)
1030 cc = recvmsg(rcvsock, mhdr, 0);
1035 struct timeval wait;
1038 fdsn = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
1039 if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
1041 memset(fdsp, 0, fdsn);
1043 wait.tv_sec = waittime; wait.tv_usec = 0;
1045 if (select(sock+1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0)
1046 cc = recvmsg(rcvsock, mhdr, 0);
1053 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
1055 setpolicy(int so, char *policy)
1059 buf = ipsec_set_policy(policy, strlen(policy));
1061 warnx("%s", ipsec_strerror());
1064 (void)setsockopt(so, IPPROTO_IPV6, IPV6_IPSEC_POLICY,
1065 buf, ipsec_get_policylen(buf));
1074 send_probe(int seq, u_long hops)
1076 struct icmp6_hdr *icp;
1077 struct sctphdr *sctp;
1078 struct udphdr *outudp;
1079 struct sctp_chunkhdr *chk;
1080 struct sctp_init_chunk *init;
1081 struct sctp_paramhdr *param;
1086 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
1087 (char *)&i, sizeof(i)) < 0) {
1088 perror("setsockopt IPV6_UNICAST_HOPS");
1091 Dst.sin6_port = htons(port + seq);
1094 case IPPROTO_ICMPV6:
1095 icp = (struct icmp6_hdr *)outpacket;
1097 icp->icmp6_type = ICMP6_ECHO_REQUEST;
1098 icp->icmp6_code = 0;
1099 icp->icmp6_cksum = 0;
1100 icp->icmp6_id = ident;
1101 icp->icmp6_seq = htons(seq);
1104 outudp = (struct udphdr *) outpacket;
1105 outudp->uh_sport = htons(ident);
1106 outudp->uh_dport = htons(port+seq);
1107 outudp->uh_ulen = htons(datalen);
1109 outudp->uh_sum = udp_cksum(&Src, &Dst, outpacket, datalen);
1112 /* No space for anything. No harm as seq/tv32 are decorative. */
1115 sctp = (struct sctphdr *)outpacket;
1117 sctp->src_port = htons(ident);
1118 sctp->dest_port = htons(port + seq);
1119 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1120 sizeof(struct sctp_init_chunk))) {
1123 sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port;
1125 sctp->checksum = htonl(0);
1126 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1127 sizeof(struct sctp_init_chunk))) {
1129 * Send a packet containing an INIT chunk. This works
1130 * better in case of firewalls on the path, but
1131 * results in a probe packet containing at least
1132 * 32 bytes of payload. For shorter payloads, use
1133 * SHUTDOWN-ACK chunks.
1135 init = (struct sctp_init_chunk *)(sctp + 1);
1136 init->ch.chunk_type = SCTP_INITIATION;
1137 init->ch.chunk_flags = 0;
1138 init->ch.chunk_length = htons((u_int16_t)(datalen -
1139 sizeof(struct sctphdr)));
1140 init->init.initiate_tag = (sctp->src_port << 16) |
1142 init->init.a_rwnd = htonl(1500);
1143 init->init.num_outbound_streams = htons(1);
1144 init->init.num_inbound_streams = htons(1);
1145 init->init.initial_tsn = htonl(0);
1146 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1147 sizeof(struct sctp_init_chunk) +
1148 sizeof(struct sctp_paramhdr))) {
1149 param = (struct sctp_paramhdr *)(init + 1);
1150 param->param_type = htons(SCTP_PAD);
1151 param->param_length =
1152 htons((u_int16_t)(datalen -
1153 sizeof(struct sctphdr) -
1154 sizeof(struct sctp_init_chunk)));
1158 * Send a packet containing a SHUTDOWN-ACK chunk,
1159 * possibly followed by a PAD chunk.
1161 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1162 sizeof(struct sctp_chunkhdr))) {
1163 chk = (struct sctp_chunkhdr *)(sctp + 1);
1164 chk->chunk_type = SCTP_SHUTDOWN_ACK;
1165 chk->chunk_flags = 0;
1166 chk->chunk_length = htons(4);
1168 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1169 2 * sizeof(struct sctp_chunkhdr))) {
1171 chk->chunk_type = SCTP_PAD_CHUNK;
1172 chk->chunk_flags = 0;
1173 chk->chunk_length = htons((u_int16_t)(datalen -
1174 sizeof(struct sctphdr) -
1175 sizeof(struct sctp_chunkhdr)));
1178 sctp->checksum = sctp_crc32c(outpacket, datalen);
1181 tcp = (struct tcphdr *)outpacket;
1183 tcp->th_sport = htons(ident);
1184 tcp->th_dport = htons(port + seq);
1185 tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
1188 tcp->th_flags = TH_SYN;
1190 tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen);
1193 fprintf(stderr, "Unknown probe protocol %d.\n", useproto);
1197 i = send(sndsock, (char *)outpacket, datalen, 0);
1198 if (i < 0 || (u_long)i != datalen) {
1201 printf("traceroute6: wrote %s %lu chars, ret=%d\n",
1202 hostname, datalen, i);
1203 (void) fflush(stdout);
1208 get_hoplim(struct msghdr *mhdr)
1212 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1213 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1214 if (cm->cmsg_level == IPPROTO_IPV6 &&
1215 cm->cmsg_type == IPV6_HOPLIMIT &&
1216 cm->cmsg_len == CMSG_LEN(sizeof(int)))
1217 return (*(int *)CMSG_DATA(cm));
1224 deltaT(struct timeval *t1p, struct timeval *t2p)
1228 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1229 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1234 * Convert an ICMP "type" field to a printable string.
1239 u_char t = t0 & 0xff;
1243 case ICMP6_DST_UNREACH:
1244 cp = "Destination Unreachable";
1246 case ICMP6_PACKET_TOO_BIG:
1247 cp = "Packet Too Big";
1249 case ICMP6_TIME_EXCEEDED:
1250 cp = "Time Exceeded";
1252 case ICMP6_PARAM_PROB:
1253 cp = "Parameter Problem";
1255 case ICMP6_ECHO_REQUEST:
1256 cp = "Echo Request";
1258 case ICMP6_ECHO_REPLY:
1261 case ICMP6_MEMBERSHIP_QUERY:
1262 cp = "Group Membership Query";
1264 case ICMP6_MEMBERSHIP_REPORT:
1265 cp = "Group Membership Report";
1267 case ICMP6_MEMBERSHIP_REDUCTION:
1268 cp = "Group Membership Reduction";
1270 case ND_ROUTER_SOLICIT:
1271 cp = "Router Solicitation";
1273 case ND_ROUTER_ADVERT:
1274 cp = "Router Advertisement";
1276 case ND_NEIGHBOR_SOLICIT:
1277 cp = "Neighbor Solicitation";
1279 case ND_NEIGHBOR_ADVERT:
1280 cp = "Neighbor Advertisement";
1293 packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code)
1295 struct icmp6_hdr *icp;
1296 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1297 char *buf = (char *)mhdr->msg_iov[0].iov_base;
1300 char hbuf[NI_MAXHOST];
1308 ip = (struct ip6_hdr *) buf;
1309 hlen = sizeof(struct ip6_hdr);
1310 if (cc < hlen + sizeof(struct icmp6_hdr)) {
1312 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1313 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1314 strlcpy(hbuf, "invalid", sizeof(hbuf));
1315 printf("packet too short (%d bytes) from %s\n", cc,
1321 icp = (struct icmp6_hdr *)(buf + hlen);
1323 if (cc < (int)sizeof(struct icmp6_hdr)) {
1325 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1326 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1327 strlcpy(hbuf, "invalid", sizeof(hbuf));
1328 printf("data too short (%d bytes) from %s\n", cc, hbuf);
1332 icp = (struct icmp6_hdr *)buf;
1334 /* get optional information via advanced API */
1337 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1338 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1339 if (cm->cmsg_level == IPPROTO_IPV6 &&
1340 cm->cmsg_type == IPV6_PKTINFO &&
1342 CMSG_LEN(sizeof(struct in6_pktinfo)))
1343 rcvpktinfo = (struct in6_pktinfo *)(CMSG_DATA(cm));
1345 if (cm->cmsg_level == IPPROTO_IPV6 &&
1346 cm->cmsg_type == IPV6_HOPLIMIT &&
1347 cm->cmsg_len == CMSG_LEN(sizeof(int)))
1348 hlimp = (int *)CMSG_DATA(cm);
1350 if (rcvpktinfo == NULL || hlimp == NULL) {
1351 warnx("failed to get received hop limit or packet info");
1355 rcvhlim = 0; /*XXX*/
1361 *type = icp->icmp6_type;
1362 *code = icp->icmp6_code;
1363 if ((*type == ICMP6_TIME_EXCEEDED &&
1364 *code == ICMP6_TIME_EXCEED_TRANSIT) ||
1365 (*type == ICMP6_DST_UNREACH) ||
1366 (*type == ICMP6_PARAM_PROB &&
1367 *code == ICMP6_PARAMPROB_NEXTHEADER)) {
1368 struct ip6_hdr *hip;
1369 struct icmp6_hdr *icmp;
1370 struct sctp_init_chunk *init;
1371 struct sctphdr *sctp;
1376 hip = (struct ip6_hdr *)(icp + 1);
1377 if ((up = get_uphdr(hip, (u_char *)(buf + cc))) == NULL) {
1379 warnx("failed to get upper layer header");
1383 case IPPROTO_ICMPV6:
1384 icmp = (struct icmp6_hdr *)up;
1385 if (icmp->icmp6_id == ident &&
1386 icmp->icmp6_seq == htons(seq))
1390 udp = (struct udphdr *)up;
1391 if (udp->uh_sport == htons(ident) &&
1392 udp->uh_dport == htons(port + seq))
1396 sctp = (struct sctphdr *)up;
1397 if (sctp->src_port != htons(ident) ||
1398 sctp->dest_port != htons(port + seq)) {
1401 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1402 sizeof(struct sctp_init_chunk))) {
1403 if (sctp->v_tag != 0) {
1406 init = (struct sctp_init_chunk *)(sctp + 1);
1407 /* Check the initiate tag, if available. */
1408 if ((char *)&init->init.a_rwnd > buf + cc) {
1411 if (init->init.initiate_tag == (u_int32_t)
1412 ((sctp->src_port << 16) | sctp->dest_port)) {
1417 (u_int32_t)((sctp->src_port << 16) |
1424 tcp = (struct tcphdr *)up;
1425 if (tcp->th_sport == htons(ident) &&
1426 tcp->th_dport == htons(port + seq) &&
1428 (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport))
1434 fprintf(stderr, "Unknown probe proto %d.\n", useproto);
1437 } else if (useproto == IPPROTO_ICMPV6 && *type == ICMP6_ECHO_REPLY) {
1438 if (icp->icmp6_id == ident &&
1439 icp->icmp6_seq == htons(seq))
1443 char sbuf[NI_MAXHOST+1], dbuf[INET6_ADDRSTRLEN];
1447 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1448 sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0)
1449 strlcpy(sbuf, "invalid", sizeof(sbuf));
1450 printf("\n%d bytes from %s to %s", cc, sbuf,
1451 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1452 dbuf, sizeof(dbuf)) : "?");
1453 printf(": icmp type %d (%s) code %d\n", *type, pr_type(*type),
1455 p = (u_int8_t *)(icp + 1);
1457 for (i = 0; i < cc; i++) {
1462 printf("%02x", p[i]);
1463 if (i % WIDTH == WIDTH - 1)
1466 if (cc % WIDTH != 0)
1473 * Increment pointer until find the UDP or ICMP header.
1476 get_uphdr(struct ip6_hdr *ip6, u_char *lim)
1478 u_char *cp = (u_char *)ip6, nh;
1480 static u_char none_hdr[1]; /* Fake pointer for IPPROTO_NONE. */
1482 if (cp + sizeof(*ip6) > lim)
1486 cp += sizeof(struct ip6_hdr);
1488 while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) {
1492 case IPPROTO_ICMPV6:
1493 return (useproto == nh ? cp : NULL);
1497 return (useproto == nh ? cp : NULL);
1499 return (useproto == nh ? none_hdr : NULL);
1500 case IPPROTO_FRAGMENT:
1501 hlen = sizeof(struct ip6_frag);
1502 nh = ((struct ip6_frag *)cp)->ip6f_nxt;
1505 hlen = (((struct ip6_ext *)cp)->ip6e_len + 2) << 2;
1506 nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1509 hlen = (((struct ip6_ext *)cp)->ip6e_len + 1) << 3;
1510 nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1524 const char *types[] = { "NAME", "ADDR" };
1526 cap_channel_t *casper;
1528 casper = cap_init();
1530 errx(1, "unable to create casper process");
1531 capdns = cap_service_open(casper, "system.dns");
1533 errx(1, "unable to open system.dns service");
1534 if (cap_dns_type_limit(capdns, types, nitems(types)) < 0)
1535 errx(1, "unable to limit access to system.dns service");
1536 families[0] = AF_INET6;
1537 if (cap_dns_family_limit(capdns, families, nitems(families)) < 0)
1538 errx(1, "unable to limit access to system.dns service");
1540 #endif /* WITH_CASPER */
1544 print(struct msghdr *mhdr, int cc)
1546 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1547 char hbuf[NI_MAXHOST];
1549 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1550 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1551 strlcpy(hbuf, "invalid", sizeof(hbuf));
1553 printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6));
1555 printf(" %s", hbuf);
1557 printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf);
1559 printf(" %s", inetname((struct sockaddr *)from));
1563 printf(" %d bytes to %s", cc,
1564 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1565 hbuf, sizeof(hbuf)) : "?");
1567 printf(" %d bytes of data to %s", cc,
1568 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1569 hbuf, sizeof(hbuf)) : "?");
1575 * Construct an Internet address representation.
1576 * If the nflag has been supplied, give
1577 * numeric value, otherwise try for symbolic name.
1580 inetname(struct sockaddr *sa)
1582 static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1];
1583 static int first = 1;
1586 if (first && !nflag) {
1588 if (gethostname(domain, sizeof(domain)) == 0 &&
1589 (cp = strchr(domain, '.')))
1590 (void) strlcpy(domain, cp + 1, sizeof(domain));
1596 if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0,
1597 NI_NAMEREQD) == 0) {
1598 if ((cp = strchr(line, '.')) &&
1599 !strcmp(cp + 1, domain))
1607 if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0,
1608 NI_NUMERICHOST) != 0)
1609 strlcpy(line, "invalid", sizeof(line));
1614 * CRC32C routine for the Stream Control Transmission Protocol
1617 #define CRC32C(c, d) (c = (c>>8) ^ crc_c[(c^(d))&0xFF])
1619 static u_int32_t crc_c[256] = {
1620 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
1621 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
1622 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
1623 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
1624 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
1625 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
1626 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
1627 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
1628 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
1629 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
1630 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
1631 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
1632 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
1633 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
1634 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
1635 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
1636 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
1637 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
1638 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
1639 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
1640 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
1641 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
1642 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
1643 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
1644 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
1645 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
1646 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
1647 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
1648 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
1649 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
1650 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
1651 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
1652 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
1653 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
1654 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
1655 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
1656 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
1657 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
1658 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
1659 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
1660 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
1661 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
1662 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
1663 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
1664 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
1665 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
1666 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
1667 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
1668 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
1669 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
1670 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
1671 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
1672 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
1673 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
1674 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
1675 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
1676 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
1677 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
1678 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
1679 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
1680 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
1681 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
1682 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
1683 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
1687 sctp_crc32c(void *pack, u_int32_t len)
1689 u_int32_t i, crc32c;
1690 u_int8_t byte0, byte1, byte2, byte3;
1691 u_int8_t *buf = (u_int8_t *)pack;
1694 for (i = 0; i < len; i++)
1695 CRC32C(crc32c, buf[i]);
1697 byte0 = crc32c & 0xff;
1698 byte1 = (crc32c>>8) & 0xff;
1699 byte2 = (crc32c>>16) & 0xff;
1700 byte3 = (crc32c>>24) & 0xff;
1701 crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
1702 return htonl(crc32c);
1706 in_cksum(u_int16_t *addr, int len)
1709 u_int16_t *w = addr;
1714 * Our algorithm is simple, using a 32 bit accumulator (sum),
1715 * we add sequential 16 bit words to it, and at the end, fold
1716 * back all the carry bits from the top 16 bits into the lower
1724 /* mop up an odd byte, if necessary */
1726 sum += *(u_char *)w;
1729 * add back carry outs from top 16 bits to low 16 bits
1731 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
1732 sum += (sum >> 16); /* add carry */
1733 answer = ~sum; /* truncate to 16 bits */
1738 udp_cksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1739 void *payload, u_int32_t len)
1742 struct in6_addr src;
1743 struct in6_addr dst;
1750 pseudo_hdr.src = src->sin6_addr;
1751 pseudo_hdr.dst = dst->sin6_addr;
1752 pseudo_hdr.len = htonl(len);
1753 pseudo_hdr.zero[0] = 0;
1754 pseudo_hdr.zero[1] = 0;
1755 pseudo_hdr.zero[2] = 0;
1756 pseudo_hdr.next = IPPROTO_UDP;
1758 sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1759 sum[0] = in_cksum(payload, len);
1761 return (~in_cksum(sum, sizeof(sum)));
1765 tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1766 void *payload, u_int32_t len)
1769 struct in6_addr src;
1770 struct in6_addr dst;
1777 pseudo_hdr.src = src->sin6_addr;
1778 pseudo_hdr.dst = dst->sin6_addr;
1779 pseudo_hdr.len = htonl(len);
1780 pseudo_hdr.zero[0] = 0;
1781 pseudo_hdr.zero[1] = 0;
1782 pseudo_hdr.zero[2] = 0;
1783 pseudo_hdr.next = IPPROTO_TCP;
1785 sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1786 sum[0] = in_cksum(payload, len);
1788 return (~in_cksum(sum, sizeof(sum)));
1796 "usage: traceroute6 [-adIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n"
1797 " [-m hoplimit] [-p port] [-q probes] [-s src] [-w waittime] target\n"