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