1 /* $NetBSD: ping.c,v 1.123 2025/12/12 06:53:53 knakahara Exp $ */ 2 3 /* 4 * Copyright (c) 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Mike Muuss. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 /* 36 * P I N G . C 37 * 38 * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility, 39 * measure round-trip-delays and packet loss across network paths. 40 * 41 * Author - 42 * Mike Muuss 43 * U. S. Army Ballistic Research Laboratory 44 * December, 1983 45 * Modified at Uc Berkeley 46 * Record Route and verbose headers - Phil Dykstra, BRL, March 1988. 47 * Multicast options (ttl, if, loop) - Steve Deering, Stanford, August 1988. 48 * ttl, duplicate detection - Cliff Frost, UCB, April 1989 49 * Pad pattern - Cliff Frost (from Tom Ferrin, UCSF), April 1989 50 * 51 * Status - 52 * Public Domain. Distribution Unlimited. 53 * 54 * Bugs - 55 * More statistics could always be gathered. 56 * This program has to run SUID to ROOT to access the ICMP socket. 57 */ 58 59 #include <sys/cdefs.h> 60 #ifndef lint 61 __RCSID("$NetBSD: ping.c,v 1.123 2025/12/12 06:53:53 knakahara Exp $"); 62 #endif 63 64 #include <stdio.h> 65 #include <stddef.h> 66 #include <errno.h> 67 #include <signal.h> 68 #include <sys/time.h> 69 #include <sys/types.h> 70 #include <sys/param.h> 71 #include <sys/socket.h> 72 #include <sys/file.h> 73 #include <termios.h> 74 #include <stdlib.h> 75 #include <unistd.h> 76 #include <poll.h> 77 #include <limits.h> 78 #include <math.h> 79 #include <string.h> 80 #include <err.h> 81 82 #include <netinet/in_systm.h> 83 #include <netinet/in.h> 84 #include <netinet/ip.h> 85 #include <netinet/ip_icmp.h> 86 #include <netinet/ip_var.h> 87 #include <arpa/inet.h> 88 #include <ctype.h> 89 #include <netdb.h> 90 91 #ifdef IPSEC 92 #include <netipsec/ipsec.h> 93 #endif /*IPSEC*/ 94 95 #include "prog_ops.h" 96 97 #define FLOOD_INTVL 0.01 /* default flood output interval */ 98 #define MAXPACKET (IP_MAXPACKET-60-8) /* max packet size */ 99 100 #define F_VERBOSE 0x0001 101 #define F_QUIET 0x0002 /* minimize all output */ 102 #define F_SEMI_QUIET 0x0004 /* ignore our ICMP errors */ 103 #define F_FLOOD 0x0008 /* flood-ping */ 104 #define F_RECORD_ROUTE 0x0010 /* record route */ 105 #define F_SOURCE_ROUTE 0x0020 /* loose source route */ 106 #define F_PING_FILLED 0x0040 /* is buffer filled with user data? */ 107 #define F_PING_RANDOM 0x0080 /* use random data */ 108 #define F_NUMERIC 0x0100 /* do not do gethostbyaddr() calls */ 109 #define F_TIMING 0x0200 /* room for a timestamp */ 110 #define F_DF 0x0400 /* set IP DF bit */ 111 #define F_SOURCE_ADDR 0x0800 /* set source IP address/interface */ 112 #define F_ONCE 0x1000 /* exit(0) after receiving 1 reply */ 113 #define F_MCAST 0x2000 /* multicast target */ 114 #define F_MCAST_NOLOOP 0x4000 /* no multicast loopback */ 115 #define F_AUDIBLE 0x8000 /* audible output */ 116 #define F_TIMING64 0x10000 /* 64 bit time, nanoseconds */ 117 #ifdef IPSEC 118 #ifdef IPSEC_POLICY_IPSEC 119 #define F_POLICY 0x20000 120 #else 121 #define F_AUTHHDR 0x20000 122 #define F_ENCRYPT 0x40000 123 #endif /*IPSEC_POLICY_IPSEC*/ 124 #endif /*IPSEC*/ 125 126 127 /* MAX_DUP_CHK is the number of bits in received table, the 128 * maximum number of received sequence numbers we can track to check 129 * for duplicates. 130 */ 131 #define MAX_DUP_CHK (8 * 2048) 132 static u_char rcvd_tbl[MAX_DUP_CHK/8]; 133 static int nrepeats = 0; 134 #define A(seq) rcvd_tbl[(seq/8)%sizeof(rcvd_tbl)] /* byte in array */ 135 #define B(seq) (1 << (seq & 0x07)) /* bit in byte */ 136 #define SET(seq) (A(seq) |= B(seq)) 137 #define CLR(seq) (A(seq) &= (~B(seq))) 138 #define TST(seq) (A(seq) & B(seq)) 139 140 struct tv32 { 141 int32_t tv32_sec; 142 int32_t tv32_usec; 143 }; 144 145 146 static u_char *packet; 147 static int packlen; 148 static int pingflags = 0, options; 149 static int pongflags = 0; 150 static char *fill_pat; 151 152 static int s; /* Socket file descriptor */ 153 static int sloop; /* Socket file descriptor/loopback */ 154 155 #define ICMP_HEADER_LEN 8 /* size of icmp header, see also man "-s" option */ 156 #define PHDR_LEN sizeof(struct tv32) /* size of timestamp header */ 157 #define PHDR64_LEN sizeof(struct timespec) /* size of timestamp header */ 158 static struct sockaddr_in whereto, send_addr; /* Who to ping */ 159 static struct sockaddr_in src_addr; /* from where */ 160 static struct sockaddr_in loc_addr; /* 127.1 */ 161 static int datalen; /* How much data */ 162 static int phdrlen; 163 164 static sigset_t blockmask, enablemask; /* signal masks */ 165 166 #ifndef __NetBSD__ 167 static char *progname; 168 #define getprogname() (progname) 169 #define setprogname(name) ((void)(progname = (name))) 170 #endif 171 172 static char hostname[MAXHOSTNAMELEN]; 173 174 static struct { 175 struct ip o_ip; 176 char o_opt[MAX_IPOPTLEN]; 177 union { 178 u_char u_buf[MAXPACKET+offsetof(struct icmp, icmp_data)]; 179 struct icmp u_icmp; 180 } o_u; 181 } out_pack; 182 #define opack_icmp out_pack.o_u.u_icmp 183 static struct ip *opack_ip; 184 185 static uint8_t optspace[MAX_IPOPTLEN]; /* record route space */ 186 static int optlen; 187 188 static int npackets; /* total packets to send */ 189 static int preload; /* number of packets to "preload" */ 190 static int ntransmitted; /* output sequence # = #sent */ 191 static int ident; /* 16 random bits to identify our packets */ 192 193 static int nreceived; /* # of packets we got back */ 194 195 static double interval; /* interval between packets */ 196 static struct timespec interval_tv; 197 static double tmin = 999999999.0; 198 static double tmax = 0.0; 199 static double tsum = 0.0; /* sum of all times */ 200 static double tsumsq = 0.0; 201 static double maxwait = 0.0; 202 203 static int bufspace = IP_MAXPACKET; 204 205 static struct timespec now, clear_cache, last_tx, next_tx, first_tx; 206 static struct timespec last_rx, first_rx; 207 static int lastrcvd = 1; /* last ping sent has been received */ 208 209 static struct timespec jiggle_time; 210 static int jiggle_cnt, total_jiggled, jiggle_direction = -1; 211 212 __dead static void doit(void); 213 static void prefinish(int); 214 static void prtsig(int); 215 __dead static void finish(int); 216 static void blocksignals(void); 217 static void enablesignals(void); 218 static void summary(int); 219 static void pinger(void); 220 static void fill(void); 221 static void rnd_fill(void); 222 static double diffsec(struct timespec *, struct timespec *); 223 #if 0 224 static void timespecadd(struct timespec *, struct timespec *); 225 #endif 226 static void sec_to_timespec(const double, struct timespec *); 227 static double timespec_to_sec(const struct timespec *); 228 static void pr_pack(u_char *, int, struct sockaddr_in *); 229 static u_int16_t in_cksum(u_int16_t *, u_int); 230 static void pr_saddr(u_char *); 231 static char *pr_addr(struct in_addr *); 232 static void pr_iph(struct icmp *, int); 233 static void pr_retip(struct icmp *, int); 234 static int pr_icmph(struct icmp *, struct sockaddr_in *, int); 235 static void jiggle(int), jiggle_flush(int); 236 static void gethost(const char *, const char *, 237 struct sockaddr_in *, char *, int); 238 __dead static void usage(void); 239 240 int 241 main(int argc, char *argv[]) 242 { 243 int c, i, on = 1, hostind = 0; 244 long l; 245 int len = -1, compat = 0; 246 u_char ttl = 0; 247 u_long tos = 0; 248 char *p; 249 #ifdef IPSEC 250 #ifdef IPSEC_POLICY_IPSEC 251 char *policy_in = NULL; 252 char *policy_out = NULL; 253 #endif 254 #endif 255 #ifdef SIGINFO 256 struct sigaction sa; 257 #endif 258 259 if (prog_init && prog_init() == -1) 260 err(EXIT_FAILURE, "init failed"); 261 262 if ((s = prog_socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) 263 err(EXIT_FAILURE, "Cannot create socket"); 264 if ((sloop = prog_socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) 265 err(EXIT_FAILURE, "Cannot create socket"); 266 267 /* 268 * sloop is never read on. This prevents packets from 269 * queueing in its recv buffer. 270 */ 271 if (prog_shutdown(sloop, SHUT_RD) == -1) 272 warn("Cannot shutdown for read"); 273 274 if (prog_setuid(prog_getuid()) == -1) 275 err(EXIT_FAILURE, "setuid"); 276 277 setprogname(argv[0]); 278 279 #ifndef IPSEC 280 #define IPSECOPT 281 #else 282 #ifdef IPSEC_POLICY_IPSEC 283 #define IPSECOPT "E:" 284 #else 285 #define IPSECOPT "AE" 286 #endif /*IPSEC_POLICY_IPSEC*/ 287 #endif 288 while ((c = getopt(argc, argv, 289 "ac:CdDfg:h:i:I:l:Lnop:PqQrRs:t:T:vw:" IPSECOPT)) != -1) { 290 #undef IPSECOPT 291 switch (c) { 292 case 'a': 293 pingflags |= F_AUDIBLE; 294 break; 295 case 'C': 296 compat = 1; 297 break; 298 case 'c': 299 l = strtol(optarg, &p, 0); 300 if (*p != '\0' || l <= 0) 301 errx(EXIT_FAILURE, 302 "Bad/invalid number of packets: %s", 303 optarg); 304 #if INT_MAX < LONG_MAX 305 if (l > INT_MAX) 306 errx(EXIT_FAILURE, 307 "Too many packets to count: %ld", l); 308 #endif 309 npackets = l; 310 break; 311 case 'D': 312 pingflags |= F_DF; 313 break; 314 case 'd': 315 options |= SO_DEBUG; 316 break; 317 case 'f': 318 pingflags |= F_FLOOD; 319 break; 320 case 'h': 321 hostind = optind-1; 322 break; 323 case 'i': /* wait between sending packets */ 324 interval = strtod(optarg, &p); 325 if (*p != '\0' || interval <= 0) 326 errx(EXIT_FAILURE, "Bad/invalid interval: %s", 327 optarg); 328 /* 329 * In order to avoid overflowing the microseconds 330 * argument of poll() the interval must be less than 331 * INT_MAX/1000. Limit it to one second less than 332 * that to be safe. 333 */ 334 if (interval >= INT_MAX/1000.0 - 1.0) 335 errx(EXIT_FAILURE, 336 "Timing interval %g too large", interval); 337 break; 338 case 'l': 339 l = strtol(optarg, &p, 0); 340 if (*p != '\0' || l < 0) 341 errx(EXIT_FAILURE, "Bad/invalid preload value: " 342 "%s", optarg); 343 #if INT_MAX < LONG_MAX 344 if (l > INT_MAX) 345 errx(EXIT_FAILURE, 346 "Too many preload packets: %ld", l); 347 #endif 348 preload = l; 349 break; 350 case 'n': 351 pingflags |= F_NUMERIC; 352 break; 353 case 'o': 354 pingflags |= F_ONCE; 355 break; 356 case 'p': /* fill buffer with user pattern */ 357 if (pingflags & F_PING_RANDOM) 358 errx(EXIT_FAILURE, 359 "Only one of -P and -p allowed"); 360 pingflags |= F_PING_FILLED; 361 fill_pat = optarg; 362 break; 363 case 'P': 364 if (pingflags & F_PING_FILLED) 365 errx(EXIT_FAILURE, 366 "Only one of -P and -p allowed"); 367 pingflags |= F_PING_RANDOM; 368 break; 369 case 'q': 370 pingflags |= F_QUIET; 371 break; 372 case 'Q': 373 pingflags |= F_SEMI_QUIET; 374 break; 375 case 'r': 376 options |= SO_DONTROUTE; 377 break; 378 case 's': /* size of packet to send */ 379 l = strtol(optarg, &p, 0); 380 if (*p != '\0' || l < 0) 381 errx(EXIT_FAILURE, 382 "Bad/invalid packet size: %s", optarg); 383 if (l > MAXPACKET) 384 errx(EXIT_FAILURE, "packet size is too large"); 385 len = (int)l; 386 break; 387 case 'v': 388 pingflags |= F_VERBOSE; 389 break; 390 case 'R': 391 pingflags |= F_RECORD_ROUTE; 392 break; 393 case 'L': 394 pingflags |= F_MCAST_NOLOOP; 395 break; 396 case 't': 397 tos = strtoul(optarg, &p, 0); 398 if (*p != '\0' || tos > 0xFF) 399 errx(EXIT_FAILURE, "bad tos value: %s", optarg); 400 break; 401 case 'T': 402 l = strtol(optarg, &p, 0); 403 if (*p != '\0' || l > 255 || l <= 0) 404 errx(EXIT_FAILURE, "ttl out of range: %s", 405 optarg); 406 ttl = (u_char)l; /* cannot check >255 otherwise */ 407 break; 408 case 'I': 409 pingflags |= F_SOURCE_ADDR; 410 gethost("-I", optarg, &src_addr, 0, 0); 411 break; 412 case 'g': 413 pingflags |= F_SOURCE_ROUTE; 414 gethost("-g", optarg, &send_addr, 0, 0); 415 break; 416 case 'w': 417 maxwait = strtod(optarg, &p); 418 if (*p != '\0' || maxwait <= 0) 419 errx(EXIT_FAILURE, "Bad/invalid maxwait time: " 420 "%s", optarg); 421 break; 422 #ifdef IPSEC 423 #ifdef IPSEC_POLICY_IPSEC 424 case 'E': 425 pingflags |= F_POLICY; 426 if (!strncmp("in", optarg, 2)) { 427 policy_in = strdup(optarg); 428 if (!policy_in) 429 err(EXIT_FAILURE, "strdup"); 430 } else if (!strncmp("out", optarg, 3)) { 431 policy_out = strdup(optarg); 432 if (!policy_out) 433 err(EXIT_FAILURE, "strdup"); 434 } else 435 errx(EXIT_FAILURE, "invalid security policy: " 436 "%s", optarg); 437 break; 438 #else 439 case 'A': 440 pingflags |= F_AUTHHDR; 441 break; 442 case 'E': 443 pingflags |= F_ENCRYPT; 444 break; 445 #endif /*IPSEC_POLICY_IPSEC*/ 446 #endif /*IPSEC*/ 447 default: 448 usage(); 449 break; 450 } 451 } 452 453 if (interval == 0) 454 interval = (pingflags & F_FLOOD) ? FLOOD_INTVL : 1.0; 455 if (pingflags & F_FLOOD && prog_getuid()) 456 errx(EXIT_FAILURE, "Must be superuser to use -f"); 457 if (interval < 1.0 && prog_getuid()) 458 errx(EXIT_FAILURE, "Must be superuser to use < 1 sec " 459 "ping interval"); 460 if (preload > 0 && prog_getuid()) 461 errx(EXIT_FAILURE, "Must be superuser to use -l"); 462 463 sec_to_timespec(interval, &interval_tv); 464 if (interval_tv.tv_sec == 0 && interval_tv.tv_nsec == 0) { 465 errx(EXIT_FAILURE, "Packet interval must be at least 1 ns"); 466 } 467 468 if ((pingflags & (F_AUDIBLE|F_FLOOD)) == (F_AUDIBLE|F_FLOOD)) 469 warnx("Sorry, no audible output for flood pings"); 470 471 if (npackets != 0) { 472 npackets += preload; 473 } else { 474 npackets = INT_MAX; 475 } 476 477 if (hostind == 0) { 478 if (optind != argc-1) 479 usage(); 480 else 481 hostind = optind; 482 } 483 else if (hostind >= argc - 1) 484 usage(); 485 486 gethost("", argv[hostind], &whereto, hostname, sizeof(hostname)); 487 if (IN_MULTICAST(ntohl(whereto.sin_addr.s_addr))) 488 pingflags |= F_MCAST; 489 if (!(pingflags & F_SOURCE_ROUTE)) 490 (void) memcpy(&send_addr, &whereto, sizeof(send_addr)); 491 492 loc_addr.sin_family = AF_INET; 493 loc_addr.sin_len = sizeof(struct sockaddr_in); 494 loc_addr.sin_addr.s_addr = htonl((127 << 24) + 1); 495 496 if (len != -1) 497 datalen = len; 498 else 499 datalen = 64 - ICMP_HEADER_LEN; 500 if (!compat && datalen >= (int)PHDR64_LEN) { /* can we time them? */ 501 pingflags |= F_TIMING64; 502 phdrlen = PHDR64_LEN; 503 } else if (datalen >= (int)PHDR_LEN) { /* can we time them? */ 504 pingflags |= F_TIMING; 505 phdrlen = PHDR_LEN; 506 } else 507 phdrlen = 0; 508 509 packlen = datalen + 60 + 76; /* MAXIP + MAXICMP */ 510 if ((packet = malloc(packlen)) == NULL) 511 err(EXIT_FAILURE, "Can't allocate %d bytes", packlen); 512 513 if (pingflags & F_PING_FILLED) { 514 fill(); 515 } else if (pingflags & F_PING_RANDOM) { 516 rnd_fill(); 517 } else { 518 for (i = phdrlen; i < datalen; i++) 519 opack_icmp.icmp_data[i] = i; 520 } 521 522 ident = arc4random() & 0xFFFF; 523 524 if (options & SO_DEBUG) { 525 if (prog_setsockopt(s, SOL_SOCKET, SO_DEBUG, 526 (char *)&on, sizeof(on)) == -1) 527 warn("Can't turn on socket debugging"); 528 } 529 if (options & SO_DONTROUTE) { 530 if (prog_setsockopt(s, SOL_SOCKET, SO_DONTROUTE, 531 (char *)&on, sizeof(on)) == -1) 532 warn("SO_DONTROUTE"); 533 } 534 535 if (options & SO_DEBUG) { 536 if (prog_setsockopt(sloop, SOL_SOCKET, SO_DEBUG, 537 (char *)&on, sizeof(on)) == -1) 538 warn("Can't turn on socket debugging"); 539 } 540 if (options & SO_DONTROUTE) { 541 if (prog_setsockopt(sloop, SOL_SOCKET, SO_DONTROUTE, 542 (char *)&on, sizeof(on)) == -1) 543 warn("SO_DONTROUTE"); 544 } 545 546 if (pingflags & F_SOURCE_ROUTE) { 547 optspace[IPOPT_OPTVAL] = IPOPT_LSRR; 548 optspace[IPOPT_OLEN] = optlen = 7; 549 optspace[IPOPT_OFFSET] = IPOPT_MINOFF; 550 (void)memcpy(&optspace[IPOPT_MINOFF-1], &whereto.sin_addr, 551 sizeof(whereto.sin_addr)); 552 optspace[optlen++] = IPOPT_NOP; 553 } 554 if (pingflags & F_RECORD_ROUTE) { 555 optspace[optlen+IPOPT_OPTVAL] = IPOPT_RR; 556 optspace[optlen+IPOPT_OLEN] = (MAX_IPOPTLEN -1-optlen); 557 optspace[optlen+IPOPT_OFFSET] = IPOPT_MINOFF; 558 optlen = MAX_IPOPTLEN; 559 } 560 /* this leaves opack_ip 0(mod 4) aligned */ 561 opack_ip = (struct ip *)((char *)&out_pack.o_ip 562 + sizeof(out_pack.o_opt) 563 - optlen); 564 (void) memcpy(opack_ip + 1, optspace, optlen); 565 566 if (prog_setsockopt(s, IPPROTO_IP, IP_HDRINCL, 567 (char *) &on, sizeof(on)) < 0) 568 err(EXIT_FAILURE, "Can't set special IP header"); 569 570 opack_ip->ip_v = IPVERSION; 571 opack_ip->ip_hl = (sizeof(struct ip)+optlen) >> 2; 572 opack_ip->ip_tos = tos; 573 opack_ip->ip_off = (pingflags & F_DF) ? IP_DF : 0; 574 opack_ip->ip_ttl = ttl ? ttl : MAXTTL; 575 opack_ip->ip_p = IPPROTO_ICMP; 576 opack_ip->ip_src = src_addr.sin_addr; 577 opack_ip->ip_dst = send_addr.sin_addr; 578 579 if (pingflags & F_MCAST) { 580 if (pingflags & F_MCAST_NOLOOP) { 581 u_char loop = 0; 582 if (prog_setsockopt(s, IPPROTO_IP, 583 IP_MULTICAST_LOOP, 584 (char *) &loop, 1) < 0) 585 err(EXIT_FAILURE, "Can't disable multicast loopback"); 586 } 587 588 if (ttl != 0 589 && prog_setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, 590 (char *) &ttl, 1) < 0) 591 err(EXIT_FAILURE, "Can't set multicast time-to-live"); 592 593 if ((pingflags & F_SOURCE_ADDR) 594 && prog_setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, 595 (char *) &src_addr.sin_addr, 596 sizeof(src_addr.sin_addr)) < 0) 597 err(EXIT_FAILURE, "Can't set multicast source interface"); 598 599 } else if (pingflags & F_SOURCE_ADDR) { 600 if (prog_setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, 601 (char *) &src_addr.sin_addr, 602 sizeof(src_addr.sin_addr)) < 0) 603 err(EXIT_FAILURE, "Can't set source interface/address"); 604 } 605 #ifdef IPSEC 606 #ifdef IPSEC_POLICY_IPSEC 607 { 608 char *buf; 609 if (pingflags & F_POLICY) { 610 if (policy_in != NULL) { 611 buf = ipsec_set_policy(policy_in, strlen(policy_in)); 612 if (buf == NULL) 613 errx(EXIT_FAILURE, "%s", ipsec_strerror()); 614 if (prog_setsockopt(s, IPPROTO_IP, IP_IPSEC_POLICY, 615 buf, ipsec_get_policylen(buf)) < 0) { 616 err(EXIT_FAILURE, "ipsec policy cannot be " 617 "configured"); 618 } 619 free(buf); 620 } 621 if (policy_out != NULL) { 622 buf = ipsec_set_policy(policy_out, strlen(policy_out)); 623 if (buf == NULL) 624 errx(EXIT_FAILURE, "%s", ipsec_strerror()); 625 if (prog_setsockopt(s, IPPROTO_IP, IP_IPSEC_POLICY, 626 buf, ipsec_get_policylen(buf)) < 0) { 627 err(EXIT_FAILURE, "ipsec policy cannot be " 628 "configured"); 629 } 630 free(buf); 631 } 632 } 633 buf = ipsec_set_policy("out bypass", strlen("out bypass")); 634 if (buf == NULL) 635 errx(EXIT_FAILURE, "%s", ipsec_strerror()); 636 if (prog_setsockopt(sloop, IPPROTO_IP, IP_IPSEC_POLICY, 637 buf, ipsec_get_policylen(buf)) < 0) { 638 #if 0 639 warnx("ipsec is not configured"); 640 #else 641 /* ignore it, should be okay */ 642 #endif 643 } 644 free(buf); 645 } 646 #else 647 { 648 int optval; 649 if (pingflags & F_AUTHHDR) { 650 optval = IPSEC_LEVEL_REQUIRE; 651 #ifdef IP_AUTH_TRANS_LEVEL 652 (void)prog_setsockopt(s, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, 653 (char *)&optval, sizeof(optval)); 654 #else 655 (void)prog_setsockopt(s, IPPROTO_IP, IP_AUTH_LEVEL, 656 (char *)&optval, sizeof(optval)); 657 #endif 658 } 659 if (pingflags & F_ENCRYPT) { 660 optval = IPSEC_LEVEL_REQUIRE; 661 (void)prog_setsockopt(s, IPPROTO_IP, IP_ESP_TRANS_LEVEL, 662 (char *)&optval, sizeof(optval)); 663 } 664 optval = IPSEC_LEVEL_BYPASS; 665 #ifdef IP_AUTH_TRANS_LEVEL 666 (void)prog_setsockopt(sloop, IPPROTO_IP, IP_AUTH_TRANS_LEVEL, 667 (char *)&optval, sizeof(optval)); 668 #else 669 (void)prog_setsockopt(sloop, IPPROTO_IP, IP_AUTH_LEVEL, 670 (char *)&optval, sizeof(optval)); 671 #endif 672 (void)prog_setsockopt(sloop, IPPROTO_IP, IP_ESP_TRANS_LEVEL, 673 (char *)&optval, sizeof(optval)); 674 } 675 #endif /*IPSEC_POLICY_IPSEC*/ 676 #endif /*IPSEC*/ 677 678 (void)printf("PING %s (%s): %d data bytes\n", hostname, 679 inet_ntoa(whereto.sin_addr), datalen); 680 681 /* When pinging the broadcast address, you can get a lot 682 * of answers. Doing something so evil is useful if you 683 * are trying to stress the ethernet, or just want to 684 * fill the arp cache to get some stuff for /etc/ethers. 685 */ 686 while (0 > prog_setsockopt(s, SOL_SOCKET, SO_RCVBUF, 687 (char*)&bufspace, sizeof(bufspace))) { 688 if ((bufspace -= 4096) <= 0) 689 err(EXIT_FAILURE, "Cannot set the receive buffer size"); 690 } 691 692 /* make it possible to send giant probes, but do not worry now 693 * if it fails, since we probably won't send giant probes. 694 */ 695 (void)prog_setsockopt(s, SOL_SOCKET, SO_SNDBUF, 696 (char*)&bufspace, sizeof(bufspace)); 697 698 (void)signal(SIGINT, prefinish); 699 700 /* 701 * Set up two signal masks: 702 * - blockmask blocks the signals we catch 703 * - enablemask does not 704 */ 705 706 sigemptyset(&enablemask); 707 sigemptyset(&blockmask); 708 sigaddset(&blockmask, SIGINT); 709 #ifdef SIGINFO 710 sigaddset(&blockmask, SIGINFO); 711 #else 712 sigaddset(&blockmask, SIGQUIT); 713 #endif 714 715 #ifdef SIGINFO 716 sa.sa_handler = prtsig; 717 sa.sa_flags = SA_NOKERNINFO; 718 sigemptyset(&sa.sa_mask); 719 (void)sigaction(SIGINFO, &sa, NULL); 720 #else 721 (void)signal(SIGQUIT, prtsig); 722 #endif 723 (void)signal(SIGCONT, prtsig); 724 725 blocksignals(); 726 727 /* fire off them quickies */ 728 for (i = 0; i < preload; i++) { 729 clock_gettime(CLOCK_MONOTONIC, &now); 730 pinger(); 731 } 732 733 doit(); 734 return 0; 735 } 736 737 static void 738 doit(void) 739 { 740 int cc; 741 struct sockaddr_in from; 742 socklen_t fromlen; 743 double sec, last, d_last; 744 struct pollfd fdmaskp[1]; 745 746 (void)clock_gettime(CLOCK_MONOTONIC, &clear_cache); 747 if (maxwait != 0) { 748 last = timespec_to_sec(&clear_cache) + maxwait; 749 d_last = 0; 750 } else { 751 last = 0; 752 d_last = 365*24*60*60; 753 } 754 755 do { 756 clock_gettime(CLOCK_MONOTONIC, &now); 757 758 if (last != 0) 759 d_last = last - timespec_to_sec(&now); 760 761 if (ntransmitted < npackets && d_last > 0) { 762 /* send if within 100 usec or late for next packet */ 763 sec = diffsec(&next_tx, &now); 764 if (sec <= 0.0001 || 765 (lastrcvd && (pingflags & F_FLOOD))) { 766 pinger(); 767 sec = diffsec(&next_tx, &now); 768 } 769 if (sec < 0.0) 770 sec = 0.0; 771 if (d_last < sec) 772 sec = d_last; 773 774 } else { 775 /* For the last response, wait twice as long as the 776 * worst case seen, or 10 times as long as the 777 * maximum interpacket interval, whichever is longer. 778 */ 779 sec = MAX(2 * tmax, 10 * interval) - 780 diffsec(&now, &last_tx); 781 if (d_last < sec) 782 sec = d_last; 783 if (sec <= 0) 784 break; 785 } 786 787 788 fdmaskp[0].fd = s; 789 fdmaskp[0].events = POLLIN; 790 791 enablesignals(); 792 cc = prog_poll(fdmaskp, 1, (int)(sec * 1000)); 793 blocksignals(); 794 795 if (cc <= 0) { 796 if (cc < 0) { 797 if (errno == EINTR) 798 continue; 799 jiggle_flush(1); 800 err(EXIT_FAILURE, "poll"); 801 } 802 continue; 803 } 804 805 fromlen = sizeof(from); 806 cc = prog_recvfrom(s, (char *) packet, packlen, 807 0, (struct sockaddr *)&from, 808 &fromlen); 809 if (cc < 0) { 810 if (errno != EINTR) { 811 jiggle_flush(1); 812 warn("recvfrom"); 813 (void)fflush(stderr); 814 } 815 continue; 816 } 817 clock_gettime(CLOCK_MONOTONIC, &now); 818 pr_pack(packet, cc, &from); 819 820 } while (nreceived < npackets 821 && (nreceived == 0 || !(pingflags & F_ONCE))); 822 823 finish(0); 824 } 825 826 827 static void 828 jiggle_flush(int nl) /* new line if there are dots */ 829 { 830 int serrno = errno; 831 832 if (jiggle_cnt > 0) { 833 total_jiggled += jiggle_cnt; 834 jiggle_direction = 1; 835 do { 836 (void)putchar('.'); 837 } while (--jiggle_cnt > 0); 838 839 } else if (jiggle_cnt < 0) { 840 total_jiggled -= jiggle_cnt; 841 jiggle_direction = -1; 842 do { 843 (void)putchar('\b'); 844 } while (++jiggle_cnt < 0); 845 } 846 847 if (nl) { 848 if (total_jiggled != 0) 849 (void)putchar('\n'); 850 total_jiggled = 0; 851 jiggle_direction = -1; 852 } 853 854 (void)fflush(stdout); 855 (void)fflush(stderr); 856 jiggle_time = now; 857 errno = serrno; 858 } 859 860 861 /* jiggle the cursor for flood-ping 862 */ 863 static void 864 jiggle(int delta) 865 { 866 double dt; 867 868 if (pingflags & F_QUIET) 869 return; 870 871 /* do not back up into messages */ 872 if (total_jiggled+jiggle_cnt+delta < 0) 873 return; 874 875 jiggle_cnt += delta; 876 877 /* flush the FLOOD dots when things are quiet 878 * or occasionally to make the cursor jiggle. 879 */ 880 dt = diffsec(&last_tx, &jiggle_time); 881 if (dt > 0.2 || (dt >= 0.15 && delta*jiggle_direction < 0)) 882 jiggle_flush(0); 883 } 884 885 886 /* 887 * Compose and transmit an ICMP ECHO REQUEST packet. The IP packet 888 * will be added on by the kernel. The ID field is random, 889 * and the sequence number is an ascending integer. The first phdrlen bytes 890 * of the data portion are used to hold a UNIX "timeval" struct in VAX 891 * byte-order, to compute the round-trip time, or a UNIX "timespec" in native 892 * format. 893 */ 894 static void 895 pinger(void) 896 { 897 struct tv32 tv32; 898 int i, cc, sw; 899 double waittime; 900 long numskip; 901 902 opack_icmp.icmp_code = 0; 903 opack_icmp.icmp_seq = htons((u_int16_t)(ntransmitted)); 904 905 /* clear the cached route in the kernel after an ICMP 906 * response such as a Redirect is seen to stop causing 907 * more such packets. Also clear the cached route 908 * periodically in case of routing changes that make 909 * black holes come and go. 910 */ 911 if (clear_cache.tv_sec != now.tv_sec) { 912 opack_icmp.icmp_type = ICMP_ECHOREPLY; 913 opack_icmp.icmp_id = ~ident; 914 opack_icmp.icmp_cksum = 0; 915 opack_icmp.icmp_cksum = in_cksum((u_int16_t *)&opack_icmp, 916 ICMP_MINLEN); 917 sw = 0; 918 if (prog_setsockopt(sloop, IPPROTO_IP, IP_HDRINCL, 919 (char *)&sw, sizeof(sw)) < 0) 920 err(EXIT_FAILURE, "Can't turn off special IP header"); 921 if (prog_sendto(sloop, (char *) &opack_icmp, 922 ICMP_MINLEN, MSG_DONTROUTE, 923 (struct sockaddr *)&loc_addr, 924 sizeof(struct sockaddr_in)) < 0) { 925 /* 926 * XXX: we only report this as a warning in verbose 927 * mode because people get confused when they see 928 * this error when they are running in single user 929 * mode and they have not configured lo0 930 */ 931 if (pingflags & F_VERBOSE) 932 warn("failed to clear cached route"); 933 } 934 sw = 1; 935 if (prog_setsockopt(sloop, IPPROTO_IP, IP_HDRINCL, 936 (char *)&sw, sizeof(sw)) < 0) 937 err(EXIT_FAILURE, "Can't set special IP header"); 938 939 (void)clock_gettime(CLOCK_MONOTONIC, &clear_cache); 940 } 941 942 opack_icmp.icmp_type = ICMP_ECHO; 943 opack_icmp.icmp_id = ident; 944 945 if (pingflags & F_TIMING) { 946 tv32.tv32_sec = (uint32_t)htonl(now.tv_sec); 947 tv32.tv32_usec = htonl(now.tv_nsec / 1000); 948 (void) memcpy(&opack_icmp.icmp_data[0], &tv32, sizeof(tv32)); 949 } else if (pingflags & F_TIMING64) 950 (void) memcpy(&opack_icmp.icmp_data[0], &now, sizeof(now)); 951 952 cc = MAX(datalen, ICMP_MINLEN) + ICMP_HEADER_LEN; 953 opack_icmp.icmp_cksum = 0; 954 opack_icmp.icmp_cksum = in_cksum((u_int16_t *)&opack_icmp, cc); 955 956 cc += opack_ip->ip_hl<<2; 957 opack_ip->ip_len = cc; 958 i = prog_sendto(s, (char *) opack_ip, cc, 0, 959 (struct sockaddr *)&send_addr, sizeof(struct sockaddr_in)); 960 if (i != cc) { 961 jiggle_flush(1); 962 if (i < 0) 963 warn("sendto"); 964 else 965 warnx("wrote %s %d chars, ret=%d", hostname, cc, i); 966 (void)fflush(stderr); 967 } 968 lastrcvd = 0; 969 970 CLR(ntransmitted); 971 ntransmitted++; 972 973 last_tx = now; 974 if (next_tx.tv_sec == 0) { 975 first_tx = now; 976 next_tx = now; 977 } 978 979 /* Transmit regularly, at always the same microsecond in the 980 * second when going at one packet per second. 981 * If we are at most 100 ms behind, send extras to get caught up. 982 * Otherwise, skip packets we were too slow to send. 983 */ 984 waittime = diffsec(&next_tx, &now); 985 if (waittime < -1.0) { 986 /* very behind - forget about being precise */ 987 next_tx.tv_sec += (int)(-waittime); 988 } else if (waittime < -0.1) { 989 /* behind - skip a few */ 990 if (interval_tv.tv_sec == 0) { 991 numskip = (long)(-waittime / interval_tv.tv_nsec); 992 next_tx.tv_nsec += numskip * interval_tv.tv_nsec; 993 /* 994 * We can add at most one second's worth, but allow 995 * for tv_nsec reaching 2 billion just in case FP 996 * issues strike. 997 */ 998 while (next_tx.tv_nsec >= 1000000000) { 999 next_tx.tv_sec++; 1000 next_tx.tv_nsec -= 1000000000; 1001 } 1002 } else { 1003 do { 1004 timespecadd(&next_tx, &interval_tv, &next_tx); 1005 } while (diffsec(&next_tx, &now) < -0.1); 1006 } 1007 1008 } else if (waittime <= interval) { 1009 timespecadd(&next_tx, &interval_tv, &next_tx); 1010 } 1011 1012 if (pingflags & F_FLOOD) 1013 jiggle(1); 1014 1015 /* While the packet is going out, ready buffer for the next 1016 * packet. Use a fast but not very good random number generator. 1017 */ 1018 if (pingflags & F_PING_RANDOM) 1019 rnd_fill(); 1020 } 1021 1022 1023 static void 1024 pr_pack_sub(int cc, 1025 char *addr, 1026 int seqno, 1027 int dupflag, 1028 int ttl, 1029 double triptime) 1030 { 1031 jiggle_flush(1); 1032 1033 if (pingflags & F_FLOOD) 1034 return; 1035 1036 (void)printf("%d bytes from %s: icmp_seq=%u", cc, addr, seqno); 1037 if (dupflag) 1038 (void)printf(" DUP!"); 1039 (void)printf(" ttl=%d", ttl); 1040 if (pingflags & (F_TIMING|F_TIMING64)) { 1041 const unsigned int prec = (pingflags & F_TIMING64) != 0 ? 6 : 3; 1042 1043 (void)printf(" time=%.*f ms", prec, triptime*1000.0); 1044 } 1045 1046 /* 1047 * Send beep to stderr, since that's more likely than stdout 1048 * to go to a terminal.. 1049 */ 1050 if (pingflags & F_AUDIBLE && !dupflag) 1051 (void)fprintf(stderr,"\a"); 1052 } 1053 1054 1055 /* 1056 * Print out the packet, if it came from us. This logic is necessary 1057 * because ALL readers of the ICMP socket get a copy of ALL ICMP packets 1058 * which arrive ('tis only fair). This permits multiple copies of this 1059 * program to be run without having intermingled output (or statistics!). 1060 */ 1061 static void 1062 pr_pack(u_char *buf, 1063 int tot_len, 1064 struct sockaddr_in *from) 1065 { 1066 struct ip *ip; 1067 struct icmp *icp; 1068 int i, j, net_len; 1069 u_char *cp; 1070 static int old_rrlen; 1071 static char old_rr[MAX_IPOPTLEN]; 1072 int hlen, dupflag = 0, dumped; 1073 double triptime = 0.0; 1074 #define PR_PACK_SUB() {if (!dumped) { \ 1075 dumped = 1; \ 1076 pr_pack_sub(net_len, inet_ntoa(from->sin_addr), \ 1077 ntohs((u_int16_t)icp->icmp_seq), \ 1078 dupflag, ip->ip_ttl, triptime);}} 1079 1080 /* Check the IP header */ 1081 ip = (struct ip *) buf; 1082 hlen = ip->ip_hl << 2; 1083 if (hlen < (int)sizeof(*ip) || tot_len < hlen + ICMP_MINLEN) { 1084 if (pingflags & F_VERBOSE) { 1085 jiggle_flush(1); 1086 (void)printf("packet too short (%d bytes) from %s\n", 1087 tot_len, inet_ntoa(from->sin_addr)); 1088 } 1089 return; 1090 } 1091 1092 /* Now the ICMP part */ 1093 dumped = 0; 1094 net_len = tot_len - hlen; 1095 icp = (struct icmp *)(buf + hlen); 1096 if (icp->icmp_type == ICMP_ECHOREPLY 1097 && icp->icmp_id == ident) { 1098 1099 if (icp->icmp_seq == htons((u_int16_t)(ntransmitted-1))) 1100 lastrcvd = 1; 1101 last_rx = now; 1102 if (first_rx.tv_sec == 0) 1103 first_rx = last_rx; 1104 nreceived++; 1105 if (pingflags & (F_TIMING|F_TIMING64)) { 1106 struct timespec tv; 1107 1108 if (pingflags & F_TIMING) { 1109 struct tv32 tv32; 1110 1111 (void)memcpy(&tv32, icp->icmp_data, sizeof(tv32)); 1112 tv.tv_sec = (uint32_t)ntohl(tv32.tv32_sec); 1113 tv.tv_nsec = ntohl(tv32.tv32_usec) * 1000; 1114 } else if (pingflags & F_TIMING64) 1115 (void)memcpy(&tv, icp->icmp_data, sizeof(tv)); 1116 else 1117 memset(&tv, 0, sizeof(tv)); /* XXX: gcc */ 1118 1119 triptime = diffsec(&last_rx, &tv); 1120 tsum += triptime; 1121 tsumsq += triptime * triptime; 1122 if (triptime < tmin) 1123 tmin = triptime; 1124 if (triptime > tmax) 1125 tmax = triptime; 1126 } 1127 1128 if (TST(ntohs((u_int16_t)icp->icmp_seq))) { 1129 nrepeats++, nreceived--; 1130 dupflag=1; 1131 } else { 1132 SET(ntohs((u_int16_t)icp->icmp_seq)); 1133 } 1134 1135 if (tot_len != opack_ip->ip_len) { 1136 PR_PACK_SUB(); 1137 switch (opack_ip->ip_len - tot_len) { 1138 case MAX_IPOPTLEN: 1139 if ((pongflags & F_RECORD_ROUTE) != 0) 1140 break; 1141 if ((pingflags & F_RECORD_ROUTE) == 0) 1142 goto out; 1143 pongflags |= F_RECORD_ROUTE; 1144 (void)printf("\nremote host does not " 1145 "support record route"); 1146 break; 1147 case 8: 1148 if ((pongflags & F_SOURCE_ROUTE) != 0) 1149 break; 1150 if ((pingflags & F_SOURCE_ROUTE) == 0) 1151 goto out; 1152 pongflags |= F_SOURCE_ROUTE; 1153 (void)printf("\nremote host does not " 1154 "support source route"); 1155 break; 1156 default: 1157 out: 1158 (void)printf("\nwrong total length %d " 1159 "instead of %d", tot_len, opack_ip->ip_len); 1160 break; 1161 } 1162 } 1163 1164 if (!dupflag) { 1165 static u_int16_t last_seqno = 0xffff; 1166 u_int16_t seqno = ntohs((u_int16_t)icp->icmp_seq); 1167 u_int16_t gap = seqno - (last_seqno + 1); 1168 if (gap > 0 && gap < 0x8000 && 1169 (pingflags & F_VERBOSE)) { 1170 (void)printf("[*** sequence gap of %u " 1171 "packets from %u ... %u ***]\n", gap, 1172 (u_int16_t) (last_seqno + 1), 1173 (u_int16_t) (seqno - 1)); 1174 if (pingflags & F_QUIET) 1175 summary(0); 1176 } 1177 1178 if (gap < 0x8000) 1179 last_seqno = seqno; 1180 } 1181 1182 if (pingflags & F_QUIET) 1183 return; 1184 1185 if (!(pingflags & F_FLOOD)) 1186 PR_PACK_SUB(); 1187 1188 /* check the data */ 1189 if ((size_t)(tot_len - hlen) > 1190 offsetof(struct icmp, icmp_data) + datalen 1191 && !(pingflags & F_PING_RANDOM) 1192 && memcmp(icp->icmp_data + phdrlen, 1193 opack_icmp.icmp_data + phdrlen, 1194 datalen - phdrlen)) { 1195 for (i = phdrlen; i < datalen; i++) { 1196 if (icp->icmp_data[i] != 1197 opack_icmp.icmp_data[i]) 1198 break; 1199 } 1200 PR_PACK_SUB(); 1201 (void)printf("\nwrong data byte #%d should have been" 1202 " %#x but was %#x", i - phdrlen, 1203 (u_char)opack_icmp.icmp_data[i], 1204 (u_char)icp->icmp_data[i]); 1205 for (i = phdrlen; i < datalen; i++) { 1206 if ((i % 16) == 0) 1207 (void)printf("\n\t"); 1208 (void)printf("%2x ",(u_char)icp->icmp_data[i]); 1209 } 1210 } 1211 1212 } else { 1213 if (!pr_icmph(icp, from, net_len)) 1214 return; 1215 dumped = 2; 1216 } 1217 1218 /* Display any IP options */ 1219 cp = buf + sizeof(struct ip); 1220 while (hlen > (int)sizeof(struct ip)) { 1221 switch (*cp) { 1222 case IPOPT_EOL: 1223 hlen = 0; 1224 break; 1225 case IPOPT_LSRR: 1226 hlen -= 2; 1227 j = *++cp; 1228 ++cp; 1229 j -= IPOPT_MINOFF; 1230 if (j <= 0) 1231 continue; 1232 if (dumped <= 1) { 1233 j = ((j+3)/4)*4; 1234 hlen -= j; 1235 cp += j; 1236 break; 1237 } 1238 PR_PACK_SUB(); 1239 (void)printf("\nLSRR: "); 1240 for (;;) { 1241 pr_saddr(cp); 1242 cp += 4; 1243 hlen -= 4; 1244 j -= 4; 1245 if (j <= 0) 1246 break; 1247 (void)putchar('\n'); 1248 } 1249 break; 1250 case IPOPT_RR: 1251 j = *++cp; /* get length */ 1252 i = *++cp; /* and pointer */ 1253 hlen -= 2; 1254 if (i > j) 1255 i = j; 1256 i -= IPOPT_MINOFF; 1257 if (i <= 0) 1258 continue; 1259 if (dumped <= 1) { 1260 if (i == old_rrlen 1261 && !memcmp(cp, old_rr, i)) { 1262 if (dumped) 1263 (void)printf("\t(same route)"); 1264 j = ((i+3)/4)*4; 1265 hlen -= j; 1266 cp += j; 1267 break; 1268 } 1269 old_rrlen = i; 1270 (void) memcpy(old_rr, cp, i); 1271 } 1272 if (!dumped) { 1273 jiggle_flush(1); 1274 (void)printf("RR: "); 1275 dumped = 1; 1276 } else { 1277 (void)printf("\nRR: "); 1278 } 1279 for (;;) { 1280 pr_saddr(cp); 1281 cp += 4; 1282 hlen -= 4; 1283 i -= 4; 1284 if (i <= 0) 1285 break; 1286 (void)putchar('\n'); 1287 } 1288 break; 1289 case IPOPT_NOP: 1290 if (dumped <= 1) 1291 break; 1292 PR_PACK_SUB(); 1293 (void)printf("\nNOP"); 1294 break; 1295 default: 1296 PR_PACK_SUB(); 1297 (void)printf("\nunknown option 0x%x", *cp); 1298 break; 1299 } 1300 hlen--; 1301 cp++; 1302 } 1303 1304 if (dumped) { 1305 (void)putchar('\n'); 1306 (void)fflush(stdout); 1307 } else { 1308 jiggle(-1); 1309 } 1310 } 1311 1312 1313 /* Compute the IP checksum 1314 * This assumes the packet is less than 32K long. 1315 */ 1316 static u_int16_t 1317 in_cksum(u_int16_t *p, u_int len) 1318 { 1319 u_int32_t sum = 0; 1320 int nwords = len >> 1; 1321 1322 while (nwords-- != 0) 1323 sum += *p++; 1324 1325 if (len & 1) { 1326 union { 1327 u_int16_t w; 1328 u_int8_t c[2]; 1329 } u; 1330 u.c[0] = *(u_char *)p; 1331 u.c[1] = 0; 1332 sum += u.w; 1333 } 1334 1335 /* end-around-carry */ 1336 sum = (sum >> 16) + (sum & 0xffff); 1337 sum += (sum >> 16); 1338 return (~sum); 1339 } 1340 1341 1342 /* 1343 * compute the difference of two timespecs in seconds 1344 */ 1345 static double 1346 diffsec(struct timespec *timenow, 1347 struct timespec *then) 1348 { 1349 if (timenow->tv_sec == 0) 1350 return -1; 1351 return (timenow->tv_sec - then->tv_sec) 1352 * 1.0 + (timenow->tv_nsec - then->tv_nsec) / 1000000000.0; 1353 } 1354 1355 1356 #if 0 1357 static void 1358 timespecadd(struct timespec *t1, 1359 struct timespec *t2) 1360 { 1361 1362 t1->tv_sec += t2->tv_sec; 1363 if ((t1->tv_nsec += t2->tv_nsec) >= 1000000000) { 1364 t1->tv_sec++; 1365 t1->tv_nsec -= 1000000000; 1366 } 1367 } 1368 #endif 1369 1370 1371 static void 1372 sec_to_timespec(const double sec, struct timespec *tp) 1373 { 1374 tp->tv_sec = sec; 1375 tp->tv_nsec = (sec - tp->tv_sec) * 1000000000.0; 1376 } 1377 1378 1379 static double 1380 timespec_to_sec(const struct timespec *tp) 1381 { 1382 return tp->tv_sec + tp->tv_nsec / 1000000000.0; 1383 } 1384 1385 1386 /* 1387 * Print statistics. 1388 * Heavily buffered STDIO is used here, so that all the statistics 1389 * will be written with 1 sys-write call. This is nice when more 1390 * than one copy of the program is running on a terminal; it prevents 1391 * the statistics output from becoming intermingled. 1392 */ 1393 static void 1394 summary(int header) 1395 { 1396 jiggle_flush(1); 1397 1398 if (header) 1399 (void)printf("\n----%s PING Statistics----\n", hostname); 1400 (void)printf("%d packets transmitted, ", ntransmitted); 1401 (void)printf("%d packets received, ", nreceived); 1402 if (nrepeats) 1403 (void)printf("+%d duplicates, ", nrepeats); 1404 if (ntransmitted) { 1405 if (nreceived > ntransmitted) 1406 (void)printf("-- somebody's duplicating packets!"); 1407 else 1408 (void)printf("%.1f%% packet loss", 1409 (((ntransmitted-nreceived)*100.0) / 1410 ntransmitted)); 1411 } 1412 (void)printf("\n"); 1413 if (nreceived && (pingflags & (F_TIMING|F_TIMING64))) { 1414 double n = nreceived + nrepeats; 1415 double avg = (tsum / n); 1416 double variance = 0.0; 1417 const unsigned int prec = (pingflags & F_TIMING64) != 0 ? 6 : 3; 1418 if (n>1) 1419 variance = (tsumsq - n*avg*avg) /(n-1); 1420 1421 (void)printf("round-trip min/avg/max/stddev = " 1422 "%.*f/%.*f/%.*f/%.*f ms\n", 1423 prec, tmin * 1000.0, 1424 prec, avg * 1000.0, 1425 prec, tmax * 1000.0, 1426 prec, sqrt(variance) * 1000.0); 1427 if (pingflags & F_FLOOD) { 1428 double r = diffsec(&last_rx, &first_rx); 1429 double t = diffsec(&last_tx, &first_tx); 1430 if (r == 0) 1431 r = 0.0001; 1432 if (t == 0) 1433 t = 0.0001; 1434 (void)printf(" %.1f packets/sec sent, " 1435 " %.1f packets/sec received\n", 1436 ntransmitted/t, nreceived/r); 1437 } 1438 } 1439 } 1440 1441 1442 /* 1443 * Print statistics when SIGINFO is received. 1444 */ 1445 /* ARGSUSED */ 1446 static void 1447 prtsig(int dummy) 1448 { 1449 1450 summary(0); 1451 #ifndef SIGINFO 1452 (void)signal(SIGQUIT, prtsig); 1453 #endif 1454 } 1455 1456 1457 /* 1458 * On the first SIGINT, allow any outstanding packets to dribble in 1459 */ 1460 static void 1461 prefinish(int sig) 1462 { 1463 if (lastrcvd /* quit now if caught up */ 1464 || nreceived == 0) /* or if remote is dead */ 1465 finish(0); 1466 1467 (void)signal(sig, finish); /* do this only the 1st time */ 1468 1469 if (npackets > ntransmitted) /* let the normal limit work */ 1470 npackets = ntransmitted; 1471 } 1472 1473 /* 1474 * Print statistics and give up. 1475 */ 1476 /* ARGSUSED */ 1477 static void 1478 finish(int dummy) 1479 { 1480 #ifdef SIGINFO 1481 (void)signal(SIGINFO, SIG_DFL); 1482 #else 1483 (void)signal(SIGQUIT, SIG_DFL); 1484 #endif 1485 1486 summary(1); 1487 exit(nreceived > 0 ? 0 : 2); 1488 } 1489 1490 static void 1491 blocksignals(void) 1492 { 1493 if (sigprocmask(SIG_SETMASK, &blockmask, NULL) == -1) { 1494 err(EXIT_FAILURE, "blocksignals: sigprocmask"); 1495 } 1496 } 1497 1498 static void 1499 enablesignals(void) 1500 { 1501 if (sigprocmask(SIG_SETMASK, &enablemask, NULL) == -1) { 1502 err(EXIT_FAILURE, "enablesignals: sigprocmask"); 1503 } 1504 } 1505 1506 1507 static int /* 0=do not print it */ 1508 ck_pr_icmph(struct icmp *icp, 1509 struct sockaddr_in *from, 1510 int cc, 1511 int override) /* 1=override VERBOSE if interesting */ 1512 { 1513 int hlen; 1514 struct ip ipb, *ip = &ipb; 1515 struct icmp icp2b, *icp2 = &icp2b; 1516 int res; 1517 1518 if (pingflags & F_VERBOSE) { 1519 res = 1; 1520 jiggle_flush(1); 1521 } else { 1522 res = 0; 1523 } 1524 1525 (void) memcpy(ip, icp->icmp_data, sizeof(*ip)); 1526 hlen = ip->ip_hl << 2; 1527 if (ip->ip_p == IPPROTO_ICMP 1528 && hlen + 6 <= cc) { 1529 (void) memcpy(icp2, &icp->icmp_data[hlen], sizeof(*icp2)); 1530 if (icp2->icmp_id == ident) { 1531 /* remember to clear route cached in kernel 1532 * if this non-Echo-Reply ICMP message was for one 1533 * of our packets. 1534 */ 1535 clear_cache.tv_sec = 0; 1536 1537 if (!res && override 1538 && (pingflags & (F_QUIET|F_SEMI_QUIET)) == 0) { 1539 jiggle_flush(1); 1540 (void)printf("%d bytes from %s: ", 1541 cc, pr_addr(&from->sin_addr)); 1542 res = 1; 1543 } 1544 } 1545 } 1546 1547 return res; 1548 } 1549 1550 1551 /* 1552 * Print a descriptive string about an ICMP header other than an echo reply. 1553 */ 1554 static int /* 0=printed nothing */ 1555 pr_icmph(struct icmp *icp, 1556 struct sockaddr_in *from, 1557 int cc) 1558 { 1559 switch (icp->icmp_type ) { 1560 case ICMP_UNREACH: 1561 if (!ck_pr_icmph(icp, from, cc, 1)) 1562 return 0; 1563 switch (icp->icmp_code) { 1564 case ICMP_UNREACH_NET: 1565 (void)printf("Destination Net Unreachable"); 1566 break; 1567 case ICMP_UNREACH_HOST: 1568 (void)printf("Destination Host Unreachable"); 1569 break; 1570 case ICMP_UNREACH_PROTOCOL: 1571 (void)printf("Destination Protocol Unreachable"); 1572 break; 1573 case ICMP_UNREACH_PORT: 1574 (void)printf("Destination Port Unreachable"); 1575 break; 1576 case ICMP_UNREACH_NEEDFRAG: 1577 (void)printf("frag needed and DF set. Next MTU=%d", 1578 ntohs(icp->icmp_nextmtu)); 1579 break; 1580 case ICMP_UNREACH_SRCFAIL: 1581 (void)printf("Source Route Failed"); 1582 break; 1583 case ICMP_UNREACH_NET_UNKNOWN: 1584 (void)printf("Unreachable unknown net"); 1585 break; 1586 case ICMP_UNREACH_HOST_UNKNOWN: 1587 (void)printf("Unreachable unknown host"); 1588 break; 1589 case ICMP_UNREACH_ISOLATED: 1590 (void)printf("Unreachable host isolated"); 1591 break; 1592 case ICMP_UNREACH_NET_PROHIB: 1593 (void)printf("Net prohibited access"); 1594 break; 1595 case ICMP_UNREACH_HOST_PROHIB: 1596 (void)printf("Host prohibited access"); 1597 break; 1598 case ICMP_UNREACH_TOSNET: 1599 (void)printf("Bad TOS for net"); 1600 break; 1601 case ICMP_UNREACH_TOSHOST: 1602 (void)printf("Bad TOS for host"); 1603 break; 1604 case 13: 1605 (void)printf("Communication prohibited"); 1606 break; 1607 case 14: 1608 (void)printf("Host precedence violation"); 1609 break; 1610 case 15: 1611 (void)printf("Precedence cutoff"); 1612 break; 1613 default: 1614 (void)printf("Bad Destination Unreachable Code: %d", 1615 icp->icmp_code); 1616 break; 1617 } 1618 /* Print returned IP header information */ 1619 pr_retip(icp, cc); 1620 break; 1621 1622 case ICMP_SOURCEQUENCH: 1623 if (!ck_pr_icmph(icp, from, cc, 1)) 1624 return 0; 1625 (void)printf("Source Quench"); 1626 pr_retip(icp, cc); 1627 break; 1628 1629 case ICMP_REDIRECT: 1630 if (!ck_pr_icmph(icp, from, cc, 1)) 1631 return 0; 1632 switch (icp->icmp_code) { 1633 case ICMP_REDIRECT_NET: 1634 (void)printf("Redirect Network"); 1635 break; 1636 case ICMP_REDIRECT_HOST: 1637 (void)printf("Redirect Host"); 1638 break; 1639 case ICMP_REDIRECT_TOSNET: 1640 (void)printf("Redirect Type of Service and Network"); 1641 break; 1642 case ICMP_REDIRECT_TOSHOST: 1643 (void)printf("Redirect Type of Service and Host"); 1644 break; 1645 default: 1646 (void)printf("Redirect--Bad Code: %d", icp->icmp_code); 1647 break; 1648 } 1649 (void)printf(" New router addr: %s", 1650 pr_addr(&icp->icmp_hun.ih_gwaddr)); 1651 pr_retip(icp, cc); 1652 break; 1653 1654 case ICMP_ECHO: 1655 if (!ck_pr_icmph(icp, from, cc, 0)) 1656 return 0; 1657 (void)printf("Echo Request: ID=%d seq=%d", 1658 ntohs(icp->icmp_id), ntohs(icp->icmp_seq)); 1659 break; 1660 1661 case ICMP_ECHOREPLY: 1662 /* displaying other's pings is too noisey */ 1663 #if 0 1664 if (!ck_pr_icmph(icp, from, cc, 0)) 1665 return 0; 1666 (void)printf("Echo Reply: ID=%d seq=%d", 1667 ntohs(icp->icmp_id), ntohs(icp->icmp_seq)); 1668 break; 1669 #else 1670 return 0; 1671 #endif 1672 1673 case ICMP_ROUTERADVERT: 1674 if (!ck_pr_icmph(icp, from, cc, 0)) 1675 return 0; 1676 (void)printf("Router Discovery Advert"); 1677 break; 1678 1679 case ICMP_ROUTERSOLICIT: 1680 if (!ck_pr_icmph(icp, from, cc, 0)) 1681 return 0; 1682 (void)printf("Router Discovery Solicit"); 1683 break; 1684 1685 case ICMP_TIMXCEED: 1686 if (!ck_pr_icmph(icp, from, cc, 1)) 1687 return 0; 1688 switch (icp->icmp_code ) { 1689 case ICMP_TIMXCEED_INTRANS: 1690 (void)printf("Time To Live exceeded"); 1691 break; 1692 case ICMP_TIMXCEED_REASS: 1693 (void)printf("Frag reassembly time exceeded"); 1694 break; 1695 default: 1696 (void)printf("Time exceeded, Bad Code: %d", 1697 icp->icmp_code); 1698 break; 1699 } 1700 pr_retip(icp, cc); 1701 break; 1702 1703 case ICMP_PARAMPROB: 1704 if (!ck_pr_icmph(icp, from, cc, 1)) 1705 return 0; 1706 (void)printf("Parameter problem: pointer = 0x%02x", 1707 icp->icmp_hun.ih_pptr); 1708 pr_retip(icp, cc); 1709 break; 1710 1711 case ICMP_TSTAMP: 1712 if (!ck_pr_icmph(icp, from, cc, 0)) 1713 return 0; 1714 (void)printf("Timestamp"); 1715 break; 1716 1717 case ICMP_TSTAMPREPLY: 1718 if (!ck_pr_icmph(icp, from, cc, 0)) 1719 return 0; 1720 (void)printf("Timestamp Reply"); 1721 break; 1722 1723 case ICMP_IREQ: 1724 if (!ck_pr_icmph(icp, from, cc, 0)) 1725 return 0; 1726 (void)printf("Information Request"); 1727 break; 1728 1729 case ICMP_IREQREPLY: 1730 if (!ck_pr_icmph(icp, from, cc, 0)) 1731 return 0; 1732 (void)printf("Information Reply"); 1733 break; 1734 1735 case ICMP_MASKREQ: 1736 if (!ck_pr_icmph(icp, from, cc, 0)) 1737 return 0; 1738 (void)printf("Address Mask Request"); 1739 break; 1740 1741 case ICMP_MASKREPLY: 1742 if (!ck_pr_icmph(icp, from, cc, 0)) 1743 return 0; 1744 (void)printf("Address Mask Reply"); 1745 break; 1746 1747 default: 1748 if (!ck_pr_icmph(icp, from, cc, 0)) 1749 return 0; 1750 (void)printf("Bad ICMP type: %d", icp->icmp_type); 1751 if (pingflags & F_VERBOSE) 1752 pr_iph(icp, cc); 1753 } 1754 1755 return 1; 1756 } 1757 1758 1759 /* 1760 * Print an IP header with options. 1761 */ 1762 static void 1763 pr_iph(struct icmp *icp, 1764 int cc) 1765 { 1766 int hlen; 1767 u_char *cp; 1768 struct ip __aligned(4) ipb; 1769 struct ip *ip = &ipb; 1770 1771 (void) memcpy(ip, icp->icmp_data, sizeof(*ip)); 1772 1773 hlen = ip->ip_hl << 2; 1774 cp = (u_char *) &icp->icmp_data[20]; /* point to options */ 1775 1776 (void)printf("\n Vr HL TOS Len ID Flg off TTL Pro cks Src Dst\n"); 1777 (void)printf(" %1x %1x %02x %04x %04x", 1778 ip->ip_v, ip->ip_hl, ip->ip_tos, ip->ip_len, ip->ip_id); 1779 (void)printf(" %1x %04x", 1780 ((ip->ip_off)&0xe000)>>13, (ip->ip_off)&0x1fff); 1781 (void)printf(" %02x %02x %04x", 1782 ip->ip_ttl, ip->ip_p, ip->ip_sum); 1783 (void)printf(" %15s ", 1784 inet_ntoa(*(struct in_addr *)&ip->ip_src.s_addr)); 1785 (void)printf(" %s ", inet_ntoa(*(struct in_addr *)&ip->ip_dst.s_addr)); 1786 /* dump any option bytes */ 1787 while (hlen-- > 20 && cp < (u_char*)icp+cc) { 1788 (void)printf("%02x", *cp++); 1789 } 1790 } 1791 1792 /* 1793 * Print an ASCII host address starting from a string of bytes. 1794 */ 1795 static void 1796 pr_saddr(u_char *cp) 1797 { 1798 n_long l; 1799 struct in_addr addr; 1800 1801 l = (u_char)*++cp; 1802 l = (l<<8) + (u_char)*++cp; 1803 l = (l<<8) + (u_char)*++cp; 1804 l = (l<<8) + (u_char)*++cp; 1805 addr.s_addr = htonl(l); 1806 (void)printf("\t%s", (l == 0) ? "0.0.0.0" : pr_addr(&addr)); 1807 } 1808 1809 1810 /* 1811 * Return an ASCII host address 1812 * as a dotted quad and optionally with a hostname 1813 */ 1814 static char * 1815 pr_addr(struct in_addr *addr) /* in network order */ 1816 { 1817 struct hostent *hp; 1818 static char buf[MAXHOSTNAMELEN+4+16+1]; 1819 1820 if ((pingflags & F_NUMERIC) 1821 || !(hp = gethostbyaddr((char *)addr, sizeof(*addr), AF_INET))) { 1822 (void)snprintf(buf, sizeof(buf), "%s", inet_ntoa(*addr)); 1823 } else { 1824 (void)snprintf(buf, sizeof(buf), "%s (%s)", hp->h_name, 1825 inet_ntoa(*addr)); 1826 } 1827 1828 return buf; 1829 } 1830 1831 /* 1832 * Dump some info on a returned (via ICMP) IP packet. 1833 */ 1834 static void 1835 pr_retip(struct icmp *icp, 1836 int cc) 1837 { 1838 int hlen; 1839 u_char *cp; 1840 struct ip ipb, *ip = &ipb; 1841 1842 (void) memcpy(ip, icp->icmp_data, sizeof(*ip)); 1843 1844 if (pingflags & F_VERBOSE) 1845 pr_iph(icp, cc); 1846 1847 hlen = ip->ip_hl << 2; 1848 cp = (u_char *) &icp->icmp_data[hlen]; 1849 1850 if (ip->ip_p == IPPROTO_TCP) { 1851 if (pingflags & F_VERBOSE) 1852 (void)printf("\n TCP: from port %u, to port %u", 1853 (*cp*256+*(cp+1)), (*(cp+2)*256+*(cp+3))); 1854 } else if (ip->ip_p == IPPROTO_UDP) { 1855 if (pingflags & F_VERBOSE) 1856 (void)printf("\n UDP: from port %u, to port %u", 1857 (*cp*256+*(cp+1)), (*(cp+2)*256+*(cp+3))); 1858 } else if (ip->ip_p == IPPROTO_ICMP) { 1859 struct icmp icp2; 1860 (void) memcpy(&icp2, cp, sizeof(icp2)); 1861 if (icp2.icmp_type == ICMP_ECHO) { 1862 if (pingflags & F_VERBOSE) 1863 (void)printf("\n ID=%u icmp_seq=%u", 1864 ntohs((u_int16_t)icp2.icmp_id), 1865 ntohs((u_int16_t)icp2.icmp_seq)); 1866 else 1867 (void)printf(" for icmp_seq=%u", 1868 ntohs((u_int16_t)icp2.icmp_seq)); 1869 } 1870 } 1871 } 1872 1873 static void 1874 fill(void) 1875 { 1876 int i, j, k; 1877 char *cp; 1878 int pat[16]; 1879 1880 for (cp = fill_pat; *cp != '\0'; cp++) { 1881 if (!isxdigit((unsigned char)*cp)) 1882 break; 1883 } 1884 if (cp == fill_pat || *cp != '\0' || (cp-fill_pat) > 16*2) { 1885 (void)fflush(stdout); 1886 errx(EXIT_FAILURE, "\"-p %s\": patterns must be specified with" 1887 " 1-32 hex digits\n", 1888 fill_pat); 1889 } 1890 1891 i = sscanf(fill_pat, 1892 "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 1893 &pat[0], &pat[1], &pat[2], &pat[3], 1894 &pat[4], &pat[5], &pat[6], &pat[7], 1895 &pat[8], &pat[9], &pat[10], &pat[11], 1896 &pat[12], &pat[13], &pat[14], &pat[15]); 1897 1898 for (k = phdrlen, j = 0; k < datalen; k++) { 1899 opack_icmp.icmp_data[k] = pat[j]; 1900 if (++j >= i) 1901 j = 0; 1902 } 1903 1904 if (!(pingflags & F_QUIET)) { 1905 (void)printf("PATTERN: 0x"); 1906 for (j=0; j<i; j++) 1907 (void)printf("%02x", 1908 (u_char)opack_icmp.icmp_data[phdrlen + j]); 1909 (void)printf("\n"); 1910 } 1911 1912 } 1913 1914 1915 static void 1916 rnd_fill(void) 1917 { 1918 static u_int32_t rnd; 1919 int i; 1920 1921 for (i = phdrlen; i < datalen; i++) { 1922 rnd = (3141592621U * rnd + 663896637U); 1923 opack_icmp.icmp_data[i] = rnd>>24; 1924 } 1925 } 1926 1927 1928 static void 1929 gethost(const char *arg, 1930 const char *name, 1931 struct sockaddr_in *sa, 1932 char *realname, 1933 int realname_len) 1934 { 1935 struct hostent *hp; 1936 1937 (void)memset(sa, 0, sizeof(*sa)); 1938 sa->sin_family = AF_INET; 1939 sa->sin_len = sizeof(struct sockaddr_in); 1940 1941 /* If it is an IP address, try to convert it to a name to 1942 * have something nice to display. 1943 */ 1944 if (inet_aton(name, &sa->sin_addr) != 0) { 1945 if (realname) { 1946 if (pingflags & F_NUMERIC) 1947 hp = 0; 1948 else 1949 hp = gethostbyaddr((char *)&sa->sin_addr, 1950 sizeof(sa->sin_addr), AF_INET); 1951 (void)strlcpy(realname, hp ? hp->h_name : name, 1952 realname_len); 1953 } 1954 return; 1955 } 1956 1957 hp = gethostbyname(name); 1958 if (!hp) 1959 errx(EXIT_FAILURE, "Cannot resolve \"%s\" (%s)", 1960 name, hstrerror(h_errno)); 1961 1962 if (hp->h_addrtype != AF_INET) 1963 errx(EXIT_FAILURE, "%s only supported with IP", arg); 1964 1965 (void)memcpy(&sa->sin_addr, hp->h_addr, sizeof(sa->sin_addr)); 1966 1967 if (realname) 1968 (void)strlcpy(realname, hp->h_name, realname_len); 1969 } 1970 1971 1972 static void 1973 usage(void) 1974 { 1975 #ifdef IPSEC 1976 #ifdef IPSEC_POLICY_IPSEC 1977 #define IPSECOPT "\n [-E policy] " 1978 #else 1979 #define IPSECOPT "\n [-AE] " 1980 #endif /*IPSEC_POLICY_IPSEC*/ 1981 #else 1982 #define IPSECOPT "" 1983 #endif /*IPSEC*/ 1984 1985 (void)fprintf(stderr, "usage: \n" 1986 "%s [-aCDdfLnoPQqRrv] [-c count] [-g gateway] [-h host]" 1987 " [-I addr] [-i interval]\n" 1988 " [-l preload] [-p pattern] [-s size] [-T ttl] [-t tos]" 1989 " [-w maxwait] " IPSECOPT "host\n", 1990 getprogname()); 1991 exit(1); 1992 } 1993