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