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