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