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