runsvd: shrink by Vladimir
[oweals/busybox.git] / networking / arping.c
index 6383f9a88e9771ba22431c3b01e0242f8dbc067f..aba32b8692c172519b3681cbafe0937303c8a6ad 100644 (file)
@@ -61,10 +61,16 @@ struct globals {
 #define received   (G.received  )
 #define brd_recv   (G.brd_recv  )
 #define req_recv   (G.req_recv  )
-#define INIT_G() \
-       do { \
-               count = -1; \
-       } while (0)
+#define INIT_G() do { \
+       count = -1; \
+} while (0)
+
+// If GNUisms are not available...
+//static void *mempcpy(void *_dst, const void *_src, int n)
+//{
+//     memcpy(_dst, _src, n);
+//     return (char*)_dst + n;
+//}
 
 static int send_pack(struct in_addr *src_addr,
                        struct in_addr *dst_addr, struct sockaddr_ll *ME,
@@ -75,27 +81,21 @@ static int send_pack(struct in_addr *src_addr,
        struct arphdr *ah = (struct arphdr *) buf;
        unsigned char *p = (unsigned char *) (ah + 1);
 
-       ah->ar_hrd = htons(ME->sll_hatype);
        ah->ar_hrd = htons(ARPHRD_ETHER);
        ah->ar_pro = htons(ETH_P_IP);
        ah->ar_hln = ME->sll_halen;
        ah->ar_pln = 4;
        ah->ar_op = option_mask32 & ADVERT ? htons(ARPOP_REPLY) : htons(ARPOP_REQUEST);
 
-       memcpy(p, &ME->sll_addr, ah->ar_hln);
-       p += ME->sll_halen;
-
-       memcpy(p, src_addr, 4);
-       p += 4;
+       p = mempcpy(p, &ME->sll_addr, ah->ar_hln);
+       p = mempcpy(p, src_addr, 4);
 
        if (option_mask32 & ADVERT)
-               memcpy(p, &ME->sll_addr, ah->ar_hln);
+               p = mempcpy(p, &ME->sll_addr, ah->ar_hln);
        else
-               memcpy(p, &HE->sll_addr, ah->ar_hln);
-       p += ah->ar_hln;
+               p = mempcpy(p, &HE->sll_addr, ah->ar_hln);
 
-       memcpy(p, dst_addr, 4);
-       p += 4;
+       p = mempcpy(p, dst_addr, 4);
 
        err = sendto(sock_fd, buf, p - buf, 0, (struct sockaddr *) HE, sizeof(*HE));
        if (err == p - buf) {
@@ -107,7 +107,7 @@ static int send_pack(struct in_addr *src_addr,
        return err;
 }
 
-static void finish(void) ATTRIBUTE_NORETURN;
+static void finish(void) NORETURN;
 static void finish(void)
 {
        if (!(option_mask32 & QUIET)) {
@@ -121,7 +121,7 @@ static void finish(void)
        if (option_mask32 & DAD)
                exit(!!received);
        if (option_mask32 & UNSOLICITED)
-               exit(0);
+               exit(EXIT_SUCCESS);
        exit(!received);
 }
 
@@ -148,7 +148,7 @@ static void catcher(void)
        alarm(1);
 }
 
-static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)
+static bool recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)
 {
        struct arphdr *ah = (struct arphdr *) buf;
        unsigned char *p = (unsigned char *) (ah + 1);
@@ -158,35 +158,33 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)
        if (FROM->sll_pkttype != PACKET_HOST
         && FROM->sll_pkttype != PACKET_BROADCAST
         && FROM->sll_pkttype != PACKET_MULTICAST)
-               return 0;
+               return false;
 
        /* Only these types are recognised */
        if (ah->ar_op != htons(ARPOP_REQUEST) && ah->ar_op != htons(ARPOP_REPLY))
-               return 0;
+               return false;
 
        /* ARPHRD check and this darned FDDI hack here :-( */
        if (ah->ar_hrd != htons(FROM->sll_hatype)
         && (FROM->sll_hatype != ARPHRD_FDDI || ah->ar_hrd != htons(ARPHRD_ETHER)))
-               return 0;
+               return false;
 
        /* Protocol must be IP. */
-       if (ah->ar_pro != htons(ETH_P_IP))
-               return 0;
-       if (ah->ar_pln != 4)
-               return 0;
-       if (ah->ar_hln != me.sll_halen)
-               return 0;
-       if (len < sizeof(*ah) + 2 * (4 + ah->ar_hln))
-               return 0;
+       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))))
+               return false;
+
        memcpy(&src_ip, p + ah->ar_hln, 4);
        memcpy(&dst_ip, p + ah->ar_hln + 4 + ah->ar_hln, 4);
