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 tclass = -1;
350 static int options; /* socket options */
352 static int waittime = 5; /* time to wait for response (in seconds) */
353 static int nflag; /* print addresses numerically */
354 static int useproto = IPPROTO_UDP; /* protocol to use to send packet */
355 static int lflag; /* print both numerical address & hostname */
356 static int as_path; /* print as numbers for each hop */
357 static char *as_server = NULL;
361 main(int argc, char *argv[])
363 int mib[4] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_DEFHLIM };
364 char hbuf[NI_MAXHOST], src0[NI_MAXHOST], *ep;
365 int ch, i, on = 1, seq, rcvcmsglen, error;
366 struct addrinfo hints, *res;
367 static u_char *rcvcmsgbuf;
368 u_long probe, hops, lport, ltclass;
373 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
374 char ipsec_inpolicy[] = "in bypass";
375 char ipsec_outpolicy[] = "out bypass";
384 if ((rcvsock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) {
385 perror("socket(ICMPv6)");
390 (void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &i, &size, NULL, 0);
393 /* specify to tell receiving interface */
394 #ifdef IPV6_RECVPKTINFO
395 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
397 err(1, "setsockopt(IPV6_RECVPKTINFO)");
398 #else /* old adv. API */
399 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_PKTINFO, &on,
401 err(1, "setsockopt(IPV6_PKTINFO)");
404 /* specify to tell value of hoplimit field of received IP6 hdr */
405 #ifdef IPV6_RECVHOPLIMIT
406 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
408 err(1, "setsockopt(IPV6_RECVHOPLIMIT)");
409 #else /* old adv. API */
410 if (setsockopt(rcvsock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on,
412 err(1, "setsockopt(IPV6_HOPLIMIT)");
416 ident = htons(getpid() & 0xffff); /* same as ping6 */
418 while ((ch = getopt(argc, argv, "aA:df:g:Ilm:nNp:q:rs:St:TUvw:")) != -1)
433 first_hop = strtoul(optarg, &ep, 0);
434 if (errno || !*optarg || *ep || first_hop > 255) {
436 "traceroute6: invalid min hoplimit.\n");
441 /* XXX use after capability mode is entered */
442 hp = getipnodebyname(optarg, AF_INET6, 0, &h_errno);
445 "traceroute6: unknown host %s\n", optarg);
450 * XXX: We can't detect the number of
451 * intermediate nodes yet.
453 if ((rth = inet6_rth_init((void *)rtbuf,
454 sizeof(rtbuf), IPV6_RTHDR_TYPE_0,
457 "inet6_rth_init failed.\n");
461 if (inet6_rth_add((void *)rth,
462 (struct in6_addr *)hp->h_addr)) {
464 "inet6_rth_add failed for %s\n",
471 useproto = IPPROTO_ICMPV6;
479 max_hops = strtoul(optarg, &ep, 0);
480 if (errno || !*optarg || *ep || max_hops > 255) {
482 "traceroute6: invalid max hoplimit.\n");
490 useproto = IPPROTO_NONE;
495 lport = strtoul(optarg, &ep, 0);
496 if (errno || !*optarg || *ep) {
497 fprintf(stderr, "traceroute6: invalid port.\n");
500 if (lport == 0 || lport != (lport & 0xffff)) {
502 "traceroute6: port out of range.\n");
505 port = lport & 0xffff;
510 nprobes = strtoul(optarg, &ep, 0);
511 if (errno || !*optarg || *ep) {
513 "traceroute6: invalid nprobes.\n");
518 "traceroute6: nprobes must be >0.\n");
523 options |= SO_DONTROUTE;
527 * set the ip source address of the outbound
528 * probe (e.g., on a multi-homed host).
533 useproto = IPPROTO_SCTP;
538 ltclass = strtoul(optarg, &ep, 0);
539 if (errno || !*optarg || *ep || ltclass > 255) {
541 "traceroute6: invalid traffic class.\n");
544 tclass = (int)ltclass;
547 useproto = IPPROTO_TCP;
550 useproto = IPPROTO_UDP;
558 waittime = strtoul(optarg, &ep, 0);
559 if (errno || !*optarg || *ep) {
561 "traceroute6: invalid wait time.\n");
566 "traceroute6: wait must be >= 1 sec.\n");
577 * Open socket to send probe packets.
587 if ((sndsock = socket(AF_INET6, SOCK_RAW, useproto)) < 0) {
588 perror("socket(SOCK_RAW)");
593 fprintf(stderr, "traceroute6: unknown probe protocol %d\n",
597 if (max_hops < first_hop) {
599 "traceroute6: max hoplimit must be larger than first hoplimit.\n");
605 if (setresuid(uid, uid, uid) == -1) {
611 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_TCLASS, &tclass,
612 sizeof(int)) == -1) {
613 perror("setsockopt(IPV6_TCLASS)");
618 if (argc < 1 || argc > 2)
622 setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
627 memset(&hints, 0, sizeof(hints));
628 hints.ai_family = PF_INET6;
629 hints.ai_socktype = SOCK_RAW;
630 hints.ai_protocol = IPPROTO_ICMPV6;
631 hints.ai_flags = AI_CANONNAME;
633 error = cap_getaddrinfo(capdns, *argv, NULL, &hints, &res);
637 "traceroute6: %s\n", gai_strerror(error));
640 if (res->ai_addrlen != sizeof(Dst)) {
642 "traceroute6: size of sockaddr mismatch\n");
645 memcpy(&Dst, res->ai_addr, res->ai_addrlen);
646 hostname = res->ai_canonname ? strdup(res->ai_canonname) : *argv;
648 fprintf(stderr, "traceroute6: not enough core\n");
652 if (cap_getnameinfo(capdns, res->ai_addr, res->ai_addrlen, hbuf,
653 sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
654 strlcpy(hbuf, "?", sizeof(hbuf));
655 fprintf(stderr, "traceroute6: Warning: %s has multiple "
656 "addresses; using %s\n", hostname, hbuf);
662 datalen = strtoul(*argv, &ep, 0);
665 "traceroute6: invalid packet length.\n");
671 minlen = ICMP6ECHOLEN;
674 minlen = sizeof(struct udphdr);
681 minlen = sizeof(struct sctphdr);
684 minlen = sizeof(struct tcphdr);
687 fprintf(stderr, "traceroute6: unknown probe protocol %d.\n",
691 if (datalen < minlen)
693 else if (datalen >= MAXPACKET) {
695 "traceroute6: packet size must be %zu <= s < %d.\n",
699 if ((useproto == IPPROTO_SCTP) && (datalen & 3)) {
701 "traceroute6: packet size must be a multiple of 4.\n");
704 outpacket = malloc(datalen);
709 (void) bzero((char *)outpacket, datalen);
711 /* initialize msghdr for receiving packets */
712 rcviov[0].iov_base = (caddr_t)packet;
713 rcviov[0].iov_len = sizeof(packet);
714 rcvmhdr.msg_name = (caddr_t)&Rcv;
715 rcvmhdr.msg_namelen = sizeof(Rcv);
716 rcvmhdr.msg_iov = rcviov;
717 rcvmhdr.msg_iovlen = 1;
718 rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
719 CMSG_SPACE(sizeof(int));
720 if ((rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) {
721 fprintf(stderr, "traceroute6: malloc failed\n");
724 rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf;
725 rcvmhdr.msg_controllen = rcvcmsglen;
727 if (options & SO_DEBUG)
728 (void) setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG,
729 (char *)&on, sizeof(on));
730 if (options & SO_DONTROUTE)
731 (void) setsockopt(rcvsock, SOL_SOCKET, SO_DONTROUTE,
732 (char *)&on, sizeof(on));
733 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
735 * do not raise error even if setsockopt fails, kernel may have ipsec
738 if (setpolicy(rcvsock, ipsec_inpolicy) < 0)
739 errx(1, "%s", ipsec_strerror());
740 if (setpolicy(rcvsock, ipsec_outpolicy) < 0)
741 errx(1, "%s", ipsec_strerror());
744 int level = IPSEC_LEVEL_NONE;
746 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
748 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
750 #ifdef IP_AUTH_TRANS_LEVEL
751 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
754 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
757 #ifdef IP_AUTH_NETWORK_LEVEL
758 (void)setsockopt(rcvsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
762 #endif /* !(IPSEC && IPSEC_POLICY_IPSEC) */
768 if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&i,
770 perror("setsockopt(SO_SNDBUF)");
773 #endif /* SO_SNDBUF */
774 if (options & SO_DEBUG)
775 (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
776 (char *)&on, sizeof(on));
777 if (options & SO_DONTROUTE)
778 (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
779 (char *)&on, sizeof(on));
780 if (rth) {/* XXX: there is no library to finalize the header... */
781 rth->ip6r_len = rth->ip6r_segleft * 2;
782 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_RTHDR,
783 (void *)rth, (rth->ip6r_len + 1) << 3)) {
784 fprintf(stderr, "setsockopt(IPV6_RTHDR): %s\n",
789 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
791 * do not raise error even if setsockopt fails, kernel may have ipsec
794 if (setpolicy(sndsock, ipsec_inpolicy) < 0)
795 errx(1, "%s", ipsec_strerror());
796 if (setpolicy(sndsock, ipsec_outpolicy) < 0)
797 errx(1, "%s", ipsec_strerror());
800 int level = IPSEC_LEVEL_BYPASS;
802 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL, &level,
804 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_ESP_NETWORK_LEVEL, &level,
806 #ifdef IP_AUTH_TRANS_LEVEL
807 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL, &level,
810 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_LEVEL, &level,
813 #ifdef IP_AUTH_NETWORK_LEVEL
814 (void)setsockopt(sndsock, IPPROTO_IPV6, IPV6_AUTH_NETWORK_LEVEL, &level,
818 #endif /* !(IPSEC && IPSEC_POLICY_IPSEC) */
823 bzero(&Src, sizeof(Src));
825 memset(&hints, 0, sizeof(hints));
826 hints.ai_family = AF_INET6;
827 hints.ai_socktype = SOCK_DGRAM; /*dummy*/
828 hints.ai_flags = AI_NUMERICHOST;
829 error = cap_getaddrinfo(capdns, source, "0", &hints, &res);
831 printf("traceroute6: %s: %s\n", source,
832 gai_strerror(error));
835 if (res->ai_addrlen > sizeof(Src)) {
836 printf("traceroute6: %s: %s\n", source,
837 gai_strerror(error));
840 memcpy(&Src, res->ai_addr, res->ai_addrlen);
843 struct sockaddr_in6 Nxt;
848 Nxt.sin6_port = htons(DUMMY_PORT);
850 bcopy(inet6_rthdr_getaddr(cmsg, 1), &Nxt.sin6_addr,
851 sizeof(Nxt.sin6_addr));
852 if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
856 if (connect(dummy, (struct sockaddr *)&Nxt, Nxt.sin6_len) < 0) {
861 if (getsockname(dummy, (struct sockaddr *)&Src, &len) < 0) {
862 perror("getsockname");
865 if (cap_getnameinfo(capdns, (struct sockaddr *)&Src, Src.sin6_len,
866 src0, sizeof(src0), NULL, 0, NI_NUMERICHOST)) {
867 fprintf(stderr, "getnameinfo failed for source\n");
874 Src.sin6_port = htons(0);
875 if (bind(sndsock, (struct sockaddr *)&Src, Src.sin6_len) < 0) {
884 if (getsockname(sndsock, (struct sockaddr *)&Src, &len) < 0) {
885 perror("getsockname");
888 srcport = ntohs(Src.sin6_port);
892 asn = as_setup(as_server);
895 "traceroute6: as_setup failed, AS# lookups"
897 (void)fflush(stderr);
905 if (cap_getnameinfo(capdns, (struct sockaddr *)&Dst, Dst.sin6_len, hbuf,
906 sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
907 strlcpy(hbuf, "(invalid)", sizeof(hbuf));
908 fprintf(stderr, "traceroute6");
909 fprintf(stderr, " to %s (%s)", hostname, hbuf);
911 fprintf(stderr, " from %s", source);
912 fprintf(stderr, ", %lu hops max, %lu byte packets\n",
914 datalen + ((useproto == IPPROTO_UDP) ? sizeof(struct udphdr) : 0));
915 (void) fflush(stderr);
918 printf("Skipping %lu intermediate hops\n", first_hop - 1);
920 if (connect(sndsock, (struct sockaddr *)&Dst,
922 fprintf(stderr, "connect: %s\n", strerror(errno));
927 * Here we enter capability mode. Further down access to global
928 * namespaces (e.g filesystem) is restricted (see capsicum(4)).
929 * We must connect(2) our socket before this point.
932 if (caph_enter_casper() < 0) {
933 fprintf(stderr, "caph_enter_casper: %s\n", strerror(errno));
937 cap_rights_init(&rights, CAP_SEND, CAP_SETSOCKOPT);
938 if (caph_rights_limit(sndsock, &rights) < 0) {
939 fprintf(stderr, "caph_rights_limit sndsock: %s\n",
947 for (hops = first_hop; hops <= max_hops; ++hops) {
948 struct in6_addr lastaddr;
950 unsigned unreachable = 0;
952 printf("%2lu ", hops);
953 bzero(&lastaddr, sizeof(lastaddr));
954 for (probe = 0; probe < nprobes; ++probe) {
956 struct timeval t1, t2;
958 (void) gettimeofday(&t1, NULL);
959 send_probe(++seq, hops);
960 while ((cc = wait_for_reply(rcvsock, &rcvmhdr))) {
961 (void) gettimeofday(&t2, NULL);
962 if (packet_ok(&rcvmhdr, cc, seq, &type, &code)) {
963 if (!IN6_ARE_ADDR_EQUAL(&Rcv.sin6_addr,
966 fputs("\n ", stdout);
968 lastaddr = Rcv.sin6_addr;
970 printf(" %.3f ms", deltaT(&t1, &t2));
971 if (type == ICMP6_DST_UNREACH) {
973 case ICMP6_DST_UNREACH_NOROUTE:
977 case ICMP6_DST_UNREACH_ADMIN:
981 case ICMP6_DST_UNREACH_NOTNEIGHBOR:
985 case ICMP6_DST_UNREACH_ADDR:
989 case ICMP6_DST_UNREACH_NOPORT:
996 } else if (type == ICMP6_PARAM_PROB &&
997 code == ICMP6_PARAMPROB_NEXTHEADER) {
1000 } else if (type == ICMP6_ECHO_REPLY) {
1007 } else if (deltaT(&t1, &t2) > waittime * 1000) {
1014 (void) fflush(stdout);
1018 (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) {
1029 wait_for_reply(int sock, struct msghdr *mhdr)
1032 struct pollfd pfd[1];
1036 pfd[0].events = POLLIN;
1039 if (poll(pfd, 1, waittime * 1000) > 0)
1040 cc = recvmsg(rcvsock, mhdr, 0);
1045 struct timeval wait;
1048 fdsn = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
1049 if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
1051 memset(fdsp, 0, fdsn);
1053 wait.tv_sec = waittime; wait.tv_usec = 0;
1055 if (select(sock+1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0)
1056 cc = recvmsg(rcvsock, mhdr, 0);
1063 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
1065 setpolicy(int so, char *policy)
1069 buf = ipsec_set_policy(policy, strlen(policy));
1071 warnx("%s", ipsec_strerror());
1074 (void)setsockopt(so, IPPROTO_IPV6, IPV6_IPSEC_POLICY,
1075 buf, ipsec_get_policylen(buf));
1084 send_probe(int seq, u_long hops)
1086 struct icmp6_hdr *icp;
1087 struct sctphdr *sctp;
1088 struct udphdr *outudp;
1089 struct sctp_chunkhdr *chk;
1090 struct sctp_init_chunk *init;
1091 struct sctp_paramhdr *param;
1096 if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
1097 (char *)&i, sizeof(i)) < 0) {
1098 perror("setsockopt IPV6_UNICAST_HOPS");
1101 Dst.sin6_port = htons(port + seq);
1104 case IPPROTO_ICMPV6:
1105 icp = (struct icmp6_hdr *)outpacket;
1107 icp->icmp6_type = ICMP6_ECHO_REQUEST;
1108 icp->icmp6_code = 0;
1109 icp->icmp6_cksum = 0;
1110 icp->icmp6_id = ident;
1111 icp->icmp6_seq = htons(seq);
1114 outudp = (struct udphdr *) outpacket;
1115 outudp->uh_sport = htons(ident);
1116 outudp->uh_dport = htons(port+seq);
1117 outudp->uh_ulen = htons(datalen);
1118 outudp->uh_sum = udp_cksum(&Src, &Dst, outpacket, datalen);
1121 /* No space for anything. No harm as seq/tv32 are decorative. */
1124 sctp = (struct sctphdr *)outpacket;
1126 sctp->src_port = htons(ident);
1127 sctp->dest_port = htons(port + seq);
1128 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1129 sizeof(struct sctp_init_chunk))) {
1132 sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port;
1134 sctp->checksum = htonl(0);
1135 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1136 sizeof(struct sctp_init_chunk))) {
1138 * Send a packet containing an INIT chunk. This works
1139 * better in case of firewalls on the path, but
1140 * results in a probe packet containing at least
1141 * 32 bytes of payload. For shorter payloads, use
1142 * SHUTDOWN-ACK chunks.
1144 init = (struct sctp_init_chunk *)(sctp + 1);
1145 init->ch.chunk_type = SCTP_INITIATION;
1146 init->ch.chunk_flags = 0;
1147 init->ch.chunk_length = htons((u_int16_t)(datalen -
1148 sizeof(struct sctphdr)));
1149 init->init.initiate_tag = (sctp->src_port << 16) |
1151 init->init.a_rwnd = htonl(1500);
1152 init->init.num_outbound_streams = htons(1);
1153 init->init.num_inbound_streams = htons(1);
1154 init->init.initial_tsn = htonl(0);
1155 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1156 sizeof(struct sctp_init_chunk) +
1157 sizeof(struct sctp_paramhdr))) {
1158 param = (struct sctp_paramhdr *)(init + 1);
1159 param->param_type = htons(SCTP_PAD);
1160 param->param_length =
1161 htons((u_int16_t)(datalen -
1162 sizeof(struct sctphdr) -
1163 sizeof(struct sctp_init_chunk)));
1167 * Send a packet containing a SHUTDOWN-ACK chunk,
1168 * possibly followed by a PAD chunk.
1170 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1171 sizeof(struct sctp_chunkhdr))) {
1172 chk = (struct sctp_chunkhdr *)(sctp + 1);
1173 chk->chunk_type = SCTP_SHUTDOWN_ACK;
1174 chk->chunk_flags = 0;
1175 chk->chunk_length = htons(4);
1177 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1178 2 * sizeof(struct sctp_chunkhdr))) {
1180 chk->chunk_type = SCTP_PAD_CHUNK;
1181 chk->chunk_flags = 0;
1182 chk->chunk_length = htons((u_int16_t)(datalen -
1183 sizeof(struct sctphdr) -
1184 sizeof(struct sctp_chunkhdr)));
1187 sctp->checksum = sctp_crc32c(outpacket, datalen);
1190 tcp = (struct tcphdr *)outpacket;
1192 tcp->th_sport = htons(ident);
1193 tcp->th_dport = htons(port + seq);
1194 tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
1197 tcp->th_flags = TH_SYN;
1199 tcp->th_sum = tcp_chksum(&Src, &Dst, outpacket, datalen);
1202 fprintf(stderr, "Unknown probe protocol %d.\n", useproto);
1206 i = send(sndsock, (char *)outpacket, datalen, 0);
1207 if (i < 0 || (u_long)i != datalen) {
1210 printf("traceroute6: wrote %s %lu chars, ret=%d\n",
1211 hostname, datalen, i);
1212 (void) fflush(stdout);
1217 get_hoplim(struct msghdr *mhdr)
1221 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1222 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1223 if (cm->cmsg_level == IPPROTO_IPV6 &&
1224 cm->cmsg_type == IPV6_HOPLIMIT &&
1225 cm->cmsg_len == CMSG_LEN(sizeof(int)))
1226 return (*(int *)CMSG_DATA(cm));
1233 deltaT(struct timeval *t1p, struct timeval *t2p)
1237 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1238 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1243 * Convert an ICMP "type" field to a printable string.
1248 u_char t = t0 & 0xff;
1252 case ICMP6_DST_UNREACH:
1253 cp = "Destination Unreachable";
1255 case ICMP6_PACKET_TOO_BIG:
1256 cp = "Packet Too Big";
1258 case ICMP6_TIME_EXCEEDED:
1259 cp = "Time Exceeded";
1261 case ICMP6_PARAM_PROB:
1262 cp = "Parameter Problem";
1264 case ICMP6_ECHO_REQUEST:
1265 cp = "Echo Request";
1267 case ICMP6_ECHO_REPLY:
1270 case ICMP6_MEMBERSHIP_QUERY:
1271 cp = "Group Membership Query";
1273 case ICMP6_MEMBERSHIP_REPORT:
1274 cp = "Group Membership Report";
1276 case ICMP6_MEMBERSHIP_REDUCTION:
1277 cp = "Group Membership Reduction";
1279 case ND_ROUTER_SOLICIT:
1280 cp = "Router Solicitation";
1282 case ND_ROUTER_ADVERT:
1283 cp = "Router Advertisement";
1285 case ND_NEIGHBOR_SOLICIT:
1286 cp = "Neighbor Solicitation";
1288 case ND_NEIGHBOR_ADVERT:
1289 cp = "Neighbor Advertisement";
1302 packet_ok(struct msghdr *mhdr, int cc, int seq, u_char *type, u_char *code)
1304 struct icmp6_hdr *icp;
1305 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1306 char *buf = (char *)mhdr->msg_iov[0].iov_base;
1309 char hbuf[NI_MAXHOST];
1317 ip = (struct ip6_hdr *) buf;
1318 hlen = sizeof(struct ip6_hdr);
1319 if (cc < hlen + sizeof(struct icmp6_hdr)) {
1321 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1322 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1323 strlcpy(hbuf, "invalid", sizeof(hbuf));
1324 printf("packet too short (%d bytes) from %s\n", cc,
1330 icp = (struct icmp6_hdr *)(buf + hlen);
1332 if (cc < (int)sizeof(struct icmp6_hdr)) {
1334 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1335 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1336 strlcpy(hbuf, "invalid", sizeof(hbuf));
1337 printf("data too short (%d bytes) from %s\n", cc, hbuf);
1341 icp = (struct icmp6_hdr *)buf;
1343 /* get optional information via advanced API */
1346 for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(mhdr); cm;
1347 cm = (struct cmsghdr *)CMSG_NXTHDR(mhdr, cm)) {
1348 if (cm->cmsg_level == IPPROTO_IPV6 &&
1349 cm->cmsg_type == IPV6_PKTINFO &&
1351 CMSG_LEN(sizeof(struct in6_pktinfo)))
1352 rcvpktinfo = (struct in6_pktinfo *)(CMSG_DATA(cm));
1354 if (cm->cmsg_level == IPPROTO_IPV6 &&
1355 cm->cmsg_type == IPV6_HOPLIMIT &&
1356 cm->cmsg_len == CMSG_LEN(sizeof(int)))
1357 hlimp = (int *)CMSG_DATA(cm);
1359 if (rcvpktinfo == NULL || hlimp == NULL) {
1360 warnx("failed to get received hop limit or packet info");
1364 rcvhlim = 0; /*XXX*/
1370 *type = icp->icmp6_type;
1371 *code = icp->icmp6_code;
1372 if ((*type == ICMP6_TIME_EXCEEDED &&
1373 *code == ICMP6_TIME_EXCEED_TRANSIT) ||
1374 (*type == ICMP6_DST_UNREACH) ||
1375 (*type == ICMP6_PARAM_PROB &&
1376 *code == ICMP6_PARAMPROB_NEXTHEADER)) {
1377 struct ip6_hdr *hip;
1378 struct icmp6_hdr *icmp;
1379 struct sctp_init_chunk *init;
1380 struct sctphdr *sctp;
1385 hip = (struct ip6_hdr *)(icp + 1);
1386 if ((up = get_uphdr(hip, (u_char *)(buf + cc))) == NULL) {
1388 warnx("failed to get upper layer header");
1392 case IPPROTO_ICMPV6:
1393 icmp = (struct icmp6_hdr *)up;
1394 if (icmp->icmp6_id == ident &&
1395 icmp->icmp6_seq == htons(seq))
1399 udp = (struct udphdr *)up;
1400 if (udp->uh_sport == htons(ident) &&
1401 udp->uh_dport == htons(port + seq))
1405 sctp = (struct sctphdr *)up;
1406 if (sctp->src_port != htons(ident) ||
1407 sctp->dest_port != htons(port + seq)) {
1410 if (datalen >= (u_long)(sizeof(struct sctphdr) +
1411 sizeof(struct sctp_init_chunk))) {
1412 if (sctp->v_tag != 0) {
1415 init = (struct sctp_init_chunk *)(sctp + 1);
1416 /* Check the initiate tag, if available. */
1417 if ((char *)&init->init.a_rwnd > buf + cc) {
1420 if (init->init.initiate_tag == (u_int32_t)
1421 ((sctp->src_port << 16) | sctp->dest_port)) {
1426 (u_int32_t)((sctp->src_port << 16) |
1433 tcp = (struct tcphdr *)up;
1434 if (tcp->th_sport == htons(ident) &&
1435 tcp->th_dport == htons(port + seq) &&
1437 (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport))
1443 fprintf(stderr, "Unknown probe proto %d.\n", useproto);
1446 } else if (useproto == IPPROTO_ICMPV6 && *type == ICMP6_ECHO_REPLY) {
1447 if (icp->icmp6_id == ident &&
1448 icp->icmp6_seq == htons(seq))
1452 char sbuf[NI_MAXHOST+1], dbuf[INET6_ADDRSTRLEN];
1456 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1457 sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0)
1458 strlcpy(sbuf, "invalid", sizeof(sbuf));
1459 printf("\n%d bytes from %s to %s", cc, sbuf,
1460 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1461 dbuf, sizeof(dbuf)) : "?");
1462 printf(": icmp type %d (%s) code %d\n", *type, pr_type(*type),
1464 p = (u_int8_t *)(icp + 1);
1466 for (i = 0; i < cc; i++) {
1471 printf("%02x", p[i]);
1472 if (i % WIDTH == WIDTH - 1)
1475 if (cc % WIDTH != 0)
1482 * Increment pointer until find the UDP or ICMP header.
1485 get_uphdr(struct ip6_hdr *ip6, u_char *lim)
1487 u_char *cp = (u_char *)ip6, nh;
1489 static u_char none_hdr[1]; /* Fake pointer for IPPROTO_NONE. */
1491 if (cp + sizeof(*ip6) > lim)
1495 cp += sizeof(struct ip6_hdr);
1497 while (lim - cp >= (nh == IPPROTO_NONE ? 0 : 8)) {
1501 case IPPROTO_ICMPV6:
1502 return (useproto == nh ? cp : NULL);
1506 return (useproto == nh ? cp : NULL);
1508 return (useproto == nh ? none_hdr : NULL);
1509 case IPPROTO_FRAGMENT:
1510 hlen = sizeof(struct ip6_frag);
1511 nh = ((struct ip6_frag *)cp)->ip6f_nxt;
1514 hlen = (((struct ip6_ext *)cp)->ip6e_len + 2) << 2;
1515 nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1518 hlen = (((struct ip6_ext *)cp)->ip6e_len + 1) << 3;
1519 nh = ((struct ip6_ext *)cp)->ip6e_nxt;
1533 const char *types[] = { "NAME", "ADDR" };
1535 cap_channel_t *casper;
1537 casper = cap_init();
1539 errx(1, "unable to create casper process");
1540 capdns = cap_service_open(casper, "system.dns");
1542 errx(1, "unable to open system.dns service");
1543 if (cap_dns_type_limit(capdns, types, nitems(types)) < 0)
1544 errx(1, "unable to limit access to system.dns service");
1545 families[0] = AF_INET6;
1546 if (cap_dns_family_limit(capdns, families, nitems(families)) < 0)
1547 errx(1, "unable to limit access to system.dns service");
1549 #endif /* WITH_CASPER */
1553 print(struct msghdr *mhdr, int cc)
1555 struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
1556 char hbuf[NI_MAXHOST];
1558 if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
1559 hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
1560 strlcpy(hbuf, "invalid", sizeof(hbuf));
1562 printf(" [AS%u]", as_lookup(asn, hbuf, AF_INET6));
1564 printf(" %s", hbuf);
1566 printf(" %s (%s)", inetname((struct sockaddr *)from), hbuf);
1568 printf(" %s", inetname((struct sockaddr *)from));
1572 printf(" %d bytes to %s", cc,
1573 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1574 hbuf, sizeof(hbuf)) : "?");
1576 printf(" %d bytes of data to %s", cc,
1577 rcvpktinfo ? inet_ntop(AF_INET6, &rcvpktinfo->ipi6_addr,
1578 hbuf, sizeof(hbuf)) : "?");
1584 * Construct an Internet address representation.
1585 * If the nflag has been supplied, give
1586 * numeric value, otherwise try for symbolic name.
1589 inetname(struct sockaddr *sa)
1591 static char line[NI_MAXHOST], domain[MAXHOSTNAMELEN + 1];
1592 static int first = 1;
1595 if (first && !nflag) {
1597 if (gethostname(domain, sizeof(domain)) == 0 &&
1598 (cp = strchr(domain, '.')))
1599 (void) strlcpy(domain, cp + 1, sizeof(domain));
1605 if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0,
1606 NI_NAMEREQD) == 0) {
1607 if ((cp = strchr(line, '.')) &&
1608 !strcmp(cp + 1, domain))
1616 if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0,
1617 NI_NUMERICHOST) != 0)
1618 strlcpy(line, "invalid", sizeof(line));
1623 * CRC32C routine for the Stream Control Transmission Protocol
1626 #define CRC32C(c, d) (c = (c>>8) ^ crc_c[(c^(d))&0xFF])
1628 static u_int32_t crc_c[256] = {
1629 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
1630 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
1631 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
1632 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
1633 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
1634 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
1635 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
1636 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
1637 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
1638 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
1639 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
1640 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
1641 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
1642 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
1643 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
1644 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
1645 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
1646 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
1647 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
1648 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
1649 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
1650 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
1651 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
1652 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
1653 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
1654 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
1655 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
1656 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
1657 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
1658 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
1659 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
1660 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
1661 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
1662 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
1663 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
1664 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
1665 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
1666 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
1667 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
1668 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
1669 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
1670 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
1671 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
1672 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
1673 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
1674 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
1675 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
1676 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
1677 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
1678 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
1679 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
1680 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
1681 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
1682 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
1683 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
1684 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
1685 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
1686 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
1687 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
1688 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
1689 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
1690 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
1691 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
1692 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
1696 sctp_crc32c(void *pack, u_int32_t len)
1698 u_int32_t i, crc32c;
1699 u_int8_t byte0, byte1, byte2, byte3;
1700 u_int8_t *buf = (u_int8_t *)pack;
1703 for (i = 0; i < len; i++)
1704 CRC32C(crc32c, buf[i]);
1706 byte0 = crc32c & 0xff;
1707 byte1 = (crc32c>>8) & 0xff;
1708 byte2 = (crc32c>>16) & 0xff;
1709 byte3 = (crc32c>>24) & 0xff;
1710 crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
1711 return htonl(crc32c);
1715 in_cksum(u_int16_t *addr, int len)
1718 u_int16_t *w = addr;
1723 * Our algorithm is simple, using a 32 bit accumulator (sum),
1724 * we add sequential 16 bit words to it, and at the end, fold
1725 * back all the carry bits from the top 16 bits into the lower
1733 /* mop up an odd byte, if necessary */
1735 sum += *(u_char *)w;
1738 * add back carry outs from top 16 bits to low 16 bits
1740 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
1741 sum += (sum >> 16); /* add carry */
1742 answer = ~sum; /* truncate to 16 bits */
1747 udp_cksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1748 void *payload, u_int32_t len)
1751 struct in6_addr src;
1752 struct in6_addr dst;
1759 pseudo_hdr.src = src->sin6_addr;
1760 pseudo_hdr.dst = dst->sin6_addr;
1761 pseudo_hdr.len = htonl(len);
1762 pseudo_hdr.zero[0] = 0;
1763 pseudo_hdr.zero[1] = 0;
1764 pseudo_hdr.zero[2] = 0;
1765 pseudo_hdr.next = IPPROTO_UDP;
1767 sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1768 sum[0] = in_cksum(payload, len);
1770 return (~in_cksum(sum, sizeof(sum)));
1774 tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
1775 void *payload, u_int32_t len)
1778 struct in6_addr src;
1779 struct in6_addr dst;
1786 pseudo_hdr.src = src->sin6_addr;
1787 pseudo_hdr.dst = dst->sin6_addr;
1788 pseudo_hdr.len = htonl(len);
1789 pseudo_hdr.zero[0] = 0;
1790 pseudo_hdr.zero[1] = 0;
1791 pseudo_hdr.zero[2] = 0;
1792 pseudo_hdr.next = IPPROTO_TCP;
1794 sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
1795 sum[0] = in_cksum(payload, len);
1797 return (~in_cksum(sum, sizeof(sum)));
1805 "usage: traceroute6 [-adIlnNrSTUv] [-A as_server] [-f firsthop] [-g gateway]\n"
1806 " [-m hoplimit] [-p port] [-q probes] [-s src] [-w waittime] target\n"