1 /* $NetBSD: traceroute.c,v 1.65 2006/05/31 20:23:52 rpaulo 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.65 2006/05/31 20:23:52 rpaulo Exp $"); 33 #endif 34 #endif 35 36 /* 37 * traceroute host - trace the route ip packets follow going to "host". 38 * 39 * Attempt to trace the route an ip packet would follow to some 40 * internet host. We find out intermediate hops by launching probe 41 * packets with a small ttl (time to live) then listening for an 42 * icmp "time exceeded" reply from a gateway. We start our probes 43 * with a ttl of one and increase by one until we get an icmp "port 44 * unreachable" (which means we got to "host") or hit a max (which 45 * defaults to 30 hops & can be changed with the -m flag). Three 46 * probes (change with -q flag) are sent at each ttl setting and a 47 * line is printed showing the ttl, address of the gateway and 48 * round trip time of each probe. If the probe answers come from 49 * different gateways, the address of each responding system will 50 * be printed. If there is no response within a 5 sec. timeout 51 * interval (changed with the -w flag), a "*" is printed for that 52 * probe. 53 * 54 * Probe packets are UDP format. We don't want the destination 55 * host to process them so the destination port is set to an 56 * unlikely value (if some clod on the destination is using that 57 * value, it can be changed with the -p flag). 58 * 59 * A sample use might be: 60 * 61 * [yak 71]% traceroute nis.nsf.net. 62 * traceroute to nis.nsf.net (35.1.1.48), 30 hops max, 56 byte packet 63 * 1 helios.ee.lbl.gov (128.3.112.1) 19 ms 19 ms 0 ms 64 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms 65 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 39 ms 19 ms 66 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 39 ms 67 * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 39 ms 39 ms 39 ms 68 * 6 128.32.197.4 (128.32.197.4) 40 ms 59 ms 59 ms 69 * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 59 ms 70 * 8 129.140.70.13 (129.140.70.13) 99 ms 99 ms 80 ms 71 * 9 129.140.71.6 (129.140.71.6) 139 ms 239 ms 319 ms 72 * 10 129.140.81.7 (129.140.81.7) 220 ms 199 ms 199 ms 73 * 11 nic.merit.edu (35.1.1.48) 239 ms 239 ms 239 ms 74 * 75 * Note that lines 2 & 3 are the same. This is due to a buggy 76 * kernel on the 2nd hop system -- lbl-csam.arpa -- that forwards 77 * packets with a zero ttl. 78 * 79 * A more interesting example is: 80 * 81 * [yak 72]% traceroute allspice.lcs.mit.edu. 82 * traceroute to allspice.lcs.mit.edu (18.26.0.115), 30 hops max 83 * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms 84 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 19 ms 19 ms 85 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 19 ms 86 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 19 ms 39 ms 39 ms 87 * 5 ccn-nerif22.Berkeley.EDU (128.32.168.22) 20 ms 39 ms 39 ms 88 * 6 128.32.197.4 (128.32.197.4) 59 ms 119 ms 39 ms 89 * 7 131.119.2.5 (131.119.2.5) 59 ms 59 ms 39 ms 90 * 8 129.140.70.13 (129.140.70.13) 80 ms 79 ms 99 ms 91 * 9 129.140.71.6 (129.140.71.6) 139 ms 139 ms 159 ms 92 * 10 129.140.81.7 (129.140.81.7) 199 ms 180 ms 300 ms 93 * 11 129.140.72.17 (129.140.72.17) 300 ms 239 ms 239 ms 94 * 12 * * * 95 * 13 128.121.54.72 (128.121.54.72) 259 ms 499 ms 279 ms 96 * 14 * * * 97 * 15 * * * 98 * 16 * * * 99 * 17 * * * 100 * 18 ALLSPICE.LCS.MIT.EDU (18.26.0.115) 339 ms 279 ms 279 ms 101 * 102 * (I start to see why I'm having so much trouble with mail to 103 * MIT.) Note that the gateways 12, 14, 15, 16 & 17 hops away 104 * either don't send ICMP "time exceeded" messages or send them 105 * with a ttl too small to reach us. 14 - 17 are running the 106 * MIT C Gateway code that doesn't send "time exceeded"s. God 107 * only knows what's going on with 12. 108 * 109 * The silent gateway 12 in the above may be the result of a bug in 110 * the 4.[23]BSD network code (and its derivatives): 4.x (x <= 3) 111 * sends an unreachable message using whatever ttl remains in the 112 * original datagram. Since, for gateways, the remaining ttl is 113 * zero, the icmp "time exceeded" is guaranteed to not make it back 114 * to us. The behavior of this bug is slightly more interesting 115 * when it appears on the destination system: 116 * 117 * 1 helios.ee.lbl.gov (128.3.112.1) 0 ms 0 ms 0 ms 118 * 2 lilac-dmc.Berkeley.EDU (128.32.216.1) 39 ms 19 ms 39 ms 119 * 3 lilac-dmc.Berkeley.EDU (128.32.216.1) 19 ms 39 ms 19 ms 120 * 4 ccngw-ner-cc.Berkeley.EDU (128.32.136.23) 39 ms 40 ms 19 ms 121 * 5 ccn-nerif35.Berkeley.EDU (128.32.168.35) 39 ms 39 ms 39 ms 122 * 6 csgw.Berkeley.EDU (128.32.133.254) 39 ms 59 ms 39 ms 123 * 7 * * * 124 * 8 * * * 125 * 9 * * * 126 * 10 * * * 127 * 11 * * * 128 * 12 * * * 129 * 13 rip.Berkeley.EDU (128.32.131.22) 59 ms ! 39 ms ! 39 ms ! 130 * 131 * Notice that there are 12 "gateways" (13 is the final 132 * destination) and exactly the last half of them are "missing". 133 * What's really happening is that rip (a Sun-3 running Sun OS3.5) 134 * is using the ttl from our arriving datagram as the ttl in its 135 * icmp reply. So, the reply will time out on the return path 136 * (with no notice sent to anyone since icmp's aren't sent for 137 * icmp's) until we probe with a ttl that's at least twice the path 138 * length. I.e., rip is really only 7 hops away. A reply that 139 * returns with a ttl of 1 is a clue this problem exists. 140 * Traceroute prints a "!" after the time if the ttl is <= 1. 141 * Since vendors ship a lot of obsolete (DEC's Ultrix, Sun 3.x) or 142 * non-standard (HPUX) software, expect to see this problem 143 * frequently and/or take care picking the target host of your 144 * probes. 145 * 146 * Other possible annotations after the time are !H, !N, !P (got a host, 147 * network or protocol unreachable, respectively), !S or !F (source 148 * route failed or fragmentation needed -- neither of these should 149 * ever occur and the associated gateway is busted if you see one). If 150 * almost all the probes result in some kind of unreachable, traceroute 151 * will give up and exit. 152 * 153 * Notes 154 * ----- 155 * This program must be run by root or be setuid. (I suggest that 156 * you *don't* make it setuid -- casual use could result in a lot 157 * of unnecessary traffic on our poor, congested nets.) 158 * 159 * This program requires a kernel mod that does not appear in any 160 * system available from Berkeley: A raw ip socket using proto 161 * IPPROTO_RAW must interpret the data sent as an ip datagram (as 162 * opposed to data to be wrapped in a ip datagram). See the README 163 * file that came with the source to this program for a description 164 * of the mods I made to /sys/netinet/raw_ip.c. Your mileage may 165 * vary. But, again, ANY 4.x (x < 4) BSD KERNEL WILL HAVE TO BE 166 * MODIFIED TO RUN THIS PROGRAM. 167 * 168 * The udp port usage may appear bizarre (well, ok, it is bizarre). 169 * The problem is that an icmp message only contains 8 bytes of 170 * data from the original datagram. 8 bytes is the size of a udp 171 * header so, if we want to associate replies with the original 172 * datagram, the necessary information must be encoded into the 173 * udp header (the ip id could be used but there's no way to 174 * interlock with the kernel's assignment of ip id's and, anyway, 175 * it would have taken a lot more kernel hacking to allow this 176 * code to set the ip id). So, to allow two or more users to 177 * use traceroute simultaneously, we use this task's pid as the 178 * source port (the high bit is set to move the port number out 179 * of the "likely" range). To keep track of which probe is being 180 * replied to (so times and/or hop counts don't get confused by a 181 * reply that was delayed in transit), we increment the destination 182 * port number before each probe. 183 * 184 * Don't use this as a coding example. I was trying to find a 185 * routing problem and this code sort-of popped out after 48 hours 186 * without sleep. I was amazed it ever compiled, much less ran. 187 * 188 * I stole the idea for this program from Steve Deering. Since 189 * the first release, I've learned that had I attended the right 190 * IETF working group meetings, I also could have stolen it from Guy 191 * Almes or Matt Mathis. I don't know (or care) who came up with 192 * the idea first. I envy the originators' perspicacity and I'm 193 * glad they didn't keep the idea a secret. 194 * 195 * Tim Seaver, Ken Adelman and C. Philip Wood provided bug fixes and/or 196 * enhancements to the original distribution. 197 * 198 * I've hacked up a round-trip-route version of this that works by 199 * sending a loose-source-routed udp datagram through the destination 200 * back to yourself. Unfortunately, SO many gateways botch source 201 * routing, the thing is almost worthless. Maybe one day... 202 * 203 * -- Van Jacobson (van@ee.lbl.gov) 204 * Tue Dec 20 03:50:13 PST 1988 205 */ 206 207 #include <sys/param.h> 208 #include <sys/file.h> 209 #include <sys/ioctl.h> 210 #include <sys/socket.h> 211 #include <sys/time.h> 212 #include <sys/sysctl.h> 213 214 #include <netinet/in_systm.h> 215 #include <netinet/in.h> 216 #include <netinet/ip.h> 217 #include <netinet/ip_var.h> 218 #include <netinet/ip_icmp.h> 219 #include <netinet/udp.h> 220 #include <netinet/udp_var.h> 221 222 #include <arpa/inet.h> 223 224 #include <ctype.h> 225 #include <errno.h> 226 #ifdef HAVE_MALLOC_H 227 #include <malloc.h> 228 #endif 229 #include <memory.h> 230 #include <netdb.h> 231 #include <stdio.h> 232 #include <stdlib.h> 233 #include <string.h> 234 #include <unistd.h> 235 #include <poll.h> 236 #ifdef IPSEC 237 #include <net/route.h> 238 #include <netinet6/ipsec.h> 239 #endif 240 241 #include "gnuc.h" 242 #ifdef HAVE_OS_PROTO_H 243 #include "os-proto.h" 244 #endif 245 246 #include "ifaddrlist.h" 247 #include "as.h" 248 249 /* Maximum number of gateways (include room for one noop) */ 250 #define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(u_int32_t))) 251 252 #ifndef MAXHOSTNAMELEN 253 #define MAXHOSTNAMELEN 64 254 #endif 255 256 #define Fprintf (void)fprintf 257 #define Printf (void)printf 258 259 /* Host name and address list */ 260 struct hostinfo { 261 char *name; 262 int n; 263 u_int32_t *addrs; 264 }; 265 266 /* Data section of the probe packet */ 267 struct outdata { 268 u_char seq; /* sequence number of this packet */ 269 u_char ttl; /* ttl packet left with */ 270 struct timeval tv; /* time packet left */ 271 }; 272 273 /* 274 * Support for ICMP extensions 275 * 276 * http://www.ietf.org/proceedings/01aug/I-D/draft-ietf-mpls-icmp-02.txt 277 */ 278 #define ICMP_EXT_OFFSET 8 /* ICMP type, code, checksum, unused */ + \ 279 128 /* original datagram */ 280 #define ICMP_EXT_VERSION 2 281 /* 282 * ICMP extensions, common header 283 */ 284 struct icmp_ext_cmn_hdr { 285 #if BYTE_ORDER == BIG_ENDIAN 286 unsigned char version:4; 287 unsigned char reserved1:4; 288 #else 289 unsigned char reserved1:4; 290 unsigned char version:4; 291 #endif 292 unsigned char reserved2; 293 unsigned short checksum; 294 }; 295 296 /* 297 * ICMP extensions, object header 298 */ 299 struct icmp_ext_obj_hdr { 300 u_short length; 301 u_char class_num; 302 #define MPLS_STACK_ENTRY_CLASS 1 303 u_char c_type; 304 #define MPLS_STACK_ENTRY_C_TYPE 1 305 }; 306 307 struct mpls_header { 308 #if BYTE_ORDER == BIG_ENDIAN 309 uint32_t label:20; 310 unsigned char exp:3; 311 unsigned char s:1; 312 unsigned char ttl:8; 313 #else 314 unsigned char ttl:8; 315 unsigned char s:1; 316 unsigned char exp:3; 317 uint32_t label:20; 318 #endif 319 }; 320 321 u_char packet[512]; /* last inbound (icmp) packet */ 322 323 struct ip *outip; /* last output (udp) packet */ 324 struct udphdr *outudp; /* last output (udp) packet */ 325 void *outmark; /* packed location of struct outdata */ 326 struct outdata outsetup; /* setup and copy for alignment */ 327 328 struct icmp *outicmp; /* last output (icmp) packet */ 329 330 /* loose source route gateway list (including room for final destination) */ 331 u_int32_t gwlist[NGATEWAYS + 1]; 332 333 int s; /* receive (icmp) socket file descriptor */ 334 int sndsock; /* send (udp/icmp) socket file descriptor */ 335 336 struct sockaddr whereto; /* Who to try to reach */ 337 struct sockaddr_in wherefrom; /* Who we are */ 338 int packlen; /* total length of packet */ 339 int minpacket; /* min ip packet size */ 340 int maxpacket = 32 * 1024; /* max ip packet size */ 341 int printed_ttl = 0; 342 343 char *prog; 344 char *source; 345 char *hostname; 346 char *device; 347 348 int nprobes = 3; 349 int max_ttl = 30; 350 int first_ttl = 1; 351 u_int16_t ident; 352 in_port_t port = 32768 + 666; /* start udp dest port # for probe packets */ 353 354 int options; /* socket options */ 355 int verbose; 356 int waittime = 5; /* time to wait for response (in seconds) */ 357 int nflag; /* print addresses numerically */ 358 int dump; 359 int Mflag; /* show MPLS labels if any */ 360 int as_path; /* print as numbers for each hop */ 361 char *as_server = NULL; 362 void *asn; 363 int useicmp; /* use icmp echo instead of udp packets */ 364 #ifdef CANT_HACK_CKSUM 365 int docksum = 0; /* don't calculate checksums */ 366 #else 367 int docksum = 1; /* calculate checksums */ 368 #endif 369 int optlen; /* length of ip options */ 370 371 int mtus[] = { 372 17914, 373 8166, 374 4464, 375 4352, 376 2048, 377 2002, 378 1536, 379 1500, 380 1492, 381 1480, 382 1280, 383 1006, 384 576, 385 552, 386 544, 387 512, 388 508, 389 296, 390 68, 391 0 392 }; 393 int *mtuptr = &mtus[0]; 394 int mtudisc = 0; 395 int nextmtu; /* from ICMP error, set by packet_ok(), might be 0 */ 396 397 extern int optind; 398 extern int opterr; 399 extern char *optarg; 400 401 /* Forwards */ 402 double deltaT(struct timeval *, struct timeval *); 403 void freehostinfo(struct hostinfo *); 404 void getaddr(u_int32_t *, char *); 405 struct hostinfo *gethostinfo(char *); 406 u_int16_t in_cksum(u_int16_t *, int); 407 u_int16_t in_cksum2(u_int16_t, u_int16_t *, int); 408 char *inetname(struct in_addr); 409 int main(int, char **); 410 int packet_ok(u_char *, int, struct sockaddr_in *, int); 411 char *pr_type(u_char); 412 void print(u_char *, int, struct sockaddr_in *); 413 void resize_packet(void); 414 void dump_packet(void); 415 void send_probe(int, int, struct timeval *); 416 void setsin(struct sockaddr_in *, u_int32_t); 417 int str2val(const char *, const char *, int, int); 418 void tvsub(struct timeval *, struct timeval *); 419 __dead void usage(void); 420 int wait_for_reply(int, struct sockaddr_in *, struct timeval *); 421 void decode_extensions(unsigned char *buf, int ip_len); 422 void frag_err(void); 423 int find_local_ip(struct sockaddr_in *, struct sockaddr_in *); 424 #ifdef IPSEC 425 #ifdef IPSEC_POLICY_IPSEC 426 int setpolicy(int so, char *policy); 427 #endif 428 #endif 429 430 int 431 main(int argc, char **argv) 432 { 433 int op, code, n; 434 char *cp; 435 u_char *outp; 436 u_int32_t *ap; 437 struct sockaddr_in *from = &wherefrom; 438 struct sockaddr_in *to = (struct sockaddr_in *)&whereto; 439 struct hostinfo *hi; 440 int on = 1; 441 int ttl, probe, i; 442 int seq = 0; 443 int tos = 0, settos = 0, ttl_flag = 0; 444 int lsrr = 0; 445 u_int16_t off = 0; 446 struct ifaddrlist *al, *al2; 447 char errbuf[132]; 448 int mib[4] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_DEFTTL }; 449 size_t size = sizeof(max_ttl); 450 451 (void) sysctl(mib, sizeof(mib)/sizeof(mib[0]), &max_ttl, &size, 452 NULL, 0); 453 454 if ((cp = strrchr(argv[0], '/')) != NULL) 455 prog = cp + 1; 456 else 457 prog = argv[0]; 458 459 opterr = 0; 460 while ((op = getopt(argc, argv, "aA:dDFPIMnlrvxf:g:i:m:p:q:s:t:w:")) != -1) 461 switch (op) { 462 463 case 'a': 464 as_path = 1; 465 break; 466 467 case 'A': 468 as_path = 1; 469 as_server = optarg; 470 break; 471 472 case 'd': 473 options |= SO_DEBUG; 474 break; 475 476 case 'D': 477 dump = 1; 478 break; 479 480 case 'f': 481 first_ttl = str2val(optarg, "first ttl", 1, 255); 482 break; 483 484 case 'F': 485 off = IP_DF; 486 break; 487 488 case 'g': 489 if (lsrr >= NGATEWAYS) { 490 Fprintf(stderr, 491 "%s: No more than %d gateways\n", 492 prog, NGATEWAYS); 493 exit(1); 494 } 495 getaddr(gwlist + lsrr, optarg); 496 ++lsrr; 497 break; 498 499 case 'i': 500 device = optarg; 501 break; 502 503 case 'I': 504 ++useicmp; 505 break; 506 507 case 'l': 508 ++ttl_flag; 509 break; 510 511 case 'm': 512 max_ttl = str2val(optarg, "max ttl", 1, 255); 513 break; 514 515 case 'M': 516 Mflag = 1; 517 break; 518 519 case 'n': 520 ++nflag; 521 break; 522 523 case 'p': 524 port = str2val(optarg, "port", 1, -1); 525 break; 526 527 case 'q': 528 nprobes = str2val(optarg, "nprobes", 1, -1); 529 break; 530 531 case 'r': 532 options |= SO_DONTROUTE; 533 break; 534 535 case 's': 536 /* 537 * set the ip source address of the outbound 538 * probe (e.g., on a multi-homed host). 539 */ 540 source = optarg; 541 break; 542 543 case 't': 544 tos = str2val(optarg, "tos", 0, 255); 545 ++settos; 546 break; 547 548 case 'v': 549 ++verbose; 550 break; 551 552 case 'x': 553 docksum = (docksum == 0); 554 break; 555 556 case 'w': 557 waittime = str2val(optarg, "wait time", 2, 24 * 3600); 558 break; 559 560 case 'P': 561 off = IP_DF; 562 mtudisc = 1; 563 break; 564 565 default: 566 usage(); 567 } 568 569 if (first_ttl > max_ttl) { 570 Fprintf(stderr, 571 "%s: first ttl (%d) may not be greater than max ttl (%d)\n", 572 prog, first_ttl, max_ttl); 573 exit(1); 574 } 575 576 if (!docksum) 577 Fprintf(stderr, "%s: Warning: ckecksums disabled\n", prog); 578 579 if (lsrr > 0) 580 optlen = (lsrr + 1) * sizeof(gwlist[0]); 581 minpacket = sizeof(*outip) + sizeof(struct outdata) + optlen; 582 if (useicmp) 583 minpacket += 8; /* XXX magic number */ 584 else 585 minpacket += sizeof(*outudp); 586 if (packlen == 0) 587 packlen = minpacket; /* minimum sized packet */ 588 else if (minpacket > packlen || packlen > maxpacket) { 589 Fprintf(stderr, "%s: packet size must be %d <= s <= %d\n", 590 prog, minpacket, maxpacket); 591 exit(1); 592 } 593 594 if (mtudisc) 595 packlen = *mtuptr++; 596 597 /* Process destination and optional packet size */ 598 switch (argc - optind) { 599 600 case 2: 601 packlen = str2val(argv[optind + 1], 602 "packet length", minpacket, -1); 603 /* Fall through */ 604 605 case 1: 606 hostname = argv[optind]; 607 hi = gethostinfo(hostname); 608 setsin(to, hi->addrs[0]); 609 if (hi->n > 1) 610 Fprintf(stderr, 611 "%s: Warning: %s has multiple addresses; using %s\n", 612 prog, hostname, inet_ntoa(to->sin_addr)); 613 hostname = hi->name; 614 hi->name = NULL; 615 freehostinfo(hi); 616 break; 617 618 default: 619 usage(); 620 } 621 622 #ifdef HAVE_SETLINEBUF 623 setlinebuf (stdout); 624 #else 625 setvbuf(stdout, NULL, _IOLBF, 0); 626 #endif 627 628 outip = (struct ip *)malloc((unsigned)packlen); 629 if (outip == NULL) { 630 Fprintf(stderr, "%s: malloc: %s\n", prog, strerror(errno)); 631 exit(1); 632 } 633 memset((char *)outip, 0, packlen); 634 635 outip->ip_v = IPVERSION; 636 if (settos) 637 outip->ip_tos = tos; 638 #ifdef BYTESWAP_IP_LEN 639 outip->ip_len = htons(packlen); 640 #else 641 outip->ip_len = packlen; 642 #endif 643 outip->ip_off = off; 644 outp = (u_char *)(outip + 1); 645 #ifdef HAVE_RAW_OPTIONS 646 if (lsrr > 0) { 647 u_char *optlist; 648 649 optlist = outp; 650 outp += optlen; 651 652 /* final hop */ 653 gwlist[lsrr] = to->sin_addr.s_addr; 654 655 outip->ip_dst.s_addr = gwlist[0]; 656 657 /* force 4 byte alignment */ 658 optlist[0] = IPOPT_NOP; 659 /* loose source route option */ 660 optlist[1] = IPOPT_LSRR; 661 i = lsrr * sizeof(gwlist[0]); 662 optlist[2] = i + 3; 663 /* Pointer to LSRR addresses */ 664 optlist[3] = IPOPT_MINOFF; 665 memcpy(optlist + 4, gwlist + 1, i); 666 } else 667 #endif 668 outip->ip_dst = to->sin_addr; 669 670 outip->ip_hl = (outp - (u_char *)outip) >> 2; 671 ident = htons(arc4random() & 0xffff) | 0x8000; 672 if (useicmp) { 673 outip->ip_p = IPPROTO_ICMP; 674 675 outicmp = (struct icmp *)outp; 676 outicmp->icmp_type = ICMP_ECHO; 677 outicmp->icmp_id = htons(ident); 678 679 outmark = outp + 8; /* XXX magic number */ 680 } else { 681 outip->ip_p = IPPROTO_UDP; 682 683 outudp = (struct udphdr *)outp; 684 outudp->uh_sport = htons(ident); 685 outudp->uh_ulen = 686 htons((u_int16_t)(packlen - (sizeof(*outip) + optlen))); 687 outmark = outudp + 1; 688 } 689 690 if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) { 691 Fprintf(stderr, "%s: icmp socket: %s\n", prog, strerror(errno)); 692 exit(1); 693 } 694 if (options & SO_DEBUG) 695 (void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&on, 696 sizeof(on)); 697 #ifdef IPSEC 698 #ifdef IPSEC_POLICY_IPSEC 699 /* 700 * do not raise error even if setsockopt fails, kernel may have ipsec 701 * turned off. 702 */ 703 if (setpolicy(s, "in bypass") < 0) 704 exit(1); 705 if (setpolicy(s, "out bypass") < 0) 706 exit(1); 707 #else 708 { 709 int level = IPSEC_LEVEL_AVAIL; 710 711 (void)setsockopt(s, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level, 712 sizeof(level)); 713 (void)setsockopt(s, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level, 714 sizeof(level)); 715 #ifdef IP_AUTH_TRANS_LEVEL 716 (void)setsockopt(s, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level, 717 sizeof(level)); 718 #else 719 (void)setsockopt(s, IPPROTO_IP, IP_AUTH_LEVEL, &level, 720 sizeof(level)); 721 #endif 722 #ifdef IP_AUTH_NETWORK_LEVEL 723 (void)setsockopt(s, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level, 724 sizeof(level)); 725 #endif 726 } 727 #endif /*IPSEC_POLICY_IPSEC*/ 728 #endif /*IPSEC*/ 729 730 #ifndef __hpux 731 sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); 732 #else 733 sndsock = socket(AF_INET, SOCK_RAW, 734 useicmp ? IPPROTO_ICMP : IPPROTO_UDP); 735 #endif 736 if (sndsock < 0) { 737 Fprintf(stderr, "%s: raw socket: %s\n", prog, strerror(errno)); 738 exit(1); 739 } 740 741 #ifdef IPSEC 742 #ifdef IPSEC_POLICY_IPSEC 743 /* 744 * do not raise error even if setsockopt fails, kernel may have ipsec 745 * turned off. 746 */ 747 if (setpolicy(sndsock, "in bypass") < 0) 748 exit(1); 749 if (setpolicy(sndsock, "out bypass") < 0) 750 exit(1); 751 #else 752 { 753 int level = IPSEC_LEVEL_BYPASS; 754 755 (void)setsockopt(sndsock, IPPROTO_IP, IP_ESP_TRANS_LEVEL, &level, 756 sizeof(level)); 757 (void)setsockopt(sndsock, IPPROTO_IP, IP_ESP_NETWORK_LEVEL, &level, 758 sizeof(level)); 759 #ifdef IP_AUTH_TRANS_LEVEL 760 (void)setsockopt(sndsock, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, &level, 761 sizeof(level)); 762 #else 763 (void)setsockopt(sndsock, IPPROTO_IP, IP_AUTH_LEVEL, &level, 764 sizeof(level)); 765 #endif 766 #ifdef IP_AUTH_NETWORK_LEVEL 767 (void)setsockopt(sndsock, IPPROTO_IP, IP_AUTH_NETWORK_LEVEL, &level, 768 sizeof(level)); 769 #endif 770 } 771 #endif /*IPSEC_POLICY_IPSEC*/ 772 #endif /*IPSEC*/ 773 774 /* Revert to non-privileged user after opening sockets */ 775 setuid(getuid()); 776 777 #if defined(IP_OPTIONS) && !defined(HAVE_RAW_OPTIONS) 778 if (lsrr > 0) { 779 u_char optlist[MAX_IPOPTLEN]; 780 781 /* final hop */ 782 gwlist[lsrr] = to->sin_addr.s_addr; 783 ++lsrr; 784 785 /* force 4 byte alignment */ 786 optlist[0] = IPOPT_NOP; 787 /* loose source route option */ 788 optlist[1] = IPOPT_LSRR; 789 i = lsrr * sizeof(gwlist[0]); 790 optlist[2] = i + 3; 791 /* Pointer to LSRR addresses */ 792 optlist[3] = IPOPT_MINOFF; 793 memcpy(optlist + 4, gwlist, i); 794 795 if ((setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS, optlist, 796 i + sizeof(gwlist[0]))) < 0) { 797 Fprintf(stderr, "%s: IP_OPTIONS: %s\n", 798 prog, strerror(errno)); 799 exit(1); 800 } 801 } 802 #endif 803 804 #ifdef SO_SNDBUF 805 if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&packlen, 806 sizeof(packlen)) < 0) { 807 Fprintf(stderr, "%s: SO_SNDBUF: %s\n", prog, strerror(errno)); 808 exit(1); 809 } 810 #endif 811 #ifdef IP_HDRINCL 812 if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on, 813 sizeof(on)) < 0) { 814 Fprintf(stderr, "%s: IP_HDRINCL: %s\n", prog, strerror(errno)); 815 exit(1); 816 } 817 #else 818 #ifdef IP_TOS 819 if (settos && setsockopt(sndsock, IPPROTO_IP, IP_TOS, 820 (char *)&tos, sizeof(tos)) < 0) { 821 Fprintf(stderr, "%s: setsockopt tos %d: %s\n", 822 prog, tos, strerror(errno)); 823 exit(1); 824 } 825 #endif 826 #endif 827 if (options & SO_DEBUG) 828 (void)setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, (char *)&on, 829 sizeof(on)); 830 if (options & SO_DONTROUTE) 831 (void)setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, (char *)&on, 832 sizeof(on)); 833 834 /* Get the interface address list */ 835 n = ifaddrlist(&al, errbuf, sizeof errbuf); 836 al2 = al; 837 if (n < 0) { 838 Fprintf(stderr, "%s: ifaddrlist: %s\n", prog, errbuf); 839 exit(1); 840 } 841 if (n == 0) { 842 Fprintf(stderr, 843 "%s: Can't find any network interfaces\n", prog); 844 exit(1); 845 } 846 847 /* Look for a specific device */ 848 if (device != NULL) { 849 for (i = n; i > 0; --i, ++al2) 850 if (strcmp(device, al2->device) == 0) 851 break; 852 if (i <= 0) { 853 Fprintf(stderr, "%s: Can't find interface %s\n", 854 prog, device); 855 exit(1); 856 } 857 } 858 859 /* Determine our source address */ 860 if (source == NULL) { 861 /* 862 * If a device was specified, use the interface address. 863 * Otherwise, use the first interface found. 864 * Warn if there are more than one. 865 */ 866 setsin(from, al2->addr); 867 if (n > 1 && device == NULL && !find_local_ip(from, to)) { 868 Fprintf(stderr, 869 "%s: Warning: Multiple interfaces found; using %s @ %s\n", 870 prog, inet_ntoa(from->sin_addr), al2->device); 871 } 872 } else { 873 hi = gethostinfo(source); 874 source = hi->name; 875 hi->name = NULL; 876 if (device == NULL) { 877 /* 878 * Use the first interface found. 879 * Warn if there are more than one. 880 */ 881 setsin(from, hi->addrs[0]); 882 if (hi->n > 1) 883 Fprintf(stderr, 884 "%s: Warning: %s has multiple addresses; using %s\n", 885 prog, source, inet_ntoa(from->sin_addr)); 886 } else { 887 /* 888 * Make sure the source specified matches the 889 * interface address. 890 */ 891 for (i = hi->n, ap = hi->addrs; i > 0; --i, ++ap) 892 if (*ap == al2->addr) 893 break; 894 if (i <= 0) { 895 Fprintf(stderr, 896 "%s: %s is not on interface %s\n", 897 prog, source, device); 898 exit(1); 899 } 900 setsin(from, *ap); 901 } 902 freehostinfo(hi); 903 } 904 905 /* 906 * If not root, make sure source address matches a local interface. 907 * (The list of addresses produced by ifaddrlist() automatically 908 * excludes interfaces that are marked down and/or loopback.) 909 */ 910 if (getuid()) { 911 al2 = al; 912 for (i = n; i > 0; --i, ++al2) 913 if (from->sin_addr.s_addr == al2->addr) 914 break; 915 if (i <= 0) { 916 Fprintf(stderr, "%s: %s is not a valid local address " 917 "and you are not superuser.\n", prog, 918 inet_ntoa(from->sin_addr)); 919 exit(1); 920 } 921 } 922 923 outip->ip_src = from->sin_addr; 924 #ifndef IP_HDRINCL 925 if (bind(sndsock, (struct sockaddr *)from, sizeof(*from)) < 0) { 926 Fprintf(stderr, "%s: bind: %s\n", 927 prog, strerror(errno)); 928 exit (1); 929 } 930 #endif 931 932 if (as_path) { 933 asn = as_setup(as_server); 934 if (asn == NULL) { 935 Fprintf(stderr, "%s: as_setup failed, AS# lookups disabled\n", 936 prog); 937 (void)fflush(stderr); 938 as_path = 0; 939 } 940 } 941 942 setuid(getuid()); 943 Fprintf(stderr, "%s to %s (%s)", 944 prog, hostname, inet_ntoa(to->sin_addr)); 945 if (source) 946 Fprintf(stderr, " from %s", source); 947 Fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, packlen); 948 (void)fflush(stderr); 949 950 for (ttl = first_ttl; ttl <= max_ttl; ++ttl) { 951 u_int32_t lastaddr = 0; 952 int got_there = 0; 953 int unreachable = 0; 954 955 again: 956 printed_ttl = 0; 957 for (probe = 0; probe < nprobes; ++probe) { 958 int cc; 959 struct timeval t1, t2; 960 struct ip *ip; 961 (void)gettimeofday(&t1, NULL); 962 send_probe(++seq, ttl, &t1); 963 while ((cc = wait_for_reply(s, from, &t1)) != 0) { 964 (void)gettimeofday(&t2, NULL); 965 /* 966 * Since we'll be receiving all ICMP 967 * messages to this host above, we may 968 * never end up with cc=0, so we need 969 * an additional termination check. 970 */ 971 if (t2.tv_sec - t1.tv_sec > waittime) { 972 cc = 0; 973 break; 974 } 975 i = packet_ok(packet, cc, from, seq); 976 /* Skip short packet */ 977 if (i == 0) 978 continue; 979 if (from->sin_addr.s_addr != lastaddr) { 980 print(packet, cc, from); 981 lastaddr = from->sin_addr.s_addr; 982 } 983 ip = (struct ip *)packet; 984 Printf(" %.3f ms", deltaT(&t1, &t2)); 985 if (ttl_flag) 986 Printf(" (ttl = %d)", ip->ip_ttl); 987 if (i == -2) { 988 #ifndef ARCHAIC 989 if (ip->ip_ttl <= 1) 990 Printf(" !"); 991 #endif 992 ++got_there; 993 break; 994 } 995 996 /* time exceeded in transit */ 997 if (i == -1) 998 break; 999 code = i - 1; 1000 switch (code) { 1001 1002 case ICMP_UNREACH_PORT: 1003 #ifndef ARCHAIC 1004 if (ip->ip_ttl <= 1) 1005 Printf(" !"); 1006 #endif 1007 ++got_there; 1008 break; 1009 1010 case ICMP_UNREACH_NET: 1011 ++unreachable; 1012 Printf(" !N"); 1013 break; 1014 1015 case ICMP_UNREACH_HOST: 1016 ++unreachable; 1017 Printf(" !H"); 1018 break; 1019 1020 case ICMP_UNREACH_PROTOCOL: 1021 ++got_there; 1022 Printf(" !P"); 1023 break; 1024 1025 case ICMP_UNREACH_NEEDFRAG: 1026 if (mtudisc) { 1027 frag_err(); 1028 goto again; 1029 } else { 1030 ++unreachable; 1031 Printf(" !F"); 1032 } 1033 break; 1034 1035 case ICMP_UNREACH_SRCFAIL: 1036 ++unreachable; 1037 Printf(" !S"); 1038 break; 1039 1040 /* rfc1716 */ 1041 #ifndef ICMP_UNREACH_FILTER_PROHIB 1042 #define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohibited filter */ 1043 #endif 1044 case ICMP_UNREACH_FILTER_PROHIB: 1045 ++unreachable; 1046 Printf(" !X"); 1047 break; 1048 1049 default: 1050 ++unreachable; 1051 Printf(" !<%d>", code); 1052 break; 1053 } 1054 break; 1055 } 1056 if (cc == 0) 1057 Printf(" *"); 1058 else if (cc && probe == nprobes - 1 && Mflag) 1059 decode_extensions(packet, cc); 1060 (void)fflush(stdout); 1061 } 1062 putchar('\n'); 1063 if (got_there || 1064 (unreachable > 0 && unreachable >= ((nprobes + 1) / 2))) 1065 break; 1066 } 1067 1068 if (as_path) 1069 as_shutdown(asn); 1070 1071 exit(0); 1072 } 1073 1074 int 1075 wait_for_reply(int sock, struct sockaddr_in *fromp, struct timeval *tp) 1076 { 1077 struct pollfd set[1]; 1078 struct timeval now, wait; 1079 int cc = 0; 1080 socklen_t fromlen = sizeof(*fromp); 1081 int retval; 1082 1083 set[0].fd = sock; 1084 set[0].events = POLLIN; 1085 1086 wait.tv_sec = tp->tv_sec + waittime; 1087 wait.tv_usec = tp->tv_usec; 1088 (void)gettimeofday(&now, NULL); 1089 tvsub(&wait, &now); 1090 1091 if (wait.tv_sec < 0) { 1092 wait.tv_sec = 0; 1093 wait.tv_usec = 0; 1094 } 1095 1096 retval = poll(set, 1, wait.tv_sec * 1000 + wait.tv_usec / 1000); 1097 if (retval < 0) { 1098 /* If we continue, we probably just flood the remote host. */ 1099 Fprintf(stderr, "%s: select: %s\n", prog, strerror(errno)); 1100 exit(1); 1101 } 1102 if (retval > 0) { 1103 cc = recvfrom(s, (char *)packet, sizeof(packet), 0, 1104 (struct sockaddr *)fromp, &fromlen); 1105 } 1106 1107 return(cc); 1108 } 1109 1110 void 1111 decode_extensions(unsigned char *buf, int ip_len) 1112 { 1113 struct icmp_ext_cmn_hdr *cmn_hdr; 1114 struct icmp_ext_obj_hdr *obj_hdr; 1115 union { 1116 struct mpls_header mpls; 1117 uint32_t mpls_h; 1118 } mpls; 1119 int datalen, obj_len; 1120 struct ip *ip; 1121 1122 ip = (struct ip *)buf; 1123 1124 if (ip_len <= sizeof(struct ip) + ICMP_EXT_OFFSET) { 1125 /* 1126 * No support for ICMP extensions on this host 1127 */ 1128 return; 1129 } 1130 1131 /* 1132 * Move forward to the start of the ICMP extensions, if present 1133 */ 1134 buf += (ip->ip_hl << 2) + ICMP_EXT_OFFSET; 1135 cmn_hdr = (struct icmp_ext_cmn_hdr *)buf; 1136 1137 if (cmn_hdr->version != ICMP_EXT_VERSION) { 1138 /* 1139 * Unknown version 1140 */ 1141 return; 1142 } 1143 1144 datalen = ip_len - ((u_char *)cmn_hdr - (u_char *)ip); 1145 1146 /* 1147 * Check the checksum, cmn_hdr->checksum == 0 means no checksum'ing 1148 * done by sender. 1149 * 1150 * If the checksum is ok, we'll get 0, as the checksum is calculated 1151 * with the checksum field being 0'd. 1152 */ 1153 if (ntohs(cmn_hdr->checksum) && 1154 in_cksum((u_short *)cmn_hdr, datalen)) { 1155 1156 return; 1157 } 1158 1159 buf += sizeof(*cmn_hdr); 1160 datalen -= sizeof(*cmn_hdr); 1161 1162 while (datalen > 0) { 1163 obj_hdr = (struct icmp_ext_obj_hdr *)buf; 1164 obj_len = ntohs(obj_hdr->length); 1165 1166 /* 1167 * Sanity check the length field 1168 */ 1169 if (obj_len > datalen) { 1170 return; 1171 } 1172 1173 datalen -= obj_len; 1174 1175 /* 1176 * Move past the object header 1177 */ 1178 buf += sizeof(struct icmp_ext_obj_hdr); 1179 obj_len -= sizeof(struct icmp_ext_obj_hdr); 1180 1181 switch (obj_hdr->class_num) { 1182 case MPLS_STACK_ENTRY_CLASS: 1183 switch (obj_hdr->c_type) { 1184 case MPLS_STACK_ENTRY_C_TYPE: 1185 while (obj_len >= sizeof(uint32_t)) { 1186 mpls.mpls_h = ntohl(*(uint32_t *)buf); 1187 1188 buf += sizeof(uint32_t); 1189 obj_len -= sizeof(uint32_t); 1190 1191 printf(" [MPLS: Label %d Exp %d]", 1192 mpls.mpls.label, mpls.mpls.exp); 1193 } 1194 if (obj_len > 0) { 1195 /* 1196 * Something went wrong, and we're at 1197 * a unknown offset into the packet, 1198 * ditch the rest of it. 1199 */ 1200 return; 1201 } 1202 break; 1203 default: 1204 /* 1205 * Unknown object, skip past it 1206 */ 1207 buf += ntohs(obj_hdr->length) - 1208 sizeof(struct icmp_ext_obj_hdr); 1209 break; 1210 } 1211 break; 1212 1213 default: 1214 /* 1215 * Unknown object, skip past it 1216 */ 1217 buf += ntohs(obj_hdr->length) - 1218 sizeof(struct icmp_ext_obj_hdr); 1219 break; 1220 } 1221 } 1222 } 1223 1224 void 1225 dump_packet() 1226 { 1227 u_char *p; 1228 int i; 1229 1230 Fprintf(stderr, "packet data:"); 1231 1232 #ifdef __hpux 1233 for (p = useicmp ? (u_char *)outicmp : (u_char *)outudp, i = 0; i < 1234 i < packlen - (sizeof(*outip) + optlen); i++) 1235 #else 1236 for (p = (u_char *)outip, i = 0; i < packlen; i++) 1237 #endif 1238 { 1239 if ((i % 24) == 0) 1240 Fprintf(stderr, "\n "); 1241 Fprintf(stderr, " %02x", *p++); 1242 } 1243 Fprintf(stderr, "\n"); 1244 } 1245 1246 void 1247 send_probe(int seq, int ttl, struct timeval *tp) 1248 { 1249 int cc; 1250 struct udpiphdr * ui; 1251 int oldmtu = packlen; 1252 1253 again: 1254 #ifdef BYTESWAP_IP_LEN 1255 outip->ip_len = htons(packlen); 1256 #else 1257 outip->ip_len = packlen; 1258 #endif 1259 outip->ip_ttl = ttl; 1260 #ifndef __hpux 1261 outip->ip_id = htons(ident + seq); 1262 #endif 1263 1264 /* 1265 * In most cases, the kernel will recalculate the ip checksum. 1266 * But we must do it anyway so that the udp checksum comes out 1267 * right. 1268 */ 1269 if (docksum) { 1270 outip->ip_sum = 1271 in_cksum((u_int16_t *)outip, sizeof(*outip) + optlen); 1272 if (outip->ip_sum == 0) 1273 outip->ip_sum = 0xffff; 1274 } 1275 1276 /* Payload */ 1277 outsetup.seq = seq; 1278 outsetup.ttl = ttl; 1279 outsetup.tv = *tp; 1280 memcpy(outmark,&outsetup,sizeof(outsetup)); 1281 1282 if (useicmp) 1283 outicmp->icmp_seq = htons(seq); 1284 else 1285 outudp->uh_dport = htons(port + seq); 1286 1287 /* (We can only do the checksum if we know our ip address) */ 1288 if (docksum) { 1289 if (useicmp) { 1290 outicmp->icmp_cksum = 0; 1291 outicmp->icmp_cksum = in_cksum((u_int16_t *)outicmp, 1292 packlen - (sizeof(*outip) + optlen)); 1293 if (outicmp->icmp_cksum == 0) 1294 outicmp->icmp_cksum = 0xffff; 1295 } else { 1296 u_int16_t sum; 1297 struct { 1298 struct in_addr src; 1299 struct in_addr dst; 1300 u_int8_t zero; 1301 u_int8_t protocol; 1302 u_int16_t len; 1303 } __attribute__((__packed__)) phdr; 1304 1305 /* Checksum */ 1306 ui = (struct udpiphdr *)outip; 1307 memset(&phdr, 0, sizeof(phdr)); 1308 phdr.src = ui->ui_src; 1309 phdr.dst = ((struct sockaddr_in *)&whereto)->sin_addr; 1310 phdr.protocol = ui->ui_pr; 1311 phdr.len = outudp->uh_ulen; 1312 outudp->uh_sum = 0; 1313 sum = in_cksum2(0, (u_int16_t *)&phdr, sizeof(phdr)); 1314 sum = in_cksum2(sum, (u_int16_t *)outudp, ntohs(outudp->uh_ulen)); 1315 sum = ~sum; /** XXXSCW: Quell SuperH Compiler Bug */ 1316 outudp->uh_sum = sum; 1317 if (outudp->uh_sum == 0) 1318 outudp->uh_sum = 0xffff; 1319 } 1320 } 1321 1322 /* XXX undocumented debugging hack */ 1323 if (verbose > 1) { 1324 const u_int16_t *sp; 1325 int nshorts, i; 1326 1327 sp = (u_int16_t *)outip; 1328 nshorts = (u_int)packlen / sizeof(u_int16_t); 1329 i = 0; 1330 Printf("[ %d bytes", packlen); 1331 while (--nshorts >= 0) { 1332 if ((i++ % 8) == 0) 1333 Printf("\n\t"); 1334 Printf(" %04x", ntohs(*sp++)); 1335 } 1336 if (packlen & 1) { 1337 if ((i % 8) == 0) 1338 Printf("\n\t"); 1339 Printf(" %02x", *(u_char *)sp); 1340 } 1341 Printf("]\n"); 1342 } 1343 1344 #if !defined(IP_HDRINCL) && defined(IP_TTL) 1345 if (setsockopt(sndsock, IPPROTO_IP, IP_TTL, 1346 (char *)&ttl, sizeof(ttl)) < 0) { 1347 Fprintf(stderr, "%s: setsockopt ttl %d: %s\n", 1348 prog, ttl, strerror(errno)); 1349 exit(1); 1350 } 1351 #endif 1352 if (dump) 1353 dump_packet(); 1354 1355 #ifdef __hpux 1356 cc = sendto(sndsock, useicmp ? (char *)outicmp : (char *)outudp, 1357 packlen - (sizeof(*outip) + optlen), 0, &whereto, sizeof(whereto)); 1358 if (cc > 0) 1359 cc += sizeof(*outip) + optlen; 1360 #else 1361 cc = sendto(sndsock, (char *)outip, 1362 packlen, 0, &whereto, sizeof(whereto)); 1363 #endif 1364 if (cc < 0 || cc != packlen) { 1365 if (cc < 0) { 1366 /* 1367 * An errno of EMSGSIZE means we're writing too big a 1368 * datagram for the interface. We have to just 1369 * decrease the packet size until we find one that 1370 * works. 1371 * 1372 * XXX maybe we should try to read the outgoing if's 1373 * mtu? 1374 */ 1375 if (errno == EMSGSIZE) { 1376 packlen = *mtuptr++; 1377 resize_packet(); 1378 goto again; 1379 } else 1380 Fprintf(stderr, "%s: sendto: %s\n", 1381 prog, strerror(errno)); 1382 } 1383 1384 Printf("%s: wrote %s %d chars, ret=%d\n", 1385 prog, hostname, packlen, cc); 1386 (void)fflush(stdout); 1387 } 1388 if (oldmtu != packlen) { 1389 Printf("message too big, " 1390 "trying new MTU = %d\n", packlen); 1391 printed_ttl = 0; 1392 } 1393 if (!printed_ttl) { 1394 Printf("%2d ", ttl); 1395 printed_ttl = 1; 1396 } 1397 1398 } 1399 1400 double 1401 deltaT(struct timeval *t1p, struct timeval *t2p) 1402 { 1403 double dt; 1404 1405 dt = (double)(t2p->tv_sec - t1p->tv_sec) * 1000.0 + 1406 (double)(t2p->tv_usec - t1p->tv_usec) / 1000.0; 1407 return (dt); 1408 } 1409 1410 /* 1411 * Convert an ICMP "type" field to a printable string. 1412 */ 1413 char * 1414 pr_type(u_char t) 1415 { 1416 static char *ttab[] = { 1417 "Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable", 1418 "Source Quench", "Redirect", "ICMP 6", "ICMP 7", 1419 "Echo", "ICMP 9", "ICMP 10", "Time Exceeded", 1420 "Param Problem", "Timestamp", "Timestamp Reply", "Info Request", 1421 "Info Reply" 1422 }; 1423 1424 if (t > 16) 1425 return("OUT-OF-RANGE"); 1426 1427 return(ttab[t]); 1428 } 1429 1430 int 1431 packet_ok(u_char *buf, int cc, struct sockaddr_in *from, int seq) 1432 { 1433 struct icmp *icp; 1434 u_char type, code; 1435 int hlen; 1436 #ifndef ARCHAIC 1437 struct ip *ip; 1438 1439 ip = (struct ip *) buf; 1440 hlen = ip->ip_hl << 2; 1441 if (cc < hlen + ICMP_MINLEN) { 1442 if (verbose) 1443 Printf("packet too short (%d bytes) from %s\n", cc, 1444 inet_ntoa(from->sin_addr)); 1445 return (0); 1446 } 1447 cc -= hlen; 1448 icp = (struct icmp *)(buf + hlen); 1449 #else 1450 icp = (struct icmp *)buf; 1451 #endif 1452 type = icp->icmp_type; 1453 code = icp->icmp_code; 1454 if ((type == ICMP_TIMXCEED && code == ICMP_TIMXCEED_INTRANS) || 1455 type == ICMP_UNREACH || type == ICMP_ECHOREPLY) { 1456 struct ip *hip; 1457 struct udphdr *up; 1458 struct icmp *hicmp; 1459 1460 hip = &icp->icmp_ip; 1461 hlen = hip->ip_hl << 2; 1462 1463 nextmtu = ntohs(icp->icmp_nextmtu); /* for frag_err() */ 1464 1465 if (useicmp) { 1466 /* XXX */ 1467 if (type == ICMP_ECHOREPLY && 1468 icp->icmp_id == htons(ident) && 1469 icp->icmp_seq == htons(seq)) 1470 return (-2); 1471 1472 hicmp = (struct icmp *)((u_char *)hip + hlen); 1473 /* XXX 8 is a magic number */ 1474 if (hlen + 8 <= cc && 1475 hip->ip_p == IPPROTO_ICMP && 1476 hicmp->icmp_id == htons(ident) && 1477 hicmp->icmp_seq == htons(seq)) 1478 return (type == ICMP_TIMXCEED ? -1 : code + 1); 1479 } else { 1480 up = (struct udphdr *)((u_char *)hip + hlen); 1481 /* XXX 8 is a magic number */ 1482 if (hlen + 12 <= cc && 1483 hip->ip_p == IPPROTO_UDP && 1484 up->uh_sport == htons(ident) && 1485 up->uh_dport == htons(port + seq)) 1486 return (type == ICMP_TIMXCEED ? -1 : code + 1); 1487 } 1488 } 1489 #ifndef ARCHAIC 1490 if (verbose) { 1491 int i; 1492 u_int32_t *lp = (u_int32_t *)&icp->icmp_ip; 1493 1494 Printf("\n%d bytes from %s to ", cc, inet_ntoa(from->sin_addr)); 1495 Printf("%s: icmp type %d (%s) code %d\n", 1496 inet_ntoa(ip->ip_dst), type, pr_type(type), icp->icmp_code); 1497 for (i = 4; i < cc ; i += sizeof(*lp)) 1498 Printf("%2d: x%8.8x\n", i, *lp++); 1499 } 1500 #endif 1501 return(0); 1502 } 1503 1504 void resize_packet(void) 1505 { 1506 if (useicmp) { 1507 outicmp->icmp_cksum = 0; 1508 outicmp->icmp_cksum = in_cksum((u_int16_t *)outicmp, 1509 packlen - (sizeof(*outip) + optlen)); 1510 if (outicmp->icmp_cksum == 0) 1511 outicmp->icmp_cksum = 0xffff; 1512 } else { 1513 outudp->uh_ulen = 1514 htons((u_int16_t)(packlen - (sizeof(*outip) + optlen))); 1515 } 1516 } 1517 1518 void 1519 print(u_char *buf, int cc, struct sockaddr_in *from) 1520 { 1521 struct ip *ip; 1522 int hlen; 1523 1524 ip = (struct ip *) buf; 1525 hlen = ip->ip_hl << 2; 1526 cc -= hlen; 1527 1528 if (as_path) 1529 Printf(" [AS%d]", as_lookup(asn, &from->sin_addr)); 1530 1531 if (nflag) 1532 Printf(" %s", inet_ntoa(from->sin_addr)); 1533 else 1534 Printf(" %s (%s)", inetname(from->sin_addr), 1535 inet_ntoa(from->sin_addr)); 1536 1537 if (verbose) 1538 Printf(" %d bytes to %s", cc, inet_ntoa (ip->ip_dst)); 1539 } 1540 1541 u_int16_t 1542 in_cksum(u_int16_t *addr, int len) 1543 { 1544 1545 return ~in_cksum2(0, addr, len); 1546 } 1547 1548 /* 1549 * Checksum routine for Internet Protocol family headers (C Version) 1550 */ 1551 u_int16_t 1552 in_cksum2(u_int16_t seed, u_int16_t *addr, int len) 1553 { 1554 int nleft = len; 1555 u_int16_t *w = addr; 1556 union { 1557 u_int16_t w; 1558 u_int8_t b[2]; 1559 } answer; 1560 int32_t sum = seed; 1561 1562 /* 1563 * Our algorithm is simple, using a 32 bit accumulator (sum), 1564 * we add sequential 16 bit words to it, and at the end, fold 1565 * back all the carry bits from the top 16 bits into the lower 1566 * 16 bits. 1567 */ 1568 while (nleft > 1) { 1569 sum += *w++; 1570 nleft -= 2; 1571 } 1572 1573 /* mop up an odd byte, if necessary */ 1574 if (nleft == 1) { 1575 answer.b[0] = *(u_char *)w; 1576 answer.b[1] = 0; 1577 sum += answer.w; 1578 } 1579 1580 /* 1581 * add back carry outs from top 16 bits to low 16 bits 1582 */ 1583 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ 1584 sum += (sum >> 16); /* add carry */ 1585 answer.w = sum; /* truncate to 16 bits */ 1586 return (answer.w); 1587 } 1588 1589 /* 1590 * Subtract 2 timeval structs: out = out - in. 1591 * Out is assumed to be >= in. 1592 */ 1593 void 1594 tvsub(struct timeval *out, struct timeval *in) 1595 { 1596 1597 if ((out->tv_usec -= in->tv_usec) < 0) { 1598 --out->tv_sec; 1599 out->tv_usec += 1000000; 1600 } 1601 out->tv_sec -= in->tv_sec; 1602 } 1603 1604 /* 1605 * Construct an Internet address representation. 1606 * If the nflag has been supplied, give 1607 * numeric value, otherwise try for symbolic name. 1608 */ 1609 char * 1610 inetname(struct in_addr in) 1611 { 1612 char *cp; 1613 struct hostent *hp; 1614 static int first = 1; 1615 static char domain[MAXHOSTNAMELEN + 1], line[MAXHOSTNAMELEN + 1]; 1616 1617 if (first && !nflag) { 1618 int rv; 1619 1620 first = 0; 1621 rv = gethostname(domain, sizeof domain); 1622 if (rv == 0 && (cp = strchr(domain, '.')) != NULL) { 1623 (void)strlcpy(domain, cp + 1, sizeof(domain)); 1624 } else 1625 domain[0] = '\0'; 1626 } 1627 if (!nflag && in.s_addr != INADDR_ANY) { 1628 hp = gethostbyaddr((char *)&in, sizeof(in), AF_INET); 1629 if (hp != NULL) { 1630 if ((cp = strchr(hp->h_name, '.')) != NULL && 1631 strcmp(cp + 1, domain) == 0) 1632 *cp = '\0'; 1633 (void)strlcpy(line, hp->h_name, sizeof(line)); 1634 return (line); 1635 } 1636 } 1637 return (inet_ntoa(in)); 1638 } 1639 1640 struct hostinfo * 1641 gethostinfo(char *hostname) 1642 { 1643 int n; 1644 struct hostent *hp; 1645 struct hostinfo *hi; 1646 char **p; 1647 u_int32_t *ap; 1648 struct in_addr addr; 1649 1650 hi = calloc(1, sizeof(*hi)); 1651 if (hi == NULL) { 1652 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno)); 1653 exit(1); 1654 } 1655 if (inet_aton(hostname, &addr) != 0) { 1656 hi->name = strdup(hostname); 1657 if (!hi->name) { 1658 Fprintf(stderr, "%s: strdup %s\n", prog, 1659 strerror(errno)); 1660 exit(1); 1661 } 1662 hi->n = 1; 1663 hi->addrs = calloc(1, sizeof(hi->addrs[0])); 1664 if (hi->addrs == NULL) { 1665 Fprintf(stderr, "%s: calloc %s\n", 1666 prog, strerror(errno)); 1667 exit(1); 1668 } 1669 hi->addrs[0] = addr.s_addr; 1670 return (hi); 1671 } 1672 1673 hp = gethostbyname(hostname); 1674 if (hp == NULL) { 1675 Fprintf(stderr, "%s: unknown host %s\n", prog, hostname); 1676 exit(1); 1677 } 1678 if (hp->h_addrtype != AF_INET || hp->h_length != 4) { 1679 Fprintf(stderr, "%s: bad host %s\n", prog, hostname); 1680 exit(1); 1681 } 1682 hi->name = strdup(hp->h_name); 1683 if (!hi->name) { 1684 Fprintf(stderr, "%s: strdup %s\n", prog, strerror(errno)); 1685 exit(1); 1686 } 1687 for (n = 0, p = hp->h_addr_list; *p != NULL; ++n, ++p) 1688 continue; 1689 hi->n = n; 1690 hi->addrs = calloc(n, sizeof(hi->addrs[0])); 1691 if (hi->addrs == NULL) { 1692 Fprintf(stderr, "%s: calloc %s\n", prog, strerror(errno)); 1693 exit(1); 1694 } 1695 for (ap = hi->addrs, p = hp->h_addr_list; *p != NULL; ++ap, ++p) 1696 memcpy(ap, *p, sizeof(*ap)); 1697 return (hi); 1698 } 1699 1700 void 1701 freehostinfo(struct hostinfo *hi) 1702 { 1703 if (hi->name != NULL) { 1704 free(hi->name); 1705 hi->name = NULL; 1706 } 1707 free((char *)hi->addrs); 1708 free((char *)hi); 1709 } 1710 1711 void 1712 getaddr(u_int32_t *ap, char *hostname) 1713 { 1714 struct hostinfo *hi; 1715 1716 hi = gethostinfo(hostname); 1717 *ap = hi->addrs[0]; 1718 freehostinfo(hi); 1719 } 1720 1721 void 1722 setsin(struct sockaddr_in *sin, u_int32_t addr) 1723 { 1724 1725 memset(sin, 0, sizeof(*sin)); 1726 #ifdef HAVE_SOCKADDR_SA_LEN 1727 sin->sin_len = sizeof(*sin); 1728 #endif 1729 sin->sin_family = AF_INET; 1730 sin->sin_addr.s_addr = addr; 1731 } 1732 1733 /* String to value with optional min and max. Handles decimal and hex. */ 1734 int 1735 str2val(const char *str, const char *what, int mi, int ma) 1736 { 1737 const char *cp; 1738 long val; 1739 char *ep; 1740 1741 errno = 0; 1742 ep = NULL; 1743 if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) { 1744 cp = str + 2; 1745 val = strtol(cp, &ep, 16); 1746 } else 1747 val = strtol(str, &ep, 10); 1748 if (errno || str[0] == '\0' || *ep != '\0') { 1749 Fprintf(stderr, "%s: \"%s\" bad value for %s \n", 1750 prog, str, what); 1751 exit(1); 1752 } 1753 if (val < mi && mi >= 0) { 1754 if (mi == 0) 1755 Fprintf(stderr, "%s: %s must be >= %d\n", 1756 prog, what, mi); 1757 else 1758 Fprintf(stderr, "%s: %s must be > %d\n", 1759 prog, what, mi - 1); 1760 exit(1); 1761 } 1762 if (val > ma && ma >= 0) { 1763 Fprintf(stderr, "%s: %s must be <= %d\n", prog, what, ma); 1764 exit(1); 1765 } 1766 return ((int)val); 1767 } 1768 1769 __dead void 1770 usage(void) 1771 { 1772 extern char version[]; 1773 1774 Fprintf(stderr, "Version %s\n", version); 1775 Fprintf(stderr, "usage: %s [-adDFPIlMnrvx] [-g gateway] [-i iface] \ 1776 [-f first_ttl]\n\t[-m max_ttl] [-p port] [-q nqueries] [-s src_addr] [-t tos]\n\t\ 1777 [-w waittime] [-A as_server] host [packetlen]\n", 1778 prog); 1779 exit(1); 1780 } 1781 1782 /* 1783 * Received ICMP unreachable (fragmentation required and DF set). 1784 * If the ICMP error was from a "new" router, it'll contain the next-hop 1785 * MTU that we should use next. Otherwise we'll just keep going in the 1786 * mtus[] table, trying until we hit a valid MTU. 1787 */ 1788 1789 1790 void 1791 frag_err() 1792 { 1793 int i; 1794 1795 if (nextmtu > 0 && nextmtu < packlen) { 1796 Printf("\nfragmentation required and DF set, " 1797 "next hop MTU = %d\n", 1798 nextmtu); 1799 packlen = nextmtu; 1800 for (i = 0; mtus[i] > 0; i++) { 1801 if (mtus[i] < nextmtu) { 1802 mtuptr = &mtus[i]; /* next one to try */ 1803 break; 1804 } 1805 } 1806 } else { 1807 Printf("\nfragmentation required and DF set. "); 1808 if (nextmtu) 1809 Printf("\nBogus next hop MTU = %d > last MTU = %d. ", 1810 nextmtu, packlen); 1811 packlen = *mtuptr++; 1812 Printf("Trying new MTU = %d\n", packlen); 1813 } 1814 resize_packet(); 1815 } 1816 1817 int 1818 find_local_ip(struct sockaddr_in *from, struct sockaddr_in *to) 1819 { 1820 int sock; 1821 struct sockaddr_in help; 1822 socklen_t help_len; 1823 1824 sock = socket(AF_INET, SOCK_DGRAM, 0); 1825 if (sock < 0) return (0); 1826 1827 help.sin_family = AF_INET; 1828 /* 1829 * At this point the port number doesn't matter 1830 * since it only has to be greater than zero. 1831 */ 1832 help.sin_port = 42; 1833 help.sin_addr.s_addr = to->sin_addr.s_addr; 1834 if (connect(sock, (struct sockaddr *)&help, sizeof(help)) < 0) { 1835 (void)close(sock); 1836 return (0); 1837 } 1838 1839 help_len = sizeof(help); 1840 if (getsockname(sock, (struct sockaddr *)&help, &help_len) < 0 || 1841 help_len != sizeof(help) || 1842 help.sin_addr.s_addr == INADDR_ANY) { 1843 (void)close(sock); 1844 return (0); 1845 } 1846 1847 (void)close(sock); 1848 setsin(from, help.sin_addr.s_addr); 1849 return (1); 1850 } 1851 1852 #ifdef IPSEC 1853 #ifdef IPSEC_POLICY_IPSEC 1854 int 1855 setpolicy(so, policy) 1856 int so; 1857 char *policy; 1858 { 1859 char *buf; 1860 1861 buf = ipsec_set_policy(policy, strlen(policy)); 1862 if (buf == NULL) { 1863 Fprintf(stderr, "%s: %s\n", prog, ipsec_strerror()); 1864 return -1; 1865 } 1866 (void)setsockopt(so, IPPROTO_IP, IP_IPSEC_POLICY, 1867 buf, ipsec_get_policylen(buf)); 1868 1869 free(buf); 1870 1871 return 0; 1872 } 1873 #endif 1874 #endif 1875 1876