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