xref: /NextBSD/contrib/traceroute/traceroute.c (revision 287e3b14e9552995def1802ec9c5034f4adf28ec)
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
23 static const char copyright[] =
24     "@(#) Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000\n\
25 The Regents of the University of California.  All rights reserved.\n";
26 #if 0
27 static const char rcsid[] =
28     "@(#)$Id: traceroute.c,v 1.68 2000/12/14 08:04:33 leres Exp $ (LBL)";
29 #endif
30 static 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 */
275 struct 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 */
289 struct hostinfo {
290 	char *name;
291 	int n;
292 	u_int32_t *addrs;
293 };
294 
295 /* Data section of the probe packet */
296 struct 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) */
304 struct my_pmtu {
305 	u_short ipm_void;
306 	u_short ipm_nextmtu;
307 };
308 #endif
309 
310 u_char	packet[512];		/* last inbound (icmp) packet */
311 
312 struct ip *outip;		/* last output ip packet */
313 u_char *outp;		/* last output inner protocol packet */
314 
315 struct ip *hip = NULL;		/* Quoted IP header */
316 int hiplen = 0;
317 
318 /* loose source route gateway list (including room for final destination) */
319 u_int32_t gwlist[NGATEWAYS + 1];
320 
321 int s;				/* receive (icmp) socket file descriptor */
322 int sndsock;			/* send (udp) socket file descriptor */
323 
324 struct sockaddr whereto;	/* Who to try to reach */
325 struct sockaddr wherefrom;	/* Who we are */
326 int packlen;			/* total length of packet */
327 int protlen;			/* length of protocol part of packet */
328 int minpacket;			/* min ip packet size */
329 int maxpacket = 32 * 1024;	/* max ip packet size */
330 int pmtu;			/* Path MTU Discovery (RFC1191) */
331 u_int pausemsecs;
332 
333 char *prog;
334 char *source;
335 char *hostname;
336 char *device;
337 static const char devnull[] = "/dev/null";
338 
339 int nprobes = -1;
340 int max_ttl;
341 int first_ttl = 1;
342 u_short ident;
343 u_short port;			/* protocol specific base "port" */
344 
345 int options;			/* socket options */
346 int verbose;
347 int waittime = 5;		/* time to wait for response (in seconds) */
348 int nflag;			/* print addresses numerically */
349 int as_path;			/* print as numbers for each hop */
350 char *as_server = NULL;
351 void *asn;
352 #ifdef CANT_HACK_IPCKSUM
353 int doipcksum = 0;		/* don't calculate ip checksums by default */
354 #else
355 int doipcksum = 1;		/* calculate ip checksums by default */
356 #endif
357 int optlen;			/* length of ip options */
358 int fixedPort = 0;		/* Use fixed destination port for TCP and UDP */
359 int printdiff = 0;		/* Print the difference between sent and quoted */
360 
361 extern int optind;
362 extern int opterr;
363 extern char *optarg;
364 
365 /* Forwards */
366 double	deltaT(struct timeval *, struct timeval *);
367 void	freehostinfo(struct hostinfo *);
368 void	getaddr(u_int32_t *, char *);
369 struct	hostinfo *gethostinfo(char *);
370 u_short	in_cksum(u_short *, int);
371 u_int32_t sctp_crc32c(const void *, u_int32_t);
372 char	*inetname(struct in_addr);
373 int	main(int, char **);
374 u_short p_cksum(struct ip *, u_short *, int, int);
375 int	packet_ok(u_char *, int, struct sockaddr_in *, int);
376 char	*pr_type(u_char);
377 void	print(u_char *, int, struct sockaddr_in *);
378 #ifdef	IPSEC
379 int	setpolicy __P((int so, char *policy));
380 #endif
381 void	send_probe(int, int);
382 struct outproto *setproto(char *);
383 int	str2val(const char *, const char *, int, int);
384 void	tvsub(struct timeval *, struct timeval *);
385 void usage(void);
386 int	wait_for_reply(int, struct sockaddr_in *, const struct timeval *);
387 void pkt_compare(const u_char *, int, const u_char *, int);
388 #ifndef HAVE_USLEEP
389 int	usleep(u_int);
390 #endif
391 
392 void	udp_prep(struct outdata *);
393 int	udp_check(const u_char *, int);
394 void	udplite_prep(struct outdata *);
395 int	udplite_check(const u_char *, int);
396 void	tcp_prep(struct outdata *);
397 int	tcp_check(const u_char *, int);
398 void	sctp_prep(struct outdata *);
399 int	sctp_check(const u_char *, int);
400 void	gre_prep(struct outdata *);
401 int	gre_check(const u_char *, int);
402 void	gen_prep(struct outdata *);
403 int	gen_check(const u_char *, int);
404 void	icmp_prep(struct outdata *);
405 int	icmp_check(const u_char *, int);
406 
407 /* Descriptor structure for each outgoing protocol we support */
408 struct 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. */
422 struct	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 };
487 struct	outproto *proto = &protos[0];
488 
489 const char *ip_hdr_key = "vhtslen id  off tlprsum srcip   dstip   opts";
490 
491 int
main(int argc,char ** argv)492 main(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 
1176 int
wait_for_reply(register int sock,register struct sockaddr_in * fromp,register const struct timeval * tp)1177 wait_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 
1215 void
send_probe(int seq,int ttl)1216 send_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)
1267 int
setpolicy(so,policy)1268 setpolicy(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 
1288 double
deltaT(struct timeval * t1p,struct timeval * t2p)1289 deltaT(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  */
1301 char *
pr_type(register u_char t)1302 pr_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 
1318 int
packet_ok(register u_char * buf,int cc,register struct sockaddr_in * from,register int seq)1319 packet_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 
1385 void
icmp_prep(struct outdata * outdata)1386 icmp_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 
1399 int
icmp_check(const u_char * data,int seq)1400 icmp_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 
1408 void
udp_prep(struct outdata * outdata)1409 udp_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 
1425 int
udp_check(const u_char * data,int seq)1426 udp_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 
1434 void
udplite_prep(struct outdata * outdata)1435 udplite_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 
1451 int
udplite_check(const u_char * data,int seq)1452 udplite_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 
1460 void
tcp_prep(struct outdata * outdata)1461 tcp_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 
1477 int
tcp_check(const u_char * data,int seq)1478 tcp_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 
1487 void
sctp_prep(struct outdata * outdata)1488 sctp_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 
1517 int
sctp_check(const u_char * data,int seq)1518 sctp_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 
1528 void
gre_prep(struct outdata * outdata)1529 gre_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 
1539 int
gre_check(const u_char * data,int seq)1540 gre_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 
1548 void
gen_prep(struct outdata * outdata)1549 gen_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 
1557 int
gen_check(const u_char * data,int seq)1558 gen_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 
1566 void
print(register u_char * buf,register int cc,register struct sockaddr_in * from)1567 print(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  */
1594 u_short
p_cksum(struct ip * ip,u_short * data,int len,int cov)1595 p_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  */
1614 u_short
in_cksum(register u_short * addr,register int len)1615 in_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 
1652 static 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 
1719 u_int32_t
sctp_crc32c(const void * packet,u_int32_t len)1720 sctp_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  */
1742 void
tvsub(register struct timeval * out,register struct timeval * in)1743 tvsub(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  */
1758 char *
inetname(struct in_addr in)1759 inetname(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 
1800 struct hostinfo *
gethostinfo(register char * hostname)1801 gethostinfo(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 
1856 void
freehostinfo(register struct hostinfo * hi)1857 freehostinfo(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 
1867 void
getaddr(register u_int32_t * ap,register char * hostname)1868 getaddr(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 
1877 void
setsin(register struct sockaddr_in * sin,register u_int32_t addr)1878 setsin(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. */
1890 int
str2val(register const char * str,register const char * what,register int mi,register int ma)1891 str2val(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 
1924 struct outproto *
setproto(char * pname)1925 setproto(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 
1950 void
pkt_compare(const u_char * a,int la,const u_char * b,int lb)1951 pkt_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 
1970 void
usage(void)1971 usage(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