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