1 /* $NetBSD: traceroute.c,v 1.61 2004/04/22 01:41:22 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.61 2004/04/22 01:41:22 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@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 = htons(arc4random() & 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