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/tcp.h>
224 #include <netinet/tcpip.h>
226 #include <arpa/inet.h>
229 #include <net/route.h>
230 #include <netipsec/ipsec.h> /* XXX */
248 #ifndef ICMP_UNREACH_FILTER_PROHIB
249 #define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohibited filter */
251 #ifndef ICMP_UNREACH_HOST_PRECEDENCE
252 #define ICMP_UNREACH_HOST_PRECEDENCE 14 /* host precedence violation */
254 #ifndef ICMP_UNREACH_PRECEDENCE_CUTOFF
255 #define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* precedence cutoff */
258 #include "findsaddr.h"
259 #include "ifaddrlist.h"
261 #include "traceroute.h"
263 /* Maximum number of gateways (include room for one noop) */
264 #define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(u_int32_t)))
266 #ifndef MAXHOSTNAMELEN
267 #define MAXHOSTNAMELEN 64
270 #define Fprintf (void)fprintf
271 #define Printf (void)printf
273 /* What a GRE packet header looks like */
277 u_int16_t length; /* PPTP version of these fields */
281 #define IPPROTO_GRE 47
284 /* For GRE, we prepare what looks like a PPTP packet */
285 #define GRE_PPTP_PROTO 0x880b
287 /* Host name and address list */
294 /* Data section of the probe packet */
296 u_char seq; /* sequence number of this packet */
297 u_char ttl; /* ttl packet left with */
298 struct timeval tv; /* time packet left */
301 #ifndef HAVE_ICMP_NEXTMTU
302 /* Path MTU Discovery (RFC1191) */
309 u_char packet[512]; /* last inbound (icmp) packet */
311 struct ip *outip; /* last output ip packet */
312 u_char *outp; /* last output inner protocol packet */
314 struct ip *hip = NULL; /* Quoted IP header */
317 /* loose source route gateway list (including room for final destination) */
318 u_int32_t gwlist[NGATEWAYS + 1];
320 int s; /* receive (icmp) socket file descriptor */
321 int sndsock; /* send (udp) socket file descriptor */
323 struct sockaddr whereto; /* Who to try to reach */
324 struct sockaddr wherefrom; /* Who we are */
325 int packlen; /* total length of packet */
326 int protlen; /* length of protocol part of packet */
327 int minpacket; /* min ip packet size */
328 int maxpacket = 32 * 1024; /* max ip packet size */
329 int pmtu; /* Path MTU Discovery (RFC1191) */
336 static const char devnull[] = "/dev/null";
342 u_short port; /* protocol specific base "port" */
344 int options; /* socket options */
346 int waittime = 5; /* time to wait for response (in seconds) */
347 int nflag; /* print addresses numerically */
348 int as_path; /* print as numbers for each hop */
349 char *as_server = NULL;
351 #ifdef CANT_HACK_IPCKSUM
352 int doipcksum = 0; /* don't calculate ip checksums by default */
354 int doipcksum = 1; /* calculate ip checksums by default */
356 int optlen; /* length of ip options */
357 int fixedPort = 0; /* Use fixed destination port for TCP and UDP */
358 int printdiff = 0; /* Print the difference between sent and quoted */
365 double deltaT(struct timeval *, struct timeval *);
366 void freehostinfo(struct hostinfo *);
367 void getaddr(u_int32_t *, char *);
368 struct hostinfo *gethostinfo(char *);
369 u_short in_cksum(u_short *, int);
370 char *inetname(struct in_addr);
371 int main(int, char **);
372 u_short p_cksum(struct ip *, u_short *, int);
373 int packet_ok(u_char *, int, struct sockaddr_in *, int);
374 char *pr_type(u_char);
375 void print(u_char *, int, struct sockaddr_in *);
377 int setpolicy __P((int so, char *policy));
379 void send_probe(int, int);
380 struct outproto *setproto(char *);
381 int str2val(const char *, const char *, int, int);
382 void tvsub(struct timeval *, struct timeval *);
384 int wait_for_reply(int, struct sockaddr_in *, const struct timeval *);
385 void pkt_compare(const u_char *, int, const u_char *, int);
390 void udp_prep(struct outdata *);
391 int udp_check(const u_char *, int);
392 void tcp_prep(struct outdata *);
393 int tcp_check(const u_char *, int);
394 void gre_prep(struct outdata *);
395 int gre_check(const u_char *, int);
396 void gen_prep(struct outdata *);
397 int gen_check(const u_char *, int);
398 void icmp_prep(struct outdata *);
399 int icmp_check(const u_char *, int);
401 /* Descriptor structure for each outgoing protocol we support */
403 char *name; /* name of protocol */
404 const char *key; /* An ascii key for the bytes of the header */
405 u_char num; /* IP protocol number */
406 u_short hdrlen; /* max size of protocol header */
407 u_short port; /* default base protocol-specific "port" */
408 void (*prepare)(struct outdata *);
409 /* finish preparing an outgoing packet */
410 int (*check)(const u_char *, int);
411 /* check an incoming packet */
414 /* List of supported protocols. The first one is the default. The last
415 one is the handler for generic protocols not explicitly listed. */
416 struct outproto protos[] = {
421 sizeof(struct udphdr),
428 "spt dpt seq ack xxflwin sum urp",
430 sizeof(struct tcphdr),
439 sizeof(struct grehdr),
463 struct outproto *proto = &protos[0];
465 const char *ip_hdr_key = "vhtslen id off tlprsum srcip dstip opts";
468 main(int argc, char **argv)
470 register int op, code, n;
472 register const char *err;
473 register u_int32_t *ap;
474 register struct sockaddr_in *from = (struct sockaddr_in *)&wherefrom;
475 register struct sockaddr_in *to = (struct sockaddr_in *)&whereto;
476 register struct hostinfo *hi;
478 register struct protoent *pe;
479 register int ttl, probe, i;
480 register int seq = 0;
481 int tos = 0, settos = 0;
482 register int lsrr = 0;
483 register u_short off = 0;
484 struct ifaddrlist *al;
486 int requestPort = -1;
490 /* Insure the socket fds won't be 0, 1 or 2 */
491 if (open(devnull, O_RDONLY) < 0 ||
492 open(devnull, O_RDONLY) < 0 ||
493 open(devnull, O_RDONLY) < 0) {
494 Fprintf(stderr, "%s: open \"%s\": %s\n",
495 prog, devnull, strerror(errno));
499 * Do the setuid-required stuff first, then lose priveleges ASAP.
500 * Do error checking for these two calls where they appeared in
504 pe = getprotobyname(cp);
506 if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0)
508 else if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
512 if (setuid(getuid()) != 0) {
519 int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
520 size_t sz = sizeof(max_ttl);
522 if (sysctl(mib, 4, &max_ttl, &sz, NULL, 0) == -1) {
523 perror("sysctl(net.inet.ip.ttl)");
533 else if ((cp = strrchr(argv[0], '/')) != NULL)
539 while ((op = getopt(argc, argv, "aA:edDFInrSvxf:g:i:M:m:P:p:q:s:t:w:z:")) != EOF)
563 case 'M': /* FreeBSD compat. */
564 first_ttl = str2val(optarg, "first ttl", 1, 255);
572 if (lsrr >= NGATEWAYS) {
574 "%s: No more than %d gateways\n",
578 getaddr(gwlist + lsrr, optarg);
587 proto = setproto("icmp");
591 max_ttl = str2val(optarg, "max ttl", 1, 255);
599 proto = setproto(optarg);
603 requestPort = (u_short)str2val(optarg, "port",
608 nprobes = str2val(optarg, "nprobes", 1, -1);
612 options |= SO_DONTROUTE;
617 * set the ip source address of the outbound
618 * probe (e.g., on a multi-homed host).
628 tos = str2val(optarg, "tos", 0, 255);
637 doipcksum = (doipcksum == 0);
641 waittime = str2val(optarg, "wait time",
646 pausemsecs = str2val(optarg, "pause msecs",
654 /* Set requested port, if any, else default for this protocol */
655 port = (requestPort != -1) ? requestPort : proto->port;
658 nprobes = printdiff ? 1 : 3;
660 if (first_ttl > max_ttl) {
662 "%s: first ttl (%d) may not be greater than max ttl (%d)\n",
663 prog, first_ttl, max_ttl);
668 Fprintf(stderr, "%s: Warning: ip checksums disabled\n", prog);
671 optlen = (lsrr + 1) * sizeof(gwlist[0]);
672 minpacket = sizeof(*outip) + proto->hdrlen + sizeof(struct outdata) + optlen;
673 packlen = minpacket; /* minimum sized packet */
675 /* Process destination and optional packet size */
676 switch (argc - optind) {
679 packlen = str2val(argv[optind + 1],
680 "packet length", minpacket, maxpacket);
684 hostname = argv[optind];
685 hi = gethostinfo(hostname);
686 setsin(to, hi->addrs[0]);
689 "%s: Warning: %s has multiple addresses; using %s\n",
690 prog, hostname, inet_ntoa(to->sin_addr));
700 #ifdef HAVE_SETLINEBUF
703 setvbuf(stdout, NULL, _IOLBF, 0);
706 protlen = packlen - sizeof(*outip) - optlen;
708 outip = (struct ip *)malloc((unsigned)packlen);
710 Fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno));
713 memset((char *)outip, 0, packlen);
715 outip->ip_v = IPVERSION;
718 #ifdef BYTESWAP_IP_HDR
719 outip->ip_len = htons(packlen);
720 outip->ip_off = htons(off);
722 outip->ip_len = packlen;
725 outip->ip_p = proto->num;
726 outp = (u_char *)(outip + 1);
727 #ifdef HAVE_RAW_OPTIONS
729 register u_char *optlist;
735 gwlist[lsrr] = to->sin_addr.s_addr;
737 outip->ip_dst.s_addr = gwlist[0];
739 /* force 4 byte alignment */
740 optlist[0] = IPOPT_NOP;
741 /* loose source route option */
742 optlist[1] = IPOPT_LSRR;
743 i = lsrr * sizeof(gwlist[0]);
745 /* Pointer to LSRR addresses */
746 optlist[3] = IPOPT_MINOFF;
747 memcpy(optlist + 4, gwlist + 1, i);
750 outip->ip_dst = to->sin_addr;
752 outip->ip_hl = (outp - (u_char *)outip) >> 2;
753 ident = (getpid() & 0xffff) | 0x8000;
756 Fprintf(stderr, "%s: unknown protocol %s\n", prog, cp);
761 Fprintf(stderr, "%s: icmp socket: %s\n", prog, strerror(errno));
764 if (options & SO_DEBUG)
765 (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on,
767 if (options & SO_DONTROUTE)
768 (void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
771 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
772 if (setpolicy(s, "in bypass") < 0)
773 errx(1, "%s", ipsec_strerror());
775 if (setpolicy(s, "out bypass") < 0)
776 errx(1, "%s", ipsec_strerror());
777 #endif /* defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) */
781 Fprintf(stderr, "%s: raw socket: %s\n", prog, strerror(errno));
785 #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
787 u_char optlist[MAX_IPOPTLEN];
790 if ((pe = getprotobyname(cp)) == NULL) {
791 Fprintf(stderr, "%s: unknown protocol %s\n", prog, cp);
796 gwlist[lsrr] = to->sin_addr.s_addr;
799 /* force 4 byte alignment */
800 optlist[0] = IPOPT_NOP;
801 /* loose source route option */
802 optlist[1] = IPOPT_LSRR;
803 i = lsrr * sizeof(gwlist[0]);
805 /* Pointer to LSRR addresses */
806 optlist[3] = IPOPT_MINOFF;
807 memcpy(optlist + 4, gwlist, i);
809 if ((setsockopt(sndsock, pe->p_proto, IP_OPTIONS,
810 (char *)optlist, i + sizeof(gwlist[0]))) < 0) {
811 Fprintf(stderr, "%s: IP_OPTIONS: %s\n",
812 prog, strerror(errno));
819 if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packlen,
820 sizeof(packlen)) < 0) {
821 Fprintf(stderr, "%s: SO_SNDBUF: %s\n", prog, strerror(errno));
826 if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
828 Fprintf(stderr, "%s: IP_HDRINCL: %s\n", prog, strerror(errno));
833 if (settos && setsockopt(sndsock, IPPROTO_IP, IP_TOS,
834 (char *)&tos, sizeof(tos)) < 0) {
835 Fprintf(stderr, "%s: setsockopt tos %d: %s\n",
836 prog, tos, strerror(errno));
841 if (options & SO_DEBUG)
842 (void)setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on,
844 if (options & SO_DONTROUTE)
845 (void)setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
848 /* Get the interface address list */
849 n = ifaddrlist(&al, errbuf);
851 Fprintf(stderr, "%s: ifaddrlist: %s\n", prog, errbuf);
856 "%s: Can't find any network interfaces\n", prog);
860 /* Look for a specific device */
861 if (device != NULL) {
862 for (i = n; i > 0; --i, ++al)
863 if (strcmp(device, al->device) == 0)
866 Fprintf(stderr, "%s: Can't find interface %.32s\n",
872 /* Determine our source address */
873 if (source == NULL) {
875 * If a device was specified, use the interface address.
876 * Otherwise, try to determine our source address.
879 setsin(from, al->addr);
880 else if ((err = findsaddr(to, from)) != NULL) {
881 Fprintf(stderr, "%s: findsaddr: %s\n",
886 hi = gethostinfo(source);
890 * If the device was specified make sure it
891 * corresponds to the source address specified.
892 * Otherwise, use the first address (and warn if
893 * there are more than one).
895 if (device != NULL) {
896 for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
901 "%s: %s is not on interface %.32s\n",
902 prog, source, device);
907 setsin(from, hi->addrs[0]);
910 "%s: Warning: %s has multiple addresses; using %s\n",
911 prog, source, inet_ntoa(from->sin_addr));
916 outip->ip_src = from->sin_addr;
918 /* Check the source address (-s), if any, is valid */
919 if (bind(sndsock, (struct sockaddr *)from, sizeof(*from)) < 0) {
920 Fprintf(stderr, "%s: bind: %s\n",
921 prog, strerror(errno));
926 asn = as_setup(as_server);
928 Fprintf(stderr, "%s: as_setup failed, AS# lookups"
929 " disabled\n", prog);
930 (void)fflush(stderr);
935 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
936 if (setpolicy(sndsock, "in bypass") < 0)
937 errx(1, "%s", ipsec_strerror());
939 if (setpolicy(sndsock, "out bypass") < 0)
940 errx(1, "%s", ipsec_strerror());
941 #endif /* defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) */
943 Fprintf(stderr, "%s to %s (%s)",
944 prog, hostname, inet_ntoa(to->sin_addr));
946 Fprintf(stderr, " from %s", source);
947 Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen);
948 (void)fflush(stderr);
950 for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
951 u_int32_t lastaddr = 0;
959 for (probe = 0, loss = 0; probe < nprobes; ++probe) {
961 struct timeval t1, t2;
962 register struct ip *ip;
963 struct outdata outdata;
965 if (sentfirst && pausemsecs > 0)
966 usleep(pausemsecs * 1000);
967 /* Prepare outgoing data */
971 /* Avoid alignment problems by copying bytewise: */
972 (void)gettimeofday(&t1, NULL);
973 memcpy(&outdata.tv, &t1, sizeof(outdata.tv));
975 /* Finalize and send packet */
976 (*proto->prepare)(&outdata);
977 send_probe(seq, ttl);
980 /* Wait for a reply */
981 while ((cc = wait_for_reply(s, from, &t1)) != 0) {
985 (void)gettimeofday(&t2, NULL);
986 i = packet_ok(packet, cc, from, seq);
987 /* Skip short packet */
991 from->sin_addr.s_addr != lastaddr) {
992 if (gotlastaddr) printf("\n ");
993 print(packet, cc, from);
994 lastaddr = from->sin_addr.s_addr;
997 T = deltaT(&t1, &t2);
998 #ifdef SANE_PRECISION
1001 else if (T >= 100.0)
1008 Printf(" %.*f ms", precis, T);
1012 -(outip->ip_hl << 3),
1016 pkt_compare((void *)outip, packlen,
1017 (void *)hip, hiplen);
1021 ip = (struct ip *)packet;
1022 if (ip->ip_ttl <= 1)
1028 /* time exceeded in transit */
1034 case ICMP_UNREACH_PORT:
1036 ip = (struct ip *)packet;
1037 if (ip->ip_ttl <= 1)
1043 case ICMP_UNREACH_NET:
1048 case ICMP_UNREACH_HOST:
1053 case ICMP_UNREACH_PROTOCOL:
1058 case ICMP_UNREACH_NEEDFRAG:
1060 Printf(" !F-%d", pmtu);
1063 case ICMP_UNREACH_SRCFAIL:
1068 case ICMP_UNREACH_NET_UNKNOWN:
1073 case ICMP_UNREACH_HOST_UNKNOWN:
1078 case ICMP_UNREACH_ISOLATED:
1083 case ICMP_UNREACH_NET_PROHIB:
1088 case ICMP_UNREACH_HOST_PROHIB:
1093 case ICMP_UNREACH_TOSNET:
1098 case ICMP_UNREACH_TOSHOST:
1103 case ICMP_UNREACH_FILTER_PROHIB:
1108 case ICMP_UNREACH_HOST_PRECEDENCE:
1113 case ICMP_UNREACH_PRECEDENCE_CUTOFF:
1120 Printf(" !<%d>", code);
1129 (void)fflush(stdout);
1132 Printf(" (%d%% loss)", (loss * 100) / nprobes);
1136 (unreachable > 0 && unreachable >= nprobes - 1))
1145 wait_for_reply(register int sock, register struct sockaddr_in *fromp,
1146 register const struct timeval *tp)
1150 struct timeval now, wait;
1151 register int cc = 0;
1153 int fromlen = sizeof(*fromp);
1155 nfds = howmany(sock + 1, NFDBITS);
1156 if ((fdsp = malloc(nfds * sizeof(fd_mask))) == NULL)
1158 memset(fdsp, 0, nfds * sizeof(fd_mask));
1161 wait.tv_sec = tp->tv_sec + waittime;
1162 wait.tv_usec = tp->tv_usec;
1163 (void)gettimeofday(&now, NULL);
1165 if (wait.tv_sec < 0) {
1170 error = select(sock + 1, fdsp, NULL, NULL, &wait);
1171 if (error == -1 && errno == EINVAL) {
1172 Fprintf(stderr, "%s: botched select() args\n", prog);
1176 cc = recvfrom(sock, (char *)packet, sizeof(packet), 0,
1177 (struct sockaddr *)fromp, &fromlen);
1184 send_probe(int seq, int ttl)
1188 outip->ip_ttl = ttl;
1189 outip->ip_id = htons(ident + seq);
1191 /* XXX undocumented debugging hack */
1193 register const u_short *sp;
1194 register int nshorts, i;
1196 sp = (u_short *)outip;
1197 nshorts = (u_int)packlen / sizeof(u_short);
1199 Printf("[ %d bytes", packlen);
1200 while (--nshorts >= 0) {
1203 Printf(" %04x", ntohs(*sp++));
1208 Printf(" %02x", *(u_char *)sp);
1213 #if !defined(IP_HDRINCL) && defined(IP_TTL)
1214 if (setsockopt(sndsock, IPPROTO_IP, IP_TTL,
1215 (char *)&ttl, sizeof(ttl)) < 0) {
1216 Fprintf(stderr, "%s: setsockopt ttl %d: %s\n",
1217 prog, ttl, strerror(errno));
1222 cc = sendto(sndsock, (char *)outip,
1223 packlen, 0, &whereto, sizeof(whereto));
1224 if (cc < 0 || cc != packlen) {
1226 Fprintf(stderr, "%s: sendto: %s\n",
1227 prog, strerror(errno));
1228 Printf("%s: wrote %s %d chars, ret=%d\n",
1229 prog, hostname, packlen, cc);
1230 (void)fflush(stdout);
1234 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
1236 setpolicy(so, policy)
1242 buf = ipsec_set_policy(policy, strlen(policy));
1244 warnx("%s", ipsec_strerror());
1247 (void)setsockopt(so, IPPROTO_IP, IP_IPSEC_POLICY,
1248 buf, ipsec_get_policylen(buf));
1257 deltaT(struct timeval *t1p, struct timeval *t2p)
1261 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1262 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1267 * Convert an ICMP "type" field to a printable string.
1270 pr_type(register u_char t)
1272 static char *ttab[] = {
1273 "Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable",
1274 "Source Quench", "Redirect", "ICMP 6", "ICMP 7",
1275 "Echo", "ICMP 9", "ICMP 10", "Time Exceeded",
1276 "Param Problem", "Timestamp", "Timestamp Reply", "Info Request",
1281 return("OUT-OF-RANGE");
1287 packet_ok(register u_char *buf, int cc, register struct sockaddr_in *from,
1290 register struct icmp *icp;
1291 register u_char type, code;
1294 register struct ip *ip;
1296 ip = (struct ip *) buf;
1297 hlen = ip->ip_hl << 2;
1298 if (cc < hlen + ICMP_MINLEN) {
1300 Printf("packet too short (%d bytes) from %s\n", cc,
1301 inet_ntoa(from->sin_addr));
1305 icp = (struct icmp *)(buf + hlen);
1307 icp = (struct icmp *)buf;
1309 type = icp->icmp_type;
1310 code = icp->icmp_code;
1311 /* Path MTU Discovery (RFC1191) */
1312 if (code != ICMP_UNREACH_NEEDFRAG)
1315 #ifdef HAVE_ICMP_NEXTMTU
1316 pmtu = ntohs(icp->icmp_nextmtu);
1318 pmtu = ntohs(((struct my_pmtu *)&icp->icmp_void)->ipm_nextmtu);
1321 if (type == ICMP_ECHOREPLY
1322 && proto->num == IPPROTO_ICMP
1323 && (*proto->check)((u_char *)icp, (u_char)seq))
1325 if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
1326 type == ICMP_UNREACH) {
1329 hip = &icp->icmp_ip;
1330 hiplen = ((u_char *)icp + cc) - (u_char *)hip;
1331 hlen = hip->ip_hl << 2;
1332 inner = (u_char *)((u_char *)hip + hlen);
1334 && hip->ip_p == proto->num
1335 && (*proto->check)(inner, (u_char)seq))
1336 return (type == ICMP_TIMXCEED ? -1 : code + 1);
1341 u_int32_t *lp = (u_int32_t *)&icp->icmp_ip;
1343 Printf("\n%d bytes from %s to ", cc, inet_ntoa(from->sin_addr));
1344 Printf("%s: icmp type %d (%s) code %d\n",
1345 inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
1346 for (i = 4; i < cc ; i += sizeof(*lp))
1347 Printf("%2d: x%8.8x\n", i, *lp++);
1354 icmp_prep(struct outdata *outdata)
1356 struct icmp *const icmpheader = (struct icmp *) outp;
1358 icmpheader->icmp_type = ICMP_ECHO;
1359 icmpheader->icmp_id = htons(ident);
1360 icmpheader->icmp_seq = htons(outdata->seq);
1361 icmpheader->icmp_cksum = 0;
1362 icmpheader->icmp_cksum = in_cksum((u_short *)icmpheader, protlen);
1363 if (icmpheader->icmp_cksum == 0)
1364 icmpheader->icmp_cksum = 0xffff;
1368 icmp_check(const u_char *data, int seq)
1370 struct icmp *const icmpheader = (struct icmp *) data;
1372 return (icmpheader->icmp_id == htons(ident)
1373 && icmpheader->icmp_seq == htons(seq));
1377 udp_prep(struct outdata *outdata)
1379 struct udphdr *const outudp = (struct udphdr *) outp;
1381 outudp->uh_sport = htons(ident + (fixedPort ? outdata->seq : 0));
1382 outudp->uh_dport = htons(port + (fixedPort ? 0 : outdata->seq));
1383 outudp->uh_ulen = htons((u_short)protlen);
1386 u_short sum = p_cksum(outip, (u_short*)outudp, protlen);
1387 outudp->uh_sum = (sum) ? sum : 0xffff;
1394 udp_check(const u_char *data, int seq)
1396 struct udphdr *const udp = (struct udphdr *) data;
1398 return (ntohs(udp->uh_sport) == ident + (fixedPort ? seq : 0) &&
1399 ntohs(udp->uh_dport) == port + (fixedPort ? 0 : seq));
1403 tcp_prep(struct outdata *outdata)
1405 struct tcphdr *const tcp = (struct tcphdr *) outp;
1407 tcp->th_sport = htons(ident);
1408 tcp->th_dport = htons(port + (fixedPort ? 0 : outdata->seq));
1409 tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
1412 tcp->th_flags = TH_SYN;
1416 u_short sum = p_cksum(outip, (u_short*)tcp, protlen);
1417 tcp->th_sum = (sum) ? sum : 0xffff;
1422 tcp_check(const u_char *data, int seq)
1424 struct tcphdr *const tcp = (struct tcphdr *) data;
1426 return (ntohs(tcp->th_sport) == ident
1427 && ntohs(tcp->th_dport) == port + (fixedPort ? 0 : seq)
1428 && tcp->th_seq == (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport));
1432 gre_prep(struct outdata *outdata)
1434 struct grehdr *const gre = (struct grehdr *) outp;
1436 gre->flags = htons(0x2001);
1437 gre->proto = htons(port);
1439 gre->callId = htons(ident + outdata->seq);
1443 gre_check(const u_char *data, int seq)
1445 struct grehdr *const gre = (struct grehdr *) data;
1447 return(ntohs(gre->proto) == port
1448 && ntohs(gre->callId) == ident + seq);
1452 gen_prep(struct outdata *outdata)
1454 u_int16_t *const ptr = (u_int16_t *) outp;
1456 ptr[0] = htons(ident);
1457 ptr[1] = htons(port + outdata->seq);
1461 gen_check(const u_char *data, int seq)
1463 u_int16_t *const ptr = (u_int16_t *) data;
1465 return(ntohs(ptr[0]) == ident
1466 && ntohs(ptr[1]) == port + seq);
1470 print(register u_char *buf, register int cc, register struct sockaddr_in *from)
1472 register struct ip *ip;
1474 char addr[INET_ADDRSTRLEN];
1476 ip = (struct ip *) buf;
1477 hlen = ip->ip_hl << 2;
1480 strlcpy(addr, inet_ntoa(from->sin_addr), sizeof(addr));
1483 Printf(" [AS%u]", as_lookup(asn, addr, AF_INET));
1486 Printf(" %s", addr);
1488 Printf(" %s (%s)", inetname(from->sin_addr), addr);
1491 Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
1495 * Checksum routine for UDP and TCP headers.
1498 p_cksum(struct ip *ip, u_short *data, int len)
1500 static struct ipovly ipo;
1503 ipo.ih_pr = ip->ip_p;
1504 ipo.ih_len = htons(len);
1505 ipo.ih_src = ip->ip_src;
1506 ipo.ih_dst = ip->ip_dst;
1508 sum[1] = in_cksum((u_short*)&ipo, sizeof(ipo)); /* pseudo ip hdr cksum */
1509 sum[0] = in_cksum(data, len); /* payload data cksum */
1511 return ~in_cksum(sum, sizeof(sum));
1515 * Checksum routine for Internet Protocol family headers (C Version)
1518 in_cksum(register u_short *addr, register int len)
1520 register int nleft = len;
1521 register u_short *w = addr;
1522 register u_short answer;
1523 register int sum = 0;
1526 * Our algorithm is simple, using a 32 bit accumulator (sum),
1527 * we add sequential 16 bit words to it, and at the end, fold
1528 * back all the carry bits from the top 16 bits into the lower
1536 /* mop up an odd byte, if necessary */
1538 sum += *(u_char *)w;
1541 * add back carry outs from top 16 bits to low 16 bits
1543 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
1544 sum += (sum >> 16); /* add carry */
1545 answer = ~sum; /* truncate to 16 bits */
1550 * Subtract 2 timeval structs: out = out - in.
1551 * Out is assumed to be within about LONG_MAX seconds of in.
1554 tvsub(register struct timeval *out, register struct timeval *in)
1557 if ((out->tv_usec -= in->tv_usec) < 0) {
1559 out->tv_usec += 1000000;
1561 out->tv_sec -= in->tv_sec;
1565 * Construct an Internet address representation.
1566 * If the nflag has been supplied, give
1567 * numeric value, otherwise try for symbolic name.
1570 inetname(struct in_addr in)
1573 register struct hostent *hp;
1574 static int first = 1;
1575 static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1];
1577 if (first && !nflag) {
1579 if (gethostname(domain, sizeof(domain) - 1) < 0)
1582 cp = strchr(domain, '.');
1584 hp = gethostbyname(domain);
1586 cp = strchr(hp->h_name, '.');
1592 (void)strncpy(domain, cp, sizeof(domain) - 1);
1593 domain[sizeof(domain) - 1] = '\0';
1597 if (!nflag && in.s_addr != INADDR_ANY) {
1598 hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
1600 if ((cp = strchr(hp->h_name, '.')) != NULL &&
1601 strcmp(cp + 1, domain) == 0)
1603 (void)strncpy(line, hp->h_name, sizeof(line) - 1);
1604 line[sizeof(line) - 1] = '\0';
1608 return (inet_ntoa(in));
1612 gethostinfo(register char *hostname)
1615 register struct hostent *hp;
1616 register struct hostinfo *hi;
1618 register u_int32_t addr, *ap;
1620 if (strlen(hostname) >= MAXHOSTNAMELEN) {
1621 Fprintf(stderr, "%s: hostname \"%.32s...\" is too long\n",
1625 hi = calloc(1, sizeof(*hi));
1627 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1630 addr = inet_addr(hostname);
1631 if ((int32_t)addr != -1) {
1632 hi->name = strdup(hostname);
1634 hi->addrs = calloc(1, sizeof(hi->addrs[0]));
1635 if (hi->addrs == NULL) {
1636 Fprintf(stderr, "%s: calloc %s\n",
1637 prog, strerror(errno));
1640 hi->addrs[0] = addr;
1644 hp = gethostbyname(hostname);
1646 Fprintf(stderr, "%s: unknown host %s\n", prog, hostname);
1649 if (hp->h_addrtype != AF_INET || hp->h_length != 4) {
1650 Fprintf(stderr, "%s: bad host %s\n", prog, hostname);
1653 hi->name = strdup(hp->h_name);
1654 for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
1657 hi->addrs = calloc(n, sizeof(hi->addrs[0]));
1658 if (hi->addrs == NULL) {
1659 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1662 for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
1663 memcpy(ap, *p, sizeof(*ap));
1668 freehostinfo(register struct hostinfo *hi)
1670 if (hi->name != NULL) {
1674 free((char *)hi->addrs);
1679 getaddr(register u_int32_t *ap, register char *hostname)
1681 register struct hostinfo *hi;
1683 hi = gethostinfo(hostname);
1689 setsin(register struct sockaddr_in *sin, register u_int32_t addr)
1692 memset(sin, 0, sizeof(*sin));
1693 #ifdef HAVE_SOCKADDR_SA_LEN
1694 sin->sin_len = sizeof(*sin);
1696 sin->sin_family = AF_INET;
1697 sin->sin_addr.s_addr = addr;
1700 /* String to value with optional min and max. Handles decimal and hex. */
1702 str2val(register const char *str, register const char *what,
1703 register int mi, register int ma)
1705 register const char *cp;
1709 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
1711 val = (int)strtol(cp, &ep, 16);
1713 val = (int)strtol(str, &ep, 10);
1715 Fprintf(stderr, "%s: \"%s\" bad value for %s \n",
1719 if (val < mi && mi >= 0) {
1721 Fprintf(stderr, "%s: %s must be >= %d\n",
1724 Fprintf(stderr, "%s: %s must be > %d\n",
1725 prog, what, mi - 1);
1728 if (val > ma && ma >= 0) {
1729 Fprintf(stderr, "%s: %s must be <= %d\n", prog, what, ma);
1736 setproto(char *pname)
1738 struct outproto *proto;
1741 for (i = 0; protos[i].name != NULL; i++) {
1742 if (strcasecmp(protos[i].name, pname) == 0) {
1747 if (proto->name == NULL) { /* generic handler */
1748 struct protoent *pe;
1751 /* Determine the IP protocol number */
1752 if ((pe = getprotobyname(pname)) != NULL)
1755 pnum = str2val(optarg, "proto number", 1, 255);
1762 pkt_compare(const u_char *a, int la, const u_char *b, int lb) {
1766 for (i = 0; i < la; i++)
1767 Printf("%02x", (unsigned int)a[i]);
1769 l = (la <= lb) ? la : lb;
1770 for (i = 0; i < l; i++)
1774 Printf("%02x", (unsigned int)b[i]);
1776 Printf("%02x", (unsigned int)b[i]);
1784 extern char version[];
1786 Fprintf(stderr, "Version %s\n", version);
1788 "Usage: %s [-adDeFInrSvx] [-f first_ttl] [-g gateway] [-i iface]\n"
1789 "\t[-m max_ttl] [-p port] [-P proto] [-q nqueries] [-s src_addr]\n"
1790 "\t[-t tos] [-w waittime] [-A as_server] [-z pausemsecs] host [packetlen]\n", prog);