PINGINTERVAL = 1 /* second */
};
-#define O_QUIET (1 << 0)
-
-#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */
-#define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */
-#define SET(bit) (A(bit) |= B(bit))
-#define CLR(bit) (A(bit) &= (~B(bit)))
-#define TST(bit) (A(bit) & B(bit))
-
static void ping(const char *host);
/* common routines */
+
static int in_cksum(unsigned short *buf, int sz)
{
int nleft = sz;
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
ans = ~sum;
- return (ans);
+ return ans;
}
-/* simple version */
#ifndef CONFIG_FEATURE_FANCY_PING
+
+/* simple version */
+
static char *hostname;
static void noresp(int ign)
}
#else /* ! CONFIG_FEATURE_FANCY_PING */
+
/* full(er) version */
+
+#define OPT_STRING "qc:s:I:"
+enum {
+ OPT_QUIET = 1 << 0,
+};
+
static struct sockaddr_in pingaddr;
static struct sockaddr_in sourceaddr;
static int pingsock = -1;
-static int datalen; /* intentionally uninitialized to work around gcc bug */
+static unsigned datalen; /* intentionally uninitialized to work around gcc bug */
-static long ntransmitted, nreceived, nrepeats, pingcount;
-static int myid, options;
+static unsigned long ntransmitted, nreceived, nrepeats, pingcount;
+static int myid;
static unsigned long tmin = ULONG_MAX, tmax, tsum;
static char rcvd_tbl[MAX_DUP_CHK / 8];
static void pingstats(int);
static void unpack(char *, int, struct sockaddr_in *);
+#define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */
+#define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */
+#define SET(bit) (A(bit) |= B(bit))
+#define CLR(bit) (A(bit) &= (~B(bit)))
+#define TST(bit) (A(bit) & B(bit))
+
/**************************************************************************/
static void pingstats(int junk)
signal(SIGINT, SIG_IGN);
printf("\n--- %s ping statistics ---\n", hostent->h_name);
- printf("%ld packets transmitted, ", ntransmitted);
- printf("%ld packets received, ", nreceived);
+ printf("%lu packets transmitted, ", ntransmitted);
+ printf("%lu packets received, ", nreceived);
if (nrepeats)
- printf("%ld duplicates, ", nrepeats);
+ printf("%lu duplicates, ", nrepeats);
if (ntransmitted)
- printf("%ld%% packet loss\n",
+ printf("%lu%% packet loss\n",
(ntransmitted - nreceived) * 100 / ntransmitted);
if (nreceived)
printf("round-trip min/avg/max = %lu.%lu/%lu.%lu/%lu.%lu ms\n",
dupflag = 0;
}
- if (options & O_QUIET)
+ if (option_mask32 & OPT_QUIET)
return;
printf("%d bytes from %s: icmp_seq=%u", sz,
printf(" time=%lu.%lu ms", triptime / 10, triptime % 10);
if (dupflag)
printf(" (DUP!)");
- printf("\n");
+ puts("");
} else
if (icmppkt->icmp_type != ICMP_ECHO)
- bb_error_msg("Warning: Got ICMP %d (%s)",
+ bb_error_msg("warning: got ICMP %d (%s)",
icmppkt->icmp_type, icmp_type_name(icmppkt->icmp_type));
fflush(stdout);
}
pingsock = create_icmp_socket();
if (sourceaddr.sin_addr.s_addr) {
- if (bind(pingsock, (struct sockaddr*)&sourceaddr, sizeof(sourceaddr)) == -1)
- bb_error_msg_and_die("could not bind to address");
+ xbind(pingsock, (struct sockaddr*)&sourceaddr, sizeof(sourceaddr));
}
memset(&pingaddr, 0, sizeof(struct sockaddr_in));
memcpy(&pingaddr.sin_addr, hostent->h_addr, sizeof(pingaddr.sin_addr));
/* enable broadcast pings */
- sockopt = 1;
- setsockopt(pingsock, SOL_SOCKET, SO_BROADCAST, (char *) &sockopt,
- sizeof(sockopt));
+ setsockopt_broadcast(pingsock);
/* set recv buf for broadcast pings */
sockopt = 48 * 1024;
int ping_main(int argc, char **argv)
{
- char *thisarg;
+ char *opt_c, *opt_s, *opt_I;
datalen = DEFDATALEN; /* initialized here rather than in global scope to work around gcc bug */
- argc--;
- argv++;
- /* Parse any options */
- while (argc >= 1 && **argv == '-') {
- thisarg = *argv;
- thisarg++;
- switch (*thisarg) {
- case 'q':
- options |= O_QUIET;
- break;
- case 'c':
- if (--argc <= 0)
- bb_show_usage();
- argv++;
- pingcount = atoi(*argv);
- break;
- case 's':
- if (--argc <= 0)
- bb_show_usage();
- argv++;
- datalen = atoi(*argv);
- break;
- case 'I':
- if (--argc <= 0)
- bb_show_usage();
- argv++;
-/* ping6 accepts iface too:
- if_index = if_nametoindex(*argv);
- if (!if_index) ...
- make it true for ping too. TODO.
-*/
- if (parse_nipquad(*argv, &sourceaddr))
- bb_show_usage();
- break;
- default:
+ /* exactly one argument needed */
+ opt_complementary = "=1";
+ getopt32(argc, argv, OPT_STRING, &opt_c, &opt_s, &opt_I);
+ if (option_mask32 & 2) pingcount = xatoul(opt_c); // -c
+ if (option_mask32 & 4) datalen = xatou16(opt_s); // -s
+ if (option_mask32 & 8) { // -I
+/* TODO: ping6 accepts iface too:
+ if_index = if_nametoindex(*argv);
+ if (!if_index) ...
+make it true for ping. */
+ if (parse_nipquad(opt_I, &sourceaddr))
bb_show_usage();
- }
- argc--;
- argv++;
}
- if (argc < 1)
- bb_show_usage();
myid = (int16_t) getpid();
- ping(*argv);
+ ping(argv[optind]);
return EXIT_SUCCESS;
}
#endif /* ! CONFIG_FEATURE_FANCY_PING */