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