Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (17 years ago)
Author:
Bruno Cornec
Message:

Update to busybox 1.7.2

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.5/mindi-busybox/networking/ifconfig.c

    r821 r1765  
    2727 */
    2828
    29 #include <stdio.h>
    30 #include <stdlib.h>
    31 #include <string.h>     /* strcmp and friends */
    32 #include <ctype.h>      /* isdigit and friends */
    33 #include <stddef.h>     /* offsetof */
    34 #include <unistd.h>
    35 #include <netdb.h>
    36 #include <sys/ioctl.h>
    3729#include <net/if.h>
    3830#include <net/if_arp.h>
    3931#include <netinet/in.h>
    40 #if __GLIBC__ >=2 && __GLIBC_MINOR >= 1
     32#if defined(__GLIBC__) && __GLIBC__ >=2 && __GLIBC_MINOR__ >= 1
    4133#include <netpacket/packet.h>
    4234#include <net/ethernet.h>
     
    4638#endif
    4739#include "inet_common.h"
    48 #include "busybox.h"
    49 
    50 #ifdef CONFIG_FEATURE_IFCONFIG_SLIP
     40#include "libbb.h"
     41
     42#if ENABLE_FEATURE_IFCONFIG_SLIP
    5143# include <net/if_slip.h>
    5244#endif
     
    7163#endif
    7264
    73 #ifdef CONFIG_FEATURE_IPV6
     65#if ENABLE_FEATURE_IPV6
    7466struct in6_ifreq {
    7567    struct in6_addr ifr6_addr;
     
    122114#define A_SET_AFTER      0x40   /* Set a flag at the end. */
    123115#define A_COLON_CHK      0x80   /* Is this needed?  See below. */
    124 #ifdef CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS
     116#if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS
    125117#define A_HOSTNAME      0x100   /* Set if it is ip addr. */
    126118#define A_BROADCAST     0x200   /* Set if it is broadcast addr. */
     
    179171struct options {
    180172    const char *name;
    181 #ifdef CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS
     173#if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS
    182174    const unsigned int flags:6;
    183175    const unsigned int arg_flags:10;
     
    198190    {"SIOCSIFNETMASK", SIOCSIFNETMASK, ifreq_offsetof(ifr_netmask)},
    199191    {"SIOCSIFBRDADDR", SIOCSIFBRDADDR, ifreq_offsetof(ifr_broadaddr)},
    200 #ifdef CONFIG_FEATURE_IFCONFIG_HW
     192#if ENABLE_FEATURE_IFCONFIG_HW
    201193    {"SIOCSIFHWADDR",  SIOCSIFHWADDR,  ifreq_offsetof(ifr_hwaddr)},
    202194#endif
     
    208200    {"SIOCSOUTFILL",   SIOCSOUTFILL,   ifreq_offsetof(ifr_data)},
    209201#endif
    210 #ifdef CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ
     202#if ENABLE_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ
    211203    {"SIOCSIFMAP",     SIOCSIFMAP,     ifreq_offsetof(ifr_map.mem_start)},
    212204    {"SIOCSIFMAP",     SIOCSIFMAP,     ifreq_offsetof(ifr_map.base_addr)},
     
    214206#endif
    215207    /* Last entry if for unmatched (possibly hostname) arg. */
    216 #ifdef CONFIG_FEATURE_IPV6
     208#if ENABLE_FEATURE_IPV6
    217209    {"SIOCSIFADDR",    SIOCSIFADDR,    ifreq_offsetof(ifr_addr)}, /* IPv6 version ignores the offset */
    218210    {"SIOCDIFADDR",    SIOCDIFADDR,    ifreq_offsetof(ifr_addr)}, /* IPv6 version ignores the offset */
     
    228220    {"netmask",     N_ARG,         ARG_NETMASK,     0},
    229221    {"broadcast",   N_ARG | M_CLR, ARG_BROADCAST,   IFF_BROADCAST},
    230 #ifdef CONFIG_FEATURE_IFCONFIG_HW
     222#if ENABLE_FEATURE_IFCONFIG_HW
    231223    {"hw",          N_ARG, ARG_HW,                  0},
    232224#endif
     
    238230    {"outfill",     N_ARG,         ARG_OUTFILL,     0},
    239231#endif
    240 #ifdef CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ
     232#if ENABLE_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ
    241233    {"mem_start",   N_ARG,         ARG_MEM_START,   0},
    242234    {"io_addr",     N_ARG,         ARG_IO_ADDR,     0},
    243235    {"irq",         N_ARG,         ARG_IRQ,         0},
    244236#endif
    245 #ifdef CONFIG_FEATURE_IPV6
     237#if ENABLE_FEATURE_IPV6
    246238    {"add",         N_ARG,         ARG_ADD_DEL,     0},
    247239    {"del",         N_ARG,         ARG_ADD_DEL,     0},
     
    262254 */
    263255
    264 #ifdef CONFIG_FEATURE_IFCONFIG_HW
    265 static int in_ether(char *bufp, struct sockaddr *sap);
    266 #endif
    267 
    268 #ifdef CONFIG_FEATURE_IFCONFIG_STATUS
    269 extern int interface_opt_a;
    270 extern int display_interfaces(char *ifname);
     256#if ENABLE_FEATURE_IFCONFIG_HW
     257static int in_ether(const char *bufp, struct sockaddr *sap);
    271258#endif
    272259
     
    275262 */
    276263
     264int ifconfig_main(int argc, char **argv);
    277265int ifconfig_main(int argc, char **argv)
    278266{
    279267    struct ifreq ifr;
    280268    struct sockaddr_in sai;
    281 #ifdef CONFIG_FEATURE_IPV6
    282     struct sockaddr_in6 sai6;
    283 #endif
    284 #ifdef CONFIG_FEATURE_IFCONFIG_HW
     269#if ENABLE_FEATURE_IFCONFIG_HW
    285270    struct sockaddr sa;
    286271#endif
     
    288273    const struct options *op;
    289274    int sockfd;         /* socket fd we use to manipulate stuff with */
    290     int goterr;
    291275    int selector;
    292 #ifdef CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS
     276#if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS
    293277    unsigned int mask;
    294278    unsigned int did_flags;
     
    299283#endif
    300284    char *p;
    301     char host[128];
    302 
    303     goterr = 0;
     285    /*char host[128];*/
     286    const char *host = NULL; /* make gcc happy */
     287
    304288    did_flags = 0;
    305 #ifdef CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS
     289#if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS
    306290    sai_hostname = 0;
    307291    sai_netmask = 0;
     
    312296    --argc;
    313297
    314 #ifdef CONFIG_FEATURE_IFCONFIG_STATUS
    315     if ((argc > 0) && (((*argv)[0] == '-') && ((*argv)[1] == 'a') && !(*argv)[2])) {
     298#if ENABLE_FEATURE_IFCONFIG_STATUS
     299    if (argc > 0 && (argv[0][0] == '-' && argv[0][1] == 'a' && !argv[0][2])) {
    316300        interface_opt_a = 1;
    317301        --argc;
     
    321305
    322306    if (argc <= 1) {
    323 #ifdef CONFIG_FEATURE_IFCONFIG_STATUS
     307#if ENABLE_FEATURE_IFCONFIG_STATUS
    324308        return display_interfaces(argc ? *argv : NULL);
    325309#else
    326         bb_error_msg_and_die
    327             ("ifconfig was not compiled with interface status display support.");
     310        bb_error_msg_and_die("no support for status display");
    328311#endif
    329312    }
    330313
    331314    /* Create a channel to the NET kernel. */
    332     sockfd = bb_xsocket(AF_INET, SOCK_DGRAM, 0);
     315    sockfd = xsocket(AF_INET, SOCK_DGRAM, 0);
    333316
    334317    /* get interface name */
     
    345328        for (op = OptArray; op->name; op++) {   /* Find table entry. */
    346329            if (strcmp(p, op->name) == 0) { /* If name matches... */
    347                 if ((mask &= op->flags)) {  /* set the mask and go. */
     330                mask &= op->flags;
     331                if (mask)   /* set the mask and go. */
    348332                    goto FOUND_ARG;
    349                 }
    350333                /* If we get here, there was a valid arg with an */
    351334                /* invalid '-' prefix. */
    352                 ++goterr;
    353                 goto LOOP;
     335                bb_error_msg_and_die("bad: '%s'", p-1);
    354336            }
    355337        }
    356338
    357339        /* We fell through, so treat as possible hostname. */
    358         a1op = Arg1Opt + (sizeof(Arg1Opt) / sizeof(Arg1Opt[0])) - 1;
     340        a1op = Arg1Opt + ARRAY_SIZE(Arg1Opt) - 1;
    359341        mask = op->arg_flags;
    360342        goto HOSTNAME;
    361343
    362       FOUND_ARG:
     344 FOUND_ARG:
    363345        if (mask & ARG_MASK) {
    364346            mask = op->arg_flags;
    365347            a1op = Arg1Opt + (op - OptArray);
    366             if (mask & A_NETMASK & did_flags) {
     348            if (mask & A_NETMASK & did_flags)
    367349                bb_show_usage();
    368             }
    369350            if (*++argv == NULL) {
    370                 if (mask & A_ARG_REQ) {
     351                if (mask & A_ARG_REQ)
    371352                    bb_show_usage();
    372                 } else {
    373                     --argv;
    374                     mask &= A_SET_AFTER;    /* just for broadcast */
    375                 }
     353                --argv;
     354                mask &= A_SET_AFTER;    /* just for broadcast */
    376355            } else {    /* got an arg so process it */
    377               HOSTNAME:
     356 HOSTNAME:
    378357                did_flags |= (mask & (A_NETMASK|A_HOSTNAME));
    379358                if (mask & A_CAST_HOST_COPY) {
    380 #ifdef CONFIG_FEATURE_IFCONFIG_HW
     359#if ENABLE_FEATURE_IFCONFIG_HW
    381360                    if (mask & A_CAST_RESOLVE) {
    382361#endif
    383 #ifdef CONFIG_FEATURE_IPV6
     362#if ENABLE_FEATURE_IPV6
    384363                        char *prefix;
    385364                        int prefix_len = 0;
    386365#endif
    387 
    388                         safe_strncpy(host, *argv, (sizeof host));
    389 #ifdef CONFIG_FEATURE_IPV6
    390                         if ((prefix = strchr(host, '/'))) {
    391                             if (safe_strtoi(prefix + 1, &prefix_len) ||
    392                                 (prefix_len < 0) || (prefix_len > 128))
    393                             {
    394                                 ++goterr;
    395                                 goto LOOP;
    396                             }
    397                             *prefix = 0;
     366                        /*safe_strncpy(host, *argv, (sizeof host));*/
     367                        host = *argv;
     368#if ENABLE_FEATURE_IPV6
     369                        prefix = strchr(host, '/');
     370                        if (prefix) {
     371                            prefix_len = xatou_range(prefix + 1, 0, 128);
     372                            *prefix = '\0';
    398373                        }
    399374#endif
    400 
    401375                        sai.sin_family = AF_INET;
    402376                        sai.sin_port = 0;
    403                         if (!strcmp(host, bb_INET_default)) {
     377                        if (!strcmp(host, bb_str_default)) {
    404378                            /* Default is special, meaning 0.0.0.0. */
    405379                            sai.sin_addr.s_addr = INADDR_ANY;
    406 #ifdef CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS
    407                         } else if (((host[0] == '+') && !host[1]) && (mask & A_BROADCAST) &&
    408                                    (did_flags & (A_NETMASK|A_HOSTNAME)) == (A_NETMASK|A_HOSTNAME)) {
     380                        }
     381#if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS
     382                        else if ((host[0] == '+' && !host[1]) && (mask & A_BROADCAST)
     383                         && (did_flags & (A_NETMASK|A_HOSTNAME)) == (A_NETMASK|A_HOSTNAME)
     384                        ) {
    409385                            /* + is special, meaning broadcast is derived. */
    410386                            sai.sin_addr.s_addr = (~sai_netmask) | (sai_hostname & sai_netmask);
    411 #endif
    412 #ifdef CONFIG_FEATURE_IPV6
    413                         } else if (inet_pton(AF_INET6, host, &sai6.sin6_addr) > 0) {
    414                             int sockfd6;
    415                             struct in6_ifreq ifr6;
    416 
    417                             memcpy((char *) &ifr6.ifr6_addr,
    418                                    (char *) &sai6.sin6_addr,
    419                                    sizeof(struct in6_addr));
    420 
    421                             /* Create a channel to the NET kernel. */
    422                             if ((sockfd6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
    423                                 bb_perror_msg_and_die("socket6");
    424                             }
    425                             if (ioctl(sockfd6, SIOGIFINDEX, &ifr) < 0) {
    426                                 perror("SIOGIFINDEX");
    427                                 ++goterr;
     387                        }
     388#endif
     389                        else {
     390                            len_and_sockaddr *lsa;
     391                            if (strcmp(host, "inet") == 0)
     392                                continue; /* compat stuff */
     393                            lsa = xhost2sockaddr(host, 0);
     394#if ENABLE_FEATURE_IPV6
     395                            if (lsa->sa.sa_family == AF_INET6) {
     396                                int sockfd6;
     397                                struct in6_ifreq ifr6;
     398
     399                                memcpy((char *) &ifr6.ifr6_addr,
     400                                        (char *) &(lsa->sin6.sin6_addr),
     401                                        sizeof(struct in6_addr));
     402
     403                                /* Create a channel to the NET kernel. */
     404                                sockfd6 = xsocket(AF_INET6, SOCK_DGRAM, 0);
     405                                xioctl(sockfd6, SIOGIFINDEX, &ifr);
     406                                ifr6.ifr6_ifindex = ifr.ifr_ifindex;
     407                                ifr6.ifr6_prefixlen = prefix_len;
     408                                ioctl_or_perror_and_die(sockfd6, a1op->selector, &ifr6, "%s", a1op->name);
     409                                if (ENABLE_FEATURE_CLEAN_UP)
     410                                    free(lsa);
    428411                                continue;
    429412                            }
    430                             ifr6.ifr6_ifindex = ifr.ifr_ifindex;
    431                             ifr6.ifr6_prefixlen = prefix_len;
    432                             if (ioctl(sockfd6, a1op->selector, &ifr6) < 0) {
    433                                 perror(a1op->name);
    434                                 ++goterr;
    435                             }
    436                             continue;
    437 #endif
    438                         } else if (inet_aton(host, &sai.sin_addr) == 0) {
    439                             /* It's not a dotted quad. */
    440                             struct hostent *hp;
    441                             if ((hp = gethostbyname(host)) == (struct hostent *)NULL) {
    442                                 ++goterr;
    443                                 continue;
    444                             }
    445                             memcpy((char *) &sai.sin_addr, (char *) hp->h_addr_list[0],
    446                             sizeof(struct in_addr));
     413#endif
     414                            sai.sin_addr = lsa->sin.sin_addr;
     415                            if (ENABLE_FEATURE_CLEAN_UP)
     416                                free(lsa);
    447417                        }
    448 #ifdef CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS
    449                         if (mask & A_HOSTNAME) {
     418#if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS
     419                        if (mask & A_HOSTNAME)
    450420                            sai_hostname = sai.sin_addr.s_addr;
    451                         }
    452                         if (mask & A_NETMASK) {
     421                        if (mask & A_NETMASK)
    453422                            sai_netmask = sai.sin_addr.s_addr;
    454                         }
    455423#endif
    456424                        p = (char *) &sai;
    457 #ifdef CONFIG_FEATURE_IFCONFIG_HW
     425#if ENABLE_FEATURE_IFCONFIG_HW
    458426                    } else {    /* A_CAST_HOST_COPY_IN_ETHER */
    459427                        /* This is the "hw" arg case. */
    460                         if (strcmp("ether", *argv) || (*++argv == NULL)) {
     428                        if (strcmp("ether", *argv) || !*++argv)
    461429                            bb_show_usage();
    462                         }
    463                         safe_strncpy(host, *argv, (sizeof host));
    464                         if (in_ether(host, &sa)) {
    465                             bb_error_msg("invalid hw-addr %s", host);
    466                             ++goterr;
    467                             continue;
    468                         }
     430                        /*safe_strncpy(host, *argv, sizeof(host));*/
     431                        host = *argv;
     432                        if (in_ether(host, &sa))
     433                            bb_error_msg_and_die("invalid hw-addr %s", host);
    469434                        p = (char *) &sa;
    470435                    }
    471436#endif
    472                     memcpy((((char *) (&ifr)) + a1op->ifr_offset),
     437                    memcpy( (((char *)&ifr) + a1op->ifr_offset),
    473438                           p, sizeof(struct sockaddr));
    474439                } else {
     440                    /* FIXME: error check?? */
    475441                    unsigned long i = strtoul(*argv, NULL, 0);
    476 
    477                     p = ((char *) (&ifr)) + a1op->ifr_offset;
    478 #ifdef CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ
     442                    p = ((char *)&ifr) + a1op->ifr_offset;
     443#if ENABLE_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ
    479444                    if (mask & A_MAP_TYPE) {
    480                         if (ioctl(sockfd, SIOCGIFMAP, &ifr) < 0) {
    481                             ++goterr;
    482                             continue;
    483                         }
    484                         if ((mask & A_MAP_UCHAR) == A_MAP_UCHAR) {
     445                        xioctl(sockfd, SIOCGIFMAP, &ifr);
     446                        if ((mask & A_MAP_UCHAR) == A_MAP_UCHAR)
    485447                            *((unsigned char *) p) = i;
    486                         } else if (mask & A_MAP_USHORT) {
     448                        else if (mask & A_MAP_USHORT)
    487449                            *((unsigned short *) p) = i;
    488                         } else {
     450                        else
    489451                            *((unsigned long *) p) = i;
    490                         }
    491452                    } else
    492453#endif
    493                     if (mask & A_CAST_CHAR_PTR) {
     454                    if (mask & A_CAST_CHAR_PTR)
    494455                        *((caddr_t *) p) = (caddr_t) i;
    495                     } else {    /* A_CAST_INT */
     456                    else    /* A_CAST_INT */
    496457                        *((int *) p) = i;
    497                     }
    498458                }
    499459
    500                 if (ioctl(sockfd, a1op->selector, &ifr) < 0) {
    501                     perror(a1op->name);
    502                     ++goterr;
    503                     continue;
    504                 }
     460                ioctl_or_perror_and_die(sockfd, a1op->selector, &ifr, "%s", a1op->name);
    505461#ifdef QUESTIONABLE_ALIAS_CASE
    506462                if (mask & A_COLON_CHK) {
    507463                    /*
    508464                     * Don't do the set_flag() if the address is an alias with
    509                      * a - at the end, since it's deleted already! - Roman
     465                     * a '-' at the end, since it's deleted already! - Roman
    510466                     *
    511467                     * Should really use regex.h here, not sure though how well
     
    514470                    char *ptr;
    515471                    short int found_colon = 0;
    516 
    517                     for (ptr = ifr.ifr_name; *ptr; ptr++) {
    518                         if (*ptr == ':') {
     472                    for (ptr = ifr.ifr_name; *ptr; ptr++)
     473                        if (*ptr == ':')
    519474                            found_colon++;
    520                         }
    521                     }
    522 
    523                     if (found_colon && *(ptr - 1) == '-') {
     475                    if (found_colon && ptr[-1] == '-')
    524476                        continue;
    525                     }
    526477                }
    527478#endif
    528479            }
    529             if (!(mask & A_SET_AFTER)) {
     480            if (!(mask & A_SET_AFTER))
    530481                continue;
    531             }
    532482            mask = N_SET;
    533483        }
    534484
    535         if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
    536             perror("SIOCGIFFLAGS");
    537             ++goterr;
    538         } else {
    539             selector = op->selector;
    540             if (mask & SET_MASK) {
    541                 ifr.ifr_flags |= selector;
    542             } else {
    543                 ifr.ifr_flags &= ~selector;
    544             }
    545             if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) {
    546                 perror("SIOCSIFFLAGS");
    547                 ++goterr;
    548             }
    549         }
    550       LOOP:
    551         continue;
    552     }                   /* end of while-loop */
    553 
    554     if (ENABLE_FEATURE_CLEAN_UP) close(sockfd);
    555     return goterr;
     485        xioctl(sockfd, SIOCGIFFLAGS, &ifr);
     486        selector = op->selector;
     487        if (mask & SET_MASK)
     488            ifr.ifr_flags |= selector;
     489        else
     490            ifr.ifr_flags &= ~selector;
     491        xioctl(sockfd, SIOCSIFFLAGS, &ifr);
     492    } /* while () */
     493
     494    if (ENABLE_FEATURE_CLEAN_UP)
     495        close(sockfd);
     496    return 0;
    556497}
    557498
    558 #ifdef CONFIG_FEATURE_IFCONFIG_HW
     499#if ENABLE_FEATURE_IFCONFIG_HW
    559500/* Input an Ethernet address and convert to binary. */
    560 static int in_ether(char *bufp, struct sockaddr *sap)
     501static int in_ether(const char *bufp, struct sockaddr *sap)
    561502{
    562503    char *ptr;
     
    595536    } while (++i < ETH_ALEN);
    596537
    597     return (int) (*bufp);   /* Error if we don't end at end of string. */
     538    return *bufp; /* Error if we don't end at end of string. */
    598539}
    599540#endif
Note: See TracChangeset for help on using the changeset viewer.