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