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