Merge from vendor branch GCC:
[dragonfly.git] / contrib / traceroute / traceroute.c
1 /*
2  * Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996
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  * @(#) Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996 The Regents of the University of California.  All rights reserved.
22  * @(#)$Header: traceroute.c,v 1.43 96/09/27 20:08:10 leres Exp $ (LBL)
23  * $FreeBSD: src/contrib/traceroute/traceroute.c,v 1.11.2.6 2002/08/05 23:37:16 fenner Exp $
24  * $DragonFly: src/contrib/traceroute/Attic/traceroute.c,v 1.2 2003/06/17 04:24:07 dillon Exp $
25  */
26
27 /*
28  * traceroute host  - trace the route ip packets follow going to "host".
29  *
30  * Attempt to trace the route an ip packet would follow to some
31  * internet host.  We find out intermediate hops by launching probe
32  * packets with a small ttl (time to live) then listening for an
33  * icmp "time exceeded" reply from a gateway.  We start our probes
34  * with a ttl of one and increase by one until we get an icmp "port
35  * unreachable" (which means we got to "host") or hit a max (which
36  * defaults to net.inet.ip.ttl hops & can be changed with the -m flag).
37  * Three probes (change with -q flag) are sent at each ttl setting and
38  * a line is printed showing the ttl, address of the gateway and
39  * round trip time of each probe.  If the probe answers come from
40  * different gateways, the address of each responding system will
41  * be printed.  If there is no response within a 5 sec. timeout
42  * interval (changed with the -w flag), a "*" is printed for that
43  * probe.
44  *
45  * Probe packets are UDP format.  We don't want the destination
46  * host to process them so the destination port is set to an
47  * unlikely value (if some clod on the destination is using that
48  * value, it can be changed with the -p flag).
49  *
50  * A sample use might be:
51  *
52  *     [yak 71]% traceroute nis.nsf.net.
53  *     traceroute to nis.nsf.net (35.1.1.48), 64 hops max, 56 byte packet
54  *      1  helios.ee.lbl.gov (128.3.112.1)  19 ms  19 ms  0 ms
55  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
56  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  39 ms  19 ms
57  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  39 ms
58  *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  39 ms  39 ms  39 ms
59  *      6  128.32.197.4 (128.32.197.4)  40 ms  59 ms  59 ms
60  *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  59 ms
61  *      8  129.140.70.13 (129.140.70.13)  99 ms  99 ms  80 ms
62  *      9  129.140.71.6 (129.140.71.6)  139 ms  239 ms  319 ms
63  *     10  129.140.81.7 (129.140.81.7)  220 ms  199 ms  199 ms
64  *     11  nic.merit.edu (35.1.1.48)  239 ms  239 ms  239 ms
65  *
66  * Note that lines 2 & 3 are the same.  This is due to a buggy
67  * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
68  * packets with a zero ttl.
69  *
70  * A more interesting example is:
71  *
72  *     [yak 72]% traceroute allspice.lcs.mit.edu.
73  *     traceroute to allspice.lcs.mit.edu (18.26.0.115), 64 hops max
74  *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
75  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  19 ms  19 ms
76  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  19 ms
77  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  19 ms  39 ms  39 ms
78  *      5  ccn-nerif22.Berkeley.EDU (128.32.168.22)  20 ms  39 ms  39 ms
79  *      6  128.32.197.4 (128.32.197.4)  59 ms  119 ms  39 ms
80  *      7  131.119.2.5 (131.119.2.5)  59 ms  59 ms  39 ms
81  *      8  129.140.70.13 (129.140.70.13)  80 ms  79 ms  99 ms
82  *      9  129.140.71.6 (129.140.71.6)  139 ms  139 ms  159 ms
83  *     10  129.140.81.7 (129.140.81.7)  199 ms  180 ms  300 ms
84  *     11  129.140.72.17 (129.140.72.17)  300 ms  239 ms  239 ms
85  *     12  * * *
86  *     13  128.121.54.72 (128.121.54.72)  259 ms  499 ms  279 ms
87  *     14  * * *
88  *     15  * * *
89  *     16  * * *
90  *     17  * * *
91  *     18  ALLSPICE.LCS.MIT.EDU (18.26.0.115)  339 ms  279 ms  279 ms
92  *
93  * (I start to see why I'm having so much trouble with mail to
94  * MIT.)  Note that the gateways 12, 14, 15, 16 & 17 hops away
95  * either don't send ICMP "time exceeded" messages or send them
96  * with a ttl too small to reach us.  14 - 17 are running the
97  * MIT C Gateway code that doesn't send "time exceeded"s.  God
98  * only knows what's going on with 12.
99  *
100  * The silent gateway 12 in the above may be the result of a bug in
101  * the 4.[23]BSD network code (and its derivatives):  4.x (x <= 3)
102  * sends an unreachable message using whatever ttl remains in the
103  * original datagram.  Since, for gateways, the remaining ttl is
104  * zero, the icmp "time exceeded" is guaranteed to not make it back
105  * to us.  The behavior of this bug is slightly more interesting
106  * when it appears on the destination system:
107  *
108  *      1  helios.ee.lbl.gov (128.3.112.1)  0 ms  0 ms  0 ms
109  *      2  lilac-dmc.Berkeley.EDU (128.32.216.1)  39 ms  19 ms  39 ms
110  *      3  lilac-dmc.Berkeley.EDU (128.32.216.1)  19 ms  39 ms  19 ms
111  *      4  ccngw-ner-cc.Berkeley.EDU (128.32.136.23)  39 ms  40 ms  19 ms
112  *      5  ccn-nerif35.Berkeley.EDU (128.32.168.35)  39 ms  39 ms  39 ms
113  *      6  csgw.Berkeley.EDU (128.32.133.254)  39 ms  59 ms  39 ms
114  *      7  * * *
115  *      8  * * *
116  *      9  * * *
117  *     10  * * *
118  *     11  * * *
119  *     12  * * *
120  *     13  rip.Berkeley.EDU (128.32.131.22)  59 ms !  39 ms !  39 ms !
121  *
122  * Notice that there are 12 "gateways" (13 is the final
123  * destination) and exactly the last half of them are "missing".
124  * What's really happening is that rip (a Sun-3 running Sun OS3.5)
125  * is using the ttl from our arriving datagram as the ttl in its
126  * icmp reply.  So, the reply will time out on the return path
127  * (with no notice sent to anyone since icmp's aren't sent for
128  * icmp's) until we probe with a ttl that's at least twice the path
129  * length.  I.e., rip is really only 7 hops away.  A reply that
130  * returns with a ttl of 1 is a clue this problem exists.
131  * Traceroute prints a "!" after the time if the ttl is <= 1.
132  * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
133  * non-standard (HPUX) software, expect to see this problem
134  * frequently and/or take care picking the target host of your
135  * probes.
136  *
137  * Other possible annotations after the time are !H, !N, !P (got a host,
138  * network or protocol unreachable, respectively), !S or !F (source
139  * route failed or fragmentation needed -- neither of these should
140  * ever occur and the associated gateway is busted if you see one).  If
141  * almost all the probes result in some kind of unreachable, traceroute
142  * will give up and exit.
143  *
144  * Notes
145  * -----
146  * This program must be run by root or be setuid.  (I suggest that
147  * you *don't* make it setuid -- casual use could result in a lot
148  * of unnecessary traffic on our poor, congested nets.)
149  *
150  * This program requires a kernel mod that does not appear in any
151  * system available from Berkeley:  A raw ip socket using proto
152  * IPPROTO_RAW must interpret the data sent as an ip datagram (as
153  * opposed to data to be wrapped in a ip datagram).  See the README
154  * file that came with the source to this program for a description
155  * of the mods I made to /sys/netinet/raw_ip.c.  Your mileage may
156  * vary.  But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
157  * MODIFIED TO RUN THIS PROGRAM.
158  *
159  * The udp port usage may appear bizarre (well, ok, it is bizarre).
160  * The problem is that an icmp message only contains 8 bytes of
161  * data from the original datagram.  8 bytes is the size of a udp
162  * header so, if we want to associate replies with the original
163  * datagram, the necessary information must be encoded into the
164  * udp header (the ip id could be used but there's no way to
165  * interlock with the kernel's assignment of ip id's and, anyway,
166  * it would have taken a lot more kernel hacking to allow this
167  * code to set the ip id).  So, to allow two or more users to
168  * use traceroute simultaneously, we use this task's pid as the
169  * source port (the high bit is set to move the port number out
170  * of the "likely" range).  To keep track of which probe is being
171  * replied to (so times and/or hop counts don't get confused by a
172  * reply that was delayed in transit), we increment the destination
173  * port number before each probe.
174  *
175  * Don't use this as a coding example.  I was trying to find a
176  * routing problem and this code sort-of popped out after 48 hours
177  * without sleep.  I was amazed it ever compiled, much less ran.
178  *
179  * I stole the idea for this program from Steve Deering.  Since
180  * the first release, I've learned that had I attended the right
181  * IETF working group meetings, I also could have stolen it from Guy
182  * Almes or Matt Mathis.  I don't know (or care) who came up with
183  * the idea first.  I envy the originators' perspicacity and I'm
184  * glad they didn't keep the idea a secret.
185  *
186  * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
187  * enhancements to the original distribution.
188  *
189  * I've hacked up a round-trip-route version of this that works by
190  * sending a loose-source-routed udp datagram through the destination
191  * back to yourself.  Unfortunately, SO many gateways botch source
192  * routing, the thing is almost worthless.  Maybe one day...
193  *
194  *  -- Van Jacobson (van@ee.lbl.gov)
195  *     Tue Dec 20 03:50:13 PST 1988
196  */
197
198 #include <sys/param.h>
199 #include <sys/file.h>
200 #include <sys/ioctl.h>
201 #ifdef HAVE_SYS_SELECT_H
202 #include <sys/select.h>
203 #endif
204 #include <sys/socket.h>
205 #ifdef HAVE_SYS_SYSCTL_H
206 #include <sys/sysctl.h>
207 #endif
208 #include <sys/time.h>
209
210 #include <netinet/in_systm.h>
211 #include <netinet/in.h>
212 #include <netinet/ip.h>
213 #include <netinet/ip_var.h>
214 #include <netinet/ip_icmp.h>
215 #include <netinet/udp.h>
216 #include <netinet/tcp.h>
217
218 #include <arpa/inet.h>
219
220 #ifdef  IPSEC
221 #include <net/route.h>
222 #include <netinet6/ipsec.h>     /* XXX */
223 #endif  /* IPSEC */
224
225 #include <ctype.h>
226 #include <errno.h>
227 #ifdef HAVE_MALLOC_H
228 #include <malloc.h>
229 #endif
230 #include <memory.h>
231 #include <netdb.h>
232 #include <stdio.h>
233 #include <stdlib.h>
234 #include <string.h>
235 #include <unistd.h>
236
237 #include "gnuc.h"
238 #ifdef HAVE_OS_PROTO_H
239 #include "os-proto.h"
240 #endif
241
242 /* Maximum number of gateways (include room for one noop) */
243 #define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(u_int32_t)))
244
245 #ifndef MAXHOSTNAMELEN
246 #define MAXHOSTNAMELEN  64
247 #endif
248
249 #define Fprintf (void)fprintf
250 #define Printf (void)printf
251
252 /* What a GRE packet header looks like */
253 struct grehdr {
254         u_int16_t   flags;
255         u_int16_t   proto;
256         u_int16_t   length;     /* PPTP version of these fields */
257         u_int16_t   callId;
258 };
259 #ifndef IPPROTO_GRE
260 #define IPPROTO_GRE     47
261 #endif
262
263 /* For GRE, we prepare what looks like a PPTP packet */
264 #define GRE_PPTP_PROTO  0x880b
265
266 /* Data section of the probe packet */
267 struct outdata {
268         u_char seq;             /* sequence number of this packet */
269         u_char ttl;             /* ttl packet left with */
270         struct timeval tv;      /* time packet left */
271         int    optlen;          /* length of ip options */
272 };
273
274 /* Descriptor structure for each outgoing protocol we support */
275 struct outproto {
276         char    *name;          /* name of protocol */
277         u_char  num;            /* IP protocol number */
278         u_short hdrlen;         /* max size of protocol header */
279         u_short port;           /* default base protocol-specific "port" */
280         void    (*prepare)(struct outdata *);
281                                 /* finish preparing an outgoing packet */
282         int     (*check)(const u_char *, int);
283                                 /* check an incoming packet */
284 };
285
286 u_char  packet[512];            /* last inbound (icmp) packet */
287
288 struct ip *outip;               /* last output ip packet */
289 u_char *outprot;                /* last output inner protocol packet */
290
291 /* loose source route gateway list (including room for final destination) */
292 u_int32_t gwlist[NGATEWAYS + 1];
293
294 int s;                          /* receive (icmp) socket file descriptor */
295 int sndsock;                    /* send (udp) socket file descriptor */
296
297 struct sockaddr whereto;        /* Who to try to reach */
298 int packlen;                    /* total length of packet */
299 int protlen;                    /* length of protocol part of packet */
300 int maxpacket = 32 * 1024;      /* max ip packet size */
301
302 char *prog;
303 char *source;
304 char *hostname;
305
306 int nprobes = 3;
307 int min_ttl = 1;
308 int max_ttl;
309 u_short ident;
310 u_short port;                   /* protocol specific base "port" */
311
312 int options;                    /* socket options */
313 int verbose;
314 int waittime = 5;               /* time to wait for response (in seconds) */
315 int nflag;                      /* print addresses numerically */
316
317 extern int optind;
318 extern int opterr;
319 extern char *optarg;
320
321 /* Forwards */
322 double  deltaT(struct timeval *, struct timeval *);
323 u_short in_cksum(u_short *, int);
324 char    *inetname(struct in_addr);
325 int     main(int, char **);
326 int     packet_ok(u_char *, int, struct sockaddr_in *, int);
327 char    *pr_type(u_char);
328 void    print(u_char *, int, struct sockaddr_in *);
329 char    *getaddr(u_int32_t *, char *);
330 char    *getsin(struct sockaddr_in *, char *);
331 char    *savestr(const char *);
332 #ifdef  IPSEC
333 int     setpolicy __P((int so, char *policy));
334 #endif
335 void    send_probe(int, int);
336 void    tvsub(struct timeval *, struct timeval *);
337 __dead  void usage(void);
338 int     wait_for_reply(int, struct sockaddr_in *, struct timeval *);
339
340 void    udp_prep(struct outdata *);
341 int     udp_check(const u_char *, int);
342 void    tcp_prep(struct outdata *);
343 int     tcp_check(const u_char *, int);
344 void    gre_prep(struct outdata *);
345 int     gre_check(const u_char *, int);
346 void    gen_prep(struct outdata *);
347 int     gen_check(const u_char *, int);
348 void    icmp_prep(struct outdata *);
349 int     icmp_check(const u_char *, int);
350
351 /* List of supported protocols. The first one is the default. The last
352    one is the handler for generic protocols not explicitly listed. */
353 struct  outproto protos[] = {
354         {
355                 "udp",
356                 IPPROTO_UDP,
357                 sizeof(struct udphdr),
358                 32768 + 666,
359                 udp_prep,
360                 udp_check
361         },
362         {
363                 "tcp",
364                 IPPROTO_TCP,
365                 sizeof(struct tcphdr),
366                 32768 + 666,
367                 tcp_prep,
368                 tcp_check
369         },
370         {
371                 "gre",
372                 IPPROTO_GRE,
373                 sizeof(struct grehdr),
374                 GRE_PPTP_PROTO,
375                 gre_prep,
376                 gre_check
377         },
378         {
379                 "icmp",
380                 IPPROTO_ICMP,
381                 sizeof(struct icmp),
382                 0,
383                 icmp_prep,
384                 icmp_check
385         },
386         {
387                 NULL,
388                 0,
389                 2 * sizeof(u_short),
390                 0,
391                 gen_prep,
392                 gen_check
393         },
394 };
395 struct  outproto *proto = &protos[0];
396
397 int
398 main(int argc, char **argv)
399 {
400         register int op, code;
401         register char *cp;
402         struct sockaddr_in from;
403         register struct sockaddr_in *to = (struct sockaddr_in *)&whereto;
404         int on = 1;
405         register struct protoent *pe;
406         register int ttl, probe, i;
407         register int seq = 0;
408         register int tos = 0;
409         register int lsrr = 0;
410         register int optlen = 0;
411         int requestPort = -1;
412         int sump = 0;
413         int sockerrno;
414
415         /*
416          * Do the setuid-required stuff first, then lose priveleges ASAP.
417          * Do error checking for these two calls where they appeared in
418          * the original code.
419          */
420         cp = "icmp";
421         pe = getprotobyname(cp);
422         if (pe) {
423                 if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0)
424                         sockerrno = errno;
425                 else if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
426                         sockerrno = errno;
427         }
428
429         setuid(getuid());
430
431 #ifdef IPCTL_DEFTTL
432         {
433                 int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
434                 size_t sz = sizeof(max_ttl);
435
436                 if (sysctl(mib, 4, &max_ttl, &sz, NULL, 0) == -1)
437                         err(1, "sysctl(net.inet.ip.ttl)");
438         }
439 #else
440         max_ttl = 30;
441 #endif
442
443         if ((cp = strrchr(argv[0], '/')) != NULL)
444                 prog = cp + 1;
445         else
446                 prog = argv[0];
447
448         opterr = 0;
449         while ((op = getopt(argc, argv, "Sdnrvg:M:m:P:p:q:s:t:w:")) != EOF)
450                 switch (op) {
451
452                 case 'S':
453                         sump = 1;
454                         break;
455                 case 'd':
456                         options |= SO_DEBUG;
457                         break;
458
459                 case 'g':
460                         if (lsrr >= NGATEWAYS) {
461                                 Fprintf(stderr,
462                                     "%s: No more than %d gateways\n",
463                                     prog, NGATEWAYS);
464                                 exit(1);
465                         }
466                         (void)getaddr(gwlist + lsrr, optarg);
467                         ++lsrr;
468                         break;
469
470                 case 'M':
471                         min_ttl = atoi(optarg);
472                         if (min_ttl < 1 || min_ttl > 0xff) {
473                                 Fprintf(stderr, "%s: invalid ttl value %s\n",
474                                     prog, optarg);
475                                 exit(1);
476                         }
477                         break;
478
479                 case 'm':
480                         max_ttl = atoi(optarg);
481                         if (max_ttl < 1 || max_ttl > 0xff) {
482                                 Fprintf(stderr, "%s: invalid ttl value %s\n",
483                                     prog, optarg);
484                                 exit(1);
485                         }
486                         break;
487
488                 case 'n':
489                         ++nflag;
490                         break;
491
492                 case 'P':
493                         for (i = 0; protos[i].name != NULL; i++) {
494                                 if (strcasecmp(protos[i].name, optarg) == 0) {
495                                         break;
496                                 }
497                         }
498                         proto = &protos[i];
499                         if (proto->name == NULL) {      /* generic handler */
500                                 struct protoent *pe;
501                                 u_long pnum;
502                                 char *eptr;
503
504                                 /* Determine the IP protocol number */
505                                 if ((pe = getprotobyname(optarg)) != NULL)
506                                         pnum = pe->p_proto;
507                                 else {
508                                         pnum = strtoul(optarg, &eptr, 10);
509                                         if (pnum > 0xff
510                                             || *optarg == '\0'
511                                             || *eptr != '\0') {
512                                                 Fprintf(stderr, "%s: unknown "
513                                                     "protocol \"%s\"\n",
514                                                     prog, optarg);
515                                                 exit(1);
516                                         }
517                                 }
518                                 proto->num = pnum;
519                         }
520                         break;
521
522                 case 'p':
523                         requestPort = atoi(optarg);
524                         if (requestPort <= 0) {
525                                 Fprintf(stderr, "%s: port must be > 0\n", prog);
526                                 exit(1);
527                         }
528                         break;
529
530                 case 'q':
531                         nprobes = atoi(optarg);
532                         if (nprobes <= 0) {
533                                 Fprintf(stderr, "%s: nprobes must be > 0\n",
534                                     prog);
535                                 exit(1);
536                         }
537                         break;
538
539                 case 'r':
540                         options |= SO_DONTROUTE;
541                         break;
542
543                 case 's':
544                         /*
545                          * set the ip source address of the outbound
546                          * probe (e.g., on a multi-homed host).
547                          */
548                         source = optarg;
549                         break;
550
551                 case 't':
552                         tos = atoi(optarg);
553                         if (tos < 0 || tos > 255) {
554                                 Fprintf(stderr, "%s: tos must be 0 to 255\n",
555                                     prog);
556                                 exit(1);
557                         }
558                         break;
559
560                 case 'v':
561                         ++verbose;
562                         break;
563
564                 case 'w':
565                         waittime = atoi(optarg);
566                         if (waittime <= 1 || waittime >= 24L * 60 * 60) {
567                                 Fprintf(stderr,
568                                     "%s: wait must be > 1 sec and < 1 day\n",
569                                     prog);
570                                 exit(1);
571                         }
572                         break;
573
574                 default:
575                         usage();
576                 }
577
578         /* Set requested port, if any, else default for this protocol */
579         port = (requestPort != -1) ? requestPort : proto->port;
580
581         /* Check min vs. max TTL */
582         if (min_ttl > max_ttl) {
583                 Fprintf(stderr, "%s: min ttl must be <= max ttl\n", prog);
584                 exit(1);
585         }
586
587         /* Process destination and optional packet size */
588         switch (argc - optind) {
589
590         case 2:
591                 packlen = atoi(argv[optind + 1]);
592                 /* Fall thorugh */
593
594         case 1:
595                 hostname = savestr(getsin(to, argv[optind]));
596                 break;
597
598         default:
599                 usage();
600         }
601
602 #ifdef HAVE_SETLINEBUF
603         setlinebuf (stdout);
604 #else
605         setvbuf(stdout, NULL, _IOLBF, 0);
606 #endif
607
608         if (lsrr > 0)
609                 optlen = (lsrr + 1) * sizeof(gwlist[0]);
610         i = sizeof(*outip) + proto->hdrlen + sizeof(struct outdata) + optlen;
611         if (packlen == 0)
612                 packlen = i;                    /* minimum sized packet */
613         else if (i > packlen || packlen > maxpacket) {
614                 Fprintf(stderr, "%s: packet size must be %d <= s <= %d\n",
615                     prog, i, maxpacket);
616                 exit(1);
617         }
618         protlen = packlen - sizeof(*outip) - optlen;
619
620         outip = (struct ip *)malloc((unsigned)packlen);
621         if (outip == NULL) {
622                 Fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno));
623                 exit(1);
624         }
625         memset((char *)outip, 0, packlen);
626
627         outip->ip_v = IPVERSION;
628         outip->ip_tos = tos;
629 #ifdef BYTESWAP_IP_LEN
630         outip->ip_len = htons(packlen);
631 #else
632         outip->ip_len = packlen;
633 #endif
634         outip->ip_p = proto->num;
635         outprot = (u_char *)(outip + 1);
636 #ifdef HAVE_RAW_OPTIONS
637         if (lsrr > 0) {
638                 register u_char *optlist;
639
640                 optlist = (u_char *)outprot;
641                 (u_char *)outprot += optlen;
642
643                 /* final hop */
644                 gwlist[lsrr] = to->sin_addr.s_addr;
645
646                 outip->ip_dst.s_addr = gwlist[0];
647
648                 /* force 4 byte alignment */
649                 optlist[0] = IPOPT_NOP;
650                 /* loose source route option */
651                 optlist[1] = IPOPT_LSRR;
652                 i = lsrr * sizeof(gwlist[0]);
653                 optlist[2] = i + 3;
654                 /* Pointer to LSRR addresses */
655                 optlist[3] = IPOPT_MINOFF;
656                 memcpy(optlist + 4, gwlist + 1, i);
657         } else
658 #endif
659                 outip->ip_dst = to->sin_addr;
660
661         outip->ip_hl = ((u_char *)outprot - (u_char *)outip) >> 2;
662
663         ident = (getpid() & 0xffff) | 0x8000;
664
665         if (pe == NULL) {
666                 Fprintf(stderr, "%s: unknown protocol %s\n", prog, cp);
667                 exit(1);
668         }
669         if (s < 0) {
670                 errno = sockerrno;
671                 Fprintf(stderr, "%s: icmp socket: %s\n", prog, strerror(errno));
672                 exit(1);
673         }
674         if (options & SO_DEBUG)
675                 (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on,
676                     sizeof(on));
677         if (options & SO_DONTROUTE)
678                 (void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
679                     sizeof(on));
680
681 #if     defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
682         if (setpolicy(s, "in bypass") < 0)
683                 errx(1, "%s", ipsec_strerror());
684
685         if (setpolicy(s, "out bypass") < 0)
686                 errx(1, "%s", ipsec_strerror());
687 #endif  /* defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) */
688
689         if (sndsock < 0) {
690                 errno = sockerrno;
691                 Fprintf(stderr, "%s: raw socket: %s\n", prog, strerror(errno));
692                 exit(1);
693         }
694
695 #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
696         if (lsrr > 0) {
697                 u_char optlist[MAX_IPOPTLEN];
698
699                 cp = "ip";
700                 if ((pe = getprotobyname(cp)) == NULL) {
701                         Fprintf(stderr, "%s: unknown protocol %s\n", prog, cp);
702                         exit(1);
703                 }
704
705                 /* final hop */
706                 gwlist[lsrr] = to->sin_addr.s_addr;
707                 ++lsrr;
708
709                 /* force 4 byte alignment */
710                 optlist[0] = IPOPT_NOP;
711                 /* loose source route option */
712                 optlist[1] = IPOPT_LSRR;
713                 i = lsrr * sizeof(gwlist[0]);
714                 optlist[2] = i + 3;
715                 /* Pointer to LSRR addresses */
716                 optlist[3] = IPOPT_MINOFF;
717                 memcpy(optlist + 4, gwlist, i);
718
719                 if ((setsockopt(sndsock, pe->p_proto, IP_OPTIONS, optlist,
720                     i + sizeof(gwlist[0]))) < 0) {
721                         Fprintf(stderr, "%s: IP_OPTIONS: %s\n",
722                             prog, strerror(errno));
723                         exit(1);
724                     }
725         }
726 #endif
727
728 #ifdef SO_SNDBUF
729         if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packlen,
730             sizeof(packlen)) < 0) {
731                 Fprintf(stderr, "%s: SO_SNDBUF: %s\n", prog, strerror(errno));
732                 exit(1);
733         }
734 #endif
735 #ifdef IP_HDRINCL
736         if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
737             sizeof(on)) < 0) {
738                 Fprintf(stderr, "%s: IP_HDRINCL: %s\n", prog, strerror(errno));
739                 exit(1);
740         }
741 #endif
742         if (options & SO_DEBUG)
743                 (void)setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on,
744                     sizeof(on));
745         if (options & SO_DONTROUTE)
746                 (void)setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
747                     sizeof(on));
748
749         if (source != NULL) {
750                 source = savestr(getsin(&from, source));
751                 outip->ip_src = from.sin_addr;
752 #ifndef IP_HDRINCL
753                 if (bind(sndsock, (struct sockaddr *)&from, sizeof(from)) < 0) {
754                         Fprintf(stderr, "%s: bind: %s\n",
755                             prog, strerror(errno));
756                         exit (1);
757                 }
758 #endif
759         }
760
761 #if     defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
762         if (setpolicy(sndsock, "in bypass") < 0)
763                 errx(1, "%s", ipsec_strerror());
764
765         if (setpolicy(sndsock, "out bypass") < 0)
766                 errx(1, "%s", ipsec_strerror());
767 #endif  /* defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) */
768
769         Fprintf(stderr, "%s to %s (%s)",
770             prog, hostname, inet_ntoa(to->sin_addr));
771         if (source)
772                 Fprintf(stderr, " from %s", source);
773         Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen);
774         (void)fflush(stderr);
775
776         for (ttl = min_ttl; ttl <= max_ttl; ++ttl) {
777                 u_int32_t lastaddr = 0;
778                 int got_there = 0;
779                 int unreachable = 0;
780                 int loss;
781
782                 Printf("%2d ", ttl);
783                 for (probe = 0, loss = 0; probe < nprobes; ++probe) {
784                         register int cc;
785                         struct timeval t1, t2;
786                         struct timezone tz;
787                         register struct ip *ip;
788                         struct outdata outdata;
789
790                         /* Prepare outgoing data */
791                         outdata.seq = ++seq;
792                         outdata.ttl = ttl;
793                         outdata.optlen = optlen;
794
795                         /* Avoid alignment problems by copying bytewise: */
796                         (void)gettimeofday(&t1, &tz);
797                         memcpy(&outdata.tv, &t1, sizeof(outdata.tv));
798
799                         /* Finalize and send packet */
800                         (*proto->prepare)(&outdata);
801                         send_probe(seq, ttl);
802
803                         /* Wait for a reply */
804                         while ((cc = wait_for_reply(s, &from, &t1)) != 0) {
805                                 double T;
806                                 int precis;
807
808                                 (void)gettimeofday(&t2, &tz);
809                                 i = packet_ok(packet, cc, &from, seq);
810                                 /* Skip short packet */
811                                 if (i == 0)
812                                         continue;
813                                 if (from.sin_addr.s_addr != lastaddr) {
814                                         print(packet, cc, &from);
815                                         lastaddr = from.sin_addr.s_addr;
816                                 }
817                                 T = deltaT(&t1, &t2);
818 #ifdef SANE_PRECISION
819                                 if (T >= 1000.0)
820                                         precis = 0;
821                                 else if (T >= 100.0)
822                                         precis = 1;
823                                 else if (T >= 10.0)
824                                         precis = 2;
825                                 else
826 #endif
827                                         precis = 3;
828                                 Printf("  %.*f ms", precis, T);
829                                 if (i == -2) {
830 #ifndef ARCHAIC
831                                         ip = (struct ip *)packet;
832                                         if (ip->ip_ttl <= 1)
833                                                 Printf(" !");
834 #endif
835
836                                         ++got_there;
837                                         break;
838                                 }
839
840                                 /* time exceeded in transit */
841                                 if (i == -1)
842                                         break;
843                                         
844                                 code = i - 1;
845                                 switch (code) {
846
847                                 case ICMP_UNREACH_PORT:
848 #ifndef ARCHAIC
849                                         ip = (struct ip *)packet;
850                                         if (ip->ip_ttl <= 1)
851                                                 Printf(" !");
852 #endif
853                                         ++got_there;
854                                         break;
855
856                                 case ICMP_UNREACH_NET:
857                                         ++unreachable;
858                                         Printf(" !N");
859                                         break;
860
861                                 case ICMP_UNREACH_HOST:
862                                         ++unreachable;
863                                         Printf(" !H");
864                                         break;
865
866                                 case ICMP_UNREACH_PROTOCOL:
867                                         ++got_there;
868                                         Printf(" !P");
869                                         break;
870
871                                 case ICMP_UNREACH_NEEDFRAG:
872                                         ++unreachable;
873                                         Printf(" !F");
874                                         break;
875
876                                 case ICMP_UNREACH_SRCFAIL:
877                                         ++unreachable;
878                                         Printf(" !S");
879                                         break;
880
881 /* rfc1716 */
882 #ifndef ICMP_UNREACH_FILTER_PROHIB
883 #define ICMP_UNREACH_FILTER_PROHIB      13      /* admin prohibited filter */
884 #endif
885                                 case ICMP_UNREACH_FILTER_PROHIB:
886                                         ++unreachable;
887                                         Printf(" !X");
888                                         break;
889
890                                 default:
891                                         ++unreachable;
892                                         Printf(" !<%d>", code);
893                                         break;
894                                 }
895                                 break;
896                         }
897                         if (cc == 0) {
898                                 loss++;
899                                 Printf(" *");
900                         }
901                         (void)fflush(stdout);
902                 }
903                 if (sump) {
904                         Printf(" (%d%% loss)", (loss * 100) / nprobes);
905                 }
906                 putchar('\n');
907                 if (got_there ||
908                     (unreachable > 0 && unreachable >= nprobes - 1))
909                         break;
910         }
911         exit(0);
912 }
913
914 int
915 wait_for_reply(register int sock, register struct sockaddr_in *fromp,
916     register struct timeval *tp)
917 {
918         fd_set *fdsp;
919         size_t nfds;
920         struct timeval now, wait;
921         struct timezone tz;
922         register int cc = 0;
923         register int error;
924         int fromlen = sizeof(*fromp);
925
926         nfds = howmany(sock + 1, NFDBITS);
927         if ((fdsp = malloc(nfds * sizeof(fd_mask))) == NULL)
928                 err(1, "malloc");
929         memset(fdsp, 0, nfds * sizeof(fd_mask));
930         FD_SET(sock, fdsp);
931
932         wait.tv_sec = tp->tv_sec + waittime;
933         wait.tv_usec = tp->tv_usec;
934         (void)gettimeofday(&now, &tz);
935         tvsub(&wait, &now);
936         if (wait.tv_sec < 0) {
937                 wait.tv_sec = 0;
938                 wait.tv_usec = 1;
939         }
940
941         error = select(sock + 1, fdsp, NULL, NULL, &wait);
942         if (error == -1 && errno == EINVAL) {
943                 Fprintf(stderr, "%s: botched select() args\n", prog);
944                 exit(1);
945         }
946         if (error > 0)
947                 cc = recvfrom(s, (char *)packet, sizeof(packet), 0,
948                             (struct sockaddr *)fromp, &fromlen);
949
950         free(fdsp);
951         return(cc);
952 }
953
954 #if     defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
955 int
956 setpolicy(so, policy)
957         int so;
958         char *policy;
959 {
960         char *buf;
961
962         buf = ipsec_set_policy(policy, strlen(policy));
963         if (buf == NULL) {
964                 warnx("%s", ipsec_strerror());
965                 return -1;
966         }
967         (void)setsockopt(so, IPPROTO_IP, IP_IPSEC_POLICY,
968                 buf, ipsec_get_policylen(buf));
969
970         free(buf);
971
972         return 0;
973 }
974 #endif
975
976 void
977 send_probe(int seq, int ttl)
978 {
979         register int i;
980
981         outip->ip_ttl = ttl;
982         outip->ip_id = htons(ident + seq);
983
984         i = sendto(sndsock, (char *)outip, packlen, 0, &whereto,
985                    sizeof(whereto));
986         if (i < 0 || i != packlen)  {
987                 if (i < 0)
988                         Fprintf(stderr, "%s: sendto: %s\n",
989                             prog, strerror(errno));
990                 Printf("%s: wrote %s %d chars, ret=%d\n",
991                     prog, hostname, packlen, i);
992                 (void)fflush(stdout);
993         }
994 }
995
996 double
997 deltaT(struct timeval *t1p, struct timeval *t2p)
998 {
999         register double dt;
1000
1001         dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1002              (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1003         return (dt);
1004 }
1005
1006 /*
1007  * Convert an ICMP "type" field to a printable string.
1008  */
1009 char *
1010 pr_type(register u_char t)
1011 {
1012         static char *ttab[] = {
1013         "Echo Reply",   "ICMP 1",       "ICMP 2",       "Dest Unreachable",
1014         "Source Quench", "Redirect",    "ICMP 6",       "ICMP 7",
1015         "Echo",         "ICMP 9",       "ICMP 10",      "Time Exceeded",
1016         "Param Problem", "Timestamp",   "Timestamp Reply", "Info Request",
1017         "Info Reply"
1018         };
1019
1020         if (t > 16)
1021                 return("OUT-OF-RANGE");
1022
1023         return(ttab[t]);
1024 }
1025
1026 int
1027 packet_ok(register u_char *buf, int cc, register struct sockaddr_in *from,
1028     register int seq)
1029 {
1030         register struct icmp *icp;
1031         register u_char type, code;
1032         register int hlen;
1033 #ifndef ARCHAIC
1034         register struct ip *ip;
1035
1036         ip = (struct ip *) buf;
1037         hlen = ip->ip_hl << 2;
1038         if (cc < hlen + ICMP_MINLEN) {
1039                 if (verbose)
1040                         Printf("packet too short (%d bytes) from %s\n", cc,
1041                                 inet_ntoa(from->sin_addr));
1042                 return (0);
1043         }
1044         cc -= hlen;
1045         icp = (struct icmp *)(buf + hlen);
1046 #else
1047         icp = (struct icmp *)buf;
1048 #endif
1049         type = icp->icmp_type;
1050         code = icp->icmp_code;
1051         if (type == ICMP_ECHOREPLY
1052             && proto->num == IPPROTO_ICMP
1053             && (*proto->check)((u_char *)icp,seq))
1054                 return -2;
1055         if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
1056             type == ICMP_UNREACH) {
1057                 struct ip *hip;
1058                 u_char *inner;
1059
1060                 hip = &icp->icmp_ip;
1061                 hlen = hip->ip_hl << 2;
1062                 inner = (u_char *)((u_char *)hip + hlen);
1063                 if (hlen + 12 <= cc
1064                     && hip->ip_p == proto->num
1065                     && (*proto->check)(inner, seq))
1066                         return (type == ICMP_TIMXCEED ? -1 : code + 1);
1067         }
1068 #ifndef ARCHAIC
1069         if (verbose) {
1070                 register int i;
1071                 u_int32_t *lp = (u_int32_t *)&icp->icmp_ip;
1072
1073                 Printf("\n%d bytes from %s to ", cc, inet_ntoa(from->sin_addr));
1074                 Printf("%s: icmp type %d (%s) code %d\n",
1075                     inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
1076                 for (i = 4; i < cc ; i += sizeof(*lp))
1077                         Printf("%2d: x%8.8x\n", i, *lp++);
1078         }
1079 #endif
1080         return(0);
1081 }
1082
1083 void
1084 icmp_prep(struct outdata *outdata)
1085 {
1086         struct icmp *const icmpheader = (struct icmp *) outprot;
1087
1088         icmpheader->icmp_type = ICMP_ECHO;
1089         icmpheader->icmp_id = htons(ident);
1090         icmpheader->icmp_seq = htons(outdata->seq);
1091
1092         icmpheader->icmp_cksum = 0;
1093         icmpheader->icmp_cksum = in_cksum((u_short *)icmpheader,
1094             packlen - (sizeof(*outip) + outdata->optlen));
1095         if (icmpheader->icmp_cksum == 0)
1096                 icmpheader->icmp_cksum = 0xffff;
1097
1098 }
1099
1100 int
1101 icmp_check(const u_char *data, int seq)
1102 {
1103         struct icmp *const icmpheader = (struct icmp *) data;
1104
1105         return (icmpheader->icmp_id == htons(ident)
1106             && icmpheader->icmp_seq == htons(seq));
1107 }
1108
1109 void
1110 udp_prep(struct outdata *outdata)
1111 {
1112         struct udphdr *const udp = (struct udphdr *) outprot;
1113
1114         udp->uh_sport = htons(ident);
1115         udp->uh_dport = htons(port + outdata->seq);
1116         udp->uh_ulen = htons((u_short)protlen);
1117 }
1118
1119 int
1120 udp_check(const u_char *data, int seq)
1121 {
1122         struct udphdr *const udp = (struct udphdr *) data;
1123
1124         return (ntohs(udp->uh_sport) == ident
1125             && ntohs(udp->uh_dport) == port + seq);
1126 }
1127
1128 void
1129 tcp_prep(struct outdata *outdata)
1130 {
1131         struct tcphdr *const tcp = (struct tcphdr *) outprot;
1132
1133         tcp->th_sport = htons(ident);
1134         tcp->th_dport = htons(port + outdata->seq);
1135         tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
1136         tcp->th_ack = 0;
1137         tcp->th_off = 5;
1138         tcp->th_flags = TH_SYN;
1139 }
1140
1141 int
1142 tcp_check(const u_char *data, int seq)
1143 {
1144         struct tcphdr *const tcp = (struct tcphdr *) data;
1145
1146         return (ntohs(tcp->th_sport) == ident
1147             && ntohs(tcp->th_dport) == port + seq);
1148 }
1149
1150 void
1151 gre_prep(struct outdata *outdata)
1152 {
1153         struct grehdr *const gre = (struct grehdr *) outprot;
1154
1155         gre->flags = htons(0x2001);
1156         gre->proto = htons(port);
1157         gre->length = 0;
1158         gre->callId = htons(ident + outdata->seq);
1159 }
1160
1161 int
1162 gre_check(const u_char *data, int seq)
1163 {
1164         struct grehdr *const gre = (struct grehdr *) data;
1165
1166         return(ntohs(gre->proto) == port
1167             && ntohs(gre->callId) == ident + seq);
1168 }
1169
1170 void
1171 gen_prep(struct outdata *outdata)
1172 {
1173         u_int16_t *const ptr = (u_int16_t *) outprot;
1174
1175         ptr[0] = htons(ident);
1176         ptr[1] = htons(port + outdata->seq);
1177 }
1178
1179 int
1180 gen_check(const u_char *data, int seq)
1181 {
1182         u_int16_t *const ptr = (u_int16_t *) data;
1183
1184         return(ntohs(ptr[0]) == ident
1185             && ntohs(ptr[1]) == port + seq);
1186 }
1187
1188 void
1189 print(register u_char *buf, register int cc, register struct sockaddr_in *from)
1190 {
1191         register struct ip *ip;
1192         register int hlen;
1193
1194         ip = (struct ip *) buf;
1195         hlen = ip->ip_hl << 2;
1196         cc -= hlen;
1197
1198         if (nflag)
1199                 Printf(" %s", inet_ntoa(from->sin_addr));
1200         else
1201                 Printf(" %s (%s)", inetname(from->sin_addr),
1202                     inet_ntoa(from->sin_addr));
1203
1204         if (verbose)
1205                 Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
1206 }
1207
1208 /*
1209  * Checksum routine for Internet Protocol family headers (C Version)
1210  */
1211 u_short
1212 in_cksum(register u_short *addr, register int len)
1213 {
1214         register int nleft = len;
1215         register u_short *w = addr;
1216         register u_short answer;
1217         register int sum = 0;
1218
1219         /*
1220          *  Our algorithm is simple, using a 32 bit accumulator (sum),
1221          *  we add sequential 16 bit words to it, and at the end, fold
1222          *  back all the carry bits from the top 16 bits into the lower
1223          *  16 bits.
1224          */
1225         while (nleft > 1)  {
1226                 sum += *w++;
1227                 nleft -= 2;
1228         }
1229
1230         /* mop up an odd byte, if necessary */
1231         if (nleft == 1)
1232                 sum += *(u_char *)w;
1233
1234         /*
1235          * add back carry outs from top 16 bits to low 16 bits
1236          */
1237         sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */
1238         sum += (sum >> 16);                     /* add carry */
1239         answer = ~sum;                          /* truncate to 16 bits */
1240         return (answer);
1241 }
1242
1243 /*
1244  * Subtract 2 timeval structs:  out = out - in.
1245  * Out is assumed to be within about LONG_MAX seconds of in.
1246  */
1247 void
1248 tvsub(register struct timeval *out, register struct timeval *in)
1249 {
1250
1251         if ((out->tv_usec -= in->tv_usec) < 0)   {
1252                 --out->tv_sec;
1253                 out->tv_usec += 1000000;
1254         }
1255         out->tv_sec -= in->tv_sec;
1256 }
1257
1258 /*
1259  * Construct an Internet address representation.
1260  * If the nflag has been supplied, give
1261  * numeric value, otherwise try for symbolic name.
1262  */
1263 char *
1264 inetname(struct in_addr in)
1265 {
1266         register char *cp;
1267         register struct hostent *hp;
1268         static int first = 1;
1269         static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1];
1270
1271         if (first && !nflag) {
1272                 first = 0;
1273                 if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
1274                     (cp = strchr(domain, '.')) != NULL) {
1275                         (void)strncpy(domain, cp + 1, sizeof(domain) - 1);
1276                         domain[sizeof(domain) - 1] = '\0';
1277                 } else
1278                         domain[0] = '\0';
1279         }
1280         if (!nflag && in.s_addr != INADDR_ANY) {
1281                 hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
1282                 if (hp != NULL) {
1283                         if ((cp = strchr(hp->h_name, '.')) != NULL &&
1284                             strcmp(cp + 1, domain) == 0)
1285                                 *cp = '\0';
1286                         (void)strncpy(line, hp->h_name, sizeof(line) - 1);
1287                         line[sizeof(line) - 1] = '\0';
1288                         return (line);
1289                 }
1290         }
1291         return (inet_ntoa(in));
1292 }
1293
1294 char *
1295 getaddr(register u_int32_t *ap, register char *hostname)
1296 {
1297         register struct hostent *hp;
1298
1299         *ap = inet_addr(hostname);
1300         if ((int32_t)*ap != -1)
1301                 return (hostname);
1302
1303         hp = gethostbyname(hostname);
1304         if (hp == NULL) {
1305                 Fprintf(stderr, "%s: unknown host %s\n", prog, hostname);
1306                 exit(1);
1307         }
1308         if (hp->h_addrtype != AF_INET || hp->h_length != 4) {
1309                 Fprintf(stderr, "%s: bad host %s\n", prog, hostname);
1310                 exit(1);
1311         }
1312         memcpy((caddr_t)ap, hp->h_addr, hp->h_length);
1313         return (hp->h_name);
1314 }
1315
1316 char *
1317 getsin(register struct sockaddr_in *sin, register char *hostname)
1318 {
1319
1320         memset(sin, 0, sizeof(*sin));
1321         sin->sin_family = AF_INET;
1322         return (getaddr((u_int32_t *)&sin->sin_addr.s_addr, hostname));
1323 }
1324
1325 char *
1326 savestr(register const char *str)
1327 {
1328         register char *cp;
1329
1330         cp = strdup(str);
1331         if (cp == NULL) {
1332                 Fprintf(stderr, "%s: strdup: %s\n", prog, strerror(errno));
1333                 exit(1);
1334         }
1335         return (cp);
1336 }
1337
1338 __dead void
1339 usage(void)
1340 {
1341         extern char version[];
1342
1343         Fprintf(stderr, "Version %s\n", version);
1344         Fprintf(stderr, "Usage: %s [-Sdnrv] [-w wait] [-m max_ttl] [-M min_ttl] \
1345 [-P proto]\n\t [-p port#] [-q nqueries] [-t tos] [-s src_addr] [-g gateway] \
1346 \n\t host [data_size]\n", prog);
1347         exit(1);
1348 }