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