arping: move packet buffer, sigset and struct ifreq to malloced "globals"
This way, we can zero them all in one go. We do malloc() anyway, thus nothing is lost by mallocing "globals" function old new delta arping_main 1683 1686 +3 finish 100 86 -14 catcher 350 310 -40 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/2 up/down: 3/-54) Total: -51 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
e015d0659f
commit
d3162773d5
@ -79,8 +79,11 @@ struct globals {
|
||||
unsigned received;
|
||||
unsigned brd_recv;
|
||||
unsigned req_recv;
|
||||
|
||||
struct ifreq ifr;
|
||||
sigset_t sset;
|
||||
unsigned char packet[4096];
|
||||
} FIX_ALIASING;
|
||||
#define G (*(struct globals*)bb_common_bufsiz1)
|
||||
#define src (G.src )
|
||||
#define dst (G.dst )
|
||||
#define me (G.me )
|
||||
@ -95,8 +98,11 @@ struct globals {
|
||||
#define received (G.received )
|
||||
#define brd_recv (G.brd_recv )
|
||||
#define req_recv (G.req_recv )
|
||||
//#define G (*(struct globals*)bb_common_bufsiz1)
|
||||
#define G (*ptr_to_globals)
|
||||
#define INIT_G() do { \
|
||||
setup_common_bufsiz(); \
|
||||
/*setup_common_bufsiz();*/ \
|
||||
SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
|
||||
count = -1; \
|
||||
} while (0)
|
||||
|
||||
@ -183,15 +189,10 @@ static void recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)
|
||||
struct arphdr *ah = (struct arphdr *) buf;
|
||||
unsigned char *p = (unsigned char *) (ah + 1);
|
||||
struct in_addr src_ip, dst_ip;
|
||||
|
||||
/* moves below assume in_addr is 4 bytes big, ensure that */
|
||||
struct BUG_in_addr_must_be_4 {
|
||||
char BUG_in_addr_must_be_4[
|
||||
sizeof(struct in_addr) == 4 ? 1 : -1
|
||||
];
|
||||
char BUG_s_addr_must_be_4[
|
||||
sizeof(src_ip.s_addr) == 4 ? 1 : -1
|
||||
];
|
||||
};
|
||||
BUILD_BUG_ON(sizeof(struct in_addr) != 4);
|
||||
BUILD_BUG_ON(sizeof(src_ip.s_addr) != 4);
|
||||
|
||||
/* Filter out wild packets */
|
||||
if (FROM->sll_pkttype != PACKET_HOST
|
||||
@ -212,8 +213,10 @@ static void recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)
|
||||
if (ah->ar_pro != htons(ETH_P_IP)
|
||||
|| (ah->ar_pln != 4)
|
||||
|| (ah->ar_hln != me.sll_halen)
|
||||
|| (len < (int)(sizeof(*ah) + 2 * (4 + ah->ar_hln))))
|
||||
|| (len < (int)(sizeof(*ah) + 2 * (4 + ah->ar_hln)))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
move_from_unaligned32(src_ip.s_addr, p + ah->ar_hln);
|
||||
move_from_unaligned32(dst_ip.s_addr, p + ah->ar_hln + 4 + ah->ar_hln);
|
||||
@ -292,7 +295,6 @@ int arping_main(int argc UNUSED_PARAM, char **argv)
|
||||
const char *device = "eth0";
|
||||
char *source = NULL;
|
||||
char *target;
|
||||
unsigned char *packet;
|
||||
char *err_str;
|
||||
|
||||
INIT_G();
|
||||
@ -316,27 +318,21 @@ int arping_main(int argc UNUSED_PARAM, char **argv)
|
||||
err_str = xasprintf("interface %s %%s", device);
|
||||
xfunc_error_retval = 2;
|
||||
|
||||
{
|
||||
struct ifreq ifr;
|
||||
/*memset(&G.ifr, 0, sizeof(G.ifr)); - zeroed by INIT_G */
|
||||
strncpy_IFNAMSIZ(G.ifr.ifr_name, device);
|
||||
ioctl_or_perror_and_die(sock_fd, SIOCGIFINDEX, &G.ifr, err_str, "not found");
|
||||
me.sll_ifindex = G.ifr.ifr_ifindex;
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strncpy_IFNAMSIZ(ifr.ifr_name, device);
|
||||
/* We use ifr.ifr_name in error msg so that problem
|
||||
* with truncated name will be visible */
|
||||
ioctl_or_perror_and_die(sock_fd, SIOCGIFINDEX, &ifr, err_str, "not found");
|
||||
me.sll_ifindex = ifr.ifr_ifindex;
|
||||
xioctl(sock_fd, SIOCGIFFLAGS, (char *) &G.ifr);
|
||||
|
||||
xioctl(sock_fd, SIOCGIFFLAGS, (char *) &ifr);
|
||||
|
||||
if (!(ifr.ifr_flags & IFF_UP)) {
|
||||
bb_error_msg_and_die(err_str, "is down");
|
||||
}
|
||||
if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) {
|
||||
bb_error_msg(err_str, "is not ARPable");
|
||||
BUILD_BUG_ON(DAD != 2);
|
||||
/* exit 0 if DAD, else exit 2 */
|
||||
return (~option_mask32 & DAD);
|
||||
}
|
||||
if (!(G.ifr.ifr_flags & IFF_UP)) {
|
||||
bb_error_msg_and_die(err_str, "is down");
|
||||
}
|
||||
if (G.ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) {
|
||||
bb_error_msg(err_str, "is not ARPable");
|
||||
BUILD_BUG_ON(DAD != 2);
|
||||
/* exit 0 if DAD, else exit 2 */
|
||||
return (~option_mask32 & DAD);
|
||||
}
|
||||
|
||||
/* if (!inet_aton(target, &dst)) - not needed */ {
|
||||
@ -413,8 +409,9 @@ int arping_main(int argc UNUSED_PARAM, char **argv)
|
||||
printf(" from %s %s\n", inet_ntoa(src), device);
|
||||
}
|
||||
|
||||
packet = xmalloc(4096);
|
||||
|
||||
/*sigemptyset(&G.sset); - zeroed by INIT_G */
|
||||
sigaddset(&G.sset, SIGALRM);
|
||||
sigaddset(&G.sset, SIGINT);
|
||||
signal_SA_RESTART_empty_mask(SIGINT, (void (*)(int))finish);
|
||||
signal_SA_RESTART_empty_mask(SIGALRM, (void (*)(int))catcher);
|
||||
|
||||
@ -422,28 +419,24 @@ int arping_main(int argc UNUSED_PARAM, char **argv)
|
||||
catcher();
|
||||
|
||||
while (1) {
|
||||
sigset_t sset;
|
||||
struct sockaddr_ll from;
|
||||
socklen_t alen = sizeof(from);
|
||||
int cc;
|
||||
|
||||
sigemptyset(&sset);
|
||||
sigaddset(&sset, SIGALRM);
|
||||
sigaddset(&sset, SIGINT);
|
||||
/* Unblock SIGALRM so that the previously called alarm()
|
||||
* can prevent recvfrom from blocking forever in case the
|
||||
* inherited procmask is blocking SIGALRM.
|
||||
*/
|
||||
sigprocmask(SIG_UNBLOCK, &sset, NULL);
|
||||
sigprocmask(SIG_UNBLOCK, &G.sset, NULL);
|
||||
|
||||
cc = recvfrom(sock_fd, packet, 4096, 0, (struct sockaddr *) &from, &alen);
|
||||
cc = recvfrom(sock_fd, G.packet, sizeof(G.packet), 0, (struct sockaddr *) &from, &alen);
|
||||
|
||||
/* Don't allow SIGALRMs while we process the reply */
|
||||
sigprocmask(SIG_BLOCK, &sset, NULL);
|
||||
sigprocmask(SIG_BLOCK, &G.sset, NULL);
|
||||
if (cc < 0) {
|
||||
bb_perror_msg("recvfrom");
|
||||
continue;
|
||||
}
|
||||
recv_pack(packet, cc, &from);
|
||||
recv_pack(G.packet, cc, &from);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user