Ignore:
Timestamp:
Jan 1, 2014, 12:47:38 AM (10 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.21.1
File:
1 edited

Legend:

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

    r2725 r3232  
    2727 */
    2828
     29//usage:#define ifconfig_trivial_usage
     30//usage:    IF_FEATURE_IFCONFIG_STATUS("[-a]") " interface [address]"
     31//usage:#define ifconfig_full_usage "\n\n"
     32//usage:       "Configure a network interface\n"
     33//usage:     "\n"
     34//usage:    IF_FEATURE_IPV6(
     35//usage:       "    [add ADDRESS[/PREFIXLEN]]\n")
     36//usage:    IF_FEATURE_IPV6(
     37//usage:       "    [del ADDRESS[/PREFIXLEN]]\n")
     38//usage:       "    [[-]broadcast [ADDRESS]] [[-]pointopoint [ADDRESS]]\n"
     39//usage:       "    [netmask ADDRESS] [dstaddr ADDRESS]\n"
     40//usage:    IF_FEATURE_IFCONFIG_SLIP(
     41//usage:       "    [outfill NN] [keepalive NN]\n")
     42//usage:       "    " IF_FEATURE_IFCONFIG_HW("[hw ether" IF_FEATURE_HWIB("|infiniband")" ADDRESS] ") "[metric NN] [mtu NN]\n"
     43//usage:       "    [[-]trailers] [[-]arp] [[-]allmulti]\n"
     44//usage:       "    [multicast] [[-]promisc] [txqueuelen NN] [[-]dynamic]\n"
     45//usage:    IF_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ(
     46//usage:       "    [mem_start NN] [io_addr NN] [irq NN]\n")
     47//usage:       "    [up|down] ..."
     48
     49#include "libbb.h"
     50#include "inet_common.h"
    2951#include <net/if.h>
    3052#include <net/if_arp.h>
    3153#include <netinet/in.h>
    32 #if defined(__GLIBC__) && __GLIBC__ >=2 && __GLIBC_MINOR__ >= 1
    33 #include <netpacket/packet.h>
    34 #include <net/ethernet.h>
    35 #else
    36 #include <sys/types.h>
    37 #include <netinet/if_ether.h>
    38 #endif
    39 #include "libbb.h"
    40 #include "inet_common.h"
     54#ifdef HAVE_NET_ETHERNET_H
     55# include <net/ethernet.h>
     56#endif
    4157
    4258#if ENABLE_FEATURE_IFCONFIG_SLIP
     
    159175
    160176
    161 /*
    162  * Set up the tables.  Warning!  They must have corresponding order!
    163  */
    164 
    165177struct arg1opt {
    166178    const char *name;
     
    182194
    183195#define ifreq_offsetof(x)  offsetof(struct ifreq, x)
     196
     197/*
     198 * Set up the tables.  Warning!  They must have corresponding order!
     199 */
    184200
    185201static const struct arg1opt Arg1Opt[] = {
     
    205221    { "SIFMAP",     SIOCSIFMAP,     ifreq_offsetof(ifr_map.irq) },
    206222#endif
    207     /* Last entry if for unmatched (possibly hostname) arg. */
    208223#if ENABLE_FEATURE_IPV6
    209224    { "SIFADDR",    SIOCSIFADDR,    ifreq_offsetof(ifr_addr) }, /* IPv6 version ignores the offset */
    210225    { "DIFADDR",    SIOCDIFADDR,    ifreq_offsetof(ifr_addr) }, /* IPv6 version ignores the offset */
    211226#endif
     227    /* Last entry is for unmatched (assumed to be hostname/address) arg. */
    212228    { "SIFADDR",    SIOCSIFADDR,    ifreq_offsetof(ifr_addr) },
    213229};
     
    250266};
    251267
    252 /*
    253  * A couple of prototypes.
    254  */
    255268#if ENABLE_FEATURE_IFCONFIG_HW
    256 static int in_ether(const char *bufp, struct sockaddr *sap);
    257 #endif
    258 
    259 /*
    260  * Our main function.
    261  */
     269/* Input an Ethernet address and convert to binary. */
     270static int in_ether(const char *bufp, struct sockaddr *sap)
     271{
     272    char *ptr;
     273    int i, j;
     274    unsigned char val;
     275    unsigned char c;
     276
     277    sap->sa_family = ARPHRD_ETHER;
     278    ptr = (char *) sap->sa_data;
     279
     280    i = 0;
     281    do {
     282        j = val = 0;
     283
     284        /* We might get a semicolon here - not required. */
     285        if (i && (*bufp == ':')) {
     286            bufp++;
     287        }
     288
     289        do {
     290            c = *bufp;
     291            if (((unsigned char)(c - '0')) <= 9) {
     292                c -= '0';
     293            } else if ((unsigned char)((c|0x20) - 'a') <= 5) {
     294                c = (unsigned char)((c|0x20) - 'a') + 10;
     295            } else if (j && (c == ':' || c == 0)) {
     296                break;
     297            } else {
     298                return -1;
     299            }
     300            ++bufp;
     301            val <<= 4;
     302            val += c;
     303        } while (++j < 2);
     304        *ptr++ = val;
     305    } while (++i < ETH_ALEN);
     306
     307    return *bufp; /* Error if we don't end at end of string. */
     308}
     309#endif
     310
    262311int ifconfig_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
    263312int ifconfig_main(int argc UNUSED_PARAM, char **argv)
     
    315364
    316365    /* Process the remaining arguments. */
    317     while (*++argv != (char *) NULL) {
     366    while (*++argv != NULL) {
    318367        p = *argv;
    319368        mask = N_MASK;
     
    341390        if (mask & ARG_MASK) {
    342391            mask = op->arg_flags;
    343             a1op = Arg1Opt + (op - OptArray);
    344392            if (mask & A_NETMASK & did_flags)
    345393                bb_show_usage();
     394            a1op = Arg1Opt + (op - OptArray);
    346395            if (*++argv == NULL) {
    347396                if (mask & A_ARG_REQ)
     
    356405                    if (mask & A_CAST_RESOLVE) {
    357406#endif
    358 #if ENABLE_FEATURE_IPV6
    359                         char *prefix;
    360                         int prefix_len = 0;
    361 #endif
    362                         /*safe_strncpy(host, *argv, (sizeof host));*/
    363407                        host = *argv;
    364 #if ENABLE_FEATURE_IPV6
    365                         prefix = strchr(host, '/');
    366                         if (prefix) {
    367                             prefix_len = xatou_range(prefix + 1, 0, 128);
    368                             *prefix = '\0';
    369                         }
    370 #endif
     408                        if (strcmp(host, "inet") == 0)
     409                            continue; /* compat stuff */
    371410                        sai.sin_family = AF_INET;
    372411                        sai.sin_port = 0;
     
    376415                        }
    377416#if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS
    378                         else if ((host[0] == '+' && !host[1]) && (mask & A_BROADCAST)
     417                        else if ((host[0] == '+' && !host[1])
     418                         && (mask & A_BROADCAST)
    379419                         && (did_flags & (A_NETMASK|A_HOSTNAME)) == (A_NETMASK|A_HOSTNAME)
    380420                        ) {
     
    385425                        else {
    386426                            len_and_sockaddr *lsa;
    387                             if (strcmp(host, "inet") == 0)
    388                                 continue; /* compat stuff */
     427#if ENABLE_FEATURE_IPV6
     428                            char *prefix;
     429                            int prefix_len = 0;
     430                            prefix = strchr(host, '/');
     431                            if (prefix) {
     432                                prefix_len = xatou_range(prefix + 1, 0, 128);
     433                                *prefix = '\0';
     434                            }
     435 resolve:
     436#endif
    389437                            lsa = xhost2sockaddr(host, 0);
    390438#if ENABLE_FEATURE_IPV6
     439                            if (lsa->u.sa.sa_family != AF_INET6 && prefix) {
     440/* TODO: we do not support "ifconfig eth0 up 1.2.3.4/17".
     441 * For now, just make it fail instead of silently ignoring "/17" part:
     442 */
     443                                *prefix = '/';
     444                                goto resolve;
     445                            }
    391446                            if (lsa->u.sa.sa_family == AF_INET6) {
    392447                                int sockfd6;
    393448                                struct in6_ifreq ifr6;
    394449
    395                                 memcpy((char *) &ifr6.ifr6_addr,
    396                                         (char *) &(lsa->u.sin6.sin6_addr),
    397                                         sizeof(struct in6_addr));
    398 
    399                                 /* Create a channel to the NET kernel. */
    400450                                sockfd6 = xsocket(AF_INET6, SOCK_DGRAM, 0);
    401                                 xioctl(sockfd6, SIOGIFINDEX, &ifr);
     451                                xioctl(sockfd6, SIOCGIFINDEX, &ifr);
    402452                                ifr6.ifr6_ifindex = ifr.ifr_ifindex;
    403453                                ifr6.ifr6_prefixlen = prefix_len;
     454                                memcpy(&ifr6.ifr6_addr,
     455                                        &lsa->u.sin6.sin6_addr,
     456                                        sizeof(struct in6_addr));
    404457                                ioctl_or_perror_and_die(sockfd6, a1op->selector, &ifr6, "SIOC%s", a1op->name);
    405458                                if (ENABLE_FEATURE_CLEAN_UP)
     
    422475                    } else {    /* A_CAST_HOST_COPY_IN_ETHER */
    423476                        /* This is the "hw" arg case. */
    424                         smalluint hw_class= index_in_substrings("ether\0"
     477                        smalluint hw_class = index_in_substrings("ether\0"
    425478                                IF_FEATURE_HWIB("infiniband\0"), *argv) + 1;
    426479                        if (!hw_class || !*++argv)
    427480                            bb_show_usage();
    428                         /*safe_strncpy(host, *argv, sizeof(host));*/
    429481                        host = *argv;
    430482                        if (hw_class == 1 ? in_ether(host, &sa) : in_ib(host, &sa))
     
    433485                    }
    434486#endif
    435                     memcpy( (((char *)&ifr) + a1op->ifr_offset),
    436                            p, sizeof(struct sockaddr));
     487                    memcpy( ((char *)&ifr) + a1op->ifr_offset,
     488                        p, sizeof(struct sockaddr));
    437489                } else {
    438490                    /* FIXME: error check?? */
     
    443495                        xioctl(sockfd, SIOCGIFMAP, &ifr);
    444496                        if ((mask & A_MAP_UCHAR) == A_MAP_UCHAR)
    445                             *((unsigned char *) p) = i;
     497                            *(unsigned char *) p = i;
    446498                        else if (mask & A_MAP_USHORT)
    447                             *((unsigned short *) p) = i;
     499                            *(unsigned short *) p = i;
    448500                        else
    449                             *((unsigned long *) p) = i;
     501                            *(unsigned long *) p = i;
    450502                    } else
    451503#endif
    452504                    if (mask & A_CAST_CHAR_PTR)
    453                         *((caddr_t *) p) = (caddr_t) i;
     505                        *(caddr_t *) p = (caddr_t) i;
    454506                    else    /* A_CAST_INT */
    455                         *((int *) p) = i;
     507                        *(int *) p = i;
    456508                }
    457509
     
    479531                continue;
    480532            mask = N_SET;
    481         }
     533        } /* if (mask & ARG_MASK) */
    482534
    483535        xioctl(sockfd, SIOCGIFFLAGS, &ifr);
     
    494546    return 0;
    495547}
    496 
    497 #if ENABLE_FEATURE_IFCONFIG_HW
    498 /* Input an Ethernet address and convert to binary. */
    499 static int in_ether(const char *bufp, struct sockaddr *sap)
    500 {
    501     char *ptr;
    502     int i, j;
    503     unsigned char val;
    504     unsigned char c;
    505 
    506     sap->sa_family = ARPHRD_ETHER;
    507     ptr = (char *) sap->sa_data;
    508 
    509     i = 0;
    510     do {
    511         j = val = 0;
    512 
    513         /* We might get a semicolon here - not required. */
    514         if (i && (*bufp == ':')) {
    515             bufp++;
    516         }
    517 
    518         do {
    519             c = *bufp;
    520             if (((unsigned char)(c - '0')) <= 9) {
    521                 c -= '0';
    522             } else if (((unsigned char)((c|0x20) - 'a')) <= 5) {
    523                 c = (c|0x20) - ('a'-10);
    524             } else if (j && (c == ':' || c == 0)) {
    525                 break;
    526             } else {
    527                 return -1;
    528             }
    529             ++bufp;
    530             val <<= 4;
    531             val += c;
    532         } while (++j < 2);
    533         *ptr++ = val;
    534     } while (++i < ETH_ALEN);
    535 
    536     return *bufp; /* Error if we don't end at end of string. */
    537 }
    538 #endif
Note: See TracChangeset for help on using the changeset viewer.