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