]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/traceroute/traceroute.c
MFC r368207,368607:
[FreeBSD/stable/10.git] / contrib / traceroute / traceroute.c
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
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
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
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
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
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 *
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 *
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 *
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
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
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
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
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 *
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
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
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 }