2 * Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 static const char copyright[] =
24 "@(#) Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000\n\
25 The Regents of the University of California. All rights reserved.\n";
27 static const char rcsid[] =
28 "@(#)$Id: traceroute.c,v 1.68 2000/12/14 08:04:33 leres Exp $ (LBL)";
30 static const char rcsid[] =
35 * traceroute host - trace the route ip packets follow going to "host".
37 * Attempt to trace the route an ip packet would follow to some
38 * internet host. We find out intermediate hops by launching probe
39 * packets with a small ttl (time to live) then listening for an
40 * icmp "time exceeded" reply from a gateway. We start our probes
41 * with a ttl of one and increase by one until we get an icmp "port
42 * unreachable" (which means we got to "host") or hit a max (which
43 * defaults to net.inet.ip.ttl hops & can be changed with the -m flag).
44 * Three probes (change with -q flag) are sent at each ttl setting and
45 * a line is printed showing the ttl, address of the gateway and
46 * round trip time of each probe. If the probe answers come from
47 * different gateways, the address of each responding system will
48 * be printed. If there is no response within a 5 sec. timeout
49 * interval (changed with the -w flag), a "*" is printed for that
52 * Probe packets are UDP format. We don't want the destination
53 * host to process them so the destination port is set to an
54 * unlikely value (if some clod on the destination is using that
55 * value, it can be changed with the -p flag).
57 * A sample use might be:
59 * [yak 71]% traceroute nis.nsf.net.
60 * traceroute to nis.nsf.net (35.1.1.48), 64 hops max, 56 byte packet
61 * 1 helios.ee.lbl.gov (128.3.112.1) 19 ms 19 ms 0 ms
62 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
63 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
64 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 39 ms
65 * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 39 ms 39 ms 39 ms
66 * 6 128.32.197.4 (128.32.197.4) 40 ms 59 ms 59 ms
67 * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 59 ms
68 * 8 129.140.70.13 (129.140.70.13) 99 ms 99 ms 80 ms
69 * 9 129.140.71.6 (129.140.71.6) 139 ms 239 ms 319 ms
70 * 10 129.140.81.7 (129.140.81.7) 220 ms 199 ms 199 ms
71 * 11 nic.merit.edu (35.1.1.48) 239 ms 239 ms 239 ms
73 * Note that lines 2 & 3 are the same. This is due to a buggy
74 * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
75 * packets with a zero ttl.
77 * A more interesting example is:
79 * [yak 72]% traceroute allspice.lcs.mit.edu.
80 * traceroute to allspice.lcs.mit.edu (18.26.0.115), 64 hops max
81 * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms
82 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 19 ms 19 ms
83 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 19 ms
84 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 19 ms 39 ms 39 ms
85 * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 20 ms 39 ms 39 ms
86 * 6 128.32.197.4 (128.32.197.4) 59 ms 119 ms 39 ms
87 * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 39 ms
88 * 8 129.140.70.13 (129.140.70.13) 80 ms 79 ms 99 ms
89 * 9 129.140.71.6 (129.140.71.6) 139 ms 139 ms 159 ms
90 * 10 129.140.81.7 (129.140.81.7) 199 ms 180 ms 300 ms
91 * 11 129.140.72.17 (129.140.72.17) 300 ms 239 ms 239 ms
93 * 13 128.121.54.72 (128.121.54.72) 259 ms 499 ms 279 ms
98 * 18 ALLSPICE.LCS.MIT.EDU (18.26.0.115) 339 ms 279 ms 279 ms
100 * (I start to see why I'm having so much trouble with mail to
101 * MIT.) Note that the gateways 12, 14, 15, 16 & 17 hops away
102 * either don't send ICMP "time exceeded" messages or send them
103 * with a ttl too small to reach us. 14 - 17 are running the
104 * MIT C Gateway code that doesn't send "time exceeded"s. God
105 * only knows what's going on with 12.
107 * The silent gateway 12 in the above may be the result of a bug in
108 * the 4.[23]BSD network code (and its derivatives): 4.x (x <= 3)
109 * sends an unreachable message using whatever ttl remains in the
110 * original datagram. Since, for gateways, the remaining ttl is
111 * zero, the icmp "time exceeded" is guaranteed to not make it back
112 * to us. The behavior of this bug is slightly more interesting
113 * when it appears on the destination system:
115 * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms
116 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 39 ms
117 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 39 ms 19 ms
118 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 19 ms
119 * 5 ccn-nerif35.Berkeley.EDU (128.32.168.35) 39 ms 39 ms 39 ms
120 * 6 csgw.Berkeley.EDU (128.32.133.254) 39 ms 59 ms 39 ms
127 * 13 rip.Berkeley.EDU (128.32.131.22) 59 ms ! 39 ms ! 39 ms !
129 * Notice that there are 12 "gateways" (13 is the final
130 * destination) and exactly the last half of them are "missing".
131 * What's really happening is that rip (a Sun-3 running Sun OS3.5)
132 * is using the ttl from our arriving datagram as the ttl in its
133 * icmp reply. So, the reply will time out on the return path
134 * (with no notice sent to anyone since icmp's aren't sent for
135 * icmp's) until we probe with a ttl that's at least twice the path
136 * length. I.e., rip is really only 7 hops away. A reply that
137 * returns with a ttl of 1 is a clue this problem exists.
138 * Traceroute prints a "!" after the time if the ttl is <= 1.
139 * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
140 * non-standard (HPUX) software, expect to see this problem
141 * frequently and/or take care picking the target host of your
144 * Other possible annotations after the time are !H, !N, !P (got a host,
145 * network or protocol unreachable, respectively), !S or !F (source
146 * route failed or fragmentation needed -- neither of these should
147 * ever occur and the associated gateway is busted if you see one). If
148 * almost all the probes result in some kind of unreachable, traceroute
149 * will give up and exit.
153 * This program must be run by root or be setuid. (I suggest that
154 * you *don't* make it setuid -- casual use could result in a lot
155 * of unnecessary traffic on our poor, congested nets.)
157 * This program requires a kernel mod that does not appear in any
158 * system available from Berkeley: A raw ip socket using proto
159 * IPPROTO_RAW must interpret the data sent as an ip datagram (as
160 * opposed to data to be wrapped in a ip datagram). See the README
161 * file that came with the source to this program for a description
162 * of the mods I made to /sys/netinet/raw_ip.c. Your mileage may
163 * vary. But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
164 * MODIFIED TO RUN THIS PROGRAM.
166 * The udp port usage may appear bizarre (well, ok, it is bizarre).
167 * The problem is that an icmp message only contains 8 bytes of
168 * data from the original datagram. 8 bytes is the size of a udp
169 * header so, if we want to associate replies with the original
170 * datagram, the necessary information must be encoded into the
171 * udp header (the ip id could be used but there's no way to
172 * interlock with the kernel's assignment of ip id's and, anyway,
173 * it would have taken a lot more kernel hacking to allow this
174 * code to set the ip id). So, to allow two or more users to
175 * use traceroute simultaneously, we use this task's pid as the
176 * source port (the high bit is set to move the port number out
177 * of the "likely" range). To keep track of which probe is being
178 * replied to (so times and/or hop counts don't get confused by a
179 * reply that was delayed in transit), we increment the destination
180 * port number before each probe.
182 * Don't use this as a coding example. I was trying to find a
183 * routing problem and this code sort-of popped out after 48 hours
184 * without sleep. I was amazed it ever compiled, much less ran.
186 * I stole the idea for this program from Steve Deering. Since
187 * the first release, I've learned that had I attended the right
188 * IETF working group meetings, I also could have stolen it from Guy
189 * Almes or Matt Mathis. I don't know (or care) who came up with
190 * the idea first. I envy the originators' perspicacity and I'm
191 * glad they didn't keep the idea a secret.
193 * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
194 * enhancements to the original distribution.
196 * I've hacked up a round-trip-route version of this that works by
197 * sending a loose-source-routed udp datagram through the destination
198 * back to yourself. Unfortunately, SO many gateways botch source
199 * routing, the thing is almost worthless. Maybe one day...
201 * -- Van Jacobson (van@ee.lbl.gov)
202 * Tue Dec 20 03:50:13 PST 1988
205 #include <sys/param.h>
206 #include <sys/file.h>
207 #include <sys/ioctl.h>
208 #ifdef HAVE_SYS_SELECT_H
209 #include <sys/select.h>
211 #include <sys/socket.h>
212 #ifdef HAVE_SYS_SYSCTL_H
213 #include <sys/sysctl.h>
215 #include <sys/time.h>
217 #include <netinet/in_systm.h>
218 #include <netinet/in.h>
219 #include <netinet/ip.h>
220 #include <netinet/ip_var.h>
221 #include <netinet/ip_icmp.h>
222 #include <netinet/udp.h>
223 #include <netinet/udp_var.h>
224 #include <netinet/tcp.h>
225 #include <netinet/tcpip.h>
227 #include <arpa/inet.h>
230 #include <net/route.h>
231 #include <netinet6/ipsec.h> /* XXX */
249 #ifdef HAVE_OS_PROTO_H
250 #include "os-proto.h"
254 #ifndef ICMP_UNREACH_FILTER_PROHIB
255 #define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohibited filter */
257 #ifndef ICMP_UNREACH_HOST_PRECEDENCE
258 #define ICMP_UNREACH_HOST_PRECEDENCE 14 /* host precedence violation */
260 #ifndef ICMP_UNREACH_PRECEDENCE_CUTOFF
261 #define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* precedence cutoff */
264 #include "findsaddr.h"
265 #include "ifaddrlist.h"
266 #include "traceroute.h"
268 /* Maximum number of gateways (include room for one noop) */
269 #define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(u_int32_t)))
271 #ifndef MAXHOSTNAMELEN
272 #define MAXHOSTNAMELEN 64
275 #define Fprintf (void)fprintf
276 #define Printf (void)printf
278 /* What a GRE packet header looks like */
282 u_int16_t length; /* PPTP version of these fields */
286 #define IPPROTO_GRE 47
289 /* For GRE, we prepare what looks like a PPTP packet */
290 #define GRE_PPTP_PROTO 0x880b
292 /* Host name and address list */
299 /* Data section of the probe packet */
301 u_char seq; /* sequence number of this packet */
302 u_char ttl; /* ttl packet left with */
303 struct timeval tv; /* time packet left */
306 #ifndef HAVE_ICMP_NEXTMTU
307 /* Path MTU Discovery (RFC1191) */
314 u_char packet[512]; /* last inbound (icmp) packet */
316 struct ip *outip; /* last output ip packet */
317 u_char *outp; /* last output inner protocol packet */
319 /* loose source route gateway list (including room for final destination) */
320 u_int32_t gwlist[NGATEWAYS + 1];
322 int s; /* receive (icmp) socket file descriptor */
323 int sndsock; /* send (udp) socket file descriptor */
325 struct sockaddr whereto; /* Who to try to reach */
326 struct sockaddr wherefrom; /* Who we are */
327 int packlen; /* total length of packet */
328 int protlen; /* length of protocol part of packet */
329 int minpacket; /* min ip packet size */
330 int maxpacket = 32 * 1024; /* max ip packet size */
331 int pmtu; /* Path MTU Discovery (RFC1191) */
338 static const char devnull[] = "/dev/null";
344 u_short port; /* protocol specific base "port" */
346 int options; /* socket options */
348 int waittime = 5; /* time to wait for response (in seconds) */
349 int nflag; /* print addresses numerically */
350 #ifdef CANT_HACK_IPCKSUM
351 int doipcksum = 0; /* don't calculate ip checksums by default */
353 int doipcksum = 1; /* calculate ip checksums by default */
355 int optlen; /* length of ip options */
356 int fixedPort = 0; /* Use fixed destination port for TCP and UDP */
363 double deltaT(struct timeval *, struct timeval *);
364 void freehostinfo(struct hostinfo *);
365 void getaddr(u_int32_t *, char *);
366 struct hostinfo *gethostinfo(char *);
367 u_short in_cksum(u_short *, int);
368 char *inetname(struct in_addr);
369 int main(int, char **);
370 u_short p_cksum(struct ip *, u_short *, int);
371 int packet_ok(u_char *, int, struct sockaddr_in *, int);
372 char *pr_type(u_char);
373 void print(u_char *, int, struct sockaddr_in *);
375 int setpolicy __P((int so, char *policy));
377 void send_probe(int, int);
378 struct outproto *setproto(char *);
379 int str2val(const char *, const char *, int, int);
380 void tvsub(struct timeval *, struct timeval *);
382 int wait_for_reply(int, struct sockaddr_in *, const struct timeval *);
387 void udp_prep(struct outdata *);
388 int udp_check(const u_char *, int);
389 void tcp_prep(struct outdata *);
390 int tcp_check(const u_char *, int);
391 void gre_prep(struct outdata *);
392 int gre_check(const u_char *, int);
393 void gen_prep(struct outdata *);
394 int gen_check(const u_char *, int);
395 void icmp_prep(struct outdata *);
396 int icmp_check(const u_char *, int);
398 /* Descriptor structure for each outgoing protocol we support */
400 char *name; /* name of protocol */
401 u_char num; /* IP protocol number */
402 u_short hdrlen; /* max size of protocol header */
403 u_short port; /* default base protocol-specific "port" */
404 void (*prepare)(struct outdata *);
405 /* finish preparing an outgoing packet */
406 int (*check)(const u_char *, int);
407 /* check an incoming packet */
410 /* List of supported protocols. The first one is the default. The last
411 one is the handler for generic protocols not explicitly listed. */
412 struct outproto protos[] = {
416 sizeof(struct udphdr),
424 sizeof(struct tcphdr),
432 sizeof(struct grehdr),
454 struct outproto *proto = &protos[0];
457 main(int argc, char **argv)
459 register int op, code, n;
461 register const char *err;
462 register u_int32_t *ap;
463 register struct sockaddr_in *from = (struct sockaddr_in *)&wherefrom;
464 register struct sockaddr_in *to = (struct sockaddr_in *)&whereto;
465 register struct hostinfo *hi;
467 register struct protoent *pe;
468 register int ttl, probe, i;
469 register int seq = 0;
470 int tos = 0, settos = 0;
471 register int lsrr = 0;
472 register u_short off = 0;
473 struct ifaddrlist *al;
475 int requestPort = -1;
479 /* Insure the socket fds won't be 0, 1 or 2 */
480 if (open(devnull, O_RDONLY) < 0 ||
481 open(devnull, O_RDONLY) < 0 ||
482 open(devnull, O_RDONLY) < 0) {
483 Fprintf(stderr, "%s: open \"%s\": %s\n",
484 prog, devnull, strerror(errno));
488 * Do the setuid-required stuff first, then lose priveleges ASAP.
489 * Do error checking for these two calls where they appeared in
493 pe = getprotobyname(cp);
495 if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0)
497 else if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
505 int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
506 size_t sz = sizeof(max_ttl);
508 if (sysctl(mib, 4, &max_ttl, &sz, NULL, 0) == -1) {
509 perror("sysctl(net.inet.ip.ttl)");
519 else if ((cp = strrchr(argv[0], '/')) != NULL)
525 while ((op = getopt(argc, argv, "edFInrSvxf:g:i:M:m:P:p:q:s:t:w:z:")) != EOF)
537 case 'M': /* FreeBSD compat. */
538 first_ttl = str2val(optarg, "first ttl", 1, 255);
546 if (lsrr >= NGATEWAYS) {
548 "%s: No more than %d gateways\n",
552 getaddr(gwlist + lsrr, optarg);
561 proto = setproto("icmp");
565 max_ttl = str2val(optarg, "max ttl", 1, 255);
573 proto = setproto(optarg);
577 requestPort = (u_short)str2val(optarg, "port",
582 nprobes = str2val(optarg, "nprobes", 1, -1);
586 options |= SO_DONTROUTE;
591 * set the ip source address of the outbound
592 * probe (e.g., on a multi-homed host).
602 tos = str2val(optarg, "tos", 0, 255);
611 doipcksum = (doipcksum == 0);
615 waittime = str2val(optarg, "wait time",
620 pausemsecs = str2val(optarg, "pause msecs",
628 /* Set requested port, if any, else default for this protocol */
629 port = (requestPort != -1) ? requestPort : proto->port;
631 if (first_ttl > max_ttl) {
633 "%s: first ttl (%d) may not be greater than max ttl (%d)\n",
634 prog, first_ttl, max_ttl);
639 Fprintf(stderr, "%s: Warning: ip checksums disabled\n", prog);
642 optlen = (lsrr + 1) * sizeof(gwlist[0]);
643 minpacket = sizeof(*outip) + proto->hdrlen + sizeof(struct outdata) + optlen;
644 packlen = minpacket; /* minimum sized packet */
646 /* Process destination and optional packet size */
647 switch (argc - optind) {
650 packlen = str2val(argv[optind + 1],
651 "packet length", minpacket, maxpacket);
655 hostname = argv[optind];
656 hi = gethostinfo(hostname);
657 setsin(to, hi->addrs[0]);
660 "%s: Warning: %s has multiple addresses; using %s\n",
661 prog, hostname, inet_ntoa(to->sin_addr));
671 #ifdef HAVE_SETLINEBUF
674 setvbuf(stdout, NULL, _IOLBF, 0);
677 protlen = packlen - sizeof(*outip) - optlen;
679 outip = (struct ip *)malloc((unsigned)packlen);
681 Fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno));
684 memset((char *)outip, 0, packlen);
686 outip->ip_v = IPVERSION;
689 #ifdef BYTESWAP_IP_HDR
690 outip->ip_len = htons(packlen);
691 outip->ip_off = htons(off);
693 outip->ip_len = packlen;
696 outip->ip_p = proto->num;
697 outp = (u_char *)(outip + 1);
698 #ifdef HAVE_RAW_OPTIONS
700 register u_char *optlist;
706 gwlist[lsrr] = to->sin_addr.s_addr;
708 outip->ip_dst.s_addr = gwlist[0];
710 /* force 4 byte alignment */
711 optlist[0] = IPOPT_NOP;
712 /* loose source route option */
713 optlist[1] = IPOPT_LSRR;
714 i = lsrr * sizeof(gwlist[0]);
716 /* Pointer to LSRR addresses */
717 optlist[3] = IPOPT_MINOFF;
718 memcpy(optlist + 4, gwlist + 1, i);
721 outip->ip_dst = to->sin_addr;
723 outip->ip_hl = (outp - (u_char *)outip) >> 2;
724 ident = (getpid() & 0xffff) | 0x8000;
727 Fprintf(stderr, "%s: unknown protocol %s\n", prog, cp);
732 Fprintf(stderr, "%s: icmp socket: %s\n", prog, strerror(errno));
735 if (options & SO_DEBUG)
736 (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on,
738 if (options & SO_DONTROUTE)
739 (void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
742 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
743 if (setpolicy(s, "in bypass") < 0)
744 errx(1, "%s", ipsec_strerror());
746 if (setpolicy(s, "out bypass") < 0)
747 errx(1, "%s", ipsec_strerror());
748 #endif /* defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) */
752 Fprintf(stderr, "%s: raw socket: %s\n", prog, strerror(errno));
756 #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
758 u_char optlist[MAX_IPOPTLEN];
761 if ((pe = getprotobyname(cp)) == NULL) {
762 Fprintf(stderr, "%s: unknown protocol %s\n", prog, cp);
767 gwlist[lsrr] = to->sin_addr.s_addr;
770 /* force 4 byte alignment */
771 optlist[0] = IPOPT_NOP;
772 /* loose source route option */
773 optlist[1] = IPOPT_LSRR;
774 i = lsrr * sizeof(gwlist[0]);
776 /* Pointer to LSRR addresses */
777 optlist[3] = IPOPT_MINOFF;
778 memcpy(optlist + 4, gwlist, i);
780 if ((setsockopt(sndsock, pe->p_proto, IP_OPTIONS,
781 (char *)optlist, i + sizeof(gwlist[0]))) < 0) {
782 Fprintf(stderr, "%s: IP_OPTIONS: %s\n",
783 prog, strerror(errno));
790 if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packlen,
791 sizeof(packlen)) < 0) {
792 Fprintf(stderr, "%s: SO_SNDBUF: %s\n", prog, strerror(errno));
797 if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
799 Fprintf(stderr, "%s: IP_HDRINCL: %s\n", prog, strerror(errno));
804 if (settos && setsockopt(sndsock, IPPROTO_IP, IP_TOS,
805 (char *)&tos, sizeof(tos)) < 0) {
806 Fprintf(stderr, "%s: setsockopt tos %d: %s\n",
807 prog, tos, strerror(errno));
812 if (options & SO_DEBUG)
813 (void)setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on,
815 if (options & SO_DONTROUTE)
816 (void)setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
819 /* Get the interface address list */
820 n = ifaddrlist(&al, errbuf);
822 Fprintf(stderr, "%s: ifaddrlist: %s\n", prog, errbuf);
827 "%s: Can't find any network interfaces\n", prog);
831 /* Look for a specific device */
832 if (device != NULL) {
833 for (i = n; i > 0; --i, ++al)
834 if (strcmp(device, al->device) == 0)
837 Fprintf(stderr, "%s: Can't find interface %.32s\n",
843 /* Determine our source address */
844 if (source == NULL) {
846 * If a device was specified, use the interface address.
847 * Otherwise, try to determine our source address.
850 setsin(from, al->addr);
851 else if ((err = findsaddr(to, from)) != NULL) {
852 Fprintf(stderr, "%s: findsaddr: %s\n",
857 hi = gethostinfo(source);
861 * If the device was specified make sure it
862 * corresponds to the source address specified.
863 * Otherwise, use the first address (and warn if
864 * there are more than one).
866 if (device != NULL) {
867 for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
872 "%s: %s is not on interface %.32s\n",
873 prog, source, device);
878 setsin(from, hi->addrs[0]);
881 "%s: Warning: %s has multiple addresses; using %s\n",
882 prog, source, inet_ntoa(from->sin_addr));
887 outip->ip_src = from->sin_addr;
889 /* Check the source address (-s), if any, is valid */
890 if (bind(sndsock, (struct sockaddr *)from, sizeof(*from)) < 0) {
891 Fprintf(stderr, "%s: bind: %s\n",
892 prog, strerror(errno));
896 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
897 if (setpolicy(sndsock, "in bypass") < 0)
898 errx(1, "%s", ipsec_strerror());
900 if (setpolicy(sndsock, "out bypass") < 0)
901 errx(1, "%s", ipsec_strerror());
902 #endif /* defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) */
904 Fprintf(stderr, "%s to %s (%s)",
905 prog, hostname, inet_ntoa(to->sin_addr));
907 Fprintf(stderr, " from %s", source);
908 Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen);
909 (void)fflush(stderr);
911 for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
912 u_int32_t lastaddr = 0;
920 for (probe = 0, loss = 0; probe < nprobes; ++probe) {
922 struct timeval t1, t2;
924 register struct ip *ip;
925 struct outdata outdata;
927 if (sentfirst && pausemsecs > 0)
928 usleep(pausemsecs * 1000);
929 /* Prepare outgoing data */
933 /* Avoid alignment problems by copying bytewise: */
934 (void)gettimeofday(&t1, &tz);
935 memcpy(&outdata.tv, &t1, sizeof(outdata.tv));
937 /* Finalize and send packet */
938 (*proto->prepare)(&outdata);
939 send_probe(seq, ttl);
942 /* Wait for a reply */
943 while ((cc = wait_for_reply(s, from, &t1)) != 0) {
947 (void)gettimeofday(&t2, &tz);
948 i = packet_ok(packet, cc, from, seq);
949 /* Skip short packet */
953 from->sin_addr.s_addr != lastaddr) {
954 if (gotlastaddr) printf("\n ");
955 print(packet, cc, from);
956 lastaddr = from->sin_addr.s_addr;
959 T = deltaT(&t1, &t2);
960 #ifdef SANE_PRECISION
970 Printf(" %.*f ms", precis, T);
973 ip = (struct ip *)packet;
980 /* time exceeded in transit */
986 case ICMP_UNREACH_PORT:
988 ip = (struct ip *)packet;
995 case ICMP_UNREACH_NET:
1000 case ICMP_UNREACH_HOST:
1005 case ICMP_UNREACH_PROTOCOL:
1010 case ICMP_UNREACH_NEEDFRAG:
1012 Printf(" !F-%d", pmtu);
1015 case ICMP_UNREACH_SRCFAIL:
1020 case ICMP_UNREACH_NET_UNKNOWN:
1025 case ICMP_UNREACH_HOST_UNKNOWN:
1030 case ICMP_UNREACH_ISOLATED:
1035 case ICMP_UNREACH_NET_PROHIB:
1040 case ICMP_UNREACH_HOST_PROHIB:
1045 case ICMP_UNREACH_TOSNET:
1050 case ICMP_UNREACH_TOSHOST:
1055 case ICMP_UNREACH_FILTER_PROHIB:
1060 case ICMP_UNREACH_HOST_PRECEDENCE:
1065 case ICMP_UNREACH_PRECEDENCE_CUTOFF:
1072 Printf(" !<%d>", code);
1081 (void)fflush(stdout);
1084 Printf(" (%d%% loss)", (loss * 100) / nprobes);
1088 (unreachable > 0 && unreachable >= nprobes - 1))
1095 wait_for_reply(register int sock, register struct sockaddr_in *fromp,
1096 register const struct timeval *tp)
1100 struct timeval now, wait;
1102 register int cc = 0;
1104 int fromlen = sizeof(*fromp);
1106 nfds = howmany(sock + 1, NFDBITS);
1107 if ((fdsp = malloc(nfds * sizeof(fd_mask))) == NULL)
1109 memset(fdsp, 0, nfds * sizeof(fd_mask));
1112 wait.tv_sec = tp->tv_sec + waittime;
1113 wait.tv_usec = tp->tv_usec;
1114 (void)gettimeofday(&now, &tz);
1116 if (wait.tv_sec < 0) {
1121 error = select(sock + 1, fdsp, NULL, NULL, &wait);
1122 if (error == -1 && errno == EINVAL) {
1123 Fprintf(stderr, "%s: botched select() args\n", prog);
1127 cc = recvfrom(sock, (char *)packet, sizeof(packet), 0,
1128 (struct sockaddr *)fromp, &fromlen);
1135 send_probe(int seq, int ttl)
1139 outip->ip_ttl = ttl;
1140 outip->ip_id = htons(ident + seq);
1142 /* XXX undocumented debugging hack */
1144 register const u_short *sp;
1145 register int nshorts, i;
1147 sp = (u_short *)outip;
1148 nshorts = (u_int)packlen / sizeof(u_short);
1150 Printf("[ %d bytes", packlen);
1151 while (--nshorts >= 0) {
1154 Printf(" %04x", ntohs(*sp++));
1159 Printf(" %02x", *(u_char *)sp);
1164 #if !defined(IP_HDRINCL) && defined(IP_TTL)
1165 if (setsockopt(sndsock, IPPROTO_IP, IP_TTL,
1166 (char *)&ttl, sizeof(ttl)) < 0) {
1167 Fprintf(stderr, "%s: setsockopt ttl %d: %s\n",
1168 prog, ttl, strerror(errno));
1173 cc = sendto(sndsock, (char *)outip,
1174 packlen, 0, &whereto, sizeof(whereto));
1175 if (cc < 0 || cc != packlen) {
1177 Fprintf(stderr, "%s: sendto: %s\n",
1178 prog, strerror(errno));
1179 Printf("%s: wrote %s %d chars, ret=%d\n",
1180 prog, hostname, packlen, cc);
1181 (void)fflush(stdout);
1185 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
1187 setpolicy(so, policy)
1193 buf = ipsec_set_policy(policy, strlen(policy));
1195 warnx("%s", ipsec_strerror());
1198 (void)setsockopt(so, IPPROTO_IP, IP_IPSEC_POLICY,
1199 buf, ipsec_get_policylen(buf));
1208 deltaT(struct timeval *t1p, struct timeval *t2p)
1212 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1213 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1218 * Convert an ICMP "type" field to a printable string.
1221 pr_type(register u_char t)
1223 static char *ttab[] = {
1224 "Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable",
1225 "Source Quench", "Redirect", "ICMP 6", "ICMP 7",
1226 "Echo", "ICMP 9", "ICMP 10", "Time Exceeded",
1227 "Param Problem", "Timestamp", "Timestamp Reply", "Info Request",
1232 return("OUT-OF-RANGE");
1238 packet_ok(register u_char *buf, int cc, register struct sockaddr_in *from,
1241 register struct icmp *icp;
1242 register u_char type, code;
1245 register struct ip *ip;
1247 ip = (struct ip *) buf;
1248 hlen = ip->ip_hl << 2;
1249 if (cc < hlen + ICMP_MINLEN) {
1251 Printf("packet too short (%d bytes) from %s\n", cc,
1252 inet_ntoa(from->sin_addr));
1256 icp = (struct icmp *)(buf + hlen);
1258 icp = (struct icmp *)buf;
1260 type = icp->icmp_type;
1261 code = icp->icmp_code;
1262 /* Path MTU Discovery (RFC1191) */
1263 if (code != ICMP_UNREACH_NEEDFRAG)
1266 #ifdef HAVE_ICMP_NEXTMTU
1267 pmtu = ntohs(icp->icmp_nextmtu);
1269 pmtu = ntohs(((struct my_pmtu *)&icp->icmp_void)->ipm_nextmtu);
1272 if (type == ICMP_ECHOREPLY
1273 && proto->num == IPPROTO_ICMP
1274 && (*proto->check)((u_char *)icp, (u_char)seq))
1276 if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
1277 type == ICMP_UNREACH) {
1281 hip = &icp->icmp_ip;
1282 hlen = hip->ip_hl << 2;
1283 inner = (u_char *)((u_char *)hip + hlen);
1285 && hip->ip_p == proto->num
1286 && (*proto->check)(inner, (u_char)seq))
1287 return (type == ICMP_TIMXCEED ? -1 : code + 1);
1292 u_int32_t *lp = (u_int32_t *)&icp->icmp_ip;
1294 Printf("\n%d bytes from %s to ", cc, inet_ntoa(from->sin_addr));
1295 Printf("%s: icmp type %d (%s) code %d\n",
1296 inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
1297 for (i = 4; i < cc ; i += sizeof(*lp))
1298 Printf("%2d: x%8.8x\n", i, *lp++);
1305 icmp_prep(struct outdata *outdata)
1307 struct icmp *const icmpheader = (struct icmp *) outp;
1309 icmpheader->icmp_type = ICMP_ECHO;
1310 icmpheader->icmp_id = htons(ident);
1311 icmpheader->icmp_seq = htons(outdata->seq);
1312 icmpheader->icmp_cksum = 0;
1313 icmpheader->icmp_cksum = in_cksum((u_short *)icmpheader, protlen);
1314 if (icmpheader->icmp_cksum == 0)
1315 icmpheader->icmp_cksum = 0xffff;
1319 icmp_check(const u_char *data, int seq)
1321 struct icmp *const icmpheader = (struct icmp *) data;
1323 return (icmpheader->icmp_id == htons(ident)
1324 && icmpheader->icmp_seq == htons(seq));
1328 udp_prep(struct outdata *outdata)
1330 struct udphdr *const outudp = (struct udphdr *) outp;
1332 outudp->uh_sport = htons(ident + (fixedPort ? outdata->seq : 0));
1333 outudp->uh_dport = htons(port + (fixedPort ? 0 : outdata->seq));
1334 outudp->uh_ulen = htons((u_short)protlen);
1337 u_short sum = p_cksum(outip, (u_short*)outudp, protlen);
1338 outudp->uh_sum = (sum) ? sum : 0xffff;
1345 udp_check(const u_char *data, int seq)
1347 struct udphdr *const udp = (struct udphdr *) data;
1349 return (ntohs(udp->uh_sport) == ident + (fixedPort ? seq : 0) &&
1350 ntohs(udp->uh_dport) == port + (fixedPort ? 0 : seq));
1354 tcp_prep(struct outdata *outdata)
1356 struct tcphdr *const tcp = (struct tcphdr *) outp;
1358 tcp->th_sport = htons(ident);
1359 tcp->th_dport = htons(port + (fixedPort ? 0 : outdata->seq));
1360 tcp->th_seq = (tcp->th_sport << 16) | (tcp->th_dport +
1361 (fixedPort ? outdata->seq : 0));
1364 tcp->th_flags = TH_SYN;
1368 u_short sum = p_cksum(outip, (u_short*)tcp, protlen);
1369 tcp->th_sum = (sum) ? sum : 0xffff;
1374 tcp_check(const u_char *data, int seq)
1376 struct tcphdr *const tcp = (struct tcphdr *) data;
1378 return (ntohs(tcp->th_sport) == ident
1379 && ntohs(tcp->th_dport) == port + (fixedPort ? 0 : seq))
1380 && tcp->th_seq == (ident << 16) | (port + seq);
1384 gre_prep(struct outdata *outdata)
1386 struct grehdr *const gre = (struct grehdr *) outp;
1388 gre->flags = htons(0x2001);
1389 gre->proto = htons(port);
1391 gre->callId = htons(ident + outdata->seq);
1395 gre_check(const u_char *data, int seq)
1397 struct grehdr *const gre = (struct grehdr *) data;
1399 return(ntohs(gre->proto) == port
1400 && ntohs(gre->callId) == ident + seq);
1404 gen_prep(struct outdata *outdata)
1406 u_int16_t *const ptr = (u_int16_t *) outp;
1408 ptr[0] = htons(ident);
1409 ptr[1] = htons(port + outdata->seq);
1413 gen_check(const u_char *data, int seq)
1415 u_int16_t *const ptr = (u_int16_t *) data;
1417 return(ntohs(ptr[0]) == ident
1418 && ntohs(ptr[1]) == port + seq);
1422 print(register u_char *buf, register int cc, register struct sockaddr_in *from)
1424 register struct ip *ip;
1427 ip = (struct ip *) buf;
1428 hlen = ip->ip_hl << 2;
1432 Printf(" %s", inet_ntoa(from->sin_addr));
1434 Printf(" %s (%s)", inetname(from->sin_addr),
1435 inet_ntoa(from->sin_addr));
1438 Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
1442 * Checksum routine for UDP and TCP headers.
1445 p_cksum(struct ip *ip, u_short *data, int len)
1447 static struct ipovly ipo;
1451 ipo.ih_pr = ip->ip_p;
1452 ipo.ih_len = htons(len);
1453 ipo.ih_src = ip->ip_src;
1454 ipo.ih_dst = ip->ip_dst;
1456 sumh = in_cksum((u_short*)&ipo, sizeof(ipo)); /* pseudo ip hdr cksum */
1457 sumd = in_cksum((u_short*)data, len); /* payload data cksum */
1458 sumt = (sumh << 16) | (sumd);
1460 return ~in_cksum((u_short*)&sumt, sizeof(sumt));
1464 * Checksum routine for Internet Protocol family headers (C Version)
1467 in_cksum(register u_short *addr, register int len)
1469 register int nleft = len;
1470 register u_short *w = addr;
1471 register u_short answer;
1472 register int sum = 0;
1475 * Our algorithm is simple, using a 32 bit accumulator (sum),
1476 * we add sequential 16 bit words to it, and at the end, fold
1477 * back all the carry bits from the top 16 bits into the lower
1485 /* mop up an odd byte, if necessary */
1487 sum += *(u_char *)w;
1490 * add back carry outs from top 16 bits to low 16 bits
1492 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
1493 sum += (sum >> 16); /* add carry */
1494 answer = ~sum; /* truncate to 16 bits */
1499 * Subtract 2 timeval structs: out = out - in.
1500 * Out is assumed to be within about LONG_MAX seconds of in.
1503 tvsub(register struct timeval *out, register struct timeval *in)
1506 if ((out->tv_usec -= in->tv_usec) < 0) {
1508 out->tv_usec += 1000000;
1510 out->tv_sec -= in->tv_sec;
1514 * Construct an Internet address representation.
1515 * If the nflag has been supplied, give
1516 * numeric value, otherwise try for symbolic name.
1519 inetname(struct in_addr in)
1522 register struct hostent *hp;
1523 static int first = 1;
1524 static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1];
1526 if (first && !nflag) {
1528 if (gethostname(domain, sizeof(domain) - 1) < 0)
1531 cp = strchr(domain, '.');
1533 hp = gethostbyname(domain);
1535 cp = strchr(hp->h_name, '.');
1541 (void)strncpy(domain, cp, sizeof(domain) - 1);
1542 domain[sizeof(domain) - 1] = '\0';
1546 if (!nflag && in.s_addr != INADDR_ANY) {
1547 hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
1549 if ((cp = strchr(hp->h_name, '.')) != NULL &&
1550 strcmp(cp + 1, domain) == 0)
1552 (void)strncpy(line, hp->h_name, sizeof(line) - 1);
1553 line[sizeof(line) - 1] = '\0';
1557 return (inet_ntoa(in));
1561 gethostinfo(register char *hostname)
1564 register struct hostent *hp;
1565 register struct hostinfo *hi;
1567 register u_int32_t addr, *ap;
1569 if (strlen(hostname) > 64) {
1570 Fprintf(stderr, "%s: hostname \"%.32s...\" is too long\n",
1574 hi = calloc(1, sizeof(*hi));
1576 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1579 addr = inet_addr(hostname);
1580 if ((int32_t)addr != -1) {
1581 hi->name = strdup(hostname);
1583 hi->addrs = calloc(1, sizeof(hi->addrs[0]));
1584 if (hi->addrs == NULL) {
1585 Fprintf(stderr, "%s: calloc %s\n",
1586 prog, strerror(errno));
1589 hi->addrs[0] = addr;
1593 hp = gethostbyname(hostname);
1595 Fprintf(stderr, "%s: unknown host %s\n", prog, hostname);
1598 if (hp->h_addrtype != AF_INET || hp->h_length != 4) {
1599 Fprintf(stderr, "%s: bad host %s\n", prog, hostname);
1602 hi->name = strdup(hp->h_name);
1603 for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
1606 hi->addrs = calloc(n, sizeof(hi->addrs[0]));
1607 if (hi->addrs == NULL) {
1608 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1611 for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
1612 memcpy(ap, *p, sizeof(*ap));
1617 freehostinfo(register struct hostinfo *hi)
1619 if (hi->name != NULL) {
1623 free((char *)hi->addrs);
1628 getaddr(register u_int32_t *ap, register char *hostname)
1630 register struct hostinfo *hi;
1632 hi = gethostinfo(hostname);
1638 setsin(register struct sockaddr_in *sin, register u_int32_t addr)
1641 memset(sin, 0, sizeof(*sin));
1642 #ifdef HAVE_SOCKADDR_SA_LEN
1643 sin->sin_len = sizeof(*sin);
1645 sin->sin_family = AF_INET;
1646 sin->sin_addr.s_addr = addr;
1649 /* String to value with optional min and max. Handles decimal and hex. */
1651 str2val(register const char *str, register const char *what,
1652 register int mi, register int ma)
1654 register const char *cp;
1658 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
1660 val = (int)strtol(cp, &ep, 16);
1662 val = (int)strtol(str, &ep, 10);
1664 Fprintf(stderr, "%s: \"%s\" bad value for %s \n",
1668 if (val < mi && mi >= 0) {
1670 Fprintf(stderr, "%s: %s must be >= %d\n",
1673 Fprintf(stderr, "%s: %s must be > %d\n",
1674 prog, what, mi - 1);
1677 if (val > ma && ma >= 0) {
1678 Fprintf(stderr, "%s: %s must be <= %d\n", prog, what, ma);
1685 setproto(char *pname)
1687 struct outproto *proto;
1690 for (i = 0; protos[i].name != NULL; i++) {
1691 if (strcasecmp(protos[i].name, pname) == 0) {
1696 if (proto->name == NULL) { /* generic handler */
1697 struct protoent *pe;
1700 /* Determine the IP protocol number */
1701 if ((pe = getprotobyname(pname)) != NULL)
1704 pnum = str2val(optarg, "proto number", 1, 255);
1713 extern char version[];
1715 Fprintf(stderr, "Version %s\n", version);
1717 "Usage: %s [-dFInrSvx] [-g gateway] [-i iface] [-f first_ttl]\n"
1718 "\t[-m max_ttl] [-p port] [-P proto] [-q nqueries] [-s src_addr]\n"
1719 "\t[-t tos] [-w waittime] [-z pausemsecs] host [packetlen]\n", prog);