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

    r1765 r2725  
    55 * Written 2000 by Andi Kleen.
    66 * Busybox port 2002 by Nick Fedchik <nick@fedchik.org.ua>
    7  *          Glenn McGrath <bug1@iinet.net.au>
     7 *          Glenn McGrath
     8 * Extended matching support 2008 by Nico Erfurth <masta@perlgolf.de>
    89 *
    9  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
     10 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    1011 */
    1112
     
    1415#include <net/if.h>
    1516#include <netinet/ether.h>
    16 
    17 
    18 /* Older versions of net/if.h do not appear to define IF_NAMESIZE. */
    19 #ifndef IF_NAMESIZE
    20 #  ifdef IFNAMSIZ
    21 #    define IF_NAMESIZE IFNAMSIZ
    22 #  else
    23 #    define IF_NAMESIZE 16
    24 #  endif
    25 #endif
    26 
    27 /* take from linux/sockios.h */
    28 #define SIOCSIFNAME 0x8923  /* set interface name */
     17#include <linux/sockios.h>
     18
     19#ifndef IFNAMSIZ
     20#define IFNAMSIZ 16
     21#endif
     22
     23/* Taken from linux/sockios.h */
     24#define SIOCSIFNAME  0x8923  /* set interface name */
    2925
    3026/* Octets in one Ethernet addr, from <linux/if_ether.h> */
    31 #define ETH_ALEN    6
     27#define ETH_ALEN     6
    3228
    3329#ifndef ifr_newname
     
    3531#endif
    3632
    37 typedef struct mactable_s {
    38     struct mactable_s *next;
    39     struct mactable_s *prev;
     33typedef struct ethtable_s {
     34    struct ethtable_s *next;
     35    struct ethtable_s *prev;
    4036    char *ifname;
    4137    struct ether_addr *mac;
    42 } mactable_t;
    43 
    44 /* Check ascii str_macaddr, convert and copy to *mac */
    45 static struct ether_addr *cc_macaddr(const char *str_macaddr)
    46 {
    47     struct ether_addr *lmac, *mac;
    48 
    49     lmac = ether_aton(str_macaddr);
    50     if (lmac == NULL)
    51         bb_error_msg_and_die("cannot parse MAC %s", str_macaddr);
    52     mac = xmalloc(ETH_ALEN);
    53     memcpy(mac, lmac, ETH_ALEN);
    54 
    55     return mac;
     38#if ENABLE_FEATURE_NAMEIF_EXTENDED
     39    char *bus_info;
     40    char *driver;
     41#endif
     42} ethtable_t;
     43
     44#if ENABLE_FEATURE_NAMEIF_EXTENDED
     45/* Cut'n'paste from ethtool.h */
     46#define ETHTOOL_BUSINFO_LEN 32
     47/* these strings are set to whatever the driver author decides... */
     48struct ethtool_drvinfo {
     49    uint32_t cmd;
     50    char  driver[32]; /* driver short name, "tulip", "eepro100" */
     51    char  version[32];  /* driver version string */
     52    char  fw_version[32]; /* firmware version string, if applicable */
     53    char  bus_info[ETHTOOL_BUSINFO_LEN];  /* Bus info for this IF. */
     54    /* For PCI devices, use pci_dev->slot_name. */
     55    char  reserved1[32];
     56    char  reserved2[16];
     57    uint32_t n_stats;  /* number of u64's from ETHTOOL_GSTATS */
     58    uint32_t testinfo_len;
     59    uint32_t eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */
     60    uint32_t regdump_len;  /* Size of data from ETHTOOL_GREGS (bytes) */
     61};
     62#define ETHTOOL_GDRVINFO  0x00000003 /* Get driver info. */
     63#endif
     64
     65
     66static void nameif_parse_selector(ethtable_t *ch, char *selector)
     67{
     68    struct ether_addr *lmac;
     69#if ENABLE_FEATURE_NAMEIF_EXTENDED
     70    int found_selector = 0;
     71
     72    while (*selector) {
     73        char *next;
     74#endif
     75        selector = skip_whitespace(selector);
     76#if ENABLE_FEATURE_NAMEIF_EXTENDED
     77        if (*selector == '\0')
     78            break;
     79        /* Search for the end .... */
     80        next = skip_non_whitespace(selector);
     81        if (*next)
     82            *next++ = '\0';
     83        /* Check for selectors, mac= is assumed */
     84        if (strncmp(selector, "bus=", 4) == 0) {
     85            ch->bus_info = xstrdup(selector + 4);
     86            found_selector++;
     87        } else if (strncmp(selector, "driver=", 7) == 0) {
     88            ch->driver = xstrdup(selector + 7);
     89            found_selector++;
     90        } else {
     91#endif
     92            lmac = xmalloc(ETH_ALEN);
     93            ch->mac = ether_aton_r(selector + (strncmp(selector, "mac=", 4) != 0 ? 0 : 4), lmac);
     94            if (ch->mac == NULL)
     95                bb_error_msg_and_die("can't parse %s", selector);
     96#if  ENABLE_FEATURE_NAMEIF_EXTENDED
     97            found_selector++;
     98        };
     99        selector = next;
     100    }
     101    if (found_selector == 0)
     102        bb_error_msg_and_die("no selectors found for %s", ch->ifname);
     103#endif
    56104}
    57105
    58 int nameif_main(int argc, char **argv);
     106static void prepend_new_eth_table(ethtable_t **clist, char *ifname, char *selector)
     107{
     108    ethtable_t *ch;
     109    if (strlen(ifname) >= IFNAMSIZ)
     110        bb_error_msg_and_die("interface name '%s' too long", ifname);
     111    ch = xzalloc(sizeof(*ch));
     112    ch->ifname = xstrdup(ifname);
     113    nameif_parse_selector(ch, selector);
     114    ch->next = *clist;
     115    if (*clist)
     116        (*clist)->prev = ch;
     117    *clist = ch;
     118}
     119
     120#if ENABLE_FEATURE_CLEAN_UP
     121static void delete_eth_table(ethtable_t *ch)
     122{
     123    free(ch->ifname);
     124#if ENABLE_FEATURE_NAMEIF_EXTENDED
     125    free(ch->bus_info);
     126    free(ch->driver);
     127#endif
     128    free(ch->mac);
     129    free(ch);
     130};
     131#else
     132void delete_eth_table(ethtable_t *ch);
     133#endif
     134
     135int nameif_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    59136int nameif_main(int argc, char **argv)
    60137{
    61     mactable_t *clist = NULL;
    62     FILE *ifh;
     138    ethtable_t *clist = NULL;
    63139    const char *fname = "/etc/mactab";
    64     char *line;
    65140    int ctl_sk;
    66     int if_index = 1;
    67     mactable_t *ch;
     141    ethtable_t *ch;
     142    parser_t *parser;
     143    char *token[2];
    68144
    69145    if (1 & getopt32(argv, "sc:", &fname)) {
    70146        openlog(applet_name, 0, LOG_LOCAL0);
    71         logmode = LOGMODE_SYSLOG;
    72     }
    73 
    74     if ((argc - optind) & 1)
     147        /* Why not just "="? I assume logging to stderr
     148         * can't hurt. 2>/dev/null if you don't like it: */
     149        logmode |= LOGMODE_SYSLOG;
     150    }
     151    argc -= optind;
     152    argv += optind;
     153
     154    if (argc & 1)
    75155        bb_show_usage();
    76156
    77     if (optind < argc) {
    78         char **a = argv + optind;
    79 
    80         while (*a) {
    81             if (strlen(*a) > IF_NAMESIZE)
    82                 bb_error_msg_and_die("interface name '%s' "
    83                         "too long", *a);
    84             ch = xzalloc(sizeof(mactable_t));
    85             ch->ifname = xstrdup(*a++);
    86             ch->mac = cc_macaddr(*a++);
    87             if (clist)
    88                 clist->prev = ch;
    89             ch->next = clist;
    90             clist = ch;
     157    if (argc) {
     158        while (*argv) {
     159            char *ifname = xstrdup(*argv++);
     160            prepend_new_eth_table(&clist, ifname, *argv++);
    91161        }
    92162    } else {
    93         ifh = xfopen(fname, "r");
    94 
    95         while ((line = xmalloc_fgets(ifh)) != NULL) {
    96             char *line_ptr;
    97             size_t name_length;
    98 
    99             line_ptr = line + strspn(line, " \t");
    100             if ((line_ptr[0] == '#') || (line_ptr[0] == '\n')) {
    101                 free(line);
     163        parser = config_open(fname);
     164        while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL))
     165            prepend_new_eth_table(&clist, token[0], token[1]);
     166        config_close(parser);
     167    }
     168
     169    ctl_sk = xsocket(PF_INET, SOCK_DGRAM, 0);
     170    parser = config_open2("/proc/net/dev", xfopen_for_read);
     171
     172    while (clist && config_read(parser, token, 2, 2, "\0: \t", PARSE_NORMAL)) {
     173        struct ifreq ifr;
     174#if  ENABLE_FEATURE_NAMEIF_EXTENDED
     175        struct ethtool_drvinfo drvinfo;
     176#endif
     177        if (parser->lineno < 2)
     178            continue; /* Skip the first two lines */
     179
     180        /* Find the current interface name and copy it to ifr.ifr_name */
     181        memset(&ifr, 0, sizeof(struct ifreq));
     182        strncpy_IFNAMSIZ(ifr.ifr_name, token[0]);
     183
     184#if ENABLE_FEATURE_NAMEIF_EXTENDED
     185        /* Check for driver etc. */
     186        memset(&drvinfo, 0, sizeof(struct ethtool_drvinfo));
     187        drvinfo.cmd = ETHTOOL_GDRVINFO;
     188        ifr.ifr_data = (caddr_t) &drvinfo;
     189        /* Get driver and businfo first, so we have it in drvinfo */
     190        ioctl(ctl_sk, SIOCETHTOOL, &ifr);
     191#endif
     192        ioctl(ctl_sk, SIOCGIFHWADDR, &ifr);
     193
     194        /* Search the list for a matching device */
     195        for (ch = clist; ch; ch = ch->next) {
     196#if ENABLE_FEATURE_NAMEIF_EXTENDED
     197            if (ch->bus_info && strcmp(ch->bus_info, drvinfo.bus_info) != 0)
    102198                continue;
    103             }
    104             name_length = strcspn(line_ptr, " \t");
    105             ch = xzalloc(sizeof(mactable_t));
    106             ch->ifname = xstrndup(line_ptr, name_length);
    107             if (name_length > IF_NAMESIZE)
    108                 bb_error_msg_and_die("interface name '%s' "
    109                         "too long", ch->ifname);
    110             line_ptr += name_length;
    111             line_ptr += strspn(line_ptr, " \t");
    112             name_length = strspn(line_ptr, "0123456789ABCDEFabcdef:");
    113             line_ptr[name_length] = '\0';
    114             ch->mac = cc_macaddr(line_ptr);
    115             if (clist)
    116                 clist->prev = ch;
    117             ch->next = clist;
    118             clist = ch;
    119             free(line);
     199            if (ch->driver && strcmp(ch->driver, drvinfo.driver) != 0)
     200                continue;
     201#endif
     202            if (ch->mac && memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN) != 0)
     203                continue;
     204            /* if we came here, all selectors have matched */
     205            break;
    120206        }
    121         fclose(ifh);
    122     }
    123 
    124     ctl_sk = xsocket(PF_INET, SOCK_DGRAM, 0);
    125 
    126     while (clist) {
    127         struct ifreq ifr;
    128 
    129         memset(&ifr, 0, sizeof(struct ifreq));
    130         if_index++;
    131         ifr.ifr_ifindex = if_index;
    132 
    133         /* Get ifname by index or die */
    134         if (ioctl(ctl_sk, SIOCGIFNAME, &ifr))
    135             break;
    136 
    137         /* Has this device hwaddr? */
    138         if (ioctl(ctl_sk, SIOCGIFHWADDR, &ifr))
     207        /* Nothing found for current interface */
     208        if (!ch)
    139209            continue;
    140210
    141         /* Search for mac like in ifr.ifr_hwaddr.sa_data */
     211        if (strcmp(ifr.ifr_name, ch->ifname) != 0) {
     212            strcpy(ifr.ifr_newname, ch->ifname);
     213            ioctl_or_perror_and_die(ctl_sk, SIOCSIFNAME, &ifr,
     214                    "can't change ifname %s to %s",
     215                    ifr.ifr_name, ch->ifname);
     216        }
     217        /* Remove list entry of renamed interface */
     218        if (ch->prev != NULL)
     219            ch->prev->next = ch->next;
     220        else
     221            clist = ch->next;
     222        if (ch->next != NULL)
     223            ch->next->prev = ch->prev;
     224        if (ENABLE_FEATURE_CLEAN_UP)
     225            delete_eth_table(ch);
     226    }
     227    if (ENABLE_FEATURE_CLEAN_UP) {
    142228        for (ch = clist; ch; ch = ch->next)
    143             if (!memcmp(ch->mac, ifr.ifr_hwaddr.sa_data, ETH_ALEN))
    144                 break;
    145 
    146         /* Nothing found for current ifr.ifr_hwaddr.sa_data */
    147         if (ch == NULL)
    148             continue;
    149 
    150         strcpy(ifr.ifr_newname, ch->ifname);
    151         ioctl_or_perror_and_die(ctl_sk, SIOCSIFNAME, &ifr,
    152                     "cannot change ifname %s to %s",
    153                     ifr.ifr_name, ch->ifname);
    154 
    155         /* Remove list entry of renamed interface */
    156         if (ch->prev != NULL) {
    157             (ch->prev)->next = ch->next;
    158         } else {
    159             clist = ch->next;
    160         }
    161         if (ch->next != NULL)
    162             (ch->next)->prev = ch->prev;
    163         if (ENABLE_FEATURE_CLEAN_UP) {
    164             free(ch->ifname);
    165             free(ch->mac);
    166             free(ch);
    167         }
    168     }
     229            delete_eth_table(ch);
     230        config_close(parser);
     231    };
    169232
    170233    return 0;
Note: See TracChangeset for help on using the changeset viewer.