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/ip.h>
266 #include <netinet/ip6.h>
267 #include <netinet/icmp6.h>
268 #include <netinet/sctp.h>
269 #include <netinet/sctp_header.h>
270 #include <netinet/tcp.h>
271 #include <netinet/udp.h>
274 #include <net/route.h>
275 #include <netipsec/ipsec.h>
280 #define DUMMY_PORT 10010
282 #define MAXPACKET 65535 /* max ip packet size */
284 static u_char packet[512]; /* last inbound (icmp) packet */
285 static char *outpacket; /* last output packet */
287 int main(int, char *[]);
288 int wait_for_reply(int, struct msghdr *);
289 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
290 int setpolicy(int so, char *policy);
292 void send_probe(int, u_long);
293 void *get_uphdr(struct ip6_hdr *, u_char *);
294 void capdns_open(void);
295 int get_hoplim(struct msghdr *);
296 double deltaT(struct timeval *, struct timeval *);
297 const char *pr_type(int);
298 int packet_ok(struct msghdr *, int, int, u_char *, u_char *, u_char *);
299 void print(struct msghdr *, int);
300 const char *inetname(struct sockaddr *);
301 u_int32_t sctp_crc32c(void *, u_int32_t);
302 u_int16_t in_cksum(u_int16_t *addr, int);
303 u_int16_t udp_cksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
305 u_int16_t tcp_chksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
309 static int rcvsock; /* receive (icmp) socket file descriptor */
310 static int sndsock; /* send (raw/udp) socket file descriptor */
312 static struct msghdr rcvmhdr;
313 static struct iovec rcviov[2];
315 static struct in6_pktinfo *rcvpktinfo;
317 static struct sockaddr_in6 Src, Dst, Rcv;
318 static u_long datalen = 20; /* How much data */
319 #define ICMP6ECHOLEN 8
320 /* XXX: 2064 = 127(max hops in type 0 rthdr) * sizeof(ip6_hdr) + 16(margin) */
321 static char rtbuf[2064];
322 static struct ip6_rthdr *rth;
323 static struct cmsghdr *cmsg;
325 static char *source = NULL;
326 static char *hostname;
328 static cap_channel_t *capdns;
330 static u_long nprobes = 3;
331 static u_long first_hop = 1;
332 static u_long max_hops = 30;
333 static u_int16_t srcport;
334 static u_int16_t port = 32768 + 666; /* start udp dest port # for probe packets */
335 static u_int16_t ident;
336 static int tclass = -1;
337 static int options; /* socket options */
339 static int waittime = 5; /* time to wait for response (in seconds) */
340 static int nflag; /* print addresses numerically */
341 static int useproto = IPPROTO_UDP; /* protocol to use to send packet */
342 static int lflag; /* print both numerical address & hostname */
343 static int as_path; /* print as numbers for each hop */
344 static int ecnflag; /* ECN bleaching detection flag */
345 static char *as_server = NULL;
349 main(int argc, char *argv[])
351 int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM };
352 char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep;
353 int ch, i, on = 1, seq, rcvcmsglen, error;
354 struct addrinfo hints, *res;
355 static u_char *rcvcmsgbuf;
356 u_long probe, hops, lport, ltclass;
360 u_char type, code, ecn;
361 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
362 char ipsec_inpolicy[] = "in bypass";
363 char ipsec_outpolicy[] = "out bypass";
372 if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
373 perror("socket(ICMPv6)");
378 (void) sysctl(mib, sizeof(mib) / sizeof(mib[0]), &i, &size, NULL, 0);
381 /* specify to tell receiving interface */
382 #ifdef IPV6_RECVPKTINFO
383 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
385 err(1, "setsockopt(IPV6_RECVPKTINFO)");
386 #else /* old adv. API */
387 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_PKTINFO, &on,
389 err(1, "setsockopt(IPV6_PKTINFO)");
392 /* specify to tell value of hoplimit field of received IP6 hdr */
393 #ifdef IPV6_RECVHOPLIMIT
394 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
396 err(1, "setsockopt(IPV6_RECVHOPLIMIT)");
397 #else /* old adv. API */
398 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on,
400 err(1, "setsockopt(IPV6_HOPLIMIT)");
404 ident = htons(getpid() & 0xffff); /* same as ping6 */
406 while ((ch = getopt(argc, argv, "aA:dEf:g:Ilm:nNp:q:rs:St:TUvw:")) != -1)
424 first_hop = strtoul(optarg, &ep, 0);
425 if (errno || !*optarg || *ep || first_hop > 255) {
427 "traceroute6: invalid min hoplimit.\n");
432 /* XXX use after capability mode is entered */
433 hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno);
436 "traceroute6: unknown host %s\n", optarg);
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",
462 useproto = IPPROTO_ICMPV6;
470 max_hops = strtoul(optarg, &ep, 0);
471 if (errno || !*optarg || *ep || max_hops > 255) {
473 "traceroute6: invalid max hoplimit.\n");
481 useproto = IPPROTO_NONE;
486 lport = strtoul(optarg, &ep, 0);
487 if (errno || !*optarg || *ep) {
488 fprintf(stderr, "traceroute6: invalid port.\n");
491 if (lport == 0 || lport != (lport & 0xffff)) {
493 "traceroute6: port out of range.\n");
496 port = lport & 0xffff;
501 nprobes = strtoul(optarg, &ep, 0);
502 if (errno || !*optarg || *ep) {
504 "traceroute6: invalid nprobes.\n");
509 "traceroute6: nprobes must be >0.\n");
514 options |= SO_DONTROUTE;
518 * set the ip source address of the outbound
519 * probe (e.g., on a multi-homed host).
524 useproto = IPPROTO_SCTP;
529 ltclass = strtoul(optarg, &ep, 0);
530 if (errno || !*optarg || *ep || ltclass > 255) {
532 "traceroute6: invalid traffic class.\n");
535 tclass = (int)ltclass;
538 useproto = IPPROTO_TCP;
541 useproto = IPPROTO_UDP;
549 waittime = strtoul(optarg, &ep, 0);
550 if (errno || !*optarg || *ep) {
552 "traceroute6: invalid wait time.\n");
557 "traceroute6: wait must be >= 1 sec.\n");
568 * Open socket to send probe packets.
576 if ((sndsock = socket(AF_INET6, SOCK_RAW, useproto)) < 0) {
577 perror("socket(SOCK_RAW)");
582 fprintf(stderr, "traceroute6: unknown probe protocol %d\n",
586 if (max_hops < first_hop) {
588 "traceroute6: max hoplimit must be larger than first hoplimit.\n");
594 tclass &= ~IPTOS_ECN_MASK;
598 tclass |= IPTOS_ECN_ECT1;
603 if (setresuid(uid, uid, uid) == -1) {
609 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_TCLASS, &tclass,
610 sizeof(int)) == -1) {
611 perror("setsockopt(IPV6_TCLASS)");
616 if (argc < 1 || argc > 2)
620 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
625 memset(&hints, 0, sizeof(hints));
626 hints.ai_family = PF_INET6;
627 hints.ai_socktype = SOCK_RAW;
628 hints.ai_protocol = IPPROTO_ICMPV6;
629 hints.ai_flags = AI_CANONNAME;
631 error = cap_getaddrinfo(capdns, *argv, NULL, &hints, &res);
635 "traceroute6: %s\n", gai_strerror(error));
638 if (res->ai_addrlen != sizeof(Dst)) {
640 "traceroute6: size of sockaddr mismatch\n");
643 memcpy(&Dst, res->ai_addr, res->ai_addrlen);
644 hostname = res->ai_canonname ? strdup(res->ai_canonname) : *argv;
646 fprintf(stderr, "traceroute6: not enough core\n");
650 if (cap_getnameinfo(capdns, res->ai_addr, res->ai_addrlen, hbuf,
651 sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
652 strlcpy(hbuf, "?", sizeof(hbuf));
653 fprintf(stderr, "traceroute6: Warning: %s has multiple "
654 "addresses; using %s\n", hostname, hbuf);
660 datalen = strtoul(*argv, &ep, 0);
663 "traceroute6: invalid packet length.\n");
669 minlen = ICMP6ECHOLEN;
672 minlen = sizeof(struct udphdr);
679 minlen = sizeof(struct sctphdr);
682 minlen = sizeof(struct tcphdr);
685 fprintf(stderr, "traceroute6: unknown probe protocol %d.\n",
689 if (datalen < minlen)
691 else if (datalen >= MAXPACKET) {
693 "traceroute6: packet size must be %zu <= s < %d.\n",
697 if ((useproto == IPPROTO_SCTP) && (datalen & 3)) {
699 "traceroute6: packet size must be a multiple of 4.\n");
702 outpacket = malloc(datalen);
707 (void) bzero((char *)outpacket, datalen);
709 /* initialize msghdr for receiving packets */
710 rcviov[0].iov_base = (caddr_t)packet;
711 rcviov[0].iov_len = sizeof(packet);
712 rcvmhdr.msg_name = (caddr_t)&Rcv;
713 rcvmhdr.msg_namelen = sizeof(Rcv);
714 rcvmhdr.msg_iov = rcviov;
715 rcvmhdr.msg_iovlen = 1;
716 rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
717 CMSG_SPACE(sizeof(int));
718 if ((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) {
719 fprintf(stderr, "traceroute6: malloc failed\n");
722 rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf;
723 rcvmhdr.msg_controllen = rcvcmsglen;
725 if (options & SO_DEBUG)
726 (void) setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG,
727 (char *)&on, sizeof(on));
728 if (options & SO_DONTROUTE)
729 (void) setsockopt(rcvsock, SOL_SOCKET, SO_DONTROUTE,
730 (char *)&on, sizeof(on));
731 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
733 * do not raise error even if setsockopt fails, kernel may have ipsec
736 if (setpolicy(rcvsock, ipsec_inpolicy) < 0)
737 errx(1, "%s", ipsec_strerror());
738 if (setpolicy(rcvsock, ipsec_outpolicy) < 0)
739 errx(1, "%s", ipsec_strerror());
742 int level = IPSEC_LEVEL_NONE;
744 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
746 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
748 #ifdef IP_AUTH_TRANS_LEVEL
749 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
752 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
755 #ifdef IP_AUTH_NETWORK_LEVEL
756 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
760 #endif /* !(IPSEC && IPSEC_POLICY_IPSEC) */
766 if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&i,
768 perror("setsockopt(SO_SNDBUF)");
771 #endif /* SO_SNDBUF */
772 if (options & SO_DEBUG)
773 (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
774 (char *)&on, sizeof(on));
775 if (options & SO_DONTROUTE)
776 (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
777 (char *)&on, sizeof(on));
778 if (rth) {/* XXX: there is no library to finalize the header... */
779 rth->ip6r_len = rth->ip6r_segleft * 2;
780 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_RTHDR,
781 (void *)rth, (rth->ip6r_len + 1) << 3)) {
782 fprintf(stderr, "setsockopt(IPV6_RTHDR): %s\n",
787 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
789 * do not raise error even if setsockopt fails, kernel may have ipsec
792 if (setpolicy(sndsock, ipsec_inpolicy) < 0)
793 errx(1, "%s", ipsec_strerror());
794 if (setpolicy(sndsock, ipsec_outpolicy) < 0)
795 errx(1, "%s", ipsec_strerror());
798 int level = IPSEC_LEVEL_BYPASS;
800 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
802 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
804 #ifdef IP_AUTH_TRANS_LEVEL
805 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
808 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
811 #ifdef IP_AUTH_NETWORK_LEVEL
812 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
816 #endif /* !(IPSEC && IPSEC_POLICY_IPSEC) */
821 bzero(&Src, sizeof(Src));
823 memset(&hints, 0, sizeof(hints));
824 hints.ai_family = AF_INET6;
825 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
826 hints.ai_flags = AI_NUMERICHOST;
827 error = cap_getaddrinfo(capdns, source, "0", &hints, &res);
829 printf("traceroute6: %s: %s\n", source,
830 gai_strerror(error));
833 if (res->ai_addrlen > sizeof(Src)) {
834 printf("traceroute6: %s: %s\n", source,
835 gai_strerror(error));
838 memcpy(&Src, res->ai_addr, res->ai_addrlen);
841 struct sockaddr_in6 Nxt;
846 Nxt.sin6_port = htons(DUMMY_PORT);
848 bcopy(inet6_rthdr_getaddr(cmsg, 1), &Nxt.sin6_addr,
849 sizeof(Nxt.sin6_addr));
850 if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
854 if (connect(dummy, (struct sockaddr *)&Nxt, Nxt.sin6_len) < 0) {
859 if (getsockname(dummy, (struct sockaddr *)&Src, &len) < 0) {
860 perror("getsockname");
863 if (cap_getnameinfo(capdns, (struct sockaddr *)&Src, Src.sin6_len,
864 src0, sizeof(src0), NULL, 0, NI_NUMERICHOST)) {
865 fprintf(stderr, "getnameinfo failed for source\n");
872 Src.sin6_port = htons(0);
873 if (bind(sndsock, (struct sockaddr *)&Src, Src.sin6_len) < 0) {
882 if (getsockname(sndsock, (struct sockaddr *)&Src, &len) < 0) {
883 perror("getsockname");
886 srcport = ntohs(Src.sin6_port);
890 asn = as_setup(as_server);
893 "traceroute6: as_setup failed, AS# lookups"
895 (void)fflush(stderr);
903 if (cap_getnameinfo(capdns, (struct sockaddr *)&Dst, Dst.sin6_len, hbuf,
904 sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
905 strlcpy(hbuf, "(invalid)", sizeof(hbuf));
906 fprintf(stderr, "traceroute6");
907 fprintf(stderr, " to %s (%s)", hostname, hbuf);
909 fprintf(stderr, " from %s", source);
910 fprintf(stderr, ", %lu hops max, %lu byte packets\n",
912 datalen + ((useproto == IPPROTO_UDP) ? sizeof(struct udphdr) : 0));
913 (void) fflush(stderr);
916 printf("Skipping %lu intermediate hops\n", first_hop - 1);
918 if (connect(sndsock, (struct sockaddr *)&Dst,
920 fprintf(stderr, "connect: %s\n", strerror(errno));
925 * Here we enter capability mode. Further down access to global
926 * namespaces (e.g filesystem) is restricted (see capsicum(4)).
927 * We must connect(2) our socket before this point.
929 if (caph_enter_casper() < 0) {
930 fprintf(stderr, "caph_enter_casper: %s\n", strerror(errno));
934 cap_rights_init(&rights, CAP_SEND, CAP_SETSOCKOPT);
935 if (caph_rights_limit(sndsock, &rights) < 0) {
936 fprintf(stderr, "caph_rights_limit sndsock: %s\n",
940 cap_rights_init(&rights, CAP_RECV, CAP_EVENT);
941 if (caph_rights_limit(rcvsock, &rights) < 0) {
942 fprintf(stderr, "caph_rights_limit rcvsock: %s\n",
950 for (hops = first_hop; hops <= max_hops; ++hops) {
951 struct in6_addr lastaddr;
953 unsigned unreachable = 0;
955 printf("%2lu ", hops);
956 bzero(&lastaddr, sizeof(lastaddr));
957 for (probe = 0; probe < nprobes; ++probe) {
959 struct timeval t1, t2;
961 (void) gettimeofday(&t1, NULL);
962 send_probe(++seq, hops);
963 while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) {
964 (void) gettimeofday(&t2, NULL);
965 if (packet_ok(&rcvmhdr, cc, seq, &type, &code, &ecn)) {
966 if (!IN6_ARE_ADDR_EQUAL(&Rcv.sin6_addr,
969 fputs("\n ", stdout);
971 lastaddr = Rcv.sin6_addr;
973 printf(" %.3f ms", deltaT(&t1, &t2));
977 printf(" (ecn=passed)");
979 case IPTOS_ECN_NOTECT:
980 printf(" (ecn=bleached)");
983 printf(" (ecn=congested)");
986 printf(" (ecn=mangled)");
990 if (type == ICMP6_DST_UNREACH) {
992 case ICMP6_DST_UNREACH_NOROUTE:
996 case ICMP6_DST_UNREACH_ADMIN:
1000 case ICMP6_DST_UNREACH_NOTNEIGHBOR:
1004 case ICMP6_DST_UNREACH_ADDR:
1008 case ICMP6_DST_UNREACH_NOPORT:
1015 } else if (type == ICMP6_PARAM_PROB &&
1016 code == ICMP6_PARAMPROB_NEXTHEADER) {
1019 } else if (type == ICMP6_ECHO_REPLY) {
1026 } else if (deltaT(&t1, &t2) > waittime * 1000) {
1033 (void) fflush(stdout);
1037 (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) {
1048 wait_for_reply(int sock, struct msghdr *mhdr)
1051 struct pollfd pfd[1];
1055 pfd[0].events = POLLIN;
1058 if (poll(pfd, 1, waittime * 1000) > 0 &&
1059 pfd[0].revents & POLLIN)
1060 cc = recvmsg(rcvsock, mhdr, 0);
1065 struct timeval wait;
1068 fdsn = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
1069 if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
1071 memset(fdsp, 0, fdsn);
1073 wait.tv_sec = waittime; wait.tv_usec = 0;
1075 if (select(sock + 1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0)
1076 cc = recvmsg(rcvsock, mhdr, 0);
1083 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
1085 setpolicy(int so, char *policy)
1089 buf = ipsec_set_policy(policy, strlen(policy));
1091 warnx("%s", ipsec_strerror());
1094 (void)setsockopt(so, IPPROTO_IPV6, IPV6_IPSEC_POLICY,
1095 buf, ipsec_get_policylen(buf));
1104 send_probe(int seq, u_long hops)
1106 struct icmp6_hdr *icp;
1107 struct sctphdr *sctp;
1108 struct udphdr *outudp;
1109 struct sctp_chunkhdr *chk;
1110 struct sctp_init_chunk *init;
1111 struct sctp_paramhdr *param;
1116 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
1117 (char *)&i, sizeof(i)) < 0) {
1118 perror("setsockopt IPV6_UNICAST_HOPS");
1121 Dst.sin6_port = htons(port + seq);
1124 case IPPROTO_ICMPV6:
1125 icp = (struct icmp6_hdr *)outpacket;
1127 icp->icmp6_type = ICMP6_ECHO_REQUEST;
1128 icp->icmp6_code = 0;
1129 icp->icmp6_cksum = 0;
1130 icp->icmp6_id = ident;
1131 icp->icmp6_seq = htons(seq);
1134 outudp = (struct udphdr *) outpacket;
1135 outudp->uh_sport = htons(ident);
1136 outudp->uh_dport = htons(port + seq);
1137 outudp->uh_ulen = htons(datalen);
1139 outudp->uh_sum = udp_cksum(&Src, &Dst, outpacket, datalen);
1142 /* No space for anything. No harm as seq/tv32 are decorative. */
1145 sctp = (struct sctphdr *)outpacket;
1147 sctp->src_port = htons(ident);
1148 sctp->dest_port = htons(port + seq);
1149 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1150 sizeof(struct sctp_init_chunk))) {
1153 sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port;
1155 sctp->checksum = htonl(0);
1156 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1157 sizeof(struct sctp_init_chunk))) {
1159 * Send a packet containing an INIT chunk. This works
1160 * better in case of firewalls on the path, but
1161 * results in a probe packet containing at least
1162 * 32 bytes of payload. For shorter payloads, use
1163 * SHUTDOWN-ACK chunks.
1165 init = (struct sctp_init_chunk *)(sctp + 1);
1166 init->ch.chunk_type = SCTP_INITIATION;
1167 init->ch.chunk_flags = 0;
1168 init->ch.chunk_length = htons((u_int16_t)(datalen -
1169 sizeof(struct sctphdr)));
1170 init->init.initiate_tag = (sctp->src_port << 16) |
1172 init->init.a_rwnd = htonl(1500);
1173 init->init.num_outbound_streams = htons(1);
1174 init->init.num_inbound_streams = htons(1);
1175 init->init.initial_tsn = htonl(0);
1176 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1177 sizeof(struct sctp_init_chunk) +
1178 sizeof(struct sctp_paramhdr))) {
1179 param = (struct sctp_paramhdr *)(init + 1);
1180 param->param_type = htons(SCTP_PAD);
1181 param->param_length =
1182 htons((u_int16_t)(datalen -
1183 sizeof(struct sctphdr) -
1184 sizeof(struct sctp_init_chunk)));
1188 * Send a packet containing a SHUTDOWN-ACK chunk,
1189 * possibly followed by a PAD chunk.
1191 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1192 sizeof(struct sctp_chunkhdr))) {
1193 chk = (struct sctp_chunkhdr *)(sctp + 1);
1194 chk->chunk_type = SCTP_SHUTDOWN_ACK;
1195 chk->chunk_flags = 0;
1196 chk->chunk_length = htons(4);
1198 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1199 2 * sizeof(struct sctp_chunkhdr))) {
1201 chk->chunk_type = SCTP_PAD_CHUNK;
1202 chk->chunk_flags = 0;
1203 chk->chunk_length = htons((u_int16_t)(datalen -
1204 sizeof(struct sctphdr) -
1205 sizeof(struct sctp_chunkhdr)));
1208 sctp->checksum = sctp_crc32c(outpacket, datalen);
1211 tcp = (struct tcphdr *)outpacket;
1213 tcp->th_sport = htons(ident);
1214 tcp->th_dport = htons(port + seq);
1215 tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
1218 tcp->th_flags = TH_SYN;
1220 tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen);
1223 fprintf(stderr, "Unknown probe protocol %d.\n", useproto);
1227 i = send(sndsock, (char *)outpacket, datalen, 0);
1228 if (i < 0 || (u_long)i != datalen) {
1231 printf("traceroute6: wrote %s %lu chars, ret=%d\n",
1232 hostname, datalen, i);
1233 (void) fflush(stdout);
1238 get_hoplim(struct msghdr *mhdr)
1242 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1243 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1244 if (cm->cmsg_level == IPPROTO_IPV6 &&
1245 cm->cmsg_type == IPV6_HOPLIMIT &&
1246 cm->cmsg_len == CMSG_LEN(sizeof(int)))
1247 return (*(int *)CMSG_DATA(cm));
1254 deltaT(struct timeval *t1p, struct timeval *t2p)
1258 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1259 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1264 * Convert an ICMP "type" field to a printable string.
1269 u_char t = t0 & 0xff;
1273 case ICMP6_DST_UNREACH:
1274 cp = "Destination Unreachable";
1276 case ICMP6_PACKET_TOO_BIG:
1277 cp = "Packet Too Big";
1279 case ICMP6_TIME_EXCEEDED:
1280 cp = "Time Exceeded";
1282 case ICMP6_PARAM_PROB:
1283 cp = "Parameter Problem";
1285 case ICMP6_ECHO_REQUEST:
1286 cp = "Echo Request";
1288 case ICMP6_ECHO_REPLY:
1291 case ICMP6_MEMBERSHIP_QUERY:
1292 cp = "Group Membership Query";
1294 case ICMP6_MEMBERSHIP_REPORT:
1295 cp = "Group Membership Report";
1297 case ICMP6_MEMBERSHIP_REDUCTION:
1298 cp = "Group Membership Reduction";
1300 case ND_ROUTER_SOLICIT:
1301 cp = "Router Solicitation";
1303 case ND_ROUTER_ADVERT:
1304 cp = "Router Advertisement";
1306 case ND_NEIGHBOR_SOLICIT:
1307 cp = "Neighbor Solicitation";
1309 case ND_NEIGHBOR_ADVERT:
1310 cp = "Neighbor Advertisement";
1323 packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code,
1326 struct icmp6_hdr *icp;
1327 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1328 char *buf = (char *)mhdr->msg_iov[0].iov_base;
1331 char hbuf[NI_MAXHOST];
1339 ip = (struct ip6_hdr *) buf;
1340 hlen = sizeof(struct ip6_hdr);
1341 if (cc < hlen + sizeof(struct icmp6_hdr)) {
1343 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1344 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1345 strlcpy(hbuf, "invalid", sizeof(hbuf));
1346 printf("packet too short (%d bytes) from %s\n", cc,
1352 icp = (struct icmp6_hdr *)(buf + hlen);
1354 if (cc < (int)sizeof(struct icmp6_hdr)) {
1356 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1357 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1358 strlcpy(hbuf, "invalid", sizeof(hbuf));
1359 printf("data too short (%d bytes) from %s\n", cc, hbuf);
1363 icp = (struct icmp6_hdr *)buf;
1365 /* get optional information via advanced API */
1368 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1369 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1370 if (cm->cmsg_level == IPPROTO_IPV6 &&
1371 cm->cmsg_type == IPV6_PKTINFO &&
1373 CMSG_LEN(sizeof(struct in6_pktinfo)))
1374 rcvpktinfo = (struct in6_pktinfo *)(CMSG_DATA(cm));
1376 if (cm->cmsg_level == IPPROTO_IPV6 &&
1377 cm->cmsg_type == IPV6_HOPLIMIT &&
1378 cm->cmsg_len == CMSG_LEN(sizeof(int)))
1379 hlimp = (int *)CMSG_DATA(cm);
1381 if (rcvpktinfo == NULL || hlimp == NULL) {
1382 warnx("failed to get received hop limit or packet info");
1386 rcvhlim = 0; /*XXX*/
1391 *type = icp->icmp6_type;
1392 *code = icp->icmp6_code;
1393 if ((*type == ICMP6_TIME_EXCEEDED &&
1394 *code == ICMP6_TIME_EXCEED_TRANSIT) ||
1395 (*type == ICMP6_DST_UNREACH) ||
1396 (*type == ICMP6_PARAM_PROB &&
1397 *code == ICMP6_PARAMPROB_NEXTHEADER)) {
1398 struct ip6_hdr *hip;
1399 struct icmp6_hdr *icmp;
1400 struct sctp_init_chunk *init;
1401 struct sctphdr *sctp;
1406 hip = (struct ip6_hdr *)(icp + 1);
1407 *ecn = ntohl(hip->ip6_flow & IPV6_ECN_MASK) >> 20;
1408 if ((up = get_uphdr(hip, (u_char *)(buf + cc))) == NULL) {
1410 warnx("failed to get upper layer header");
1414 case IPPROTO_ICMPV6:
1415 icmp = (struct icmp6_hdr *)up;
1416 if (icmp->icmp6_id == ident &&
1417 icmp->icmp6_seq == htons(seq))
1421 udp = (struct udphdr *)up;
1422 if (udp->uh_sport == htons(ident) &&
1423 udp->uh_dport == htons(port + seq))
1427 sctp = (struct sctphdr *)up;
1428 if (sctp->src_port != htons(ident) ||
1429 sctp->dest_port != htons(port + seq)) {
1432 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1433 sizeof(struct sctp_init_chunk))) {
1434 if (sctp->v_tag != 0) {
1437 init = (struct sctp_init_chunk *)(sctp + 1);
1438 /* Check the initiate tag, if available. */
1439 if ((char *)&init->init.a_rwnd > buf + cc) {
1442 if (init->init.initiate_tag == (u_int32_t)
1443 ((sctp->src_port << 16) | sctp->dest_port)) {
1448 (u_int32_t)((sctp->src_port << 16) |
1455 tcp = (struct tcphdr *)up;
1456 if (tcp->th_sport == htons(ident) &&
1457 tcp->th_dport == htons(port + seq) &&
1459 (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport))
1465 fprintf(stderr, "Unknown probe proto %d.\n", useproto);
1468 } else if (useproto == IPPROTO_ICMPV6 && *type == ICMP6_ECHO_REPLY) {
1469 if (icp->icmp6_id == ident &&
1470 icp->icmp6_seq == htons(seq))
1474 char sbuf[NI_MAXHOST + 1], dbuf[INET6_ADDRSTRLEN];
1478 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1479 sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0)
1480 strlcpy(sbuf, "invalid", sizeof(sbuf));
1481 printf("\n%d bytes from %s to %s", cc, sbuf,
1482 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1483 dbuf, sizeof(dbuf)) : "?");
1484 printf(": icmp type %d (%s) code %d\n", *type, pr_type(*type),
1486 p = (u_int8_t *)(icp + 1);
1488 for (i = 0; i < cc; i++) {
1493 printf("%02x", p[i]);
1494 if (i % WIDTH == WIDTH - 1)
1497 if (cc % WIDTH != 0)
1504 * Increment pointer until find the UDP or ICMP header.
1507 get_uphdr(struct ip6_hdr *ip6, u_char *lim)
1509 u_char *cp = (u_char *)ip6, nh;
1511 static u_char none_hdr[1]; /* Fake pointer for IPPROTO_NONE. */
1513 if (cp + sizeof(*ip6) > lim)
1517 cp += sizeof(struct ip6_hdr);
1519 while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) {
1523 case IPPROTO_ICMPV6:
1524 return (useproto == nh ? cp : NULL);
1528 return (useproto == nh ? cp : NULL);
1530 return (useproto == nh ? none_hdr : NULL);
1531 case IPPROTO_FRAGMENT:
1532 hlen = sizeof(struct ip6_frag);
1533 nh = ((struct ip6_frag *)cp)->ip6f_nxt;
1536 hlen = (((struct ip6_ext *)cp)->ip6e_len + 2) << 2;
1537 nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1540 hlen = (((struct ip6_ext *)cp)->ip6e_len + 1) << 3;
1541 nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1555 const char *types[] = { "NAME", "ADDR" };
1557 cap_channel_t *casper;
1559 casper = cap_init();
1561 errx(1, "unable to create casper process");
1562 capdns = cap_service_open(casper, "system.dns");
1564 errx(1, "unable to open system.dns service");
1565 if (cap_dns_type_limit(capdns, types, nitems(types)) < 0)
1566 errx(1, "unable to limit access to system.dns service");
1567 families[0] = AF_INET6;
1568 if (cap_dns_family_limit(capdns, families, nitems(families)) < 0)
1569 errx(1, "unable to limit access to system.dns service");
1571 #endif /* WITH_CASPER */
1575 print(struct msghdr *mhdr, int cc)
1577 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1578 char hbuf[NI_MAXHOST];
1580 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1581 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1582 strlcpy(hbuf, "invalid", sizeof(hbuf));
1584 printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6));
1586 printf(" %s", hbuf);
1588 printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf);
1590 printf(" %s", inetname((struct sockaddr *)from));
1594 printf(" %d bytes to %s", cc,
1595 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1596 hbuf, sizeof(hbuf)) : "?");
1598 printf(" %d bytes of data to %s", cc,
1599 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1600 hbuf, sizeof(hbuf)) : "?");
1606 * Construct an Internet address representation.
1607 * If the nflag has been supplied, give
1608 * numeric value, otherwise try for symbolic name.
1611 inetname(struct sockaddr *sa)
1613 static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1];
1614 static int first = 1;
1617 if (first && !nflag) {
1619 if (gethostname(domain, sizeof(domain)) == 0 &&
1620 (cp = strchr(domain, '.')))
1621 (void) strlcpy(domain, cp + 1, sizeof(domain));
1627 if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0,
1628 NI_NAMEREQD) == 0) {
1629 if ((cp = strchr(line, '.')) &&
1630 !strcmp(cp + 1, domain))
1638 if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0,
1639 NI_NUMERICHOST) != 0)
1640 strlcpy(line, "invalid", sizeof(line));
1645 * CRC32C routine for the Stream Control Transmission Protocol
1648 #define CRC32C(c, d) (c = (c >> 8) ^ crc_c[(c ^ (d)) & 0xFF])
1650 static u_int32_t crc_c[256] = {
1651 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
1652 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
1653 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
1654 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
1655 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
1656 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
1657 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
1658 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
1659 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
1660 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
1661 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
1662 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
1663 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
1664 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
1665 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
1666 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
1667 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
1668 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
1669 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
1670 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
1671 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
1672 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
1673 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
1674 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
1675 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
1676 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
1677 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
1678 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
1679 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
1680 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
1681 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
1682 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
1683 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
1684 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
1685 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
1686 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
1687 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
1688 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
1689 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
1690 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
1691 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
1692 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
1693 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
1694 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
1695 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
1696 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
1697 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
1698 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
1699 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
1700 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
1701 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
1702 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
1703 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
1704 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
1705 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
1706 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
1707 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
1708 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
1709 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
1710 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
1711 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
1712 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
1713 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
1714 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
1718 sctp_crc32c(void *pack, u_int32_t len)
1720 u_int32_t i, crc32c;
1721 u_int8_t byte0, byte1, byte2, byte3;
1722 u_int8_t *buf = (u_int8_t *)pack;
1725 for (i = 0; i < len; i++)
1726 CRC32C(crc32c, buf[i]);
1728 byte0 = crc32c & 0xff;
1729 byte1 = (crc32c >> 8) & 0xff;
1730 byte2 = (crc32c >> 16) & 0xff;
1731 byte3 = (crc32c >> 24) & 0xff;
1732 crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
1733 return (htonl(crc32c));
1737 in_cksum(u_int16_t *addr, int len)
1740 u_int16_t *w = addr;
1745 * Our algorithm is simple, using a 32 bit accumulator (sum),
1746 * we add sequential 16 bit words to it, and at the end, fold
1747 * back all the carry bits from the top 16 bits into the lower
1755 /* mop up an odd byte, if necessary */
1757 sum += *(u_char *)w;
1760 * add back carry outs from top 16 bits to low 16 bits
1762 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
1763 sum += (sum >> 16); /* add carry */
1764 answer = ~sum; /* truncate to 16 bits */
1769 udp_cksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1770 void *payload, u_int32_t len)
1773 struct in6_addr src;
1774 struct in6_addr dst;
1781 pseudo_hdr.src = src->sin6_addr;
1782 pseudo_hdr.dst = dst->sin6_addr;
1783 pseudo_hdr.len = htonl(len);
1784 pseudo_hdr.zero[0] = 0;
1785 pseudo_hdr.zero[1] = 0;
1786 pseudo_hdr.zero[2] = 0;
1787 pseudo_hdr.next = IPPROTO_UDP;
1789 sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1790 sum[0] = in_cksum(payload, len);
1792 return (~in_cksum(sum, sizeof(sum)));
1796 tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1797 void *payload, u_int32_t len)
1800 struct in6_addr src;
1801 struct in6_addr dst;
1808 pseudo_hdr.src = src->sin6_addr;
1809 pseudo_hdr.dst = dst->sin6_addr;
1810 pseudo_hdr.len = htonl(len);
1811 pseudo_hdr.zero[0] = 0;
1812 pseudo_hdr.zero[1] = 0;
1813 pseudo_hdr.zero[2] = 0;
1814 pseudo_hdr.next = IPPROTO_TCP;
1816 sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1817 sum[0] = in_cksum(payload, len);
1819 return (~in_cksum(sum, sizeof(sum)));
1827 "usage: traceroute6 [-adEIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n"
1828 " [-m hoplimit] [-p port] [-q probes] [-s src] [-w waittime] target\n"