ash: fix for read $IFS splitting. Closes bug 235
[oweals/busybox.git] / networking / libiproute / ipaddress.c
index 3bf854e113bced440d07eae61d2fc125f6b88d3a..03f5073fbb69e59f5b492f60d7dff1a5934ce0ee 100644 (file)
 #include "rt_names.h"
 #include "utils.h"
 
+#ifndef IFF_LOWER_UP
+/* from linux/if.h */
+#define IFF_LOWER_UP   0x10000         /* driver signals L1 up*/
+#endif
 
 typedef struct filter_t {
        char *label;
@@ -41,16 +45,15 @@ typedef struct filter_t {
 
 static void print_link_flags(unsigned flags, unsigned mdown)
 {
+       static const int flag_masks[] = {
+               IFF_LOOPBACK, IFF_BROADCAST, IFF_POINTOPOINT,
+               IFF_MULTICAST, IFF_NOARP, IFF_UP, IFF_LOWER_UP };
+       static const char flag_labels[] ALIGN1 =
+               "LOOPBACK\0""BROADCAST\0""POINTOPOINT\0"
+               "MULTICAST\0""NOARP\0""UP\0""LOWER_UP\0";
+
        bb_putchar('<');
        flags &= ~IFF_RUNNING;
-#define _PF(f) if (flags & IFF_##f) { \
-                 flags &= ~IFF_##f; \
-                 printf(#f "%s", flags ? "," : ""); }
-       _PF(LOOPBACK);
-       _PF(BROADCAST);
-       _PF(POINTOPOINT);
-       _PF(MULTICAST);
-       _PF(NOARP);
 #if 0
        _PF(ALLMULTI);
        _PF(PROMISC);
@@ -62,8 +65,7 @@ static void print_link_flags(unsigned flags, unsigned mdown)
        _PF(PORTSEL);
        _PF(NOTRAILERS);
 #endif
-       _PF(UP);
-#undef _PF
+       flags = print_flags_separated(flag_masks, flag_labels, flags, ",");
        if (flags)
                printf("%x", flags);
        if (mdown)
@@ -81,7 +83,7 @@ static void print_queuelen(char *name)
                return;
 
        memset(&ifr, 0, sizeof(ifr));
-       strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+       strncpy_IFNAMSIZ(ifr.ifr_name, name);
        if (ioctl_or_warn(s, SIOCGIFTXQLEN, &ifr) < 0) {
                close(s);
                return;
@@ -92,12 +94,11 @@ static void print_queuelen(char *name)
                printf("qlen %d", ifr.ifr_qlen);
 }
 
-static int print_linkinfo(const struct nlmsghdr *n)
+static NOINLINE int print_linkinfo(const struct nlmsghdr *n)
 {
        struct ifinfomsg *ifi = NLMSG_DATA(n);
-       struct rtattr * tb[IFLA_MAX+1];
+       struct rtattr *tb[IFLA_MAX+1];
        int len = n->nlmsg_len;
-       unsigned m_flag = 0;
 
        if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
                return 0;
@@ -128,22 +129,27 @@ static int print_linkinfo(const struct nlmsghdr *n)
                printf("Deleted ");
 
        printf("%d: %s", ifi->ifi_index,
-               tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>");
-
-       if (tb[IFLA_LINK]) {
-               SPRINT_BUF(b1);
-               int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
-               if (iflink == 0)
-                       printf("@NONE: ");
-               else {
-                       printf("@%s: ", ll_idx_n2a(iflink, b1));
-                       m_flag = ll_index_to_flags(iflink);
-                       m_flag = !(m_flag & IFF_UP);
+               /*tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>" - we checked tb[IFLA_IFNAME] above*/
+               (char*)RTA_DATA(tb[IFLA_IFNAME])
+       );
+
+       {
+               unsigned m_flag = 0;
+               if (tb[IFLA_LINK]) {
+                       SPRINT_BUF(b1);
+                       int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
+                       if (iflink == 0)
+                               printf("@NONE: ");
+                       else {
+                               printf("@%s: ", ll_idx_n2a(iflink, b1));
+                               m_flag = ll_index_to_flags(iflink);
+                               m_flag = !(m_flag & IFF_UP);
+                       }
+               } else {
+                       printf(": ");
                }
-       } else {
-               printf(": ");
+               print_link_flags(ifi->ifi_flags, m_flag);
        }
-       print_link_flags(ifi->ifi_flags, m_flag);
 
        if (tb[IFLA_MTU])
                printf("mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
@@ -160,7 +166,7 @@ static int print_linkinfo(const struct nlmsghdr *n)
 
        if (!filter.family || filter.family == AF_PACKET) {
                SPRINT_BUF(b1);
-               printf("%c    link/%s ", _SL_, ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));
+               printf("%c    link/%s ", _SL_, ll_type_n2a(ifi->ifi_type, b1));
 
                if (tb[IFLA_ADDRESS]) {
                        fputs(ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
@@ -180,7 +186,7 @@ static int print_linkinfo(const struct nlmsghdr *n)
                }
        }
        bb_putchar('\n');
-       /*fflush(stdout);*/
+       /*fflush_all();*/
        return 0;
 }
 
@@ -194,8 +200,8 @@ static int flush_update(void)
        return 0;
 }
 
-static int print_addrinfo(struct sockaddr_nl *who ATTRIBUTE_UNUSED,
-               struct nlmsghdr *n, void *arg ATTRIBUTE_UNUSED)
+static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
+               struct nlmsghdr *n, void *arg UNUSED_PARAM)
 {
        struct ifaddrmsg *ifa = NLMSG_DATA(n);
        int len = n->nlmsg_len;
@@ -278,17 +284,16 @@ static int print_addrinfo(struct sockaddr_nl *who ATTRIBUTE_UNUSED,
 
        if (rta_tb[IFA_LOCAL]) {
                fputs(rt_addr_n2a(ifa->ifa_family,
-                                             RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
                                              RTA_DATA(rta_tb[IFA_LOCAL]),
                                              abuf, sizeof(abuf)), stdout);
 
-               if (rta_tb[IFA_ADDRESS] == NULL ||
-                   memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0) {
+               if (rta_tb[IFA_ADDRESS] == NULL
+                || memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0
+               ) {
                        printf("/%d ", ifa->ifa_prefixlen);
                } else {
                        printf(" peer %s/%d ",
                                rt_addr_n2a(ifa->ifa_family,
-                                           RTA_PAYLOAD(rta_tb[IFA_ADDRESS]),
                                            RTA_DATA(rta_tb[IFA_ADDRESS]),
                                            abuf, sizeof(abuf)),
                                ifa->ifa_prefixlen);
@@ -298,18 +303,16 @@ static int print_addrinfo(struct sockaddr_nl *who ATTRIBUTE_UNUSED,
        if (rta_tb[IFA_BROADCAST]) {
                printf("brd %s ",
                        rt_addr_n2a(ifa->ifa_family,
-                                   RTA_PAYLOAD(rta_tb[IFA_BROADCAST]),
                                    RTA_DATA(rta_tb[IFA_BROADCAST]),
                                    abuf, sizeof(abuf)));
        }
        if (rta_tb[IFA_ANYCAST]) {
                printf("any %s ",
                        rt_addr_n2a(ifa->ifa_family,
-                                   RTA_PAYLOAD(rta_tb[IFA_ANYCAST]),
                                    RTA_DATA(rta_tb[IFA_ANYCAST]),
                                    abuf, sizeof(abuf)));
        }
-       printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1)));
+       printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1));
        if (ifa->ifa_flags & IFA_F_SECONDARY) {
                ifa->ifa_flags &= ~IFA_F_SECONDARY;
                printf("secondary ");
@@ -345,13 +348,12 @@ static int print_addrinfo(struct sockaddr_nl *who ATTRIBUTE_UNUSED,
                printf("       %s", buf);
        }
        bb_putchar('\n');
-       /*fflush(stdout);*/
+       /*fflush_all();*/
        return 0;
 }
 
 
-struct nlmsg_list
-{
+struct nlmsg_list {
        struct nlmsg_list *next;
        struct nlmsghdr   h;
 };
@@ -378,18 +380,16 @@ static int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo)
 }
 
 
-static int store_nlmsg(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+static int FAST_FUNC store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 {
        struct nlmsg_list **linfo = (struct nlmsg_list**)arg;
        struct nlmsg_list *h;
        struct nlmsg_list **lp;
 
-       h = malloc(n->nlmsg_len+sizeof(void*));
-       if (h == NULL)
-               return -1;
+       h = xzalloc(n->nlmsg_len + sizeof(void*));
 
        memcpy(&h->h, n, n->nlmsg_len);
-       h->next = NULL;
+       /*h->next = NULL; - xzalloc did it */
 
        for (lp = linfo; *lp; lp = &(*lp)->next)
                continue;
@@ -428,7 +428,7 @@ int ipaddr_list_or_flush(char **argv, int flush)
                        bb_error_msg_and_die(bb_msg_requires_arg, "flush");
                }
                if (filter.family == AF_PACKET) {
-                       bb_error_msg_and_die("cannot flush link addresses");
+                       bb_error_msg_and_die("can't flush link addresses");
                }
        }