traceroute.c revision 1.77 1 /* $NetBSD: traceroute.c,v 1.77 2011/05/10 01:52:49 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.77 2011/05/10 01:52:49 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 Fprintf(stderr, "%s: icmp socket: %s\n", prog, strerror(errno));
458 exit(1);
459 }
460
461 /*
462 * XXX 'useicmp' will always be zero here. I think the HP-UX users
463 * running our traceroute code will forgive us.
464 */
465 #ifndef __hpux
466 sndsock = prog_socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
467 #else
468 sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW
469 useicmp ? IPPROTO_ICMP : IPPROTO_UDP);
470 #endif
471 if (sndsock < 0) {
472 Fprintf(stderr, "%s: raw socket: %s\n", prog, strerror(errno));
473 exit(1);
474 }
475
476 /* Revert to non-privileged user after opening sockets */
477 setuid(getuid());
478
479 (void) prog_sysctl(mib, sizeof(mib)/sizeof(mib[0]), &max_ttl, &size,
480 NULL, 0);
481
482 opterr = 0;
483 while ((op = getopt(argc, argv, "aA:dDFPIMnlrvxf:g:i:m:p:q:s:t:w:")) != -1)
484 switch (op) {
485
486 case 'a':
487 as_path = 1;
488 break;
489
490 case 'A':
491 as_path = 1;
492 as_server = optarg;
493 break;
494
495 case 'd':
496 options |= SO_DEBUG;
497 break;
498
499 case 'D':
500 dump = 1;
501 break;
502
503 case 'f':
504 first_ttl = str2val(optarg, "first ttl", 1, 255);
505 break;
506
507 case 'F':
508 off = IP_DF;
509 break;
510
511 case 'g':
512 if (lsrr >= NGATEWAYS) {
513 Fprintf(stderr,
514 "%s: No more than %d gateways\n",
515 prog, NGATEWAYS);
516 exit(1);
517 }
518 getaddr(gwlist + lsrr, optarg);
519 ++lsrr;
520 break;
521
522 case 'i':
523 device = optarg;
524 break;
525
526 case 'I':
527 ++useicmp;
528 break;
529
530 case 'l':
531 ++ttl_flag;
532 break;
533
534 case 'm':
535 max_ttl = str2val(optarg, "max ttl", 1, 255);
536 break;
537
538 case 'M':
539 Mflag = 1;
540 break;
541
542 case 'n':
543 ++nflag;
544 break;
545
546 case 'p':
547 port = str2val(optarg, "port", 1, -1);
548 break;
549
550 case 'q':
551 nprobes = str2val(optarg, "nprobes", 1, -1);
552 break;
553
554 case 'r':
555 options |= SO_DONTROUTE;
556 break;
557
558 case 's':
559 /*
560 * set the ip source address of the outbound
561 * probe (e.g., on a multi-homed host).
562 */
563 source = optarg;
564 break;
565
566 case 't':
567 tos = str2val(optarg, "tos", 0, 255);
568 ++settos;
569 break;
570
571 case 'v':
572 ++verbose;
573 break;
574
575 case 'x':
576 docksum = (docksum == 0);
577 break;
578
579 case 'w':
580 waittime = str2val(optarg, "wait time", 2, 24 * 3600);
581 break;
582
583 case 'P':
584 off = IP_DF;
585 mtudisc = 1;
586 break;
587
588 default:
589 usage();
590 }
591
592 if (first_ttl > max_ttl) {
593 Fprintf(stderr,
594 "%s: first ttl (%d) may not be greater than max ttl (%d)\n",
595 prog, first_ttl, max_ttl);
596 exit(1);
597 }
598
599 if (!docksum)
600 Fprintf(stderr, "%s: Warning: ckecksums disabled\n", prog);
601
602 if (lsrr > 0)
603 optlen = (lsrr + 1) * sizeof(gwlist[0]);
604 minpacket = sizeof(*outip) + sizeof(struct outdata) + optlen;
605 if (useicmp)
606 minpacket += 8; /* XXX magic number */
607 else
608 minpacket += sizeof(*outudp);
609 if (packlen == 0)
610 packlen = minpacket; /* minimum sized packet */
611 else if (minpacket > packlen || packlen > maxpacket) {
612 Fprintf(stderr, "%s: packet size must be %d <= s <= %d\n",
613 prog, minpacket, maxpacket);
614 exit(1);
615 }
616
617 if (mtudisc)
618 packlen = *mtuptr++;
619
620 /* Process destination and optional packet size */
621 switch (argc - optind) {
622
623 case 2:
624 packlen = str2val(argv[optind + 1],
625 "packet length", minpacket, -1);
626 /* Fall through */
627
628 case 1:
629 hostname = argv[optind];
630 hi = gethostinfo(hostname);
631 setsin(to, hi->addrs[0]);
632 if (hi->n > 1)
633 Fprintf(stderr,
634 "%s: Warning: %s has multiple addresses; using %s\n",
635 prog, hostname, inet_ntoa(to->sin_addr));
636 hostname = hi->name;
637 hi->name = NULL;
638 freehostinfo(hi);
639 break;
640
641 default:
642 usage();
643 }
644
645 #ifdef HAVE_SETLINEBUF
646 setlinebuf (stdout);
647 #else
648 setvbuf(stdout, NULL, _IOLBF, 0);
649 #endif
650
651 outip = (struct ip *)malloc((unsigned)packlen);
652 if (outip == NULL) {
653 Fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno));
654 exit(1);
655 }
656 memset((char *)outip, 0, packlen);
657
658 outip->ip_v = IPVERSION;
659 if (settos)
660 outip->ip_tos = tos;
661 #ifdef BYTESWAP_IP_LEN
662 outip->ip_len = htons(packlen);
663 #else
664 outip->ip_len = packlen;
665 #endif
666 outip->ip_off = off;
667 outp = (u_char *)(outip + 1);
668 #ifdef HAVE_RAW_OPTIONS
669 if (lsrr > 0) {
670 u_char *optlist;
671
672 optlist = outp;
673 outp += optlen;
674
675 /* final hop */
676 gwlist[lsrr] = to->sin_addr.s_addr;
677
678 outip->ip_dst.s_addr = gwlist[0];
679
680 /* force 4 byte alignment */
681 optlist[0] = IPOPT_NOP;
682 /* loose source route option */
683 optlist[1] = IPOPT_LSRR;
684 i = lsrr * sizeof(gwlist[0]);
685 optlist[2] = i + 3;
686 /* Pointer to LSRR addresses */
687 optlist[3] = IPOPT_MINOFF;
688 memcpy(optlist + 4, gwlist + 1, i);
689 } else
690 #endif
691 outip->ip_dst = to->sin_addr;
692
693 outip->ip_hl = (outp - (u_char *)outip) >> 2;
694 ident = htons(arc4random() & 0xffff) | 0x8000;
695 if (useicmp) {
696 outip->ip_p = IPPROTO_ICMP;
697
698 outicmp = (struct icmp *)outp;
699 outicmp->icmp_type = ICMP_ECHO;
700 outicmp->icmp_id = htons(ident);
701
702 outmark = outp + 8; /* XXX magic number */
703 } else {
704 outip->ip_p = IPPROTO_UDP;
705
706 outudp = (struct udphdr *)outp;
707 outudp->uh_sport = htons(ident);
708 outudp->uh_ulen =
709 htons((u_int16_t)(packlen - (sizeof(*outip) + optlen)));
710 outmark = outudp + 1;
711 }
712
713 if (options & SO_DEBUG)
714 (void)prog_setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on,
715 sizeof(on));
716 #ifdef IPSEC
717 #ifdef IPSEC_POLICY_IPSEC
718 /*
719 * do not raise error even if setsockopt fails, kernel may have ipsec
720 * turned off.
721 */
722 if (setpolicy(s, "in bypass") < 0)
723 exit(1);
724 if (setpolicy(s, "out bypass") < 0)
725 exit(1);
726 #else
727 {
728 int level = IPSEC_LEVEL_AVAIL;
729
730 (void)prog_setsockopt(s, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level,
731 sizeof(level));
732 (void)prog_setsockopt(s, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level,
733 sizeof(level));
734 #ifdef IP_AUTH_TRANS_LEVEL
735 (void)prog_setsockopt(s, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level,
736 sizeof(level));
737 #else
738 (void)prog_setsockopt(s, IPPROTO_IP, IP_AUTH_LEVEL, &level,
739 sizeof(level));
740 #endif
741 #ifdef IP_AUTH_NETWORK_LEVEL
742 (void)prog_setsockopt(s, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level,
743 sizeof(level));
744 #endif
745 }
746 #endif /*IPSEC_POLICY_IPSEC*/
747 #endif /*IPSEC*/
748
749 #ifdef IPSEC
750 #ifdef IPSEC_POLICY_IPSEC
751 /*
752 * do not raise error even if setsockopt fails, kernel may have ipsec
753 * turned off.
754 */
755 if (setpolicy(sndsock, "in bypass") < 0)
756 exit(1);
757 if (setpolicy(sndsock, "out bypass") < 0)
758 exit(1);
759 #else
760 {
761 int level = IPSEC_LEVEL_BYPASS;
762
763 (void)prog_setsockopt(sndsock, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level,
764 sizeof(level));
765 (void)prog_setsockopt(sndsock, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level,
766 sizeof(level));
767 #ifdef IP_AUTH_TRANS_LEVEL
768 (void)prog_setsockopt(sndsock, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level,
769 sizeof(level));
770 #else
771 (void)prog_setsockopt(sndsock, IPPROTO_IP, IP_AUTH_LEVEL, &level,
772 sizeof(level));
773 #endif
774 #ifdef IP_AUTH_NETWORK_LEVEL
775 (void)prog_setsockopt(sndsock, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level,
776 sizeof(level));
777 #endif
778 }
779 #endif /*IPSEC_POLICY_IPSEC*/
780 #endif /*IPSEC*/
781
782 #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
783 if (lsrr > 0) {
784 u_char optlist[MAX_IPOPTLEN];
785
786 /* final hop */
787 gwlist[lsrr] = to->sin_addr.s_addr;
788 ++lsrr;
789
790 /* force 4 byte alignment */
791 optlist[0] = IPOPT_NOP;
792 /* loose source route option */
793 optlist[1] = IPOPT_LSRR;
794 i = lsrr * sizeof(gwlist[0]);
795 optlist[2] = i + 3;
796 /* Pointer to LSRR addresses */
797 optlist[3] = IPOPT_MINOFF;
798 memcpy(optlist + 4, gwlist, i);
799
800 if ((prog_setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS, optlist,
801 i + sizeof(gwlist[0]))) < 0) {
802 Fprintf(stderr, "%s: IP_OPTIONS: %s\n",
803 prog, strerror(errno));
804 exit(1);
805 }
806 }
807 #endif
808
809 #ifdef SO_SNDBUF
810 if (prog_setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packlen,
811 sizeof(packlen)) < 0) {
812 Fprintf(stderr, "%s: SO_SNDBUF: %s\n", prog, strerror(errno));
813 exit(1);
814 }
815 #endif
816 #ifdef IP_HDRINCL
817 if (prog_setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
818 sizeof(on)) < 0) {
819 Fprintf(stderr, "%s: IP_HDRINCL: %s\n", prog, strerror(errno));
820 exit(1);
821 }
822 #else
823 #ifdef IP_TOS
824 if (settos && prog_setsockopt(sndsock, IPPROTO_IP, IP_TOS,
825 (char *)&tos, sizeof(tos)) < 0) {
826 Fprintf(stderr, "%s: setsockopt tos %d: %s\n",
827 prog, tos, strerror(errno));
828 exit(1);
829 }
830 #endif
831 #endif
832 if (options & SO_DEBUG)
833 (void)prog_setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on,
834 sizeof(on));
835 if (options & SO_DONTROUTE)
836 (void)prog_setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
837 sizeof(on));
838
839 /* Get the interface address list */
840 n = ifaddrlist(&al, errbuf, sizeof errbuf);
841 al2 = al;
842 if (n < 0) {
843 Fprintf(stderr, "%s: ifaddrlist: %s\n", prog, errbuf);
844 exit(1);
845 }
846 if (n == 0) {
847 Fprintf(stderr,
848 "%s: Can't find any network interfaces\n", prog);
849 exit(1);
850 }
851
852 /* Look for a specific device */
853 if (device != NULL) {
854 for (i = n; i > 0; --i, ++al2)
855 if (strcmp(device, al2->device) == 0)
856 break;
857 if (i <= 0) {
858 Fprintf(stderr, "%s: Can't find interface %s\n",
859 prog, device);
860 exit(1);
861 }
862 }
863
864 /* Determine our source address */
865 if (source == NULL) {
866 /*
867 * If a device was specified, use the interface address.
868 * Otherwise, use the first interface found.
869 * Warn if there are more than one.
870 */
871 setsin(from, al2->addr);
872 if (n > 1 && device == NULL && !find_local_ip(from, to)) {
873 Fprintf(stderr,
874 "%s: Warning: Multiple interfaces found; using %s @ %s\n",
875 prog, inet_ntoa(from->sin_addr), al2->device);
876 }
877 } else {
878 hi = gethostinfo(source);
879 source = hi->name;
880 hi->name = NULL;
881 if (device == NULL) {
882 /*
883 * Use the first interface found.
884 * Warn if there are more than one.
885 */
886 setsin(from, hi->addrs[0]);
887 if (hi->n > 1)
888 Fprintf(stderr,
889 "%s: Warning: %s has multiple addresses; using %s\n",
890 prog, source, inet_ntoa(from->sin_addr));
891 } else {
892 /*
893 * Make sure the source specified matches the
894 * interface address.
895 */
896 for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
897 if (*ap == al2->addr)
898 break;
899 if (i <= 0) {
900 Fprintf(stderr,
901 "%s: %s is not on interface %s\n",
902 prog, source, device);
903 exit(1);
904 }
905 setsin(from, *ap);
906 }
907 freehostinfo(hi);
908 }
909
910 /*
911 * If not root, make sure source address matches a local interface.
912 * (The list of addresses produced by ifaddrlist() automatically
913 * excludes interfaces that are marked down and/or loopback.)
914 */
915 if (getuid()) {
916 al2 = al;
917 for (i = n; i > 0; --i, ++al2)
918 if (from->sin_addr.s_addr == al2->addr)
919 break;
920 if (i <= 0) {
921 Fprintf(stderr, "%s: %s is not a valid local address "
922 "and you are not superuser.\n", prog,
923 inet_ntoa(from->sin_addr));
924 exit(1);
925 }
926 }
927
928 outip->ip_src = from->sin_addr;
929 #ifndef IP_HDRINCL
930 if (bind(sndsock, (struct sockaddr *)from, sizeof(*from)) < 0) {
931 Fprintf(stderr, "%s: bind: %s\n",
932 prog, strerror(errno));
933 exit (1);
934 }
935 #endif
936
937 if (as_path) {
938 asn = as_setup(as_server);
939 if (asn == NULL) {
940 Fprintf(stderr, "%s: as_setup failed, AS# lookups disabled\n",
941 prog);
942 (void)fflush(stderr);
943 as_path = 0;
944 }
945 }
946
947 setuid(getuid());
948 Fprintf(stderr, "%s to %s (%s)",
949 prog, hostname, inet_ntoa(to->sin_addr));
950 if (source)
951 Fprintf(stderr, " from %s", source);
952 Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen);
953 (void)fflush(stderr);
954
955 for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
956 u_int32_t lastaddr = 0;
957 int got_there = 0;
958 int unreachable = 0;
959
960 again:
961 printed_ttl = 0;
962 for (probe = 0; probe < nprobes; ++probe) {
963 int cc;
964 struct timeval t1, t2;
965 struct ip *ip;
966 (void)gettimeofday(&t1, NULL);
967 if (!useicmp && htons(port + seq + 1) == 0)
968 seq++;
969 send_probe(++seq, ttl, &t1);
970 while ((cc = wait_for_reply(s, from, &t1)) != 0) {
971 (void)gettimeofday(&t2, NULL);
972 /*
973 * Since we'll be receiving all ICMP
974 * messages to this host above, we may
975 * never end up with cc=0, so we need
976 * an additional termination check.
977 */
978 if (t2.tv_sec - t1.tv_sec > waittime) {
979 cc = 0;
980 break;
981 }
982 i = packet_ok(packet, cc, from, seq);
983 /* Skip short packet */
984 if (i == 0)
985 continue;
986 if (from->sin_addr.s_addr != lastaddr) {
987 print(packet, cc, from);
988 lastaddr = from->sin_addr.s_addr;
989 }
990 ip = (struct ip *)packet;
991 Printf(" %.3f ms", deltaT(&t1, &t2));
992 if (ttl_flag)
993 Printf(" (ttl = %d)", ip->ip_ttl);
994 if (i == -2) {
995 #ifndef ARCHAIC
996 if (ip->ip_ttl <= 1)
997 Printf(" !");
998 #endif
999 ++got_there;
1000 break;
1001 }
1002
1003 /* time exceeded in transit */
1004 if (i == -1)
1005 break;
1006 code = i - 1;
1007 switch (code) {
1008
1009 case ICMP_UNREACH_PORT:
1010 #ifndef ARCHAIC
1011 if (ip->ip_ttl <= 1)
1012 Printf(" !");
1013 #endif
1014 ++got_there;
1015 break;
1016
1017 case ICMP_UNREACH_NET:
1018 ++unreachable;
1019 Printf(" !N");
1020 break;
1021
1022 case ICMP_UNREACH_HOST:
1023 ++unreachable;
1024 Printf(" !H");
1025 break;
1026
1027 case ICMP_UNREACH_PROTOCOL:
1028 ++got_there;
1029 Printf(" !P");
1030 break;
1031
1032 case ICMP_UNREACH_NEEDFRAG:
1033 if (mtudisc) {
1034 frag_err();
1035 goto again;
1036 } else {
1037 ++unreachable;
1038 Printf(" !F");
1039 }
1040 break;
1041
1042 case ICMP_UNREACH_SRCFAIL:
1043 ++unreachable;
1044 Printf(" !S");
1045 break;
1046
1047 /* rfc1716 */
1048 #ifndef ICMP_UNREACH_FILTER_PROHIB
1049 #define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohibited filter */
1050 #endif
1051 case ICMP_UNREACH_FILTER_PROHIB:
1052 ++unreachable;
1053 Printf(" !X");
1054 break;
1055
1056 default:
1057 ++unreachable;
1058 Printf(" !<%d>", code);
1059 break;
1060 }
1061 break;
1062 }
1063 if (cc == 0)
1064 Printf(" *");
1065 else if (cc && probe == nprobes - 1 && Mflag)
1066 decode_extensions(packet, cc);
1067 (void)fflush(stdout);
1068 }
1069 putchar('\n');
1070 if (got_there ||
1071 (unreachable > 0 && unreachable >= ((nprobes + 1) / 2)))
1072 break;
1073 }
1074
1075 if (as_path)
1076 as_shutdown(asn);
1077
1078 exit(0);
1079 }
1080
1081 static ssize_t
1082 wait_for_reply(int sock, struct sockaddr_in *fromp, struct timeval *tp)
1083 {
1084 struct pollfd set[1];
1085 struct timeval now, wait;
1086 ssize_t cc = 0;
1087 socklen_t fromlen = sizeof(*fromp);
1088 int retval;
1089
1090 set[0].fd = sock;
1091 set[0].events = POLLIN;
1092
1093 wait.tv_sec = tp->tv_sec + waittime;
1094 wait.tv_usec = tp->tv_usec;
1095 (void)gettimeofday(&now, NULL);
1096 tvsub(&wait, &now);
1097
1098 if (wait.tv_sec < 0) {
1099 wait.tv_sec = 0;
1100 wait.tv_usec = 0;
1101 }
1102
1103 retval = prog_poll(set, 1, wait.tv_sec * 1000 + wait.tv_usec / 1000);
1104 if (retval < 0) {
1105 /* If we continue, we probably just flood the remote host. */
1106 Fprintf(stderr, "%s: poll: %s\n", prog, strerror(errno));
1107 exit(1);
1108 }
1109 if (retval > 0) {
1110 cc = prog_recvfrom(s, (char *)packet, sizeof(packet), 0,
1111 (struct sockaddr *)fromp, &fromlen);
1112 }
1113
1114 return cc;
1115 }
1116
1117 static void
1118 decode_extensions(unsigned char *buf, int ip_len)
1119 {
1120 struct icmp_ext_cmn_hdr *cmn_hdr;
1121 struct icmp_ext_obj_hdr *obj_hdr;
1122 union {
1123 struct mpls_header mpls;
1124 uint32_t mpls_h;
1125 } mpls;
1126 size_t datalen, obj_len;
1127 struct ip *ip;
1128
1129 ip = (struct ip *)buf;
1130
1131 if (ip_len < (int)((ip->ip_hl << 2) + ICMP_EXT_OFFSET +
1132 sizeof(struct icmp_ext_cmn_hdr))) {
1133 /*
1134 * No support for ICMP extensions on this host
1135 */
1136 return;
1137 }
1138
1139 /*
1140 * Move forward to the start of the ICMP extensions, if present
1141 */
1142 buf += (ip->ip_hl << 2) + ICMP_EXT_OFFSET;
1143 cmn_hdr = (struct icmp_ext_cmn_hdr *)buf;
1144
1145 if (cmn_hdr->version != ICMP_EXT_VERSION) {
1146 /*
1147 * Unknown version
1148 */
1149 return;
1150 }
1151
1152 datalen = ip_len - ((u_char *)cmn_hdr - (u_char *)ip);
1153
1154 /*
1155 * Check the checksum, cmn_hdr->checksum == 0 means no checksum'ing
1156 * done by sender.
1157 *
1158 * If the checksum is ok, we'll get 0, as the checksum is calculated
1159 * with the checksum field being 0'd.
1160 */
1161 if (ntohs(cmn_hdr->checksum) &&
1162 in_cksum((u_short *)cmn_hdr, datalen)) {
1163
1164 return;
1165 }
1166
1167 buf += sizeof(*cmn_hdr);
1168 datalen -= sizeof(*cmn_hdr);
1169
1170 while (datalen >= sizeof(struct icmp_ext_obj_hdr)) {
1171 obj_hdr = (struct icmp_ext_obj_hdr *)buf;
1172 obj_len = ntohs(obj_hdr->length);
1173
1174 /*
1175 * Sanity check the length field
1176 */
1177 if (obj_len > datalen)
1178 return;
1179
1180 datalen -= obj_len;
1181
1182 /*
1183 * Move past the object header
1184 */
1185 buf += sizeof(struct icmp_ext_obj_hdr);
1186 obj_len -= sizeof(struct icmp_ext_obj_hdr);
1187
1188 switch (obj_hdr->class_num) {
1189 case MPLS_STACK_ENTRY_CLASS:
1190 switch (obj_hdr->c_type) {
1191 case MPLS_STACK_ENTRY_C_TYPE:
1192 while (obj_len >= sizeof(uint32_t)) {
1193 mpls.mpls_h = ntohl(*(uint32_t *)buf);
1194
1195 buf += sizeof(uint32_t);
1196 obj_len -= sizeof(uint32_t);
1197
1198 printf(" [MPLS: Label %d Exp %d]",
1199 mpls.mpls.label, mpls.mpls.exp);
1200 }
1201 if (obj_len > 0) {
1202 /*
1203 * Something went wrong, and we're at
1204 * a unknown offset into the packet,
1205 * ditch the rest of it.
1206 */
1207 return;
1208 }
1209 break;
1210 default:
1211 /*
1212 * Unknown object, skip past it
1213 */
1214 buf += ntohs(obj_hdr->length) -
1215 sizeof(struct icmp_ext_obj_hdr);
1216 break;
1217 }
1218 break;
1219
1220 default:
1221 /*
1222 * Unknown object, skip past it
1223 */
1224 buf += ntohs(obj_hdr->length) -
1225 sizeof(struct icmp_ext_obj_hdr);
1226 break;
1227 }
1228 }
1229 }
1230
1231 static void
1232 dump_packet(void)
1233 {
1234 u_char *p;
1235 int i;
1236
1237 Fprintf(stderr, "packet data:");
1238
1239 #ifdef __hpux
1240 for (p = useicmp ? (u_char *)outicmp : (u_char *)outudp, i = 0; i <
1241 i < packlen - (sizeof(*outip) + optlen); i++)
1242 #else
1243 for (p = (u_char *)outip, i = 0; i < packlen; i++)
1244 #endif
1245 {
1246 if ((i % 24) == 0)
1247 Fprintf(stderr, "\n ");
1248 Fprintf(stderr, " %02x", *p++);
1249 }
1250 Fprintf(stderr, "\n");
1251 }
1252
1253 void
1254 send_probe(int seq, int ttl, struct timeval *tp)
1255 {
1256 int cc;
1257 struct udpiphdr * ui;
1258 int oldmtu = packlen;
1259
1260 again:
1261 #ifdef BYTESWAP_IP_LEN
1262 outip->ip_len = htons(packlen);
1263 #else
1264 outip->ip_len = packlen;
1265 #endif
1266 outip->ip_ttl = ttl;
1267 #ifndef __hpux
1268 outip->ip_id = htons(ident + seq);
1269 #endif
1270
1271 /*
1272 * In most cases, the kernel will recalculate the ip checksum.
1273 * But we must do it anyway so that the udp checksum comes out
1274 * right.
1275 */
1276 if (docksum) {
1277 outip->ip_sum =
1278 in_cksum((u_int16_t *)outip, sizeof(*outip) + optlen);
1279 if (outip->ip_sum == 0)
1280 outip->ip_sum = 0xffff;
1281 }
1282
1283 /* Payload */
1284 outsetup.seq = seq;
1285 outsetup.ttl = ttl;
1286 outsetup.tv.tv32_sec = htonl(tp->tv_sec);
1287 outsetup.tv.tv32_usec = htonl(tp->tv_usec);
1288 memcpy(outmark,&outsetup,sizeof(outsetup));
1289
1290 if (useicmp)
1291 outicmp->icmp_seq = htons(seq);
1292 else
1293 outudp->uh_dport = htons(port + seq);
1294
1295 /* (We can only do the checksum if we know our ip address) */
1296 if (docksum) {
1297 if (useicmp) {
1298 outicmp->icmp_cksum = 0;
1299 outicmp->icmp_cksum = in_cksum((u_int16_t *)outicmp,
1300 packlen - (sizeof(*outip) + optlen));
1301 if (outicmp->icmp_cksum == 0)
1302 outicmp->icmp_cksum = 0xffff;
1303 } else {
1304 u_int16_t sum;
1305 struct {
1306 struct in_addr src;
1307 struct in_addr dst;
1308 u_int8_t zero;
1309 u_int8_t protocol;
1310 u_int16_t len;
1311 } __packed phdr;
1312
1313 /* Checksum */
1314 ui = (struct udpiphdr *)outip;
1315 memset(&phdr, 0, sizeof(phdr));
1316 phdr.src = ui->ui_src;
1317 phdr.dst = ((struct sockaddr_in *)&whereto)->sin_addr;
1318 phdr.protocol = ui->ui_pr;
1319 phdr.len = outudp->uh_ulen;
1320 outudp->uh_sum = 0;
1321 sum = in_cksum2(0, (u_int16_t *)&phdr, sizeof(phdr));
1322 sum = in_cksum2(sum, (u_int16_t *)outudp, ntohs(outudp->uh_ulen));
1323 outudp->uh_sum = ~sum;
1324 if (outudp->uh_sum == 0)
1325 outudp->uh_sum = 0xffff;
1326 }
1327 }
1328
1329 /* XXX undocumented debugging hack */
1330 if (verbose > 1) {
1331 const u_int16_t *sp;
1332 int nshorts, i;
1333
1334 sp = (u_int16_t *)outip;
1335 nshorts = (u_int)packlen / sizeof(u_int16_t);
1336 i = 0;
1337 Printf("[ %d bytes", packlen);
1338 while (--nshorts >= 0) {
1339 if ((i++ % 8) == 0)
1340 Printf("\n\t");
1341 Printf(" %04x", ntohs(*sp++));
1342 }
1343 if (packlen & 1) {
1344 if ((i % 8) == 0)
1345 Printf("\n\t");
1346 Printf(" %02x", *(const u_char *)sp);
1347 }
1348 Printf("]\n");
1349 }
1350
1351 #if !defined(IP_HDRINCL) && defined(IP_TTL)
1352 if (prog_setsockopt(sndsock, IPPROTO_IP, IP_TTL,
1353 (char *)&ttl, sizeof(ttl)) < 0) {
1354 Fprintf(stderr, "%s: setsockopt ttl %d: %s\n",
1355 prog, ttl, strerror(errno));
1356 exit(1);
1357 }
1358 #endif
1359 if (dump)
1360 dump_packet();
1361
1362 #ifdef __hpux
1363 cc = sendto(sndsock, useicmp ? (char *)outicmp : (char *)outudp,
1364 packlen - (sizeof(*outip) + optlen), 0, &whereto, sizeof(whereto));
1365 if (cc > 0)
1366 cc += sizeof(*outip) + optlen;
1367 #else
1368 cc = prog_sendto(sndsock, (char *)outip,
1369 packlen, 0, &whereto, sizeof(whereto));
1370 #endif
1371 if (cc < 0 || cc != packlen) {
1372 if (cc < 0) {
1373 /*
1374 * An errno of EMSGSIZE means we're writing too big a
1375 * datagram for the interface. We have to just
1376 * decrease the packet size until we find one that
1377 * works.
1378 *
1379 * XXX maybe we should try to read the outgoing if's
1380 * mtu?
1381 */
1382 if (errno == EMSGSIZE) {
1383 packlen = *mtuptr++;
1384 resize_packet();
1385 goto again;
1386 } else
1387 Fprintf(stderr, "%s: sendto: %s\n",
1388 prog, strerror(errno));
1389 }
1390
1391 Printf("%s: wrote %s %d chars, ret=%d\n",
1392 prog, hostname, packlen, cc);
1393 (void)fflush(stdout);
1394 }
1395 if (oldmtu != packlen) {
1396 Printf("message too big, "
1397 "trying new MTU = %d\n", packlen);
1398 printed_ttl = 0;
1399 }
1400 if (!printed_ttl) {
1401 Printf("%2d ", ttl);
1402 printed_ttl = 1;
1403 }
1404
1405 }
1406
1407 static double
1408 deltaT(struct timeval *t1p, struct timeval *t2p)
1409 {
1410 double dt;
1411
1412 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1413 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1414 return (dt);
1415 }
1416
1417 /*
1418 * Convert an ICMP "type" field to a printable string.
1419 */
1420 static const char *
1421 pr_type(u_char t)
1422 {
1423 static const char *ttab[] = {
1424 "Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable",
1425 "Source Quench", "Redirect", "ICMP 6", "ICMP 7",
1426 "Echo", "ICMP 9", "ICMP 10", "Time Exceeded",
1427 "Param Problem", "Timestamp", "Timestamp Reply", "Info Request",
1428 "Info Reply"
1429 };
1430
1431 if (t > 16)
1432 return "OUT-OF-RANGE";
1433
1434 return ttab[t];
1435 }
1436
1437 static int
1438 packet_ok(u_char *buf, ssize_t cc, struct sockaddr_in *from, int seq)
1439 {
1440 struct icmp *icp;
1441 u_char type, code;
1442 int hlen;
1443 #ifndef ARCHAIC
1444 struct ip *ip;
1445
1446 ip = (struct ip *) buf;
1447 hlen = ip->ip_hl << 2;
1448 if (cc < hlen + ICMP_MINLEN) {
1449 if (verbose)
1450 Printf("packet too short (%zd bytes) from %s\n", cc,
1451 inet_ntoa(from->sin_addr));
1452 return (0);
1453 }
1454 cc -= hlen;
1455 icp = (struct icmp *)(buf + hlen);
1456 #else
1457 icp = (struct icmp *)buf;
1458 #endif
1459 type = icp->icmp_type;
1460 code = icp->icmp_code;
1461 if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
1462 type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
1463 struct ip *hip;
1464 struct udphdr *up;
1465 struct icmp *hicmp;
1466
1467 hip = &icp->icmp_ip;
1468 hlen = hip->ip_hl << 2;
1469
1470 nextmtu = ntohs(icp->icmp_nextmtu); /* for frag_err() */
1471
1472 if (useicmp) {
1473 /* XXX */
1474 if (type == ICMP_ECHOREPLY &&
1475 icp->icmp_id == htons(ident) &&
1476 icp->icmp_seq == htons(seq))
1477 return (-2);
1478
1479 hicmp = (struct icmp *)((u_char *)hip + hlen);
1480 /* XXX 8 is a magic number */
1481 if (hlen + 8 <= cc &&
1482 hip->ip_p == IPPROTO_ICMP &&
1483 hicmp->icmp_id == htons(ident) &&
1484 hicmp->icmp_seq == htons(seq))
1485 return (type == ICMP_TIMXCEED ? -1 : code + 1);
1486 } else {
1487 up = (struct udphdr *)((u_char *)hip + hlen);
1488 /* XXX 8 is a magic number */
1489 if (hlen + 12 <= cc &&
1490 hip->ip_p == IPPROTO_UDP &&
1491 up->uh_sport == htons(ident) &&
1492 up->uh_dport == htons(port + seq))
1493 return (type == ICMP_TIMXCEED ? -1 : code + 1);
1494 }
1495 }
1496 #ifndef ARCHAIC
1497 if (verbose) {
1498 int i;
1499 u_int32_t *lp = (u_int32_t *)&icp->icmp_ip;
1500
1501 Printf("\n%zd bytes from %s to ", cc, inet_ntoa(from->sin_addr));
1502 Printf("%s: icmp type %d (%s) code %d\n",
1503 inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
1504 for (i = 4; i < cc ; i += sizeof(*lp))
1505 Printf("%2d: x%8.8x\n", i, *lp++);
1506 }
1507 #endif
1508 return(0);
1509 }
1510
1511 static void
1512 resize_packet(void)
1513 {
1514 if (useicmp) {
1515 outicmp->icmp_cksum = 0;
1516 outicmp->icmp_cksum = in_cksum((u_int16_t *)outicmp,
1517 packlen - (sizeof(*outip) + optlen));
1518 if (outicmp->icmp_cksum == 0)
1519 outicmp->icmp_cksum = 0xffff;
1520 } else {
1521 outudp->uh_ulen =
1522 htons((u_int16_t)(packlen - (sizeof(*outip) + optlen)));
1523 }
1524 }
1525
1526 static void
1527 print(u_char *buf, int cc, struct sockaddr_in *from)
1528 {
1529 struct ip *ip;
1530 int hlen;
1531 char addr[INET_ADDRSTRLEN];
1532
1533 ip = (struct ip *) buf;
1534 hlen = ip->ip_hl << 2;
1535 cc -= hlen;
1536
1537 strlcpy(addr, inet_ntoa(from->sin_addr), sizeof(addr));
1538
1539 if (as_path)
1540 Printf(" [AS%u]", as_lookup(asn, addr, AF_INET));
1541
1542 if (nflag)
1543 Printf(" %s", addr);
1544 else
1545 Printf(" %s (%s)", inetname(from->sin_addr), addr);
1546
1547 if (verbose)
1548 Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
1549 }
1550
1551 static u_int16_t
1552 in_cksum(u_int16_t *addr, int len)
1553 {
1554
1555 return ~in_cksum2(0, addr, len);
1556 }
1557
1558 /*
1559 * Checksum routine for Internet Protocol family headers (C Version)
1560 */
1561 static u_int16_t
1562 in_cksum2(u_int16_t seed, u_int16_t *addr, int len)
1563 {
1564 int nleft = len;
1565 u_int16_t *w = addr;
1566 union {
1567 u_int16_t w;
1568 u_int8_t b[2];
1569 } answer;
1570 int32_t sum = seed;
1571
1572 /*
1573 * Our algorithm is simple, using a 32 bit accumulator (sum),
1574 * we add sequential 16 bit words to it, and at the end, fold
1575 * back all the carry bits from the top 16 bits into the lower
1576 * 16 bits.
1577 */
1578 while (nleft > 1) {
1579 sum += *w++;
1580 nleft -= 2;
1581 }
1582
1583 /* mop up an odd byte, if necessary */
1584 if (nleft == 1) {
1585 answer.b[0] = *(u_char *)w;
1586 answer.b[1] = 0;
1587 sum += answer.w;
1588 }
1589
1590 /*
1591 * add back carry outs from top 16 bits to low 16 bits
1592 */
1593 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
1594 sum += (sum >> 16); /* add carry */
1595 answer.w = sum; /* truncate to 16 bits */
1596 return (answer.w);
1597 }
1598
1599 /*
1600 * Subtract 2 timeval structs: out = out - in.
1601 * Out is assumed to be >= in.
1602 */
1603 static void
1604 tvsub(struct timeval *out, struct timeval *in)
1605 {
1606
1607 if ((out->tv_usec -= in->tv_usec) < 0) {
1608 --out->tv_sec;
1609 out->tv_usec += 1000000;
1610 }
1611 out->tv_sec -= in->tv_sec;
1612 }
1613
1614 /*
1615 * Construct an Internet address representation.
1616 * If the nflag has been supplied, give
1617 * numeric value, otherwise try for symbolic name.
1618 */
1619 static char *
1620 inetname(struct in_addr in)
1621 {
1622 char *cp;
1623 struct hostent *hp;
1624 static int first = 1;
1625 static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1];
1626
1627 if (first && !nflag) {
1628 int rv;
1629
1630 first = 0;
1631 rv = gethostname(domain, sizeof domain);
1632 if (rv == 0 && (cp = strchr(domain, '.')) != NULL) {
1633 (void)strlcpy(domain, cp + 1, sizeof(domain));
1634 } else
1635 domain[0] = '\0';
1636 }
1637 if (!nflag && in.s_addr != INADDR_ANY) {
1638 hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
1639 if (hp != NULL) {
1640 if ((cp = strchr(hp->h_name, '.')) != NULL &&
1641 strcmp(cp + 1, domain) == 0)
1642 *cp = '\0';
1643 (void)strlcpy(line, hp->h_name, sizeof(line));
1644 return (line);
1645 }
1646 }
1647 return (inet_ntoa(in));
1648 }
1649
1650 static struct hostinfo *
1651 gethostinfo(char *hname)
1652 {
1653 int n;
1654 struct hostent *hp;
1655 struct hostinfo *hi;
1656 char **p;
1657 u_int32_t *ap;
1658 struct in_addr addr;
1659
1660 hi = calloc(1, sizeof(*hi));
1661 if (hi == NULL) {
1662 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1663 exit(1);
1664 }
1665 if (inet_aton(hname, &addr) != 0) {
1666 hi->name = strdup(hname);
1667 if (!hi->name) {
1668 Fprintf(stderr, "%s: strdup %s\n", prog,
1669 strerror(errno));
1670 exit(1);
1671 }
1672 hi->n = 1;
1673 hi->addrs = calloc(1, sizeof(hi->addrs[0]));
1674 if (hi->addrs == NULL) {
1675 Fprintf(stderr, "%s: calloc %s\n",
1676 prog, strerror(errno));
1677 exit(1);
1678 }
1679 hi->addrs[0] = addr.s_addr;
1680 return (hi);
1681 }
1682
1683 hp = gethostbyname(hname);
1684 if (hp == NULL) {
1685 Fprintf(stderr, "%s: unknown host %s\n", prog, hname);
1686 exit(1);
1687 }
1688 if (hp->h_addrtype != AF_INET || hp->h_length != 4) {
1689 Fprintf(stderr, "%s: bad host %s\n", prog, hname);
1690 exit(1);
1691 }
1692 hi->name = strdup(hp->h_name);
1693 if (!hi->name) {
1694 Fprintf(stderr, "%s: strdup %s\n", prog, strerror(errno));
1695 exit(1);
1696 }
1697 for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
1698 continue;
1699 hi->n = n;
1700 hi->addrs = calloc(n, sizeof(hi->addrs[0]));
1701 if (hi->addrs == NULL) {
1702 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1703 exit(1);
1704 }
1705 for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
1706 memcpy(ap, *p, sizeof(*ap));
1707 return (hi);
1708 }
1709
1710 static void
1711 freehostinfo(struct hostinfo *hi)
1712 {
1713 if (hi->name != NULL) {
1714 free(hi->name);
1715 hi->name = NULL;
1716 }
1717 free((char *)hi->addrs);
1718 free((char *)hi);
1719 }
1720
1721 static void
1722 getaddr(u_int32_t *ap, char *hname)
1723 {
1724 struct hostinfo *hi;
1725
1726 hi = gethostinfo(hname);
1727 *ap = hi->addrs[0];
1728 freehostinfo(hi);
1729 }
1730
1731 static void
1732 setsin(struct sockaddr_in *sin, u_int32_t addr)
1733 {
1734
1735 memset(sin, 0, sizeof(*sin));
1736 #ifdef HAVE_SOCKADDR_SA_LEN
1737 sin->sin_len = sizeof(*sin);
1738 #endif
1739 sin->sin_family = AF_INET;
1740 sin->sin_addr.s_addr = addr;
1741 }
1742
1743 /* String to value with optional min and max. Handles decimal and hex. */
1744 static int
1745 str2val(const char *str, const char *what, int mi, int ma)
1746 {
1747 const char *cp;
1748 long val;
1749 char *ep;
1750
1751 errno = 0;
1752 ep = NULL;
1753 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
1754 cp = str + 2;
1755 val = strtol(cp, &ep, 16);
1756 } else
1757 val = strtol(str, &ep, 10);
1758 if (errno || str[0] == '\0' || *ep != '\0') {
1759 Fprintf(stderr, "%s: \"%s\" bad value for %s \n",
1760 prog, str, what);
1761 exit(1);
1762 }
1763 if (val < mi && mi >= 0) {
1764 if (mi == 0)
1765 Fprintf(stderr, "%s: %s must be >= %d\n",
1766 prog, what, mi);
1767 else
1768 Fprintf(stderr, "%s: %s must be > %d\n",
1769 prog, what, mi - 1);
1770 exit(1);
1771 }
1772 if (val > ma && ma >= 0) {
1773 Fprintf(stderr, "%s: %s must be <= %d\n", prog, what, ma);
1774 exit(1);
1775 }
1776 return ((int)val);
1777 }
1778
1779 __dead void
1780 usage(void)
1781 {
1782 extern char version[];
1783
1784 Fprintf(stderr, "Version %s\n", version);
1785 Fprintf(stderr, "usage: %s [-adDFPIlMnrvx] [-g gateway] [-i iface] \
1786 [-f first_ttl]\n\t[-m max_ttl] [-p port] [-q nqueries] [-s src_addr] [-t tos]\n\t\
1787 [-w waittime] [-A as_server] host [packetlen]\n",
1788 prog);
1789 exit(1);
1790 }
1791
1792 /*
1793 * Received ICMP unreachable (fragmentation required and DF set).
1794 * If the ICMP error was from a "new" router, it'll contain the next-hop
1795 * MTU that we should use next. Otherwise we'll just keep going in the
1796 * mtus[] table, trying until we hit a valid MTU.
1797 */
1798
1799
1800 void
1801 frag_err()
1802 {
1803 int i;
1804
1805 if (nextmtu > 0 && nextmtu < packlen) {
1806 Printf("\nfragmentation required and DF set, "
1807 "next hop MTU = %d\n",
1808 nextmtu);
1809 packlen = nextmtu;
1810 for (i = 0; mtus[i] > 0; i++) {
1811 if (mtus[i] < nextmtu) {
1812 mtuptr = &mtus[i]; /* next one to try */
1813 break;
1814 }
1815 }
1816 } else {
1817 Printf("\nfragmentation required and DF set. ");
1818 if (nextmtu)
1819 Printf("\nBogus next hop MTU = %d > last MTU = %d. ",
1820 nextmtu, packlen);
1821 packlen = *mtuptr++;
1822 Printf("Trying new MTU = %d\n", packlen);
1823 }
1824 resize_packet();
1825 }
1826
1827 int
1828 find_local_ip(struct sockaddr_in *from, struct sockaddr_in *to)
1829 {
1830 int sock;
1831 struct sockaddr_in help;
1832 socklen_t help_len;
1833
1834 sock = prog_socket(AF_INET, SOCK_DGRAM, 0);
1835 if (sock < 0) return (0);
1836
1837 help.sin_family = AF_INET;
1838 /*
1839 * At this point the port number doesn't matter
1840 * since it only has to be greater than zero.
1841 */
1842 help.sin_port = 42;
1843 help.sin_addr.s_addr = to->sin_addr.s_addr;
1844 if (prog_connect(sock, (struct sockaddr *)&help, sizeof(help)) < 0) {
1845 (void)prog_close(sock);
1846 return (0);
1847 }
1848
1849 help_len = sizeof(help);
1850 if (prog_getsockname(sock, (struct sockaddr *)&help, &help_len) < 0 ||
1851 help_len != sizeof(help) ||
1852 help.sin_addr.s_addr == INADDR_ANY) {
1853 (void)prog_close(sock);
1854 return (0);
1855 }
1856
1857 (void)prog_close(sock);
1858 setsin(from, help.sin_addr.s_addr);
1859 return (1);
1860 }
1861
1862 #ifdef IPSEC
1863 #ifdef IPSEC_POLICY_IPSEC
1864 static int
1865 setpolicy(int so, const char *policy)
1866 {
1867 char *buf;
1868
1869 buf = ipsec_set_policy(policy, strlen(policy));
1870 if (buf == NULL) {
1871 Fprintf(stderr, "%s: %s\n", prog, ipsec_strerror());
1872 return -1;
1873 }
1874 (void)prog_setsockopt(so, IPPROTO_IP, IP_IPSEC_POLICY,
1875 buf, ipsec_get_policylen(buf));
1876
1877 free(buf);
1878
1879 return 0;
1880 }
1881 #endif
1882 #endif
1883
1884