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

Update to busybox 1.7.2

Location:
branches/2.2.5/mindi-busybox/networking/libiproute
Files:
2 added
3 deleted
19 edited

Legend:

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

    r821 r1765  
     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/2.2.5/mindi-busybox/networking/libiproute/ip_parse_common_args.c

    r821 r1765  
     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/2.2.5/mindi-busybox/networking/libiproute/ipaddress.c

    r821 r1765  
     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/2.2.5/mindi-busybox/networking/libiproute/iplink.c

    r821 r1765  
     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/2.2.5/mindi-busybox/networking/libiproute/iproute.c

    r821 r1765  
    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/2.2.5/mindi-busybox/networking/libiproute/iptunnel.c

    r821 r1765  
     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/2.2.5/mindi-busybox/networking/libiproute/libnetlink.c

    r821 r1765  
     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/2.2.5/mindi-busybox/networking/libiproute/libnetlink.h

    r821 r1765  
     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/2.2.5/mindi-busybox/networking/libiproute/ll_addr.c

    r821 r1765  
     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/2.2.5/mindi-busybox/networking/libiproute/ll_map.c

    r821 r1765  
     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/2.2.5/mindi-busybox/networking/libiproute/ll_map.h

    r821 r1765  
     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/2.2.5/mindi-busybox/networking/libiproute/ll_proto.c

    r821 r1765  
     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/2.2.5/mindi-busybox/networking/libiproute/ll_types.c

    r821 r1765  
     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/2.2.5/mindi-busybox/networking/libiproute/rt_names.c

    r821 r1765  
     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/2.2.5/mindi-busybox/networking/libiproute/rt_names.h

    r821 r1765  
     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/2.2.5/mindi-busybox/networking/libiproute/rtm_map.c

    r821 r1765  
     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/2.2.5/mindi-busybox/networking/libiproute/rtm_map.h

    r821 r1765  
     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/2.2.5/mindi-busybox/networking/libiproute/utils.c

    r821 r1765  
     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/2.2.5/mindi-busybox/networking/libiproute/utils.h

    r821 r1765  
     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.