arping: move packet buffer, sigset and struct ifreq to malloced "globals"
authorDenys Vlasenko <vda.linux@googlemail.com>
Sun, 11 Feb 2018 13:35:05 +0000 (14:35 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sun, 11 Feb 2018 13:35:46 +0000 (14:35 +0100)
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>
networking/arping.c

index 97e9e680a821ea6ab5836f562ef694a6182a00c8..a16f04b9f73ba1f0b5864d33ea89e87a03d80ec0 100644 (file)
@@ -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(&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;
+       /*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;
 
-               xioctl(sock_fd, SIOCGIFFLAGS, (char *) &ifr);
+       xioctl(sock_fd, SIOCGIFFLAGS, (char *) &G.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);
        }
 }