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/iplink.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * iplink.c "ip link".
    4  *
    53 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    64 *
    7  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     5 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    86 */
    9 
    10 //#include <sys/ioctl.h>
    11 //#include <sys/socket.h>
    127#include <net/if.h>
    138#include <net/if_packet.h>
     
    1914#include "utils.h"
    2015
     16#ifndef IFLA_LINKINFO
     17# define IFLA_LINKINFO 18
     18# define IFLA_INFO_KIND 1
     19#endif
     20
    2121/* taken from linux/sockios.h */
    22 #define SIOCSIFNAME 0x8923      /* set interface name */
    23 
    24 static void on_off(const char *msg) ATTRIBUTE_NORETURN;
    25 static void on_off(const char *msg)
    26 {
    27     bb_error_msg_and_die("error: argument of \"%s\" must be \"on\" or \"off\"", msg);
    28 }
     22#define SIOCSIFNAME  0x8923  /* set interface name */
    2923
    3024/* Exits on error */
     
    4842    int fd;
    4943
    50     strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
     44    strncpy_IFNAMSIZ(ifr.ifr_name, dev);
    5145    fd = get_ctl_fd();
    5246    xioctl(fd, SIOCGIFFLAGS, &ifr);
     
    6559    int fd;
    6660
    67     strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
    68     strncpy(ifr.ifr_newname, newdev, sizeof(ifr.ifr_newname));
     61    strncpy_IFNAMSIZ(ifr.ifr_name, dev);
     62    strncpy_IFNAMSIZ(ifr.ifr_newname, newdev);
    6963    fd = get_ctl_fd();
    7064    xioctl(fd, SIOCSIFNAME, &ifr);
     
    8074    s = get_ctl_fd();
    8175    memset(&ifr, 0, sizeof(ifr));
    82     strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
     76    strncpy_IFNAMSIZ(ifr.ifr_name, dev);
    8377    ifr.ifr_qlen = qlen;
    8478    xioctl(s, SIOCSIFTXQLEN, &ifr);
     
    9488    s = get_ctl_fd();
    9589    memset(&ifr, 0, sizeof(ifr));
    96     strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
     90    strncpy_IFNAMSIZ(ifr.ifr_name, dev);
    9791    ifr.ifr_mtu = mtu;
    9892    xioctl(s, SIOCSIFMTU, &ifr);
     
    111105
    112106    memset(&ifr, 0, sizeof(ifr));
    113     strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
     107    strncpy_IFNAMSIZ(ifr.ifr_name, dev);
    114108    xioctl(s, SIOCGIFINDEX, &ifr);
    115109
     
    119113    me.sll_protocol = htons(ETH_P_LOOP);
    120114    xbind(s, (struct sockaddr*)&me, sizeof(me));
    121 
    122115    alen = sizeof(me);
    123     if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) {
    124         bb_perror_msg_and_die("getsockname");
    125     }
     116    getsockname(s, (struct sockaddr*)&me, &alen);
     117    //never happens:
     118    //if (getsockname(s, (struct sockaddr*)&me, &alen) == -1)
     119    //  bb_perror_msg_and_die("getsockname");
    126120    close(s);
    127121    *htype = me.sll_hatype;
     
    135129
    136130    memset(ifr, 0, sizeof(*ifr));
    137     strncpy(ifr->ifr_name, dev, sizeof(ifr->ifr_name));
     131    strncpy_IFNAMSIZ(ifr->ifr_name, dev);
    138132    ifr->ifr_hwaddr.sa_family = hatype;
    139     alen = ll_addr_a2n((unsigned char *)(ifr->ifr_hwaddr.sa_data), 14, lla);
     133
     134    alen = hatype == 1/*ARPHRD_ETHER*/ ? 14/*ETH_HLEN*/ : 19/*INFINIBAND_HLEN*/;
     135    alen = ll_addr_a2n((unsigned char *)(ifr->ifr_hwaddr.sa_data), alen, lla);
    140136    if (alen < 0)
    141         exit(1);
     137        exit(EXIT_FAILURE);
    142138    if (alen != halen) {
    143139        bb_error_msg_and_die("wrong address (%s) length: expected %d bytes", lla, halen);
     
    159155
    160156
     157static void die_must_be_on_off(const char *msg) NORETURN;
     158static void die_must_be_on_off(const char *msg)
     159{
     160    bb_error_msg_and_die("argument of \"%s\" must be \"on\" or \"off\"", msg);
     161}
     162
    161163/* Return value becomes exitcode. It's okay to not return at all */
    162 static int do_set(int argc, char **argv)
     164static int do_set(char **argv)
    163165{
    164166    char *dev = NULL;
     
    173175    int htype, halen;
    174176    static const char keywords[] ALIGN1 =
    175         "up\0""down\0""name\0""mtu\0""multicast\0""arp\0""addr\0""dev\0"
    176         "on\0""off\0";
    177     enum { ARG_up = 1, ARG_down, ARG_name, ARG_mtu, ARG_multicast, ARG_arp,
    178         ARG_addr, ARG_dev, PARM_on, PARM_off };
     177        "up\0""down\0""name\0""mtu\0""qlen\0""multicast\0"
     178        "arp\0""address\0""dev\0";
     179    enum { ARG_up = 0, ARG_down, ARG_name, ARG_mtu, ARG_qlen, ARG_multicast,
     180        ARG_arp, ARG_addr, ARG_dev };
     181    static const char str_on_off[] ALIGN1 = "on\0""off\0";
     182    enum { PARM_on = 0, PARM_off };
    179183    smalluint key;
    180184
    181     while (argc > 0) {
    182         key = index_in_strings(keywords, *argv) + 1;
     185    while (*argv) {
     186        /* substring search ensures that e.g. "addr" and "address"
     187         * are both accepted */
     188        key = index_in_substrings(keywords, *argv);
    183189        if (key == ARG_up) {
    184190            mask |= IFF_UP;
     
    194200            if (mtu != -1)
    195201                duparg("mtu", *argv);
    196             if (get_integer(&mtu, *argv, 0))
    197                 invarg(*argv, "mtu");
    198         } else if (key == ARG_multicast) {
    199             NEXT_ARG();
    200             mask |= IFF_MULTICAST;
    201             key = index_in_strings(keywords, *argv) + 1;
    202             if (key == PARM_on) {
    203                 flags |= IFF_MULTICAST;
    204             } else if (key == PARM_off) {
    205                 flags &= ~IFF_MULTICAST;
    206             } else
    207                 on_off("multicast");
    208         } else if (key == ARG_arp) {
    209             NEXT_ARG();
    210             mask |= IFF_NOARP;
    211             key = index_in_strings(keywords, *argv) + 1;
    212             if (key == PARM_on) {
    213                 flags &= ~IFF_NOARP;
    214             } else if (key == PARM_off) {
    215                 flags |= IFF_NOARP;
    216             } else
    217                 on_off("arp");
     202            mtu = get_unsigned(*argv, "mtu");
     203        } else if (key == ARG_qlen) {
     204            NEXT_ARG();
     205            if (qlen != -1)
     206                duparg("qlen", *argv);
     207            qlen = get_unsigned(*argv, "qlen");
    218208        } else if (key == ARG_addr) {
    219209            NEXT_ARG();
    220210            newaddr = *argv;
    221         } else {
     211        } else if (key >= ARG_dev) {
    222212            if (key == ARG_dev) {
    223213                NEXT_ARG();
     
    226216                duparg2("dev", *argv);
    227217            dev = *argv;
    228         }
    229         argc--; argv++;
     218        } else {
     219            int param;
     220            NEXT_ARG();
     221            param = index_in_strings(str_on_off, *argv);
     222            if (key == ARG_multicast) {
     223                if (param < 0)
     224                    die_must_be_on_off("multicast");
     225                mask |= IFF_MULTICAST;
     226                if (param == PARM_on)
     227                    flags |= IFF_MULTICAST;
     228                else
     229                    flags &= ~IFF_MULTICAST;
     230            } else if (key == ARG_arp) {
     231                if (param < 0)
     232                    die_must_be_on_off("arp");
     233                mask |= IFF_NOARP;
     234                if (param == PARM_on)
     235                    flags &= ~IFF_NOARP;
     236                else
     237                    flags |= IFF_NOARP;
     238            }
     239        }
     240        argv++;
    230241    }
    231242
     
    238249        if (newaddr) {
    239250            parse_address(dev, htype, halen, newaddr, &ifr0);
     251            set_address(&ifr0, 0);
    240252        }
    241253        if (newbrd) {
    242254            parse_address(dev, htype, halen, newbrd, &ifr1);
     255            set_address(&ifr1, 1);
    243256        }
    244257    }
     
    254267        set_mtu(dev, mtu);
    255268    }
    256     if (newaddr || newbrd) {
    257         if (newbrd) {
    258             set_address(&ifr1, 1);
    259         }
    260         if (newaddr) {
    261             set_address(&ifr0, 0);
    262         }
    263     }
    264269    if (mask)
    265270        do_chflags(dev, flags, mask);
     
    267272}
    268273
    269 static int ipaddr_list_link(int argc, char **argv)
     274static int ipaddr_list_link(char **argv)
    270275{
    271276    preferred_family = AF_PACKET;
    272     return ipaddr_list_or_flush(argc, argv, 0);
    273 }
    274 
     277    return ipaddr_list_or_flush(argv, 0);
     278}
     279
     280#ifndef NLMSG_TAIL
     281#define NLMSG_TAIL(nmsg) \
     282    ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
     283#endif
    275284/* Return value becomes exitcode. It's okay to not return at all */
    276 int do_iplink(int argc, char **argv)
     285static int do_change(char **argv, const unsigned rtm)
    277286{
    278287    static const char keywords[] ALIGN1 =
    279         "set\0""show\0""lst\0""list\0";
    280     smalluint key;
    281     if (argc <= 0)
    282         return ipaddr_list_link(0, NULL);
    283     key = index_in_substrings(keywords, *argv) + 1;
    284     if (key == 0)
    285         bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
    286     argc--; argv++;
    287     if (key == 1) /* set */
    288         return do_set(argc, argv);
    289     else /* show, lst, list */
    290         return ipaddr_list_link(argc, argv);
    291 }
     288        "link\0""name\0""type\0""dev\0";
     289    enum {
     290        ARG_link,
     291        ARG_name,
     292        ARG_type,
     293        ARG_dev,
     294    };
     295    struct rtnl_handle rth;
     296    struct {
     297        struct nlmsghdr  n;
     298        struct ifinfomsg i;
     299        char             buf[1024];
     300    } req;
     301    smalluint arg;
     302    char *name_str = NULL, *link_str = NULL, *type_str = NULL, *dev_str = NULL;
     303
     304    memset(&req, 0, sizeof(req));
     305
     306    req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
     307    req.n.nlmsg_flags = NLM_F_REQUEST;
     308    req.n.nlmsg_type = rtm;
     309    req.i.ifi_family = preferred_family;
     310    if (rtm == RTM_NEWLINK)
     311        req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
     312
     313    while (*argv) {
     314        arg = index_in_substrings(keywords, *argv);
     315        if (arg == ARG_link) {
     316            NEXT_ARG();
     317            link_str = *argv;
     318        } else if (arg == ARG_name) {
     319            NEXT_ARG();
     320            name_str = *argv;
     321        } else if (arg == ARG_type) {
     322            NEXT_ARG();
     323            type_str = *argv;
     324        } else {
     325            if (arg == ARG_dev) {
     326                if (dev_str)
     327                    duparg(*argv, "dev");
     328                NEXT_ARG();
     329            }
     330            dev_str = *argv;
     331        }
     332        argv++;
     333    }
     334    xrtnl_open(&rth);
     335    ll_init_map(&rth);
     336    if (type_str) {
     337        struct rtattr *linkinfo = NLMSG_TAIL(&req.n);
     338
     339        addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0);
     340        addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, type_str,
     341                strlen(type_str));
     342        linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo;
     343    }
     344    if (rtm != RTM_NEWLINK) {
     345        if (!dev_str)
     346            return 1; /* Need a device to delete */
     347        req.i.ifi_index = xll_name_to_index(dev_str);
     348    } else {
     349        if (!name_str)
     350            name_str = dev_str;
     351        if (link_str) {
     352            int idx = xll_name_to_index(link_str);
     353            addattr_l(&req.n, sizeof(req), IFLA_LINK, &idx, 4);
     354        }
     355    }
     356    if (name_str) {
     357        const size_t name_len = strlen(name_str) + 1;
     358        if (name_len < 2 || name_len > IFNAMSIZ)
     359            invarg(name_str, "name");
     360        addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name_str, name_len);
     361    }
     362    if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
     363        return 2;
     364    return 0;
     365}
     366
     367/* Return value becomes exitcode. It's okay to not return at all */
     368int FAST_FUNC do_iplink(char **argv)
     369{
     370    static const char keywords[] ALIGN1 =
     371        "add\0""delete\0""set\0""show\0""lst\0""list\0";
     372    if (*argv) {
     373        smalluint key = index_in_substrings(keywords, *argv);
     374        if (key > 5) /* invalid argument */
     375            bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
     376        argv++;
     377        if (key <= 1) /* add/delete */
     378            return do_change(argv, key ? RTM_DELLINK : RTM_NEWLINK);
     379        else if (key == 2) /* set */
     380            return do_set(argv);
     381    }
     382    /* show, lst, list */
     383    return ipaddr_list_link(argv);
     384}
Note: See TracChangeset for help on using the changeset viewer.