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