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