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