summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko2007-03-03 00:36:35 +0000
committerDenis Vlasenko2007-03-03 00:36:35 +0000
commit19c238bc909d1e06a6bc70fe5f74124b64a4fa9d (patch)
treea696356bc1b8c002af41aa928bc6bf64d3832f17
parent2110aa9ece6f30563068b2ea29bd75e6ea1787eb (diff)
downloadbusybox-19c238bc909d1e06a6bc70fe5f74124b64a4fa9d.zip
busybox-19c238bc909d1e06a6bc70fe5f74124b64a4fa9d.tar.gz
ping: don't measure times if ping payload is less than 8 bytes;
commonalize some ping code.
-rw-r--r--libbb/create_icmp6_socket.c10
-rw-r--r--libbb/create_icmp_socket.c10
-rw-r--r--networking/ping.c180
3 files changed, 83 insertions, 117 deletions
diff --git a/libbb/create_icmp6_socket.c b/libbb/create_icmp6_socket.c
index c3d1b55..b90f3e9 100644
--- a/libbb/create_icmp6_socket.c
+++ b/libbb/create_icmp6_socket.c
@@ -10,8 +10,6 @@
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
-#include <errno.h>
-#include <unistd.h>
#include "libbb.h"
#ifdef CONFIG_FEATURE_IPV6
@@ -23,12 +21,12 @@ int create_icmp6_socket(void)
proto = getprotobyname("ipv6-icmp");
/* if getprotobyname failed, just silently force
* proto->p_proto to have the correct value for "ipv6-icmp" */
- if ((sock = socket(AF_INET6, SOCK_RAW,
- (proto ? proto->p_proto : IPPROTO_ICMPV6))) < 0) {
+ sock = socket(AF_INET6, SOCK_RAW,
+ (proto ? proto->p_proto : IPPROTO_ICMPV6));
+ if (sock < 0) {
if (errno == EPERM)
bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
- else
- bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket);
+ bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket);
}
/* drop root privs if running setuid */
diff --git a/libbb/create_icmp_socket.c b/libbb/create_icmp_socket.c
index 431c4d8..6664548 100644
--- a/libbb/create_icmp_socket.c
+++ b/libbb/create_icmp_socket.c
@@ -10,8 +10,6 @@
#include <sys/types.h>
#include <netdb.h>
#include <sys/socket.h>
-#include <errno.h>
-#include <unistd.h>
#include "libbb.h"
int create_icmp_socket(void)
@@ -22,12 +20,12 @@ int create_icmp_socket(void)
proto = getprotobyname("icmp");
/* if getprotobyname failed, just silently force
* proto->p_proto to have the correct value for "icmp" */
- if ((sock = socket(AF_INET, SOCK_RAW,
- (proto ? proto->p_proto : 1))) < 0) { /* 1 == ICMP */
+ sock = socket(AF_INET, SOCK_RAW,
+ (proto ? proto->p_proto : 1)); /* 1 == ICMP */
+ if (sock < 0) {
if (errno == EPERM)
bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
- else
- bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket);
+ bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket);
}
/* drop root privs if running setuid */
diff --git a/networking/ping.c b/networking/ping.c
index 4c1ec83..bbe2c9f 100644
--- a/networking/ping.c
+++ b/networking/ping.c
@@ -262,7 +262,8 @@ static int if_index;
static unsigned long ntransmitted, nreceived, nrepeats, pingcount;
static int myid;
-static unsigned long tmin = ULONG_MAX, tmax, tsum;
+static unsigned tmin = UINT_MAX, tmax;
+static unsigned long tsum;
static char rcvd_tbl[MAX_DUP_CHK / 8];
static const char *hostname;
@@ -278,8 +279,6 @@ static const char *dotted;
static void pingstats(int junk ATTRIBUTE_UNUSED)
{
- int status;
-
signal(SIGINT, SIG_IGN);
printf("\n--- %s ping statistics ---\n", hostname);
@@ -290,16 +289,12 @@ static void pingstats(int junk ATTRIBUTE_UNUSED)
if (ntransmitted)
ntransmitted = (ntransmitted - nreceived) * 100 / ntransmitted;
printf("%lu%% packet loss\n", ntransmitted);
- if (nreceived)
- printf("round-trip min/avg/max = %lu.%lu/%lu.%lu/%lu.%lu ms\n",
+ if (tmin != UINT_MAX)
+ printf("round-trip min/avg/max = %u.%u/%lu.%lu/%u.%u ms\n",
tmin / 10, tmin % 10,
(tsum / (nreceived + nrepeats)) / 10,
(tsum / (nreceived + nrepeats)) % 10, tmax / 10, tmax % 10);
- if (nreceived != 0)
- status = EXIT_SUCCESS;
- else
- status = EXIT_FAILURE;
- exit(status);
+ exit(nreceived == 0); /* (nreceived == 0) is true (1) -- 'failure' */
}
static void sendping_tail(void (*sp)(int), const void *pkt, int size_pkt)
@@ -406,15 +401,57 @@ static const char *icmp6_type_name(int id)
}
#endif
+static void unpack_tail(int sz, struct timeval *tp,
+ const char *from_str,
+ uint16_t recv_seq, int ttl)
+{
+ const char *dupmsg = " (DUP!)";
+ unsigned triptime = triptime; /* for gcc */
+
+ ++nreceived;
+
+ if (tp) {
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ tv.tv_usec -= tp->tv_usec;
+ if (tv.tv_usec < 0) {
+ --tv.tv_sec;
+ tv.tv_usec += 1000000;
+ }
+ tv.tv_sec -= tp->tv_sec;
+
+ triptime = tv.tv_sec * 10000 + (tv.tv_usec / 100);
+ tsum += triptime;
+ if (triptime < tmin)
+ tmin = triptime;
+ if (triptime > tmax)
+ tmax = triptime;
+ }
+
+ if (TST(recv_seq % MAX_DUP_CHK)) {
+ ++nrepeats;
+ --nreceived;
+ } else {
+ SET(recv_seq % MAX_DUP_CHK);
+ dupmsg += 7;
+ }
+
+ if (option_mask32 & OPT_QUIET)
+ return;
+
+ printf("%d bytes from %s: seq=%u ttl=%d", sz,
+ from_str, recv_seq, ttl);
+ if (tp)
+ printf(" time=%u.%u ms", triptime / 10, triptime % 10);
+ puts(dupmsg);
+ fflush(stdout);
+}
static void unpack4(char *buf, int sz, struct sockaddr_in *from)
{
struct icmp *icmppkt;
struct iphdr *iphdr;
- struct timeval tv, *tp;
- int hlen, dupflag;
- unsigned long triptime;
-
- gettimeofday(&tv, NULL);
+ int hlen;
/* discard if too short */
if (sz < (datalen + ICMP_MINLEN))
@@ -430,61 +467,25 @@ static void unpack4(char *buf, int sz, struct sockaddr_in *from)
if (icmppkt->icmp_type == ICMP_ECHOREPLY) {
uint16_t recv_seq = ntohs(icmppkt->icmp_seq);
- ++nreceived;
- tp = (struct timeval *) icmppkt->icmp_data;
-
- if ((tv.tv_usec -= tp->tv_usec) < 0) {
- --tv.tv_sec;
- tv.tv_usec += 1000000;
- }
- tv.tv_sec -= tp->tv_sec;
-
- triptime = tv.tv_sec * 10000 + (tv.tv_usec / 100);
- tsum += triptime;
- if (triptime < tmin)
- tmin = triptime;
- if (triptime > tmax)
- tmax = triptime;
-
- if (TST(recv_seq % MAX_DUP_CHK)) {
- ++nrepeats;
- --nreceived;
- dupflag = 1;
- } else {
- SET(recv_seq % MAX_DUP_CHK);
- dupflag = 0;
- }
-
- if (option_mask32 & OPT_QUIET)
- return;
-
- printf("%d bytes from %s: icmp_seq=%u", sz,
- inet_ntoa(*(struct in_addr *) &from->sin_addr.s_addr),
- recv_seq);
- printf(" ttl=%d", iphdr->ttl);
- printf(" time=%lu.%lu ms", triptime / 10, triptime % 10);
- if (dupflag)
- printf(" (DUP!)");
- puts("");
- } else {
- if (icmppkt->icmp_type != ICMP_ECHO)
- bb_error_msg("warning: got ICMP %d (%s)",
- icmppkt->icmp_type,
- icmp_type_name(icmppkt->icmp_type));
+ struct timeval *tp = NULL;
+
+ if (sz >= ICMP_MINLEN + sizeof(struct timeval))
+ tp = (struct timeval *) icmppkt->icmp_data;
+ unpack_tail(sz, tp,
+ inet_ntoa(*(struct in_addr *) &from->sin_addr.s_addr),
+ recv_seq, iphdr->ttl);
+ } else if (icmppkt->icmp_type != ICMP_ECHO) {
+ bb_error_msg("warning: got ICMP %d (%s)",
+ icmppkt->icmp_type,
+ icmp_type_name(icmppkt->icmp_type));
}
- fflush(stdout);
}
#if ENABLE_PING6
static void unpack6(char *packet, int sz, struct sockaddr_in6 *from, int hoplimit)
{
struct icmp6_hdr *icmppkt;
- struct timeval tv, *tp;
- int dupflag;
- unsigned long triptime;
char buf[INET6_ADDRSTRLEN];
- gettimeofday(&tv, NULL);
-
/* discard if too short */
if (sz < (datalen + sizeof(struct icmp6_hdr)))
return;
@@ -495,50 +496,19 @@ static void unpack6(char *packet, int sz, struct sockaddr_in6 *from, int hoplimi
if (icmppkt->icmp6_type == ICMP6_ECHO_REPLY) {
uint16_t recv_seq = ntohs(icmppkt->icmp6_seq);
- ++nreceived;
- tp = (struct timeval *) &icmppkt->icmp6_data8[4];
-
- if ((tv.tv_usec -= tp->tv_usec) < 0) {
- --tv.tv_sec;
- tv.tv_usec += 1000000;
- }
- tv.tv_sec -= tp->tv_sec;
-
- triptime = tv.tv_sec * 10000 + (tv.tv_usec / 100);
- tsum += triptime;
- if (triptime < tmin)
- tmin = triptime;
- if (triptime > tmax)
- tmax = triptime;
-
- if (TST(recv_seq % MAX_DUP_CHK)) {
- ++nrepeats;
- --nreceived;
- dupflag = 1;
- } else {
- SET(recv_seq % MAX_DUP_CHK);
- dupflag = 0;
- }
-
- if (option_mask32 & OPT_QUIET)
- return;
-
- printf("%d bytes from %s: icmp6_seq=%u", sz,
- inet_ntop(AF_INET6, &pingaddr.sin6.sin6_addr,
- buf, sizeof(buf)),
- recv_seq);
- printf(" ttl=%d time=%lu.%lu ms", hoplimit,
- triptime / 10, triptime % 10);
- if (dupflag)
- printf(" (DUP!)");
- puts("");
- } else {
- if (icmppkt->icmp6_type != ICMP6_ECHO_REQUEST)
- bb_error_msg("warning: got ICMP %d (%s)",
- icmppkt->icmp6_type,
- icmp6_type_name(icmppkt->icmp6_type));
+ struct timeval *tp = NULL;
+
+ if (sz >= sizeof(struct icmp6_hdr) + sizeof(struct timeval))
+ tp = (struct timeval *) &icmppkt->icmp6_data8[4];
+ unpack_tail(sz, tp,
+ inet_ntop(AF_INET6, &pingaddr.sin6.sin6_addr,
+ buf, sizeof(buf)),
+ recv_seq, hoplimit);
+ } else if (icmppkt->icmp6_type != ICMP6_ECHO_REQUEST) {
+ bb_error_msg("warning: got ICMP %d (%s)",
+ icmppkt->icmp6_type,
+ icmp6_type_name(icmppkt->icmp6_type));
}
- fflush(stdout);
}
#endif