Ignore:
Timestamp:
Nov 6, 2007, 11:01:53 AM (16 years ago)
Author:
Bruno Cornec
Message:
  • Better output for mindi-busybox revision
  • Remove dummy file created on NFS - report from Arnaud Tiger <arnaud.tiger_at_hp.com>
  • strace useful for debug
  • fix new versions for pb (2.0.0 for mindi and 1.7.2 for mindi-busybox)
  • fix build process for mindi-busybox + options used in that version (dd for label-partitions-as-necessary)
  • fix typo in label-partitions-as-necessary which doesn't seem to work
  • Update to busybox 1.7.2
  • perl is now required at restore time to support uuid swap partitions (and will be used for many other thigs

in the future for sure)

  • next mindi version will be 2.0.0 due to all the changes made in it (udev may break working distros)
  • small optimization in mindi on keyboard handling (one single find instead of multiple)
  • better interaction for USB device when launching mindi manually
  • attempt to automatically guess block disk size for ramdisk
  • fix typos in bkphw
  • Fix the remaining problem with UUID support for swap partitions
  • Updates mondoarchive man page for USB support
  • Adds preliminary Hardware support to mindi (Proliant SSSTK)
  • Tries to add udev support also for rhel4
  • Fix UUID support which was still broken.
  • Be conservative in test for the start-nfs script
  • Update config file for mindi-busybox for 1.7.2 migration
  • Try to run around a busybox bug (1.2.2 pb on inexistant links)
  • Add build content for mindi-busybox in pb
  • Remove distributions content for mindi-busybox
  • Fix a warning on inexistant raidtab
  • Solve problem on tmpfs in restore init (Problem of inexistant symlink and busybox)
  • Create MONDO_CACHE and use it everywhere + creation at start
  • Really never try to eject a USB device
  • Fix a issue with &> usage (replaced with 1> and 2>)
  • Adds magic file to depllist in order to have file working + ldd which helps for debugging issues
  • tty modes correct to avoid sh error messages
  • Use ext3 normally and not ext2 instead
  • USB device should be corrected after reading (take 1st part)
  • Adds a mount_USB_here function derived from mount_CDROM_here
  • usb detection place before /dev detection in device name at restore time
  • Fix when restoring from USB: media is asked in interactive mode
  • Adds USB support for mondorestore
  • mount_cdrom => mount_media
  • elilo.efi is now searched throughout /boot/efi and not in a fixed place as there is no standard
  • untar-and-softlink => untar (+ interface change)
  • suppress useless softlinks creation/removal in boot process
  • avoids udevd messages on groups
  • Increase # of disks to 99 as in mindi at restore time (should be a conf file parameter)
  • skip existing big file creation
  • seems to work correctly for USB mindi boot
  • Adds group and tty link to udev conf
  • Always load usb-torage (even 2.6) to initiate USB bus discovery
  • Better printing of messages
  • Attempt to fix a bug in supporting OpenSusE 10.3 kernel for initramfs (mindi may now use multiple regex for kernel initrd detection)
  • Links were not correctly done as non relative for modules in mindi
  • exclusion of modules denied now works
  • Also create modules in their ordinary place, so that classical modprobe works + copy modules.dep
  • Fix bugs for DENY_MODS handling
  • Add device /dev/console for udev
  • ide-generic should now really be excluded
  • Fix a bug in major number for tty
  • If udev then adds modprobe/insmod to rootfs
  • tty0 is also cretaed with udev
  • ide-generic put rather in DENY_MODS
  • udevd remove from deplist s handled in mindi directly
  • better default for mindi when using --usb
  • Handles dynamically linked busybox (in case we want to use it soon ;-)
  • Adds fixed devices to create for udev
  • ide-generic should not be part of the initrd when using libata v2
  • support a dynamically linked udev (case on Ubuntu 7.10 and Mandriva 2008.0 so should be quite generic) This will give incitation to move to dyn. linked binaries in the initrd which will help for other tasks (ia6 4)
  • Improvement in udev support (do not use cl options not available in busybox)
  • Udev in mindi
    • auto creation of the right links at boot time with udev-links.conf(from Mandriva 2008.0)
    • rework startup of udev as current makes kernel crash (from Mandriva 2008.0)
    • add support for 64 bits udev
  • Try to render MyInsmod silent at boot time
  • Adds udev support (mandatory for newest distributions to avoid remapping of devices in a different way as on the original system)
  • We also need vaft format support for USB boot
  • Adds libusual support (Ubuntu 7.10 needs it for USB)
  • Improve Ubuntu/Debian keyboard detection and support
  • pbinit adapted to new pb (0.8.10). Filtering of docs done in it
  • Suppress some mondo warnings and errors on USB again
  • Tries to fix lack of files in deb mindi package
  • Verify should now work for USB devices
  • More log/mesages improvement for USB support
  • - Supress g_erase_tmpdir_and_scratchdir
  • Improve some log messages for USB support
  • Try to improve install in mindi to avoid issues with isolinux.cfg not installed vene if in the pkg :-(
  • Improve mindi-busybox build
  • In conformity with pb 0.8.9
  • Add support for Ubuntu 7.10 in build process
  • Add USB Key button to Menu UI (CD streamer removed)
  • Attempt to fix error messages on tmp/scratch files at the end by removing those dir at the latest possible.
  • Fix a bug linked to the size of the -E param which could be used (Arnaud Tiger/René Ribaud).
  • Integrate ~/.pbrc content into mondorescue.pb (required project-builder >= 0.8.7)
  • Put mondorescue in conformity with new pb filtering rules
  • Add USB support at restore time (no test done yet). New start-usb script PB varibale added where useful
  • Unmounting USB device before removal of temporary scratchdir
  • Stil refining USB copy back to mondo (one command was not executed)
  • No need to have the image subdor in the csratchdir when USB.
  • umount the USB partition before attempting to use it
  • Remove useless copy from mindi to mondo at end of USB handling

(risky merge, we are raising the limits of 2 diverging branches. The status of stable is not completely sure as such. Will need lots of tests, but it's not yet done :-()
(merge -r1692:1769 $SVN_M/branches/2.2.5)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/stable/mindi-busybox/networking/interface.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * stolen from net-tools-1.59 and stripped down for busybox by
     
    1516 *              one or more of the system's networking interfaces.
    1617 *
    17  * Version:     $Id: interface.c,v 1.25 2004/08/26 21:45:21 andersen Exp $
    1818 *
    1919 * Author:      Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
     
    3232 */
    3333
    34 #include "inet_common.h"
    35 #include <stdio.h>
    36 #include <errno.h>
    37 #include <stdlib.h>
    38 #include <string.h>
    39 #include <unistd.h>
    40 #include <fcntl.h>
    41 #include <ctype.h>
    42 #include <sys/ioctl.h>
    43 #include <sys/types.h>
    4434#include <net/if.h>
    4535#include <net/if_arp.h>
    46 #include "busybox.h"
    47 
    48 #ifdef CONFIG_FEATURE_IPV6
     36#include "inet_common.h"
     37#include "libbb.h"
     38
     39#if ENABLE_FEATURE_IPV6
    4940# define HAVE_AFINET6 1
    5041#else
     
    5546#define _PATH_PROCNET_IFINET6           "/proc/net/if_inet6"
    5647
    57 #if HAVE_AFINET6
     48#ifdef HAVE_AFINET6
    5849
    5950#ifndef _LINUX_IN6_H
     
    7061#endif
    7162
    72 #endif                          /* HAVE_AFINET6 */
     63#endif /* HAVE_AFINET6 */
    7364
    7465/* Defines for glibc2.0 users. */
     
    9182#endif
    9283
    93 /* This structure defines protocol families and their handlers. */
    94 struct aftype {
    95     const char *name;
    96     const char *title;
    97     int af;
    98     int alen;
    99     char *(*print) (unsigned char *);
    100     char *(*sprint) (struct sockaddr *, int numeric);
    101     int (*input) (int type, char *bufp, struct sockaddr *);
    102     void (*herror) (char *text);
    103     int (*rprint) (int options);
    104     int (*rinput) (int typ, int ext, char **argv);
    105 
    106     /* may modify src */
    107     int (*getmask) (char *src, struct sockaddr * mask, char *name);
    108 
    109     int fd;
    110     char *flag_file;
    111 };
    112 
    11384/* Display an Internet socket address. */
    114 static char *INET_sprint(struct sockaddr *sap, int numeric)
    115 {
    116     static char buff[128];
    117 
     85static const char *INET_sprint(struct sockaddr *sap, int numeric)
     86{
     87    static char *buff;
     88
     89    free(buff);
    11890    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
    119         return safe_strncpy(buff, "[NONE SET]", sizeof(buff));
    120 
    121     if (INET_rresolve(buff, sizeof(buff), (struct sockaddr_in *) sap,
    122                       numeric, 0xffffff00) != 0)
    123         return (NULL);
    124 
    125     return (buff);
    126 }
    127 
    128 static struct aftype inet_aftype = {
     91        return "[NONE SET]";
     92    buff = INET_rresolve((struct sockaddr_in *) sap, numeric, 0xffffff00);
     93    return buff;
     94}
     95
     96#ifdef UNUSED_AND_BUGGY
     97static int INET_getsock(char *bufp, struct sockaddr *sap)
     98{
     99    char *sp = bufp, *bp;
     100    unsigned int i;
     101    unsigned val;
     102    struct sockaddr_in *sock_in;
     103
     104    sock_in = (struct sockaddr_in *) sap;
     105    sock_in->sin_family = AF_INET;
     106    sock_in->sin_port = 0;
     107
     108    val = 0;
     109    bp = (char *) &val;
     110    for (i = 0; i < sizeof(sock_in->sin_addr.s_addr); i++) {
     111        *sp = toupper(*sp);
     112
     113        if ((unsigned)(*sp - 'A') <= 5)
     114            bp[i] |= (int) (*sp - ('A' - 10));
     115        else if (isdigit(*sp))
     116            bp[i] |= (int) (*sp - '0');
     117        else
     118            return -1;
     119
     120        bp[i] <<= 4;
     121        sp++;
     122        *sp = toupper(*sp);
     123
     124        if ((unsigned)(*sp - 'A') <= 5)
     125            bp[i] |= (int) (*sp - ('A' - 10));
     126        else if (isdigit(*sp))
     127            bp[i] |= (int) (*sp - '0');
     128        else
     129            return -1;
     130
     131        sp++;
     132    }
     133    sock_in->sin_addr.s_addr = htonl(val);
     134
     135    return (sp - bufp);
     136}
     137#endif
     138
     139static int INET_input(/*int type,*/ const char *bufp, struct sockaddr *sap)
     140{
     141    return INET_resolve(bufp, (struct sockaddr_in *) sap, 0);
     142/*
     143    switch (type) {
     144    case 1:
     145        return (INET_getsock(bufp, sap));
     146    case 256:
     147        return (INET_resolve(bufp, (struct sockaddr_in *) sap, 1));
     148    default:
     149        return (INET_resolve(bufp, (struct sockaddr_in *) sap, 0));
     150    }
     151*/
     152}
     153
     154static const struct aftype inet_aftype = {
    129155    .name =     "inet",
    130156    .title =    "DARPA Internet",
     
    132158    .alen =     4,
    133159    .sprint =   INET_sprint,
    134     .fd =       -1
    135 };
    136 
    137 #if HAVE_AFINET6
     160    .input =    INET_input,
     161};
     162
     163#ifdef HAVE_AFINET6
    138164
    139165/* Display an Internet socket address. */
    140166/* dirty! struct sockaddr usually doesn't suffer for inet6 addresses, fst. */
    141 static char *INET6_sprint(struct sockaddr *sap, int numeric)
    142 {
    143     static char buff[128];
    144 
     167static const char *INET6_sprint(struct sockaddr *sap, int numeric)
     168{
     169    static char *buff;
     170
     171    free(buff);
    145172    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
    146         return safe_strncpy(buff, "[NONE SET]", sizeof(buff));
    147     if (INET6_rresolve
    148         (buff, sizeof(buff), (struct sockaddr_in6 *) sap, numeric) != 0)
    149         return safe_strncpy(buff, "[UNKNOWN]", sizeof(buff));
    150     return (buff);
    151 }
    152 
    153 static struct aftype inet6_aftype = {
     173        return "[NONE SET]";
     174    buff = INET6_rresolve((struct sockaddr_in6 *) sap, numeric);
     175    return buff;
     176}
     177
     178#ifdef UNUSED
     179static int INET6_getsock(char *bufp, struct sockaddr *sap)
     180{
     181    struct sockaddr_in6 *sin6;
     182
     183    sin6 = (struct sockaddr_in6 *) sap;
     184    sin6->sin6_family = AF_INET6;
     185    sin6->sin6_port = 0;
     186
     187    if (inet_pton(AF_INET6, bufp, sin6->sin6_addr.s6_addr) <= 0)
     188        return -1;
     189
     190    return 16;          /* ?;) */
     191}
     192#endif
     193
     194static int INET6_input(/*int type,*/ const char *bufp, struct sockaddr *sap)
     195{
     196    return INET6_resolve(bufp, (struct sockaddr_in6 *) sap);
     197/*
     198    switch (type) {
     199    case 1:
     200        return (INET6_getsock(bufp, sap));
     201    default:
     202        return (INET6_resolve(bufp, (struct sockaddr_in6 *) sap));
     203    }
     204*/
     205}
     206
     207static const struct aftype inet6_aftype = {
    154208    .name =     "inet6",
    155209    .title =    "IPv6",
     
    157211    .alen =     sizeof(struct in6_addr),
    158212    .sprint =   INET6_sprint,
    159     .fd =       -1
    160 };
    161 
    162 #endif                          /* HAVE_AFINET6 */
     213    .input =    INET6_input,
     214};
     215
     216#endif /* HAVE_AFINET6 */
    163217
    164218/* Display an UNSPEC address. */
    165219static char *UNSPEC_print(unsigned char *ptr)
    166220{
    167     static char buff[sizeof(struct sockaddr) * 3 + 1];
     221    static char *buff;
     222
    168223    char *pos;
    169224    unsigned int i;
    170225
     226    if (!buff);
     227        buff = xmalloc(sizeof(struct sockaddr) * 3 + 1);
    171228    pos = buff;
    172229    for (i = 0; i < sizeof(struct sockaddr); i++) {
     
    177234    /* Erase trailing "-".  Works as long as sizeof(struct sockaddr) != 0 */
    178235    *--pos = '\0';
    179     return (buff);
     236    return buff;
    180237}
    181238
    182239/* Display an UNSPEC socket address. */
    183 static char *UNSPEC_sprint(struct sockaddr *sap, int numeric)
    184 {
    185     static char buf[64];
    186 
     240static const char *UNSPEC_sprint(struct sockaddr *sap, int numeric)
     241{
    187242    if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
    188         return safe_strncpy(buf, "[NONE SET]", sizeof(buf));
    189     return (UNSPEC_print((unsigned char *)sap->sa_data));
    190 }
    191 
    192 static struct aftype unspec_aftype = {
    193     "unspec", "UNSPEC", AF_UNSPEC, 0,
    194     UNSPEC_print, UNSPEC_sprint, NULL, NULL,
    195     NULL,
    196 };
    197 
    198 static struct aftype * const aftypes[] = {
     243        return "[NONE SET]";
     244    return UNSPEC_print((unsigned char *)sap->sa_data);
     245}
     246
     247static const struct aftype unspec_aftype = {
     248    .name   = "unspec",
     249    .title  = "UNSPEC",
     250    .af     = AF_UNSPEC,
     251    .alen    = 0,
     252    .print  = UNSPEC_print,
     253    .sprint = UNSPEC_sprint,
     254};
     255
     256static const struct aftype *const aftypes[] = {
    199257    &inet_aftype,
    200 #if HAVE_AFINET6
     258#ifdef HAVE_AFINET6
    201259    &inet6_aftype,
    202260#endif
     
    206264
    207265/* Check our protocol family table for this family. */
    208 static struct aftype *get_afntype(int af)
    209 {
    210     struct aftype * const *afp;
     266const struct aftype *get_aftype(const char *name)
     267{
     268    const struct aftype *const *afp;
     269
     270    afp = aftypes;
     271    while (*afp != NULL) {
     272        if (!strcmp((*afp)->name, name))
     273            return (*afp);
     274        afp++;
     275    }
     276    return NULL;
     277}
     278
     279/* Check our protocol family table for this family. */
     280static const struct aftype *get_afntype(int af)
     281{
     282    const struct aftype *const *afp;
    211283
    212284    afp = aftypes;
    213285    while (*afp != NULL) {
    214286        if ((*afp)->af == af)
    215             return (*afp);
     287            return *afp;
    216288        afp++;
    217289    }
    218     return (NULL);
    219 }
    220 
    221 /* Check our protocol family table for this family and return its socket */
    222 static int get_socket_for_af(int af)
    223 {
    224     struct aftype * const *afp;
    225 
    226     afp = aftypes;
    227     while (*afp != NULL) {
    228         if ((*afp)->af == af)
    229             return (*afp)->fd;
    230         afp++;
    231     }
    232     return -1;
     290    return NULL;
    233291}
    234292
     
    284342
    285343
    286 int interface_opt_a = 0;    /* show all interfaces          */
     344smallint interface_opt_a;   /* show all interfaces */
    287345
    288346static struct interface *int_list, *int_last;
    289 static int skfd = -1;   /* generic raw socket desc.     */
    290 
    291 
    292 static int sockets_open(int family)
    293 {
    294     struct aftype * const *aft;
    295     int sfd = -1;
    296     static int force = -1;
    297 
    298     if (force < 0) {
    299         force = 0;
    300         if (get_linux_version_code() < KERNEL_VERSION(2,1,0))
    301             force = 1;
    302         if (access("/proc/net", R_OK))
    303             force = 1;
    304     }
    305     for (aft = aftypes; *aft; aft++) {
    306         struct aftype *af = *aft;
    307         int type = SOCK_DGRAM;
    308 
    309         if (af->af == AF_UNSPEC)
    310             continue;
    311         if (family && family != af->af)
    312             continue;
    313         if (af->fd != -1) {
    314             sfd = af->fd;
    315             continue;
    316         }
    317         /* Check some /proc file first to not stress kmod */
    318         if (!family && !force && af->flag_file) {
    319             if (access(af->flag_file, R_OK))
    320                 continue;
    321         }
    322         af->fd = socket(af->af, type, 0);
    323         if (af->fd >= 0)
    324             sfd = af->fd;
    325     }
    326     if (sfd < 0) {
    327         bb_error_msg("No usable address families found.");
    328     }
    329     return sfd;
    330 }
    331 
    332 #ifdef CONFIG_FEATURE_CLEAN_UP
    333 static void sockets_close(void)
    334 {
    335     struct aftype * const *aft;
    336     for (aft = aftypes; *aft != NULL; aft++) {
    337         struct aftype *af = *aft;
    338         if( af->fd != -1 ) {
    339             close(af->fd);
    340             af->fd = -1;
    341         }
    342     }
    343 }
    344 #endif
    345 
     347
     348
     349#if 0
    346350/* like strcmp(), but knows about numbers */
     351except that the freshly added calls to xatoul() brf on ethernet aliases with
     352uClibc with e.g.: ife->name='lo'  name='eth0:1'
    347353static int nstrcmp(const char *a, const char *b)
    348354{
     
    363369
    364370    if (isdigit(*a) && isdigit(*b)) {
    365         return atoi(a_ptr) > atoi(b_ptr) ? 1 : -1;
     371        return xatoul(a_ptr) > xatoul(b_ptr) ? 1 : -1;
    366372    }
    367373    return *a - *b;
    368374}
     375#endif
    369376
    370377static struct interface *add_interface(char *name)
     
    373380
    374381    for (ife = int_last; ife; ife = ife->prev) {
    375         int n = nstrcmp(ife->name, name);
     382        int n = /*n*/strcmp(ife->name, name);
    376383
    377384        if (n == 0)
     
    392399    *nextp = new;
    393400    return new;
    394 }
    395 
    396 
    397 static int if_readconf(void)
    398 {
    399     int numreqs = 30;
    400     struct ifconf ifc;
    401     struct ifreq *ifr;
    402     int n, err = -1;
    403     int skfd2;
    404 
    405     /* SIOCGIFCONF currently seems to only work properly on AF_INET sockets
    406        (as of 2.1.128) */
    407     skfd2 = get_socket_for_af(AF_INET);
    408     if (skfd2 < 0) {
    409         bb_perror_msg(("warning: no inet socket available"));
    410         /* Try to soldier on with whatever socket we can get hold of.  */
    411         skfd2 = sockets_open(0);
    412         if (skfd2 < 0)
    413             return -1;
    414     }
    415 
    416     ifc.ifc_buf = NULL;
    417     for (;;) {
    418         ifc.ifc_len = sizeof(struct ifreq) * numreqs;
    419         ifc.ifc_buf = xrealloc(ifc.ifc_buf, ifc.ifc_len);
    420 
    421         if (ioctl(skfd2, SIOCGIFCONF, &ifc) < 0) {
    422             perror("SIOCGIFCONF");
    423             goto out;
    424         }
    425         if (ifc.ifc_len == sizeof(struct ifreq) * numreqs) {
    426             /* assume it overflowed and try again */
    427             numreqs += 10;
    428             continue;
    429         }
    430         break;
    431     }
    432 
    433     ifr = ifc.ifc_req;
    434     for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) {
    435         add_interface(ifr->ifr_name);
    436         ifr++;
    437     }
    438     err = 0;
    439 
    440   out:
    441     free(ifc.ifc_buf);
    442     return err;
    443401}
    444402
     
    477435 * args. */
    478436
    479 /* static const char * const ss_fmt[] = { */
     437/* static const char *const ss_fmt[] = { */
    480438/*  "%lln%llu%lu%lu%lu%lu%ln%ln%lln%llu%lu%lu%lu%lu%lu", */
    481439/*  "%llu%llu%lu%lu%lu%lu%ln%ln%llu%llu%lu%lu%lu%lu%lu", */
     
    485443    /* Lie about the size of the int pointed to for %n. */
    486444#if INT_MAX == LONG_MAX
    487 static const char * const ss_fmt[] = {
     445static const char *const ss_fmt[] = {
    488446    "%n%llu%u%u%u%u%n%n%n%llu%u%u%u%u%u",
    489447    "%llu%llu%u%u%u%u%n%n%llu%llu%u%u%u%u%u",
     
    491449};
    492450#else
    493 static const char * const ss_fmt[] = {
     451static const char *const ss_fmt[] = {
    494452    "%n%llu%lu%lu%lu%lu%n%n%n%llu%lu%lu%lu%lu%lu",
    495453    "%llu%llu%lu%lu%lu%lu%n%n%llu%llu%lu%lu%lu%lu%lu",
     
    542500}
    543501
     502static int if_readconf(void)
     503{
     504    int numreqs = 30;
     505    struct ifconf ifc;
     506    struct ifreq *ifr;
     507    int n, err = -1;
     508    int skfd;
     509
     510    ifc.ifc_buf = NULL;
     511
     512    /* SIOCGIFCONF currently seems to only work properly on AF_INET sockets
     513       (as of 2.1.128) */
     514    skfd = socket(AF_INET, SOCK_DGRAM, 0);
     515    if (skfd < 0) {
     516        bb_perror_msg("error: no inet socket available");
     517        return -1;
     518    }
     519
     520    for (;;) {
     521        ifc.ifc_len = sizeof(struct ifreq) * numreqs;
     522        ifc.ifc_buf = xrealloc(ifc.ifc_buf, ifc.ifc_len);
     523
     524        if (ioctl_or_warn(skfd, SIOCGIFCONF, &ifc) < 0) {
     525            goto out;
     526        }
     527        if (ifc.ifc_len == sizeof(struct ifreq) * numreqs) {
     528            /* assume it overflowed and try again */
     529            numreqs += 10;
     530            continue;
     531        }
     532        break;
     533    }
     534
     535    ifr = ifc.ifc_req;
     536    for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) {
     537        add_interface(ifr->ifr_name);
     538        ifr++;
     539    }
     540    err = 0;
     541
     542 out:
     543    close(skfd);
     544    free(ifc.ifc_buf);
     545    return err;
     546}
     547
    544548static int if_readlist_proc(char *target)
    545549{
    546     static int proc_read;
     550    static smallint proc_read;
     551
    547552    FILE *fh;
    548553    char buf[512];
     
    557562    fh = fopen(_PATH_PROCNET_DEV, "r");
    558563    if (!fh) {
    559         bb_perror_msg("Warning: cannot open %s. Limited output.", _PATH_PROCNET_DEV);
     564        bb_perror_msg("warning: cannot open %s, limiting output", _PATH_PROCNET_DEV);
    560565        return if_readconf();
    561566    }
     
    577582    }
    578583    if (ferror(fh)) {
    579         perror(_PATH_PROCNET_DEV);
     584        bb_perror_msg(_PATH_PROCNET_DEV);
    580585        err = -1;
    581586        proc_read = 0;
     
    588593{
    589594    int err = if_readlist_proc(NULL);
    590 
     595    /* Needed in order to get ethN:M aliases */
    591596    if (!err)
    592597        err = if_readconf();
     
    594599}
    595600
    596 static int for_all_interfaces(int (*doit) (struct interface *, void *),
    597                               void *cookie)
    598 {
    599     struct interface *ife;
    600 
    601     if (!int_list && (if_readlist() < 0))
    602         return -1;
    603     for (ife = int_list; ife; ife = ife->next) {
    604         int err = doit(ife, cookie);
    605 
    606         if (err)
    607             return err;
    608     }
    609     return 0;
    610 }
    611 
    612601/* Fetch the interface configuration from the kernel. */
    613602static int if_fetch(struct interface *ife)
    614603{
    615604    struct ifreq ifr;
    616     int fd;
    617605    char *ifname = ife->name;
    618 
    619     strcpy(ifr.ifr_name, ifname);
    620     if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0)
    621         return (-1);
     606    int skfd;
     607
     608    skfd = xsocket(AF_INET, SOCK_DGRAM, 0);
     609
     610    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
     611    if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) {
     612        close(skfd);
     613        return -1;
     614    }
    622615    ife->flags = ifr.ifr_flags;
    623616
    624     strcpy(ifr.ifr_name, ifname);
    625     if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
    626         memset(ife->hwaddr, 0, 32);
    627     else
     617    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
     618    memset(ife->hwaddr, 0, 32);
     619    if (ioctl(skfd, SIOCGIFHWADDR, &ifr) >= 0)
    628620        memcpy(ife->hwaddr, ifr.ifr_hwaddr.sa_data, 8);
    629621
    630622    ife->type = ifr.ifr_hwaddr.sa_family;
    631623
    632     strcpy(ifr.ifr_name, ifname);
    633     if (ioctl(skfd, SIOCGIFMETRIC, &ifr) < 0)
    634         ife->metric = 0;
    635     else
     624    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
     625    ife->metric = 0;
     626    if (ioctl(skfd, SIOCGIFMETRIC, &ifr) >= 0)
    636627        ife->metric = ifr.ifr_metric;
    637628
    638     strcpy(ifr.ifr_name, ifname);
    639     if (ioctl(skfd, SIOCGIFMTU, &ifr) < 0)
    640         ife->mtu = 0;
    641     else
     629    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
     630    ife->mtu = 0;
     631    if (ioctl(skfd, SIOCGIFMTU, &ifr) >= 0)
    642632        ife->mtu = ifr.ifr_mtu;
    643633
     634    memset(&ife->map, 0, sizeof(struct ifmap));
    644635#ifdef SIOCGIFMAP
    645     strcpy(ifr.ifr_name, ifname);
     636    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
    646637    if (ioctl(skfd, SIOCGIFMAP, &ifr) == 0)
    647638        ife->map = ifr.ifr_map;
    648     else
    649 #endif
    650         memset(&ife->map, 0, sizeof(struct ifmap));
     639#endif
    651640
    652641#ifdef HAVE_TXQUEUELEN
    653     strcpy(ifr.ifr_name, ifname);
    654     if (ioctl(skfd, SIOCGIFTXQLEN, &ifr) < 0)
    655         ife->tx_queue_len = -1; /* unknown value */
    656     else
     642    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
     643    ife->tx_queue_len = -1; /* unknown value */
     644    if (ioctl(skfd, SIOCGIFTXQLEN, &ifr) >= 0)
    657645        ife->tx_queue_len = ifr.ifr_qlen;
    658646#else
     
    660648#endif
    661649
    662     /* IPv4 address? */
    663     fd = get_socket_for_af(AF_INET);
    664     if (fd >= 0) {
    665         strcpy(ifr.ifr_name, ifname);
    666         ifr.ifr_addr.sa_family = AF_INET;
    667         if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) {
    668             ife->has_ip = 1;
    669             ife->addr = ifr.ifr_addr;
    670             strcpy(ifr.ifr_name, ifname);
    671             if (ioctl(fd, SIOCGIFDSTADDR, &ifr) < 0)
    672                 memset(&ife->dstaddr, 0, sizeof(struct sockaddr));
    673             else
    674                 ife->dstaddr = ifr.ifr_dstaddr;
    675 
    676             strcpy(ifr.ifr_name, ifname);
    677             if (ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0)
    678                 memset(&ife->broadaddr, 0, sizeof(struct sockaddr));
    679             else
    680                 ife->broadaddr = ifr.ifr_broadaddr;
    681 
    682             strcpy(ifr.ifr_name, ifname);
    683             if (ioctl(fd, SIOCGIFNETMASK, &ifr) < 0)
    684                 memset(&ife->netmask, 0, sizeof(struct sockaddr));
    685             else
    686                 ife->netmask = ifr.ifr_netmask;
    687         } else
    688             memset(&ife->addr, 0, sizeof(struct sockaddr));
    689     }
    690 
     650    strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
     651    ifr.ifr_addr.sa_family = AF_INET;
     652    memset(&ife->addr, 0, sizeof(struct sockaddr));
     653    if (ioctl(skfd, SIOCGIFADDR, &ifr) == 0) {
     654        ife->has_ip = 1;
     655        ife->addr = ifr.ifr_addr;
     656        strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
     657        memset(&ife->dstaddr, 0, sizeof(struct sockaddr));
     658        if (ioctl(skfd, SIOCGIFDSTADDR, &ifr) >= 0)
     659            ife->dstaddr = ifr.ifr_dstaddr;
     660
     661        strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
     662        memset(&ife->broadaddr, 0, sizeof(struct sockaddr));
     663        if (ioctl(skfd, SIOCGIFBRDADDR, &ifr) >= 0)
     664            ife->broadaddr = ifr.ifr_broadaddr;
     665
     666        strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
     667        memset(&ife->netmask, 0, sizeof(struct sockaddr));
     668        if (ioctl(skfd, SIOCGIFNETMASK, &ifr) >= 0)
     669            ife->netmask = ifr.ifr_netmask;
     670    }
     671
     672    close(skfd);
    691673    return 0;
    692674}
     
    696678{
    697679    if (if_fetch(ife) < 0) {
    698         char *errmsg;
     680        const char *errmsg;
    699681
    700682        if (errno == ENODEV) {
     
    711693}
    712694
    713 /* This structure defines hardware protocols and their handlers. */
    714 struct hwtype {
    715     const char * const name;
    716     const char *title;
    717     int type;
    718     int alen;
    719     char *(*print) (unsigned char *);
    720     int (*input) (char *, struct sockaddr *);
    721     int (*activate) (int fd);
    722     int suppress_null_addr;
    723 };
    724 
    725695static const struct hwtype unspec_hwtype = {
    726696    .name =     "unspec",
     
    738708#include <net/if_arp.h>
    739709
    740 #if (__GLIBC__ >=2 && __GLIBC_MINOR >= 1) || defined(_NEWLIB_VERSION)
     710#if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined(_NEWLIB_VERSION)
    741711#include <net/ethernet.h>
    742712#else
     
    747717static char *pr_ether(unsigned char *ptr)
    748718{
    749     static char buff[64];
    750 
    751     snprintf(buff, sizeof(buff), "%02X:%02X:%02X:%02X:%02X:%02X",
     719    static char *buff;
     720
     721    free(buff);
     722    buff = xasprintf("%02X:%02X:%02X:%02X:%02X:%02X",
    752723             (ptr[0] & 0377), (ptr[1] & 0377), (ptr[2] & 0377),
    753724             (ptr[3] & 0377), (ptr[4] & 0377), (ptr[5] & 0377)
    754725        );
    755     return (buff);
    756 }
     726    return buff;
     727}
     728
     729static int in_ether(const char *bufp, struct sockaddr *sap);
    757730
    758731static const struct hwtype ether_hwtype = {
     
    761734    .type =     ARPHRD_ETHER,
    762735    .alen =     ETH_ALEN,
    763     .print =    pr_ether
    764 };
     736    .print =    pr_ether,
     737    .input =    in_ether
     738};
     739
     740static unsigned hexchar2int(char c)
     741{
     742    if (isdigit(c))
     743        return c - '0';
     744    c &= ~0x20; /* a -> A */
     745    if ((unsigned)(c - 'A') <= 5)
     746        return c - ('A' - 10);
     747    return ~0U;
     748}
     749
     750/* Input an Ethernet address and convert to binary. */
     751static int in_ether(const char *bufp, struct sockaddr *sap)
     752{
     753    unsigned char *ptr;
     754    char c;
     755    int i;
     756    unsigned val;
     757
     758    sap->sa_family = ether_hwtype.type;
     759    ptr = (unsigned char*) sap->sa_data;
     760
     761    i = 0;
     762    while ((*bufp != '\0') && (i < ETH_ALEN)) {
     763        val = hexchar2int(*bufp++) * 0x10;
     764        if (val > 0xff) {
     765            errno = EINVAL;
     766            return -1;
     767        }
     768        c = *bufp;
     769        if (c == ':' || c == 0)
     770            val >>= 4;
     771        else {
     772            val |= hexchar2int(c);
     773            if (val > 0xff) {
     774                errno = EINVAL;
     775                return -1;
     776            }
     777        }
     778        if (c != 0)
     779            bufp++;
     780        *ptr++ = (unsigned char) val;
     781        i++;
     782
     783        /* We might get a semicolon here - not required. */
     784        if (*bufp == ':') {
     785            bufp++;
     786        }
     787    }
     788    return 0;
     789}
    765790
    766791#include <net/if_arp.h>
     
    772797};
    773798
    774 #ifdef CONFIG_FEATURE_IPV6
     799#if ENABLE_FEATURE_IPV6
    775800static const struct hwtype sit_hwtype = {
    776801    .name =         "sit",
     
    779804    .print =        UNSPEC_print,
    780805    .suppress_null_addr =   1
    781 } ;
    782 #endif
    783 
    784 static const struct hwtype * const hwtypes[] = {
     806};
     807#endif
     808
     809static const struct hwtype *const hwtypes[] = {
    785810    &loop_hwtype,
    786811    &ether_hwtype,
    787812    &ppp_hwtype,
    788813    &unspec_hwtype,
    789 #ifdef CONFIG_FEATURE_IPV6
     814#if ENABLE_FEATURE_IPV6
    790815    &sit_hwtype,
    791816#endif
     
    794819
    795820#ifdef IFF_PORTSEL
    796 static const char * const if_port_text[] = {
     821static const char *const if_port_text[] = {
    797822    /* Keep in step with <linux/netdevice.h> */
    798823    "unknown",
     
    808833
    809834/* Check our hardware type table for this type. */
    810 static const struct hwtype *get_hwntype(int type)
    811 {
    812     const struct hwtype * const *hwp;
     835const struct hwtype *get_hwtype(const char *name)
     836{
     837    const struct hwtype *const *hwp;
     838
     839    hwp = hwtypes;
     840    while (*hwp != NULL) {
     841        if (!strcmp((*hwp)->name, name))
     842            return (*hwp);
     843        hwp++;
     844    }
     845    return NULL;
     846}
     847
     848/* Check our hardware type table for this type. */
     849const struct hwtype *get_hwntype(int type)
     850{
     851    const struct hwtype *const *hwp;
    813852
    814853    hwp = hwtypes;
    815854    while (*hwp != NULL) {
    816855        if ((*hwp)->type == type)
    817             return (*hwp);
     856            return *hwp;
    818857        hwp++;
    819858    }
    820     return (NULL);
     859    return NULL;
    821860}
    822861
     
    833872}
    834873
    835 static const char TRext[] = "\0\0\0Ki\0Mi\0Gi\0Ti";
     874static const char TRext[] ALIGN1 = "\0\0\0Ki\0Mi\0Gi\0Ti";
    836875
    837876static void print_bytes_scaled(unsigned long long ull, const char *end)
     
    858897}
    859898
    860 static const char * const ife_print_flags_strs[] = {
    861     "UP ",
    862     "BROADCAST ",
    863     "DEBUG ",
    864     "LOOPBACK ",
    865     "POINTOPOINT ",
    866     "NOTRAILERS ",
    867     "RUNNING ",
    868     "NOARP ",
    869     "PROMISC ",
    870     "ALLMULTI ",
    871     "SLAVE ",
    872     "MASTER ",
    873     "MULTICAST ",
    874 #ifdef HAVE_DYNAMIC
    875     "DYNAMIC "
    876 #endif
    877 };
    878 
    879 static const unsigned short ife_print_flags_mask[] = {
    880     IFF_UP,
    881     IFF_BROADCAST,
    882     IFF_DEBUG,
    883     IFF_LOOPBACK,
    884     IFF_POINTOPOINT,
    885     IFF_NOTRAILERS,
    886     IFF_RUNNING,
    887     IFF_NOARP,
    888     IFF_PROMISC,
    889     IFF_ALLMULTI,
    890     IFF_SLAVE,
    891     IFF_MASTER,
    892     IFF_MULTICAST,
    893 #ifdef HAVE_DYNAMIC
    894     IFF_DYNAMIC
    895 #endif
    896     0
    897 };
    898 
    899899static void ife_print(struct interface *ptr)
    900900{
    901     struct aftype *ap;
     901    const struct aftype *ap;
    902902    const struct hwtype *hw;
    903903    int hf;
    904904    int can_compress = 0;
    905905
    906 #if HAVE_AFINET6
     906#ifdef HAVE_AFINET6
    907907    FILE *f;
    908908    char addr6[40], devname[20];
     
    938938    }
    939939#endif
    940     printf("\n");
     940    puts("");
    941941
    942942    if (ptr->has_ip) {
     
    952952    }
    953953
    954 #if HAVE_AFINET6
     954#ifdef HAVE_AFINET6
    955955
    956956#define IPV6_ADDR_ANY           0x0000U
     
    971971#define IPV6_ADDR_RESERVED      0x2000U /* reserved address space */
    972972
    973     if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
     973    f = fopen(_PATH_PROCNET_IFINET6, "r");
     974    if (f != NULL) {
    974975        while (fscanf
    975                (f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
     976               (f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n",
    976977                addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4],
    977978                addr6p[5], addr6p[6], addr6p[7], &if_idx, &plen, &scope,
    978                 &dad_status, devname) != EOF) {
     979                &dad_status, devname) != EOF
     980        ) {
    979981            if (!strcmp(devname, ptr->name)) {
    980982                sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
     
    985987                sap.sin6_family = AF_INET6;
    986988                printf("          inet6 addr: %s/%d",
    987                        inet6_aftype.sprint((struct sockaddr *) &sap, 1),
     989                       INET6_sprint((struct sockaddr *) &sap, 1),
    988990                       plen);
    989991                printf(" Scope:");
    990992                switch (scope & IPV6_ADDR_SCOPE_MASK) {
    991993                case 0:
    992                     printf("Global");
     994                    puts("Global");
    993995                    break;
    994996                case IPV6_ADDR_LINKLOCAL:
    995                     printf("Link");
     997                    puts("Link");
    996998                    break;
    997999                case IPV6_ADDR_SITELOCAL:
    998                     printf("Site");
     1000                    puts("Site");
    9991001                    break;
    10001002                case IPV6_ADDR_COMPATv4:
    1001                     printf("Compat");
     1003                    puts("Compat");
    10021004                    break;
    10031005                case IPV6_ADDR_LOOPBACK:
    1004                     printf("Host");
     1006                    puts("Host");
    10051007                    break;
    10061008                default:
    1007                     printf("Unknown");
     1009                    puts("Unknown");
    10081010                }
    1009                 printf("\n");
    10101011            }
    10111012        }
     
    10201021        printf("[NO FLAGS] ");
    10211022    } else {
    1022         int i = 0;
     1023        static const char ife_print_flags_strs[] ALIGN1 =
     1024            "UP\0"
     1025            "BROADCAST\0"
     1026            "DEBUG\0"
     1027            "LOOPBACK\0"
     1028            "POINTOPOINT\0"
     1029            "NOTRAILERS\0"
     1030            "RUNNING\0"
     1031            "NOARP\0"
     1032            "PROMISC\0"
     1033            "ALLMULTI\0"
     1034            "SLAVE\0"
     1035            "MASTER\0"
     1036            "MULTICAST\0"
     1037#ifdef HAVE_DYNAMIC
     1038            "DYNAMIC\0"
     1039#endif
     1040            ;
     1041        static const unsigned short ife_print_flags_mask[] ALIGN2 = {
     1042            IFF_UP,
     1043            IFF_BROADCAST,
     1044            IFF_DEBUG,
     1045            IFF_LOOPBACK,
     1046            IFF_POINTOPOINT,
     1047            IFF_NOTRAILERS,
     1048            IFF_RUNNING,
     1049            IFF_NOARP,
     1050            IFF_PROMISC,
     1051            IFF_ALLMULTI,
     1052            IFF_SLAVE,
     1053            IFF_MASTER,
     1054            IFF_MULTICAST
     1055#ifdef HAVE_DYNAMIC
     1056            ,IFF_DYNAMIC
     1057#endif
     1058        };
     1059        const unsigned short *mask = ife_print_flags_mask;
     1060        const char *str = ife_print_flags_strs;
    10231061        do {
    1024             if (ptr->flags & ife_print_flags_mask[i]) {
    1025                 printf(ife_print_flags_strs[i]);
     1062            if (ptr->flags & *mask) {
     1063                printf("%s ", str);
    10261064            }
    1027         } while (ife_print_flags_mask[++i]);
     1065            mask++;
     1066            str += strlen(str) + 1;
     1067        } while (*str);
    10281068    }
    10291069
     
    10341074        printf("  Outfill:%d  Keepalive:%d", ptr->outfill, ptr->keepalive);
    10351075#endif
    1036     printf("\n");
     1076    puts("");
    10371077
    10381078    /* If needed, display the interface statistics. */
     
    10831123        if (ptr->map.dma)
    10841124            printf("DMA chan:%x ", ptr->map.dma);
    1085         printf("\n");
    1086     }
    1087     printf("\n");
    1088 }
    1089 
    1090 
    1091 static int do_if_print(struct interface *ife, void *cookie)
    1092 {
    1093     int *opt_a = (int *) cookie;
     1125        puts("");
     1126    }
     1127    puts("");
     1128}
     1129
     1130
     1131static int do_if_print(struct interface *ife) /*, int *opt_a)*/
     1132{
    10941133    int res;
    10951134
    10961135    res = do_if_fetch(ife);
    10971136    if (res >= 0) {
    1098         if ((ife->flags & IFF_UP) || *opt_a)
     1137        if ((ife->flags & IFF_UP) || interface_opt_a)
    10991138            ife_print(ife);
    11001139    }
     
    11121151}
    11131152
     1153#ifdef UNUSED
     1154static int for_all_interfaces(int (*doit) (struct interface *, void *),
     1155                              void *cookie)
     1156{
     1157    struct interface *ife;
     1158
     1159    if (!int_list && (if_readlist() < 0))
     1160        return -1;
     1161    for (ife = int_list; ife; ife = ife->next) {
     1162        int err = doit(ife, cookie);
     1163
     1164        if (err)
     1165            return err;
     1166    }
     1167    return 0;
     1168}
     1169#endif
     1170
    11141171/* for ipv4 add/del modes */
    11151172static int if_print(char *ifname)
    11161173{
     1174    struct interface *ife;
    11171175    int res;
    11181176
    11191177    if (!ifname) {
    1120         res = for_all_interfaces(do_if_print, &interface_opt_a);
    1121     } else {
    1122         struct interface *ife;
    1123 
    1124         ife = lookup_interface(ifname);
    1125         res = do_if_fetch(ife);
    1126         if (res >= 0)
    1127             ife_print(ife);
    1128     }
     1178        /*res = for_all_interfaces(do_if_print, &interface_opt_a);*/
     1179        if (!int_list && (if_readlist() < 0))
     1180            return -1;
     1181        for (ife = int_list; ife; ife = ife->next) {
     1182            int err = do_if_print(ife); /*, &interface_opt_a);*/
     1183            if (err)
     1184                return err;
     1185        }
     1186        return 0;
     1187    }
     1188    ife = lookup_interface(ifname);
     1189    res = do_if_fetch(ife);
     1190    if (res >= 0)
     1191        ife_print(ife);
    11291192    return res;
    11301193}
    11311194
    1132 int display_interfaces(char *ifname);
    11331195int display_interfaces(char *ifname)
    11341196{
    11351197    int status;
    11361198
    1137     /* Create a channel to the NET kernel. */
    1138     if ((skfd = sockets_open(0)) < 0) {
    1139         bb_perror_msg_and_die("socket");
    1140     }
    1141 
    1142     /* Do we have to show the current setup? */
    11431199    status = if_print(ifname);
    1144 #ifdef CONFIG_FEATURE_CLEAN_UP
    1145     sockets_close();
    1146 #endif
    1147     exit(status < 0);
    1148 }
     1200
     1201    return (status < 0); /* status < 0 == 1 -- error */
     1202}
Note: See TracChangeset for help on using the changeset viewer.