ip: add a #define for older kernels
[oweals/busybox.git] / networking / arp.c
index 7a36f44bbf2a2f3082f5aee4fc60f7c522fff0ee..0ef267a35c90bcd319f035b5a705481afa1d98d8 100644 (file)
@@ -13,7 +13,7 @@
  * modified for getopt32 by Arne Bernin <arne [at] alamut.de>
  */
 
-#include "busybox.h"
+#include "libbb.h"
 #include "inet_common.h"
 
 #include <arpa/inet.h>
 #define DFLT_AF "inet"
 #define DFLT_HW "ether"
 
-#define        ARP_OPT_A (0x1)
-#define        ARP_OPT_p (0x2)
-#define        ARP_OPT_H (0x4)
-#define        ARP_OPT_t (0x8)
-#define        ARP_OPT_i (0x10)
-#define        ARP_OPT_a (0x20)
-#define        ARP_OPT_d (0x40)
-#define        ARP_OPT_n (0x80)        /* do not resolve addresses     */
-#define        ARP_OPT_D (0x100)       /* HW-address is devicename     */
-#define        ARP_OPT_s (0x200)
-#define        ARP_OPT_v (0x400 * DEBUG)       /* debugging output flag        */
-
-
-static const struct aftype *ap; /* current address family       */
-static const struct hwtype *hw; /* current hardware type        */
-static int sockfd;              /* active socket descriptor     */
-static smallint hw_set;         /* flag if hw-type was set (-H) */
-static const char *device = ""; /* current device               */
-
-static const char *const options[] = {
-       "pub",
-       "priv",
-       "temp",
-       "trail",
-       "dontpub",
-       "auto",
-       "dev",
-       "netmask",
-       NULL
+enum {
+       ARP_OPT_A = (1 << 0),
+       ARP_OPT_p = (1 << 1),
+       ARP_OPT_H = (1 << 2),
+       ARP_OPT_t = (1 << 3),
+       ARP_OPT_i = (1 << 4),
+       ARP_OPT_a = (1 << 5),
+       ARP_OPT_d = (1 << 6),
+       ARP_OPT_n = (1 << 7), /* do not resolve addresses */
+       ARP_OPT_D = (1 << 8), /* HW-address is devicename */
+       ARP_OPT_s = (1 << 9),
+       ARP_OPT_v = (1 << 10) * DEBUG, /* debugging output flag */
 };
 
+enum {
+       sockfd = 3, /* active socket descriptor */
+};
+
+struct globals {
+       const struct aftype *ap; /* current address family */
+       const struct hwtype *hw; /* current hardware type */
+       const char *device;      /* current device */
+       smallint hw_set;         /* flag if hw-type was set (-H) */
+
+} FIX_ALIASING;
+#define G (*(struct globals*)&bb_common_bufsiz1)
+#define ap         (G.ap        )
+#define hw         (G.hw        )
+#define device     (G.device    )
+#define hw_set     (G.hw_set    )
+#define INIT_G() do { \
+       device = ""; \
+} while (0)
+
+
+static const char options[] ALIGN1 =
+       "pub\0"
+       "priv\0"
+       "temp\0"
+       "trail\0"
+       "dontpub\0"
+       "auto\0"
+       "dev\0"
+       "netmask\0";
+
 /* Delete an entry from the ARP cache. */
 /* Called only from main, once */
 static int arp_del(char **args)
@@ -85,7 +99,7 @@ static int arp_del(char **args)
        req.arp_flags = ATF_PERM;
        args++;
        while (*args != NULL) {
-               switch (index_in_str_array(options, *args)) {
+               switch (index_in_strings(options, *args)) {
                case 0: /* "pub" */
                        flags |= 1;
                        args++;
@@ -188,9 +202,8 @@ static void arp_getdevhw(char *ifname, struct sockaddr *sa,
        const struct hwtype *xhw;
 
        strcpy(ifr.ifr_name, ifname);
-       if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0) {
-               bb_perror_msg_and_die("cant get HW-Address for '%s'", ifname);
-       }
+       ioctl_or_perror_and_die(sockfd, SIOCGIFHWADDR, &ifr,
+                                       "cant get HW-Address for '%s'", ifname);
        if (hwt && (ifr.ifr_hwaddr.sa_family != hw->type)) {
                bb_error_msg_and_die("protocol type mismatch");
        }
@@ -203,7 +216,7 @@ static void arp_getdevhw(char *ifname, struct sockaddr *sa,
                }
                bb_error_msg("device '%s' has HW address %s '%s'",
                                         ifname, xhw->name,
-                                        xhw->print((char *) &ifr.ifr_hwaddr.sa_data));
+                                        xhw->print((unsigned char *) &ifr.ifr_hwaddr.sa_data));
        }
 }
 
