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