arping: fix a bug where there is implicit count of 4G;

eliminate data/bss usage; code shrink

function                                             old     new   delta
timeout_us                                             4       -      -4
static.start                                           4       -      -4
src                                                    4       -      -4
sock                                                   4       -      -4
sent                                                   4       -      -4
req_recv                                               4       -      -4
received                                               4       -      -4
last                                                   4       -      -4
dst                                                    4       -      -4
count                                                  4       -      -4
brd_sent                                               4       -      -4
brd_recv                                               4       -      -4
catcher                                              375     365     -10
me                                                    20       -     -20
he                                                    20       -     -20
arping_main                                         1941    1874     -67
------------------------------------------------------------------------------
(add/remove: 0/14 grow/shrink: 0/2 up/down: 0/-165)          Total: -165 bytes
   text    data     bss     dec     hex filename
 783035     941    9244  793220   c1a84 busybox_old
 782907     937    9156  793000   c19a8 busybox_unstripped
This commit is contained in:
Denis Vlasenko 2007-11-23 09:15:26 +00:00
parent 3831c91c95
commit fff9b699f1

View File

@ -18,12 +18,6 @@
/* We don't expect to see 1000+ seconds delay, unsigned is enough */ /* We don't expect to see 1000+ seconds delay, unsigned is enough */
#define MONOTONIC_US() ((unsigned)monotonic_us()) #define MONOTONIC_US() ((unsigned)monotonic_us())
static struct in_addr src;
static struct in_addr dst;
static struct sockaddr_ll me;
static struct sockaddr_ll he;
static unsigned last;
enum { enum {
DAD = 1, DAD = 1,
UNSOLICITED = 2, UNSOLICITED = 2,
@ -34,14 +28,43 @@ enum {
UNICASTING = 64 UNICASTING = 64
}; };
static int sock; struct globals {
static unsigned count = UINT_MAX; struct in_addr src;
static unsigned timeout_us; struct in_addr dst;
static unsigned sent; struct sockaddr_ll me;
static unsigned brd_sent; struct sockaddr_ll he;
static unsigned received; int sock;
static unsigned brd_recv;
static unsigned req_recv; int count; // = -1;
unsigned last;
unsigned timeout_us;
unsigned start;
unsigned sent;
unsigned brd_sent;
unsigned received;
unsigned brd_recv;
unsigned req_recv;
};
#define G (*(struct globals*)&bb_common_bufsiz1)
#define src (G.src )
#define dst (G.dst )
#define me (G.me )
#define he (G.he )
#define sock (G.sock )
#define count (G.count )
#define last (G.last )
#define timeout_us (G.timeout_us)
#define start (G.start )
#define sent (G.sent )
#define brd_sent (G.brd_sent )
#define received (G.received )
#define brd_recv (G.brd_recv )
#define req_recv (G.req_recv )
#define INIT_G() \
do { \
count = -1; \
} while (0)
static int send_pack(struct in_addr *src_addr, static int send_pack(struct in_addr *src_addr,
struct in_addr *dst_addr, struct sockaddr_ll *ME, struct in_addr *dst_addr, struct sockaddr_ll *ME,
@ -106,8 +129,6 @@ static void finish(void)
static void catcher(void) static void catcher(void)
{ {
static unsigned start;
unsigned now; unsigned now;
now = MONOTONIC_US(); now = MONOTONIC_US();
@ -117,6 +138,8 @@ static void catcher(void)
if (count == 0 || (timeout_us && (now - start) > (timeout_us + 500000))) if (count == 0 || (timeout_us && (now - start) > (timeout_us + 500000)))
finish(); finish();
/* count < 0 means "infinite count" */
if (count > 0)
count--; count--;
if (last == 0 || (now - last) > 500000) { if (last == 0 || (now - last) > 500000) {
@ -236,6 +259,8 @@ int arping_main(int argc, char **argv)
char *target; char *target;
unsigned char *packet; unsigned char *packet;
INIT_G();
sock = xsocket(PF_PACKET, SOCK_DGRAM, 0); sock = xsocket(PF_PACKET, SOCK_DGRAM, 0);
// Drop suid root privileges // Drop suid root privileges
@ -252,14 +277,9 @@ int arping_main(int argc, char **argv)
opt = getopt32(argv, "DUAqfbc:w:I:s:", opt = getopt32(argv, "DUAqfbc:w:I:s:",
&str_count, &str_timeout, &device, &source); &str_count, &str_timeout, &device, &source);
if (opt & 0x40) /* -c: count */ if (opt & 0x40) /* -c: count */
count = xatou(str_count); count = xatoi_u(str_count);
if (opt & 0x80) /* -w: timeout */ if (opt & 0x80) /* -w: timeout */
timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000; timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000;
//if (opt & 0x100) /* -I: interface */
if (strlen(device) >= IF_NAMESIZE) {
bb_error_msg_and_die("interface name '%s' is too long",
device);
}
//if (opt & 0x200) /* -s: source */ //if (opt & 0x200) /* -s: source */
option_mask32 &= 0x3f; /* set respective flags */ option_mask32 &= 0x3f; /* set respective flags */
} }
@ -272,8 +292,10 @@ int arping_main(int argc, char **argv)
struct ifreq ifr; struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr)); memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, device, IFNAMSIZ - 1); strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name) - 1);
ioctl_or_perror_and_die(sock, SIOCGIFINDEX, &ifr, "interface %s not found", device); /* We use ifr.ifr_name in error msg so that problem
* with truncated name will be visible */
ioctl_or_perror_and_die(sock, SIOCGIFINDEX, &ifr, "interface %s not found", ifr.ifr_name);
ifindex = ifr.ifr_ifindex; ifindex = ifr.ifr_ifindex;
xioctl(sock, SIOCGIFFLAGS, (char *) &ifr); xioctl(sock, SIOCGIFFLAGS, (char *) &ifr);
@ -308,7 +330,7 @@ int arping_main(int argc, char **argv)
if (device) { if (device) {
if (setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device) + 1) == -1) if (setsockopt(probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device, strlen(device) + 1) == -1)
bb_error_msg("warning: interface %s is ignored", device); bb_perror_msg("cannot bind to device %s", device);
} }
memset(&saddr, 0, sizeof(saddr)); memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET; saddr.sin_family = AF_INET;
@ -322,7 +344,7 @@ int arping_main(int argc, char **argv)
saddr.sin_addr = dst; saddr.sin_addr = dst;
if (setsockopt(probe_fd, SOL_SOCKET, SO_DONTROUTE, &const_int_1, sizeof(const_int_1)) == -1) if (setsockopt(probe_fd, SOL_SOCKET, SO_DONTROUTE, &const_int_1, sizeof(const_int_1)) == -1)
bb_perror_msg("warning: setsockopt(SO_DONTROUTE)"); bb_perror_msg("setsockopt(SO_DONTROUTE)");
xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr));
if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1) { if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1) {
bb_error_msg_and_die("getsockname"); bb_error_msg_and_die("getsockname");
@ -345,22 +367,22 @@ int arping_main(int argc, char **argv)
} }
} }
if (me.sll_halen == 0) { if (me.sll_halen == 0) {
bb_error_msg("interface \"%s\" is not ARPable (no ll address)", device); bb_error_msg("interface %s is not ARPable (no ll address)", device);
return (option_mask32 & DAD ? 0 : 2); return (option_mask32 & DAD ? 0 : 2);
} }
he = me; he = me;
memset(he.sll_addr, -1, he.sll_halen); memset(he.sll_addr, -1, he.sll_halen);
if (!src.s_addr && !(option_mask32 & DAD)) {
bb_error_msg_and_die("no src address in the non-DAD mode");
}
if (!(option_mask32 & QUIET)) { if (!(option_mask32 & QUIET)) {
printf("ARPING to %s from %s via %s\n", printf("ARPING to %s from %s via %s\n",
inet_ntoa(dst), inet_ntoa(src), inet_ntoa(dst), inet_ntoa(src),
device ? device : "unknown"); device ? device : "unknown");
} }
if (!src.s_addr && !(option_mask32 & DAD)) {
bb_error_msg_and_die("no src address in the non-DAD mode");
}
{ {
struct sigaction sa; struct sigaction sa;