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