+
+       if (dst.s_addr != src_ip.s_addr)
+               return false;
        if (!(option_mask32 & DAD)) {
-               if (dst.s_addr != src_ip.s_addr)
-                       return 0;
-               if (src.s_addr != dst_ip.s_addr)
-                       return 0;
-               if (memcmp(p + ah->ar_hln + 4, &me.sll_addr, ah->ar_hln))
-                       return 0;
+               if ((src.s_addr != dst_ip.s_addr)
+                       || (memcmp(p + ah->ar_hln + 4, &me.sll_addr, ah->ar_hln)))
+                       return false;
        } else {
                /* DAD packet was:
                   src_ip = 0 (or some src)
@@ -201,12 +199,9 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)
                   also that it matches to dst_ip, otherwise
                   dst_ip/dst_hw do not matter.
                 */
-               if (src_ip.s_addr != dst.s_addr)
-                       return 0;
-               if (memcmp(p, &me.sll_addr, me.sll_halen) == 0)
-                       return 0;
-               if (src.s_addr && src.s_addr != dst_ip.s_addr)
-                       return 0;
+               if ((memcmp(p, &me.sll_addr, me.sll_halen) == 0)
+                       || (src.s_addr && src.s_addr != dst_ip.s_addr))
+                       return false;
        }
        if (!(option_mask32 & QUIET)) {
                int s_printed = 0;
@@ -246,16 +241,17 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)
                memcpy(he.sll_addr, p, me.sll_halen);
                option_mask32 |= UNICASTING;
        }
-       return 1;
+       return true;
 }
 
 int arping_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
-int arping_main(int argc, char **argv)
+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();
 
@@ -265,18 +261,17 @@ int arping_main(int argc, char **argv)
        // Need to remove SUID_NEVER from applets.h for this to work
        //xsetuid(getuid());
 
+       err_str = xasprintf("interface %s %%s", device);
        {
                unsigned opt;
-               char *str_count, *str_timeout;
+               char *str_timeout;
 
                /* Dad also sets quit_on_reply.
                 * Advert also sets unsolicited.
                 */
-               opt_complementary = "=1:Df:AU";
+               opt_complementary = "=1:Df:AU:c+";
                opt = getopt32(argv, "DUAqfbc:w:I:s:",
-                               &str_count, &str_timeout, &device, &source);
-               if (opt & 0x40) /* -c: count */
-                       count = xatoi_u(str_count);
+                               &count, &str_timeout, &device, &source);
                if (opt & 0x80) /* -w: timeout */
                        timeout_us = xatou_range(str_timeout, 0, INT_MAX/2000000) * 1000000 + 500000;
                //if (opt & 0x200) /* -s: source */
@@ -294,16 +289,16 @@ int arping_main(int argc, char **argv)
                strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name) - 1);
                /* 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, "interface %s not found", ifr.ifr_name);
+               ioctl_or_perror_and_die(sock_fd, SIOCGIFINDEX, &ifr, err_str, "not found");
                me.sll_ifindex = ifr.ifr_ifindex;
 
                xioctl(sock_fd, SIOCGIFFLAGS, (char *) &ifr);
 
                if (!(ifr.ifr_flags & IFF_UP)) {
-                       bb_error_msg_and_die("interface %s is down", device);
+                       bb_error_msg_and_die(err_str, "is down");
                }
                if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) {
-                       bb_error_msg("interface %s is not ARPable", device);
+                       bb_error_msg(err_str, "is not ARPable");
                        return (option_mask32 & DAD ? 0 : 2);
                }
        }
@@ -311,7 +306,7 @@ int arping_main(int argc, char **argv)
        /* if (!inet_aton(target, &dst)) - not needed */ {
                len_and_sockaddr *lsa;
                lsa = xhost_and_af2sockaddr(target, 0, AF_INET);
-               memcpy(&dst, &lsa->sin.sin_addr.s_addr, 4);
+               memcpy(&dst, &lsa->u.sin.sin_addr.s_addr, 4);
                if (ENABLE_FEATURE_CLEAN_UP)
                        free(lsa);
        }
@@ -368,7 +363,7 @@ int arping_main(int argc, char **argv)
                }
        }
        if (me.sll_halen == 0) {
-               bb_error_msg("interface %s is not ARPable (no ll address)", device);
+               bb_error_msg(err_str, "is not ARPable (no ll address)");
                return (option_mask32 & DAD ? 0 : 2);
        }
        he = me;
@@ -380,18 +375,8 @@ int arping_main(int argc, char **argv)
                printf(" from %s via %s\n", inet_ntoa(src), device);
        }
 
-       {
-               struct sigaction sa;
-
-               memset(&sa, 0, sizeof(sa));
-               sa.sa_flags = SA_RESTART;
-
-               sa.sa_handler = (void (*)(int)) finish;
-               sigaction(SIGINT, &sa, NULL);
-
-               sa.sa_handler = (void (*)(int)) catcher;
-               sigaction(SIGALRM, &sa, NULL);
-       }
+       signal_SA_RESTART_empty_mask(SIGINT,  (void (*)(int))finish);
+       signal_SA_RESTART_empty_mask(SIGALRM, (void (*)(int))catcher);
 
        catcher();