1 /*	$OpenBSD: traceroute.c,v 1.61 2004/01/26 18:23:51 deraadt Exp $	*/
2 /*	$NetBSD: traceroute.c,v 1.10 1995/05/21 15:50:45 mycroft Exp $	*/
3 
4 /*-
5  * Copyright (c) 1990, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * Van Jacobson.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  * $DragonFly: src/usr.sbin/traceroute/traceroute.c,v 1.6 2004/12/18 22:48:14 swildner Exp $
36  * @(#)traceroute.c	8.1 (Berkeley) 6/6/93
37  */
38 
39 /*
40  * traceroute host  - trace the route ip packets follow going to "host".
41  *
42  * Attempt to trace the route an ip packet would follow to some
43  * internet host.  We find out intermediate hops by launching probe
44  * packets with a small ttl (time to live) then listening for an
45  * icmp "time exceeded" reply from a gateway.  We start our probes
46  * with a ttl of one and increase by one until we get an icmp "port
47  * unreachable" (which means we got to "host") or hit a max (which
48  * defaults to 64 hops & can be changed with the -m flag).  Three
49  * probes (change with -q flag) are sent at each ttl setting and a
50  * line is printed showing the ttl, address of the gateway and
51  * round trip time of each probe.  If the probe answers come from
52  * different gateways, the address of each responding system will
53  * be printed.  If there is no response within a 5 sec. timeout
54  * interval (changed with the -w flag), a "*" is printed for that
55  * probe.
56  *
57  * Probe packets are UDP format.  We don't want the destination
58  * host to process them so the destination port is set to an
59  * unlikely value (if some clod on the destination is using that
60  * value, it can be changed with the -p flag).
61  *
62  * A sample use might be:
63  *
64  *     [yak 71]% traceroute nis.nsf.net.
65  *     traceroute to nis.nsf.net (35.1.1.48), 64 hops max, 56 byte packet
66  *      1  helios.ee.lbl.gov (128.3.112.1)  19 ms  19 ms  0 ms
67  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
68  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
69  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  39 ms
70  *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  39 ms  39 ms  39 ms
71  *      6  128.32.197.4 (128.32.197.4)  40 ms  59 ms  59 ms
72  *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  59 ms
73  *      8  129.140.70.13 (129.140.70.13)  99 ms  99 ms  80 ms
74  *      9  129.140.71.6 (129.140.71.6)  139 ms  239 ms  319 ms
75  *     10  129.140.81.7 (129.140.81.7)  220 ms  199 ms  199 ms
76  *     11  nic.merit.edu (35.1.1.48)  239 ms  239 ms  239 ms
77  *
78  * Note that lines 2 & 3 are the same.  This is due to a buggy
79  * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
80  * packets with a zero ttl.
81  *
82  * A more interesting example is:
83  *
84  *     [yak 72]% traceroute allspice.lcs.mit.edu.
85  *     traceroute to allspice.lcs.mit.edu (18.26.0.115), 64 hops max
86  *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
87  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  19 ms  19 ms
88  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  19 ms
89  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  19 ms  39 ms  39 ms
90  *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  20 ms  39 ms  39 ms
91  *      6  128.32.197.4 (128.32.197.4)  59 ms  119 ms  39 ms
92  *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  39 ms
93  *      8  129.140.70.13 (129.140.70.13)  80 ms  79 ms  99 ms
94  *      9  129.140.71.6 (129.140.71.6)  139 ms  139 ms  159 ms
95  *     10  129.140.81.7 (129.140.81.7)  199 ms  180 ms  300 ms
96  *     11  129.140.72.17 (129.140.72.17)  300 ms  239 ms  239 ms
97  *     12  * * *
98  *     13  128.121.54.72 (128.121.54.72)  259 ms  499 ms  279 ms
99  *     14  * * *
100  *     15  * * *
101  *     16  * * *
102  *     17  * * *
103  *     18  ALLSPICE.LCS.MIT.EDU (18.26.0.115)  339 ms  279 ms  279 ms
104  *
105  * (I start to see why I'm having so much trouble with mail to
106  * MIT.)  Note that the gateways 12, 14, 15, 16 & 17 hops away
107  * either don't send ICMP "time exceeded" messages or send them
108  * with a ttl too small to reach us.  14 - 17 are running the
109  * MIT C Gateway code that doesn't send "time exceeded"s.  God
110  * only knows what's going on with 12.
111  *
112  * The silent gateway 12 in the above may be the result of a bug in
113  * the 4.[23]BSD network code (and its derivatives):  4.x (x <= 3)
114  * sends an unreachable message using whatever ttl remains in the
115  * original datagram.  Since, for gateways, the remaining ttl is
116  * zero, the icmp "time exceeded" is guaranteed to not make it back
117  * to us.  The behavior of this bug is slightly more interesting
118  * when it appears on the destination system:
119  *
120  *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
121  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  39 ms
122  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  39 ms  19 ms
123  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  19 ms
124  *      5  ccn-nerif35.Berkeley.EDU (128.32.168.35)  39 ms  39 ms  39 ms
125  *      6  csgw.Berkeley.EDU (128.32.133.254)  39 ms  59 ms  39 ms
126  *      7  * * *
127  *      8  * * *
128  *      9  * * *
129  *     10  * * *
130  *     11  * * *
131  *     12  * * *
132  *     13  rip.Berkeley.EDU (128.32.131.22)  59 ms !  39 ms !  39 ms !
133  *
134  * Notice that there are 12 "gateways" (13 is the final
135  * destination) and exactly the last half of them are "missing".
136  * What's really happening is that rip (a Sun-3 running Sun OS3.5)
137  * is using the ttl from our arriving datagram as the ttl in its
138  * icmp reply.  So, the reply will time out on the return path
139  * (with no notice sent to anyone since icmp's aren't sent for
140  * icmp's) until we probe with a ttl that's at least twice the path
141  * length.  I.e., rip is really only 7 hops away.  A reply that
142  * returns with a ttl of 1 is a clue this problem exists.
143  * Traceroute prints a "!" after the time if the ttl is <= 1.
144  * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
145  * non-standard (HPUX) software, expect to see this problem
146  * frequently and/or take care picking the target host of your
147  * probes.
148  *
149  * Other possible annotations after the time are !H, !N, !P (got a host,
150  * network or protocol unreachable, respectively), !S or !F (source
151  * route failed or fragmentation needed -- neither of these should
152  * ever occur and the associated gateway is busted if you see one).  If
153  * almost all the probes result in some kind of unreachable, traceroute
154  * will give up and exit.
155  *
156  * Notes
157  * -----
158  * This program must be run by root or be setuid.  (I suggest that
159  * you *don't* make it setuid -- casual use could result in a lot
160  * of unnecessary traffic on our poor, congested nets.)
161  *
162  * This program requires a kernel mod that does not appear in any
163  * system available from Berkeley:  A raw ip socket using proto
164  * IPPROTO_RAW must interpret the data sent as an ip datagram (as
165  * opposed to data to be wrapped in a ip datagram).  See the README
166  * file that came with the source to this program for a description
167  * of the mods I made to /sys/netinet/raw_ip.c.  Your mileage may
168  * vary.  But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
169  * MODIFIED TO RUN THIS PROGRAM.
170  *
171  * The udp port usage may appear bizarre (well, ok, it is bizarre).
172  * The problem is that an icmp message only contains 8 bytes of
173  * data from the original datagram.  8 bytes is the size of a udp
174  * header so, if we want to associate replies with the original
175  * datagram, the necessary information must be encoded into the
176  * udp header (the ip id could be used but there's no way to
177  * interlock with the kernel's assignment of ip id's and, anyway,
178  * it would have taken a lot more kernel hacking to allow this
179  * code to set the ip id).  So, to allow two or more users to
180  * use traceroute simultaneously, we use this task's pid as the
181  * source port (the high bit is set to move the port number out
182  * of the "likely" range).  To keep track of which probe is being
183  * replied to (so times and/or hop counts don't get confused by a
184  * reply that was delayed in transit), we increment the destination
185  * port number before each probe.
186  *
187  * Don't use this as a coding example.  I was trying to find a
188  * routing problem and this code sort-of popped out after 48 hours
189  * without sleep.  I was amazed it ever compiled, much less ran.
190  *
191  * I stole the idea for this program from Steve Deering.  Since
192  * the first release, I've learned that had I attended the right
193  * IETF working group meetings, I also could have stolen it from Guy
194  * Almes or Matt Mathis.  I don't know (or care) who came up with
195  * the idea first.  I envy the originators' perspicacity and I'm
196  * glad they didn't keep the idea a secret.
197  *
198  * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
199  * enhancements to the original distribution.
200  *
201  * I've hacked up a round-trip-route version of this that works by
202  * sending a loose-source-routed udp datagram through the destination
203  * back to yourself.  Unfortunately, SO many gateways botch source
204  * routing, the thing is almost worthless.  Maybe one day...
205  *
206  *  -- Van Jacobson (van@helios.ee.lbl.gov)
207  *     Tue Dec 20 03:50:13 PST 1988
208  */
209 
210 #include <sys/param.h>
211 #include <sys/time.h>
212 #include <sys/socket.h>
213 #include <sys/file.h>
214 #include <sys/ioctl.h>
215 #include <sys/sysctl.h>
216 
217 #include <netinet/in_systm.h>
218 #include <netinet/in.h>
219 #include <netinet/ip.h>
220 #include <netinet/ip_icmp.h>
221 #include <netinet/ip_var.h>
222 #include <netinet/udp.h>
223 
224 #include <arpa/inet.h>
225 
226 #include <ctype.h>
227 #include <err.h>
228 #include <errno.h>
229 #include <netdb.h>
230 #include <stdio.h>
231 #include <stdlib.h>
232 #include <string.h>
233 #include <unistd.h>
234 
235 #define	MAX_LSRR	((MAX_IPOPTLEN - 4) / 4)
236 
237 /*
238  * Format of the data in a (udp) probe packet.
239  */
240 struct packetdata {
241 	u_char seq;		/* sequence number of this packet */
242 	u_int8_t ttl;		/* ttl packet left with */
243 	u_int32_t sec;		/* time packet left */
244 	u_int32_t usec;
245 };
246 
247 struct in_addr gateway[MAX_LSRR + 1];
248 int lsrrlen = 0;
249 int32_t sec_perturb;
250 int32_t usec_perturb;
251 
252 u_char packet[512], *outpacket;	/* last inbound (icmp) packet */
253 
254 void dump_packet(void);
255 int wait_for_reply(int, struct sockaddr_in *, struct timeval *);
256 void send_probe(int, u_int8_t, int, struct sockaddr_in *);
257 int packet_ok(u_char *, int, struct sockaddr_in *, int, int);
258 const char *pr_type(u_int8_t);
259 void print(u_char *, int, struct sockaddr_in *);
260 char *inetname(struct in_addr);
261 u_short in_cksum(u_short *, int);
262 void usage(void);
263 
264 int s;				/* receive (icmp) socket file descriptor */
265 int sndsock;			/* send (udp) socket file descriptor */
266 
267 int datalen;			/* How much data */
268 int headerlen;			/* How long packet's header is */
269 
270 char *source = 0;
271 char *hostname;
272 
273 int nprobes = 3;
274 u_int8_t max_ttl = IPDEFTTL;
275 u_int8_t first_ttl = 1;
276 u_short ident;
277 u_short port = 32768+666;	/* start udp dest port # for probe packets */
278 u_char	proto = IPPROTO_UDP;
279 u_int8_t  icmp_type = ICMP_ECHO; /* default ICMP code/type */
280 u_char  icmp_code = 0;
281 int options;			/* socket options */
282 int verbose;
283 int waittime = 5;		/* time to wait for response (in seconds) */
284 int nflag;			/* print addresses numerically */
285 int dump;
286 
287 int
288 main(int argc, char *argv[])
289 {
290 	int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
291 	int ttl_flag = 0, incflag = 1, protoset = 0, sump = 0;
292 	int ch, i, lsrr = 0, on = 1, probe, seq = 0, tos = 0;
293 	size_t size = sizeof(max_ttl);
294 	struct sockaddr_in from, to;
295 	struct hostent *hp;
296 	u_int32_t tmprnd;
297 	struct ip *ip;
298 	u_int8_t ttl;
299 	char *ep;
300 	long l;
301 
302 	if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
303 		err(5, "icmp socket");
304 	if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
305 		err(5, "raw socket");
306 
307 	/* revoke privs */
308 	seteuid(getuid());
309 	setuid(getuid());
310 
311 	sysctl(mib, sizeof(mib)/sizeof(mib[0]), &max_ttl, &size, NULL, 0);
312 
313 	while ((ch = getopt(argc, argv, "SDIdg:f:m:np:q:rs:t:w:vlP:c")) != -1)
314 		switch (ch) {
315 		case 'S':
316 			sump = 1;
317 			break;
318 		case 'f':
319 			errno = 0;
320 			ep = NULL;
321 			l = strtol(optarg, &ep, 10);
322 			if (errno || !*optarg || *ep || l < 1 || l > max_ttl)
323 				errx(1, "min ttl must be 1 to %u.", max_ttl);
324 			first_ttl = (u_int8_t)l;
325 			break;
326 		case 'c':
327 			incflag = 0;
328 			break;
329 		case 'd':
330 			options |= SO_DEBUG;
331 			break;
332 		case 'D':
333 			dump = 1;
334 			break;
335 		case 'g':
336 			if (lsrr >= MAX_LSRR)
337 				errx(1, "too many gateways; max %d", MAX_LSRR);
338 			if (inet_aton(optarg, &gateway[lsrr]) == 0) {
339 				hp = gethostbyname(optarg);
340 				if (hp == 0)
341 					errx(1, "unknown host %s", optarg);
342 				memcpy(&gateway[lsrr], hp->h_addr, hp->h_length);
343 			}
344 			if (++lsrr == 1)
345 				lsrrlen = 4;
346 			lsrrlen += 4;
347 			break;
348 		case 'I':
349 			if (protoset)
350 				errx(1, "protocol already set with -P");
351 			protoset = 1;
352 			proto = IPPROTO_ICMP;
353 			break;
354 		case 'l':
355 			ttl_flag++;
356 			break;
357 		case 'm':
358 			errno = 0;
359 			ep = NULL;
360 			l = strtol(optarg, &ep, 10);
361 			if (errno || !*optarg || *ep || l < first_ttl ||
362 			    l > MAXTTL)
363 				errx(1, "max ttl must be %u to %u.", first_ttl,
364 				    MAXTTL);
365 			max_ttl = (u_int8_t)l;
366 			break;
367 		case 'n':
368 			nflag++;
369 			break;
370 		case 'p':
371 			errno = 0;
372 			ep = NULL;
373 			l = strtol(optarg, &ep, 10);
374 			if (errno || !*optarg || *ep || l <= 0 || l >= 65536)
375 				errx(1, "port must be >0, <65536.");
376 			port = (int)l;
377 			break;
378 		case 'P':
379 			if (protoset)
380 				errx(1, "protocol already set with -I");
381 			protoset = 1;
382 			errno = 0;
383 			ep = NULL;
384 			l = strtol(optarg, &ep, 10);
385 			if (errno || !*optarg || *ep || l < 1 ||
386 			    l >= IPPROTO_MAX) {
387 				struct protoent *pent;
388 
389 				pent = getprotobyname(optarg);
390 				if (pent)
391 					proto = pent->p_proto;
392 				else
393 					errx(1, "proto must be >=1, or a name.");
394 			} else
395 				proto = (int)l;
396 			break;
397 		case 'q':
398 			errno = 0;
399 			ep = NULL;
400 			l = strtol(optarg, &ep, 10);
401 			if (errno || !*optarg || *ep || l < 1 || l > INT_MAX)
402 				errx(1, "nprobes must be >0.");
403 			nprobes = (int)l;
404 			break;
405 		case 'r':
406 			options |= SO_DONTROUTE;
407 			break;
408 		case 's':
409 			/*
410 			 * set the ip source address of the outbound
411 			 * probe (e.g., on a multi-homed host).
412 			 */
413 			source = optarg;
414 			break;
415 		case 't':
416 			errno = 0;
417 			ep = NULL;
418 			l = strtol(optarg, &ep, 10);
419 			if (errno || !*optarg || *ep || l < 0 || l > 255)
420 				errx(1, "tos must be 0 to 255.");
421 			tos = (int)l;
422 			break;
423 		case 'v':
424 			verbose++;
425 			break;
426 		case 'w':
427 			errno = 0;
428 			ep = NULL;
429 			l = strtol(optarg, &ep, 10);
430 			if (errno || !*optarg || *ep || l <= 1 || l > INT_MAX)
431 				errx(1, "wait must be >1 sec.");
432 			waittime = (int)l;
433 			break;
434 		default:
435 			usage();
436 		}
437 	argc -= optind;
438 	argv += optind;
439 
440 	if (argc < 1)
441 		usage();
442 
443 	setlinebuf (stdout);
444 
445 	memset(&to, 0, sizeof(struct sockaddr));
446 	to.sin_family = AF_INET;
447 	if (inet_aton(*argv, &to.sin_addr) != 0)
448 		hostname = *argv;
449 	else {
450 		hp = gethostbyname(*argv);
451 		if (hp == 0)
452 			errx(1, "unknown host %s", *argv);
453 		to.sin_family = hp->h_addrtype;
454 		memcpy(&to.sin_addr, hp->h_addr, hp->h_length);
455 		if ((hostname = strdup(hp->h_name)) == NULL)
456 			err(1, "malloc");
457 		if (hp->h_addr_list[1] != NULL)
458 			warnx("Warning: %s has multiple addresses; using %s",
459 			    hostname, inet_ntoa(to.sin_addr));
460 	}
461 	if (*++argv) {
462 		errno = 0;
463 		ep = NULL;
464 		l = strtol(*argv, &ep, 10);
465 		if (errno || !*argv || *ep || l < 0 || l > INT_MAX)
466 			errx(1, "datalen out of range");
467 		datalen = (int)l;
468 	}
469 
470 	switch (proto) {
471 	case IPPROTO_UDP:
472 		headerlen = (sizeof(struct ip) + lsrrlen +
473 		    sizeof(struct udphdr) + sizeof(struct packetdata));
474 		break;
475 	case IPPROTO_ICMP:
476 		headerlen = (sizeof(struct ip) + lsrrlen +
477 		    sizeof(struct icmp) + sizeof(struct packetdata));
478 		break;
479 	default:
480 		headerlen = (sizeof(struct ip) + lsrrlen +
481 		    sizeof(struct packetdata));
482 	}
483 
484 	if (datalen < 0 || datalen > IP_MAXPACKET - headerlen)
485 		errx(1, "packet size must be 0 to %d.",
486 		    IP_MAXPACKET - headerlen);
487 
488 	datalen += headerlen;
489 
490 	outpacket = (u_char *)malloc(datalen);
491 	if (outpacket == NULL)
492 		err(1, "malloc");
493 	memset(outpacket, 0, datalen);
494 
495 	ip = (struct ip *)outpacket;
496 	if (lsrr != 0) {
497 		u_char *p = (u_char *)(ip + 1);
498 
499 		*p++ = IPOPT_NOP;
500 		*p++ = IPOPT_LSRR;
501 		*p++ = lsrrlen - 1;
502 		*p++ = IPOPT_MINOFF;
503 		gateway[lsrr] = to.sin_addr;
504 		for (i = 1; i <= lsrr; i++) {
505 			memcpy(p, &gateway[i], sizeof(struct in_addr));
506 			p += sizeof(struct in_addr);
507 		}
508 		ip->ip_dst = gateway[0];
509 	} else
510 		ip->ip_dst = to.sin_addr;
511 	ip->ip_off = htons(0);
512 	ip->ip_hl = (sizeof(struct ip) + lsrrlen) >> 2;
513 	ip->ip_p = proto;
514 	ip->ip_v = IPVERSION;
515 	ip->ip_tos = tos;
516 
517 	ident = (getpid() & 0xffff) | 0x8000;
518 	tmprnd = arc4random();
519 	sec_perturb = (tmprnd & 0x80000000) ? -(tmprnd & 0x7ff) :
520 	    (tmprnd & 0x7ff);
521 	usec_perturb = arc4random();
522 
523 	if (options & SO_DEBUG)
524 		setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof(on));
525 #ifdef SO_SNDBUF
526 	if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,
527 	    sizeof(datalen)) < 0)
528 		err(6, "SO_SNDBUF");
529 #endif /* SO_SNDBUF */
530 #ifdef IP_HDRINCL
531 	if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
532 	    sizeof(on)) < 0)
533 		err(6, "IP_HDRINCL");
534 #endif /* IP_HDRINCL */
535 	if (options & SO_DEBUG)
536 		setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
537 		    (char *)&on, sizeof(on));
538 	if (options & SO_DONTROUTE)
539 		setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
540 		    (char *)&on, sizeof(on));
541 
542 	if (source) {
543 		memset(&from, 0, sizeof(struct sockaddr));
544 		from.sin_family = AF_INET;
545 		if (inet_aton(source, &from.sin_addr) == 0)
546 			errx(1, "unknown host %s", source);
547 		ip->ip_src = from.sin_addr;
548 		if (getuid() != 0 &&
549 		    (ntohl(from.sin_addr.s_addr) & 0xff000000U) == 0x7f000000U &&
550 		    (ntohl(to.sin_addr.s_addr) & 0xff000000U) != 0x7f000000U)
551 			errx(1, "source is on 127/8, destination is not");
552 
553 		if (getuid() &&
554 		    bind(sndsock, (struct sockaddr *)&from, sizeof(from)) < 0)
555 			err(1, "bind");
556 	}
557 
558 	fprintf(stderr, "traceroute to %s (%s)", hostname,
559 		inet_ntoa(to.sin_addr));
560 	if (source)
561 		fprintf(stderr, " from %s", source);
562 	fprintf(stderr, ", %u hops max, %d byte packets\n", max_ttl, datalen);
563 	fflush(stderr);
564 
565 	if (first_ttl > 1)
566 		printf("Skipping %u intermediate hops\n", first_ttl - 1);
567 
568 	for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
569 		int got_there = 0, unreachable = 0, timeout = 0, loss;
570 		in_addr_t lastaddr = 0;
571 		quad_t dt;
572 
573 		printf("%2u ", ttl);
574 		for (probe = 0, loss = 0; probe < nprobes; ++probe) {
575 			int cc;
576 			struct timeval t1, t2;
577 			int code;
578 
579 			gettimeofday(&t1, NULL);
580 			send_probe(++seq, ttl, incflag, &to);
581 			while ((cc = wait_for_reply(s, &from, &t1))) {
582 				gettimeofday(&t2, NULL);
583 				if (t2.tv_sec - t1.tv_sec > waittime) {
584 					cc = 0;
585 					break;
586 				}
587 				i = packet_ok(packet, cc, &from, seq, incflag);
588 				/* Skip short packet */
589 				if (i == 0)
590 					continue;
591 				if (from.sin_addr.s_addr != lastaddr) {
592 					print(packet, cc, &from);
593 					lastaddr = from.sin_addr.s_addr;
594 				}
595 				dt = (quad_t)(t2.tv_sec - t1.tv_sec) * 1000000 +
596 				    (quad_t)(t2.tv_usec - t1.tv_usec);
597 				printf("  %u", (u_int)(dt / 1000));
598 				if (dt % 1000)
599 					printf(".%u", (u_int)(dt % 1000));
600 				printf(" ms");
601 				ip = (struct ip *)packet;
602 				if (ttl_flag)
603 					printf(" (%u)", ip->ip_ttl);
604 				if (i == -2) {
605 #ifndef ARCHAIC
606 					ip = (struct ip *)packet;
607 					if (ip->ip_ttl <= 1)
608 						printf(" !");
609 #endif
610 					++got_there;
611 					break;
612 				}
613 				/* time exceeded in transit */
614 				if (i == -1)
615 					break;
616 				code = i - 1;
617 				switch (code) {
618 				case ICMP_UNREACH_PORT:
619 #ifndef ARCHAIC
620 					ip = (struct ip *)packet;
621 					if (ip->ip_ttl <= 1)
622 						printf(" !");
623 #endif /* ARCHAIC */
624 					++got_there;
625 					break;
626 				case ICMP_UNREACH_NET:
627 					++unreachable;
628 					printf(" !N");
629 					break;
630 				case ICMP_UNREACH_HOST:
631 					++unreachable;
632 					printf(" !H");
633 					break;
634 				case ICMP_UNREACH_PROTOCOL:
635 					++got_there;
636 					printf(" !P");
637 					break;
638 				case ICMP_UNREACH_NEEDFRAG:
639 					++unreachable;
640 					printf(" !F");
641 					break;
642 				case ICMP_UNREACH_SRCFAIL:
643 					++unreachable;
644 					printf(" !S");
645 					break;
646 				case ICMP_UNREACH_FILTER_PROHIB:
647 					++unreachable;
648 					printf(" !X");
649 					break;
650 				case ICMP_UNREACH_NET_PROHIB: /*misuse*/
651 					++unreachable;
652 					printf(" !A");
653 					break;
654 				case ICMP_UNREACH_HOST_PROHIB:
655 					++unreachable;
656 					printf(" !C");
657 					break;
658 				case ICMP_UNREACH_NET_UNKNOWN:
659 				case ICMP_UNREACH_HOST_UNKNOWN:
660 					++unreachable;
661 					printf(" !U");
662 					break;
663 				case ICMP_UNREACH_ISOLATED:
664 					++unreachable;
665 					printf(" !I");
666 					break;
667 				case ICMP_UNREACH_TOSNET:
668 				case ICMP_UNREACH_TOSHOST:
669 					++unreachable;
670 					printf(" !T");
671 					break;
672 				default:
673 					++unreachable;
674 					printf(" !<%d>", i - 1);
675 					break;
676 				}
677 				break;
678 			}
679 			if (cc == 0) {
680 				printf(" *");
681 				timeout++;
682 				loss++;
683 			}
684 			fflush(stdout);
685 		}
686 		if (sump)
687 			printf(" (%d%% loss)", (loss * 100) / nprobes);
688 		putchar('\n');
689 		if (got_there || (unreachable && (unreachable + timeout) >= nprobes))
690 			break;
691 	}
692 	exit(0);
693 }
694 
695 int
696 wait_for_reply(int sock, struct sockaddr_in *from, struct timeval *sent)
697 {
698 	socklen_t fromlen = sizeof (*from);
699 	struct timeval now, wait;
700 	int cc = 0, fdsn;
701 	fd_set *fdsp;
702 
703 	fdsn = howmany(sock+1, NFDBITS) * sizeof(fd_mask);
704 	if ((fdsp = (fd_set *)malloc(fdsn)) == NULL)
705 		err(1, "malloc");
706 	memset(fdsp, 0, fdsn);
707 	FD_SET(sock, fdsp);
708 	gettimeofday(&now, NULL);
709 	wait.tv_sec = (sent->tv_sec + waittime) - now.tv_sec;
710 	wait.tv_usec =  sent->tv_usec - now.tv_usec;
711 	if (wait.tv_usec < 0) {
712 		wait.tv_usec += 1000000;
713 		wait.tv_sec--;
714 	}
715 	if (wait.tv_sec < 0)
716 		wait.tv_sec = wait.tv_usec = 0;
717 
718 	if (select(sock+1, fdsp, (fd_set *)0, (fd_set *)0, &wait) > 0)
719 		cc = recvfrom(s, (char *)packet, sizeof(packet), 0,
720 		    (struct sockaddr *)from, &fromlen);
721 
722 	free(fdsp);
723 	return (cc);
724 }
725 
726 void
727 dump_packet(void)
728 {
729 	u_char *p;
730 	int i;
731 
732 	fprintf(stderr, "packet data:");
733 	for (p = outpacket, i = 0; i < datalen; i++) {
734 		if ((i % 24) == 0)
735 			fprintf(stderr, "\n ");
736 		fprintf(stderr, " %02x", *p++);
737 	}
738 	fprintf(stderr, "\n");
739 }
740 
741 void
742 send_probe(int seq, u_int8_t ttl, int iflag, struct sockaddr_in *to)
743 {
744 	struct ip *ip = (struct ip *)outpacket;
745 	u_char *p = (u_char *)(ip + 1);
746 	struct udphdr *up = (struct udphdr *)(p + lsrrlen);
747 	struct icmp *icmpp = (struct icmp *)(p + lsrrlen);
748 	struct packetdata *op;
749 	struct timeval tv;
750 	int i;
751 
752 	ip->ip_len = datalen;
753 	ip->ip_ttl = ttl;
754 	ip->ip_id = htons(ident+seq);
755 
756 	switch (proto) {
757 	case IPPROTO_ICMP:
758 		icmpp->icmp_type = icmp_type;
759 		icmpp->icmp_code = icmp_code;
760 		icmpp->icmp_seq = htons(seq);
761 		icmpp->icmp_id = htons(ident);
762 		op = (struct packetdata *)(icmpp + 1);
763 		break;
764 	case IPPROTO_UDP:
765 		up->uh_sport = htons(ident);
766 		if (iflag)
767 			up->uh_dport = htons(port+seq);
768 		else
769 			up->uh_dport = htons(port);
770 		up->uh_ulen = htons((u_short)(datalen - sizeof(struct ip) -
771 		    lsrrlen));
772 		up->uh_sum = 0;
773 		op = (struct packetdata *)(up + 1);
774 		break;
775 	default:
776 		op = (struct packetdata *)(ip + 1);
777 		break;
778 	}
779 	op->seq = seq;
780 	op->ttl = ttl;
781 
782 	/*
783 	 * We don't want hostiles snooping the net to get any useful
784 	 * information about us. Send the timestamp in network byte order,
785 	 * and perturb the timestamp enough that they won't know our
786 	 * real clock ticker. We don't want to perturb the time by too
787 	 * much: being off by a suspiciously large amount might indicate
788 	 * OpenBSD.
789 	 *
790 	 * The timestamps in the packet are currently unused. If future
791 	 * work wants to use them they will have to subtract out the
792 	 * perturbation first.
793 	 */
794 	gettimeofday(&tv, NULL);
795 	op->sec = htonl(tv.tv_sec + sec_perturb);
796 	op->usec = htonl((tv.tv_usec + usec_perturb) % 1000000);
797 
798 	if (proto == IPPROTO_ICMP && icmp_type == ICMP_ECHO) {
799 		icmpp->icmp_cksum = 0;
800 		icmpp->icmp_cksum = in_cksum((u_short *)icmpp,
801 		    datalen - sizeof(struct ip) - lsrrlen);
802 		if (icmpp->icmp_cksum == 0)
803 			icmpp->icmp_cksum = 0xffff;
804 	}
805 
806 	if (dump)
807 		dump_packet();
808 
809 	i = sendto(sndsock, outpacket, datalen, 0, (struct sockaddr *)to,
810 	    sizeof(struct sockaddr_in));
811 	if (i < 0 || i != datalen)  {
812 		if (i < 0)
813 			perror("sendto");
814 		printf("traceroute: wrote %s %d chars, ret=%d\n", hostname,
815 		    datalen, i);
816 		fflush(stdout);
817 	}
818 }
819 
820 static const char *ttab[] = {
821 	"Echo Reply",
822 	"ICMP 1",
823 	"ICMP 2",
824 	"Dest Unreachable",
825 	"Source Quench",
826 	"Redirect",
827 	"ICMP 6",
828 	"ICMP 7",
829 	"Echo",
830 	"Router Advert",
831 	"Router Solicit",
832 	"Time Exceeded",
833 	"Param Problem",
834 	"Timestamp",
835 	"Timestamp Reply",
836 	"Info Request",
837 	"Info Reply",
838 	"Mask Request",
839 	"Mask Reply"
840 };
841 
842 /*
843  * Convert an ICMP "type" field to a printable string.
844  */
845 const char *
846 pr_type(u_int8_t t)
847 {
848 	if (t > 18)
849 		return ("OUT-OF-RANGE");
850 	return (ttab[t]);
851 }
852 
853 int
854 packet_ok(u_char *buf, int cc, struct sockaddr_in *from, int seq, int iflag)
855 {
856 	struct icmp *icp;
857 	u_char code;
858 	u_int8_t type;
859 	int hlen;
860 #ifndef ARCHAIC
861 	struct ip *ip;
862 
863 	ip = (struct ip *) buf;
864 	hlen = ip->ip_hl << 2;
865 	if (cc < hlen + ICMP_MINLEN) {
866 		if (verbose)
867 			printf("packet too short (%d bytes) from %s\n", cc,
868 			    inet_ntoa(from->sin_addr));
869 		return (0);
870 	}
871 	cc -= hlen;
872 	icp = (struct icmp *)(buf + hlen);
873 #else
874 	icp = (struct icmp *)buf;
875 #endif /* ARCHAIC */
876 	type = icp->icmp_type;
877 	code = icp->icmp_code;
878 	if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
879 	    type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
880 		struct ip *hip;
881 		struct udphdr *up;
882 		struct icmp *icmpp;
883 
884 		hip = &icp->icmp_ip;
885 		hlen = hip->ip_hl << 2;
886 
887 		switch (proto) {
888 		case IPPROTO_ICMP:
889 			if (icmp_type == ICMP_ECHO &&
890 			    type == ICMP_ECHOREPLY &&
891 			    icp->icmp_id == htons(ident) &&
892 			    icp->icmp_seq == htons(seq))
893 				return (-2); /* we got there */
894 
895 			icmpp = (struct icmp *)((u_char *)hip + hlen);
896 			if (hlen + 8 <= cc && hip->ip_p == IPPROTO_ICMP &&
897 			    icmpp->icmp_id == htons(ident) &&
898 			    icmpp->icmp_seq == htons(seq))
899 				return (type == ICMP_TIMXCEED? -1 : code + 1);
900 			break;
901 
902 		case IPPROTO_UDP:
903 			up = (struct udphdr *)((u_char *)hip + hlen);
904 			if (hlen + 12 <= cc && hip->ip_p == proto &&
905 			    up->uh_sport == htons(ident) &&
906 			    ((iflag && up->uh_dport == htons(port + seq)) ||
907 			    (!iflag && up->uh_dport == htons(port))))
908 				return (type == ICMP_TIMXCEED? -1 : code + 1);
909 			break;
910 		default:
911 			/* this is some odd, user specified proto,
912 			 * how do we check it?
913 			 */
914 			if (hip->ip_p == proto)
915 				return (type == ICMP_TIMXCEED? -1 : code + 1);
916 		}
917 	}
918 #ifndef ARCHAIC
919 	if (verbose) {
920 		int i;
921 		in_addr_t *lp = (in_addr_t *)&icp->icmp_ip;
922 
923 		printf("\n%d bytes from %s", cc, inet_ntoa(from->sin_addr));
924 		printf(" to %s", inet_ntoa(ip->ip_dst));
925 		printf(": icmp type %u (%s) code %d\n", type, pr_type(type),
926 		    icp->icmp_code);
927 		for (i = 4; i < cc ; i += sizeof(in_addr_t))
928 			printf("%2d: x%8.8lx\n", i, (unsigned long)*lp++);
929 	}
930 #endif /* ARCHAIC */
931 	return (0);
932 }
933 
934 void
935 print(u_char *buf, int cc, struct sockaddr_in *from)
936 {
937 	struct ip *ip;
938 	int hlen;
939 
940 	ip = (struct ip *) buf;
941 	hlen = ip->ip_hl << 2;
942 	cc -= hlen;
943 
944 	if (nflag)
945 		printf(" %s", inet_ntoa(from->sin_addr));
946 	else
947 		printf(" %s (%s)", inetname(from->sin_addr),
948 		    inet_ntoa(from->sin_addr));
949 
950 	if (verbose)
951 		printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
952 }
953 
954 
955 /*
956  * Checksum routine for Internet Protocol family headers (C Version)
957  */
958 u_short
959 in_cksum(u_short *addr, int len)
960 {
961 	u_short *w = addr, answer;
962 	int nleft = len, sum = 0;
963 
964 	/*
965 	 *  Our algorithm is simple, using a 32 bit accumulator (sum),
966 	 *  we add sequential 16 bit words to it, and at the end, fold
967 	 *  back all the carry bits from the top 16 bits into the lower
968 	 *  16 bits.
969 	 */
970 	while (nleft > 1)  {
971 		sum += *w++;
972 		nleft -= 2;
973 	}
974 
975 	/* mop up an odd byte, if necessary */
976 	if (nleft == 1)
977 		sum += *(u_char *)w;
978 
979 	/*
980 	 * add back carry outs from top 16 bits to low 16 bits
981 	 */
982 	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
983 	sum += (sum >> 16);			/* add carry */
984 	answer = ~sum;				/* truncate to 16 bits */
985 	return (answer);
986 }
987 
988 /*
989  * Construct an Internet address representation.
990  * If the nflag has been supplied, give
991  * numeric value, otherwise try for symbolic name.
992  */
993 char *
994 inetname(struct in_addr in)
995 {
996 	static char domain[MAXHOSTNAMELEN], line[MAXHOSTNAMELEN];
997 	static int first = 1;
998 	struct hostent *hp;
999 	char *cp;
1000 
1001 	if (first && !nflag) {
1002 		first = 0;
1003 		if (gethostname(domain, sizeof domain) == 0 &&
1004 		    (cp = strchr(domain, '.')) != NULL) {
1005 			strlcpy(domain, cp + 1, sizeof(domain));
1006 		}
1007 	}
1008 	if (!nflag && in.s_addr != INADDR_ANY) {
1009 		hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
1010 		if (hp != NULL) {
1011 			if ((cp = strchr(hp->h_name, '.')) != NULL &&
1012 			    strcmp(cp + 1, domain) == 0)
1013 				*cp = '\0';
1014 			strlcpy(line, hp->h_name, sizeof(line));
1015 			return (line);
1016 		}
1017 	}
1018 	return (inet_ntoa(in));
1019 }
1020 
1021 void
1022 usage(void)
1023 {
1024 	fprintf(stderr,
1025 	    "usage: %s [-cdDIlnrSv] [-f first_ttl] [-g gateway_addr] [-m max_ttl]\n"
1026 	    "\t[-p port] [-P proto] [-q nqueries] [-s src_addr] [-t tos]\n"
1027 	    "\t[-w waittime] host [packetsize]\n", getprogname());
1028 	exit(1);
1029 }
1030