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)

Location:
branches/stable/mindi-busybox/networking/libiproute
Files:
3 deleted
19 edited
2 copied

Legend:

Unmodified
Added
Removed
  • branches/stable/mindi-busybox/networking/libiproute/ip_common.h

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12#ifndef _IP_COMMON_H
    23#define _IP_COMMON_H 1
    34
    4 #include "busybox.h"
     5#include "libbb.h"
    56#include <asm/types.h>
    67#include <linux/netlink.h>
    78#include <linux/rtnetlink.h>
    8 
    9 
    10 extern int preferred_family;
    11 extern char * _SL_;
     9#if !defined IFA_RTA
     10#include <linux/if_addr.h>
     11#endif
     12#if !defined IFLA_RTA
     13#include <linux/if_link.h>
     14#endif
    1215
    1316extern void ip_parse_common_args(int *argcp, char ***argvp);
     
    1720extern void iplink_usage(void) ATTRIBUTE_NORETURN;
    1821extern void ipneigh_reset_filter(void);
     22
    1923extern int do_ipaddr(int argc, char **argv);
    2024extern int do_iproute(int argc, char **argv);
  • branches/stable/mindi-busybox/networking/libiproute/ip_parse_common_args.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * ip.c     "ip" utility frontend.
     
    1516 */
    1617
    17 #include <string.h>
    18 
    19 #include "libbb.h"
     18#include "ip_common.h"  /* #include "libbb.h" is inside */
    2019#include "utils.h"
    21 #include "ip_common.h"
    22 
    2320
    2421int preferred_family = AF_UNSPEC;
    25 int oneline = 0;
    26 char * _SL_ = NULL;
     22smallint oneline;
     23char _SL_;
    2724
    2825void ip_parse_common_args(int *argcp, char ***argvp)
     
    3027    int argc = *argcp;
    3128    char **argv = *argvp;
     29    static const char ip_common_commands[] ALIGN1 =
     30        "-family\0""inet\0""inet6\0""link\0"
     31        "-4\0""-6\0""-0\0""-oneline\0";
     32    enum {
     33        ARG_family = 1,
     34        ARG_inet,
     35        ARG_inet6,
     36        ARG_link,
     37        ARG_IPv4,
     38        ARG_IPv6,
     39        ARG_packet,
     40        ARG_oneline
     41    };
     42    smalluint arg;
    3243
    3344    while (argc > 1) {
     
    3546
    3647        if (strcmp(opt,"--") == 0) {
    37             argc--; argv++;
     48            argc--;
     49            argv++;
    3850            break;
    3951        }
    40 
    4152        if (opt[0] != '-')
    4253            break;
    43 
    4454        if (opt[1] == '-')
    4555            opt++;
    46 
    47         if (matches(opt, "-family") == 0) {
     56        arg = index_in_strings(ip_common_commands, opt) + 1;
     57        if (arg == ARG_family) {
    4858            argc--;
    4959            argv++;
    50             if (! argv[1])
    51                 bb_show_usage();
    52             if (strcmp(argv[1], "inet") == 0)
     60            if (!argv[1])
     61                bb_show_usage();
     62            arg = index_in_strings(ip_common_commands, argv[1]) + 1;
     63            if (arg == ARG_inet)
    5364                preferred_family = AF_INET;
    54             else if (strcmp(argv[1], "inet6") == 0)
     65            else if (arg == ARG_inet6)
    5566                preferred_family = AF_INET6;
    56             else if (strcmp(argv[1], "link") == 0)
     67            else if (arg == ARG_link)
    5768                preferred_family = AF_PACKET;
    5869            else
    5970                invarg(argv[1], "protocol family");
    60         } else if (strcmp(opt, "-4") == 0) {
     71        } else if (arg == ARG_IPv4) {
    6172            preferred_family = AF_INET;
    62         } else if (strcmp(opt, "-6") == 0) {
     73        } else if (arg == ARG_IPv6) {
    6374            preferred_family = AF_INET6;
    64         } else if (strcmp(opt, "-0") == 0) {
     75        } else if (arg == ARG_packet) {
    6576            preferred_family = AF_PACKET;
    66         } else if (matches(opt, "-oneline") == 0) {
     77        } else if (arg == ARG_oneline) {
    6778            ++oneline;
    6879        } else {
    6980            bb_show_usage();
    7081        }
    71         argc--; argv++;
     82        argc--;
     83        argv++;
    7284    }
    73     _SL_ = oneline ? "\\" : "\n" ;
     85    _SL_ = oneline ? '\\' : '\n';
    7486    *argcp = argc;
    7587    *argvp = argv;
  • branches/stable/mindi-busybox/networking/libiproute/ipaddress.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * ipaddress.c      "ip address".
     
    1011 */
    1112
    12 #include "libbb.h"
    13 #include <sys/socket.h>
    14 #include <sys/ioctl.h>
    15 
     13//#include <sys/socket.h>
     14//#include <sys/ioctl.h>
    1615#include <fnmatch.h>
    17 #include <string.h>
    18 #include <unistd.h>
    19 
    2016#include <net/if.h>
    2117#include <net/if_arp.h>
    2218
     19#include "ip_common.h"  /* #include "libbb.h" is inside */
    2320#include "rt_names.h"
    2421#include "utils.h"
    25 #include "ip_common.h"
    26 
    27 
    28 static struct
    29 {
     22
     23
     24typedef struct filter_t {
    3025    int ifindex;
    3126    int family;
     
    4237    int flushe;
    4338    struct rtnl_handle *rth;
    44 } filter;
     39} filter_t;
     40
     41#define filter (*(filter_t*)&bb_common_bufsiz1)
     42
    4543
    4644static void print_link_flags(FILE *fp, unsigned flags, unsigned mdown)
     
    4947    flags &= ~IFF_RUNNING;
    5048#define _PF(f) if (flags&IFF_##f) { \
    51           flags &= ~IFF_##f ; \
     49          flags &= ~IFF_##f; \
    5250          fprintf(fp, #f "%s", flags ? "," : ""); }
    5351    _PF(LOOPBACK);
     
    8684
    8785    memset(&ifr, 0, sizeof(ifr));
    88     strcpy(ifr.ifr_name, name);
    89     if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) {
    90         perror("SIOCGIFXQLEN");
     86    strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
     87    if (ioctl_or_warn(s, SIOCGIFTXQLEN, &ifr) < 0) {
    9188        close(s);
    9289        return;
     
    9996
    10097static int print_linkinfo(struct sockaddr_nl ATTRIBUTE_UNUSED *who,
    101         struct nlmsghdr *n, void ATTRIBUTE_UNUSED *arg)
     98        const struct nlmsghdr *n, void ATTRIBUTE_UNUSED *arg)
    10299{
    103100    FILE *fp = (FILE*)arg;
     
    125122        return -1;
    126123    }
    127     if (filter.label &&
    128         (!filter.family || filter.family == AF_PACKET) &&
    129         fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
    130         return 0;
     124    if (filter.label
     125     && (!filter.family || filter.family == AF_PACKET)
     126     && fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)
     127    ) {
     128        return 0;
     129    }
    131130
    132131    if (n->nlmsg_type == RTM_DELLINK)
     
    166165    if (!filter.family || filter.family == AF_PACKET) {
    167166        SPRINT_BUF(b1);
    168         fprintf(fp, "%s", _SL_);
    169         fprintf(fp, "    link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));
     167        fprintf(fp, "%c    link/%s ", _SL_, ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));
    170168
    171169        if (tb[IFLA_ADDRESS]) {
     
    186184        }
    187185    }
    188     fprintf(fp, "\n");
     186    fputc('\n', fp);
    189187    fflush(fp);
    190188    return 0;
     
    194192{
    195193    if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) {
    196         perror("Failed to send flush request\n");
     194        bb_perror_msg("failed to send flush request");
    197195        return -1;
    198196    }
     
    341339        struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]);
    342340        char buf[128];
    343         fprintf(fp, "%s", _SL_);
     341        fputc(_SL_, fp);
    344342        if (ci->ifa_valid == 0xFFFFFFFFU)
    345343            sprintf(buf, "valid_lft forever");
     
    352350        fprintf(fp, "       %s", buf);
    353351    }
    354     fprintf(fp, "\n");
     352    fputc('\n', fp);
    355353    fflush(fp);
    356354    return 0;
     
    366364static int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *fp)
    367365{
    368     for ( ;ainfo ; ainfo = ainfo->next) {
     366    for (; ainfo; ainfo = ainfo->next) {
    369367        struct nlmsghdr *n = &ainfo->h;
    370368        struct ifaddrmsg *ifa = NLMSG_DATA(n);
     
    412410}
    413411
     412/* Return value becomes exitcode. It's okay to not return at all */
    414413int ipaddr_list_or_flush(int argc, char **argv, int flush)
    415414{
    416     static const char *const option[] = { "to", "scope", "up", "label", "dev", 0 };
     415    static const char option[] ALIGN1 = "to\0""scope\0""up\0""label\0""dev\0";
    417416
    418417    struct nlmsg_list *linfo = NULL;
     
    431430    if (flush) {
    432431        if (argc <= 0) {
    433             bb_error_msg(bb_msg_requires_arg, "flush");
    434             return -1;
     432            bb_error_msg_and_die(bb_msg_requires_arg, "flush");
    435433        }
    436434        if (filter.family == AF_PACKET) {
    437             bb_error_msg("Cannot flush link addresses.");
    438             return -1;
     435            bb_error_msg_and_die("cannot flush link addresses");
    439436        }
    440437    }
    441438
    442439    while (argc > 0) {
    443         const int option_num = compare_string_array(option, *argv);
     440        const int option_num = index_in_strings(option, *argv);
    444441        switch (option_num) {
    445442            case 0: /* to */
     
    484481    }
    485482
    486     if (rtnl_open(&rth, 0) < 0)
    487         exit(1);
    488 
    489     if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK) < 0) {
    490         bb_perror_msg_and_die("Cannot send dump request");
    491     }
    492 
    493     if (rtnl_dump_filter(&rth, store_nlmsg, &linfo, NULL, NULL) < 0) {
    494         bb_error_msg_and_die("Dump terminated");
    495     }
     483    xrtnl_open(&rth);
     484
     485    xrtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK);
     486    xrtnl_dump_filter(&rth, store_nlmsg, &linfo);
    496487
    497488    if (filter_dev) {
    498         filter.ifindex = ll_name_to_index(filter_dev);
    499         if (filter.ifindex <= 0) {
    500             bb_error_msg("Device \"%s\" does not exist", filter_dev);
    501             return -1;
    502         }
     489        filter.ifindex = xll_name_to_index(filter_dev);
    503490    }
    504491
     
    512499
    513500        for (;;) {
    514             if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {
    515                 perror("Cannot send dump request");
    516                 exit(1);
    517             }
     501            xrtnl_wilddump_request(&rth, filter.family, RTM_GETADDR);
    518502            filter.flushed = 0;
    519             if (rtnl_dump_filter(&rth, print_addrinfo, stdout, NULL, NULL) < 0) {
    520                 fprintf(stderr, "Flush terminated\n");
    521                 exit(1);
    522             }
     503            xrtnl_dump_filter(&rth, print_addrinfo, stdout);
    523504            if (filter.flushed == 0) {
    524                 fflush(stdout);
    525505                return 0;
    526506            }
    527507            if (flush_update() < 0)
    528                 exit(1);
     508                return 1;
    529509        }
    530510    }
    531511
    532512    if (filter.family != AF_PACKET) {
    533         if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {
    534             bb_perror_msg_and_die("Cannot send dump request");
    535         }
    536 
    537         if (rtnl_dump_filter(&rth, store_nlmsg, &ainfo, NULL, NULL) < 0) {
    538             bb_error_msg_and_die("Dump terminated");
    539         }
     513        xrtnl_wilddump_request(&rth, filter.family, RTM_GETADDR);
     514        xrtnl_dump_filter(&rth, store_nlmsg, &ainfo);
    540515    }
    541516
     
    601576    }
    602577
    603     for (l=linfo; l; l = l->next) {
     578    for (l = linfo; l; l = l->next) {
    604579        if (no_link || print_linkinfo(NULL, &l->h, stdout) == 0) {
    605580            struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
     
    607582                print_selected_addrinfo(ifi->ifi_index, ainfo, stdout);
    608583        }
    609         fflush(stdout);
    610     }
    611 
    612     exit(0);
     584        fflush(stdout); /* why? */
     585    }
     586
     587    return 0;
    613588}
    614589
     
    616591{
    617592    if (lcl->family == AF_INET) {
    618         if (lcl->bytelen >= 1 && *(__u8*)&lcl->data == 127)
     593        if (lcl->bytelen >= 1 && *(uint8_t*)&lcl->data == 127)
    619594            return RT_SCOPE_HOST;
    620595    }
     
    622597}
    623598
     599/* Return value becomes exitcode. It's okay to not return at all */
    624600static int ipaddr_modify(int cmd, int argc, char **argv)
    625601{
    626     static const char *const option[] = {
    627         "peer", "remote", "broadcast", "brd",
    628         "anycast", "scope", "dev", "label", "local", 0
    629     };
    630 
     602    static const char option[] ALIGN1 =
     603        "peer\0""remote\0""broadcast\0""brd\0"
     604        "anycast\0""scope\0""dev\0""label\0""local\0";
    631605    struct rtnl_handle rth;
    632606    struct {
    633         struct nlmsghdr     n;
    634         struct ifaddrmsg    ifa;
    635         char            buf[256];
     607        struct nlmsghdr  n;
     608        struct ifaddrmsg ifa;
     609        char             buf[256];
    636610    } req;
    637     char  *d = NULL;
    638     char  *l = NULL;
     611    char *d = NULL;
     612    char *l = NULL;
    639613    inet_prefix lcl;
    640614    inet_prefix peer;
     
    643617    int brd_len = 0;
    644618    int any_len = 0;
    645     int scoped = 0;
     619    bool scoped = 0;
    646620
    647621    memset(&req, 0, sizeof(req));
     
    653627
    654628    while (argc > 0) {
    655         const int option_num = compare_string_array(option, *argv);
     629        const int option_num = index_in_strings(option, *argv);
    656630        switch (option_num) {
    657631            case 0: /* peer */
     
    678652                    duparg("broadcast", *argv);
    679653                }
    680                 if (strcmp(*argv, "+") == 0) {
     654                if (LONE_CHAR(*argv, '+')) {
    681655                    brd_len = -1;
    682656                }
    683                 else if (strcmp(*argv, "-") == 0) {
     657                else if (LONE_DASH(*argv)) {
    684658                    brd_len = -2;
    685659                } else {
     
    748722        return -1;
    749723    }
    750     if (l && matches(d, l) != 0) {
     724    if (l && strncmp(d, l, strlen(d)) != 0) {
    751725        bb_error_msg_and_die("\"dev\" (%s) must match \"label\" (%s)", d, l);
    752726    }
     
    763737        int i;
    764738        if (req.ifa.ifa_family != AF_INET) {
    765             bb_error_msg("Broadcast can be set only for IPv4 addresses");
    766             return -1;
     739            bb_error_msg_and_die("broadcast can be set only for IPv4 addresses");
    767740        }
    768741        brd = peer;
     
    781754        req.ifa.ifa_scope = default_scope(&lcl);
    782755
    783     if (rtnl_open(&rth, 0) < 0)
    784         exit(1);
     756    xrtnl_open(&rth);
    785757
    786758    ll_init_map(&rth);
    787759
    788     if ((req.ifa.ifa_index = ll_name_to_index(d)) == 0) {
    789         bb_error_msg("Cannot find device \"%s\"", d);
    790         return -1;
    791     }
     760    req.ifa.ifa_index = xll_name_to_index(d);
    792761
    793762    if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
    794         exit(2);
    795 
    796     exit(0);
    797 }
    798 
     763        return 2;
     764
     765    return 0;
     766}
     767
     768/* Return value becomes exitcode. It's okay to not return at all */
    799769int do_ipaddr(int argc, char **argv)
    800770{
    801     static const char *const commands[] = {
    802         "add", "delete", "list", "show", "lst", "flush", 0
    803     };
    804 
    805     int command_num = 2;
     771    static const char commands[] ALIGN1 =
     772        "add\0""delete\0""list\0""show\0""lst\0""flush\0";
     773
     774    int command_num = 2; /* default command is list */
    806775
    807776    if (*argv) {
    808         command_num = compare_string_array(commands, *argv);
    809     }
    810     switch (command_num) {
    811         case 0: /* add */
    812             return ipaddr_modify(RTM_NEWADDR, argc-1, argv+1);
    813         case 1: /* delete */
    814             return ipaddr_modify(RTM_DELADDR, argc-1, argv+1);
    815         case 2: /* list */
    816         case 3: /* show */
    817         case 4: /* lst */
    818             return ipaddr_list_or_flush(argc-1, argv+1, 0);
    819         case 5: /* flush */
    820             return ipaddr_list_or_flush(argc-1, argv+1, 1);
    821     }
    822     bb_error_msg_and_die("Unknown command %s", *argv);
    823 }
     777        command_num = index_in_substrings(commands, *argv);
     778    }
     779    if (command_num < 0 || command_num > 5)
     780        bb_error_msg_and_die("unknown command %s", *argv);
     781    --argc;
     782    ++argv;
     783    if (command_num == 0) /* add */
     784        return ipaddr_modify(RTM_NEWADDR, argc, argv);
     785    else if (command_num == 1) /* delete */
     786        return ipaddr_modify(RTM_DELADDR, argc, argv);
     787    else if (command_num == 5) /* flush */
     788        return ipaddr_list_or_flush(argc, argv, 1);
     789    else /* 2 == list, 3 == show, 4 == lst */
     790        return ipaddr_list_or_flush(argc, argv, 0);
     791}
  • branches/stable/mindi-busybox/networking/libiproute/iplink.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    2  * iplink.c     "ip link".
     3 * iplink.c "ip link".
    34 *
    4  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
     5 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    56 *
    67 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    78 */
    89
    9 #include "libbb.h"
    10 
    11 #include <sys/ioctl.h>
    12 #include <sys/socket.h>
    13 
    14 #include <errno.h>
    15 #include <string.h>
    16 #include <unistd.h>
    17 
     10//#include <sys/ioctl.h>
     11//#include <sys/socket.h>
    1812#include <net/if.h>
    1913#include <net/if_packet.h>
    2014#include <netpacket/packet.h>
    21 
    2215#include <net/ethernet.h>
    2316
     17#include "ip_common.h"  /* #include "libbb.h" is inside */
    2418#include "rt_names.h"
    2519#include "utils.h"
    26 #include "ip_common.h"
    27 
    28 /* take from linux/sockios.h */
     20
     21/* taken from linux/sockios.h */
    2922#define SIOCSIFNAME 0x8923      /* set interface name */
    3023
    31 static int do_link;
    32 
    33 static int on_off(char *msg)
    34 {
    35     bb_error_msg("Error: argument of \"%s\" must be \"on\" or \"off\"", msg);
    36     return -1;
    37 }
    38 
     24static void on_off(const char *msg) ATTRIBUTE_NORETURN;
     25static void on_off(const char *msg)
     26{
     27    bb_error_msg_and_die("error: argument of \"%s\" must be \"on\" or \"off\"", msg);
     28}
     29
     30/* Exits on error */
    3931static int get_ctl_fd(void)
    4032{
    41     int s_errno;
    4233    int fd;
    4334
     
    4536    if (fd >= 0)
    4637        return fd;
    47     s_errno = errno;
    4838    fd = socket(PF_PACKET, SOCK_DGRAM, 0);
    4939    if (fd >= 0)
    5040        return fd;
    51     fd = socket(PF_INET6, SOCK_DGRAM, 0);
    52     if (fd >= 0)
    53         return fd;
    54     errno = s_errno;
    55     perror("Cannot create control socket");
    56     return -1;
    57 }
    58 
    59 static int do_chflags(char *dev, __u32 flags, __u32 mask)
     41    return xsocket(PF_INET6, SOCK_DGRAM, 0);
     42}
     43
     44/* Exits on error */
     45static void do_chflags(char *dev, uint32_t flags, uint32_t mask)
    6046{
    6147    struct ifreq ifr;
    6248    int fd;
    63     int err;
    64 
    65     strcpy(ifr.ifr_name, dev);
     49
     50    strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
    6651    fd = get_ctl_fd();
    67     if (fd < 0)
    68         return -1;
    69     err = ioctl(fd, SIOCGIFFLAGS, &ifr);
    70     if (err) {
    71         perror("SIOCGIFFLAGS");
    72         close(fd);
    73         return -1;
    74     }
    75     if ((ifr.ifr_flags^flags)&mask) {
     52    xioctl(fd, SIOCGIFFLAGS, &ifr);
     53    if ((ifr.ifr_flags ^ flags) & mask) {
    7654        ifr.ifr_flags &= ~mask;
    77         ifr.ifr_flags |= mask&flags;
    78         err = ioctl(fd, SIOCSIFFLAGS, &ifr);
    79         if (err)
    80             perror("SIOCSIFFLAGS");
     55        ifr.ifr_flags |= mask & flags;
     56        xioctl(fd, SIOCSIFFLAGS, &ifr);
    8157    }
    8258    close(fd);
    83     return err;
    84 }
    85 
    86 static int do_changename(char *dev, char *newdev)
     59}
     60
     61/* Exits on error */
     62static void do_changename(char *dev, char *newdev)
    8763{
    8864    struct ifreq ifr;
    8965    int fd;
    90     int err;
    91 
    92     strcpy(ifr.ifr_name, dev);
    93     strcpy(ifr.ifr_newname, newdev);
     66
     67    strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
     68    strncpy(ifr.ifr_newname, newdev, sizeof(ifr.ifr_newname));
    9469    fd = get_ctl_fd();
    95     if (fd < 0)
    96         return -1;
    97     err = ioctl(fd, SIOCSIFNAME, &ifr);
    98     if (err) {
    99         perror("SIOCSIFNAME");
    100         close(fd);
    101         return -1;
    102     }
     70    xioctl(fd, SIOCSIFNAME, &ifr);
    10371    close(fd);
    104     return err;
    105 }
    106 
    107 static int set_qlen(char *dev, int qlen)
     72}
     73
     74/* Exits on error */
     75static void set_qlen(char *dev, int qlen)
    10876{
    10977    struct ifreq ifr;
     
    11179
    11280    s = get_ctl_fd();
    113     if (s < 0)
    114         return -1;
    115 
    11681    memset(&ifr, 0, sizeof(ifr));
    117     strcpy(ifr.ifr_name, dev);
     82    strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
    11883    ifr.ifr_qlen = qlen;
    119     if (ioctl(s, SIOCSIFTXQLEN, &ifr) < 0) {
    120         perror("SIOCSIFXQLEN");
    121         close(s);
    122         return -1;
    123     }
    124     close(s);
    125 
    126     return 0;
    127 }
    128 
    129 static int set_mtu(char *dev, int mtu)
     84    xioctl(s, SIOCSIFTXQLEN, &ifr);
     85    close(s);
     86}
     87
     88/* Exits on error */
     89static void set_mtu(char *dev, int mtu)
    13090{
    13191    struct ifreq ifr;
     
    13393
    13494    s = get_ctl_fd();
    135     if (s < 0)
    136         return -1;
    137 
    13895    memset(&ifr, 0, sizeof(ifr));
    139     strcpy(ifr.ifr_name, dev);
     96    strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
    14097    ifr.ifr_mtu = mtu;
    141     if (ioctl(s, SIOCSIFMTU, &ifr) < 0) {
    142         perror("SIOCSIFMTU");
    143         close(s);
    144         return -1;
    145     }
    146     close(s);
    147 
    148     return 0;
    149 }
    150 
     98    xioctl(s, SIOCSIFMTU, &ifr);
     99    close(s);
     100}
     101
     102/* Exits on error */
    151103static int get_address(char *dev, int *htype)
    152104{
     
    156108    int s;
    157109
    158     s = socket(PF_PACKET, SOCK_DGRAM, 0);
    159     if (s < 0) {
    160         perror("socket(PF_PACKET)");
    161         return -1;
    162     }
     110    s = xsocket(PF_PACKET, SOCK_DGRAM, 0);
    163111
    164112    memset(&ifr, 0, sizeof(ifr));
    165     strcpy(ifr.ifr_name, dev);
    166     if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
    167         perror("SIOCGIFINDEX");
    168         close(s);
    169         return -1;
    170     }
     113    strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
     114    xioctl(s, SIOCGIFINDEX, &ifr);
    171115
    172116    memset(&me, 0, sizeof(me));
     
    174118    me.sll_ifindex = ifr.ifr_ifindex;
    175119    me.sll_protocol = htons(ETH_P_LOOP);
    176     if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) {
    177         perror("bind");
    178         close(s);
    179         return -1;
    180     }
     120    xbind(s, (struct sockaddr*)&me, sizeof(me));
    181121
    182122    alen = sizeof(me);
    183123    if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) {
    184         perror("getsockname");
    185         close(s);
    186         return -1;
     124        bb_perror_msg_and_die("getsockname");
    187125    }
    188126    close(s);
     
    191129}
    192130
    193 static int parse_address(char *dev, int hatype, int halen, char *lla, struct ifreq *ifr)
     131/* Exits on error */
     132static void parse_address(char *dev, int hatype, int halen, char *lla, struct ifreq *ifr)
    194133{
    195134    int alen;
    196135
    197136    memset(ifr, 0, sizeof(*ifr));
    198     strcpy(ifr->ifr_name, dev);
     137    strncpy(ifr->ifr_name, dev, sizeof(ifr->ifr_name));
    199138    ifr->ifr_hwaddr.sa_family = hatype;
    200139    alen = ll_addr_a2n((unsigned char *)(ifr->ifr_hwaddr.sa_data), 14, lla);
    201140    if (alen < 0)
    202         return -1;
     141        exit(1);
    203142    if (alen != halen) {
    204         bb_error_msg("Wrong address (%s) length: expected %d bytes", lla, halen);
    205         return -1;
    206     }
    207     return 0;
    208 }
    209 
    210 static int set_address(struct ifreq *ifr, int brd)
     143        bb_error_msg_and_die("wrong address (%s) length: expected %d bytes", lla, halen);
     144    }
     145}
     146
     147/* Exits on error */
     148static void set_address(struct ifreq *ifr, int brd)
    211149{
    212150    int s;
    213151
    214152    s = get_ctl_fd();
    215     if (s < 0)
    216         return -1;
    217     if (ioctl(s, brd?SIOCSIFHWBROADCAST:SIOCSIFHWADDR, ifr) < 0) {
    218         perror(brd?"SIOCSIFHWBROADCAST":"SIOCSIFHWADDR");
    219         close(s);
    220         return -1;
    221     }
    222     close(s);
    223     return 0;
    224 }
    225 
    226 
     153    if (brd)
     154        xioctl(s, SIOCSIFHWBROADCAST, ifr);
     155    else
     156        xioctl(s, SIOCSIFHWADDR, ifr);
     157    close(s);
     158}
     159
     160
     161/* Return value becomes exitcode. It's okay to not return at all */
    227162static int do_set(int argc, char **argv)
    228163{
    229164    char *dev = NULL;
    230     __u32 mask = 0;
    231     __u32 flags = 0;
     165    uint32_t mask = 0;
     166    uint32_t flags = 0;
    232167    int qlen = -1;
    233168    int mtu = -1;
     
    237172    char *newname = NULL;
    238173    int htype, halen;
     174    static const char keywords[] ALIGN1 =
     175        "up\0""down\0""name\0""mtu\0""multicast\0""arp\0""addr\0""dev\0"
     176        "on\0""off\0";
     177    enum { ARG_up = 1, ARG_down, ARG_name, ARG_mtu, ARG_multicast, ARG_arp,
     178        ARG_addr, ARG_dev, PARM_on, PARM_off };
     179    smalluint key;
    239180
    240181    while (argc > 0) {
    241         if (strcmp(*argv, "up") == 0) {
     182        key = index_in_strings(keywords, *argv) + 1;
     183        if (key == ARG_up) {
    242184            mask |= IFF_UP;
    243185            flags |= IFF_UP;
    244         } else if (strcmp(*argv, "down") == 0) {
     186        } else if (key == ARG_down) {
    245187            mask |= IFF_UP;
    246188            flags &= ~IFF_UP;
    247         } else if (strcmp(*argv, "name") == 0) {
     189        } else if (key == ARG_name) {
    248190            NEXT_ARG();
    249191            newname = *argv;
    250         } else if (strcmp(*argv, "mtu") == 0) {
     192        } else if (key == ARG_mtu) {
    251193            NEXT_ARG();
    252194            if (mtu != -1)
     
    254196            if (get_integer(&mtu, *argv, 0))
    255197                invarg(*argv, "mtu");
    256         } else if (strcmp(*argv, "multicast") == 0) {
     198        } else if (key == ARG_multicast) {
    257199            NEXT_ARG();
    258200            mask |= IFF_MULTICAST;
    259             if (strcmp(*argv, "on") == 0) {
     201            key = index_in_strings(keywords, *argv) + 1;
     202            if (key == PARM_on) {
    260203                flags |= IFF_MULTICAST;
    261             } else if (strcmp(*argv, "off") == 0) {
     204            } else if (key == PARM_off) {
    262205                flags &= ~IFF_MULTICAST;
    263206            } else
    264                 return on_off("multicast");
    265         } else if (strcmp(*argv, "arp") == 0) {
     207                on_off("multicast");
     208        } else if (key == ARG_arp) {
    266209            NEXT_ARG();
    267210            mask |= IFF_NOARP;
    268             if (strcmp(*argv, "on") == 0) {
     211            key = index_in_strings(keywords, *argv) + 1;
     212            if (key == PARM_on) {
    269213                flags &= ~IFF_NOARP;
    270             } else if (strcmp(*argv, "off") == 0) {
     214            } else if (key == PARM_off) {
    271215                flags |= IFF_NOARP;
    272216            } else
    273                 return on_off("noarp");
    274         } else if (strcmp(*argv, "addr") == 0) {
     217                on_off("arp");
     218        } else if (key == ARG_addr) {
    275219            NEXT_ARG();
    276220            newaddr = *argv;
    277221        } else {
    278             if (strcmp(*argv, "dev") == 0) {
     222            if (key == ARG_dev) {
    279223                NEXT_ARG();
    280224            }
     
    287231
    288232    if (!dev) {
    289         bb_error_msg(bb_msg_requires_arg, "\"dev\"");
    290         exit(-1);
     233        bb_error_msg_and_die(bb_msg_requires_arg, "\"dev\"");
    291234    }
    292235
    293236    if (newaddr || newbrd) {
    294237        halen = get_address(dev, &htype);
    295         if (halen < 0)
    296             return -1;
    297238        if (newaddr) {
    298             if (parse_address(dev, htype, halen, newaddr, &ifr0) < 0)
    299                 return -1;
     239            parse_address(dev, htype, halen, newaddr, &ifr0);
    300240        }
    301241        if (newbrd) {
    302             if (parse_address(dev, htype, halen, newbrd, &ifr1) < 0)
    303                 return -1;
     242            parse_address(dev, htype, halen, newbrd, &ifr1);
    304243        }
    305244    }
    306245
    307246    if (newname && strcmp(dev, newname)) {
    308         if (do_changename(dev, newname) < 0)
    309             return -1;
     247        do_changename(dev, newname);
    310248        dev = newname;
    311249    }
    312250    if (qlen != -1) {
    313         if (set_qlen(dev, qlen) < 0)
    314             return -1;
     251        set_qlen(dev, qlen);
    315252    }
    316253    if (mtu != -1) {
    317         if (set_mtu(dev, mtu) < 0)
    318             return -1;
     254        set_mtu(dev, mtu);
    319255    }
    320256    if (newaddr || newbrd) {
    321257        if (newbrd) {
    322             if (set_address(&ifr1, 1) < 0)
    323                 return -1;
     258            set_address(&ifr1, 1);
    324259        }
    325260        if (newaddr) {
    326             if (set_address(&ifr0, 0) < 0)
    327                 return -1;
     261            set_address(&ifr0, 0);
    328262        }
    329263    }
    330264    if (mask)
    331         return do_chflags(dev, flags, mask);
     265        do_chflags(dev, flags, mask);
    332266    return 0;
    333267}
     
    336270{
    337271    preferred_family = AF_PACKET;
    338     do_link = 1;
    339272    return ipaddr_list_or_flush(argc, argv, 0);
    340273}
    341274
     275/* Return value becomes exitcode. It's okay to not return at all */
    342276int do_iplink(int argc, char **argv)
    343277{
    344     if (argc > 0) {
    345         if (matches(*argv, "set") == 0)
    346             return do_set(argc-1, argv+1);
    347         if (matches(*argv, "show") == 0 ||
    348             matches(*argv, "lst") == 0 ||
    349             matches(*argv, "list") == 0)
    350             return ipaddr_list_link(argc-1, argv+1);
    351     } else
     278    static const char keywords[] ALIGN1 =
     279        "set\0""show\0""lst\0""list\0";
     280    smalluint key;
     281    if (argc <= 0)
    352282        return ipaddr_list_link(0, NULL);
    353 
    354     bb_error_msg("Command \"%s\" is unknown.", *argv);
    355     exit(-1);
    356 }
     283    key = index_in_substrings(keywords, *argv) + 1;
     284    if (key == 0)
     285        bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
     286    argc--; argv++;
     287    if (key == 1) /* set */
     288        return do_set(argc, argv);
     289    else /* show, lst, list */
     290        return ipaddr_list_link(argc, argv);
     291}
  • branches/stable/mindi-busybox/networking/libiproute/iproute.c

    r821 r1770  
    1414 */
    1515
    16 #include "libbb.h"
    17 
    18 #include <sys/socket.h>
    19 
    20 #include <string.h>
    21 #include <fcntl.h>
    22 #include <unistd.h>
    23 
     16#include "ip_common.h"  /* #include "libbb.h" is inside */
    2417#include "rt_names.h"
    2518#include "utils.h"
    26 #include "ip_common.h"
    2719
    2820#ifndef RTAX_RTTVAR
     
    3123
    3224
    33 static struct
    34 {
     25typedef struct filter_t {
    3526    int tb;
    3627    int flushed;
     
    5243    inet_prefix rsrc;
    5344    inet_prefix msrc;
    54 } filter;
     45} filter_t;
     46
     47#define filter (*(filter_t*)&bb_common_bufsiz1)
    5548
    5649static int flush_update(void)
    5750{
    5851    if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) {
    59         perror("Failed to send flush request\n");
     52        bb_perror_msg("failed to send flush request");
    6053        return -1;
    6154    }
    6255    filter.flushp = 0;
    6356    return 0;
     57}
     58
     59static unsigned get_hz(void)
     60{
     61    static unsigned hz_internal;
     62    FILE *fp;
     63
     64    if (hz_internal)
     65        return hz_internal;
     66
     67    fp = fopen("/proc/net/psched", "r");
     68    if (fp) {
     69        unsigned nom, denom;
     70
     71        if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2)
     72            if (nom == 1000000)
     73                hz_internal = denom;
     74        fclose(fp);
     75    }
     76    if (!hz_internal)
     77        hz_internal = sysconf(_SC_CLK_TCK);
     78    return hz_internal;
    6479}
    6580
     
    86101        return 0;
    87102    len -= NLMSG_LENGTH(sizeof(*r));
    88     if (len < 0) {
    89         bb_error_msg("wrong nlmsg len %d", len);
    90         return -1;
    91     }
     103    if (len < 0)
     104        bb_error_msg_and_die("wrong nlmsg len %d", len);
    92105
    93106    if (r->rtm_family == AF_INET6)
     
    170183        if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
    171184            if (flush_update())
    172                 return -1;
     185                bb_error_msg_and_die("flush");
    173186        }
    174187        fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp));
     
    249262    }
    250263    if (tb[RTA_PRIORITY]) {
    251         fprintf(fp, " metric %d ", *(__u32*)RTA_DATA(tb[RTA_PRIORITY]));
     264        fprintf(fp, " metric %d ", *(uint32_t*)RTA_DATA(tb[RTA_PRIORITY]));
    252265    }
    253266    if (r->rtm_family == AF_INET6) {
     
    257270        }
    258271        if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) {
    259             static int hz;
    260             if (!hz) {
    261                 hz = get_hz();
    262             }
    263272            if (r->rtm_flags & RTM_F_CLONED) {
    264                 fprintf(fp, "%s    cache ", _SL_);
     273                fprintf(fp, "%c    cache ", _SL_);
    265274            }
    266275            if (ci->rta_expires) {
    267                 fprintf(fp, " expires %dsec", ci->rta_expires/hz);
     276                fprintf(fp, " expires %dsec", ci->rta_expires / get_hz());
    268277            }
    269278            if (ci->rta_error != 0) {
     
    278287        fprintf(fp, " iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF])));
    279288    }
    280     fprintf(fp, "\n");
     289    fputc('\n', fp);
    281290    fflush(fp);
    282291    return 0;
    283292}
    284293
     294/* Return value becomes exitcode. It's okay to not return at all */
    285295static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
    286296{
     297    static const char keywords[] ALIGN1 =
     298        "src\0""via\0""mtu\0""lock\0""protocol\0"USE_FEATURE_IP_RULE("table\0")
     299        "dev\0""oif\0""to\0";
     300    enum {
     301        ARG_src,
     302        ARG_via,
     303        ARG_mtu, PARM_lock,
     304        ARG_protocol,
     305USE_FEATURE_IP_RULE(ARG_table,)
     306        ARG_dev,
     307        ARG_oif,
     308        ARG_to
     309    };
     310    enum {
     311        gw_ok = 1 << 0,
     312        dst_ok = 1 << 1,
     313        proto_ok = 1 << 2,
     314        type_ok = 1 << 3
     315    };
    287316    struct rtnl_handle rth;
    288317    struct {
     
    291320        char            buf[1024];
    292321    } req;
    293     char  mxbuf[256];
     322    char mxbuf[256];
    294323    struct rtattr * mxrta = (void*)mxbuf;
    295324    unsigned mxlock = 0;
    296     char  *d = NULL;
    297     int gw_ok = 0;
    298     int dst_ok = 0;
    299     int proto_ok = 0;
    300     int type_ok = 0;
     325    char *d = NULL;
     326    smalluint ok = 0;
     327    int arg;
    301328
    302329    memset(&req, 0, sizeof(req));
     
    319346
    320347    while (argc > 0) {
    321         if (strcmp(*argv, "src") == 0) {
     348        arg = index_in_substrings(keywords, *argv);
     349        if (arg == ARG_src) {
    322350            inet_prefix addr;
     351            NEXT_ARG();
     352            get_addr(&addr, *argv, req.r.rtm_family);
     353            if (req.r.rtm_family == AF_UNSPEC)
     354                req.r.rtm_family = addr.family;
     355            addattr_l(&req.n, sizeof(req), RTA_PREFSRC, &addr.data, addr.bytelen);
     356        } else if (arg == ARG_via) {
     357            inet_prefix addr;
     358            ok |= gw_ok;
    323359            NEXT_ARG();
    324360            get_addr(&addr, *argv, req.r.rtm_family);
     
    326362                req.r.rtm_family = addr.family;
    327363            }
    328             addattr_l(&req.n, sizeof(req), RTA_PREFSRC, &addr.data, addr.bytelen);
    329         } else if (strcmp(*argv, "via") == 0) {
    330             inet_prefix addr;
    331             gw_ok = 1;
    332             NEXT_ARG();
    333             get_addr(&addr, *argv, req.r.rtm_family);
    334             if (req.r.rtm_family == AF_UNSPEC) {
    335                 req.r.rtm_family = addr.family;
    336             }
    337364            addattr_l(&req.n, sizeof(req), RTA_GATEWAY, &addr.data, addr.bytelen);
    338         } else if (strcmp(*argv, "mtu") == 0) {
     365        } else if (arg == ARG_mtu) {
    339366            unsigned mtu;
    340367            NEXT_ARG();
    341             if (strcmp(*argv, "lock") == 0) {
     368            if (index_in_strings(keywords, *argv) == PARM_lock) {
    342369                mxlock |= (1<<RTAX_MTU);
    343370                NEXT_ARG();
    344371            }
    345             if (get_unsigned(&mtu, *argv, 0)) {
     372            if (get_unsigned(&mtu, *argv, 0))
    346373                invarg(*argv, "mtu");
    347             }
    348374            rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu);
    349         } else if (matches(*argv, "protocol") == 0) {
     375        } else if (arg == ARG_protocol) {
    350376            uint32_t prot;
    351377            NEXT_ARG();
     
    353379                invarg(*argv, "protocol");
    354380            req.r.rtm_protocol = prot;
    355             proto_ok =1;
    356         } else if (strcmp(*argv, "dev") == 0 ||
    357                strcmp(*argv, "oif") == 0) {
     381            ok |= proto_ok;
     382#if ENABLE_FEATURE_IP_RULE
     383        } else if (arg == ARG_table) {
     384            uint32_t tid;
     385            NEXT_ARG();
     386            if (rtnl_rttable_a2n(&tid, *argv))
     387                invarg(*argv, "table");
     388            req.r.rtm_table = tid;
     389#endif
     390        } else if (arg == ARG_dev || arg == ARG_oif) {
    358391            NEXT_ARG();
    359392            d = *argv;
     
    362395            inet_prefix dst;
    363396
    364             if (strcmp(*argv, "to") == 0) {
    365                 NEXT_ARG();
    366             }
    367             if ((**argv < '0' || **argv > '9') &&
    368                 rtnl_rtntype_a2n(&type, *argv) == 0) {
     397            if (arg == ARG_to) {
     398                NEXT_ARG();
     399            }
     400            if ((**argv < '0' || **argv > '9')
     401                && rtnl_rtntype_a2n(&type, *argv) == 0) {
    369402                NEXT_ARG();
    370403                req.r.rtm_type = type;
    371                 type_ok = 1;
    372             }
    373 
    374             if (dst_ok) {
     404                ok |= type_ok;
     405            }
     406
     407            if (ok & dst_ok) {
    375408                duparg2("to", *argv);
    376409            }
     
    380413            }
    381414            req.r.rtm_dst_len = dst.bitlen;
    382             dst_ok = 1;
     415            ok |= dst_ok;
    383416            if (dst.bytelen) {
    384417                addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen);
     
    388421    }
    389422
    390     if (rtnl_open(&rth, 0) < 0) {
    391         exit(1);
    392     }
     423    xrtnl_open(&rth);
    393424
    394425    if (d)  {
     
    398429
    399430        if (d) {
    400             if ((idx = ll_name_to_index(d)) == 0) {
    401                 bb_error_msg("Cannot find device \"%s\"", d);
    402                 return -1;
    403             }
     431            idx = xll_name_to_index(d);
    404432            addattr32(&req.n, sizeof(req), RTA_OIF, idx);
    405433        }
     
    413441    }
    414442
     443    if (req.r.rtm_type == RTN_LOCAL || req.r.rtm_type == RTN_NAT)
     444        req.r.rtm_scope = RT_SCOPE_HOST;
     445    else if (req.r.rtm_type == RTN_BROADCAST ||
     446            req.r.rtm_type == RTN_MULTICAST ||
     447            req.r.rtm_type == RTN_ANYCAST)
     448        req.r.rtm_scope = RT_SCOPE_LINK;
     449    else if (req.r.rtm_type == RTN_UNICAST || req.r.rtm_type == RTN_UNSPEC) {
     450        if (cmd == RTM_DELROUTE)
     451            req.r.rtm_scope = RT_SCOPE_NOWHERE;
     452        else if (!(ok & gw_ok))
     453            req.r.rtm_scope = RT_SCOPE_LINK;
     454    }
     455
    415456    if (req.r.rtm_family == AF_UNSPEC) {
    416457        req.r.rtm_family = AF_INET;
     
    418459
    419460    if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) {
    420         exit(2);
     461        return 2;
    421462    }
    422463
     
    444485    req.rtm.rtm_flags |= RTM_F_CLONED;
    445486
    446     return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr));
    447 }
    448 
    449 static int iproute_flush_cache(void)
    450 {
    451 #define ROUTE_FLUSH_PATH "/proc/sys/net/ipv4/route/flush"
    452 
    453     int len;
    454     int flush_fd = open (ROUTE_FLUSH_PATH, O_WRONLY);
    455     char *buffer = "-1";
     487    return xsendto(rth->fd, (void*)&req, sizeof(req), (struct sockaddr*)&nladdr, sizeof(nladdr));
     488}
     489
     490static void iproute_flush_cache(void)
     491{
     492    static const char fn[] ALIGN1 = "/proc/sys/net/ipv4/route/flush";
     493    int flush_fd = open_or_warn(fn, O_WRONLY);
    456494
    457495    if (flush_fd < 0) {
    458         fprintf (stderr, "Cannot open \"%s\"\n", ROUTE_FLUSH_PATH);
    459         return -1;
    460     }
    461 
    462     len = strlen (buffer);
    463 
    464     if ((write (flush_fd, (void *)buffer, len)) < len) {
    465         fprintf (stderr, "Cannot flush routing cache\n");
    466         return -1;
     496        return;
     497    }
     498
     499    if (write(flush_fd, "-1", 2) < 2) {
     500        bb_perror_msg("cannot flush routing cache");
     501        return;
    467502    }
    468503    close(flush_fd);
    469     return 0;
    470504}
    471505
     
    477511}
    478512
     513/* Return value becomes exitcode. It's okay to not return at all */
    479514static int iproute_list_or_flush(int argc, char **argv, int flush)
    480515{
     
    483518    char *id = NULL;
    484519    char *od = NULL;
    485 
     520    static const char keywords[] ALIGN1 =
     521        "protocol\0""all\0""dev\0""oif\0""iif\0""via\0""table\0""cache\0" /*all*/
     522        "from\0""root\0""match\0""exact\0""to\0"/*root match exact*/;
     523    enum {
     524        ARG_proto, PARM_all,
     525        ARG_dev,
     526        ARG_oif,
     527        ARG_iif,
     528        ARG_via,
     529        ARG_table, PARM_cache, /*PARM_all,*/
     530        ARG_from, PARM_root, PARM_match, PARM_exact,
     531        ARG_to  /*PARM_root, PARM_match, PARM_exact*/
     532    };
     533    int arg, parm;
    486534    iproute_reset_filter();
    487535    filter.tb = RT_TABLE_MAIN;
    488536
    489     if (flush && argc <= 0) {
    490         bb_error_msg(bb_msg_requires_arg, "\"ip route flush\"");
    491         return -1;
    492     }
     537    if (flush && argc <= 0)
     538        bb_error_msg_and_die(bb_msg_requires_arg, "\"ip route flush\"");
    493539
    494540    while (argc > 0) {
    495         if (matches(*argv, "protocol") == 0) {
     541        arg = index_in_substrings(keywords, *argv);
     542        if (arg == ARG_proto) {
    496543            uint32_t prot = 0;
    497544            NEXT_ARG();
    498545            filter.protocolmask = -1;
    499546            if (rtnl_rtprot_a2n(&prot, *argv)) {
    500                 if (strcmp(*argv, "all") != 0) {
     547                if (index_in_strings(keywords, *argv) != PARM_all)
    501548                    invarg(*argv, "protocol");
    502                 }
    503549                prot = 0;
    504550                filter.protocolmask = 0;
    505551            }
    506552            filter.protocol = prot;
    507         } else if (strcmp(*argv, "dev") == 0 ||
    508                strcmp(*argv, "oif") == 0) {
     553        } else if (arg == ARG_dev || arg == ARG_oif) {
    509554            NEXT_ARG();
    510555            od = *argv;
    511         } else if (strcmp(*argv, "iif") == 0) {
     556        } else if (arg == ARG_iif) {
    512557            NEXT_ARG();
    513558            id = *argv;
    514         } else if (matches(*argv, "from") == 0) {
    515             NEXT_ARG();
    516             if (matches(*argv, "root") == 0) {
     559        } else if (arg == ARG_via) {
     560            NEXT_ARG();
     561            get_prefix(&filter.rvia, *argv, do_ipv6);
     562        } else if (arg == ARG_table) {
     563            NEXT_ARG();
     564            parm = index_in_substrings(keywords, *argv);
     565            if (parm == PARM_cache)
     566                filter.tb = -1;
     567            else if (parm == PARM_all)
     568                filter.tb = 0;
     569            else
     570                invarg(*argv, "table");
     571        } else if (arg == ARG_from) {
     572            NEXT_ARG();
     573            parm = index_in_substrings(keywords, *argv);
     574            if (parm == PARM_root) {
    517575                NEXT_ARG();
    518576                get_prefix(&filter.rsrc, *argv, do_ipv6);
    519             } else if (matches(*argv, "match") == 0) {
     577            } else if (parm == PARM_match) {
    520578                NEXT_ARG();
    521579                get_prefix(&filter.msrc, *argv, do_ipv6);
    522580            } else {
    523                 if (matches(*argv, "exact") == 0) {
     581                if (parm == PARM_exact)
    524582                    NEXT_ARG();
    525                 }
    526583                get_prefix(&filter.msrc, *argv, do_ipv6);
    527584                filter.rsrc = filter.msrc;
    528585            }
    529586        } else {
    530             if (matches(*argv, "to") == 0) {
    531                 NEXT_ARG();
    532             }
    533             if (matches(*argv, "root") == 0) {
     587            /* parm = arg; // would be more plausible, we reuse arg here */
     588            if (arg == ARG_to) {
     589                NEXT_ARG();
     590                arg = index_in_substrings(keywords, *argv);
     591            }
     592            if (arg == PARM_root) {
    534593                NEXT_ARG();
    535594                get_prefix(&filter.rdst, *argv, do_ipv6);
    536             } else if (matches(*argv, "match") == 0) {
     595            } else if (arg == PARM_match) {
    537596                NEXT_ARG();
    538597                get_prefix(&filter.mdst, *argv, do_ipv6);
    539             } else if (matches(*argv, "table") == 0) {
    540                 NEXT_ARG();
    541                 if (matches(*argv, "cache") == 0) {
    542                     filter.tb = -1;
    543                 } else if (matches(*argv, "main") != 0) {
    544                     invarg(*argv, "table");
    545                 }
    546             } else if (matches(*argv, "cache") == 0) {
    547                 filter.tb = -1;
    548598            } else {
    549                 if (matches(*argv, "exact") == 0) {
     599                if (arg == PARM_exact)
    550600                    NEXT_ARG();
    551                 }
    552601                get_prefix(&filter.mdst, *argv, do_ipv6);
    553602                filter.rdst = filter.mdst;
    554603            }
    555604        }
    556         argc--; argv++;
     605        argc--;
     606        argv++;
    557607    }
    558608
     
    561611    }
    562612
    563     if (rtnl_open(&rth, 0) < 0) {
    564         exit(1);
    565     }
     613    xrtnl_open(&rth);
    566614
    567615    ll_init_map(&rth);
     
    571619
    572620        if (id) {
    573             if ((idx = ll_name_to_index(id)) == 0) {
    574                 bb_error_msg("Cannot find device \"%s\"", id);
    575                 return -1;
    576             }
     621            idx = xll_name_to_index(id);
    577622            filter.iif = idx;
    578623            filter.iifmask = -1;
    579624        }
    580625        if (od) {
    581             if ((idx = ll_name_to_index(od)) == 0) {
    582                 bb_error_msg("Cannot find device \"%s\"", od);
    583             }
     626            idx = xll_name_to_index(od);
    584627            filter.oif = idx;
    585628            filter.oifmask = -1;
     
    603646
    604647        for (;;) {
    605             if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) {
    606                 perror("Cannot send dump request");
    607                 return -1;
    608             }
     648            xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
    609649            filter.flushed = 0;
    610             if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) {
    611                 bb_error_msg("Flush terminated\n");
    612                 return -1;
    613             }
    614             if (filter.flushed == 0) {
    615                 fflush(stdout);
     650            xrtnl_dump_filter(&rth, print_route, stdout);
     651            if (filter.flushed == 0)
    616652                return 0;
    617             }
    618             if (flush_update() < 0)
    619                 exit(1);
     653            if (flush_update())
     654                return 1;
    620655        }
    621656    }
    622657
    623658    if (filter.tb != -1) {
    624         if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) {
    625             bb_perror_msg_and_die("Cannot send dump request");
    626         }
    627     } else {
    628         if (rtnl_rtcache_request(&rth, do_ipv6) < 0) {
    629             bb_perror_msg_and_die("Cannot send dump request");
    630         }
    631     }
    632 
    633     if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) {
    634         bb_error_msg_and_die("Dump terminated");
    635     }
    636 
    637     exit(0);
    638 }
    639 
    640 
     659        xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
     660    } else if (rtnl_rtcache_request(&rth, do_ipv6) < 0) {
     661        bb_perror_msg_and_die("cannot send dump request");
     662    }
     663    xrtnl_dump_filter(&rth, print_route, stdout);
     664
     665    return 0;
     666}
     667
     668
     669/* Return value becomes exitcode. It's okay to not return at all */
    641670static int iproute_get(int argc, char **argv)
    642671{
    643672    struct rtnl_handle rth;
    644673    struct {
    645         struct nlmsghdr     n;
    646         struct rtmsg        r;
    647         char            buf[1024];
     674        struct nlmsghdr n;
     675        struct rtmsg    r;
     676        char            buf[1024];
    648677    } req;
    649     char  *idev = NULL;
    650     char  *odev = NULL;
    651     int connected = 0;
    652     int from_ok = 0;
    653     static const char * const options[] =
    654         { "from", "iif", "oif", "dev", "notify", "connected", "to", 0 };
     678    char *idev = NULL;
     679    char *odev = NULL;
     680    bool connected = 0;
     681    bool from_ok = 0;
     682    static const char options[] ALIGN1 =
     683        "from\0""iif\0""oif\0""dev\0""notify\0""connected\0""to\0";
    655684
    656685    memset(&req, 0, sizeof(req));
     
    671700
    672701    while (argc > 0) {
    673         switch (compare_string_array(options, *argv)) {
     702        switch (index_in_strings(options, *argv)) {
    674703            case 0: /* from */
    675704            {
     
    724753    }
    725754
    726     if (rtnl_open(&rth, 0) < 0)
    727         exit(1);
     755    xrtnl_open(&rth);
    728756
    729757    ll_init_map(&rth);
     
    733761
    734762        if (idev) {
    735             if ((idx = ll_name_to_index(idev)) == 0) {
    736                 bb_error_msg("Cannot find device \"%s\"", idev);
    737                 return -1;
    738             }
     763            idx = xll_name_to_index(idev);
    739764            addattr32(&req.n, sizeof(req), RTA_IIF, idx);
    740765        }
    741766        if (odev) {
    742             if ((idx = ll_name_to_index(odev)) == 0) {
    743                 bb_error_msg("Cannot find device \"%s\"", odev);
    744                 return -1;
    745             }
     767            idx = xll_name_to_index(odev);
    746768            addattr32(&req.n, sizeof(req), RTA_OIF, idx);
    747769        }
     
    753775
    754776    if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) {
    755         exit(2);
     777        return 2;
    756778    }
    757779
     
    761783        struct rtattr * tb[RTA_MAX+1];
    762784
    763         if (print_route(NULL, &req.n, (void*)stdout) < 0) {
    764             bb_error_msg_and_die("An error :-)");
    765         }
     785        print_route(NULL, &req.n, (void*)stdout);
    766786
    767787        if (req.n.nlmsg_type != RTM_NEWROUTE) {
    768             bb_error_msg("Not a route?");
    769             return -1;
     788            bb_error_msg_and_die("not a route?");
    770789        }
    771790        len -= NLMSG_LENGTH(sizeof(*r));
    772791        if (len < 0) {
    773             bb_error_msg("Wrong len %d", len);
    774             return -1;
     792            bb_error_msg_and_die("wrong len %d", len);
    775793        }
    776794
     
    782800            r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]);
    783801        } else if (!tb[RTA_SRC]) {
    784             bb_error_msg("Failed to connect the route");
    785             return -1;
     802            bb_error_msg_and_die("failed to connect the route");
    786803        }
    787804        if (!odev && tb[RTA_OIF]) {
     
    798815
    799816        if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) {
    800             exit(2);
    801         }
    802     }
    803 
    804     if (print_route(NULL, &req.n, (void*)stdout) < 0) {
    805         bb_error_msg_and_die("An error :-)");
    806     }
    807 
    808     exit(0);
    809 }
    810 
     817            return 2;
     818        }
     819    }
     820    print_route(NULL, &req.n, (void*)stdout);
     821    return 0;
     822}
     823
     824/* Return value becomes exitcode. It's okay to not return at all */
    811825int do_iproute(int argc, char **argv)
    812826{
    813     static const char * const ip_route_commands[] =
    814         { "add", "append", "change", "chg", "delete", "del", "get",
    815         "list", "show", "prepend", "replace", "test", "flush", 0 };
    816     int command_num = 7;
    817     unsigned int flags = 0;
     827    static const char ip_route_commands[] ALIGN1 =
     828    /*0-3*/ "add\0""append\0""change\0""chg\0"
     829    /*4-7*/ "delete\0""get\0""list\0""show\0"
     830    /*8..*/ "prepend\0""replace\0""test\0""flush\0";
     831    int command_num = 6;
     832    unsigned flags = 0;
    818833    int cmd = RTM_NEWROUTE;
    819834
     835    /* "Standard" 'ip r a' treats 'a' as 'add', not 'append' */
     836    /* It probably means that it is using "first match" rule */
    820837    if (*argv) {
    821         command_num = compare_string_array(ip_route_commands, *argv);
    822     }
    823     switch(command_num) {
    824         case 0: /* add*/
     838        command_num = index_in_substrings(ip_route_commands, *argv);
     839    }
     840    switch (command_num) {
     841        case 0: /* add */
    825842            flags = NLM_F_CREATE|NLM_F_EXCL;
    826843            break;
     
    833850            break;
    834851        case 4: /* delete */
    835         case 5: /* del */
    836852            cmd = RTM_DELROUTE;
    837853            break;
    838         case 6: /* get */
     854        case 5: /* get */
    839855            return iproute_get(argc-1, argv+1);
    840         case 7: /* list */
    841         case 8: /* show */
     856        case 6: /* list */
     857        case 7: /* show */
    842858            return iproute_list_or_flush(argc-1, argv+1, 0);
    843         case 9: /* prepend */
     859        case 8: /* prepend */
    844860            flags = NLM_F_CREATE;
    845         case 10: /* replace */
     861        case 9: /* replace */
    846862            flags = NLM_F_CREATE|NLM_F_REPLACE;
    847         case 11: /* test */
     863        case 10: /* test */
    848864            flags = NLM_F_EXCL;
    849         case 12: /* flush */
     865        case 11: /* flush */
    850866            return iproute_list_or_flush(argc-1, argv+1, 1);
    851867        default:
    852             bb_error_msg_and_die("Unknown command %s", *argv);
     868            bb_error_msg_and_die("unknown command %s", *argv);
    853869    }
    854870
  • branches/stable/mindi-busybox/networking/libiproute/iptunnel.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * iptunnel.c          "ip tunnel"
     
    1415 */
    1516
    16 #include "libbb.h"
    17 #include <sys/socket.h>
    18 #include <sys/ioctl.h>
    19 
    20 #include <string.h>
    21 #include <unistd.h>
    22 
    2317#include <netinet/ip.h>
    24 
    2518#include <net/if.h>
    2619#include <net/if_arp.h>
    27 
    2820#include <asm/types.h>
    2921#ifndef __constant_htons
     
    3224#include <linux/if_tunnel.h>
    3325
     26#include "ip_common.h"  /* #include "libbb.h" is inside */
    3427#include "rt_names.h"
    3528#include "utils.h"
    36 #include "ip_common.h"
    37 
    38 
     29
     30
     31/* Dies on error */
    3932static int do_ioctl_get_ifindex(char *dev)
    4033{
     
    4235    int fd;
    4336
    44     strcpy(ifr.ifr_name, dev);
    45     fd = socket(AF_INET, SOCK_DGRAM, 0);
    46     if (ioctl(fd, SIOCGIFINDEX, &ifr)) {
    47         bb_perror_msg("ioctl");
    48         return 0;
    49     }
     37    strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
     38    fd = xsocket(AF_INET, SOCK_DGRAM, 0);
     39    xioctl(fd, SIOCGIFINDEX, &ifr);
    5040    close(fd);
    5141    return ifr.ifr_ifindex;
     
    5343
    5444static int do_ioctl_get_iftype(char *dev)
    55 {
    56     struct ifreq ifr;
    57     int fd;
    58 
    59     strcpy(ifr.ifr_name, dev);
    60     fd = socket(AF_INET, SOCK_DGRAM, 0);
    61     if (ioctl(fd, SIOCGIFHWADDR, &ifr)) {
    62         bb_perror_msg("ioctl");
    63         return -1;
    64     }
    65     close(fd);
    66     return ifr.ifr_addr.sa_family;
    67 }
    68 
    69 
    70 static char *do_ioctl_get_ifname(int idx)
    71 {
    72     static struct ifreq ifr;
    73     int fd;
    74 
    75     ifr.ifr_ifindex = idx;
    76     fd = socket(AF_INET, SOCK_DGRAM, 0);
    77     if (ioctl(fd, SIOCGIFNAME, &ifr)) {
    78         bb_perror_msg("ioctl");
    79         return NULL;
    80     }
    81     close(fd);
    82     return ifr.ifr_name;
    83 }
    84 
    85 
    86 
    87 static int do_get_ioctl(char *basedev, struct ip_tunnel_parm *p)
    8845{
    8946    struct ifreq ifr;
     
    9148    int err;
    9249
    93     strcpy(ifr.ifr_name, basedev);
    94     ifr.ifr_ifru.ifru_data = (void*)p;
    95     fd = socket(AF_INET, SOCK_DGRAM, 0);
    96     err = ioctl(fd, SIOCGETTUNNEL, &ifr);
    97     if (err) {
    98         bb_perror_msg("ioctl");
    99     }
     50    strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
     51    fd = xsocket(AF_INET, SOCK_DGRAM, 0);
     52    err = ioctl_or_warn(fd, SIOCGIFHWADDR, &ifr);
    10053    close(fd);
    101     return err;
    102 }
    103 
    104 static int do_add_ioctl(int cmd, char *basedev, struct ip_tunnel_parm *p)
     54    return err ? -1 : ifr.ifr_addr.sa_family;
     55}
     56
     57static char *do_ioctl_get_ifname(int idx)
    10558{
    10659    struct ifreq ifr;
     
    10861    int err;
    10962
    110     if (cmd == SIOCCHGTUNNEL && p->name[0]) {
    111         strcpy(ifr.ifr_name, p->name);
    112     } else {
    113         strcpy(ifr.ifr_name, basedev);
    114     }
    115     ifr.ifr_ifru.ifru_data = (void*)p;
    116     fd = socket(AF_INET, SOCK_DGRAM, 0);
    117     err = ioctl(fd, cmd, &ifr);
    118     if (err) {
    119         bb_perror_msg("ioctl");
    120     }
     63    ifr.ifr_ifindex = idx;
     64    fd = xsocket(AF_INET, SOCK_DGRAM, 0);
     65    err = ioctl_or_warn(fd, SIOCGIFNAME, &ifr);
    12166    close(fd);
    122     return err;
    123 }
    124 
    125 static int do_del_ioctl(char *basedev, struct ip_tunnel_parm *p)
     67    return err ? NULL : xstrndup(ifr.ifr_name, sizeof(ifr.ifr_name));
     68}
     69
     70static int do_get_ioctl(const char *basedev, struct ip_tunnel_parm *p)
    12671{
    12772    struct ifreq ifr;
     
    12974    int err;
    13075
    131     if (p->name[0]) {
    132         strcpy(ifr.ifr_name, p->name);
    133     } else {
    134         strcpy(ifr.ifr_name, basedev);
    135     }
     76    strncpy(ifr.ifr_name, basedev, sizeof(ifr.ifr_name));
    13677    ifr.ifr_ifru.ifru_data = (void*)p;
    137     fd = socket(AF_INET, SOCK_DGRAM, 0);
    138     err = ioctl(fd, SIOCDELTUNNEL, &ifr);
    139     if (err) {
    140         bb_perror_msg("ioctl");
    141     }
     78    fd = xsocket(AF_INET, SOCK_DGRAM, 0);
     79    err = ioctl_or_warn(fd, SIOCGETTUNNEL, &ifr);
    14280    close(fd);
    14381    return err;
    14482}
    14583
    146 static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
    147 {
     84/* Dies on error, otherwise returns 0 */
     85static int do_add_ioctl(int cmd, const char *basedev, struct ip_tunnel_parm *p)
     86{
     87    struct ifreq ifr;
     88    int fd;
     89
     90    if (cmd == SIOCCHGTUNNEL && p->name[0]) {
     91        strncpy(ifr.ifr_name, p->name, sizeof(ifr.ifr_name));
     92    } else {
     93        strncpy(ifr.ifr_name, basedev, sizeof(ifr.ifr_name));
     94    }
     95    ifr.ifr_ifru.ifru_data = (void*)p;
     96    fd = xsocket(AF_INET, SOCK_DGRAM, 0);
     97#if ENABLE_IOCTL_HEX2STR_ERROR
     98    /* #define magic will turn ioctl# into string */
     99    if (cmd == SIOCCHGTUNNEL)
     100        xioctl(fd, SIOCCHGTUNNEL, &ifr);
     101    else
     102        xioctl(fd, SIOCADDTUNNEL, &ifr);
     103#else
     104    xioctl(fd, cmd, &ifr);
     105#endif
     106    close(fd);
     107    return 0;
     108}
     109
     110/* Dies on error, otherwise returns 0 */
     111static int do_del_ioctl(const char *basedev, struct ip_tunnel_parm *p)
     112{
     113    struct ifreq ifr;
     114    int fd;
     115
     116    if (p->name[0]) {
     117        strncpy(ifr.ifr_name, p->name, sizeof(ifr.ifr_name));
     118    } else {
     119        strncpy(ifr.ifr_name, basedev, sizeof(ifr.ifr_name));
     120    }
     121    ifr.ifr_ifru.ifru_data = (void*)p;
     122    fd = xsocket(AF_INET, SOCK_DGRAM, 0);
     123    xioctl(fd, SIOCDELTUNNEL, &ifr);
     124    close(fd);
     125    return 0;
     126}
     127
     128/* Dies on error */
     129static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
     130{
     131    static const char keywords[] ALIGN1 =
     132        "mode\0""ipip\0""ip/ip\0""gre\0""gre/ip\0""sit\0""ipv6/ip\0"
     133        "key\0""ikey\0""okey\0""seq\0""iseq\0""oseq\0"
     134        "csum\0""icsum\0""ocsum\0""nopmtudisc\0""pmtudisc\0"
     135        "remote\0""any\0""local\0""dev\0"
     136        "ttl\0""inherit\0""tos\0""dsfield\0"
     137        "name\0";
     138    enum {
     139        ARG_mode, ARG_ipip, ARG_ip_ip, ARG_gre, ARG_gre_ip, ARG_sit, ARG_ip6_ip,
     140        ARG_key, ARG_ikey, ARG_okey, ARG_seq, ARG_iseq, ARG_oseq,
     141        ARG_csum, ARG_icsum, ARG_ocsum, ARG_nopmtudisc, ARG_pmtudisc,
     142        ARG_remote, ARG_any, ARG_local, ARG_dev,
     143        ARG_ttl, ARG_inherit, ARG_tos, ARG_dsfield,
     144        ARG_name
     145    };
    148146    int count = 0;
    149147    char medium[IFNAMSIZ];
     148    int key;
     149
    150150    memset(p, 0, sizeof(*p));
    151151    memset(&medium, 0, sizeof(medium));
     
    154154    p->iph.ihl = 5;
    155155#ifndef IP_DF
    156 #define IP_DF       0x4000      /* Flag: "Don't Fragment"   */
     156#define IP_DF 0x4000  /* Flag: "Don't Fragment" */
    157157#endif
    158158    p->iph.frag_off = htons(IP_DF);
    159159
    160160    while (argc > 0) {
    161         if (strcmp(*argv, "mode") == 0) {
    162             NEXT_ARG();
    163             if (strcmp(*argv, "ipip") == 0 ||
    164                 strcmp(*argv, "ip/ip") == 0) {
     161        key = index_in_strings(keywords, *argv);
     162        if (key == ARG_mode) {
     163            NEXT_ARG();
     164            key = index_in_strings(keywords, *argv);
     165            if (key == ARG_ipip ||
     166                key == ARG_ip_ip) {
    165167                if (p->iph.protocol && p->iph.protocol != IPPROTO_IPIP) {
    166                     bb_error_msg("You managed to ask for more than one tunnel mode.");
    167                     exit(-1);
     168                    bb_error_msg_and_die("you managed to ask for more than one tunnel mode");
    168169                }
    169170                p->iph.protocol = IPPROTO_IPIP;
    170             } else if (strcmp(*argv, "gre") == 0 ||
    171                    strcmp(*argv, "gre/ip") == 0) {
     171            } else if (key == ARG_gre ||
     172                   key == ARG_gre_ip) {
    172173                if (p->iph.protocol && p->iph.protocol != IPPROTO_GRE) {
    173                     bb_error_msg("You managed to ask for more than one tunnel mode.");
    174                     exit(-1);
     174                    bb_error_msg_and_die("you managed to ask for more than one tunnel mode");
    175175                }
    176176                p->iph.protocol = IPPROTO_GRE;
    177             } else if (strcmp(*argv, "sit") == 0 ||
    178                    strcmp(*argv, "ipv6/ip") == 0) {
     177            } else if (key == ARG_sit ||
     178                   key == ARG_ip6_ip) {
    179179                if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) {
    180                     bb_error_msg("You managed to ask for more than one tunnel mode.");
    181                     exit(-1);
     180                    bb_error_msg_and_die("you managed to ask for more than one tunnel mode");
    182181                }
    183182                p->iph.protocol = IPPROTO_IPV6;
    184183            } else {
    185                 bb_error_msg("Cannot guess tunnel mode.");
    186                 exit(-1);
    187             }
    188         } else if (strcmp(*argv, "key") == 0) {
     184                bb_error_msg_and_die("cannot guess tunnel mode");
     185            }
     186        } else if (key == ARG_key) {
    189187            unsigned uval;
    190188            NEXT_ARG();
     
    195193            else {
    196194                if (get_unsigned(&uval, *argv, 0)<0) {
    197                     bb_error_msg("invalid value of \"key\"");
    198                     exit(-1);
     195                    bb_error_msg_and_die("invalid value of \"key\"");
    199196                }
    200197                p->i_key = p->o_key = htonl(uval);
    201198            }
    202         } else if (strcmp(*argv, "ikey") == 0) {
     199        } else if (key == ARG_ikey) {
    203200            unsigned uval;
    204201            NEXT_ARG();
     
    208205            else {
    209206                if (get_unsigned(&uval, *argv, 0)<0) {
    210                     bb_error_msg("invalid value of \"ikey\"");
    211                     exit(-1);
     207                    bb_error_msg_and_die("invalid value of \"ikey\"");
    212208                }
    213209                p->i_key = htonl(uval);
    214210            }
    215         } else if (strcmp(*argv, "okey") == 0) {
     211        } else if (key == ARG_okey) {
    216212            unsigned uval;
    217213            NEXT_ARG();
     
    221217            else {
    222218                if (get_unsigned(&uval, *argv, 0)<0) {
    223                     bb_error_msg("invalid value of \"okey\"");
    224                     exit(-1);
     219                    bb_error_msg_and_die("invalid value of \"okey\"");
    225220                }
    226221                p->o_key = htonl(uval);
    227222            }
    228         } else if (strcmp(*argv, "seq") == 0) {
     223        } else if (key == ARG_seq) {
    229224            p->i_flags |= GRE_SEQ;
    230225            p->o_flags |= GRE_SEQ;
    231         } else if (strcmp(*argv, "iseq") == 0) {
     226        } else if (key == ARG_iseq) {
    232227            p->i_flags |= GRE_SEQ;
    233         } else if (strcmp(*argv, "oseq") == 0) {
     228        } else if (key == ARG_oseq) {
    234229            p->o_flags |= GRE_SEQ;
    235         } else if (strcmp(*argv, "csum") == 0) {
     230        } else if (key == ARG_csum) {
    236231            p->i_flags |= GRE_CSUM;
    237232            p->o_flags |= GRE_CSUM;
    238         } else if (strcmp(*argv, "icsum") == 0) {
     233        } else if (key == ARG_icsum) {
    239234            p->i_flags |= GRE_CSUM;
    240         } else if (strcmp(*argv, "ocsum") == 0) {
     235        } else if (key == ARG_ocsum) {
    241236            p->o_flags |= GRE_CSUM;
    242         } else if (strcmp(*argv, "nopmtudisc") == 0) {
     237        } else if (key == ARG_nopmtudisc) {
    243238            p->iph.frag_off = 0;
    244         } else if (strcmp(*argv, "pmtudisc") == 0) {
     239        } else if (key == ARG_pmtudisc) {
    245240            p->iph.frag_off = htons(IP_DF);
    246         } else if (strcmp(*argv, "remote") == 0) {
    247             NEXT_ARG();
    248             if (strcmp(*argv, "any"))
     241        } else if (key == ARG_remote) {
     242            NEXT_ARG();
     243            key = index_in_strings(keywords, *argv);
     244            if (key == ARG_any)
    249245                p->iph.daddr = get_addr32(*argv);
    250         } else if (strcmp(*argv, "local") == 0) {
    251             NEXT_ARG();
    252             if (strcmp(*argv, "any"))
     246        } else if (key == ARG_local) {
     247            NEXT_ARG();
     248            key = index_in_strings(keywords, *argv);
     249            if (key == ARG_any)
    253250                p->iph.saddr = get_addr32(*argv);
    254         } else if (strcmp(*argv, "dev") == 0) {
     251        } else if (key == ARG_dev) {
    255252            NEXT_ARG();
    256253            strncpy(medium, *argv, IFNAMSIZ-1);
    257         } else if (strcmp(*argv, "ttl") == 0) {
     254        } else if (key == ARG_ttl) {
    258255            unsigned uval;
    259256            NEXT_ARG();
    260             if (strcmp(*argv, "inherit") != 0) {
     257            key = index_in_strings(keywords, *argv);
     258            if (key != ARG_inherit) {
    261259                if (get_unsigned(&uval, *argv, 0))
    262260                    invarg(*argv, "TTL");
     
    265263                p->iph.ttl = uval;
    266264            }
    267         } else if (strcmp(*argv, "tos") == 0 ||
    268                matches(*argv, "dsfield") == 0) {
    269             __u32 uval;
    270             NEXT_ARG();
    271             if (strcmp(*argv, "inherit") != 0) {
     265        } else if (key == ARG_tos ||
     266               key == ARG_dsfield) {
     267            uint32_t uval;
     268            NEXT_ARG();
     269            key = index_in_strings(keywords, *argv);
     270            if (key != ARG_inherit) {
    272271                if (rtnl_dsfield_a2n(&uval, *argv))
    273272                    invarg(*argv, "TOS");
     
    276275                p->iph.tos = 1;
    277276        } else {
    278             if (strcmp(*argv, "name") == 0) {
     277            if (key == ARG_name) {
    279278                NEXT_ARG();
    280279            }
     
    286285                memset(&old_p, 0, sizeof(old_p));
    287286                if (do_get_ioctl(*argv, &old_p))
    288                     return -1;
     287                    exit(1);
    289288                *p = old_p;
    290289            }
    291290        }
    292291        count++;
    293         argc--; argv++;
    294     }
    295 
     292        argc--;
     293        argv++;
     294    }
    296295
    297296    if (p->iph.protocol == 0) {
     
    306305    if (p->iph.protocol == IPPROTO_IPIP || p->iph.protocol == IPPROTO_IPV6) {
    307306        if ((p->i_flags & GRE_KEY) || (p->o_flags & GRE_KEY)) {
    308             bb_error_msg("Keys are not allowed with ipip and sit.");
    309             return -1;
     307            bb_error_msg_and_die("keys are not allowed with ipip and sit");
    310308        }
    311309    }
     
    313311    if (medium[0]) {
    314312        p->link = do_ioctl_get_ifindex(medium);
    315         if (p->link == 0)
    316             return -1;
    317313    }
    318314
     
    326322    }
    327323    if (IN_MULTICAST(ntohl(p->iph.daddr)) && !p->iph.saddr) {
    328         bb_error_msg("Broadcast tunnel requires a source address.");
    329         return -1;
    330     }
    331     return 0;
    332 }
    333 
    334 
     324        bb_error_msg_and_die("broadcast tunnel requires a source address");
     325    }
     326}
     327
     328
     329/* Return value becomes exitcode. It's okay to not return at all */
    335330static int do_add(int cmd, int argc, char **argv)
    336331{
    337332    struct ip_tunnel_parm p;
    338333
    339     if (parse_args(argc, argv, cmd, &p) < 0)
    340         return -1;
     334    parse_args(argc, argv, cmd, &p);
    341335
    342336    if (p.iph.ttl && p.iph.frag_off == 0) {
    343         bb_error_msg("ttl != 0 and noptmudisc are incompatible");
    344         return -1;
     337        bb_error_msg_and_die("ttl != 0 and noptmudisc are incompatible");
    345338    }
    346339
     
    353346        return do_add_ioctl(cmd, "sit0", &p);
    354347    default:
    355         bb_error_msg("cannot determine tunnel mode (ipip, gre or sit)");
    356         return -1;
    357     }
    358     return -1;
    359 }
    360 
     348        bb_error_msg_and_die("cannot determine tunnel mode (ipip, gre or sit)");
     349    }
     350}
     351
     352/* Return value becomes exitcode. It's okay to not return at all */
    361353static int do_del(int argc, char **argv)
    362354{
    363355    struct ip_tunnel_parm p;
    364356
    365     if (parse_args(argc, argv, SIOCDELTUNNEL, &p) < 0)
    366         return -1;
     357    parse_args(argc, argv, SIOCDELTUNNEL, &p);
    367358
    368359    switch (p.iph.protocol) {
     
    376367        return do_del_ioctl(p.name, &p);
    377368    }
    378     return -1;
    379369}
    380370
     
    399389    if (p->link) {
    400390        char *n = do_ioctl_get_ifname(p->link);
    401         if (n)
     391        if (n) {
    402392            printf(" dev %s ", n);
     393            free(n);
     394        }
    403395    }
    404396    if (p->iph.ttl)
     
    409401        SPRINT_BUF(b1);
    410402        printf(" tos");
    411         if (p->iph.tos&1)
     403        if (p->iph.tos & 1)
    412404            printf(" inherit");
    413         if (p->iph.tos&~1)
    414             printf("%c%s ", p->iph.tos&1 ? '/' : ' ',
    415                    rtnl_dsfield_n2a(p->iph.tos&~1, b1, sizeof(b1)));
    416     }
    417     if (!(p->iph.frag_off&htons(IP_DF)))
     405        if (p->iph.tos & ~1)
     406            printf("%c%s ", p->iph.tos & 1 ? '/' : ' ',
     407                   rtnl_dsfield_n2a(p->iph.tos & ~1, b1, sizeof(b1)));
     408    }
     409    if (!(p->iph.frag_off & htons(IP_DF)))
    418410        printf(" nopmtudisc");
    419411
    420     if ((p->i_flags&GRE_KEY) && (p->o_flags&GRE_KEY) && p->o_key == p->i_key)
     412    if ((p->i_flags & GRE_KEY) && (p->o_flags & GRE_KEY) && p->o_key == p->i_key)
    421413        printf(" key %s", s3);
    422     else if ((p->i_flags|p->o_flags)&GRE_KEY) {
    423         if (p->i_flags&GRE_KEY)
     414    else if ((p->i_flags | p->o_flags) & GRE_KEY) {
     415        if (p->i_flags & GRE_KEY)
    424416            printf(" ikey %s ", s3);
    425         if (p->o_flags&GRE_KEY)
     417        if (p->o_flags & GRE_KEY)
    426418            printf(" okey %s ", s4);
    427419    }
    428420
    429     if (p->i_flags&GRE_SEQ)
    430         printf("%s  Drop packets out of sequence.\n", _SL_);
    431     if (p->i_flags&GRE_CSUM)
    432         printf("%s  Checksum in received packet is required.", _SL_);
    433     if (p->o_flags&GRE_SEQ)
    434         printf("%s  Sequence packets on output.", _SL_);
    435     if (p->o_flags&GRE_CSUM)
    436         printf("%s  Checksum output packets.", _SL_);
    437 }
    438 
    439 static int do_tunnels_list(struct ip_tunnel_parm *p)
     421    if (p->i_flags & GRE_SEQ)
     422        printf("%c  Drop packets out of sequence.\n", _SL_);
     423    if (p->i_flags & GRE_CSUM)
     424        printf("%c  Checksum in received packet is required.", _SL_);
     425    if (p->o_flags & GRE_SEQ)
     426        printf("%c  Sequence packets on output.", _SL_);
     427    if (p->o_flags & GRE_CSUM)
     428        printf("%c  Checksum output packets.", _SL_);
     429}
     430
     431static void do_tunnels_list(struct ip_tunnel_parm *p)
    440432{
    441433    char name[IFNAMSIZ];
    442     unsigned long  rx_bytes, rx_packets, rx_errs, rx_drops,
    443     rx_fifo, rx_frame,
    444     tx_bytes, tx_packets, tx_errs, tx_drops,
    445     tx_fifo, tx_colls, tx_carrier, rx_multi;
     434    unsigned long rx_bytes, rx_packets, rx_errs, rx_drops,
     435        rx_fifo, rx_frame,
     436        tx_bytes, tx_packets, tx_errs, tx_drops,
     437        tx_fifo, tx_colls, tx_carrier, rx_multi;
    446438    int type;
    447439    struct ip_tunnel_parm p1;
    448 
    449440    char buf[512];
    450     FILE *fp = fopen("/proc/net/dev", "r");
     441    FILE *fp = fopen_or_warn("/proc/net/dev", "r");
     442
    451443    if (fp == NULL) {
    452         perror("fopen");
    453         return -1;
     444        return;
    454445    }
    455446
     
    459450    while (fgets(buf, sizeof(buf), fp) != NULL) {
    460451        char *ptr;
    461         buf[sizeof(buf) - 1] = 0;
    462         if ((ptr = strchr(buf, ':')) == NULL ||
     452
     453        /*buf[sizeof(buf) - 1] = 0; - fgets is safe anyway */
     454        ptr = strchr(buf, ':');
     455        if (ptr == NULL ||
    463456            (*ptr++ = 0, sscanf(buf, "%s", name) != 1)) {
    464             bb_error_msg("Wrong format of /proc/net/dev. Sorry.");
    465             return -1;
     457            bb_error_msg("wrong format of /proc/net/dev");
     458            return;
    466459        }
    467460        if (sscanf(ptr, "%lu%lu%lu%lu%lu%lu%lu%*d%lu%lu%lu%lu%lu%lu%lu",
     
    475468        type = do_ioctl_get_iftype(name);
    476469        if (type == -1) {
    477             bb_error_msg("Failed to get type of [%s]", name);
     470            bb_error_msg("cannot get type of [%s]", name);
    478471            continue;
    479472        }
     
    490483            continue;
    491484        print_tunnel(&p1);
    492         printf("\n");
    493     }
    494     return 0;
    495 }
    496 
     485        puts("");
     486    }
     487}
     488
     489/* Return value becomes exitcode. It's okay to not return at all */
    497490static int do_show(int argc, char **argv)
    498491{
     
    500493    struct ip_tunnel_parm p;
    501494
    502     if (parse_args(argc, argv, SIOCGETTUNNEL, &p) < 0)
    503         return -1;
     495    parse_args(argc, argv, SIOCGETTUNNEL, &p);
    504496
    505497    switch (p.iph.protocol) {
     
    521513
    522514    print_tunnel(&p);
    523     printf("\n");
     515    puts("");
    524516    return 0;
    525517}
    526518
     519/* Return value becomes exitcode. It's okay to not return at all */
    527520int do_iptunnel(int argc, char **argv)
    528521{
    529     if (argc > 0) {
    530         if (matches(*argv, "add") == 0)
    531             return do_add(SIOCADDTUNNEL, argc-1, argv+1);
    532         if (matches(*argv, "change") == 0)
    533             return do_add(SIOCCHGTUNNEL, argc-1, argv+1);
    534         if (matches(*argv, "del") == 0)
    535             return do_del(argc-1, argv+1);
    536         if (matches(*argv, "show") == 0 ||
    537             matches(*argv, "lst") == 0 ||
    538             matches(*argv, "list") == 0)
    539             return do_show(argc-1, argv+1);
    540     } else
    541         return do_show(0, NULL);
    542 
    543     bb_error_msg("Command \"%s\" is unknown.", *argv);
    544     exit(-1);
    545 }
     522    static const char keywords[] ALIGN1 =
     523        "add\0""change\0""delete\0""show\0""list\0""lst\0";
     524    enum { ARG_add = 0, ARG_change, ARG_del, ARG_show, ARG_list, ARG_lst };
     525    int key;
     526
     527    if (argc) {
     528        key = index_in_substrings(keywords, *argv);
     529        if (key < 0)
     530            bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
     531        --argc;
     532        ++argv;
     533        if (key == ARG_add)
     534            return do_add(SIOCADDTUNNEL, argc, argv);
     535        if (key == ARG_change)
     536            return do_add(SIOCCHGTUNNEL, argc, argv);
     537        if (key == ARG_del)
     538            return do_del(argc, argv);
     539    }
     540    return do_show(argc, argv);
     541}
  • branches/stable/mindi-busybox/networking/libiproute/libnetlink.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * libnetlink.c RTnetlink service routines.
     
    1112 */
    1213
     14#include <sys/socket.h>
     15#include <sys/uio.h>
     16
    1317#include "libbb.h"
    14 #include <sys/socket.h>
    15 
    16 #include <errno.h>
    17 #include <string.h>
    18 #include <time.h>
    19 #include <unistd.h>
    20 
    21 #include <sys/uio.h>
    22 
    2318#include "libnetlink.h"
    2419
     
    2823}
    2924
    30 int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions)
     25int xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/)
    3126{
    3227    socklen_t addr_len;
     
    3429    memset(rth, 0, sizeof(rth));
    3530
    36     rth->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
    37     if (rth->fd < 0) {
    38         bb_perror_msg("Cannot open netlink socket");
    39         return -1;
    40     }
     31    rth->fd = xsocket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
    4132
    4233    memset(&rth->local, 0, sizeof(rth->local));
    4334    rth->local.nl_family = AF_NETLINK;
    44     rth->local.nl_groups = subscriptions;
    45 
    46     if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) {
    47         bb_perror_msg("Cannot bind netlink socket");
    48         return -1;
    49     }
     35    /*rth->local.nl_groups = subscriptions;*/
     36
     37    xbind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local));
    5038    addr_len = sizeof(rth->local);
    51     if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) {
    52         bb_perror_msg("Cannot getsockname");
    53         return -1;
    54     }
    55     if (addr_len != sizeof(rth->local)) {
    56         bb_error_msg("Wrong address length %d", addr_len);
    57         return -1;
    58     }
    59     if (rth->local.nl_family != AF_NETLINK) {
    60         bb_error_msg("Wrong address family %d", rth->local.nl_family);
    61         return -1;
    62     }
     39    if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0)
     40        bb_perror_msg_and_die("cannot getsockname");
     41    if (addr_len != sizeof(rth->local))
     42        bb_error_msg_and_die("wrong address length %d", addr_len);
     43    if (rth->local.nl_family != AF_NETLINK)
     44        bb_error_msg_and_die("wrong address family %d", rth->local.nl_family);
    6345    rth->seq = time(NULL);
    6446    return 0;
    6547}
    6648
    67 int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
     49int xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
    6850{
    6951    struct {
     
    8365    req.g.rtgen_family = family;
    8466
    85     return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr));
     67    return xsendto(rth->fd, (void*)&req, sizeof(req),
     68                 (struct sockaddr*)&nladdr, sizeof(nladdr));
    8669}
    8770
     
    9376    nladdr.nl_family = AF_NETLINK;
    9477
    95     return sendto(rth->fd, buf, len, 0, (struct sockaddr*)&nladdr, sizeof(nladdr));
     78    return xsendto(rth->fd, buf, len, (struct sockaddr*)&nladdr, sizeof(nladdr));
    9679}
    9780
     
    120103}
    121104
    122 int rtnl_dump_filter(struct rtnl_handle *rth,
    123              int (*filter)(struct sockaddr_nl *, struct nlmsghdr *n, void *),
    124              void *arg1,
    125              int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *),
    126              void *arg2)
    127 {
    128     char    buf[8192];
     105static int rtnl_dump_filter(struct rtnl_handle *rth,
     106        int (*filter)(struct sockaddr_nl *, struct nlmsghdr *n, void *),
     107        void *arg1/*,
     108        int (*junk)(struct sockaddr_nl *, struct nlmsghdr *n, void *),
     109        void *arg2*/)
     110{
     111    char buf[8192];
    129112    struct sockaddr_nl nladdr;
    130113    struct iovec iov = { buf, sizeof(buf) };
     
    164147                h->nlmsg_pid != rth->local.nl_pid ||
    165148                h->nlmsg_seq != rth->dump) {
    166                 if (junk) {
     149/*              if (junk) {
    167150                    err = junk(&nladdr, h, arg2);
    168                     if (err < 0) {
     151                    if (err < 0)
    169152                        return err;
    170                     }
    171                 }
     153                } */
    172154                goto skip_it;
    173155            }
     
    187169            }
    188170            err = filter(&nladdr, h, arg1);
    189             if (err < 0) {
     171            if (err < 0)
    190172                return err;
    191             }
    192173
    193174skip_it:
     
    195176        }
    196177        if (msg.msg_flags & MSG_TRUNC) {
    197             bb_error_msg("Message truncated");
     178            bb_error_msg("message truncated");
    198179            continue;
    199180        }
    200181        if (status) {
    201             bb_error_msg_and_die("!!!Remnant of size %d", status);
    202         }
    203     }
     182            bb_error_msg_and_die("remnant of size %d!", status);
     183        }
     184    }
     185}
     186
     187int xrtnl_dump_filter(struct rtnl_handle *rth,
     188        int (*filter)(struct sockaddr_nl *, struct nlmsghdr *n, void *),
     189        void *arg1)
     190{
     191    int ret = rtnl_dump_filter(rth, filter, arg1/*, NULL, NULL*/);
     192    if (ret < 0)
     193        bb_error_msg_and_die("dump terminated");
     194    return ret;
    204195}
    205196
     
    234225
    235226    if (status < 0) {
    236         bb_perror_msg("Cannot talk to rtnetlink");
     227        bb_perror_msg("cannot talk to rtnetlink");
    237228        return -1;
    238229    }
     
    265256            if (l<0 || len>status) {
    266257                if (msg.msg_flags & MSG_TRUNC) {
    267                     bb_error_msg("Truncated message");
     258                    bb_error_msg("truncated message");
    268259                    return -1;
    269260                }
    270                 bb_error_msg_and_die("!!!malformed message: len=%d", len);
     261                bb_error_msg_and_die("malformed message: len=%d!", len);
    271262            }
    272263
     
    304295            }
    305296
    306             bb_error_msg("Unexpected reply!!!");
     297            bb_error_msg("unexpected reply!");
    307298
    308299            status -= NLMSG_ALIGN(len);
     
    310301        }
    311302        if (msg.msg_flags & MSG_TRUNC) {
    312             bb_error_msg("Message truncated");
     303            bb_error_msg("message truncated");
    313304            continue;
    314305        }
    315306        if (status) {
    316             bb_error_msg_and_die("!!!Remnant of size %d", status);
    317         }
    318     }
    319 }
    320 
    321 int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data)
     307            bb_error_msg_and_die("remnant of size %d!", status);
     308        }
     309    }
     310}
     311
     312int addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data)
    322313{
    323314    int len = RTA_LENGTH(4);
     
    348339}
    349340
    350 int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data)
     341int rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data)
    351342{
    352343    int len = RTA_LENGTH(4);
     
    390381    }
    391382    if (len) {
    392         bb_error_msg("!!!Deficit %d, rta_len=%d", len, rta->rta_len);
    393     }
    394     return 0;
    395 }
     383        bb_error_msg("deficit %d, rta_len=%d!", len, rta->rta_len);
     384    }
     385    return 0;
     386}
  • branches/stable/mindi-busybox/networking/libiproute/libnetlink.h

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12#ifndef __LIBNETLINK_H__
    23#define __LIBNETLINK_H__ 1
    34
    4 #include <asm/types.h>
     5#include <linux/types.h>
     6/* We need linux/types.h because older kernels use __u32 etc
     7 * in linux/[rt]netlink.h. 2.6.19 seems to be ok, though */
    58#include <linux/netlink.h>
    69#include <linux/rtnetlink.h>
     
    1114    struct sockaddr_nl  local;
    1215    struct sockaddr_nl  peer;
    13     __u32           seq;
    14     __u32           dump;
     16    uint32_t        seq;
     17    uint32_t        dump;
    1518};
    1619
    17 extern int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions);
     20extern int xrtnl_open(struct rtnl_handle *rth);
    1821extern void rtnl_close(struct rtnl_handle *rth);
    19 extern int rtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type);
     22extern int xrtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type);
    2023extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len);
    21 extern int rtnl_dump_filter(struct rtnl_handle *rth,
    22                 int (*filter)(struct sockaddr_nl *, struct nlmsghdr *n, void *),
    23                 void *arg1,
    24                 int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *),
    25                 void *arg2);
     24extern int xrtnl_dump_filter(struct rtnl_handle *rth,
     25            int (*filter)(struct sockaddr_nl*, struct nlmsghdr *n, void*),
     26            void *arg1);
    2627extern int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer,
    27              unsigned groups, struct nlmsghdr *answer,
    28              int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *),
    29              void *jarg);
     28            unsigned groups, struct nlmsghdr *answer,
     29            int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *),
     30            void *jarg);
    3031extern int rtnl_send(struct rtnl_handle *rth, char *buf, int);
    3132
    3233
    33 extern int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data);
     34extern int addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data);
    3435extern int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen);
    35 extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32 data);
     36extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data);
    3637extern int rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen);
    3738
    3839extern int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len);
    3940
    40 
    4141#endif /* __LIBNETLINK_H__ */
    42 
  • branches/stable/mindi-busybox/networking/libiproute/ll_addr.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * ll_addr.c
     
    1011 */
    1112
    12 #include "libbb.h"
    13 
    14 #include <string.h>
    1513#include <net/if_arp.h>
    1614
     15#include "libbb.h"
    1716#include "rt_names.h"
    1817#include "utils.h"
     
    3130    for (i=0; i<alen; i++) {
    3231        if (i==0) {
    33             snprintf(buf+l, blen, "%02x", addr[i]);
     32            snprintf(buf+l, blen, ":%02x"+1, addr[i]);
    3433            blen -= 2;
    3534            l += 2;
     
    4847        inet_prefix pfx;
    4948        if (get_addr_1(&pfx, arg, AF_INET)) {
    50             bb_error_msg("\"%s\" is invalid lladdr.", arg);
     49            bb_error_msg("\"%s\" is invalid lladdr", arg);
    5150            return -1;
    5251        }
     
    6766            }
    6867            if (sscanf(arg, "%x", &temp) != 1) {
    69                 bb_error_msg("\"%s\" is invalid lladdr.", arg);
     68                bb_error_msg("\"%s\" is invalid lladdr", arg);
    7069                return -1;
    7170            }
    7271            if (temp < 0 || temp > 255) {
    73                 bb_error_msg("\"%s\" is invalid lladdr.", arg);
     72                bb_error_msg("\"%s\" is invalid lladdr", arg);
    7473                return -1;
    7574            }
  • branches/stable/mindi-busybox/networking/libiproute/ll_map.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * ll_map.c
     
    1112 */
    1213
     14#include <net/if.h> /* struct ifreq and co. */
     15
    1316#include "libbb.h"
    14 #include <string.h>
    15 
    1617#include "libnetlink.h"
    1718#include "ll_map.h"
    1819
    19 struct idxmap
    20 {
    21     struct idxmap * next;
    22     int     index;
    23     int     type;
    24     int     alen;
    25     unsigned    flags;
    26     unsigned char   addr[8];
    27     char        name[16];
     20struct idxmap {
     21    struct idxmap *next;
     22    int            index;
     23    int            type;
     24    int            alen;
     25    unsigned       flags;
     26    unsigned char  addr[8];
     27    char           name[16];
    2828};
    2929
    3030static struct idxmap *idxmap[16];
     31
     32static struct idxmap *find_by_index(int idx)
     33{
     34    struct idxmap *im;
     35
     36    for (im = idxmap[idx & 0xF]; im; im = im->next)
     37        if (im->index == idx)
     38            return im;
     39    return NULL;
     40}
    3141
    3242int ll_remember_index(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
     
    4353        return -1;
    4454
    45 
    4655    memset(tb, 0, sizeof(tb));
    4756    parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n));
     
    4958        return 0;
    5059
    51     h = ifi->ifi_index&0xF;
     60    h = ifi->ifi_index & 0xF;
    5261
    53     for (imp=&idxmap[h]; (im=*imp)!=NULL; imp = &im->next)
     62    for (imp = &idxmap[h]; (im = *imp) != NULL; imp = &im->next)
    5463        if (im->index == ifi->ifi_index)
    55             break;
     64            goto found;
    5665
    57     if (im == NULL) {
    58         im = xmalloc(sizeof(*im));
    59         im->next = *imp;
    60         im->index = ifi->ifi_index;
    61         *imp = im;
    62     }
    63 
     66    im = xmalloc(sizeof(*im));
     67    im->next = *imp;
     68    im->index = ifi->ifi_index;
     69    *imp = im;
     70 found:
    6471    im->type = ifi->ifi_type;
    6572    im->flags = ifi->ifi_flags;
     
    8491    if (idx == 0)
    8592        return "*";
    86     for (im = idxmap[idx&0xF]; im; im = im->next)
    87         if (im->index == idx)
    88             return im->name;
     93    im = find_by_index(idx);
     94    if (im)
     95        return im->name;
    8996    snprintf(buf, 16, "if%d", idx);
    9097    return buf;
     
    99106}
    100107
     108#ifdef UNUSED
    101109int ll_index_to_type(int idx)
    102110{
     
    105113    if (idx == 0)
    106114        return -1;
    107     for (im = idxmap[idx&0xF]; im; im = im->next)
    108         if (im->index == idx)
    109             return im->type;
     115    im = find_by_index(idx);
     116    if (im)
     117        return im->type;
    110118    return -1;
    111119}
     120#endif
    112121
    113122unsigned ll_index_to_flags(int idx)
     
    117126    if (idx == 0)
    118127        return 0;
    119 
    120     for (im = idxmap[idx&0xF]; im; im = im->next)
    121         if (im->index == idx)
    122             return im->flags;
     128    im = find_by_index(idx);
     129    if (im)
     130        return im->flags;
    123131    return 0;
    124132}
    125133
    126 int ll_name_to_index(char *name)
     134int xll_name_to_index(const char *const name)
    127135{
     136    int ret = 0;
     137    int sock_fd;
     138
     139/* caching is not warranted - no users which repeatedly call it */
     140#ifdef UNUSED
    128141    static char ncache[16];
    129142    static int icache;
     143
    130144    struct idxmap *im;
    131145    int i;
    132146
    133147    if (name == NULL)
    134         return 0;
    135     if (icache && strcmp(name, ncache) == 0)
    136         return icache;
    137     for (i=0; i<16; i++) {
     148        goto out;
     149    if (icache && strcmp(name, ncache) == 0) {
     150        ret = icache;
     151        goto out;
     152    }
     153    for (i = 0; i < 16; i++) {
    138154        for (im = idxmap[i]; im; im = im->next) {
    139155            if (strcmp(im->name, name) == 0) {
    140156                icache = im->index;
    141157                strcpy(ncache, name);
    142                 return im->index;
     158                ret = im->index;
     159                goto out;
    143160            }
    144161        }
    145162    }
    146     return 0;
     163    /* We have not found the interface in our cache, but the kernel
     164     * may still know about it. One reason is that we may be using
     165     * module on-demand loading, which means that the kernel will
     166     * load the module and make the interface exist only when
     167     * we explicitely request it (check for dev_load() in net/core/dev.c).
     168     * I can think of other similar scenario, but they are less common...
     169     * Jean II */
     170#endif
     171
     172    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
     173    if (sock_fd) {
     174        struct ifreq ifr;
     175        int tmp;
     176
     177        strncpy(ifr.ifr_name, name, IFNAMSIZ);
     178        ifr.ifr_ifindex = -1;
     179        tmp = ioctl(sock_fd, SIOCGIFINDEX, &ifr);
     180        close(sock_fd);
     181        if (tmp >= 0)
     182            /* In theory, we should redump the interface list
     183             * to update our cache, this is left as an exercise
     184             * to the reader... Jean II */
     185            ret = ifr.ifr_ifindex;
     186    }
     187/* out:*/
     188    if (ret <= 0)
     189        bb_error_msg_and_die("cannot find device \"%s\"", name);
     190    return ret;
    147191}
    148192
    149193int ll_init_map(struct rtnl_handle *rth)
    150194{
    151     if (rtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK) < 0) {
    152         perror("Cannot send dump request");
    153         exit(1);
    154     }
    155 
    156     if (rtnl_dump_filter(rth, ll_remember_index, &idxmap, NULL, NULL) < 0) {
    157         fprintf(stderr, "Dump terminated\n");
    158         exit(1);
    159     }
     195    xrtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK);
     196    xrtnl_dump_filter(rth, ll_remember_index, &idxmap);
    160197    return 0;
    161198}
  • branches/stable/mindi-busybox/networking/libiproute/ll_map.h

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12#ifndef __LL_MAP_H__
    23#define __LL_MAP_H__ 1
    34
    4 extern int ll_remember_index(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
    5 extern int ll_init_map(struct rtnl_handle *rth);
    6 extern int ll_name_to_index(char *name);
    7 extern const char *ll_index_to_name(int idx);
    8 extern const char *ll_idx_n2a(int idx, char *buf);
    9 extern int ll_index_to_type(int idx);
    10 extern unsigned ll_index_to_flags(int idx);
     5int ll_remember_index(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
     6int ll_init_map(struct rtnl_handle *rth);
     7int xll_name_to_index(const char *const name);
     8const char *ll_index_to_name(int idx);
     9const char *ll_idx_n2a(int idx, char *buf);
     10/* int ll_index_to_type(int idx); */
     11unsigned ll_index_to_flags(int idx);
    1112
    1213#endif /* __LL_MAP_H__ */
  • branches/stable/mindi-busybox/networking/libiproute/ll_proto.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * ll_proto.c
     
    1112
    1213#include "libbb.h"
    13 #include <string.h>
    14 
    1514#include "rt_names.h"
    1615#include "utils.h"
    1716
    18 #if __GLIBC__ >=2 && __GLIBC_MINOR >= 1
     17#if defined(__GLIBC__) && __GLIBC__ >=2 && __GLIBC_MINOR__ >= 1
    1918#include <net/ethernet.h>
    2019#else
     
    2524static struct {
    2625    int id;
    27     char *name;
     26    const char *name;
    2827} llproto_names[] = {
    2928__PF(LOOP,loop)
     
    9897    id = ntohs(id);
    9998
    100     for (i=0; i<sizeof(llproto_names)/sizeof(llproto_names[0]); i++) {
     99    for (i=0; i < ARRAY_SIZE(llproto_names); i++) {
    101100         if (llproto_names[i].id == id)
    102101            return llproto_names[i].name;
     
    109108{
    110109    int i;
    111     for (i=0; i<sizeof(llproto_names)/sizeof(llproto_names[0]); i++) {
     110    for (i=0; i < ARRAY_SIZE(llproto_names); i++) {
    112111         if (strcasecmp(llproto_names[i].name, buf) == 0) {
    113112             *id = htons(llproto_names[i].id);
  • branches/stable/mindi-busybox/networking/libiproute/ll_types.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * ll_types.c
     
    910 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    1011 */
    11 #include <stdio.h>
    1212#include <arpa/inet.h>
    13 
    1413#include <linux/if_arp.h>
    1514
     15#include "libbb.h"
    1616#include "rt_names.h"
    1717
    18 const char * ll_type_n2a(int type, char *buf, int len)
     18const char* ll_type_n2a(int type, char *buf, int len)
    1919{
    2020#define __PF(f,n) { ARPHRD_##f, #n },
    21 static struct {
     21static const struct {
    2222    int type;
    23     char *name;
     23    const char *name;
    2424} arphrd_names[] = {
    2525{ 0, "generic" },
     
    109109
    110110    int i;
    111     for (i=0; i<sizeof(arphrd_names)/sizeof(arphrd_names[0]); i++) {
     111    for (i = 0; i < ARRAY_SIZE(arphrd_names); i++) {
    112112         if (arphrd_names[i].type == type)
    113113            return arphrd_names[i].name;
  • branches/stable/mindi-busybox/networking/libiproute/rt_names.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * rt_names.c       rtnetlink names DB.
     
    910 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    1011 */
    11 #include <stdio.h>
    12 #include <stdlib.h>
    13 #include <string.h>
    14 
    15 #include <stdint.h>
     12
     13#include "libbb.h"
    1614#include "rt_names.h"
    1715
    18 static void rtnl_tab_initialize(char *file, char **tab, int size)
     16static void rtnl_tab_initialize(const char *file, const char **tab, int size)
    1917{
    2018    char buf[512];
     
    3331        if (*p == '#' || *p == '\n' || *p == 0)
    3432            continue;
    35         if (sscanf(p, "0x%x %s\n", &id, namebuf) != 2 &&
    36             sscanf(p, "0x%x %s #", &id, namebuf) != 2 &&
    37             sscanf(p, "%d %s\n", &id, namebuf) != 2 &&
    38             sscanf(p, "%d %s #", &id, namebuf) != 2) {
    39             fprintf(stderr, "Database %s is corrupted at %s\n",
     33        if (sscanf(p, "0x%x %s\n", &id, namebuf) != 2
     34         && sscanf(p, "0x%x %s #", &id, namebuf) != 2
     35         && sscanf(p, "%d %s\n", &id, namebuf) != 2
     36         && sscanf(p, "%d %s #", &id, namebuf) != 2
     37        ) {
     38            bb_error_msg("database %s is corrupted at %s",
    4039                file, p);
    4140            return;
    4241        }
    4342
    44         if (id<0 || id>size)
     43        if (id < 0 || id > size)
    4544            continue;
    4645
    47         tab[id] = strdup(namebuf);
     46        tab[id] = xstrdup(namebuf);
    4847    }
    4948    fclose(fp);
     
    5150
    5251
    53 static char * rtnl_rtprot_tab[256] = {
    54     "none",
    55     "redirect",
    56     "kernel",
    57     "boot",
    58     "static",
    59     NULL,
    60     NULL,
    61     NULL,
    62     "gated",
    63     "ra",
    64     "mrt",
    65     "zebra",
    66     "bird",
    67 };
    68 
    69 
    70 
    71 static int rtnl_rtprot_init;
     52static const char **rtnl_rtprot_tab; /* [256] */
    7253
    7354static void rtnl_rtprot_initialize(void)
    7455{
    75     rtnl_rtprot_init = 1;
     56    static const char *const init_tab[] = {
     57        "none",
     58        "redirect",
     59        "kernel",
     60        "boot",
     61        "static",
     62        NULL,
     63        NULL,
     64        NULL,
     65        "gated",
     66        "ra",
     67        "mrt",
     68        "zebra",
     69        "bird",
     70    };
     71    if (rtnl_rtprot_tab) return;
     72    rtnl_rtprot_tab = xzalloc(256 * sizeof(rtnl_rtprot_tab[0]));
     73    memcpy(rtnl_rtprot_tab, init_tab, sizeof(init_tab));
    7674    rtnl_tab_initialize("/etc/iproute2/rt_protos",
    7775                rtnl_rtprot_tab, 256);
    7876}
    7977
    80 const char * rtnl_rtprot_n2a(int id, char *buf, int len)
    81 {
    82     if (id<0 || id>=256) {
    83         snprintf(buf, len, "%d", id);
    84         return buf;
    85     }
    86     if (!rtnl_rtprot_tab[id]) {
    87         if (!rtnl_rtprot_init)
    88             rtnl_rtprot_initialize();
    89     }
     78
     79const char* rtnl_rtprot_n2a(int id, char *buf, int len)
     80{
     81    if (id < 0 || id >= 256) {
     82        snprintf(buf, len, "%d", id);
     83        return buf;
     84    }
     85
     86    rtnl_rtprot_initialize();
     87
    9088    if (rtnl_rtprot_tab[id])
    9189        return rtnl_rtprot_tab[id];
     
    9694int rtnl_rtprot_a2n(uint32_t *id, char *arg)
    9795{
    98     static char *cache = NULL;
    99     static unsigned long res;
    100     char *end;
    101     int i;
    102 
    103     if (cache && strcmp(cache, arg) == 0) {
    104         *id = res;
    105         return 0;
    106     }
    107 
    108     if (!rtnl_rtprot_init)
    109         rtnl_rtprot_initialize();
    110 
    111     for (i=0; i<256; i++) {
     96    static const char *cache = NULL;
     97    static unsigned long res;
     98    int i;
     99
     100    if (cache && strcmp(cache, arg) == 0) {
     101        *id = res;
     102        return 0;
     103    }
     104
     105    rtnl_rtprot_initialize();
     106
     107    for (i = 0; i < 256; i++) {
    112108        if (rtnl_rtprot_tab[i] &&
    113109            strcmp(rtnl_rtprot_tab[i], arg) == 0) {
     
    119115    }
    120116
    121     res = strtoul(arg, &end, 0);
    122     if (!end || end == arg || *end || res > 255)
     117    res = bb_strtoul(arg, NULL, 0);
     118    if (errno || res > 255)
    123119        return -1;
    124120    *id = res;
     
    127123
    128124
    129 
    130 static char * rtnl_rtscope_tab[256] = {
    131     "global",
    132 };
    133 
    134 static int rtnl_rtscope_init;
     125static const char **rtnl_rtscope_tab; /* [256] */
    135126
    136127static void rtnl_rtscope_initialize(void)
    137128{
    138     rtnl_rtscope_init = 1;
     129    if (rtnl_rtscope_tab) return;
     130    rtnl_rtscope_tab = xzalloc(256 * sizeof(rtnl_rtscope_tab[0]));
     131    rtnl_rtscope_tab[0] = "global";
    139132    rtnl_rtscope_tab[255] = "nowhere";
    140133    rtnl_rtscope_tab[254] = "host";
     
    145138}
    146139
    147 const char * rtnl_rtscope_n2a(int id, char *buf, int len)
    148 {
    149     if (id<0 || id>=256) {
    150         snprintf(buf, len, "%d", id);
    151         return buf;
    152     }
    153     if (!rtnl_rtscope_tab[id]) {
    154         if (!rtnl_rtscope_init)
    155             rtnl_rtscope_initialize();
    156     }
     140
     141const char* rtnl_rtscope_n2a(int id, char *buf, int len)
     142{
     143    if (id < 0 || id >= 256) {
     144        snprintf(buf, len, "%d", id);
     145        return buf;
     146    }
     147
     148    rtnl_rtscope_initialize();
     149
    157150    if (rtnl_rtscope_tab[id])
    158151        return rtnl_rtscope_tab[id];
     
    163156int rtnl_rtscope_a2n(uint32_t *id, char *arg)
    164157{
    165     static char *cache = NULL;
    166     static unsigned long res;
    167     char *end;
    168     int i;
    169 
    170     if (cache && strcmp(cache, arg) == 0) {
    171         *id = res;
    172         return 0;
    173     }
    174 
    175     if (!rtnl_rtscope_init)
    176         rtnl_rtscope_initialize();
    177 
    178     for (i=0; i<256; i++) {
     158    static const char *cache = NULL;
     159    static unsigned long res;
     160    int i;
     161
     162    if (cache && strcmp(cache, arg) == 0) {
     163        *id = res;
     164        return 0;
     165    }
     166
     167    rtnl_rtscope_initialize();
     168
     169    for (i = 0; i < 256; i++) {
    179170        if (rtnl_rtscope_tab[i] &&
    180171            strcmp(rtnl_rtscope_tab[i], arg) == 0) {
     
    186177    }
    187178
    188     res = strtoul(arg, &end, 0);
    189     if (!end || end == arg || *end || res > 255)
     179    res = bb_strtoul(arg, NULL, 0);
     180    if (errno || res > 255)
    190181        return -1;
    191182    *id = res;
     
    194185
    195186
    196 
    197 static char * rtnl_rtrealm_tab[256] = {
    198     "unknown",
    199 };
    200 
    201 static int rtnl_rtrealm_init;
     187static const char **rtnl_rtrealm_tab; /* [256] */
    202188
    203189static void rtnl_rtrealm_initialize(void)
    204190{
    205     rtnl_rtrealm_init = 1;
     191    if (rtnl_rtrealm_tab) return;
     192    rtnl_rtrealm_tab = xzalloc(256 * sizeof(rtnl_rtrealm_tab[0]));
     193    rtnl_rtrealm_tab[0] = "unknown";
    206194    rtnl_tab_initialize("/etc/iproute2/rt_realms",
    207195                rtnl_rtrealm_tab, 256);
    208196}
    209197
     198
    210199int rtnl_rtrealm_a2n(uint32_t *id, char *arg)
    211200{
    212     static char *cache = NULL;
    213     static unsigned long res;
    214     char *end;
    215     int i;
    216 
    217     if (cache && strcmp(cache, arg) == 0) {
    218         *id = res;
    219         return 0;
    220     }
    221 
    222     if (!rtnl_rtrealm_init)
    223         rtnl_rtrealm_initialize();
    224 
    225     for (i=0; i<256; i++) {
     201    static const char *cache = NULL;
     202    static unsigned long res;
     203    int i;
     204
     205    if (cache && strcmp(cache, arg) == 0) {
     206        *id = res;
     207        return 0;
     208    }
     209
     210    rtnl_rtrealm_initialize();
     211
     212    for (i = 0; i < 256; i++) {
    226213        if (rtnl_rtrealm_tab[i] &&
    227214            strcmp(rtnl_rtrealm_tab[i], arg) == 0) {
     
    233220    }
    234221
    235     res = strtoul(arg, &end, 0);
    236     if (!end || end == arg || *end || res > 255)
     222    res = bb_strtoul(arg, NULL, 0);
     223    if (errno || res > 255)
    237224        return -1;
    238225    *id = res;
     
    240227}
    241228
    242 
    243 
    244 static char * rtnl_rtdsfield_tab[256] = {
    245     "0",
    246 };
    247 
    248 static int rtnl_rtdsfield_init;
     229#if ENABLE_FEATURE_IP_RULE
     230const char* rtnl_rtrealm_n2a(int id, char *buf, int len)
     231{
     232    if (id < 0 || id >= 256) {
     233        snprintf(buf, len, "%d", id);
     234        return buf;
     235    }
     236
     237    rtnl_rtrealm_initialize();
     238
     239    if (rtnl_rtrealm_tab[id])
     240        return rtnl_rtrealm_tab[id];
     241    snprintf(buf, len, "%d", id);
     242    return buf;
     243}
     244#endif
     245
     246
     247static const char **rtnl_rtdsfield_tab; /* [256] */
    249248
    250249static void rtnl_rtdsfield_initialize(void)
    251250{
    252     rtnl_rtdsfield_init = 1;
     251    if (rtnl_rtdsfield_tab) return;
     252    rtnl_rtdsfield_tab = xzalloc(256 * sizeof(rtnl_rtdsfield_tab[0]));
     253    rtnl_rtdsfield_tab[0] = "0";
    253254    rtnl_tab_initialize("/etc/iproute2/rt_dsfield",
    254255                rtnl_rtdsfield_tab, 256);
    255256}
    256257
     258
    257259const char * rtnl_dsfield_n2a(int id, char *buf, int len)
    258260{
    259     if (id<0 || id>=256) {
    260         snprintf(buf, len, "%d", id);
    261         return buf;
    262     }
    263     if (!rtnl_rtdsfield_tab[id]) {
    264         if (!rtnl_rtdsfield_init)
    265             rtnl_rtdsfield_initialize();
    266     }
     261    if (id < 0 || id >= 256) {
     262        snprintf(buf, len, "%d", id);
     263        return buf;
     264    }
     265
     266    rtnl_rtdsfield_initialize();
     267
    267268    if (rtnl_rtdsfield_tab[id])
    268269        return rtnl_rtdsfield_tab[id];
     
    274275int rtnl_dsfield_a2n(uint32_t *id, char *arg)
    275276{
    276     static char *cache = NULL;
    277     static unsigned long res;
    278     char *end;
    279     int i;
    280 
    281     if (cache && strcmp(cache, arg) == 0) {
    282         *id = res;
    283         return 0;
    284     }
    285 
    286     if (!rtnl_rtdsfield_init)
    287         rtnl_rtdsfield_initialize();
    288 
    289     for (i=0; i<256; i++) {
     277    static const char *cache = NULL;
     278    static unsigned long res;
     279    int i;
     280
     281    if (cache && strcmp(cache, arg) == 0) {
     282        *id = res;
     283        return 0;
     284    }
     285
     286    rtnl_rtdsfield_initialize();
     287
     288    for (i = 0; i < 256; i++) {
    290289        if (rtnl_rtdsfield_tab[i] &&
    291290            strcmp(rtnl_rtdsfield_tab[i], arg) == 0) {
     
    297296    }
    298297
    299     res = strtoul(arg, &end, 16);
    300     if (!end || end == arg || *end || res > 255)
     298    res = bb_strtoul(arg, NULL, 16);
     299    if (errno || res > 255)
    301300        return -1;
    302301    *id = res;
     
    304303}
    305304
     305
     306#if ENABLE_FEATURE_IP_RULE
     307static const char **rtnl_rttable_tab; /* [256] */
     308
     309static void rtnl_rttable_initialize(void)
     310{
     311    if (rtnl_rtdsfield_tab) return;
     312    rtnl_rttable_tab = xzalloc(256 * sizeof(rtnl_rttable_tab[0]));
     313    rtnl_rttable_tab[0] = "unspec";
     314    rtnl_rttable_tab[255] = "local";
     315    rtnl_rttable_tab[254] = "main";
     316    rtnl_rttable_tab[253] = "default";
     317    rtnl_tab_initialize("/etc/iproute2/rt_tables", rtnl_rttable_tab, 256);
     318}
     319
     320
     321const char *rtnl_rttable_n2a(int id, char *buf, int len)
     322{
     323    if (id < 0 || id >= 256) {
     324        snprintf(buf, len, "%d", id);
     325        return buf;
     326    }
     327
     328    rtnl_rttable_initialize();
     329
     330    if (rtnl_rttable_tab[id])
     331        return rtnl_rttable_tab[id];
     332    snprintf(buf, len, "%d", id);
     333    return buf;
     334}
     335
     336int rtnl_rttable_a2n(uint32_t * id, char *arg)
     337{
     338    static char *cache = NULL;
     339    static unsigned long res;
     340    int i;
     341
     342    if (cache && strcmp(cache, arg) == 0) {
     343        *id = res;
     344        return 0;
     345    }
     346
     347    rtnl_rttable_initialize();
     348
     349    for (i = 0; i < 256; i++) {
     350        if (rtnl_rttable_tab[i] && strcmp(rtnl_rttable_tab[i], arg) == 0) {
     351            cache = (char*)rtnl_rttable_tab[i];
     352            res = i;
     353            *id = res;
     354            return 0;
     355        }
     356    }
     357
     358    i = bb_strtoul(arg, NULL, 0);
     359    if (errno || i > 255)
     360        return -1;
     361    *id = i;
     362    return 0;
     363}
     364
     365#endif
  • branches/stable/mindi-busybox/networking/libiproute/rt_names.h

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12#ifndef RT_NAMES_H_
    23#define RT_NAMES_H_ 1
     
    67extern const char* rtnl_rtprot_n2a(int id, char *buf, int len);
    78extern const char* rtnl_rtscope_n2a(int id, char *buf, int len);
     9extern const char* rtnl_rtrealm_n2a(int id, char *buf, int len);
    810extern const char* rtnl_dsfield_n2a(int id, char *buf, int len);
     11extern const char* rtnl_rttable_n2a(int id, char *buf, int len);
    912extern int rtnl_rtprot_a2n(uint32_t *id, char *arg);
    1013extern int rtnl_rtscope_a2n(uint32_t *id, char *arg);
    1114extern int rtnl_rtrealm_a2n(uint32_t *id, char *arg);
    1215extern int rtnl_dsfield_a2n(uint32_t *id, char *arg);
     16extern int rtnl_rttable_a2n(uint32_t *id, char *arg);
    1317
    1418
    15 extern const char * ll_type_n2a(int type, char *buf, int len);
     19extern const char* ll_type_n2a(int type, char *buf, int len);
    1620
    17 extern const char *ll_addr_n2a(unsigned char *addr, int alen, int type,
     21extern const char* ll_addr_n2a(unsigned char *addr, int alen, int type,
    1822                char *buf, int blen);
    1923extern int ll_addr_a2n(unsigned char *lladdr, int len, char *arg);
    2024
    21 extern const char * ll_proto_n2a(unsigned short id, char *buf, int len);
     25extern const char* ll_proto_n2a(unsigned short id, char *buf, int len);
    2226extern int ll_proto_a2n(unsigned short *id, char *buf);
    2327
    24 
    2528#endif
  • branches/stable/mindi-busybox/networking/libiproute/rtm_map.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * rtm_map.c
     
    1112 */
    1213
    13 #include <stdlib.h>
    14 #include <string.h>
    15 
     14#include "libbb.h"
    1615#include "rt_names.h"
    1716#include "utils.h"
    1817
    19 char *rtnl_rtntype_n2a(int id, char *buf, int len)
     18const char *rtnl_rtntype_n2a(int id, char *buf, int len)
    2019{
    2120    switch (id) {
     
    5352int rtnl_rtntype_a2n(int *id, char *arg)
    5453{
     54    static const char keywords[] ALIGN1 =
     55        "local\0""nat\0""broadcast\0""brd\0""anycast\0"
     56        "multicast\0""prohibit\0""unreachable\0""blackhole\0"
     57        "xresolve\0""unicast\0""throw\0";
     58    enum {
     59        ARG_local = 1, ARG_nat, ARG_broadcast, ARG_brd, ARG_anycast,
     60        ARG_multicast, ARG_prohibit, ARG_unreachable, ARG_blackhole,
     61        ARG_xresolve, ARG_unicast, ARG_throw
     62    };
     63    const smalluint key = index_in_substrings(keywords, arg) + 1;
    5564    char *end;
    5665    unsigned long res;
    5766
    58     if (strcmp(arg, "local") == 0)
     67    if (key == ARG_local)
    5968        res = RTN_LOCAL;
    60     else if (strcmp(arg, "nat") == 0)
     69    else if (key == ARG_nat)
    6170        res = RTN_NAT;
    62     else if (matches(arg, "broadcast") == 0 ||
    63          strcmp(arg, "brd") == 0)
     71    else if (key == ARG_broadcast || key == ARG_brd)
    6472        res = RTN_BROADCAST;
    65     else if (matches(arg, "anycast") == 0)
     73    else if (key == ARG_anycast)
    6674        res = RTN_ANYCAST;
    67     else if (matches(arg, "multicast") == 0)
     75    else if (key == ARG_multicast)
    6876        res = RTN_MULTICAST;
    69     else if (matches(arg, "prohibit") == 0)
     77    else if (key == ARG_prohibit)
    7078        res = RTN_PROHIBIT;
    71     else if (matches(arg, "unreachable") == 0)
     79    else if (key == ARG_unreachable)
    7280        res = RTN_UNREACHABLE;
    73     else if (matches(arg, "blackhole") == 0)
     81    else if (key == ARG_blackhole)
    7482        res = RTN_BLACKHOLE;
    75     else if (matches(arg, "xresolve") == 0)
     83    else if (key == ARG_xresolve)
    7684        res = RTN_XRESOLVE;
    77     else if (matches(arg, "unicast") == 0)
     85    else if (key == ARG_unicast)
    7886        res = RTN_UNICAST;
    79     else if (strcmp(arg, "throw") == 0)
     87    else if (key == ARG_throw)
    8088        res = RTN_THROW;
    8189    else {
     
    8896}
    8997
    90 int get_rt_realms(__u32 *realms, char *arg)
     98int get_rt_realms(uint32_t *realms, char *arg)
    9199{
    92     __u32 realm = 0;
     100    uint32_t realm = 0;
    93101    char *p = strchr(arg, '/');
    94102
  • branches/stable/mindi-busybox/networking/libiproute/rtm_map.h

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12#ifndef __RTM_MAP_H__
    23#define __RTM_MAP_H__ 1
    34
    4 char *rtnl_rtntype_n2a(int id, char *buf, int len);
     5const char *rtnl_rtntype_n2a(int id, char *buf, int len);
    56int rtnl_rtntype_a2n(int *id, char *arg);
    67
    7 int get_rt_realms(__u32 *realms, char *arg);
     8int get_rt_realms(uint32_t *realms, char *arg);
    89
    910
  • branches/stable/mindi-busybox/networking/libiproute/utils.c

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12/*
    23 * utils.c
     
    1213
    1314#include "libbb.h"
    14 
    15 #include <string.h>
    16 #include <unistd.h>
    17 
    1815#include "utils.h"
    1916#include "inet_common.h"
     
    3229    return 0;
    3330}
    34 
     31//XXX: FIXME: use some libbb function instead
    3532int get_unsigned(unsigned *val, char *arg, int base)
    3633{
     
    4744}
    4845
    49 int get_u32(__u32 * val, char *arg, int base)
     46int get_u32(uint32_t * val, char *arg, int base)
    5047{
    5148    unsigned long res;
     
    6158}
    6259
    63 int get_u16(__u16 * val, char *arg, int base)
     60int get_u16(uint16_t * val, char *arg, int base)
    6461{
    6562    unsigned long res;
     
    7572}
    7673
    77 int get_u8(__u8 * val, char *arg, int base)
     74int get_u8(uint8_t * val, char *arg, int base)
    7875{
    7976    unsigned long res;
     
    8986}
    9087
    91 int get_s16(__s16 * val, char *arg, int base)
     88int get_s16(int16_t * val, char *arg, int base)
    9289{
    9390    long res;
     
    103100}
    104101
    105 int get_s8(__s8 * val, char *arg, int base)
     102int get_s8(int8_t * val, char *arg, int base)
    106103{
    107104    long res;
     
    125122    memset(addr, 0, sizeof(*addr));
    126123
    127     if (strcmp(name, bb_INET_default) == 0 ||
     124    if (strcmp(name, bb_str_default) == 0 ||
    128125        strcmp(name, "all") == 0 || strcmp(name, "any") == 0) {
    129126        addr->family = family;
     
    169166    memset(dst, 0, sizeof(*dst));
    170167
    171     if (strcmp(arg, bb_INET_default) == 0 || strcmp(arg, "any") == 0) {
     168    if (strcmp(arg, bb_str_default) == 0 || strcmp(arg, "any") == 0) {
    172169        dst->family = family;
    173170        dst->bytelen = 0;
     
    178175    slash = strchr(arg, '/');
    179176    if (slash)
    180         *slash = 0;
     177        *slash = '\0';
    181178    err = get_addr_1(dst, arg, family);
    182179    if (err == 0) {
     
    197194        }
    198195    }
    199   done:
     196 done:
    200197    if (slash)
    201198        *slash = '/';
     
    206203{
    207204    if (family == AF_PACKET) {
    208         bb_error_msg_and_die("\"%s\" may be inet address, but it is not allowed in this context.", arg);
     205        bb_error_msg_and_die("\"%s\" may be inet address, but it is not allowed in this context", arg);
    209206    }
    210207    if (get_addr_1(dst, arg, family)) {
    211         bb_error_msg_and_die("an inet address is expected rather than \"%s\".", arg);
     208        bb_error_msg_and_die("an inet address is expected rather than \"%s\"", arg);
    212209    }
    213210    return 0;
     
    217214{
    218215    if (family == AF_PACKET) {
    219         bb_error_msg_and_die("\"%s\" may be inet address, but it is not allowed in this context.", arg);
     216        bb_error_msg_and_die("\"%s\" may be inet address, but it is not allowed in this context", arg);
    220217    }
    221218    if (get_prefix_1(dst, arg, family)) {
    222         bb_error_msg_and_die("an inet address is expected rather than \"%s\".", arg);
    223     }
    224     return 0;
    225 }
    226 
    227 __u32 get_addr32(char *name)
     219        bb_error_msg_and_die("an inet address is expected rather than \"%s\"", arg);
     220    }
     221    return 0;
     222}
     223
     224uint32_t get_addr32(char *name)
    228225{
    229226    inet_prefix addr;
     
    237234void incomplete_command(void)
    238235{
    239     bb_error_msg("Command line is not complete. Try option \"help\"");
    240     exit(-1);
    241 }
    242 
    243 void invarg(const char * const arg, const char * const opt)
    244 {
    245     bb_error_msg(bb_msg_invalid_arg, arg, opt);
    246     exit(-1);
    247 }
    248 
    249 void duparg(char *key, char *arg)
    250 {
    251     bb_error_msg("duplicate \"%s\": \"%s\" is the second value.", key, arg);
    252     exit(-1);
    253 }
    254 
    255 void duparg2(char *key, char *arg)
    256 {
    257     bb_error_msg("either \"%s\" is duplicate, or \"%s\" is a garbage.", key, arg);
    258     exit(-1);
    259 }
    260 
    261 int matches(char *cmd, char *pattern)
    262 {
    263     int len = strlen(cmd);
    264 
    265     if (len > strlen(pattern)) {
    266         return -1;
    267     }
    268     return memcmp(pattern, cmd, len);
     236    bb_error_msg_and_die("command line is not complete, try option \"help\"");
     237}
     238
     239void invarg(const char *arg, const char *opt)
     240{
     241    bb_error_msg_and_die(bb_msg_invalid_arg, arg, opt);
     242}
     243
     244void duparg(const char *key, const char *arg)
     245{
     246    bb_error_msg_and_die("duplicate \"%s\": \"%s\" is the second value", key, arg);
     247}
     248
     249void duparg2(const char *key, const char *arg)
     250{
     251    bb_error_msg_and_die("either \"%s\" is duplicate, or \"%s\" is garbage", key, arg);
    269252}
    270253
    271254int inet_addr_match(inet_prefix * a, inet_prefix * b, int bits)
    272255{
    273     __u32 *a1 = a->data;
    274     __u32 *a2 = b->data;
     256    uint32_t *a1 = a->data;
     257    uint32_t *a2 = b->data;
    275258    int words = bits >> 0x05;
    276259
     
    282265
    283266    if (bits) {
    284         __u32 w1, w2;
    285         __u32 mask;
     267        uint32_t w1, w2;
     268        uint32_t mask;
    286269
    287270        w1 = a1[words];
     
    295278
    296279    return 0;
    297 }
    298 
    299 int __iproute2_hz_internal;
    300 
    301 int __get_hz(void)
    302 {
    303     int hz = 0;
    304     FILE *fp = fopen("/proc/net/psched", "r");
    305 
    306     if (fp) {
    307         unsigned nom, denom;
    308 
    309         if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2)
    310             if (nom == 1000000)
    311                 hz = denom;
    312         fclose(fp);
    313     }
    314     if (hz)
    315         return hz;
    316     return sysconf(_SC_CLK_TCK);
    317280}
    318281
     
    347310            }
    348311        }
    349         if (len > 0 && (h_ent = gethostbyaddr(addr, len, af)) != NULL) {
    350             snprintf(buf, buflen - 1, "%s", h_ent->h_name);
    351             return buf;
     312        if (len > 0) {
     313            h_ent = gethostbyaddr(addr, len, af);
     314            if (h_ent != NULL) {
     315                safe_strncpy(buf, h_ent->h_name, buflen);
     316                return buf;
     317            }
    352318        }
    353319    }
  • branches/stable/mindi-busybox/networking/libiproute/utils.h

    r821 r1770  
     1/* vi: set sw=4 ts=4: */
    12#ifndef __UTILS_H__
    23#define __UTILS_H__ 1
    3 
    4 #include "libbb.h"
    5 #include <asm/types.h>
    6 #include <resolv.h>
    74
    85#include "libnetlink.h"
     
    118
    129extern int preferred_family;
    13 extern int show_stats;
    14 extern int show_details;
    15 extern int show_raw;
    16 extern int resolve_hosts;
    17 extern int oneline;
    18 extern char * _SL_;
     10extern smallint show_stats;    /* UNUSED */
     11extern smallint show_details;  /* UNUSED */
     12extern smallint show_raw;      /* UNUSED */
     13extern smallint resolve_hosts; /* UNUSED */
     14extern smallint oneline;
     15extern char _SL_;
    1916
    2017#ifndef IPPROTO_ESP
     
    3027extern void incomplete_command(void) ATTRIBUTE_NORETURN;
    3128
    32 #define NEXT_ARG() do { argv++; if (--argc <= 0) incomplete_command(); } while(0)
     29#define NEXT_ARG() do { argv++; if (--argc <= 0) incomplete_command(); } while (0)
    3330
    3431typedef struct
    3532{
    36     __u8 family;
    37     __u8 bytelen;
    38     __s16 bitlen;
    39     __u32 data[4];
     33    uint8_t family;
     34    uint8_t bytelen;
     35    int16_t bitlen;
     36    uint32_t data[4];
    4037} inet_prefix;
    4138
     
    4542#endif
    4643
    47 struct dn_naddr
    48 {
     44struct dn_naddr {
    4945    unsigned short          a_len;
    5046    unsigned char a_addr[DN_MAXADDL];
     
    5854};
    5955
    60 extern __u32 get_addr32(char *name);
     56extern uint32_t get_addr32(char *name);
    6157extern int get_addr_1(inet_prefix *dst, char *arg, int family);
    6258extern int get_prefix_1(inet_prefix *dst, char *arg, int family);
     
    6965#define get_ushort get_u16
    7066#define get_short get_s16
    71 extern int get_u32(__u32 *val, char *arg, int base);
    72 extern int get_u16(__u16 *val, char *arg, int base);
    73 extern int get_s16(__s16 *val, char *arg, int base);
    74 extern int get_u8(__u8 *val, char *arg, int base);
    75 extern int get_s8(__s8 *val, char *arg, int base);
     67extern int get_u32(uint32_t *val, char *arg, int base);
     68extern int get_u16(uint16_t *val, char *arg, int base);
     69extern int get_s16(int16_t *val, char *arg, int base);
     70extern int get_u8(uint8_t *val, char *arg, int base);
     71extern int get_s8(int8_t *val, char *arg, int base);
    7672
    7773extern const char *format_host(int af, int len, void *addr, char *buf, int buflen);
    7874extern const char *rt_addr_n2a(int af, int len, void *addr, char *buf, int buflen);
    7975
    80 void invarg(const char * const, const char * const) ATTRIBUTE_NORETURN;
    81 void duparg(char *, char *) ATTRIBUTE_NORETURN;
    82 void duparg2(char *, char *) ATTRIBUTE_NORETURN;
    83 int matches(char *arg, char *pattern);
    84 extern int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits);
     76void invarg(const char *, const char *) ATTRIBUTE_NORETURN;
     77void duparg(const char *, const char *) ATTRIBUTE_NORETURN;
     78void duparg2(const char *, const char *) ATTRIBUTE_NORETURN;
     79int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits);
    8580
    8681const char *dnet_ntop(int af, const void *addr, char *str, size_t len);
     
    9085int ipx_pton(int af, const char *src, void *addr);
    9186
    92 extern int __iproute2_hz_internal;
    93 extern int __get_hz(void);
    94 
    95 static __inline__ int get_hz(void)
    96 {
    97     if (__iproute2_hz_internal == 0)
    98         __iproute2_hz_internal = __get_hz();
    99     return __iproute2_hz_internal;
    100 }
    101 
    10287#endif /* __UTILS_H__ */
Note: See TracChangeset for help on using the changeset viewer.