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