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