1313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* 2313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Modified for NRL 4.4BSD IPv6 release. 3313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 07/31/96 bgp 4313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 5313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Search for "#ifdef NRL" to find the changes. 6313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 7313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 8313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* 9313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Modified for Linux IPv6 by Pedro Roque <roque@di.fc.ul.pt> 10313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 31/07/1996 11313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 12313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * As ICMP error messages for IPv6 now include more than 8 bytes 13313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * UDP datagrams are now sent via an UDP socket instead of magic 14313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * RAW socket tricks. 15313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 16313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Original copyright and comments left intact. They might not 17313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * match the code anymore. 18313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 19313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 20313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/*- 21313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Copyright (c) 1990, 1993 22313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * The Regents of the University of California. All rights reserved. 23313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 24313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * This code is derived from software contributed to Berkeley by 25313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Van Jacobson. 26313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 27313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Redistribution and use in source and binary forms, with or without 28313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * modification, are permitted provided that the following conditions 29313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * are met: 30313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 1. Redistributions of source code must retain the above copyright 31313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * notice, this list of conditions and the following disclaimer. 32313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 2. Redistributions in binary form must reproduce the above copyright 33313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * notice, this list of conditions and the following disclaimer in the 34313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * documentation and/or other materials provided with the distribution. 35313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 3. All advertising materials mentioning features or use of this software 36313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * must display the following acknowledgement: 37313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * This product includes software developed by the University of 38313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * California, Berkeley and its contributors. 39313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 4. Neither the name of the University nor the names of its contributors 40313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * may be used to endorse or promote products derived from this software 41313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * without specific prior written permission. 42313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 43313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 44313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 45313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 46313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 47313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 48313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 49313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 50313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 51313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 52313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 53313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * SUCH DAMAGE. 54313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 55313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 56313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifndef lint 57313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittichar copyright[] = 58313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti"@(#) Copyright (c) 1990, 1993\n\ 59313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti The Regents of the University of California. All rights reserved.\n"; 60313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif /* not lint */ 61313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 62313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* 63313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * traceroute host - trace the route ip packets follow going to "host". 64313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 65313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Attempt to trace the route an ip packet would follow to some 66313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * internet host. We find out intermediate hops by launching probe 67313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * packets with a small ttl (time to live) then listening for an 68313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * icmp "time exceeded" reply from a gateway. We start our probes 69313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * with a ttl of one and increase by one until we get an icmp "port 70313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * unreachable" (which means we got to "host") or hit a max (which 71313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * defaults to 30 hops & can be changed with the -m flag). Three 72313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * probes (change with -q flag) are sent at each ttl setting and a 73313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * line is printed showing the ttl, address of the gateway and 74313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * round trip time of each probe. If the probe answers come from 75313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * different gateways, the address of each responding system will 76313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * be printed. If there is no response within a 5 sec. timeout 77313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * interval (changed with the -w flag), a "*" is printed for that 78313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * probe. 79313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 80313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Probe packets are UDP format. We don't want the destination 81313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * host to process them so the destination port is set to an 82313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * unlikely value (if some clod on the destination is using that 83313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * value, it can be changed with the -p flag). 84313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 85313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * A sample use might be: 86313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 87313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * [yak 71]% traceroute nis.nsf.net. 88313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 56 byte packet 89313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 1 helios.ee.lbl.gov (128.3.112.1) 19 ms 19 ms 0 ms 90313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms 91313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms 92313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 39 ms 93313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 39 ms 39 ms 39 ms 94313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 6 128.32.197.4 (128.32.197.4) 40 ms 59 ms 59 ms 95313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 59 ms 96313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 8 129.140.70.13 (129.140.70.13) 99 ms 99 ms 80 ms 97313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 9 129.140.71.6 (129.140.71.6) 139 ms 239 ms 319 ms 98313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 10 129.140.81.7 (129.140.81.7) 220 ms 199 ms 199 ms 99313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 11 nic.merit.edu (35.1.1.48) 239 ms 239 ms 239 ms 100313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 101313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Note that lines 2 & 3 are the same. This is due to a buggy 102313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards 103313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * packets with a zero ttl. 104313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 105313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * A more interesting example is: 106313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 107313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * [yak 72]% traceroute allspice.lcs.mit.edu. 108313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max 109313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms 110313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 19 ms 19 ms 111313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 19 ms 112313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 19 ms 39 ms 39 ms 113313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 20 ms 39 ms 39 ms 114313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 6 128.32.197.4 (128.32.197.4) 59 ms 119 ms 39 ms 115313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 39 ms 116313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 8 129.140.70.13 (129.140.70.13) 80 ms 79 ms 99 ms 117313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 9 129.140.71.6 (129.140.71.6) 139 ms 139 ms 159 ms 118313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 10 129.140.81.7 (129.140.81.7) 199 ms 180 ms 300 ms 119313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 11 129.140.72.17 (129.140.72.17) 300 ms 239 ms 239 ms 120313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 12 * * * 121313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 13 128.121.54.72 (128.121.54.72) 259 ms 499 ms 279 ms 122313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 14 * * * 123313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 15 * * * 124313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 16 * * * 125313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 17 * * * 126313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 18 ALLSPICE.LCS.MIT.EDU (18.26.0.115) 339 ms 279 ms 279 ms 127313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 128313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * (I start to see why I'm having so much trouble with mail to 129313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * MIT.) Note that the gateways 12, 14, 15, 16 & 17 hops away 130313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * either don't send ICMP "time exceeded" messages or send them 131313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * with a ttl too small to reach us. 14 - 17 are running the 132313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * MIT C Gateway code that doesn't send "time exceeded"s. God 133313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * only knows what's going on with 12. 134313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 135313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * The silent gateway 12 in the above may be the result of a bug in 136313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * the 4.[23]BSD network code (and its derivatives): 4.x (x <= 3) 137313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * sends an unreachable message using whatever ttl remains in the 138313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * original datagram. Since, for gateways, the remaining ttl is 139313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * zero, the icmp "time exceeded" is guaranteed to not make it back 140313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * to us. The behavior of this bug is slightly more interesting 141313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * when it appears on the destination system: 142313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 143313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms 144313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 39 ms 145313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 39 ms 19 ms 146313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 19 ms 147313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 5 ccn-nerif35.Berkeley.EDU (128.32.168.35) 39 ms 39 ms 39 ms 148313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 6 csgw.Berkeley.EDU (128.32.133.254) 39 ms 59 ms 39 ms 149313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 7 * * * 150313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 8 * * * 151313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 9 * * * 152313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 10 * * * 153313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 11 * * * 154313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 12 * * * 155313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 13 rip.Berkeley.EDU (128.32.131.22) 59 ms ! 39 ms ! 39 ms ! 156313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 157313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Notice that there are 12 "gateways" (13 is the final 158313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * destination) and exactly the last half of them are "missing". 159313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * What's really happening is that rip (a Sun-3 running Sun OS3.5) 160313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * is using the ttl from our arriving datagram as the ttl in its 161313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * icmp reply. So, the reply will time out on the return path 162313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * (with no notice sent to anyone since icmp's aren't sent for 163313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * icmp's) until we probe with a ttl that's at least twice the path 164313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * length. I.e., rip is really only 7 hops away. A reply that 165313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * returns with a ttl of 1 is a clue this problem exists. 166313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Traceroute prints a "!" after the time if the ttl is <= 1. 167313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or 168313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * non-standard (HPUX) software, expect to see this problem 169313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * frequently and/or take care picking the target host of your 170313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * probes. 171313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 172313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Other possible annotations after the time are !H, !N, !P (got a host, 173313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * network or protocol unreachable, respectively), !S or !F (source 174313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * route failed or fragmentation needed -- neither of these should 175313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * ever occur and the associated gateway is busted if you see one). If 176313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * almost all the probes result in some kind of unreachable, traceroute 177313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * will give up and exit. 178313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 179313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Notes 180313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * ----- 181313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * This program must be run by root or be setuid. (I suggest that 182313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * you *don't* make it setuid -- casual use could result in a lot 183313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * of unnecessary traffic on our poor, congested nets.) 184313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 185313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * This program requires a kernel mod that does not appear in any 186313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * system available from Berkeley: A raw ip socket using proto 187313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * IPPROTO_RAW must interpret the data sent as an ip datagram (as 188313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * opposed to data to be wrapped in a ip datagram). See the README 189313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * file that came with the source to this program for a description 190313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * of the mods I made to /sys/netinet/raw_ip.c. Your mileage may 191313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * vary. But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE 192313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * MODIFIED TO RUN THIS PROGRAM. 193313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 194313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * The udp port usage may appear bizarre (well, ok, it is bizarre). 195313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * The problem is that an icmp message only contains 8 bytes of 196313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * data from the original datagram. 8 bytes is the size of a udp 197313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * header so, if we want to associate replies with the original 198313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * datagram, the necessary information must be encoded into the 199313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * udp header (the ip id could be used but there's no way to 200313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * interlock with the kernel's assignment of ip id's and, anyway, 201313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * it would have taken a lot more kernel hacking to allow this 202313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * code to set the ip id). So, to allow two or more users to 203313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * use traceroute simultaneously, we use this task's pid as the 204313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * source port (the high bit is set to move the port number out 205313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * of the "likely" range). To keep track of which probe is being 206313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * replied to (so times and/or hop counts don't get confused by a 207313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * reply that was delayed in transit), we increment the destination 208313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * port number before each probe. 209313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 210313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Don't use this as a coding example. I was trying to find a 211313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * routing problem and this code sort-of popped out after 48 hours 212313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * without sleep. I was amazed it ever compiled, much less ran. 213313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 214313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * I stole the idea for this program from Steve Deering. Since 215313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * the first release, I've learned that had I attended the right 216313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * IETF working group meetings, I also could have stolen it from Guy 217313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Almes or Matt Mathis. I don't know (or care) who came up with 218313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * the idea first. I envy the originators' perspicacity and I'm 219313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * glad they didn't keep the idea a secret. 220313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 221313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or 222313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * enhancements to the original distribution. 223313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 224313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * I've hacked up a round-trip-route version of this that works by 225313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * sending a loose-source-routed udp datagram through the destination 226313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * back to yourself. Unfortunately, SO many gateways botch source 227313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * routing, the thing is almost worthless. Maybe one day... 228313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * 229313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * -- Van Jacobson (van@helios.ee.lbl.gov) 230313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Tue Dec 20 03:50:13 PST 1988 231313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 232313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 233313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/param.h> 234313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/time.h> 235313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/socket.h> 236313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/file.h> 237313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/ioctl.h> 238313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <net/if.h> 239313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 240313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#if __linux__ 241313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <endian.h> 242313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 243313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <netinet/in_systm.h> 244313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <netinet/in.h> 245313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <netinet/ip.h> 246313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <netinet/ip_icmp.h> 247313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <netinet/udp.h> 248313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 249313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <netinet/ip6.h> 250313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <netinet/icmp6.h> 251313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <linux/types.h> 252313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifdef CAPABILITIES 253313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <sys/capability.h> 254313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 255313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 256313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifdef USE_IDN 257313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <idna.h> 258313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <locale.h> 259313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 260313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 261313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <arpa/inet.h> 262313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 263313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <netdb.h> 264313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <stdio.h> 265313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <errno.h> 266313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <stdlib.h> 267313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <string.h> 268313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include <unistd.h> 269313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 270313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#include "SNAPSHOT.h" 271313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 272313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifndef SOL_IPV6 273313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define SOL_IPV6 IPPROTO_IPV6 274313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 275313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 276313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define MAXPACKET 65535 277313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define MAX_HOSTNAMELEN NI_MAXHOST 278313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 279313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifndef FD_SET 280313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define NFDBITS (8*sizeof(fd_set)) 281313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define FD_SETSIZE NFDBITS 282313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) 283313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) 284313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) 285313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define FD_ZERO(p) memset((char *)(p), 0, sizeof(*(p))) 286313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 287313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 288313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define Fprintf (void)fprintf 289313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#define Printf (void)printf 290313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 291313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiu_char packet[512]; /* last inbound (icmp) packet */ 292313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 293313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint wait_for_reply(int, struct sockaddr_in6 *, struct in6_addr *, int); 294313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint packet_ok(u_char *buf, int cc, struct sockaddr_in6 *from, 295313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct in6_addr *to, int seq, struct timeval *); 296313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid send_probe(int seq, int ttl); 297313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittidouble deltaT (struct timeval *, struct timeval *); 298313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid print(unsigned char *buf, int cc, struct sockaddr_in6 *from); 299313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid tvsub (struct timeval *, struct timeval *); 300313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid usage(void); 301313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 302313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint icmp_sock; /* receive (icmp) socket file descriptor */ 303313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint sndsock; /* send (udp) socket file descriptor */ 304313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct timezone tz; /* leftover */ 305313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 306313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct sockaddr_in6 whereto; /* Who to try to reach */ 307313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 308313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct sockaddr_in6 saddr; 309313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct sockaddr_in6 firsthop; 310313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittichar *source = NULL; 311313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittichar *device = NULL; 312313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittichar *hostname; 313313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 314313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint nprobes = 3; 315313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint max_ttl = 30; 316313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittipid_t ident; 317313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiu_short port = 32768+666; /* start udp dest port # for probe packets */ 318313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint options; /* socket options */ 319313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint verbose; 320313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint waittime = 5; /* time to wait for response (in seconds) */ 321313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint nflag; /* print addresses numerically */ 322313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 323313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 324313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittistruct pkt_format 325313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 326313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __u32 ident; 327313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti __u32 seq; 328313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct timeval tv; 329313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti}; 330313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 331313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittichar *sendbuff; 332313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint datalen = sizeof(struct pkt_format); 333313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 334313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 335313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 336313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint main(int argc, char *argv[]) 337313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 338313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char pa[MAX_HOSTNAMELEN]; 339313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti extern char *optarg; 340313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti extern int optind; 341313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct hostent *hp; 342313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct sockaddr_in6 from, *to; 343313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int ch, i, on, probe, seq, tos, ttl; 344313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int socket_errno; 345313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 346313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); 347313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti socket_errno = errno; 348313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 349313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (setuid(getuid())) { 350313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti perror("traceroute6: setuid"); 351313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(-1); 352313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 353313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifdef CAPABILITIES 354313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti { 355313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti cap_t caps = cap_init(); 356313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (cap_set_proc(caps)) { 357313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti perror("traceroute6: cap_set_proc"); 358313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(-1); 359313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 360313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti cap_free(caps); 361313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 362313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 363313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 364313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifdef USE_IDN 365313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti setlocale(LC_ALL, ""); 366313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 367313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 368313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti on = 1; 369313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti seq = tos = 0; 370313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti to = (struct sockaddr_in6 *)&whereto; 371313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti while ((ch = getopt(argc, argv, "dm:np:q:rs:t:w:vi:g:V")) != EOF) { 372313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti switch(ch) { 373313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'd': 374313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti options |= SO_DEBUG; 375313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 376313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'm': 377313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti max_ttl = atoi(optarg); 378313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (max_ttl <= 1) { 379313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Fprintf(stderr, 380313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti "traceroute: max ttl must be >1.\n"); 381313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 382313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 383313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 384313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'n': 385313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti nflag++; 386313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 387313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'p': 388313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti port = atoi(optarg); 389313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (port < 1) { 390313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Fprintf(stderr, 391313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti "traceroute: port must be >0.\n"); 392313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 393313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 394313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 395313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'q': 396313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti nprobes = atoi(optarg); 397313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (nprobes < 1) { 398313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Fprintf(stderr, 399313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti "traceroute: nprobes must be >0.\n"); 400313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 401313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 402313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 403313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'r': 404313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti options |= SO_DONTROUTE; 405313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 406313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 's': 407313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* 408313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * set the ip source address of the outbound 409313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * probe (e.g., on a multi-homed host). 410313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 411313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti source = optarg; 412313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 413313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'i': 414313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti device = optarg; 415313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 416313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'g': 417313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Fprintf(stderr, "Sorry, rthdr is not yet supported\n"); 418313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 419313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'v': 420313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti verbose++; 421313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 422313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'w': 423313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti waittime = atoi(optarg); 424313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (waittime <= 1) { 425313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Fprintf(stderr, 426313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti "traceroute: wait must be >1 sec.\n"); 427313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 428313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 429313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 430313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 'V': 431313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti printf("traceroute6 utility, iputils-%s\n", SNAPSHOT); 432313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(0); 433313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti default: 434313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti usage(); 435313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 436313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 437313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti argc -= optind; 438313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti argv += optind; 439313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 440313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (argc < 1) 441313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti usage(); 442313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 443313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti setlinebuf (stdout); 444313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 445313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti (void) memset((char *)&whereto, 0, sizeof(whereto)); 446313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 447313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti to->sin6_family = AF_INET6; 448313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti to->sin6_port = htons(port); 449313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 450313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (inet_pton(AF_INET6, *argv, &to->sin6_addr) > 0) { 451313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti hostname = *argv; 452313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } else { 453313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char *idn = NULL; 454313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifdef USE_IDN 455313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (idna_to_ascii_lz(*argv, &idn, 0) != IDNA_SUCCESS) 456313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti idn = NULL; 457313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 458313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti hp = gethostbyname2(idn ? idn : *argv, AF_INET6); 459313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (hp) { 460313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memmove((caddr_t)&to->sin6_addr, hp->h_addr, sizeof(to->sin6_addr)); 461313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti hostname = (char *)hp->h_name; 462313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } else { 463313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti (void)fprintf(stderr, 464313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti "traceroute: unknown host %s\n", *argv); 465313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 466313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 467313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 468313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti firsthop = *to; 469313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (*++argv) { 470313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti datalen = atoi(*argv); 471313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Message for rpm maintainers: have _shame_. If you want 472313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * to fix something send the patch to me for sanity checking. 473313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * "datalen" patch is a shit. */ 474313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (datalen == 0) 475313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti datalen = sizeof(struct pkt_format); 476313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti else if (datalen < (int)sizeof(struct pkt_format) || 477313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti datalen >= MAXPACKET) { 478313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Fprintf(stderr, 479313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti "traceroute: packet size must be %d <= s < %d.\n", 480313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti (int)sizeof(struct pkt_format), MAXPACKET); 481313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 482313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 483313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 484313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 485313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ident = getpid(); 486313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 487313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sendbuff = malloc(datalen); 488313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (sendbuff == NULL) { 489313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti fprintf(stderr, "malloc failed\n"); 490313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 491313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 492313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 493313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (icmp_sock < 0) { 494313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti errno = socket_errno; 495313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti perror("traceroute6: icmp socket"); 496313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 497313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 498313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 499313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifdef IPV6_RECVPKTINFO 500313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti setsockopt(icmp_sock, SOL_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)); 501313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti setsockopt(icmp_sock, SOL_IPV6, IPV6_2292PKTINFO, &on, sizeof(on)); 502313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#else 503313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti setsockopt(icmp_sock, SOL_IPV6, IPV6_PKTINFO, &on, sizeof(on)); 504313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 505313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 506313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (options & SO_DEBUG) 507313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti setsockopt(icmp_sock, SOL_SOCKET, SO_DEBUG, 508313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti (char *)&on, sizeof(on)); 509313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (options & SO_DONTROUTE) 510313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti setsockopt(icmp_sock, SOL_SOCKET, SO_DONTROUTE, 511313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti (char *)&on, sizeof(on)); 512313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 513313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifdef __linux__ 514313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti on = 2; 515313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (setsockopt(icmp_sock, SOL_RAW, IPV6_CHECKSUM, &on, sizeof(on)) < 0) { 516313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* checksum should be enabled by default and setting this 517313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * option might fail anyway. 518313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 519313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti fprintf(stderr, "setsockopt(RAW_CHECKSUM) failed - try to continue."); 520313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 521313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 522313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 523313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 524313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti perror("traceroute: UDP socket"); 525313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(5); 526313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 527313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifdef SO_SNDBUF 528313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen, 529313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sizeof(datalen)) < 0) { 530313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti perror("traceroute: SO_SNDBUF"); 531313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(6); 532313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 533313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif /* SO_SNDBUF */ 534313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 535313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (options & SO_DEBUG) 536313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti (void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, 537313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti (char *)&on, sizeof(on)); 538313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (options & SO_DONTROUTE) 539313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti (void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, 540313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti (char *)&on, sizeof(on)); 541313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 542313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (source == NULL) { 543313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti socklen_t alen; 544313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int probe_fd = socket(AF_INET6, SOCK_DGRAM, 0); 545313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 546313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (probe_fd < 0) { 547313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti perror("socket"); 548313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 549313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 550313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (device) { 551313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device)+1) == -1) 552313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti perror("WARNING: interface is ignored"); 553313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 554313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti firsthop.sin6_port = htons(1025); 555313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (connect(probe_fd, (struct sockaddr*)&firsthop, sizeof(firsthop)) == -1) { 556313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti perror("connect"); 557313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 558313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 559313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti alen = sizeof(saddr); 560313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (getsockname(probe_fd, (struct sockaddr*)&saddr, &alen) == -1) { 561313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti perror("getsockname"); 562313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 563313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 564313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti saddr.sin6_port = 0; 565313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti close(probe_fd); 566313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } else { 567313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti (void) memset((char *)&saddr, 0, sizeof(saddr)); 568313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti saddr.sin6_family = AF_INET6; 569313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (inet_pton(AF_INET6, source, &saddr.sin6_addr) <= 0) 570313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti { 571313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Printf("traceroute: unknown addr %s\n", source); 572313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 573313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 574313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 575313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 576313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (bind(sndsock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { 577313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti perror ("traceroute: bind sending socket"); 578313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit (1); 579313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 580313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (bind(icmp_sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { 581313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti perror ("traceroute: bind icmp6 socket"); 582313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit (1); 583313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 584313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 585313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Fprintf(stderr, "traceroute to %s (%s)", hostname, 586313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti inet_ntop(AF_INET6, &to->sin6_addr, pa, sizeof(pa))); 587313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 588313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Fprintf(stderr, " from %s", 589313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti inet_ntop(AF_INET6, &saddr.sin6_addr, pa, sizeof(pa))); 590313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, datalen); 591313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti (void) fflush(stderr); 592313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 593313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (ttl = 1; ttl <= max_ttl; ++ttl) { 594313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct in6_addr lastaddr = {{{0,}}}; 595313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int got_there = 0; 596313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int unreachable = 0; 597313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 598313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Printf("%2d ", ttl); 599313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (probe = 0; probe < nprobes; ++probe) { 600313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int cc, reset_timer; 601313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct timeval t1, t2; 602313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct timezone tz; 603313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct in6_addr to; 604313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 605313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti gettimeofday(&t1, &tz); 606313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti send_probe(++seq, ttl); 607313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti reset_timer = 1; 608313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 609313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti while ((cc = wait_for_reply(icmp_sock, &from, &to, reset_timer)) != 0) { 610313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti gettimeofday(&t2, &tz); 611313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if ((i = packet_ok(packet, cc, &from, &to, seq, &t1))) { 612313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti reset_timer = 1; 613313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (memcmp(&from.sin6_addr, &lastaddr, sizeof(from.sin6_addr))) { 614313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti print(packet, cc, &from); 615313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memcpy(&lastaddr, 616313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti &from.sin6_addr, 617313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sizeof(lastaddr)); 618313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 619313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Printf(" %g ms", deltaT(&t1, &t2)); 620313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti switch(i - 1) { 621313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case ICMP6_DST_UNREACH_NOPORT: 622313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ++got_there; 623313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 624313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 625313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case ICMP6_DST_UNREACH_NOROUTE: 626313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ++unreachable; 627313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Printf(" !N"); 628313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 629313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case ICMP6_DST_UNREACH_ADDR: 630313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ++unreachable; 631313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Printf(" !H"); 632313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 633313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 634313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case ICMP6_DST_UNREACH_ADMIN: 635313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ++unreachable; 636313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Printf(" !S"); 637313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 638313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 639313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti break; 640313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } else 641313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti reset_timer = 0; 642313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 643313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (cc <= 0) 644313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Printf(" *"); 645313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti (void) fflush(stdout); 646313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 647313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti putchar('\n'); 648313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (got_there || 649313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti (unreachable > 0 && unreachable >= nprobes-1)) 650313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(0); 651313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 652313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 653313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return 0; 654313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 655313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 656313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint 657313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiwait_for_reply(sock, from, to, reset_timer) 658313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int sock; 659313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct sockaddr_in6 *from; 660313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct in6_addr *to; 661313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int reset_timer; 662313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 663313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti fd_set fds; 664313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti static struct timeval wait; 665313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int cc = 0; 666313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char cbuf[512]; 667313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 668313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti FD_ZERO(&fds); 669313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti FD_SET(sock, &fds); 670313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (reset_timer) { 671313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* 672313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * traceroute could hang if someone else has a ping 673313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * running and our ICMP reply gets dropped but we don't 674313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * realize it because we keep waking up to handle those 675313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * other ICMP packets that keep coming in. To fix this, 676313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * "reset_timer" will only be true if the last packet that 677313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * came in was for us or if this is the first time we're 678313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * waiting for a reply since sending out a probe. Note 679313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * that this takes advantage of the select() feature on 680313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Linux where the remaining timeout is written to the 681313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * struct timeval area. 682313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 683313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti wait.tv_sec = waittime; 684313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti wait.tv_usec = 0; 685313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 686313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 687313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (select(sock+1, &fds, (fd_set *)0, (fd_set *)0, &wait) > 0) { 688313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct iovec iov; 689313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct msghdr msg; 690313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti iov.iov_base = packet; 691313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti iov.iov_len = sizeof(packet); 692313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti msg.msg_name = (void *)from; 693313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti msg.msg_namelen = sizeof(*from); 694313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti msg.msg_iov = &iov; 695313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti msg.msg_iovlen = 1; 696313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti msg.msg_flags = 0; 697313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti msg.msg_control = cbuf; 698313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti msg.msg_controllen = sizeof(cbuf); 699313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 700313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti cc = recvmsg(icmp_sock, &msg, 0); 701313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (cc >= 0) { 702313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct cmsghdr *cmsg; 703313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct in6_pktinfo *ipi; 704313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 705313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (cmsg = CMSG_FIRSTHDR(&msg); 706313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti cmsg; 707313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti cmsg = CMSG_NXTHDR(&msg, cmsg)) { 708313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (cmsg->cmsg_level != SOL_IPV6) 709313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti continue; 710313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti switch (cmsg->cmsg_type) { 711313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case IPV6_PKTINFO: 712313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifdef IPV6_2292PKTINFO 713313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case IPV6_2292PKTINFO: 714313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 715313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ipi = (struct in6_pktinfo *)CMSG_DATA(cmsg); 716313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti memcpy(to, ipi, sizeof(*to)); 717313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 718313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 719313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 720313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 721313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 722313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return(cc); 723313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 724313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 725313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 726313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid send_probe(int seq, int ttl) 727313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 728313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct pkt_format *pkt = (struct pkt_format *) sendbuff; 729313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int i; 730313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 731313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pkt->ident = htonl(ident); 732313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pkt->seq = htonl(seq); 733313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti gettimeofday(&pkt->tv, &tz); 734313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 735313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti i = setsockopt(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)); 736313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (i < 0) 737313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti { 738313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti perror("setsockopt"); 739313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 740313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 741313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 742313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti do { 743313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti i = sendto(sndsock, sendbuff, datalen, 0, 744313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti (struct sockaddr *)&whereto, sizeof(whereto)); 745313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } while (i<0 && errno == ECONNREFUSED); 746313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 747313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (i < 0 || i != datalen) { 748313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (i<0) 749313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti perror("sendto"); 750313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Printf("traceroute: wrote %s %d chars, ret=%d\n", hostname, 751313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti datalen, i); 752313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti (void) fflush(stdout); 753313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 754313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 755313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 756313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 757313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittidouble deltaT(struct timeval *t1p, struct timeval *t2p) 758313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 759313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti register double dt; 760313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 761313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 + 762313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0; 763313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return (dt); 764313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 765313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 766313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 767313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* 768313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Convert an ICMP "type" field to a printable string. 769313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 770313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittichar * pr_type(unsigned char t) 771313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 772313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti switch(t) { 773313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* Unknown */ 774313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 0: 775313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return "Error"; 776313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 1: 777313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* ICMP6_DST_UNREACH: */ 778313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return "Destination Unreachable"; 779313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 2: 780313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* ICMP6_PACKET_TOO_BIG: */ 781313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return "Packet Too Big"; 782313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 3: 783313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* ICMP6_TIME_EXCEEDED */ 784313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return "Time Exceeded in Transit"; 785313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 4: 786313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* ICMP6_PARAM_PROB */ 787313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return "Parameter Problem"; 788313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 128: 789313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* ICMP6_ECHO_REQUEST */ 790313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return "Echo Request"; 791313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 129: 792313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* ICMP6_ECHO_REPLY */ 793313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return "Echo Reply"; 794313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 130: 795313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* ICMP6_MEMBERSHIP_QUERY */ 796313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return "Membership Query"; 797313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 131: 798313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* ICMP6_MEMBERSHIP_REPORT */ 799313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return "Membership Report"; 800313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 132: 801313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* ICMP6_MEMBERSHIP_REDUCTION */ 802313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return "Membership Reduction"; 803313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 133: 804313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* ND_ROUTER_SOLICIT */ 805313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return "Router Solicitation"; 806313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 134: 807313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* ND_ROUTER_ADVERT */ 808313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return "Router Advertisement"; 809313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 135: 810313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* ND_NEIGHBOR_SOLICIT */ 811313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return "Neighbor Solicitation"; 812313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 136: 813313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* ND_NEIGHBOR_ADVERT */ 814313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return "Neighbor Advertisement"; 815313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti case 137: 816313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti /* ND_REDIRECT */ 817313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return "Redirect"; 818313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 819313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 820313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return("OUT-OF-RANGE"); 821313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 822313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 823313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 824313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittiint packet_ok(u_char *buf, int cc, struct sockaddr_in6 *from, 825313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct in6_addr *to, int seq, 826313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct timeval *tv) 827313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 828313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct icmp6_hdr *icp; 829313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti u_char type, code; 830313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 831313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti icp = (struct icmp6_hdr *) buf; 832313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 833313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti type = icp->icmp6_type; 834313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti code = icp->icmp6_code; 835313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 836313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if ((type == ICMP6_TIME_EXCEEDED && code == ICMP6_TIME_EXCEED_TRANSIT) || 837313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti type == ICMP6_DST_UNREACH) 838313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti { 839313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct ip6_hdr *hip; 840313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct udphdr *up; 841313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int nexthdr; 842313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 843313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti hip = (struct ip6_hdr *) (icp + 1); 844313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti up = (struct udphdr *)(hip+1); 845313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti nexthdr = hip->ip6_nxt; 846313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 847313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (nexthdr == 44) { 848313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti nexthdr = *(unsigned char*)up; 849313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti up++; 850313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 851313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (nexthdr == IPPROTO_UDP) 852313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti { 853313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct pkt_format *pkt; 854313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 855313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pkt = (struct pkt_format *) (up + 1); 856313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 857313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (ntohl(pkt->ident) == ident && 858313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti ntohl(pkt->seq) == seq) 859313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti { 860313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti *tv = pkt->tv; 861313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return (type == ICMP6_TIME_EXCEEDED ? -1 : code+1); 862313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 863313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 864313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 865313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 866313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 867313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (verbose) { 868313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti unsigned char *p; 869313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char pa1[MAX_HOSTNAMELEN]; 870313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char pa2[MAX_HOSTNAMELEN]; 871313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti int i; 872313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 873313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti p = (unsigned char *) (icp + 1); 874313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 875313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Printf("\n%d bytes from %s to %s", cc, 876313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti inet_ntop(AF_INET6, &from->sin6_addr, pa1, sizeof(pa1)), 877313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti inet_ntop(AF_INET6, to, pa2, sizeof(pa2))); 878313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 879313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Printf(": icmp type %d (%s) code %d\n", type, pr_type(type), 880313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti icp->icmp6_code); 881313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 882313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti cc -= sizeof(struct icmp6_hdr); 883313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti for (i = 0; i < cc ; i++) { 884313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (i % 16 == 0) 885313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Printf("%04x:", i); 886313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (i % 4 == 0) 887313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Printf(" "); 888313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Printf("%02x", 0xff & (unsigned)p[i]); 889313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (i % 16 == 15 && i + 1 < cc) 890313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Printf("\n"); 891313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 892313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Printf("\n"); 893313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 894313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 895313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti return(0); 896313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 897313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 898313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 899313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid print(unsigned char *buf, int cc, struct sockaddr_in6 *from) 900313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 901313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char pa[MAX_HOSTNAMELEN]; 902313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 903313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (nflag) 904313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Printf(" %s", inet_ntop(AF_INET6, &from->sin6_addr, 905313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti pa, sizeof(pa))); 906313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti else 907313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti { 908313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti const char *hostname; 909313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti struct hostent *hp; 910313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti char *s = NULL; 911313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 912313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti hostname = inet_ntop(AF_INET6, &from->sin6_addr, pa, sizeof(pa)); 913313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 914313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if ((hp = gethostbyaddr((char *)&from->sin6_addr, 915313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti sizeof(from->sin6_addr), AF_INET6))) { 916313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#ifdef USE_IDN 917313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if (idna_to_unicode_lzlz(hp->h_name, &s, 0) != IDNA_SUCCESS) 918313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti s = NULL; 919313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti#endif 920313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 921313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 922313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti Printf(" %s (%s)", hp ? (s ? s : hp->h_name) : hostname, pa); 923313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 924313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti free(s); 925313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 926313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 927313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 928313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 929313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti/* 930313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Subtract 2 timeval structs: out = out - in. 931313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti * Out is assumed to be >= in. 932313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti */ 933313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid 934313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittitvsub(out, in) 935313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti register struct timeval *out, *in; 936313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 937313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti if ((out->tv_usec -= in->tv_usec) < 0) { 938313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti out->tv_sec--; 939313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti out->tv_usec += 1000000; 940313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti } 941313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti out->tv_sec -= in->tv_sec; 942313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 943313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti 944313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colittivoid usage(void) 945313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti{ 946313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti fprintf(stderr, 947313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti"Usage: traceroute6 [-dnrvV] [-m max_ttl] [-p port#] [-q nqueries]\n\t\ 948313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti[-s src_addr] [-t tos] [-w wait] host [data size]\n"); 949313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti exit(1); 950313379eb6b9da55f7371adef39a92153a0707d4aLorenzo Colitti} 951