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 struct ip *hip = NULL; /* Quoted IP header */
322 /* loose source route gateway list (including room for final destination) */
323 u_int32_t gwlist[NGATEWAYS + 1];
325 int s; /* receive (icmp) socket file descriptor */
326 int sndsock; /* send (udp) socket file descriptor */
328 struct sockaddr whereto; /* Who to try to reach */
329 struct sockaddr wherefrom; /* Who we are */
330 int packlen; /* total length of packet */
331 int protlen; /* length of protocol part of packet */
332 int minpacket; /* min ip packet size */
333 int maxpacket = 32 * 1024; /* max ip packet size */
334 int pmtu; /* Path MTU Discovery (RFC1191) */
341 static const char devnull[] = "/dev/null";
347 u_short port; /* protocol specific base "port" */
349 int options; /* socket options */
351 int waittime = 5; /* time to wait for response (in seconds) */
352 int nflag; /* print addresses numerically */
353 #ifdef CANT_HACK_IPCKSUM
354 int doipcksum = 0; /* don't calculate ip checksums by default */
356 int doipcksum = 1; /* calculate ip checksums by default */
358 int optlen; /* length of ip options */
359 int fixedPort = 0; /* Use fixed destination port for TCP and UDP */
360 int printdiff = 0; /* Print the difference between sent and quoted */
367 double deltaT(struct timeval *, struct timeval *);
368 void freehostinfo(struct hostinfo *);
369 void getaddr(u_int32_t *, char *);
370 struct hostinfo *gethostinfo(char *);
371 u_short in_cksum(u_short *, int);
372 char *inetname(struct in_addr);
373 int main(int, char **);
374 u_short p_cksum(struct ip *, u_short *, int);
375 int packet_ok(u_char *, int, struct sockaddr_in *, int);
376 char *pr_type(u_char);
377 void print(u_char *, int, struct sockaddr_in *);
379 int setpolicy __P((int so, char *policy));
381 void send_probe(int, int);
382 struct outproto *setproto(char *);
383 int str2val(const char *, const char *, int, int);
384 void tvsub(struct timeval *, struct timeval *);
386 int wait_for_reply(int, struct sockaddr_in *, const struct timeval *);
387 void pkt_compare(const u_char *, int, const u_char *, int);
392 void udp_prep(struct outdata *);
393 int udp_check(const u_char *, int);
394 void tcp_prep(struct outdata *);
395 int tcp_check(const u_char *, int);
396 void gre_prep(struct outdata *);
397 int gre_check(const u_char *, int);
398 void gen_prep(struct outdata *);
399 int gen_check(const u_char *, int);
400 void icmp_prep(struct outdata *);
401 int icmp_check(const u_char *, int);
403 /* Descriptor structure for each outgoing protocol we support */
405 char *name; /* name of protocol */
406 const char *key; /* An ascii key for the bytes of the header */
407 u_char num; /* IP protocol number */
408 u_short hdrlen; /* max size of protocol header */
409 u_short port; /* default base protocol-specific "port" */
410 void (*prepare)(struct outdata *);
411 /* finish preparing an outgoing packet */
412 int (*check)(const u_char *, int);
413 /* check an incoming packet */
416 /* List of supported protocols. The first one is the default. The last
417 one is the handler for generic protocols not explicitly listed. */
418 struct outproto protos[] = {
423 sizeof(struct udphdr),
430 "spt dpt seq ack xxflwin sum urp",
432 sizeof(struct tcphdr),
441 sizeof(struct grehdr),
465 struct outproto *proto = &protos[0];
467 const char *ip_hdr_key = "vhtslen id off tlprsum srcip dstip opts";
470 main(int argc, char **argv)
472 register int op, code, n;
474 register const char *err;
475 register u_int32_t *ap;
476 register struct sockaddr_in *from = (struct sockaddr_in *)&wherefrom;
477 register struct sockaddr_in *to = (struct sockaddr_in *)&whereto;
478 register struct hostinfo *hi;
480 register struct protoent *pe;
481 register int ttl, probe, i;
482 register int seq = 0;
483 int tos = 0, settos = 0;
484 register int lsrr = 0;
485 register u_short off = 0;
486 struct ifaddrlist *al;
488 int requestPort = -1;
492 /* Insure the socket fds won't be 0, 1 or 2 */
493 if (open(devnull, O_RDONLY) < 0 ||
494 open(devnull, O_RDONLY) < 0 ||
495 open(devnull, O_RDONLY) < 0) {
496 Fprintf(stderr, "%s: open \"%s\": %s\n",
497 prog, devnull, strerror(errno));
501 * Do the setuid-required stuff first, then lose priveleges ASAP.
502 * Do error checking for these two calls where they appeared in
506 pe = getprotobyname(cp);
508 if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0)
510 else if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
518 int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
519 size_t sz = sizeof(max_ttl);
521 if (sysctl(mib, 4, &max_ttl, &sz, NULL, 0) == -1) {
522 perror("sysctl(net.inet.ip.ttl)");
532 else if ((cp = strrchr(argv[0], '/')) != NULL)
538 while ((op = getopt(argc, argv, "edDFInrSvxf:g:i:M:m:P:p:q:s:t:w:z:")) != EOF)
554 case 'M': /* FreeBSD compat. */
555 first_ttl = str2val(optarg, "first ttl", 1, 255);
563 if (lsrr >= NGATEWAYS) {
565 "%s: No more than %d gateways\n",
569 getaddr(gwlist + lsrr, optarg);
578 proto = setproto("icmp");
582 max_ttl = str2val(optarg, "max ttl", 1, 255);
590 proto = setproto(optarg);
594 requestPort = (u_short)str2val(optarg, "port",
599 nprobes = str2val(optarg, "nprobes", 1, -1);
603 options |= SO_DONTROUTE;
608 * set the ip source address of the outbound
609 * probe (e.g., on a multi-homed host).
619 tos = str2val(optarg, "tos", 0, 255);
628 doipcksum = (doipcksum == 0);
632 waittime = str2val(optarg, "wait time",
637 pausemsecs = str2val(optarg, "pause msecs",
645 /* Set requested port, if any, else default for this protocol */
646 port = (requestPort != -1) ? requestPort : proto->port;
649 nprobes = printdiff ? 1 : 3;
651 if (first_ttl > max_ttl) {
653 "%s: first ttl (%d) may not be greater than max ttl (%d)\n",
654 prog, first_ttl, max_ttl);
659 Fprintf(stderr, "%s: Warning: ip checksums disabled\n", prog);
662 optlen = (lsrr + 1) * sizeof(gwlist[0]);
663 minpacket = sizeof(*outip) + proto->hdrlen + sizeof(struct outdata) + optlen;
664 packlen = minpacket; /* minimum sized packet */
666 /* Process destination and optional packet size */
667 switch (argc - optind) {
670 packlen = str2val(argv[optind + 1],
671 "packet length", minpacket, maxpacket);
675 hostname = argv[optind];
676 hi = gethostinfo(hostname);
677 setsin(to, hi->addrs[0]);
680 "%s: Warning: %s has multiple addresses; using %s\n",
681 prog, hostname, inet_ntoa(to->sin_addr));
691 #ifdef HAVE_SETLINEBUF
694 setvbuf(stdout, NULL, _IOLBF, 0);
697 protlen = packlen - sizeof(*outip) - optlen;
699 outip = (struct ip *)malloc((unsigned)packlen);
701 Fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno));
704 memset((char *)outip, 0, packlen);
706 outip->ip_v = IPVERSION;
709 #ifdef BYTESWAP_IP_HDR
710 outip->ip_len = htons(packlen);
711 outip->ip_off = htons(off);
713 outip->ip_len = packlen;
716 outip->ip_p = proto->num;
717 outp = (u_char *)(outip + 1);
718 #ifdef HAVE_RAW_OPTIONS
720 register u_char *optlist;
726 gwlist[lsrr] = to->sin_addr.s_addr;
728 outip->ip_dst.s_addr = gwlist[0];
730 /* force 4 byte alignment */
731 optlist[0] = IPOPT_NOP;
732 /* loose source route option */
733 optlist[1] = IPOPT_LSRR;
734 i = lsrr * sizeof(gwlist[0]);
736 /* Pointer to LSRR addresses */
737 optlist[3] = IPOPT_MINOFF;
738 memcpy(optlist + 4, gwlist + 1, i);
741 outip->ip_dst = to->sin_addr;
743 outip->ip_hl = (outp - (u_char *)outip) >> 2;
744 ident = (getpid() & 0xffff) | 0x8000;
747 Fprintf(stderr, "%s: unknown protocol %s\n", prog, cp);
752 Fprintf(stderr, "%s: icmp socket: %s\n", prog, strerror(errno));
755 if (options & SO_DEBUG)
756 (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on,
758 if (options & SO_DONTROUTE)
759 (void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
762 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
763 if (setpolicy(s, "in bypass") < 0)
764 errx(1, "%s", ipsec_strerror());
766 if (setpolicy(s, "out bypass") < 0)
767 errx(1, "%s", ipsec_strerror());
768 #endif /* defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) */
772 Fprintf(stderr, "%s: raw socket: %s\n", prog, strerror(errno));
776 #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
778 u_char optlist[MAX_IPOPTLEN];
781 if ((pe = getprotobyname(cp)) == NULL) {
782 Fprintf(stderr, "%s: unknown protocol %s\n", prog, cp);
787 gwlist[lsrr] = to->sin_addr.s_addr;
790 /* force 4 byte alignment */
791 optlist[0] = IPOPT_NOP;
792 /* loose source route option */
793 optlist[1] = IPOPT_LSRR;
794 i = lsrr * sizeof(gwlist[0]);
796 /* Pointer to LSRR addresses */
797 optlist[3] = IPOPT_MINOFF;
798 memcpy(optlist + 4, gwlist, i);
800 if ((setsockopt(sndsock, pe->p_proto, IP_OPTIONS,
801 (char *)optlist, i + sizeof(gwlist[0]))) < 0) {
802 Fprintf(stderr, "%s: IP_OPTIONS: %s\n",
803 prog, strerror(errno));
810 if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packlen,
811 sizeof(packlen)) < 0) {
812 Fprintf(stderr, "%s: SO_SNDBUF: %s\n", prog, strerror(errno));
817 if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
819 Fprintf(stderr, "%s: IP_HDRINCL: %s\n", prog, strerror(errno));
824 if (settos && setsockopt(sndsock, IPPROTO_IP, IP_TOS,
825 (char *)&tos, sizeof(tos)) < 0) {
826 Fprintf(stderr, "%s: setsockopt tos %d: %s\n",
827 prog, tos, strerror(errno));
832 if (options & SO_DEBUG)
833 (void)setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on,
835 if (options & SO_DONTROUTE)
836 (void)setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
839 /* Get the interface address list */
840 n = ifaddrlist(&al, errbuf);
842 Fprintf(stderr, "%s: ifaddrlist: %s\n", prog, errbuf);
847 "%s: Can't find any network interfaces\n", prog);
851 /* Look for a specific device */
852 if (device != NULL) {
853 for (i = n; i > 0; --i, ++al)
854 if (strcmp(device, al->device) == 0)
857 Fprintf(stderr, "%s: Can't find interface %.32s\n",
863 /* Determine our source address */
864 if (source == NULL) {
866 * If a device was specified, use the interface address.
867 * Otherwise, try to determine our source address.
870 setsin(from, al->addr);
871 else if ((err = findsaddr(to, from)) != NULL) {
872 Fprintf(stderr, "%s: findsaddr: %s\n",
877 hi = gethostinfo(source);
881 * If the device was specified make sure it
882 * corresponds to the source address specified.
883 * Otherwise, use the first address (and warn if
884 * there are more than one).
886 if (device != NULL) {
887 for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
892 "%s: %s is not on interface %.32s\n",
893 prog, source, device);
898 setsin(from, hi->addrs[0]);
901 "%s: Warning: %s has multiple addresses; using %s\n",
902 prog, source, inet_ntoa(from->sin_addr));
907 outip->ip_src = from->sin_addr;
909 /* Check the source address (-s), if any, is valid */
910 if (bind(sndsock, (struct sockaddr *)from, sizeof(*from)) < 0) {
911 Fprintf(stderr, "%s: bind: %s\n",
912 prog, strerror(errno));
916 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
917 if (setpolicy(sndsock, "in bypass") < 0)
918 errx(1, "%s", ipsec_strerror());
920 if (setpolicy(sndsock, "out bypass") < 0)
921 errx(1, "%s", ipsec_strerror());
922 #endif /* defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) */
924 Fprintf(stderr, "%s to %s (%s)",
925 prog, hostname, inet_ntoa(to->sin_addr));
927 Fprintf(stderr, " from %s", source);
928 Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen);
929 (void)fflush(stderr);
931 for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
932 u_int32_t lastaddr = 0;
940 for (probe = 0, loss = 0; probe < nprobes; ++probe) {
942 struct timeval t1, t2;
944 register struct ip *ip;
945 struct outdata outdata;
947 if (sentfirst && pausemsecs > 0)
948 usleep(pausemsecs * 1000);
949 /* Prepare outgoing data */
953 /* Avoid alignment problems by copying bytewise: */
954 (void)gettimeofday(&t1, &tz);
955 memcpy(&outdata.tv, &t1, sizeof(outdata.tv));
957 /* Finalize and send packet */
958 (*proto->prepare)(&outdata);
959 send_probe(seq, ttl);
962 /* Wait for a reply */
963 while ((cc = wait_for_reply(s, from, &t1)) != 0) {
967 (void)gettimeofday(&t2, &tz);
968 i = packet_ok(packet, cc, from, seq);
969 /* Skip short packet */
973 from->sin_addr.s_addr != lastaddr) {
974 if (gotlastaddr) printf("\n ");
975 print(packet, cc, from);
976 lastaddr = from->sin_addr.s_addr;
979 T = deltaT(&t1, &t2);
980 #ifdef SANE_PRECISION
990 Printf(" %.*f ms", precis, T);
994 -(outip->ip_hl << 3),
998 pkt_compare((void *)outip, packlen,
999 (void *)hip, hiplen);
1003 ip = (struct ip *)packet;
1004 if (ip->ip_ttl <= 1)
1010 /* time exceeded in transit */
1016 case ICMP_UNREACH_PORT:
1018 ip = (struct ip *)packet;
1019 if (ip->ip_ttl <= 1)
1025 case ICMP_UNREACH_NET:
1030 case ICMP_UNREACH_HOST:
1035 case ICMP_UNREACH_PROTOCOL:
1040 case ICMP_UNREACH_NEEDFRAG:
1042 Printf(" !F-%d", pmtu);
1045 case ICMP_UNREACH_SRCFAIL:
1050 case ICMP_UNREACH_NET_UNKNOWN:
1055 case ICMP_UNREACH_HOST_UNKNOWN:
1060 case ICMP_UNREACH_ISOLATED:
1065 case ICMP_UNREACH_NET_PROHIB:
1070 case ICMP_UNREACH_HOST_PROHIB:
1075 case ICMP_UNREACH_TOSNET:
1080 case ICMP_UNREACH_TOSHOST:
1085 case ICMP_UNREACH_FILTER_PROHIB:
1090 case ICMP_UNREACH_HOST_PRECEDENCE:
1095 case ICMP_UNREACH_PRECEDENCE_CUTOFF:
1102 Printf(" !<%d>", code);
1111 (void)fflush(stdout);
1114 Printf(" (%d%% loss)", (loss * 100) / nprobes);
1118 (unreachable > 0 && unreachable >= nprobes - 1))
1125 wait_for_reply(register int sock, register struct sockaddr_in *fromp,
1126 register const struct timeval *tp)
1130 struct timeval now, wait;
1132 register int cc = 0;
1134 int fromlen = sizeof(*fromp);
1136 nfds = howmany(sock + 1, NFDBITS);
1137 if ((fdsp = malloc(nfds * sizeof(fd_mask))) == NULL)
1139 memset(fdsp, 0, nfds * sizeof(fd_mask));
1142 wait.tv_sec = tp->tv_sec + waittime;
1143 wait.tv_usec = tp->tv_usec;
1144 (void)gettimeofday(&now, &tz);
1146 if (wait.tv_sec < 0) {
1151 error = select(sock + 1, fdsp, NULL, NULL, &wait);
1152 if (error == -1 && errno == EINVAL) {
1153 Fprintf(stderr, "%s: botched select() args\n", prog);
1157 cc = recvfrom(sock, (char *)packet, sizeof(packet), 0,
1158 (struct sockaddr *)fromp, &fromlen);
1165 send_probe(int seq, int ttl)
1169 outip->ip_ttl = ttl;
1170 outip->ip_id = htons(ident + seq);
1172 /* XXX undocumented debugging hack */
1174 register const u_short *sp;
1175 register int nshorts, i;
1177 sp = (u_short *)outip;
1178 nshorts = (u_int)packlen / sizeof(u_short);
1180 Printf("[ %d bytes", packlen);
1181 while (--nshorts >= 0) {
1184 Printf(" %04x", ntohs(*sp++));
1189 Printf(" %02x", *(u_char *)sp);
1194 #if !defined(IP_HDRINCL) && defined(IP_TTL)
1195 if (setsockopt(sndsock, IPPROTO_IP, IP_TTL,
1196 (char *)&ttl, sizeof(ttl)) < 0) {
1197 Fprintf(stderr, "%s: setsockopt ttl %d: %s\n",
1198 prog, ttl, strerror(errno));
1203 cc = sendto(sndsock, (char *)outip,
1204 packlen, 0, &whereto, sizeof(whereto));
1205 if (cc < 0 || cc != packlen) {
1207 Fprintf(stderr, "%s: sendto: %s\n",
1208 prog, strerror(errno));
1209 Printf("%s: wrote %s %d chars, ret=%d\n",
1210 prog, hostname, packlen, cc);
1211 (void)fflush(stdout);
1215 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
1217 setpolicy(so, policy)
1223 buf = ipsec_set_policy(policy, strlen(policy));
1225 warnx("%s", ipsec_strerror());
1228 (void)setsockopt(so, IPPROTO_IP, IP_IPSEC_POLICY,
1229 buf, ipsec_get_policylen(buf));
1238 deltaT(struct timeval *t1p, struct timeval *t2p)
1242 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1243 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1248 * Convert an ICMP "type" field to a printable string.
1251 pr_type(register u_char t)
1253 static char *ttab[] = {
1254 "Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable",
1255 "Source Quench", "Redirect", "ICMP 6", "ICMP 7",
1256 "Echo", "ICMP 9", "ICMP 10", "Time Exceeded",
1257 "Param Problem", "Timestamp", "Timestamp Reply", "Info Request",
1262 return("OUT-OF-RANGE");
1268 packet_ok(register u_char *buf, int cc, register struct sockaddr_in *from,
1271 register struct icmp *icp;
1272 register u_char type, code;
1275 register struct ip *ip;
1277 ip = (struct ip *) buf;
1278 hlen = ip->ip_hl << 2;
1279 if (cc < hlen + ICMP_MINLEN) {
1281 Printf("packet too short (%d bytes) from %s\n", cc,
1282 inet_ntoa(from->sin_addr));
1286 icp = (struct icmp *)(buf + hlen);
1288 icp = (struct icmp *)buf;
1290 type = icp->icmp_type;
1291 code = icp->icmp_code;
1292 /* Path MTU Discovery (RFC1191) */
1293 if (code != ICMP_UNREACH_NEEDFRAG)
1296 #ifdef HAVE_ICMP_NEXTMTU
1297 pmtu = ntohs(icp->icmp_nextmtu);
1299 pmtu = ntohs(((struct my_pmtu *)&icp->icmp_void)->ipm_nextmtu);
1302 if (type == ICMP_ECHOREPLY
1303 && proto->num == IPPROTO_ICMP
1304 && (*proto->check)((u_char *)icp, (u_char)seq))
1306 if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
1307 type == ICMP_UNREACH) {
1310 hip = &icp->icmp_ip;
1311 hiplen = ((u_char *)icp + cc) - (u_char *)hip;
1312 hlen = hip->ip_hl << 2;
1313 inner = (u_char *)((u_char *)hip + hlen);
1315 && hip->ip_p == proto->num
1316 && (*proto->check)(inner, (u_char)seq))
1317 return (type == ICMP_TIMXCEED ? -1 : code + 1);
1322 u_int32_t *lp = (u_int32_t *)&icp->icmp_ip;
1324 Printf("\n%d bytes from %s to ", cc, inet_ntoa(from->sin_addr));
1325 Printf("%s: icmp type %d (%s) code %d\n",
1326 inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
1327 for (i = 4; i < cc ; i += sizeof(*lp))
1328 Printf("%2d: x%8.8x\n", i, *lp++);
1335 icmp_prep(struct outdata *outdata)
1337 struct icmp *const icmpheader = (struct icmp *) outp;
1339 icmpheader->icmp_type = ICMP_ECHO;
1340 icmpheader->icmp_id = htons(ident);
1341 icmpheader->icmp_seq = htons(outdata->seq);
1342 icmpheader->icmp_cksum = 0;
1343 icmpheader->icmp_cksum = in_cksum((u_short *)icmpheader, protlen);
1344 if (icmpheader->icmp_cksum == 0)
1345 icmpheader->icmp_cksum = 0xffff;
1349 icmp_check(const u_char *data, int seq)
1351 struct icmp *const icmpheader = (struct icmp *) data;
1353 return (icmpheader->icmp_id == htons(ident)
1354 && icmpheader->icmp_seq == htons(seq));
1358 udp_prep(struct outdata *outdata)
1360 struct udphdr *const outudp = (struct udphdr *) outp;
1362 outudp->uh_sport = htons(ident + (fixedPort ? outdata->seq : 0));
1363 outudp->uh_dport = htons(port + (fixedPort ? 0 : outdata->seq));
1364 outudp->uh_ulen = htons((u_short)protlen);
1367 u_short sum = p_cksum(outip, (u_short*)outudp, protlen);
1368 outudp->uh_sum = (sum) ? sum : 0xffff;
1375 udp_check(const u_char *data, int seq)
1377 struct udphdr *const udp = (struct udphdr *) data;
1379 return (ntohs(udp->uh_sport) == ident + (fixedPort ? seq : 0) &&
1380 ntohs(udp->uh_dport) == port + (fixedPort ? 0 : seq));
1384 tcp_prep(struct outdata *outdata)
1386 struct tcphdr *const tcp = (struct tcphdr *) outp;
1388 tcp->th_sport = htons(ident);
1389 tcp->th_dport = htons(port + (fixedPort ? 0 : outdata->seq));
1390 tcp->th_seq = (tcp->th_sport << 16) | (tcp->th_dport +
1391 (fixedPort ? outdata->seq : 0));
1394 tcp->th_flags = TH_SYN;
1398 u_short sum = p_cksum(outip, (u_short*)tcp, protlen);
1399 tcp->th_sum = (sum) ? sum : 0xffff;
1404 tcp_check(const u_char *data, int seq)
1406 struct tcphdr *const tcp = (struct tcphdr *) data;
1408 return (ntohs(tcp->th_sport) == ident
1409 && ntohs(tcp->th_dport) == port + (fixedPort ? 0 : seq))
1410 && tcp->th_seq == (ident << 16) | (port + seq);
1414 gre_prep(struct outdata *outdata)
1416 struct grehdr *const gre = (struct grehdr *) outp;
1418 gre->flags = htons(0x2001);
1419 gre->proto = htons(port);
1421 gre->callId = htons(ident + outdata->seq);
1425 gre_check(const u_char *data, int seq)
1427 struct grehdr *const gre = (struct grehdr *) data;
1429 return(ntohs(gre->proto) == port
1430 && ntohs(gre->callId) == ident + seq);
1434 gen_prep(struct outdata *outdata)
1436 u_int16_t *const ptr = (u_int16_t *) outp;
1438 ptr[0] = htons(ident);
1439 ptr[1] = htons(port + outdata->seq);
1443 gen_check(const u_char *data, int seq)
1445 u_int16_t *const ptr = (u_int16_t *) data;
1447 return(ntohs(ptr[0]) == ident
1448 && ntohs(ptr[1]) == port + seq);
1452 print(register u_char *buf, register int cc, register struct sockaddr_in *from)
1454 register struct ip *ip;
1457 ip = (struct ip *) buf;
1458 hlen = ip->ip_hl << 2;
1462 Printf(" %s", inet_ntoa(from->sin_addr));
1464 Printf(" %s (%s)", inetname(from->sin_addr),
1465 inet_ntoa(from->sin_addr));
1468 Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
1472 * Checksum routine for UDP and TCP headers.
1475 p_cksum(struct ip *ip, u_short *data, int len)
1477 static struct ipovly ipo;
1481 ipo.ih_pr = ip->ip_p;
1482 ipo.ih_len = htons(len);
1483 ipo.ih_src = ip->ip_src;
1484 ipo.ih_dst = ip->ip_dst;
1486 sumh = in_cksum((u_short*)&ipo, sizeof(ipo)); /* pseudo ip hdr cksum */
1487 sumd = in_cksum((u_short*)data, len); /* payload data cksum */
1488 sumt = (sumh << 16) | (sumd);
1490 return ~in_cksum((u_short*)&sumt, sizeof(sumt));
1494 * Checksum routine for Internet Protocol family headers (C Version)
1497 in_cksum(register u_short *addr, register int len)
1499 register int nleft = len;
1500 register u_short *w = addr;
1501 register u_short answer;
1502 register int sum = 0;
1505 * Our algorithm is simple, using a 32 bit accumulator (sum),
1506 * we add sequential 16 bit words to it, and at the end, fold
1507 * back all the carry bits from the top 16 bits into the lower
1515 /* mop up an odd byte, if necessary */
1517 sum += *(u_char *)w;
1520 * add back carry outs from top 16 bits to low 16 bits
1522 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
1523 sum += (sum >> 16); /* add carry */
1524 answer = ~sum; /* truncate to 16 bits */
1529 * Subtract 2 timeval structs: out = out - in.
1530 * Out is assumed to be within about LONG_MAX seconds of in.
1533 tvsub(register struct timeval *out, register struct timeval *in)
1536 if ((out->tv_usec -= in->tv_usec) < 0) {
1538 out->tv_usec += 1000000;
1540 out->tv_sec -= in->tv_sec;
1544 * Construct an Internet address representation.
1545 * If the nflag has been supplied, give
1546 * numeric value, otherwise try for symbolic name.
1549 inetname(struct in_addr in)
1552 register struct hostent *hp;
1553 static int first = 1;
1554 static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1];
1556 if (first && !nflag) {
1558 if (gethostname(domain, sizeof(domain) - 1) < 0)
1561 cp = strchr(domain, '.');
1563 hp = gethostbyname(domain);
1565 cp = strchr(hp->h_name, '.');
1571 (void)strncpy(domain, cp, sizeof(domain) - 1);
1572 domain[sizeof(domain) - 1] = '\0';
1576 if (!nflag && in.s_addr != INADDR_ANY) {
1577 hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
1579 if ((cp = strchr(hp->h_name, '.')) != NULL &&
1580 strcmp(cp + 1, domain) == 0)
1582 (void)strncpy(line, hp->h_name, sizeof(line) - 1);
1583 line[sizeof(line) - 1] = '\0';
1587 return (inet_ntoa(in));
1591 gethostinfo(register char *hostname)
1594 register struct hostent *hp;
1595 register struct hostinfo *hi;
1597 register u_int32_t addr, *ap;
1599 if (strlen(hostname) > 64) {
1600 Fprintf(stderr, "%s: hostname \"%.32s...\" is too long\n",
1604 hi = calloc(1, sizeof(*hi));
1606 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1609 addr = inet_addr(hostname);
1610 if ((int32_t)addr != -1) {
1611 hi->name = strdup(hostname);
1613 hi->addrs = calloc(1, sizeof(hi->addrs[0]));
1614 if (hi->addrs == NULL) {
1615 Fprintf(stderr, "%s: calloc %s\n",
1616 prog, strerror(errno));
1619 hi->addrs[0] = addr;
1623 hp = gethostbyname(hostname);
1625 Fprintf(stderr, "%s: unknown host %s\n", prog, hostname);
1628 if (hp->h_addrtype != AF_INET || hp->h_length != 4) {
1629 Fprintf(stderr, "%s: bad host %s\n", prog, hostname);
1632 hi->name = strdup(hp->h_name);
1633 for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
1636 hi->addrs = calloc(n, sizeof(hi->addrs[0]));
1637 if (hi->addrs == NULL) {
1638 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1641 for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
1642 memcpy(ap, *p, sizeof(*ap));
1647 freehostinfo(register struct hostinfo *hi)
1649 if (hi->name != NULL) {
1653 free((char *)hi->addrs);
1658 getaddr(register u_int32_t *ap, register char *hostname)
1660 register struct hostinfo *hi;
1662 hi = gethostinfo(hostname);
1668 setsin(register struct sockaddr_in *sin, register u_int32_t addr)
1671 memset(sin, 0, sizeof(*sin));
1672 #ifdef HAVE_SOCKADDR_SA_LEN
1673 sin->sin_len = sizeof(*sin);
1675 sin->sin_family = AF_INET;
1676 sin->sin_addr.s_addr = addr;
1679 /* String to value with optional min and max. Handles decimal and hex. */
1681 str2val(register const char *str, register const char *what,
1682 register int mi, register int ma)
1684 register const char *cp;
1688 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
1690 val = (int)strtol(cp, &ep, 16);
1692 val = (int)strtol(str, &ep, 10);
1694 Fprintf(stderr, "%s: \"%s\" bad value for %s \n",
1698 if (val < mi && mi >= 0) {
1700 Fprintf(stderr, "%s: %s must be >= %d\n",
1703 Fprintf(stderr, "%s: %s must be > %d\n",
1704 prog, what, mi - 1);
1707 if (val > ma && ma >= 0) {
1708 Fprintf(stderr, "%s: %s must be <= %d\n", prog, what, ma);
1715 setproto(char *pname)
1717 struct outproto *proto;
1720 for (i = 0; protos[i].name != NULL; i++) {
1721 if (strcasecmp(protos[i].name, pname) == 0) {
1726 if (proto->name == NULL) { /* generic handler */
1727 struct protoent *pe;
1730 /* Determine the IP protocol number */
1731 if ((pe = getprotobyname(pname)) != NULL)
1734 pnum = str2val(optarg, "proto number", 1, 255);
1741 pkt_compare(const u_char *a, int la, const u_char *b, int lb) {
1745 for (i = 0; i < la; i++)
1746 Printf("%02x", (unsigned int)a[i]);
1748 l = (la <= lb) ? la : lb;
1749 for (i = 0; i < l; i++)
1753 Printf("%02x", (unsigned int)b[i]);
1755 Printf("%02x", (unsigned int)b[i]);
1763 extern char version[];
1765 Fprintf(stderr, "Version %s\n", version);
1767 "Usage: %s [-dDeFInrSvx] [-f first_ttl] [-g gateway] [-i iface]\n"
1768 "\t[-m max_ttl] [-p port] [-P proto] [-q nqueries] [-s src_addr]\n"
1769 "\t[-t tos] [-w waittime] [-z pausemsecs] host [packetlen]\n", prog);