diff --git a/sbin/ping/ping.c b/sbin/ping/ping.c --- a/sbin/ping/ping.c +++ b/sbin/ping/ping.c @@ -203,6 +203,7 @@ static int interval = 1000; /* interval between packets, ms */ static int waittime = MAXWAIT; /* timeout for each packet */ static long nrcvtimeout = 0; /* # of packets we got back after waittime */ +static uint16_t lastseq; /* the latest seq # for the received packets */ /* timing */ static int timing; /* flag to do timing */ @@ -913,14 +914,15 @@ iov.iov_base = packet; iov.iov_len = IP_MAXPACKET; - if (preload == 0) - pinger(); /* send the first ping */ - else { - if (npackets != 0 && preload > npackets) - preload = npackets; - while (preload--) /* fire off them quickies */ - pinger(); - } + if (npackets != 0 && preload > npackets) + preload = npackets; + else if (preload == 0) + preload = 1; + + /* Send the first ping. If preload > 1, fire off them quickies. */ + for (i = 0; i < preload; i++) + pinger(); + (void)clock_gettime(CLOCK_MONOTONIC, &last); if (options & F_FLOOD) { @@ -985,6 +987,22 @@ (npackets && nreceived >= npackets)) break; } + if (n == 0 && almost_done == 0 && + (options & F_QUIET) == 0 && (options & F_FLOOD) == 0 && + (nreceived == 0 || ntransmitted - 1 > lastseq)) { + int seq = preload; + /* + * XXX: the timeout messages for payload > 1 will be + * displayed only when all of them are missing. + */ + while (seq) { + printf("Request timeout for icmp_seq %u\n", + (uint16_t)(ntransmitted - seq)); + fflush(stdout); + seq--; + } + preload = 1; + } if (n == 0 || options & F_FLOOD) { if (sweepmax && sntransmitted == snpackets) { if (datalen + sweepincr > sweepmax) @@ -1230,7 +1248,7 @@ timing = 0; } - seq = ntohs(icp.icmp_seq); + seq = lastseq = ntohs(icp.icmp_seq); if (TST(seq % mx_dup_ck)) { ++nrepeats; diff --git a/sbin/ping/ping6.c b/sbin/ping/ping6.c --- a/sbin/ping/ping6.c +++ b/sbin/ping/ping6.c @@ -250,6 +250,7 @@ static int interval = 1000; /* interval between packets in ms */ static int waittime = MAXWAIT; /* timeout for each packet */ static long nrcvtimeout = 0; /* # of packets we got back after waittime */ +static uint16_t lastseq; /* the latest seq # for the received packets */ /* timing */ static int timing; /* flag to do timing */ @@ -1149,14 +1150,14 @@ printf("%s --> ", pr_addr((struct sockaddr *)&src, sizeof(src))); printf("%s\n", pr_addr((struct sockaddr *)&dst, sizeof(dst))); - if (preload == 0) + if (npackets != 0 && preload > npackets) + preload = npackets; + else if (preload == 0) + preload = 1; + + for (i = 0; i < preload; i++) pinger(); - else { - if (npackets != 0 && preload > npackets) - preload = npackets; - while (preload--) - pinger(); - } + clock_gettime(CLOCK_MONOTONIC, &last); sigemptyset(&si_sa.sa_mask); @@ -1253,6 +1254,19 @@ (npackets > 0 && nreceived >= npackets)) break; } + if (n == 0 && almost_done == 0 && + (options & F_QUIET) == 0 && (options & F_FLOOD) == 0 && + (nreceived == 0 || nreceived - 1 > lastseq)) { + int seq = preload; + + while (seq) { + printf("Request timeout for icmp_seq %u\n", + (uint16_t)(ntransmitted - seq)); + fflush(stdout); + seq--; + } + preload = 1; + } if (n == 0 || (options & F_FLOOD)) { if (npackets == 0 || ntransmitted < npackets) pinger(); @@ -1638,7 +1652,7 @@ } if (icp->icmp6_type == ICMP6_ECHO_REPLY && myechoreply(icp)) { - seq = ntohs(icp->icmp6_seq); + seq = lastseq = ntohs(icp->icmp6_seq); ++nreceived; if (timing) { memcpy(&tpp, icp + 1, sizeof(tpp));