1 /* $NetBSD: traceroute.c,v 1.84 2018/01/19 14:30:09 maxv Exp $ */
2
3 /*
4 * Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that: (1) source code distributions
9 * retain the above copyright notice and this paragraph in its entirety, (2)
10 * distributions including binary code include the above copyright notice and
11 * this paragraph in its entirety in the documentation or other materials
12 * provided with the distribution, and (3) all advertising materials mentioning
13 * features or use of this software display the following acknowledgement:
14 * ``This product includes software developed by the University of California,
15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16 * the University nor the names of its contributors may be used to endorse
17 * or promote products derived from this software without specific prior
18 * written permission.
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 */
23
24 #include <sys/cdefs.h>
25 #ifndef lint
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 #else
30 __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1991, 1994, 1995, 1996, 1997,\
31 1998, 1999, 2000\
32 The Regents of the University of California. All rights reserved.");
33 __RCSID("$NetBSD: traceroute.c,v 1.84 2018/01/19 14:30:09 maxv Exp $");
34 #endif
35 #endif
36
37 /*
38 * traceroute host - trace the route ip packets follow going to "host".
39 *
40 * Attempt to trace the route an ip packet would follow to some
41 * internet host. We find out intermediate hops by launching probe
42 * packets with a small ttl (time to live) then listening for an
43 * icmp "time exceeded" reply from a gateway. We start our probes
44 * with a ttl of one and increase by one until we get an icmp "port
45 * unreachable" (which means we got to "host") or hit a max (which
46 * defaults to 30 hops & can be changed with the -m flag). Three
47 * probes (change with -q flag) are sent at each ttl setting and a
48 * line is printed showing the ttl, address of the gateway and
49 * round trip time of each probe. If the probe answers come from
50 * different gateways, the address of each responding system will
51 * be printed. If there is no response within a 5 sec. timeout
52 * interval (changed with the -w flag), a "*" is printed for that
53 * probe.
54 *
55 * Probe packets are UDP format. We don't want the destination
56 * host to process them so the destination port is set to an
57 * unlikely value (if some clod on the destination is using that
58 * value, it can be changed with the -p flag).
59 *
60 * A sample use might be:
61 *
62 * [yak 71]% traceroute nis.nsf.net.
63 * traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 56 byte packet
64 * 1 helios.ee.lbl.gov (128.3.112.1) 19 ms 19 ms 0 ms
65 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
66 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms
67 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 39 ms
68 * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 39 ms 39 ms 39 ms
69 * 6 128.32.197.4 (128.32.197.4) 40 ms 59 ms 59 ms
70 * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 59 ms
71 * 8 129.140.70.13 (129.140.70.13) 99 ms 99 ms 80 ms
72 * 9 129.140.71.6 (129.140.71.6) 139 ms 239 ms 319 ms
73 * 10 129.140.81.7 (129.140.81.7) 220 ms 199 ms 199 ms
74 * 11 nic.merit.edu (35.1.1.48) 239 ms 239 ms 239 ms
75 *
76 * Note that lines 2 & 3 are the same. This is due to a buggy
77 * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards
78 * packets with a zero ttl.
79 *
80 * A more interesting example is:
81 *
82 * [yak 72]% traceroute allspice.lcs.mit.edu.
83 * traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max
84 * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms
85 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 19 ms 19 ms
86 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 19 ms
87 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 19 ms 39 ms 39 ms
88 * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 20 ms 39 ms 39 ms
89 * 6 128.32.197.4 (128.32.197.4) 59 ms 119 ms 39 ms
90 * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 39 ms
91 * 8 129.140.70.13 (129.140.70.13) 80 ms 79 ms 99 ms
92 * 9 129.140.71.6 (129.140.71.6) 139 ms 139 ms 159 ms
93 * 10 129.140.81.7 (129.140.81.7) 199 ms 180 ms 300 ms
94 * 11 129.140.72.17 (129.140.72.17) 300 ms 239 ms 239 ms
95 * 12 * * *
96 * 13 128.121.54.72 (128.121.54.72) 259 ms 499 ms 279 ms
97 * 14 * * *
98 * 15 * * *
99 * 16 * * *
100 * 17 * * *
101 * 18 ALLSPICE.LCS.MIT.EDU (18.26.0.115) 339 ms 279 ms 279 ms
102 *
103 * (I start to see why I'm having so much trouble with mail to
104 * MIT.) Note that the gateways 12, 14, 15, 16 & 17 hops away
105 * either don't send ICMP "time exceeded" messages or send them
106 * with a ttl too small to reach us. 14 - 17 are running the
107 * MIT C Gateway code that doesn't send "time exceeded"s. God
108 * only knows what's going on with 12.
109 *
110 * The silent gateway 12 in the above may be the result of a bug in
111 * the 4.[23]BSD network code (and its derivatives): 4.x (x <= 3)
112 * sends an unreachable message using whatever ttl remains in the
113 * original datagram. Since, for gateways, the remaining ttl is
114 * zero, the icmp "time exceeded" is guaranteed to not make it back
115 * to us. The behavior of this bug is slightly more interesting
116 * when it appears on the destination system:
117 *
118 * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms
119 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 39 ms
120 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 39 ms 19 ms
121 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 19 ms
122 * 5 ccn-nerif35.Berkeley.EDU (128.32.168.35) 39 ms 39 ms 39 ms
123 * 6 csgw.Berkeley.EDU (128.32.133.254) 39 ms 59 ms 39 ms
124 * 7 * * *
125 * 8 * * *
126 * 9 * * *
127 * 10 * * *
128 * 11 * * *
129 * 12 * * *
130 * 13 rip.Berkeley.EDU (128.32.131.22) 59 ms ! 39 ms ! 39 ms !
131 *
132 * Notice that there are 12 "gateways" (13 is the final
133 * destination) and exactly the last half of them are "missing".
134 * What's really happening is that rip (a Sun-3 running Sun OS3.5)
135 * is using the ttl from our arriving datagram as the ttl in its
136 * icmp reply. So, the reply will time out on the return path
137 * (with no notice sent to anyone since icmp's aren't sent for
138 * icmp's) until we probe with a ttl that's at least twice the path
139 * length. I.e., rip is really only 7 hops away. A reply that
140 * returns with a ttl of 1 is a clue this problem exists.
141 * Traceroute prints a "!" after the time if the ttl is <= 1.
142 * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or
143 * non-standard (HPUX) software, expect to see this problem
144 * frequently and/or take care picking the target host of your
145 * probes.
146 *
147 * Other possible annotations after the time are !H, !N, !P (got a host,
148 * network or protocol unreachable, respectively), !S or !F (source
149 * route failed or fragmentation needed -- neither of these should
150 * ever occur and the associated gateway is busted if you see one). If
151 * almost all the probes result in some kind of unreachable, traceroute
152 * will give up and exit.
153 *
154 * Notes
155 * -----
156 * This program must be run by root or be setuid. (I suggest that
157 * you *don't* make it setuid -- casual use could result in a lot
158 * of unnecessary traffic on our poor, congested nets.)
159 *
160 * This program requires a kernel mod that does not appear in any
161 * system available from Berkeley: A raw ip socket using proto
162 * IPPROTO_RAW must interpret the data sent as an ip datagram (as
163 * opposed to data to be wrapped in a ip datagram). See the README
164 * file that came with the source to this program for a description
165 * of the mods I made to /sys/netinet/raw_ip.c. Your mileage may
166 * vary. But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE
167 * MODIFIED TO RUN THIS PROGRAM.
168 *
169 * The udp port usage may appear bizarre (well, ok, it is bizarre).
170 * The problem is that an icmp message only contains 8 bytes of
171 * data from the original datagram. 8 bytes is the size of a udp
172 * header so, if we want to associate replies with the original
173 * datagram, the necessary information must be encoded into the
174 * udp header (the ip id could be used but there's no way to
175 * interlock with the kernel's assignment of ip id's and, anyway,
176 * it would have taken a lot more kernel hacking to allow this
177 * code to set the ip id). So, to allow two or more users to
178 * use traceroute simultaneously, we use this task's pid as the
179 * source port (the high bit is set to move the port number out
180 * of the "likely" range). To keep track of which probe is being
181 * replied to (so times and/or hop counts don't get confused by a
182 * reply that was delayed in transit), we increment the destination
183 * port number before each probe.
184 *
185 * Don't use this as a coding example. I was trying to find a
186 * routing problem and this code sort-of popped out after 48 hours
187 * without sleep. I was amazed it ever compiled, much less ran.
188 *
189 * I stole the idea for this program from Steve Deering. Since
190 * the first release, I've learned that had I attended the right
191 * IETF working group meetings, I also could have stolen it from Guy
192 * Almes or Matt Mathis. I don't know (or care) who came up with
193 * the idea first. I envy the originators' perspicacity and I'm
194 * glad they didn't keep the idea a secret.
195 *
196 * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or
197 * enhancements to the original distribution.
198 *
199 * I've hacked up a round-trip-route version of this that works by
200 * sending a loose-source-routed udp datagram through the destination
201 * back to yourself. Unfortunately, SO many gateways botch source
202 * routing, the thing is almost worthless. Maybe one day...
203 *
204 * -- Van Jacobson (van@ee.lbl.gov)
205 * Tue Dec 20 03:50:13 PST 1988
206 */
207
208 #include <sys/param.h>
209 #include <sys/file.h>
210 #include <sys/ioctl.h>
211 #include <sys/socket.h>
212 #include <sys/time.h>
213 #include <sys/sysctl.h>
214
215 #include <netinet/in_systm.h>
216 #include <netinet/in.h>
217 #include <netinet/ip.h>
218 #include <netinet/ip_var.h>
219 #include <netinet/ip_icmp.h>
220 #include <netinet/udp.h>
221 #include <netinet/udp_var.h>
222
223 #include <arpa/inet.h>
224
225 #include <ctype.h>
226 #include <err.h>
227 #include <errno.h>
228 #ifdef HAVE_MALLOC_H
229 #include <malloc.h>
230 #endif
231 #include <memory.h>
232 #include <netdb.h>
233 #include <stdio.h>
234 #include <stdlib.h>
235 #include <string.h>
236 #include <unistd.h>
237 #include <poll.h>
238 #ifdef IPSEC
239 #include <net/route.h>
240 #include <netipsec/ipsec.h>
241 #endif
242
243 #include "gnuc.h"
244 #ifdef HAVE_OS_PROTO_H
245 #include "os-proto.h"
246 #endif
247
248 /* rfc1716 */
249 #ifndef ICMP_UNREACH_FILTER_PROHIB
250 #define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohibited filter */
251 #endif
252 #ifndef ICMP_UNREACH_HOST_PRECEDENCE
253 #define ICMP_UNREACH_HOST_PRECEDENCE 14 /* host precedence violation */
254 #endif
255 #ifndef ICMP_UNREACH_PRECEDENCE_CUTOFF
256 #define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* precedence cutoff */
257 #endif
258
259 #include "ifaddrlist.h"
260 #include "as.h"
261 #include "prog_ops.h"
262
263 /* Maximum number of gateways (include room for one noop) */
264 #define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(u_int32_t)))
265
266 #ifndef MAXHOSTNAMELEN
267 #define MAXHOSTNAMELEN 64
268 #endif
269
270 #define Fprintf (void)fprintf
271 #define Printf (void)printf
272
273 /* Host name and address list */
274 struct hostinfo {
275 char *name;
276 int n;
277 u_int32_t *addrs;
278 };
279
280 /* Data section of the probe packet */
281 struct outdata {
282 u_char seq; /* sequence number of this packet */
283 u_char ttl; /* ttl packet left with */
284 struct tv32 {
285 int32_t tv32_sec;
286 int32_t tv32_usec;
287 } tv; /* time packet left */
288 };
289
290 /*
291 * Support for ICMP extensions
292 *
293 * http://www.ietf.org/proceedings/01aug/I-D/draft-ietf-mpls-icmp-02.txt
294 */
295 #ifdef ICMP_EXT_OFFSET
296 #undef ICMP_EXT_OFFSET
297 #endif
298 #define ICMP_EXT_OFFSET 8 /* ICMP type, code, checksum, unused */ + \
299 128 /* original datagram */
300 #define MPLS_STACK_ENTRY_CLASS 1
301 #define MPLS_STACK_ENTRY_C_TYPE 1
302
303 struct mpls_header {
304 #if BYTE_ORDER == BIG_ENDIAN
305 uint32_t label:20;
306 unsigned char exp:3;
307 unsigned char s:1;
308 unsigned char ttl:8;
309 #else
310 unsigned char ttl:8;
311 unsigned char s:1;
312 unsigned char exp:3;
313 uint32_t label:20;
314 #endif
315 };
316
317 #ifndef HAVE_ICMP_NEXTMTU
318 /* Path MTU Discovery (RFC1191) */
319 struct my_pmtu {
320 u_short ipm_void;
321 u_short ipm_nextmtu;
322 };
323 #endif
324
325 static u_char packet[512]; /* last inbound (icmp) packet */
326
327 static struct ip *outip; /* last output (udp) packet */
328 static struct udphdr *outudp; /* last output (udp) packet */
329 static void *outmark; /* packed location of struct outdata */
330 static struct outdata outsetup; /* setup and copy for alignment */
331
332 static struct icmp *outicmp; /* last output (icmp) packet */
333
334 /* loose source route gateway list (including room for final destination) */
335 static u_int32_t gwlist[NGATEWAYS + 1];
336
337 static int s; /* receive (icmp) socket file descriptor */
338 static int sndsock; /* send (udp/icmp) socket file descriptor */
339
340 static struct sockaddr whereto; /* Who to try to reach */
341 static struct sockaddr wherefrom; /* Who we are */
342 static int packlen; /* total length of packet */
343 static int minpacket; /* min ip packet size */
344 static int maxpacket = 32 * 1024; /* max ip packet size */
345 static int printed_ttl = 0;
346 static int pmtu; /* Path MTU Discovery (RFC1191) */
347 static u_int pausemsecs;
348
349 static const char *prog;
350 static char *source;
351 static char *hostname;
352 static char *device;
353 #ifdef notdef
354 static const char devnull[] = "/dev/null";
355 #endif
356
357 static int nprobes = 3;
358 static int max_ttl = 30;
359 static int first_ttl = 1;
360 static u_int16_t ident;
361 static in_port_t port = 32768 + 666; /* start udp dest port # for probe packets */
362
363 static int options; /* socket options */
364 static int verbose;
365 static int waittime = 5; /* time to wait for response (in seconds) */
366 static int nflag; /* print addresses numerically */
367 static int dump;
368 static int Mflag; /* show MPLS labels if any */
369 static int as_path; /* print as numbers for each hop */
370 static char *as_server = NULL;
371 static void *asn;
372 static int useicmp = 0; /* use icmp echo instead of udp packets */
373 #ifdef CANT_HACK_CKSUM
374 static int doipcksum = 0; /* don't calculate checksums */
375 #else
376 static int doipcksum = 1; /* calculate checksums */
377 #endif
378 static int optlen; /* length of ip options */
379
380 static int mtus[] = {
381 17914,
382 8166,
383 4464,
384 4352,
385 2048,
386 2002,
387 1536,
388 1500,
389 1492,
390 1480,
391 1280,
392 1006,
393 576,
394 552,
395 544,
396 512,
397 508,
398 296,
399 68,
400 0
401 };
402 static int *mtuptr = &mtus[0];
403 static int mtudisc = 0;
404 static int nextmtu; /* from ICMP error, set by packet_ok(), might be 0 */
405
406 /* Forwards */
407 static double deltaT(struct timeval *, struct timeval *);
408 static void freehostinfo(struct hostinfo *);
409 static void getaddr(u_int32_t *, char *);
410 static struct hostinfo *gethostinfo(char *);
411 static u_int16_t in_cksum(u_int16_t *, int);
412 static u_int16_t in_cksum2(u_int16_t, u_int16_t *, int);
413 static char *inetname(struct in_addr);
414 static int packet_ok(u_char *, ssize_t, struct sockaddr_in *, int);
415 static const char *pr_type(u_char);
416 static void print(u_char *, int, struct sockaddr_in *);
417 static void resize_packet(void);
418 static void dump_packet(void);
419 static void send_probe(int, int, struct timeval *);
420 static void setsin(struct sockaddr_in *, u_int32_t);
421 static int str2val(const char *, const char *, int, int);
422 static void tvsub(struct timeval *, struct timeval *);
423 static void usage(void) __attribute__((__noreturn__));
424 static ssize_t wait_for_reply(int, struct sockaddr_in *, const struct timeval *);
425 static void decode_extensions(unsigned char *buf, int ip_len);
426 static void frag_err(void);
427 static int find_local_ip(struct sockaddr_in *, struct sockaddr_in *);
428 #ifdef IPSEC
429 #ifdef IPSEC_POLICY_IPSEC
430 static int setpolicy(int, const char *);
431 #endif
432 #endif
433
434 int
main(int argc,char ** argv)435 main(int argc, char **argv)
436 {
437 int op, code, n;
438 u_char *outp;
439 u_int32_t *ap;
440 struct sockaddr_in *from = (struct sockaddr_in *)&wherefrom;
441 struct sockaddr_in *to = (struct sockaddr_in *)&whereto;
442 struct hostinfo *hi;
443 int on = 1;
444 int ttl, probe, i;
445 int seq = 0;
446 int tos = 0, settos = 0, ttl_flag = 0;
447 int lsrr = 0;
448 u_int16_t off = 0;
449 struct ifaddrlist *al, *al2;
450 char errbuf[132];
451 int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
452 size_t size = sizeof(max_ttl);
453
454 setprogname(argv[0]);
455 prog = getprogname();
456
457 if (prog_init && prog_init() == -1)
458 err(1, "init failed");
459
460 #ifdef notdef
461 /* Kernel takes care of it */
462 /* Insure the socket fds won't be 0, 1 or 2 */
463 if (open(devnull, O_RDONLY) < 0 ||
464 open(devnull, O_RDONLY) < 0 ||
465 open(devnull, O_RDONLY) < 0)
466 err(1, "Cannot open `%s'", devnull);
467 #endif
468 if ((s = prog_socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
469 err(1, "icmp socket");
470
471 /*
472 * XXX 'useicmp' will always be zero here. I think the HP-UX users
473 * running our traceroute code will forgive us.
474 */
475 #ifndef __hpux
476 sndsock = prog_socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
477 #else
478 sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW
479 useicmp ? IPPROTO_ICMP : IPPROTO_UDP);
480 #endif
481 if (sndsock < 0)
482 err(1, "raw socket");
483
484 (void) prog_sysctl(mib, sizeof(mib)/sizeof(mib[0]), &max_ttl, &size,
485 NULL, 0);
486
487 opterr = 0;
488 while ((op = getopt(argc, argv, "aA:dDFPIMnlrvxf:g:i:m:p:q:s:t:w:z:")) != -1)
489 switch (op) {
490
491 case 'a':
492 as_path = 1;
493 break;
494
495 case 'A':
496 as_path = 1;
497 as_server = optarg;
498 break;
499
500 case 'd':
501 options |= SO_DEBUG;
502 break;
503
504 case 'D':
505 dump = 1;
506 break;
507
508 case 'f':
509 first_ttl = str2val(optarg, "first ttl", 1, 255);
510 break;
511
512 case 'F':
513 off = IP_DF;
514 break;
515
516 case 'g':
517 if (lsrr >= NGATEWAYS)
518 errx(1, "more than %d gateways", NGATEWAYS);
519 getaddr(gwlist + lsrr, optarg);
520 ++lsrr;
521 break;
522
523 case 'i':
524 device = optarg;
525 break;
526
527 case 'I':
528 ++useicmp;
529 break;
530
531 case 'l':
532 ++ttl_flag;
533 break;
534
535 case 'm':
536 max_ttl = str2val(optarg, "max ttl", 1, 255);
537 break;
538
539 case 'M':
540 Mflag = 1;
541 break;
542
543 case 'n':
544 ++nflag;
545 break;
546
547 case 'p':
548 port = (u_short)str2val(optarg, "port",
549 1, (1 << 16) - 1);
550 break;
551
552 case 'q':
553 nprobes = str2val(optarg, "nprobes", 1, -1);
554 break;
555
556 case 'r':
557 options |= SO_DONTROUTE;
558 break;
559
560 case 's':
561 /*
562 * set the ip source address of the outbound
563 * probe (e.g., on a multi-homed host).
564 */
565 source = optarg;
566 break;
567
568 case 't':
569 tos = str2val(optarg, "tos", 0, 255);
570 ++settos;
571 break;
572
573 case 'v':
574 ++verbose;
575 break;
576
577 case 'x':
578 doipcksum = (doipcksum == 0);
579 break;
580
581 case 'w':
582 waittime = str2val(optarg, "wait time",
583 2, 24 * 60 * 60);
584 break;
585
586 case 'z':
587 pausemsecs = str2val(optarg, "pause msecs",
588 0, 60 * 60 * 1000);
589 break;
590
591 case 'P':
592 off = IP_DF;
593 mtudisc = 1;
594 break;
595
596 default:
597 usage();
598 }
599
600 if (first_ttl > max_ttl)
601 errx(1, "first ttl (%d) may not be greater than max ttl (%d)",
602 first_ttl, max_ttl);
603
604 if (!doipcksum)
605 warnx("ip checksums disabled");
606
607 if (lsrr > 0)
608 optlen = (lsrr + 1) * sizeof(gwlist[0]);
609 minpacket = sizeof(*outip) + sizeof(struct outdata) + optlen;
610 if (useicmp)
611 minpacket += 8; /* XXX magic number */
612 else
613 minpacket += sizeof(*outudp);
614 packlen = minpacket; /* minimum sized packet */
615
616 if (mtudisc)
617 packlen = *mtuptr++;
618
619 /* Process destination and optional packet size */
620 switch (argc - optind) {
621
622 case 2:
623 packlen = str2val(argv[optind + 1],
624 "packet length", minpacket, maxpacket);
625 /* Fall through */
626
627 case 1:
628 hostname = argv[optind];
629 hi = gethostinfo(hostname);
630 setsin(to, hi->addrs[0]);
631 if (hi->n > 1)
632 warnx("%s has multiple addresses; using %s",
633 hostname, inet_ntoa(to->sin_addr));
634 hostname = hi->name;
635 hi->name = NULL;
636 freehostinfo(hi);
637 break;
638
639 default:
640 usage();
641 }
642
643 #ifdef HAVE_SETLINEBUF
644 setlinebuf (stdout);
645 #else
646 setvbuf(stdout, NULL, _IOLBF, 0);
647 #endif
648
649 outip = malloc((unsigned)packlen);
650 if (outip == NULL)
651 err(1, "malloc");
652 memset(outip, 0, packlen);
653
654 outip->ip_v = IPVERSION;
655 if (settos)
656 outip->ip_tos = tos;
657 #ifdef BYTESWAP_IP_HDR
658 outip->ip_len = htons(packlen);
659 outip->ip_off = htons(off);
660 #else
661 outip->ip_len = packlen;
662 outip->ip_off = off;
663 #endif
664 outp = (u_char *)(outip + 1);
665 #ifdef HAVE_RAW_OPTIONS
666 if (lsrr > 0) {
667 u_char *optlist;
668
669 optlist = outp;
670 outp += optlen;
671
672 /* final hop */
673 gwlist[lsrr] = to->sin_addr.s_addr;
674
675 outip->ip_dst.s_addr = gwlist[0];
676
677 /* force 4 byte alignment */
678 optlist[0] = IPOPT_NOP;
679 /* loose source route option */
680 optlist[1] = IPOPT_LSRR;
681 i = lsrr * sizeof(gwlist[0]);
682 optlist[2] = i + 3;
683 /* Pointer to LSRR addresses */
684 optlist[3] = IPOPT_MINOFF;
685 memcpy(optlist + 4, gwlist + 1, i);
686 } else
687 #endif
688 outip->ip_dst = to->sin_addr;
689
690 outip->ip_hl = (outp - (u_char *)outip) >> 2;
691 ident = htons(arc4random() & 0xffff) | 0x8000;
692 if (useicmp) {
693 outip->ip_p = IPPROTO_ICMP;
694
695 outicmp = (struct icmp *)outp;
696 outicmp->icmp_type = ICMP_ECHO;
697 outicmp->icmp_id = htons(ident);
698
699 outmark = outp + 8; /* XXX magic number */
700 } else {
701 outip->ip_p = IPPROTO_UDP;
702
703 outudp = (struct udphdr *)outp;
704 outudp->uh_sport = htons(ident);
705 outudp->uh_ulen =
706 htons((u_int16_t)(packlen - (sizeof(*outip) + optlen)));
707 outmark = outudp + 1;
708 }
709
710 if (options & SO_DEBUG)
711 (void)prog_setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on,
712 sizeof(on));
713 #ifdef IPSEC
714 #ifdef IPSEC_POLICY_IPSEC
715 /*
716 * do not raise error even if setsockopt fails, kernel may have ipsec
717 * turned off.
718 */
719 if (setpolicy(s, "in bypass") < 0)
720 exit(1);
721 if (setpolicy(s, "out bypass") < 0)
722 exit(1);
723 #else
724 {
725 int level = IPSEC_LEVEL_AVAIL;
726
727 (void)prog_setsockopt(s, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level,
728 sizeof(level));
729 (void)prog_setsockopt(s, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level,
730 sizeof(level));
731 #ifdef IP_AUTH_TRANS_LEVEL
732 (void)prog_setsockopt(s, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level,
733 sizeof(level));
734 #else
735 (void)prog_setsockopt(s, IPPROTO_IP, IP_AUTH_LEVEL, &level,
736 sizeof(level));
737 #endif
738 #ifdef IP_AUTH_NETWORK_LEVEL
739 (void)prog_setsockopt(s, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level,
740 sizeof(level));
741 #endif
742 }
743 #endif /*IPSEC_POLICY_IPSEC*/
744 #endif /*IPSEC*/
745
746 #ifdef IPSEC
747 #ifdef IPSEC_POLICY_IPSEC
748 /*
749 * do not raise error even if setsockopt fails, kernel may have ipsec
750 * turned off.
751 */
752 if (setpolicy(sndsock, "in bypass") < 0)
753 exit(1);
754 if (setpolicy(sndsock, "out bypass") < 0)
755 exit(1);
756 #else
757 {
758 int level = IPSEC_LEVEL_BYPASS;
759
760 (void)prog_setsockopt(sndsock, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level,
761 sizeof(level));
762 (void)prog_setsockopt(sndsock, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level,
763 sizeof(level));
764 #ifdef IP_AUTH_TRANS_LEVEL
765 (void)prog_setsockopt(sndsock, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level,
766 sizeof(level));
767 #else
768 (void)prog_setsockopt(sndsock, IPPROTO_IP, IP_AUTH_LEVEL, &level,
769 sizeof(level));
770 #endif
771 #ifdef IP_AUTH_NETWORK_LEVEL
772 (void)prog_setsockopt(sndsock, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level,
773 sizeof(level));
774 #endif
775 }
776 #endif /*IPSEC_POLICY_IPSEC*/
777 #endif /*IPSEC*/
778
779 #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
780 if (lsrr > 0) {
781 u_char optlist[MAX_IPOPTLEN];
782
783 /* final hop */
784 gwlist[lsrr] = to->sin_addr.s_addr;
785 ++lsrr;
786
787 /* force 4 byte alignment */
788 optlist[0] = IPOPT_NOP;
789 /* loose source route option */
790 optlist[1] = IPOPT_LSRR;
791 i = lsrr * sizeof(gwlist[0]);
792 optlist[2] = i + 3;
793 /* Pointer to LSRR addresses */
794 optlist[3] = IPOPT_MINOFF;
795 memcpy(optlist + 4, gwlist, i);
796
797 if ((prog_setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS, optlist,
798 i + sizeof(gwlist[0]))) < 0)
799 err(1, "IP_OPTIONS");
800 }
801 #endif
802
803 #ifdef SO_SNDBUF
804 if (prog_setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packlen,
805 sizeof(packlen)) < 0)
806 err(1, "SO_SNDBUF");
807 #endif
808 #ifdef IP_HDRINCL
809 if (prog_setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
810 sizeof(on)) < 0)
811 err(1, "IP_HDRINCL");
812 #else
813 #ifdef IP_TOS
814 if (settos && prog_setsockopt(sndsock, IPPROTO_IP, IP_TOS,
815 &tos, sizeof(tos)) < 0)
816 err(1, "setsockopt tos %d", tos);
817 #endif
818 #endif
819 if (options & SO_DEBUG)
820 if (prog_setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, &on,
821 sizeof(on)) < 0)
822 err(1, "setsockopt debug %d", tos);
823 if (options & SO_DONTROUTE)
824 if (prog_setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, &on,
825 sizeof(on)) < 0)
826 err(1, "setsockopt dontroute %d", tos);
827
828 /* Get the interface address list */
829 n = ifaddrlist(&al, errbuf, sizeof errbuf);
830 al2 = al;
831 if (n < 0)
832 errx(1, "ifaddrlist (%s)", errbuf);
833 if (n == 0)
834 errx(1, "Can't find any network interfaces");
835
836 /* Look for a specific device */
837 if (device != NULL) {
838 for (i = n; i > 0; --i, ++al2)
839 if (strcmp(device, al2->device) == 0)
840 break;
841 if (i <= 0)
842 errx(1, "Can't find interface %.32s", device);
843 }
844
845 /* Determine our source address */
846 if (source == NULL) {
847 /*
848 * If a device was specified, use the interface address.
849 * Otherwise, try to determine our source address.
850 * Warn if there are more than one.
851 */
852 setsin(from, al2->addr);
853 if (n > 1 && device == NULL && !find_local_ip(from, to)) {
854 warnx("Multiple interfaces found; using %s @ %s",
855 inet_ntoa(from->sin_addr), al2->device);
856 }
857 } else {
858 hi = gethostinfo(source);
859 source = hi->name;
860 hi->name = NULL;
861 if (device == NULL) {
862 /*
863 * Use the first interface found.
864 * Warn if there are more than one.
865 */
866 setsin(from, hi->addrs[0]);
867 if (hi->n > 1)
868 warnx("%s has multiple addresses; using %s",
869 source, inet_ntoa(from->sin_addr));
870 } else {
871 /*
872 * Make sure the source specified matches the
873 * interface address.
874 */
875 for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
876 if (*ap == al2->addr)
877 break;
878 if (i <= 0)
879 errx(1, "%s is not on interface %s",
880 source, device);
881 setsin(from, *ap);
882 }
883 freehostinfo(hi);
884 }
885
886 /* Revert to non-privileged user after opening sockets */
887 setgid(getgid());
888 setuid(getuid());
889
890 /*
891 * If not root, make sure source address matches a local interface.
892 * (The list of addresses produced by ifaddrlist() automatically
893 * excludes interfaces that are marked down and/or loopback.)
894 */
895 if (getuid()) {
896 al2 = al;
897 for (i = n; i > 0; --i, ++al2)
898 if (from->sin_addr.s_addr == al2->addr)
899 break;
900 if (i <= 0)
901 errx(1, "%s is not a valid local address "
902 "and you are not superuser.",
903 inet_ntoa(from->sin_addr));
904 }
905
906 outip->ip_src = from->sin_addr;
907 #ifndef IP_HDRINCL
908 if (bind(sndsock, (struct sockaddr *)from, sizeof(*from)) < 0)
909 err(1, "bind");
910 #endif
911
912 if (as_path) {
913 asn = as_setup(as_server);
914 if (asn == NULL) {
915 warnx("as_setup failed, AS# lookups disabled");
916 (void)fflush(stderr);
917 as_path = 0;
918 }
919 }
920
921 setuid(getuid());
922 Fprintf(stderr, "%s to %s (%s)",
923 prog, hostname, inet_ntoa(to->sin_addr));
924 if (source)
925 Fprintf(stderr, " from %s", source);
926 Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen);
927 (void)fflush(stderr);
928
929 for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
930 u_int32_t lastaddr = 0;
931 int gotlastaddr = 0;
932 int got_there = 0;
933 int unreachable = 0;
934 int sentfirst = 0;
935
936 again:
937 printed_ttl = 0;
938 for (probe = 0; probe < nprobes; ++probe) {
939 int cc;
940 struct timeval t1, t2;
941 struct ip *ip;
942 if (sentfirst && pausemsecs > 0)
943 usleep(pausemsecs * 1000);
944 (void)gettimeofday(&t1, NULL);
945 if (!useicmp && htons(port + seq + 1) == 0)
946 seq++;
947 send_probe(++seq, ttl, &t1);
948 ++sentfirst;
949 while ((cc = wait_for_reply(s, from, &t1)) != 0) {
950 (void)gettimeofday(&t2, NULL);
951 /*
952 * Since we'll be receiving all ICMP
953 * messages to this host above, we may
954 * never end up with cc=0, so we need
955 * an additional termination check.
956 */
957 if (t2.tv_sec - t1.tv_sec > waittime) {
958 cc = 0;
959 break;
960 }
961 i = packet_ok(packet, cc, from, seq);
962 /* Skip short packet */
963 if (i == 0)
964 continue;
965 if (!gotlastaddr ||
966 from->sin_addr.s_addr != lastaddr) {
967 if (gotlastaddr) printf("\n ");
968 print(packet, cc, from);
969 lastaddr = from->sin_addr.s_addr;
970 ++gotlastaddr;
971 }
972 ip = (struct ip *)packet;
973 Printf(" %.3f ms", deltaT(&t1, &t2));
974 if (ttl_flag)
975 Printf(" (ttl = %d)", ip->ip_ttl);
976 if (i == -2) {
977 #ifndef ARCHAIC
978 if (ip->ip_ttl <= 1)
979 Printf(" !");
980 #endif
981 ++got_there;
982 break;
983 }
984
985 /* time exceeded in transit */
986 if (i == -1)
987 break;
988 code = i - 1;
989 switch (code) {
990
991 case ICMP_UNREACH_PORT:
992 #ifndef ARCHAIC
993 if (ip->ip_ttl <= 1)
994 Printf(" !");
995 #endif
996 ++got_there;
997 break;
998
999 case ICMP_UNREACH_NET:
1000 ++unreachable;
1001 Printf(" !N");
1002 break;
1003
1004 case ICMP_UNREACH_HOST:
1005 ++unreachable;
1006 Printf(" !H");
1007 break;
1008
1009 case ICMP_UNREACH_PROTOCOL:
1010 ++got_there;
1011 Printf(" !P");
1012 break;
1013
1014 case ICMP_UNREACH_NEEDFRAG:
1015 if (mtudisc) {
1016 frag_err();
1017 goto again;
1018 } else {
1019 ++unreachable;
1020 Printf(" !F-%d", pmtu);
1021 }
1022 break;
1023
1024 case ICMP_UNREACH_SRCFAIL:
1025 ++unreachable;
1026 Printf(" !S");
1027 break;
1028
1029 case ICMP_UNREACH_FILTER_PROHIB:
1030 ++unreachable;
1031 Printf(" !X");
1032 break;
1033
1034 case ICMP_UNREACH_HOST_PRECEDENCE:
1035 ++unreachable;
1036 Printf(" !V");
1037 break;
1038
1039 case ICMP_UNREACH_PRECEDENCE_CUTOFF:
1040 ++unreachable;
1041 Printf(" !C");
1042 break;
1043
1044 default:
1045 ++unreachable;
1046 Printf(" !<%d>", code);
1047 break;
1048 }
1049 break;
1050 }
1051 if (cc == 0)
1052 Printf(" *");
1053 else if (cc && probe == nprobes - 1 && Mflag)
1054 decode_extensions(packet, cc);
1055 (void)fflush(stdout);
1056 }
1057 putchar('\n');
1058 if (got_there ||
1059 (unreachable > 0 && unreachable >= ((nprobes + 1) / 2)))
1060 break;
1061 }
1062
1063 if (as_path)
1064 as_shutdown(asn);
1065
1066 exit(0);
1067 }
1068
1069 static ssize_t
wait_for_reply(int sock,struct sockaddr_in * fromp,const struct timeval * tp)1070 wait_for_reply(int sock, struct sockaddr_in *fromp, const struct timeval *tp)
1071 {
1072 struct pollfd set[1];
1073 struct timeval now, wait;
1074 ssize_t cc = 0;
1075 socklen_t fromlen = sizeof(*fromp);
1076 int retval;
1077
1078 set[0].fd = sock;
1079 set[0].events = POLLIN;
1080
1081 wait.tv_sec = tp->tv_sec + waittime;
1082 wait.tv_usec = tp->tv_usec;
1083 (void)gettimeofday(&now, NULL);
1084 tvsub(&wait, &now);
1085
1086 if (wait.tv_sec < 0) {
1087 wait.tv_sec = 0;
1088 wait.tv_usec = 0;
1089 }
1090
1091 retval = prog_poll(set, 1, wait.tv_sec * 1000 + wait.tv_usec / 1000);
1092 if (retval < 0)
1093 /* If we continue, we probably just flood the remote host. */
1094 err(1, "poll");
1095 if (retval > 0) {
1096 cc = prog_recvfrom(sock, (char *)packet, sizeof(packet), 0,
1097 (struct sockaddr *)fromp, &fromlen);
1098 }
1099
1100 return cc;
1101 }
1102
1103 static void
decode_extensions(unsigned char * buf,int ip_len)1104 decode_extensions(unsigned char *buf, int ip_len)
1105 {
1106 struct icmp_ext_hdr *cmn_hdr;
1107 struct icmp_ext_obj_hdr *obj_hdr;
1108 union {
1109 struct mpls_header mpls;
1110 uint32_t mpls_h;
1111 } mpls;
1112 size_t datalen, obj_len;
1113 struct ip *ip;
1114
1115 ip = (struct ip *)buf;
1116
1117 if (ip_len < (int)((ip->ip_hl << 2) + ICMP_EXT_OFFSET +
1118 sizeof(struct icmp_ext_hdr))) {
1119 /*
1120 * No support for ICMP extensions on this host
1121 */
1122 return;
1123 }
1124
1125 /*
1126 * Move forward to the start of the ICMP extensions, if present
1127 */
1128 buf += (ip->ip_hl << 2) + ICMP_EXT_OFFSET;
1129 cmn_hdr = (struct icmp_ext_hdr *)buf;
1130
1131 if (cmn_hdr->version != ICMP_EXT_VERSION) {
1132 /*
1133 * Unknown version
1134 */
1135 return;
1136 }
1137
1138 datalen = ip_len - ((u_char *)cmn_hdr - (u_char *)ip);
1139
1140 /*
1141 * Check the checksum, cmn_hdr->checksum == 0 means no checksum'ing
1142 * done by sender.
1143 *
1144 * If the checksum is ok, we'll get 0, as the checksum is calculated
1145 * with the checksum field being 0'd.
1146 */
1147 if (ntohs(cmn_hdr->checksum) &&
1148 in_cksum((u_short *)cmn_hdr, datalen)) {
1149
1150 return;
1151 }
1152
1153 buf += sizeof(*cmn_hdr);
1154 datalen -= sizeof(*cmn_hdr);
1155
1156 while (datalen >= sizeof(struct icmp_ext_obj_hdr)) {
1157 obj_hdr = (struct icmp_ext_obj_hdr *)buf;
1158 obj_len = ntohs(obj_hdr->length);
1159
1160 /*
1161 * Sanity check the length field
1162 */
1163 if (obj_len > datalen)
1164 return;
1165
1166 datalen -= obj_len;
1167
1168 /*
1169 * Move past the object header
1170 */
1171 buf += sizeof(struct icmp_ext_obj_hdr);
1172 obj_len -= sizeof(struct icmp_ext_obj_hdr);
1173
1174 switch (obj_hdr->class_num) {
1175 case MPLS_STACK_ENTRY_CLASS:
1176 switch (obj_hdr->c_type) {
1177 case MPLS_STACK_ENTRY_C_TYPE:
1178 while (obj_len >= sizeof(uint32_t)) {
1179 mpls.mpls_h = ntohl(*(uint32_t *)buf);
1180
1181 buf += sizeof(uint32_t);
1182 obj_len -= sizeof(uint32_t);
1183
1184 printf(" [MPLS: Label %d Exp %d]",
1185 mpls.mpls.label, mpls.mpls.exp);
1186 }
1187 if (obj_len > 0) {
1188 /*
1189 * Something went wrong, and we're at
1190 * a unknown offset into the packet,
1191 * ditch the rest of it.
1192 */
1193 return;
1194 }
1195 break;
1196 default:
1197 /*
1198 * Unknown object, skip past it
1199 */
1200 buf += ntohs(obj_hdr->length) -
1201 sizeof(struct icmp_ext_obj_hdr);
1202 break;
1203 }
1204 break;
1205
1206 default:
1207 /*
1208 * Unknown object, skip past it
1209 */
1210 buf += ntohs(obj_hdr->length) -
1211 sizeof(struct icmp_ext_obj_hdr);
1212 break;
1213 }
1214 }
1215 }
1216
1217 static void
dump_packet(void)1218 dump_packet(void)
1219 {
1220 u_char *p;
1221 int i;
1222
1223 Fprintf(stderr, "packet data:");
1224
1225 #ifdef __hpux
1226 for (p = useicmp ? (u_char *)outicmp : (u_char *)outudp, i = 0;
1227 i < packlen - (sizeof(*outip) + optlen); i++)
1228 #else
1229 for (p = (u_char *)outip, i = 0; i < packlen; i++)
1230 #endif
1231 {
1232 if ((i % 24) == 0)
1233 Fprintf(stderr, "\n ");
1234 Fprintf(stderr, " %02x", *p++);
1235 }
1236 Fprintf(stderr, "\n");
1237 }
1238
1239 void
send_probe(int seq,int ttl,struct timeval * tp)1240 send_probe(int seq, int ttl, struct timeval *tp)
1241 {
1242 int cc;
1243 struct udpiphdr * ui, *oui;
1244 int oldmtu = packlen;
1245 struct ip tip;
1246
1247 again:
1248 #ifdef BYTESWAP_IP_LEN
1249 outip->ip_len = htons(packlen);
1250 #else
1251 outip->ip_len = packlen;
1252 #endif
1253 outip->ip_ttl = ttl;
1254 #ifndef __hpux
1255 outip->ip_id = htons(ident + seq);
1256 #endif
1257
1258 /*
1259 * In most cases, the kernel will recalculate the ip checksum.
1260 * But we must do it anyway so that the udp checksum comes out
1261 * right.
1262 */
1263 if (doipcksum) {
1264 outip->ip_sum =
1265 in_cksum((u_int16_t *)outip, sizeof(*outip) + optlen);
1266 if (outip->ip_sum == 0)
1267 outip->ip_sum = 0xffff;
1268 }
1269
1270 /* Payload */
1271 outsetup.seq = seq;
1272 outsetup.ttl = ttl;
1273 outsetup.tv.tv32_sec = htonl(tp->tv_sec);
1274 outsetup.tv.tv32_usec = htonl(tp->tv_usec);
1275 memcpy(outmark,&outsetup,sizeof(outsetup));
1276
1277 if (useicmp)
1278 outicmp->icmp_seq = htons(seq);
1279 else
1280 outudp->uh_dport = htons(port + seq);
1281
1282 if (useicmp) {
1283 /* Always calculate checksum for icmp packets */
1284 outicmp->icmp_cksum = 0;
1285 outicmp->icmp_cksum = in_cksum((u_short *)outicmp,
1286 packlen - (sizeof(*outip) + optlen));
1287 if (outicmp->icmp_cksum == 0)
1288 outicmp->icmp_cksum = 0xffff;
1289 } else if (doipcksum) {
1290 /* Checksum (we must save and restore ip header) */
1291 tip = *outip;
1292 ui = (struct udpiphdr *)outip;
1293 oui = (struct udpiphdr *)&tip;
1294 /* Easier to zero and put back things that are ok */
1295 memset(ui, 0, sizeof(ui->ui_i));
1296 ui->ui_src = oui->ui_src;
1297 ui->ui_dst = oui->ui_dst;
1298 ui->ui_pr = oui->ui_pr;
1299 ui->ui_len = outudp->uh_ulen;
1300 outudp->uh_sum = 0;
1301 outudp->uh_sum = in_cksum((u_short *)ui, packlen);
1302 if (outudp->uh_sum == 0)
1303 outudp->uh_sum = 0xffff;
1304 *outip = tip;
1305 }
1306
1307 /* XXX undocumented debugging hack */
1308 if (verbose > 1) {
1309 const u_int16_t *sp;
1310 int nshorts, i;
1311
1312 sp = (u_int16_t *)outip;
1313 nshorts = (u_int)packlen / sizeof(u_int16_t);
1314 i = 0;
1315 Printf("[ %d bytes", packlen);
1316 while (--nshorts >= 0) {
1317 if ((i++ % 8) == 0)
1318 Printf("\n\t");
1319 Printf(" %04x", ntohs(*sp++));
1320 }
1321 if (packlen & 1) {
1322 if ((i % 8) == 0)
1323 Printf("\n\t");
1324 Printf(" %02x", *(const u_char *)sp);
1325 }
1326 Printf("]\n");
1327 }
1328
1329 #if !defined(IP_HDRINCL) && defined(IP_TTL)
1330 if (prog_setsockopt(sndsock, IPPROTO_IP, IP_TTL,
1331 (char *)&ttl, sizeof(ttl)) < 0)
1332 err(1, "setsockopt ttl %d", ttl);
1333 #endif
1334 if (dump)
1335 dump_packet();
1336
1337 #ifdef __hpux
1338 cc = sendto(sndsock, useicmp ? (char *)outicmp : (char *)outudp,
1339 packlen - (sizeof(*outip) + optlen), 0, &whereto, sizeof(whereto));
1340 if (cc > 0)
1341 cc += sizeof(*outip) + optlen;
1342 #else
1343 cc = prog_sendto(sndsock, (char *)outip,
1344 packlen, 0, &whereto, sizeof(whereto));
1345 #endif
1346 if (cc < 0 || cc != packlen) {
1347 if (cc < 0) {
1348 /*
1349 * An errno of EMSGSIZE means we're writing too big a
1350 * datagram for the interface. We have to just
1351 * decrease the packet size until we find one that
1352 * works.
1353 *
1354 * XXX maybe we should try to read the outgoing if's
1355 * mtu?
1356 */
1357 if (errno == EMSGSIZE) {
1358 packlen = *mtuptr++;
1359 resize_packet();
1360 goto again;
1361 } else
1362 warn("sendto");
1363 }
1364
1365 Printf("%s: wrote %s %d chars, ret=%d\n",
1366 prog, hostname, packlen, cc);
1367 (void)fflush(stdout);
1368 }
1369 if (oldmtu != packlen) {
1370 Printf("message too big, "
1371 "trying new MTU = %d\n", packlen);
1372 printed_ttl = 0;
1373 }
1374 if (!printed_ttl) {
1375 Printf("%2d ", ttl);
1376 printed_ttl = 1;
1377 }
1378
1379 }
1380
1381 static double
deltaT(struct timeval * t1p,struct timeval * t2p)1382 deltaT(struct timeval *t1p, struct timeval *t2p)
1383 {
1384 double dt;
1385
1386 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1387 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1388 return dt;
1389 }
1390
1391 /*
1392 * Convert an ICMP "type" field to a printable string.
1393 */
1394 static const char *
pr_type(u_char t)1395 pr_type(u_char t)
1396 {
1397 static const char *ttab[] = {
1398 "Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable",
1399 "Source Quench", "Redirect", "ICMP 6", "ICMP 7",
1400 "Echo", "ICMP 9", "ICMP 10", "Time Exceeded",
1401 "Param Problem", "Timestamp", "Timestamp Reply", "Info Request",
1402 "Info Reply"
1403 };
1404
1405 if (t > 16)
1406 return "OUT-OF-RANGE";
1407
1408 return ttab[t];
1409 }
1410
1411 static int
packet_ok(u_char * buf,ssize_t cc,struct sockaddr_in * from,int seq)1412 packet_ok(u_char *buf, ssize_t cc, struct sockaddr_in *from, int seq)
1413 {
1414 struct icmp *icp;
1415 u_char type, code;
1416 int hlen;
1417 #ifndef ARCHAIC
1418 struct ip *ip;
1419
1420 ip = (struct ip *) buf;
1421 hlen = ip->ip_hl << 2;
1422 if (cc < hlen + ICMP_MINLEN) {
1423 if (verbose)
1424 Printf("packet too short (%zd bytes) from %s\n", cc,
1425 inet_ntoa(from->sin_addr));
1426 return 0;
1427 }
1428 cc -= hlen;
1429 icp = (struct icmp *)(buf + hlen);
1430 #else
1431 icp = (struct icmp *)buf;
1432 #endif
1433 type = icp->icmp_type;
1434 code = icp->icmp_code;
1435 /* Path MTU Discovery (RFC1191) */
1436 if (code != ICMP_UNREACH_NEEDFRAG)
1437 pmtu = 0;
1438 else {
1439 #ifdef HAVE_ICMP_NEXTMTU
1440 pmtu = ntohs(icp->icmp_nextmtu);
1441 #else
1442 pmtu = ntohs(((struct my_pmtu *)&icp->icmp_void)->ipm_nextmtu);
1443 #endif
1444 }
1445 if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
1446 type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
1447 struct ip *hip;
1448 struct udphdr *up;
1449 struct icmp *hicmp;
1450
1451 hip = &icp->icmp_ip;
1452 hlen = hip->ip_hl << 2;
1453
1454 nextmtu = ntohs(icp->icmp_nextmtu); /* for frag_err() */
1455
1456 if (useicmp) {
1457 /* XXX */
1458 if (type == ICMP_ECHOREPLY &&
1459 icp->icmp_id == htons(ident) &&
1460 icp->icmp_seq == htons(seq))
1461 return -2;
1462
1463 hicmp = (struct icmp *)((u_char *)hip + hlen);
1464 /* XXX 8 is a magic number */
1465 if (hlen + 8 <= cc &&
1466 hip->ip_p == IPPROTO_ICMP &&
1467 hicmp->icmp_id == htons(ident) &&
1468 hicmp->icmp_seq == htons(seq))
1469 return type == ICMP_TIMXCEED ? -1 : code + 1;
1470 } else {
1471 up = (struct udphdr *)((u_char *)hip + hlen);
1472 /* XXX 8 is a magic number */
1473 if (hlen + 12 <= cc &&
1474 hip->ip_p == IPPROTO_UDP &&
1475 up->uh_sport == htons(ident) &&
1476 up->uh_dport == htons(port + seq))
1477 return type == ICMP_TIMXCEED ? -1 : code + 1;
1478 }
1479 }
1480 #ifndef ARCHAIC
1481 if (verbose) {
1482 int i;
1483 u_int32_t *lp = (u_int32_t *)&icp->icmp_ip;
1484
1485 Printf("\n%zd bytes from %s to ", cc, inet_ntoa(from->sin_addr));
1486 Printf("%s: icmp type %d (%s) code %d\n",
1487 inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
1488 for (i = 4; i < cc ; i += sizeof(*lp))
1489 Printf("%2d: x%8.8x\n", i, *lp++);
1490 }
1491 #endif
1492 return(0);
1493 }
1494
1495 static void
resize_packet(void)1496 resize_packet(void)
1497 {
1498 if (useicmp) {
1499 outicmp->icmp_cksum = 0;
1500 outicmp->icmp_cksum = in_cksum((u_int16_t *)outicmp,
1501 packlen - (sizeof(*outip) + optlen));
1502 if (outicmp->icmp_cksum == 0)
1503 outicmp->icmp_cksum = 0xffff;
1504 } else {
1505 outudp->uh_ulen =
1506 htons((u_int16_t)(packlen - (sizeof(*outip) + optlen)));
1507 }
1508 }
1509
1510 static void
print(u_char * buf,int cc,struct sockaddr_in * from)1511 print(u_char *buf, int cc, struct sockaddr_in *from)
1512 {
1513 struct ip *ip;
1514 int hlen;
1515 char addr[INET_ADDRSTRLEN];
1516
1517 ip = (struct ip *) buf;
1518 hlen = ip->ip_hl << 2;
1519 cc -= hlen;
1520
1521 strlcpy(addr, inet_ntoa(from->sin_addr), sizeof(addr));
1522
1523 if (as_path)
1524 Printf(" [AS%u]", as_lookup(asn, addr, AF_INET));
1525
1526 if (nflag)
1527 Printf(" %s", addr);
1528 else
1529 Printf(" %s (%s)", inetname(from->sin_addr), addr);
1530
1531 if (verbose)
1532 Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
1533 }
1534
1535 static u_int16_t
in_cksum(u_int16_t * addr,int len)1536 in_cksum(u_int16_t *addr, int len)
1537 {
1538
1539 return ~in_cksum2(0, addr, len);
1540 }
1541
1542 /*
1543 * Checksum routine for Internet Protocol family headers (C Version)
1544 */
1545 static u_int16_t
in_cksum2(u_int16_t seed,u_int16_t * addr,int len)1546 in_cksum2(u_int16_t seed, u_int16_t *addr, int len)
1547 {
1548 int nleft = len;
1549 u_int16_t *w = addr;
1550 union {
1551 u_int16_t w;
1552 u_int8_t b[2];
1553 } answer;
1554 int32_t sum = seed;
1555
1556 /*
1557 * Our algorithm is simple, using a 32 bit accumulator (sum),
1558 * we add sequential 16 bit words to it, and at the end, fold
1559 * back all the carry bits from the top 16 bits into the lower
1560 * 16 bits.
1561 */
1562 while (nleft > 1) {
1563 sum += *w++;
1564 nleft -= 2;
1565 }
1566
1567 /* mop up an odd byte, if necessary */
1568 if (nleft == 1) {
1569 answer.b[0] = *(u_char *)w;
1570 answer.b[1] = 0;
1571 sum += answer.w;
1572 }
1573
1574 /*
1575 * add back carry outs from top 16 bits to low 16 bits
1576 */
1577 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
1578 sum += (sum >> 16); /* add carry */
1579 answer.w = sum; /* truncate to 16 bits */
1580 return answer.w;
1581 }
1582
1583 /*
1584 * Subtract 2 timeval structs: out = out - in.
1585 * Out is assumed to be >= in.
1586 */
1587 static void
tvsub(struct timeval * out,struct timeval * in)1588 tvsub(struct timeval *out, struct timeval *in)
1589 {
1590
1591 if ((out->tv_usec -= in->tv_usec) < 0) {
1592 --out->tv_sec;
1593 out->tv_usec += 1000000;
1594 }
1595 out->tv_sec -= in->tv_sec;
1596 }
1597
1598 /*
1599 * Construct an Internet address representation.
1600 * If the nflag has been supplied, give
1601 * numeric value, otherwise try for symbolic name.
1602 */
1603 static char *
inetname(struct in_addr in)1604 inetname(struct in_addr in)
1605 {
1606 char *cp;
1607 struct hostent *hp;
1608 static int first = 1;
1609 static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1];
1610
1611 if (first && !nflag) {
1612
1613 first = 0;
1614 if (gethostname(domain, sizeof(domain) - 1) < 0)
1615 domain[0] = '\0';
1616 else {
1617 cp = strchr(domain, '.');
1618 if (cp == NULL) {
1619 hp = gethostbyname(domain);
1620 if (hp != NULL)
1621 cp = strchr(hp->h_name, '.');
1622 }
1623 if (cp == NULL)
1624 domain[0] = '\0';
1625 else {
1626 ++cp;
1627 (void)strlcpy(domain, cp, sizeof(domain));
1628 }
1629 }
1630 }
1631 if (!nflag && in.s_addr != INADDR_ANY) {
1632 hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
1633 if (hp != NULL) {
1634 if ((cp = strchr(hp->h_name, '.')) != NULL &&
1635 strcmp(cp + 1, domain) == 0)
1636 *cp = '\0';
1637 (void)strlcpy(line, hp->h_name, sizeof(line));
1638 return line;
1639 }
1640 }
1641 return inet_ntoa(in);
1642 }
1643
1644 static struct hostinfo *
gethostinfo(char * hname)1645 gethostinfo(char *hname)
1646 {
1647 int n;
1648 struct hostent *hp;
1649 struct hostinfo *hi;
1650 char **p;
1651 u_int32_t *ap;
1652 struct in_addr addr;
1653
1654 hi = calloc(1, sizeof(*hi));
1655 if (hi == NULL)
1656 err(1, "calloc");
1657 if (inet_aton(hname, &addr) != 0) {
1658 hi->name = strdup(hname);
1659 if (!hi->name)
1660 err(1, "strdup");
1661 hi->n = 1;
1662 hi->addrs = calloc(1, sizeof(hi->addrs[0]));
1663 if (hi->addrs == NULL)
1664 err(1, "calloc");
1665 hi->addrs[0] = addr.s_addr;
1666 return hi;
1667 }
1668
1669 hp = gethostbyname(hname);
1670 if (hp == NULL)
1671 errx(1, "unknown host %s", hname);
1672 if (hp->h_addrtype != AF_INET || hp->h_length != 4)
1673 errx(1, "bad host %s", hname);
1674 hi->name = strdup(hp->h_name);
1675 if (!hi->name)
1676 err(1, "strdup");
1677 for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
1678 continue;
1679 hi->n = n;
1680 hi->addrs = calloc(n, sizeof(hi->addrs[0]));
1681 if (hi->addrs == NULL)
1682 err(1, "calloc");
1683 for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
1684 memcpy(ap, *p, sizeof(*ap));
1685 return hi;
1686 }
1687
1688 static void
freehostinfo(struct hostinfo * hi)1689 freehostinfo(struct hostinfo *hi)
1690 {
1691 if (hi->name != NULL) {
1692 free(hi->name);
1693 hi->name = NULL;
1694 }
1695 free(hi->addrs);
1696 free(hi);
1697 }
1698
1699 static void
getaddr(u_int32_t * ap,char * hname)1700 getaddr(u_int32_t *ap, char *hname)
1701 {
1702 struct hostinfo *hi;
1703
1704 hi = gethostinfo(hname);
1705 *ap = hi->addrs[0];
1706 freehostinfo(hi);
1707 }
1708
1709 static void
setsin(struct sockaddr_in * sin,u_int32_t addr)1710 setsin(struct sockaddr_in *sin, u_int32_t addr)
1711 {
1712
1713 memset(sin, 0, sizeof(*sin));
1714 #ifdef HAVE_SOCKADDR_SA_LEN
1715 sin->sin_len = sizeof(*sin);
1716 #endif
1717 sin->sin_family = AF_INET;
1718 sin->sin_addr.s_addr = addr;
1719 }
1720
1721 /* String to value with optional min and max. Handles decimal and hex. */
1722 static int
str2val(const char * str,const char * what,int mi,int ma)1723 str2val(const char *str, const char *what, int mi, int ma)
1724 {
1725 const char *cp;
1726 long val;
1727 char *ep;
1728
1729 errno = 0;
1730 ep = NULL;
1731 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
1732 cp = str + 2;
1733 val = strtol(cp, &ep, 16);
1734 } else
1735 val = strtol(str, &ep, 10);
1736 if (errno || str[0] == '\0' || *ep != '\0')
1737 errx(1, "\"%s\" bad value for %s", str, what);
1738 if (val < mi && mi >= 0) {
1739 if (mi == 0)
1740 errx(1, "%s must be >= %d", what, mi);
1741 else
1742 errx(1, "%s must be > %d", what, mi - 1);
1743 }
1744 if (val > ma && ma >= 0)
1745 errx(1, "%s must be <= %d", what, ma);
1746 return (int)val;
1747 }
1748
1749 __dead void
usage(void)1750 usage(void)
1751 {
1752 extern char version[];
1753
1754 Fprintf(stderr, "Version %s\n", version);
1755 Fprintf(stderr, "Usage: %s [-adDFPIlMnrvx] [-g gateway] [-i iface] \
1756 [-f first_ttl]\n\t[-m max_ttl] [-p port] [-q nqueries] [-s src_addr] [-t tos]\n\t\
1757 [-w waittime] [-z pausemsecs] [-A as_server] host [packetlen]\n",
1758 getprogname());
1759 exit(1);
1760 }
1761
1762 /*
1763 * Received ICMP unreachable (fragmentation required and DF set).
1764 * If the ICMP error was from a "new" router, it'll contain the next-hop
1765 * MTU that we should use next. Otherwise we'll just keep going in the
1766 * mtus[] table, trying until we hit a valid MTU.
1767 */
1768
1769
1770 void
frag_err()1771 frag_err()
1772 {
1773 int i;
1774
1775 if (nextmtu > 0 && nextmtu < packlen) {
1776 Printf("\nfragmentation required and DF set, "
1777 "next hop MTU = %d\n",
1778 nextmtu);
1779 packlen = nextmtu;
1780 for (i = 0; mtus[i] > 0; i++) {
1781 if (mtus[i] < nextmtu) {
1782 mtuptr = &mtus[i]; /* next one to try */
1783 break;
1784 }
1785 }
1786 } else {
1787 Printf("\nfragmentation required and DF set. ");
1788 if (nextmtu)
1789 Printf("\nBogus next hop MTU = %d > last MTU = %d. ",
1790 nextmtu, packlen);
1791 packlen = *mtuptr++;
1792 Printf("Trying new MTU = %d\n", packlen);
1793 }
1794 resize_packet();
1795 }
1796
1797 int
find_local_ip(struct sockaddr_in * from,struct sockaddr_in * to)1798 find_local_ip(struct sockaddr_in *from, struct sockaddr_in *to)
1799 {
1800 int sock;
1801 struct sockaddr_in help;
1802 socklen_t help_len;
1803
1804 sock = prog_socket(AF_INET, SOCK_DGRAM, 0);
1805 if (sock < 0) return 0;
1806
1807 help.sin_family = AF_INET;
1808 /*
1809 * At this point the port number doesn't matter
1810 * since it only has to be greater than zero.
1811 */
1812 help.sin_port = 42;
1813 help.sin_addr.s_addr = to->sin_addr.s_addr;
1814 if (prog_connect(sock, (struct sockaddr *)&help, sizeof(help)) < 0) {
1815 (void)prog_close(sock);
1816 return 0;
1817 }
1818
1819 help_len = sizeof(help);
1820 if (prog_getsockname(sock, (struct sockaddr *)&help, &help_len) < 0 ||
1821 help_len != sizeof(help) ||
1822 help.sin_addr.s_addr == INADDR_ANY) {
1823 (void)prog_close(sock);
1824 return 0;
1825 }
1826
1827 (void)prog_close(sock);
1828 setsin(from, help.sin_addr.s_addr);
1829 return 1;
1830 }
1831
1832 #ifdef IPSEC
1833 #ifdef IPSEC_POLICY_IPSEC
1834 static int
setpolicy(int so,const char * policy)1835 setpolicy(int so, const char *policy)
1836 {
1837 char *buf;
1838
1839 buf = ipsec_set_policy(policy, strlen(policy));
1840 if (buf == NULL) {
1841 warnx("%s", ipsec_strerror());
1842 return -1;
1843 }
1844 (void)prog_setsockopt(so, IPPROTO_IP, IP_IPSEC_POLICY,
1845 buf, ipsec_get_policylen(buf));
1846
1847 free(buf);
1848
1849 return 0;
1850 }
1851 #endif
1852 #endif
1853
1854