xref: /netbsd-src/usr.sbin/traceroute/traceroute.c (revision fad4c9f71477ae11cea2ee75ec82151ac770a534)
1 /*	$NetBSD: traceroute.c,v 1.65 2006/05/31 20:23:52 rpaulo Exp $	*/
2 
3 /*
4  * Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996, 1997
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that: (1) source code distributions
9  * retain the above copyright notice and this paragraph in its entirety, (2)
10  * distributions including binary code include the above copyright notice and
11  * this paragraph in its entirety in the documentation or other materials
12  * provided with the distribution, and (3) all advertising materials mentioning
13  * features or use of this software display the following acknowledgement:
14  * ``This product includes software developed by the University of California,
15  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16  * the University nor the names of its contributors may be used to endorse
17  * or promote products derived from this software without specific prior
18  * written permission.
19  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22  */
23 
24 #include <sys/cdefs.h>
25 #ifndef lint
26 #if 0
27 static const char rcsid[] =
28     "@(#)Header: traceroute.c,v 1.49 97/06/13 02:30:23 leres Exp  (LBL)";
29 #else
30 __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996, 1997\n\
31 The Regents of the University of California.  All rights reserved.\n");
32 __RCSID("$NetBSD: traceroute.c,v 1.65 2006/05/31 20:23:52 rpaulo Exp $");
33 #endif
34 #endif
35 
36 /*
37  * traceroute host  - trace the route ip packets follow going to "host".
38  *
39  * Attempt to trace the route an ip packet would follow to some
40  * internet host.  We find out intermediate hops by launching probe
41  * packets with a small ttl (time to live) then listening for an
42  * icmp "time exceeded" reply from a gateway.  We start our probes
43  * with a ttl of one and increase by one until we get an icmp "port
44  * unreachable" (which means we got to "host") or hit a max (which
45  * defaults to 30 hops & can be changed with the -m flag).  Three
46  * probes (change with -q flag) are sent at each ttl setting and a
47  * line is printed showing the ttl, address of the gateway and
48  * round trip time of each probe.  If the probe answers come from
49  * different gateways, the address of each responding system will
50  * be printed.  If there is no response within a 5 sec. timeout
51  * interval (changed with the -w flag), a "*" is printed for that
52  * probe.
53  *
54  * Probe packets are UDP format.  We don't want the destination
55  * host to process them so the destination port is set to an
56  * unlikely value (if some clod on the destination is using that
57  * value, it can be changed with the -p flag).
58  *
59  * A sample use might be:
60  *
61  *     [yak 71]% traceroute nis.nsf.net.
62  *     traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 56 byte packet
63  *      1  helios.ee.lbl.gov (128.3.112.1)  19 ms  19 ms  0 ms
64  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
65  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
66  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  39 ms
67  *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  39 ms  39 ms  39 ms
68  *      6  128.32.197.4 (128.32.197.4)  40 ms  59 ms  59 ms
69  *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  59 ms
70  *      8  129.140.70.13 (129.140.70.13)  99 ms  99 ms  80 ms
71  *      9  129.140.71.6 (129.140.71.6)  139 ms  239 ms  319 ms
72  *     10  129.140.81.7 (129.140.81.7)  220 ms  199 ms  199 ms
73  *     11  nic.merit.edu (35.1.1.48)  239 ms  239 ms  239 ms
74  *
75  * Note that lines 2 & 3 are the same.  This is due to a buggy
76  * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
77  * packets with a zero ttl.
78  *
79  * A more interesting example is:
80  *
81  *     [yak 72]% traceroute allspice.lcs.mit.edu.
82  *     traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max
83  *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
84  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  19 ms  19 ms
85  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  19 ms
86  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  19 ms  39 ms  39 ms
87  *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  20 ms  39 ms  39 ms
88  *      6  128.32.197.4 (128.32.197.4)  59 ms  119 ms  39 ms
89  *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  39 ms
90  *      8  129.140.70.13 (129.140.70.13)  80 ms  79 ms  99 ms
91  *      9  129.140.71.6 (129.140.71.6)  139 ms  139 ms  159 ms
92  *     10  129.140.81.7 (129.140.81.7)  199 ms  180 ms  300 ms
93  *     11  129.140.72.17 (129.140.72.17)  300 ms  239 ms  239 ms
94  *     12  * * *
95  *     13  128.121.54.72 (128.121.54.72)  259 ms  499 ms  279 ms
96  *     14  * * *
97  *     15  * * *
98  *     16  * * *
99  *     17  * * *
100  *     18  ALLSPICE.LCS.MIT.EDU (18.26.0.115)  339 ms  279 ms  279 ms
101  *
102  * (I start to see why I'm having so much trouble with mail to
103  * MIT.)  Note that the gateways 12, 14, 15, 16 & 17 hops away
104  * either don't send ICMP "time exceeded" messages or send them
105  * with a ttl too small to reach us.  14 - 17 are running the
106  * MIT C Gateway code that doesn't send "time exceeded"s.  God
107  * only knows what's going on with 12.
108  *
109  * The silent gateway 12 in the above may be the result of a bug in
110  * the 4.[23]BSD network code (and its derivatives):  4.x (x <= 3)
111  * sends an unreachable message using whatever ttl remains in the
112  * original datagram.  Since, for gateways, the remaining ttl is
113  * zero, the icmp "time exceeded" is guaranteed to not make it back
114  * to us.  The behavior of this bug is slightly more interesting
115  * when it appears on the destination system:
116  *
117  *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
118  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  39 ms
119  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  39 ms  19 ms
120  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  19 ms
121  *      5  ccn-nerif35.Berkeley.EDU (128.32.168.35)  39 ms  39 ms  39 ms
122  *      6  csgw.Berkeley.EDU (128.32.133.254)  39 ms  59 ms  39 ms
123  *      7  * * *
124  *      8  * * *
125  *      9  * * *
126  *     10  * * *
127  *     11  * * *
128  *     12  * * *
129  *     13  rip.Berkeley.EDU (128.32.131.22)  59 ms !  39 ms !  39 ms !
130  *
131  * Notice that there are 12 "gateways" (13 is the final
132  * destination) and exactly the last half of them are "missing".
133  * What's really happening is that rip (a Sun-3 running Sun OS3.5)
134  * is using the ttl from our arriving datagram as the ttl in its
135  * icmp reply.  So, the reply will time out on the return path
136  * (with no notice sent to anyone since icmp's aren't sent for
137  * icmp's) until we probe with a ttl that's at least twice the path
138  * length.  I.e., rip is really only 7 hops away.  A reply that
139  * returns with a ttl of 1 is a clue this problem exists.
140  * Traceroute prints a "!" after the time if the ttl is <= 1.
141  * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
142  * non-standard (HPUX) software, expect to see this problem
143  * frequently and/or take care picking the target host of your
144  * probes.
145  *
146  * Other possible annotations after the time are !H, !N, !P (got a host,
147  * network or protocol unreachable, respectively), !S or !F (source
148  * route failed or fragmentation needed -- neither of these should
149  * ever occur and the associated gateway is busted if you see one).  If
150  * almost all the probes result in some kind of unreachable, traceroute
151  * will give up and exit.
152  *
153  * Notes
154  * -----
155  * This program must be run by root or be setuid.  (I suggest that
156  * you *don't* make it setuid -- casual use could result in a lot
157  * of unnecessary traffic on our poor, congested nets.)
158  *
159  * This program requires a kernel mod that does not appear in any
160  * system available from Berkeley:  A raw ip socket using proto
161  * IPPROTO_RAW must interpret the data sent as an ip datagram (as
162  * opposed to data to be wrapped in a ip datagram).  See the README
163  * file that came with the source to this program for a description
164  * of the mods I made to /sys/netinet/raw_ip.c.  Your mileage may
165  * vary.  But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
166  * MODIFIED TO RUN THIS PROGRAM.
167  *
168  * The udp port usage may appear bizarre (well, ok, it is bizarre).
169  * The problem is that an icmp message only contains 8 bytes of
170  * data from the original datagram.  8 bytes is the size of a udp
171  * header so, if we want to associate replies with the original
172  * datagram, the necessary information must be encoded into the
173  * udp header (the ip id could be used but there's no way to
174  * interlock with the kernel's assignment of ip id's and, anyway,
175  * it would have taken a lot more kernel hacking to allow this
176  * code to set the ip id).  So, to allow two or more users to
177  * use traceroute simultaneously, we use this task's pid as the
178  * source port (the high bit is set to move the port number out
179  * of the "likely" range).  To keep track of which probe is being
180  * replied to (so times and/or hop counts don't get confused by a
181  * reply that was delayed in transit), we increment the destination
182  * port number before each probe.
183  *
184  * Don't use this as a coding example.  I was trying to find a
185  * routing problem and this code sort-of popped out after 48 hours
186  * without sleep.  I was amazed it ever compiled, much less ran.
187  *
188  * I stole the idea for this program from Steve Deering.  Since
189  * the first release, I've learned that had I attended the right
190  * IETF working group meetings, I also could have stolen it from Guy
191  * Almes or Matt Mathis.  I don't know (or care) who came up with
192  * the idea first.  I envy the originators' perspicacity and I'm
193  * glad they didn't keep the idea a secret.
194  *
195  * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
196  * enhancements to the original distribution.
197  *
198  * I've hacked up a round-trip-route version of this that works by
199  * sending a loose-source-routed udp datagram through the destination
200  * back to yourself.  Unfortunately, SO many gateways botch source
201  * routing, the thing is almost worthless.  Maybe one day...
202  *
203  *  -- Van Jacobson (van@ee.lbl.gov)
204  *     Tue Dec 20 03:50:13 PST 1988
205  */
206 
207 #include <sys/param.h>
208 #include <sys/file.h>
209 #include <sys/ioctl.h>
210 #include <sys/socket.h>
211 #include <sys/time.h>
212 #include <sys/sysctl.h>
213 
214 #include <netinet/in_systm.h>
215 #include <netinet/in.h>
216 #include <netinet/ip.h>
217 #include <netinet/ip_var.h>
218 #include <netinet/ip_icmp.h>
219 #include <netinet/udp.h>
220 #include <netinet/udp_var.h>
221 
222 #include <arpa/inet.h>
223 
224 #include <ctype.h>
225 #include <errno.h>
226 #ifdef HAVE_MALLOC_H
227 #include <malloc.h>
228 #endif
229 #include <memory.h>
230 #include <netdb.h>
231 #include <stdio.h>
232 #include <stdlib.h>
233 #include <string.h>
234 #include <unistd.h>
235 #include <poll.h>
236 #ifdef IPSEC
237 #include <net/route.h>
238 #include <netinet6/ipsec.h>
239 #endif
240 
241 #include "gnuc.h"
242 #ifdef HAVE_OS_PROTO_H
243 #include "os-proto.h"
244 #endif
245 
246 #include "ifaddrlist.h"
247 #include "as.h"
248 
249 /* Maximum number of gateways (include room for one noop) */
250 #define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(u_int32_t)))
251 
252 #ifndef MAXHOSTNAMELEN
253 #define MAXHOSTNAMELEN	64
254 #endif
255 
256 #define Fprintf (void)fprintf
257 #define Printf (void)printf
258 
259 /* Host name and address list */
260 struct hostinfo {
261 	char *name;
262 	int n;
263 	u_int32_t *addrs;
264 };
265 
266 /* Data section of the probe packet */
267 struct outdata {
268 	u_char seq;		/* sequence number of this packet */
269 	u_char ttl;		/* ttl packet left with */
270 	struct timeval tv;	/* time packet left */
271 };
272 
273 /*
274  * Support for ICMP extensions
275  *
276  * http://www.ietf.org/proceedings/01aug/I-D/draft-ietf-mpls-icmp-02.txt
277  */
278 #define ICMP_EXT_OFFSET    8 /* ICMP type, code, checksum, unused */ + \
279                          128 /* original datagram */
280 #define ICMP_EXT_VERSION 2
281 /*
282  * ICMP extensions, common header
283  */
284 struct icmp_ext_cmn_hdr {
285 #if BYTE_ORDER == BIG_ENDIAN
286 	unsigned char   version:4;
287 	unsigned char   reserved1:4;
288 #else
289 	unsigned char   reserved1:4;
290 	unsigned char   version:4;
291 #endif
292 	unsigned char   reserved2;
293 	unsigned short  checksum;
294 };
295 
296 /*
297  * ICMP extensions, object header
298  */
299 struct icmp_ext_obj_hdr {
300     u_short length;
301     u_char  class_num;
302 #define MPLS_STACK_ENTRY_CLASS 1
303     u_char  c_type;
304 #define MPLS_STACK_ENTRY_C_TYPE 1
305 };
306 
307 struct mpls_header {
308 #if BYTE_ORDER == BIG_ENDIAN
309 	 uint32_t	label:20;
310 	 unsigned char  exp:3;
311 	 unsigned char  s:1;
312 	 unsigned char  ttl:8;
313 #else
314 	 unsigned char  ttl:8;
315 	 unsigned char  s:1;
316 	 unsigned char  exp:3;
317 	 uint32_t	label:20;
318 #endif
319 };
320 
321 u_char	packet[512];		/* last inbound (icmp) packet */
322 
323 struct ip *outip;		/* last output (udp) packet */
324 struct udphdr *outudp;		/* last output (udp) packet */
325 void *outmark;			/* packed location of struct outdata */
326 struct outdata outsetup;	/* setup and copy for alignment */
327 
328 struct icmp *outicmp;		/* last output (icmp) packet */
329 
330 /* loose source route gateway list (including room for final destination) */
331 u_int32_t gwlist[NGATEWAYS + 1];
332 
333 int s;				/* receive (icmp) socket file descriptor */
334 int sndsock;			/* send (udp/icmp) socket file descriptor */
335 
336 struct sockaddr whereto;	/* Who to try to reach */
337 struct sockaddr_in wherefrom;	/* Who we are */
338 int packlen;			/* total length of packet */
339 int minpacket;			/* min ip packet size */
340 int maxpacket = 32 * 1024;	/* max ip packet size */
341 int printed_ttl = 0;
342 
343 char *prog;
344 char *source;
345 char *hostname;
346 char *device;
347 
348 int nprobes = 3;
349 int max_ttl = 30;
350 int first_ttl = 1;
351 u_int16_t ident;
352 in_port_t port = 32768 + 666;	/* start udp dest port # for probe packets */
353 
354 int options;			/* socket options */
355 int verbose;
356 int waittime = 5;		/* time to wait for response (in seconds) */
357 int nflag;			/* print addresses numerically */
358 int dump;
359 int Mflag;			/* show MPLS labels if any */
360 int as_path;			/* print as numbers for each hop */
361 char *as_server = NULL;
362 void *asn;
363 int useicmp;			/* use icmp echo instead of udp packets */
364 #ifdef CANT_HACK_CKSUM
365 int docksum = 0;		/* don't calculate checksums */
366 #else
367 int docksum = 1;		/* calculate checksums */
368 #endif
369 int optlen;			/* length of ip options */
370 
371 int mtus[] = {
372         17914,
373          8166,
374          4464,
375          4352,
376          2048,
377          2002,
378          1536,
379          1500,
380          1492,
381 	 1480,
382 	 1280,
383          1006,
384           576,
385           552,
386           544,
387           512,
388           508,
389           296,
390            68,
391             0
392 };
393 int *mtuptr = &mtus[0];
394 int mtudisc = 0;
395 int nextmtu;   /* from ICMP error, set by packet_ok(), might be 0 */
396 
397 extern int optind;
398 extern int opterr;
399 extern char *optarg;
400 
401 /* Forwards */
402 double	deltaT(struct timeval *, struct timeval *);
403 void	freehostinfo(struct hostinfo *);
404 void	getaddr(u_int32_t *, char *);
405 struct	hostinfo *gethostinfo(char *);
406 u_int16_t in_cksum(u_int16_t *, int);
407 u_int16_t in_cksum2(u_int16_t, u_int16_t *, int);
408 char	*inetname(struct in_addr);
409 int	main(int, char **);
410 int	packet_ok(u_char *, int, struct sockaddr_in *, int);
411 char	*pr_type(u_char);
412 void	print(u_char *, int, struct sockaddr_in *);
413 void	resize_packet(void);
414 void	dump_packet(void);
415 void	send_probe(int, int, struct timeval *);
416 void	setsin(struct sockaddr_in *, u_int32_t);
417 int	str2val(const char *, const char *, int, int);
418 void	tvsub(struct timeval *, struct timeval *);
419 __dead	void usage(void);
420 int	wait_for_reply(int, struct sockaddr_in *, struct timeval *);
421 void	decode_extensions(unsigned char *buf, int ip_len);
422 void	frag_err(void);
423 int	find_local_ip(struct sockaddr_in *, struct sockaddr_in *);
424 #ifdef IPSEC
425 #ifdef IPSEC_POLICY_IPSEC
426 int	setpolicy(int so, char *policy);
427 #endif
428 #endif
429 
430 int
431 main(int argc, char **argv)
432 {
433 	int op, code, n;
434 	char *cp;
435 	u_char *outp;
436 	u_int32_t *ap;
437 	struct sockaddr_in *from = &wherefrom;
438 	struct sockaddr_in *to = (struct sockaddr_in *)&whereto;
439 	struct hostinfo *hi;
440 	int on = 1;
441 	int ttl, probe, i;
442 	int seq = 0;
443 	int tos = 0, settos = 0, ttl_flag = 0;
444 	int lsrr = 0;
445 	u_int16_t off = 0;
446 	struct ifaddrlist *al, *al2;
447 	char errbuf[132];
448 	int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
449 	size_t size = sizeof(max_ttl);
450 
451 	(void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &max_ttl, &size,
452 	    NULL, 0);
453 
454 	if ((cp = strrchr(argv[0], '/')) != NULL)
455 		prog = cp + 1;
456 	else
457 		prog = argv[0];
458 
459 	opterr = 0;
460 	while ((op = getopt(argc, argv, "aA:dDFPIMnlrvxf:g:i:m:p:q:s:t:w:")) != -1)
461 		switch (op) {
462 
463 		case 'a':
464 			as_path = 1;
465 			break;
466 
467 		case 'A':
468 			as_path = 1;
469 			as_server = optarg;
470 			break;
471 
472 		case 'd':
473 			options |= SO_DEBUG;
474 			break;
475 
476 		case 'D':
477 			dump = 1;
478 			break;
479 
480 		case 'f':
481 			first_ttl = str2val(optarg, "first ttl", 1, 255);
482 			break;
483 
484 		case 'F':
485 			off = IP_DF;
486 			break;
487 
488 		case 'g':
489 			if (lsrr >= NGATEWAYS) {
490 				Fprintf(stderr,
491 				    "%s: No more than %d gateways\n",
492 				    prog, NGATEWAYS);
493 				exit(1);
494 			}
495 			getaddr(gwlist + lsrr, optarg);
496 			++lsrr;
497 			break;
498 
499 		case 'i':
500 			device = optarg;
501 			break;
502 
503 		case 'I':
504 			++useicmp;
505 			break;
506 
507 		case 'l':
508 			++ttl_flag;
509 			break;
510 
511 		case 'm':
512 			max_ttl = str2val(optarg, "max ttl", 1, 255);
513 			break;
514 
515 		case 'M':
516 			Mflag = 1;
517 			break;
518 
519 		case 'n':
520 			++nflag;
521 			break;
522 
523 		case 'p':
524 			port = str2val(optarg, "port", 1, -1);
525 			break;
526 
527 		case 'q':
528 			nprobes = str2val(optarg, "nprobes", 1, -1);
529 			break;
530 
531 		case 'r':
532 			options |= SO_DONTROUTE;
533 			break;
534 
535 		case 's':
536 			/*
537 			 * set the ip source address of the outbound
538 			 * probe (e.g., on a multi-homed host).
539 			 */
540 			source = optarg;
541 			break;
542 
543 		case 't':
544 			tos = str2val(optarg, "tos", 0, 255);
545 			++settos;
546 			break;
547 
548 		case 'v':
549 			++verbose;
550 			break;
551 
552 		case 'x':
553 			docksum = (docksum == 0);
554 			break;
555 
556 		case 'w':
557 			waittime = str2val(optarg, "wait time", 2, 24 * 3600);
558 			break;
559 
560 		case 'P':
561 			off = IP_DF;
562 			mtudisc = 1;
563 			break;
564 
565 		default:
566 			usage();
567 		}
568 
569 	if (first_ttl > max_ttl) {
570 		Fprintf(stderr,
571 		    "%s: first ttl (%d) may not be greater than max ttl (%d)\n",
572 		    prog, first_ttl, max_ttl);
573 		exit(1);
574 	}
575 
576 	if (!docksum)
577 		Fprintf(stderr, "%s: Warning: ckecksums disabled\n", prog);
578 
579 	if (lsrr > 0)
580 		optlen = (lsrr + 1) * sizeof(gwlist[0]);
581 	minpacket = sizeof(*outip) + sizeof(struct outdata) + optlen;
582 	if (useicmp)
583 		minpacket += 8;			/* XXX magic number */
584 	else
585 		minpacket += sizeof(*outudp);
586 	if (packlen == 0)
587 		packlen = minpacket;		/* minimum sized packet */
588 	else if (minpacket > packlen || packlen > maxpacket) {
589 		Fprintf(stderr, "%s: packet size must be %d <= s <= %d\n",
590 		    prog, minpacket, maxpacket);
591 		exit(1);
592 	}
593 
594 	if (mtudisc)
595 		packlen = *mtuptr++;
596 
597 	/* Process destination and optional packet size */
598 	switch (argc - optind) {
599 
600 	case 2:
601 		packlen = str2val(argv[optind + 1],
602 		    "packet length", minpacket, -1);
603 		/* Fall through */
604 
605 	case 1:
606 		hostname = argv[optind];
607 		hi = gethostinfo(hostname);
608 		setsin(to, hi->addrs[0]);
609 		if (hi->n > 1)
610 			Fprintf(stderr,
611 		    "%s: Warning: %s has multiple addresses; using %s\n",
612 				prog, hostname, inet_ntoa(to->sin_addr));
613 		hostname = hi->name;
614 		hi->name = NULL;
615 		freehostinfo(hi);
616 		break;
617 
618 	default:
619 		usage();
620 	}
621 
622 #ifdef HAVE_SETLINEBUF
623 	setlinebuf (stdout);
624 #else
625 	setvbuf(stdout, NULL, _IOLBF, 0);
626 #endif
627 
628 	outip = (struct ip *)malloc((unsigned)packlen);
629 	if (outip == NULL) {
630 		Fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno));
631 		exit(1);
632 	}
633 	memset((char *)outip, 0, packlen);
634 
635 	outip->ip_v = IPVERSION;
636 	if (settos)
637 		outip->ip_tos = tos;
638 #ifdef BYTESWAP_IP_LEN
639 	outip->ip_len = htons(packlen);
640 #else
641 	outip->ip_len = packlen;
642 #endif
643 	outip->ip_off = off;
644 	outp = (u_char *)(outip + 1);
645 #ifdef HAVE_RAW_OPTIONS
646 	if (lsrr > 0) {
647 		u_char *optlist;
648 
649 		optlist = outp;
650 		outp += optlen;
651 
652 		/* final hop */
653 		gwlist[lsrr] = to->sin_addr.s_addr;
654 
655 		outip->ip_dst.s_addr = gwlist[0];
656 
657 		/* force 4 byte alignment */
658 		optlist[0] = IPOPT_NOP;
659 		/* loose source route option */
660 		optlist[1] = IPOPT_LSRR;
661 		i = lsrr * sizeof(gwlist[0]);
662 		optlist[2] = i + 3;
663 		/* Pointer to LSRR addresses */
664 		optlist[3] = IPOPT_MINOFF;
665 		memcpy(optlist + 4, gwlist + 1, i);
666 	} else
667 #endif
668 		outip->ip_dst = to->sin_addr;
669 
670 	outip->ip_hl = (outp - (u_char *)outip) >> 2;
671 	ident = htons(arc4random() & 0xffff) | 0x8000;
672 	if (useicmp) {
673 		outip->ip_p = IPPROTO_ICMP;
674 
675 		outicmp = (struct icmp *)outp;
676 		outicmp->icmp_type = ICMP_ECHO;
677 		outicmp->icmp_id = htons(ident);
678 
679 		outmark = outp + 8;	/* XXX magic number */
680 	} else {
681 		outip->ip_p = IPPROTO_UDP;
682 
683 		outudp = (struct udphdr *)outp;
684 		outudp->uh_sport = htons(ident);
685 		outudp->uh_ulen =
686 		    htons((u_int16_t)(packlen - (sizeof(*outip) + optlen)));
687 		outmark = outudp + 1;
688 	}
689 
690 	if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
691 		Fprintf(stderr, "%s: icmp socket: %s\n", prog, strerror(errno));
692 		exit(1);
693 	}
694 	if (options & SO_DEBUG)
695 		(void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on,
696 		    sizeof(on));
697 #ifdef IPSEC
698 #ifdef IPSEC_POLICY_IPSEC
699 	/*
700 	 * do not raise error even if setsockopt fails, kernel may have ipsec
701 	 * turned off.
702 	 */
703 	if (setpolicy(s, "in bypass") < 0)
704 		exit(1);
705 	if (setpolicy(s, "out bypass") < 0)
706 		exit(1);
707 #else
708     {
709 	int level = IPSEC_LEVEL_AVAIL;
710 
711 	(void)setsockopt(s, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level,
712 		sizeof(level));
713 	(void)setsockopt(s, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level,
714 		sizeof(level));
715 #ifdef IP_AUTH_TRANS_LEVEL
716 	(void)setsockopt(s, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level,
717 		sizeof(level));
718 #else
719 	(void)setsockopt(s, IPPROTO_IP, IP_AUTH_LEVEL, &level,
720 		sizeof(level));
721 #endif
722 #ifdef IP_AUTH_NETWORK_LEVEL
723 	(void)setsockopt(s, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level,
724 		sizeof(level));
725 #endif
726     }
727 #endif /*IPSEC_POLICY_IPSEC*/
728 #endif /*IPSEC*/
729 
730 #ifndef __hpux
731 	sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
732 #else
733 	sndsock = socket(AF_INET, SOCK_RAW,
734 	    useicmp ? IPPROTO_ICMP : IPPROTO_UDP);
735 #endif
736 	if (sndsock < 0) {
737 		Fprintf(stderr, "%s: raw socket: %s\n", prog, strerror(errno));
738 		exit(1);
739 	}
740 
741 #ifdef IPSEC
742 #ifdef IPSEC_POLICY_IPSEC
743 	/*
744 	 * do not raise error even if setsockopt fails, kernel may have ipsec
745 	 * turned off.
746 	 */
747 	if (setpolicy(sndsock, "in bypass") < 0)
748 		exit(1);
749 	if (setpolicy(sndsock, "out bypass") < 0)
750 		exit(1);
751 #else
752     {
753 	int level = IPSEC_LEVEL_BYPASS;
754 
755 	(void)setsockopt(sndsock, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level,
756 		sizeof(level));
757 	(void)setsockopt(sndsock, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level,
758 		sizeof(level));
759 #ifdef IP_AUTH_TRANS_LEVEL
760 	(void)setsockopt(sndsock, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level,
761 		sizeof(level));
762 #else
763 	(void)setsockopt(sndsock, IPPROTO_IP, IP_AUTH_LEVEL, &level,
764 		sizeof(level));
765 #endif
766 #ifdef IP_AUTH_NETWORK_LEVEL
767 	(void)setsockopt(sndsock, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level,
768 		sizeof(level));
769 #endif
770     }
771 #endif /*IPSEC_POLICY_IPSEC*/
772 #endif /*IPSEC*/
773 
774 	/* Revert to non-privileged user after opening sockets */
775 	setuid(getuid());
776 
777 #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
778 	if (lsrr > 0) {
779 		u_char optlist[MAX_IPOPTLEN];
780 
781 		/* final hop */
782 		gwlist[lsrr] = to->sin_addr.s_addr;
783 		++lsrr;
784 
785 		/* force 4 byte alignment */
786 		optlist[0] = IPOPT_NOP;
787 		/* loose source route option */
788 		optlist[1] = IPOPT_LSRR;
789 		i = lsrr * sizeof(gwlist[0]);
790 		optlist[2] = i + 3;
791 		/* Pointer to LSRR addresses */
792 		optlist[3] = IPOPT_MINOFF;
793 		memcpy(optlist + 4, gwlist, i);
794 
795 		if ((setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS, optlist,
796 		    i + sizeof(gwlist[0]))) < 0) {
797 			Fprintf(stderr, "%s: IP_OPTIONS: %s\n",
798 			    prog, strerror(errno));
799 			exit(1);
800 		    }
801 	}
802 #endif
803 
804 #ifdef SO_SNDBUF
805 	if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packlen,
806 	    sizeof(packlen)) < 0) {
807 		Fprintf(stderr, "%s: SO_SNDBUF: %s\n", prog, strerror(errno));
808 		exit(1);
809 	}
810 #endif
811 #ifdef IP_HDRINCL
812 	if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
813 	    sizeof(on)) < 0) {
814 		Fprintf(stderr, "%s: IP_HDRINCL: %s\n", prog, strerror(errno));
815 		exit(1);
816 	}
817 #else
818 #ifdef IP_TOS
819 	if (settos && setsockopt(sndsock, IPPROTO_IP, IP_TOS,
820 	    (char *)&tos, sizeof(tos)) < 0) {
821 		Fprintf(stderr, "%s: setsockopt tos %d: %s\n",
822 		    prog, tos, strerror(errno));
823 		exit(1);
824 	}
825 #endif
826 #endif
827 	if (options & SO_DEBUG)
828 		(void)setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on,
829 		    sizeof(on));
830 	if (options & SO_DONTROUTE)
831 		(void)setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
832 		    sizeof(on));
833 
834 	/* Get the interface address list */
835 	n = ifaddrlist(&al, errbuf, sizeof errbuf);
836 	al2 = al;
837 	if (n < 0) {
838 		Fprintf(stderr, "%s: ifaddrlist: %s\n", prog, errbuf);
839 		exit(1);
840 	}
841 	if (n == 0) {
842 		Fprintf(stderr,
843 		    "%s: Can't find any network interfaces\n", prog);
844 		exit(1);
845 	}
846 
847 	/* Look for a specific device */
848 	if (device != NULL) {
849 		for (i = n; i > 0; --i, ++al2)
850 			if (strcmp(device, al2->device) == 0)
851 				break;
852 		if (i <= 0) {
853 			Fprintf(stderr, "%s: Can't find interface %s\n",
854 			    prog, device);
855 			exit(1);
856 		}
857 	}
858 
859 	/* Determine our source address */
860 	if (source == NULL) {
861 		/*
862 		 * If a device was specified, use the interface address.
863 		 * Otherwise, use the first interface found.
864 		 * Warn if there are more than one.
865 		 */
866 		setsin(from, al2->addr);
867 		if (n > 1 && device == NULL && !find_local_ip(from, to)) {
868 			Fprintf(stderr,
869 		    "%s: Warning: Multiple interfaces found; using %s @ %s\n",
870 			    prog, inet_ntoa(from->sin_addr), al2->device);
871 		}
872 	} else {
873 		hi = gethostinfo(source);
874 		source = hi->name;
875 		hi->name = NULL;
876 		if (device == NULL) {
877 			/*
878 			 * Use the first interface found.
879 			 * Warn if there are more than one.
880 			 */
881 			setsin(from, hi->addrs[0]);
882 			if (hi->n > 1)
883 				Fprintf(stderr,
884 			"%s: Warning: %s has multiple addresses; using %s\n",
885 				    prog, source, inet_ntoa(from->sin_addr));
886 		} else {
887 			/*
888 			 * Make sure the source specified matches the
889 			 * interface address.
890 			 */
891 			for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
892 				if (*ap == al2->addr)
893 					break;
894 			if (i <= 0) {
895 				Fprintf(stderr,
896 				    "%s: %s is not on interface %s\n",
897 				    prog, source, device);
898 				exit(1);
899 			}
900 			setsin(from, *ap);
901 		}
902 		freehostinfo(hi);
903 	}
904 
905 	/*
906 	 * If not root, make sure source address matches a local interface.
907 	 * (The list of addresses produced by ifaddrlist() automatically
908 	 * excludes interfaces that are marked down and/or loopback.)
909 	 */
910 	if (getuid())  {
911 		al2 = al;
912 		for (i = n; i > 0; --i, ++al2)
913 			if (from->sin_addr.s_addr == al2->addr)
914 			    break;
915 		if (i <= 0) {
916 			Fprintf(stderr, "%s: %s is not a valid local address "
917 			    "and you are not superuser.\n", prog,
918 			    inet_ntoa(from->sin_addr));
919 			exit(1);
920 		}
921 	}
922 
923 	outip->ip_src = from->sin_addr;
924 #ifndef IP_HDRINCL
925 	if (bind(sndsock, (struct sockaddr *)from, sizeof(*from)) < 0) {
926 		Fprintf(stderr, "%s: bind: %s\n",
927 		    prog, strerror(errno));
928 		exit (1);
929 	}
930 #endif
931 
932 	if (as_path) {
933 		asn = as_setup(as_server);
934 		if (asn == NULL) {
935 			Fprintf(stderr, "%s: as_setup failed, AS# lookups disabled\n",
936 				prog);
937 			(void)fflush(stderr);
938 			as_path = 0;
939 		}
940 	}
941 
942 	setuid(getuid());
943 	Fprintf(stderr, "%s to %s (%s)",
944 	    prog, hostname, inet_ntoa(to->sin_addr));
945 	if (source)
946 		Fprintf(stderr, " from %s", source);
947 	Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen);
948 	(void)fflush(stderr);
949 
950 	for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
951 		u_int32_t lastaddr = 0;
952 		int got_there = 0;
953 		int unreachable = 0;
954 
955 again:
956 		printed_ttl = 0;
957 		for (probe = 0; probe < nprobes; ++probe) {
958 			int cc;
959 			struct timeval t1, t2;
960 			struct ip *ip;
961 			(void)gettimeofday(&t1, NULL);
962 			send_probe(++seq, ttl, &t1);
963 			while ((cc = wait_for_reply(s, from, &t1)) != 0) {
964 				(void)gettimeofday(&t2, NULL);
965 				/*
966 				 * Since we'll be receiving all ICMP
967 				 * messages to this host above, we may
968 				 * never end up with cc=0, so we need
969 				 * an additional termination check.
970 				 */
971 				if (t2.tv_sec - t1.tv_sec > waittime) {
972 					cc = 0;
973 					break;
974 				}
975 				i = packet_ok(packet, cc, from, seq);
976 				/* Skip short packet */
977 				if (i == 0)
978 					continue;
979 				if (from->sin_addr.s_addr != lastaddr) {
980 					print(packet, cc, from);
981 					lastaddr = from->sin_addr.s_addr;
982 				}
983 				ip = (struct ip *)packet;
984 				Printf("  %.3f ms", deltaT(&t1, &t2));
985 				if (ttl_flag)
986 					Printf(" (ttl = %d)", ip->ip_ttl);
987 				if (i == -2) {
988 #ifndef ARCHAIC
989 					if (ip->ip_ttl <= 1)
990 						Printf(" !");
991 #endif
992 					++got_there;
993 					break;
994 				}
995 
996 				/* time exceeded in transit */
997 				if (i == -1)
998 					break;
999 				code = i - 1;
1000 				switch (code) {
1001 
1002 				case ICMP_UNREACH_PORT:
1003 #ifndef ARCHAIC
1004 					if (ip->ip_ttl <= 1)
1005 						Printf(" !");
1006 #endif
1007 					++got_there;
1008 					break;
1009 
1010 				case ICMP_UNREACH_NET:
1011 					++unreachable;
1012 					Printf(" !N");
1013 					break;
1014 
1015 				case ICMP_UNREACH_HOST:
1016 					++unreachable;
1017 					Printf(" !H");
1018 					break;
1019 
1020 				case ICMP_UNREACH_PROTOCOL:
1021 					++got_there;
1022 					Printf(" !P");
1023 					break;
1024 
1025 				case ICMP_UNREACH_NEEDFRAG:
1026 					if (mtudisc) {
1027 						frag_err();
1028 						goto again;
1029 					} else {
1030 						++unreachable;
1031 						Printf(" !F");
1032 					}
1033 					break;
1034 
1035 				case ICMP_UNREACH_SRCFAIL:
1036 					++unreachable;
1037 					Printf(" !S");
1038 					break;
1039 
1040 /* rfc1716 */
1041 #ifndef ICMP_UNREACH_FILTER_PROHIB
1042 #define ICMP_UNREACH_FILTER_PROHIB	13	/* admin prohibited filter */
1043 #endif
1044 				case ICMP_UNREACH_FILTER_PROHIB:
1045 					++unreachable;
1046 					Printf(" !X");
1047 					break;
1048 
1049 				default:
1050 					++unreachable;
1051 					Printf(" !<%d>", code);
1052 					break;
1053 				}
1054 				break;
1055 			}
1056 			if (cc == 0)
1057 				Printf(" *");
1058 			else if (cc && probe == nprobes - 1 && Mflag)
1059 				decode_extensions(packet, cc);
1060 			(void)fflush(stdout);
1061 		}
1062 		putchar('\n');
1063 		if (got_there ||
1064 		    (unreachable > 0 && unreachable >= ((nprobes + 1) / 2)))
1065 			break;
1066 	}
1067 
1068 	if (as_path)
1069 		as_shutdown(asn);
1070 
1071 	exit(0);
1072 }
1073 
1074 int
1075 wait_for_reply(int sock, struct sockaddr_in *fromp, struct timeval *tp)
1076 {
1077 	struct pollfd set[1];
1078 	struct timeval now, wait;
1079 	int cc = 0;
1080 	socklen_t fromlen = sizeof(*fromp);
1081 	int retval;
1082 
1083 	set[0].fd = sock;
1084 	set[0].events = POLLIN;
1085 
1086 	wait.tv_sec = tp->tv_sec + waittime;
1087 	wait.tv_usec = tp->tv_usec;
1088 	(void)gettimeofday(&now, NULL);
1089 	tvsub(&wait, &now);
1090 
1091 	if (wait.tv_sec < 0) {
1092 		wait.tv_sec = 0;
1093 		wait.tv_usec = 0;
1094 	}
1095 
1096 	retval = poll(set, 1, wait.tv_sec * 1000 + wait.tv_usec / 1000);
1097 	if (retval < 0)  {
1098 		/* If we continue, we probably just flood the remote host. */
1099 		Fprintf(stderr, "%s: select: %s\n", prog, strerror(errno));
1100 		exit(1);
1101 	}
1102 	if (retval > 0)  {
1103 		cc = recvfrom(s, (char *)packet, sizeof(packet), 0,
1104 			    (struct sockaddr *)fromp, &fromlen);
1105 	}
1106 
1107 	return(cc);
1108 }
1109 
1110 void
1111 decode_extensions(unsigned char *buf, int ip_len)
1112 {
1113         struct icmp_ext_cmn_hdr *cmn_hdr;
1114         struct icmp_ext_obj_hdr *obj_hdr;
1115         union {
1116                 struct mpls_header mpls;
1117                 uint32_t mpls_h;
1118         } mpls;
1119         int datalen, obj_len;
1120         struct ip *ip;
1121 
1122         ip = (struct ip *)buf;
1123 
1124         if (ip_len <= sizeof(struct ip) + ICMP_EXT_OFFSET) {
1125 		/*
1126 		 * No support for ICMP extensions on this host
1127 		 */
1128 		return;
1129         }
1130 
1131         /*
1132          * Move forward to the start of the ICMP extensions, if present
1133          */
1134         buf += (ip->ip_hl << 2) + ICMP_EXT_OFFSET;
1135         cmn_hdr = (struct icmp_ext_cmn_hdr *)buf;
1136 
1137         if (cmn_hdr->version != ICMP_EXT_VERSION) {
1138 		/*
1139 		 * Unknown version
1140 		 */
1141 		return;
1142         }
1143 
1144         datalen = ip_len - ((u_char *)cmn_hdr - (u_char *)ip);
1145 
1146         /*
1147          * Check the checksum, cmn_hdr->checksum == 0 means no checksum'ing
1148          * done by sender.
1149          *
1150         * If the checksum is ok, we'll get 0, as the checksum is calculated
1151          * with the checksum field being 0'd.
1152          */
1153         if (ntohs(cmn_hdr->checksum) &&
1154             in_cksum((u_short *)cmn_hdr, datalen)) {
1155 
1156             return;
1157         }
1158 
1159         buf += sizeof(*cmn_hdr);
1160         datalen -= sizeof(*cmn_hdr);
1161 
1162         while (datalen > 0) {
1163 		obj_hdr = (struct icmp_ext_obj_hdr *)buf;
1164 		obj_len = ntohs(obj_hdr->length);
1165 
1166 		/*
1167 		 * Sanity check the length field
1168 		 */
1169 		if (obj_len > datalen) {
1170 			return;
1171 		}
1172 
1173 		datalen -= obj_len;
1174 
1175 		/*
1176 		 * Move past the object header
1177 		 */
1178 		buf += sizeof(struct icmp_ext_obj_hdr);
1179 		obj_len -= sizeof(struct icmp_ext_obj_hdr);
1180 
1181 		switch (obj_hdr->class_num) {
1182 		case MPLS_STACK_ENTRY_CLASS:
1183 			switch (obj_hdr->c_type) {
1184 			case MPLS_STACK_ENTRY_C_TYPE:
1185 				while (obj_len >= sizeof(uint32_t)) {
1186 					mpls.mpls_h = ntohl(*(uint32_t *)buf);
1187 
1188 					buf += sizeof(uint32_t);
1189 					obj_len -= sizeof(uint32_t);
1190 
1191 					printf(" [MPLS: Label %d Exp %d]",
1192 					    mpls.mpls.label, mpls.mpls.exp);
1193 				}
1194 				if (obj_len > 0) {
1195 					/*
1196 					 * Something went wrong, and we're at
1197 					 * a unknown offset into the packet,
1198 					 * ditch the rest of it.
1199 					 */
1200 					return;
1201 				}
1202 				break;
1203 			default:
1204 				/*
1205 				 * Unknown object, skip past it
1206 				 */
1207 				buf += ntohs(obj_hdr->length) -
1208 				    sizeof(struct icmp_ext_obj_hdr);
1209 				break;
1210 			}
1211 			break;
1212 
1213 		default:
1214 			/*
1215 			 * Unknown object, skip past it
1216 			 */
1217 			buf += ntohs(obj_hdr->length) -
1218 			    sizeof(struct icmp_ext_obj_hdr);
1219 			break;
1220 		}
1221 	}
1222 }
1223 
1224 void
1225 dump_packet()
1226 {
1227 	u_char *p;
1228 	int i;
1229 
1230 	Fprintf(stderr, "packet data:");
1231 
1232 #ifdef __hpux
1233 	for (p = useicmp ? (u_char *)outicmp : (u_char *)outudp, i = 0; i <
1234 	    i < packlen - (sizeof(*outip) + optlen); i++)
1235 #else
1236 	for (p = (u_char *)outip, i = 0; i < packlen; i++)
1237 #endif
1238 	{
1239 		if ((i % 24) == 0)
1240 			Fprintf(stderr, "\n ");
1241 		Fprintf(stderr, " %02x", *p++);
1242 	}
1243 	Fprintf(stderr, "\n");
1244 }
1245 
1246 void
1247 send_probe(int seq, int ttl, struct timeval *tp)
1248 {
1249 	int cc;
1250 	struct udpiphdr * ui;
1251 	int oldmtu = packlen;
1252 
1253 again:
1254 #ifdef BYTESWAP_IP_LEN
1255 	outip->ip_len = htons(packlen);
1256 #else
1257 	outip->ip_len = packlen;
1258 #endif
1259 	outip->ip_ttl = ttl;
1260 #ifndef __hpux
1261 	outip->ip_id = htons(ident + seq);
1262 #endif
1263 
1264 	/*
1265 	 * In most cases, the kernel will recalculate the ip checksum.
1266 	 * But we must do it anyway so that the udp checksum comes out
1267 	 * right.
1268 	 */
1269 	if (docksum) {
1270 		outip->ip_sum =
1271 		    in_cksum((u_int16_t *)outip, sizeof(*outip) + optlen);
1272 		if (outip->ip_sum == 0)
1273 			outip->ip_sum = 0xffff;
1274 	}
1275 
1276 	/* Payload */
1277 	outsetup.seq = seq;
1278 	outsetup.ttl = ttl;
1279 	outsetup.tv  = *tp;
1280 	memcpy(outmark,&outsetup,sizeof(outsetup));
1281 
1282 	if (useicmp)
1283 		outicmp->icmp_seq = htons(seq);
1284 	else
1285 		outudp->uh_dport = htons(port + seq);
1286 
1287 	/* (We can only do the checksum if we know our ip address) */
1288 	if (docksum) {
1289 		if (useicmp) {
1290 			outicmp->icmp_cksum = 0;
1291 			outicmp->icmp_cksum = in_cksum((u_int16_t *)outicmp,
1292 			    packlen - (sizeof(*outip) + optlen));
1293 			if (outicmp->icmp_cksum == 0)
1294 				outicmp->icmp_cksum = 0xffff;
1295 		} else {
1296 			u_int16_t sum;
1297 			struct {
1298 				struct in_addr src;
1299 				struct in_addr dst;
1300 				u_int8_t zero;
1301 				u_int8_t protocol;
1302 				u_int16_t len;
1303 			} __attribute__((__packed__)) phdr;
1304 
1305 			/* Checksum */
1306 			ui = (struct udpiphdr *)outip;
1307 			memset(&phdr, 0, sizeof(phdr));
1308 			phdr.src = ui->ui_src;
1309 			phdr.dst = ((struct sockaddr_in *)&whereto)->sin_addr;
1310 			phdr.protocol = ui->ui_pr;
1311 			phdr.len = outudp->uh_ulen;
1312 			outudp->uh_sum = 0;
1313 			sum = in_cksum2(0, (u_int16_t *)&phdr, sizeof(phdr));
1314 			sum = in_cksum2(sum, (u_int16_t *)outudp, ntohs(outudp->uh_ulen));
1315 			sum = ~sum;	/** XXXSCW: Quell SuperH Compiler Bug */
1316 			outudp->uh_sum = sum;
1317 			if (outudp->uh_sum == 0)
1318 				outudp->uh_sum = 0xffff;
1319 		}
1320 	}
1321 
1322 	/* XXX undocumented debugging hack */
1323 	if (verbose > 1) {
1324 		const u_int16_t *sp;
1325 		int nshorts, i;
1326 
1327 		sp = (u_int16_t *)outip;
1328 		nshorts = (u_int)packlen / sizeof(u_int16_t);
1329 		i = 0;
1330 		Printf("[ %d bytes", packlen);
1331 		while (--nshorts >= 0) {
1332 			if ((i++ % 8) == 0)
1333 				Printf("\n\t");
1334 			Printf(" %04x", ntohs(*sp++));
1335 		}
1336 		if (packlen & 1) {
1337 			if ((i % 8) == 0)
1338 				Printf("\n\t");
1339 			Printf(" %02x", *(u_char *)sp);
1340 		}
1341 		Printf("]\n");
1342 	}
1343 
1344 #if !defined(IP_HDRINCL) && defined(IP_TTL)
1345 	if (setsockopt(sndsock, IPPROTO_IP, IP_TTL,
1346 	    (char *)&ttl, sizeof(ttl)) < 0) {
1347 		Fprintf(stderr, "%s: setsockopt ttl %d: %s\n",
1348 		    prog, ttl, strerror(errno));
1349 		exit(1);
1350 	}
1351 #endif
1352 	if (dump)
1353 		dump_packet();
1354 
1355 #ifdef __hpux
1356 	cc = sendto(sndsock, useicmp ? (char *)outicmp : (char *)outudp,
1357 	    packlen - (sizeof(*outip) + optlen), 0, &whereto, sizeof(whereto));
1358 	if (cc > 0)
1359 		cc += sizeof(*outip) + optlen;
1360 #else
1361 	cc = sendto(sndsock, (char *)outip,
1362 	    packlen, 0, &whereto, sizeof(whereto));
1363 #endif
1364 	if (cc < 0 || cc != packlen)  {
1365 		if (cc < 0) {
1366 			/*
1367 			 * An errno of EMSGSIZE means we're writing too big a
1368 			 * datagram for the interface.  We have to just
1369 			 * decrease the packet size until we find one that
1370 			 * works.
1371 			 *
1372 			 * XXX maybe we should try to read the outgoing if's
1373 			 * mtu?
1374 			 */
1375 			if (errno == EMSGSIZE) {
1376 				packlen = *mtuptr++;
1377 				resize_packet();
1378 				goto again;
1379 			} else
1380 				Fprintf(stderr, "%s: sendto: %s\n",
1381 				    prog, strerror(errno));
1382 		}
1383 
1384 		Printf("%s: wrote %s %d chars, ret=%d\n",
1385 		    prog, hostname, packlen, cc);
1386 		(void)fflush(stdout);
1387 	}
1388 	if (oldmtu != packlen) {
1389 		Printf("message too big, "
1390 		    "trying new MTU = %d\n", packlen);
1391 		printed_ttl = 0;
1392 	}
1393 	if (!printed_ttl) {
1394 		Printf("%2d ", ttl);
1395 		printed_ttl = 1;
1396 	}
1397 
1398 }
1399 
1400 double
1401 deltaT(struct timeval *t1p, struct timeval *t2p)
1402 {
1403 	double dt;
1404 
1405 	dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1406 	     (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1407 	return (dt);
1408 }
1409 
1410 /*
1411  * Convert an ICMP "type" field to a printable string.
1412  */
1413 char *
1414 pr_type(u_char t)
1415 {
1416 	static char *ttab[] = {
1417 	"Echo Reply",	"ICMP 1",	"ICMP 2",	"Dest Unreachable",
1418 	"Source Quench", "Redirect",	"ICMP 6",	"ICMP 7",
1419 	"Echo",		"ICMP 9",	"ICMP 10",	"Time Exceeded",
1420 	"Param Problem", "Timestamp",	"Timestamp Reply", "Info Request",
1421 	"Info Reply"
1422 	};
1423 
1424 	if (t > 16)
1425 		return("OUT-OF-RANGE");
1426 
1427 	return(ttab[t]);
1428 }
1429 
1430 int
1431 packet_ok(u_char *buf, int cc, struct sockaddr_in *from, int seq)
1432 {
1433 	struct icmp *icp;
1434 	u_char type, code;
1435 	int hlen;
1436 #ifndef ARCHAIC
1437 	struct ip *ip;
1438 
1439 	ip = (struct ip *) buf;
1440 	hlen = ip->ip_hl << 2;
1441 	if (cc < hlen + ICMP_MINLEN) {
1442 		if (verbose)
1443 			Printf("packet too short (%d bytes) from %s\n", cc,
1444 				inet_ntoa(from->sin_addr));
1445 		return (0);
1446 	}
1447 	cc -= hlen;
1448 	icp = (struct icmp *)(buf + hlen);
1449 #else
1450 	icp = (struct icmp *)buf;
1451 #endif
1452 	type = icp->icmp_type;
1453 	code = icp->icmp_code;
1454 	if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
1455 	    type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
1456 		struct ip *hip;
1457 		struct udphdr *up;
1458 		struct icmp *hicmp;
1459 
1460 		hip = &icp->icmp_ip;
1461 		hlen = hip->ip_hl << 2;
1462 
1463 		nextmtu = ntohs(icp->icmp_nextmtu);	/* for frag_err() */
1464 
1465 		if (useicmp) {
1466 			/* XXX */
1467 			if (type == ICMP_ECHOREPLY &&
1468 			    icp->icmp_id == htons(ident) &&
1469 			    icp->icmp_seq == htons(seq))
1470 				return (-2);
1471 
1472 			hicmp = (struct icmp *)((u_char *)hip + hlen);
1473 			/* XXX 8 is a magic number */
1474 			if (hlen + 8 <= cc &&
1475 			    hip->ip_p == IPPROTO_ICMP &&
1476 			    hicmp->icmp_id == htons(ident) &&
1477 			    hicmp->icmp_seq == htons(seq))
1478 				return (type == ICMP_TIMXCEED ? -1 : code + 1);
1479 		} else {
1480 			up = (struct udphdr *)((u_char *)hip + hlen);
1481 			/* XXX 8 is a magic number */
1482 			if (hlen + 12 <= cc &&
1483 			    hip->ip_p == IPPROTO_UDP &&
1484 			    up->uh_sport == htons(ident) &&
1485 			    up->uh_dport == htons(port + seq))
1486 				return (type == ICMP_TIMXCEED ? -1 : code + 1);
1487 		}
1488 	}
1489 #ifndef ARCHAIC
1490 	if (verbose) {
1491 		int i;
1492 		u_int32_t *lp = (u_int32_t *)&icp->icmp_ip;
1493 
1494 		Printf("\n%d bytes from %s to ", cc, inet_ntoa(from->sin_addr));
1495 		Printf("%s: icmp type %d (%s) code %d\n",
1496 		    inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
1497 		for (i = 4; i < cc ; i += sizeof(*lp))
1498 			Printf("%2d: x%8.8x\n", i, *lp++);
1499 	}
1500 #endif
1501 	return(0);
1502 }
1503 
1504 void resize_packet(void)
1505 {
1506 	if (useicmp) {
1507 		outicmp->icmp_cksum = 0;
1508 		outicmp->icmp_cksum = in_cksum((u_int16_t *)outicmp,
1509 		    packlen - (sizeof(*outip) + optlen));
1510 		if (outicmp->icmp_cksum == 0)
1511 			outicmp->icmp_cksum = 0xffff;
1512 	} else {
1513 		outudp->uh_ulen =
1514 		    htons((u_int16_t)(packlen - (sizeof(*outip) + optlen)));
1515 	}
1516 }
1517 
1518 void
1519 print(u_char *buf, int cc, struct sockaddr_in *from)
1520 {
1521 	struct ip *ip;
1522 	int hlen;
1523 
1524 	ip = (struct ip *) buf;
1525 	hlen = ip->ip_hl << 2;
1526 	cc -= hlen;
1527 
1528 	if (as_path)
1529 		Printf(" [AS%d]", as_lookup(asn, &from->sin_addr));
1530 
1531 	if (nflag)
1532 		Printf(" %s", inet_ntoa(from->sin_addr));
1533 	else
1534 		Printf(" %s (%s)", inetname(from->sin_addr),
1535 		    inet_ntoa(from->sin_addr));
1536 
1537 	if (verbose)
1538 		Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
1539 }
1540 
1541 u_int16_t
1542 in_cksum(u_int16_t *addr, int len)
1543 {
1544 
1545 	return ~in_cksum2(0, addr, len);
1546 }
1547 
1548 /*
1549  * Checksum routine for Internet Protocol family headers (C Version)
1550  */
1551 u_int16_t
1552 in_cksum2(u_int16_t seed, u_int16_t *addr, int len)
1553 {
1554 	int nleft = len;
1555 	u_int16_t *w = addr;
1556 	union {
1557 		u_int16_t w;
1558 		u_int8_t b[2];
1559 	} answer;
1560 	int32_t sum = seed;
1561 
1562 	/*
1563 	 *  Our algorithm is simple, using a 32 bit accumulator (sum),
1564 	 *  we add sequential 16 bit words to it, and at the end, fold
1565 	 *  back all the carry bits from the top 16 bits into the lower
1566 	 *  16 bits.
1567 	 */
1568 	while (nleft > 1)  {
1569 		sum += *w++;
1570 		nleft -= 2;
1571 	}
1572 
1573 	/* mop up an odd byte, if necessary */
1574 	if (nleft == 1) {
1575 		answer.b[0] = *(u_char *)w;
1576 		answer.b[1] = 0;
1577 		sum += answer.w;
1578 	}
1579 
1580 	/*
1581 	 * add back carry outs from top 16 bits to low 16 bits
1582 	 */
1583 	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
1584 	sum += (sum >> 16);			/* add carry */
1585 	answer.w = sum;				/* truncate to 16 bits */
1586 	return (answer.w);
1587 }
1588 
1589 /*
1590  * Subtract 2 timeval structs:  out = out - in.
1591  * Out is assumed to be >= in.
1592  */
1593 void
1594 tvsub(struct timeval *out, struct timeval *in)
1595 {
1596 
1597 	if ((out->tv_usec -= in->tv_usec) < 0)   {
1598 		--out->tv_sec;
1599 		out->tv_usec += 1000000;
1600 	}
1601 	out->tv_sec -= in->tv_sec;
1602 }
1603 
1604 /*
1605  * Construct an Internet address representation.
1606  * If the nflag has been supplied, give
1607  * numeric value, otherwise try for symbolic name.
1608  */
1609 char *
1610 inetname(struct in_addr in)
1611 {
1612 	char *cp;
1613 	struct hostent *hp;
1614 	static int first = 1;
1615 	static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1];
1616 
1617 	if (first && !nflag) {
1618 		int rv;
1619 
1620 		first = 0;
1621 		rv = gethostname(domain, sizeof domain);
1622 		if (rv == 0 && (cp = strchr(domain, '.')) != NULL) {
1623 			(void)strlcpy(domain, cp + 1, sizeof(domain));
1624 		} else
1625 			domain[0] = '\0';
1626 	}
1627 	if (!nflag && in.s_addr != INADDR_ANY) {
1628 		hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
1629 		if (hp != NULL) {
1630 			if ((cp = strchr(hp->h_name, '.')) != NULL &&
1631 			    strcmp(cp + 1, domain) == 0)
1632 				*cp = '\0';
1633 			(void)strlcpy(line, hp->h_name, sizeof(line));
1634 			return (line);
1635 		}
1636 	}
1637 	return (inet_ntoa(in));
1638 }
1639 
1640 struct hostinfo *
1641 gethostinfo(char *hostname)
1642 {
1643 	int n;
1644 	struct hostent *hp;
1645 	struct hostinfo *hi;
1646 	char **p;
1647 	u_int32_t *ap;
1648 	struct in_addr addr;
1649 
1650 	hi = calloc(1, sizeof(*hi));
1651 	if (hi == NULL) {
1652 		Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1653 		exit(1);
1654 	}
1655 	if (inet_aton(hostname, &addr) != 0) {
1656 		hi->name = strdup(hostname);
1657 		if (!hi->name) {
1658 			Fprintf(stderr, "%s: strdup %s\n", prog,
1659 			    strerror(errno));
1660 			exit(1);
1661 		}
1662 		hi->n = 1;
1663 		hi->addrs = calloc(1, sizeof(hi->addrs[0]));
1664 		if (hi->addrs == NULL) {
1665 			Fprintf(stderr, "%s: calloc %s\n",
1666 			    prog, strerror(errno));
1667 			exit(1);
1668 		}
1669 		hi->addrs[0] = addr.s_addr;
1670 		return (hi);
1671 	}
1672 
1673 	hp = gethostbyname(hostname);
1674 	if (hp == NULL) {
1675 		Fprintf(stderr, "%s: unknown host %s\n", prog, hostname);
1676 		exit(1);
1677 	}
1678 	if (hp->h_addrtype != AF_INET || hp->h_length != 4) {
1679 		Fprintf(stderr, "%s: bad host %s\n", prog, hostname);
1680 		exit(1);
1681 	}
1682 	hi->name = strdup(hp->h_name);
1683 	if (!hi->name) {
1684 		Fprintf(stderr, "%s: strdup %s\n", prog, strerror(errno));
1685 		exit(1);
1686 	}
1687 	for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
1688 		continue;
1689 	hi->n = n;
1690 	hi->addrs = calloc(n, sizeof(hi->addrs[0]));
1691 	if (hi->addrs == NULL) {
1692 		Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1693 		exit(1);
1694 	}
1695 	for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
1696 		memcpy(ap, *p, sizeof(*ap));
1697 	return (hi);
1698 }
1699 
1700 void
1701 freehostinfo(struct hostinfo *hi)
1702 {
1703 	if (hi->name != NULL) {
1704 		free(hi->name);
1705 		hi->name = NULL;
1706 	}
1707 	free((char *)hi->addrs);
1708 	free((char *)hi);
1709 }
1710 
1711 void
1712 getaddr(u_int32_t *ap, char *hostname)
1713 {
1714 	struct hostinfo *hi;
1715 
1716 	hi = gethostinfo(hostname);
1717 	*ap = hi->addrs[0];
1718 	freehostinfo(hi);
1719 }
1720 
1721 void
1722 setsin(struct sockaddr_in *sin, u_int32_t addr)
1723 {
1724 
1725 	memset(sin, 0, sizeof(*sin));
1726 #ifdef HAVE_SOCKADDR_SA_LEN
1727 	sin->sin_len = sizeof(*sin);
1728 #endif
1729 	sin->sin_family = AF_INET;
1730 	sin->sin_addr.s_addr = addr;
1731 }
1732 
1733 /* String to value with optional min and max. Handles decimal and hex. */
1734 int
1735 str2val(const char *str, const char *what, int mi, int ma)
1736 {
1737 	const char *cp;
1738 	long val;
1739 	char *ep;
1740 
1741 	errno = 0;
1742 	ep = NULL;
1743 	if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
1744 		cp = str + 2;
1745 		val = strtol(cp, &ep, 16);
1746 	} else
1747 		val = strtol(str, &ep, 10);
1748 	if (errno || str[0] == '\0' || *ep != '\0') {
1749 		Fprintf(stderr, "%s: \"%s\" bad value for %s \n",
1750 		    prog, str, what);
1751 		exit(1);
1752 	}
1753 	if (val < mi && mi >= 0) {
1754 		if (mi == 0)
1755 			Fprintf(stderr, "%s: %s must be >= %d\n",
1756 			    prog, what, mi);
1757 		else
1758 			Fprintf(stderr, "%s: %s must be > %d\n",
1759 			    prog, what, mi - 1);
1760 		exit(1);
1761 	}
1762 	if (val > ma && ma >= 0) {
1763 		Fprintf(stderr, "%s: %s must be <= %d\n", prog, what, ma);
1764 		exit(1);
1765 	}
1766 	return ((int)val);
1767 }
1768 
1769 __dead void
1770 usage(void)
1771 {
1772 	extern char version[];
1773 
1774 	Fprintf(stderr, "Version %s\n", version);
1775 	Fprintf(stderr, "usage: %s [-adDFPIlMnrvx] [-g gateway] [-i iface] \
1776 [-f first_ttl]\n\t[-m max_ttl] [-p port] [-q nqueries] [-s src_addr] [-t tos]\n\t\
1777 [-w waittime] [-A as_server] host [packetlen]\n",
1778 	    prog);
1779 	exit(1);
1780 }
1781 
1782 /*
1783  * Received ICMP unreachable (fragmentation required and DF set).
1784  * If the ICMP error was from a "new" router, it'll contain the next-hop
1785  * MTU that we should use next.  Otherwise we'll just keep going in the
1786  * mtus[] table, trying until we hit a valid MTU.
1787  */
1788 
1789 
1790 void
1791 frag_err()
1792 {
1793         int i;
1794 
1795         if (nextmtu > 0 && nextmtu < packlen) {
1796                 Printf("\nfragmentation required and DF set, "
1797 		     "next hop MTU = %d\n",
1798                         nextmtu);
1799                 packlen = nextmtu;
1800                 for (i = 0; mtus[i] > 0; i++) {
1801                         if (mtus[i] < nextmtu) {
1802                                 mtuptr = &mtus[i];    /* next one to try */
1803                                 break;
1804                         }
1805                 }
1806         } else {
1807                 Printf("\nfragmentation required and DF set. ");
1808 		if (nextmtu)
1809 			Printf("\nBogus next hop MTU = %d > last MTU = %d. ",
1810 			    nextmtu, packlen);
1811                 packlen = *mtuptr++;
1812 		Printf("Trying new MTU = %d\n", packlen);
1813         }
1814 	resize_packet();
1815 }
1816 
1817 int
1818 find_local_ip(struct sockaddr_in *from, struct sockaddr_in *to)
1819 {
1820 	int sock;
1821 	struct sockaddr_in help;
1822 	socklen_t help_len;
1823 
1824 	sock = socket(AF_INET, SOCK_DGRAM, 0);
1825 	if (sock < 0) return (0);
1826 
1827 	help.sin_family = AF_INET;
1828 	/*
1829 	 * At this point the port number doesn't matter
1830 	 * since it only has to be greater than zero.
1831 	 */
1832 	help.sin_port = 42;
1833 	help.sin_addr.s_addr = to->sin_addr.s_addr;
1834 	if (connect(sock, (struct sockaddr *)&help, sizeof(help)) < 0) {
1835 		(void)close(sock);
1836 		return (0);
1837 	}
1838 
1839 	help_len = sizeof(help);
1840 	if (getsockname(sock, (struct sockaddr *)&help, &help_len) < 0 ||
1841 	    help_len != sizeof(help) ||
1842 	    help.sin_addr.s_addr == INADDR_ANY) {
1843 		(void)close(sock);
1844 		return (0);
1845 	}
1846 
1847 	(void)close(sock);
1848 	setsin(from, help.sin_addr.s_addr);
1849 	return (1);
1850 }
1851 
1852 #ifdef IPSEC
1853 #ifdef IPSEC_POLICY_IPSEC
1854 int
1855 setpolicy(so, policy)
1856 	int so;
1857 	char *policy;
1858 {
1859 	char *buf;
1860 
1861 	buf = ipsec_set_policy(policy, strlen(policy));
1862 	if (buf == NULL) {
1863 		Fprintf(stderr, "%s: %s\n", prog, ipsec_strerror());
1864 		return -1;
1865 	}
1866 	(void)setsockopt(so, IPPROTO_IP, IP_IPSEC_POLICY,
1867 		buf, ipsec_get_policylen(buf));
1868 
1869 	free(buf);
1870 
1871 	return 0;
1872 }
1873 #endif
1874 #endif
1875 
1876