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/sctp.h>
223#include <netinet/udp.h>
224#include <netinet/tcp.h>
225#include <netinet/tcpip.h>
226
227#include <arpa/inet.h>
228
229#ifdef	IPSEC
230#include <net/route.h>
231#include <netipsec/ipsec.h>	/* XXX */
232#endif	/* IPSEC */
233
234#include <ctype.h>
235#include <err.h>
236#include <errno.h>
237#include <fcntl.h>
238#ifdef HAVE_MALLOC_H
239#include <malloc.h>
240#endif
241#include <memory.h>
242#include <netdb.h>
243#include <stdio.h>
244#include <stdlib.h>
245#include <string.h>
246#include <unistd.h>
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 "findsaddr.h"
260#include "ifaddrlist.h"
261#include "as.h"
262#include "traceroute.h"
263
264/* Maximum number of gateways (include room for one noop) */
265#define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(u_int32_t)))
266
267#ifndef MAXHOSTNAMELEN
268#define MAXHOSTNAMELEN	64
269#endif
270
271#define Fprintf (void)fprintf
272#define Printf (void)printf
273
274/* What a GRE packet header looks like */
275struct grehdr {
276	u_int16_t   flags;
277	u_int16_t   proto;
278	u_int16_t   length;	/* PPTP version of these fields */
279	u_int16_t   callId;
280};
281#ifndef IPPROTO_GRE
282#define IPPROTO_GRE	47
283#endif
284
285/* For GRE, we prepare what looks like a PPTP packet */
286#define GRE_PPTP_PROTO	0x880b
287
288/* Host name and address list */
289struct hostinfo {
290	char *name;
291	int n;
292	u_int32_t *addrs;
293};
294
295/* Data section of the probe packet */
296struct outdata {
297	u_char seq;		/* sequence number of this packet */
298	u_char ttl;		/* ttl packet left with */
299	struct timeval tv;	/* time packet left */
300};
301
302#ifndef HAVE_ICMP_NEXTMTU
303/* Path MTU Discovery (RFC1191) */
304struct my_pmtu {
305	u_short ipm_void;
306	u_short ipm_nextmtu;
307};
308#endif
309
310u_char	packet[512];		/* last inbound (icmp) packet */
311
312struct ip *outip;		/* last output ip packet */
313u_char *outp;		/* last output inner protocol packet */
314
315struct ip *hip = NULL;		/* Quoted IP header */
316int hiplen = 0;
317
318/* loose source route gateway list (including room for final destination) */
319u_int32_t gwlist[NGATEWAYS + 1];
320
321int s;				/* receive (icmp) socket file descriptor */
322int sndsock;			/* send (udp) socket file descriptor */
323
324struct sockaddr whereto;	/* Who to try to reach */
325struct sockaddr wherefrom;	/* Who we are */
326int packlen;			/* total length of packet */
327int protlen;			/* length of protocol part of packet */
328int minpacket;			/* min ip packet size */
329int maxpacket = 32 * 1024;	/* max ip packet size */
330int pmtu;			/* Path MTU Discovery (RFC1191) */
331u_int pausemsecs;
332
333char *prog;
334char *source;
335char *hostname;
336char *device;
337static const char devnull[] = "/dev/null";
338
339int nprobes = -1;
340int max_ttl;
341int first_ttl = 1;
342u_short ident;
343u_short port;			/* protocol specific base "port" */
344
345int options;			/* socket options */
346int verbose;
347int waittime = 5;		/* time to wait for response (in seconds) */
348int nflag;			/* print addresses numerically */
349int as_path;			/* print as numbers for each hop */
350char *as_server = NULL;
351void *asn;
352#ifdef CANT_HACK_IPCKSUM
353int doipcksum = 0;		/* don't calculate ip checksums by default */
354#else
355int doipcksum = 1;		/* calculate ip checksums by default */
356#endif
357int optlen;			/* length of ip options */
358int fixedPort = 0;		/* Use fixed destination port for TCP and UDP */
359int printdiff = 0;		/* Print the difference between sent and quoted */
360
361extern int optind;
362extern int opterr;
363extern char *optarg;
364
365/* Forwards */
366double	deltaT(struct timeval *, struct timeval *);
367void	freehostinfo(struct hostinfo *);
368void	getaddr(u_int32_t *, char *);
369struct	hostinfo *gethostinfo(char *);
370u_short	in_cksum(u_short *, int);
371u_int32_t sctp_crc32c(const void *, u_int32_t);
372char	*inetname(struct in_addr);
373int	main(int, char **);
374u_short p_cksum(struct ip *, u_short *, int, int);
375int	packet_ok(u_char *, int, struct sockaddr_in *, int);
376char	*pr_type(u_char);
377void	print(u_char *, int, struct sockaddr_in *);
378#ifdef	IPSEC
379int	setpolicy __P((int so, char *policy));
380#endif
381void	send_probe(int, int);
382struct outproto *setproto(char *);
383int	str2val(const char *, const char *, int, int);
384void	tvsub(struct timeval *, struct timeval *);
385void usage(void);
386int	wait_for_reply(int, struct sockaddr_in *, const struct timeval *);
387void pkt_compare(const u_char *, int, const u_char *, int);
388#ifndef HAVE_USLEEP
389int	usleep(u_int);
390#endif
391
392void	udp_prep(struct outdata *);
393int	udp_check(const u_char *, int);
394void	udplite_prep(struct outdata *);
395int	udplite_check(const u_char *, int);
396void	tcp_prep(struct outdata *);
397int	tcp_check(const u_char *, int);
398void	sctp_prep(struct outdata *);
399int	sctp_check(const u_char *, int);
400void	gre_prep(struct outdata *);
401int	gre_check(const u_char *, int);
402void	gen_prep(struct outdata *);
403int	gen_check(const u_char *, int);
404void	icmp_prep(struct outdata *);
405int	icmp_check(const u_char *, int);
406
407/* Descriptor structure for each outgoing protocol we support */
408struct outproto {
409	char	*name;		/* name of protocol */
410	const char *key;	/* An ascii key for the bytes of the header */
411	u_char	num;		/* IP protocol number */
412	u_short	hdrlen;		/* max size of protocol header */
413	u_short	port;		/* default base protocol-specific "port" */
414	void	(*prepare)(struct outdata *);
415				/* finish preparing an outgoing packet */
416	int	(*check)(const u_char *, int);
417				/* check an incoming packet */
418};
419
420/* List of supported protocols. The first one is the default. The last
421   one is the handler for generic protocols not explicitly listed. */
422struct	outproto protos[] = {
423	{
424		"udp",
425		"spt dpt len sum",
426		IPPROTO_UDP,
427		sizeof(struct udphdr),
428		32768 + 666,
429		udp_prep,
430		udp_check
431	},
432	{
433		"udplite",
434		"spt dpt cov sum",
435		IPPROTO_UDPLITE,
436		sizeof(struct udphdr),
437		32768 + 666,
438		udplite_prep,
439		udplite_check
440	},
441	{
442		"tcp",
443		"spt dpt seq     ack     xxflwin sum urp",
444		IPPROTO_TCP,
445		sizeof(struct tcphdr),
446		32768 + 666,
447		tcp_prep,
448		tcp_check
449	},
450	{
451		"sctp",
452		"spt dpt vtag    crc     tyfllen tyfllen ",
453		IPPROTO_SCTP,
454		sizeof(struct sctphdr),
455		32768 + 666,
456		sctp_prep,
457		sctp_check
458	},
459	{
460		"gre",
461		"flg pro len clid",
462		IPPROTO_GRE,
463		sizeof(struct grehdr),
464		GRE_PPTP_PROTO,
465		gre_prep,
466		gre_check
467	},
468	{
469		"icmp",
470		"typ cod sum ",
471		IPPROTO_ICMP,
472		sizeof(struct icmp),
473		0,
474		icmp_prep,
475		icmp_check
476	},
477	{
478		NULL,
479		"",
480		0,
481		2 * sizeof(u_short),
482		0,
483		gen_prep,
484		gen_check
485	},
486};
487struct	outproto *proto = &protos[0];
488
489const char *ip_hdr_key = "vhtslen id  off tlprsum srcip   dstip   opts";
490
491int
492main(int argc, char **argv)
493{
494	register int op, code, n;
495	register char *cp;
496	register const char *err;
497	register u_int32_t *ap;
498	register struct sockaddr_in *from = (struct sockaddr_in *)&wherefrom;
499	register struct sockaddr_in *to = (struct sockaddr_in *)&whereto;
500	register struct hostinfo *hi;
501	int on = 1;
502	register struct protoent *pe;
503	register int ttl, probe, i;
504	register int seq = 0;
505	int tos = 0, settos = 0;
506	register int lsrr = 0;
507	register u_short off = 0;
508	struct ifaddrlist *al;
509	char errbuf[132];
510	int requestPort = -1;
511	int sump = 0;
512	int sockerrno;
513
514	/* Insure the socket fds won't be 0, 1 or 2 */
515	if (open(devnull, O_RDONLY) < 0 ||
516	    open(devnull, O_RDONLY) < 0 ||
517	    open(devnull, O_RDONLY) < 0) {
518		Fprintf(stderr, "%s: open \"%s\": %s\n",
519		    prog, devnull, strerror(errno));
520		exit(1);
521	}
522	/*
523	 * Do the setuid-required stuff first, then lose priveleges ASAP.
524	 * Do error checking for these two calls where they appeared in
525	 * the original code.
526	 */
527	cp = "icmp";
528	pe = getprotobyname(cp);
529	if (pe) {
530		if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0)
531			sockerrno = errno;
532		else if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
533			sockerrno = errno;
534	}
535
536	if (setuid(getuid()) != 0) {
537		perror("setuid()");
538		exit(1);
539	}
540
541#ifdef IPCTL_DEFTTL
542	{
543		int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
544		size_t sz = sizeof(max_ttl);
545
546		if (sysctl(mib, 4, &max_ttl, &sz, NULL, 0) == -1) {
547			perror("sysctl(net.inet.ip.ttl)");
548			exit(1);
549		}
550	}
551#else
552	max_ttl = 30;
553#endif
554
555	if (argv[0] == NULL)
556		prog = "traceroute";
557	else if ((cp = strrchr(argv[0], '/')) != NULL)
558		prog = cp + 1;
559	else
560		prog = argv[0];
561
562	opterr = 0;
563	while ((op = getopt(argc, argv, "aA:edDFInrSvxf:g:i:M:m:P:p:q:s:t:w:z:")) != EOF)
564		switch (op) {
565		case 'a':
566			as_path = 1;
567			break;
568
569		case 'A':
570			as_path = 1;
571			as_server = optarg;
572			break;
573
574		case 'd':
575			options |= SO_DEBUG;
576			break;
577
578		case 'D':
579			printdiff = 1;
580			break;
581
582		case 'e':
583			fixedPort = 1;
584			break;
585
586		case 'f':
587		case 'M':	/* FreeBSD compat. */
588			first_ttl = str2val(optarg, "first ttl", 1, 255);
589			break;
590
591		case 'F':
592			off = IP_DF;
593			break;
594
595		case 'g':
596			if (lsrr >= NGATEWAYS) {
597				Fprintf(stderr,
598				    "%s: No more than %d gateways\n",
599				    prog, NGATEWAYS);
600				exit(1);
601			}
602			getaddr(gwlist + lsrr, optarg);
603			++lsrr;
604			break;
605
606		case 'i':
607			device = optarg;
608			break;
609
610		case 'I':
611			proto = setproto("icmp");
612			break;
613
614		case 'm':
615			max_ttl = str2val(optarg, "max ttl", 1, 255);
616			break;
617
618		case 'n':
619			++nflag;
620			break;
621
622		case 'P':
623			proto = setproto(optarg);
624			break;
625
626		case 'p':
627			requestPort = (u_short)str2val(optarg, "port",
628			    1, (1 << 16) - 1);
629			break;
630
631		case 'q':
632			nprobes = str2val(optarg, "nprobes", 1, -1);
633			break;
634
635		case 'r':
636			options |= SO_DONTROUTE;
637			break;
638
639		case 's':
640			/*
641			 * set the ip source address of the outbound
642			 * probe (e.g., on a multi-homed host).
643			 */
644			source = optarg;
645			break;
646
647		case 'S':
648			sump = 1;
649			break;
650
651		case 't':
652			tos = str2val(optarg, "tos", 0, 255);
653			++settos;
654			break;
655
656		case 'v':
657			++verbose;
658			break;
659
660		case 'x':
661			doipcksum = (doipcksum == 0);
662			break;
663
664		case 'w':
665			waittime = str2val(optarg, "wait time",
666			    1, 24 * 60 * 60);
667			break;
668
669		case 'z':
670			pausemsecs = str2val(optarg, "pause msecs",
671			    0, 60 * 60 * 1000);
672			break;
673
674		default:
675			usage();
676		}
677
678	/* Set requested port, if any, else default for this protocol */
679	port = (requestPort != -1) ? requestPort : proto->port;
680
681	if (nprobes == -1)
682		nprobes = printdiff ? 1 : 3;
683
684	if (first_ttl > max_ttl) {
685		Fprintf(stderr,
686		    "%s: first ttl (%d) may not be greater than max ttl (%d)\n",
687		    prog, first_ttl, max_ttl);
688		exit(1);
689	}
690
691	if (!doipcksum)
692		Fprintf(stderr, "%s: Warning: ip checksums disabled\n", prog);
693
694	if (lsrr > 0)
695		optlen = (lsrr + 1) * sizeof(gwlist[0]);
696	minpacket = sizeof(*outip) + proto->hdrlen + optlen;
697	if (minpacket > 40)
698		packlen = minpacket;
699	else
700		packlen = 40;
701
702	/* Process destination and optional packet size */
703	switch (argc - optind) {
704
705	case 2:
706		packlen = str2val(argv[optind + 1],
707		    "packet length", minpacket, maxpacket);
708		/* Fall through */
709
710	case 1:
711		hostname = argv[optind];
712		hi = gethostinfo(hostname);
713		setsin(to, hi->addrs[0]);
714		if (hi->n > 1)
715			Fprintf(stderr,
716		    "%s: Warning: %s has multiple addresses; using %s\n",
717				prog, hostname, inet_ntoa(to->sin_addr));
718		hostname = hi->name;
719		hi->name = NULL;
720		freehostinfo(hi);
721		break;
722
723	default:
724		usage();
725	}
726
727#ifdef HAVE_SETLINEBUF
728	setlinebuf (stdout);
729#else
730	setvbuf(stdout, NULL, _IOLBF, 0);
731#endif
732
733	protlen = packlen - sizeof(*outip) - optlen;
734	if ((proto->num == IPPROTO_SCTP) && (packlen & 3)) {
735		Fprintf(stderr, "%s: packet length must be a multiple of 4\n",
736		    prog);
737		exit(1);
738	}
739
740	outip = (struct ip *)malloc((unsigned)packlen);
741	if (outip == NULL) {
742		Fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno));
743		exit(1);
744	}
745	memset((char *)outip, 0, packlen);
746
747	outip->ip_v = IPVERSION;
748	if (settos)
749		outip->ip_tos = tos;
750#ifdef BYTESWAP_IP_HDR
751	outip->ip_len = htons(packlen);
752	outip->ip_off = htons(off);
753#else
754	outip->ip_len = packlen;
755	outip->ip_off = off;
756#endif
757	outip->ip_p = proto->num;
758	outp = (u_char *)(outip + 1);
759#ifdef HAVE_RAW_OPTIONS
760	if (lsrr > 0) {
761		register u_char *optlist;
762
763		optlist = outp;
764		outp += optlen;
765
766		/* final hop */
767		gwlist[lsrr] = to->sin_addr.s_addr;
768
769		outip->ip_dst.s_addr = gwlist[0];
770
771		/* force 4 byte alignment */
772		optlist[0] = IPOPT_NOP;
773		/* loose source route option */
774		optlist[1] = IPOPT_LSRR;
775		i = lsrr * sizeof(gwlist[0]);
776		optlist[2] = i + 3;
777		/* Pointer to LSRR addresses */
778		optlist[3] = IPOPT_MINOFF;
779		memcpy(optlist + 4, gwlist + 1, i);
780	} else
781#endif
782		outip->ip_dst = to->sin_addr;
783
784	outip->ip_hl = (outp - (u_char *)outip) >> 2;
785	ident = (getpid() & 0xffff) | 0x8000;
786
787	if (pe == NULL) {
788		Fprintf(stderr, "%s: unknown protocol %s\n", prog, cp);
789		exit(1);
790	}
791	if (s < 0) {
792		errno = sockerrno;
793		Fprintf(stderr, "%s: icmp socket: %s\n", prog, strerror(errno));
794		exit(1);
795	}
796	if (options & SO_DEBUG)
797		(void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on,
798		    sizeof(on));
799	if (options & SO_DONTROUTE)
800		(void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
801		    sizeof(on));
802
803#if	defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
804	if (setpolicy(s, "in bypass") < 0)
805		errx(1, "%s", ipsec_strerror());
806
807	if (setpolicy(s, "out bypass") < 0)
808		errx(1, "%s", ipsec_strerror());
809#endif	/* defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) */
810
811	if (sndsock < 0) {
812		errno = sockerrno;
813		Fprintf(stderr, "%s: raw socket: %s\n", prog, strerror(errno));
814		exit(1);
815	}
816
817#if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
818	if (lsrr > 0) {
819		u_char optlist[MAX_IPOPTLEN];
820
821		cp = "ip";
822		if ((pe = getprotobyname(cp)) == NULL) {
823			Fprintf(stderr, "%s: unknown protocol %s\n", prog, cp);
824			exit(1);
825		}
826
827		/* final hop */
828		gwlist[lsrr] = to->sin_addr.s_addr;
829		++lsrr;
830
831		/* force 4 byte alignment */
832		optlist[0] = IPOPT_NOP;
833		/* loose source route option */
834		optlist[1] = IPOPT_LSRR;
835		i = lsrr * sizeof(gwlist[0]);
836		optlist[2] = i + 3;
837		/* Pointer to LSRR addresses */
838		optlist[3] = IPOPT_MINOFF;
839		memcpy(optlist + 4, gwlist, i);
840
841		if ((setsockopt(sndsock, pe->p_proto, IP_OPTIONS,
842		    (char *)optlist, i + sizeof(gwlist[0]))) < 0) {
843			Fprintf(stderr, "%s: IP_OPTIONS: %s\n",
844			    prog, strerror(errno));
845			exit(1);
846		    }
847	}
848#endif
849
850#ifdef SO_SNDBUF
851	if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packlen,
852	    sizeof(packlen)) < 0) {
853		Fprintf(stderr, "%s: SO_SNDBUF: %s\n", prog, strerror(errno));
854		exit(1);
855	}
856#endif
857#ifdef IP_HDRINCL
858	if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
859	    sizeof(on)) < 0) {
860		Fprintf(stderr, "%s: IP_HDRINCL: %s\n", prog, strerror(errno));
861		exit(1);
862	}
863#else
864#ifdef IP_TOS
865	if (settos && setsockopt(sndsock, IPPROTO_IP, IP_TOS,
866	    (char *)&tos, sizeof(tos)) < 0) {
867		Fprintf(stderr, "%s: setsockopt tos %d: %s\n",
868		    prog, tos, strerror(errno));
869		exit(1);
870	}
871#endif
872#endif
873	if (options & SO_DEBUG)
874		(void)setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on,
875		    sizeof(on));
876	if (options & SO_DONTROUTE)
877		(void)setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
878		    sizeof(on));
879
880	/* Get the interface address list */
881	n = ifaddrlist(&al, errbuf);
882	if (n < 0) {
883		Fprintf(stderr, "%s: ifaddrlist: %s\n", prog, errbuf);
884		exit(1);
885	}
886	if (n == 0) {
887		Fprintf(stderr,
888		    "%s: Can't find any network interfaces\n", prog);
889		exit(1);
890	}
891
892	/* Look for a specific device */
893	if (device != NULL) {
894		for (i = n; i > 0; --i, ++al)
895			if (strcmp(device, al->device) == 0)
896				break;
897		if (i <= 0) {
898			Fprintf(stderr, "%s: Can't find interface %.32s\n",
899			    prog, device);
900			exit(1);
901		}
902	}
903
904	/* Determine our source address */
905	if (source == NULL) {
906		/*
907		 * If a device was specified, use the interface address.
908		 * Otherwise, try to determine our source address.
909		 */
910		if (device != NULL)
911			setsin(from, al->addr);
912		else if ((err = findsaddr(to, from)) != NULL) {
913			Fprintf(stderr, "%s: findsaddr: %s\n",
914			    prog, err);
915			exit(1);
916		}
917	} else {
918		hi = gethostinfo(source);
919		source = hi->name;
920		hi->name = NULL;
921		/*
922		 * If the device was specified make sure it
923		 * corresponds to the source address specified.
924		 * Otherwise, use the first address (and warn if
925		 * there are more than one).
926		 */
927		if (device != NULL) {
928			for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
929				if (*ap == al->addr)
930					break;
931			if (i <= 0) {
932				Fprintf(stderr,
933				    "%s: %s is not on interface %.32s\n",
934				    prog, source, device);
935				exit(1);
936			}
937			setsin(from, *ap);
938		} else {
939			setsin(from, hi->addrs[0]);
940			if (hi->n > 1)
941				Fprintf(stderr,
942			"%s: Warning: %s has multiple addresses; using %s\n",
943				    prog, source, inet_ntoa(from->sin_addr));
944		}
945		freehostinfo(hi);
946	}
947
948	outip->ip_src = from->sin_addr;
949
950	/* Check the source address (-s), if any, is valid */
951	if (bind(sndsock, (struct sockaddr *)from, sizeof(*from)) < 0) {
952		Fprintf(stderr, "%s: bind: %s\n",
953		    prog, strerror(errno));
954		exit (1);
955	}
956
957	if (as_path) {
958		asn = as_setup(as_server);
959		if (asn == NULL) {
960			Fprintf(stderr, "%s: as_setup failed, AS# lookups"
961			    " disabled\n", prog);
962			(void)fflush(stderr);
963			as_path = 0;
964		}
965	}
966
967#if	defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
968	if (setpolicy(sndsock, "in bypass") < 0)
969		errx(1, "%s", ipsec_strerror());
970
971	if (setpolicy(sndsock, "out bypass") < 0)
972		errx(1, "%s", ipsec_strerror());
973#endif	/* defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) */
974
975	Fprintf(stderr, "%s to %s (%s)",
976	    prog, hostname, inet_ntoa(to->sin_addr));
977	if (source)
978		Fprintf(stderr, " from %s", source);
979	Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen);
980	(void)fflush(stderr);
981
982	for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
983		u_int32_t lastaddr = 0;
984		int gotlastaddr = 0;
985		int got_there = 0;
986		int unreachable = 0;
987		int sentfirst = 0;
988		int loss;
989
990		Printf("%2d ", ttl);
991		for (probe = 0, loss = 0; probe < nprobes; ++probe) {
992			register int cc;
993			struct timeval t1, t2;
994			register struct ip *ip;
995			struct outdata outdata;
996
997			if (sentfirst && pausemsecs > 0)
998				usleep(pausemsecs * 1000);
999			/* Prepare outgoing data */
1000			outdata.seq = ++seq;
1001			outdata.ttl = ttl;
1002
1003			/* Avoid alignment problems by copying bytewise: */
1004			(void)gettimeofday(&t1, NULL);
1005			memcpy(&outdata.tv, &t1, sizeof(outdata.tv));
1006
1007			/* Finalize and send packet */
1008			(*proto->prepare)(&outdata);
1009			send_probe(seq, ttl);
1010			++sentfirst;
1011
1012			/* Wait for a reply */
1013			while ((cc = wait_for_reply(s, from, &t1)) != 0) {
1014				double T;
1015				int precis;
1016
1017				(void)gettimeofday(&t2, NULL);
1018				i = packet_ok(packet, cc, from, seq);
1019				/* Skip short packet */
1020				if (i == 0)
1021					continue;
1022				if (!gotlastaddr ||
1023				    from->sin_addr.s_addr != lastaddr) {
1024					if (gotlastaddr) printf("\n   ");
1025					print(packet, cc, from);
1026					lastaddr = from->sin_addr.s_addr;
1027					++gotlastaddr;
1028				}
1029				T = deltaT(&t1, &t2);
1030#ifdef SANE_PRECISION
1031				if (T >= 1000.0)
1032					precis = 0;
1033				else if (T >= 100.0)
1034					precis = 1;
1035				else if (T >= 10.0)
1036					precis = 2;
1037				else
1038#endif
1039					precis = 3;
1040				Printf("  %.*f ms", precis, T);
1041				if (printdiff) {
1042					Printf("\n");
1043					Printf("%*.*s%s\n",
1044					    -(outip->ip_hl << 3),
1045					    outip->ip_hl << 3,
1046					    ip_hdr_key,
1047					    proto->key);
1048					pkt_compare((void *)outip, packlen,
1049					    (void *)hip, hiplen);
1050				}
1051				if (i == -2) {
1052#ifndef ARCHAIC
1053					ip = (struct ip *)packet;
1054					if (ip->ip_ttl <= 1)
1055						Printf(" !");
1056#endif
1057					++got_there;
1058					break;
1059				}
1060				/* time exceeded in transit */
1061				if (i == -1)
1062					break;
1063				code = i - 1;
1064				switch (code) {
1065
1066				case ICMP_UNREACH_PORT:
1067#ifndef ARCHAIC
1068					ip = (struct ip *)packet;
1069					if (ip->ip_ttl <= 1)
1070						Printf(" !");
1071#endif
1072					++got_there;
1073					break;
1074
1075				case ICMP_UNREACH_NET:
1076					++unreachable;
1077					Printf(" !N");
1078					break;
1079
1080				case ICMP_UNREACH_HOST:
1081					++unreachable;
1082					Printf(" !H");
1083					break;
1084
1085				case ICMP_UNREACH_PROTOCOL:
1086					++got_there;
1087					Printf(" !P");
1088					break;
1089
1090				case ICMP_UNREACH_NEEDFRAG:
1091					++unreachable;
1092					Printf(" !F-%d", pmtu);
1093					break;
1094
1095				case ICMP_UNREACH_SRCFAIL:
1096					++unreachable;
1097					Printf(" !S");
1098					break;
1099
1100				case ICMP_UNREACH_NET_UNKNOWN:
1101					++unreachable;
1102					Printf(" !U");
1103					break;
1104
1105				case ICMP_UNREACH_HOST_UNKNOWN:
1106					++unreachable;
1107					Printf(" !W");
1108					break;
1109
1110				case ICMP_UNREACH_ISOLATED:
1111					++unreachable;
1112					Printf(" !I");
1113					break;
1114
1115				case ICMP_UNREACH_NET_PROHIB:
1116					++unreachable;
1117					Printf(" !A");
1118					break;
1119
1120				case ICMP_UNREACH_HOST_PROHIB:
1121					++unreachable;
1122					Printf(" !Z");
1123					break;
1124
1125				case ICMP_UNREACH_TOSNET:
1126					++unreachable;
1127					Printf(" !Q");
1128					break;
1129
1130				case ICMP_UNREACH_TOSHOST:
1131					++unreachable;
1132					Printf(" !T");
1133					break;
1134
1135				case ICMP_UNREACH_FILTER_PROHIB:
1136					++unreachable;
1137					Printf(" !X");
1138					break;
1139
1140				case ICMP_UNREACH_HOST_PRECEDENCE:
1141					++unreachable;
1142					Printf(" !V");
1143					break;
1144
1145				case ICMP_UNREACH_PRECEDENCE_CUTOFF:
1146					++unreachable;
1147					Printf(" !C");
1148					break;
1149
1150				default:
1151					++unreachable;
1152					Printf(" !<%d>", code);
1153					break;
1154				}
1155				break;
1156			}
1157			if (cc == 0) {
1158				loss++;
1159				Printf(" *");
1160			}
1161			(void)fflush(stdout);
1162		}
1163		if (sump) {
1164			Printf(" (%d%% loss)", (loss * 100) / nprobes);
1165		}
1166		putchar('\n');
1167		if (got_there ||
1168		    (unreachable > 0 && unreachable >= nprobes - 1))
1169			break;
1170	}
1171	if (as_path)
1172		as_shutdown(asn);
1173	exit(0);
1174}
1175
1176int
1177wait_for_reply(register int sock, register struct sockaddr_in *fromp,
1178    register const struct timeval *tp)
1179{
1180	fd_set *fdsp;
1181	size_t nfds;
1182	struct timeval now, wait;
1183	register int cc = 0;
1184	register int error;
1185	int fromlen = sizeof(*fromp);
1186
1187	nfds = howmany(sock + 1, NFDBITS);
1188	if ((fdsp = malloc(nfds * sizeof(fd_mask))) == NULL)
1189		err(1, "malloc");
1190	memset(fdsp, 0, nfds * sizeof(fd_mask));
1191	FD_SET(sock, fdsp);
1192
1193	wait.tv_sec = tp->tv_sec + waittime;
1194	wait.tv_usec = tp->tv_usec;
1195	(void)gettimeofday(&now, NULL);
1196	tvsub(&wait, &now);
1197	if (wait.tv_sec < 0) {
1198		wait.tv_sec = 0;
1199		wait.tv_usec = 1;
1200	}
1201
1202	error = select(sock + 1, fdsp, NULL, NULL, &wait);
1203	if (error == -1 && errno == EINVAL) {
1204		Fprintf(stderr, "%s: botched select() args\n", prog);
1205		exit(1);
1206	}
1207	if (error > 0)
1208		cc = recvfrom(sock, (char *)packet, sizeof(packet), 0,
1209			    (struct sockaddr *)fromp, &fromlen);
1210
1211	free(fdsp);
1212	return(cc);
1213}
1214
1215void
1216send_probe(int seq, int ttl)
1217{
1218	register int cc;
1219
1220	outip->ip_ttl = ttl;
1221	outip->ip_id = htons(ident + seq);
1222
1223	/* XXX undocumented debugging hack */
1224	if (verbose > 1) {
1225		register const u_short *sp;
1226		register int nshorts, i;
1227
1228		sp = (u_short *)outip;
1229		nshorts = (u_int)packlen / sizeof(u_short);
1230		i = 0;
1231		Printf("[ %d bytes", packlen);
1232		while (--nshorts >= 0) {
1233			if ((i++ % 8) == 0)
1234				Printf("\n\t");
1235			Printf(" %04x", ntohs(*sp++));
1236		}
1237		if (packlen & 1) {
1238			if ((i % 8) == 0)
1239				Printf("\n\t");
1240			Printf(" %02x", *(u_char *)sp);
1241		}
1242		Printf("]\n");
1243	}
1244
1245#if !defined(IP_HDRINCL) && defined(IP_TTL)
1246	if (setsockopt(sndsock, IPPROTO_IP, IP_TTL,
1247	    (char *)&ttl, sizeof(ttl)) < 0) {
1248		Fprintf(stderr, "%s: setsockopt ttl %d: %s\n",
1249		    prog, ttl, strerror(errno));
1250		exit(1);
1251	}
1252#endif
1253
1254	cc = sendto(sndsock, (char *)outip,
1255	    packlen, 0, &whereto, sizeof(whereto));
1256	if (cc < 0 || cc != packlen)  {
1257		if (cc < 0)
1258			Fprintf(stderr, "%s: sendto: %s\n",
1259			    prog, strerror(errno));
1260		Printf("%s: wrote %s %d chars, ret=%d\n",
1261		    prog, hostname, packlen, cc);
1262		(void)fflush(stdout);
1263	}
1264}
1265
1266#if	defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
1267int
1268setpolicy(so, policy)
1269	int so;
1270	char *policy;
1271{
1272	char *buf;
1273
1274	buf = ipsec_set_policy(policy, strlen(policy));
1275	if (buf == NULL) {
1276		warnx("%s", ipsec_strerror());
1277		return -1;
1278	}
1279	(void)setsockopt(so, IPPROTO_IP, IP_IPSEC_POLICY,
1280		buf, ipsec_get_policylen(buf));
1281
1282	free(buf);
1283
1284	return 0;
1285}
1286#endif
1287
1288double
1289deltaT(struct timeval *t1p, struct timeval *t2p)
1290{
1291	register double dt;
1292
1293	dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1294	     (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1295	return (dt);
1296}
1297
1298/*
1299 * Convert an ICMP "type" field to a printable string.
1300 */
1301char *
1302pr_type(register u_char t)
1303{
1304	static char *ttab[] = {
1305	"Echo Reply",	"ICMP 1",	"ICMP 2",	"Dest Unreachable",
1306	"Source Quench", "Redirect",	"ICMP 6",	"ICMP 7",
1307	"Echo",		"ICMP 9",	"ICMP 10",	"Time Exceeded",
1308	"Param Problem", "Timestamp",	"Timestamp Reply", "Info Request",
1309	"Info Reply"
1310	};
1311
1312	if (t > 16)
1313		return("OUT-OF-RANGE");
1314
1315	return(ttab[t]);
1316}
1317
1318int
1319packet_ok(register u_char *buf, int cc, register struct sockaddr_in *from,
1320    register int seq)
1321{
1322	register struct icmp *icp;
1323	register u_char type, code;
1324	register int hlen;
1325#ifndef ARCHAIC
1326	register struct ip *ip;
1327
1328	ip = (struct ip *) buf;
1329	hlen = ip->ip_hl << 2;
1330	if (cc < hlen + ICMP_MINLEN) {
1331		if (verbose)
1332			Printf("packet too short (%d bytes) from %s\n", cc,
1333				inet_ntoa(from->sin_addr));
1334		return (0);
1335	}
1336	cc -= hlen;
1337	icp = (struct icmp *)(buf + hlen);
1338#else
1339	icp = (struct icmp *)buf;
1340#endif
1341	type = icp->icmp_type;
1342	code = icp->icmp_code;
1343	/* Path MTU Discovery (RFC1191) */
1344	if (code != ICMP_UNREACH_NEEDFRAG)
1345		pmtu = 0;
1346	else {
1347#ifdef HAVE_ICMP_NEXTMTU
1348		pmtu = ntohs(icp->icmp_nextmtu);
1349#else
1350		pmtu = ntohs(((struct my_pmtu *)&icp->icmp_void)->ipm_nextmtu);
1351#endif
1352	}
1353	if (type == ICMP_ECHOREPLY
1354	    && proto->num == IPPROTO_ICMP
1355	    && (*proto->check)((u_char *)icp, (u_char)seq))
1356		return -2;
1357	if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
1358	    type == ICMP_UNREACH) {
1359		u_char *inner;
1360
1361		hip = &icp->icmp_ip;
1362		hiplen = ((u_char *)icp + cc) - (u_char *)hip;
1363		hlen = hip->ip_hl << 2;
1364		inner = (u_char *)((u_char *)hip + hlen);
1365		if (hlen + 16 <= cc
1366		    && hip->ip_p == proto->num
1367		    && (*proto->check)(inner, (u_char)seq))
1368			return (type == ICMP_TIMXCEED ? -1 : code + 1);
1369	}
1370#ifndef ARCHAIC
1371	if (verbose) {
1372		register int i;
1373		u_int32_t *lp = (u_int32_t *)&icp->icmp_ip;
1374
1375		Printf("\n%d bytes from %s to ", cc, inet_ntoa(from->sin_addr));
1376		Printf("%s: icmp type %d (%s) code %d\n",
1377		    inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
1378		for (i = 4; i <= cc - ICMP_MINLEN; i += sizeof(*lp))
1379			Printf("%2d: %8.8x\n", i, ntohl(*lp++));
1380	}
1381#endif
1382	return(0);
1383}
1384
1385void
1386icmp_prep(struct outdata *outdata)
1387{
1388	struct icmp *const icmpheader = (struct icmp *) outp;
1389
1390	icmpheader->icmp_type = ICMP_ECHO;
1391	icmpheader->icmp_id = htons(ident);
1392	icmpheader->icmp_seq = htons(outdata->seq);
1393	icmpheader->icmp_cksum = 0;
1394	icmpheader->icmp_cksum = in_cksum((u_short *)icmpheader, protlen);
1395	if (icmpheader->icmp_cksum == 0)
1396		icmpheader->icmp_cksum = 0xffff;
1397}
1398
1399int
1400icmp_check(const u_char *data, int seq)
1401{
1402	struct icmp *const icmpheader = (struct icmp *) data;
1403
1404	return (icmpheader->icmp_id == htons(ident)
1405	    && icmpheader->icmp_seq == htons(seq));
1406}
1407
1408void
1409udp_prep(struct outdata *outdata)
1410{
1411	struct udphdr *const outudp = (struct udphdr *) outp;
1412
1413	outudp->uh_sport = htons(ident + (fixedPort ? outdata->seq : 0));
1414	outudp->uh_dport = htons(port + (fixedPort ? 0 : outdata->seq));
1415	outudp->uh_ulen = htons((u_short)protlen);
1416	outudp->uh_sum = 0;
1417	if (doipcksum) {
1418	    u_short sum = p_cksum(outip, (u_short*)outudp, protlen, protlen);
1419	    outudp->uh_sum = (sum) ? sum : 0xffff;
1420	}
1421
1422	return;
1423}
1424
1425int
1426udp_check(const u_char *data, int seq)
1427{
1428	struct udphdr *const udp = (struct udphdr *) data;
1429
1430	return (ntohs(udp->uh_sport) == ident + (fixedPort ? seq : 0) &&
1431	    ntohs(udp->uh_dport) == port + (fixedPort ? 0 : seq));
1432}
1433
1434void
1435udplite_prep(struct outdata *outdata)
1436{
1437	struct udphdr *const outudp = (struct udphdr *) outp;
1438
1439	outudp->uh_sport = htons(ident + (fixedPort ? outdata->seq : 0));
1440	outudp->uh_dport = htons(port + (fixedPort ? 0 : outdata->seq));
1441	outudp->uh_ulen = htons(8);
1442	outudp->uh_sum = 0;
1443	if (doipcksum) {
1444	    u_short sum = p_cksum(outip, (u_short*)outudp, protlen, 8);
1445	    outudp->uh_sum = (sum) ? sum : 0xffff;
1446	}
1447
1448	return;
1449}
1450
1451int
1452udplite_check(const u_char *data, int seq)
1453{
1454	struct udphdr *const udp = (struct udphdr *) data;
1455
1456	return (ntohs(udp->uh_sport) == ident + (fixedPort ? seq : 0) &&
1457	    ntohs(udp->uh_dport) == port + (fixedPort ? 0 : seq));
1458}
1459
1460void
1461tcp_prep(struct outdata *outdata)
1462{
1463	struct tcphdr *const tcp = (struct tcphdr *) outp;
1464
1465	tcp->th_sport = htons(ident);
1466	tcp->th_dport = htons(port + (fixedPort ? 0 : outdata->seq));
1467	tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
1468	tcp->th_ack = 0;
1469	tcp->th_off = 5;
1470	tcp->th_flags = TH_SYN;
1471	tcp->th_sum = 0;
1472
1473	if (doipcksum)
1474	    tcp->th_sum = p_cksum(outip, (u_short*)tcp, protlen, protlen);
1475}
1476
1477int
1478tcp_check(const u_char *data, int seq)
1479{
1480	struct tcphdr *const tcp = (struct tcphdr *) data;
1481
1482	return (ntohs(tcp->th_sport) == ident
1483	    && ntohs(tcp->th_dport) == port + (fixedPort ? 0 : seq)
1484	    && tcp->th_seq == (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport));
1485}
1486
1487void
1488sctp_prep(struct outdata *outdata)
1489{
1490	struct sctphdr *const sctp = (struct sctphdr *) outp;
1491	struct sctp_chunkhdr *chk;
1492
1493	sctp->src_port = htons(ident);
1494	sctp->dest_port = htons(port + (fixedPort ? 0 : outdata->seq));
1495	sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port;
1496	sctp->checksum = htonl(0);
1497	if (protlen >=
1498	    (int)(sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr))) {
1499		chk = (struct sctp_chunkhdr *)(sctp + 1);
1500		chk->chunk_type = SCTP_SHUTDOWN_ACK;
1501		chk->chunk_flags = 0;
1502		chk->chunk_length = htons(4);
1503	}
1504	if (protlen >=
1505	    (int)(sizeof(struct sctphdr) + 2 * sizeof(struct sctp_chunkhdr))) {
1506		chk = chk + 1;
1507		chk->chunk_type = SCTP_PAD_CHUNK;
1508		chk->chunk_flags = 0;
1509		chk->chunk_length = htons(protlen -
1510		    (sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr)));
1511	}
1512	if (doipcksum) {
1513		sctp->checksum = sctp_crc32c(sctp, protlen);
1514	}
1515}
1516
1517int
1518sctp_check(const u_char *data, int seq)
1519{
1520	struct sctphdr *const sctp = (struct sctphdr *) data;
1521
1522	return (ntohs(sctp->src_port) == ident
1523	    && ntohs(sctp->dest_port) == port + (fixedPort ? 0 : seq)
1524	    && sctp->v_tag ==
1525	    (u_int32_t)((sctp->src_port << 16) | sctp->dest_port));
1526}
1527
1528void
1529gre_prep(struct outdata *outdata)
1530{
1531	struct grehdr *const gre = (struct grehdr *) outp;
1532
1533	gre->flags = htons(0x2001);
1534	gre->proto = htons(port);
1535	gre->length = 0;
1536	gre->callId = htons(ident + outdata->seq);
1537}
1538
1539int
1540gre_check(const u_char *data, int seq)
1541{
1542	struct grehdr *const gre = (struct grehdr *) data;
1543
1544	return(ntohs(gre->proto) == port
1545	    && ntohs(gre->callId) == ident + seq);
1546}
1547
1548void
1549gen_prep(struct outdata *outdata)
1550{
1551	u_int16_t *const ptr = (u_int16_t *) outp;
1552
1553	ptr[0] = htons(ident);
1554	ptr[1] = htons(port + outdata->seq);
1555}
1556
1557int
1558gen_check(const u_char *data, int seq)
1559{
1560	u_int16_t *const ptr = (u_int16_t *) data;
1561
1562	return(ntohs(ptr[0]) == ident
1563	    && ntohs(ptr[1]) == port + seq);
1564}
1565
1566void
1567print(register u_char *buf, register int cc, register struct sockaddr_in *from)
1568{
1569	register struct ip *ip;
1570	register int hlen;
1571	char addr[INET_ADDRSTRLEN];
1572
1573	ip = (struct ip *) buf;
1574	hlen = ip->ip_hl << 2;
1575	cc -= hlen;
1576
1577	strlcpy(addr, inet_ntoa(from->sin_addr), sizeof(addr));
1578
1579	if (as_path)
1580		Printf(" [AS%u]", as_lookup(asn, addr, AF_INET));
1581
1582	if (nflag)
1583		Printf(" %s", addr);
1584	else
1585		Printf(" %s (%s)", inetname(from->sin_addr), addr);
1586
1587	if (verbose)
1588		Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
1589}
1590
1591/*
1592 * Checksum routine for UDP and TCP headers.
1593 */
1594u_short
1595p_cksum(struct ip *ip, u_short *data, int len, int cov)
1596{
1597	static struct ipovly ipo;
1598	u_short sum[2];
1599
1600	ipo.ih_pr = ip->ip_p;
1601	ipo.ih_len = htons(len);
1602	ipo.ih_src = ip->ip_src;
1603	ipo.ih_dst = ip->ip_dst;
1604
1605	sum[1] = in_cksum((u_short*)&ipo, sizeof(ipo)); /* pseudo ip hdr cksum */
1606	sum[0] = in_cksum(data, cov);                   /* payload data cksum */
1607
1608	return ~in_cksum(sum, sizeof(sum));
1609}
1610
1611/*
1612 * Checksum routine for Internet Protocol family headers (C Version)
1613 */
1614u_short
1615in_cksum(register u_short *addr, register int len)
1616{
1617	register int nleft = len;
1618	register u_short *w = addr;
1619	register u_short answer;
1620	register int sum = 0;
1621
1622	/*
1623	 *  Our algorithm is simple, using a 32 bit accumulator (sum),
1624	 *  we add sequential 16 bit words to it, and at the end, fold
1625	 *  back all the carry bits from the top 16 bits into the lower
1626	 *  16 bits.
1627	 */
1628	while (nleft > 1)  {
1629		sum += *w++;
1630		nleft -= 2;
1631	}
1632
1633	/* mop up an odd byte, if necessary */
1634	if (nleft == 1)
1635		sum += *(u_char *)w;
1636
1637	/*
1638	 * add back carry outs from top 16 bits to low 16 bits
1639	 */
1640	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
1641	sum += (sum >> 16);			/* add carry */
1642	answer = ~sum;				/* truncate to 16 bits */
1643	return (answer);
1644}
1645
1646/*
1647 * CRC32C routine for the Stream Control Transmission Protocol
1648 */
1649
1650#define CRC32C(c, d) (c = (c>>8) ^ crc_c[(c^(d))&0xFF])
1651
1652static u_int32_t crc_c[256] = {
1653	0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
1654	0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
1655	0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
1656	0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
1657	0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
1658	0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
1659	0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
1660	0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
1661	0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
1662	0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
1663	0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
1664	0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
1665	0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
1666	0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
1667	0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
1668	0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
1669	0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
1670	0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
1671	0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
1672	0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
1673	0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
1674	0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
1675	0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
1676	0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
1677	0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
1678	0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
1679	0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
1680	0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
1681	0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
1682	0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
1683	0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
1684	0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
1685	0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
1686	0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
1687	0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
1688	0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
1689	0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
1690	0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
1691	0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
1692	0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
1693	0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
1694	0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
1695	0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
1696	0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
1697	0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
1698	0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
1699	0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
1700	0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
1701	0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
1702	0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
1703	0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
1704	0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
1705	0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
1706	0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
1707	0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
1708	0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
1709	0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
1710	0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
1711	0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
1712	0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
1713	0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
1714	0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
1715	0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
1716	0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
1717};
1718
1719u_int32_t
1720sctp_crc32c(const void *packet, u_int32_t len)
1721{
1722	u_int32_t i, crc32c;
1723	u_int8_t byte0, byte1, byte2, byte3;
1724	const u_int8_t *buf = (const u_int8_t *)packet;
1725
1726	crc32c = ~0;
1727	for (i = 0; i < len; i++)
1728		CRC32C(crc32c, buf[i]);
1729	crc32c = ~crc32c;
1730	byte0  = crc32c & 0xff;
1731	byte1  = (crc32c>>8) & 0xff;
1732	byte2  = (crc32c>>16) & 0xff;
1733	byte3  = (crc32c>>24) & 0xff;
1734	crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
1735	return htonl(crc32c);
1736}
1737
1738/*
1739 * Subtract 2 timeval structs:  out = out - in.
1740 * Out is assumed to be within about LONG_MAX seconds of in.
1741 */
1742void
1743tvsub(register struct timeval *out, register struct timeval *in)
1744{
1745
1746	if ((out->tv_usec -= in->tv_usec) < 0)   {
1747		--out->tv_sec;
1748		out->tv_usec += 1000000;
1749	}
1750	out->tv_sec -= in->tv_sec;
1751}
1752
1753/*
1754 * Construct an Internet address representation.
1755 * If the nflag has been supplied, give
1756 * numeric value, otherwise try for symbolic name.
1757 */
1758char *
1759inetname(struct in_addr in)
1760{
1761	register char *cp;
1762	register struct hostent *hp;
1763	static int first = 1;
1764	static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1];
1765
1766	if (first && !nflag) {
1767		first = 0;
1768		if (gethostname(domain, sizeof(domain) - 1) < 0)
1769			domain[0] = '\0';
1770		else {
1771			cp = strchr(domain, '.');
1772			if (cp == NULL) {
1773				hp = gethostbyname(domain);
1774				if (hp != NULL)
1775					cp = strchr(hp->h_name, '.');
1776			}
1777			if (cp == NULL)
1778				domain[0] = '\0';
1779			else {
1780				++cp;
1781				(void)strncpy(domain, cp, sizeof(domain) - 1);
1782				domain[sizeof(domain) - 1] = '\0';
1783			}
1784		}
1785	}
1786	if (!nflag && in.s_addr != INADDR_ANY) {
1787		hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
1788		if (hp != NULL) {
1789			if ((cp = strchr(hp->h_name, '.')) != NULL &&
1790			    strcmp(cp + 1, domain) == 0)
1791				*cp = '\0';
1792			(void)strncpy(line, hp->h_name, sizeof(line) - 1);
1793			line[sizeof(line) - 1] = '\0';
1794			return (line);
1795		}
1796	}
1797	return (inet_ntoa(in));
1798}
1799
1800struct hostinfo *
1801gethostinfo(register char *hostname)
1802{
1803	register int n;
1804	register struct hostent *hp;
1805	register struct hostinfo *hi;
1806	register char **p;
1807	register u_int32_t addr, *ap;
1808
1809	if (strlen(hostname) >= MAXHOSTNAMELEN) {
1810		Fprintf(stderr, "%s: hostname \"%.32s...\" is too long\n",
1811		    prog, hostname);
1812		exit(1);
1813	}
1814	hi = calloc(1, sizeof(*hi));
1815	if (hi == NULL) {
1816		Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1817		exit(1);
1818	}
1819	addr = inet_addr(hostname);
1820	if ((int32_t)addr != -1) {
1821		hi->name = strdup(hostname);
1822		hi->n = 1;
1823		hi->addrs = calloc(1, sizeof(hi->addrs[0]));
1824		if (hi->addrs == NULL) {
1825			Fprintf(stderr, "%s: calloc %s\n",
1826			    prog, strerror(errno));
1827			exit(1);
1828		}
1829		hi->addrs[0] = addr;
1830		return (hi);
1831	}
1832
1833	hp = gethostbyname(hostname);
1834	if (hp == NULL) {
1835		Fprintf(stderr, "%s: unknown host %s\n", prog, hostname);
1836		exit(1);
1837	}
1838	if (hp->h_addrtype != AF_INET || hp->h_length != 4) {
1839		Fprintf(stderr, "%s: bad host %s\n", prog, hostname);
1840		exit(1);
1841	}
1842	hi->name = strdup(hp->h_name);
1843	for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
1844		continue;
1845	hi->n = n;
1846	hi->addrs = calloc(n, sizeof(hi->addrs[0]));
1847	if (hi->addrs == NULL) {
1848		Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1849		exit(1);
1850	}
1851	for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
1852		memcpy(ap, *p, sizeof(*ap));
1853	return (hi);
1854}
1855
1856void
1857freehostinfo(register struct hostinfo *hi)
1858{
1859	if (hi->name != NULL) {
1860		free(hi->name);
1861		hi->name = NULL;
1862	}
1863	free((char *)hi->addrs);
1864	free((char *)hi);
1865}
1866
1867void
1868getaddr(register u_int32_t *ap, register char *hostname)
1869{
1870	register struct hostinfo *hi;
1871
1872	hi = gethostinfo(hostname);
1873	*ap = hi->addrs[0];
1874	freehostinfo(hi);
1875}
1876
1877void
1878setsin(register struct sockaddr_in *sin, register u_int32_t addr)
1879{
1880
1881	memset(sin, 0, sizeof(*sin));
1882#ifdef HAVE_SOCKADDR_SA_LEN
1883	sin->sin_len = sizeof(*sin);
1884#endif
1885	sin->sin_family = AF_INET;
1886	sin->sin_addr.s_addr = addr;
1887}
1888
1889/* String to value with optional min and max. Handles decimal and hex. */
1890int
1891str2val(register const char *str, register const char *what,
1892    register int mi, register int ma)
1893{
1894	register const char *cp;
1895	register int val;
1896	char *ep;
1897
1898	if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
1899		cp = str + 2;
1900		val = (int)strtol(cp, &ep, 16);
1901	} else
1902		val = (int)strtol(str, &ep, 10);
1903	if (*ep != '\0') {
1904		Fprintf(stderr, "%s: \"%s\" bad value for %s \n",
1905		    prog, str, what);
1906		exit(1);
1907	}
1908	if (val < mi && mi >= 0) {
1909		if (mi == 0)
1910			Fprintf(stderr, "%s: %s must be >= %d\n",
1911			    prog, what, mi);
1912		else
1913			Fprintf(stderr, "%s: %s must be > %d\n",
1914			    prog, what, mi - 1);
1915		exit(1);
1916	}
1917	if (val > ma && ma >= 0) {
1918		Fprintf(stderr, "%s: %s must be <= %d\n", prog, what, ma);
1919		exit(1);
1920	}
1921	return (val);
1922}
1923
1924struct outproto *
1925setproto(char *pname)
1926{
1927	struct outproto *proto;
1928	int i;
1929
1930	for (i = 0; protos[i].name != NULL; i++) {
1931		if (strcasecmp(protos[i].name, pname) == 0) {
1932			break;
1933		}
1934	}
1935	proto = &protos[i];
1936	if (proto->name == NULL) {	/* generic handler */
1937		struct protoent *pe;
1938		u_long pnum;
1939
1940		/* Determine the IP protocol number */
1941		if ((pe = getprotobyname(pname)) != NULL)
1942			pnum = pe->p_proto;
1943		else
1944			pnum = str2val(optarg, "proto number", 1, 255);
1945		proto->num = pnum;
1946	}
1947	return proto;
1948}
1949
1950void
1951pkt_compare(const u_char *a, int la, const u_char *b, int lb) {
1952	int l;
1953	int i;
1954
1955	for (i = 0; i < la; i++)
1956		Printf("%02x", (unsigned int)a[i]);
1957	Printf("\n");
1958	l = (la <= lb) ? la : lb;
1959	for (i = 0; i < l; i++)
1960		if (a[i] == b[i])
1961			Printf("__");
1962		else
1963			Printf("%02x", (unsigned int)b[i]);
1964	for (; i < lb; i++)
1965		Printf("%02x", (unsigned int)b[i]);
1966	Printf("\n");
1967}
1968
1969
1970void
1971usage(void)
1972{
1973	extern char version[];
1974
1975	Fprintf(stderr, "Version %s\n", version);
1976	Fprintf(stderr,
1977	    "Usage: %s [-adDeFInrSvx] [-f first_ttl] [-g gateway] [-i iface]\n"
1978	    "\t[-m max_ttl] [-p port] [-P proto] [-q nqueries] [-s src_addr]\n"
1979	    "\t[-t tos] [-w waittime] [-A as_server] [-z pausemsecs] host [packetlen]\n", prog);
1980	exit(1);
1981}
1982