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