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