1/* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Mike Muuss. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 4. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33#if 0 34#ifndef lint 35static const char copyright[] = 36"@(#) Copyright (c) 1989, 1993\n\ 37 The Regents of the University of California. All rights reserved.\n"; 38#endif /* not lint */ 39 40#ifndef lint 41static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93"; 42#endif /* not lint */ 43#endif 44#include <sys/cdefs.h> 45__FBSDID("$FreeBSD: stable/11/sbin/ping/ping.c 342143 2018-12-16 01:19:10Z eugen $"); 46 47/* 48 * P I N G . C 49 * 50 * Using the Internet Control Message Protocol (ICMP) "ECHO" facility, 51 * measure round-trip-delays and packet loss across network paths. 52 * 53 * Author - 54 * Mike Muuss 55 * U. S. Army Ballistic Research Laboratory 56 * December, 1983 57 * 58 * Status - 59 * Public Domain. Distribution Unlimited. 60 * Bugs - 61 * More statistics could always be gathered. 62 * This program has to run SUID to ROOT to access the ICMP socket. 63 */ 64 65#include <sys/param.h> /* NB: we rely on this for <sys/types.h> */ 66#include <sys/capsicum.h> 67#include <sys/socket.h> 68#include <sys/sysctl.h> 69#include <sys/time.h> 70#include <sys/uio.h> 71 72#include <netinet/in.h> 73#include <netinet/in_systm.h> 74#include <netinet/ip.h> 75#include <netinet/ip_icmp.h> 76#include <netinet/ip_var.h> 77#include <arpa/inet.h> 78 79#ifdef HAVE_LIBCASPER 80#include <libcasper.h> 81#include <casper/cap_dns.h> 82#endif 83 84#ifdef IPSEC 85#include <netipsec/ipsec.h> 86#endif /*IPSEC*/ 87 88#include <ctype.h> 89#include <err.h> 90#include <errno.h> 91#include <math.h> 92#include <netdb.h> 93#include <signal.h> 94#include <stdio.h> 95#include <stdlib.h> 96#include <string.h> 97#include <sysexits.h> 98#include <unistd.h> 99 100#define INADDR_LEN ((int)sizeof(in_addr_t)) 101#define TIMEVAL_LEN ((int)sizeof(struct tv32)) 102#define MASK_LEN (ICMP_MASKLEN - ICMP_MINLEN) 103#define TS_LEN (ICMP_TSLEN - ICMP_MINLEN) 104#define DEFDATALEN 56 /* default data length */ 105#define FLOOD_BACKOFF 20000 /* usecs to back off if F_FLOOD mode */ 106 /* runs out of buffer space */ 107#define MAXIPLEN (sizeof(struct ip) + MAX_IPOPTLEN) 108#define MAXICMPLEN (ICMP_ADVLENMIN + MAX_IPOPTLEN) 109#define MAXWAIT 10000 /* max ms to wait for response */ 110#define MAXALARM (60 * 60) /* max seconds for alarm timeout */ 111#define MAXTOS 255 112 113#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */ 114#define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */ 115#define SET(bit) (A(bit) |= B(bit)) 116#define CLR(bit) (A(bit) &= (~B(bit))) 117#define TST(bit) (A(bit) & B(bit)) 118 119struct tv32 { 120 int32_t tv32_sec; 121 int32_t tv32_usec; 122}; 123 124/* various options */ 125static int options; 126#define F_FLOOD 0x0001 127#define F_INTERVAL 0x0002 128#define F_NUMERIC 0x0004 129#define F_PINGFILLED 0x0008 130#define F_QUIET 0x0010 131#define F_RROUTE 0x0020 132#define F_SO_DEBUG 0x0040 133#define F_SO_DONTROUTE 0x0080 134#define F_VERBOSE 0x0100 135#define F_QUIET2 0x0200 136#define F_NOLOOP 0x0400 137#define F_MTTL 0x0800 138#define F_MIF 0x1000 139#define F_AUDIBLE 0x2000 140#ifdef IPSEC 141#ifdef IPSEC_POLICY_IPSEC 142#define F_POLICY 0x4000 143#endif /*IPSEC_POLICY_IPSEC*/ 144#endif /*IPSEC*/ 145#define F_TTL 0x8000 146#define F_MISSED 0x10000 147#define F_ONCE 0x20000 148#define F_HDRINCL 0x40000 149#define F_MASK 0x80000 150#define F_TIME 0x100000 151#define F_SWEEP 0x200000 152#define F_WAITTIME 0x400000 153 154/* 155 * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum 156 * number of received sequence numbers we can keep track of. Change 128 157 * to 8192 for complete accuracy... 158 */ 159#define MAX_DUP_CHK (8 * 128) 160static int mx_dup_ck = MAX_DUP_CHK; 161static char rcvd_tbl[MAX_DUP_CHK / 8]; 162 163static struct sockaddr_in whereto; /* who to ping */ 164static int datalen = DEFDATALEN; 165static int maxpayload; 166static int ssend; /* send socket file descriptor */ 167static int srecv; /* receive socket file descriptor */ 168static u_char outpackhdr[IP_MAXPACKET], *outpack; 169static char BBELL = '\a'; /* characters written for MISSED and AUDIBLE */ 170static char BSPACE = '\b'; /* characters written for flood */ 171static char DOT = '.'; 172static char *hostname; 173static char *shostname; 174static int ident; /* process id to identify our packets */ 175static int uid; /* cached uid for micro-optimization */ 176static u_char icmp_type = ICMP_ECHO; 177static u_char icmp_type_rsp = ICMP_ECHOREPLY; 178static int phdr_len = 0; 179static int send_len; 180 181/* counters */ 182static long nmissedmax; /* max value of ntransmitted - nreceived - 1 */ 183static long npackets; /* max packets to transmit */ 184static long nreceived; /* # of packets we got back */ 185static long nrepeats; /* number of duplicates */ 186static long ntransmitted; /* sequence # for outbound packets = #sent */ 187static long snpackets; /* max packets to transmit in one sweep */ 188static long sntransmitted; /* # of packets we sent in this sweep */ 189static int sweepmax; /* max value of payload in sweep */ 190static int sweepmin = 0; /* start value of payload in sweep */ 191static int sweepincr = 1; /* payload increment in sweep */ 192static int interval = 1000; /* interval between packets, ms */ 193static int waittime = MAXWAIT; /* timeout for each packet */ 194static long nrcvtimeout = 0; /* # of packets we got back after waittime */ 195 196/* timing */ 197static int timing; /* flag to do timing */ 198static double tmin = 999999999.0; /* minimum round trip time */ 199static double tmax = 0.0; /* maximum round trip time */ 200static double tsum = 0.0; /* sum of all times, for doing average */ 201static double tsumsq = 0.0; /* sum of all times squared, for std. dev. */ 202 203/* nonzero if we've been told to finish up */ 204static volatile sig_atomic_t finish_up; 205static volatile sig_atomic_t siginfo_p; 206 207#ifdef HAVE_LIBCASPER 208static cap_channel_t *capdns; 209#endif 210 211static void fill(char *, char *); 212static u_short in_cksum(u_short *, int); 213#ifdef HAVE_LIBCASPER 214static cap_channel_t *capdns_setup(void); 215#endif 216static void check_status(void); 217static void finish(void) __dead2; 218static void pinger(void); 219static char *pr_addr(struct in_addr); 220static char *pr_ntime(n_time); 221static void pr_icmph(struct icmp *); 222static void pr_iph(struct ip *); 223static void pr_pack(char *, int, struct sockaddr_in *, struct timeval *); 224static void pr_retip(struct ip *); 225static void status(int); 226static void stopit(int); 227static void tvsub(struct timeval *, const struct timeval *); 228static void usage(void) __dead2; 229 230int 231main(int argc, char *const *argv) 232{ 233 struct sockaddr_in from, sock_in; 234 struct in_addr ifaddr; 235 struct timeval last, intvl; 236 struct iovec iov; 237 struct ip *ip; 238 struct msghdr msg; 239 struct sigaction si_sa; 240 size_t sz; 241 u_char *datap, packet[IP_MAXPACKET] __aligned(4); 242 char *ep, *source, *target, *payload; 243 struct hostent *hp; 244#ifdef IPSEC_POLICY_IPSEC 245 char *policy_in, *policy_out; 246#endif 247 struct sockaddr_in *to; 248 double t; 249 u_long alarmtimeout; 250 long ltmp; 251 int almost_done, ch, df, hold, i, icmp_len, mib[4], preload; 252 int ssend_errno, srecv_errno, tos, ttl; 253 char ctrl[CMSG_SPACE(sizeof(struct timeval))]; 254 char hnamebuf[MAXHOSTNAMELEN], snamebuf[MAXHOSTNAMELEN]; 255#ifdef IP_OPTIONS 256 char rspace[MAX_IPOPTLEN]; /* record route space */ 257#endif 258 unsigned char loop, mttl; 259 260 payload = source = NULL; 261#ifdef IPSEC_POLICY_IPSEC 262 policy_in = policy_out = NULL; 263#endif 264 cap_rights_t rights; 265 bool cansandbox; 266 267 /* 268 * Do the stuff that we need root priv's for *first*, and 269 * then drop our setuid bit. Save error reporting for 270 * after arg parsing. 271 * 272 * Historicaly ping was using one socket 's' for sending and for 273 * receiving. After capsicum(4) related changes we use two 274 * sockets. It was done for special ping use case - when user 275 * issue ping on multicast or broadcast address replies come 276 * from different addresses, not from the address we 277 * connect(2)'ed to, and send socket do not receive those 278 * packets. 279 */ 280 ssend = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); 281 ssend_errno = errno; 282 srecv = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); 283 srecv_errno = errno; 284 285 if (setuid(getuid()) != 0) 286 err(EX_NOPERM, "setuid() failed"); 287 uid = getuid(); 288 289 if (ssend < 0) { 290 errno = ssend_errno; 291 err(EX_OSERR, "ssend socket"); 292 } 293 294 if (srecv < 0) { 295 errno = srecv_errno; 296 err(EX_OSERR, "srecv socket"); 297 } 298 299 alarmtimeout = df = preload = tos = 0; 300 301 outpack = outpackhdr + sizeof(struct ip); 302 while ((ch = getopt(argc, argv, 303 "Aac:DdfG:g:h:I:i:Ll:M:m:nop:QqRrS:s:T:t:vW:z:" 304#ifdef IPSEC 305#ifdef IPSEC_POLICY_IPSEC 306 "P:" 307#endif /*IPSEC_POLICY_IPSEC*/ 308#endif /*IPSEC*/ 309 )) != -1) 310 { 311 switch(ch) { 312 case 'A': 313 options |= F_MISSED; 314 break; 315 case 'a': 316 options |= F_AUDIBLE; 317 break; 318 case 'c': 319 ltmp = strtol(optarg, &ep, 0); 320 if (*ep || ep == optarg || ltmp <= 0) 321 errx(EX_USAGE, 322 "invalid count of packets to transmit: `%s'", 323 optarg); 324 npackets = ltmp; 325 break; 326 case 'D': 327 options |= F_HDRINCL; 328 df = 1; 329 break; 330 case 'd': 331 options |= F_SO_DEBUG; 332 break; 333 case 'f': 334 if (uid) { 335 errno = EPERM; 336 err(EX_NOPERM, "-f flag"); 337 } 338 options |= F_FLOOD; 339 setbuf(stdout, (char *)NULL); 340 break; 341 case 'G': /* Maximum packet size for ping sweep */ 342 ltmp = strtol(optarg, &ep, 0); 343 if (*ep || ep == optarg || ltmp <= 0) 344 errx(EX_USAGE, "invalid packet size: `%s'", 345 optarg); 346 if (uid != 0 && ltmp > DEFDATALEN) { 347 errno = EPERM; 348 err(EX_NOPERM, 349 "packet size too large: %ld > %u", 350 ltmp, DEFDATALEN); 351 } 352 options |= F_SWEEP; 353 sweepmax = ltmp; 354 break; 355 case 'g': /* Minimum packet size for ping sweep */ 356 ltmp = strtol(optarg, &ep, 0); 357 if (*ep || ep == optarg || ltmp <= 0) 358 errx(EX_USAGE, "invalid packet size: `%s'", 359 optarg); 360 if (uid != 0 && ltmp > DEFDATALEN) { 361 errno = EPERM; 362 err(EX_NOPERM, 363 "packet size too large: %ld > %u", 364 ltmp, DEFDATALEN); 365 } 366 options |= F_SWEEP; 367 sweepmin = ltmp; 368 break; 369 case 'h': /* Packet size increment for ping sweep */ 370 ltmp = strtol(optarg, &ep, 0); 371 if (*ep || ep == optarg || ltmp < 1) 372 errx(EX_USAGE, "invalid increment size: `%s'", 373 optarg); 374 if (uid != 0 && ltmp > DEFDATALEN) { 375 errno = EPERM; 376 err(EX_NOPERM, 377 "packet size too large: %ld > %u", 378 ltmp, DEFDATALEN); 379 } 380 options |= F_SWEEP; 381 sweepincr = ltmp; 382 break; 383 case 'I': /* multicast interface */ 384 if (inet_aton(optarg, &ifaddr) == 0) 385 errx(EX_USAGE, 386 "invalid multicast interface: `%s'", 387 optarg); 388 options |= F_MIF; 389 break; 390 case 'i': /* wait between sending packets */ 391 t = strtod(optarg, &ep) * 1000.0; 392 if (*ep || ep == optarg || t > (double)INT_MAX) 393 errx(EX_USAGE, "invalid timing interval: `%s'", 394 optarg); 395 options |= F_INTERVAL; 396 interval = (int)t; 397 if (uid && interval < 1000) { 398 errno = EPERM; 399 err(EX_NOPERM, "-i interval too short"); 400 } 401 break; 402 case 'L': 403 options |= F_NOLOOP; 404 loop = 0; 405 break; 406 case 'l': 407 ltmp = strtol(optarg, &ep, 0); 408 if (*ep || ep == optarg || ltmp > INT_MAX || ltmp < 0) 409 errx(EX_USAGE, 410 "invalid preload value: `%s'", optarg); 411 if (uid) { 412 errno = EPERM; 413 err(EX_NOPERM, "-l flag"); 414 } 415 preload = ltmp; 416 break; 417 case 'M': 418 switch(optarg[0]) { 419 case 'M': 420 case 'm': 421 options |= F_MASK; 422 break; 423 case 'T': 424 case 't': 425 options |= F_TIME; 426 break; 427 default: 428 errx(EX_USAGE, "invalid message: `%c'", optarg[0]); 429 break; 430 } 431 break; 432 case 'm': /* TTL */ 433 ltmp = strtol(optarg, &ep, 0); 434 if (*ep || ep == optarg || ltmp > MAXTTL || ltmp < 0) 435 errx(EX_USAGE, "invalid TTL: `%s'", optarg); 436 ttl = ltmp; 437 options |= F_TTL; 438 break; 439 case 'n': 440 options |= F_NUMERIC; 441 break; 442 case 'o': 443 options |= F_ONCE; 444 break; 445#ifdef IPSEC 446#ifdef IPSEC_POLICY_IPSEC 447 case 'P': 448 options |= F_POLICY; 449 if (!strncmp("in", optarg, 2)) 450 policy_in = strdup(optarg); 451 else if (!strncmp("out", optarg, 3)) 452 policy_out = strdup(optarg); 453 else 454 errx(1, "invalid security policy"); 455 break; 456#endif /*IPSEC_POLICY_IPSEC*/ 457#endif /*IPSEC*/ 458 case 'p': /* fill buffer with user pattern */ 459 options |= F_PINGFILLED; 460 payload = optarg; 461 break; 462 case 'Q': 463 options |= F_QUIET2; 464 break; 465 case 'q': 466 options |= F_QUIET; 467 break; 468 case 'R': 469 options |= F_RROUTE; 470 break; 471 case 'r': 472 options |= F_SO_DONTROUTE; 473 break; 474 case 'S': 475 source = optarg; 476 break; 477 case 's': /* size of packet to send */ 478 ltmp = strtol(optarg, &ep, 0); 479 if (*ep || ep == optarg || ltmp < 0) 480 errx(EX_USAGE, "invalid packet size: `%s'", 481 optarg); 482 if (uid != 0 && ltmp > DEFDATALEN) { 483 errno = EPERM; 484 err(EX_NOPERM, 485 "packet size too large: %ld > %u", 486 ltmp, DEFDATALEN); 487 } 488 datalen = ltmp; 489 break; 490 case 'T': /* multicast TTL */ 491 ltmp = strtol(optarg, &ep, 0); 492 if (*ep || ep == optarg || ltmp > MAXTTL || ltmp < 0) 493 errx(EX_USAGE, "invalid multicast TTL: `%s'", 494 optarg); 495 mttl = ltmp; 496 options |= F_MTTL; 497 break; 498 case 't': 499 alarmtimeout = strtoul(optarg, &ep, 0); 500 if ((alarmtimeout < 1) || (alarmtimeout == ULONG_MAX)) 501 errx(EX_USAGE, "invalid timeout: `%s'", 502 optarg); 503 if (alarmtimeout > MAXALARM) 504 errx(EX_USAGE, "invalid timeout: `%s' > %d", 505 optarg, MAXALARM); 506 alarm((int)alarmtimeout); 507 break; 508 case 'v': 509 options |= F_VERBOSE; 510 break; 511 case 'W': /* wait ms for answer */ 512 t = strtod(optarg, &ep); 513 if (*ep || ep == optarg || t > (double)INT_MAX) 514 errx(EX_USAGE, "invalid timing interval: `%s'", 515 optarg); 516 options |= F_WAITTIME; 517 waittime = (int)t; 518 break; 519 case 'z': 520 options |= F_HDRINCL; 521 ltmp = strtol(optarg, &ep, 0); 522 if (*ep || ep == optarg || ltmp > MAXTOS || ltmp < 0) 523 errx(EX_USAGE, "invalid TOS: `%s'", optarg); 524 tos = ltmp; 525 break; 526 default: 527 usage(); 528 } 529 } 530 531 if (argc - optind != 1) 532 usage(); 533 target = argv[optind]; 534 535 switch (options & (F_MASK|F_TIME)) { 536 case 0: break; 537 case F_MASK: 538 icmp_type = ICMP_MASKREQ; 539 icmp_type_rsp = ICMP_MASKREPLY; 540 phdr_len = MASK_LEN; 541 if (!(options & F_QUIET)) 542 (void)printf("ICMP_MASKREQ\n"); 543 break; 544 case F_TIME: 545 icmp_type = ICMP_TSTAMP; 546 icmp_type_rsp = ICMP_TSTAMPREPLY; 547 phdr_len = TS_LEN; 548 if (!(options & F_QUIET)) 549 (void)printf("ICMP_TSTAMP\n"); 550 break; 551 default: 552 errx(EX_USAGE, "ICMP_TSTAMP and ICMP_MASKREQ are exclusive."); 553 break; 554 } 555 icmp_len = sizeof(struct ip) + ICMP_MINLEN + phdr_len; 556 if (options & F_RROUTE) 557 icmp_len += MAX_IPOPTLEN; 558 maxpayload = IP_MAXPACKET - icmp_len; 559 if (datalen > maxpayload) 560 errx(EX_USAGE, "packet size too large: %d > %d", datalen, 561 maxpayload); 562 send_len = icmp_len + datalen; 563 datap = &outpack[ICMP_MINLEN + phdr_len + TIMEVAL_LEN]; 564 if (options & F_PINGFILLED) { 565 fill((char *)datap, payload); 566 } 567#ifdef HAVE_LIBCASPER 568 capdns = capdns_setup(); 569#endif 570 if (source) { 571 bzero((char *)&sock_in, sizeof(sock_in)); 572 sock_in.sin_family = AF_INET; 573 if (inet_aton(source, &sock_in.sin_addr) != 0) { 574 shostname = source; 575 } else { 576#ifdef HAVE_LIBCASPER 577 if (capdns != NULL) 578 hp = cap_gethostbyname2(capdns, source, 579 AF_INET); 580 else 581#endif 582 hp = gethostbyname2(source, AF_INET); 583 if (!hp) 584 errx(EX_NOHOST, "cannot resolve %s: %s", 585 source, hstrerror(h_errno)); 586 587 sock_in.sin_len = sizeof sock_in; 588 if ((unsigned)hp->h_length > sizeof(sock_in.sin_addr) || 589 hp->h_length < 0) 590 errx(1, "gethostbyname2: illegal address"); 591 memcpy(&sock_in.sin_addr, hp->h_addr_list[0], 592 sizeof(sock_in.sin_addr)); 593 (void)strncpy(snamebuf, hp->h_name, 594 sizeof(snamebuf) - 1); 595 snamebuf[sizeof(snamebuf) - 1] = '\0'; 596 shostname = snamebuf; 597 } 598 if (bind(ssend, (struct sockaddr *)&sock_in, sizeof sock_in) == 599 -1) 600 err(1, "bind"); 601 } 602 603 bzero(&whereto, sizeof(whereto)); 604 to = &whereto; 605 to->sin_family = AF_INET; 606 to->sin_len = sizeof *to; 607 if (inet_aton(target, &to->sin_addr) != 0) { 608 hostname = target; 609 } else { 610#ifdef HAVE_LIBCASPER 611 if (capdns != NULL) 612 hp = cap_gethostbyname2(capdns, target, AF_INET); 613 else 614#endif 615 hp = gethostbyname2(target, AF_INET); 616 if (!hp) 617 errx(EX_NOHOST, "cannot resolve %s: %s", 618 target, hstrerror(h_errno)); 619 620 if ((unsigned)hp->h_length > sizeof(to->sin_addr)) 621 errx(1, "gethostbyname2 returned an illegal address"); 622 memcpy(&to->sin_addr, hp->h_addr_list[0], sizeof to->sin_addr); 623 (void)strncpy(hnamebuf, hp->h_name, sizeof(hnamebuf) - 1); 624 hnamebuf[sizeof(hnamebuf) - 1] = '\0'; 625 hostname = hnamebuf; 626 } 627 628#ifdef HAVE_LIBCASPER 629 /* From now on we will use only reverse DNS lookups. */ 630 if (capdns != NULL) { 631 const char *types[1]; 632 633 types[0] = "ADDR"; 634 if (cap_dns_type_limit(capdns, types, 1) < 0) 635 err(1, "unable to limit access to system.dns service"); 636 } 637#endif 638 639 if (connect(ssend, (struct sockaddr *)&whereto, sizeof(whereto)) != 0) 640 err(1, "connect"); 641 642 if (options & F_FLOOD && options & F_INTERVAL) 643 errx(EX_USAGE, "-f and -i: incompatible options"); 644 645 if (options & F_FLOOD && IN_MULTICAST(ntohl(to->sin_addr.s_addr))) 646 errx(EX_USAGE, 647 "-f flag cannot be used with multicast destination"); 648 if (options & (F_MIF | F_NOLOOP | F_MTTL) 649 && !IN_MULTICAST(ntohl(to->sin_addr.s_addr))) 650 errx(EX_USAGE, 651 "-I, -L, -T flags cannot be used with unicast destination"); 652 653 if (datalen >= TIMEVAL_LEN) /* can we time transfer */ 654 timing = 1; 655 656 if (!(options & F_PINGFILLED)) 657 for (i = TIMEVAL_LEN; i < datalen; ++i) 658 *datap++ = i; 659 660 ident = getpid() & 0xFFFF; 661 662 hold = 1; 663 if (options & F_SO_DEBUG) { 664 (void)setsockopt(ssend, SOL_SOCKET, SO_DEBUG, (char *)&hold, 665 sizeof(hold)); 666 (void)setsockopt(srecv, SOL_SOCKET, SO_DEBUG, (char *)&hold, 667 sizeof(hold)); 668 } 669 if (options & F_SO_DONTROUTE) 670 (void)setsockopt(ssend, SOL_SOCKET, SO_DONTROUTE, (char *)&hold, 671 sizeof(hold)); 672#ifdef IPSEC 673#ifdef IPSEC_POLICY_IPSEC 674 if (options & F_POLICY) { 675 char *buf; 676 if (policy_in != NULL) { 677 buf = ipsec_set_policy(policy_in, strlen(policy_in)); 678 if (buf == NULL) 679 errx(EX_CONFIG, "%s", ipsec_strerror()); 680 if (setsockopt(srecv, IPPROTO_IP, IP_IPSEC_POLICY, 681 buf, ipsec_get_policylen(buf)) < 0) 682 err(EX_CONFIG, 683 "ipsec policy cannot be configured"); 684 free(buf); 685 } 686 687 if (policy_out != NULL) { 688 buf = ipsec_set_policy(policy_out, strlen(policy_out)); 689 if (buf == NULL) 690 errx(EX_CONFIG, "%s", ipsec_strerror()); 691 if (setsockopt(ssend, IPPROTO_IP, IP_IPSEC_POLICY, 692 buf, ipsec_get_policylen(buf)) < 0) 693 err(EX_CONFIG, 694 "ipsec policy cannot be configured"); 695 free(buf); 696 } 697 } 698#endif /*IPSEC_POLICY_IPSEC*/ 699#endif /*IPSEC*/ 700 701 if (options & F_HDRINCL) { 702 ip = (struct ip*)outpackhdr; 703 if (!(options & (F_TTL | F_MTTL))) { 704 mib[0] = CTL_NET; 705 mib[1] = PF_INET; 706 mib[2] = IPPROTO_IP; 707 mib[3] = IPCTL_DEFTTL; 708 sz = sizeof(ttl); 709 if (sysctl(mib, 4, &ttl, &sz, NULL, 0) == -1) 710 err(1, "sysctl(net.inet.ip.ttl)"); 711 } 712 setsockopt(ssend, IPPROTO_IP, IP_HDRINCL, &hold, sizeof(hold)); 713 ip->ip_v = IPVERSION; 714 ip->ip_hl = sizeof(struct ip) >> 2; 715 ip->ip_tos = tos; 716 ip->ip_id = 0; 717 ip->ip_off = htons(df ? IP_DF : 0); 718 ip->ip_ttl = ttl; 719 ip->ip_p = IPPROTO_ICMP; 720 ip->ip_src.s_addr = source ? sock_in.sin_addr.s_addr : INADDR_ANY; 721 ip->ip_dst = to->sin_addr; 722 } 723 724 if (options & F_NUMERIC) 725 cansandbox = true; 726#ifdef HAVE_LIBCASPER 727 else if (capdns != NULL) 728 cansandbox = true; 729#endif 730 else 731 cansandbox = false; 732 733 /* 734 * Here we enter capability mode. Further down access to global 735 * namespaces (e.g filesystem) is restricted (see capsicum(4)). 736 * We must connect(2) our socket before this point. 737 */ 738 if (cansandbox && cap_enter() < 0 && errno != ENOSYS) 739 err(1, "cap_enter"); 740 741 cap_rights_init(&rights, CAP_RECV, CAP_EVENT, CAP_SETSOCKOPT); 742 if (cap_rights_limit(srecv, &rights) < 0 && errno != ENOSYS) 743 err(1, "cap_rights_limit srecv"); 744 745 cap_rights_init(&rights, CAP_SEND, CAP_SETSOCKOPT); 746 if (cap_rights_limit(ssend, &rights) < 0 && errno != ENOSYS) 747 err(1, "cap_rights_limit ssend"); 748 749 /* record route option */ 750 if (options & F_RROUTE) { 751#ifdef IP_OPTIONS 752 bzero(rspace, sizeof(rspace)); 753 rspace[IPOPT_OPTVAL] = IPOPT_RR; 754 rspace[IPOPT_OLEN] = sizeof(rspace) - 1; 755 rspace[IPOPT_OFFSET] = IPOPT_MINOFF; 756 rspace[sizeof(rspace) - 1] = IPOPT_EOL; 757 if (setsockopt(ssend, IPPROTO_IP, IP_OPTIONS, rspace, 758 sizeof(rspace)) < 0) 759 err(EX_OSERR, "setsockopt IP_OPTIONS"); 760#else 761 errx(EX_UNAVAILABLE, 762 "record route not available in this implementation"); 763#endif /* IP_OPTIONS */ 764 } 765 766 if (options & F_TTL) { 767 if (setsockopt(ssend, IPPROTO_IP, IP_TTL, &ttl, 768 sizeof(ttl)) < 0) { 769 err(EX_OSERR, "setsockopt IP_TTL"); 770 } 771 } 772 if (options & F_NOLOOP) { 773 if (setsockopt(ssend, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, 774 sizeof(loop)) < 0) { 775 err(EX_OSERR, "setsockopt IP_MULTICAST_LOOP"); 776 } 777 } 778 if (options & F_MTTL) { 779 if (setsockopt(ssend, IPPROTO_IP, IP_MULTICAST_TTL, &mttl, 780 sizeof(mttl)) < 0) { 781 err(EX_OSERR, "setsockopt IP_MULTICAST_TTL"); 782 } 783 } 784 if (options & F_MIF) { 785 if (setsockopt(ssend, IPPROTO_IP, IP_MULTICAST_IF, &ifaddr, 786 sizeof(ifaddr)) < 0) { 787 err(EX_OSERR, "setsockopt IP_MULTICAST_IF"); 788 } 789 } 790#ifdef SO_TIMESTAMP 791 { int on = 1; 792 if (setsockopt(srecv, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)) < 0) 793 err(EX_OSERR, "setsockopt SO_TIMESTAMP"); 794 } 795#endif 796 if (sweepmax) { 797 if (sweepmin > sweepmax) 798 errx(EX_USAGE, "Maximum packet size must be no less than the minimum packet size"); 799 800 if (datalen != DEFDATALEN) 801 errx(EX_USAGE, "Packet size and ping sweep are mutually exclusive"); 802 803 if (npackets > 0) { 804 snpackets = npackets; 805 npackets = 0; 806 } else 807 snpackets = 1; 808 datalen = sweepmin; 809 send_len = icmp_len + sweepmin; 810 } 811 if (options & F_SWEEP && !sweepmax) 812 errx(EX_USAGE, "Maximum sweep size must be specified"); 813 814 /* 815 * When pinging the broadcast address, you can get a lot of answers. 816 * Doing something so evil is useful if you are trying to stress the 817 * ethernet, or just want to fill the arp cache to get some stuff for 818 * /etc/ethers. But beware: RFC 1122 allows hosts to ignore broadcast 819 * or multicast pings if they wish. 820 */ 821 822 /* 823 * XXX receive buffer needs undetermined space for mbuf overhead 824 * as well. 825 */ 826 hold = IP_MAXPACKET + 128; 827 (void)setsockopt(srecv, SOL_SOCKET, SO_RCVBUF, (char *)&hold, 828 sizeof(hold)); 829 /* CAP_SETSOCKOPT removed */ 830 cap_rights_init(&rights, CAP_RECV, CAP_EVENT); 831 if (cap_rights_limit(srecv, &rights) < 0 && errno != ENOSYS) 832 err(1, "cap_rights_limit srecv setsockopt"); 833 if (uid == 0) 834 (void)setsockopt(ssend, SOL_SOCKET, SO_SNDBUF, (char *)&hold, 835 sizeof(hold)); 836 /* CAP_SETSOCKOPT removed */ 837 cap_rights_init(&rights, CAP_SEND); 838 if (cap_rights_limit(ssend, &rights) < 0 && errno != ENOSYS) 839 err(1, "cap_rights_limit ssend setsockopt"); 840 841 if (to->sin_family == AF_INET) { 842 (void)printf("PING %s (%s)", hostname, 843 inet_ntoa(to->sin_addr)); 844 if (source) 845 (void)printf(" from %s", shostname); 846 if (sweepmax) 847 (void)printf(": (%d ... %d) data bytes\n", 848 sweepmin, sweepmax); 849 else 850 (void)printf(": %d data bytes\n", datalen); 851 852 } else { 853 if (sweepmax) 854 (void)printf("PING %s: (%d ... %d) data bytes\n", 855 hostname, sweepmin, sweepmax); 856 else 857 (void)printf("PING %s: %d data bytes\n", hostname, datalen); 858 } 859 860 /* 861 * Use sigaction() instead of signal() to get unambiguous semantics, 862 * in particular with SA_RESTART not set. 863 */ 864 865 sigemptyset(&si_sa.sa_mask); 866 si_sa.sa_flags = 0; 867 868 si_sa.sa_handler = stopit; 869 if (sigaction(SIGINT, &si_sa, 0) == -1) { 870 err(EX_OSERR, "sigaction SIGINT"); 871 } 872 873 si_sa.sa_handler = status; 874 if (sigaction(SIGINFO, &si_sa, 0) == -1) { 875 err(EX_OSERR, "sigaction"); 876 } 877 878 if (alarmtimeout > 0) { 879 si_sa.sa_handler = stopit; 880 if (sigaction(SIGALRM, &si_sa, 0) == -1) 881 err(EX_OSERR, "sigaction SIGALRM"); 882 } 883 884 bzero(&msg, sizeof(msg)); 885 msg.msg_name = (caddr_t)&from; 886 msg.msg_iov = &iov; 887 msg.msg_iovlen = 1; 888#ifdef SO_TIMESTAMP 889 msg.msg_control = (caddr_t)ctrl; 890#endif 891 iov.iov_base = packet; 892 iov.iov_len = IP_MAXPACKET; 893 894 if (preload == 0) 895 pinger(); /* send the first ping */ 896 else { 897 if (npackets != 0 && preload > npackets) 898 preload = npackets; 899 while (preload--) /* fire off them quickies */ 900 pinger(); 901 } 902 (void)gettimeofday(&last, NULL); 903 904 if (options & F_FLOOD) { 905 intvl.tv_sec = 0; 906 intvl.tv_usec = 10000; 907 } else { 908 intvl.tv_sec = interval / 1000; 909 intvl.tv_usec = interval % 1000 * 1000; 910 } 911 912 almost_done = 0; 913 while (!finish_up) { 914 struct timeval now, timeout; 915 fd_set rfds; 916 int cc, n; 917 918 check_status(); 919 if ((unsigned)srecv >= FD_SETSIZE) 920 errx(EX_OSERR, "descriptor too large"); 921 FD_ZERO(&rfds); 922 FD_SET(srecv, &rfds); 923 (void)gettimeofday(&now, NULL); 924 timeout.tv_sec = last.tv_sec + intvl.tv_sec - now.tv_sec; 925 timeout.tv_usec = last.tv_usec + intvl.tv_usec - now.tv_usec; 926 while (timeout.tv_usec < 0) { 927 timeout.tv_usec += 1000000; 928 timeout.tv_sec--; 929 } 930 while (timeout.tv_usec >= 1000000) { 931 timeout.tv_usec -= 1000000; 932 timeout.tv_sec++; 933 } 934 if (timeout.tv_sec < 0) 935 timerclear(&timeout); 936 n = select(srecv + 1, &rfds, NULL, NULL, &timeout); 937 if (n < 0) 938 continue; /* Must be EINTR. */ 939 if (n == 1) { 940 struct timeval *tv = NULL; 941#ifdef SO_TIMESTAMP 942 struct cmsghdr *cmsg = (struct cmsghdr *)&ctrl; 943 944 msg.msg_controllen = sizeof(ctrl); 945#endif 946 msg.msg_namelen = sizeof(from); 947 if ((cc = recvmsg(srecv, &msg, 0)) < 0) { 948 if (errno == EINTR) 949 continue; 950 warn("recvmsg"); 951 continue; 952 } 953#ifdef SO_TIMESTAMP 954 if (cmsg->cmsg_level == SOL_SOCKET && 955 cmsg->cmsg_type == SCM_TIMESTAMP && 956 cmsg->cmsg_len == CMSG_LEN(sizeof *tv)) { 957 /* Copy to avoid alignment problems: */ 958 memcpy(&now, CMSG_DATA(cmsg), sizeof(now)); 959 tv = &now; 960 } 961#endif 962 if (tv == NULL) { 963 (void)gettimeofday(&now, NULL); 964 tv = &now; 965 } 966 pr_pack((char *)packet, cc, &from, tv); 967 if ((options & F_ONCE && nreceived) || 968 (npackets && nreceived >= npackets)) 969 break; 970 } 971 if (n == 0 || options & F_FLOOD) { 972 if (sweepmax && sntransmitted == snpackets) { 973 for (i = 0; i < sweepincr ; ++i) 974 *datap++ = i; 975 datalen += sweepincr; 976 if (datalen > sweepmax) 977 break; 978 send_len = icmp_len + datalen; 979 sntransmitted = 0; 980 } 981 if (!npackets || ntransmitted < npackets) 982 pinger(); 983 else { 984 if (almost_done) 985 break; 986 almost_done = 1; 987 intvl.tv_usec = 0; 988 if (nreceived) { 989 intvl.tv_sec = 2 * tmax / 1000; 990 if (!intvl.tv_sec) 991 intvl.tv_sec = 1; 992 } else { 993 intvl.tv_sec = waittime / 1000; 994 intvl.tv_usec = waittime % 1000 * 1000; 995 } 996 } 997 (void)gettimeofday(&last, NULL); 998 if (ntransmitted - nreceived - 1 > nmissedmax) { 999 nmissedmax = ntransmitted - nreceived - 1; 1000 if (options & F_MISSED) 1001 (void)write(STDOUT_FILENO, &BBELL, 1); 1002 } 1003 } 1004 } 1005 finish(); 1006 /* NOTREACHED */ 1007 exit(0); /* Make the compiler happy */ 1008} 1009 1010/* 1011 * stopit -- 1012 * Set the global bit that causes the main loop to quit. 1013 * Do NOT call finish() from here, since finish() does far too much 1014 * to be called from a signal handler. 1015 */ 1016void 1017stopit(int sig __unused) 1018{ 1019 1020 /* 1021 * When doing reverse DNS lookups, the finish_up flag might not 1022 * be noticed for a while. Just exit if we get a second SIGINT. 1023 */ 1024 if (!(options & F_NUMERIC) && finish_up) 1025 _exit(nreceived ? 0 : 2); 1026 finish_up = 1; 1027} 1028 1029/* 1030 * pinger -- 1031 * Compose and transmit an ICMP ECHO REQUEST packet. The IP packet 1032 * will be added on by the kernel. The ID field is our UNIX process ID, 1033 * and the sequence number is an ascending integer. The first TIMEVAL_LEN 1034 * bytes of the data portion are used to hold a UNIX "timeval" struct in 1035 * host byte-order, to compute the round-trip time. 1036 */ 1037static void 1038pinger(void) 1039{ 1040 struct timeval now; 1041 struct tv32 tv32; 1042 struct ip *ip; 1043 struct icmp *icp; 1044 int cc, i; 1045 u_char *packet; 1046 1047 packet = outpack; 1048 icp = (struct icmp *)outpack; 1049 icp->icmp_type = icmp_type; 1050 icp->icmp_code = 0; 1051 icp->icmp_cksum = 0; 1052 icp->icmp_seq = htons(ntransmitted); 1053 icp->icmp_id = ident; /* ID */ 1054 1055 CLR(ntransmitted % mx_dup_ck); 1056 1057 if ((options & F_TIME) || timing) { 1058 (void)gettimeofday(&now, NULL); 1059 1060 tv32.tv32_sec = htonl(now.tv_sec); 1061 tv32.tv32_usec = htonl(now.tv_usec); 1062 if (options & F_TIME) 1063 icp->icmp_otime = htonl((now.tv_sec % (24*60*60)) 1064 * 1000 + now.tv_usec / 1000); 1065 if (timing) 1066 bcopy((void *)&tv32, 1067 (void *)&outpack[ICMP_MINLEN + phdr_len], 1068 sizeof(tv32)); 1069 } 1070 1071 cc = ICMP_MINLEN + phdr_len + datalen; 1072 1073 /* compute ICMP checksum here */ 1074 icp->icmp_cksum = in_cksum((u_short *)icp, cc); 1075 1076 if (options & F_HDRINCL) { 1077 cc += sizeof(struct ip); 1078 ip = (struct ip *)outpackhdr; 1079 ip->ip_len = htons(cc); 1080 ip->ip_sum = in_cksum((u_short *)outpackhdr, cc); 1081 packet = outpackhdr; 1082 } 1083 i = send(ssend, (char *)packet, cc, 0); 1084 if (i < 0 || i != cc) { 1085 if (i < 0) { 1086 if (options & F_FLOOD && errno == ENOBUFS) { 1087 usleep(FLOOD_BACKOFF); 1088 return; 1089 } 1090 warn("sendto"); 1091 } else { 1092 warn("%s: partial write: %d of %d bytes", 1093 hostname, i, cc); 1094 } 1095 } 1096 ntransmitted++; 1097 sntransmitted++; 1098 if (!(options & F_QUIET) && options & F_FLOOD) 1099 (void)write(STDOUT_FILENO, &DOT, 1); 1100} 1101 1102/* 1103 * pr_pack -- 1104 * Print out the packet, if it came from us. This logic is necessary 1105 * because ALL readers of the ICMP socket get a copy of ALL ICMP packets 1106 * which arrive ('tis only fair). This permits multiple copies of this 1107 * program to be run without having intermingled output (or statistics!). 1108 */ 1109static void 1110pr_pack(char *buf, int cc, struct sockaddr_in *from, struct timeval *tv) 1111{ 1112 struct in_addr ina; 1113 u_char *cp, *dp; 1114 struct icmp *icp; 1115 struct ip *ip; 1116 const void *tp; 1117 double triptime; 1118 int dupflag, hlen, i, j, recv_len, seq; 1119 static int old_rrlen; 1120 static char old_rr[MAX_IPOPTLEN]; 1121 1122 /* Check the IP header */ 1123 ip = (struct ip *)buf; 1124 hlen = ip->ip_hl << 2; 1125 recv_len = cc; 1126 if (cc < hlen + ICMP_MINLEN) { 1127 if (options & F_VERBOSE) 1128 warn("packet too short (%d bytes) from %s", cc, 1129 inet_ntoa(from->sin_addr)); 1130 return; 1131 } 1132 1133 /* Now the ICMP part */ 1134 cc -= hlen; 1135 icp = (struct icmp *)(buf + hlen); 1136 if (icp->icmp_type == icmp_type_rsp) { 1137 if (icp->icmp_id != ident) 1138 return; /* 'Twas not our ECHO */ 1139 ++nreceived; 1140 triptime = 0.0; 1141 if (timing) { 1142 struct timeval tv1; 1143 struct tv32 tv32; 1144#ifndef icmp_data 1145 tp = &icp->icmp_ip; 1146#else 1147 tp = icp->icmp_data; 1148#endif 1149 tp = (const char *)tp + phdr_len; 1150 1151 if ((size_t)(cc - ICMP_MINLEN - phdr_len) >= 1152 sizeof(tv1)) { 1153 /* Copy to avoid alignment problems: */ 1154 memcpy(&tv32, tp, sizeof(tv32)); 1155 tv1.tv_sec = ntohl(tv32.tv32_sec); 1156 tv1.tv_usec = ntohl(tv32.tv32_usec); 1157 tvsub(tv, &tv1); 1158 triptime = ((double)tv->tv_sec) * 1000.0 + 1159 ((double)tv->tv_usec) / 1000.0; 1160 tsum += triptime; 1161 tsumsq += triptime * triptime; 1162 if (triptime < tmin) 1163 tmin = triptime; 1164 if (triptime > tmax) 1165 tmax = triptime; 1166 } else 1167 timing = 0; 1168 } 1169 1170 seq = ntohs(icp->icmp_seq); 1171 1172 if (TST(seq % mx_dup_ck)) { 1173 ++nrepeats; 1174 --nreceived; 1175 dupflag = 1; 1176 } else { 1177 SET(seq % mx_dup_ck); 1178 dupflag = 0; 1179 } 1180 1181 if (options & F_QUIET) 1182 return; 1183 1184 if (options & F_WAITTIME && triptime > waittime) { 1185 ++nrcvtimeout; 1186 return; 1187 } 1188 1189 if (options & F_FLOOD) 1190 (void)write(STDOUT_FILENO, &BSPACE, 1); 1191 else { 1192 (void)printf("%d bytes from %s: icmp_seq=%u", cc, 1193 inet_ntoa(*(struct in_addr *)&from->sin_addr.s_addr), 1194 seq); 1195 (void)printf(" ttl=%d", ip->ip_ttl); 1196 if (timing) 1197 (void)printf(" time=%.3f ms", triptime); 1198 if (dupflag) 1199 (void)printf(" (DUP!)"); 1200 if (options & F_AUDIBLE) 1201 (void)write(STDOUT_FILENO, &BBELL, 1); 1202 if (options & F_MASK) { 1203 /* Just prentend this cast isn't ugly */ 1204 (void)printf(" mask=%s", 1205 inet_ntoa(*(struct in_addr *)&(icp->icmp_mask))); 1206 } 1207 if (options & F_TIME) { 1208 (void)printf(" tso=%s", pr_ntime(icp->icmp_otime)); 1209 (void)printf(" tsr=%s", pr_ntime(icp->icmp_rtime)); 1210 (void)printf(" tst=%s", pr_ntime(icp->icmp_ttime)); 1211 } 1212 if (recv_len != send_len) { 1213 (void)printf( 1214 "\nwrong total length %d instead of %d", 1215 recv_len, send_len); 1216 } 1217 /* check the data */ 1218 cp = (u_char*)&icp->icmp_data[phdr_len]; 1219 dp = &outpack[ICMP_MINLEN + phdr_len]; 1220 cc -= ICMP_MINLEN + phdr_len; 1221 i = 0; 1222 if (timing) { /* don't check variable timestamp */ 1223 cp += TIMEVAL_LEN; 1224 dp += TIMEVAL_LEN; 1225 cc -= TIMEVAL_LEN; 1226 i += TIMEVAL_LEN; 1227 } 1228 for (; i < datalen && cc > 0; ++i, ++cp, ++dp, --cc) { 1229 if (*cp != *dp) { 1230 (void)printf("\nwrong data byte #%d should be 0x%x but was 0x%x", 1231 i, *dp, *cp); 1232 (void)printf("\ncp:"); 1233 cp = (u_char*)&icp->icmp_data[0]; 1234 for (i = 0; i < datalen; ++i, ++cp) { 1235 if ((i % 16) == 8) 1236 (void)printf("\n\t"); 1237 (void)printf("%2x ", *cp); 1238 } 1239 (void)printf("\ndp:"); 1240 cp = &outpack[ICMP_MINLEN]; 1241 for (i = 0; i < datalen; ++i, ++cp) { 1242 if ((i % 16) == 8) 1243 (void)printf("\n\t"); 1244 (void)printf("%2x ", *cp); 1245 } 1246 break; 1247 } 1248 } 1249 } 1250 } else { 1251 /* 1252 * We've got something other than an ECHOREPLY. 1253 * See if it's a reply to something that we sent. 1254 * We can compare IP destination, protocol, 1255 * and ICMP type and ID. 1256 * 1257 * Only print all the error messages if we are running 1258 * as root to avoid leaking information not normally 1259 * available to those not running as root. 1260 */ 1261#ifndef icmp_data 1262 struct ip *oip = &icp->icmp_ip; 1263#else 1264 struct ip *oip = (struct ip *)icp->icmp_data; 1265#endif 1266 struct icmp *oicmp = (struct icmp *)(oip + 1); 1267 1268 if (((options & F_VERBOSE) && uid == 0) || 1269 (!(options & F_QUIET2) && 1270 (oip->ip_dst.s_addr == whereto.sin_addr.s_addr) && 1271 (oip->ip_p == IPPROTO_ICMP) && 1272 (oicmp->icmp_type == ICMP_ECHO) && 1273 (oicmp->icmp_id == ident))) { 1274 (void)printf("%d bytes from %s: ", cc, 1275 pr_addr(from->sin_addr)); 1276 pr_icmph(icp); 1277 } else 1278 return; 1279 } 1280 1281 /* Display any IP options */ 1282 cp = (u_char *)buf + sizeof(struct ip); 1283 1284 for (; hlen > (int)sizeof(struct ip); --hlen, ++cp) 1285 switch (*cp) { 1286 case IPOPT_EOL: 1287 hlen = 0; 1288 break; 1289 case IPOPT_LSRR: 1290 case IPOPT_SSRR: 1291 (void)printf(*cp == IPOPT_LSRR ? 1292 "\nLSRR: " : "\nSSRR: "); 1293 j = cp[IPOPT_OLEN] - IPOPT_MINOFF + 1; 1294 hlen -= 2; 1295 cp += 2; 1296 if (j >= INADDR_LEN && 1297 j <= hlen - (int)sizeof(struct ip)) { 1298 for (;;) { 1299 bcopy(++cp, &ina.s_addr, INADDR_LEN); 1300 if (ina.s_addr == 0) 1301 (void)printf("\t0.0.0.0"); 1302 else 1303 (void)printf("\t%s", 1304 pr_addr(ina)); 1305 hlen -= INADDR_LEN; 1306 cp += INADDR_LEN - 1; 1307 j -= INADDR_LEN; 1308 if (j < INADDR_LEN) 1309 break; 1310 (void)putchar('\n'); 1311 } 1312 } else 1313 (void)printf("\t(truncated route)\n"); 1314 break; 1315 case IPOPT_RR: 1316 j = cp[IPOPT_OLEN]; /* get length */ 1317 i = cp[IPOPT_OFFSET]; /* and pointer */ 1318 hlen -= 2; 1319 cp += 2; 1320 if (i > j) 1321 i = j; 1322 i = i - IPOPT_MINOFF + 1; 1323 if (i < 0 || i > (hlen - (int)sizeof(struct ip))) { 1324 old_rrlen = 0; 1325 continue; 1326 } 1327 if (i == old_rrlen 1328 && !bcmp((char *)cp, old_rr, i) 1329 && !(options & F_FLOOD)) { 1330 (void)printf("\t(same route)"); 1331 hlen -= i; 1332 cp += i; 1333 break; 1334 } 1335 old_rrlen = i; 1336 bcopy((char *)cp, old_rr, i); 1337 (void)printf("\nRR: "); 1338 if (i >= INADDR_LEN && 1339 i <= hlen - (int)sizeof(struct ip)) { 1340 for (;;) { 1341 bcopy(++cp, &ina.s_addr, INADDR_LEN); 1342 if (ina.s_addr == 0) 1343 (void)printf("\t0.0.0.0"); 1344 else 1345 (void)printf("\t%s", 1346 pr_addr(ina)); 1347 hlen -= INADDR_LEN; 1348 cp += INADDR_LEN - 1; 1349 i -= INADDR_LEN; 1350 if (i < INADDR_LEN) 1351 break; 1352 (void)putchar('\n'); 1353 } 1354 } else 1355 (void)printf("\t(truncated route)"); 1356 break; 1357 case IPOPT_NOP: 1358 (void)printf("\nNOP"); 1359 break; 1360 default: 1361 (void)printf("\nunknown option %x", *cp); 1362 break; 1363 } 1364 if (!(options & F_FLOOD)) { 1365 (void)putchar('\n'); 1366 (void)fflush(stdout); 1367 } 1368} 1369 1370/* 1371 * in_cksum -- 1372 * Checksum routine for Internet Protocol family headers (C Version) 1373 */ 1374u_short 1375in_cksum(u_short *addr, int len) 1376{ 1377 int nleft, sum; 1378 u_short *w; 1379 union { 1380 u_short us; 1381 u_char uc[2]; 1382 } last; 1383 u_short answer; 1384 1385 nleft = len; 1386 sum = 0; 1387 w = addr; 1388 1389 /* 1390 * Our algorithm is simple, using a 32 bit accumulator (sum), we add 1391 * sequential 16 bit words to it, and at the end, fold back all the 1392 * carry bits from the top 16 bits into the lower 16 bits. 1393 */ 1394 while (nleft > 1) { 1395 sum += *w++; 1396 nleft -= 2; 1397 } 1398 1399 /* mop up an odd byte, if necessary */ 1400 if (nleft == 1) { 1401 last.uc[0] = *(u_char *)w; 1402 last.uc[1] = 0; 1403 sum += last.us; 1404 } 1405 1406 /* add back carry outs from top 16 bits to low 16 bits */ 1407 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ 1408 sum += (sum >> 16); /* add carry */ 1409 answer = ~sum; /* truncate to 16 bits */ 1410 return(answer); 1411} 1412 1413/* 1414 * tvsub -- 1415 * Subtract 2 timeval structs: out = out - in. Out is assumed to 1416 * be >= in. 1417 */ 1418static void 1419tvsub(struct timeval *out, const struct timeval *in) 1420{ 1421 1422 if ((out->tv_usec -= in->tv_usec) < 0) { 1423 --out->tv_sec; 1424 out->tv_usec += 1000000; 1425 } 1426 out->tv_sec -= in->tv_sec; 1427} 1428 1429/* 1430 * status -- 1431 * Print out statistics when SIGINFO is received. 1432 */ 1433 1434static void 1435status(int sig __unused) 1436{ 1437 1438 siginfo_p = 1; 1439} 1440 1441static void 1442check_status(void) 1443{ 1444 1445 if (siginfo_p) { 1446 siginfo_p = 0; 1447 (void)fprintf(stderr, "\r%ld/%ld packets received (%.1f%%)", 1448 nreceived, ntransmitted, 1449 ntransmitted ? nreceived * 100.0 / ntransmitted : 0.0); 1450 if (nreceived && timing) 1451 (void)fprintf(stderr, " %.3f min / %.3f avg / %.3f max", 1452 tmin, tsum / (nreceived + nrepeats), tmax); 1453 (void)fprintf(stderr, "\n"); 1454 } 1455} 1456 1457/* 1458 * finish -- 1459 * Print out statistics, and give up. 1460 */ 1461static void 1462finish(void) 1463{ 1464 1465 (void)signal(SIGINT, SIG_IGN); 1466 (void)signal(SIGALRM, SIG_IGN); 1467 (void)putchar('\n'); 1468 (void)fflush(stdout); 1469 (void)printf("--- %s ping statistics ---\n", hostname); 1470 (void)printf("%ld packets transmitted, ", ntransmitted); 1471 (void)printf("%ld packets received, ", nreceived); 1472 if (nrepeats) 1473 (void)printf("+%ld duplicates, ", nrepeats); 1474 if (ntransmitted) { 1475 if (nreceived > ntransmitted) 1476 (void)printf("-- somebody's printing up packets!"); 1477 else 1478 (void)printf("%.1f%% packet loss", 1479 ((ntransmitted - nreceived) * 100.0) / 1480 ntransmitted); 1481 } 1482 if (nrcvtimeout) 1483 (void)printf(", %ld packets out of wait time", nrcvtimeout); 1484 (void)putchar('\n'); 1485 if (nreceived && timing) { 1486 double n = nreceived + nrepeats; 1487 double avg = tsum / n; 1488 double vari = tsumsq / n - avg * avg; 1489 (void)printf( 1490 "round-trip min/avg/max/stddev = %.3f/%.3f/%.3f/%.3f ms\n", 1491 tmin, avg, tmax, sqrt(vari)); 1492 } 1493 1494 if (nreceived) 1495 exit(0); 1496 else 1497 exit(2); 1498} 1499 1500#ifdef notdef 1501static char *ttab[] = { 1502 "Echo Reply", /* ip + seq + udata */ 1503 "Dest Unreachable", /* net, host, proto, port, frag, sr + IP */ 1504 "Source Quench", /* IP */ 1505 "Redirect", /* redirect type, gateway, + IP */ 1506 "Echo", 1507 "Time Exceeded", /* transit, frag reassem + IP */ 1508 "Parameter Problem", /* pointer + IP */ 1509 "Timestamp", /* id + seq + three timestamps */ 1510 "Timestamp Reply", /* " */ 1511 "Info Request", /* id + sq */ 1512 "Info Reply" /* " */ 1513}; 1514#endif 1515 1516/* 1517 * pr_icmph -- 1518 * Print a descriptive string about an ICMP header. 1519 */ 1520static void 1521pr_icmph(struct icmp *icp) 1522{ 1523 1524 switch(icp->icmp_type) { 1525 case ICMP_ECHOREPLY: 1526 (void)printf("Echo Reply\n"); 1527 /* XXX ID + Seq + Data */ 1528 break; 1529 case ICMP_UNREACH: 1530 switch(icp->icmp_code) { 1531 case ICMP_UNREACH_NET: 1532 (void)printf("Destination Net Unreachable\n"); 1533 break; 1534 case ICMP_UNREACH_HOST: 1535 (void)printf("Destination Host Unreachable\n"); 1536 break; 1537 case ICMP_UNREACH_PROTOCOL: 1538 (void)printf("Destination Protocol Unreachable\n"); 1539 break; 1540 case ICMP_UNREACH_PORT: 1541 (void)printf("Destination Port Unreachable\n"); 1542 break; 1543 case ICMP_UNREACH_NEEDFRAG: 1544 (void)printf("frag needed and DF set (MTU %d)\n", 1545 ntohs(icp->icmp_nextmtu)); 1546 break; 1547 case ICMP_UNREACH_SRCFAIL: 1548 (void)printf("Source Route Failed\n"); 1549 break; 1550 case ICMP_UNREACH_FILTER_PROHIB: 1551 (void)printf("Communication prohibited by filter\n"); 1552 break; 1553 default: 1554 (void)printf("Dest Unreachable, Bad Code: %d\n", 1555 icp->icmp_code); 1556 break; 1557 } 1558 /* Print returned IP header information */ 1559#ifndef icmp_data 1560 pr_retip(&icp->icmp_ip); 1561#else 1562 pr_retip((struct ip *)icp->icmp_data); 1563#endif 1564 break; 1565 case ICMP_SOURCEQUENCH: 1566 (void)printf("Source Quench\n"); 1567#ifndef icmp_data 1568 pr_retip(&icp->icmp_ip); 1569#else 1570 pr_retip((struct ip *)icp->icmp_data); 1571#endif 1572 break; 1573 case ICMP_REDIRECT: 1574 switch(icp->icmp_code) { 1575 case ICMP_REDIRECT_NET: 1576 (void)printf("Redirect Network"); 1577 break; 1578 case ICMP_REDIRECT_HOST: 1579 (void)printf("Redirect Host"); 1580 break; 1581 case ICMP_REDIRECT_TOSNET: 1582 (void)printf("Redirect Type of Service and Network"); 1583 break; 1584 case ICMP_REDIRECT_TOSHOST: 1585 (void)printf("Redirect Type of Service and Host"); 1586 break; 1587 default: 1588 (void)printf("Redirect, Bad Code: %d", icp->icmp_code); 1589 break; 1590 } 1591 (void)printf("(New addr: %s)\n", inet_ntoa(icp->icmp_gwaddr)); 1592#ifndef icmp_data 1593 pr_retip(&icp->icmp_ip); 1594#else 1595 pr_retip((struct ip *)icp->icmp_data); 1596#endif 1597 break; 1598 case ICMP_ECHO: 1599 (void)printf("Echo Request\n"); 1600 /* XXX ID + Seq + Data */ 1601 break; 1602 case ICMP_TIMXCEED: 1603 switch(icp->icmp_code) { 1604 case ICMP_TIMXCEED_INTRANS: 1605 (void)printf("Time to live exceeded\n"); 1606 break; 1607 case ICMP_TIMXCEED_REASS: 1608 (void)printf("Frag reassembly time exceeded\n"); 1609 break; 1610 default: 1611 (void)printf("Time exceeded, Bad Code: %d\n", 1612 icp->icmp_code); 1613 break; 1614 } 1615#ifndef icmp_data 1616 pr_retip(&icp->icmp_ip); 1617#else 1618 pr_retip((struct ip *)icp->icmp_data); 1619#endif 1620 break; 1621 case ICMP_PARAMPROB: 1622 (void)printf("Parameter problem: pointer = 0x%02x\n", 1623 icp->icmp_hun.ih_pptr); 1624#ifndef icmp_data 1625 pr_retip(&icp->icmp_ip); 1626#else 1627 pr_retip((struct ip *)icp->icmp_data); 1628#endif 1629 break; 1630 case ICMP_TSTAMP: 1631 (void)printf("Timestamp\n"); 1632 /* XXX ID + Seq + 3 timestamps */ 1633 break; 1634 case ICMP_TSTAMPREPLY: 1635 (void)printf("Timestamp Reply\n"); 1636 /* XXX ID + Seq + 3 timestamps */ 1637 break; 1638 case ICMP_IREQ: 1639 (void)printf("Information Request\n"); 1640 /* XXX ID + Seq */ 1641 break; 1642 case ICMP_IREQREPLY: 1643 (void)printf("Information Reply\n"); 1644 /* XXX ID + Seq */ 1645 break; 1646 case ICMP_MASKREQ: 1647 (void)printf("Address Mask Request\n"); 1648 break; 1649 case ICMP_MASKREPLY: 1650 (void)printf("Address Mask Reply\n"); 1651 break; 1652 case ICMP_ROUTERADVERT: 1653 (void)printf("Router Advertisement\n"); 1654 break; 1655 case ICMP_ROUTERSOLICIT: 1656 (void)printf("Router Solicitation\n"); 1657 break; 1658 default: 1659 (void)printf("Bad ICMP type: %d\n", icp->icmp_type); 1660 } 1661} 1662 1663/* 1664 * pr_iph -- 1665 * Print an IP header with options. 1666 */ 1667static void 1668pr_iph(struct ip *ip) 1669{ 1670 struct in_addr ina; 1671 u_char *cp; 1672 int hlen; 1673 1674 hlen = ip->ip_hl << 2; 1675 cp = (u_char *)ip + 20; /* point to options */ 1676 1677 (void)printf("Vr HL TOS Len ID Flg off TTL Pro cks Src Dst\n"); 1678 (void)printf(" %1x %1x %02x %04x %04x", 1679 ip->ip_v, ip->ip_hl, ip->ip_tos, ntohs(ip->ip_len), 1680 ntohs(ip->ip_id)); 1681 (void)printf(" %1lx %04lx", 1682 (u_long) (ntohl(ip->ip_off) & 0xe000) >> 13, 1683 (u_long) ntohl(ip->ip_off) & 0x1fff); 1684 (void)printf(" %02x %02x %04x", ip->ip_ttl, ip->ip_p, 1685 ntohs(ip->ip_sum)); 1686 memcpy(&ina, &ip->ip_src.s_addr, sizeof ina); 1687 (void)printf(" %s ", inet_ntoa(ina)); 1688 memcpy(&ina, &ip->ip_dst.s_addr, sizeof ina); 1689 (void)printf(" %s ", inet_ntoa(ina)); 1690 /* dump any option bytes */ 1691 while (hlen-- > 20) { 1692 (void)printf("%02x", *cp++); 1693 } 1694 (void)putchar('\n'); 1695} 1696 1697/* 1698 * pr_addr -- 1699 * Return an ascii host address as a dotted quad and optionally with 1700 * a hostname. 1701 */ 1702static char * 1703pr_addr(struct in_addr ina) 1704{ 1705 struct hostent *hp; 1706 static char buf[16 + 3 + MAXHOSTNAMELEN]; 1707 1708 if (options & F_NUMERIC) 1709 return inet_ntoa(ina); 1710 1711#ifdef HAVE_LIBCASPER 1712 if (capdns != NULL) 1713 hp = cap_gethostbyaddr(capdns, (char *)&ina, 4, AF_INET); 1714 else 1715#endif 1716 hp = gethostbyaddr((char *)&ina, 4, AF_INET); 1717 1718 if (hp == NULL) 1719 return inet_ntoa(ina); 1720 1721 (void)snprintf(buf, sizeof(buf), "%s (%s)", hp->h_name, 1722 inet_ntoa(ina)); 1723 return(buf); 1724} 1725 1726/* 1727 * pr_retip -- 1728 * Dump some info on a returned (via ICMP) IP packet. 1729 */ 1730static void 1731pr_retip(struct ip *ip) 1732{ 1733 u_char *cp; 1734 int hlen; 1735 1736 pr_iph(ip); 1737 hlen = ip->ip_hl << 2; 1738 cp = (u_char *)ip + hlen; 1739 1740 if (ip->ip_p == 6) 1741 (void)printf("TCP: from port %u, to port %u (decimal)\n", 1742 (*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3))); 1743 else if (ip->ip_p == 17) 1744 (void)printf("UDP: from port %u, to port %u (decimal)\n", 1745 (*cp * 256 + *(cp + 1)), (*(cp + 2) * 256 + *(cp + 3))); 1746} 1747 1748static char * 1749pr_ntime(n_time timestamp) 1750{ 1751 static char buf[10]; 1752 int hour, min, sec; 1753 1754 sec = ntohl(timestamp) / 1000; 1755 hour = sec / 60 / 60; 1756 min = (sec % (60 * 60)) / 60; 1757 sec = (sec % (60 * 60)) % 60; 1758 1759 (void)snprintf(buf, sizeof(buf), "%02d:%02d:%02d", hour, min, sec); 1760 1761 return (buf); 1762} 1763 1764static void 1765fill(char *bp, char *patp) 1766{ 1767 char *cp; 1768 int pat[16]; 1769 u_int ii, jj, kk; 1770 1771 for (cp = patp; *cp; cp++) { 1772 if (!isxdigit(*cp)) 1773 errx(EX_USAGE, 1774 "patterns must be specified as hex digits"); 1775 1776 } 1777 ii = sscanf(patp, 1778 "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 1779 &pat[0], &pat[1], &pat[2], &pat[3], &pat[4], &pat[5], &pat[6], 1780 &pat[7], &pat[8], &pat[9], &pat[10], &pat[11], &pat[12], 1781 &pat[13], &pat[14], &pat[15]); 1782 1783 if (ii > 0) 1784 for (kk = 0; kk <= maxpayload - (TIMEVAL_LEN + ii); kk += ii) 1785 for (jj = 0; jj < ii; ++jj) 1786 bp[jj + kk] = pat[jj]; 1787 if (!(options & F_QUIET)) { 1788 (void)printf("PATTERN: 0x"); 1789 for (jj = 0; jj < ii; ++jj) 1790 (void)printf("%02x", bp[jj] & 0xFF); 1791 (void)printf("\n"); 1792 } 1793} 1794 1795#ifdef HAVE_LIBCASPER 1796static cap_channel_t * 1797capdns_setup(void) 1798{ 1799 cap_channel_t *capcas, *capdnsloc; 1800 const char *types[2]; 1801 int families[1]; 1802 1803 capcas = cap_init(); 1804 if (capcas == NULL) 1805 err(1, "unable to create casper process"); 1806 capdnsloc = cap_service_open(capcas, "system.dns"); 1807 /* Casper capability no longer needed. */ 1808 cap_close(capcas); 1809 if (capdnsloc == NULL) 1810 err(1, "unable to open system.dns service"); 1811 types[0] = "NAME"; 1812 types[1] = "ADDR"; 1813 if (cap_dns_type_limit(capdnsloc, types, 2) < 0) 1814 err(1, "unable to limit access to system.dns service"); 1815 families[0] = AF_INET; 1816 if (cap_dns_family_limit(capdnsloc, families, 1) < 0) 1817 err(1, "unable to limit access to system.dns service"); 1818 1819 return (capdnsloc); 1820} 1821#endif /* HAVE_LIBCASPER */ 1822 1823#if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) 1824#define SECOPT " [-P policy]" 1825#else 1826#define SECOPT "" 1827#endif 1828static void 1829usage(void) 1830{ 1831 1832 (void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", 1833"usage: ping [-AaDdfnoQqRrv] [-c count] [-G sweepmaxsize] [-g sweepminsize]", 1834" [-h sweepincrsize] [-i wait] [-l preload] [-M mask | time] [-m ttl]", 1835" " SECOPT " [-p pattern] [-S src_addr] [-s packetsize] [-t timeout]", 1836" [-W waittime] [-z tos] host", 1837" ping [-AaDdfLnoQqRrv] [-c count] [-I iface] [-i wait] [-l preload]", 1838" [-M mask | time] [-m ttl]" SECOPT " [-p pattern] [-S src_addr]", 1839" [-s packetsize] [-T ttl] [-t timeout] [-W waittime]", 1840" [-z tos] mcast-group"); 1841 exit(EX_USAGE); 1842} 1843