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.2 2004/08/08 00:27:54 lindak Exp $ (LBL)";
30 static const char rcsid
[] =
31 "$FreeBSD: src/contrib/traceroute/traceroute.c,v 1.26 2004/04/17 18:44:23 pb Exp $";
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 */
362 double deltaT(struct timeval
*, struct timeval
*);
363 void freehostinfo(struct hostinfo
*);
364 void getaddr(u_int32_t
*, char *);
365 struct hostinfo
*gethostinfo(char *);
366 u_short
in_cksum(u_short
*, int);
367 char *inetname(struct in_addr
);
368 int main(int, char **);
369 u_short
p_cksum(struct ip
*, u_short
*, int);
370 int packet_ok(u_char
*, int, struct sockaddr_in
*, int);
371 char *pr_type(u_char
);
372 void print(u_char
*, int, struct sockaddr_in
*);
374 int setpolicy
__P((int so
, char *policy
));
376 void send_probe(int, int);
377 struct outproto
*setproto(char *);
378 int str2val(const char *, const char *, int, int);
379 void tvsub(struct timeval
*, struct timeval
*);
381 int wait_for_reply(int, struct sockaddr_in
*, const struct timeval
*);
386 void udp_prep(struct outdata
*);
387 int udp_check(const u_char
*, int);
388 void tcp_prep(struct outdata
*);
389 int tcp_check(const u_char
*, int);
390 void gre_prep(struct outdata
*);
391 int gre_check(const u_char
*, int);
392 void gen_prep(struct outdata
*);
393 int gen_check(const u_char
*, int);
394 void icmp_prep(struct outdata
*);
395 int icmp_check(const u_char
*, int);
397 /* Descriptor structure for each outgoing protocol we support */
399 char *name
; /* name of protocol */
400 u_char num
; /* IP protocol number */
401 u_short hdrlen
; /* max size of protocol header */
402 u_short port
; /* default base protocol-specific "port" */
403 void (*prepare
)(struct outdata
*);
404 /* finish preparing an outgoing packet */
405 int (*check
)(const u_char
*, int);
406 /* check an incoming packet */
409 /* List of supported protocols. The first one is the default. The last
410 one is the handler for generic protocols not explicitly listed. */
411 struct outproto protos
[] = {
415 sizeof(struct udphdr
),
423 sizeof(struct tcphdr
),
431 sizeof(struct grehdr
),
453 struct outproto
*proto
= &protos
[0];
456 main(int argc
, char **argv
)
458 register int op
, code
, n
;
460 register const char *err
;
461 register u_int32_t
*ap
;
462 register struct sockaddr_in
*from
= (struct sockaddr_in
*)&wherefrom
;
463 register struct sockaddr_in
*to
= (struct sockaddr_in
*)&whereto
;
464 register struct hostinfo
*hi
;
466 register struct protoent
*pe
;
467 register int ttl
, probe
, i
;
468 register int seq
= 0;
469 int tos
= 0, settos
= 0;
470 register int lsrr
= 0;
471 register u_short off
= 0;
472 struct ifaddrlist
*al
;
474 int requestPort
= -1;
478 /* Insure the socket fds won't be 0, 1 or 2 */
479 if (open(devnull
, O_RDONLY
) < 0 ||
480 open(devnull
, O_RDONLY
) < 0 ||
481 open(devnull
, O_RDONLY
) < 0) {
482 Fprintf(stderr
, "%s: open \"%s\": %s\n",
483 prog
, devnull
, strerror(errno
));
487 * Do the setuid-required stuff first, then lose priveleges ASAP.
488 * Do error checking for these two calls where they appeared in
492 pe
= getprotobyname(cp
);
494 if ((s
= socket(AF_INET
, SOCK_RAW
, pe
->p_proto
)) < 0)
496 else if ((sndsock
= socket(AF_INET
, SOCK_RAW
, IPPROTO_RAW
)) < 0)
504 int mib
[4] = { CTL_NET
, PF_INET
, IPPROTO_IP
, IPCTL_DEFTTL
};
505 size_t sz
= sizeof(max_ttl
);
507 if (sysctl(mib
, 4, &max_ttl
, &sz
, NULL
, 0) == -1) {
508 perror("sysctl(net.inet.ip.ttl)");
518 else if ((cp
= strrchr(argv
[0], '/')) != NULL
)
524 while ((op
= getopt(argc
, argv
, "dFInrSvxf:g:i:M:m:P:p:q:s:t:w:z:")) != EOF
)
532 case 'M': /* FreeBSD compat. */
533 first_ttl
= str2val(optarg
, "first ttl", 1, 255);
541 if (lsrr
>= NGATEWAYS
) {
543 "%s: No more than %d gateways\n",
547 getaddr(gwlist
+ lsrr
, optarg
);
556 proto
= setproto("icmp");
560 max_ttl
= str2val(optarg
, "max ttl", 1, 255);
568 proto
= setproto(optarg
);
572 requestPort
= (u_short
)str2val(optarg
, "port",
577 nprobes
= str2val(optarg
, "nprobes", 1, -1);
581 options
|= SO_DONTROUTE
;
586 * set the ip source address of the outbound
587 * probe (e.g., on a multi-homed host).
597 tos
= str2val(optarg
, "tos", 0, 255);
606 doipcksum
= (doipcksum
== 0);
610 waittime
= str2val(optarg
, "wait time",
615 pausemsecs
= str2val(optarg
, "pause msecs",
623 /* Set requested port, if any, else default for this protocol */
624 port
= (requestPort
!= -1) ? requestPort
: proto
->port
;
626 if (first_ttl
> max_ttl
) {
628 "%s: first ttl (%d) may not be greater than max ttl (%d)\n",
629 prog
, first_ttl
, max_ttl
);
634 Fprintf(stderr
, "%s: Warning: ip checksums disabled\n", prog
);
637 optlen
= (lsrr
+ 1) * sizeof(gwlist
[0]);
638 minpacket
= sizeof(*outip
) + proto
->hdrlen
+ sizeof(struct outdata
) + optlen
;
639 packlen
= minpacket
; /* minimum sized packet */
641 /* Process destination and optional packet size */
642 switch (argc
- optind
) {
645 packlen
= str2val(argv
[optind
+ 1],
646 "packet length", minpacket
, maxpacket
);
650 hostname
= argv
[optind
];
651 hi
= gethostinfo(hostname
);
652 setsin(to
, hi
->addrs
[0]);
655 "%s: Warning: %s has multiple addresses; using %s\n",
656 prog
, hostname
, inet_ntoa(to
->sin_addr
));
666 #ifdef HAVE_SETLINEBUF
669 setvbuf(stdout
, NULL
, _IOLBF
, 0);
672 protlen
= packlen
- sizeof(*outip
) - optlen
;
674 outip
= (struct ip
*)malloc((unsigned)packlen
);
676 Fprintf(stderr
, "%s: malloc: %s\n", prog
, strerror(errno
));
679 memset((char *)outip
, 0, packlen
);
681 outip
->ip_v
= IPVERSION
;
684 #ifdef BYTESWAP_IP_HDR
685 outip
->ip_len
= htons(packlen
);
686 outip
->ip_off
= htons(off
);
688 outip
->ip_len
= packlen
;
691 outip
->ip_p
= proto
->num
;
692 outp
= (u_char
*)(outip
+ 1);
693 #ifdef HAVE_RAW_OPTIONS
695 register u_char
*optlist
;
701 gwlist
[lsrr
] = to
->sin_addr
.s_addr
;
703 outip
->ip_dst
.s_addr
= gwlist
[0];
705 /* force 4 byte alignment */
706 optlist
[0] = IPOPT_NOP
;
707 /* loose source route option */
708 optlist
[1] = IPOPT_LSRR
;
709 i
= lsrr
* sizeof(gwlist
[0]);
711 /* Pointer to LSRR addresses */
712 optlist
[3] = IPOPT_MINOFF
;
713 memcpy(optlist
+ 4, gwlist
+ 1, i
);
716 outip
->ip_dst
= to
->sin_addr
;
718 outip
->ip_hl
= (outp
- (u_char
*)outip
) >> 2;
719 ident
= (getpid() & 0xffff) | 0x8000;
722 Fprintf(stderr
, "%s: unknown protocol %s\n", prog
, cp
);
727 Fprintf(stderr
, "%s: icmp socket: %s\n", prog
, strerror(errno
));
730 if (options
& SO_DEBUG
)
731 (void)setsockopt(s
, SOL_SOCKET
, SO_DEBUG
, (char *)&on
,
733 if (options
& SO_DONTROUTE
)
734 (void)setsockopt(s
, SOL_SOCKET
, SO_DONTROUTE
, (char *)&on
,
737 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
738 if (setpolicy(s
, "in bypass") < 0)
739 errx(1, "%s", ipsec_strerror());
741 if (setpolicy(s
, "out bypass") < 0)
742 errx(1, "%s", ipsec_strerror());
743 #endif /* defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) */
747 Fprintf(stderr
, "%s: raw socket: %s\n", prog
, strerror(errno
));
751 #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
753 u_char optlist
[MAX_IPOPTLEN
];
756 if ((pe
= getprotobyname(cp
)) == NULL
) {
757 Fprintf(stderr
, "%s: unknown protocol %s\n", prog
, cp
);
762 gwlist
[lsrr
] = to
->sin_addr
.s_addr
;
765 /* force 4 byte alignment */
766 optlist
[0] = IPOPT_NOP
;
767 /* loose source route option */
768 optlist
[1] = IPOPT_LSRR
;
769 i
= lsrr
* sizeof(gwlist
[0]);
771 /* Pointer to LSRR addresses */
772 optlist
[3] = IPOPT_MINOFF
;
773 memcpy(optlist
+ 4, gwlist
, i
);
775 if ((setsockopt(sndsock
, pe
->p_proto
, IP_OPTIONS
,
776 (char *)optlist
, i
+ sizeof(gwlist
[0]))) < 0) {
777 Fprintf(stderr
, "%s: IP_OPTIONS: %s\n",
778 prog
, strerror(errno
));
785 if (setsockopt(sndsock
, SOL_SOCKET
, SO_SNDBUF
, (char *)&packlen
,
786 sizeof(packlen
)) < 0) {
787 Fprintf(stderr
, "%s: SO_SNDBUF: %s\n", prog
, strerror(errno
));
792 if (setsockopt(sndsock
, IPPROTO_IP
, IP_HDRINCL
, (char *)&on
,
794 Fprintf(stderr
, "%s: IP_HDRINCL: %s\n", prog
, strerror(errno
));
799 if (settos
&& setsockopt(sndsock
, IPPROTO_IP
, IP_TOS
,
800 (char *)&tos
, sizeof(tos
)) < 0) {
801 Fprintf(stderr
, "%s: setsockopt tos %d: %s\n",
802 prog
, tos
, strerror(errno
));
807 if (options
& SO_DEBUG
)
808 (void)setsockopt(sndsock
, SOL_SOCKET
, SO_DEBUG
, (char *)&on
,
810 if (options
& SO_DONTROUTE
)
811 (void)setsockopt(sndsock
, SOL_SOCKET
, SO_DONTROUTE
, (char *)&on
,
814 /* Get the interface address list */
815 n
= ifaddrlist(&al
, errbuf
);
817 Fprintf(stderr
, "%s: ifaddrlist: %s\n", prog
, errbuf
);
822 "%s: Can't find any network interfaces\n", prog
);
826 /* Look for a specific device */
827 if (device
!= NULL
) {
828 for (i
= n
; i
> 0; --i
, ++al
)
829 if (strcmp(device
, al
->device
) == 0)
832 Fprintf(stderr
, "%s: Can't find interface %.32s\n",
838 /* Determine our source address */
839 if (source
== NULL
) {
841 * If a device was specified, use the interface address.
842 * Otherwise, try to determine our source address.
845 setsin(from
, al
->addr
);
846 else if ((err
= findsaddr(to
, from
)) != NULL
) {
847 Fprintf(stderr
, "%s: findsaddr: %s\n",
852 hi
= gethostinfo(source
);
856 * If the device was specified make sure it
857 * corresponds to the source address specified.
858 * Otherwise, use the first address (and warn if
859 * there are more than one).
861 if (device
!= NULL
) {
862 for (i
= hi
->n
, ap
= hi
->addrs
; i
> 0; --i
, ++ap
)
867 "%s: %s is not on interface %.32s\n",
868 prog
, source
, device
);
873 setsin(from
, hi
->addrs
[0]);
876 "%s: Warning: %s has multiple addresses; using %s\n",
877 prog
, source
, inet_ntoa(from
->sin_addr
));
882 outip
->ip_src
= from
->sin_addr
;
884 /* Check the source address (-s), if any, is valid */
885 if (bind(sndsock
, (struct sockaddr
*)from
, sizeof(*from
)) < 0) {
886 Fprintf(stderr
, "%s: bind: %s\n",
887 prog
, strerror(errno
));
891 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
892 if (setpolicy(sndsock
, "in bypass") < 0)
893 errx(1, "%s", ipsec_strerror());
895 if (setpolicy(sndsock
, "out bypass") < 0)
896 errx(1, "%s", ipsec_strerror());
897 #endif /* defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) */
899 Fprintf(stderr
, "%s to %s (%s)",
900 prog
, hostname
, inet_ntoa(to
->sin_addr
));
902 Fprintf(stderr
, " from %s", source
);
903 Fprintf(stderr
, ", %d hops max, %d byte packets\n", max_ttl
, packlen
);
904 (void)fflush(stderr
);
906 for (ttl
= first_ttl
; ttl
<= max_ttl
; ++ttl
) {
907 u_int32_t lastaddr
= 0;
915 for (probe
= 0, loss
= 0; probe
< nprobes
; ++probe
) {
917 struct timeval t1
, t2
;
919 register struct ip
*ip
;
920 struct outdata outdata
;
922 if (sentfirst
&& pausemsecs
> 0)
923 usleep(pausemsecs
* 1000);
924 /* Prepare outgoing data */
928 /* Avoid alignment problems by copying bytewise: */
929 (void)gettimeofday(&t1
, &tz
);
930 memcpy(&outdata
.tv
, &t1
, sizeof(outdata
.tv
));
932 /* Finalize and send packet */
933 (*proto
->prepare
)(&outdata
);
934 send_probe(seq
, ttl
);
937 /* Wait for a reply */
938 while ((cc
= wait_for_reply(s
, from
, &t1
)) != 0) {
942 (void)gettimeofday(&t2
, &tz
);
943 i
= packet_ok(packet
, cc
, from
, seq
);
944 /* Skip short packet */
948 from
->sin_addr
.s_addr
!= lastaddr
) {
949 print(packet
, cc
, from
);
950 lastaddr
= from
->sin_addr
.s_addr
;
953 T
= deltaT(&t1
, &t2
);
954 #ifdef SANE_PRECISION
964 Printf(" %.*f ms", precis
, T
);
967 ip
= (struct ip
*)packet
;
974 /* time exceeded in transit */
980 case ICMP_UNREACH_PORT
:
982 ip
= (struct ip
*)packet
;
989 case ICMP_UNREACH_NET
:
994 case ICMP_UNREACH_HOST
:
999 case ICMP_UNREACH_PROTOCOL
:
1004 case ICMP_UNREACH_NEEDFRAG
:
1006 Printf(" !F-%d", pmtu
);
1009 case ICMP_UNREACH_SRCFAIL
:
1014 case ICMP_UNREACH_FILTER_PROHIB
:
1019 case ICMP_UNREACH_HOST_PRECEDENCE
:
1024 case ICMP_UNREACH_PRECEDENCE_CUTOFF
:
1031 Printf(" !<%d>", code
);
1040 (void)fflush(stdout
);
1043 Printf(" (%d%% loss)", (loss
* 100) / nprobes
);
1047 (unreachable
> 0 && unreachable
>= nprobes
- 1))
1054 wait_for_reply(register int sock
, register struct sockaddr_in
*fromp
,
1055 register const struct timeval
*tp
)
1059 struct timeval now
, wait
;
1061 register int cc
= 0;
1063 int fromlen
= sizeof(*fromp
);
1065 nfds
= howmany(sock
+ 1, NFDBITS
);
1066 if ((fdsp
= malloc(nfds
* sizeof(fd_mask
))) == NULL
)
1068 memset(fdsp
, 0, nfds
* sizeof(fd_mask
));
1071 wait
.tv_sec
= tp
->tv_sec
+ waittime
;
1072 wait
.tv_usec
= tp
->tv_usec
;
1073 (void)gettimeofday(&now
, &tz
);
1075 if (wait
.tv_sec
< 0) {
1080 error
= select(sock
+ 1, fdsp
, NULL
, NULL
, &wait
);
1081 if (error
== -1 && errno
== EINVAL
) {
1082 Fprintf(stderr
, "%s: botched select() args\n", prog
);
1086 cc
= recvfrom(sock
, (char *)packet
, sizeof(packet
), 0,
1087 (struct sockaddr
*)fromp
, &fromlen
);
1094 send_probe(int seq
, int ttl
)
1098 outip
->ip_ttl
= ttl
;
1099 outip
->ip_id
= htons(ident
+ seq
);
1101 /* XXX undocumented debugging hack */
1103 register const u_short
*sp
;
1104 register int nshorts
, i
;
1106 sp
= (u_short
*)outip
;
1107 nshorts
= (u_int
)packlen
/ sizeof(u_short
);
1109 Printf("[ %d bytes", packlen
);
1110 while (--nshorts
>= 0) {
1113 Printf(" %04x", ntohs(*sp
++));
1118 Printf(" %02x", *(u_char
*)sp
);
1123 #if !defined(IP_HDRINCL) && defined(IP_TTL)
1124 if (setsockopt(sndsock
, IPPROTO_IP
, IP_TTL
,
1125 (char *)&ttl
, sizeof(ttl
)) < 0) {
1126 Fprintf(stderr
, "%s: setsockopt ttl %d: %s\n",
1127 prog
, ttl
, strerror(errno
));
1132 cc
= sendto(sndsock
, (char *)outip
,
1133 packlen
, 0, &whereto
, sizeof(whereto
));
1134 if (cc
< 0 || cc
!= packlen
) {
1136 Fprintf(stderr
, "%s: sendto: %s\n",
1137 prog
, strerror(errno
));
1138 Printf("%s: wrote %s %d chars, ret=%d\n",
1139 prog
, hostname
, packlen
, cc
);
1140 (void)fflush(stdout
);
1144 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
1146 setpolicy(so
, policy
)
1152 buf
= ipsec_set_policy(policy
, strlen(policy
));
1154 warnx("%s", ipsec_strerror());
1157 (void)setsockopt(so
, IPPROTO_IP
, IP_IPSEC_POLICY
,
1158 buf
, ipsec_get_policylen(buf
));
1167 deltaT(struct timeval
*t1p
, struct timeval
*t2p
)
1171 dt
= (double)(t2p
->tv_sec
- t1p
->tv_sec
) * 1000.0 +
1172 (double)(t2p
->tv_usec
- t1p
->tv_usec
) / 1000.0;
1177 * Convert an ICMP "type" field to a printable string.
1180 pr_type(register u_char t
)
1182 static char *ttab
[] = {
1183 "Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable",
1184 "Source Quench", "Redirect", "ICMP 6", "ICMP 7",
1185 "Echo", "ICMP 9", "ICMP 10", "Time Exceeded",
1186 "Param Problem", "Timestamp", "Timestamp Reply", "Info Request",
1191 return("OUT-OF-RANGE");
1197 packet_ok(register u_char
*buf
, int cc
, register struct sockaddr_in
*from
,
1200 register struct icmp
*icp
;
1201 register u_char type
, code
;
1204 register struct ip
*ip
;
1206 ip
= (struct ip
*) buf
;
1207 hlen
= ip
->ip_hl
<< 2;
1208 if (cc
< hlen
+ ICMP_MINLEN
) {
1210 Printf("packet too short (%d bytes) from %s\n", cc
,
1211 inet_ntoa(from
->sin_addr
));
1215 icp
= (struct icmp
*)(buf
+ hlen
);
1217 icp
= (struct icmp
*)buf
;
1219 type
= icp
->icmp_type
;
1220 code
= icp
->icmp_code
;
1221 /* Path MTU Discovery (RFC1191) */
1222 if (code
!= ICMP_UNREACH_NEEDFRAG
)
1225 #ifdef HAVE_ICMP_NEXTMTU
1226 pmtu
= ntohs(icp
->icmp_nextmtu
);
1228 pmtu
= ntohs(((struct my_pmtu
*)&icp
->icmp_void
)->ipm_nextmtu
);
1231 if (type
== ICMP_ECHOREPLY
1232 && proto
->num
== IPPROTO_ICMP
1233 && (*proto
->check
)((u_char
*)icp
, (u_char
)seq
))
1235 if ((type
== ICMP_TIMXCEED
&& code
== ICMP_TIMXCEED_INTRANS
) ||
1236 type
== ICMP_UNREACH
) {
1240 hip
= &icp
->icmp_ip
;
1241 hlen
= hip
->ip_hl
<< 2;
1242 inner
= (u_char
*)((u_char
*)hip
+ hlen
);
1244 && hip
->ip_p
== proto
->num
1245 && (*proto
->check
)(inner
, (u_char
)seq
))
1246 return (type
== ICMP_TIMXCEED
? -1 : code
+ 1);
1251 u_int32_t
*lp
= (u_int32_t
*)&icp
->icmp_ip
;
1253 Printf("\n%d bytes from %s to ", cc
, inet_ntoa(from
->sin_addr
));
1254 Printf("%s: icmp type %d (%s) code %d\n",
1255 inet_ntoa(ip
->ip_dst
), type
, pr_type(type
), icp
->icmp_code
);
1256 for (i
= 4; i
< cc
; i
+= sizeof(*lp
))
1257 Printf("%2d: x%8.8x\n", i
, *lp
++);
1264 icmp_prep(struct outdata
*outdata
)
1266 struct icmp
*const icmpheader
= (struct icmp
*) outp
;
1268 icmpheader
->icmp_type
= ICMP_ECHO
;
1269 icmpheader
->icmp_id
= htons(ident
);
1270 icmpheader
->icmp_seq
= htons(outdata
->seq
);
1271 icmpheader
->icmp_cksum
= 0;
1272 icmpheader
->icmp_cksum
= in_cksum((u_short
*)icmpheader
, protlen
);
1273 if (icmpheader
->icmp_cksum
== 0)
1274 icmpheader
->icmp_cksum
= 0xffff;
1278 icmp_check(const u_char
*data
, int seq
)
1280 struct icmp
*const icmpheader
= (struct icmp
*) data
;
1282 return (icmpheader
->icmp_id
== htons(ident
)
1283 && icmpheader
->icmp_seq
== htons(seq
));
1287 udp_prep(struct outdata
*outdata
)
1289 struct udphdr
*const outudp
= (struct udphdr
*) outp
;
1291 outudp
->uh_sport
= htons(ident
);
1292 outudp
->uh_dport
= htons(port
+ outdata
->seq
);
1293 outudp
->uh_ulen
= htons((u_short
)protlen
);
1296 u_short sum
= p_cksum(outip
, (u_short
*)outudp
, protlen
);
1297 outudp
->uh_sum
= (sum
) ? sum
: 0xffff;
1304 udp_check(const u_char
*data
, int seq
)
1306 struct udphdr
*const udp
= (struct udphdr
*) data
;
1308 return (ntohs(udp
->uh_sport
) == ident
1309 && ntohs(udp
->uh_dport
) == port
+ seq
);
1313 tcp_prep(struct outdata
*outdata
)
1315 struct tcphdr
*const tcp
= (struct tcphdr
*) outp
;
1317 tcp
->th_sport
= htons(ident
);
1318 tcp
->th_dport
= htons(port
+ outdata
->seq
);
1319 tcp
->th_seq
= (tcp
->th_sport
<< 16) | tcp
->th_dport
;
1322 tcp
->th_flags
= TH_SYN
;
1326 u_short sum
= p_cksum(outip
, (u_short
*)tcp
, protlen
);
1327 tcp
->th_sum
= (sum
) ? sum
: 0xffff;
1332 tcp_check(const u_char
*data
, int seq
)
1334 struct tcphdr
*const tcp
= (struct tcphdr
*) data
;
1336 return (ntohs(tcp
->th_sport
) == ident
1337 && ntohs(tcp
->th_dport
) == port
+ seq
);
1341 gre_prep(struct outdata
*outdata
)
1343 struct grehdr
*const gre
= (struct grehdr
*) outp
;
1345 gre
->flags
= htons(0x2001);
1346 gre
->proto
= htons(port
);
1348 gre
->callId
= htons(ident
+ outdata
->seq
);
1352 gre_check(const u_char
*data
, int seq
)
1354 struct grehdr
*const gre
= (struct grehdr
*) data
;
1356 return(ntohs(gre
->proto
) == port
1357 && ntohs(gre
->callId
) == ident
+ seq
);
1361 gen_prep(struct outdata
*outdata
)
1363 u_int16_t
*const ptr
= (u_int16_t
*) outp
;
1365 ptr
[0] = htons(ident
);
1366 ptr
[1] = htons(port
+ outdata
->seq
);
1370 gen_check(const u_char
*data
, int seq
)
1372 u_int16_t
*const ptr
= (u_int16_t
*) data
;
1374 return(ntohs(ptr
[0]) == ident
1375 && ntohs(ptr
[1]) == port
+ seq
);
1379 print(register u_char
*buf
, register int cc
, register struct sockaddr_in
*from
)
1381 register struct ip
*ip
;
1384 ip
= (struct ip
*) buf
;
1385 hlen
= ip
->ip_hl
<< 2;
1389 Printf(" %s", inet_ntoa(from
->sin_addr
));
1391 Printf(" %s (%s)", inetname(from
->sin_addr
),
1392 inet_ntoa(from
->sin_addr
));
1395 Printf(" %d bytes to %s", cc
, inet_ntoa (ip
->ip_dst
));
1399 * Checksum routine for UDP and TCP headers.
1402 p_cksum(struct ip
*ip
, u_short
*data
, int len
)
1404 static struct ipovly ipo
;
1408 ipo
.ih_pr
= ip
->ip_p
;
1409 ipo
.ih_len
= htons(len
);
1410 ipo
.ih_src
= ip
->ip_src
;
1411 ipo
.ih_dst
= ip
->ip_dst
;
1413 sumh
= in_cksum((u_short
*)&ipo
, sizeof(ipo
)); /* pseudo ip hdr cksum */
1414 sumd
= in_cksum((u_short
*)data
, len
); /* payload data cksum */
1415 sumt
= (sumh
<< 16) | (sumd
);
1417 return ~in_cksum((u_short
*)&sumt
, sizeof(sumt
));
1421 * Checksum routine for Internet Protocol family headers (C Version)
1424 in_cksum(register u_short
*addr
, register int len
)
1426 register int nleft
= len
;
1427 register u_short
*w
= addr
;
1428 register u_short answer
;
1429 register int sum
= 0;
1432 * Our algorithm is simple, using a 32 bit accumulator (sum),
1433 * we add sequential 16 bit words to it, and at the end, fold
1434 * back all the carry bits from the top 16 bits into the lower
1442 /* mop up an odd byte, if necessary */
1444 sum
+= *(u_char
*)w
;
1447 * add back carry outs from top 16 bits to low 16 bits
1449 sum
= (sum
>> 16) + (sum
& 0xffff); /* add hi 16 to low 16 */
1450 sum
+= (sum
>> 16); /* add carry */
1451 answer
= ~sum
; /* truncate to 16 bits */
1456 * Subtract 2 timeval structs: out = out - in.
1457 * Out is assumed to be within about LONG_MAX seconds of in.
1460 tvsub(register struct timeval
*out
, register struct timeval
*in
)
1463 if ((out
->tv_usec
-= in
->tv_usec
) < 0) {
1465 out
->tv_usec
+= 1000000;
1467 out
->tv_sec
-= in
->tv_sec
;
1471 * Construct an Internet address representation.
1472 * If the nflag has been supplied, give
1473 * numeric value, otherwise try for symbolic name.
1476 inetname(struct in_addr in
)
1479 register struct hostent
*hp
;
1480 static int first
= 1;
1481 static char domain
[MAXHOSTNAMELEN
+ 1], line
[MAXHOSTNAMELEN
+ 1];
1483 if (first
&& !nflag
) {
1485 if (gethostname(domain
, sizeof(domain
) - 1) < 0)
1488 cp
= strchr(domain
, '.');
1490 hp
= gethostbyname(domain
);
1492 cp
= strchr(hp
->h_name
, '.');
1498 (void)strncpy(domain
, cp
, sizeof(domain
) - 1);
1499 domain
[sizeof(domain
) - 1] = '\0';
1503 if (!nflag
&& in
.s_addr
!= INADDR_ANY
) {
1504 hp
= gethostbyaddr((char *)&in
, sizeof(in
), AF_INET
);
1506 if ((cp
= strchr(hp
->h_name
, '.')) != NULL
&&
1507 strcmp(cp
+ 1, domain
) == 0)
1509 (void)strncpy(line
, hp
->h_name
, sizeof(line
) - 1);
1510 line
[sizeof(line
) - 1] = '\0';
1514 return (inet_ntoa(in
));
1518 gethostinfo(register char *hostname
)
1521 register struct hostent
*hp
;
1522 register struct hostinfo
*hi
;
1524 register u_int32_t addr
, *ap
;
1526 if (strlen(hostname
) > 64) {
1527 Fprintf(stderr
, "%s: hostname \"%.32s...\" is too long\n",
1531 hi
= calloc(1, sizeof(*hi
));
1533 Fprintf(stderr
, "%s: calloc %s\n", prog
, strerror(errno
));
1536 addr
= inet_addr(hostname
);
1537 if ((int32_t)addr
!= -1) {
1538 hi
->name
= strdup(hostname
);
1540 hi
->addrs
= calloc(1, sizeof(hi
->addrs
[0]));
1541 if (hi
->addrs
== NULL
) {
1542 Fprintf(stderr
, "%s: calloc %s\n",
1543 prog
, strerror(errno
));
1546 hi
->addrs
[0] = addr
;
1550 hp
= gethostbyname(hostname
);
1552 Fprintf(stderr
, "%s: unknown host %s\n", prog
, hostname
);
1555 if (hp
->h_addrtype
!= AF_INET
|| hp
->h_length
!= 4) {
1556 Fprintf(stderr
, "%s: bad host %s\n", prog
, hostname
);
1559 hi
->name
= strdup(hp
->h_name
);
1560 for (n
= 0, p
= hp
->h_addr_list
; *p
!= NULL
; ++n
, ++p
)
1563 hi
->addrs
= calloc(n
, sizeof(hi
->addrs
[0]));
1564 if (hi
->addrs
== NULL
) {
1565 Fprintf(stderr
, "%s: calloc %s\n", prog
, strerror(errno
));
1568 for (ap
= hi
->addrs
, p
= hp
->h_addr_list
; *p
!= NULL
; ++ap
, ++p
)
1569 memcpy(ap
, *p
, sizeof(*ap
));
1574 freehostinfo(register struct hostinfo
*hi
)
1576 if (hi
->name
!= NULL
) {
1580 free((char *)hi
->addrs
);
1585 getaddr(register u_int32_t
*ap
, register char *hostname
)
1587 register struct hostinfo
*hi
;
1589 hi
= gethostinfo(hostname
);
1595 setsin(register struct sockaddr_in
*sin
, register u_int32_t addr
)
1598 memset(sin
, 0, sizeof(*sin
));
1599 #ifdef HAVE_SOCKADDR_SA_LEN
1600 sin
->sin_len
= sizeof(*sin
);
1602 sin
->sin_family
= AF_INET
;
1603 sin
->sin_addr
.s_addr
= addr
;
1606 /* String to value with optional min and max. Handles decimal and hex. */
1608 str2val(register const char *str
, register const char *what
,
1609 register int mi
, register int ma
)
1611 register const char *cp
;
1615 if (str
[0] == '0' && (str
[1] == 'x' || str
[1] == 'X')) {
1617 val
= (int)strtol(cp
, &ep
, 16);
1619 val
= (int)strtol(str
, &ep
, 10);
1621 Fprintf(stderr
, "%s: \"%s\" bad value for %s \n",
1625 if (val
< mi
&& mi
>= 0) {
1627 Fprintf(stderr
, "%s: %s must be >= %d\n",
1630 Fprintf(stderr
, "%s: %s must be > %d\n",
1631 prog
, what
, mi
- 1);
1634 if (val
> ma
&& ma
>= 0) {
1635 Fprintf(stderr
, "%s: %s must be <= %d\n", prog
, what
, ma
);
1642 setproto(char *pname
)
1644 struct outproto
*proto
;
1647 for (i
= 0; protos
[i
].name
!= NULL
; i
++) {
1648 if (strcasecmp(protos
[i
].name
, pname
) == 0) {
1653 if (proto
->name
== NULL
) { /* generic handler */
1654 struct protoent
*pe
;
1657 /* Determine the IP protocol number */
1658 if ((pe
= getprotobyname(pname
)) != NULL
)
1661 pnum
= str2val(optarg
, "proto number", 1, 255);
1670 extern char version
[];
1672 Fprintf(stderr
, "Version %s\n", version
);
1674 "Usage: %s [-dFInrSvx] [-g gateway] [-i iface] [-f first_ttl]\n"
1675 "\t[-m max_ttl] [-p port] [-P proto] [-q nqueries] [-s src_addr]\n"
1676 "\t[-t tos] [-w waittime] [-z pausemsecs] host [packetlen]\n", prog
);