@@ -240,7 +253,7 @@ static int arp_set(char **args)
        /* Check out any modifiers. */
        flags = ATF_PERM | ATF_COM;
        while (*args != NULL) {
-               switch (index_in_str_array(options, *args)) {
+               switch (index_in_strings(options, *args)) {
                case 0: /* "pub" */
                        flags |= ATF_PUBL;
                        args++;
@@ -306,9 +319,7 @@ static int arp_set(char **args)
        /* Call the kernel. */
        if (option_mask32 & ARP_OPT_v)
                bb_error_msg("SIOCSARP()");
-       if (ioctl(sockfd, SIOCSARP, &req) < 0) {
-               bb_perror_msg_and_die("SIOCSARP");
-       }
+       xioctl(sockfd, SIOCSARP, &req);
        return 0;
 }
 
@@ -318,6 +329,26 @@ static void
 arp_disp(const char *name, char *ip, int type, int arp_flags,
                 char *hwa, char *mask, char *dev)
 {
+       static const int arp_masks[] = {
+               ATF_PERM, ATF_PUBL,
+#ifdef HAVE_ATF_MAGIC
+               ATF_MAGIC,
+#endif
+#ifdef HAVE_ATF_DONTPUB
+               ATF_DONTPUB,
+#endif
+               ATF_USETRAILERS,
+       };
+       static const char arp_labels[] ALIGN1 = "PERM\0""PUP\0"
+#ifdef HAVE_ATF_MAGIC
+               "AUTO\0"
+#endif
+#ifdef HAVE_ATF_DONTPUB
+               "DONTPUB\0"
+#endif
+               "TRAIL\0"
+       ;
+
        const struct hwtype *xhw;
 
        xhw = get_hwntype(type);
@@ -338,22 +369,8 @@ arp_disp(const char *name, char *ip, int type, int arp_flags,
        if (arp_flags & ATF_NETMASK)
                printf("netmask %s ", mask);
 
-       if (arp_flags & ATF_PERM)
-               printf("PERM ");
-       if (arp_flags & ATF_PUBL)
-               printf("PUP ");
-#ifdef HAVE_ATF_MAGIC
-       if (arp_flags & ATF_MAGIC)
-               printf("AUTO ");
-#endif
-#ifdef HAVE_ATF_DONTPUB
-       if (arp_flags & ATF_DONTPUB)
-               printf("DONTPUB ");
-#endif
-       if (arp_flags & ATF_USETRAILERS)
-               printf("TRAIL ");
-
-       printf("on %s\n", dev);
+       print_flags_separated(arp_masks, arp_labels, arp_flags, " ");
+       printf(" on %s\n", dev);
 }
 
 /* Display the contents of the ARP cache in the kernel. */
@@ -381,7 +398,7 @@ static int arp_show(char *name)
                }
                host = xstrdup(ap->sprint(&sa, 1));
        }
-       fp = xfopen("/proc/net/arp", "r");
+       fp = xfopen_for_read("/proc/net/arp");
        /* Bypass header -- read one line */
        fgets(line, sizeof(line), fp);
 
@@ -439,32 +456,35 @@ static int arp_show(char *name)
        return 0;
 }
 
-int arp_main(int argc, char **argv);
-int arp_main(int argc, char **argv)
+int arp_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int arp_main(int argc UNUSED_PARAM, char **argv)
 {
-       char *hw_type;
-       char *protocol;
+       const char *hw_type = "ether";
+       const char *protocol;
+       unsigned opts;
+
+       INIT_G();
 
-       /* Initialize variables... */
+       xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), sockfd);
        ap = get_aftype(DFLT_AF);
        if (!ap)
                bb_error_msg_and_die("%s: %s not supported", DFLT_AF, "address family");
 
-       getopt32(argc, argv, "A:p:H:t:i:adnDsv", &protocol, &protocol,
+       opts = getopt32(argv, "A:p:H:t:i:adnDsv", &protocol, &protocol,
                                 &hw_type, &hw_type, &device);
        argv += optind;
-       if (option_mask32 & ARP_OPT_A || option_mask32 & ARP_OPT_p) {
+       if (opts & (ARP_OPT_A | ARP_OPT_p)) {
                ap = get_aftype(protocol);
                if (ap == NULL)
                        bb_error_msg_and_die("%s: unknown %s", protocol, "address family");
        }
-       if (option_mask32 & ARP_OPT_A || option_mask32 & ARP_OPT_p) {
+       if (opts & (ARP_OPT_A | ARP_OPT_p)) {
                hw = get_hwtype(hw_type);
                if (hw == NULL)
                        bb_error_msg_and_die("%s: unknown %s", hw_type, "hardware type");
                hw_set = 1;
        }
-       //if (option_mask32 & ARP_OPT_i)... -i
+       //if (opts & ARP_OPT_i)... -i
 
        if (ap->af != AF_INET) {
                bb_error_msg_and_die("%s: kernel only supports 'inet'", ap->name);
@@ -481,16 +501,15 @@ int arp_main(int argc, char **argv)
                bb_error_msg_and_die("%s: %s without ARP support",
                                                         hw->name, "hardware type");
        }
-       sockfd = xsocket(AF_INET, SOCK_DGRAM, 0);
 
        /* Now see what we have to do here... */
-       if (option_mask32 & (ARP_OPT_d|ARP_OPT_s)) {
+       if (opts & (ARP_OPT_d | ARP_OPT_s)) {
                if (argv[0] == NULL)
                        bb_error_msg_and_die("need host name");
-               if (option_mask32 & ARP_OPT_s)
+               if (opts & ARP_OPT_s)
                        return arp_set(argv);
                return arp_del(argv);
        }
-       //if (option_mask32 & ARP_OPT_a) - default
+       //if (opts & ARP_OPT_a) - default
        return arp_show(argv[0]);
 }