xref: /netbsd-src/usr.sbin/traceroute/traceroute.c (revision 1b9578b8c2c1f848eeb16dabbfd7d1f0d9fdefbd)
1 /*	$NetBSD: traceroute.c,v 1.78 2011/05/12 01:59:16 christos 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\
31  The Regents of the University of California.  All rights reserved.");
32 __RCSID("$NetBSD: traceroute.c,v 1.78 2011/05/12 01:59:16 christos 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 <err.h>
226 #include <errno.h>
227 #ifdef HAVE_MALLOC_H
228 #include <malloc.h>
229 #endif
230 #include <memory.h>
231 #include <netdb.h>
232 #include <stdio.h>
233 #include <stdlib.h>
234 #include <string.h>
235 #include <unistd.h>
236 #include <poll.h>
237 #ifdef IPSEC
238 #include <net/route.h>
239 #include <netinet6/ipsec.h>
240 #endif
241 
242 #include "gnuc.h"
243 #ifdef HAVE_OS_PROTO_H
244 #include "os-proto.h"
245 #endif
246 
247 #include "ifaddrlist.h"
248 #include "as.h"
249 #include "prog_ops.h"
250 
251 /* Maximum number of gateways (include room for one noop) */
252 #define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(u_int32_t)))
253 
254 #ifndef MAXHOSTNAMELEN
255 #define MAXHOSTNAMELEN	64
256 #endif
257 
258 #define Fprintf (void)fprintf
259 #define Printf (void)printf
260 
261 /* Host name and address list */
262 struct hostinfo {
263 	char *name;
264 	int n;
265 	u_int32_t *addrs;
266 };
267 
268 /* Data section of the probe packet */
269 struct outdata {
270 	u_char seq;		/* sequence number of this packet */
271 	u_char ttl;		/* ttl packet left with */
272 	struct tv32 {
273 		int32_t tv32_sec;
274 		int32_t tv32_usec;
275 	} tv;			/* time packet left */
276 };
277 
278 /*
279  * Support for ICMP extensions
280  *
281  * http://www.ietf.org/proceedings/01aug/I-D/draft-ietf-mpls-icmp-02.txt
282  */
283 #define ICMP_EXT_OFFSET    8 /* ICMP type, code, checksum, unused */ + \
284                          128 /* original datagram */
285 #define ICMP_EXT_VERSION 2
286 /*
287  * ICMP extensions, common header
288  */
289 struct icmp_ext_cmn_hdr {
290 #if BYTE_ORDER == BIG_ENDIAN
291 	unsigned char   version:4;
292 	unsigned char   reserved1:4;
293 #else
294 	unsigned char   reserved1:4;
295 	unsigned char   version:4;
296 #endif
297 	unsigned char   reserved2;
298 	unsigned short  checksum;
299 };
300 
301 /*
302  * ICMP extensions, object header
303  */
304 struct icmp_ext_obj_hdr {
305     u_short length;
306     u_char  class_num;
307 #define MPLS_STACK_ENTRY_CLASS 1
308     u_char  c_type;
309 #define MPLS_STACK_ENTRY_C_TYPE 1
310 };
311 
312 struct mpls_header {
313 #if BYTE_ORDER == BIG_ENDIAN
314 	 uint32_t	label:20;
315 	 unsigned char  exp:3;
316 	 unsigned char  s:1;
317 	 unsigned char  ttl:8;
318 #else
319 	 unsigned char  ttl:8;
320 	 unsigned char  s:1;
321 	 unsigned char  exp:3;
322 	 uint32_t	label:20;
323 #endif
324 };
325 
326 static u_char	packet[512];		/* last inbound (icmp) packet */
327 
328 static struct ip *outip;		/* last output (udp) packet */
329 static struct udphdr *outudp;		/* last output (udp) packet */
330 static void *outmark;			/* packed location of struct outdata */
331 static struct outdata outsetup;	/* setup and copy for alignment */
332 
333 static struct icmp *outicmp;		/* last output (icmp) packet */
334 
335 /* loose source route gateway list (including room for final destination) */
336 static u_int32_t gwlist[NGATEWAYS + 1];
337 
338 static int s;				/* receive (icmp) socket file descriptor */
339 static int sndsock;			/* send (udp/icmp) socket file descriptor */
340 
341 static struct sockaddr whereto;	/* Who to try to reach */
342 static struct sockaddr_in wherefrom;	/* Who we are */
343 static int packlen;			/* total length of packet */
344 static int minpacket;			/* min ip packet size */
345 static int maxpacket = 32 * 1024;	/* max ip packet size */
346 static int printed_ttl = 0;
347 
348 static const char *prog;
349 static char *source;
350 static char *hostname;
351 static char *device;
352 
353 static int nprobes = 3;
354 static int max_ttl = 30;
355 static int first_ttl = 1;
356 static u_int16_t ident;
357 static in_port_t port = 32768 + 666;	/* start udp dest port # for probe packets */
358 
359 static int options;			/* socket options */
360 static int verbose;
361 static int waittime = 5;		/* time to wait for response (in seconds) */
362 static int nflag;			/* print addresses numerically */
363 static int dump;
364 static int Mflag;			/* show MPLS labels if any */
365 static int as_path;			/* print as numbers for each hop */
366 static char *as_server = NULL;
367 static void *asn;
368 static int useicmp = 0;		/* use icmp echo instead of udp packets */
369 #ifdef CANT_HACK_CKSUM
370 static int docksum = 0;		/* don't calculate checksums */
371 #else
372 static int docksum = 1;		/* calculate checksums */
373 #endif
374 static int optlen;			/* length of ip options */
375 
376 static int mtus[] = {
377         17914,
378          8166,
379          4464,
380          4352,
381          2048,
382          2002,
383          1536,
384          1500,
385          1492,
386 	 1480,
387 	 1280,
388          1006,
389           576,
390           552,
391           544,
392           512,
393           508,
394           296,
395            68,
396             0
397 };
398 static int *mtuptr = &mtus[0];
399 static int mtudisc = 0;
400 static int nextmtu;   /* from ICMP error, set by packet_ok(), might be 0 */
401 
402 /* Forwards */
403 static double deltaT(struct timeval *, struct timeval *);
404 static void freehostinfo(struct hostinfo *);
405 static void getaddr(u_int32_t *, char *);
406 static struct hostinfo *gethostinfo(char *);
407 static u_int16_t in_cksum(u_int16_t *, int);
408 static u_int16_t in_cksum2(u_int16_t, u_int16_t *, int);
409 static char *inetname(struct in_addr);
410 static int packet_ok(u_char *, ssize_t, struct sockaddr_in *, int);
411 static const char *pr_type(u_char);
412 static void print(u_char *, int, struct sockaddr_in *);
413 static void resize_packet(void);
414 static void dump_packet(void);
415 static void send_probe(int, int, struct timeval *);
416 static void setsin(struct sockaddr_in *, u_int32_t);
417 static int str2val(const char *, const char *, int, int);
418 static void tvsub(struct timeval *, struct timeval *);
419 static void usage(void) __attribute__((__noreturn__));
420 static ssize_t wait_for_reply(int, struct sockaddr_in *, struct timeval *);
421 static void decode_extensions(unsigned char *buf, int ip_len);
422 static void frag_err(void);
423 static int find_local_ip(struct sockaddr_in *, struct sockaddr_in *);
424 #ifdef IPSEC
425 #ifdef IPSEC_POLICY_IPSEC
426 static int setpolicy(int, const char *);
427 #endif
428 #endif
429 
430 int
431 main(int argc, char **argv)
432 {
433 	int op, code, n;
434 	u_char *outp;
435 	u_int32_t *ap;
436 	struct sockaddr_in *from = &wherefrom;
437 	struct sockaddr_in *to = (struct sockaddr_in *)&whereto;
438 	struct hostinfo *hi;
439 	int on = 1;
440 	int ttl, probe, i;
441 	int seq = 0;
442 	int tos = 0, settos = 0, ttl_flag = 0;
443 	int lsrr = 0;
444 	u_int16_t off = 0;
445 	struct ifaddrlist *al, *al2;
446 	char errbuf[132];
447 	int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
448 	size_t size = sizeof(max_ttl);
449 
450 	setprogname(argv[0]);
451 	prog = getprogname();
452 
453 	if (prog_init && prog_init() == -1)
454 		err(1, "init failed");
455 
456 	if ((s = prog_socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
457 		err(1, "icmp socket");
458 
459 	/*
460 	 * XXX 'useicmp' will always be zero here. I think the HP-UX users
461 	 * running our traceroute code will forgive us.
462 	 */
463 #ifndef __hpux
464 	sndsock = prog_socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
465 #else
466 	sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW
467 	    useicmp ? IPPROTO_ICMP : IPPROTO_UDP);
468 #endif
469 	if (sndsock < 0)
470 		err(1, "raw socket");
471 
472 	/* Revert to non-privileged user after opening sockets */
473 	setuid(getuid());
474 
475 	(void) prog_sysctl(mib, sizeof(mib)/sizeof(mib[0]), &max_ttl, &size,
476 	    NULL, 0);
477 
478 	opterr = 0;
479 	while ((op = getopt(argc, argv, "aA:dDFPIMnlrvxf:g:i:m:p:q:s:t:w:")) != -1)
480 		switch (op) {
481 
482 		case 'a':
483 			as_path = 1;
484 			break;
485 
486 		case 'A':
487 			as_path = 1;
488 			as_server = optarg;
489 			break;
490 
491 		case 'd':
492 			options |= SO_DEBUG;
493 			break;
494 
495 		case 'D':
496 			dump = 1;
497 			break;
498 
499 		case 'f':
500 			first_ttl = str2val(optarg, "first ttl", 1, 255);
501 			break;
502 
503 		case 'F':
504 			off = IP_DF;
505 			break;
506 
507 		case 'g':
508 			if (lsrr >= NGATEWAYS)
509 				errx(1, "more than %d gateways", NGATEWAYS);
510 			getaddr(gwlist + lsrr, optarg);
511 			++lsrr;
512 			break;
513 
514 		case 'i':
515 			device = optarg;
516 			break;
517 
518 		case 'I':
519 			++useicmp;
520 			break;
521 
522 		case 'l':
523 			++ttl_flag;
524 			break;
525 
526 		case 'm':
527 			max_ttl = str2val(optarg, "max ttl", 1, 255);
528 			break;
529 
530 		case 'M':
531 			Mflag = 1;
532 			break;
533 
534 		case 'n':
535 			++nflag;
536 			break;
537 
538 		case 'p':
539 			port = str2val(optarg, "port", 1, -1);
540 			break;
541 
542 		case 'q':
543 			nprobes = str2val(optarg, "nprobes", 1, -1);
544 			break;
545 
546 		case 'r':
547 			options |= SO_DONTROUTE;
548 			break;
549 
550 		case 's':
551 			/*
552 			 * set the ip source address of the outbound
553 			 * probe (e.g., on a multi-homed host).
554 			 */
555 			source = optarg;
556 			break;
557 
558 		case 't':
559 			tos = str2val(optarg, "tos", 0, 255);
560 			++settos;
561 			break;
562 
563 		case 'v':
564 			++verbose;
565 			break;
566 
567 		case 'x':
568 			docksum = (docksum == 0);
569 			break;
570 
571 		case 'w':
572 			waittime = str2val(optarg, "wait time", 2, 24 * 3600);
573 			break;
574 
575 		case 'P':
576 			off = IP_DF;
577 			mtudisc = 1;
578 			break;
579 
580 		default:
581 			usage();
582 		}
583 
584 	if (first_ttl > max_ttl)
585 		errx(1, "first ttl (%d) may not be greater than max ttl (%d)",
586 		    first_ttl, max_ttl);
587 
588 	if (!docksum)
589 		warnx("ckecksums disabled");
590 
591 	if (lsrr > 0)
592 		optlen = (lsrr + 1) * sizeof(gwlist[0]);
593 	minpacket = sizeof(*outip) + sizeof(struct outdata) + optlen;
594 	if (useicmp)
595 		minpacket += 8;			/* XXX magic number */
596 	else
597 		minpacket += sizeof(*outudp);
598 	if (packlen == 0)
599 		packlen = minpacket;		/* minimum sized packet */
600 	else if (minpacket > packlen || packlen > maxpacket)
601 		errx(1, "packet size must be %d <= s <= %d",
602 		    minpacket, maxpacket);
603 
604 	if (mtudisc)
605 		packlen = *mtuptr++;
606 
607 	/* Process destination and optional packet size */
608 	switch (argc - optind) {
609 
610 	case 2:
611 		packlen = str2val(argv[optind + 1],
612 		    "packet length", minpacket, -1);
613 		/* Fall through */
614 
615 	case 1:
616 		hostname = argv[optind];
617 		hi = gethostinfo(hostname);
618 		setsin(to, hi->addrs[0]);
619 		if (hi->n > 1)
620 			warnx("%s has multiple addresses; using %s",
621 			    hostname, inet_ntoa(to->sin_addr));
622 		hostname = hi->name;
623 		hi->name = NULL;
624 		freehostinfo(hi);
625 		break;
626 
627 	default:
628 		usage();
629 	}
630 
631 #ifdef HAVE_SETLINEBUF
632 	setlinebuf (stdout);
633 #else
634 	setvbuf(stdout, NULL, _IOLBF, 0);
635 #endif
636 
637 	outip = malloc((unsigned)packlen);
638 	if (outip == NULL)
639 		err(1, "malloc");
640 	memset(outip, 0, packlen);
641 
642 	outip->ip_v = IPVERSION;
643 	if (settos)
644 		outip->ip_tos = tos;
645 #ifdef BYTESWAP_IP_LEN
646 	outip->ip_len = htons(packlen);
647 #else
648 	outip->ip_len = packlen;
649 #endif
650 	outip->ip_off = off;
651 	outp = (u_char *)(outip + 1);
652 #ifdef HAVE_RAW_OPTIONS
653 	if (lsrr > 0) {
654 		u_char *optlist;
655 
656 		optlist = outp;
657 		outp += optlen;
658 
659 		/* final hop */
660 		gwlist[lsrr] = to->sin_addr.s_addr;
661 
662 		outip->ip_dst.s_addr = gwlist[0];
663 
664 		/* force 4 byte alignment */
665 		optlist[0] = IPOPT_NOP;
666 		/* loose source route option */
667 		optlist[1] = IPOPT_LSRR;
668 		i = lsrr * sizeof(gwlist[0]);
669 		optlist[2] = i + 3;
670 		/* Pointer to LSRR addresses */
671 		optlist[3] = IPOPT_MINOFF;
672 		memcpy(optlist + 4, gwlist + 1, i);
673 	} else
674 #endif
675 		outip->ip_dst = to->sin_addr;
676 
677 	outip->ip_hl = (outp - (u_char *)outip) >> 2;
678 	ident = htons(arc4random() & 0xffff) | 0x8000;
679 	if (useicmp) {
680 		outip->ip_p = IPPROTO_ICMP;
681 
682 		outicmp = (struct icmp *)outp;
683 		outicmp->icmp_type = ICMP_ECHO;
684 		outicmp->icmp_id = htons(ident);
685 
686 		outmark = outp + 8;	/* XXX magic number */
687 	} else {
688 		outip->ip_p = IPPROTO_UDP;
689 
690 		outudp = (struct udphdr *)outp;
691 		outudp->uh_sport = htons(ident);
692 		outudp->uh_ulen =
693 		    htons((u_int16_t)(packlen - (sizeof(*outip) + optlen)));
694 		outmark = outudp + 1;
695 	}
696 
697 	if (options & SO_DEBUG)
698 		(void)prog_setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on,
699 		    sizeof(on));
700 #ifdef IPSEC
701 #ifdef IPSEC_POLICY_IPSEC
702 	/*
703 	 * do not raise error even if setsockopt fails, kernel may have ipsec
704 	 * turned off.
705 	 */
706 	if (setpolicy(s, "in bypass") < 0)
707 		exit(1);
708 	if (setpolicy(s, "out bypass") < 0)
709 		exit(1);
710 #else
711     {
712 	int level = IPSEC_LEVEL_AVAIL;
713 
714 	(void)prog_setsockopt(s, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level,
715 		sizeof(level));
716 	(void)prog_setsockopt(s, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level,
717 		sizeof(level));
718 #ifdef IP_AUTH_TRANS_LEVEL
719 	(void)prog_setsockopt(s, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level,
720 		sizeof(level));
721 #else
722 	(void)prog_setsockopt(s, IPPROTO_IP, IP_AUTH_LEVEL, &level,
723 		sizeof(level));
724 #endif
725 #ifdef IP_AUTH_NETWORK_LEVEL
726 	(void)prog_setsockopt(s, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level,
727 		sizeof(level));
728 #endif
729     }
730 #endif /*IPSEC_POLICY_IPSEC*/
731 #endif /*IPSEC*/
732 
733 #ifdef IPSEC
734 #ifdef IPSEC_POLICY_IPSEC
735 	/*
736 	 * do not raise error even if setsockopt fails, kernel may have ipsec
737 	 * turned off.
738 	 */
739 	if (setpolicy(sndsock, "in bypass") < 0)
740 		exit(1);
741 	if (setpolicy(sndsock, "out bypass") < 0)
742 		exit(1);
743 #else
744     {
745 	int level = IPSEC_LEVEL_BYPASS;
746 
747 	(void)prog_setsockopt(sndsock, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level,
748 		sizeof(level));
749 	(void)prog_setsockopt(sndsock, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level,
750 		sizeof(level));
751 #ifdef IP_AUTH_TRANS_LEVEL
752 	(void)prog_setsockopt(sndsock, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level,
753 		sizeof(level));
754 #else
755 	(void)prog_setsockopt(sndsock, IPPROTO_IP, IP_AUTH_LEVEL, &level,
756 		sizeof(level));
757 #endif
758 #ifdef IP_AUTH_NETWORK_LEVEL
759 	(void)prog_setsockopt(sndsock, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level,
760 		sizeof(level));
761 #endif
762     }
763 #endif /*IPSEC_POLICY_IPSEC*/
764 #endif /*IPSEC*/
765 
766 #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
767 	if (lsrr > 0) {
768 		u_char optlist[MAX_IPOPTLEN];
769 
770 		/* final hop */
771 		gwlist[lsrr] = to->sin_addr.s_addr;
772 		++lsrr;
773 
774 		/* force 4 byte alignment */
775 		optlist[0] = IPOPT_NOP;
776 		/* loose source route option */
777 		optlist[1] = IPOPT_LSRR;
778 		i = lsrr * sizeof(gwlist[0]);
779 		optlist[2] = i + 3;
780 		/* Pointer to LSRR addresses */
781 		optlist[3] = IPOPT_MINOFF;
782 		memcpy(optlist + 4, gwlist, i);
783 
784 		if ((prog_setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS, optlist,
785 		    i + sizeof(gwlist[0]))) < 0)
786 			err(1, "IP_OPTIONS");
787 	}
788 #endif
789 
790 #ifdef SO_SNDBUF
791 	if (prog_setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packlen,
792 	    sizeof(packlen)) < 0)
793 		err(1, "SO_SNDBUF");
794 #endif
795 #ifdef IP_HDRINCL
796 	if (prog_setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
797 	    sizeof(on)) < 0)
798 		err(1, "IP_HDRINCL");
799 #else
800 #ifdef IP_TOS
801 	if (settos && prog_setsockopt(sndsock, IPPROTO_IP, IP_TOS,
802 	    &tos, sizeof(tos)) < 0)
803 		err(1, "setsockopt tos %d", tos);
804 #endif
805 #endif
806 	if (options & SO_DEBUG)
807 		if (prog_setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, &on,
808 		    sizeof(on)) < 0)
809 			err(1, "setsockopt debug %d", tos);
810 	if (options & SO_DONTROUTE)
811 		if (prog_setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, &on,
812 		    sizeof(on)) < 0)
813 			err(1, "setsockopt dontroute %d", tos);
814 
815 	/* Get the interface address list */
816 	n = ifaddrlist(&al, errbuf, sizeof errbuf);
817 	al2 = al;
818 	if (n < 0)
819 		errx(1, "ifaddrlist (%s)", errbuf);
820 	if (n == 0)
821 		errx(1, "Can't find any network interfaces");
822 
823 	/* Look for a specific device */
824 	if (device != NULL) {
825 		for (i = n; i > 0; --i, ++al2)
826 			if (strcmp(device, al2->device) == 0)
827 				break;
828 		if (i <= 0)
829 			errx(1, "Can't find interface %s", device);
830 	}
831 
832 	/* Determine our source address */
833 	if (source == NULL) {
834 		/*
835 		 * If a device was specified, use the interface address.
836 		 * Otherwise, use the first interface found.
837 		 * Warn if there are more than one.
838 		 */
839 		setsin(from, al2->addr);
840 		if (n > 1 && device == NULL && !find_local_ip(from, to)) {
841 			warnx("Multiple interfaces found; using %s @ %s",
842 			    inet_ntoa(from->sin_addr), al2->device);
843 		}
844 	} else {
845 		hi = gethostinfo(source);
846 		source = hi->name;
847 		hi->name = NULL;
848 		if (device == NULL) {
849 			/*
850 			 * Use the first interface found.
851 			 * Warn if there are more than one.
852 			 */
853 			setsin(from, hi->addrs[0]);
854 			if (hi->n > 1)
855 				warnx("%s has multiple addresses; using %s",
856 				    source, inet_ntoa(from->sin_addr));
857 		} else {
858 			/*
859 			 * Make sure the source specified matches the
860 			 * interface address.
861 			 */
862 			for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
863 				if (*ap == al2->addr)
864 					break;
865 			if (i <= 0)
866 				errx(1, "%s is not on interface %s",
867 				    source, device);
868 			setsin(from, *ap);
869 		}
870 		freehostinfo(hi);
871 	}
872 
873 	/*
874 	 * If not root, make sure source address matches a local interface.
875 	 * (The list of addresses produced by ifaddrlist() automatically
876 	 * excludes interfaces that are marked down and/or loopback.)
877 	 */
878 	if (getuid())  {
879 		al2 = al;
880 		for (i = n; i > 0; --i, ++al2)
881 			if (from->sin_addr.s_addr == al2->addr)
882 			    break;
883 		if (i <= 0)
884 			errx(1, "%s is not a valid local address "
885 			    "and you are not superuser.",
886 			    inet_ntoa(from->sin_addr));
887 	}
888 
889 	outip->ip_src = from->sin_addr;
890 #ifndef IP_HDRINCL
891 	if (bind(sndsock, (struct sockaddr *)from, sizeof(*from)) < 0)
892 		err(1, "bind");
893 #endif
894 
895 	if (as_path) {
896 		asn = as_setup(as_server);
897 		if (asn == NULL) {
898 			warnx("as_setup failed, AS# lookups disabled");
899 			(void)fflush(stderr);
900 			as_path = 0;
901 		}
902 	}
903 
904 	setuid(getuid());
905 	Fprintf(stderr, "%s to %s (%s)",
906 	    prog, hostname, inet_ntoa(to->sin_addr));
907 	if (source)
908 		Fprintf(stderr, " from %s", source);
909 	Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen);
910 	(void)fflush(stderr);
911 
912 	for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
913 		u_int32_t lastaddr = 0;
914 		int got_there = 0;
915 		int unreachable = 0;
916 
917 again:
918 		printed_ttl = 0;
919 		for (probe = 0; probe < nprobes; ++probe) {
920 			int cc;
921 			struct timeval t1, t2;
922 			struct ip *ip;
923 			(void)gettimeofday(&t1, NULL);
924 			if (!useicmp && htons(port + seq + 1) == 0)
925 				seq++;
926 			send_probe(++seq, ttl, &t1);
927 			while ((cc = wait_for_reply(s, from, &t1)) != 0) {
928 				(void)gettimeofday(&t2, NULL);
929 				/*
930 				 * Since we'll be receiving all ICMP
931 				 * messages to this host above, we may
932 				 * never end up with cc=0, so we need
933 				 * an additional termination check.
934 				 */
935 				if (t2.tv_sec - t1.tv_sec > waittime) {
936 					cc = 0;
937 					break;
938 				}
939 				i = packet_ok(packet, cc, from, seq);
940 				/* Skip short packet */
941 				if (i == 0)
942 					continue;
943 				if (from->sin_addr.s_addr != lastaddr) {
944 					print(packet, cc, from);
945 					lastaddr = from->sin_addr.s_addr;
946 				}
947 				ip = (struct ip *)packet;
948 				Printf("  %.3f ms", deltaT(&t1, &t2));
949 				if (ttl_flag)
950 					Printf(" (ttl = %d)", ip->ip_ttl);
951 				if (i == -2) {
952 #ifndef ARCHAIC
953 					if (ip->ip_ttl <= 1)
954 						Printf(" !");
955 #endif
956 					++got_there;
957 					break;
958 				}
959 
960 				/* time exceeded in transit */
961 				if (i == -1)
962 					break;
963 				code = i - 1;
964 				switch (code) {
965 
966 				case ICMP_UNREACH_PORT:
967 #ifndef ARCHAIC
968 					if (ip->ip_ttl <= 1)
969 						Printf(" !");
970 #endif
971 					++got_there;
972 					break;
973 
974 				case ICMP_UNREACH_NET:
975 					++unreachable;
976 					Printf(" !N");
977 					break;
978 
979 				case ICMP_UNREACH_HOST:
980 					++unreachable;
981 					Printf(" !H");
982 					break;
983 
984 				case ICMP_UNREACH_PROTOCOL:
985 					++got_there;
986 					Printf(" !P");
987 					break;
988 
989 				case ICMP_UNREACH_NEEDFRAG:
990 					if (mtudisc) {
991 						frag_err();
992 						goto again;
993 					} else {
994 						++unreachable;
995 						Printf(" !F");
996 					}
997 					break;
998 
999 				case ICMP_UNREACH_SRCFAIL:
1000 					++unreachable;
1001 					Printf(" !S");
1002 					break;
1003 
1004 /* rfc1716 */
1005 #ifndef ICMP_UNREACH_FILTER_PROHIB
1006 #define ICMP_UNREACH_FILTER_PROHIB	13	/* admin prohibited filter */
1007 #endif
1008 				case ICMP_UNREACH_FILTER_PROHIB:
1009 					++unreachable;
1010 					Printf(" !X");
1011 					break;
1012 
1013 				default:
1014 					++unreachable;
1015 					Printf(" !<%d>", code);
1016 					break;
1017 				}
1018 				break;
1019 			}
1020 			if (cc == 0)
1021 				Printf(" *");
1022 			else if (cc && probe == nprobes - 1 && Mflag)
1023 				decode_extensions(packet, cc);
1024 			(void)fflush(stdout);
1025 		}
1026 		putchar('\n');
1027 		if (got_there ||
1028 		    (unreachable > 0 && unreachable >= ((nprobes + 1) / 2)))
1029 			break;
1030 	}
1031 
1032 	if (as_path)
1033 		as_shutdown(asn);
1034 
1035 	exit(0);
1036 }
1037 
1038 static ssize_t
1039 wait_for_reply(int sock, struct sockaddr_in *fromp, struct timeval *tp)
1040 {
1041 	struct pollfd set[1];
1042 	struct timeval now, wait;
1043 	ssize_t cc = 0;
1044 	socklen_t fromlen = sizeof(*fromp);
1045 	int retval;
1046 
1047 	set[0].fd = sock;
1048 	set[0].events = POLLIN;
1049 
1050 	wait.tv_sec = tp->tv_sec + waittime;
1051 	wait.tv_usec = tp->tv_usec;
1052 	(void)gettimeofday(&now, NULL);
1053 	tvsub(&wait, &now);
1054 
1055 	if (wait.tv_sec < 0) {
1056 		wait.tv_sec = 0;
1057 		wait.tv_usec = 0;
1058 	}
1059 
1060 	retval = prog_poll(set, 1, wait.tv_sec * 1000 + wait.tv_usec / 1000);
1061 	if (retval < 0)
1062 		/* If we continue, we probably just flood the remote host. */
1063 		err(1, "poll");
1064 	if (retval > 0)  {
1065 		cc = prog_recvfrom(s, (char *)packet, sizeof(packet), 0,
1066 			    (struct sockaddr *)fromp, &fromlen);
1067 	}
1068 
1069 	return cc;
1070 }
1071 
1072 static void
1073 decode_extensions(unsigned char *buf, int ip_len)
1074 {
1075         struct icmp_ext_cmn_hdr *cmn_hdr;
1076         struct icmp_ext_obj_hdr *obj_hdr;
1077         union {
1078                 struct mpls_header mpls;
1079                 uint32_t mpls_h;
1080         } mpls;
1081         size_t datalen, obj_len;
1082         struct ip *ip;
1083 
1084         ip = (struct ip *)buf;
1085 
1086         if (ip_len < (int)((ip->ip_hl << 2) + ICMP_EXT_OFFSET +
1087 	    sizeof(struct icmp_ext_cmn_hdr))) {
1088 		/*
1089 		 * No support for ICMP extensions on this host
1090 		 */
1091 		return;
1092         }
1093 
1094         /*
1095          * Move forward to the start of the ICMP extensions, if present
1096          */
1097         buf += (ip->ip_hl << 2) + ICMP_EXT_OFFSET;
1098         cmn_hdr = (struct icmp_ext_cmn_hdr *)buf;
1099 
1100         if (cmn_hdr->version != ICMP_EXT_VERSION) {
1101 		/*
1102 		 * Unknown version
1103 		 */
1104 		return;
1105         }
1106 
1107         datalen = ip_len - ((u_char *)cmn_hdr - (u_char *)ip);
1108 
1109         /*
1110          * Check the checksum, cmn_hdr->checksum == 0 means no checksum'ing
1111          * done by sender.
1112          *
1113         * If the checksum is ok, we'll get 0, as the checksum is calculated
1114          * with the checksum field being 0'd.
1115          */
1116         if (ntohs(cmn_hdr->checksum) &&
1117             in_cksum((u_short *)cmn_hdr, datalen)) {
1118 
1119             return;
1120         }
1121 
1122         buf += sizeof(*cmn_hdr);
1123         datalen -= sizeof(*cmn_hdr);
1124 
1125         while (datalen >= sizeof(struct icmp_ext_obj_hdr)) {
1126 		obj_hdr = (struct icmp_ext_obj_hdr *)buf;
1127 		obj_len = ntohs(obj_hdr->length);
1128 
1129 		/*
1130 		 * Sanity check the length field
1131 		 */
1132 		if (obj_len > datalen)
1133 			return;
1134 
1135 		datalen -= obj_len;
1136 
1137 		/*
1138 		 * Move past the object header
1139 		 */
1140 		buf += sizeof(struct icmp_ext_obj_hdr);
1141 		obj_len -= sizeof(struct icmp_ext_obj_hdr);
1142 
1143 		switch (obj_hdr->class_num) {
1144 		case MPLS_STACK_ENTRY_CLASS:
1145 			switch (obj_hdr->c_type) {
1146 			case MPLS_STACK_ENTRY_C_TYPE:
1147 				while (obj_len >= sizeof(uint32_t)) {
1148 					mpls.mpls_h = ntohl(*(uint32_t *)buf);
1149 
1150 					buf += sizeof(uint32_t);
1151 					obj_len -= sizeof(uint32_t);
1152 
1153 					printf(" [MPLS: Label %d Exp %d]",
1154 					    mpls.mpls.label, mpls.mpls.exp);
1155 				}
1156 				if (obj_len > 0) {
1157 					/*
1158 					 * Something went wrong, and we're at
1159 					 * a unknown offset into the packet,
1160 					 * ditch the rest of it.
1161 					 */
1162 					return;
1163 				}
1164 				break;
1165 			default:
1166 				/*
1167 				 * Unknown object, skip past it
1168 				 */
1169 				buf += ntohs(obj_hdr->length) -
1170 				    sizeof(struct icmp_ext_obj_hdr);
1171 				break;
1172 			}
1173 			break;
1174 
1175 		default:
1176 			/*
1177 			 * Unknown object, skip past it
1178 			 */
1179 			buf += ntohs(obj_hdr->length) -
1180 			    sizeof(struct icmp_ext_obj_hdr);
1181 			break;
1182 		}
1183 	}
1184 }
1185 
1186 static void
1187 dump_packet(void)
1188 {
1189 	u_char *p;
1190 	int i;
1191 
1192 	Fprintf(stderr, "packet data:");
1193 
1194 #ifdef __hpux
1195 	for (p = useicmp ? (u_char *)outicmp : (u_char *)outudp, i = 0; i <
1196 	    i < packlen - (sizeof(*outip) + optlen); i++)
1197 #else
1198 	for (p = (u_char *)outip, i = 0; i < packlen; i++)
1199 #endif
1200 	{
1201 		if ((i % 24) == 0)
1202 			Fprintf(stderr, "\n ");
1203 		Fprintf(stderr, " %02x", *p++);
1204 	}
1205 	Fprintf(stderr, "\n");
1206 }
1207 
1208 void
1209 send_probe(int seq, int ttl, struct timeval *tp)
1210 {
1211 	int cc;
1212 	struct udpiphdr * ui;
1213 	int oldmtu = packlen;
1214 
1215 again:
1216 #ifdef BYTESWAP_IP_LEN
1217 	outip->ip_len = htons(packlen);
1218 #else
1219 	outip->ip_len = packlen;
1220 #endif
1221 	outip->ip_ttl = ttl;
1222 #ifndef __hpux
1223 	outip->ip_id = htons(ident + seq);
1224 #endif
1225 
1226 	/*
1227 	 * In most cases, the kernel will recalculate the ip checksum.
1228 	 * But we must do it anyway so that the udp checksum comes out
1229 	 * right.
1230 	 */
1231 	if (docksum) {
1232 		outip->ip_sum =
1233 		    in_cksum((u_int16_t *)outip, sizeof(*outip) + optlen);
1234 		if (outip->ip_sum == 0)
1235 			outip->ip_sum = 0xffff;
1236 	}
1237 
1238 	/* Payload */
1239 	outsetup.seq = seq;
1240 	outsetup.ttl = ttl;
1241 	outsetup.tv.tv32_sec = htonl(tp->tv_sec);
1242 	outsetup.tv.tv32_usec = htonl(tp->tv_usec);
1243 	memcpy(outmark,&outsetup,sizeof(outsetup));
1244 
1245 	if (useicmp)
1246 		outicmp->icmp_seq = htons(seq);
1247 	else
1248 		outudp->uh_dport = htons(port + seq);
1249 
1250 	/* (We can only do the checksum if we know our ip address) */
1251 	if (docksum) {
1252 		if (useicmp) {
1253 			outicmp->icmp_cksum = 0;
1254 			outicmp->icmp_cksum = in_cksum((u_int16_t *)outicmp,
1255 			    packlen - (sizeof(*outip) + optlen));
1256 			if (outicmp->icmp_cksum == 0)
1257 				outicmp->icmp_cksum = 0xffff;
1258 		} else {
1259 			u_int16_t sum;
1260 			struct {
1261 				struct in_addr src;
1262 				struct in_addr dst;
1263 				u_int8_t zero;
1264 				u_int8_t protocol;
1265 				u_int16_t len;
1266 			} __packed phdr;
1267 
1268 			/* Checksum */
1269 			ui = (struct udpiphdr *)outip;
1270 			memset(&phdr, 0, sizeof(phdr));
1271 			phdr.src = ui->ui_src;
1272 			phdr.dst = ((struct sockaddr_in *)&whereto)->sin_addr;
1273 			phdr.protocol = ui->ui_pr;
1274 			phdr.len = outudp->uh_ulen;
1275 			outudp->uh_sum = 0;
1276 			sum = in_cksum2(0, (u_int16_t *)&phdr, sizeof(phdr));
1277 			sum = in_cksum2(sum, (u_int16_t *)outudp, ntohs(outudp->uh_ulen));
1278 			outudp->uh_sum = ~sum;
1279 			if (outudp->uh_sum == 0)
1280 				outudp->uh_sum = 0xffff;
1281 		}
1282 	}
1283 
1284 	/* XXX undocumented debugging hack */
1285 	if (verbose > 1) {
1286 		const u_int16_t *sp;
1287 		int nshorts, i;
1288 
1289 		sp = (u_int16_t *)outip;
1290 		nshorts = (u_int)packlen / sizeof(u_int16_t);
1291 		i = 0;
1292 		Printf("[ %d bytes", packlen);
1293 		while (--nshorts >= 0) {
1294 			if ((i++ % 8) == 0)
1295 				Printf("\n\t");
1296 			Printf(" %04x", ntohs(*sp++));
1297 		}
1298 		if (packlen & 1) {
1299 			if ((i % 8) == 0)
1300 				Printf("\n\t");
1301 			Printf(" %02x", *(const u_char *)sp);
1302 		}
1303 		Printf("]\n");
1304 	}
1305 
1306 #if !defined(IP_HDRINCL) && defined(IP_TTL)
1307 	if (prog_setsockopt(sndsock, IPPROTO_IP, IP_TTL,
1308 	    (char *)&ttl, sizeof(ttl)) < 0)
1309 		err(1, "setsockopt ttl %d", ttl);
1310 #endif
1311 	if (dump)
1312 		dump_packet();
1313 
1314 #ifdef __hpux
1315 	cc = sendto(sndsock, useicmp ? (char *)outicmp : (char *)outudp,
1316 	    packlen - (sizeof(*outip) + optlen), 0, &whereto, sizeof(whereto));
1317 	if (cc > 0)
1318 		cc += sizeof(*outip) + optlen;
1319 #else
1320 	cc = prog_sendto(sndsock, (char *)outip,
1321 	    packlen, 0, &whereto, sizeof(whereto));
1322 #endif
1323 	if (cc < 0 || cc != packlen)  {
1324 		if (cc < 0) {
1325 			/*
1326 			 * An errno of EMSGSIZE means we're writing too big a
1327 			 * datagram for the interface.  We have to just
1328 			 * decrease the packet size until we find one that
1329 			 * works.
1330 			 *
1331 			 * XXX maybe we should try to read the outgoing if's
1332 			 * mtu?
1333 			 */
1334 			if (errno == EMSGSIZE) {
1335 				packlen = *mtuptr++;
1336 				resize_packet();
1337 				goto again;
1338 			} else
1339 				warn("sendto");
1340 		}
1341 
1342 		Printf("%s: wrote %s %d chars, ret=%d\n",
1343 		    prog, hostname, packlen, cc);
1344 		(void)fflush(stdout);
1345 	}
1346 	if (oldmtu != packlen) {
1347 		Printf("message too big, "
1348 		    "trying new MTU = %d\n", packlen);
1349 		printed_ttl = 0;
1350 	}
1351 	if (!printed_ttl) {
1352 		Printf("%2d ", ttl);
1353 		printed_ttl = 1;
1354 	}
1355 
1356 }
1357 
1358 static double
1359 deltaT(struct timeval *t1p, struct timeval *t2p)
1360 {
1361 	double dt;
1362 
1363 	dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1364 	     (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1365 	return dt;
1366 }
1367 
1368 /*
1369  * Convert an ICMP "type" field to a printable string.
1370  */
1371 static const char *
1372 pr_type(u_char t)
1373 {
1374 	static const char *ttab[] = {
1375 	"Echo Reply",	"ICMP 1",	"ICMP 2",	"Dest Unreachable",
1376 	"Source Quench", "Redirect",	"ICMP 6",	"ICMP 7",
1377 	"Echo",		"ICMP 9",	"ICMP 10",	"Time Exceeded",
1378 	"Param Problem", "Timestamp",	"Timestamp Reply", "Info Request",
1379 	"Info Reply"
1380 	};
1381 
1382 	if (t > 16)
1383 		return "OUT-OF-RANGE";
1384 
1385 	return ttab[t];
1386 }
1387 
1388 static int
1389 packet_ok(u_char *buf, ssize_t cc, struct sockaddr_in *from, int seq)
1390 {
1391 	struct icmp *icp;
1392 	u_char type, code;
1393 	int hlen;
1394 #ifndef ARCHAIC
1395 	struct ip *ip;
1396 
1397 	ip = (struct ip *) buf;
1398 	hlen = ip->ip_hl << 2;
1399 	if (cc < hlen + ICMP_MINLEN) {
1400 		if (verbose)
1401 			Printf("packet too short (%zd bytes) from %s\n", cc,
1402 				inet_ntoa(from->sin_addr));
1403 		return 0;
1404 	}
1405 	cc -= hlen;
1406 	icp = (struct icmp *)(buf + hlen);
1407 #else
1408 	icp = (struct icmp *)buf;
1409 #endif
1410 	type = icp->icmp_type;
1411 	code = icp->icmp_code;
1412 	if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
1413 	    type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
1414 		struct ip *hip;
1415 		struct udphdr *up;
1416 		struct icmp *hicmp;
1417 
1418 		hip = &icp->icmp_ip;
1419 		hlen = hip->ip_hl << 2;
1420 
1421 		nextmtu = ntohs(icp->icmp_nextmtu);	/* for frag_err() */
1422 
1423 		if (useicmp) {
1424 			/* XXX */
1425 			if (type == ICMP_ECHOREPLY &&
1426 			    icp->icmp_id == htons(ident) &&
1427 			    icp->icmp_seq == htons(seq))
1428 				return -2;
1429 
1430 			hicmp = (struct icmp *)((u_char *)hip + hlen);
1431 			/* XXX 8 is a magic number */
1432 			if (hlen + 8 <= cc &&
1433 			    hip->ip_p == IPPROTO_ICMP &&
1434 			    hicmp->icmp_id == htons(ident) &&
1435 			    hicmp->icmp_seq == htons(seq))
1436 				return type == ICMP_TIMXCEED ? -1 : code + 1;
1437 		} else {
1438 			up = (struct udphdr *)((u_char *)hip + hlen);
1439 			/* XXX 8 is a magic number */
1440 			if (hlen + 12 <= cc &&
1441 			    hip->ip_p == IPPROTO_UDP &&
1442 			    up->uh_sport == htons(ident) &&
1443 			    up->uh_dport == htons(port + seq))
1444 				return type == ICMP_TIMXCEED ? -1 : code + 1;
1445 		}
1446 	}
1447 #ifndef ARCHAIC
1448 	if (verbose) {
1449 		int i;
1450 		u_int32_t *lp = (u_int32_t *)&icp->icmp_ip;
1451 
1452 		Printf("\n%zd bytes from %s to ", cc, inet_ntoa(from->sin_addr));
1453 		Printf("%s: icmp type %d (%s) code %d\n",
1454 		    inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
1455 		for (i = 4; i < cc ; i += sizeof(*lp))
1456 			Printf("%2d: x%8.8x\n", i, *lp++);
1457 	}
1458 #endif
1459 	return(0);
1460 }
1461 
1462 static void
1463 resize_packet(void)
1464 {
1465 	if (useicmp) {
1466 		outicmp->icmp_cksum = 0;
1467 		outicmp->icmp_cksum = in_cksum((u_int16_t *)outicmp,
1468 		    packlen - (sizeof(*outip) + optlen));
1469 		if (outicmp->icmp_cksum == 0)
1470 			outicmp->icmp_cksum = 0xffff;
1471 	} else {
1472 		outudp->uh_ulen =
1473 		    htons((u_int16_t)(packlen - (sizeof(*outip) + optlen)));
1474 	}
1475 }
1476 
1477 static void
1478 print(u_char *buf, int cc, struct sockaddr_in *from)
1479 {
1480 	struct ip *ip;
1481 	int hlen;
1482 	char addr[INET_ADDRSTRLEN];
1483 
1484 	ip = (struct ip *) buf;
1485 	hlen = ip->ip_hl << 2;
1486 	cc -= hlen;
1487 
1488 	strlcpy(addr, inet_ntoa(from->sin_addr), sizeof(addr));
1489 
1490 	if (as_path)
1491 		Printf(" [AS%u]", as_lookup(asn, addr, AF_INET));
1492 
1493 	if (nflag)
1494 		Printf(" %s", addr);
1495 	else
1496 		Printf(" %s (%s)", inetname(from->sin_addr), addr);
1497 
1498 	if (verbose)
1499 		Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
1500 }
1501 
1502 static u_int16_t
1503 in_cksum(u_int16_t *addr, int len)
1504 {
1505 
1506 	return ~in_cksum2(0, addr, len);
1507 }
1508 
1509 /*
1510  * Checksum routine for Internet Protocol family headers (C Version)
1511  */
1512 static u_int16_t
1513 in_cksum2(u_int16_t seed, u_int16_t *addr, int len)
1514 {
1515 	int nleft = len;
1516 	u_int16_t *w = addr;
1517 	union {
1518 		u_int16_t w;
1519 		u_int8_t b[2];
1520 	} answer;
1521 	int32_t sum = seed;
1522 
1523 	/*
1524 	 *  Our algorithm is simple, using a 32 bit accumulator (sum),
1525 	 *  we add sequential 16 bit words to it, and at the end, fold
1526 	 *  back all the carry bits from the top 16 bits into the lower
1527 	 *  16 bits.
1528 	 */
1529 	while (nleft > 1)  {
1530 		sum += *w++;
1531 		nleft -= 2;
1532 	}
1533 
1534 	/* mop up an odd byte, if necessary */
1535 	if (nleft == 1) {
1536 		answer.b[0] = *(u_char *)w;
1537 		answer.b[1] = 0;
1538 		sum += answer.w;
1539 	}
1540 
1541 	/*
1542 	 * add back carry outs from top 16 bits to low 16 bits
1543 	 */
1544 	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
1545 	sum += (sum >> 16);			/* add carry */
1546 	answer.w = sum;				/* truncate to 16 bits */
1547 	return answer.w;
1548 }
1549 
1550 /*
1551  * Subtract 2 timeval structs:  out = out - in.
1552  * Out is assumed to be >= in.
1553  */
1554 static void
1555 tvsub(struct timeval *out, struct timeval *in)
1556 {
1557 
1558 	if ((out->tv_usec -= in->tv_usec) < 0)   {
1559 		--out->tv_sec;
1560 		out->tv_usec += 1000000;
1561 	}
1562 	out->tv_sec -= in->tv_sec;
1563 }
1564 
1565 /*
1566  * Construct an Internet address representation.
1567  * If the nflag has been supplied, give
1568  * numeric value, otherwise try for symbolic name.
1569  */
1570 static char *
1571 inetname(struct in_addr in)
1572 {
1573 	char *cp;
1574 	struct hostent *hp;
1575 	static int first = 1;
1576 	static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1];
1577 
1578 	if (first && !nflag) {
1579 		int rv;
1580 
1581 		first = 0;
1582 		rv = gethostname(domain, sizeof domain);
1583 		if (rv == 0 && (cp = strchr(domain, '.')) != NULL) {
1584 			(void)strlcpy(domain, cp + 1, sizeof(domain));
1585 		} else
1586 			domain[0] = '\0';
1587 	}
1588 	if (!nflag && in.s_addr != INADDR_ANY) {
1589 		hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
1590 		if (hp != NULL) {
1591 			if ((cp = strchr(hp->h_name, '.')) != NULL &&
1592 			    strcmp(cp + 1, domain) == 0)
1593 				*cp = '\0';
1594 			(void)strlcpy(line, hp->h_name, sizeof(line));
1595 			return line;
1596 		}
1597 	}
1598 	return inet_ntoa(in);
1599 }
1600 
1601 static struct hostinfo *
1602 gethostinfo(char *hname)
1603 {
1604 	int n;
1605 	struct hostent *hp;
1606 	struct hostinfo *hi;
1607 	char **p;
1608 	u_int32_t *ap;
1609 	struct in_addr addr;
1610 
1611 	hi = calloc(1, sizeof(*hi));
1612 	if (hi == NULL)
1613 		err(1, "calloc");
1614 	if (inet_aton(hname, &addr) != 0) {
1615 		hi->name = strdup(hname);
1616 		if (!hi->name)
1617 			err(1, "strdup");
1618 		hi->n = 1;
1619 		hi->addrs = calloc(1, sizeof(hi->addrs[0]));
1620 		if (hi->addrs == NULL)
1621 			err(1, "calloc");
1622 		hi->addrs[0] = addr.s_addr;
1623 		return hi;
1624 	}
1625 
1626 	hp = gethostbyname(hname);
1627 	if (hp == NULL)
1628 		errx(1, "unknown host %s", hname);
1629 	if (hp->h_addrtype != AF_INET || hp->h_length != 4)
1630 		errx(1, "bad host %s", hname);
1631 	hi->name = strdup(hp->h_name);
1632 	if (!hi->name)
1633 		err(1, "strdup");
1634 	for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
1635 		continue;
1636 	hi->n = n;
1637 	hi->addrs = calloc(n, sizeof(hi->addrs[0]));
1638 	if (hi->addrs == NULL)
1639 		err(1, "calloc");
1640 	for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
1641 		memcpy(ap, *p, sizeof(*ap));
1642 	return hi;
1643 }
1644 
1645 static void
1646 freehostinfo(struct hostinfo *hi)
1647 {
1648 	if (hi->name != NULL) {
1649 		free(hi->name);
1650 		hi->name = NULL;
1651 	}
1652 	free(hi->addrs);
1653 	free(hi);
1654 }
1655 
1656 static void
1657 getaddr(u_int32_t *ap, char *hname)
1658 {
1659 	struct hostinfo *hi;
1660 
1661 	hi = gethostinfo(hname);
1662 	*ap = hi->addrs[0];
1663 	freehostinfo(hi);
1664 }
1665 
1666 static void
1667 setsin(struct sockaddr_in *sin, u_int32_t addr)
1668 {
1669 
1670 	memset(sin, 0, sizeof(*sin));
1671 #ifdef HAVE_SOCKADDR_SA_LEN
1672 	sin->sin_len = sizeof(*sin);
1673 #endif
1674 	sin->sin_family = AF_INET;
1675 	sin->sin_addr.s_addr = addr;
1676 }
1677 
1678 /* String to value with optional min and max. Handles decimal and hex. */
1679 static int
1680 str2val(const char *str, const char *what, int mi, int ma)
1681 {
1682 	const char *cp;
1683 	long val;
1684 	char *ep;
1685 
1686 	errno = 0;
1687 	ep = NULL;
1688 	if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
1689 		cp = str + 2;
1690 		val = strtol(cp, &ep, 16);
1691 	} else
1692 		val = strtol(str, &ep, 10);
1693 	if (errno || str[0] == '\0' || *ep != '\0')
1694 		errx(1, "\"%s\" bad value for %s", str, what);
1695 	if (val < mi && mi >= 0) {
1696 		if (mi == 0)
1697 			errx(1, "%s must be >= %d", what, mi);
1698 		else
1699 			errx(1, "%s must be > %d", what, mi - 1);
1700 	}
1701 	if (val > ma && ma >= 0)
1702 		errx(1, "%s must be <= %d", what, ma);
1703 	return (int)val;
1704 }
1705 
1706 __dead void
1707 usage(void)
1708 {
1709 	extern char version[];
1710 
1711 	Fprintf(stderr, "Version %s\n", version);
1712 	Fprintf(stderr, "Usage: %s [-adDFPIlMnrvx] [-g gateway] [-i iface] \
1713 [-f first_ttl]\n\t[-m max_ttl] [-p port] [-q nqueries] [-s src_addr] [-t tos]\n\t\
1714 [-w waittime] [-A as_server] host [packetlen]\n",
1715 	    getprogname());
1716 	exit(1);
1717 }
1718 
1719 /*
1720  * Received ICMP unreachable (fragmentation required and DF set).
1721  * If the ICMP error was from a "new" router, it'll contain the next-hop
1722  * MTU that we should use next.  Otherwise we'll just keep going in the
1723  * mtus[] table, trying until we hit a valid MTU.
1724  */
1725 
1726 
1727 void
1728 frag_err()
1729 {
1730         int i;
1731 
1732         if (nextmtu > 0 && nextmtu < packlen) {
1733                 Printf("\nfragmentation required and DF set, "
1734 		     "next hop MTU = %d\n",
1735                         nextmtu);
1736                 packlen = nextmtu;
1737                 for (i = 0; mtus[i] > 0; i++) {
1738                         if (mtus[i] < nextmtu) {
1739                                 mtuptr = &mtus[i];    /* next one to try */
1740                                 break;
1741                         }
1742                 }
1743         } else {
1744                 Printf("\nfragmentation required and DF set. ");
1745 		if (nextmtu)
1746 			Printf("\nBogus next hop MTU = %d > last MTU = %d. ",
1747 			    nextmtu, packlen);
1748                 packlen = *mtuptr++;
1749 		Printf("Trying new MTU = %d\n", packlen);
1750         }
1751 	resize_packet();
1752 }
1753 
1754 int
1755 find_local_ip(struct sockaddr_in *from, struct sockaddr_in *to)
1756 {
1757 	int sock;
1758 	struct sockaddr_in help;
1759 	socklen_t help_len;
1760 
1761 	sock = prog_socket(AF_INET, SOCK_DGRAM, 0);
1762 	if (sock < 0) return 0;
1763 
1764 	help.sin_family = AF_INET;
1765 	/*
1766 	 * At this point the port number doesn't matter
1767 	 * since it only has to be greater than zero.
1768 	 */
1769 	help.sin_port = 42;
1770 	help.sin_addr.s_addr = to->sin_addr.s_addr;
1771 	if (prog_connect(sock, (struct sockaddr *)&help, sizeof(help)) < 0) {
1772 		(void)prog_close(sock);
1773 		return 0;
1774 	}
1775 
1776 	help_len = sizeof(help);
1777 	if (prog_getsockname(sock, (struct sockaddr *)&help, &help_len) < 0 ||
1778 	    help_len != sizeof(help) ||
1779 	    help.sin_addr.s_addr == INADDR_ANY) {
1780 		(void)prog_close(sock);
1781 		return 0;
1782 	}
1783 
1784 	(void)prog_close(sock);
1785 	setsin(from, help.sin_addr.s_addr);
1786 	return 1;
1787 }
1788 
1789 #ifdef IPSEC
1790 #ifdef IPSEC_POLICY_IPSEC
1791 static int
1792 setpolicy(int so, const char *policy)
1793 {
1794 	char *buf;
1795 
1796 	buf = ipsec_set_policy(policy, strlen(policy));
1797 	if (buf == NULL) {
1798 		warnx("%s", ipsec_strerror());
1799 		return -1;
1800 	}
1801 	(void)prog_setsockopt(so, IPPROTO_IP, IP_IPSEC_POLICY,
1802 		buf, ipsec_get_policylen(buf));
1803 
1804 	free(buf);
1805 
1806 	return 0;
1807 }
1808 #endif
1809 #endif
1810 
1811