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