traceroute.c revision 1.53 1 /* $NetBSD: traceroute.c,v 1.53 2002/08/12 02:51:07 itojun 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.53 2002/08/12 02:51:07 itojun 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 #ifdef HAVE_SYS_SELECT_H
211 #include <sys/select.h>
212 #endif
213 #include <sys/socket.h>
214 #include <sys/time.h>
215 #include <sys/sysctl.h>
216
217 #include <netinet/in_systm.h>
218 #include <netinet/in.h>
219 #include <netinet/ip.h>
220 #include <netinet/ip_var.h>
221 #include <netinet/ip_icmp.h>
222 #include <netinet/udp.h>
223 #include <netinet/udp_var.h>
224
225 #include <arpa/inet.h>
226
227 #include <ctype.h>
228 #include <errno.h>
229 #ifdef HAVE_MALLOC_H
230 #include <malloc.h>
231 #endif
232 #include <memory.h>
233 #include <netdb.h>
234 #include <stdio.h>
235 #include <stdlib.h>
236 #include <string.h>
237 #include <unistd.h>
238 #ifdef IPSEC
239 #include <net/route.h>
240 #include <netinet6/ipsec.h>
241 #endif
242
243 #include "gnuc.h"
244 #ifdef HAVE_OS_PROTO_H
245 #include "os-proto.h"
246 #endif
247
248 #include "ifaddrlist.h"
249 #include "savestr.h"
250 #include "as.h"
251
252 /* Maximum number of gateways (include room for one noop) */
253 #define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(u_int32_t)))
254
255 #ifndef MAXHOSTNAMELEN
256 #define MAXHOSTNAMELEN 64
257 #endif
258
259 #define Fprintf (void)fprintf
260 #define Printf (void)printf
261
262 /* Host name and address list */
263 struct hostinfo {
264 char *name;
265 int n;
266 u_int32_t *addrs;
267 };
268
269 /* Data section of the probe packet */
270 struct outdata {
271 u_char seq; /* sequence number of this packet */
272 u_char ttl; /* ttl packet left with */
273 struct timeval tv; /* time packet left */
274 };
275
276 u_char packet[512]; /* last inbound (icmp) packet */
277
278 struct ip *outip; /* last output (udp) packet */
279 struct udphdr *outudp; /* last output (udp) packet */
280 void *outmark; /* packed location of struct outdata */
281 struct outdata outsetup; /* setup and copy for alignment */
282
283 struct icmp *outicmp; /* last output (icmp) packet */
284
285 /* loose source route gateway list (including room for final destination) */
286 u_int32_t gwlist[NGATEWAYS + 1];
287
288 int s; /* receive (icmp) socket file descriptor */
289 int sndsock; /* send (udp/icmp) socket file descriptor */
290
291 struct sockaddr whereto; /* Who to try to reach */
292 struct sockaddr_in wherefrom; /* Who we are */
293 int packlen; /* total length of packet */
294 int minpacket; /* min ip packet size */
295 int maxpacket = 32 * 1024; /* max ip packet size */
296 int printed_ttl = 0;
297
298 char *prog;
299 char *source;
300 char *hostname;
301 char *device;
302
303 int nprobes = 3;
304 int max_ttl = 30;
305 int first_ttl = 1;
306 u_int16_t ident;
307 in_port_t port = 32768 + 666; /* start udp dest port # for probe packets */
308
309 int options; /* socket options */
310 int verbose;
311 int waittime = 5; /* time to wait for response (in seconds) */
312 int nflag; /* print addresses numerically */
313 int dump;
314 int as_path; /* print as numbers for each hop */
315 char *as_server = NULL;
316 void *asn;
317 int useicmp; /* use icmp echo instead of udp packets */
318 #ifdef CANT_HACK_CKSUM
319 int docksum = 0; /* don't calculate checksums */
320 #else
321 int docksum = 1; /* calculate checksums */
322 #endif
323 int optlen; /* length of ip options */
324
325 int mtus[] = {
326 17914,
327 8166,
328 4464,
329 4352,
330 2048,
331 2002,
332 1536,
333 1500,
334 1492,
335 1480,
336 1280,
337 1006,
338 576,
339 552,
340 544,
341 512,
342 508,
343 296,
344 68,
345 0
346 };
347 int *mtuptr = &mtus[0];
348 int mtudisc = 0;
349 int nextmtu; /* from ICMP error, set by packet_ok(), might be 0 */
350
351 extern int optind;
352 extern int opterr;
353 extern char *optarg;
354
355 /* Forwards */
356 double deltaT(struct timeval *, struct timeval *);
357 void freehostinfo(struct hostinfo *);
358 void getaddr(u_int32_t *, char *);
359 struct hostinfo *gethostinfo(char *);
360 u_int16_t in_cksum(u_int16_t *, int);
361 u_int16_t in_cksum2(u_int16_t, u_int16_t *, int);
362 char *inetname(struct in_addr);
363 int main(int, char **);
364 int packet_ok(u_char *, int, struct sockaddr_in *, int);
365 char *pr_type(u_char);
366 void print(u_char *, int, struct sockaddr_in *);
367 void resize_packet(void);
368 void dump_packet(void);
369 void send_probe(int, int, struct timeval *);
370 void setsin(struct sockaddr_in *, u_int32_t);
371 int str2val(const char *, const char *, int, int);
372 void tvsub(struct timeval *, struct timeval *);
373 __dead void usage(void);
374 int wait_for_reply(int, struct sockaddr_in *, struct timeval *);
375 void frag_err(void);
376 int find_local_ip(struct sockaddr_in *, struct sockaddr_in *);
377 #ifdef IPSEC
378 #ifdef IPSEC_POLICY_IPSEC
379 int setpolicy(int so, char *policy);
380 #endif
381 #endif
382
383 int
384 main(int argc, char **argv)
385 {
386 int op, code, n;
387 char *cp;
388 u_char *outp;
389 u_int32_t *ap;
390 struct sockaddr_in *from = &wherefrom;
391 struct sockaddr_in *to = (struct sockaddr_in *)&whereto;
392 struct hostinfo *hi;
393 int on = 1;
394 int ttl, probe, i;
395 int seq = 0;
396 int tos = 0, settos = 0, ttl_flag = 0;
397 int lsrr = 0;
398 u_int16_t off = 0;
399 struct ifaddrlist *al, *al2;
400 char errbuf[132];
401 int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL };
402 size_t size = sizeof(max_ttl);
403
404 (void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &max_ttl, &size,
405 NULL, 0);
406
407 if ((cp = strrchr(argv[0], '/')) != NULL)
408 prog = cp + 1;
409 else
410 prog = argv[0];
411
412 opterr = 0;
413 while ((op = getopt(argc, argv, "aA:dDFPInlrvxf:g:i:m:p:q:s:t:w:")) != -1)
414 switch (op) {
415
416 case 'a':
417 as_path = 1;
418 break;
419
420 case 'A':
421 as_path = 1;
422 as_server = optarg;
423 break;
424
425 case 'd':
426 options |= SO_DEBUG;
427 break;
428
429 case 'D':
430 dump = 1;
431 break;
432
433 case 'f':
434 first_ttl = str2val(optarg, "first ttl", 1, 255);
435 break;
436
437 case 'F':
438 off = IP_DF;
439 break;
440
441 case 'g':
442 if (lsrr >= NGATEWAYS) {
443 Fprintf(stderr,
444 "%s: No more than %d gateways\n",
445 prog, NGATEWAYS);
446 exit(1);
447 }
448 getaddr(gwlist + lsrr, optarg);
449 ++lsrr;
450 break;
451
452 case 'i':
453 device = optarg;
454 break;
455
456 case 'I':
457 ++useicmp;
458 break;
459
460 case 'l':
461 ++ttl_flag;
462 break;
463
464 case 'm':
465 max_ttl = str2val(optarg, "max ttl", 1, 255);
466 break;
467
468 case 'n':
469 ++nflag;
470 break;
471
472 case 'p':
473 port = str2val(optarg, "port", 1, -1);
474 break;
475
476 case 'q':
477 nprobes = str2val(optarg, "nprobes", 1, -1);
478 break;
479
480 case 'r':
481 options |= SO_DONTROUTE;
482 break;
483
484 case 's':
485 /*
486 * set the ip source address of the outbound
487 * probe (e.g., on a multi-homed host).
488 */
489 source = optarg;
490 break;
491
492 case 't':
493 tos = str2val(optarg, "tos", 0, 255);
494 ++settos;
495 break;
496
497 case 'v':
498 ++verbose;
499 break;
500
501 case 'x':
502 docksum = (docksum == 0);
503 break;
504
505 case 'w':
506 waittime = str2val(optarg, "wait time", 2, 24 * 3600);
507 break;
508
509 case 'P':
510 off = IP_DF;
511 mtudisc = 1;
512 break;
513
514 default:
515 usage();
516 }
517
518 if (first_ttl > max_ttl) {
519 Fprintf(stderr,
520 "%s: first ttl (%d) may not be greater than max ttl (%d)\n",
521 prog, first_ttl, max_ttl);
522 exit(1);
523 }
524
525 if (!docksum)
526 Fprintf(stderr, "%s: Warning: ckecksums disabled\n", prog);
527
528 if (lsrr > 0)
529 optlen = (lsrr + 1) * sizeof(gwlist[0]);
530 minpacket = sizeof(*outip) + sizeof(struct outdata) + optlen;
531 if (useicmp)
532 minpacket += 8; /* XXX magic number */
533 else
534 minpacket += sizeof(*outudp);
535 if (packlen == 0)
536 packlen = minpacket; /* minimum sized packet */
537 else if (minpacket > packlen || packlen > maxpacket) {
538 Fprintf(stderr, "%s: packet size must be %d <= s <= %d\n",
539 prog, minpacket, maxpacket);
540 exit(1);
541 }
542
543 if (mtudisc)
544 packlen = *mtuptr++;
545
546 /* Process destination and optional packet size */
547 switch (argc - optind) {
548
549 case 2:
550 packlen = str2val(argv[optind + 1],
551 "packet length", minpacket, -1);
552 /* Fall through */
553
554 case 1:
555 hostname = argv[optind];
556 hi = gethostinfo(hostname);
557 setsin(to, hi->addrs[0]);
558 if (hi->n > 1)
559 Fprintf(stderr,
560 "%s: Warning: %s has multiple addresses; using %s\n",
561 prog, hostname, inet_ntoa(to->sin_addr));
562 hostname = hi->name;
563 hi->name = NULL;
564 freehostinfo(hi);
565 break;
566
567 default:
568 usage();
569 }
570
571 #ifdef HAVE_SETLINEBUF
572 setlinebuf (stdout);
573 #else
574 setvbuf(stdout, NULL, _IOLBF, 0);
575 #endif
576
577 outip = (struct ip *)malloc((unsigned)packlen);
578 if (outip == NULL) {
579 Fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno));
580 exit(1);
581 }
582 memset((char *)outip, 0, packlen);
583
584 outip->ip_v = IPVERSION;
585 if (settos)
586 outip->ip_tos = tos;
587 #ifdef BYTESWAP_IP_LEN
588 outip->ip_len = htons(packlen);
589 #else
590 outip->ip_len = packlen;
591 #endif
592 outip->ip_off = off;
593 outp = (u_char *)(outip + 1);
594 #ifdef HAVE_RAW_OPTIONS
595 if (lsrr > 0) {
596 u_char *optlist;
597
598 optlist = outp;
599 outp += optlen;
600
601 /* final hop */
602 gwlist[lsrr] = to->sin_addr.s_addr;
603
604 outip->ip_dst.s_addr = gwlist[0];
605
606 /* force 4 byte alignment */
607 optlist[0] = IPOPT_NOP;
608 /* loose source route option */
609 optlist[1] = IPOPT_LSRR;
610 i = lsrr * sizeof(gwlist[0]);
611 optlist[2] = i + 3;
612 /* Pointer to LSRR addresses */
613 optlist[3] = IPOPT_MINOFF;
614 memcpy(optlist + 4, gwlist + 1, i);
615 } else
616 #endif
617 outip->ip_dst = to->sin_addr;
618
619 outip->ip_hl = (outp - (u_char *)outip) >> 2;
620 ident = (getpid() & 0xffff) | 0x8000;
621 if (useicmp) {
622 outip->ip_p = IPPROTO_ICMP;
623
624 outicmp = (struct icmp *)outp;
625 outicmp->icmp_type = ICMP_ECHO;
626 outicmp->icmp_id = htons(ident);
627
628 outmark = outp + 8; /* XXX magic number */
629 } else {
630 outip->ip_p = IPPROTO_UDP;
631
632 outudp = (struct udphdr *)outp;
633 outudp->uh_sport = htons(ident);
634 outudp->uh_ulen =
635 htons((u_int16_t)(packlen - (sizeof(*outip) + optlen)));
636 outmark = outudp + 1;
637 }
638
639 if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) {
640 Fprintf(stderr, "%s: icmp socket: %s\n", prog, strerror(errno));
641 exit(1);
642 }
643 if (options & SO_DEBUG)
644 (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on,
645 sizeof(on));
646 #ifdef IPSEC
647 #ifdef IPSEC_POLICY_IPSEC
648 /*
649 * do not raise error even if setsockopt fails, kernel may have ipsec
650 * turned off.
651 */
652 if (setpolicy(s, "in bypass") < 0)
653 exit(1);
654 if (setpolicy(s, "out bypass") < 0)
655 exit(1);
656 #else
657 {
658 int level = IPSEC_LEVEL_AVAIL;
659
660 (void)setsockopt(s, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level,
661 sizeof(level));
662 (void)setsockopt(s, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level,
663 sizeof(level));
664 #ifdef IP_AUTH_TRANS_LEVEL
665 (void)setsockopt(s, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level,
666 sizeof(level));
667 #else
668 (void)setsockopt(s, IPPROTO_IP, IP_AUTH_LEVEL, &level,
669 sizeof(level));
670 #endif
671 #ifdef IP_AUTH_NETWORK_LEVEL
672 (void)setsockopt(s, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level,
673 sizeof(level));
674 #endif
675 }
676 #endif /*IPSEC_POLICY_IPSEC*/
677 #endif /*IPSEC*/
678
679 #ifndef __hpux
680 sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
681 #else
682 sndsock = socket(AF_INET, SOCK_RAW,
683 useicmp ? IPPROTO_ICMP : IPPROTO_UDP);
684 #endif
685 if (sndsock < 0) {
686 Fprintf(stderr, "%s: raw socket: %s\n", prog, strerror(errno));
687 exit(1);
688 }
689
690 #ifdef IPSEC
691 #ifdef IPSEC_POLICY_IPSEC
692 /*
693 * do not raise error even if setsockopt fails, kernel may have ipsec
694 * turned off.
695 */
696 if (setpolicy(sndsock, "in bypass") < 0)
697 exit(1);
698 if (setpolicy(sndsock, "out bypass") < 0)
699 exit(1);
700 #else
701 {
702 int level = IPSEC_LEVEL_BYPASS;
703
704 (void)setsockopt(sndsock, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level,
705 sizeof(level));
706 (void)setsockopt(sndsock, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level,
707 sizeof(level));
708 #ifdef IP_AUTH_TRANS_LEVEL
709 (void)setsockopt(sndsock, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level,
710 sizeof(level));
711 #else
712 (void)setsockopt(sndsock, IPPROTO_IP, IP_AUTH_LEVEL, &level,
713 sizeof(level));
714 #endif
715 #ifdef IP_AUTH_NETWORK_LEVEL
716 (void)setsockopt(sndsock, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level,
717 sizeof(level));
718 #endif
719 }
720 #endif /*IPSEC_POLICY_IPSEC*/
721 #endif /*IPSEC*/
722
723 /* Revert to non-privileged user after opening sockets */
724 setuid(getuid());
725
726 #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS)
727 if (lsrr > 0) {
728 u_char optlist[MAX_IPOPTLEN];
729
730 /* final hop */
731 gwlist[lsrr] = to->sin_addr.s_addr;
732 ++lsrr;
733
734 /* force 4 byte alignment */
735 optlist[0] = IPOPT_NOP;
736 /* loose source route option */
737 optlist[1] = IPOPT_LSRR;
738 i = lsrr * sizeof(gwlist[0]);
739 optlist[2] = i + 3;
740 /* Pointer to LSRR addresses */
741 optlist[3] = IPOPT_MINOFF;
742 memcpy(optlist + 4, gwlist, i);
743
744 if ((setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS, optlist,
745 i + sizeof(gwlist[0]))) < 0) {
746 Fprintf(stderr, "%s: IP_OPTIONS: %s\n",
747 prog, strerror(errno));
748 exit(1);
749 }
750 }
751 #endif
752
753 #ifdef SO_SNDBUF
754 if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packlen,
755 sizeof(packlen)) < 0) {
756 Fprintf(stderr, "%s: SO_SNDBUF: %s\n", prog, strerror(errno));
757 exit(1);
758 }
759 #endif
760 #ifdef IP_HDRINCL
761 if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
762 sizeof(on)) < 0) {
763 Fprintf(stderr, "%s: IP_HDRINCL: %s\n", prog, strerror(errno));
764 exit(1);
765 }
766 #else
767 #ifdef IP_TOS
768 if (settos && setsockopt(sndsock, IPPROTO_IP, IP_TOS,
769 (char *)&tos, sizeof(tos)) < 0) {
770 Fprintf(stderr, "%s: setsockopt tos %d: %s\n",
771 prog, tos, strerror(errno));
772 exit(1);
773 }
774 #endif
775 #endif
776 if (options & SO_DEBUG)
777 (void)setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on,
778 sizeof(on));
779 if (options & SO_DONTROUTE)
780 (void)setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on,
781 sizeof(on));
782
783 /* Get the interface address list */
784 n = ifaddrlist(&al, errbuf, sizeof errbuf);
785 al2 = al;
786 if (n < 0) {
787 Fprintf(stderr, "%s: ifaddrlist: %s\n", prog, errbuf);
788 exit(1);
789 }
790 if (n == 0) {
791 Fprintf(stderr,
792 "%s: Can't find any network interfaces\n", prog);
793 exit(1);
794 }
795
796 /* Look for a specific device */
797 if (device != NULL) {
798 for (i = n; i > 0; --i, ++al2)
799 if (strcmp(device, al2->device) == 0)
800 break;
801 if (i <= 0) {
802 Fprintf(stderr, "%s: Can't find interface %s\n",
803 prog, device);
804 exit(1);
805 }
806 }
807
808 /* Determine our source address */
809 if (source == NULL) {
810 /*
811 * If a device was specified, use the interface address.
812 * Otherwise, use the first interface found.
813 * Warn if there are more than one.
814 */
815 setsin(from, al2->addr);
816 if (n > 1 && device == NULL && !find_local_ip(from, to)) {
817 Fprintf(stderr,
818 "%s: Warning: Multiple interfaces found; using %s @ %s\n",
819 prog, inet_ntoa(from->sin_addr), al2->device);
820 }
821 } else {
822 hi = gethostinfo(source);
823 source = hi->name;
824 hi->name = NULL;
825 if (device == NULL) {
826 /*
827 * Use the first interface found.
828 * Warn if there are more than one.
829 */
830 setsin(from, hi->addrs[0]);
831 if (hi->n > 1)
832 Fprintf(stderr,
833 "%s: Warning: %s has multiple addresses; using %s\n",
834 prog, source, inet_ntoa(from->sin_addr));
835 } else {
836 /*
837 * Make sure the source specified matches the
838 * interface address.
839 */
840 for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap)
841 if (*ap == al2->addr)
842 break;
843 if (i <= 0) {
844 Fprintf(stderr,
845 "%s: %s is not on interface %s\n",
846 prog, source, device);
847 exit(1);
848 }
849 setsin(from, *ap);
850 }
851 freehostinfo(hi);
852 }
853
854 /*
855 * If not root, make sure source address matches a local interface.
856 * (The list of addresses produced by ifaddrlist() automatically
857 * excludes interfaces that are marked down and/or loopback.)
858 */
859 if (getuid()) {
860 al2 = al;
861 for (i = n; i > 0; --i, ++al2)
862 if (from->sin_addr.s_addr == al2->addr)
863 break;
864 if (i <= 0) {
865 Fprintf(stderr, "%s: %s is not a valid local address "
866 "and you are not superuser.\n", prog,
867 inet_ntoa(from->sin_addr));
868 exit(1);
869 }
870 }
871
872 outip->ip_src = from->sin_addr;
873 #ifndef IP_HDRINCL
874 if (bind(sndsock, (struct sockaddr *)from, sizeof(*from)) < 0) {
875 Fprintf(stderr, "%s: bind: %s\n",
876 prog, strerror(errno));
877 exit (1);
878 }
879 #endif
880
881 if (as_path) {
882 asn = as_setup(as_server);
883 if (asn == NULL) {
884 Fprintf(stderr, "%s: as_setup failed, AS# lookups disabled\n",
885 prog);
886 (void)fflush(stderr);
887 as_path = 0;
888 }
889 }
890
891 setuid(getuid());
892 Fprintf(stderr, "%s to %s (%s)",
893 prog, hostname, inet_ntoa(to->sin_addr));
894 if (source)
895 Fprintf(stderr, " from %s", source);
896 Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen);
897 (void)fflush(stderr);
898
899 for (ttl = first_ttl; ttl <= max_ttl; ++ttl) {
900 u_int32_t lastaddr = 0;
901 int got_there = 0;
902 int unreachable = 0;
903
904 again:
905 printed_ttl = 0;
906 for (probe = 0; probe < nprobes; ++probe) {
907 int cc;
908 struct timeval t1, t2;
909 struct ip *ip;
910 (void)gettimeofday(&t1, NULL);
911 send_probe(++seq, ttl, &t1);
912 while ((cc = wait_for_reply(s, from, &t1)) != 0) {
913 (void)gettimeofday(&t2, NULL);
914 /*
915 * Since we'll be receiving all ICMP
916 * messages to this host above, we may
917 * never end up with cc=0, so we need
918 * an additional termination check.
919 */
920 if (t2.tv_sec - t1.tv_sec > waittime) {
921 cc = 0;
922 break;
923 }
924 i = packet_ok(packet, cc, from, seq);
925 /* Skip short packet */
926 if (i == 0)
927 continue;
928 if (from->sin_addr.s_addr != lastaddr) {
929 print(packet, cc, from);
930 lastaddr = from->sin_addr.s_addr;
931 }
932 ip = (struct ip *)packet;
933 Printf(" %.3f ms", deltaT(&t1, &t2));
934 if (ttl_flag)
935 Printf(" (ttl = %d)", ip->ip_ttl);
936 if (i == -2) {
937 #ifndef ARCHAIC
938 if (ip->ip_ttl <= 1)
939 Printf(" !");
940 #endif
941 ++got_there;
942 break;
943 }
944
945 /* time exceeded in transit */
946 if (i == -1)
947 break;
948 code = i - 1;
949 switch (code) {
950
951 case ICMP_UNREACH_PORT:
952 #ifndef ARCHAIC
953 if (ip->ip_ttl <= 1)
954 Printf(" !");
955 #endif
956 ++got_there;
957 break;
958
959 case ICMP_UNREACH_NET:
960 ++unreachable;
961 Printf(" !N");
962 break;
963
964 case ICMP_UNREACH_HOST:
965 ++unreachable;
966 Printf(" !H");
967 break;
968
969 case ICMP_UNREACH_PROTOCOL:
970 ++got_there;
971 Printf(" !P");
972 break;
973
974 case ICMP_UNREACH_NEEDFRAG:
975 if (mtudisc) {
976 frag_err();
977 goto again;
978 } else {
979 ++unreachable;
980 Printf(" !F");
981 }
982 break;
983
984 case ICMP_UNREACH_SRCFAIL:
985 ++unreachable;
986 Printf(" !S");
987 break;
988
989 /* rfc1716 */
990 #ifndef ICMP_UNREACH_FILTER_PROHIB
991 #define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohibited filter */
992 #endif
993 case ICMP_UNREACH_FILTER_PROHIB:
994 ++unreachable;
995 Printf(" !X");
996 break;
997
998 default:
999 ++unreachable;
1000 Printf(" !<%d>", code);
1001 break;
1002 }
1003 break;
1004 }
1005 if (cc == 0)
1006 Printf(" *");
1007 (void)fflush(stdout);
1008 }
1009 putchar('\n');
1010 if (got_there ||
1011 (unreachable > 0 && unreachable >= ((nprobes + 1) / 2)))
1012 break;
1013 }
1014
1015 if (as_path)
1016 as_shutdown(asn);
1017
1018 exit(0);
1019 }
1020
1021 int
1022 wait_for_reply(int sock, struct sockaddr_in *fromp, struct timeval *tp)
1023 {
1024 fd_set *fdsp;
1025 size_t nfds;
1026 struct timeval now, wait;
1027 int cc = 0;
1028 int fromlen = sizeof(*fromp);
1029 int retval;
1030
1031 nfds = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
1032 if ((fdsp = malloc(nfds)) == NULL) {
1033 Fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno));
1034 exit(1);
1035 }
1036 memset(fdsp, 0, nfds);
1037 FD_SET(sock, fdsp);
1038
1039 wait.tv_sec = tp->tv_sec + waittime;
1040 wait.tv_usec = tp->tv_usec;
1041 (void)gettimeofday(&now, NULL);
1042 tvsub(&wait, &now);
1043
1044 if (wait.tv_sec < 0) {
1045 wait.tv_sec = 0;
1046 wait.tv_usec = 0;
1047 }
1048
1049 retval = select(sock + 1, fdsp, NULL, NULL, &wait);
1050 free(fdsp);
1051 if (retval < 0) {
1052 /* If we continue, we probably just flood the remote host. */
1053 Fprintf(stderr, "%s: select: %s\n", prog, strerror(errno));
1054 exit(1);
1055 }
1056 if (retval > 0) {
1057 cc = recvfrom(s, (char *)packet, sizeof(packet), 0,
1058 (struct sockaddr *)fromp, &fromlen);
1059 }
1060
1061 return(cc);
1062 }
1063
1064 void
1065 dump_packet()
1066 {
1067 u_char *p;
1068 int i;
1069
1070 Fprintf(stderr, "packet data:");
1071
1072 #ifdef __hpux
1073 for (p = useicmp ? (u_char *)outicmp : (u_char *)outudp, i = 0; i <
1074 i < packlen - (sizeof(*outip) + optlen); i++)
1075 #else
1076 for (p = (u_char *)outip, i = 0; i < packlen; i++)
1077 #endif
1078 {
1079 if ((i % 24) == 0)
1080 Fprintf(stderr, "\n ");
1081 Fprintf(stderr, " %02x", *p++);
1082 }
1083 Fprintf(stderr, "\n");
1084 }
1085
1086 void
1087 send_probe(int seq, int ttl, struct timeval *tp)
1088 {
1089 int cc;
1090 struct udpiphdr * ui;
1091 int oldmtu = packlen;
1092
1093 again:
1094 #ifdef BYTESWAP_IP_LEN
1095 outip->ip_len = htons(packlen);
1096 #else
1097 outip->ip_len = packlen;
1098 #endif
1099 outip->ip_ttl = ttl;
1100 #ifndef __hpux
1101 outip->ip_id = htons(ident + seq);
1102 #endif
1103
1104 /*
1105 * In most cases, the kernel will recalculate the ip checksum.
1106 * But we must do it anyway so that the udp checksum comes out
1107 * right.
1108 */
1109 if (docksum) {
1110 outip->ip_sum =
1111 in_cksum((u_int16_t *)outip, sizeof(*outip) + optlen);
1112 if (outip->ip_sum == 0)
1113 outip->ip_sum = 0xffff;
1114 }
1115
1116 /* Payload */
1117 outsetup.seq = seq;
1118 outsetup.ttl = ttl;
1119 outsetup.tv = *tp;
1120 memcpy(outmark,&outsetup,sizeof(outsetup));
1121
1122 if (useicmp)
1123 outicmp->icmp_seq = htons(seq);
1124 else
1125 outudp->uh_dport = htons(port + seq);
1126
1127 /* (We can only do the checksum if we know our ip address) */
1128 if (docksum) {
1129 if (useicmp) {
1130 outicmp->icmp_cksum = 0;
1131 outicmp->icmp_cksum = in_cksum((u_int16_t *)outicmp,
1132 packlen - (sizeof(*outip) + optlen));
1133 if (outicmp->icmp_cksum == 0)
1134 outicmp->icmp_cksum = 0xffff;
1135 } else {
1136 u_int16_t sum;
1137 struct {
1138 struct in_addr src;
1139 struct in_addr dst;
1140 u_int8_t zero;
1141 u_int8_t protocol;
1142 u_int16_t len;
1143 } __attribute__((__packed__)) phdr;
1144
1145 /* Checksum */
1146 ui = (struct udpiphdr *)outip;
1147 memset(&phdr, 0, sizeof(phdr));
1148 phdr.src = ui->ui_src;
1149 phdr.dst = ((struct sockaddr_in *)&whereto)->sin_addr;
1150 phdr.protocol = ui->ui_pr;
1151 phdr.len = outudp->uh_ulen;
1152 outudp->uh_sum = 0;
1153 sum = in_cksum2(0, (u_int16_t *)&phdr, sizeof(phdr));
1154 sum = in_cksum2(sum, (u_int16_t *)outudp, ntohs(outudp->uh_ulen));
1155 sum = ~sum; /** XXXSCW: Quell SuperH Compiler Bug */
1156 outudp->uh_sum = sum;
1157 if (outudp->uh_sum == 0)
1158 outudp->uh_sum = 0xffff;
1159 }
1160 }
1161
1162 /* XXX undocumented debugging hack */
1163 if (verbose > 1) {
1164 const u_int16_t *sp;
1165 int nshorts, i;
1166
1167 sp = (u_int16_t *)outip;
1168 nshorts = (u_int)packlen / sizeof(u_int16_t);
1169 i = 0;
1170 Printf("[ %d bytes", packlen);
1171 while (--nshorts >= 0) {
1172 if ((i++ % 8) == 0)
1173 Printf("\n\t");
1174 Printf(" %04x", ntohs(*sp++));
1175 }
1176 if (packlen & 1) {
1177 if ((i % 8) == 0)
1178 Printf("\n\t");
1179 Printf(" %02x", *(u_char *)sp);
1180 }
1181 Printf("]\n");
1182 }
1183
1184 #if !defined(IP_HDRINCL) && defined(IP_TTL)
1185 if (setsockopt(sndsock, IPPROTO_IP, IP_TTL,
1186 (char *)&ttl, sizeof(ttl)) < 0) {
1187 Fprintf(stderr, "%s: setsockopt ttl %d: %s\n",
1188 prog, ttl, strerror(errno));
1189 exit(1);
1190 }
1191 #endif
1192 if (dump)
1193 dump_packet();
1194
1195 #ifdef __hpux
1196 cc = sendto(sndsock, useicmp ? (char *)outicmp : (char *)outudp,
1197 packlen - (sizeof(*outip) + optlen), 0, &whereto, sizeof(whereto));
1198 if (cc > 0)
1199 cc += sizeof(*outip) + optlen;
1200 #else
1201 cc = sendto(sndsock, (char *)outip,
1202 packlen, 0, &whereto, sizeof(whereto));
1203 #endif
1204 if (cc < 0 || cc != packlen) {
1205 if (cc < 0) {
1206 /*
1207 * An errno of EMSGSIZE means we're writing too big a
1208 * datagram for the interface. We have to just
1209 * decrease the packet size until we find one that
1210 * works.
1211 *
1212 * XXX maybe we should try to read the outgoing if's
1213 * mtu?
1214 */
1215 if (errno == EMSGSIZE) {
1216 packlen = *mtuptr++;
1217 resize_packet();
1218 goto again;
1219 } else
1220 Fprintf(stderr, "%s: sendto: %s\n",
1221 prog, strerror(errno));
1222 }
1223
1224 Printf("%s: wrote %s %d chars, ret=%d\n",
1225 prog, hostname, packlen, cc);
1226 (void)fflush(stdout);
1227 }
1228 if (oldmtu != packlen) {
1229 Printf("message too big, "
1230 "trying new MTU = %d\n", packlen);
1231 printed_ttl = 0;
1232 }
1233 if (!printed_ttl) {
1234 Printf("%2d ", ttl);
1235 printed_ttl = 1;
1236 }
1237
1238 }
1239
1240 double
1241 deltaT(struct timeval *t1p, struct timeval *t2p)
1242 {
1243 double dt;
1244
1245 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 +
1246 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0;
1247 return (dt);
1248 }
1249
1250 /*
1251 * Convert an ICMP "type" field to a printable string.
1252 */
1253 char *
1254 pr_type(u_char t)
1255 {
1256 static char *ttab[] = {
1257 "Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable",
1258 "Source Quench", "Redirect", "ICMP 6", "ICMP 7",
1259 "Echo", "ICMP 9", "ICMP 10", "Time Exceeded",
1260 "Param Problem", "Timestamp", "Timestamp Reply", "Info Request",
1261 "Info Reply"
1262 };
1263
1264 if (t > 16)
1265 return("OUT-OF-RANGE");
1266
1267 return(ttab[t]);
1268 }
1269
1270 int
1271 packet_ok(u_char *buf, int cc, struct sockaddr_in *from, int seq)
1272 {
1273 struct icmp *icp;
1274 u_char type, code;
1275 int hlen;
1276 #ifndef ARCHAIC
1277 struct ip *ip;
1278
1279 ip = (struct ip *) buf;
1280 hlen = ip->ip_hl << 2;
1281 if (cc < hlen + ICMP_MINLEN) {
1282 if (verbose)
1283 Printf("packet too short (%d bytes) from %s\n", cc,
1284 inet_ntoa(from->sin_addr));
1285 return (0);
1286 }
1287 cc -= hlen;
1288 icp = (struct icmp *)(buf + hlen);
1289 #else
1290 icp = (struct icmp *)buf;
1291 #endif
1292 type = icp->icmp_type;
1293 code = icp->icmp_code;
1294 if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) ||
1295 type == ICMP_UNREACH || type == ICMP_ECHOREPLY) {
1296 struct ip *hip;
1297 struct udphdr *up;
1298 struct icmp *hicmp;
1299
1300 hip = &icp->icmp_ip;
1301 hlen = hip->ip_hl << 2;
1302
1303 nextmtu = ntohs(icp->icmp_nextmtu); /* for frag_err() */
1304
1305 if (useicmp) {
1306 /* XXX */
1307 if (type == ICMP_ECHOREPLY &&
1308 icp->icmp_id == htons(ident) &&
1309 icp->icmp_seq == htons(seq))
1310 return (-2);
1311
1312 hicmp = (struct icmp *)((u_char *)hip + hlen);
1313 /* XXX 8 is a magic number */
1314 if (hlen + 8 <= cc &&
1315 hip->ip_p == IPPROTO_ICMP &&
1316 hicmp->icmp_id == htons(ident) &&
1317 hicmp->icmp_seq == htons(seq))
1318 return (type == ICMP_TIMXCEED ? -1 : code + 1);
1319 } else {
1320 up = (struct udphdr *)((u_char *)hip + hlen);
1321 /* XXX 8 is a magic number */
1322 if (hlen + 12 <= cc &&
1323 hip->ip_p == IPPROTO_UDP &&
1324 up->uh_sport == htons(ident) &&
1325 up->uh_dport == htons(port + seq))
1326 return (type == ICMP_TIMXCEED ? -1 : code + 1);
1327 }
1328 }
1329 #ifndef ARCHAIC
1330 if (verbose) {
1331 int i;
1332 u_int32_t *lp = (u_int32_t *)&icp->icmp_ip;
1333
1334 Printf("\n%d bytes from %s to ", cc, inet_ntoa(from->sin_addr));
1335 Printf("%s: icmp type %d (%s) code %d\n",
1336 inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code);
1337 for (i = 4; i < cc ; i += sizeof(*lp))
1338 Printf("%2d: x%8.8x\n", i, *lp++);
1339 }
1340 #endif
1341 return(0);
1342 }
1343
1344 void resize_packet(void)
1345 {
1346 if (useicmp) {
1347 outicmp->icmp_cksum = 0;
1348 outicmp->icmp_cksum = in_cksum((u_int16_t *)outicmp,
1349 packlen - (sizeof(*outip) + optlen));
1350 if (outicmp->icmp_cksum == 0)
1351 outicmp->icmp_cksum = 0xffff;
1352 } else {
1353 outudp->uh_ulen =
1354 htons((u_int16_t)(packlen - (sizeof(*outip) + optlen)));
1355 }
1356 }
1357
1358 void
1359 print(u_char *buf, int cc, struct sockaddr_in *from)
1360 {
1361 struct ip *ip;
1362 int hlen;
1363
1364 ip = (struct ip *) buf;
1365 hlen = ip->ip_hl << 2;
1366 cc -= hlen;
1367
1368 if (as_path)
1369 Printf(" [AS%d]", as_lookup(asn, &from->sin_addr));
1370
1371 if (nflag)
1372 Printf(" %s", inet_ntoa(from->sin_addr));
1373 else
1374 Printf(" %s (%s)", inetname(from->sin_addr),
1375 inet_ntoa(from->sin_addr));
1376
1377 if (verbose)
1378 Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst));
1379 }
1380
1381 u_int16_t
1382 in_cksum(u_int16_t *addr, int len)
1383 {
1384
1385 return ~in_cksum2(0, addr, len);
1386 }
1387
1388 /*
1389 * Checksum routine for Internet Protocol family headers (C Version)
1390 */
1391 u_int16_t
1392 in_cksum2(u_int16_t seed, u_int16_t *addr, int len)
1393 {
1394 int nleft = len;
1395 u_int16_t *w = addr;
1396 union {
1397 u_int16_t w;
1398 u_int8_t b[2];
1399 } answer;
1400 int32_t sum = seed;
1401
1402 /*
1403 * Our algorithm is simple, using a 32 bit accumulator (sum),
1404 * we add sequential 16 bit words to it, and at the end, fold
1405 * back all the carry bits from the top 16 bits into the lower
1406 * 16 bits.
1407 */
1408 while (nleft > 1) {
1409 sum += *w++;
1410 nleft -= 2;
1411 }
1412
1413 /* mop up an odd byte, if necessary */
1414 if (nleft == 1) {
1415 answer.b[0] = *(u_char *)w;
1416 answer.b[1] = 0;
1417 sum += answer.w;
1418 }
1419
1420 /*
1421 * add back carry outs from top 16 bits to low 16 bits
1422 */
1423 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
1424 sum += (sum >> 16); /* add carry */
1425 answer.w = sum; /* truncate to 16 bits */
1426 return (answer.w);
1427 }
1428
1429 /*
1430 * Subtract 2 timeval structs: out = out - in.
1431 * Out is assumed to be >= in.
1432 */
1433 void
1434 tvsub(struct timeval *out, struct timeval *in)
1435 {
1436
1437 if ((out->tv_usec -= in->tv_usec) < 0) {
1438 --out->tv_sec;
1439 out->tv_usec += 1000000;
1440 }
1441 out->tv_sec -= in->tv_sec;
1442 }
1443
1444 /*
1445 * Construct an Internet address representation.
1446 * If the nflag has been supplied, give
1447 * numeric value, otherwise try for symbolic name.
1448 */
1449 char *
1450 inetname(struct in_addr in)
1451 {
1452 char *cp;
1453 struct hostent *hp;
1454 static int first = 1;
1455 static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1];
1456
1457 if (first && !nflag) {
1458 int rv;
1459
1460 first = 0;
1461 rv = gethostname(domain, sizeof domain);
1462 domain[sizeof(domain) - 1] = '\0';
1463 if (rv == 0 && (cp = strchr(domain, '.')) != NULL) {
1464 (void)strncpy(domain, cp + 1, sizeof(domain) - 1);
1465 } else
1466 domain[0] = '\0';
1467 }
1468 if (!nflag && in.s_addr != INADDR_ANY) {
1469 hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET);
1470 if (hp != NULL) {
1471 if ((cp = strchr(hp->h_name, '.')) != NULL &&
1472 strcmp(cp + 1, domain) == 0)
1473 *cp = '\0';
1474 (void)strncpy(line, hp->h_name, sizeof(line) - 1);
1475 line[sizeof(line) - 1] = '\0';
1476 return (line);
1477 }
1478 }
1479 return (inet_ntoa(in));
1480 }
1481
1482 struct hostinfo *
1483 gethostinfo(char *hostname)
1484 {
1485 int n;
1486 struct hostent *hp;
1487 struct hostinfo *hi;
1488 char **p;
1489 u_int32_t *ap;
1490 struct in_addr addr;
1491
1492 hi = calloc(1, sizeof(*hi));
1493 if (hi == NULL) {
1494 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1495 exit(1);
1496 }
1497 if (inet_aton(hostname, &addr) != 0) {
1498 hi->name = strdup(hostname);
1499 hi->n = 1;
1500 hi->addrs = calloc(1, sizeof(hi->addrs[0]));
1501 if (hi->addrs == NULL) {
1502 Fprintf(stderr, "%s: calloc %s\n",
1503 prog, strerror(errno));
1504 exit(1);
1505 }
1506 hi->addrs[0] = addr.s_addr;
1507 return (hi);
1508 }
1509
1510 hp = gethostbyname(hostname);
1511 if (hp == NULL) {
1512 Fprintf(stderr, "%s: unknown host %s\n", prog, hostname);
1513 exit(1);
1514 }
1515 if (hp->h_addrtype != AF_INET || hp->h_length != 4) {
1516 Fprintf(stderr, "%s: bad host %s\n", prog, hostname);
1517 exit(1);
1518 }
1519 hi->name = strdup(hp->h_name);
1520 for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p)
1521 continue;
1522 hi->n = n;
1523 hi->addrs = calloc(n, sizeof(hi->addrs[0]));
1524 if (hi->addrs == NULL) {
1525 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno));
1526 exit(1);
1527 }
1528 for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p)
1529 memcpy(ap, *p, sizeof(*ap));
1530 return (hi);
1531 }
1532
1533 void
1534 freehostinfo(struct hostinfo *hi)
1535 {
1536 if (hi->name != NULL) {
1537 free(hi->name);
1538 hi->name = NULL;
1539 }
1540 free((char *)hi->addrs);
1541 free((char *)hi);
1542 }
1543
1544 void
1545 getaddr(u_int32_t *ap, char *hostname)
1546 {
1547 struct hostinfo *hi;
1548
1549 hi = gethostinfo(hostname);
1550 *ap = hi->addrs[0];
1551 freehostinfo(hi);
1552 }
1553
1554 void
1555 setsin(struct sockaddr_in *sin, u_int32_t addr)
1556 {
1557
1558 memset(sin, 0, sizeof(*sin));
1559 #ifdef HAVE_SOCKADDR_SA_LEN
1560 sin->sin_len = sizeof(*sin);
1561 #endif
1562 sin->sin_family = AF_INET;
1563 sin->sin_addr.s_addr = addr;
1564 }
1565
1566 /* String to value with optional min and max. Handles decimal and hex. */
1567 int
1568 str2val(const char *str, const char *what, int mi, int ma)
1569 {
1570 const char *cp;
1571 int val;
1572 char *ep;
1573
1574 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {
1575 cp = str + 2;
1576 val = (int)strtol(cp, &ep, 16);
1577 } else
1578 val = (int)strtol(str, &ep, 10);
1579 if (*ep != '\0') {
1580 Fprintf(stderr, "%s: \"%s\" bad value for %s \n",
1581 prog, str, what);
1582 exit(1);
1583 }
1584 if (val < mi && mi >= 0) {
1585 if (mi == 0)
1586 Fprintf(stderr, "%s: %s must be >= %d\n",
1587 prog, what, mi);
1588 else
1589 Fprintf(stderr, "%s: %s must be > %d\n",
1590 prog, what, mi - 1);
1591 exit(1);
1592 }
1593 if (val > ma && ma >= 0) {
1594 Fprintf(stderr, "%s: %s must be <= %d\n", prog, what, ma);
1595 exit(1);
1596 }
1597 return (val);
1598 }
1599
1600 __dead void
1601 usage(void)
1602 {
1603 extern char version[];
1604
1605 Fprintf(stderr, "Version %s\n", version);
1606 Fprintf(stderr, "Usage: %s [-adDFPIlnrvx] [-g gateway] [-i iface] \
1607 [-f first_ttl]\n\t[-m max_ttl] [-p port] [-q nqueries] [-s src_addr] [-t tos]\n\t\
1608 [-w waittime] [-A as_server] host [packetlen]\n",
1609 prog);
1610 exit(1);
1611 }
1612
1613 /*
1614 * Received ICMP unreachable (fragmentation required and DF set).
1615 * If the ICMP error was from a "new" router, it'll contain the next-hop
1616 * MTU that we should use next. Otherwise we'll just keep going in the
1617 * mtus[] table, trying until we hit a valid MTU.
1618 */
1619
1620
1621 void
1622 frag_err()
1623 {
1624 int i;
1625
1626 if (nextmtu > 0 && nextmtu < packlen) {
1627 Printf("\nfragmentation required and DF set, "
1628 "next hop MTU = %d\n",
1629 nextmtu);
1630 packlen = nextmtu;
1631 for (i = 0; mtus[i] > 0; i++) {
1632 if (mtus[i] < nextmtu) {
1633 mtuptr = &mtus[i]; /* next one to try */
1634 break;
1635 }
1636 }
1637 } else {
1638 Printf("\nfragmentation required and DF set. ");
1639 if (nextmtu)
1640 Printf("\nBogus next hop MTU = %d > last MTU = %d. ",
1641 nextmtu, packlen);
1642 packlen = *mtuptr++;
1643 Printf("Trying new MTU = %d\n", packlen);
1644 }
1645 resize_packet();
1646 }
1647
1648 int
1649 find_local_ip(struct sockaddr_in *from, struct sockaddr_in *to)
1650 {
1651 int sock;
1652 struct sockaddr_in help;
1653 int help_len;
1654
1655 sock = socket(AF_INET, SOCK_DGRAM, 0);
1656 if (sock < 0) return (0);
1657
1658 help.sin_family = AF_INET;
1659 /*
1660 * At this point the port number doesn't matter
1661 * since it only has to be greater than zero.
1662 */
1663 help.sin_port = 42;
1664 help.sin_addr.s_addr = to->sin_addr.s_addr;
1665 if (connect(sock, (struct sockaddr *)&help, sizeof(help)) < 0) {
1666 (void)close(sock);
1667 return (0);
1668 }
1669
1670 help_len = sizeof(help);
1671 if (getsockname(sock, (struct sockaddr *)&help, &help_len) < 0 ||
1672 help_len != sizeof(help) ||
1673 help.sin_addr.s_addr == INADDR_ANY) {
1674 (void)close(sock);
1675 return (0);
1676 }
1677
1678 (void)close(sock);
1679 setsin(from, help.sin_addr.s_addr);
1680 return (1);
1681 }
1682
1683 #ifdef IPSEC
1684 #ifdef IPSEC_POLICY_IPSEC
1685 int
1686 setpolicy(so, policy)
1687 int so;
1688 char *policy;
1689 {
1690 char *buf;
1691
1692 buf = ipsec_set_policy(policy, strlen(policy));
1693 if (buf == NULL) {
1694 Fprintf(stderr, "%s: %s\n", prog, ipsec_strerror());
1695 return -1;
1696 }
1697 (void)setsockopt(so, IPPROTO_IP, IP_IPSEC_POLICY,
1698 buf, ipsec_get_policylen(buf));
1699
1700 free(buf);
1701
1702 return 0;
1703 }
1704 #endif
1705 #endif
1706
1707