1 #include "ping_common.h"
13 int mx_dup_ck = MAX_DUP_CHK;
14 char rcvd_tbl[MAX_DUP_CHK / 8];
18 long npackets; /* max packets to transmit */
19 long nreceived; /* # of packets we got back */
20 long nrepeats; /* number of duplicates */
21 long ntransmitted; /* sequence # for outbound packets = #sent */
22 long nchecksum; /* replies with bad checksum */
23 long nerrors; /* icmp errors */
24 int interval = 1000; /* interval between packets (msec) */
26 int deadline = 0; /* time to die */
27 int lingertime = MAXWAIT*1000;
28 struct timeval start_time, cur_time;
30 volatile int status_snapshot;
33 /* Stupid workarounds for bugs/missing functionality in older linuces.
34 * confirm_flag fixes refusing service of kernels without MSG_CONFIRM.
35 * i.e. for linux-2.2 */
36 int confirm_flag = MSG_CONFIRM;
37 /* And this is workaround for bug in IP_RECVERR on raw sockets which is present
38 * in linux-2.2.[0-19], linux-2.4.[0-7] */
42 int timing; /* flag to do timing */
43 long tmin = LONG_MAX; /* minimum round trip time */
44 long tmax; /* maximum round trip time */
45 /* Message for rpm maintainers: have _shame_. If you want
46 * to fix something send the patch to me for sanity checking.
47 * "sparcfix" patch is a complete non-sense, apparenly the person
48 * prepared it was stoned.
50 long long tsum; /* sum of all times, for doing average */
54 int datalen = DEFDATALEN;
58 int ident; /* process id to identify our packets */
60 static int screen_width = INT_MAX;
62 /* Fills all the outpack, excluding ICMP header, but _including_
63 * timestamp area with supplied pattern.
65 static void fill(char *patp)
70 u_char *bp = outpack+8;
72 for (cp = patp; *cp; cp++) {
75 "ping: patterns must be specified as hex digits.\n");
80 "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x",
81 &pat[0], &pat[1], &pat[2], &pat[3], &pat[4], &pat[5], &pat[6],
82 &pat[7], &pat[8], &pat[9], &pat[10], &pat[11], &pat[12],
83 &pat[13], &pat[14], &pat[15]);
86 for (kk = 0; kk <= maxpacket - (8 + ii); kk += ii)
87 for (jj = 0; jj < ii; ++jj)
88 bp[jj + kk] = pat[jj];
90 if (!(options & F_QUIET)) {
91 printf("PATTERN: 0x");
92 for (jj = 0; jj < ii; ++jj)
93 printf("%02x", bp[jj] & 0xFF);
98 void common_options(int ch)
102 options |= F_AUDIBLE;
105 options |= F_ADAPTIVE;
108 npackets = atoi(optarg);
110 fprintf(stderr, "ping: bad number of packets to transmit.\n");
115 options |= F_SO_DEBUG;
119 setbuf(stdout, (char *)NULL);
121 case 'i': /* wait between sending packets */
123 if (strchr(optarg, '.')) {
125 if (sscanf(optarg, "%f", &t) != 1) {
126 fprintf(stderr, "ping: bad timing interval.\n");
129 interval = (int)(t*1000);
130 } else if (sscanf(optarg, "%d", &interval) == 1) {
133 fprintf(stderr, "ping: bad timing interval.\n");
138 fprintf(stderr, "ping: bad timing interval.\n");
141 options |= F_INTERVAL;
145 deadline = atoi(optarg);
147 fprintf(stderr, "ping: bad wait time.\n");
152 preload = atoi(optarg);
154 fprintf(stderr, "ping: bad preload value, should be 1..%d\n", mx_dup_ck);
157 if (preload > mx_dup_ck)
159 if (uid && preload > 3) {
160 fprintf(stderr, "ping: cannot set preload to value > 3\n");
165 sndbuf = atoi(optarg);
167 fprintf(stderr, "ping: bad sndbuf value.\n");
172 options |= F_NUMERIC;
174 case 'p': /* fill buffer with user pattern */
175 options |= F_PINGFILLED;
182 options |= F_SO_DONTROUTE;
184 case 's': /* size of packet to send */
185 datalen = atoi(optarg);
187 fprintf(stderr, "ping: illegal negative packet size %d.\n", datalen);
192 options |= F_VERBOSE;
200 if (ttl < 0 || ttl > 255) {
201 fprintf(stderr, "ping: ttl %u out of range\n", ttl);
206 options |= F_LATENCY;
209 options |= F_STRICTSOURCE;
212 lingertime = atoi(optarg);
213 if (lingertime < 0 || lingertime > INT_MAX/1000000) {
214 fprintf(stderr, "ping: bad linger time.\n");
220 printf("ping utility, iputils-ss%s\n", SNAPSHOT);
228 static void sigexit(int signo)
233 static void sigstatus(int signo)
239 int __schedule_exit(int next)
241 static unsigned long waittime;
249 if (waittime < 1000*interval)
250 waittime = 1000*interval;
252 waittime = lingertime*1000;
254 if (next < 0 || next < waittime/1000)
255 next = waittime/1000;
257 it.it_interval.tv_sec = 0;
258 it.it_interval.tv_usec = 0;
259 it.it_value.tv_sec = waittime/1000000;
260 it.it_value.tv_usec = waittime%1000000;
261 setitimer(ITIMER_REAL, &it, NULL);
265 static inline void update_interval(void)
267 int est = rtt ? rtt/8 : interval*1000;
269 interval = (est+rtt_addend+500)/1000;
270 if (uid && interval < MINUSERINTERVAL)
271 interval = MINUSERINTERVAL;
276 * Compose and transmit an ICMP ECHO REQUEST packet. The IP packet
277 * will be added on by the kernel. The ID field is our UNIX process ID,
278 * and the sequence number is an ascending integer. The first 8 bytes
279 * of the data portion are used to hold a UNIX "timeval" struct in VAX
280 * byte-order, to compute the round-trip time.
284 static int oom_count;
288 /* Have we already sent enough? If we have, return an arbitrary positive value. */
289 if (exiting || (npackets && ntransmitted >= npackets && !deadline))
292 /* Check that packets < rate*time + preload */
293 if (cur_time.tv_sec == 0) {
294 gettimeofday(&cur_time, NULL);
295 tokens = interval*(preload-1);
300 gettimeofday(&tv, NULL);
301 ntokens = (tv.tv_sec - cur_time.tv_sec)*1000 +
302 (tv.tv_usec-cur_time.tv_usec)/1000;
304 /* Case of unlimited flood is special;
305 * if we see no reply, they are limited to 100pps */
306 if (ntokens < MININTERVAL && in_flight() >= preload)
307 return MININTERVAL-ntokens;
310 if (ntokens > interval*preload)
311 ntokens = interval*preload;
312 if (ntokens < interval)
313 return interval - ntokens;
316 tokens = ntokens - interval;
324 advance_ntransmitted();
325 if (!(options & F_QUIET) && (options & F_FLOOD)) {
326 /* Very silly, but without this output with
327 * high preload or pipe size is very confusing. */
328 if ((preload < screen_width && pipesize < screen_width) ||
329 in_flight() < screen_width)
330 write(STDOUT_FILENO, ".", 1);
332 return interval - tokens;
335 /* And handle various errors... */
337 /* Apparently, it is some fatal bug. */
339 } else if (errno == ENOBUFS || errno == ENOMEM) {
342 /* Device queue overflow or OOM. Packet is not sent. */
344 /* Slowdown. This works only in adaptive mode (option -A) */
345 rtt_addend += (rtt < 8*50000 ? rtt/8 : 50000);
346 if (options&F_ADAPTIVE)
348 nores_interval = SCHINT(interval/2);
349 if (nores_interval > 500)
350 nores_interval = 500;
352 if (oom_count*nores_interval < lingertime)
353 return nores_interval;
355 /* Fall to hard error. It is to avoid complete deadlock
356 * on stuck output device even when dealine was not requested.
357 * Expected timings are screwed up in any case, but we will
358 * exit some day. :-) */
359 } else if (errno == EAGAIN) {
360 /* Socket buffer is full. */
364 if ((i=receive_error_msg()) > 0) {
365 /* An ICMP error arrived. */
369 /* Compatibility with old linuces. */
370 if (i == 0 && confirm_flag && errno == EINVAL) {
378 /* Hard local error. Pretend we sent packet. */
379 advance_ntransmitted();
381 if (i == 0 && !(options & F_QUIET)) {
382 if (options & F_FLOOD)
383 write(STDOUT_FILENO, "E", 1);
385 perror("ping: sendmsg");
388 return SCHINT(interval);
391 /* Set socket buffers, "alloc" is an estimate of memory taken by single packet. */
393 void sock_setbufs(int icmp_sock, int alloc)
396 socklen_t tmplen = sizeof(hold);
400 setsockopt(icmp_sock, SOL_SOCKET, SO_SNDBUF, (char *)&sndbuf, sizeof(sndbuf));
402 rcvbuf = hold = alloc * preload;
405 setsockopt(icmp_sock, SOL_SOCKET, SO_RCVBUF, (char *)&hold, sizeof(hold));
406 if (getsockopt(icmp_sock, SOL_SOCKET, SO_RCVBUF, (char *)&hold, &tmplen) == 0) {
408 fprintf(stderr, "WARNING: probably, rcvbuf is not enough to hold preload.\n");
412 /* Protocol independent setup and parameter checks. */
414 void setup(int icmp_sock)
419 if ((options & F_FLOOD) && !(options & F_INTERVAL))
422 if (uid && interval < MINUSERINTERVAL) {
423 fprintf(stderr, "ping: cannot flood; minimal interval, allowed for user, is %dms\n", MINUSERINTERVAL);
427 if (interval >= INT_MAX/preload) {
428 fprintf(stderr, "ping: illegal preload and/or interval\n");
433 if (options & F_SO_DEBUG)
434 setsockopt(icmp_sock, SOL_SOCKET, SO_DEBUG, (char *)&hold, sizeof(hold));
435 if (options & F_SO_DONTROUTE)
436 setsockopt(icmp_sock, SOL_SOCKET, SO_DONTROUTE, (char *)&hold, sizeof(hold));
439 if (!(options&F_LATENCY)) {
441 if (setsockopt(icmp_sock, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on)))
442 fprintf(stderr, "Warning: no SO_TIMESTAMP support, falling back to SIOCGSTAMP\n");
446 /* Set some SNDTIMEO to prevent blocking forever
447 * on sends, when device is too slow or stalls. Just put limit
448 * of one second, or "interval", if it is less.
452 if (interval < 1000) {
454 tv.tv_usec = 1000 * SCHINT(interval);
456 setsockopt(icmp_sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&tv, sizeof(tv));
458 /* Set RCVTIMEO to "interval". Note, it is just an optimization
459 * allowing to avoid redundant poll(). */
460 tv.tv_sec = SCHINT(interval)/1000;
461 tv.tv_usec = 1000*(SCHINT(interval)%1000);
462 if (setsockopt(icmp_sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(tv)))
463 options |= F_FLOOD_POLL;
465 if (!(options & F_PINGFILLED)) {
467 u_char *p = outpack+8;
469 /* Do not forget about case of small datalen,
470 * fill timestamp area too!
472 for (i = 0; i < datalen; ++i)
476 ident = getpid() & 0xFFFF;
478 set_signal(SIGINT, sigexit);
479 set_signal(SIGALRM, sigexit);
480 set_signal(SIGQUIT, sigstatus);
482 gettimeofday(&start_time, NULL);
487 it.it_interval.tv_sec = 0;
488 it.it_interval.tv_usec = 0;
489 it.it_value.tv_sec = deadline;
490 it.it_value.tv_usec = 0;
491 setitimer(ITIMER_REAL, &it, NULL);
494 if (isatty(STDOUT_FILENO)) {
497 if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1) {
499 screen_width = w.ws_col;
504 void main_loop(int icmp_sock, __u8 *packet, int packlen)
515 iov.iov_base = (char *)packet;
518 /* Check exit conditions. */
521 if (npackets && nreceived + nerrors >= npackets)
523 if (deadline && nerrors)
525 /* Check for and do special actions. */
529 /* Send probes scheduled to this time. */
532 next = schedule_exit(next);
535 /* "next" is time to send next probe, if positive.
536 * If next<=0 send now or as soon as possible. */
538 /* Technical part. Looks wicked. Could be dropped,
539 * if everyone used the newest kernel. :-)
541 * 1. Provide intervals less than resolution of scheduler.
542 * Solution: spinning.
543 * 2. Avoid use of poll(), when recvmsg() can provide
544 * timed waiting (SO_RCVTIMEO). */
546 if ((options & (F_ADAPTIVE|F_FLOOD_POLL)) || next<SCHINT(interval)) {
547 int recv_expected = in_flight();
549 /* If we are here, recvmsg() is unable to wait for
550 * required timeout. */
551 if (1000*next <= 1000000/(int)HZ) {
552 /* Very short timeout... So, if we wait for
553 * something, we sleep for MININTERVAL.
554 * Otherwise, spin! */
559 /* When spinning, no reasons to poll.
560 * Use nonblocking recvmsg() instead. */
561 polling = MSG_DONTWAIT;
568 ((options & (F_ADAPTIVE|F_FLOOD_POLL)) || interval)) {
571 pset.events = POLLIN|POLLERR;
573 if (poll(&pset, 1, next) < 1 ||
574 !(pset.revents&(POLLIN|POLLERR)))
576 polling = MSG_DONTWAIT;
581 struct timeval *recv_timep = NULL;
582 struct timeval recv_time;
583 int not_ours = 0; /* Raw socket can receive messages
584 * destined to other running pings. */
586 iov.iov_len = packlen;
587 memset(&msg, 0, sizeof(msg));
588 msg.msg_name = addrbuf;
589 msg.msg_namelen = sizeof(addrbuf);
592 msg.msg_control = ans_data;
593 msg.msg_controllen = sizeof(ans_data);
595 cc = recvmsg(icmp_sock, &msg, polling);
596 polling = MSG_DONTWAIT;
599 if (errno == EAGAIN || errno == EINTR)
601 if (!receive_error_msg()) {
603 perror("ping: recvmsg");
611 for (c = CMSG_FIRSTHDR(&msg); c; c = CMSG_NXTHDR(&msg, c)) {
612 if (c->cmsg_level != SOL_SOCKET ||
613 c->cmsg_type != SO_TIMESTAMP)
615 if (c->cmsg_len < CMSG_LEN(sizeof(struct timeval)))
617 recv_timep = (struct timeval*)CMSG_DATA(c);
621 if ((options&F_LATENCY) || recv_timep == NULL) {
622 if ((options&F_LATENCY) ||
623 ioctl(icmp_sock, SIOCGSTAMP, &recv_time))
624 gettimeofday(&recv_time, NULL);
625 recv_timep = &recv_time;
628 not_ours = parse_reply(&msg, cc, addrbuf, recv_timep);
631 /* See? ... someone runs another ping on this host. */
635 /* If nothing is in flight, "break" returns us to pinger. */
636 if (in_flight() == 0)
639 /* Otherwise, try to recvmsg() again. recvmsg()
640 * is nonblocking after the first iteration, so that
641 * if nothing is queued, it will receive EAGAIN
642 * and return to pinger. */
648 int gather_statistics(__u8 *ptr, int cc, __u16 seq, int hops,
649 int csfailed, struct timeval *tv, char *from)
658 if (timing && cc >= 8+sizeof(struct timeval)) {
659 struct timeval tmp_tv;
660 memcpy(&tmp_tv, ptr, sizeof(tmp_tv));
664 triptime = tv->tv_sec * 1000000 + tv->tv_usec;
666 fprintf(stderr, "Warning: time of day goes back (%ldus), taking countermeasures.\n", triptime);
668 if (!(options & F_LATENCY)) {
669 gettimeofday(tv, NULL);
670 options |= F_LATENCY;
676 tsum2 += (long long)triptime * (long long)triptime;
684 rtt += triptime-rtt/8;
685 if (options&F_ADAPTIVE)
693 } else if (TST(seq % mx_dup_ck)) {
698 SET(seq % mx_dup_ck);
701 confirm = confirm_flag;
703 if (options & F_QUIET)
706 if (options & F_FLOOD) {
708 write(STDOUT_FILENO, "\b \b", 3);
710 write(STDOUT_FILENO, "\bC", 1);
714 printf("%d bytes from %s: icmp_seq=%u", cc, from, seq);
717 printf(" ttl=%d", hops);
719 if (cc < datalen+8) {
720 printf(" (truncated)\n");
724 if (triptime >= 100000)
725 printf(" time=%ld ms", triptime/1000);
726 else if (triptime >= 10000)
727 printf(" time=%ld.%01ld ms", triptime/1000,
728 (triptime%1000)/100);
729 else if (triptime >= 1000)
730 printf(" time=%ld.%02ld ms", triptime/1000,
733 printf(" time=%ld.%03ld ms", triptime/1000,
739 printf(" (BAD CHECKSUM!)");
742 cp = ((u_char*)ptr) + sizeof(struct timeval);
743 dp = &outpack[8 + sizeof(struct timeval)];
744 for (i = sizeof(struct timeval); i < datalen; ++i, ++cp, ++dp) {
746 printf("\nwrong data byte #%d should be 0x%x but was 0x%x",
748 cp = (u_char*)ptr + sizeof(struct timeval);
749 for (i = sizeof(struct timeval); i < datalen; ++i, ++cp) {
750 if ((i % 32) == sizeof(struct timeval))
751 printf("\n#%d\t", i);
761 static long llsqrt(long long a)
763 long long prev = ~((long long)1 << 63);
778 * Print out statistics, and give up.
782 struct timeval tv = cur_time;
784 tvsub(&tv, &start_time);
788 printf("--- %s ping statistics ---\n", hostname);
789 printf("%ld packets transmitted, ", ntransmitted);
790 printf("%ld received", nreceived);
792 printf(", +%ld duplicates", nrepeats);
794 printf(", +%ld corrupted", nchecksum);
796 printf(", +%ld errors", nerrors);
798 printf(", %d%% packet loss",
799 (int) ((((long long)(ntransmitted - nreceived)) * 100) /
801 printf(", time %ldms", 1000*tv.tv_sec+tv.tv_usec/1000);
805 if (nreceived && timing) {
808 tsum /= nreceived + nrepeats;
809 tsum2 /= nreceived + nrepeats;
810 tmdev = llsqrt(tsum2 - tsum * tsum);
812 printf("rtt min/avg/max/mdev = %ld.%03ld/%lu.%03ld/%ld.%03ld/%ld.%03ld ms",
813 (long)tmin/1000, (long)tmin%1000,
814 (unsigned long)(tsum/1000), (long)(tsum%1000),
815 (long)tmax/1000, (long)tmax%1000,
816 (long)tmdev/1000, (long)tmdev%1000
820 printf(", pipe %d", pipesize);
821 if (ntransmitted > 1 && (!interval || (options&(F_FLOOD|F_ADAPTIVE)))) {
822 int ipg = (1000000*(long long)tv.tv_sec+tv.tv_usec)/(ntransmitted-1);
823 printf(", ipg/ewma %d.%03d/%d.%03d ms",
824 ipg/1000, ipg%1000, rtt/8000, (rtt/8)%1000);
827 exit(!nreceived || (deadline && nreceived < npackets));
839 loss = (((long long)(ntransmitted - nreceived)) * 100) / ntransmitted;
841 fprintf(stderr, "\r%ld/%ld packets, %d%% loss", ntransmitted, nreceived, loss);
843 if (nreceived && timing) {
844 tavg = tsum / (nreceived + nrepeats);
846 fprintf(stderr, ", min/avg/ewma/max = %ld.%03ld/%lu.%03ld/%d.%03d/%ld.%03ld ms",
847 (long)tmin/1000, (long)tmin%1000,
848 tavg/1000, tavg%1000,
849 rtt/8000, (rtt/8)%1000,
850 (long)tmax/1000, (long)tmax%1000
853 fprintf(stderr, "\n");