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