Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/networking/libiproute/ipaddress.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * ipaddress.c      "ip address".
     3 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    44 *
    5  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    6  *
    7  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
     5 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    86 *
    97 * Changes:
    10  *  Laszlo Valko <valko@linux.karinthy.hu> 990223: address label must be zero terminated
     8 * Laszlo Valko <valko@linux.karinthy.hu> 990223: address label must be zero terminated
    119 */
    1210
    13 //#include <sys/socket.h>
    14 //#include <sys/ioctl.h>
    1511#include <fnmatch.h>
    1612#include <net/if.h>
     
    2117#include "utils.h"
    2218
    23 
    24 typedef struct filter_t {
    25     int ifindex;
    26     int family;
    27     int oneline;
    28     int showqueue;
    29     inet_prefix pfx;
     19#ifndef IFF_LOWER_UP
     20/* from linux/if.h */
     21#define IFF_LOWER_UP  0x10000  /* driver signals L1 up */
     22#endif
     23
     24struct filter_t {
     25    char *label;
     26    char *flushb;
     27    struct rtnl_handle *rth;
    3028    int scope, scopemask;
    3129    int flags, flagmask;
    32     int up;
    33     char *label;
    34     int flushed;
    35     char *flushb;
    3630    int flushp;
    3731    int flushe;
    38     struct rtnl_handle *rth;
    39 } filter_t;
    40 
    41 #define filter (*(filter_t*)&bb_common_bufsiz1)
    42 
    43 
    44 static void print_link_flags(FILE *fp, unsigned flags, unsigned mdown)
    45 {
    46     fprintf(fp, "<");
     32    int ifindex;
     33    family_t family;
     34    smallint showqueue;
     35    smallint oneline;
     36    smallint up;
     37    smallint flushed;
     38    inet_prefix pfx;
     39} FIX_ALIASING;
     40typedef struct filter_t filter_t;
     41
     42#define G_filter (*(filter_t*)&bb_common_bufsiz1)
     43
     44
     45static void print_link_flags(unsigned flags, unsigned mdown)
     46{
     47    static const int flag_masks[] = {
     48        IFF_LOOPBACK, IFF_BROADCAST, IFF_POINTOPOINT,
     49        IFF_MULTICAST, IFF_NOARP, IFF_UP, IFF_LOWER_UP };
     50    static const char flag_labels[] ALIGN1 =
     51        "LOOPBACK\0""BROADCAST\0""POINTOPOINT\0"
     52        "MULTICAST\0""NOARP\0""UP\0""LOWER_UP\0";
     53
     54    bb_putchar('<');
     55    if (flags & IFF_UP && !(flags & IFF_RUNNING))
     56        printf("NO-CARRIER,");
    4757    flags &= ~IFF_RUNNING;
    48 #define _PF(f) if (flags&IFF_##f) { \
    49           flags &= ~IFF_##f; \
    50           fprintf(fp, #f "%s", flags ? "," : ""); }
    51     _PF(LOOPBACK);
    52     _PF(BROADCAST);
    53     _PF(POINTOPOINT);
    54     _PF(MULTICAST);
    55     _PF(NOARP);
    5658#if 0
    5759    _PF(ALLMULTI);
     
    6567    _PF(NOTRAILERS);
    6668#endif
    67     _PF(UP);
    68 #undef _PF
     69    flags = print_flags_separated(flag_masks, flag_labels, flags, ",");
    6970    if (flags)
    70         fprintf(fp, "%x", flags);
     71        printf("%x", flags);
    7172    if (mdown)
    72         fprintf(fp, ",M-DOWN");
    73     fprintf(fp, "> ");
     73        printf(",M-DOWN");
     74    printf("> ");
    7475}
    7576
     
    8485
    8586    memset(&ifr, 0, sizeof(ifr));
    86     strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
     87    strncpy_IFNAMSIZ(ifr.ifr_name, name);
    8788    if (ioctl_or_warn(s, SIOCGIFTXQLEN, &ifr) < 0) {
    8889        close(s);
     
    9596}
    9697
    97 static int print_linkinfo(struct sockaddr_nl ATTRIBUTE_UNUSED *who,
    98         const struct nlmsghdr *n, void ATTRIBUTE_UNUSED *arg)
    99 {
    100     FILE *fp = (FILE*)arg;
     98static NOINLINE int print_linkinfo(const struct nlmsghdr *n)
     99{
    101100    struct ifinfomsg *ifi = NLMSG_DATA(n);
    102     struct rtattr * tb[IFLA_MAX+1];
     101    struct rtattr *tb[IFLA_MAX+1];
    103102    int len = n->nlmsg_len;
    104     unsigned m_flag = 0;
    105103
    106104    if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
     
    111109        return -1;
    112110
    113     if (filter.ifindex && ifi->ifi_index != filter.ifindex)
    114         return 0;
    115     if (filter.up && !(ifi->ifi_flags&IFF_UP))
     111    if (G_filter.ifindex && ifi->ifi_index != G_filter.ifindex)
     112        return 0;
     113    if (G_filter.up && !(ifi->ifi_flags & IFF_UP))
    116114        return 0;
    117115
     
    122120        return -1;
    123121    }
    124     if (filter.label
    125      && (!filter.family || filter.family == AF_PACKET)
    126      && fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)
     122    if (G_filter.label
     123     && (!G_filter.family || G_filter.family == AF_PACKET)
     124     && fnmatch(G_filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)
    127125    ) {
    128126        return 0;
     
    130128
    131129    if (n->nlmsg_type == RTM_DELLINK)
    132         fprintf(fp, "Deleted ");
    133 
    134     fprintf(fp, "%d: %s", ifi->ifi_index,
    135         tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>");
    136 
    137     if (tb[IFLA_LINK]) {
    138         SPRINT_BUF(b1);
    139         int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
    140         if (iflink == 0)
    141             fprintf(fp, "@NONE: ");
    142         else {
    143             fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1));
    144             m_flag = ll_index_to_flags(iflink);
    145             m_flag = !(m_flag & IFF_UP);
    146         }
    147     } else {
    148         fprintf(fp, ": ");
    149     }
    150     print_link_flags(fp, ifi->ifi_flags, m_flag);
     130        printf("Deleted ");
     131
     132    printf("%d: %s", ifi->ifi_index,
     133        /*tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>" - we checked tb[IFLA_IFNAME] above*/
     134        (char*)RTA_DATA(tb[IFLA_IFNAME])
     135    );
     136
     137    {
     138        unsigned m_flag = 0;
     139        if (tb[IFLA_LINK]) {
     140            SPRINT_BUF(b1);
     141            int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
     142            if (iflink == 0)
     143                printf("@NONE: ");
     144            else {
     145                printf("@%s: ", ll_idx_n2a(iflink, b1));
     146                m_flag = ll_index_to_flags(iflink);
     147                m_flag = !(m_flag & IFF_UP);
     148            }
     149        } else {
     150            printf(": ");
     151        }
     152        print_link_flags(ifi->ifi_flags, m_flag);
     153    }
    151154
    152155    if (tb[IFLA_MTU])
    153         fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
     156        printf("mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
    154157    if (tb[IFLA_QDISC])
    155         fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC]));
     158        printf("qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC]));
    156159#ifdef IFLA_MASTER
    157160    if (tb[IFLA_MASTER]) {
    158161        SPRINT_BUF(b1);
    159         fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
     162        printf("master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
    160163    }
    161164#endif
    162     if (filter.showqueue)
     165    if (tb[IFLA_OPERSTATE]) {
     166        static const char operstate_labels[] ALIGN1 =
     167            "UNKNOWN\0""NOTPRESENT\0""DOWN\0""LOWERLAYERDOWN\0"
     168            "TESTING\0""DORMANT\0""UP\0";
     169        printf("state %s ", nth_string(operstate_labels,
     170                    *(uint8_t *)RTA_DATA(tb[IFLA_OPERSTATE])));
     171    }
     172    if (G_filter.showqueue)
    163173        print_queuelen((char*)RTA_DATA(tb[IFLA_IFNAME]));
    164174
    165     if (!filter.family || filter.family == AF_PACKET) {
     175    if (!G_filter.family || G_filter.family == AF_PACKET) {
    166176        SPRINT_BUF(b1);
    167         fprintf(fp, "%c    link/%s ", _SL_, ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));
     177        printf("%c    link/%s ", _SL_, ll_type_n2a(ifi->ifi_type, b1));
    168178
    169179        if (tb[IFLA_ADDRESS]) {
    170             fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
     180            fputs(ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
    171181                              RTA_PAYLOAD(tb[IFLA_ADDRESS]),
    172182                              ifi->ifi_type,
    173                               b1, sizeof(b1)));
     183                              b1, sizeof(b1)), stdout);
    174184        }
    175185        if (tb[IFLA_BROADCAST]) {
    176             if (ifi->ifi_flags&IFF_POINTOPOINT)
    177                 fprintf(fp, " peer ");
     186            if (ifi->ifi_flags & IFF_POINTOPOINT)
     187                printf(" peer ");
    178188            else
    179                 fprintf(fp, " brd ");
    180             fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
     189                printf(" brd ");
     190            fputs(ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
    181191                              RTA_PAYLOAD(tb[IFLA_BROADCAST]),
    182192                              ifi->ifi_type,
    183                               b1, sizeof(b1)));
    184         }
    185     }
    186     fputc('\n', fp);
    187     fflush(fp);
     193                              b1, sizeof(b1)), stdout);
     194        }
     195    }
     196    bb_putchar('\n');
     197    /*fflush_all();*/
    188198    return 0;
    189199}
     
    191201static int flush_update(void)
    192202{
    193     if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) {
    194         bb_perror_msg("failed to send flush request");
     203    if (rtnl_send(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) {
     204        bb_perror_msg("can't send flush request");
    195205        return -1;
    196206    }
    197     filter.flushp = 0;
     207    G_filter.flushp = 0;
    198208    return 0;
    199209}
    200210
    201 static int print_addrinfo(struct sockaddr_nl ATTRIBUTE_UNUSED *who,
    202         struct nlmsghdr *n, void ATTRIBUTE_UNUSED *arg)
    203 {
    204     FILE *fp = (FILE*)arg;
     211static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
     212        struct nlmsghdr *n, void *arg UNUSED_PARAM)
     213{
    205214    struct ifaddrmsg *ifa = NLMSG_DATA(n);
    206215    int len = n->nlmsg_len;
     
    217226    }
    218227
    219     if (filter.flushb && n->nlmsg_type != RTM_NEWADDR)
     228    if (G_filter.flushb && n->nlmsg_type != RTM_NEWADDR)
    220229        return 0;
    221230
     
    228237        rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL];
    229238
    230     if (filter.ifindex && filter.ifindex != ifa->ifa_index)
    231         return 0;
    232     if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
    233         return 0;
    234     if ((filter.flags^ifa->ifa_flags)&filter.flagmask)
    235         return 0;
    236     if (filter.label) {
     239    if (G_filter.ifindex && G_filter.ifindex != ifa->ifa_index)
     240        return 0;
     241    if ((G_filter.scope ^ ifa->ifa_scope) & G_filter.scopemask)
     242        return 0;
     243    if ((G_filter.flags ^ ifa->ifa_flags) & G_filter.flagmask)
     244        return 0;
     245    if (G_filter.label) {
    237246        const char *label;
    238247        if (rta_tb[IFA_LABEL])
     
    240249        else
    241250            label = ll_idx_n2a(ifa->ifa_index, b1);
    242         if (fnmatch(filter.label, label, 0) != 0)
     251        if (fnmatch(G_filter.label, label, 0) != 0)
    243252            return 0;
    244253    }
    245     if (filter.pfx.family) {
     254    if (G_filter.pfx.family) {
    246255        if (rta_tb[IFA_LOCAL]) {
    247256            inet_prefix dst;
     
    249258            dst.family = ifa->ifa_family;
    250259            memcpy(&dst.data, RTA_DATA(rta_tb[IFA_LOCAL]), RTA_PAYLOAD(rta_tb[IFA_LOCAL]));
    251             if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
     260            if (inet_addr_match(&dst, &G_filter.pfx, G_filter.pfx.bitlen))
    252261                return 0;
    253262        }
    254263    }
    255264
    256     if (filter.flushb) {
     265    if (G_filter.flushb) {
    257266        struct nlmsghdr *fn;
    258         if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
     267        if (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len > G_filter.flushe) {
    259268            if (flush_update())
    260269                return -1;
    261270        }
    262         fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp));
     271        fn = (struct nlmsghdr*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp));
    263272        memcpy(fn, n, n->nlmsg_len);
    264273        fn->nlmsg_type = RTM_DELADDR;
    265274        fn->nlmsg_flags = NLM_F_REQUEST;
    266         fn->nlmsg_seq = ++filter.rth->seq;
    267         filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb;
    268         filter.flushed++;
     275        fn->nlmsg_seq = ++G_filter.rth->seq;
     276        G_filter.flushp = (((char*)fn) + n->nlmsg_len) - G_filter.flushb;
     277        G_filter.flushed = 1;
    269278        return 0;
    270279    }
    271280
    272281    if (n->nlmsg_type == RTM_DELADDR)
    273         fprintf(fp, "Deleted ");
    274 
    275     if (filter.oneline)
    276         fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index));
     282        printf("Deleted ");
     283
     284    if (G_filter.oneline)
     285        printf("%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index));
    277286    if (ifa->ifa_family == AF_INET)
    278         fprintf(fp, "    inet ");
     287        printf("    inet ");
    279288    else if (ifa->ifa_family == AF_INET6)
    280         fprintf(fp, "    inet6 ");
     289        printf("    inet6 ");
    281290    else
    282         fprintf(fp, "    family %d ", ifa->ifa_family);
     291        printf("    family %d ", ifa->ifa_family);
    283292
    284293    if (rta_tb[IFA_LOCAL]) {
    285         fprintf(fp, "%s", rt_addr_n2a(ifa->ifa_family,
    286                           RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
     294        fputs(rt_addr_n2a(ifa->ifa_family,
    287295                          RTA_DATA(rta_tb[IFA_LOCAL]),
    288                           abuf, sizeof(abuf)));
    289 
    290         if (rta_tb[IFA_ADDRESS] == NULL ||
    291             memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0) {
    292             fprintf(fp, "/%d ", ifa->ifa_prefixlen);
     296                          abuf, sizeof(abuf)), stdout);
     297
     298        if (rta_tb[IFA_ADDRESS] == NULL
     299         || memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0
     300        ) {
     301            printf("/%d ", ifa->ifa_prefixlen);
    293302        } else {
    294             fprintf(fp, " peer %s/%d ",
     303            printf(" peer %s/%d ",
    295304                rt_addr_n2a(ifa->ifa_family,
    296                         RTA_PAYLOAD(rta_tb[IFA_ADDRESS]),
    297305                        RTA_DATA(rta_tb[IFA_ADDRESS]),
    298306                        abuf, sizeof(abuf)),
     
    302310
    303311    if (rta_tb[IFA_BROADCAST]) {
    304         fprintf(fp, "brd %s ",
     312        printf("brd %s ",
    305313            rt_addr_n2a(ifa->ifa_family,
    306                     RTA_PAYLOAD(rta_tb[IFA_BROADCAST]),
    307314                    RTA_DATA(rta_tb[IFA_BROADCAST]),
    308315                    abuf, sizeof(abuf)));
    309316    }
    310317    if (rta_tb[IFA_ANYCAST]) {
    311         fprintf(fp, "any %s ",
     318        printf("any %s ",
    312319            rt_addr_n2a(ifa->ifa_family,
    313                     RTA_PAYLOAD(rta_tb[IFA_ANYCAST]),
    314320                    RTA_DATA(rta_tb[IFA_ANYCAST]),
    315321                    abuf, sizeof(abuf)));
    316322    }
    317     fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1)));
    318     if (ifa->ifa_flags&IFA_F_SECONDARY) {
     323    printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1));
     324    if (ifa->ifa_flags & IFA_F_SECONDARY) {
    319325        ifa->ifa_flags &= ~IFA_F_SECONDARY;
    320         fprintf(fp, "secondary ");
    321     }
    322     if (ifa->ifa_flags&IFA_F_TENTATIVE) {
     326        printf("secondary ");
     327    }
     328    if (ifa->ifa_flags & IFA_F_TENTATIVE) {
    323329        ifa->ifa_flags &= ~IFA_F_TENTATIVE;
    324         fprintf(fp, "tentative ");
    325     }
    326     if (ifa->ifa_flags&IFA_F_DEPRECATED) {
     330        printf("tentative ");
     331    }
     332    if (ifa->ifa_flags & IFA_F_DEPRECATED) {
    327333        ifa->ifa_flags &= ~IFA_F_DEPRECATED;
    328         fprintf(fp, "deprecated ");
    329     }
    330     if (!(ifa->ifa_flags&IFA_F_PERMANENT)) {
    331         fprintf(fp, "dynamic ");
     334        printf("deprecated ");
     335    }
     336    if (!(ifa->ifa_flags & IFA_F_PERMANENT)) {
     337        printf("dynamic ");
    332338    } else
    333339        ifa->ifa_flags &= ~IFA_F_PERMANENT;
    334340    if (ifa->ifa_flags)
    335         fprintf(fp, "flags %02x ", ifa->ifa_flags);
     341        printf("flags %02x ", ifa->ifa_flags);
    336342    if (rta_tb[IFA_LABEL])
    337         fprintf(fp, "%s", (char*)RTA_DATA(rta_tb[IFA_LABEL]));
     343        fputs((char*)RTA_DATA(rta_tb[IFA_LABEL]), stdout);
    338344    if (rta_tb[IFA_CACHEINFO]) {
    339345        struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]);
    340346        char buf[128];
    341         fputc(_SL_, fp);
     347        bb_putchar(_SL_);
    342348        if (ci->ifa_valid == 0xFFFFFFFFU)
    343349            sprintf(buf, "valid_lft forever");
     
    348354        else
    349355            sprintf(buf+strlen(buf), " preferred_lft %dsec", ci->ifa_prefered);
    350         fprintf(fp, "       %s", buf);
    351     }
    352     fputc('\n', fp);
    353     fflush(fp);
     356        printf("       %s", buf);
     357    }
     358    bb_putchar('\n');
     359    /*fflush_all();*/
    354360    return 0;
    355361}
    356362
    357363
    358 struct nlmsg_list
    359 {
     364struct nlmsg_list {
    360365    struct nlmsg_list *next;
    361     struct nlmsghdr   h;
     366    struct nlmsghdr   h;
    362367};
    363368
    364 static int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *fp)
     369static int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo)
    365370{
    366371    for (; ainfo; ainfo = ainfo->next) {
     
    370375        if (n->nlmsg_type != RTM_NEWADDR)
    371376            continue;
    372 
    373377        if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifa)))
    374378            return -1;
    375 
    376         if (ifa->ifa_index != ifindex ||
    377             (filter.family && filter.family != ifa->ifa_family))
     379        if (ifa->ifa_index != ifindex
     380         || (G_filter.family && G_filter.family != ifa->ifa_family)
     381        ) {
    378382            continue;
    379 
    380         print_addrinfo(NULL, n, fp);
     383        }
     384        print_addrinfo(NULL, n, NULL);
    381385    }
    382386    return 0;
     
    384388
    385389
    386 static int store_nlmsg(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
     390static int FAST_FUNC store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
    387391{
    388392    struct nlmsg_list **linfo = (struct nlmsg_list**)arg;
     
    390394    struct nlmsg_list **lp;
    391395
    392     h = malloc(n->nlmsg_len+sizeof(void*));
    393     if (h == NULL)
    394         return -1;
     396    h = xzalloc(n->nlmsg_len + sizeof(void*));
    395397
    396398    memcpy(&h->h, n, n->nlmsg_len);
    397     h->next = NULL;
    398 
    399     for (lp = linfo; *lp; lp = &(*lp)->next) /* NOTHING */;
     399    /*h->next = NULL; - xzalloc did it */
     400
     401    for (lp = linfo; *lp; lp = &(*lp)->next)
     402        continue;
    400403    *lp = h;
    401404
     
    406409static void ipaddr_reset_filter(int _oneline)
    407410{
    408     memset(&filter, 0, sizeof(filter));
    409     filter.oneline = _oneline;
     411    memset(&G_filter, 0, sizeof(G_filter));
     412    G_filter.oneline = _oneline;
    410413}
    411414
    412415/* Return value becomes exitcode. It's okay to not return at all */
    413 int ipaddr_list_or_flush(int argc, char **argv, int flush)
     416int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush)
    414417{
    415418    static const char option[] ALIGN1 = "to\0""scope\0""up\0""label\0""dev\0";
     
    423426
    424427    ipaddr_reset_filter(oneline);
    425     filter.showqueue = 1;
    426 
    427     if (filter.family == AF_UNSPEC)
    428         filter.family = preferred_family;
     428    G_filter.showqueue = 1;
     429
     430    if (G_filter.family == AF_UNSPEC)
     431        G_filter.family = preferred_family;
    429432
    430433    if (flush) {
    431         if (argc <= 0) {
     434        if (!*argv) {
    432435            bb_error_msg_and_die(bb_msg_requires_arg, "flush");
    433436        }
    434         if (filter.family == AF_PACKET) {
    435             bb_error_msg_and_die("cannot flush link addresses");
    436         }
    437     }
    438 
    439     while (argc > 0) {
    440         const int option_num = index_in_strings(option, *argv);
    441         switch (option_num) {
    442             case 0: /* to */
     437        if (G_filter.family == AF_PACKET) {
     438            bb_error_msg_and_die("can't flush link addresses");
     439        }
     440    }
     441
     442    while (*argv) {
     443        const smalluint key = index_in_strings(option, *argv);
     444        if (key == 0) { /* to */
     445            NEXT_ARG();
     446            get_prefix(&G_filter.pfx, *argv, G_filter.family);
     447            if (G_filter.family == AF_UNSPEC) {
     448                G_filter.family = G_filter.pfx.family;
     449            }
     450        } else if (key == 1) { /* scope */
     451            uint32_t scope = 0;
     452            NEXT_ARG();
     453            G_filter.scopemask = -1;
     454            if (rtnl_rtscope_a2n(&scope, *argv)) {
     455                if (strcmp(*argv, "all") != 0) {
     456                    invarg(*argv, "scope");
     457                }
     458                scope = RT_SCOPE_NOWHERE;
     459                G_filter.scopemask = 0;
     460            }
     461            G_filter.scope = scope;
     462        } else if (key == 2) { /* up */
     463            G_filter.up = 1;
     464        } else if (key == 3) { /* label */
     465            NEXT_ARG();
     466            G_filter.label = *argv;
     467        } else {
     468            if (key == 4) /* dev */
    443469                NEXT_ARG();
    444                 get_prefix(&filter.pfx, *argv, filter.family);
    445                 if (filter.family == AF_UNSPEC) {
    446                     filter.family = filter.pfx.family;
    447                 }
    448                 break;
    449             case 1: /* scope */
    450             {
    451                 uint32_t scope = 0;
    452                 NEXT_ARG();
    453                 filter.scopemask = -1;
    454                 if (rtnl_rtscope_a2n(&scope, *argv)) {
    455                     if (strcmp(*argv, "all") != 0) {
    456                         invarg(*argv, "scope");
    457                     }
    458                     scope = RT_SCOPE_NOWHERE;
    459                     filter.scopemask = 0;
    460                 }
    461                 filter.scope = scope;
    462                 break;
    463             }
    464             case 2: /* up */
    465                 filter.up = 1;
    466                 break;
    467             case 3: /* label */
    468                 NEXT_ARG();
    469                 filter.label = *argv;
    470                 break;
    471             case 4: /* dev */
    472                 NEXT_ARG();
    473             default:
    474                 if (filter_dev) {
    475                     duparg2("dev", *argv);
    476                 }
    477                 filter_dev = *argv;
     470            if (filter_dev)
     471                duparg2("dev", *argv);
     472            filter_dev = *argv;
    478473        }
    479474        argv++;
    480         argc--;
    481475    }
    482476
     
    487481
    488482    if (filter_dev) {
    489         filter.ifindex = xll_name_to_index(filter_dev);
     483        G_filter.ifindex = xll_name_to_index(filter_dev);
    490484    }
    491485
     
    493487        char flushb[4096-512];
    494488
    495         filter.flushb = flushb;
    496         filter.flushp = 0;
    497         filter.flushe = sizeof(flushb);
    498         filter.rth = &rth;
     489        G_filter.flushb = flushb;
     490        G_filter.flushp = 0;
     491        G_filter.flushe = sizeof(flushb);
     492        G_filter.rth = &rth;
    499493
    500494        for (;;) {
    501             xrtnl_wilddump_request(&rth, filter.family, RTM_GETADDR);
    502             filter.flushed = 0;
    503             xrtnl_dump_filter(&rth, print_addrinfo, stdout);
    504             if (filter.flushed == 0) {
     495            xrtnl_wilddump_request(&rth, G_filter.family, RTM_GETADDR);
     496            G_filter.flushed = 0;
     497            xrtnl_dump_filter(&rth, print_addrinfo, NULL);
     498            if (G_filter.flushed == 0) {
    505499                return 0;
    506500            }
    507             if (flush_update() < 0)
     501            if (flush_update() < 0) {
    508502                return 1;
    509         }
    510     }
    511 
    512     if (filter.family != AF_PACKET) {
    513         xrtnl_wilddump_request(&rth, filter.family, RTM_GETADDR);
     503            }
     504        }
     505    }
     506
     507    if (G_filter.family != AF_PACKET) {
     508        xrtnl_wilddump_request(&rth, G_filter.family, RTM_GETADDR);
    514509        xrtnl_dump_filter(&rth, store_nlmsg, &ainfo);
    515510    }
    516511
    517512
    518     if (filter.family && filter.family != AF_PACKET) {
     513    if (G_filter.family && G_filter.family != AF_PACKET) {
    519514        struct nlmsg_list **lp;
    520         lp=&linfo;
    521 
    522         if (filter.oneline)
     515        lp = &linfo;
     516
     517        if (G_filter.oneline)
    523518            no_link = 1;
    524519
    525         while ((l=*lp)!=NULL) {
     520        while ((l = *lp) != NULL) {
    526521            int ok = 0;
    527522            struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
    528523            struct nlmsg_list *a;
    529524
    530             for (a=ainfo; a; a=a->next) {
     525            for (a = ainfo; a; a = a->next) {
    531526                struct nlmsghdr *n = &a->h;
    532527                struct ifaddrmsg *ifa = NLMSG_DATA(n);
    533528
    534                 if (ifa->ifa_index != ifi->ifi_index ||
    535                     (filter.family && filter.family != ifa->ifa_family))
     529                if (ifa->ifa_index != ifi->ifi_index
     530                 || (G_filter.family && G_filter.family != ifa->ifa_family)
     531                ) {
    536532                    continue;
    537                 if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
     533                }
     534                if ((G_filter.scope ^ ifa->ifa_scope) & G_filter.scopemask)
    538535                    continue;
    539                 if ((filter.flags^ifa->ifa_flags)&filter.flagmask)
     536                if ((G_filter.flags ^ ifa->ifa_flags) & G_filter.flagmask)
    540537                    continue;
    541                 if (filter.pfx.family || filter.label) {
     538                if (G_filter.pfx.family || G_filter.label) {
    542539                    struct rtattr *tb[IFA_MAX+1];
    543540                    memset(tb, 0, sizeof(tb));
     
    546543                        tb[IFA_LOCAL] = tb[IFA_ADDRESS];
    547544
    548                     if (filter.pfx.family && tb[IFA_LOCAL]) {
     545                    if (G_filter.pfx.family && tb[IFA_LOCAL]) {
    549546                        inet_prefix dst;
    550547                        memset(&dst, 0, sizeof(dst));
    551548                        dst.family = ifa->ifa_family;
    552549                        memcpy(&dst.data, RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_LOCAL]));
    553                         if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
     550                        if (inet_addr_match(&dst, &G_filter.pfx, G_filter.pfx.bitlen))
    554551                            continue;
    555552                    }
    556                     if (filter.label) {
     553                    if (G_filter.label) {
    557554                        SPRINT_BUF(b1);
    558555                        const char *label;
     
    561558                        else
    562559                            label = ll_idx_n2a(ifa->ifa_index, b1);
    563                         if (fnmatch(filter.label, label, 0) != 0)
     560                        if (fnmatch(G_filter.label, label, 0) != 0)
    564561                            continue;
    565562                    }
     
    577574
    578575    for (l = linfo; l; l = l->next) {
    579         if (no_link || print_linkinfo(NULL, &l->h, stdout) == 0) {
     576        if (no_link || print_linkinfo(&l->h) == 0) {
    580577            struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
    581             if (filter.family != AF_PACKET)
    582                 print_selected_addrinfo(ifi->ifi_index, ainfo, stdout);
    583         }
    584         fflush(stdout); /* why? */
     578            if (G_filter.family != AF_PACKET)
     579                print_selected_addrinfo(ifi->ifi_index, ainfo);
     580        }
    585581    }
    586582
     
    598594
    599595/* Return value becomes exitcode. It's okay to not return at all */
    600 static int ipaddr_modify(int cmd, int argc, char **argv)
     596static int ipaddr_modify(int cmd, char **argv)
    601597{
    602598    static const char option[] ALIGN1 =
     
    626622    req.ifa.ifa_family = preferred_family;
    627623
    628     while (argc > 0) {
    629         const int option_num = index_in_strings(option, *argv);
    630         switch (option_num) {
    631             case 0: /* peer */
    632             case 1: /* remote */
     624    while (*argv) {
     625        const smalluint arg = index_in_strings(option, *argv);
     626        if (arg <= 1) { /* peer, remote */
     627            NEXT_ARG();
     628
     629            if (peer_len) {
     630                duparg("peer", *argv);
     631            }
     632            get_prefix(&peer, *argv, req.ifa.ifa_family);
     633            peer_len = peer.bytelen;
     634            if (req.ifa.ifa_family == AF_UNSPEC) {
     635                req.ifa.ifa_family = peer.family;
     636            }
     637            addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen);
     638            req.ifa.ifa_prefixlen = peer.bitlen;
     639        } else if (arg <= 3) { /* broadcast, brd */
     640            inet_prefix addr;
     641            NEXT_ARG();
     642            if (brd_len) {
     643                duparg("broadcast", *argv);
     644            }
     645            if (LONE_CHAR(*argv, '+')) {
     646                brd_len = -1;
     647            } else if (LONE_DASH(*argv)) {
     648                brd_len = -2;
     649            } else {
     650                get_addr(&addr, *argv, req.ifa.ifa_family);
     651                if (req.ifa.ifa_family == AF_UNSPEC)
     652                    req.ifa.ifa_family = addr.family;
     653                addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen);
     654                brd_len = addr.bytelen;
     655            }
     656        } else if (arg == 4) { /* anycast */
     657            inet_prefix addr;
     658            NEXT_ARG();
     659            if (any_len) {
     660                duparg("anycast", *argv);
     661            }
     662            get_addr(&addr, *argv, req.ifa.ifa_family);
     663            if (req.ifa.ifa_family == AF_UNSPEC) {
     664                req.ifa.ifa_family = addr.family;
     665            }
     666            addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen);
     667            any_len = addr.bytelen;
     668        } else if (arg == 5) { /* scope */
     669            uint32_t scope = 0;
     670            NEXT_ARG();
     671            if (rtnl_rtscope_a2n(&scope, *argv)) {
     672                invarg(*argv, "scope");
     673            }
     674            req.ifa.ifa_scope = scope;
     675            scoped = 1;
     676        } else if (arg == 6) { /* dev */
     677            NEXT_ARG();
     678            d = *argv;
     679        } else if (arg == 7) { /* label */
     680            NEXT_ARG();
     681            l = *argv;
     682            addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1);
     683        } else {
     684            if (arg == 8) /* local */
    633685                NEXT_ARG();
    634 
    635                 if (peer_len) {
    636                     duparg("peer", *argv);
    637                 }
    638                 get_prefix(&peer, *argv, req.ifa.ifa_family);
    639                 peer_len = peer.bytelen;
    640                 if (req.ifa.ifa_family == AF_UNSPEC) {
    641                     req.ifa.ifa_family = peer.family;
    642                 }
    643                 addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen);
    644                 req.ifa.ifa_prefixlen = peer.bitlen;
    645                 break;
    646             case 2: /* broadcast */
    647             case 3: /* brd */
    648             {
    649                 inet_prefix addr;
    650                 NEXT_ARG();
    651                 if (brd_len) {
    652                     duparg("broadcast", *argv);
    653                 }
    654                 if (LONE_CHAR(*argv, '+')) {
    655                     brd_len = -1;
    656                 }
    657                 else if (LONE_DASH(*argv)) {
    658                     brd_len = -2;
    659                 } else {
    660                     get_addr(&addr, *argv, req.ifa.ifa_family);
    661                     if (req.ifa.ifa_family == AF_UNSPEC)
    662                         req.ifa.ifa_family = addr.family;
    663                     addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen);
    664                     brd_len = addr.bytelen;
    665                 }
    666                 break;
    667             }
    668             case 4: /* anycast */
    669             {
    670                 inet_prefix addr;
    671                 NEXT_ARG();
    672                 if (any_len) {
    673                     duparg("anycast", *argv);
    674                 }
    675                 get_addr(&addr, *argv, req.ifa.ifa_family);
    676                 if (req.ifa.ifa_family == AF_UNSPEC) {
    677                     req.ifa.ifa_family = addr.family;
    678                 }
    679                 addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen);
    680                 any_len = addr.bytelen;
    681                 break;
    682             }
    683             case 5: /* scope */
    684             {
    685                 uint32_t scope = 0;
    686                 NEXT_ARG();
    687                 if (rtnl_rtscope_a2n(&scope, *argv)) {
    688                     invarg(*argv, "scope");
    689                 }
    690                 req.ifa.ifa_scope = scope;
    691                 scoped = 1;
    692                 break;
    693             }
    694             case 6: /* dev */
    695                 NEXT_ARG();
    696                 d = *argv;
    697                 break;
    698             case 7: /* label */
    699                 NEXT_ARG();
    700                 l = *argv;
    701                 addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l)+1);
    702                 break;
    703             case 8: /* local */
    704                 NEXT_ARG();
    705             default:
    706                 if (local_len) {
    707                     duparg2("local", *argv);
    708                 }
    709                 get_prefix(&lcl, *argv, req.ifa.ifa_family);
    710                 if (req.ifa.ifa_family == AF_UNSPEC) {
    711                     req.ifa.ifa_family = lcl.family;
    712                 }
    713                 addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen);
    714                 local_len = lcl.bytelen;
    715         }
    716         argc--;
     686            if (local_len) {
     687                duparg2("local", *argv);
     688            }
     689            get_prefix(&lcl, *argv, req.ifa.ifa_family);
     690            if (req.ifa.ifa_family == AF_UNSPEC) {
     691                req.ifa.ifa_family = lcl.family;
     692            }
     693            addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen);
     694            local_len = lcl.bytelen;
     695        }
    717696        argv++;
    718697    }
    719698
    720     if (d == NULL) {
    721         bb_error_msg(bb_msg_requires_arg,"\"dev\"");
    722         return -1;
     699    if (!d) {
     700        /* There was no "dev IFACE", but we need that */
     701        bb_error_msg_and_die("need \"dev IFACE\"");
    723702    }
    724703    if (l && strncmp(d, l, strlen(d)) != 0) {
     
    767746
    768747/* Return value becomes exitcode. It's okay to not return at all */
    769 int do_ipaddr(int argc, char **argv)
     748int FAST_FUNC do_ipaddr(char **argv)
    770749{
    771750    static const char commands[] ALIGN1 =
    772751        "add\0""delete\0""list\0""show\0""lst\0""flush\0";
    773 
    774     int command_num = 2; /* default command is list */
    775 
     752    smalluint cmd = 2;
    776753    if (*argv) {
    777         command_num = index_in_substrings(commands, *argv);
    778     }
    779     if (command_num < 0 || command_num > 5)
    780         bb_error_msg_and_die("unknown command %s", *argv);
    781     --argc;
    782     ++argv;
    783     if (command_num == 0) /* add */
    784         return ipaddr_modify(RTM_NEWADDR, argc, argv);
    785     else if (command_num == 1) /* delete */
    786         return ipaddr_modify(RTM_DELADDR, argc, argv);
    787     else if (command_num == 5) /* flush */
    788         return ipaddr_list_or_flush(argc, argv, 1);
    789     else /* 2 == list, 3 == show, 4 == lst */
    790         return ipaddr_list_or_flush(argc, argv, 0);
    791 }
     754        cmd = index_in_substrings(commands, *argv);
     755        if (cmd > 5)
     756            bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
     757        argv++;
     758        if (cmd <= 1)
     759            return ipaddr_modify((cmd == 0) ? RTM_NEWADDR : RTM_DELADDR, argv);
     760    }
     761    /* 2 == list, 3 == show, 4 == lst */
     762    return ipaddr_list_or_flush(argv, cmd == 5);
     763}
Note: See TracChangeset for help on using the changeset viewer.