2 * Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000
3 * The Regents of the University of California. All rights reserved.
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
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.
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";
27 static const char rcsid[] =
28 "@(#)$Id: traceroute.c,v 1.68 2000/12/14 08:04:33 leres Exp $ (LBL)";
30 static const char rcsid[] =
35 * traceroute host - trace the route ip packets follow going to "host".
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
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).
57 * A sample use might be:
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
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.
77 * A more interesting example is:
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
93 * 13 128.121.54.72 (128.121.54.72) 259 ms 499 ms 279 ms
98 * 18 ALLSPICE.LCS.MIT.EDU (18.26.0.115) 339 ms 279 ms 279 ms
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.
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:
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
127 * 13 rip.Berkeley.EDU (128.32.131.22) 59 ms ! 39 ms ! 39 ms !
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
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.
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.)
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.
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.
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.
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.
193 * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
194 * enhancements to the original distribution.
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...
201 * -- Van Jacobson (van@ee.lbl.gov)
202 * Tue Dec 20 03:50:13 PST 1988
205 #include <sys/param.h>
206 #include <sys/file.h>
207 #include <sys/ioctl.h>
208 #ifdef HAVE_SYS_SELECT_H
209 #include <sys/select.h>
211 #include <sys/socket.h>
212 #ifdef HAVE_SYS_SYSCTL_H
213 #include <sys/sysctl.h>
215 #include <sys/time.h>
217 #include <netinet/in_systm.h>
218 #include <netinet/in.h>
219 #include <netinet/ip.h>
220 #include <netinet/ip_var.h>
221 #include <netinet/ip_icmp.h>
222 #include <netinet/sctp.h>
223 #include <netinet/udp.h>
224 #include <netinet/tcp.h>
225 #include <netinet/tcpip.h>
227 #include <arpa/inet.h>
230 #include <net/route.h>
231 #include <netipsec/ipsec.h> /* XXX */
249 #ifndef ICMP_UNREACH_FILTER_PROHIB
250 #define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohibited filter */
252 #ifndef ICMP_UNREACH_HOST_PRECEDENCE
253 #define ICMP_UNREACH_HOST_PRECEDENCE 14 /* host precedence violation */
255 #ifndef ICMP_UNREACH_PRECEDENCE_CUTOFF
256 #define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* precedence cutoff */
259 #include "findsaddr.h"
260 #include "ifaddrlist.h"
262 #include "traceroute.h"
264 /* Maximum number of gateways (include room for one noop) */
265 #define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(u_int32_t)))
267 #ifndef MAXHOSTNAMELEN
268 #define MAXHOSTNAMELEN 64
271 #define Fprintf (void)fprintf
272 #define Printf (void)printf
274 /* What a GRE packet header looks like */
278 u_int16_t length; /* PPTP version of these fields */
282 #define IPPROTO_GRE 47
285 /* For GRE, we prepare what looks like a PPTP packet */
286 #define GRE_PPTP_PROTO 0x880b
288 /* Host name and address list */
295 /* Data section of the probe packet */
297 u_char seq; /* sequence number of this packet */
298 u_char ttl; /* ttl packet left with */
299 struct timeval tv; /* time packet left */
302 #ifndef HAVE_ICMP_NEXTMTU
303 /* Path MTU Discovery (RFC1191) */
310 u_char packet[512]; /* last inbound (icmp) packet */
312 struct ip *outip; /* last output ip packet */
313 u_char *outp; /* last output inner protocol packet */
315 struct ip *hip = NULL; /* Quoted IP header */
318 /* loose source route gateway list (including room for final destination) */
319 u_int32_t gwlist[NGATEWAYS + 1];
321 int s; /* receive (icmp) socket file descriptor */
322 int sndsock; /* send (udp) socket file descriptor */
324 struct sockaddr whereto; /* Who to try to reach */
325 struct sockaddr wherefrom; /* Who we are */
326 int packlen; /* total length of packet */
327 int protlen; /* length of protocol part of packet */
328 int minpacket; /* min ip packet size */
329 int maxpacket = 32 * 1024; /* max ip packet size */
330 int pmtu; /* Path MTU Discovery (RFC1191) */
337 static const char devnull[] = "/dev/null";
343 u_short port; /* protocol specific base "port" */
345 int options; /* socket options */
347 int waittime = 5; /* time to wait for response (in seconds) */
348 int nflag; /* print addresses numerically */
349 int as_path; /* print as numbers for each hop */
350 char *as_server = NULL;
352 #ifdef CANT_HACK_IPCKSUM
353 int doipcksum = 0; /* don't calculate ip checksums by default */
355 int doipcksum = 1; /* calculate ip checksums by default */
357 int optlen; /* length of ip options */
358 int fixedPort = 0; /* Use fixed destination port for TCP and UDP */
359 int printdiff = 0; /* Print the difference between sent and quoted */
366 double deltaT(struct timeval *, struct timeval *);
367 void freehostinfo(struct hostinfo *);
368 void getaddr(u_int32_t *, char *);
369 struct hostinfo *gethostinfo(char *);
370 u_short in_cksum(u_short *, int);
371 u_int32_t sctp_crc32c(const void *, u_int32_t);
372 char *inetname(struct in_addr);
373 int main(int, char **);
374 u_short p_cksum(struct ip *, u_short *, int, int);
375 int packet_ok(u_char *, int, struct sockaddr_in *, int);
376 char *pr_type(u_char);
377 void print(u_char *, int, struct sockaddr_in *);
379 int setpolicy __P((int so, char *policy));
381 void send_probe(int, int);
382 struct outproto *setproto(char *);
383 int str2val(const char *, const char *, int, int);
384 void tvsub(struct timeval *, struct timeval *);
386 int wait_for_reply(int, struct sockaddr_in *, const struct timeval *);
387 void pkt_compare(const u_char *, int, const u_char *, int);
392 void udp_prep(struct outdata *);
393 int udp_check(const u_char *, int);
394 void udplite_prep(struct outdata *);
395 int udplite_check(const u_char *, int);
396 void tcp_prep(struct outdata *);
397 int tcp_check(const u_char *, int);
398 void sctp_prep(struct outdata *);
399 int sctp_check(const u_char *, int);
400 void gre_prep(struct outdata *);
401 int gre_check(const u_char *, int);
402 void gen_prep(struct outdata *);
403 int gen_check(const u_char *, int);
404 void icmp_prep(struct outdata *);
405 int icmp_check(const u_char *, int);
407 /* Descriptor structure for each outgoing protocol we support */
409 char *name; /* name of protocol */
410 const char *key; /* An ascii key for the bytes of the header */
411 u_char num; /* IP protocol number */
412 u_short hdrlen; /* max size of protocol header */
413 u_short port; /* default base protocol-specific "port" */
414 void (*prepare)(struct outdata *);
415 /* finish preparing an outgoing packet */
416 int (*check)(const u_char *, int);
417 /* check an incoming packet */
420 /* List of supported protocols. The first one is the default. The last
421 one is the handler for generic protocols not explicitly listed. */
422 struct outproto protos[] = {
427 sizeof(struct udphdr),
436 sizeof(struct udphdr),
443 "spt dpt seq ack xxflwin sum urp",
445 sizeof(struct tcphdr),
452 "spt dpt vtag crc tyfllen tyfllen ",
454 sizeof(struct sctphdr),
463 sizeof(struct grehdr),
487 struct outproto *proto = &protos[0];
489 const char *ip_hdr_key = "vhtslen id off tlprsum srcip dstip opts";
492 main(int argc, char **argv)
494 register int op, code, n;
496 register const char *err;
497 register u_int32_t *ap;
498 register struct sockaddr_in *from = (struct sockaddr_in *)&wherefrom;
499 register struct sockaddr_in *to = (struct sockaddr_in *)&whereto;
500 register struct hostinfo *hi;
502 register struct protoent *pe;
503 register int ttl, probe, i;
504 register int seq = 0;
505 int tos = 0, settos = 0;
506 register int lsrr = 0;
507 register u_short off = 0;
508 struct ifaddrlist *al;
510 int requestPort = -1;
514 /* Insure the socket fds won't be 0, 1 or 2 */
515 if (open(devnull, O_RDONLY) < 0 ||
516 open(devnull, O_RDONLY) < 0 ||
517 open(devnull, O_RDONLY) < 0) {
518 Fprintf(stderr, "%s: open \"%s\": %s\n",
519 prog, devnull, strerror(errno));
523 * Do the setuid-required stuff first, then lose priveleges ASAP.
524 * Do error checking for these two calls where they appeared in
528 pe = getprotobyname(cp);
530 if ((s = socket(AF_INET, SOCK_RAW, pe->p_proto)) < 0)
532 else if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
536 if (setuid(getuid()) != 0) {
543 int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
544 size_t sz = sizeof(max_ttl);
546 if (sysctl(mib, 4, &max_ttl, &sz, NULL, 0) == -1) {
547 perror("sysctl(net.inet.ip.ttl)");
557 else if ((cp = strrchr(argv[0], '/')) != NULL)
563 while ((op = getopt(argc, argv, "aA:edDFInrSvxf:g:i:M:m:P:p:q:s:t:w:z:")) != EOF)
587 case 'M': /* FreeBSD compat. */
588 first_ttl = str2val(optarg, "first ttl", 1, 255);
596 if (lsrr >= NGATEWAYS) {
598 "%s: No more than %d gateways\n",
602 getaddr(gwlist + lsrr, optarg);
611 proto = setproto("icmp");
615 max_ttl = str2val(optarg, "max ttl", 1, 255);
623 proto = setproto(optarg);
627 requestPort = (u_short)str2val(optarg, "port",
632 nprobes = str2val(optarg, "nprobes", 1, -1);
636 options |= SO_DONTROUTE;
641 * set the ip source address of the outbound
642 * probe (e.g., on a multi-homed host).
652 tos = str2val(optarg, "tos", 0, 255);
661 doipcksum = (doipcksum == 0);
665 waittime = str2val(optarg, "wait time",
670 pausemsecs = str2val(optarg, "pause msecs",
678 /* Set requested port, if any, else default for this protocol */
679 port = (requestPort != -1) ? requestPort : proto->port;
682 nprobes = printdiff ? 1 : 3;
684 if (first_ttl > max_ttl) {
686 "%s: first ttl (%d) may not be greater than max ttl (%d)\n",
687 prog, first_ttl, max_ttl);
692 Fprintf(stderr, "%s: Warning: ip checksums disabled\n", prog);
695 optlen = (lsrr + 1) * sizeof(gwlist[0]);
696 minpacket = sizeof(*outip) + proto->hdrlen + optlen;
702 /* Process destination and optional packet size */
703 switch (argc - optind) {
706 packlen = str2val(argv[optind + 1],
707 "packet length", minpacket, maxpacket);
711 hostname = argv[optind];
712 hi = gethostinfo(hostname);
713 setsin(to, hi->addrs[0]);
716 "%s: Warning: %s has multiple addresses; using %s\n",
717 prog, hostname, inet_ntoa(to->sin_addr));
727 #ifdef HAVE_SETLINEBUF
730 setvbuf(stdout, NULL, _IOLBF, 0);
733 protlen = packlen - sizeof(*outip) - optlen;
734 if ((proto->num == IPPROTO_SCTP) && (packlen & 3)) {
735 Fprintf(stderr, "%s: packet length must be a multiple of 4\n",
740 outip = (struct ip *)malloc((unsigned)packlen);
742 Fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno));
745 memset((char *)outip, 0, packlen);
747 outip->ip_v = IPVERSION;
750 #ifdef BYTESWAP_IP_HDR
751 outip->ip_len = htons(packlen);
752 outip->ip_off = htons(off);
754 outip->ip_len = packlen;
757 outip->ip_p = proto->num;
758 outp = (u_char *)(outip + 1);
759 #ifdef HAVE_RAW_OPTIONS
761 register u_char *optlist;
767 gwlist[lsrr] = to->sin_addr.s_addr;
769 outip->ip_dst.s_addr = gwlist[0];
771 /* force 4 byte alignment */
772 optlist[0] = IPOPT_NOP;
773 /* loose source route option */
774 optlist[1] = IPOPT_LSRR;
775 i = lsrr * sizeof(gwlist[0]);
777 /* Pointer to LSRR addresses */
778 optlist[3] = IPOPT_MINOFF;
779 memcpy(optlist + 4, gwlist + 1, i);
782 outip->ip_dst = to->sin_addr;
784 outip->ip_hl = (outp - (u_char *)outip) >> 2;
785 ident = (getpid() & 0xffff) | 0x8000;
788 Fprintf(stderr, "%s: unknown protocol %s\n", prog, cp);
793 Fprintf(stderr, "%s: icmp socket: %s\n", prog, strerror(errno));
796 if (options & SO_DEBUG)
797 (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on,
799 if (options & SO_DONTROUTE)
800 (void)setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
803 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
804 if (setpolicy(s, "in bypass") < 0)
805 errx(1, "%s", ipsec_strerror());
807 if (setpolicy(s, "out bypass") < 0)
808 errx(1, "%s", ipsec_strerror());
809 #endif /* defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) */
813 Fprintf(stderr, "%s: raw socket: %s\n", prog, strerror(errno));
817 #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
819 u_char optlist[MAX_IPOPTLEN];
822 if ((pe = getprotobyname(cp)) == NULL) {
823 Fprintf(stderr, "%s: unknown protocol %s\n", prog, cp);
828 gwlist[lsrr] = to->sin_addr.s_addr;
831 /* force 4 byte alignment */
832 optlist[0] = IPOPT_NOP;
833 /* loose source route option */
834 optlist[1] = IPOPT_LSRR;
835 i = lsrr * sizeof(gwlist[0]);
837 /* Pointer to LSRR addresses */
838 optlist[3] = IPOPT_MINOFF;
839 memcpy(optlist + 4, gwlist, i);
841 if ((setsockopt(sndsock, pe->p_proto, IP_OPTIONS,
842 (char *)optlist, i + sizeof(gwlist[0]))) < 0) {
843 Fprintf(stderr, "%s: IP_OPTIONS: %s\n",
844 prog, strerror(errno));
851 if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packlen,
852 sizeof(packlen)) < 0) {
853 Fprintf(stderr, "%s: SO_SNDBUF: %s\n", prog, strerror(errno));
858 if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
860 Fprintf(stderr, "%s: IP_HDRINCL: %s\n", prog, strerror(errno));
865 if (settos && setsockopt(sndsock, IPPROTO_IP, IP_TOS,
866 (char *)&tos, sizeof(tos)) < 0) {
867 Fprintf(stderr, "%s: setsockopt tos %d: %s\n",
868 prog, tos, strerror(errno));
873 if (options & SO_DEBUG)
874 (void)setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on,
876 if (options & SO_DONTROUTE)
877 (void)setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
880 /* Get the interface address list */
881 n = ifaddrlist(&al, errbuf);
883 Fprintf(stderr, "%s: ifaddrlist: %s\n", prog, errbuf);
888 "%s: Can't find any network interfaces\n", prog);
892 /* Look for a specific device */
893 if (device != NULL) {
894 for (i = n; i > 0; --i, ++al)
895 if (strcmp(device, al->device) == 0)
898 Fprintf(stderr, "%s: Can't find interface %.32s\n",
904 /* Determine our source address */
905 if (source == NULL) {
907 * If a device was specified, use the interface address.
908 * Otherwise, try to determine our source address.
911 setsin(from, al->addr);
912 else if ((err = findsaddr(to, from)) != NULL) {
913 Fprintf(stderr, "%s: findsaddr: %s\n",
918 hi = gethostinfo(source);
922 * If the device was specified make sure it
923 * corresponds to the source address specified.
924 * Otherwise, use the first address (and warn if
925 * there are more than one).
927 if (device != NULL) {
928 for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
933 "%s: %s is not on interface %.32s\n",
934 prog, source, device);
939 setsin(from, hi->addrs[0]);
942 "%s: Warning: %s has multiple addresses; using %s\n",
943 prog, source, inet_ntoa(from->sin_addr));
948 outip->ip_src = from->sin_addr;
950 /* Check the source address (-s), if any, is valid */
951 if (bind(sndsock, (struct sockaddr *)from, sizeof(*from)) < 0) {
952 Fprintf(stderr, "%s: bind: %s\n",
953 prog, strerror(errno));
958 asn = as_setup(as_server);
960 Fprintf(stderr, "%s: as_setup failed, AS# lookups"
961 " disabled\n", prog);
962 (void)fflush(stderr);
967 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
968 if (setpolicy(sndsock, "in bypass") < 0)
969 errx(1, "%s", ipsec_strerror());
971 if (setpolicy(sndsock, "out bypass") < 0)
972 errx(1, "%s", ipsec_strerror());
973 #endif /* defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) */
975 Fprintf(stderr, "%s to %s (%s)",
976 prog, hostname, inet_ntoa(to->sin_addr));
978 Fprintf(stderr, " from %s", source);
979 Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen);
980 (void)fflush(stderr);
982 for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
983 u_int32_t lastaddr = 0;
991 for (probe = 0, loss = 0; probe < nprobes; ++probe) {
993 struct timeval t1, t2;
994 register struct ip *ip;
995 struct outdata outdata;
997 if (sentfirst && pausemsecs > 0)
998 usleep(pausemsecs * 1000);
999 /* Prepare outgoing data */
1000 outdata.seq = ++seq;
1003 /* Avoid alignment problems by copying bytewise: */
1004 (void)gettimeofday(&t1, NULL);
1005 memcpy(&outdata.tv, &t1, sizeof(outdata.tv));
1007 /* Finalize and send packet */
1008 (*proto->prepare)(&outdata);
1009 send_probe(seq, ttl);
1012 /* Wait for a reply */
1013 while ((cc = wait_for_reply(s, from, &t1)) != 0) {
1017 (void)gettimeofday(&t2, NULL);
1018 i = packet_ok(packet, cc, from, seq);
1019 /* Skip short packet */
1023 from->sin_addr.s_addr != lastaddr) {
1024 if (gotlastaddr) printf("\n ");
1025 print(packet, cc, from);
1026 lastaddr = from->sin_addr.s_addr;
1029 T = deltaT(&t1, &t2);
1030 #ifdef SANE_PRECISION
1033 else if (T >= 100.0)
1040 Printf(" %.*f ms", precis, T);
1044 -(outip->ip_hl << 3),
1048 pkt_compare((void *)outip, packlen,
1049 (void *)hip, hiplen);
1053 ip = (struct ip *)packet;
1054 if (ip->ip_ttl <= 1)
1060 /* time exceeded in transit */
1066 case ICMP_UNREACH_PORT:
1068 ip = (struct ip *)packet;
1069 if (ip->ip_ttl <= 1)
1075 case ICMP_UNREACH_NET:
1080 case ICMP_UNREACH_HOST:
1085 case ICMP_UNREACH_PROTOCOL:
1090 case ICMP_UNREACH_NEEDFRAG:
1092 Printf(" !F-%d", pmtu);
1095 case ICMP_UNREACH_SRCFAIL:
1100 case ICMP_UNREACH_NET_UNKNOWN:
1105 case ICMP_UNREACH_HOST_UNKNOWN:
1110 case ICMP_UNREACH_ISOLATED:
1115 case ICMP_UNREACH_NET_PROHIB:
1120 case ICMP_UNREACH_HOST_PROHIB:
1125 case ICMP_UNREACH_TOSNET:
1130 case ICMP_UNREACH_TOSHOST:
1135 case ICMP_UNREACH_FILTER_PROHIB:
1140 case ICMP_UNREACH_HOST_PRECEDENCE:
1145 case ICMP_UNREACH_PRECEDENCE_CUTOFF:
1152 Printf(" !<%d>", code);
1161 (void)fflush(stdout);
1164 Printf(" (%d%% loss)", (loss * 100) / nprobes);
1168 (unreachable > 0 && unreachable >= nprobes - 1))
1177 wait_for_reply(register int sock, register struct sockaddr_in *fromp,
1178 register const struct timeval *tp)
1182 struct timeval now, wait;
1183 register int cc = 0;
1185 int fromlen = sizeof(*fromp);
1187 nfds = howmany(sock + 1, NFDBITS);
1188 if ((fdsp = malloc(nfds * sizeof(fd_mask))) == NULL)
1190 memset(fdsp, 0, nfds * sizeof(fd_mask));
1193 wait.tv_sec = tp->tv_sec + waittime;
1194 wait.tv_usec = tp->tv_usec;
1195 (void)gettimeofday(&now, NULL);
1197 if (wait.tv_sec < 0) {
1202 error = select(sock + 1, fdsp, NULL, NULL, &wait);
1203 if (error == -1 && errno == EINVAL) {
1204 Fprintf(stderr, "%s: botched select() args\n", prog);
1208 cc = recvfrom(sock, (char *)packet, sizeof(packet), 0,
1209 (struct sockaddr *)fromp, &fromlen);
1216 send_probe(int seq, int ttl)
1220 outip->ip_ttl = ttl;
1221 outip->ip_id = htons(ident + seq);
1223 /* XXX undocumented debugging hack */
1225 register const u_short *sp;
1226 register int nshorts, i;
1228 sp = (u_short *)outip;
1229 nshorts = (u_int)packlen / sizeof(u_short);
1231 Printf("[ %d bytes", packlen);
1232 while (--nshorts >= 0) {
1235 Printf(" %04x", ntohs(*sp++));
1240 Printf(" %02x", *(u_char *)sp);
1245 #if !defined(IP_HDRINCL) && defined(IP_TTL)
1246 if (setsockopt(sndsock, IPPROTO_IP, IP_TTL,
1247 (char *)&ttl, sizeof(ttl)) < 0) {
1248 Fprintf(stderr, "%s: setsockopt ttl %d: %s\n",
1249 prog, ttl, strerror(errno));
1254 cc = sendto(sndsock, (char *)outip,
1255 packlen, 0, &whereto, sizeof(whereto));
1256 if (cc < 0 || cc != packlen) {
1258 Fprintf(stderr, "%s: sendto: %s\n",
1259 prog, strerror(errno));
1260 Printf("%s: wrote %s %d chars, ret=%d\n",
1261 prog, hostname, packlen, cc);
1262 (void)fflush(stdout);
1266 #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC)
1268 setpolicy(so, policy)
1274 buf = ipsec_set_policy(policy, strlen(policy));
1276 warnx("%s", ipsec_strerror());
1279 (void)setsockopt(so, IPPROTO_IP, IP_IPSEC_POLICY,
1280 buf, ipsec_get_policylen(buf));
1289 deltaT(struct timeval *t1p, struct timeval *t2p)
1293 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1294 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1299 * Convert an ICMP "type" field to a printable string.
1302 pr_type(register u_char t)
1304 static char *ttab[] = {
1305 "Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable",
1306 "Source Quench", "Redirect", "ICMP 6", "ICMP 7",
1307 "Echo", "ICMP 9", "ICMP 10", "Time Exceeded",
1308 "Param Problem", "Timestamp", "Timestamp Reply", "Info Request",
1313 return("OUT-OF-RANGE");
1319 packet_ok(register u_char *buf, int cc, register struct sockaddr_in *from,
1322 register struct icmp *icp;
1323 register u_char type, code;
1326 register struct ip *ip;
1328 ip = (struct ip *) buf;
1329 hlen = ip->ip_hl << 2;
1330 if (cc < hlen + ICMP_MINLEN) {
1332 Printf("packet too short (%d bytes) from %s\n", cc,
1333 inet_ntoa(from->sin_addr));
1337 icp = (struct icmp *)(buf + hlen);
1339 icp = (struct icmp *)buf;
1341 type = icp->icmp_type;
1342 code = icp->icmp_code;
1343 /* Path MTU Discovery (RFC1191) */
1344 if (code != ICMP_UNREACH_NEEDFRAG)
1347 #ifdef HAVE_ICMP_NEXTMTU
1348 pmtu = ntohs(icp->icmp_nextmtu);
1350 pmtu = ntohs(((struct my_pmtu *)&icp->icmp_void)->ipm_nextmtu);
1353 if (type == ICMP_ECHOREPLY
1354 && proto->num == IPPROTO_ICMP
1355 && (*proto->check)((u_char *)icp, (u_char)seq))
1357 if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
1358 type == ICMP_UNREACH) {
1361 hip = &icp->icmp_ip;
1362 hiplen = ((u_char *)icp + cc) - (u_char *)hip;
1363 hlen = hip->ip_hl << 2;
1364 inner = (u_char *)((u_char *)hip + hlen);
1366 && hip->ip_p == proto->num
1367 && (*proto->check)(inner, (u_char)seq))
1368 return (type == ICMP_TIMXCEED ? -1 : code + 1);
1373 u_int32_t *lp = (u_int32_t *)&icp->icmp_ip;
1375 Printf("\n%d bytes from %s to ", cc, inet_ntoa(from->sin_addr));
1376 Printf("%s: icmp type %d (%s) code %d\n",
1377 inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
1378 for (i = 4; i <= cc - ICMP_MINLEN; i += sizeof(*lp))
1379 Printf("%2d: %8.8x\n", i, ntohl(*lp++));
1386 icmp_prep(struct outdata *outdata)
1388 struct icmp *const icmpheader = (struct icmp *) outp;
1390 icmpheader->icmp_type = ICMP_ECHO;
1391 icmpheader->icmp_id = htons(ident);
1392 icmpheader->icmp_seq = htons(outdata->seq);
1393 icmpheader->icmp_cksum = 0;
1394 icmpheader->icmp_cksum = in_cksum((u_short *)icmpheader, protlen);
1395 if (icmpheader->icmp_cksum == 0)
1396 icmpheader->icmp_cksum = 0xffff;
1400 icmp_check(const u_char *data, int seq)
1402 struct icmp *const icmpheader = (struct icmp *) data;
1404 return (icmpheader->icmp_id == htons(ident)
1405 && icmpheader->icmp_seq == htons(seq));
1409 udp_prep(struct outdata *outdata)
1411 struct udphdr *const outudp = (struct udphdr *) outp;
1413 outudp->uh_sport = htons(ident + (fixedPort ? outdata->seq : 0));
1414 outudp->uh_dport = htons(port + (fixedPort ? 0 : outdata->seq));
1415 outudp->uh_ulen = htons((u_short)protlen);
1418 u_short sum = p_cksum(outip, (u_short*)outudp, protlen, protlen);
1419 outudp->uh_sum = (sum) ? sum : 0xffff;
1426 udp_check(const u_char *data, int seq)
1428 struct udphdr *const udp = (struct udphdr *) data;
1430 return (ntohs(udp->uh_sport) == ident + (fixedPort ? seq : 0) &&
1431 ntohs(udp->uh_dport) == port + (fixedPort ? 0 : seq));
1435 udplite_prep(struct outdata *outdata)
1437 struct udphdr *const outudp = (struct udphdr *) outp;
1439 outudp->uh_sport = htons(ident + (fixedPort ? outdata->seq : 0));
1440 outudp->uh_dport = htons(port + (fixedPort ? 0 : outdata->seq));
1441 outudp->uh_ulen = htons(8);
1444 u_short sum = p_cksum(outip, (u_short*)outudp, protlen, 8);
1445 outudp->uh_sum = (sum) ? sum : 0xffff;
1452 udplite_check(const u_char *data, int seq)
1454 struct udphdr *const udp = (struct udphdr *) data;
1456 return (ntohs(udp->uh_sport) == ident + (fixedPort ? seq : 0) &&
1457 ntohs(udp->uh_dport) == port + (fixedPort ? 0 : seq));
1461 tcp_prep(struct outdata *outdata)
1463 struct tcphdr *const tcp = (struct tcphdr *) outp;
1465 tcp->th_sport = htons(ident);
1466 tcp->th_dport = htons(port + (fixedPort ? 0 : outdata->seq));
1467 tcp->th_seq = (tcp->th_sport << 16) | tcp->th_dport;
1470 tcp->th_flags = TH_SYN;
1474 tcp->th_sum = p_cksum(outip, (u_short*)tcp, protlen, protlen);
1478 tcp_check(const u_char *data, int seq)
1480 struct tcphdr *const tcp = (struct tcphdr *) data;
1482 return (ntohs(tcp->th_sport) == ident
1483 && ntohs(tcp->th_dport) == port + (fixedPort ? 0 : seq)
1484 && tcp->th_seq == (tcp_seq)((tcp->th_sport << 16) | tcp->th_dport));
1488 sctp_prep(struct outdata *outdata)
1490 struct sctphdr *const sctp = (struct sctphdr *) outp;
1491 struct sctp_chunkhdr *chk;
1493 sctp->src_port = htons(ident);
1494 sctp->dest_port = htons(port + (fixedPort ? 0 : outdata->seq));
1495 sctp->v_tag = (sctp->src_port << 16) | sctp->dest_port;
1496 sctp->checksum = htonl(0);
1498 (int)(sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr))) {
1499 chk = (struct sctp_chunkhdr *)(sctp + 1);
1500 chk->chunk_type = SCTP_SHUTDOWN_ACK;
1501 chk->chunk_flags = 0;
1502 chk->chunk_length = htons(4);
1505 (int)(sizeof(struct sctphdr) + 2 * sizeof(struct sctp_chunkhdr))) {
1507 chk->chunk_type = SCTP_PAD_CHUNK;
1508 chk->chunk_flags = 0;
1509 chk->chunk_length = htons(protlen -
1510 (sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr)));
1513 sctp->checksum = sctp_crc32c(sctp, protlen);
1518 sctp_check(const u_char *data, int seq)
1520 struct sctphdr *const sctp = (struct sctphdr *) data;
1522 return (ntohs(sctp->src_port) == ident
1523 && ntohs(sctp->dest_port) == port + (fixedPort ? 0 : seq)
1525 (u_int32_t)((sctp->src_port << 16) | sctp->dest_port));
1529 gre_prep(struct outdata *outdata)
1531 struct grehdr *const gre = (struct grehdr *) outp;
1533 gre->flags = htons(0x2001);
1534 gre->proto = htons(port);
1536 gre->callId = htons(ident + outdata->seq);
1540 gre_check(const u_char *data, int seq)
1542 struct grehdr *const gre = (struct grehdr *) data;
1544 return(ntohs(gre->proto) == port
1545 && ntohs(gre->callId) == ident + seq);
1549 gen_prep(struct outdata *outdata)
1551 u_int16_t *const ptr = (u_int16_t *) outp;
1553 ptr[0] = htons(ident);
1554 ptr[1] = htons(port + outdata->seq);
1558 gen_check(const u_char *data, int seq)
1560 u_int16_t *const ptr = (u_int16_t *) data;
1562 return(ntohs(ptr[0]) == ident
1563 && ntohs(ptr[1]) == port + seq);
1567 print(register u_char *buf, register int cc, register struct sockaddr_in *from)
1569 register struct ip *ip;
1571 char addr[INET_ADDRSTRLEN];
1573 ip = (struct ip *) buf;
1574 hlen = ip->ip_hl << 2;
1577 strlcpy(addr, inet_ntoa(from->sin_addr), sizeof(addr));
1580 Printf(" [AS%u]", as_lookup(asn, addr, AF_INET));
1583 Printf(" %s", addr);
1585 Printf(" %s (%s)", inetname(from->sin_addr), addr);
1588 Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
1592 * Checksum routine for UDP and TCP headers.
1595 p_cksum(struct ip *ip, u_short *data, int len, int cov)
1597 static struct ipovly ipo;
1600 ipo.ih_pr = ip->ip_p;
1601 ipo.ih_len = htons(len);
1602 ipo.ih_src = ip->ip_src;
1603 ipo.ih_dst = ip->ip_dst;
1605 sum[1] = in_cksum((u_short*)&ipo, sizeof(ipo)); /* pseudo ip hdr cksum */
1606 sum[0] = in_cksum(data, cov); /* payload data cksum */
1608 return ~in_cksum(sum, sizeof(sum));
1612 * Checksum routine for Internet Protocol family headers (C Version)
1615 in_cksum(register u_short *addr, register int len)
1617 register int nleft = len;
1618 register u_short *w = addr;
1619 register u_short answer;
1620 register int sum = 0;
1623 * Our algorithm is simple, using a 32 bit accumulator (sum),
1624 * we add sequential 16 bit words to it, and at the end, fold
1625 * back all the carry bits from the top 16 bits into the lower
1633 /* mop up an odd byte, if necessary */
1635 sum += *(u_char *)w;
1638 * add back carry outs from top 16 bits to low 16 bits
1640 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
1641 sum += (sum >> 16); /* add carry */
1642 answer = ~sum; /* truncate to 16 bits */
1647 * CRC32C routine for the Stream Control Transmission Protocol
1650 #define CRC32C(c, d) (c = (c>>8) ^ crc_c[(c^(d))&0xFF])
1652 static u_int32_t crc_c[256] = {
1653 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
1654 0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
1655 0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
1656 0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
1657 0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
1658 0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
1659 0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
1660 0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
1661 0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
1662 0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
1663 0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
1664 0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
1665 0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
1666 0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
1667 0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
1668 0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
1669 0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
1670 0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
1671 0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
1672 0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
1673 0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
1674 0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
1675 0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
1676 0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
1677 0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
1678 0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
1679 0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
1680 0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
1681 0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
1682 0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
1683 0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
1684 0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
1685 0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
1686 0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
1687 0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
1688 0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
1689 0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
1690 0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
1691 0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
1692 0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
1693 0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
1694 0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
1695 0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
1696 0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
1697 0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
1698 0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
1699 0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
1700 0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
1701 0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
1702 0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
1703 0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
1704 0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
1705 0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
1706 0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
1707 0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
1708 0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
1709 0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
1710 0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
1711 0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
1712 0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
1713 0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
1714 0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
1715 0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
1716 0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
1720 sctp_crc32c(const void *packet, u_int32_t len)
1722 u_int32_t i, crc32c;
1723 u_int8_t byte0, byte1, byte2, byte3;
1724 const u_int8_t *buf = (const u_int8_t *)packet;
1727 for (i = 0; i < len; i++)
1728 CRC32C(crc32c, buf[i]);
1730 byte0 = crc32c & 0xff;
1731 byte1 = (crc32c>>8) & 0xff;
1732 byte2 = (crc32c>>16) & 0xff;
1733 byte3 = (crc32c>>24) & 0xff;
1734 crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
1735 return htonl(crc32c);
1739 * Subtract 2 timeval structs: out = out - in.
1740 * Out is assumed to be within about LONG_MAX seconds of in.
1743 tvsub(register struct timeval *out, register struct timeval *in)
1746 if ((out->tv_usec -= in->tv_usec) < 0) {
1748 out->tv_usec += 1000000;
1750 out->tv_sec -= in->tv_sec;
1754 * Construct an Internet address representation.
1755 * If the nflag has been supplied, give
1756 * numeric value, otherwise try for symbolic name.
1759 inetname(struct in_addr in)
1762 register struct hostent *hp;
1763 static int first = 1;
1764 static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1];
1766 if (first && !nflag) {
1768 if (gethostname(domain, sizeof(domain) - 1) < 0)
1771 cp = strchr(domain, '.');
1773 hp = gethostbyname(domain);
1775 cp = strchr(hp->h_name, '.');
1781 (void)strncpy(domain, cp, sizeof(domain) - 1);
1782 domain[sizeof(domain) - 1] = '\0';
1786 if (!nflag && in.s_addr != INADDR_ANY) {
1787 hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
1789 if ((cp = strchr(hp->h_name, '.')) != NULL &&
1790 strcmp(cp + 1, domain) == 0)
1792 (void)strncpy(line, hp->h_name, sizeof(line) - 1);
1793 line[sizeof(line) - 1] = '\0';
1797 return (inet_ntoa(in));
1801 gethostinfo(register char *hostname)
1804 register struct hostent *hp;
1805 register struct hostinfo *hi;
1807 register u_int32_t addr, *ap;
1809 if (strlen(hostname) >= MAXHOSTNAMELEN) {
1810 Fprintf(stderr, "%s: hostname \"%.32s...\" is too long\n",
1814 hi = calloc(1, sizeof(*hi));
1816 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1819 addr = inet_addr(hostname);
1820 if ((int32_t)addr != -1) {
1821 hi->name = strdup(hostname);
1823 hi->addrs = calloc(1, sizeof(hi->addrs[0]));
1824 if (hi->addrs == NULL) {
1825 Fprintf(stderr, "%s: calloc %s\n",
1826 prog, strerror(errno));
1829 hi->addrs[0] = addr;
1833 hp = gethostbyname(hostname);
1835 Fprintf(stderr, "%s: unknown host %s\n", prog, hostname);
1838 if (hp->h_addrtype != AF_INET || hp->h_length != 4) {
1839 Fprintf(stderr, "%s: bad host %s\n", prog, hostname);
1842 hi->name = strdup(hp->h_name);
1843 for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
1846 hi->addrs = calloc(n, sizeof(hi->addrs[0]));
1847 if (hi->addrs == NULL) {
1848 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1851 for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
1852 memcpy(ap, *p, sizeof(*ap));
1857 freehostinfo(register struct hostinfo *hi)
1859 if (hi->name != NULL) {
1863 free((char *)hi->addrs);
1868 getaddr(register u_int32_t *ap, register char *hostname)
1870 register struct hostinfo *hi;
1872 hi = gethostinfo(hostname);
1878 setsin(register struct sockaddr_in *sin, register u_int32_t addr)
1881 memset(sin, 0, sizeof(*sin));
1882 #ifdef HAVE_SOCKADDR_SA_LEN
1883 sin->sin_len = sizeof(*sin);
1885 sin->sin_family = AF_INET;
1886 sin->sin_addr.s_addr = addr;
1889 /* String to value with optional min and max. Handles decimal and hex. */
1891 str2val(register const char *str, register const char *what,
1892 register int mi, register int ma)
1894 register const char *cp;
1898 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
1900 val = (int)strtol(cp, &ep, 16);
1902 val = (int)strtol(str, &ep, 10);
1904 Fprintf(stderr, "%s: \"%s\" bad value for %s \n",
1908 if (val < mi && mi >= 0) {
1910 Fprintf(stderr, "%s: %s must be >= %d\n",
1913 Fprintf(stderr, "%s: %s must be > %d\n",
1914 prog, what, mi - 1);
1917 if (val > ma && ma >= 0) {
1918 Fprintf(stderr, "%s: %s must be <= %d\n", prog, what, ma);
1925 setproto(char *pname)
1927 struct outproto *proto;
1930 for (i = 0; protos[i].name != NULL; i++) {
1931 if (strcasecmp(protos[i].name, pname) == 0) {
1936 if (proto->name == NULL) { /* generic handler */
1937 struct protoent *pe;
1940 /* Determine the IP protocol number */
1941 if ((pe = getprotobyname(pname)) != NULL)
1944 pnum = str2val(optarg, "proto number", 1, 255);
1951 pkt_compare(const u_char *a, int la, const u_char *b, int lb) {
1955 for (i = 0; i < la; i++)
1956 Printf("%02x", (unsigned int)a[i]);
1958 l = (la <= lb) ? la : lb;
1959 for (i = 0; i < l; i++)
1963 Printf("%02x", (unsigned int)b[i]);
1965 Printf("%02x", (unsigned int)b[i]);
1973 extern char version[];
1975 Fprintf(stderr, "Version %s\n", version);
1977 "Usage: %s [-adDeFInrSvx] [-f first_ttl] [-g gateway] [-i iface]\n"
1978 "\t[-m max_ttl] [-p port] [-P proto] [-q nqueries] [-s src_addr]\n"
1979 "\t[-t tos] [-w waittime] [-A as_server] [-z pausemsecs] host [packetlen]\n", prog);