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
27static 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 */
274struct hostinfo {
275	char *name;
276	int n;
277	u_int32_t *addrs;
278};
279
280/* Data section of the probe packet */
281struct 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
303struct 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) */
319struct my_pmtu {
320	u_short ipm_void;
321	u_short ipm_nextmtu;
322};
323#endif
324
325static u_char	packet[512];		/* last inbound (icmp) packet */
326
327static struct ip *outip;		/* last output (udp) packet */
328static struct udphdr *outudp;		/* last output (udp) packet */
329static void *outmark;			/* packed location of struct outdata */
330static struct outdata outsetup;	/* setup and copy for alignment */
331
332static struct icmp *outicmp;		/* last output (icmp) packet */
333
334/* loose source route gateway list (including room for final destination) */
335static u_int32_t gwlist[NGATEWAYS + 1];
336
337static int s;				/* receive (icmp) socket file descriptor */
338static int sndsock;			/* send (udp/icmp) socket file descriptor */
339
340static struct sockaddr whereto;		/* Who to try to reach */
341static struct sockaddr wherefrom;	/* Who we are */
342static int packlen;			/* total length of packet */
343static int minpacket;			/* min ip packet size */
344static int maxpacket = 32 * 1024;	/* max ip packet size */
345static int printed_ttl = 0;
346static int pmtu;			/* Path MTU Discovery (RFC1191) */
347static u_int pausemsecs;
348
349static const char *prog;
350static char *source;
351static char *hostname;
352static char *device;
353#ifdef notdef
354static const char devnull[] = "/dev/null";
355#endif
356
357static int nprobes = 3;
358static int max_ttl = 30;
359static int first_ttl = 1;
360static u_int16_t ident;
361static in_port_t port = 32768 + 666;	/* start udp dest port # for probe packets */
362
363static int options;			/* socket options */
364static int verbose;
365static int waittime = 5;		/* time to wait for response (in seconds) */
366static int nflag;			/* print addresses numerically */
367static int dump;
368static int Mflag;			/* show MPLS labels if any */
369static int as_path;			/* print as numbers for each hop */
370static char *as_server = NULL;
371static void *asn;
372static int useicmp = 0;		/* use icmp echo instead of udp packets */
373#ifdef CANT_HACK_CKSUM
374static int doipcksum = 0;		/* don't calculate checksums */
375#else
376static int doipcksum = 1;		/* calculate checksums */
377#endif
378static int optlen;			/* length of ip options */
379
380static 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};
402static int *mtuptr = &mtus[0];
403static int mtudisc = 0;
404static int nextmtu;   /* from ICMP error, set by packet_ok(), might be 0 */
405
406/* Forwards */
407static double deltaT(struct timeval *, struct timeval *);
408static void freehostinfo(struct hostinfo *);
409static void getaddr(u_int32_t *, char *);
410static struct hostinfo *gethostinfo(char *);
411static u_int16_t in_cksum(u_int16_t *, int);
412static u_int16_t in_cksum2(u_int16_t, u_int16_t *, int);
413static char *inetname(struct in_addr);
414static int packet_ok(u_char *, ssize_t, struct sockaddr_in *, int);
415static const char *pr_type(u_char);
416static void print(u_char *, int, struct sockaddr_in *);
417static void resize_packet(void);
418static void dump_packet(void);
419static void send_probe(int, int, struct timeval *);
420static void setsin(struct sockaddr_in *, u_int32_t);
421static int str2val(const char *, const char *, int, int);
422static void tvsub(struct timeval *, struct timeval *);
423static void usage(void) __attribute__((__noreturn__));
424static ssize_t wait_for_reply(int, struct sockaddr_in *, const struct timeval *);
425static void decode_extensions(unsigned char *buf, int ip_len);
426static void frag_err(void);
427static int find_local_ip(struct sockaddr_in *, struct sockaddr_in *);
428#ifdef IPSEC
429#ifdef IPSEC_POLICY_IPSEC
430static int setpolicy(int, const char *);
431#endif
432#endif
433
434int
435main(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
936again:
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
1069static ssize_t
1070wait_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
1103static void
1104decode_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
1217static void
1218dump_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
1239void
1240send_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
1247again:
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
1381static double
1382deltaT(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 */
1394static const char *
1395pr_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
1411static int
1412packet_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
1495static void
1496resize_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
1510static void
1511print(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
1535static u_int16_t
1536in_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 */
1545static u_int16_t
1546in_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 */
1587static void
1588tvsub(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 */
1603static char *
1604inetname(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
1644static struct hostinfo *
1645gethostinfo(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
1688static void
1689freehostinfo(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
1699static void
1700getaddr(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
1709static void
1710setsin(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. */
1722static int
1723str2val(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
1750usage(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
1770void
1771frag_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
1797int
1798find_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
1834static int
1835setpolicy(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