]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/traceroute/traceroute.c
MFC r314000:
[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/sctp_header.h>
225 #include <netinet/udp.h>
226 #include <netinet/tcp.h>
227 #include <netinet/tcpip.h>
228
229 #include <arpa/inet.h>
230
231 #ifdef HAVE_LIBCASPER
232 #include <libcasper.h>
233 #include <casper/cap_dns.h>
234 #endif
235
236 #ifdef  IPSEC
237 #include <net/route.h>
238 #include <netipsec/ipsec.h>     /* XXX */
239 #endif  /* IPSEC */
240
241 #include <ctype.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 HAVE_LIBCASPER
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 HAVE_LIBCASPER
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 HAVE_LIBCASPER
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 /* HAVE_LIBCASPER */
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 HAVE_LIBCASPER
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 HAVE_LIBCASPER
1010         cansandbox = true;
1011 #else
1012         if (nflag)
1013                 cansandbox = true;
1014         else
1015                 cansandbox = false;
1016 #endif
1017
1018         /*
1019          * Here we enter capability mode. Further down access to global
1020          * namespaces (e.g filesystem) is restricted (see capsicum(4)).
1021          * We must connect(2) our socket before this point.
1022          */
1023         if (cansandbox && cap_enter() < 0) {
1024                 Fprintf(stderr, "%s: cap_enter: %s\n", prog, strerror(errno));
1025                 exit(1);
1026         }
1027
1028         cap_rights_init(&rights, CAP_SEND, CAP_SETSOCKOPT);
1029         if (cansandbox && cap_rights_limit(sndsock, &rights) < 0) {
1030                 Fprintf(stderr, "%s: cap_rights_limit sndsock: %s\n", prog,
1031                     strerror(errno));
1032                 exit(1);
1033         }
1034
1035         cap_rights_init(&rights, CAP_RECV, CAP_EVENT);
1036         if (cansandbox && cap_rights_limit(s, &rights) < 0) {
1037                 Fprintf(stderr, "%s: cap_rights_limit s: %s\n", prog,
1038                     strerror(errno));
1039                 exit(1);
1040         }
1041
1042 #if     defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
1043         if (setpolicy(sndsock, "in bypass") < 0)
1044                 errx(1, "%s", ipsec_strerror());
1045
1046         if (setpolicy(sndsock, "out bypass") < 0)
1047                 errx(1, "%s", ipsec_strerror());
1048 #endif  /* defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) */
1049
1050         Fprintf(stderr, "%s to %s (%s)",
1051             prog, hostname, inet_ntoa(to->sin_addr));
1052         if (source)
1053                 Fprintf(stderr, " from %s", source);
1054         Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen);
1055         (void)fflush(stderr);
1056
1057         for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
1058                 u_int32_t lastaddr = 0;
1059                 int gotlastaddr = 0;
1060                 int got_there = 0;
1061                 int unreachable = 0;
1062                 int sentfirst = 0;
1063                 int loss;
1064
1065                 Printf("%2d ", ttl);
1066                 for (probe = 0, loss = 0; probe < nprobes; ++probe) {
1067                         register int cc;
1068                         struct timeval t1, t2;
1069                         register struct ip *ip;
1070                         struct outdata outdata;
1071
1072                         if (sentfirst && pausemsecs > 0)
1073                                 usleep(pausemsecs * 1000);
1074                         /* Prepare outgoing data */
1075                         outdata.seq = ++seq;
1076                         outdata.ttl = ttl;
1077
1078                         /* Avoid alignment problems by copying bytewise: */
1079                         (void)gettimeofday(&t1, NULL);
1080                         memcpy(&outdata.tv, &t1, sizeof(outdata.tv));
1081
1082                         /* Finalize and send packet */
1083                         (*proto->prepare)(&outdata);
1084                         send_probe(seq, ttl);
1085                         ++sentfirst;
1086
1087                         /* Wait for a reply */
1088                         while ((cc = wait_for_reply(s, from, &t1)) != 0) {
1089                                 double T;
1090                                 int precis;
1091
1092                                 (void)gettimeofday(&t2, NULL);
1093                                 i = packet_ok(packet, cc, from, seq);
1094                                 /* Skip short packet */
1095                                 if (i == 0)
1096                                         continue;
1097                                 if (!gotlastaddr ||
1098                                     from->sin_addr.s_addr != lastaddr) {
1099                                         if (gotlastaddr) printf("\n   ");
1100                                         print(packet, cc, from);
1101                                         lastaddr = from->sin_addr.s_addr;
1102                                         ++gotlastaddr;
1103                                 }
1104                                 T = deltaT(&t1, &t2);
1105 #ifdef SANE_PRECISION
1106                                 if (T >= 1000.0)
1107                                         precis = 0;
1108                                 else if (T >= 100.0)
1109                                         precis = 1;
1110                                 else if (T >= 10.0)
1111                                         precis = 2;
1112                                 else
1113 #endif
1114                                         precis = 3;
1115                                 Printf("  %.*f ms", precis, T);
1116                                 if (printdiff) {
1117                                         Printf("\n");
1118                                         Printf("%*.*s%s\n",
1119                                             -(outip->ip_hl << 3),
1120                                             outip->ip_hl << 3,
1121                                             ip_hdr_key,
1122                                             proto->key);
1123                                         pkt_compare((void *)outip, packlen,
1124                                             (void *)hip, hiplen);
1125                                 }
1126                                 if (i == -2) {
1127 #ifndef ARCHAIC
1128                                         ip = (struct ip *)packet;
1129                                         if (ip->ip_ttl <= 1)
1130                                                 Printf(" !");
1131 #endif
1132                                         ++got_there;
1133                                         break;
1134                                 }
1135                                 /* time exceeded in transit */
1136                                 if (i == -1)
1137                                         break;
1138                                 code = i - 1;
1139                                 switch (code) {
1140
1141                                 case ICMP_UNREACH_PORT:
1142 #ifndef ARCHAIC
1143                                         ip = (struct ip *)packet;
1144                                         if (ip->ip_ttl <= 1)
1145                                                 Printf(" !");
1146 #endif
1147                                         ++got_there;
1148                                         break;
1149
1150                                 case ICMP_UNREACH_NET:
1151                                         ++unreachable;
1152                                         Printf(" !N");
1153                                         break;
1154
1155                                 case ICMP_UNREACH_HOST:
1156                                         ++unreachable;
1157                                         Printf(" !H");
1158                                         break;
1159
1160                                 case ICMP_UNREACH_PROTOCOL:
1161                                         ++got_there;
1162                                         Printf(" !P");
1163                                         break;
1164
1165                                 case ICMP_UNREACH_NEEDFRAG:
1166                                         ++unreachable;
1167                                         Printf(" !F-%d", pmtu);
1168                                         break;
1169
1170                                 case ICMP_UNREACH_SRCFAIL:
1171                                         ++unreachable;
1172                                         Printf(" !S");
1173                                         break;
1174
1175                                 case ICMP_UNREACH_NET_UNKNOWN:
1176                                         ++unreachable;
1177                                         Printf(" !U");
1178                                         break;
1179
1180                                 case ICMP_UNREACH_HOST_UNKNOWN:
1181                                         ++unreachable;
1182                                         Printf(" !W");
1183                                         break;
1184
1185                                 case ICMP_UNREACH_ISOLATED:
1186                                         ++unreachable;
1187                                         Printf(" !I");
1188                                         break;
1189
1190                                 case ICMP_UNREACH_NET_PROHIB:
1191                                         ++unreachable;
1192                                         Printf(" !A");
1193                                         break;
1194
1195                                 case ICMP_UNREACH_HOST_PROHIB:
1196                                         ++unreachable;
1197                                         Printf(" !Z");
1198                                         break;
1199
1200                                 case ICMP_UNREACH_TOSNET:
1201                                         ++unreachable;
1202                                         Printf(" !Q");
1203                                         break;
1204
1205                                 case ICMP_UNREACH_TOSHOST:
1206                                         ++unreachable;
1207                                         Printf(" !T");
1208                                         break;
1209
1210                                 case ICMP_UNREACH_FILTER_PROHIB:
1211                                         ++unreachable;
1212                                         Printf(" !X");
1213                                         break;
1214
1215                                 case ICMP_UNREACH_HOST_PRECEDENCE:
1216                                         ++unreachable;
1217                                         Printf(" !V");
1218                                         break;
1219
1220                                 case ICMP_UNREACH_PRECEDENCE_CUTOFF:
1221                                         ++unreachable;
1222                                         Printf(" !C");
1223                                         break;
1224
1225                                 default:
1226                                         ++unreachable;
1227                                         Printf(" !<%d>", code);
1228                                         break;
1229                                 }
1230                                 break;
1231                         }
1232                         if (cc == 0) {
1233                                 loss++;
1234                                 Printf(" *");
1235                         }
1236                         (void)fflush(stdout);
1237                 }
1238                 if (sump) {
1239                         Printf(" (%d%% loss)", (loss * 100) / nprobes);
1240                 }
1241                 putchar('\n');
1242                 if (got_there ||
1243                     (unreachable > 0 && unreachable >= nprobes - 1))
1244                         break;
1245         }
1246         if (as_path)
1247                 as_shutdown(asn);
1248         exit(0);
1249 }
1250
1251 int
1252 wait_for_reply(register int sock, register struct sockaddr_in *fromp,
1253     register const struct timeval *tp)
1254 {
1255         fd_set *fdsp;
1256         size_t nfds;
1257         struct timeval now, wait;
1258         register int cc = 0;
1259         register int error;
1260         int fromlen = sizeof(*fromp);
1261
1262         nfds = howmany(sock + 1, NFDBITS);
1263         if ((fdsp = malloc(nfds * sizeof(fd_mask))) == NULL)
1264                 err(1, "malloc");
1265         memset(fdsp, 0, nfds * sizeof(fd_mask));
1266         FD_SET(sock, fdsp);
1267
1268         wait.tv_sec = tp->tv_sec + waittime;
1269         wait.tv_usec = tp->tv_usec;
1270         (void)gettimeofday(&now, NULL);
1271         tvsub(&wait, &now);
1272         if (wait.tv_sec < 0) {
1273                 wait.tv_sec = 0;
1274                 wait.tv_usec = 1;
1275         }
1276
1277         error = select(sock + 1, fdsp, NULL, NULL, &wait);
1278         if (error == -1 && errno == EINVAL) {
1279                 Fprintf(stderr, "%s: botched select() args\n", prog);
1280                 exit(1);
1281         }
1282         if (error > 0)
1283                 cc = recvfrom(sock, (char *)packet, sizeof(packet), 0,
1284                             (struct sockaddr *)fromp, &fromlen);
1285
1286         free(fdsp);
1287         return(cc);
1288 }
1289
1290 void
1291 send_probe(int seq, int ttl)
1292 {
1293         register int cc;
1294
1295         outip->ip_ttl = ttl;
1296         outip->ip_id = htons(ident + seq);
1297
1298         /* XXX undocumented debugging hack */
1299         if (verbose > 1) {
1300                 register const u_short *sp;
1301                 register int nshorts, i;
1302
1303                 sp = (u_short *)outip;
1304                 nshorts = (u_int)packlen / sizeof(u_short);
1305                 i = 0;
1306                 Printf("[ %d bytes", packlen);
1307                 while (--nshorts >= 0) {
1308                         if ((i++ % 8) == 0)
1309                                 Printf("\n\t");
1310                         Printf(" %04x", ntohs(*sp++));
1311                 }
1312                 if (packlen & 1) {
1313                         if ((i % 8) == 0)
1314                                 Printf("\n\t");
1315                         Printf(" %02x", *(u_char *)sp);
1316                 }
1317                 Printf("]\n");
1318         }
1319
1320 #if !defined(IP_HDRINCL) && defined(IP_TTL)
1321         if (setsockopt(sndsock, IPPROTO_IP, IP_TTL,
1322             (char *)&ttl, sizeof(ttl)) < 0) {
1323                 Fprintf(stderr, "%s: setsockopt ttl %d: %s\n",
1324                     prog, ttl, strerror(errno));
1325                 exit(1);
1326         }
1327 #endif
1328
1329         cc = send(sndsock, (char *)outip, packlen, 0);
1330         if (cc < 0 || cc != packlen)  {
1331                 if (cc < 0)
1332                         Fprintf(stderr, "%s: sendto: %s\n",
1333                             prog, strerror(errno));
1334                 Printf("%s: wrote %s %d chars, ret=%d\n",
1335                     prog, hostname, packlen, cc);
1336                 (void)fflush(stdout);
1337         }
1338 }
1339
1340 #if     defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
1341 int
1342 setpolicy(so, policy)
1343         int so;
1344         char *policy;
1345 {
1346         char *buf;
1347
1348         buf = ipsec_set_policy(policy, strlen(policy));
1349         if (buf == NULL) {
1350                 warnx("%s", ipsec_strerror());
1351                 return -1;
1352         }
1353         (void)setsockopt(so, IPPROTO_IP, IP_IPSEC_POLICY,
1354                 buf, ipsec_get_policylen(buf));
1355
1356         free(buf);
1357
1358         return 0;
1359 }
1360 #endif
1361
1362 double
1363 deltaT(struct timeval *t1p, struct timeval *t2p)
1364 {
1365         register double dt;
1366
1367         dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1368              (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1369         return (dt);
1370 }
1371
1372 /*
1373  * Convert an ICMP "type" field to a printable string.
1374  */
1375 char *
1376 pr_type(register u_char t)
1377 {
1378         static char *ttab[] = {
1379         "Echo Reply",   "ICMP 1",       "ICMP 2",       "Dest Unreachable",
1380         "Source Quench", "Redirect",    "ICMP 6",       "ICMP 7",
1381         "Echo",         "ICMP 9",       "ICMP 10",      "Time Exceeded",
1382         "Param Problem", "Timestamp",   "Timestamp Reply", "Info Request",
1383         "Info Reply"
1384         };
1385
1386         if (t > 16)
1387                 return("OUT-OF-RANGE");
1388
1389         return(ttab[t]);
1390 }
1391
1392 int
1393 packet_ok(register u_char *buf, int cc, register struct sockaddr_in *from,
1394     register int seq)
1395 {
1396         register struct icmp *icp;
1397         register u_char type, code;
1398         register int hlen;
1399 #ifndef ARCHAIC
1400         register struct ip *ip;
1401
1402         ip = (struct ip *) buf;
1403         hlen = ip->ip_hl << 2;
1404         if (cc < hlen + ICMP_MINLEN) {
1405                 if (verbose)
1406                         Printf("packet too short (%d bytes) from %s\n", cc,
1407                                 inet_ntoa(from->sin_addr));
1408                 return (0);
1409         }
1410         cc -= hlen;
1411         icp = (struct icmp *)(buf + hlen);
1412 #else
1413         icp = (struct icmp *)buf;
1414 #endif
1415         type = icp->icmp_type;
1416         code = icp->icmp_code;
1417         /* Path MTU Discovery (RFC1191) */
1418         if (code != ICMP_UNREACH_NEEDFRAG)
1419                 pmtu = 0;
1420         else {
1421 #ifdef HAVE_ICMP_NEXTMTU
1422                 pmtu = ntohs(icp->icmp_nextmtu);
1423 #else
1424                 pmtu = ntohs(((struct my_pmtu *)&icp->icmp_void)->ipm_nextmtu);
1425 #endif
1426         }
1427         if (type == ICMP_ECHOREPLY
1428             && proto->num == IPPROTO_ICMP
1429             && (*proto->check)((u_char *)icp, (u_char)seq))
1430                 return -2;
1431         if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
1432             type == ICMP_UNREACH) {
1433                 u_char *inner;
1434
1435                 hip = &icp->icmp_ip;
1436                 hiplen = ((u_char *)icp + cc) - (u_char *)hip;
1437                 hlen = hip->ip_hl << 2;
1438                 inner = (u_char *)((u_char *)hip + hlen);
1439                 if (hlen + 16 <= cc
1440                     && hip->ip_p == proto->num
1441                     && (*proto->check)(inner, (u_char)seq))
1442                         return (type == ICMP_TIMXCEED ? -1 : code + 1);
1443         }
1444 #ifndef ARCHAIC
1445         if (verbose) {
1446                 register int i;
1447                 u_int32_t *lp = (u_int32_t *)&icp->icmp_ip;
1448
1449                 Printf("\n%d bytes from %s to ", cc, inet_ntoa(from->sin_addr));
1450                 Printf("%s: icmp type %d (%s) code %d\n",
1451                     inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
1452                 for (i = 4; i <= cc - ICMP_MINLEN; i += sizeof(*lp))
1453                         Printf("%2d: %8.8x\n", i, ntohl(*lp++));
1454         }
1455 #endif
1456         return(0);
1457 }
1458
1459 void
1460 icmp_prep(struct outdata *outdata)
1461 {
1462         struct icmp *const icmpheader = (struct icmp *) outp;
1463
1464         icmpheader->icmp_type = ICMP_ECHO;
1465         icmpheader->icmp_id = htons(ident);
1466         icmpheader->icmp_seq = htons(outdata->seq);
1467         icmpheader->icmp_cksum = 0;
1468         icmpheader->icmp_cksum = in_cksum((u_short *)icmpheader, protlen);
1469         if (icmpheader->icmp_cksum == 0)
1470                 icmpheader->icmp_cksum = 0xffff;
1471 }
1472
1473 int
1474 icmp_check(const u_char *data, int seq)
1475 {
1476         struct icmp *const icmpheader = (struct icmp *) data;
1477
1478         return (icmpheader->icmp_id == htons(ident)
1479             && icmpheader->icmp_seq == htons(seq));
1480 }
1481
1482 void
1483 udp_prep(struct outdata *outdata)
1484 {
1485         struct udphdr *const outudp = (struct udphdr *) outp;
1486
1487         outudp->uh_sport = htons(ident + (fixedPort ? outdata->seq : 0));
1488         outudp->uh_dport = htons(port + (fixedPort ? 0 : outdata->seq));
1489         outudp->uh_ulen = htons((u_short)protlen);
1490         outudp->uh_sum = 0;
1491         if (doipcksum) {
1492             u_short sum = p_cksum(outip, (u_short*)outudp, protlen, protlen);
1493             outudp->uh_sum = (sum) ? sum : 0xffff;
1494         }
1495
1496         return;
1497 }
1498
1499 int
1500 udp_check(const u_char *data, int seq)
1501 {
1502         struct udphdr *const udp = (struct udphdr *) data;
1503
1504         return (ntohs(udp->uh_sport) == ident + (fixedPort ? seq : 0) &&
1505             ntohs(udp->uh_dport) == port + (fixedPort ? 0 : seq));
1506 }
1507
1508 void
1509 udplite_prep(struct outdata *outdata)
1510 {
1511         struct udphdr *const outudp = (struct udphdr *) outp;
1512
1513         outudp->uh_sport = htons(ident + (fixedPort ? outdata->seq : 0));
1514         outudp->uh_dport = htons(port + (fixedPort ? 0 : outdata->seq));
1515         outudp->uh_ulen = htons(8);
1516         outudp->uh_sum = 0;
1517         if (doipcksum) {
1518             u_short sum = p_cksum(outip, (u_short*)outudp, protlen, 8);
1519             outudp->uh_sum = (sum) ? sum : 0xffff;
1520         }
1521
1522         return;
1523 }
1524
1525 int
1526 udplite_check(const u_char *data, int seq)
1527 {
1528         struct udphdr *const udp = (struct udphdr *) data;
1529
1530         return (ntohs(udp->uh_sport) == ident + (fixedPort ? seq : 0) &&
1531             ntohs(udp->uh_dport) == port + (fixedPort ? 0 : seq));
1532 }
1533
1534 void
1535 tcp_prep(struct outdata *outdata)
1536 {
1537         struct tcphdr *const tcp = (struct tcphdr *) outp;
1538
1539         tcp->th_sport = htons(ident);
1540         tcp->th_dport = htons(port + (fixedPort ? 0 : outdata->seq));
1541         tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
1542         tcp->th_ack = 0;
1543         tcp->th_off = 5;
1544         tcp->th_flags = TH_SYN;
1545         tcp->th_sum = 0;
1546
1547         if (doipcksum)
1548             tcp->th_sum = p_cksum(outip, (u_short*)tcp, protlen, protlen);
1549 }
1550
1551 int
1552 tcp_check(const u_char *data, int seq)
1553 {
1554         struct tcphdr *const tcp = (struct tcphdr *) data;
1555
1556         return (ntohs(tcp->th_sport) == ident
1557             && ntohs(tcp->th_dport) == port + (fixedPort ? 0 : seq)
1558             && tcp->th_seq == (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport));
1559 }
1560
1561 void
1562 sctp_prep(struct outdata *outdata)
1563 {
1564         struct sctphdr *const sctp = (struct sctphdr *) outp;
1565         struct sctp_chunkhdr *chk;
1566         struct sctp_init_chunk *init;
1567         struct sctp_paramhdr *param;
1568
1569         sctp->src_port = htons(ident);
1570         sctp->dest_port = htons(port + (fixedPort ? 0 : outdata->seq));
1571         if (protlen >= (int)(sizeof(struct sctphdr) +
1572             sizeof(struct sctp_init_chunk))) {
1573                 sctp->v_tag = 0;
1574         } else {
1575                 sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port;
1576         }
1577         sctp->checksum = htonl(0);
1578         if (protlen >= (int)(sizeof(struct sctphdr) +
1579             sizeof(struct sctp_init_chunk))) {
1580                 /*
1581                  * Send a packet containing an INIT chunk. This works
1582                  * better in case of firewalls on the path, but
1583                  * results in a probe packet containing at least
1584                  * 32 bytes of payload. For shorter payloads, use
1585                  * SHUTDOWN-ACK chunks.
1586                  */
1587                 init = (struct sctp_init_chunk *)(sctp + 1);
1588                 init->ch.chunk_type = SCTP_INITIATION;
1589                 init->ch.chunk_flags = 0;
1590                 init->ch.chunk_length = htons((u_int16_t)(protlen -
1591                     sizeof(struct sctphdr)));
1592                 init->init.initiate_tag = (sctp->src_port << 16) |
1593                     sctp->dest_port;
1594                 init->init.a_rwnd = htonl(1500);
1595                 init->init.num_outbound_streams = htons(1);
1596                 init->init.num_inbound_streams = htons(1);
1597                 init->init.initial_tsn = htonl(0);
1598                 if (protlen >= (int)(sizeof(struct sctphdr) +
1599                     sizeof(struct sctp_init_chunk) +
1600                     sizeof(struct sctp_paramhdr))) {
1601                         param = (struct sctp_paramhdr *)(init + 1);
1602                         param->param_type = htons(SCTP_PAD);
1603                         param->param_length =
1604                             htons((u_int16_t)(protlen -
1605                             sizeof(struct sctphdr) -
1606                             sizeof(struct sctp_init_chunk)));
1607                 }
1608         } else {
1609                 /*
1610                  * Send a packet containing a SHUTDOWN-ACK chunk,
1611                  * possibly followed by a PAD chunk.
1612                  */
1613                 if (protlen >=
1614                     (int)(sizeof(struct sctphdr) +
1615                     sizeof(struct sctp_chunkhdr))) {
1616                         chk = (struct sctp_chunkhdr *)(sctp + 1);
1617                         chk->chunk_type = SCTP_SHUTDOWN_ACK;
1618                         chk->chunk_flags = 0;
1619                         chk->chunk_length = htons(4);
1620                 }
1621                 if (protlen >=
1622                     (int)(sizeof(struct sctphdr) +
1623                     2 * sizeof(struct sctp_chunkhdr))) {
1624                         chk = chk + 1;
1625                         chk->chunk_type = SCTP_PAD_CHUNK;
1626                         chk->chunk_flags = 0;
1627                         chk->chunk_length = htons(protlen -
1628                             (sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr)));
1629                 }
1630         }
1631         if (doipcksum) {
1632                 sctp->checksum = sctp_crc32c(sctp, protlen);
1633         }
1634 }
1635
1636 int
1637 sctp_check(const u_char *data, int seq)
1638 {
1639         struct sctphdr *const sctp = (struct sctphdr *) data;
1640
1641         if (ntohs(sctp->src_port) != ident ||
1642             ntohs(sctp->dest_port) != port + (fixedPort ? 0 : seq))
1643                 return (0);
1644         if (protlen < (int)(sizeof(struct sctphdr) +
1645             sizeof(struct sctp_init_chunk))) {
1646                 return (sctp->v_tag ==
1647                     (u_int32_t)((sctp->src_port << 16) | sctp->dest_port));
1648         } else {
1649                 /*
1650                  * Don't verify the initiate_tag, since it is not available,
1651                  * most of the time.
1652                  */
1653                 return (sctp->v_tag == 0);
1654         }
1655 }
1656
1657 void
1658 gre_prep(struct outdata *outdata)
1659 {
1660         struct grehdr *const gre = (struct grehdr *) outp;
1661
1662         gre->flags = htons(0x2001);
1663         gre->proto = htons(port);
1664         gre->length = 0;
1665         gre->callId = htons(ident + outdata->seq);
1666 }
1667
1668 int
1669 gre_check(const u_char *data, int seq)
1670 {
1671         struct grehdr *const gre = (struct grehdr *) data;
1672
1673         return(ntohs(gre->proto) == port
1674             && ntohs(gre->callId) == ident + seq);
1675 }
1676
1677 void
1678 gen_prep(struct outdata *outdata)
1679 {
1680         u_int16_t *const ptr = (u_int16_t *) outp;
1681
1682         ptr[0] = htons(ident);
1683         ptr[1] = htons(port + outdata->seq);
1684 }
1685
1686 int
1687 gen_check(const u_char *data, int seq)
1688 {
1689         u_int16_t *const ptr = (u_int16_t *) data;
1690
1691         return(ntohs(ptr[0]) == ident
1692             && ntohs(ptr[1]) == port + seq);
1693 }
1694
1695 void
1696 print(register u_char *buf, register int cc, register struct sockaddr_in *from)
1697 {
1698         register struct ip *ip;
1699         register int hlen;
1700         char addr[INET_ADDRSTRLEN];
1701
1702         ip = (struct ip *) buf;
1703         hlen = ip->ip_hl << 2;
1704         cc -= hlen;
1705
1706         strlcpy(addr, inet_ntoa(from->sin_addr), sizeof(addr));
1707
1708         if (as_path)
1709                 Printf(" [AS%u]", as_lookup(asn, addr, AF_INET));
1710
1711         if (nflag)
1712                 Printf(" %s", addr);
1713         else
1714                 Printf(" %s (%s)", inetname(from->sin_addr), addr);
1715
1716         if (verbose)
1717                 Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
1718 }
1719
1720 /*
1721  * Checksum routine for UDP and TCP headers.
1722  */
1723 u_short
1724 p_cksum(struct ip *ip, u_short *data, int len, int cov)
1725 {
1726         static struct ipovly ipo;
1727         u_short sum[2];
1728
1729         ipo.ih_pr = ip->ip_p;
1730         ipo.ih_len = htons(len);
1731         ipo.ih_src = ip->ip_src;
1732         ipo.ih_dst = ip->ip_dst;
1733
1734         sum[1] = in_cksum((u_short*)&ipo, sizeof(ipo)); /* pseudo ip hdr cksum */
1735         sum[0] = in_cksum(data, cov);                   /* payload data cksum */
1736
1737         return ~in_cksum(sum, sizeof(sum));
1738 }
1739
1740 /*
1741  * Checksum routine for Internet Protocol family headers (C Version)
1742  */
1743 u_short
1744 in_cksum(register u_short *addr, register int len)
1745 {
1746         register int nleft = len;
1747         register u_short *w = addr;
1748         register u_short answer;
1749         register int sum = 0;
1750
1751         /*
1752          *  Our algorithm is simple, using a 32 bit accumulator (sum),
1753          *  we add sequential 16 bit words to it, and at the end, fold
1754          *  back all the carry bits from the top 16 bits into the lower
1755          *  16 bits.
1756          */
1757         while (nleft > 1)  {
1758                 sum += *w++;
1759                 nleft -= 2;
1760         }
1761
1762         /* mop up an odd byte, if necessary */
1763         if (nleft == 1)
1764                 sum += *(u_char *)w;
1765
1766         /*
1767          * add back carry outs from top 16 bits to low 16 bits
1768          */
1769         sum = (sum >> 16) + (sum & 0xffff);     /* add hi 16 to low 16 */
1770         sum += (sum >> 16);                     /* add carry */
1771         answer = ~sum;                          /* truncate to 16 bits */
1772         return (answer);
1773 }
1774
1775 /*
1776  * CRC32C routine for the Stream Control Transmission Protocol
1777  */
1778
1779 #define CRC32C(c, d) (c = (c>>8) ^ crc_c[(c^(d))&0xFF])
1780
1781 static u_int32_t crc_c[256] = {
1782         0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
1783         0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
1784         0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
1785         0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
1786         0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
1787         0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
1788         0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
1789         0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
1790         0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
1791         0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
1792         0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
1793         0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
1794         0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
1795         0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
1796         0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
1797         0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
1798         0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
1799         0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
1800         0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
1801         0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
1802         0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
1803         0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
1804         0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
1805         0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
1806         0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
1807         0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
1808         0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
1809         0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
1810         0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
1811         0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
1812         0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
1813         0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
1814         0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
1815         0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
1816         0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
1817         0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
1818         0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
1819         0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
1820         0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
1821         0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
1822         0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
1823         0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
1824         0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
1825         0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
1826         0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
1827         0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
1828         0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
1829         0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
1830         0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
1831         0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
1832         0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
1833         0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
1834         0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
1835         0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
1836         0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
1837         0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
1838         0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
1839         0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
1840         0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
1841         0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
1842         0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
1843         0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
1844         0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
1845         0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
1846 };
1847
1848 u_int32_t
1849 sctp_crc32c(const void *packet, u_int32_t len)
1850 {
1851         u_int32_t i, crc32c;
1852         u_int8_t byte0, byte1, byte2, byte3;
1853         const u_int8_t *buf = (const u_int8_t *)packet;
1854
1855         crc32c = ~0;
1856         for (i = 0; i < len; i++)
1857                 CRC32C(crc32c, buf[i]);
1858         crc32c = ~crc32c;
1859         byte0  = crc32c & 0xff;
1860         byte1  = (crc32c>>8) & 0xff;
1861         byte2  = (crc32c>>16) & 0xff;
1862         byte3  = (crc32c>>24) & 0xff;
1863         crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
1864         return htonl(crc32c);
1865 }
1866
1867 /*
1868  * Subtract 2 timeval structs:  out = out - in.
1869  * Out is assumed to be within about LONG_MAX seconds of in.
1870  */
1871 void
1872 tvsub(register struct timeval *out, register struct timeval *in)
1873 {
1874
1875         if ((out->tv_usec -= in->tv_usec) < 0)   {
1876                 --out->tv_sec;
1877                 out->tv_usec += 1000000;
1878         }
1879         out->tv_sec -= in->tv_sec;
1880 }
1881
1882 /*
1883  * Construct an Internet address representation.
1884  * If the nflag has been supplied, give
1885  * numeric value, otherwise try for symbolic name.
1886  */
1887 char *
1888 inetname(struct in_addr in)
1889 {
1890         register char *cp;
1891         register struct hostent *hp;
1892         static int first = 1;
1893         static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1];
1894
1895         if (first && !nflag) {
1896                 first = 0;
1897                 if (gethostname(domain, sizeof(domain) - 1) < 0)
1898                         domain[0] = '\0';
1899                 else {
1900                         cp = strchr(domain, '.');
1901                         if (cp == NULL) {
1902 #ifdef HAVE_LIBCASPER
1903                                 if (capdns != NULL)
1904                                         hp = cap_gethostbyname(capdns, domain);
1905                                 else
1906 #endif
1907                                         hp = gethostbyname(domain);
1908                                 if (hp != NULL)
1909                                         cp = strchr(hp->h_name, '.');
1910                         }
1911                         if (cp == NULL)
1912                                 domain[0] = '\0';
1913                         else {
1914                                 ++cp;
1915                                 (void)strncpy(domain, cp, sizeof(domain) - 1);
1916                                 domain[sizeof(domain) - 1] = '\0';
1917                         }
1918                 }
1919         }
1920         if (!nflag && in.s_addr != INADDR_ANY) {
1921 #ifdef HAVE_LIBCASPER
1922                 if (capdns != NULL)
1923                         hp = cap_gethostbyaddr(capdns, (char *)&in, sizeof(in),
1924                             AF_INET);
1925                 else
1926 #endif
1927                         hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
1928                 if (hp != NULL) {
1929                         if ((cp = strchr(hp->h_name, '.')) != NULL &&
1930                             strcmp(cp + 1, domain) == 0)
1931                                 *cp = '\0';
1932                         (void)strncpy(line, hp->h_name, sizeof(line) - 1);
1933                         line[sizeof(line) - 1] = '\0';
1934                         return (line);
1935                 }
1936         }
1937         return (inet_ntoa(in));
1938 }
1939
1940 struct hostinfo *
1941 gethostinfo(register char *hostname)
1942 {
1943         register int n;
1944         register struct hostent *hp;
1945         register struct hostinfo *hi;
1946         register char **p;
1947         register u_int32_t addr, *ap;
1948
1949         if (strlen(hostname) >= MAXHOSTNAMELEN) {
1950                 Fprintf(stderr, "%s: hostname \"%.32s...\" is too long\n",
1951                     prog, hostname);
1952                 exit(1);
1953         }
1954         hi = calloc(1, sizeof(*hi));
1955         if (hi == NULL) {
1956                 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1957                 exit(1);
1958         }
1959         addr = inet_addr(hostname);
1960         if ((int32_t)addr != -1) {
1961                 hi->name = strdup(hostname);
1962                 hi->n = 1;
1963                 hi->addrs = calloc(1, sizeof(hi->addrs[0]));
1964                 if (hi->addrs == NULL) {
1965                         Fprintf(stderr, "%s: calloc %s\n",
1966                             prog, strerror(errno));
1967                         exit(1);
1968                 }
1969                 hi->addrs[0] = addr;
1970                 return (hi);
1971         }
1972
1973 #ifdef HAVE_LIBCASPER
1974         if (capdns != NULL)
1975                 hp = cap_gethostbyname(capdns, hostname);
1976         else
1977 #endif
1978                 hp = gethostbyname(hostname);
1979         if (hp == NULL) {
1980                 Fprintf(stderr, "%s: unknown host %s\n", prog, hostname);
1981                 exit(1);
1982         }
1983         if (hp->h_addrtype != AF_INET || hp->h_length != 4) {
1984                 Fprintf(stderr, "%s: bad host %s\n", prog, hostname);
1985                 exit(1);
1986         }
1987         hi->name = strdup(hp->h_name);
1988         for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
1989                 continue;
1990         hi->n = n;
1991         hi->addrs = calloc(n, sizeof(hi->addrs[0]));
1992         if (hi->addrs == NULL) {
1993                 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1994                 exit(1);
1995         }
1996         for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
1997                 memcpy(ap, *p, sizeof(*ap));
1998         return (hi);
1999 }
2000
2001 void
2002 freehostinfo(register struct hostinfo *hi)
2003 {
2004         if (hi->name != NULL) {
2005                 free(hi->name);
2006                 hi->name = NULL;
2007         }
2008         free((char *)hi->addrs);
2009         free((char *)hi);
2010 }
2011
2012 void
2013 getaddr(register u_int32_t *ap, register char *hostname)
2014 {
2015         register struct hostinfo *hi;
2016
2017         hi = gethostinfo(hostname);
2018         *ap = hi->addrs[0];
2019         freehostinfo(hi);
2020 }
2021
2022 void
2023 setsin(register struct sockaddr_in *sin, register u_int32_t addr)
2024 {
2025
2026         memset(sin, 0, sizeof(*sin));
2027 #ifdef HAVE_SOCKADDR_SA_LEN
2028         sin->sin_len = sizeof(*sin);
2029 #endif
2030         sin->sin_family = AF_INET;
2031         sin->sin_addr.s_addr = addr;
2032 }
2033
2034 /* String to value with optional min and max. Handles decimal and hex. */
2035 int
2036 str2val(register const char *str, register const char *what,
2037     register int mi, register int ma)
2038 {
2039         register const char *cp;
2040         register int val;
2041         char *ep;
2042
2043         if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
2044                 cp = str + 2;
2045                 val = (int)strtol(cp, &ep, 16);
2046         } else
2047                 val = (int)strtol(str, &ep, 10);
2048         if (*ep != '\0') {
2049                 Fprintf(stderr, "%s: \"%s\" bad value for %s \n",
2050                     prog, str, what);
2051                 exit(1);
2052         }
2053         if (val < mi && mi >= 0) {
2054                 if (mi == 0)
2055                         Fprintf(stderr, "%s: %s must be >= %d\n",
2056                             prog, what, mi);
2057                 else
2058                         Fprintf(stderr, "%s: %s must be > %d\n",
2059                             prog, what, mi - 1);
2060                 exit(1);
2061         }
2062         if (val > ma && ma >= 0) {
2063                 Fprintf(stderr, "%s: %s must be <= %d\n", prog, what, ma);
2064                 exit(1);
2065         }
2066         return (val);
2067 }
2068
2069 struct outproto *
2070 setproto(char *pname)
2071 {
2072         struct outproto *proto;
2073         int i;
2074
2075         for (i = 0; protos[i].name != NULL; i++) {
2076                 if (strcasecmp(protos[i].name, pname) == 0) {
2077                         break;
2078                 }
2079         }
2080         proto = &protos[i];
2081         if (proto->name == NULL) {      /* generic handler */
2082                 struct protoent *pe;
2083                 u_long pnum;
2084
2085                 /* Determine the IP protocol number */
2086                 if ((pe = getprotobyname(pname)) != NULL)
2087                         pnum = pe->p_proto;
2088                 else
2089                         pnum = str2val(optarg, "proto number", 1, 255);
2090                 proto->num = pnum;
2091         }
2092         return proto;
2093 }
2094
2095 void
2096 pkt_compare(const u_char *a, int la, const u_char *b, int lb) {
2097         int l;
2098         int i;
2099
2100         for (i = 0; i < la; i++)
2101                 Printf("%02x", (unsigned int)a[i]);
2102         Printf("\n");
2103         l = (la <= lb) ? la : lb;
2104         for (i = 0; i < l; i++)
2105                 if (a[i] == b[i])
2106                         Printf("__");
2107                 else
2108                         Printf("%02x", (unsigned int)b[i]);
2109         for (; i < lb; i++)
2110                 Printf("%02x", (unsigned int)b[i]);
2111         Printf("\n");
2112 }
2113
2114
2115 void
2116 usage(void)
2117 {
2118         extern char version[];
2119
2120         Fprintf(stderr, "Version %s\n", version);
2121         Fprintf(stderr,
2122             "Usage: %s [-adDeFInrSvx] [-f first_ttl] [-g gateway] [-i iface]\n"
2123             "\t[-m max_ttl] [-p port] [-P proto] [-q nqueries] [-s src_addr]\n"
2124             "\t[-t tos] [-w waittime] [-A as_server] [-z pausemsecs] host [packetlen]\n", prog);
2125         exit(1);
2126 }