1*bd1f8aebSAndroid Build Coastguard Worker /*
2*bd1f8aebSAndroid Build Coastguard Worker * Modified for NRL 4.4BSD IPv6 release.
3*bd1f8aebSAndroid Build Coastguard Worker * 07/31/96 bgp
4*bd1f8aebSAndroid Build Coastguard Worker *
5*bd1f8aebSAndroid Build Coastguard Worker * Search for "#ifdef NRL" to find the changes.
6*bd1f8aebSAndroid Build Coastguard Worker */
7*bd1f8aebSAndroid Build Coastguard Worker
8*bd1f8aebSAndroid Build Coastguard Worker /*
9*bd1f8aebSAndroid Build Coastguard Worker * Modified for Linux IPv6 by Pedro Roque <[email protected]>
10*bd1f8aebSAndroid Build Coastguard Worker * 31/07/1996
11*bd1f8aebSAndroid Build Coastguard Worker *
12*bd1f8aebSAndroid Build Coastguard Worker * As ICMP error messages for IPv6 now include more than 8 bytes
13*bd1f8aebSAndroid Build Coastguard Worker * UDP datagrams are now sent via an UDP socket instead of magic
14*bd1f8aebSAndroid Build Coastguard Worker * RAW socket tricks.
15*bd1f8aebSAndroid Build Coastguard Worker *
16*bd1f8aebSAndroid Build Coastguard Worker * Original copyright and comments left intact. They might not
17*bd1f8aebSAndroid Build Coastguard Worker * match the code anymore.
18*bd1f8aebSAndroid Build Coastguard Worker */
19*bd1f8aebSAndroid Build Coastguard Worker
20*bd1f8aebSAndroid Build Coastguard Worker /*-
21*bd1f8aebSAndroid Build Coastguard Worker * Copyright (c) 1990, 1993
22*bd1f8aebSAndroid Build Coastguard Worker * The Regents of the University of California. All rights reserved.
23*bd1f8aebSAndroid Build Coastguard Worker *
24*bd1f8aebSAndroid Build Coastguard Worker * This code is derived from software contributed to Berkeley by
25*bd1f8aebSAndroid Build Coastguard Worker * Van Jacobson.
26*bd1f8aebSAndroid Build Coastguard Worker *
27*bd1f8aebSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
28*bd1f8aebSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
29*bd1f8aebSAndroid Build Coastguard Worker * are met:
30*bd1f8aebSAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
31*bd1f8aebSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
32*bd1f8aebSAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
33*bd1f8aebSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
34*bd1f8aebSAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
35*bd1f8aebSAndroid Build Coastguard Worker * 3. All advertising materials mentioning features or use of this software
36*bd1f8aebSAndroid Build Coastguard Worker * must display the following acknowledgement:
37*bd1f8aebSAndroid Build Coastguard Worker * This product includes software developed by the University of
38*bd1f8aebSAndroid Build Coastguard Worker * California, Berkeley and its contributors.
39*bd1f8aebSAndroid Build Coastguard Worker * 4. Neither the name of the University nor the names of its contributors
40*bd1f8aebSAndroid Build Coastguard Worker * may be used to endorse or promote products derived from this software
41*bd1f8aebSAndroid Build Coastguard Worker * without specific prior written permission.
42*bd1f8aebSAndroid Build Coastguard Worker *
43*bd1f8aebSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
44*bd1f8aebSAndroid Build Coastguard Worker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45*bd1f8aebSAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46*bd1f8aebSAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
47*bd1f8aebSAndroid Build Coastguard Worker * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48*bd1f8aebSAndroid Build Coastguard Worker * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49*bd1f8aebSAndroid Build Coastguard Worker * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50*bd1f8aebSAndroid Build Coastguard Worker * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51*bd1f8aebSAndroid Build Coastguard Worker * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52*bd1f8aebSAndroid Build Coastguard Worker * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53*bd1f8aebSAndroid Build Coastguard Worker * SUCH DAMAGE.
54*bd1f8aebSAndroid Build Coastguard Worker */
55*bd1f8aebSAndroid Build Coastguard Worker
56*bd1f8aebSAndroid Build Coastguard Worker #ifndef lint
57*bd1f8aebSAndroid Build Coastguard Worker char copyright[] =
58*bd1f8aebSAndroid Build Coastguard Worker "@(#) Copyright (c) 1990, 1993\n\
59*bd1f8aebSAndroid Build Coastguard Worker The Regents of the University of California. All rights reserved.\n";
60*bd1f8aebSAndroid Build Coastguard Worker #endif /* not lint */
61*bd1f8aebSAndroid Build Coastguard Worker
62*bd1f8aebSAndroid Build Coastguard Worker /*
63*bd1f8aebSAndroid Build Coastguard Worker * traceroute host - trace the route ip packets follow going to "host".
64*bd1f8aebSAndroid Build Coastguard Worker *
65*bd1f8aebSAndroid Build Coastguard Worker * Attempt to trace the route an ip packet would follow to some
66*bd1f8aebSAndroid Build Coastguard Worker * internet host. We find out intermediate hops by launching probe
67*bd1f8aebSAndroid Build Coastguard Worker * packets with a small ttl (time to live) then listening for an
68*bd1f8aebSAndroid Build Coastguard Worker * icmp "time exceeded" reply from a gateway. We start our probes
69*bd1f8aebSAndroid Build Coastguard Worker * with a ttl of one and increase by one until we get an icmp "port
70*bd1f8aebSAndroid Build Coastguard Worker * unreachable" (which means we got to "host") or hit a max (which
71*bd1f8aebSAndroid Build Coastguard Worker * defaults to 30 hops & can be changed with the -m flag). Three
72*bd1f8aebSAndroid Build Coastguard Worker * probes (change with -q flag) are sent at each ttl setting and a
73*bd1f8aebSAndroid Build Coastguard Worker * line is printed showing the ttl, address of the gateway and
74*bd1f8aebSAndroid Build Coastguard Worker * round trip time of each probe. If the probe answers come from
75*bd1f8aebSAndroid Build Coastguard Worker * different gateways, the address of each responding system will
76*bd1f8aebSAndroid Build Coastguard Worker * be printed. If there is no response within a 5 sec. timeout
77*bd1f8aebSAndroid Build Coastguard Worker * interval (changed with the -w flag), a "*" is printed for that
78*bd1f8aebSAndroid Build Coastguard Worker * probe.
79*bd1f8aebSAndroid Build Coastguard Worker *
80*bd1f8aebSAndroid Build Coastguard Worker * Probe packets are UDP format. We don't want the destination
81*bd1f8aebSAndroid Build Coastguard Worker * host to process them so the destination port is set to an
82*bd1f8aebSAndroid Build Coastguard Worker * unlikely value (if some clod on the destination is using that
83*bd1f8aebSAndroid Build Coastguard Worker * value, it can be changed with the -p flag).
84*bd1f8aebSAndroid Build Coastguard Worker *
85*bd1f8aebSAndroid Build Coastguard Worker * A sample use might be:
86*bd1f8aebSAndroid Build Coastguard Worker *
87*bd1f8aebSAndroid Build Coastguard Worker * [yak 71]% traceroute nis.nsf.net.
88*bd1f8aebSAndroid Build Coastguard Worker * traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 56 byte packet
89*bd1f8aebSAndroid Build Coastguard Worker * 1 helios.ee.lbl.gov (128.3.112.1) 19 ms 19 ms 0 ms
90*bd1f8aebSAndroid Build Coastguard Worker * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
91*bd1f8aebSAndroid Build Coastguard Worker * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
92*bd1f8aebSAndroid Build Coastguard Worker * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 39 ms
93*bd1f8aebSAndroid Build Coastguard Worker * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 39 ms 39 ms 39 ms
94*bd1f8aebSAndroid Build Coastguard Worker * 6 128.32.197.4 (128.32.197.4) 40 ms 59 ms 59 ms
95*bd1f8aebSAndroid Build Coastguard Worker * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 59 ms
96*bd1f8aebSAndroid Build Coastguard Worker * 8 129.140.70.13 (129.140.70.13) 99 ms 99 ms 80 ms
97*bd1f8aebSAndroid Build Coastguard Worker * 9 129.140.71.6 (129.140.71.6) 139 ms 239 ms 319 ms
98*bd1f8aebSAndroid Build Coastguard Worker * 10 129.140.81.7 (129.140.81.7) 220 ms 199 ms 199 ms
99*bd1f8aebSAndroid Build Coastguard Worker * 11 nic.merit.edu (35.1.1.48) 239 ms 239 ms 239 ms
100*bd1f8aebSAndroid Build Coastguard Worker *
101*bd1f8aebSAndroid Build Coastguard Worker * Note that lines 2 & 3 are the same. This is due to a buggy
102*bd1f8aebSAndroid Build Coastguard Worker * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
103*bd1f8aebSAndroid Build Coastguard Worker * packets with a zero ttl.
104*bd1f8aebSAndroid Build Coastguard Worker *
105*bd1f8aebSAndroid Build Coastguard Worker * A more interesting example is:
106*bd1f8aebSAndroid Build Coastguard Worker *
107*bd1f8aebSAndroid Build Coastguard Worker * [yak 72]% traceroute allspice.lcs.mit.edu.
108*bd1f8aebSAndroid Build Coastguard Worker * traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max
109*bd1f8aebSAndroid Build Coastguard Worker * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms
110*bd1f8aebSAndroid Build Coastguard Worker * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 19 ms 19 ms
111*bd1f8aebSAndroid Build Coastguard Worker * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 19 ms
112*bd1f8aebSAndroid Build Coastguard Worker * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 19 ms 39 ms 39 ms
113*bd1f8aebSAndroid Build Coastguard Worker * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 20 ms 39 ms 39 ms
114*bd1f8aebSAndroid Build Coastguard Worker * 6 128.32.197.4 (128.32.197.4) 59 ms 119 ms 39 ms
115*bd1f8aebSAndroid Build Coastguard Worker * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 39 ms
116*bd1f8aebSAndroid Build Coastguard Worker * 8 129.140.70.13 (129.140.70.13) 80 ms 79 ms 99 ms
117*bd1f8aebSAndroid Build Coastguard Worker * 9 129.140.71.6 (129.140.71.6) 139 ms 139 ms 159 ms
118*bd1f8aebSAndroid Build Coastguard Worker * 10 129.140.81.7 (129.140.81.7) 199 ms 180 ms 300 ms
119*bd1f8aebSAndroid Build Coastguard Worker * 11 129.140.72.17 (129.140.72.17) 300 ms 239 ms 239 ms
120*bd1f8aebSAndroid Build Coastguard Worker * 12 * * *
121*bd1f8aebSAndroid Build Coastguard Worker * 13 128.121.54.72 (128.121.54.72) 259 ms 499 ms 279 ms
122*bd1f8aebSAndroid Build Coastguard Worker * 14 * * *
123*bd1f8aebSAndroid Build Coastguard Worker * 15 * * *
124*bd1f8aebSAndroid Build Coastguard Worker * 16 * * *
125*bd1f8aebSAndroid Build Coastguard Worker * 17 * * *
126*bd1f8aebSAndroid Build Coastguard Worker * 18 ALLSPICE.LCS.MIT.EDU (18.26.0.115) 339 ms 279 ms 279 ms
127*bd1f8aebSAndroid Build Coastguard Worker *
128*bd1f8aebSAndroid Build Coastguard Worker * (I start to see why I'm having so much trouble with mail to
129*bd1f8aebSAndroid Build Coastguard Worker * MIT.) Note that the gateways 12, 14, 15, 16 & 17 hops away
130*bd1f8aebSAndroid Build Coastguard Worker * either don't send ICMP "time exceeded" messages or send them
131*bd1f8aebSAndroid Build Coastguard Worker * with a ttl too small to reach us. 14 - 17 are running the
132*bd1f8aebSAndroid Build Coastguard Worker * MIT C Gateway code that doesn't send "time exceeded"s. God
133*bd1f8aebSAndroid Build Coastguard Worker * only knows what's going on with 12.
134*bd1f8aebSAndroid Build Coastguard Worker *
135*bd1f8aebSAndroid Build Coastguard Worker * The silent gateway 12 in the above may be the result of a bug in
136*bd1f8aebSAndroid Build Coastguard Worker * the 4.[23]BSD network code (and its derivatives): 4.x (x <= 3)
137*bd1f8aebSAndroid Build Coastguard Worker * sends an unreachable message using whatever ttl remains in the
138*bd1f8aebSAndroid Build Coastguard Worker * original datagram. Since, for gateways, the remaining ttl is
139*bd1f8aebSAndroid Build Coastguard Worker * zero, the icmp "time exceeded" is guaranteed to not make it back
140*bd1f8aebSAndroid Build Coastguard Worker * to us. The behavior of this bug is slightly more interesting
141*bd1f8aebSAndroid Build Coastguard Worker * when it appears on the destination system:
142*bd1f8aebSAndroid Build Coastguard Worker *
143*bd1f8aebSAndroid Build Coastguard Worker * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms
144*bd1f8aebSAndroid Build Coastguard Worker * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 39 ms
145*bd1f8aebSAndroid Build Coastguard Worker * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 39 ms 19 ms
146*bd1f8aebSAndroid Build Coastguard Worker * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 19 ms
147*bd1f8aebSAndroid Build Coastguard Worker * 5 ccn-nerif35.Berkeley.EDU (128.32.168.35) 39 ms 39 ms 39 ms
148*bd1f8aebSAndroid Build Coastguard Worker * 6 csgw.Berkeley.EDU (128.32.133.254) 39 ms 59 ms 39 ms
149*bd1f8aebSAndroid Build Coastguard Worker * 7 * * *
150*bd1f8aebSAndroid Build Coastguard Worker * 8 * * *
151*bd1f8aebSAndroid Build Coastguard Worker * 9 * * *
152*bd1f8aebSAndroid Build Coastguard Worker * 10 * * *
153*bd1f8aebSAndroid Build Coastguard Worker * 11 * * *
154*bd1f8aebSAndroid Build Coastguard Worker * 12 * * *
155*bd1f8aebSAndroid Build Coastguard Worker * 13 rip.Berkeley.EDU (128.32.131.22) 59 ms ! 39 ms ! 39 ms !
156*bd1f8aebSAndroid Build Coastguard Worker *
157*bd1f8aebSAndroid Build Coastguard Worker * Notice that there are 12 "gateways" (13 is the final
158*bd1f8aebSAndroid Build Coastguard Worker * destination) and exactly the last half of them are "missing".
159*bd1f8aebSAndroid Build Coastguard Worker * What's really happening is that rip (a Sun-3 running Sun OS3.5)
160*bd1f8aebSAndroid Build Coastguard Worker * is using the ttl from our arriving datagram as the ttl in its
161*bd1f8aebSAndroid Build Coastguard Worker * icmp reply. So, the reply will time out on the return path
162*bd1f8aebSAndroid Build Coastguard Worker * (with no notice sent to anyone since icmp's aren't sent for
163*bd1f8aebSAndroid Build Coastguard Worker * icmp's) until we probe with a ttl that's at least twice the path
164*bd1f8aebSAndroid Build Coastguard Worker * length. I.e., rip is really only 7 hops away. A reply that
165*bd1f8aebSAndroid Build Coastguard Worker * returns with a ttl of 1 is a clue this problem exists.
166*bd1f8aebSAndroid Build Coastguard Worker * Traceroute prints a "!" after the time if the ttl is <= 1.
167*bd1f8aebSAndroid Build Coastguard Worker * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
168*bd1f8aebSAndroid Build Coastguard Worker * non-standard (HPUX) software, expect to see this problem
169*bd1f8aebSAndroid Build Coastguard Worker * frequently and/or take care picking the target host of your
170*bd1f8aebSAndroid Build Coastguard Worker * probes.
171*bd1f8aebSAndroid Build Coastguard Worker *
172*bd1f8aebSAndroid Build Coastguard Worker * Other possible annotations after the time are !H, !N, !P (got a host,
173*bd1f8aebSAndroid Build Coastguard Worker * network or protocol unreachable, respectively), !S or !F (source
174*bd1f8aebSAndroid Build Coastguard Worker * route failed or fragmentation needed -- neither of these should
175*bd1f8aebSAndroid Build Coastguard Worker * ever occur and the associated gateway is busted if you see one). If
176*bd1f8aebSAndroid Build Coastguard Worker * almost all the probes result in some kind of unreachable, traceroute
177*bd1f8aebSAndroid Build Coastguard Worker * will give up and exit.
178*bd1f8aebSAndroid Build Coastguard Worker *
179*bd1f8aebSAndroid Build Coastguard Worker * Notes
180*bd1f8aebSAndroid Build Coastguard Worker * -----
181*bd1f8aebSAndroid Build Coastguard Worker * This program must be run by root or be setuid. (I suggest that
182*bd1f8aebSAndroid Build Coastguard Worker * you *don't* make it setuid -- casual use could result in a lot
183*bd1f8aebSAndroid Build Coastguard Worker * of unnecessary traffic on our poor, congested nets.)
184*bd1f8aebSAndroid Build Coastguard Worker *
185*bd1f8aebSAndroid Build Coastguard Worker * This program requires a kernel mod that does not appear in any
186*bd1f8aebSAndroid Build Coastguard Worker * system available from Berkeley: A raw ip socket using proto
187*bd1f8aebSAndroid Build Coastguard Worker * IPPROTO_RAW must interpret the data sent as an ip datagram (as
188*bd1f8aebSAndroid Build Coastguard Worker * opposed to data to be wrapped in a ip datagram). See the README
189*bd1f8aebSAndroid Build Coastguard Worker * file that came with the source to this program for a description
190*bd1f8aebSAndroid Build Coastguard Worker * of the mods I made to /sys/netinet/raw_ip.c. Your mileage may
191*bd1f8aebSAndroid Build Coastguard Worker * vary. But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
192*bd1f8aebSAndroid Build Coastguard Worker * MODIFIED TO RUN THIS PROGRAM.
193*bd1f8aebSAndroid Build Coastguard Worker *
194*bd1f8aebSAndroid Build Coastguard Worker * The udp port usage may appear bizarre (well, ok, it is bizarre).
195*bd1f8aebSAndroid Build Coastguard Worker * The problem is that an icmp message only contains 8 bytes of
196*bd1f8aebSAndroid Build Coastguard Worker * data from the original datagram. 8 bytes is the size of a udp
197*bd1f8aebSAndroid Build Coastguard Worker * header so, if we want to associate replies with the original
198*bd1f8aebSAndroid Build Coastguard Worker * datagram, the necessary information must be encoded into the
199*bd1f8aebSAndroid Build Coastguard Worker * udp header (the ip id could be used but there's no way to
200*bd1f8aebSAndroid Build Coastguard Worker * interlock with the kernel's assignment of ip id's and, anyway,
201*bd1f8aebSAndroid Build Coastguard Worker * it would have taken a lot more kernel hacking to allow this
202*bd1f8aebSAndroid Build Coastguard Worker * code to set the ip id). So, to allow two or more users to
203*bd1f8aebSAndroid Build Coastguard Worker * use traceroute simultaneously, we use this task's pid as the
204*bd1f8aebSAndroid Build Coastguard Worker * source port (the high bit is set to move the port number out
205*bd1f8aebSAndroid Build Coastguard Worker * of the "likely" range). To keep track of which probe is being
206*bd1f8aebSAndroid Build Coastguard Worker * replied to (so times and/or hop counts don't get confused by a
207*bd1f8aebSAndroid Build Coastguard Worker * reply that was delayed in transit), we increment the destination
208*bd1f8aebSAndroid Build Coastguard Worker * port number before each probe.
209*bd1f8aebSAndroid Build Coastguard Worker *
210*bd1f8aebSAndroid Build Coastguard Worker * Don't use this as a coding example. I was trying to find a
211*bd1f8aebSAndroid Build Coastguard Worker * routing problem and this code sort-of popped out after 48 hours
212*bd1f8aebSAndroid Build Coastguard Worker * without sleep. I was amazed it ever compiled, much less ran.
213*bd1f8aebSAndroid Build Coastguard Worker *
214*bd1f8aebSAndroid Build Coastguard Worker * I stole the idea for this program from Steve Deering. Since
215*bd1f8aebSAndroid Build Coastguard Worker * the first release, I've learned that had I attended the right
216*bd1f8aebSAndroid Build Coastguard Worker * IETF working group meetings, I also could have stolen it from Guy
217*bd1f8aebSAndroid Build Coastguard Worker * Almes or Matt Mathis. I don't know (or care) who came up with
218*bd1f8aebSAndroid Build Coastguard Worker * the idea first. I envy the originators' perspicacity and I'm
219*bd1f8aebSAndroid Build Coastguard Worker * glad they didn't keep the idea a secret.
220*bd1f8aebSAndroid Build Coastguard Worker *
221*bd1f8aebSAndroid Build Coastguard Worker * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
222*bd1f8aebSAndroid Build Coastguard Worker * enhancements to the original distribution.
223*bd1f8aebSAndroid Build Coastguard Worker *
224*bd1f8aebSAndroid Build Coastguard Worker * I've hacked up a round-trip-route version of this that works by
225*bd1f8aebSAndroid Build Coastguard Worker * sending a loose-source-routed udp datagram through the destination
226*bd1f8aebSAndroid Build Coastguard Worker * back to yourself. Unfortunately, SO many gateways botch source
227*bd1f8aebSAndroid Build Coastguard Worker * routing, the thing is almost worthless. Maybe one day...
228*bd1f8aebSAndroid Build Coastguard Worker *
229*bd1f8aebSAndroid Build Coastguard Worker * -- Van Jacobson ([email protected])
230*bd1f8aebSAndroid Build Coastguard Worker * Tue Dec 20 03:50:13 PST 1988
231*bd1f8aebSAndroid Build Coastguard Worker */
232*bd1f8aebSAndroid Build Coastguard Worker
233*bd1f8aebSAndroid Build Coastguard Worker #include <sys/param.h>
234*bd1f8aebSAndroid Build Coastguard Worker #include <sys/time.h>
235*bd1f8aebSAndroid Build Coastguard Worker #include <sys/socket.h>
236*bd1f8aebSAndroid Build Coastguard Worker #include <sys/file.h>
237*bd1f8aebSAndroid Build Coastguard Worker #include <sys/ioctl.h>
238*bd1f8aebSAndroid Build Coastguard Worker #include <net/if.h>
239*bd1f8aebSAndroid Build Coastguard Worker
240*bd1f8aebSAndroid Build Coastguard Worker #if __linux__
241*bd1f8aebSAndroid Build Coastguard Worker #include <endian.h>
242*bd1f8aebSAndroid Build Coastguard Worker #endif
243*bd1f8aebSAndroid Build Coastguard Worker #include <netinet/in_systm.h>
244*bd1f8aebSAndroid Build Coastguard Worker #include <netinet/in.h>
245*bd1f8aebSAndroid Build Coastguard Worker #include <netinet/ip.h>
246*bd1f8aebSAndroid Build Coastguard Worker #include <netinet/ip_icmp.h>
247*bd1f8aebSAndroid Build Coastguard Worker #include <netinet/udp.h>
248*bd1f8aebSAndroid Build Coastguard Worker
249*bd1f8aebSAndroid Build Coastguard Worker #include <netinet/ip6.h>
250*bd1f8aebSAndroid Build Coastguard Worker #include <netinet/icmp6.h>
251*bd1f8aebSAndroid Build Coastguard Worker #include <linux/types.h>
252*bd1f8aebSAndroid Build Coastguard Worker #ifdef CAPABILITIES
253*bd1f8aebSAndroid Build Coastguard Worker #include <sys/capability.h>
254*bd1f8aebSAndroid Build Coastguard Worker #endif
255*bd1f8aebSAndroid Build Coastguard Worker
256*bd1f8aebSAndroid Build Coastguard Worker #ifdef USE_IDN
257*bd1f8aebSAndroid Build Coastguard Worker #include <idna.h>
258*bd1f8aebSAndroid Build Coastguard Worker #include <locale.h>
259*bd1f8aebSAndroid Build Coastguard Worker #endif
260*bd1f8aebSAndroid Build Coastguard Worker
261*bd1f8aebSAndroid Build Coastguard Worker #include <arpa/inet.h>
262*bd1f8aebSAndroid Build Coastguard Worker
263*bd1f8aebSAndroid Build Coastguard Worker #include <netdb.h>
264*bd1f8aebSAndroid Build Coastguard Worker #include <stdio.h>
265*bd1f8aebSAndroid Build Coastguard Worker #include <errno.h>
266*bd1f8aebSAndroid Build Coastguard Worker #include <stdlib.h>
267*bd1f8aebSAndroid Build Coastguard Worker #include <string.h>
268*bd1f8aebSAndroid Build Coastguard Worker #include <unistd.h>
269*bd1f8aebSAndroid Build Coastguard Worker
270*bd1f8aebSAndroid Build Coastguard Worker #include "SNAPSHOT.h"
271*bd1f8aebSAndroid Build Coastguard Worker
272*bd1f8aebSAndroid Build Coastguard Worker #ifndef SOL_IPV6
273*bd1f8aebSAndroid Build Coastguard Worker #define SOL_IPV6 IPPROTO_IPV6
274*bd1f8aebSAndroid Build Coastguard Worker #endif
275*bd1f8aebSAndroid Build Coastguard Worker
276*bd1f8aebSAndroid Build Coastguard Worker #define MAXPACKET 65535
277*bd1f8aebSAndroid Build Coastguard Worker #define MAX_HOSTNAMELEN NI_MAXHOST
278*bd1f8aebSAndroid Build Coastguard Worker
279*bd1f8aebSAndroid Build Coastguard Worker #ifndef FD_SET
280*bd1f8aebSAndroid Build Coastguard Worker #define NFDBITS (8*sizeof(fd_set))
281*bd1f8aebSAndroid Build Coastguard Worker #define FD_SETSIZE NFDBITS
282*bd1f8aebSAndroid Build Coastguard Worker #define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
283*bd1f8aebSAndroid Build Coastguard Worker #define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
284*bd1f8aebSAndroid Build Coastguard Worker #define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
285*bd1f8aebSAndroid Build Coastguard Worker #define FD_ZERO(p) memset((char *)(p), 0, sizeof(*(p)))
286*bd1f8aebSAndroid Build Coastguard Worker #endif
287*bd1f8aebSAndroid Build Coastguard Worker
288*bd1f8aebSAndroid Build Coastguard Worker #define Fprintf (void)fprintf
289*bd1f8aebSAndroid Build Coastguard Worker #define Printf (void)printf
290*bd1f8aebSAndroid Build Coastguard Worker
291*bd1f8aebSAndroid Build Coastguard Worker u_char packet[512]; /* last inbound (icmp) packet */
292*bd1f8aebSAndroid Build Coastguard Worker
293*bd1f8aebSAndroid Build Coastguard Worker int wait_for_reply(int, struct sockaddr_in6 *, struct in6_addr *, int);
294*bd1f8aebSAndroid Build Coastguard Worker int packet_ok(u_char *buf, int cc, struct sockaddr_in6 *from,
295*bd1f8aebSAndroid Build Coastguard Worker struct in6_addr *to, int seq, struct timeval *);
296*bd1f8aebSAndroid Build Coastguard Worker void send_probe(int seq, int ttl);
297*bd1f8aebSAndroid Build Coastguard Worker double deltaT (struct timeval *, struct timeval *);
298*bd1f8aebSAndroid Build Coastguard Worker void print(unsigned char *buf, int cc, struct sockaddr_in6 *from);
299*bd1f8aebSAndroid Build Coastguard Worker void tvsub (struct timeval *, struct timeval *);
300*bd1f8aebSAndroid Build Coastguard Worker void usage(void);
301*bd1f8aebSAndroid Build Coastguard Worker
302*bd1f8aebSAndroid Build Coastguard Worker int icmp_sock; /* receive (icmp) socket file descriptor */
303*bd1f8aebSAndroid Build Coastguard Worker int sndsock; /* send (udp) socket file descriptor */
304*bd1f8aebSAndroid Build Coastguard Worker struct timezone tz; /* leftover */
305*bd1f8aebSAndroid Build Coastguard Worker
306*bd1f8aebSAndroid Build Coastguard Worker struct sockaddr_in6 whereto; /* Who to try to reach */
307*bd1f8aebSAndroid Build Coastguard Worker
308*bd1f8aebSAndroid Build Coastguard Worker struct sockaddr_in6 saddr;
309*bd1f8aebSAndroid Build Coastguard Worker struct sockaddr_in6 firsthop;
310*bd1f8aebSAndroid Build Coastguard Worker char *source = NULL;
311*bd1f8aebSAndroid Build Coastguard Worker char *device = NULL;
312*bd1f8aebSAndroid Build Coastguard Worker char *hostname;
313*bd1f8aebSAndroid Build Coastguard Worker
314*bd1f8aebSAndroid Build Coastguard Worker int nprobes = 3;
315*bd1f8aebSAndroid Build Coastguard Worker int max_ttl = 30;
316*bd1f8aebSAndroid Build Coastguard Worker pid_t ident;
317*bd1f8aebSAndroid Build Coastguard Worker u_short port = 32768+666; /* start udp dest port # for probe packets */
318*bd1f8aebSAndroid Build Coastguard Worker int options; /* socket options */
319*bd1f8aebSAndroid Build Coastguard Worker int verbose;
320*bd1f8aebSAndroid Build Coastguard Worker int waittime = 5; /* time to wait for response (in seconds) */
321*bd1f8aebSAndroid Build Coastguard Worker int nflag; /* print addresses numerically */
322*bd1f8aebSAndroid Build Coastguard Worker
323*bd1f8aebSAndroid Build Coastguard Worker
324*bd1f8aebSAndroid Build Coastguard Worker struct pkt_format
325*bd1f8aebSAndroid Build Coastguard Worker {
326*bd1f8aebSAndroid Build Coastguard Worker __u32 ident;
327*bd1f8aebSAndroid Build Coastguard Worker __u32 seq;
328*bd1f8aebSAndroid Build Coastguard Worker struct timeval tv;
329*bd1f8aebSAndroid Build Coastguard Worker };
330*bd1f8aebSAndroid Build Coastguard Worker
331*bd1f8aebSAndroid Build Coastguard Worker char *sendbuff;
332*bd1f8aebSAndroid Build Coastguard Worker int datalen = sizeof(struct pkt_format);
333*bd1f8aebSAndroid Build Coastguard Worker
334*bd1f8aebSAndroid Build Coastguard Worker
335*bd1f8aebSAndroid Build Coastguard Worker
main(int argc,char * argv[])336*bd1f8aebSAndroid Build Coastguard Worker int main(int argc, char *argv[])
337*bd1f8aebSAndroid Build Coastguard Worker {
338*bd1f8aebSAndroid Build Coastguard Worker char pa[MAX_HOSTNAMELEN];
339*bd1f8aebSAndroid Build Coastguard Worker extern char *optarg;
340*bd1f8aebSAndroid Build Coastguard Worker extern int optind;
341*bd1f8aebSAndroid Build Coastguard Worker struct hostent *hp;
342*bd1f8aebSAndroid Build Coastguard Worker struct sockaddr_in6 from, *to;
343*bd1f8aebSAndroid Build Coastguard Worker int ch, i, on, probe, seq, tos, ttl;
344*bd1f8aebSAndroid Build Coastguard Worker int socket_errno;
345*bd1f8aebSAndroid Build Coastguard Worker
346*bd1f8aebSAndroid Build Coastguard Worker icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
347*bd1f8aebSAndroid Build Coastguard Worker socket_errno = errno;
348*bd1f8aebSAndroid Build Coastguard Worker
349*bd1f8aebSAndroid Build Coastguard Worker if (setuid(getuid())) {
350*bd1f8aebSAndroid Build Coastguard Worker perror("traceroute6: setuid");
351*bd1f8aebSAndroid Build Coastguard Worker exit(-1);
352*bd1f8aebSAndroid Build Coastguard Worker }
353*bd1f8aebSAndroid Build Coastguard Worker #ifdef CAPABILITIES
354*bd1f8aebSAndroid Build Coastguard Worker {
355*bd1f8aebSAndroid Build Coastguard Worker cap_t caps = cap_init();
356*bd1f8aebSAndroid Build Coastguard Worker if (cap_set_proc(caps)) {
357*bd1f8aebSAndroid Build Coastguard Worker perror("traceroute6: cap_set_proc");
358*bd1f8aebSAndroid Build Coastguard Worker exit(-1);
359*bd1f8aebSAndroid Build Coastguard Worker }
360*bd1f8aebSAndroid Build Coastguard Worker cap_free(caps);
361*bd1f8aebSAndroid Build Coastguard Worker }
362*bd1f8aebSAndroid Build Coastguard Worker #endif
363*bd1f8aebSAndroid Build Coastguard Worker
364*bd1f8aebSAndroid Build Coastguard Worker #ifdef USE_IDN
365*bd1f8aebSAndroid Build Coastguard Worker setlocale(LC_ALL, "");
366*bd1f8aebSAndroid Build Coastguard Worker #endif
367*bd1f8aebSAndroid Build Coastguard Worker
368*bd1f8aebSAndroid Build Coastguard Worker on = 1;
369*bd1f8aebSAndroid Build Coastguard Worker seq = tos = 0;
370*bd1f8aebSAndroid Build Coastguard Worker to = (struct sockaddr_in6 *)&whereto;
371*bd1f8aebSAndroid Build Coastguard Worker while ((ch = getopt(argc, argv, "dm:np:q:rs:t:w:vi:g:V")) != EOF) {
372*bd1f8aebSAndroid Build Coastguard Worker switch(ch) {
373*bd1f8aebSAndroid Build Coastguard Worker case 'd':
374*bd1f8aebSAndroid Build Coastguard Worker options |= SO_DEBUG;
375*bd1f8aebSAndroid Build Coastguard Worker break;
376*bd1f8aebSAndroid Build Coastguard Worker case 'm':
377*bd1f8aebSAndroid Build Coastguard Worker max_ttl = atoi(optarg);
378*bd1f8aebSAndroid Build Coastguard Worker if (max_ttl <= 1) {
379*bd1f8aebSAndroid Build Coastguard Worker Fprintf(stderr,
380*bd1f8aebSAndroid Build Coastguard Worker "traceroute: max ttl must be >1.\n");
381*bd1f8aebSAndroid Build Coastguard Worker exit(1);
382*bd1f8aebSAndroid Build Coastguard Worker }
383*bd1f8aebSAndroid Build Coastguard Worker break;
384*bd1f8aebSAndroid Build Coastguard Worker case 'n':
385*bd1f8aebSAndroid Build Coastguard Worker nflag++;
386*bd1f8aebSAndroid Build Coastguard Worker break;
387*bd1f8aebSAndroid Build Coastguard Worker case 'p':
388*bd1f8aebSAndroid Build Coastguard Worker port = atoi(optarg);
389*bd1f8aebSAndroid Build Coastguard Worker if (port < 1) {
390*bd1f8aebSAndroid Build Coastguard Worker Fprintf(stderr,
391*bd1f8aebSAndroid Build Coastguard Worker "traceroute: port must be >0.\n");
392*bd1f8aebSAndroid Build Coastguard Worker exit(1);
393*bd1f8aebSAndroid Build Coastguard Worker }
394*bd1f8aebSAndroid Build Coastguard Worker break;
395*bd1f8aebSAndroid Build Coastguard Worker case 'q':
396*bd1f8aebSAndroid Build Coastguard Worker nprobes = atoi(optarg);
397*bd1f8aebSAndroid Build Coastguard Worker if (nprobes < 1) {
398*bd1f8aebSAndroid Build Coastguard Worker Fprintf(stderr,
399*bd1f8aebSAndroid Build Coastguard Worker "traceroute: nprobes must be >0.\n");
400*bd1f8aebSAndroid Build Coastguard Worker exit(1);
401*bd1f8aebSAndroid Build Coastguard Worker }
402*bd1f8aebSAndroid Build Coastguard Worker break;
403*bd1f8aebSAndroid Build Coastguard Worker case 'r':
404*bd1f8aebSAndroid Build Coastguard Worker options |= SO_DONTROUTE;
405*bd1f8aebSAndroid Build Coastguard Worker break;
406*bd1f8aebSAndroid Build Coastguard Worker case 's':
407*bd1f8aebSAndroid Build Coastguard Worker /*
408*bd1f8aebSAndroid Build Coastguard Worker * set the ip source address of the outbound
409*bd1f8aebSAndroid Build Coastguard Worker * probe (e.g., on a multi-homed host).
410*bd1f8aebSAndroid Build Coastguard Worker */
411*bd1f8aebSAndroid Build Coastguard Worker source = optarg;
412*bd1f8aebSAndroid Build Coastguard Worker break;
413*bd1f8aebSAndroid Build Coastguard Worker case 'i':
414*bd1f8aebSAndroid Build Coastguard Worker device = optarg;
415*bd1f8aebSAndroid Build Coastguard Worker break;
416*bd1f8aebSAndroid Build Coastguard Worker case 'g':
417*bd1f8aebSAndroid Build Coastguard Worker Fprintf(stderr, "Sorry, rthdr is not yet supported\n");
418*bd1f8aebSAndroid Build Coastguard Worker break;
419*bd1f8aebSAndroid Build Coastguard Worker case 'v':
420*bd1f8aebSAndroid Build Coastguard Worker verbose++;
421*bd1f8aebSAndroid Build Coastguard Worker break;
422*bd1f8aebSAndroid Build Coastguard Worker case 'w':
423*bd1f8aebSAndroid Build Coastguard Worker waittime = atoi(optarg);
424*bd1f8aebSAndroid Build Coastguard Worker if (waittime <= 1) {
425*bd1f8aebSAndroid Build Coastguard Worker Fprintf(stderr,
426*bd1f8aebSAndroid Build Coastguard Worker "traceroute: wait must be >1 sec.\n");
427*bd1f8aebSAndroid Build Coastguard Worker exit(1);
428*bd1f8aebSAndroid Build Coastguard Worker }
429*bd1f8aebSAndroid Build Coastguard Worker break;
430*bd1f8aebSAndroid Build Coastguard Worker case 'V':
431*bd1f8aebSAndroid Build Coastguard Worker printf("traceroute6 utility, iputils-%s\n", SNAPSHOT);
432*bd1f8aebSAndroid Build Coastguard Worker exit(0);
433*bd1f8aebSAndroid Build Coastguard Worker default:
434*bd1f8aebSAndroid Build Coastguard Worker usage();
435*bd1f8aebSAndroid Build Coastguard Worker }
436*bd1f8aebSAndroid Build Coastguard Worker }
437*bd1f8aebSAndroid Build Coastguard Worker argc -= optind;
438*bd1f8aebSAndroid Build Coastguard Worker argv += optind;
439*bd1f8aebSAndroid Build Coastguard Worker
440*bd1f8aebSAndroid Build Coastguard Worker if (argc < 1)
441*bd1f8aebSAndroid Build Coastguard Worker usage();
442*bd1f8aebSAndroid Build Coastguard Worker
443*bd1f8aebSAndroid Build Coastguard Worker setlinebuf (stdout);
444*bd1f8aebSAndroid Build Coastguard Worker
445*bd1f8aebSAndroid Build Coastguard Worker (void) memset((char *)&whereto, 0, sizeof(whereto));
446*bd1f8aebSAndroid Build Coastguard Worker
447*bd1f8aebSAndroid Build Coastguard Worker to->sin6_family = AF_INET6;
448*bd1f8aebSAndroid Build Coastguard Worker to->sin6_port = htons(port);
449*bd1f8aebSAndroid Build Coastguard Worker
450*bd1f8aebSAndroid Build Coastguard Worker if (inet_pton(AF_INET6, *argv, &to->sin6_addr) > 0) {
451*bd1f8aebSAndroid Build Coastguard Worker hostname = *argv;
452*bd1f8aebSAndroid Build Coastguard Worker } else {
453*bd1f8aebSAndroid Build Coastguard Worker char *idn = NULL;
454*bd1f8aebSAndroid Build Coastguard Worker #ifdef USE_IDN
455*bd1f8aebSAndroid Build Coastguard Worker if (idna_to_ascii_lz(*argv, &idn, 0) != IDNA_SUCCESS)
456*bd1f8aebSAndroid Build Coastguard Worker idn = NULL;
457*bd1f8aebSAndroid Build Coastguard Worker #endif
458*bd1f8aebSAndroid Build Coastguard Worker hp = gethostbyname2(idn ? idn : *argv, AF_INET6);
459*bd1f8aebSAndroid Build Coastguard Worker if (hp) {
460*bd1f8aebSAndroid Build Coastguard Worker memmove((caddr_t)&to->sin6_addr, hp->h_addr, sizeof(to->sin6_addr));
461*bd1f8aebSAndroid Build Coastguard Worker hostname = (char *)hp->h_name;
462*bd1f8aebSAndroid Build Coastguard Worker } else {
463*bd1f8aebSAndroid Build Coastguard Worker (void)fprintf(stderr,
464*bd1f8aebSAndroid Build Coastguard Worker "traceroute: unknown host %s\n", *argv);
465*bd1f8aebSAndroid Build Coastguard Worker exit(1);
466*bd1f8aebSAndroid Build Coastguard Worker }
467*bd1f8aebSAndroid Build Coastguard Worker }
468*bd1f8aebSAndroid Build Coastguard Worker firsthop = *to;
469*bd1f8aebSAndroid Build Coastguard Worker if (*++argv) {
470*bd1f8aebSAndroid Build Coastguard Worker datalen = atoi(*argv);
471*bd1f8aebSAndroid Build Coastguard Worker /* Message for rpm maintainers: have _shame_. If you want
472*bd1f8aebSAndroid Build Coastguard Worker * to fix something send the patch to me for sanity checking.
473*bd1f8aebSAndroid Build Coastguard Worker * "datalen" patch is a shit. */
474*bd1f8aebSAndroid Build Coastguard Worker if (datalen == 0)
475*bd1f8aebSAndroid Build Coastguard Worker datalen = sizeof(struct pkt_format);
476*bd1f8aebSAndroid Build Coastguard Worker else if (datalen < (int)sizeof(struct pkt_format) ||
477*bd1f8aebSAndroid Build Coastguard Worker datalen >= MAXPACKET) {
478*bd1f8aebSAndroid Build Coastguard Worker Fprintf(stderr,
479*bd1f8aebSAndroid Build Coastguard Worker "traceroute: packet size must be %d <= s < %d.\n",
480*bd1f8aebSAndroid Build Coastguard Worker (int)sizeof(struct pkt_format), MAXPACKET);
481*bd1f8aebSAndroid Build Coastguard Worker exit(1);
482*bd1f8aebSAndroid Build Coastguard Worker }
483*bd1f8aebSAndroid Build Coastguard Worker }
484*bd1f8aebSAndroid Build Coastguard Worker
485*bd1f8aebSAndroid Build Coastguard Worker ident = getpid();
486*bd1f8aebSAndroid Build Coastguard Worker
487*bd1f8aebSAndroid Build Coastguard Worker sendbuff = malloc(datalen);
488*bd1f8aebSAndroid Build Coastguard Worker if (sendbuff == NULL) {
489*bd1f8aebSAndroid Build Coastguard Worker fprintf(stderr, "malloc failed\n");
490*bd1f8aebSAndroid Build Coastguard Worker exit(1);
491*bd1f8aebSAndroid Build Coastguard Worker }
492*bd1f8aebSAndroid Build Coastguard Worker
493*bd1f8aebSAndroid Build Coastguard Worker if (icmp_sock < 0) {
494*bd1f8aebSAndroid Build Coastguard Worker errno = socket_errno;
495*bd1f8aebSAndroid Build Coastguard Worker perror("traceroute6: icmp socket");
496*bd1f8aebSAndroid Build Coastguard Worker exit(1);
497*bd1f8aebSAndroid Build Coastguard Worker }
498*bd1f8aebSAndroid Build Coastguard Worker
499*bd1f8aebSAndroid Build Coastguard Worker #ifdef IPV6_RECVPKTINFO
500*bd1f8aebSAndroid Build Coastguard Worker setsockopt(icmp_sock, SOL_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on));
501*bd1f8aebSAndroid Build Coastguard Worker setsockopt(icmp_sock, SOL_IPV6, IPV6_2292PKTINFO, &on, sizeof(on));
502*bd1f8aebSAndroid Build Coastguard Worker #else
503*bd1f8aebSAndroid Build Coastguard Worker setsockopt(icmp_sock, SOL_IPV6, IPV6_PKTINFO, &on, sizeof(on));
504*bd1f8aebSAndroid Build Coastguard Worker #endif
505*bd1f8aebSAndroid Build Coastguard Worker
506*bd1f8aebSAndroid Build Coastguard Worker if (options & SO_DEBUG)
507*bd1f8aebSAndroid Build Coastguard Worker setsockopt(icmp_sock, SOL_SOCKET, SO_DEBUG,
508*bd1f8aebSAndroid Build Coastguard Worker (char *)&on, sizeof(on));
509*bd1f8aebSAndroid Build Coastguard Worker if (options & SO_DONTROUTE)
510*bd1f8aebSAndroid Build Coastguard Worker setsockopt(icmp_sock, SOL_SOCKET, SO_DONTROUTE,
511*bd1f8aebSAndroid Build Coastguard Worker (char *)&on, sizeof(on));
512*bd1f8aebSAndroid Build Coastguard Worker
513*bd1f8aebSAndroid Build Coastguard Worker #ifdef __linux__
514*bd1f8aebSAndroid Build Coastguard Worker on = 2;
515*bd1f8aebSAndroid Build Coastguard Worker if (setsockopt(icmp_sock, SOL_RAW, IPV6_CHECKSUM, &on, sizeof(on)) < 0) {
516*bd1f8aebSAndroid Build Coastguard Worker /* checksum should be enabled by default and setting this
517*bd1f8aebSAndroid Build Coastguard Worker * option might fail anyway.
518*bd1f8aebSAndroid Build Coastguard Worker */
519*bd1f8aebSAndroid Build Coastguard Worker fprintf(stderr, "setsockopt(RAW_CHECKSUM) failed - try to continue.");
520*bd1f8aebSAndroid Build Coastguard Worker }
521*bd1f8aebSAndroid Build Coastguard Worker #endif
522*bd1f8aebSAndroid Build Coastguard Worker
523*bd1f8aebSAndroid Build Coastguard Worker if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
524*bd1f8aebSAndroid Build Coastguard Worker perror("traceroute: UDP socket");
525*bd1f8aebSAndroid Build Coastguard Worker exit(5);
526*bd1f8aebSAndroid Build Coastguard Worker }
527*bd1f8aebSAndroid Build Coastguard Worker #ifdef SO_SNDBUF
528*bd1f8aebSAndroid Build Coastguard Worker if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,
529*bd1f8aebSAndroid Build Coastguard Worker sizeof(datalen)) < 0) {
530*bd1f8aebSAndroid Build Coastguard Worker perror("traceroute: SO_SNDBUF");
531*bd1f8aebSAndroid Build Coastguard Worker exit(6);
532*bd1f8aebSAndroid Build Coastguard Worker }
533*bd1f8aebSAndroid Build Coastguard Worker #endif /* SO_SNDBUF */
534*bd1f8aebSAndroid Build Coastguard Worker
535*bd1f8aebSAndroid Build Coastguard Worker if (options & SO_DEBUG)
536*bd1f8aebSAndroid Build Coastguard Worker (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
537*bd1f8aebSAndroid Build Coastguard Worker (char *)&on, sizeof(on));
538*bd1f8aebSAndroid Build Coastguard Worker if (options & SO_DONTROUTE)
539*bd1f8aebSAndroid Build Coastguard Worker (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
540*bd1f8aebSAndroid Build Coastguard Worker (char *)&on, sizeof(on));
541*bd1f8aebSAndroid Build Coastguard Worker
542*bd1f8aebSAndroid Build Coastguard Worker if (source == NULL) {
543*bd1f8aebSAndroid Build Coastguard Worker socklen_t alen;
544*bd1f8aebSAndroid Build Coastguard Worker int probe_fd = socket(AF_INET6, SOCK_DGRAM, 0);
545*bd1f8aebSAndroid Build Coastguard Worker
546*bd1f8aebSAndroid Build Coastguard Worker if (probe_fd < 0) {
547*bd1f8aebSAndroid Build Coastguard Worker perror("socket");
548*bd1f8aebSAndroid Build Coastguard Worker exit(1);
549*bd1f8aebSAndroid Build Coastguard Worker }
550*bd1f8aebSAndroid Build Coastguard Worker if (device) {
551*bd1f8aebSAndroid Build Coastguard Worker if (setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)+1) == -1)
552*bd1f8aebSAndroid Build Coastguard Worker perror("WARNING: interface is ignored");
553*bd1f8aebSAndroid Build Coastguard Worker }
554*bd1f8aebSAndroid Build Coastguard Worker firsthop.sin6_port = htons(1025);
555*bd1f8aebSAndroid Build Coastguard Worker if (connect(probe_fd, (struct sockaddr*)&firsthop, sizeof(firsthop)) == -1) {
556*bd1f8aebSAndroid Build Coastguard Worker perror("connect");
557*bd1f8aebSAndroid Build Coastguard Worker exit(1);
558*bd1f8aebSAndroid Build Coastguard Worker }
559*bd1f8aebSAndroid Build Coastguard Worker alen = sizeof(saddr);
560*bd1f8aebSAndroid Build Coastguard Worker if (getsockname(probe_fd, (struct sockaddr*)&saddr, &alen) == -1) {
561*bd1f8aebSAndroid Build Coastguard Worker perror("getsockname");
562*bd1f8aebSAndroid Build Coastguard Worker exit(1);
563*bd1f8aebSAndroid Build Coastguard Worker }
564*bd1f8aebSAndroid Build Coastguard Worker saddr.sin6_port = 0;
565*bd1f8aebSAndroid Build Coastguard Worker close(probe_fd);
566*bd1f8aebSAndroid Build Coastguard Worker } else {
567*bd1f8aebSAndroid Build Coastguard Worker (void) memset((char *)&saddr, 0, sizeof(saddr));
568*bd1f8aebSAndroid Build Coastguard Worker saddr.sin6_family = AF_INET6;
569*bd1f8aebSAndroid Build Coastguard Worker if (inet_pton(AF_INET6, source, &saddr.sin6_addr) <= 0)
570*bd1f8aebSAndroid Build Coastguard Worker {
571*bd1f8aebSAndroid Build Coastguard Worker Printf("traceroute: unknown addr %s\n", source);
572*bd1f8aebSAndroid Build Coastguard Worker exit(1);
573*bd1f8aebSAndroid Build Coastguard Worker }
574*bd1f8aebSAndroid Build Coastguard Worker }
575*bd1f8aebSAndroid Build Coastguard Worker
576*bd1f8aebSAndroid Build Coastguard Worker if (bind(sndsock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
577*bd1f8aebSAndroid Build Coastguard Worker perror ("traceroute: bind sending socket");
578*bd1f8aebSAndroid Build Coastguard Worker exit (1);
579*bd1f8aebSAndroid Build Coastguard Worker }
580*bd1f8aebSAndroid Build Coastguard Worker if (bind(icmp_sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
581*bd1f8aebSAndroid Build Coastguard Worker perror ("traceroute: bind icmp6 socket");
582*bd1f8aebSAndroid Build Coastguard Worker exit (1);
583*bd1f8aebSAndroid Build Coastguard Worker }
584*bd1f8aebSAndroid Build Coastguard Worker
585*bd1f8aebSAndroid Build Coastguard Worker Fprintf(stderr, "traceroute to %s (%s)", hostname,
586*bd1f8aebSAndroid Build Coastguard Worker inet_ntop(AF_INET6, &to->sin6_addr, pa, sizeof(pa)));
587*bd1f8aebSAndroid Build Coastguard Worker
588*bd1f8aebSAndroid Build Coastguard Worker Fprintf(stderr, " from %s",
589*bd1f8aebSAndroid Build Coastguard Worker inet_ntop(AF_INET6, &saddr.sin6_addr, pa, sizeof(pa)));
590*bd1f8aebSAndroid Build Coastguard Worker Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, datalen);
591*bd1f8aebSAndroid Build Coastguard Worker (void) fflush(stderr);
592*bd1f8aebSAndroid Build Coastguard Worker
593*bd1f8aebSAndroid Build Coastguard Worker for (ttl = 1; ttl <= max_ttl; ++ttl) {
594*bd1f8aebSAndroid Build Coastguard Worker struct in6_addr lastaddr = {{{0,}}};
595*bd1f8aebSAndroid Build Coastguard Worker int got_there = 0;
596*bd1f8aebSAndroid Build Coastguard Worker int unreachable = 0;
597*bd1f8aebSAndroid Build Coastguard Worker
598*bd1f8aebSAndroid Build Coastguard Worker Printf("%2d ", ttl);
599*bd1f8aebSAndroid Build Coastguard Worker for (probe = 0; probe < nprobes; ++probe) {
600*bd1f8aebSAndroid Build Coastguard Worker int cc, reset_timer;
601*bd1f8aebSAndroid Build Coastguard Worker struct timeval t1, t2;
602*bd1f8aebSAndroid Build Coastguard Worker struct timezone tz;
603*bd1f8aebSAndroid Build Coastguard Worker struct in6_addr to;
604*bd1f8aebSAndroid Build Coastguard Worker
605*bd1f8aebSAndroid Build Coastguard Worker gettimeofday(&t1, &tz);
606*bd1f8aebSAndroid Build Coastguard Worker send_probe(++seq, ttl);
607*bd1f8aebSAndroid Build Coastguard Worker reset_timer = 1;
608*bd1f8aebSAndroid Build Coastguard Worker
609*bd1f8aebSAndroid Build Coastguard Worker while ((cc = wait_for_reply(icmp_sock, &from, &to, reset_timer)) != 0) {
610*bd1f8aebSAndroid Build Coastguard Worker gettimeofday(&t2, &tz);
611*bd1f8aebSAndroid Build Coastguard Worker if ((i = packet_ok(packet, cc, &from, &to, seq, &t1))) {
612*bd1f8aebSAndroid Build Coastguard Worker reset_timer = 1;
613*bd1f8aebSAndroid Build Coastguard Worker if (memcmp(&from.sin6_addr, &lastaddr, sizeof(from.sin6_addr))) {
614*bd1f8aebSAndroid Build Coastguard Worker print(packet, cc, &from);
615*bd1f8aebSAndroid Build Coastguard Worker memcpy(&lastaddr,
616*bd1f8aebSAndroid Build Coastguard Worker &from.sin6_addr,
617*bd1f8aebSAndroid Build Coastguard Worker sizeof(lastaddr));
618*bd1f8aebSAndroid Build Coastguard Worker }
619*bd1f8aebSAndroid Build Coastguard Worker Printf(" %g ms", deltaT(&t1, &t2));
620*bd1f8aebSAndroid Build Coastguard Worker switch(i - 1) {
621*bd1f8aebSAndroid Build Coastguard Worker case ICMP6_DST_UNREACH_NOPORT:
622*bd1f8aebSAndroid Build Coastguard Worker ++got_there;
623*bd1f8aebSAndroid Build Coastguard Worker break;
624*bd1f8aebSAndroid Build Coastguard Worker
625*bd1f8aebSAndroid Build Coastguard Worker case ICMP6_DST_UNREACH_NOROUTE:
626*bd1f8aebSAndroid Build Coastguard Worker ++unreachable;
627*bd1f8aebSAndroid Build Coastguard Worker Printf(" !N");
628*bd1f8aebSAndroid Build Coastguard Worker break;
629*bd1f8aebSAndroid Build Coastguard Worker case ICMP6_DST_UNREACH_ADDR:
630*bd1f8aebSAndroid Build Coastguard Worker ++unreachable;
631*bd1f8aebSAndroid Build Coastguard Worker Printf(" !H");
632*bd1f8aebSAndroid Build Coastguard Worker break;
633*bd1f8aebSAndroid Build Coastguard Worker
634*bd1f8aebSAndroid Build Coastguard Worker case ICMP6_DST_UNREACH_ADMIN:
635*bd1f8aebSAndroid Build Coastguard Worker ++unreachable;
636*bd1f8aebSAndroid Build Coastguard Worker Printf(" !S");
637*bd1f8aebSAndroid Build Coastguard Worker break;
638*bd1f8aebSAndroid Build Coastguard Worker }
639*bd1f8aebSAndroid Build Coastguard Worker break;
640*bd1f8aebSAndroid Build Coastguard Worker } else
641*bd1f8aebSAndroid Build Coastguard Worker reset_timer = 0;
642*bd1f8aebSAndroid Build Coastguard Worker }
643*bd1f8aebSAndroid Build Coastguard Worker if (cc <= 0)
644*bd1f8aebSAndroid Build Coastguard Worker Printf(" *");
645*bd1f8aebSAndroid Build Coastguard Worker (void) fflush(stdout);
646*bd1f8aebSAndroid Build Coastguard Worker }
647*bd1f8aebSAndroid Build Coastguard Worker putchar('\n');
648*bd1f8aebSAndroid Build Coastguard Worker if (got_there ||
649*bd1f8aebSAndroid Build Coastguard Worker (unreachable > 0 && unreachable >= nprobes-1))
650*bd1f8aebSAndroid Build Coastguard Worker exit(0);
651*bd1f8aebSAndroid Build Coastguard Worker }
652*bd1f8aebSAndroid Build Coastguard Worker
653*bd1f8aebSAndroid Build Coastguard Worker return 0;
654*bd1f8aebSAndroid Build Coastguard Worker }
655*bd1f8aebSAndroid Build Coastguard Worker
656*bd1f8aebSAndroid Build Coastguard Worker int
wait_for_reply(sock,from,to,reset_timer)657*bd1f8aebSAndroid Build Coastguard Worker wait_for_reply(sock, from, to, reset_timer)
658*bd1f8aebSAndroid Build Coastguard Worker int sock;
659*bd1f8aebSAndroid Build Coastguard Worker struct sockaddr_in6 *from;
660*bd1f8aebSAndroid Build Coastguard Worker struct in6_addr *to;
661*bd1f8aebSAndroid Build Coastguard Worker int reset_timer;
662*bd1f8aebSAndroid Build Coastguard Worker {
663*bd1f8aebSAndroid Build Coastguard Worker fd_set fds;
664*bd1f8aebSAndroid Build Coastguard Worker static struct timeval wait;
665*bd1f8aebSAndroid Build Coastguard Worker int cc = 0;
666*bd1f8aebSAndroid Build Coastguard Worker char cbuf[512];
667*bd1f8aebSAndroid Build Coastguard Worker
668*bd1f8aebSAndroid Build Coastguard Worker FD_ZERO(&fds);
669*bd1f8aebSAndroid Build Coastguard Worker FD_SET(sock, &fds);
670*bd1f8aebSAndroid Build Coastguard Worker if (reset_timer) {
671*bd1f8aebSAndroid Build Coastguard Worker /*
672*bd1f8aebSAndroid Build Coastguard Worker * traceroute could hang if someone else has a ping
673*bd1f8aebSAndroid Build Coastguard Worker * running and our ICMP reply gets dropped but we don't
674*bd1f8aebSAndroid Build Coastguard Worker * realize it because we keep waking up to handle those
675*bd1f8aebSAndroid Build Coastguard Worker * other ICMP packets that keep coming in. To fix this,
676*bd1f8aebSAndroid Build Coastguard Worker * "reset_timer" will only be true if the last packet that
677*bd1f8aebSAndroid Build Coastguard Worker * came in was for us or if this is the first time we're
678*bd1f8aebSAndroid Build Coastguard Worker * waiting for a reply since sending out a probe. Note
679*bd1f8aebSAndroid Build Coastguard Worker * that this takes advantage of the select() feature on
680*bd1f8aebSAndroid Build Coastguard Worker * Linux where the remaining timeout is written to the
681*bd1f8aebSAndroid Build Coastguard Worker * struct timeval area.
682*bd1f8aebSAndroid Build Coastguard Worker */
683*bd1f8aebSAndroid Build Coastguard Worker wait.tv_sec = waittime;
684*bd1f8aebSAndroid Build Coastguard Worker wait.tv_usec = 0;
685*bd1f8aebSAndroid Build Coastguard Worker }
686*bd1f8aebSAndroid Build Coastguard Worker
687*bd1f8aebSAndroid Build Coastguard Worker if (select(sock+1, &fds, (fd_set *)0, (fd_set *)0, &wait) > 0) {
688*bd1f8aebSAndroid Build Coastguard Worker struct iovec iov;
689*bd1f8aebSAndroid Build Coastguard Worker struct msghdr msg;
690*bd1f8aebSAndroid Build Coastguard Worker iov.iov_base = packet;
691*bd1f8aebSAndroid Build Coastguard Worker iov.iov_len = sizeof(packet);
692*bd1f8aebSAndroid Build Coastguard Worker msg.msg_name = (void *)from;
693*bd1f8aebSAndroid Build Coastguard Worker msg.msg_namelen = sizeof(*from);
694*bd1f8aebSAndroid Build Coastguard Worker msg.msg_iov = &iov;
695*bd1f8aebSAndroid Build Coastguard Worker msg.msg_iovlen = 1;
696*bd1f8aebSAndroid Build Coastguard Worker msg.msg_flags = 0;
697*bd1f8aebSAndroid Build Coastguard Worker msg.msg_control = cbuf;
698*bd1f8aebSAndroid Build Coastguard Worker msg.msg_controllen = sizeof(cbuf);
699*bd1f8aebSAndroid Build Coastguard Worker
700*bd1f8aebSAndroid Build Coastguard Worker cc = recvmsg(icmp_sock, &msg, 0);
701*bd1f8aebSAndroid Build Coastguard Worker if (cc >= 0) {
702*bd1f8aebSAndroid Build Coastguard Worker struct cmsghdr *cmsg;
703*bd1f8aebSAndroid Build Coastguard Worker struct in6_pktinfo *ipi;
704*bd1f8aebSAndroid Build Coastguard Worker
705*bd1f8aebSAndroid Build Coastguard Worker for (cmsg = CMSG_FIRSTHDR(&msg);
706*bd1f8aebSAndroid Build Coastguard Worker cmsg;
707*bd1f8aebSAndroid Build Coastguard Worker cmsg = CMSG_NXTHDR(&msg, cmsg)) {
708*bd1f8aebSAndroid Build Coastguard Worker if (cmsg->cmsg_level != SOL_IPV6)
709*bd1f8aebSAndroid Build Coastguard Worker continue;
710*bd1f8aebSAndroid Build Coastguard Worker switch (cmsg->cmsg_type) {
711*bd1f8aebSAndroid Build Coastguard Worker case IPV6_PKTINFO:
712*bd1f8aebSAndroid Build Coastguard Worker #ifdef IPV6_2292PKTINFO
713*bd1f8aebSAndroid Build Coastguard Worker case IPV6_2292PKTINFO:
714*bd1f8aebSAndroid Build Coastguard Worker #endif
715*bd1f8aebSAndroid Build Coastguard Worker ipi = (struct in6_pktinfo *)CMSG_DATA(cmsg);
716*bd1f8aebSAndroid Build Coastguard Worker memcpy(to, ipi, sizeof(*to));
717*bd1f8aebSAndroid Build Coastguard Worker }
718*bd1f8aebSAndroid Build Coastguard Worker }
719*bd1f8aebSAndroid Build Coastguard Worker }
720*bd1f8aebSAndroid Build Coastguard Worker }
721*bd1f8aebSAndroid Build Coastguard Worker
722*bd1f8aebSAndroid Build Coastguard Worker return(cc);
723*bd1f8aebSAndroid Build Coastguard Worker }
724*bd1f8aebSAndroid Build Coastguard Worker
725*bd1f8aebSAndroid Build Coastguard Worker
send_probe(int seq,int ttl)726*bd1f8aebSAndroid Build Coastguard Worker void send_probe(int seq, int ttl)
727*bd1f8aebSAndroid Build Coastguard Worker {
728*bd1f8aebSAndroid Build Coastguard Worker struct pkt_format *pkt = (struct pkt_format *) sendbuff;
729*bd1f8aebSAndroid Build Coastguard Worker int i;
730*bd1f8aebSAndroid Build Coastguard Worker
731*bd1f8aebSAndroid Build Coastguard Worker pkt->ident = htonl(ident);
732*bd1f8aebSAndroid Build Coastguard Worker pkt->seq = htonl(seq);
733*bd1f8aebSAndroid Build Coastguard Worker gettimeofday(&pkt->tv, &tz);
734*bd1f8aebSAndroid Build Coastguard Worker
735*bd1f8aebSAndroid Build Coastguard Worker i = setsockopt(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
736*bd1f8aebSAndroid Build Coastguard Worker if (i < 0)
737*bd1f8aebSAndroid Build Coastguard Worker {
738*bd1f8aebSAndroid Build Coastguard Worker perror("setsockopt");
739*bd1f8aebSAndroid Build Coastguard Worker exit(1);
740*bd1f8aebSAndroid Build Coastguard Worker }
741*bd1f8aebSAndroid Build Coastguard Worker
742*bd1f8aebSAndroid Build Coastguard Worker do {
743*bd1f8aebSAndroid Build Coastguard Worker i = sendto(sndsock, sendbuff, datalen, 0,
744*bd1f8aebSAndroid Build Coastguard Worker (struct sockaddr *)&whereto, sizeof(whereto));
745*bd1f8aebSAndroid Build Coastguard Worker } while (i<0 && errno == ECONNREFUSED);
746*bd1f8aebSAndroid Build Coastguard Worker
747*bd1f8aebSAndroid Build Coastguard Worker if (i < 0 || i != datalen) {
748*bd1f8aebSAndroid Build Coastguard Worker if (i<0)
749*bd1f8aebSAndroid Build Coastguard Worker perror("sendto");
750*bd1f8aebSAndroid Build Coastguard Worker Printf("traceroute: wrote %s %d chars, ret=%d\n", hostname,
751*bd1f8aebSAndroid Build Coastguard Worker datalen, i);
752*bd1f8aebSAndroid Build Coastguard Worker (void) fflush(stdout);
753*bd1f8aebSAndroid Build Coastguard Worker }
754*bd1f8aebSAndroid Build Coastguard Worker }
755*bd1f8aebSAndroid Build Coastguard Worker
756*bd1f8aebSAndroid Build Coastguard Worker
deltaT(struct timeval * t1p,struct timeval * t2p)757*bd1f8aebSAndroid Build Coastguard Worker double deltaT(struct timeval *t1p, struct timeval *t2p)
758*bd1f8aebSAndroid Build Coastguard Worker {
759*bd1f8aebSAndroid Build Coastguard Worker register double dt;
760*bd1f8aebSAndroid Build Coastguard Worker
761*bd1f8aebSAndroid Build Coastguard Worker dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
762*bd1f8aebSAndroid Build Coastguard Worker (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
763*bd1f8aebSAndroid Build Coastguard Worker return (dt);
764*bd1f8aebSAndroid Build Coastguard Worker }
765*bd1f8aebSAndroid Build Coastguard Worker
766*bd1f8aebSAndroid Build Coastguard Worker
767*bd1f8aebSAndroid Build Coastguard Worker /*
768*bd1f8aebSAndroid Build Coastguard Worker * Convert an ICMP "type" field to a printable string.
769*bd1f8aebSAndroid Build Coastguard Worker */
pr_type(unsigned char t)770*bd1f8aebSAndroid Build Coastguard Worker char * pr_type(unsigned char t)
771*bd1f8aebSAndroid Build Coastguard Worker {
772*bd1f8aebSAndroid Build Coastguard Worker switch(t) {
773*bd1f8aebSAndroid Build Coastguard Worker /* Unknown */
774*bd1f8aebSAndroid Build Coastguard Worker case 0:
775*bd1f8aebSAndroid Build Coastguard Worker return "Error";
776*bd1f8aebSAndroid Build Coastguard Worker case 1:
777*bd1f8aebSAndroid Build Coastguard Worker /* ICMP6_DST_UNREACH: */
778*bd1f8aebSAndroid Build Coastguard Worker return "Destination Unreachable";
779*bd1f8aebSAndroid Build Coastguard Worker case 2:
780*bd1f8aebSAndroid Build Coastguard Worker /* ICMP6_PACKET_TOO_BIG: */
781*bd1f8aebSAndroid Build Coastguard Worker return "Packet Too Big";
782*bd1f8aebSAndroid Build Coastguard Worker case 3:
783*bd1f8aebSAndroid Build Coastguard Worker /* ICMP6_TIME_EXCEEDED */
784*bd1f8aebSAndroid Build Coastguard Worker return "Time Exceeded in Transit";
785*bd1f8aebSAndroid Build Coastguard Worker case 4:
786*bd1f8aebSAndroid Build Coastguard Worker /* ICMP6_PARAM_PROB */
787*bd1f8aebSAndroid Build Coastguard Worker return "Parameter Problem";
788*bd1f8aebSAndroid Build Coastguard Worker case 128:
789*bd1f8aebSAndroid Build Coastguard Worker /* ICMP6_ECHO_REQUEST */
790*bd1f8aebSAndroid Build Coastguard Worker return "Echo Request";
791*bd1f8aebSAndroid Build Coastguard Worker case 129:
792*bd1f8aebSAndroid Build Coastguard Worker /* ICMP6_ECHO_REPLY */
793*bd1f8aebSAndroid Build Coastguard Worker return "Echo Reply";
794*bd1f8aebSAndroid Build Coastguard Worker case 130:
795*bd1f8aebSAndroid Build Coastguard Worker /* ICMP6_MEMBERSHIP_QUERY */
796*bd1f8aebSAndroid Build Coastguard Worker return "Membership Query";
797*bd1f8aebSAndroid Build Coastguard Worker case 131:
798*bd1f8aebSAndroid Build Coastguard Worker /* ICMP6_MEMBERSHIP_REPORT */
799*bd1f8aebSAndroid Build Coastguard Worker return "Membership Report";
800*bd1f8aebSAndroid Build Coastguard Worker case 132:
801*bd1f8aebSAndroid Build Coastguard Worker /* ICMP6_MEMBERSHIP_REDUCTION */
802*bd1f8aebSAndroid Build Coastguard Worker return "Membership Reduction";
803*bd1f8aebSAndroid Build Coastguard Worker case 133:
804*bd1f8aebSAndroid Build Coastguard Worker /* ND_ROUTER_SOLICIT */
805*bd1f8aebSAndroid Build Coastguard Worker return "Router Solicitation";
806*bd1f8aebSAndroid Build Coastguard Worker case 134:
807*bd1f8aebSAndroid Build Coastguard Worker /* ND_ROUTER_ADVERT */
808*bd1f8aebSAndroid Build Coastguard Worker return "Router Advertisement";
809*bd1f8aebSAndroid Build Coastguard Worker case 135:
810*bd1f8aebSAndroid Build Coastguard Worker /* ND_NEIGHBOR_SOLICIT */
811*bd1f8aebSAndroid Build Coastguard Worker return "Neighbor Solicitation";
812*bd1f8aebSAndroid Build Coastguard Worker case 136:
813*bd1f8aebSAndroid Build Coastguard Worker /* ND_NEIGHBOR_ADVERT */
814*bd1f8aebSAndroid Build Coastguard Worker return "Neighbor Advertisement";
815*bd1f8aebSAndroid Build Coastguard Worker case 137:
816*bd1f8aebSAndroid Build Coastguard Worker /* ND_REDIRECT */
817*bd1f8aebSAndroid Build Coastguard Worker return "Redirect";
818*bd1f8aebSAndroid Build Coastguard Worker }
819*bd1f8aebSAndroid Build Coastguard Worker
820*bd1f8aebSAndroid Build Coastguard Worker return("OUT-OF-RANGE");
821*bd1f8aebSAndroid Build Coastguard Worker }
822*bd1f8aebSAndroid Build Coastguard Worker
823*bd1f8aebSAndroid Build Coastguard Worker
packet_ok(u_char * buf,int cc,struct sockaddr_in6 * from,struct in6_addr * to,int seq,struct timeval * tv)824*bd1f8aebSAndroid Build Coastguard Worker int packet_ok(u_char *buf, int cc, struct sockaddr_in6 *from,
825*bd1f8aebSAndroid Build Coastguard Worker struct in6_addr *to, int seq,
826*bd1f8aebSAndroid Build Coastguard Worker struct timeval *tv)
827*bd1f8aebSAndroid Build Coastguard Worker {
828*bd1f8aebSAndroid Build Coastguard Worker struct icmp6_hdr *icp;
829*bd1f8aebSAndroid Build Coastguard Worker u_char type, code;
830*bd1f8aebSAndroid Build Coastguard Worker
831*bd1f8aebSAndroid Build Coastguard Worker icp = (struct icmp6_hdr *) buf;
832*bd1f8aebSAndroid Build Coastguard Worker
833*bd1f8aebSAndroid Build Coastguard Worker type = icp->icmp6_type;
834*bd1f8aebSAndroid Build Coastguard Worker code = icp->icmp6_code;
835*bd1f8aebSAndroid Build Coastguard Worker
836*bd1f8aebSAndroid Build Coastguard Worker if ((type == ICMP6_TIME_EXCEEDED && code == ICMP6_TIME_EXCEED_TRANSIT) ||
837*bd1f8aebSAndroid Build Coastguard Worker type == ICMP6_DST_UNREACH)
838*bd1f8aebSAndroid Build Coastguard Worker {
839*bd1f8aebSAndroid Build Coastguard Worker struct ip6_hdr *hip;
840*bd1f8aebSAndroid Build Coastguard Worker struct udphdr *up;
841*bd1f8aebSAndroid Build Coastguard Worker int nexthdr;
842*bd1f8aebSAndroid Build Coastguard Worker
843*bd1f8aebSAndroid Build Coastguard Worker hip = (struct ip6_hdr *) (icp + 1);
844*bd1f8aebSAndroid Build Coastguard Worker up = (struct udphdr *)(hip+1);
845*bd1f8aebSAndroid Build Coastguard Worker nexthdr = hip->ip6_nxt;
846*bd1f8aebSAndroid Build Coastguard Worker
847*bd1f8aebSAndroid Build Coastguard Worker if (nexthdr == 44) {
848*bd1f8aebSAndroid Build Coastguard Worker nexthdr = *(unsigned char*)up;
849*bd1f8aebSAndroid Build Coastguard Worker up++;
850*bd1f8aebSAndroid Build Coastguard Worker }
851*bd1f8aebSAndroid Build Coastguard Worker if (nexthdr == IPPROTO_UDP)
852*bd1f8aebSAndroid Build Coastguard Worker {
853*bd1f8aebSAndroid Build Coastguard Worker struct pkt_format *pkt;
854*bd1f8aebSAndroid Build Coastguard Worker
855*bd1f8aebSAndroid Build Coastguard Worker pkt = (struct pkt_format *) (up + 1);
856*bd1f8aebSAndroid Build Coastguard Worker
857*bd1f8aebSAndroid Build Coastguard Worker if (ntohl(pkt->ident) == ident &&
858*bd1f8aebSAndroid Build Coastguard Worker ntohl(pkt->seq) == seq)
859*bd1f8aebSAndroid Build Coastguard Worker {
860*bd1f8aebSAndroid Build Coastguard Worker *tv = pkt->tv;
861*bd1f8aebSAndroid Build Coastguard Worker return (type == ICMP6_TIME_EXCEEDED ? -1 : code+1);
862*bd1f8aebSAndroid Build Coastguard Worker }
863*bd1f8aebSAndroid Build Coastguard Worker }
864*bd1f8aebSAndroid Build Coastguard Worker
865*bd1f8aebSAndroid Build Coastguard Worker }
866*bd1f8aebSAndroid Build Coastguard Worker
867*bd1f8aebSAndroid Build Coastguard Worker if (verbose) {
868*bd1f8aebSAndroid Build Coastguard Worker unsigned char *p;
869*bd1f8aebSAndroid Build Coastguard Worker char pa1[MAX_HOSTNAMELEN];
870*bd1f8aebSAndroid Build Coastguard Worker char pa2[MAX_HOSTNAMELEN];
871*bd1f8aebSAndroid Build Coastguard Worker int i;
872*bd1f8aebSAndroid Build Coastguard Worker
873*bd1f8aebSAndroid Build Coastguard Worker p = (unsigned char *) (icp + 1);
874*bd1f8aebSAndroid Build Coastguard Worker
875*bd1f8aebSAndroid Build Coastguard Worker Printf("\n%d bytes from %s to %s", cc,
876*bd1f8aebSAndroid Build Coastguard Worker inet_ntop(AF_INET6, &from->sin6_addr, pa1, sizeof(pa1)),
877*bd1f8aebSAndroid Build Coastguard Worker inet_ntop(AF_INET6, to, pa2, sizeof(pa2)));
878*bd1f8aebSAndroid Build Coastguard Worker
879*bd1f8aebSAndroid Build Coastguard Worker Printf(": icmp type %d (%s) code %d\n", type, pr_type(type),
880*bd1f8aebSAndroid Build Coastguard Worker icp->icmp6_code);
881*bd1f8aebSAndroid Build Coastguard Worker
882*bd1f8aebSAndroid Build Coastguard Worker cc -= sizeof(struct icmp6_hdr);
883*bd1f8aebSAndroid Build Coastguard Worker for (i = 0; i < cc ; i++) {
884*bd1f8aebSAndroid Build Coastguard Worker if (i % 16 == 0)
885*bd1f8aebSAndroid Build Coastguard Worker Printf("%04x:", i);
886*bd1f8aebSAndroid Build Coastguard Worker if (i % 4 == 0)
887*bd1f8aebSAndroid Build Coastguard Worker Printf(" ");
888*bd1f8aebSAndroid Build Coastguard Worker Printf("%02x", 0xff & (unsigned)p[i]);
889*bd1f8aebSAndroid Build Coastguard Worker if (i % 16 == 15 && i + 1 < cc)
890*bd1f8aebSAndroid Build Coastguard Worker Printf("\n");
891*bd1f8aebSAndroid Build Coastguard Worker }
892*bd1f8aebSAndroid Build Coastguard Worker Printf("\n");
893*bd1f8aebSAndroid Build Coastguard Worker }
894*bd1f8aebSAndroid Build Coastguard Worker
895*bd1f8aebSAndroid Build Coastguard Worker return(0);
896*bd1f8aebSAndroid Build Coastguard Worker }
897*bd1f8aebSAndroid Build Coastguard Worker
898*bd1f8aebSAndroid Build Coastguard Worker
print(unsigned char * buf,int cc,struct sockaddr_in6 * from)899*bd1f8aebSAndroid Build Coastguard Worker void print(unsigned char *buf, int cc, struct sockaddr_in6 *from)
900*bd1f8aebSAndroid Build Coastguard Worker {
901*bd1f8aebSAndroid Build Coastguard Worker char pa[MAX_HOSTNAMELEN];
902*bd1f8aebSAndroid Build Coastguard Worker
903*bd1f8aebSAndroid Build Coastguard Worker if (nflag)
904*bd1f8aebSAndroid Build Coastguard Worker Printf(" %s", inet_ntop(AF_INET6, &from->sin6_addr,
905*bd1f8aebSAndroid Build Coastguard Worker pa, sizeof(pa)));
906*bd1f8aebSAndroid Build Coastguard Worker else
907*bd1f8aebSAndroid Build Coastguard Worker {
908*bd1f8aebSAndroid Build Coastguard Worker const char *hostname;
909*bd1f8aebSAndroid Build Coastguard Worker struct hostent *hp;
910*bd1f8aebSAndroid Build Coastguard Worker char *s = NULL;
911*bd1f8aebSAndroid Build Coastguard Worker
912*bd1f8aebSAndroid Build Coastguard Worker hostname = inet_ntop(AF_INET6, &from->sin6_addr, pa, sizeof(pa));
913*bd1f8aebSAndroid Build Coastguard Worker
914*bd1f8aebSAndroid Build Coastguard Worker if ((hp = gethostbyaddr((char *)&from->sin6_addr,
915*bd1f8aebSAndroid Build Coastguard Worker sizeof(from->sin6_addr), AF_INET6))) {
916*bd1f8aebSAndroid Build Coastguard Worker #ifdef USE_IDN
917*bd1f8aebSAndroid Build Coastguard Worker if (idna_to_unicode_lzlz(hp->h_name, &s, 0) != IDNA_SUCCESS)
918*bd1f8aebSAndroid Build Coastguard Worker s = NULL;
919*bd1f8aebSAndroid Build Coastguard Worker #endif
920*bd1f8aebSAndroid Build Coastguard Worker }
921*bd1f8aebSAndroid Build Coastguard Worker
922*bd1f8aebSAndroid Build Coastguard Worker Printf(" %s (%s)", hp ? (s ? s : hp->h_name) : hostname, pa);
923*bd1f8aebSAndroid Build Coastguard Worker
924*bd1f8aebSAndroid Build Coastguard Worker free(s);
925*bd1f8aebSAndroid Build Coastguard Worker }
926*bd1f8aebSAndroid Build Coastguard Worker }
927*bd1f8aebSAndroid Build Coastguard Worker
928*bd1f8aebSAndroid Build Coastguard Worker
929*bd1f8aebSAndroid Build Coastguard Worker /*
930*bd1f8aebSAndroid Build Coastguard Worker * Subtract 2 timeval structs: out = out - in.
931*bd1f8aebSAndroid Build Coastguard Worker * Out is assumed to be >= in.
932*bd1f8aebSAndroid Build Coastguard Worker */
933*bd1f8aebSAndroid Build Coastguard Worker void
tvsub(out,in)934*bd1f8aebSAndroid Build Coastguard Worker tvsub(out, in)
935*bd1f8aebSAndroid Build Coastguard Worker register struct timeval *out, *in;
936*bd1f8aebSAndroid Build Coastguard Worker {
937*bd1f8aebSAndroid Build Coastguard Worker if ((out->tv_usec -= in->tv_usec) < 0) {
938*bd1f8aebSAndroid Build Coastguard Worker out->tv_sec--;
939*bd1f8aebSAndroid Build Coastguard Worker out->tv_usec += 1000000;
940*bd1f8aebSAndroid Build Coastguard Worker }
941*bd1f8aebSAndroid Build Coastguard Worker out->tv_sec -= in->tv_sec;
942*bd1f8aebSAndroid Build Coastguard Worker }
943*bd1f8aebSAndroid Build Coastguard Worker
usage(void)944*bd1f8aebSAndroid Build Coastguard Worker void usage(void)
945*bd1f8aebSAndroid Build Coastguard Worker {
946*bd1f8aebSAndroid Build Coastguard Worker fprintf(stderr,
947*bd1f8aebSAndroid Build Coastguard Worker "Usage: traceroute6 [-dnrvV] [-m max_ttl] [-p port#] [-q nqueries]\n\t\
948*bd1f8aebSAndroid Build Coastguard Worker [-s src_addr] [-t tos] [-w wait] host [data size]\n");
949*bd1f8aebSAndroid Build Coastguard Worker exit(1);
950*bd1f8aebSAndroid Build Coastguard Worker }
951