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