Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
Location:
branches/2.2.9/mindi-busybox/networking/libiproute
Files:
1 added
21 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/networking/libiproute/Kbuild

    r1765 r2725  
     1# DO NOT EDIT. This file is generated from Kbuild.src
    12# Makefile for busybox
    23#
    34# Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
    45#
    5 # Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
     6# Licensed under GPLv2 or later, see file LICENSE in this source tree.
    67#
    78
    89lib-y:=
     10
     11
    912
    1013lib-$(CONFIG_SLATTACH) += \
     
    6366    rt_names.o \
    6467    utils.o
    65 
  • branches/2.2.9/mindi-busybox/networking/libiproute/ip_common.h

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    2 #ifndef _IP_COMMON_H
    3 #define _IP_COMMON_H 1
     2#ifndef IP_COMMON_H
     3#define IP_COMMON_H 1
    44
    55#include "libbb.h"
     
    1414#endif
    1515
    16 extern void ip_parse_common_args(int *argcp, char ***argvp);
    17 extern int print_neigh(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
    18 extern int ipaddr_list_or_flush(int argc, char **argv, int flush);
    19 extern int iproute_monitor(int argc, char **argv);
    20 extern void iplink_usage(void) ATTRIBUTE_NORETURN;
    21 extern void ipneigh_reset_filter(void);
     16PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
    2217
    23 extern int do_ipaddr(int argc, char **argv);
    24 extern int do_iproute(int argc, char **argv);
    25 extern int do_iprule(int argc, char **argv);
    26 extern int do_ipneigh(int argc, char **argv);
    27 extern int do_iptunnel(int argc, char **argv);
    28 extern int do_iplink(int argc, char **argv);
    29 extern int do_ipmonitor(int argc, char **argv);
    30 extern int do_multiaddr(int argc, char **argv);
    31 extern int do_multiroute(int argc, char **argv);
    32 #endif /* ip_common.h */
     18char FAST_FUNC **ip_parse_common_args(char **argv);
     19//int FAST_FUNC print_neigh(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
     20int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush);
     21//int FAST_FUNC iproute_monitor(char **argv);
     22//void FAST_FUNC ipneigh_reset_filter(void);
     23
     24int FAST_FUNC do_ipaddr(char **argv);
     25int FAST_FUNC do_iproute(char **argv);
     26int FAST_FUNC do_iprule(char **argv);
     27//int FAST_FUNC do_ipneigh(char **argv);
     28int FAST_FUNC do_iptunnel(char **argv);
     29int FAST_FUNC do_iplink(char **argv);
     30//int FAST_FUNC do_ipmonitor(char **argv);
     31//int FAST_FUNC do_multiaddr(char **argv);
     32//int FAST_FUNC do_multiroute(char **argv);
     33
     34POP_SAVED_FUNCTION_VISIBILITY
     35
     36#endif
  • branches/2.2.9/mindi-busybox/networking/libiproute/ip_parse_common_args.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * ip.c     "ip" utility frontend.
     3 * This program is free software; you can redistribute it and/or
     4 * modify it under the terms of the GNU General Public License
     5 * as published by the Free Software Foundation; either version
     6 * 2 of the License, or (at your option) any later version.
    47 *
    5  *      This program is free software; you can redistribute it and/or
    6  *      modify it under the terms of the GNU General Public License
    7  *      as published by the Free Software Foundation; either version
    8  *      2 of the License, or (at your option) any later version.
    9  *
    10  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    11  *
     8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    129 *
    1310 * Changes:
    1411 *
    15  * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
     12 * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
    1613 */
    1714
     
    1916#include "utils.h"
    2017
    21 int preferred_family = AF_UNSPEC;
     18family_t preferred_family = AF_UNSPEC;
    2219smallint oneline;
    2320char _SL_;
    2421
    25 void ip_parse_common_args(int *argcp, char ***argvp)
     22char** FAST_FUNC ip_parse_common_args(char **argv)
    2623{
    27     int argc = *argcp;
    28     char **argv = *argvp;
    2924    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";
     25        "oneline" "\0"
     26        "family" "\0"
     27        "4" "\0"
     28        "6" "\0"
     29        "0" "\0"
     30        ;
    3231    enum {
    33         ARG_family = 1,
    34         ARG_inet,
    35         ARG_inet6,
    36         ARG_link,
     32        ARG_oneline,
     33        ARG_family,
    3734        ARG_IPv4,
    3835        ARG_IPv6,
    3936        ARG_packet,
    40         ARG_oneline
    4137    };
    42     smalluint arg;
     38    static const family_t af_numbers[] = { AF_INET, AF_INET6, AF_PACKET };
     39    int arg;
    4340
    44     while (argc > 1) {
    45         char *opt = argv[1];
     41    while (*argv) {
     42        char *opt = *argv;
    4643
    47         if (strcmp(opt,"--") == 0) {
    48             argc--;
    49             argv++;
    50             break;
    51         }
    5244        if (opt[0] != '-')
    5345            break;
    54         if (opt[1] == '-')
     46        opt++;
     47        if (opt[0] == '-') {
    5548            opt++;
    56         arg = index_in_strings(ip_common_commands, opt) + 1;
     49            if (!opt[0]) { /* "--" */
     50                argv++;
     51                break;
     52            }
     53        }
     54        arg = index_in_substrings(ip_common_commands, opt);
     55        if (arg < 0)
     56            bb_show_usage();
     57        if (arg == ARG_oneline) {
     58            oneline = 1;
     59            argv++;
     60            continue;
     61        }
    5762        if (arg == ARG_family) {
    58             argc--;
     63            static const char families[] ALIGN1 =
     64                "inet" "\0" "inet6" "\0" "link" "\0";
    5965            argv++;
    60             if (!argv[1])
     66            if (!*argv)
    6167                bb_show_usage();
    62             arg = index_in_strings(ip_common_commands, argv[1]) + 1;
    63             if (arg == ARG_inet)
    64                 preferred_family = AF_INET;
    65             else if (arg == ARG_inet6)
    66                 preferred_family = AF_INET6;
    67             else if (arg == ARG_link)
    68                 preferred_family = AF_PACKET;
    69             else
    70                 invarg(argv[1], "protocol family");
    71         } else if (arg == ARG_IPv4) {
    72             preferred_family = AF_INET;
    73         } else if (arg == ARG_IPv6) {
    74             preferred_family = AF_INET6;
    75         } else if (arg == ARG_packet) {
    76             preferred_family = AF_PACKET;
    77         } else if (arg == ARG_oneline) {
    78             ++oneline;
     68            arg = index_in_strings(families, *argv);
     69            if (arg < 0)
     70                invarg(*argv, "protocol family");
     71            /* now arg == 0, 1 or 2 */
    7972        } else {
    80             bb_show_usage();
     73            arg -= ARG_IPv4;
     74            /* now arg == 0, 1 or 2 */
    8175        }
    82         argc--;
     76        preferred_family = af_numbers[arg];
    8377        argv++;
    8478    }
    8579    _SL_ = oneline ? '\\' : '\n';
    86     *argcp = argc;
    87     *argvp = argv;
     80    return argv;
    8881}
  • branches/2.2.9/mindi-busybox/networking/libiproute/ipaddress.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * ipaddress.c      "ip address".
     3 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    44 *
    5  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    6  *
    7  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
     5 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    86 *
    97 * Changes:
    10  *  Laszlo Valko <valko@linux.karinthy.hu> 990223: address label must be zero terminated
     8 * Laszlo Valko <valko@linux.karinthy.hu> 990223: address label must be zero terminated
    119 */
    1210
    13 //#include <sys/socket.h>
    14 //#include <sys/ioctl.h>
    1511#include <fnmatch.h>
    1612#include <net/if.h>
     
    2117#include "utils.h"
    2218
    23 
    24 typedef struct filter_t {
    25     int ifindex;
    26     int family;
    27     int oneline;
    28     int showqueue;
    29     inet_prefix pfx;
     19#ifndef IFF_LOWER_UP
     20/* from linux/if.h */
     21#define IFF_LOWER_UP  0x10000  /* driver signals L1 up */
     22#endif
     23
     24struct filter_t {
     25    char *label;
     26    char *flushb;
     27    struct rtnl_handle *rth;
    3028    int scope, scopemask;
    3129    int flags, flagmask;
    32     int up;
    33     char *label;
    34     int flushed;
    35     char *flushb;
    3630    int flushp;
    3731    int flushe;
    38     struct rtnl_handle *rth;
    39 } filter_t;
    40 
    41 #define filter (*(filter_t*)&bb_common_bufsiz1)
    42 
    43 
    44 static void print_link_flags(FILE *fp, unsigned flags, unsigned mdown)
    45 {
    46     fprintf(fp, "<");
     32    int ifindex;
     33    family_t family;
     34    smallint showqueue;
     35    smallint oneline;
     36    smallint up;
     37    smallint flushed;
     38    inet_prefix pfx;
     39} FIX_ALIASING;
     40typedef struct filter_t filter_t;
     41
     42#define G_filter (*(filter_t*)&bb_common_bufsiz1)
     43
     44
     45static void print_link_flags(unsigned flags, unsigned mdown)
     46{
     47    static const int flag_masks[] = {
     48        IFF_LOOPBACK, IFF_BROADCAST, IFF_POINTOPOINT,
     49        IFF_MULTICAST, IFF_NOARP, IFF_UP, IFF_LOWER_UP };
     50    static const char flag_labels[] ALIGN1 =
     51        "LOOPBACK\0""BROADCAST\0""POINTOPOINT\0"
     52        "MULTICAST\0""NOARP\0""UP\0""LOWER_UP\0";
     53
     54    bb_putchar('<');
     55    if (flags & IFF_UP && !(flags & IFF_RUNNING))
     56        printf("NO-CARRIER,");
    4757    flags &= ~IFF_RUNNING;
    48 #define _PF(f) if (flags&IFF_##f) { \
    49           flags &= ~IFF_##f; \
    50           fprintf(fp, #f "%s", flags ? "," : ""); }
    51     _PF(LOOPBACK);
    52     _PF(BROADCAST);
    53     _PF(POINTOPOINT);
    54     _PF(MULTICAST);
    55     _PF(NOARP);
    5658#if 0
    5759    _PF(ALLMULTI);
     
    6567    _PF(NOTRAILERS);
    6668#endif
    67     _PF(UP);
    68 #undef _PF
     69    flags = print_flags_separated(flag_masks, flag_labels, flags, ",");
    6970    if (flags)
    70         fprintf(fp, "%x", flags);
     71        printf("%x", flags);
    7172    if (mdown)
    72         fprintf(fp, ",M-DOWN");
    73     fprintf(fp, "> ");
     73        printf(",M-DOWN");
     74    printf("> ");
    7475}
    7576
     
    8485
    8586    memset(&ifr, 0, sizeof(ifr));
    86     strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
     87    strncpy_IFNAMSIZ(ifr.ifr_name, name);
    8788    if (ioctl_or_warn(s, SIOCGIFTXQLEN, &ifr) < 0) {
    8889        close(s);
     
    9596}
    9697
    97 static int print_linkinfo(struct sockaddr_nl ATTRIBUTE_UNUSED *who,
    98         const struct nlmsghdr *n, void ATTRIBUTE_UNUSED *arg)
    99 {
    100     FILE *fp = (FILE*)arg;
     98static NOINLINE int print_linkinfo(const struct nlmsghdr *n)
     99{
    101100    struct ifinfomsg *ifi = NLMSG_DATA(n);
    102     struct rtattr * tb[IFLA_MAX+1];
     101    struct rtattr *tb[IFLA_MAX+1];
    103102    int len = n->nlmsg_len;
    104     unsigned m_flag = 0;
    105103
    106104    if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
     
    111109        return -1;
    112110
    113     if (filter.ifindex && ifi->ifi_index != filter.ifindex)
    114         return 0;
    115     if (filter.up && !(ifi->ifi_flags&IFF_UP))
     111    if (G_filter.ifindex && ifi->ifi_index != G_filter.ifindex)
     112        return 0;
     113    if (G_filter.up && !(ifi->ifi_flags & IFF_UP))
    116114        return 0;
    117115
     
    122120        return -1;
    123121    }
    124     if (filter.label
    125      && (!filter.family || filter.family == AF_PACKET)
    126      && fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)
     122    if (G_filter.label
     123     && (!G_filter.family || G_filter.family == AF_PACKET)
     124     && fnmatch(G_filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)
    127125    ) {
    128126        return 0;
     
    130128
    131129    if (n->nlmsg_type == RTM_DELLINK)
    132         fprintf(fp, "Deleted ");
    133 
    134     fprintf(fp, "%d: %s", ifi->ifi_index,
    135         tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>");
    136 
    137     if (tb[IFLA_LINK]) {
    138         SPRINT_BUF(b1);
    139         int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
    140         if (iflink == 0)
    141             fprintf(fp, "@NONE: ");
    142         else {
    143             fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1));
    144             m_flag = ll_index_to_flags(iflink);
    145             m_flag = !(m_flag & IFF_UP);
    146         }
    147     } else {
    148         fprintf(fp, ": ");
    149     }
    150     print_link_flags(fp, ifi->ifi_flags, m_flag);
     130        printf("Deleted ");
     131
     132    printf("%d: %s", ifi->ifi_index,
     133        /*tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>" - we checked tb[IFLA_IFNAME] above*/
     134        (char*)RTA_DATA(tb[IFLA_IFNAME])
     135    );
     136
     137    {
     138        unsigned m_flag = 0;
     139        if (tb[IFLA_LINK]) {
     140            SPRINT_BUF(b1);
     141            int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
     142            if (iflink == 0)
     143                printf("@NONE: ");
     144            else {
     145                printf("@%s: ", ll_idx_n2a(iflink, b1));
     146                m_flag = ll_index_to_flags(iflink);
     147                m_flag = !(m_flag & IFF_UP);
     148            }
     149        } else {
     150            printf(": ");
     151        }
     152        print_link_flags(ifi->ifi_flags, m_flag);
     153    }
    151154
    152155    if (tb[IFLA_MTU])
    153         fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
     156        printf("mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
    154157    if (tb[IFLA_QDISC])
    155         fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC]));
     158        printf("qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC]));
    156159#ifdef IFLA_MASTER
    157160    if (tb[IFLA_MASTER]) {
    158161        SPRINT_BUF(b1);
    159         fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
     162        printf("master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
    160163    }
    161164#endif
    162     if (filter.showqueue)
     165    if (tb[IFLA_OPERSTATE]) {
     166        static const char operstate_labels[] ALIGN1 =
     167            "UNKNOWN\0""NOTPRESENT\0""DOWN\0""LOWERLAYERDOWN\0"
     168            "TESTING\0""DORMANT\0""UP\0";
     169        printf("state %s ", nth_string(operstate_labels,
     170                    *(uint8_t *)RTA_DATA(tb[IFLA_OPERSTATE])));
     171    }
     172    if (G_filter.showqueue)
    163173        print_queuelen((char*)RTA_DATA(tb[IFLA_IFNAME]));
    164174
    165     if (!filter.family || filter.family == AF_PACKET) {
     175    if (!G_filter.family || G_filter.family == AF_PACKET) {
    166176        SPRINT_BUF(b1);
    167         fprintf(fp, "%c    link/%s ", _SL_, ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));
     177        printf("%c    link/%s ", _SL_, ll_type_n2a(ifi->ifi_type, b1));
    168178
    169179        if (tb[IFLA_ADDRESS]) {
    170             fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
     180            fputs(ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
    171181                              RTA_PAYLOAD(tb[IFLA_ADDRESS]),
    172182                              ifi->ifi_type,
    173                               b1, sizeof(b1)));
     183                              b1, sizeof(b1)), stdout);
    174184        }
    175185        if (tb[IFLA_BROADCAST]) {
    176             if (ifi->ifi_flags&IFF_POINTOPOINT)
    177                 fprintf(fp, " peer ");
     186            if (ifi->ifi_flags & IFF_POINTOPOINT)
     187                printf(" peer ");
    178188            else
    179                 fprintf(fp, " brd ");
    180             fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
     189                printf(" brd ");
     190            fputs(ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
    181191                              RTA_PAYLOAD(tb[IFLA_BROADCAST]),
    182192                              ifi->ifi_type,
    183                               b1, sizeof(b1)));
    184         }
    185     }
    186     fputc('\n', fp);
    187     fflush(fp);
     193                              b1, sizeof(b1)), stdout);
     194        }
     195    }
     196    bb_putchar('\n');
     197    /*fflush_all();*/
    188198    return 0;
    189199}
     
    191201static int flush_update(void)
    192202{
    193     if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) {
    194         bb_perror_msg("failed to send flush request");
     203    if (rtnl_send(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) {
     204        bb_perror_msg("can't send flush request");
    195205        return -1;
    196206    }
    197     filter.flushp = 0;
     207    G_filter.flushp = 0;
    198208    return 0;
    199209}
    200210
    201 static int print_addrinfo(struct sockaddr_nl ATTRIBUTE_UNUSED *who,
    202         struct nlmsghdr *n, void ATTRIBUTE_UNUSED *arg)
    203 {
    204     FILE *fp = (FILE*)arg;
     211static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
     212        struct nlmsghdr *n, void *arg UNUSED_PARAM)
     213{
    205214    struct ifaddrmsg *ifa = NLMSG_DATA(n);
    206215    int len = n->nlmsg_len;
     
    217226    }
    218227
    219     if (filter.flushb && n->nlmsg_type != RTM_NEWADDR)
     228    if (G_filter.flushb && n->nlmsg_type != RTM_NEWADDR)
    220229        return 0;
    221230
     
    228237        rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL];
    229238
    230     if (filter.ifindex && filter.ifindex != ifa->ifa_index)
    231         return 0;
    232     if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
    233         return 0;
    234     if ((filter.flags^ifa->ifa_flags)&filter.flagmask)
    235         return 0;
    236     if (filter.label) {
     239    if (G_filter.ifindex && G_filter.ifindex != ifa->ifa_index)
     240        return 0;
     241    if ((G_filter.scope ^ ifa->ifa_scope) & G_filter.scopemask)
     242        return 0;
     243    if ((G_filter.flags ^ ifa->ifa_flags) & G_filter.flagmask)
     244        return 0;
     245    if (G_filter.label) {
    237246        const char *label;
    238247        if (rta_tb[IFA_LABEL])
     
    240249        else
    241250            label = ll_idx_n2a(ifa->ifa_index, b1);
    242         if (fnmatch(filter.label, label, 0) != 0)
     251        if (fnmatch(G_filter.label, label, 0) != 0)
    243252            return 0;
    244253    }
    245     if (filter.pfx.family) {
     254    if (G_filter.pfx.family) {
    246255        if (rta_tb[IFA_LOCAL]) {
    247256            inet_prefix dst;
     
    249258            dst.family = ifa->ifa_family;
    250259            memcpy(&dst.data, RTA_DATA(rta_tb[IFA_LOCAL]), RTA_PAYLOAD(rta_tb[IFA_LOCAL]));
    251             if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
     260            if (inet_addr_match(&dst, &G_filter.pfx, G_filter.pfx.bitlen))
    252261                return 0;
    253262        }
    254263    }
    255264
    256     if (filter.flushb) {
     265    if (G_filter.flushb) {
    257266        struct nlmsghdr *fn;
    258         if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
     267        if (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len > G_filter.flushe) {
    259268            if (flush_update())
    260269                return -1;
    261270        }
    262         fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp));
     271        fn = (struct nlmsghdr*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp));
    263272        memcpy(fn, n, n->nlmsg_len);
    264273        fn->nlmsg_type = RTM_DELADDR;
    265274        fn->nlmsg_flags = NLM_F_REQUEST;
    266         fn->nlmsg_seq = ++filter.rth->seq;
    267         filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb;
    268         filter.flushed++;
     275        fn->nlmsg_seq = ++G_filter.rth->seq;
     276        G_filter.flushp = (((char*)fn) + n->nlmsg_len) - G_filter.flushb;
     277        G_filter.flushed = 1;
    269278        return 0;
    270279    }
    271280
    272281    if (n->nlmsg_type == RTM_DELADDR)
    273         fprintf(fp, "Deleted ");
    274 
    275     if (filter.oneline)
    276         fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index));
     282        printf("Deleted ");
     283
     284    if (G_filter.oneline)
     285        printf("%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index));
    277286    if (ifa->ifa_family == AF_INET)
    278         fprintf(fp, "    inet ");
     287        printf("    inet ");
    279288    else if (ifa->ifa_family == AF_INET6)
    280         fprintf(fp, "    inet6 ");
     289        printf("    inet6 ");
    281290    else
    282         fprintf(fp, "    family %d ", ifa->ifa_family);
     291        printf("    family %d ", ifa->ifa_family);
    283292
    284293    if (rta_tb[IFA_LOCAL]) {
    285         fprintf(fp, "%s", rt_addr_n2a(ifa->ifa_family,
    286                           RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
     294        fputs(rt_addr_n2a(ifa->ifa_family,
    287295                          RTA_DATA(rta_tb[IFA_LOCAL]),
    288                           abuf, sizeof(abuf)));
    289 
    290         if (rta_tb[IFA_ADDRESS] == NULL ||
    291             memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0) {
    292             fprintf(fp, "/%d ", ifa->ifa_prefixlen);
     296                          abuf, sizeof(abuf)), stdout);
     297
     298        if (rta_tb[IFA_ADDRESS] == NULL
     299         || memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0
     300        ) {
     301            printf("/%d ", ifa->ifa_prefixlen);
    293302        } else {
    294             fprintf(fp, " peer %s/%d ",
     303            printf(" peer %s/%d ",
    295304                rt_addr_n2a(ifa->ifa_family,
    296                         RTA_PAYLOAD(rta_tb[IFA_ADDRESS]),
    297305                        RTA_DATA(rta_tb[IFA_ADDRESS]),
    298306                        abuf, sizeof(abuf)),
     
    302310
    303311    if (rta_tb[IFA_BROADCAST]) {
    304         fprintf(fp, "brd %s ",
     312        printf("brd %s ",
    305313            rt_addr_n2a(ifa->ifa_family,
    306                     RTA_PAYLOAD(rta_tb[IFA_BROADCAST]),
    307314                    RTA_DATA(rta_tb[IFA_BROADCAST]),
    308315                    abuf, sizeof(abuf)));
    309316    }
    310317    if (rta_tb[IFA_ANYCAST]) {
    311         fprintf(fp, "any %s ",
     318        printf("any %s ",
    312319            rt_addr_n2a(ifa->ifa_family,
    313                     RTA_PAYLOAD(rta_tb[IFA_ANYCAST]),
    314320                    RTA_DATA(rta_tb[IFA_ANYCAST]),
    315321                    abuf, sizeof(abuf)));
    316322    }
    317     fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1)));
    318     if (ifa->ifa_flags&IFA_F_SECONDARY) {
     323    printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1));
     324    if (ifa->ifa_flags & IFA_F_SECONDARY) {
    319325        ifa->ifa_flags &= ~IFA_F_SECONDARY;
    320         fprintf(fp, "secondary ");
    321     }
    322     if (ifa->ifa_flags&IFA_F_TENTATIVE) {
     326        printf("secondary ");
     327    }
     328    if (ifa->ifa_flags & IFA_F_TENTATIVE) {
    323329        ifa->ifa_flags &= ~IFA_F_TENTATIVE;
    324         fprintf(fp, "tentative ");
    325     }
    326     if (ifa->ifa_flags&IFA_F_DEPRECATED) {
     330        printf("tentative ");
     331    }
     332    if (ifa->ifa_flags & IFA_F_DEPRECATED) {
    327333        ifa->ifa_flags &= ~IFA_F_DEPRECATED;
    328         fprintf(fp, "deprecated ");
    329     }
    330     if (!(ifa->ifa_flags&IFA_F_PERMANENT)) {
    331         fprintf(fp, "dynamic ");
     334        printf("deprecated ");
     335    }
     336    if (!(ifa->ifa_flags & IFA_F_PERMANENT)) {
     337        printf("dynamic ");
    332338    } else
    333339        ifa->ifa_flags &= ~IFA_F_PERMANENT;
    334340    if (ifa->ifa_flags)
    335         fprintf(fp, "flags %02x ", ifa->ifa_flags);
     341        printf("flags %02x ", ifa->ifa_flags);
    336342    if (rta_tb[IFA_LABEL])
    337         fprintf(fp, "%s", (char*)RTA_DATA(rta_tb[IFA_LABEL]));
     343        fputs((char*)RTA_DATA(rta_tb[IFA_LABEL]), stdout);
    338344    if (rta_tb[IFA_CACHEINFO]) {
    339345        struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]);
    340346        char buf[128];
    341         fputc(_SL_, fp);
     347        bb_putchar(_SL_);
    342348        if (ci->ifa_valid == 0xFFFFFFFFU)
    343349            sprintf(buf, "valid_lft forever");
     
    348354        else
    349355            sprintf(buf+strlen(buf), " preferred_lft %dsec", ci->ifa_prefered);
    350         fprintf(fp, "       %s", buf);
    351     }
    352     fputc('\n', fp);
    353     fflush(fp);
     356        printf("       %s", buf);
     357    }
     358    bb_putchar('\n');
     359    /*fflush_all();*/
    354360    return 0;
    355361}
    356362
    357363
    358 struct nlmsg_list
    359 {
     364struct nlmsg_list {
    360365    struct nlmsg_list *next;
    361     struct nlmsghdr   h;
     366    struct nlmsghdr   h;
    362367};
    363368
    364 static int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *fp)
     369static int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo)
    365370{
    366371    for (; ainfo; ainfo = ainfo->next) {
     
    370375        if (n->nlmsg_type != RTM_NEWADDR)
    371376            continue;
    372 
    373377        if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifa)))
    374378            return -1;
    375 
    376         if (ifa->ifa_index != ifindex ||
    377             (filter.family && filter.family != ifa->ifa_family))
     379        if (ifa->ifa_index != ifindex
     380         || (G_filter.family && G_filter.family != ifa->ifa_family)
     381        ) {
    378382            continue;
    379 
    380         print_addrinfo(NULL, n, fp);
     383        }
     384        print_addrinfo(NULL, n, NULL);
    381385    }
    382386    return 0;
     
    384388
    385389
    386 static int store_nlmsg(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
     390static int FAST_FUNC store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
    387391{
    388392    struct nlmsg_list **linfo = (struct nlmsg_list**)arg;
     
    390394    struct nlmsg_list **lp;
    391395
    392     h = malloc(n->nlmsg_len+sizeof(void*));
    393     if (h == NULL)
    394         return -1;
     396    h = xzalloc(n->nlmsg_len + sizeof(void*));
    395397
    396398    memcpy(&h->h, n, n->nlmsg_len);
    397     h->next = NULL;
    398 
    399     for (lp = linfo; *lp; lp = &(*lp)->next) /* NOTHING */;
     399    /*h->next = NULL; - xzalloc did it */
     400
     401    for (lp = linfo; *lp; lp = &(*lp)->next)
     402        continue;
    400403    *lp = h;
    401404
     
    406409static void ipaddr_reset_filter(int _oneline)
    407410{
    408     memset(&filter, 0, sizeof(filter));
    409     filter.oneline = _oneline;
     411    memset(&G_filter, 0, sizeof(G_filter));
     412    G_filter.oneline = _oneline;
    410413}
    411414
    412415/* Return value becomes exitcode. It's okay to not return at all */
    413 int ipaddr_list_or_flush(int argc, char **argv, int flush)
     416int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush)
    414417{
    415418    static const char option[] ALIGN1 = "to\0""scope\0""up\0""label\0""dev\0";
     
    423426
    424427    ipaddr_reset_filter(oneline);
    425     filter.showqueue = 1;
    426 
    427     if (filter.family == AF_UNSPEC)
    428         filter.family = preferred_family;
     428    G_filter.showqueue = 1;
     429
     430    if (G_filter.family == AF_UNSPEC)
     431        G_filter.family = preferred_family;
    429432
    430433    if (flush) {
    431         if (argc <= 0) {
     434        if (!*argv) {
    432435            bb_error_msg_and_die(bb_msg_requires_arg, "flush");
    433436        }
    434         if (filter.family == AF_PACKET) {
    435             bb_error_msg_and_die("cannot flush link addresses");
    436         }
    437     }
    438 
    439     while (argc > 0) {
    440         const int option_num = index_in_strings(option, *argv);
    441         switch (option_num) {
    442             case 0: /* to */
     437        if (G_filter.family == AF_PACKET) {
     438            bb_error_msg_and_die("can't flush link addresses");
     439        }
     440    }
     441
     442    while (*argv) {
     443        const smalluint key = index_in_strings(option, *argv);
     444        if (key == 0) { /* to */
     445            NEXT_ARG();
     446            get_prefix(&G_filter.pfx, *argv, G_filter.family);
     447            if (G_filter.family == AF_UNSPEC) {
     448                G_filter.family = G_filter.pfx.family;
     449            }
     450        } else if (key == 1) { /* scope */
     451            uint32_t scope = 0;
     452            NEXT_ARG();
     453            G_filter.scopemask = -1;
     454            if (rtnl_rtscope_a2n(&scope, *argv)) {
     455                if (strcmp(*argv, "all") != 0) {
     456                    invarg(*argv, "scope");
     457                }
     458                scope = RT_SCOPE_NOWHERE;
     459                G_filter.scopemask = 0;
     460            }
     461            G_filter.scope = scope;
     462        } else if (key == 2) { /* up */
     463            G_filter.up = 1;
     464        } else if (key == 3) { /* label */
     465            NEXT_ARG();
     466            G_filter.label = *argv;
     467        } else {
     468            if (key == 4) /* dev */
    443469                NEXT_ARG();
    444                 get_prefix(&filter.pfx, *argv, filter.family);
    445                 if (filter.family == AF_UNSPEC) {
    446                     filter.family = filter.pfx.family;
    447                 }
    448                 break;
    449             case 1: /* scope */
    450             {
    451                 uint32_t scope = 0;
    452                 NEXT_ARG();
    453                 filter.scopemask = -1;
    454                 if (rtnl_rtscope_a2n(&scope, *argv)) {
    455                     if (strcmp(*argv, "all") != 0) {
    456                         invarg(*argv, "scope");
    457                     }
    458                     scope = RT_SCOPE_NOWHERE;
    459                     filter.scopemask = 0;
    460                 }
    461                 filter.scope = scope;
    462                 break;
    463             }
    464             case 2: /* up */
    465                 filter.up = 1;
    466                 break;
    467             case 3: /* label */
    468                 NEXT_ARG();
    469                 filter.label = *argv;
    470                 break;
    471             case 4: /* dev */
    472                 NEXT_ARG();
    473             default:
    474                 if (filter_dev) {
    475                     duparg2("dev", *argv);
    476                 }
    477                 filter_dev = *argv;
     470            if (filter_dev)
     471                duparg2("dev", *argv);
     472            filter_dev = *argv;
    478473        }
    479474        argv++;
    480         argc--;
    481475    }
    482476
     
    487481
    488482    if (filter_dev) {
    489         filter.ifindex = xll_name_to_index(filter_dev);
     483        G_filter.ifindex = xll_name_to_index(filter_dev);
    490484    }
    491485
     
    493487        char flushb[4096-512];
    494488
    495         filter.flushb = flushb;
    496         filter.flushp = 0;
    497         filter.flushe = sizeof(flushb);
    498         filter.rth = &rth;
     489        G_filter.flushb = flushb;
     490        G_filter.flushp = 0;
     491        G_filter.flushe = sizeof(flushb);
     492        G_filter.rth = &rth;
    499493
    500494        for (;;) {
    501             xrtnl_wilddump_request(&rth, filter.family, RTM_GETADDR);
    502             filter.flushed = 0;
    503             xrtnl_dump_filter(&rth, print_addrinfo, stdout);
    504             if (filter.flushed == 0) {
     495            xrtnl_wilddump_request(&rth, G_filter.family, RTM_GETADDR);
     496            G_filter.flushed = 0;
     497            xrtnl_dump_filter(&rth, print_addrinfo, NULL);
     498            if (G_filter.flushed == 0) {
    505499                return 0;
    506500            }
    507             if (flush_update() < 0)
     501            if (flush_update() < 0) {
    508502                return 1;
    509         }
    510     }
    511 
    512     if (filter.family != AF_PACKET) {
    513         xrtnl_wilddump_request(&rth, filter.family, RTM_GETADDR);
     503            }
     504        }
     505    }
     506
     507    if (G_filter.family != AF_PACKET) {
     508        xrtnl_wilddump_request(&rth, G_filter.family, RTM_GETADDR);
    514509        xrtnl_dump_filter(&rth, store_nlmsg, &ainfo);
    515510    }
    516511
    517512
    518     if (filter.family && filter.family != AF_PACKET) {
     513    if (G_filter.family && G_filter.family != AF_PACKET) {
    519514        struct nlmsg_list **lp;
    520         lp=&linfo;
    521 
    522         if (filter.oneline)
     515        lp = &linfo;
     516
     517        if (G_filter.oneline)
    523518            no_link = 1;
    524519
    525         while ((l=*lp)!=NULL) {
     520        while ((l = *lp) != NULL) {
    526521            int ok = 0;
    527522            struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
    528523            struct nlmsg_list *a;
    529524
    530             for (a=ainfo; a; a=a->next) {
     525            for (a = ainfo; a; a = a->next) {
    531526                struct nlmsghdr *n = &a->h;
    532527                struct ifaddrmsg *ifa = NLMSG_DATA(n);
    533528
    534                 if (ifa->ifa_index != ifi->ifi_index ||
    535                     (filter.family && filter.family != ifa->ifa_family))
     529                if (ifa->ifa_index != ifi->ifi_index
     530                 || (G_filter.family && G_filter.family != ifa->ifa_family)
     531                ) {
    536532                    continue;
    537                 if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
     533                }
     534                if ((G_filter.scope ^ ifa->ifa_scope) & G_filter.scopemask)
    538535                    continue;
    539                 if ((filter.flags^ifa->ifa_flags)&filter.flagmask)
     536                if ((G_filter.flags ^ ifa->ifa_flags) & G_filter.flagmask)
    540537                    continue;
    541                 if (filter.pfx.family || filter.label) {
     538                if (G_filter.pfx.family || G_filter.label) {
    542539                    struct rtattr *tb[IFA_MAX+1];
    543540                    memset(tb, 0, sizeof(tb));
     
    546543                        tb[IFA_LOCAL] = tb[IFA_ADDRESS];
    547544
    548                     if (filter.pfx.family && tb[IFA_LOCAL]) {
     545                    if (G_filter.pfx.family && tb[IFA_LOCAL]) {
    549546                        inet_prefix dst;
    550547                        memset(&dst, 0, sizeof(dst));
    551548                        dst.family = ifa->ifa_family;
    552549                        memcpy(&dst.data, RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_LOCAL]));
    553                         if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
     550                        if (inet_addr_match(&dst, &G_filter.pfx, G_filter.pfx.bitlen))
    554551                            continue;
    555552                    }
    556                     if (filter.label) {
     553                    if (G_filter.label) {
    557554                        SPRINT_BUF(b1);
    558555                        const char *label;
     
    561558                        else
    562559                            label = ll_idx_n2a(ifa->ifa_index, b1);
    563                         if (fnmatch(filter.label, label, 0) != 0)
     560                        if (fnmatch(G_filter.label, label, 0) != 0)
    564561                            continue;
    565562                    }
     
    577574
    578575    for (l = linfo; l; l = l->next) {
    579         if (no_link || print_linkinfo(NULL, &l->h, stdout) == 0) {
     576        if (no_link || print_linkinfo(&l->h) == 0) {
    580577            struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
    581             if (filter.family != AF_PACKET)
    582                 print_selected_addrinfo(ifi->ifi_index, ainfo, stdout);
    583         }
    584         fflush(stdout); /* why? */
     578            if (G_filter.family != AF_PACKET)
     579                print_selected_addrinfo(ifi->ifi_index, ainfo);
     580        }
    585581    }
    586582
     
    598594
    599595/* Return value becomes exitcode. It's okay to not return at all */
    600 static int ipaddr_modify(int cmd, int argc, char **argv)
     596static int ipaddr_modify(int cmd, char **argv)
    601597{
    602598    static const char option[] ALIGN1 =
     
    626622    req.ifa.ifa_family = preferred_family;
    627623
    628     while (argc > 0) {
    629         const int option_num = index_in_strings(option, *argv);
    630         switch (option_num) {
    631             case 0: /* peer */
    632             case 1: /* remote */
     624    while (*argv) {
     625        const smalluint arg = index_in_strings(option, *argv);
     626        if (arg <= 1) { /* peer, remote */
     627            NEXT_ARG();
     628
     629            if (peer_len) {
     630                duparg("peer", *argv);
     631            }
     632            get_prefix(&peer, *argv, req.ifa.ifa_family);
     633            peer_len = peer.bytelen;
     634            if (req.ifa.ifa_family == AF_UNSPEC) {
     635                req.ifa.ifa_family = peer.family;
     636            }
     637            addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen);
     638            req.ifa.ifa_prefixlen = peer.bitlen;
     639        } else if (arg <= 3) { /* broadcast, brd */
     640            inet_prefix addr;
     641            NEXT_ARG();
     642            if (brd_len) {
     643                duparg("broadcast", *argv);
     644            }
     645            if (LONE_CHAR(*argv, '+')) {
     646                brd_len = -1;
     647            } else if (LONE_DASH(*argv)) {
     648                brd_len = -2;
     649            } else {
     650                get_addr(&addr, *argv, req.ifa.ifa_family);
     651                if (req.ifa.ifa_family == AF_UNSPEC)
     652                    req.ifa.ifa_family = addr.family;
     653                addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen);
     654                brd_len = addr.bytelen;
     655            }
     656        } else if (arg == 4) { /* anycast */
     657            inet_prefix addr;
     658            NEXT_ARG();
     659            if (any_len) {
     660                duparg("anycast", *argv);
     661            }
     662            get_addr(&addr, *argv, req.ifa.ifa_family);
     663            if (req.ifa.ifa_family == AF_UNSPEC) {
     664                req.ifa.ifa_family = addr.family;
     665            }
     666            addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen);
     667            any_len = addr.bytelen;
     668        } else if (arg == 5) { /* scope */
     669            uint32_t scope = 0;
     670            NEXT_ARG();
     671            if (rtnl_rtscope_a2n(&scope, *argv)) {
     672                invarg(*argv, "scope");
     673            }
     674            req.ifa.ifa_scope = scope;
     675            scoped = 1;
     676        } else if (arg == 6) { /* dev */
     677            NEXT_ARG();
     678            d = *argv;
     679        } else if (arg == 7) { /* label */
     680            NEXT_ARG();
     681            l = *argv;
     682            addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1);
     683        } else {
     684            if (arg == 8) /* local */
    633685                NEXT_ARG();
    634 
    635                 if (peer_len) {
    636                     duparg("peer", *argv);
    637                 }
    638                 get_prefix(&peer, *argv, req.ifa.ifa_family);
    639                 peer_len = peer.bytelen;
    640                 if (req.ifa.ifa_family == AF_UNSPEC) {
    641                     req.ifa.ifa_family = peer.family;
    642                 }
    643                 addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen);
    644                 req.ifa.ifa_prefixlen = peer.bitlen;
    645                 break;
    646             case 2: /* broadcast */
    647             case 3: /* brd */
    648             {
    649                 inet_prefix addr;
    650                 NEXT_ARG();
    651                 if (brd_len) {
    652                     duparg("broadcast", *argv);
    653                 }
    654                 if (LONE_CHAR(*argv, '+')) {
    655                     brd_len = -1;
    656                 }
    657                 else if (LONE_DASH(*argv)) {
    658                     brd_len = -2;
    659                 } else {
    660                     get_addr(&addr, *argv, req.ifa.ifa_family);
    661                     if (req.ifa.ifa_family == AF_UNSPEC)
    662                         req.ifa.ifa_family = addr.family;
    663                     addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen);
    664                     brd_len = addr.bytelen;
    665                 }
    666                 break;
    667             }
    668             case 4: /* anycast */
    669             {
    670                 inet_prefix addr;
    671                 NEXT_ARG();
    672                 if (any_len) {
    673                     duparg("anycast", *argv);
    674                 }
    675                 get_addr(&addr, *argv, req.ifa.ifa_family);
    676                 if (req.ifa.ifa_family == AF_UNSPEC) {
    677                     req.ifa.ifa_family = addr.family;
    678                 }
    679                 addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen);
    680                 any_len = addr.bytelen;
    681                 break;
    682             }
    683             case 5: /* scope */
    684             {
    685                 uint32_t scope = 0;
    686                 NEXT_ARG();
    687                 if (rtnl_rtscope_a2n(&scope, *argv)) {
    688                     invarg(*argv, "scope");
    689                 }
    690                 req.ifa.ifa_scope = scope;
    691                 scoped = 1;
    692                 break;
    693             }
    694             case 6: /* dev */
    695                 NEXT_ARG();
    696                 d = *argv;
    697                 break;
    698             case 7: /* label */
    699                 NEXT_ARG();
    700                 l = *argv;
    701                 addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l)+1);
    702                 break;
    703             case 8: /* local */
    704                 NEXT_ARG();
    705             default:
    706                 if (local_len) {
    707                     duparg2("local", *argv);
    708                 }
    709                 get_prefix(&lcl, *argv, req.ifa.ifa_family);
    710                 if (req.ifa.ifa_family == AF_UNSPEC) {
    711                     req.ifa.ifa_family = lcl.family;
    712                 }
    713                 addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen);
    714                 local_len = lcl.bytelen;
    715         }
    716         argc--;
     686            if (local_len) {
     687                duparg2("local", *argv);
     688            }
     689            get_prefix(&lcl, *argv, req.ifa.ifa_family);
     690            if (req.ifa.ifa_family == AF_UNSPEC) {
     691                req.ifa.ifa_family = lcl.family;
     692            }
     693            addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen);
     694            local_len = lcl.bytelen;
     695        }
    717696        argv++;
    718697    }
    719698
    720     if (d == NULL) {
    721         bb_error_msg(bb_msg_requires_arg,"\"dev\"");
    722         return -1;
     699    if (!d) {
     700        /* There was no "dev IFACE", but we need that */
     701        bb_error_msg_and_die("need \"dev IFACE\"");
    723702    }
    724703    if (l && strncmp(d, l, strlen(d)) != 0) {
     
    767746
    768747/* Return value becomes exitcode. It's okay to not return at all */
    769 int do_ipaddr(int argc, char **argv)
     748int FAST_FUNC do_ipaddr(char **argv)
    770749{
    771750    static const char commands[] ALIGN1 =
    772751        "add\0""delete\0""list\0""show\0""lst\0""flush\0";
    773 
    774     int command_num = 2; /* default command is list */
    775 
     752    smalluint cmd = 2;
    776753    if (*argv) {
    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 }
     754        cmd = index_in_substrings(commands, *argv);
     755        if (cmd > 5)
     756            bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
     757        argv++;
     758        if (cmd <= 1)
     759            return ipaddr_modify((cmd == 0) ? RTM_NEWADDR : RTM_DELADDR, argv);
     760    }
     761    /* 2 == list, 3 == show, 4 == lst */
     762    return ipaddr_list_or_flush(argv, cmd == 5);
     763}
  • branches/2.2.9/mindi-busybox/networking/libiproute/iplink.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * iplink.c "ip link".
    4  *
    53 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    64 *
    7  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
     5 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    86 */
    9 
    10 //#include <sys/ioctl.h>
    11 //#include <sys/socket.h>
    127#include <net/if.h>
    138#include <net/if_packet.h>
     
    1914#include "utils.h"
    2015
     16#ifndef IFLA_LINKINFO
     17# define IFLA_LINKINFO 18
     18# define IFLA_INFO_KIND 1
     19#endif
     20
    2121/* taken from linux/sockios.h */
    22 #define SIOCSIFNAME 0x8923      /* set interface name */
    23 
    24 static void on_off(const char *msg) ATTRIBUTE_NORETURN;
    25 static void on_off(const char *msg)
    26 {
    27     bb_error_msg_and_die("error: argument of \"%s\" must be \"on\" or \"off\"", msg);
    28 }
     22#define SIOCSIFNAME  0x8923  /* set interface name */
    2923
    3024/* Exits on error */
     
    4842    int fd;
    4943
    50     strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
     44    strncpy_IFNAMSIZ(ifr.ifr_name, dev);
    5145    fd = get_ctl_fd();
    5246    xioctl(fd, SIOCGIFFLAGS, &ifr);
     
    6559    int fd;
    6660
    67     strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
    68     strncpy(ifr.ifr_newname, newdev, sizeof(ifr.ifr_newname));
     61    strncpy_IFNAMSIZ(ifr.ifr_name, dev);
     62    strncpy_IFNAMSIZ(ifr.ifr_newname, newdev);
    6963    fd = get_ctl_fd();
    7064    xioctl(fd, SIOCSIFNAME, &ifr);
     
    8074    s = get_ctl_fd();
    8175    memset(&ifr, 0, sizeof(ifr));
    82     strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
     76    strncpy_IFNAMSIZ(ifr.ifr_name, dev);
    8377    ifr.ifr_qlen = qlen;
    8478    xioctl(s, SIOCSIFTXQLEN, &ifr);
     
    9488    s = get_ctl_fd();
    9589    memset(&ifr, 0, sizeof(ifr));
    96     strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
     90    strncpy_IFNAMSIZ(ifr.ifr_name, dev);
    9791    ifr.ifr_mtu = mtu;
    9892    xioctl(s, SIOCSIFMTU, &ifr);
     
    111105
    112106    memset(&ifr, 0, sizeof(ifr));
    113     strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
     107    strncpy_IFNAMSIZ(ifr.ifr_name, dev);
    114108    xioctl(s, SIOCGIFINDEX, &ifr);
    115109
     
    119113    me.sll_protocol = htons(ETH_P_LOOP);
    120114    xbind(s, (struct sockaddr*)&me, sizeof(me));
    121 
    122115    alen = sizeof(me);
    123     if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) {
    124         bb_perror_msg_and_die("getsockname");
    125     }
     116    getsockname(s, (struct sockaddr*)&me, &alen);
     117    //never happens:
     118    //if (getsockname(s, (struct sockaddr*)&me, &alen) == -1)
     119    //  bb_perror_msg_and_die("getsockname");
    126120    close(s);
    127121    *htype = me.sll_hatype;
     
    135129
    136130    memset(ifr, 0, sizeof(*ifr));
    137     strncpy(ifr->ifr_name, dev, sizeof(ifr->ifr_name));
     131    strncpy_IFNAMSIZ(ifr->ifr_name, dev);
    138132    ifr->ifr_hwaddr.sa_family = hatype;
    139     alen = ll_addr_a2n((unsigned char *)(ifr->ifr_hwaddr.sa_data), 14, lla);
     133
     134    alen = hatype == 1/*ARPHRD_ETHER*/ ? 14/*ETH_HLEN*/ : 19/*INFINIBAND_HLEN*/;
     135    alen = ll_addr_a2n((unsigned char *)(ifr->ifr_hwaddr.sa_data), alen, lla);
    140136    if (alen < 0)
    141         exit(1);
     137        exit(EXIT_FAILURE);
    142138    if (alen != halen) {
    143139        bb_error_msg_and_die("wrong address (%s) length: expected %d bytes", lla, halen);
     
    159155
    160156
     157static void die_must_be_on_off(const char *msg) NORETURN;
     158static void die_must_be_on_off(const char *msg)
     159{
     160    bb_error_msg_and_die("argument of \"%s\" must be \"on\" or \"off\"", msg);
     161}
     162
    161163/* Return value becomes exitcode. It's okay to not return at all */
    162 static int do_set(int argc, char **argv)
     164static int do_set(char **argv)
    163165{
    164166    char *dev = NULL;
     
    173175    int htype, halen;
    174176    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 };
     177        "up\0""down\0""name\0""mtu\0""qlen\0""multicast\0"
     178        "arp\0""address\0""dev\0";
     179    enum { ARG_up = 0, ARG_down, ARG_name, ARG_mtu, ARG_qlen, ARG_multicast,
     180        ARG_arp, ARG_addr, ARG_dev };
     181    static const char str_on_off[] ALIGN1 = "on\0""off\0";
     182    enum { PARM_on = 0, PARM_off };
    179183    smalluint key;
    180184
    181     while (argc > 0) {
    182         key = index_in_strings(keywords, *argv) + 1;
     185    while (*argv) {
     186        /* substring search ensures that e.g. "addr" and "address"
     187         * are both accepted */
     188        key = index_in_substrings(keywords, *argv);
    183189        if (key == ARG_up) {
    184190            mask |= IFF_UP;
     
    194200            if (mtu != -1)
    195201                duparg("mtu", *argv);
    196             if (get_integer(&mtu, *argv, 0))
    197                 invarg(*argv, "mtu");
    198         } else if (key == ARG_multicast) {
    199             NEXT_ARG();
    200             mask |= IFF_MULTICAST;
    201             key = index_in_strings(keywords, *argv) + 1;
    202             if (key == PARM_on) {
    203                 flags |= IFF_MULTICAST;
    204             } else if (key == PARM_off) {
    205                 flags &= ~IFF_MULTICAST;
    206             } else
    207                 on_off("multicast");
    208         } else if (key == ARG_arp) {
    209             NEXT_ARG();
    210             mask |= IFF_NOARP;
    211             key = index_in_strings(keywords, *argv) + 1;
    212             if (key == PARM_on) {
    213                 flags &= ~IFF_NOARP;
    214             } else if (key == PARM_off) {
    215                 flags |= IFF_NOARP;
    216             } else
    217                 on_off("arp");
     202            mtu = get_unsigned(*argv, "mtu");
     203        } else if (key == ARG_qlen) {
     204            NEXT_ARG();
     205            if (qlen != -1)
     206                duparg("qlen", *argv);
     207            qlen = get_unsigned(*argv, "qlen");
    218208        } else if (key == ARG_addr) {
    219209            NEXT_ARG();
    220210            newaddr = *argv;
    221         } else {
     211        } else if (key >= ARG_dev) {
    222212            if (key == ARG_dev) {
    223213                NEXT_ARG();
     
    226216                duparg2("dev", *argv);
    227217            dev = *argv;
    228         }
    229         argc--; argv++;
     218        } else {
     219            int param;
     220            NEXT_ARG();
     221            param = index_in_strings(str_on_off, *argv);
     222            if (key == ARG_multicast) {
     223                if (param < 0)
     224                    die_must_be_on_off("multicast");
     225                mask |= IFF_MULTICAST;
     226                if (param == PARM_on)
     227                    flags |= IFF_MULTICAST;
     228                else
     229                    flags &= ~IFF_MULTICAST;
     230            } else if (key == ARG_arp) {
     231                if (param < 0)
     232                    die_must_be_on_off("arp");
     233                mask |= IFF_NOARP;
     234                if (param == PARM_on)
     235                    flags &= ~IFF_NOARP;
     236                else
     237                    flags |= IFF_NOARP;
     238            }
     239        }
     240        argv++;
    230241    }
    231242
     
    238249        if (newaddr) {
    239250            parse_address(dev, htype, halen, newaddr, &ifr0);
     251            set_address(&ifr0, 0);
    240252        }
    241253        if (newbrd) {
    242254            parse_address(dev, htype, halen, newbrd, &ifr1);
     255            set_address(&ifr1, 1);
    243256        }
    244257    }
     
    254267        set_mtu(dev, mtu);
    255268    }
    256     if (newaddr || newbrd) {
    257         if (newbrd) {
    258             set_address(&ifr1, 1);
    259         }
    260         if (newaddr) {
    261             set_address(&ifr0, 0);
    262         }
    263     }
    264269    if (mask)
    265270        do_chflags(dev, flags, mask);
     
    267272}
    268273
    269 static int ipaddr_list_link(int argc, char **argv)
     274static int ipaddr_list_link(char **argv)
    270275{
    271276    preferred_family = AF_PACKET;
    272     return ipaddr_list_or_flush(argc, argv, 0);
    273 }
    274 
     277    return ipaddr_list_or_flush(argv, 0);
     278}
     279
     280#ifndef NLMSG_TAIL
     281#define NLMSG_TAIL(nmsg) \
     282    ((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
     283#endif
    275284/* Return value becomes exitcode. It's okay to not return at all */
    276 int do_iplink(int argc, char **argv)
     285static int do_change(char **argv, const unsigned rtm)
    277286{
    278287    static const char keywords[] ALIGN1 =
    279         "set\0""show\0""lst\0""list\0";
    280     smalluint key;
    281     if (argc <= 0)
    282         return ipaddr_list_link(0, NULL);
    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 }
     288        "link\0""name\0""type\0""dev\0";
     289    enum {
     290        ARG_link,
     291        ARG_name,
     292        ARG_type,
     293        ARG_dev,
     294    };
     295    struct rtnl_handle rth;
     296    struct {
     297        struct nlmsghdr  n;
     298        struct ifinfomsg i;
     299        char             buf[1024];
     300    } req;
     301    smalluint arg;
     302    char *name_str = NULL, *link_str = NULL, *type_str = NULL, *dev_str = NULL;
     303
     304    memset(&req, 0, sizeof(req));
     305
     306    req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
     307    req.n.nlmsg_flags = NLM_F_REQUEST;
     308    req.n.nlmsg_type = rtm;
     309    req.i.ifi_family = preferred_family;
     310    if (rtm == RTM_NEWLINK)
     311        req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
     312
     313    while (*argv) {
     314        arg = index_in_substrings(keywords, *argv);
     315        if (arg == ARG_link) {
     316            NEXT_ARG();
     317            link_str = *argv;
     318        } else if (arg == ARG_name) {
     319            NEXT_ARG();
     320            name_str = *argv;
     321        } else if (arg == ARG_type) {
     322            NEXT_ARG();
     323            type_str = *argv;
     324        } else {
     325            if (arg == ARG_dev) {
     326                if (dev_str)
     327                    duparg(*argv, "dev");
     328                NEXT_ARG();
     329            }
     330            dev_str = *argv;
     331        }
     332        argv++;
     333    }
     334    xrtnl_open(&rth);
     335    ll_init_map(&rth);
     336    if (type_str) {
     337        struct rtattr *linkinfo = NLMSG_TAIL(&req.n);
     338
     339        addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0);
     340        addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, type_str,
     341                strlen(type_str));
     342        linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo;
     343    }
     344    if (rtm != RTM_NEWLINK) {
     345        if (!dev_str)
     346            return 1; /* Need a device to delete */
     347        req.i.ifi_index = xll_name_to_index(dev_str);
     348    } else {
     349        if (!name_str)
     350            name_str = dev_str;
     351        if (link_str) {
     352            int idx = xll_name_to_index(link_str);
     353            addattr_l(&req.n, sizeof(req), IFLA_LINK, &idx, 4);
     354        }
     355    }
     356    if (name_str) {
     357        const size_t name_len = strlen(name_str) + 1;
     358        if (name_len < 2 || name_len > IFNAMSIZ)
     359            invarg(name_str, "name");
     360        addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name_str, name_len);
     361    }
     362    if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
     363        return 2;
     364    return 0;
     365}
     366
     367/* Return value becomes exitcode. It's okay to not return at all */
     368int FAST_FUNC do_iplink(char **argv)
     369{
     370    static const char keywords[] ALIGN1 =
     371        "add\0""delete\0""set\0""show\0""lst\0""list\0";
     372    if (*argv) {
     373        smalluint key = index_in_substrings(keywords, *argv);
     374        if (key > 5) /* invalid argument */
     375            bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
     376        argv++;
     377        if (key <= 1) /* add/delete */
     378            return do_change(argv, key ? RTM_DELLINK : RTM_NEWLINK);
     379        else if (key == 2) /* set */
     380            return do_set(argv);
     381    }
     382    /* show, lst, list */
     383    return ipaddr_list_link(argv);
     384}
  • branches/2.2.9/mindi-busybox/networking/libiproute/iproute.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * iproute.c        "ip route".
     3 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    44 *
    5  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
    6  *
    7  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    8  *
     5 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    96 *
    107 * Changes:
    118 *
    12  * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
     9 * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
    1310 * Kunihiro Ishiguro <kunihiro@zebra.org> 001102: rtnh_ifindex was not initialized
    1411 */
    1512
    16 #include "ip_common.h"  /* #include "libbb.h" is inside */
     13#include "ip_common.h"  /* #include "libbb.h" is inside */
    1714#include "rt_names.h"
    1815#include "utils.h"
     
    2320
    2421
    25 typedef struct filter_t {
     22struct filter_t {
    2623    int tb;
    27     int flushed;
     24    smallint flushed;
    2825    char *flushb;
    2926    int flushp;
    3027    int flushe;
    3128    struct rtnl_handle *rth;
    32     int protocol, protocolmask;
    33     int scope, scopemask;
    34     int type, typemask;
    35     int tos, tosmask;
     29    //int protocol, protocolmask; - write-only fields?!
     30    //int scope, scopemask; - unused
     31    //int type; - read-only
     32    //int typemask; - unused
     33    //int tos, tosmask; - unused
    3634    int iif, iifmask;
    3735    int oif, oifmask;
    38     int realm, realmmask;
    39     inet_prefix rprefsrc;
     36    //int realm, realmmask; - unused
     37    //inet_prefix rprefsrc; - read-only
    4038    inet_prefix rvia;
    4139    inet_prefix rdst;
     
    4341    inet_prefix rsrc;
    4442    inet_prefix msrc;
    45 } filter_t;
    46 
    47 #define filter (*(filter_t*)&bb_common_bufsiz1)
     43} FIX_ALIASING;
     44typedef struct filter_t filter_t;
     45
     46#define G_filter (*(filter_t*)&bb_common_bufsiz1)
    4847
    4948static int flush_update(void)
    5049{
    51     if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) {
    52         bb_perror_msg("failed to send flush request");
     50    if (rtnl_send(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) {
     51        bb_perror_msg("can't send flush request");
    5352        return -1;
    5453    }
    55     filter.flushp = 0;
     54    G_filter.flushp = 0;
    5655    return 0;
    5756}
     
    6564        return hz_internal;
    6665
    67     fp = fopen("/proc/net/psched", "r");
     66    fp = fopen_for_read("/proc/net/psched");
    6867    if (fp) {
    6968        unsigned nom, denom;
     
    7978}
    8079
    81 static int print_route(struct sockaddr_nl *who ATTRIBUTE_UNUSED,
    82         struct nlmsghdr *n, void *arg)
     80static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
     81        struct nlmsghdr *n, void *arg UNUSED_PARAM)
    8382{
    84     FILE *fp = (FILE*)arg;
    8583    struct rtmsg *r = NLMSG_DATA(n);
    8684    int len = n->nlmsg_len;
     
    9290    SPRINT_BUF(b1);
    9391
    94 
    9592    if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) {
    9693        fprintf(stderr, "Not a route: %08x %08x %08x\n",
     
    9895        return 0;
    9996    }
    100     if (filter.flushb && n->nlmsg_type != RTM_NEWROUTE)
     97    if (G_filter.flushb && n->nlmsg_type != RTM_NEWROUTE)
    10198        return 0;
    10299    len -= NLMSG_LENGTH(sizeof(*r));
     
    110107
    111108    if (r->rtm_family == AF_INET6) {
    112         if (filter.tb) {
    113             if (filter.tb < 0) {
    114                 if (!(r->rtm_flags&RTM_F_CLONED)) {
     109        if (G_filter.tb) {
     110            if (G_filter.tb < 0) {
     111                if (!(r->rtm_flags & RTM_F_CLONED)) {
    115112                    return 0;
    116113                }
    117114            } else {
    118                 if (r->rtm_flags&RTM_F_CLONED) {
     115                if (r->rtm_flags & RTM_F_CLONED) {
    119116                    return 0;
    120117                }
    121                 if (filter.tb == RT_TABLE_LOCAL) {
     118                if (G_filter.tb == RT_TABLE_LOCAL) {
    122119                    if (r->rtm_type != RTN_LOCAL) {
    123120                        return 0;
    124121                    }
    125                 } else if (filter.tb == RT_TABLE_MAIN) {
     122                } else if (G_filter.tb == RT_TABLE_MAIN) {
    126123                    if (r->rtm_type == RTN_LOCAL) {
    127124                        return 0;
     
    133130        }
    134131    } else {
    135         if (filter.tb > 0 && filter.tb != r->rtm_table) {
     132        if (G_filter.tb > 0 && G_filter.tb != r->rtm_table) {
    136133            return 0;
    137134        }
    138135    }
    139     if (filter.rdst.family &&
    140         (r->rtm_family != filter.rdst.family || filter.rdst.bitlen > r->rtm_dst_len)) {
    141         return 0;
    142     }
    143     if (filter.mdst.family &&
    144         (r->rtm_family != filter.mdst.family ||
    145          (filter.mdst.bitlen >= 0 && filter.mdst.bitlen < r->rtm_dst_len))) {
    146         return 0;
    147     }
    148     if (filter.rsrc.family &&
    149         (r->rtm_family != filter.rsrc.family || filter.rsrc.bitlen > r->rtm_src_len)) {
    150         return 0;
    151     }
    152     if (filter.msrc.family &&
    153         (r->rtm_family != filter.msrc.family ||
    154          (filter.msrc.bitlen >= 0 && filter.msrc.bitlen < r->rtm_src_len))) {
     136    if (G_filter.rdst.family
     137     && (r->rtm_family != G_filter.rdst.family || G_filter.rdst.bitlen > r->rtm_dst_len)
     138    ) {
     139        return 0;
     140    }
     141    if (G_filter.mdst.family
     142     && (r->rtm_family != G_filter.mdst.family
     143        || (G_filter.mdst.bitlen >= 0 && G_filter.mdst.bitlen < r->rtm_dst_len)
     144        )
     145    ) {
     146        return 0;
     147    }
     148    if (G_filter.rsrc.family
     149     && (r->rtm_family != G_filter.rsrc.family || G_filter.rsrc.bitlen > r->rtm_src_len)
     150    ) {
     151        return 0;
     152    }
     153    if (G_filter.msrc.family
     154     && (r->rtm_family != G_filter.msrc.family
     155        || (G_filter.msrc.bitlen >= 0 && G_filter.msrc.bitlen < r->rtm_src_len)
     156        )
     157    ) {
    155158        return 0;
    156159    }
     
    159162    parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
    160163
    161     if (filter.rdst.family && inet_addr_match(&dst, &filter.rdst, filter.rdst.bitlen))
    162         return 0;
    163     if (filter.mdst.family && filter.mdst.bitlen >= 0 &&
    164         inet_addr_match(&dst, &filter.mdst, r->rtm_dst_len))
    165         return 0;
    166 
    167     if (filter.rsrc.family && inet_addr_match(&src, &filter.rsrc, filter.rsrc.bitlen))
    168         return 0;
    169     if (filter.msrc.family && filter.msrc.bitlen >= 0 &&
    170         inet_addr_match(&src, &filter.msrc, r->rtm_src_len))
    171         return 0;
    172 
    173     if (filter.flushb &&
    174         r->rtm_family == AF_INET6 &&
    175         r->rtm_dst_len == 0 &&
    176         r->rtm_type == RTN_UNREACHABLE &&
    177         tb[RTA_PRIORITY] &&
    178         *(int*)RTA_DATA(tb[RTA_PRIORITY]) == -1)
    179         return 0;
    180 
    181     if (filter.flushb) {
     164    if (G_filter.rdst.family
     165     && inet_addr_match(&dst, &G_filter.rdst, G_filter.rdst.bitlen)
     166    ) {
     167        return 0;
     168    }
     169    if (G_filter.mdst.family
     170     && G_filter.mdst.bitlen >= 0
     171     && inet_addr_match(&dst, &G_filter.mdst, r->rtm_dst_len)
     172    ) {
     173        return 0;
     174    }
     175    if (G_filter.rsrc.family
     176     && inet_addr_match(&src, &G_filter.rsrc, G_filter.rsrc.bitlen)
     177    ) {
     178        return 0;
     179    }
     180    if (G_filter.msrc.family && G_filter.msrc.bitlen >= 0
     181     && inet_addr_match(&src, &G_filter.msrc, r->rtm_src_len)
     182    ) {
     183        return 0;
     184    }
     185    if (G_filter.flushb
     186     && r->rtm_family == AF_INET6
     187     && r->rtm_dst_len == 0
     188     && r->rtm_type == RTN_UNREACHABLE
     189     && tb[RTA_PRIORITY]
     190     && *(int*)RTA_DATA(tb[RTA_PRIORITY]) == -1
     191    ) {
     192        return 0;
     193    }
     194
     195    if (G_filter.flushb) {
    182196        struct nlmsghdr *fn;
    183         if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
     197        if (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len > G_filter.flushe) {
    184198            if (flush_update())
    185199                bb_error_msg_and_die("flush");
    186200        }
    187         fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp));
     201        fn = (struct nlmsghdr*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp));
    188202        memcpy(fn, n, n->nlmsg_len);
    189203        fn->nlmsg_type = RTM_DELROUTE;
    190204        fn->nlmsg_flags = NLM_F_REQUEST;
    191         fn->nlmsg_seq = ++filter.rth->seq;
    192         filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb;
    193         filter.flushed++;
     205        fn->nlmsg_seq = ++G_filter.rth->seq;
     206        G_filter.flushp = (((char*)fn) + n->nlmsg_len) - G_filter.flushb;
     207        G_filter.flushed = 1;
    194208        return 0;
    195209    }
    196210
    197211    if (n->nlmsg_type == RTM_DELROUTE) {
    198         fprintf(fp, "Deleted ");
    199     }
    200     if (r->rtm_type != RTN_UNICAST && !filter.type) {
    201         fprintf(fp, "%s ", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1)));
     212        printf("Deleted ");
     213    }
     214    if (r->rtm_type != RTN_UNICAST /* && !G_filter.type - always 0 */) {
     215        printf("%s ", rtnl_rtntype_n2a(r->rtm_type, b1));
    202216    }
    203217
    204218    if (tb[RTA_DST]) {
    205219        if (r->rtm_dst_len != host_len) {
    206             fprintf(fp, "%s/%u ", rt_addr_n2a(r->rtm_family,
    207                              RTA_PAYLOAD(tb[RTA_DST]),
    208                              RTA_DATA(tb[RTA_DST]),
    209                              abuf, sizeof(abuf)),
    210                 r->rtm_dst_len
    211                 );
     220            printf("%s/%u ", rt_addr_n2a(r->rtm_family,
     221                        RTA_DATA(tb[RTA_DST]),
     222                        abuf, sizeof(abuf)),
     223                    r->rtm_dst_len
     224                    );
    212225        } else {
    213             fprintf(fp, "%s ", format_host(r->rtm_family,
    214                                RTA_PAYLOAD(tb[RTA_DST]),
    215                                RTA_DATA(tb[RTA_DST]),
    216                                abuf, sizeof(abuf))
    217                 );
     226            printf("%s ", format_host(r->rtm_family,
     227                        RTA_PAYLOAD(tb[RTA_DST]),
     228                        RTA_DATA(tb[RTA_DST]),
     229                        abuf, sizeof(abuf))
     230                    );
    218231        }
    219232    } else if (r->rtm_dst_len) {
    220         fprintf(fp, "0/%d ", r->rtm_dst_len);
     233        printf("0/%d ", r->rtm_dst_len);
    221234    } else {
    222         fprintf(fp, "default ");
     235        printf("default ");
    223236    }
    224237    if (tb[RTA_SRC]) {
    225238        if (r->rtm_src_len != host_len) {
    226             fprintf(fp, "from %s/%u ", rt_addr_n2a(r->rtm_family,
    227                              RTA_PAYLOAD(tb[RTA_SRC]),
    228                              RTA_DATA(tb[RTA_SRC]),
    229                              abuf, sizeof(abuf)),
    230                 r->rtm_src_len
    231                 );
     239            printf("from %s/%u ", rt_addr_n2a(r->rtm_family,
     240                        RTA_DATA(tb[RTA_SRC]),
     241                        abuf, sizeof(abuf)),
     242                    r->rtm_src_len
     243                    );
    232244        } else {
    233             fprintf(fp, "from %s ", format_host(r->rtm_family,
    234                                RTA_PAYLOAD(tb[RTA_SRC]),
    235                                RTA_DATA(tb[RTA_SRC]),
    236                                abuf, sizeof(abuf))
    237                 );
     245            printf("from %s ", format_host(r->rtm_family,
     246                        RTA_PAYLOAD(tb[RTA_SRC]),
     247                        RTA_DATA(tb[RTA_SRC]),
     248                        abuf, sizeof(abuf))
     249                    );
    238250        }
    239251    } else if (r->rtm_src_len) {
    240         fprintf(fp, "from 0/%u ", r->rtm_src_len);
    241     }
    242     if (tb[RTA_GATEWAY] && filter.rvia.bitlen != host_len) {
    243         fprintf(fp, "via %s ",
    244             format_host(r->rtm_family,
    245                     RTA_PAYLOAD(tb[RTA_GATEWAY]),
    246                     RTA_DATA(tb[RTA_GATEWAY]),
    247                     abuf, sizeof(abuf)));
    248     }
    249     if (tb[RTA_OIF] && filter.oifmask != -1) {
    250         fprintf(fp, "dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF])));
    251     }
    252 
    253     if (tb[RTA_PREFSRC] && filter.rprefsrc.bitlen != host_len) {
     252        printf("from 0/%u ", r->rtm_src_len);
     253    }
     254    if (tb[RTA_GATEWAY] && G_filter.rvia.bitlen != host_len) {
     255        printf("via %s ", format_host(r->rtm_family,
     256                    RTA_PAYLOAD(tb[RTA_GATEWAY]),
     257                    RTA_DATA(tb[RTA_GATEWAY]),
     258                    abuf, sizeof(abuf)));
     259    }
     260    if (tb[RTA_OIF] && G_filter.oifmask != -1) {
     261        printf("dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF])));
     262    }
     263
     264    if (tb[RTA_PREFSRC] && /*G_filter.rprefsrc.bitlen - always 0*/ 0 != host_len) {
    254265        /* Do not use format_host(). It is our local addr
    255266           and symbolic name will not be useful.
    256267         */
    257         fprintf(fp, " src %s ",
    258             rt_addr_n2a(r->rtm_family,
    259                     RTA_PAYLOAD(tb[RTA_PREFSRC]),
    260                     RTA_DATA(tb[RTA_PREFSRC]),
    261                     abuf, sizeof(abuf)));
     268        printf(" src %s ", rt_addr_n2a(r->rtm_family,
     269                    RTA_DATA(tb[RTA_PREFSRC]),
     270                    abuf, sizeof(abuf)));
    262271    }
    263272    if (tb[RTA_PRIORITY]) {
    264         fprintf(fp, " metric %d ", *(uint32_t*)RTA_DATA(tb[RTA_PRIORITY]));
     273        printf(" metric %d ", *(uint32_t*)RTA_DATA(tb[RTA_PRIORITY]));
    265274    }
    266275    if (r->rtm_family == AF_INET6) {
     
    271280        if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) {
    272281            if (r->rtm_flags & RTM_F_CLONED) {
    273                 fprintf(fp, "%c    cache ", _SL_);
     282                printf("%c    cache ", _SL_);
    274283            }
    275284            if (ci->rta_expires) {
    276                 fprintf(fp, " expires %dsec", ci->rta_expires / get_hz());
     285                printf(" expires %dsec", ci->rta_expires / get_hz());
    277286            }
    278287            if (ci->rta_error != 0) {
    279                 fprintf(fp, " error %d", ci->rta_error);
     288                printf(" error %d", ci->rta_error);
    280289            }
    281290        } else if (ci) {
    282291            if (ci->rta_error != 0)
    283                 fprintf(fp, " error %d", ci->rta_error);
    284         }
    285     }
    286     if (tb[RTA_IIF] && filter.iifmask != -1) {
    287         fprintf(fp, " iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF])));
    288     }
    289     fputc('\n', fp);
    290     fflush(fp);
     292                printf(" error %d", ci->rta_error);
     293        }
     294    }
     295    if (tb[RTA_IIF] && G_filter.iifmask != -1) {
     296        printf(" iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF])));
     297    }
     298    bb_putchar('\n');
    291299    return 0;
    292300}
    293301
    294302/* Return value becomes exitcode. It's okay to not return at all */
    295 static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
     303static int iproute_modify(int cmd, unsigned flags, char **argv)
    296304{
    297305    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";
     306        "src\0""via\0""mtu\0""lock\0""protocol\0"IF_FEATURE_IP_RULE("table\0")
     307        "dev\0""oif\0""to\0""metric\0";
    300308    enum {
    301309        ARG_src,
     
    303311        ARG_mtu, PARM_lock,
    304312        ARG_protocol,
    305 USE_FEATURE_IP_RULE(ARG_table,)
     313IF_FEATURE_IP_RULE(ARG_table,)
    306314        ARG_dev,
    307315        ARG_oif,
    308         ARG_to
     316        ARG_to,
     317        ARG_metric,
    309318    };
    310319    enum {
     
    316325    struct rtnl_handle rth;
    317326    struct {
    318         struct nlmsghdr     n;
    319         struct rtmsg        r;
    320         char            buf[1024];
     327        struct nlmsghdr n;
     328        struct rtmsg    r;
     329        char            buf[1024];
    321330    } req;
    322331    char mxbuf[256];
     
    330339
    331340    req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
    332     req.n.nlmsg_flags = NLM_F_REQUEST|flags;
     341    req.n.nlmsg_flags = NLM_F_REQUEST | flags;
    333342    req.n.nlmsg_type = cmd;
    334343    req.r.rtm_family = preferred_family;
    335     req.r.rtm_table = RT_TABLE_MAIN;
    336     req.r.rtm_scope = RT_SCOPE_NOWHERE;
     344    if (RT_TABLE_MAIN) /* if it is zero, memset already did it */
     345        req.r.rtm_table = RT_TABLE_MAIN;
     346    if (RT_SCOPE_NOWHERE)
     347        req.r.rtm_scope = RT_SCOPE_NOWHERE;
    337348
    338349    if (cmd != RTM_DELROUTE) {
     
    345356    mxrta->rta_len = RTA_LENGTH(0);
    346357
    347     while (argc > 0) {
     358    while (*argv) {
    348359        arg = index_in_substrings(keywords, *argv);
    349360        if (arg == ARG_src) {
     
    367378            NEXT_ARG();
    368379            if (index_in_strings(keywords, *argv) == PARM_lock) {
    369                 mxlock |= (1<<RTAX_MTU);
    370                 NEXT_ARG();
    371             }
    372             if (get_unsigned(&mtu, *argv, 0))
    373                 invarg(*argv, "mtu");
     380                mxlock |= (1 << RTAX_MTU);
     381                NEXT_ARG();
     382            }
     383            mtu = get_unsigned(*argv, "mtu");
    374384            rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu);
    375385        } else if (arg == ARG_protocol) {
     
    391401            NEXT_ARG();
    392402            d = *argv;
     403        } else if (arg == ARG_metric) {
     404            uint32_t metric;
     405            NEXT_ARG();
     406            metric = get_u32(*argv, "metric");
     407            addattr32(&req.n, sizeof(req), RTA_PRIORITY, metric);
    393408        } else {
    394409            int type;
     
    399414            }
    400415            if ((**argv < '0' || **argv > '9')
    401                 && rtnl_rtntype_a2n(&type, *argv) == 0) {
     416             && rtnl_rtntype_a2n(&type, *argv) == 0) {
    402417                NEXT_ARG();
    403418                req.r.rtm_type = type;
     
    418433            }
    419434        }
    420         argc--; argv++;
     435        argv++;
    421436    }
    422437
     
    443458    if (req.r.rtm_type == RTN_LOCAL || req.r.rtm_type == RTN_NAT)
    444459        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)
     460    else
     461    if (req.r.rtm_type == RTN_BROADCAST
     462     || req.r.rtm_type == RTN_MULTICAST
     463     || req.r.rtm_type == RTN_ANYCAST
     464    ) {
    448465        req.r.rtm_scope = RT_SCOPE_LINK;
     466    }
    449467    else if (req.r.rtm_type == RTN_UNICAST || req.r.rtm_type == RTN_UNSPEC) {
    450468        if (cmd == RTM_DELROUTE)
     
    478496
    479497    req.nlh.nlmsg_len = sizeof(req);
    480     req.nlh.nlmsg_type = RTM_GETROUTE;
    481     req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_REQUEST;
    482     req.nlh.nlmsg_pid = 0;
     498    if (RTM_GETROUTE)
     499        req.nlh.nlmsg_type = RTM_GETROUTE;
     500    if (NLM_F_ROOT | NLM_F_REQUEST)
     501        req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_REQUEST;
     502    /*req.nlh.nlmsg_pid = 0; - memset did it already */
    483503    req.nlh.nlmsg_seq = rth->dump = ++rth->seq;
    484504    req.rtm.rtm_family = family;
    485     req.rtm.rtm_flags |= RTM_F_CLONED;
     505    if (RTM_F_CLONED)
     506        req.rtm.rtm_flags = RTM_F_CLONED;
    486507
    487508    return xsendto(rth->fd, (void*)&req, sizeof(req), (struct sockaddr*)&nladdr, sizeof(nladdr));
     
    498519
    499520    if (write(flush_fd, "-1", 2) < 2) {
    500         bb_perror_msg("cannot flush routing cache");
     521        bb_perror_msg("can't flush routing cache");
    501522        return;
    502523    }
     
    506527static void iproute_reset_filter(void)
    507528{
    508     memset(&filter, 0, sizeof(filter));
    509     filter.mdst.bitlen = -1;
    510     filter.msrc.bitlen = -1;
     529    memset(&G_filter, 0, sizeof(G_filter));
     530    G_filter.mdst.bitlen = -1;
     531    G_filter.msrc.bitlen = -1;
    511532}
    512533
    513534/* Return value becomes exitcode. It's okay to not return at all */
    514 static int iproute_list_or_flush(int argc, char **argv, int flush)
     535static int iproute_list_or_flush(char **argv, int flush)
    515536{
    516537    int do_ipv6 = preferred_family;
     
    519540    char *od = NULL;
    520541    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*/;
     542        /* "ip route list/flush" parameters: */
     543        "protocol\0" "dev\0"   "oif\0"   "iif\0"
     544        "via\0"      "table\0" "cache\0"
     545        "from\0"     "to\0"
     546        /* and possible further keywords */
     547        "all\0"
     548        "root\0"
     549        "match\0"
     550        "exact\0"
     551        "main\0"
     552        ;
    523553    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*/
     554        KW_proto, KW_dev,   KW_oif,  KW_iif,
     555        KW_via,   KW_table, KW_cache,
     556        KW_from,  KW_to,
     557        /* */
     558        KW_all,
     559        KW_root,
     560        KW_match,
     561        KW_exact,
     562        KW_main,
    532563    };
    533564    int arg, parm;
     565
    534566    iproute_reset_filter();
    535     filter.tb = RT_TABLE_MAIN;
    536 
    537     if (flush && argc <= 0)
     567    G_filter.tb = RT_TABLE_MAIN;
     568
     569    if (flush && !*argv)
    538570        bb_error_msg_and_die(bb_msg_requires_arg, "\"ip route flush\"");
    539571
    540     while (argc > 0) {
     572    while (*argv) {
    541573        arg = index_in_substrings(keywords, *argv);
    542         if (arg == ARG_proto) {
     574        if (arg == KW_proto) {
    543575            uint32_t prot = 0;
    544576            NEXT_ARG();
    545             filter.protocolmask = -1;
     577            //G_filter.protocolmask = -1;
    546578            if (rtnl_rtprot_a2n(&prot, *argv)) {
    547                 if (index_in_strings(keywords, *argv) != PARM_all)
     579                if (index_in_strings(keywords, *argv) != KW_all)
    548580                    invarg(*argv, "protocol");
    549581                prot = 0;
    550                 filter.protocolmask = 0;
    551             }
    552             filter.protocol = prot;
    553         } else if (arg == ARG_dev || arg == ARG_oif) {
     582                //G_filter.protocolmask = 0;
     583            }
     584            //G_filter.protocol = prot;
     585        } else if (arg == KW_dev || arg == KW_oif) {
    554586            NEXT_ARG();
    555587            od = *argv;
    556         } else if (arg == ARG_iif) {
     588        } else if (arg == KW_iif) {
    557589            NEXT_ARG();
    558590            id = *argv;
    559         } else if (arg == ARG_via) {
    560             NEXT_ARG();
    561             get_prefix(&filter.rvia, *argv, do_ipv6);
    562         } else if (arg == ARG_table) {
     591        } else if (arg == KW_via) {
     592            NEXT_ARG();
     593            get_prefix(&G_filter.rvia, *argv, do_ipv6);
     594        } else if (arg == KW_table) { /* table all/cache/main */
    563595            NEXT_ARG();
    564596            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
     597            if (parm == KW_cache)
     598                G_filter.tb = -1;
     599            else if (parm == KW_all)
     600                G_filter.tb = 0;
     601            else if (parm != KW_main) {
     602#if ENABLE_FEATURE_IP_RULE
     603                uint32_t tid;
     604                if (rtnl_rttable_a2n(&tid, *argv))
     605                    invarg(*argv, "table");
     606                G_filter.tb = tid;
     607#else
    570608                invarg(*argv, "table");
    571         } else if (arg == ARG_from) {
     609#endif
     610            }
     611        } else if (arg == KW_cache) {
     612            /* The command 'ip route flush cache' is used by OpenSWAN.
     613             * Assuming it's a synonym for 'ip route flush table cache' */
     614            G_filter.tb = -1;
     615        } else if (arg == KW_from) {
    572616            NEXT_ARG();
    573617            parm = index_in_substrings(keywords, *argv);
    574             if (parm == PARM_root) {
    575                 NEXT_ARG();
    576                 get_prefix(&filter.rsrc, *argv, do_ipv6);
    577             } else if (parm == PARM_match) {
    578                 NEXT_ARG();
    579                 get_prefix(&filter.msrc, *argv, do_ipv6);
     618            if (parm == KW_root) {
     619                NEXT_ARG();
     620                get_prefix(&G_filter.rsrc, *argv, do_ipv6);
     621            } else if (parm == KW_match) {
     622                NEXT_ARG();
     623                get_prefix(&G_filter.msrc, *argv, do_ipv6);
    580624            } else {
    581                 if (parm == PARM_exact)
     625                if (parm == KW_exact)
    582626                    NEXT_ARG();
    583                 get_prefix(&filter.msrc, *argv, do_ipv6);
    584                 filter.rsrc = filter.msrc;
    585             }
    586         } else {
    587             /* parm = arg; // would be more plausible, we reuse arg here */
    588             if (arg == ARG_to) {
     627                get_prefix(&G_filter.msrc, *argv, do_ipv6);
     628                G_filter.rsrc = G_filter.msrc;
     629            }
     630        } else { /* "to" is the default parameter */
     631            if (arg == KW_to) {
    589632                NEXT_ARG();
    590633                arg = index_in_substrings(keywords, *argv);
    591634            }
    592             if (arg == PARM_root) {
    593                 NEXT_ARG();
    594                 get_prefix(&filter.rdst, *argv, do_ipv6);
    595             } else if (arg == PARM_match) {
    596                 NEXT_ARG();
    597                 get_prefix(&filter.mdst, *argv, do_ipv6);
    598             } else {
    599                 if (arg == PARM_exact)
     635            /* parm = arg; - would be more plausible, but we reuse 'arg' here */
     636            if (arg == KW_root) {
     637                NEXT_ARG();
     638                get_prefix(&G_filter.rdst, *argv, do_ipv6);
     639            } else if (arg == KW_match) {
     640                NEXT_ARG();
     641                get_prefix(&G_filter.mdst, *argv, do_ipv6);
     642            } else { /* "to exact" is the default */
     643                if (arg == KW_exact)
    600644                    NEXT_ARG();
    601                 get_prefix(&filter.mdst, *argv, do_ipv6);
    602                 filter.rdst = filter.mdst;
    603             }
    604         }
    605         argc--;
     645                get_prefix(&G_filter.mdst, *argv, do_ipv6);
     646                G_filter.rdst = G_filter.mdst;
     647            }
     648        }
    606649        argv++;
    607650    }
    608651
    609     if (do_ipv6 == AF_UNSPEC && filter.tb) {
     652    if (do_ipv6 == AF_UNSPEC && G_filter.tb) {
    610653        do_ipv6 = AF_INET;
    611654    }
    612655
    613656    xrtnl_open(&rth);
    614 
    615657    ll_init_map(&rth);
    616658
     
    620662        if (id) {
    621663            idx = xll_name_to_index(id);
    622             filter.iif = idx;
    623             filter.iifmask = -1;
     664            G_filter.iif = idx;
     665            G_filter.iifmask = -1;
    624666        }
    625667        if (od) {
    626668            idx = xll_name_to_index(od);
    627             filter.oif = idx;
    628             filter.oifmask = -1;
     669            G_filter.oif = idx;
     670            G_filter.oifmask = -1;
    629671        }
    630672    }
     
    633675        char flushb[4096-512];
    634676
    635         if (filter.tb == -1) {
     677        if (G_filter.tb == -1) { /* "flush table cache" */
    636678            if (do_ipv6 != AF_INET6)
    637679                iproute_flush_cache();
     
    640682        }
    641683
    642         filter.flushb = flushb;
    643         filter.flushp = 0;
    644         filter.flushe = sizeof(flushb);
    645         filter.rth = &rth;
     684        G_filter.flushb = flushb;
     685        G_filter.flushp = 0;
     686        G_filter.flushe = sizeof(flushb);
     687        G_filter.rth = &rth;
    646688
    647689        for (;;) {
    648690            xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
    649             filter.flushed = 0;
    650             xrtnl_dump_filter(&rth, print_route, stdout);
    651             if (filter.flushed == 0)
     691            G_filter.flushed = 0;
     692            xrtnl_dump_filter(&rth, print_route, NULL);
     693            if (G_filter.flushed == 0)
    652694                return 0;
    653695            if (flush_update())
     
    656698    }
    657699
    658     if (filter.tb != -1) {
     700    if (G_filter.tb != -1) {
    659701        xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
    660702    } 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);
     703        bb_perror_msg_and_die("can't send dump request");
     704    }
     705    xrtnl_dump_filter(&rth, print_route, NULL);
    664706
    665707    return 0;
     
    668710
    669711/* Return value becomes exitcode. It's okay to not return at all */
    670 static int iproute_get(int argc, char **argv)
     712static int iproute_get(char **argv)
    671713{
    672714    struct rtnl_handle rth;
     
    688730
    689731    req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
    690     req.n.nlmsg_flags = NLM_F_REQUEST;
    691     req.n.nlmsg_type = RTM_GETROUTE;
     732    if (NLM_F_REQUEST)
     733        req.n.nlmsg_flags = NLM_F_REQUEST;
     734    if (RTM_GETROUTE)
     735        req.n.nlmsg_type = RTM_GETROUTE;
    692736    req.r.rtm_family = preferred_family;
    693     req.r.rtm_table = 0;
    694     req.r.rtm_protocol = 0;
    695     req.r.rtm_scope = 0;
    696     req.r.rtm_type = 0;
    697     req.r.rtm_src_len = 0;
    698     req.r.rtm_dst_len = 0;
    699     req.r.rtm_tos = 0;
    700 
    701     while (argc > 0) {
     737    /*req.r.rtm_table = 0; - memset did this already */
     738    /*req.r.rtm_protocol = 0;*/
     739    /*req.r.rtm_scope = 0;*/
     740    /*req.r.rtm_type = 0;*/
     741    /*req.r.rtm_src_len = 0;*/
     742    /*req.r.rtm_dst_len = 0;*/
     743    /*req.r.rtm_tos = 0;*/
     744
     745    while (*argv) {
    702746        switch (index_in_strings(options, *argv)) {
    703747            case 0: /* from */
     
    745789                req.r.rtm_dst_len = addr.bitlen;
    746790            }
    747             argc--; argv++;
    748         }
     791        }
     792        argv++;
    749793    }
    750794
     
    783827        struct rtattr * tb[RTA_MAX+1];
    784828
    785         print_route(NULL, &req.n, (void*)stdout);
     829        print_route(NULL, &req.n, NULL);
    786830
    787831        if (req.n.nlmsg_type != RTM_NEWROUTE) {
     
    800844            r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]);
    801845        } else if (!tb[RTA_SRC]) {
    802             bb_error_msg_and_die("failed to connect the route");
     846            bb_error_msg_and_die("can't connect the route");
    803847        }
    804848        if (!odev && tb[RTA_OIF]) {
     
    818862        }
    819863    }
    820     print_route(NULL, &req.n, (void*)stdout);
     864    print_route(NULL, &req.n, NULL);
    821865    return 0;
    822866}
    823867
    824868/* Return value becomes exitcode. It's okay to not return at all */
    825 int do_iproute(int argc, char **argv)
     869int FAST_FUNC do_iproute(char **argv)
    826870{
    827871    static const char ip_route_commands[] ALIGN1 =
     
    829873    /*4-7*/ "delete\0""get\0""list\0""show\0"
    830874    /*8..*/ "prepend\0""replace\0""test\0""flush\0";
    831     int command_num = 6;
     875    int command_num;
    832876    unsigned flags = 0;
    833877    int cmd = RTM_NEWROUTE;
    834878
     879    if (!*argv)
     880        return iproute_list_or_flush(argv, 0);
     881
    835882    /* "Standard" 'ip r a' treats 'a' as 'add', not 'append' */
    836883    /* It probably means that it is using "first match" rule */
    837     if (*argv) {
    838         command_num = index_in_substrings(ip_route_commands, *argv);
    839     }
     884    command_num = index_in_substrings(ip_route_commands, *argv);
     885
    840886    switch (command_num) {
    841887        case 0: /* add */
     
    853899            break;
    854900        case 5: /* get */
    855             return iproute_get(argc-1, argv+1);
     901            return iproute_get(argv+1);
    856902        case 6: /* list */
    857903        case 7: /* show */
    858             return iproute_list_or_flush(argc-1, argv+1, 0);
     904            return iproute_list_or_flush(argv+1, 0);
    859905        case 8: /* prepend */
    860906            flags = NLM_F_CREATE;
     907            break;
    861908        case 9: /* replace */
    862909            flags = NLM_F_CREATE|NLM_F_REPLACE;
     910            break;
    863911        case 10: /* test */
    864912            flags = NLM_F_EXCL;
     913            break;
    865914        case 11: /* flush */
    866             return iproute_list_or_flush(argc-1, argv+1, 1);
     915            return iproute_list_or_flush(argv+1, 1);
    867916        default:
    868917            bb_error_msg_and_die("unknown command %s", *argv);
    869918    }
    870919
    871     return iproute_modify(cmd, flags, argc-1, argv+1);
     920    return iproute_modify(cmd, flags, argv+1);
    872921}
  • branches/2.2.9/mindi-busybox/networking/libiproute/iprule.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * iprule.c     "ip rule".
     3 * This program is free software; you can redistribute it and/or
     4 * modify it under the terms of the GNU General Public License
     5 * as published by the Free Software Foundation; either version
     6 * 2 of the License, or (at your option) any later version.
    47 *
    5  *      This program is free software; you can redistribute it and/or
    6  *      modify it under the terms of the GNU General Public License
    7  *      as published by the Free Software Foundation; either version
    8  *      2 of the License, or (at your option) any later version.
    9  *
    10  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    11  *
     8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    129 *
    1310 * Changes:
    1411 *
    15  * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
    16  * initially integrated into busybox by Bernhard Fischer
     12 * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
     13 * initially integrated into busybox by Bernhard Reutner-Fischer
    1714 */
    1815
    19 #include <syslog.h>
    20 //#include <sys/socket.h>
    2116#include <netinet/in.h>
    2217#include <netinet/ip.h>
     
    4338*/
    4439
    45 static int print_rule(struct sockaddr_nl *who ATTRIBUTE_UNUSED,
    46                     struct nlmsghdr *n, void *arg)
    47 {
    48     FILE *fp = (FILE*)arg;
     40static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM,
     41                    struct nlmsghdr *n, void *arg UNUSED_PARAM)
     42{
    4943    struct rtmsg *r = NLMSG_DATA(n);
    5044    int len = n->nlmsg_len;
     
    7367        host_len = 80;
    7468*/
    75     if (tb[RTA_PRIORITY])
    76         fprintf(fp, "%u:\t", *(unsigned*)RTA_DATA(tb[RTA_PRIORITY]));
    77     else
    78         fprintf(fp, "0:\t");
    79 
    80     fprintf(fp, "from ");
     69    printf("%u:\t", tb[RTA_PRIORITY] ?
     70                    *(unsigned*)RTA_DATA(tb[RTA_PRIORITY])
     71                    : 0);
     72    printf("from ");
    8173    if (tb[RTA_SRC]) {
    8274        if (r->rtm_src_len != host_len) {
    83             fprintf(fp, "%s/%u", rt_addr_n2a(r->rtm_family,
    84                              RTA_PAYLOAD(tb[RTA_SRC]),
     75            printf("%s/%u", rt_addr_n2a(r->rtm_family,
    8576                             RTA_DATA(tb[RTA_SRC]),
    8677                             abuf, sizeof(abuf)),
     
    8879                );
    8980        } else {
    90             fprintf(fp, "%s", format_host(r->rtm_family,
     81            fputs(format_host(r->rtm_family,
    9182                               RTA_PAYLOAD(tb[RTA_SRC]),
    9283                               RTA_DATA(tb[RTA_SRC]),
    93                                abuf, sizeof(abuf))
    94                 );
     84                               abuf, sizeof(abuf)), stdout);
    9585        }
    9686    } else if (r->rtm_src_len) {
    97         fprintf(fp, "0/%d", r->rtm_src_len);
     87        printf("0/%d", r->rtm_src_len);
    9888    } else {
    99         fprintf(fp, "all");
    100     }
    101     fprintf(fp, " ");
     89        printf("all");
     90    }
     91    bb_putchar(' ');
    10292
    10393    if (tb[RTA_DST]) {
    10494        if (r->rtm_dst_len != host_len) {
    105             fprintf(fp, "to %s/%u ", rt_addr_n2a(r->rtm_family,
    106                              RTA_PAYLOAD(tb[RTA_DST]),
     95            printf("to %s/%u ", rt_addr_n2a(r->rtm_family,
    10796                             RTA_DATA(tb[RTA_DST]),
    10897                             abuf, sizeof(abuf)),
     
    11099                );
    111100        } else {
    112             fprintf(fp, "to %s ", format_host(r->rtm_family,
     101            printf("to %s ", format_host(r->rtm_family,
    113102                               RTA_PAYLOAD(tb[RTA_DST]),
    114103                               RTA_DATA(tb[RTA_DST]),
     
    116105        }
    117106    } else if (r->rtm_dst_len) {
    118         fprintf(fp, "to 0/%d ", r->rtm_dst_len);
     107        printf("to 0/%d ", r->rtm_dst_len);
    119108    }
    120109
    121110    if (r->rtm_tos) {
    122         fprintf(fp, "tos %s ", rtnl_dsfield_n2a(r->rtm_tos, b1, sizeof(b1)));
     111        printf("tos %s ", rtnl_dsfield_n2a(r->rtm_tos, b1));
    123112    }
    124113    if (tb[RTA_PROTOINFO]) {
    125         fprintf(fp, "fwmark %#x ", *(uint32_t*)RTA_DATA(tb[RTA_PROTOINFO]));
     114        printf("fwmark %#x ", *(uint32_t*)RTA_DATA(tb[RTA_PROTOINFO]));
    126115    }
    127116
    128117    if (tb[RTA_IIF]) {
    129         fprintf(fp, "iif %s ", (char*)RTA_DATA(tb[RTA_IIF]));
     118        printf("iif %s ", (char*)RTA_DATA(tb[RTA_IIF]));
    130119    }
    131120
    132121    if (r->rtm_table)
    133         fprintf(fp, "lookup %s ", rtnl_rttable_n2a(r->rtm_table, b1, sizeof(b1)));
     122        printf("lookup %s ", rtnl_rttable_n2a(r->rtm_table, b1));
    134123
    135124    if (tb[RTA_FLOW]) {
     
    138127        to &= 0xFFFF;
    139128        if (from) {
    140             fprintf(fp, "realms %s/",
    141                 rtnl_rtrealm_n2a(from, b1, sizeof(b1)));
     129            printf("realms %s/",
     130                rtnl_rtrealm_n2a(from, b1));
    142131        }
    143         fprintf(fp, "%s ",
    144             rtnl_rtrealm_n2a(to, b1, sizeof(b1)));
     132        printf("%s ",
     133            rtnl_rtrealm_n2a(to, b1));
    145134    }
    146135
    147136    if (r->rtm_type == RTN_NAT) {
    148137        if (tb[RTA_GATEWAY]) {
    149             fprintf(fp, "map-to %s ",
     138            printf("map-to %s ",
    150139                format_host(r->rtm_family,
    151140                        RTA_PAYLOAD(tb[RTA_GATEWAY]),
     
    153142                        abuf, sizeof(abuf)));
    154143        } else
    155             fprintf(fp, "masquerade");
     144            printf("masquerade");
    156145    } else if (r->rtm_type != RTN_UNICAST)
    157         fprintf(fp, "%s", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1)));
    158 
    159     fputc('\n', fp);
    160     fflush(fp);
     146        fputs(rtnl_rtntype_n2a(r->rtm_type, b1), stdout);
     147
     148    bb_putchar('\n');
     149    /*fflush_all();*/
    161150    return 0;
    162151}
    163152
    164153/* Return value becomes exitcode. It's okay to not return at all */
    165 static int iprule_list(int argc, char **argv)
     154static int iprule_list(char **argv)
    166155{
    167156    struct rtnl_handle rth;
     
    171160        af = AF_INET;
    172161
    173     if (argc > 0) {
     162    if (*argv) {
    174163        //bb_error_msg("\"rule show\" needs no arguments");
    175         bb_warn_ignoring_args(argc);
     164        bb_warn_ignoring_args(*argv);
    176165        return -1;
    177166    }
     
    180169
    181170    xrtnl_wilddump_request(&rth, af, RTM_GETRULE);
    182     xrtnl_dump_filter(&rth, print_rule, stdout);
     171    xrtnl_dump_filter(&rth, print_rule, NULL);
    183172
    184173    return 0;
     
    186175
    187176/* Return value becomes exitcode. It's okay to not return at all */
    188 static int iprule_modify(int cmd, int argc, char **argv)
     177static int iprule_modify(int cmd, char **argv)
    189178{
    190179    static const char keywords[] ALIGN1 =
     
    200189    struct rtnl_handle rth;
    201190    struct {
    202         struct nlmsghdr n;
    203         struct rtmsg    r;
    204         char        buf[1024];
     191        struct nlmsghdr n;
     192        struct rtmsg    r;
     193        char            buf[1024];
    205194    } req;
    206195    smalluint key;
     
    222211    }
    223212
    224     while (argc > 0) {
     213    while (*argv) {
    225214        key = index_in_substrings(keywords, *argv) + 1;
    226215        if (key == 0) /* no match found in keywords array, bail out. */
     
    240229        } else if (key == ARG_preference ||
    241230               key == ARG_order ||
    242                key == ARG_priority) {
     231               key == ARG_priority
     232        ) {
    243233            uint32_t pref;
    244234            NEXT_ARG();
    245             if (get_u32(&pref, *argv, 0))
    246                 invarg(*argv, "preference");
     235            pref = get_u32(*argv, "preference");
    247236            addattr32(&req.n, sizeof(req), RTA_PRIORITY, pref);
    248237        } else if (key == ARG_tos) {
     
    255244            uint32_t fwmark;
    256245            NEXT_ARG();
    257             if (get_u32(&fwmark, *argv, 0))
    258                 invarg(*argv, "fwmark");
     246            fwmark = get_u32(*argv, "fwmark");
    259247            addattr32(&req.n, sizeof(req), RTA_PROTOINFO, fwmark);
    260248        } else if (key == ARG_realms) {
     
    265253            addattr32(&req.n, sizeof(req), RTA_FLOW, realm);
    266254        } else if (key == ARG_table ||
    267                key == ARG_lookup) {
     255               key == ARG_lookup
     256        ) {
    268257            uint32_t tid;
    269258            NEXT_ARG();
     
    273262            table_ok = 1;
    274263        } else if (key == ARG_dev ||
    275                key == ARG_iif) {
     264               key == ARG_iif
     265        ) {
    276266            NEXT_ARG();
    277267            addattr_l(&req.n, sizeof(req), RTA_IIF, *argv, strlen(*argv)+1);
    278268        } else if (key == ARG_nat ||
    279                key == ARG_map_to) {
     269               key == ARG_map_to
     270        ) {
    280271            NEXT_ARG();
    281272            addattr32(&req.n, sizeof(req), RTA_GATEWAY, get_addr32(*argv));
     
    293284            req.r.rtm_type = type;
    294285        }
    295         argc--;
    296286        argv++;
    297287    }
     
    312302
    313303/* Return value becomes exitcode. It's okay to not return at all */
    314 int do_iprule(int argc, char **argv)
     304int FAST_FUNC do_iprule(char **argv)
    315305{
    316306    static const char ip_rule_commands[] ALIGN1 =
    317307        "add\0""delete\0""list\0""show\0";
    318     int cmd = 2; /* list */
    319 
    320     if (argc < 1)
    321         return iprule_list(0, NULL);
    322     if (*argv)
    323         cmd = index_in_substrings(ip_rule_commands, *argv);
    324 
    325     switch (cmd) {
    326         case 0: /* add */
    327             cmd = RTM_NEWRULE;
    328             break;
    329         case 1: /* delete */
    330             cmd = RTM_DELRULE;
    331             break;
    332         case 2: /* list */
    333         case 3: /* show */
    334             return iprule_list(argc-1, argv+1);
    335             break;
    336         default:
    337             bb_error_msg_and_die("unknown command %s", *argv);
    338     }
    339     return iprule_modify(cmd, argc-1, argv+1);
    340 }
     308    if (*argv) {
     309        smalluint cmd = index_in_substrings(ip_rule_commands, *argv);
     310        if (cmd > 3)
     311            bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
     312        argv++;
     313        if (cmd < 2)
     314            return iprule_modify((cmd == 0) ? RTM_NEWRULE : RTM_DELRULE, argv);
     315    }
     316    return iprule_list(argv);
     317}
  • branches/2.2.9/mindi-busybox/networking/libiproute/iptunnel.c

    r1772 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * iptunnel.c          "ip tunnel"
     3 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    44 *
    5  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
    6  *
    7  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    8  *
     5 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    96 *
    107 * Changes:
    118 *
    12  * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
    13  * Rani Assaf <rani@magic.metawire.com> 980930: do not allow key for ipip/sit
    14  * Phil Karn <karn@ka9q.ampr.org>   990408: "pmtudisc" flag
     9 * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
     10 * Rani Assaf <rani@magic.metawire.com> 980930: do not allow key for ipip/sit
     11 * Phil Karn <karn@ka9q.ampr.org>       990408: "pmtudisc" flag
    1512 */
    1613
     
    1916#include <net/if_arp.h>
    2017#include <asm/types.h>
     18
    2119#ifndef __constant_htons
    2220#define __constant_htons htons
    2321#endif
    24 #include <linux/if_tunnel.h>
     22
     23// FYI: #define SIOCDEVPRIVATE 0x89F0
     24
     25/* From linux/if_tunnel.h. #including it proved troublesome
     26 * (redefiniton errors due to name collisions in linux/ and net[inet]/) */
     27#define SIOCGETTUNNEL   (SIOCDEVPRIVATE + 0)
     28#define SIOCADDTUNNEL   (SIOCDEVPRIVATE + 1)
     29#define SIOCDELTUNNEL   (SIOCDEVPRIVATE + 2)
     30#define SIOCCHGTUNNEL   (SIOCDEVPRIVATE + 3)
     31//#define SIOCGETPRL      (SIOCDEVPRIVATE + 4)
     32//#define SIOCADDPRL      (SIOCDEVPRIVATE + 5)
     33//#define SIOCDELPRL      (SIOCDEVPRIVATE + 6)
     34//#define SIOCCHGPRL      (SIOCDEVPRIVATE + 7)
     35#define GRE_CSUM        __constant_htons(0x8000)
     36//#define GRE_ROUTING     __constant_htons(0x4000)
     37#define GRE_KEY         __constant_htons(0x2000)
     38#define GRE_SEQ         __constant_htons(0x1000)
     39//#define GRE_STRICT      __constant_htons(0x0800)
     40//#define GRE_REC         __constant_htons(0x0700)
     41//#define GRE_FLAGS       __constant_htons(0x00F8)
     42//#define GRE_VERSION     __constant_htons(0x0007)
     43struct ip_tunnel_parm {
     44    char            name[IFNAMSIZ];
     45    int             link;
     46    uint16_t        i_flags;
     47    uint16_t        o_flags;
     48    uint32_t        i_key;
     49    uint32_t        o_key;
     50    struct iphdr    iph;
     51};
     52/* SIT-mode i_flags */
     53//#define SIT_ISATAP 0x0001
     54//struct ip_tunnel_prl {
     55//  uint32_t          addr;
     56//  uint16_t          flags;
     57//  uint16_t          __reserved;
     58//  uint32_t          datalen;
     59//  uint32_t          __reserved2;
     60//  /* data follows */
     61//};
     62///* PRL flags */
     63//#define PRL_DEFAULT 0x0001
    2564
    2665#include "ip_common.h"  /* #include "libbb.h" is inside */
     
    3574    int fd;
    3675
    37     strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
     76    strncpy_IFNAMSIZ(ifr.ifr_name, dev);
    3877    fd = xsocket(AF_INET, SOCK_DGRAM, 0);
    3978    xioctl(fd, SIOCGIFINDEX, &ifr);
     
    4887    int err;
    4988
    50     strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
     89    strncpy_IFNAMSIZ(ifr.ifr_name, dev);
    5190    fd = xsocket(AF_INET, SOCK_DGRAM, 0);
    5291    err = ioctl_or_warn(fd, SIOCGIFHWADDR, &ifr);
     
    74113    int err;
    75114
    76     strncpy(ifr.ifr_name, basedev, sizeof(ifr.ifr_name));
     115    strncpy_IFNAMSIZ(ifr.ifr_name, basedev);
    77116    ifr.ifr_ifru.ifru_data = (void*)p;
    78117    fd = xsocket(AF_INET, SOCK_DGRAM, 0);
     
    89128
    90129    if (cmd == SIOCCHGTUNNEL && p->name[0]) {
    91         strncpy(ifr.ifr_name, p->name, sizeof(ifr.ifr_name));
     130        strncpy_IFNAMSIZ(ifr.ifr_name, p->name);
    92131    } else {
    93         strncpy(ifr.ifr_name, basedev, sizeof(ifr.ifr_name));
     132        strncpy_IFNAMSIZ(ifr.ifr_name, basedev);
    94133    }
    95134    ifr.ifr_ifru.ifru_data = (void*)p;
     
    115154
    116155    if (p->name[0]) {
    117         strncpy(ifr.ifr_name, p->name, sizeof(ifr.ifr_name));
     156        strncpy_IFNAMSIZ(ifr.ifr_name, p->name);
    118157    } else {
    119         strncpy(ifr.ifr_name, basedev, sizeof(ifr.ifr_name));
     158        strncpy_IFNAMSIZ(ifr.ifr_name, basedev);
    120159    }
    121160    ifr.ifr_ifru.ifru_data = (void*)p;
     
    127166
    128167/* Dies on error */
    129 static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p)
     168static void parse_args(char **argv, int cmd, struct ip_tunnel_parm *p)
    130169{
    131170    static const char keywords[] ALIGN1 =
     
    149188
    150189    memset(p, 0, sizeof(*p));
    151     memset(&medium, 0, sizeof(medium));
     190    medium[0] = '\0';
    152191
    153192    p->iph.version = 4;
     
    158197    p->iph.frag_off = htons(IP_DF);
    159198
    160     while (argc > 0) {
     199    while (*argv) {
    161200        key = index_in_strings(keywords, *argv);
    162201        if (key == ARG_mode) {
     
    164203            key = index_in_strings(keywords, *argv);
    165204            if (key == ARG_ipip ||
    166                 key == ARG_ip_ip) {
     205                key == ARG_ip_ip
     206            ) {
    167207                if (p->iph.protocol && p->iph.protocol != IPPROTO_IPIP) {
    168                     bb_error_msg_and_die("you managed to ask for more than one tunnel mode");
     208                    bb_error_msg_and_die("%s tunnel mode", "you managed to ask for more than one");
    169209                }
    170210                p->iph.protocol = IPPROTO_IPIP;
    171211            } else if (key == ARG_gre ||
    172                    key == ARG_gre_ip) {
     212                   key == ARG_gre_ip
     213            ) {
    173214                if (p->iph.protocol && p->iph.protocol != IPPROTO_GRE) {
    174                     bb_error_msg_and_die("you managed to ask for more than one tunnel mode");
     215                    bb_error_msg_and_die("%s tunnel mode", "you managed to ask for more than one");
    175216                }
    176217                p->iph.protocol = IPPROTO_GRE;
    177218            } else if (key == ARG_sit ||
    178                    key == ARG_ip6_ip) {
     219                   key == ARG_ip6_ip
     220            ) {
    179221                if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) {
    180                     bb_error_msg_and_die("you managed to ask for more than one tunnel mode");
     222                    bb_error_msg_and_die("%s tunnel mode", "you managed to ask for more than one");
    181223                }
    182224                p->iph.protocol = IPPROTO_IPV6;
    183225            } else {
    184                 bb_error_msg_and_die("cannot guess tunnel mode");
     226                bb_error_msg_and_die("%s tunnel mode", "can't guess");
    185227            }
    186228        } else if (key == ARG_key) {
     
    192234                p->i_key = p->o_key = get_addr32(*argv);
    193235            else {
    194                 if (get_unsigned(&uval, *argv, 0)<0) {
    195                     bb_error_msg_and_die("invalid value of \"key\"");
    196                 }
     236                uval = get_unsigned(*argv, "key");
    197237                p->i_key = p->o_key = htonl(uval);
    198238            }
     
    204244                p->o_key = get_addr32(*argv);
    205245            else {
    206                 if (get_unsigned(&uval, *argv, 0)<0) {
    207                     bb_error_msg_and_die("invalid value of \"ikey\"");
    208                 }
     246                uval = get_unsigned(*argv, "ikey");
    209247                p->i_key = htonl(uval);
    210248            }
     
    216254                p->o_key = get_addr32(*argv);
    217255            else {
    218                 if (get_unsigned(&uval, *argv, 0)<0) {
    219                     bb_error_msg_and_die("invalid value of \"okey\"");
    220                 }
     256                uval = get_unsigned(*argv, "okey");
    221257                p->o_key = htonl(uval);
    222258            }
     
    251287        } else if (key == ARG_dev) {
    252288            NEXT_ARG();
    253             strncpy(medium, *argv, IFNAMSIZ-1);
     289            strncpy_IFNAMSIZ(medium, *argv);
    254290        } else if (key == ARG_ttl) {
    255291            unsigned uval;
     
    257293            key = index_in_strings(keywords, *argv);
    258294            if (key != ARG_inherit) {
    259                 if (get_unsigned(&uval, *argv, 0))
    260                     invarg(*argv, "TTL");
     295                uval = get_unsigned(*argv, "TTL");
    261296                if (uval > 255)
    262297                    invarg(*argv, "TTL must be <=255");
     
    264299            }
    265300        } else if (key == ARG_tos ||
    266                key == ARG_dsfield) {
     301               key == ARG_dsfield
     302        ) {
    267303            uint32_t uval;
    268304            NEXT_ARG();
     
    280316            if (p->name[0])
    281317                duparg2("name", *argv);
    282             strncpy(p->name, *argv, IFNAMSIZ);
     318            strncpy_IFNAMSIZ(p->name, *argv);
    283319            if (cmd == SIOCCHGTUNNEL && count == 0) {
    284320                struct ip_tunnel_parm old_p;
    285321                memset(&old_p, 0, sizeof(old_p));
    286322                if (do_get_ioctl(*argv, &old_p))
    287                     exit(1);
     323                    exit(EXIT_FAILURE);
    288324                *p = old_p;
    289325            }
    290326        }
    291327        count++;
    292         argc--;
    293328        argv++;
    294329    }
     
    326361}
    327362
    328 
    329363/* Return value becomes exitcode. It's okay to not return at all */
    330 static int do_add(int cmd, int argc, char **argv)
     364static int do_add(int cmd, char **argv)
    331365{
    332366    struct ip_tunnel_parm p;
    333367
    334     parse_args(argc, argv, cmd, &p);
     368    parse_args(argv, cmd, &p);
    335369
    336370    if (p.iph.ttl && p.iph.frag_off == 0) {
     
    346380        return do_add_ioctl(cmd, "sit0", &p);
    347381    default:
    348         bb_error_msg_and_die("cannot determine tunnel mode (ipip, gre or sit)");
     382        bb_error_msg_and_die("can't determine tunnel mode (ipip, gre or sit)");
    349383    }
    350384}
    351385
    352386/* Return value becomes exitcode. It's okay to not return at all */
    353 static int do_del(int argc, char **argv)
     387static int do_del(char **argv)
    354388{
    355389    struct ip_tunnel_parm p;
    356390
    357     parse_args(argc, argv, SIOCDELTUNNEL, &p);
     391    parse_args(argv, SIOCDELTUNNEL, &p);
    358392
    359393    switch (p.iph.protocol) {
     
    405439        if (p->iph.tos & ~1)
    406440            printf("%c%s ", p->iph.tos & 1 ? '/' : ' ',
    407                    rtnl_dsfield_n2a(p->iph.tos & ~1, b1, sizeof(b1)));
     441                   rtnl_dsfield_n2a(p->iph.tos & ~1, b1));
    408442    }
    409443    if (!(p->iph.frag_off & htons(IP_DF)))
     
    444478        return;
    445479    }
    446 
     480    /* skip headers */
    447481    fgets(buf, sizeof(buf), fp);
    448482    fgets(buf, sizeof(buf), fp);
     
    454488        ptr = strchr(buf, ':');
    455489        if (ptr == NULL ||
    456             (*ptr++ = 0, sscanf(buf, "%s", name) != 1)) {
     490            (*ptr++ = 0, sscanf(buf, "%s", name) != 1)
     491        ) {
    457492            bb_error_msg("wrong format of /proc/net/dev");
    458493            return;
     
    468503        type = do_ioctl_get_iftype(name);
    469504        if (type == -1) {
    470             bb_error_msg("cannot get type of [%s]", name);
     505            bb_error_msg("can't get type of [%s]", name);
    471506            continue;
    472507        }
     
    480515            (p->iph.daddr && p1.iph.daddr != p->iph.daddr) ||
    481516            (p->iph.saddr && p1.iph.saddr != p->iph.saddr) ||
    482             (p->i_key && p1.i_key != p->i_key))
     517            (p->i_key && p1.i_key != p->i_key)
     518        ) {
    483519            continue;
     520        }
    484521        print_tunnel(&p1);
    485         puts("");
     522        bb_putchar('\n');
    486523    }
    487524}
    488525
    489526/* Return value becomes exitcode. It's okay to not return at all */
    490 static int do_show(int argc, char **argv)
     527static int do_show(char **argv)
    491528{
    492529    int err;
    493530    struct ip_tunnel_parm p;
    494531
    495     parse_args(argc, argv, SIOCGETTUNNEL, &p);
     532    parse_args(argv, SIOCGETTUNNEL, &p);
    496533
    497534    switch (p.iph.protocol) {
     
    513550
    514551    print_tunnel(&p);
    515     puts("");
     552    bb_putchar('\n');
    516553    return 0;
    517554}
    518555
    519556/* Return value becomes exitcode. It's okay to not return at all */
    520 int do_iptunnel(int argc, char **argv)
     557int FAST_FUNC do_iptunnel(char **argv)
    521558{
    522559    static const char keywords[] ALIGN1 =
    523560        "add\0""change\0""delete\0""show\0""list\0""lst\0";
    524561    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)
     562
     563    if (*argv) {
     564        smalluint key = index_in_substrings(keywords, *argv);
     565        if (key > 5)
    530566            bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name);
    531         --argc;
    532         ++argv;
     567        argv++;
    533568        if (key == ARG_add)
    534             return do_add(SIOCADDTUNNEL, argc, argv);
     569            return do_add(SIOCADDTUNNEL, argv);
    535570        if (key == ARG_change)
    536             return do_add(SIOCCHGTUNNEL, argc, argv);
     571            return do_add(SIOCCHGTUNNEL, argv);
    537572        if (key == ARG_del)
    538             return do_del(argc, argv);
    539     }
    540     return do_show(argc, argv);
    541 }
     573            return do_del(argv);
     574    }
     575    return do_show(argv);
     576}
  • branches/2.2.9/mindi-busybox/networking/libiproute/libnetlink.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * libnetlink.c RTnetlink service routines.
     3 * This program is free software; you can redistribute it and/or
     4 * modify it under the terms of the GNU General Public License
     5 * as published by the Free Software Foundation; either version
     6 * 2 of the License, or (at your option) any later version.
    47 *
    5  *      This program is free software; you can redistribute it and/or
    6  *      modify it under the terms of the GNU General Public License
    7  *      as published by the Free Software Foundation; either version
    8  *      2 of the License, or (at your option) any later version.
    9  *
    10  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    11  *
     8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    129 */
    1310
     
    1815#include "libnetlink.h"
    1916
    20 void rtnl_close(struct rtnl_handle *rth)
    21 {
    22     close(rth->fd);
    23 }
    24 
    25 int xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/)
     17void FAST_FUNC xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/)
    2618{
    2719    socklen_t addr_len;
    2820
    29     memset(rth, 0, sizeof(rth));
    30 
     21    memset(rth, 0, sizeof(*rth));
    3122    rth->fd = xsocket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
    32 
    33     memset(&rth->local, 0, sizeof(rth->local));
    3423    rth->local.nl_family = AF_NETLINK;
    3524    /*rth->local.nl_groups = subscriptions;*/
     
    3726    xbind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local));
    3827    addr_len = sizeof(rth->local);
     28    getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len);
     29
     30/* too much paranoia
    3931    if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0)
    40         bb_perror_msg_and_die("cannot getsockname");
     32        bb_perror_msg_and_die("getsockname");
    4133    if (addr_len != sizeof(rth->local))
    4234        bb_error_msg_and_die("wrong address length %d", addr_len);
    4335    if (rth->local.nl_family != AF_NETLINK)
    4436        bb_error_msg_and_die("wrong address family %d", rth->local.nl_family);
     37*/
    4538    rth->seq = time(NULL);
    46     return 0;
    47 }
    48 
    49 int xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
     39}
     40
     41int FAST_FUNC xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
    5042{
    5143    struct {
     
    5345        struct rtgenmsg g;
    5446    } req;
    55     struct sockaddr_nl nladdr;
    56 
    57     memset(&nladdr, 0, sizeof(nladdr));
    58     nladdr.nl_family = AF_NETLINK;
    5947
    6048    req.nlh.nlmsg_len = sizeof(req);
     
    6553    req.g.rtgen_family = family;
    6654
    67     return xsendto(rth->fd, (void*)&req, sizeof(req),
    68                  (struct sockaddr*)&nladdr, sizeof(nladdr));
    69 }
    70 
    71 int rtnl_send(struct rtnl_handle *rth, char *buf, int len)
     55    return rtnl_send(rth, (void*)&req, sizeof(req));
     56}
     57
     58int FAST_FUNC rtnl_send(struct rtnl_handle *rth, char *buf, int len)
    7259{
    7360    struct sockaddr_nl nladdr;
     
    7966}
    8067
    81 int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len)
     68int FAST_FUNC rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len)
    8269{
    8370    struct nlmsghdr nlh;
     
    8673    struct msghdr msg = {
    8774        (void*)&nladdr, sizeof(nladdr),
    88         iov,    2,
    89         NULL,   0,
     75        iov,  2,
     76        NULL, 0,
    9077        0
    9178    };
     
    10491
    10592static int rtnl_dump_filter(struct rtnl_handle *rth,
    106         int (*filter)(struct sockaddr_nl *, struct nlmsghdr *n, void *),
     93        int (*filter)(const struct sockaddr_nl *, struct nlmsghdr *n, void *) FAST_FUNC,
    10794        void *arg1/*,
    10895        int (*junk)(struct sockaddr_nl *, struct nlmsghdr *n, void *),
    10996        void *arg2*/)
    11097{
    111     char buf[8192];
     98    int retval = -1;
     99    char *buf = xmalloc(8*1024); /* avoid big stack buffer */
    112100    struct sockaddr_nl nladdr;
    113     struct iovec iov = { buf, sizeof(buf) };
     101    struct iovec iov = { buf, 8*1024 };
    114102
    115103    while (1) {
     
    119107        struct msghdr msg = {
    120108            (void*)&nladdr, sizeof(nladdr),
    121             &iov,   1,
    122             NULL,   0,
     109            &iov, 1,
     110            NULL, 0,
    123111            0
    124112        };
     
    134122        if (status == 0) {
    135123            bb_error_msg("EOF on netlink");
    136             return -1;
     124            goto ret;
    137125        }
    138126        if (msg.msg_namelen != sizeof(nladdr)) {
     
    146134            if (nladdr.nl_pid != 0 ||
    147135                h->nlmsg_pid != rth->local.nl_pid ||
    148                 h->nlmsg_seq != rth->dump) {
    149 /*              if (junk) {
    150                     err = junk(&nladdr, h, arg2);
    151                     if (err < 0)
    152                         return err;
    153                 } */
     136                h->nlmsg_seq != rth->dump
     137            ) {
     138//              if (junk) {
     139//                  err = junk(&nladdr, h, arg2);
     140//                  if (err < 0) {
     141//                      retval = err;
     142//                      goto ret;
     143//                  }
     144//              }
    154145                goto skip_it;
    155146            }
    156147
    157148            if (h->nlmsg_type == NLMSG_DONE) {
    158                 return 0;
     149                goto ret_0;
    159150            }
    160151            if (h->nlmsg_type == NLMSG_ERROR) {
     
    166157                    bb_perror_msg("RTNETLINK answers");
    167158                }
    168                 return -1;
     159                goto ret;
    169160            }
    170161            err = filter(&nladdr, h, arg1);
    171             if (err < 0)
    172                 return err;
    173 
    174 skip_it:
     162            if (err < 0) {
     163                retval = err;
     164                goto ret;
     165            }
     166
     167 skip_it:
    175168            h = NLMSG_NEXT(h, status);
    176169        }
     
    182175            bb_error_msg_and_die("remnant of size %d!", status);
    183176        }
    184     }
    185 }
    186 
    187 int xrtnl_dump_filter(struct rtnl_handle *rth,
    188         int (*filter)(struct sockaddr_nl *, struct nlmsghdr *n, void *),
     177    } /* while (1) */
     178 ret_0:
     179    retval++; /* = 0 */
     180 ret:
     181    free(buf);
     182    return retval;
     183}
     184
     185int FAST_FUNC xrtnl_dump_filter(struct rtnl_handle *rth,
     186        int (*filter)(const struct sockaddr_nl *, struct nlmsghdr *, void *) FAST_FUNC,
    189187        void *arg1)
    190188{
     
    195193}
    196194
    197 int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer,
    198           unsigned groups, struct nlmsghdr *answer,
    199           int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *),
    200           void *jarg)
    201 {
     195int FAST_FUNC rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
     196        pid_t peer, unsigned groups,
     197        struct nlmsghdr *answer,
     198        int (*junk)(struct sockaddr_nl *, struct nlmsghdr *, void *),
     199        void *jarg)
     200{
     201/* bbox doesn't use parameters no. 3, 4, 6, 7, they are stubbed out */
     202#define peer   0
     203#define groups 0
     204#define junk   NULL
     205#define jarg   NULL
     206    int retval = -1;
    202207    int status;
    203208    unsigned seq;
     
    205210    struct sockaddr_nl nladdr;
    206211    struct iovec iov = { (void*)n, n->nlmsg_len };
    207     char   buf[8192];
     212    char   *buf = xmalloc(8*1024); /* avoid big stack buffer */
    208213    struct msghdr msg = {
    209214        (void*)&nladdr, sizeof(nladdr),
    210         &iov,   1,
    211         NULL,   0,
     215        &iov, 1,
     216        NULL, 0,
    212217        0
    213218    };
     
    215220    memset(&nladdr, 0, sizeof(nladdr));
    216221    nladdr.nl_family = AF_NETLINK;
    217     nladdr.nl_pid = peer;
    218     nladdr.nl_groups = groups;
     222//  nladdr.nl_pid = peer;
     223//  nladdr.nl_groups = groups;
    219224
    220225    n->nlmsg_seq = seq = ++rtnl->seq;
     
    225230
    226231    if (status < 0) {
    227         bb_perror_msg("cannot talk to rtnetlink");
    228         return -1;
     232        bb_perror_msg("can't talk to rtnetlink");
     233        goto ret;
    229234    }
    230235
     
    232237
    233238    while (1) {
    234         iov.iov_len = sizeof(buf);
     239        iov.iov_len = 8*1024;
    235240        status = recvmsg(rtnl->fd, &msg, 0);
    236241
     
    244249        if (status == 0) {
    245250            bb_error_msg("EOF on netlink");
    246             return -1;
     251            goto ret;
    247252        }
    248253        if (msg.msg_namelen != sizeof(nladdr)) {
    249254            bb_error_msg_and_die("sender address length == %d", msg.msg_namelen);
    250255        }
    251         for (h = (struct nlmsghdr*)buf; status >= sizeof(*h); ) {
    252             int l_err;
     256        for (h = (struct nlmsghdr*)buf; status >= (int)sizeof(*h); ) {
     257//          int l_err;
    253258            int len = h->nlmsg_len;
    254259            int l = len - sizeof(*h);
    255260
    256             if (l<0 || len>status) {
     261            if (l < 0 || len > status) {
    257262                if (msg.msg_flags & MSG_TRUNC) {
    258263                    bb_error_msg("truncated message");
    259                     return -1;
     264                    goto ret;
    260265                }
    261266                bb_error_msg_and_die("malformed message: len=%d!", len);
     
    264269            if (nladdr.nl_pid != peer ||
    265270                h->nlmsg_pid != rtnl->local.nl_pid ||
    266                 h->nlmsg_seq != seq) {
    267                 if (junk) {
    268                     l_err = junk(&nladdr, h, jarg);
    269                     if (l_err < 0) {
    270                         return l_err;
    271                     }
    272                 }
     271                h->nlmsg_seq != seq
     272            ) {
     273//              if (junk) {
     274//                  l_err = junk(&nladdr, h, jarg);
     275//                  if (l_err < 0) {
     276//                      retval = l_err;
     277//                      goto ret;
     278//                  }
     279//              }
    273280                continue;
    274281            }
     
    276283            if (h->nlmsg_type == NLMSG_ERROR) {
    277284                struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
    278                 if (l < sizeof(struct nlmsgerr)) {
     285                if (l < (int)sizeof(struct nlmsgerr)) {
    279286                    bb_error_msg("ERROR truncated");
    280287                } else {
    281                     errno = -err->error;
     288                    errno = - err->error;
    282289                    if (errno == 0) {
    283290                        if (answer) {
    284291                            memcpy(answer, h, h->nlmsg_len);
    285292                        }
    286                         return 0;
     293                        goto ret_0;
    287294                    }
    288295                    bb_perror_msg("RTNETLINK answers");
    289296                }
    290                 return -1;
     297                goto ret;
    291298            }
    292299            if (answer) {
    293300                memcpy(answer, h, h->nlmsg_len);
    294                 return 0;
     301                goto ret_0;
    295302            }
    296303
     
    307314            bb_error_msg_and_die("remnant of size %d!", status);
    308315        }
    309     }
    310 }
    311 
    312 int addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data)
     316    } /* while (1) */
     317 ret_0:
     318    retval++; /* = 0 */
     319 ret:
     320    free(buf);
     321    return retval;
     322}
     323
     324int FAST_FUNC addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data)
    313325{
    314326    int len = RTA_LENGTH(4);
    315327    struct rtattr *rta;
    316     if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen)
     328
     329    if ((int)(NLMSG_ALIGN(n->nlmsg_len) + len) > maxlen) {
    317330        return -1;
     331    }
    318332    rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len));
    319333    rta->rta_type = type;
    320334    rta->rta_len = len;
    321     memcpy(RTA_DATA(rta), &data, 4);
     335    move_to_unaligned32(RTA_DATA(rta), data);
    322336    n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len;
    323337    return 0;
    324338}
    325339
    326 int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen)
     340int FAST_FUNC addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen)
    327341{
    328342    int len = RTA_LENGTH(alen);
    329343    struct rtattr *rta;
    330344
    331     if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen)
     345    if ((int)(NLMSG_ALIGN(n->nlmsg_len) + len) > maxlen) {
    332346        return -1;
     347    }
    333348    rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len));
    334349    rta->rta_type = type;
     
    339354}
    340355
    341 int rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data)
     356int FAST_FUNC rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data)
    342357{
    343358    int len = RTA_LENGTH(4);
     
    350365    subrta->rta_type = type;
    351366    subrta->rta_len = len;
    352     memcpy(RTA_DATA(subrta), &data, 4);
     367    move_to_unaligned32(RTA_DATA(subrta), data);
    353368    rta->rta_len = NLMSG_ALIGN(rta->rta_len) + len;
    354369    return 0;
    355370}
    356371
    357 int rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen)
     372int FAST_FUNC rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen)
    358373{
    359374    struct rtattr *subrta;
     
    372387
    373388
    374 int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
     389void FAST_FUNC parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
    375390{
    376391    while (RTA_OK(rta, len)) {
     
    383398        bb_error_msg("deficit %d, rta_len=%d!", len, rta->rta_len);
    384399    }
    385     return 0;
    386 }
     400}
  • branches/2.2.9/mindi-busybox/networking/libiproute/libnetlink.h

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    2 #ifndef __LIBNETLINK_H__
    3 #define __LIBNETLINK_H__ 1
     2#ifndef LIBNETLINK_H
     3#define LIBNETLINK_H 1
    44
    55#include <linux/types.h>
     
    99#include <linux/rtnetlink.h>
    1010
    11 struct rtnl_handle
    12 {
    13     int         fd;
    14     struct sockaddr_nl  local;
    15     struct sockaddr_nl  peer;
    16     uint32_t        seq;
    17     uint32_t        dump;
     11PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
     12
     13struct rtnl_handle {
     14    int                fd;
     15    struct sockaddr_nl local;
     16    struct sockaddr_nl peer;
     17    uint32_t           seq;
     18    uint32_t           dump;
    1819};
    1920
    20 extern int xrtnl_open(struct rtnl_handle *rth);
    21 extern void rtnl_close(struct rtnl_handle *rth);
    22 extern int xrtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type);
    23 extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len);
     21extern void xrtnl_open(struct rtnl_handle *rth) FAST_FUNC;
     22#define rtnl_close(rth) (close((rth)->fd))
     23extern int xrtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type) FAST_FUNC;
     24extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) FAST_FUNC;
    2425extern int xrtnl_dump_filter(struct rtnl_handle *rth,
    25             int (*filter)(struct sockaddr_nl*, struct nlmsghdr *n, void*),
    26             void *arg1);
     26        int (*filter)(const struct sockaddr_nl*, struct nlmsghdr *n, void*) FAST_FUNC,
     27        void *arg1) FAST_FUNC;
     28
     29/* bbox doesn't use parameters no. 3, 4, 6, 7, stub them out */
     30#define rtnl_talk(rtnl, n, peer, groups, answer, junk, jarg) \
     31    rtnl_talk(rtnl, n, answer)
    2732extern int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer,
    28             unsigned groups, struct nlmsghdr *answer,
    29             int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *),
    30             void *jarg);
    31 extern int rtnl_send(struct rtnl_handle *rth, char *buf, int);
     33        unsigned groups, struct nlmsghdr *answer,
     34        int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *),
     35        void *jarg) FAST_FUNC;
     36
     37extern int rtnl_send(struct rtnl_handle *rth, char *buf, int) FAST_FUNC;
    3238
    3339
    34 extern int addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data);
    35 extern int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen);
    36 extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data);
    37 extern int rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen);
     40extern int addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data) FAST_FUNC;
     41extern int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen) FAST_FUNC;
     42extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data) FAST_FUNC;
     43extern int rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen) FAST_FUNC;
    3844
    39 extern int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len);
     45extern void parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) FAST_FUNC;
    4046
    41 #endif /* __LIBNETLINK_H__ */
     47POP_SAVED_FUNCTION_VISIBILITY
     48
     49#endif
  • branches/2.2.9/mindi-busybox/networking/libiproute/ll_addr.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * ll_addr.c
     3 * This program is free software; you can redistribute it and/or
     4 * modify it under the terms of the GNU General Public License
     5 * as published by the Free Software Foundation; either version
     6 * 2 of the License, or (at your option) any later version.
    47 *
    5  *      This program is free software; you can redistribute it and/or
    6  *      modify it under the terms of the GNU General Public License
    7  *      as published by the Free Software Foundation; either version
    8  *      2 of the License, or (at your option) any later version.
    9  *
    10  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
     8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    119 */
    1210
     
    1816
    1917
    20 const char *ll_addr_n2a(unsigned char *addr, int alen, int type, char *buf, int blen)
     18const char* FAST_FUNC ll_addr_n2a(unsigned char *addr, int alen, int type, char *buf, int blen)
    2119{
    2220    int i;
    2321    int l;
    2422
    25     if (alen == 4 &&
    26         (type == ARPHRD_TUNNEL || type == ARPHRD_SIT || type == ARPHRD_IPGRE)) {
     23    if (alen == 4
     24     && (type == ARPHRD_TUNNEL || type == ARPHRD_SIT || type == ARPHRD_IPGRE)
     25    ) {
    2726        return inet_ntop(AF_INET, addr, buf, blen);
    2827    }
    2928    l = 0;
    30     for (i=0; i<alen; i++) {
    31         if (i==0) {
    32             snprintf(buf+l, blen, ":%02x"+1, addr[i]);
     29    for (i = 0; i < alen; i++) {
     30        if (i == 0) {
     31            snprintf(buf + l, blen, ":%02x"+1, addr[i]);
    3332            blen -= 2;
    3433            l += 2;
    3534        } else {
    36             snprintf(buf+l, blen, ":%02x", addr[i]);
     35            snprintf(buf + l, blen, ":%02x", addr[i]);
    3736            blen -= 3;
    3837            l += 3;
     
    4241}
    4342
    44 int ll_addr_a2n(unsigned char *lladdr, int len, char *arg)
     43int FAST_FUNC ll_addr_a2n(unsigned char *lladdr, int len, char *arg)
    4544{
     45    int i;
     46
    4647    if (strchr(arg, '.')) {
    4748        inet_prefix pfx;
     
    5556        memcpy(lladdr, pfx.data, 4);
    5657        return 4;
    57     } else {
    58         int i;
     58    }
    5959
    60         for (i=0; i<len; i++) {
    61             int temp;
    62             char *cp = strchr(arg, ':');
    63             if (cp) {
    64                 *cp = 0;
    65                 cp++;
    66             }
    67             if (sscanf(arg, "%x", &temp) != 1) {
    68                 bb_error_msg("\"%s\" is invalid lladdr", arg);
    69                 return -1;
    70             }
    71             if (temp < 0 || temp > 255) {
    72                 bb_error_msg("\"%s\" is invalid lladdr", arg);
    73                 return -1;
    74             }
    75             lladdr[i] = temp;
    76             if (!cp) {
    77                 break;
    78             }
    79             arg = cp;
     60    for (i = 0; i < len; i++) {
     61        int temp;
     62        char *cp = strchr(arg, ':');
     63        if (cp) {
     64            *cp = 0;
     65            cp++;
    8066        }
    81         return i+1;
     67        if (sscanf(arg, "%x", &temp) != 1 || (temp < 0 || temp > 255)) {
     68            bb_error_msg("\"%s\" is invalid lladdr", arg);
     69            return -1;
     70        }
     71        lladdr[i] = temp;
     72        if (!cp) {
     73            break;
     74        }
     75        arg = cp;
    8276    }
     77    return i+1;
    8378}
  • branches/2.2.9/mindi-busybox/networking/libiproute/ll_map.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * ll_map.c
     3 * This program is free software; you can redistribute it and/or
     4 * modify it under the terms of the GNU General Public License
     5 * as published by the Free Software Foundation; either version
     6 * 2 of the License, or (at your option) any later version.
    47 *
    5  *      This program is free software; you can redistribute it and/or
    6  *      modify it under the terms of the GNU General Public License
    7  *      as published by the Free Software Foundation; either version
    8  *      2 of the License, or (at your option) any later version.
    9  *
    10  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    11  *
     8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    129 */
    1310
    14 #include <net/if.h> /* struct ifreq and co. */
     11#include <net/if.h>  /* struct ifreq and co. */
    1512
    1613#include "libbb.h"
     
    2825};
    2926
    30 static struct idxmap *idxmap[16];
     27static struct idxmap **idxmap; /* treat as *idxmap[16] */
    3128
    3229static struct idxmap *find_by_index(int idx)
     
    3431    struct idxmap *im;
    3532
    36     for (im = idxmap[idx & 0xF]; im; im = im->next)
    37         if (im->index == idx)
    38             return im;
     33    if (idxmap)
     34        for (im = idxmap[idx & 0xF]; im; im = im->next)
     35            if (im->index == idx)
     36                return im;
    3937    return NULL;
    4038}
    4139
    42 int ll_remember_index(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
     40int FAST_FUNC ll_remember_index(const struct sockaddr_nl *who UNUSED_PARAM,
     41        struct nlmsghdr *n,
     42        void *arg UNUSED_PARAM)
    4343{
    4444    int h;
     
    5858        return 0;
    5959
     60    if (!idxmap)
     61        idxmap = xzalloc(sizeof(idxmap[0]) * 16);
     62
    6063    h = ifi->ifi_index & 0xF;
    61 
    6264    for (imp = &idxmap[h]; (im = *imp) != NULL; imp = &im->next)
    6365        if (im->index == ifi->ifi_index)
     
    7476        int alen;
    7577        im->alen = alen = RTA_PAYLOAD(tb[IFLA_ADDRESS]);
    76         if (alen > sizeof(im->addr))
     78        if (alen > (int)sizeof(im->addr))
    7779            alen = sizeof(im->addr);
    7880        memcpy(im->addr, RTA_DATA(tb[IFLA_ADDRESS]), alen);
     
    8587}
    8688
    87 const char *ll_idx_n2a(int idx, char *buf)
     89const char FAST_FUNC *ll_idx_n2a(int idx, char *buf)
    8890{
    8991    struct idxmap *im;
     
    99101
    100102
    101 const char *ll_index_to_name(int idx)
     103const char FAST_FUNC *ll_index_to_name(int idx)
    102104{
    103105    static char nbuf[16];
     
    120122#endif
    121123
    122 unsigned ll_index_to_flags(int idx)
     124unsigned FAST_FUNC ll_index_to_flags(int idx)
    123125{
    124126    struct idxmap *im;
     
    132134}
    133135
    134 int xll_name_to_index(const char *const name)
     136int FAST_FUNC xll_name_to_index(const char *name)
    135137{
    136138    int ret = 0;
     
    151153        goto out;
    152154    }
    153     for (i = 0; i < 16; i++) {
    154         for (im = idxmap[i]; im; im = im->next) {
    155             if (strcmp(im->name, name) == 0) {
    156                 icache = im->index;
    157                 strcpy(ncache, name);
    158                 ret = im->index;
    159                 goto out;
     155    if (idxmap) {
     156        for (i = 0; i < 16; i++) {
     157            for (im = idxmap[i]; im; im = im->next) {
     158                if (strcmp(im->name, name) == 0) {
     159                    icache = im->index;
     160                    strcpy(ncache, name);
     161                    ret = im->index;
     162                    goto out;
     163                }
    160164            }
    161165        }
     
    171175
    172176    sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
    173     if (sock_fd) {
     177    if (sock_fd >= 0) {
    174178        struct ifreq ifr;
    175179        int tmp;
    176180
    177         strncpy(ifr.ifr_name, name, IFNAMSIZ);
     181        strncpy_IFNAMSIZ(ifr.ifr_name, name);
    178182        ifr.ifr_ifindex = -1;
    179183        tmp = ioctl(sock_fd, SIOCGIFINDEX, &ifr);
     
    187191/* out:*/
    188192    if (ret <= 0)
    189         bb_error_msg_and_die("cannot find device \"%s\"", name);
     193        bb_error_msg_and_die("can't find device '%s'", name);
    190194    return ret;
    191195}
    192196
    193 int ll_init_map(struct rtnl_handle *rth)
     197int FAST_FUNC ll_init_map(struct rtnl_handle *rth)
    194198{
    195199    xrtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK);
    196     xrtnl_dump_filter(rth, ll_remember_index, &idxmap);
     200    xrtnl_dump_filter(rth, ll_remember_index, NULL);
    197201    return 0;
    198202}
  • branches/2.2.9/mindi-busybox/networking/libiproute/ll_map.h

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    2 #ifndef __LL_MAP_H__
    3 #define __LL_MAP_H__ 1
     2#ifndef LL_MAP_H
     3#define LL_MAP_H 1
    44
    5 int ll_remember_index(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
    6 int ll_init_map(struct rtnl_handle *rth);
    7 int xll_name_to_index(const char *const name);
    8 const char *ll_index_to_name(int idx);
    9 const char *ll_idx_n2a(int idx, char *buf);
     5PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
     6
     7int ll_remember_index(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) FAST_FUNC;
     8int ll_init_map(struct rtnl_handle *rth) FAST_FUNC;
     9int xll_name_to_index(const char *name) FAST_FUNC;
     10const char *ll_index_to_name(int idx) FAST_FUNC;
     11const char *ll_idx_n2a(int idx, char *buf) FAST_FUNC;
    1012/* int ll_index_to_type(int idx); */
    11 unsigned ll_index_to_flags(int idx);
     13unsigned ll_index_to_flags(int idx) FAST_FUNC;
    1214
    13 #endif /* __LL_MAP_H__ */
     15POP_SAVED_FUNCTION_VISIBILITY
     16
     17#endif
  • branches/2.2.9/mindi-busybox/networking/libiproute/ll_proto.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * ll_proto.c
     3 * This program is free software; you can redistribute it and/or
     4 * modify it under the terms of the GNU General Public License
     5 * as published by the Free Software Foundation; either version
     6 * 2 of the License, or (at your option) any later version.
    47 *
    5  *      This program is free software; you can redistribute it and/or
    6  *      modify it under the terms of the GNU General Public License
    7  *      as published by the Free Software Foundation; either version
    8  *      2 of the License, or (at your option) any later version.
    9  *
    10  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
     8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    119 */
    1210
     
    2018#include <linux/if_ether.h>
    2119#endif
     20
     21#if !ENABLE_WERROR
     22#warning de-bloat
     23#endif
     24/* Before re-enabling this, please (1) conditionalize exotic protocols
     25 * on CONFIG_something, and (2) decouple strings and numbers
     26 * (use llproto_ids[] = n,n,n..; and llproto_names[] = "loop\0" "pup\0" ...;)
     27 */
    2228
    2329#define __PF(f,n) { ETH_P_##f, #n },
     
    9197
    9298
    93 const char * ll_proto_n2a(unsigned short id, char *buf, int len)
     99const char* FAST_FUNC ll_proto_n2a(unsigned short id, char *buf, int len)
    94100{
    95     int i;
    96 
     101    unsigned i;
    97102    id = ntohs(id);
    98 
    99     for (i=0; i < ARRAY_SIZE(llproto_names); i++) {
     103    for (i = 0; i < ARRAY_SIZE(llproto_names); i++) {
    100104         if (llproto_names[i].id == id)
    101105            return llproto_names[i].name;
     
    105109}
    106110
    107 int ll_proto_a2n(unsigned short *id, char *buf)
     111int FAST_FUNC ll_proto_a2n(unsigned short *id, char *buf)
    108112{
    109     int i;
    110     for (i=0; i < ARRAY_SIZE(llproto_names); i++) {
     113    unsigned i;
     114    for (i = 0; i < ARRAY_SIZE(llproto_names); i++) {
    111115         if (strcasecmp(llproto_names[i].name, buf) == 0) {
    112              *id = htons(llproto_names[i].id);
    113              return 0;
     116             i = llproto_names[i].id;
     117             goto good;
    114118         }
    115119    }
    116     if (get_u16(id, buf, 0))
     120    i = bb_strtou(buf, NULL, 0);
     121    if (errno || i > 0xffff)
    117122        return -1;
    118     *id = htons(*id);
     123 good:
     124    *id = htons(i);
    119125    return 0;
    120126}
  • branches/2.2.9/mindi-busybox/networking/libiproute/ll_types.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * ll_types.c
     3 * This program is free software; you can redistribute it and/or
     4 * modify it under the terms of the GNU General Public License
     5 * as published by the Free Software Foundation; either version
     6 * 2 of the License, or (at your option) any later version.
    47 *
    5  *      This program is free software; you can redistribute it and/or
    6  *      modify it under the terms of the GNU General Public License
    7  *      as published by the Free Software Foundation; either version
    8  *      2 of the License, or (at your option) any later version.
    9  *
    10  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
     8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    119 */
    1210#include <arpa/inet.h>
     
    1614#include "rt_names.h"
    1715
    18 const char* ll_type_n2a(int type, char *buf, int len)
     16const char* FAST_FUNC ll_type_n2a(int type, char *buf)
    1917{
    20 #define __PF(f,n) { ARPHRD_##f, #n },
    21 static const struct {
    22     int type;
    23     const char *name;
    24 } arphrd_names[] = {
    25 { 0, "generic" },
    26 __PF(ETHER,ether)
    27 __PF(EETHER,eether)
    28 __PF(AX25,ax25)
    29 __PF(PRONET,pronet)
    30 __PF(CHAOS,chaos)
     18    static const char arphrd_name[] =
     19    /* 0,                  */ "generic" "\0"
     20    /* ARPHRD_LOOPBACK,    */ "loopback" "\0"
     21    /* ARPHRD_ETHER,       */ "ether" "\0"
     22#ifdef ARPHRD_INFINIBAND
     23    /* ARPHRD_INFINIBAND,  */ "infiniband" "\0"
     24#endif
    3125#ifdef ARPHRD_IEEE802_TR
    32 __PF(IEEE802,ieee802)
     26    /* ARPHRD_IEEE802,     */ "ieee802" "\0"
     27    /* ARPHRD_IEEE802_TR,  */ "tr" "\0"
    3328#else
    34 __PF(IEEE802,tr)
    35 #endif
    36 __PF(ARCNET,arcnet)
    37 __PF(APPLETLK,atalk)
    38 __PF(DLCI,dlci)
     29    /* ARPHRD_IEEE802,     */ "tr" "\0"
     30#endif
     31#ifdef ARPHRD_IEEE80211
     32    /* ARPHRD_IEEE80211,   */ "ieee802.11" "\0"
     33#endif
     34#ifdef ARPHRD_IEEE1394
     35    /* ARPHRD_IEEE1394,    */ "ieee1394" "\0"
     36#endif
     37    /* ARPHRD_IRDA,        */ "irda" "\0"
     38    /* ARPHRD_SLIP,        */ "slip" "\0"
     39    /* ARPHRD_CSLIP,       */ "cslip" "\0"
     40    /* ARPHRD_SLIP6,       */ "slip6" "\0"
     41    /* ARPHRD_CSLIP6,      */ "cslip6" "\0"
     42    /* ARPHRD_PPP,         */ "ppp" "\0"
     43    /* ARPHRD_TUNNEL,      */ "ipip" "\0"
     44    /* ARPHRD_TUNNEL6,     */ "tunnel6" "\0"
     45    /* ARPHRD_SIT,         */ "sit" "\0"
     46    /* ARPHRD_IPGRE,       */ "gre" "\0"
     47#ifdef ARPHRD_VOID
     48    /* ARPHRD_VOID,        */ "void" "\0"
     49#endif
     50
     51#if ENABLE_FEATURE_IP_RARE_PROTOCOLS
     52    /* ARPHRD_EETHER,      */ "eether" "\0"
     53    /* ARPHRD_AX25,        */ "ax25" "\0"
     54    /* ARPHRD_PRONET,      */ "pronet" "\0"
     55    /* ARPHRD_CHAOS,       */ "chaos" "\0"
     56    /* ARPHRD_ARCNET,      */ "arcnet" "\0"
     57    /* ARPHRD_APPLETLK,    */ "atalk" "\0"
     58    /* ARPHRD_DLCI,        */ "dlci" "\0"
    3959#ifdef ARPHRD_ATM
    40 __PF(ATM,atm)
    41 #endif
    42 __PF(METRICOM,metricom)
     60    /* ARPHRD_ATM,         */ "atm" "\0"
     61#endif
     62    /* ARPHRD_METRICOM,    */ "metricom" "\0"
     63    /* ARPHRD_RSRVD,       */ "rsrvd" "\0"
     64    /* ARPHRD_ADAPT,       */ "adapt" "\0"
     65    /* ARPHRD_ROSE,        */ "rose" "\0"
     66    /* ARPHRD_X25,         */ "x25" "\0"
     67#ifdef ARPHRD_HWX25
     68    /* ARPHRD_HWX25,       */ "hwx25" "\0"
     69#endif
     70    /* ARPHRD_HDLC,        */ "hdlc" "\0"
     71    /* ARPHRD_LAPB,        */ "lapb" "\0"
     72#ifdef ARPHRD_DDCMP
     73    /* ARPHRD_DDCMP,       */ "ddcmp" "\0"
     74    /* ARPHRD_RAWHDLC,     */ "rawhdlc" "\0"
     75#endif
     76    /* ARPHRD_FRAD,        */ "frad" "\0"
     77    /* ARPHRD_SKIP,        */ "skip" "\0"
     78    /* ARPHRD_LOCALTLK,    */ "ltalk" "\0"
     79    /* ARPHRD_FDDI,        */ "fddi" "\0"
     80    /* ARPHRD_BIF,         */ "bif" "\0"
     81    /* ARPHRD_IPDDP,       */ "ip/ddp" "\0"
     82    /* ARPHRD_PIMREG,      */ "pimreg" "\0"
     83    /* ARPHRD_HIPPI,       */ "hippi" "\0"
     84    /* ARPHRD_ASH,         */ "ash" "\0"
     85    /* ARPHRD_ECONET,      */ "econet" "\0"
     86    /* ARPHRD_FCPP,        */ "fcpp" "\0"
     87    /* ARPHRD_FCAL,        */ "fcal" "\0"
     88    /* ARPHRD_FCPL,        */ "fcpl" "\0"
     89    /* ARPHRD_FCFABRIC,    */ "fcfb0" "\0"
     90    /* ARPHRD_FCFABRIC+1,  */ "fcfb1" "\0"
     91    /* ARPHRD_FCFABRIC+2,  */ "fcfb2" "\0"
     92    /* ARPHRD_FCFABRIC+3,  */ "fcfb3" "\0"
     93    /* ARPHRD_FCFABRIC+4,  */ "fcfb4" "\0"
     94    /* ARPHRD_FCFABRIC+5,  */ "fcfb5" "\0"
     95    /* ARPHRD_FCFABRIC+6,  */ "fcfb6" "\0"
     96    /* ARPHRD_FCFABRIC+7,  */ "fcfb7" "\0"
     97    /* ARPHRD_FCFABRIC+8,  */ "fcfb8" "\0"
     98    /* ARPHRD_FCFABRIC+9,  */ "fcfb9" "\0"
     99    /* ARPHRD_FCFABRIC+10, */ "fcfb10" "\0"
     100    /* ARPHRD_FCFABRIC+11, */ "fcfb11" "\0"
     101    /* ARPHRD_FCFABRIC+12, */ "fcfb12" "\0"
     102#endif /* FEATURE_IP_RARE_PROTOCOLS */
     103    ;
     104
     105    /* Keep these arrays in sync! */
     106
     107    static const uint16_t arphrd_type[] = {
     108    0,                  /* "generic" "\0" */
     109    ARPHRD_LOOPBACK,    /* "loopback" "\0" */
     110    ARPHRD_ETHER,       /* "ether" "\0" */
     111#ifdef ARPHRD_INFINIBAND
     112    ARPHRD_INFINIBAND,  /* "infiniband" "\0" */
     113#endif
     114#ifdef ARPHRD_IEEE802_TR
     115    ARPHRD_IEEE802,     /* "ieee802" "\0" */
     116    ARPHRD_IEEE802_TR,  /* "tr" "\0" */
     117#else
     118    ARPHRD_IEEE802,     /* "tr" "\0" */
     119#endif
     120#ifdef ARPHRD_IEEE80211
     121    ARPHRD_IEEE80211,   /* "ieee802.11" "\0" */
     122#endif
    43123#ifdef ARPHRD_IEEE1394
    44 __PF(IEEE1394,ieee1394)
    45 #endif
    46 
    47 __PF(SLIP,slip)
    48 __PF(CSLIP,cslip)
    49 __PF(SLIP6,slip6)
    50 __PF(CSLIP6,cslip6)
    51 __PF(RSRVD,rsrvd)
    52 __PF(ADAPT,adapt)
    53 __PF(ROSE,rose)
    54 __PF(X25,x25)
     124    ARPHRD_IEEE1394,    /* "ieee1394" "\0" */
     125#endif
     126    ARPHRD_IRDA,        /* "irda" "\0" */
     127    ARPHRD_SLIP,        /* "slip" "\0" */
     128    ARPHRD_CSLIP,       /* "cslip" "\0" */
     129    ARPHRD_SLIP6,       /* "slip6" "\0" */
     130    ARPHRD_CSLIP6,      /* "cslip6" "\0" */
     131    ARPHRD_PPP,         /* "ppp" "\0" */
     132    ARPHRD_TUNNEL,      /* "ipip" "\0" */
     133    ARPHRD_TUNNEL6,     /* "tunnel6" "\0" */
     134    ARPHRD_SIT,         /* "sit" "\0" */
     135    ARPHRD_IPGRE,       /* "gre" "\0" */
     136#ifdef ARPHRD_VOID
     137    ARPHRD_VOID,        /* "void" "\0" */
     138#endif
     139
     140#if ENABLE_FEATURE_IP_RARE_PROTOCOLS
     141    ARPHRD_EETHER,      /* "eether" "\0" */
     142    ARPHRD_AX25,        /* "ax25" "\0" */
     143    ARPHRD_PRONET,      /* "pronet" "\0" */
     144    ARPHRD_CHAOS,       /* "chaos" "\0" */
     145    ARPHRD_ARCNET,      /* "arcnet" "\0" */
     146    ARPHRD_APPLETLK,    /* "atalk" "\0" */
     147    ARPHRD_DLCI,        /* "dlci" "\0" */
     148#ifdef ARPHRD_ATM
     149    ARPHRD_ATM,         /* "atm" "\0" */
     150#endif
     151    ARPHRD_METRICOM,    /* "metricom" "\0" */
     152    ARPHRD_RSRVD,       /* "rsrvd" "\0" */
     153    ARPHRD_ADAPT,       /* "adapt" "\0" */
     154    ARPHRD_ROSE,        /* "rose" "\0" */
     155    ARPHRD_X25,         /* "x25" "\0" */
    55156#ifdef ARPHRD_HWX25
    56 __PF(HWX25,hwx25)
    57 #endif
    58 __PF(PPP,ppp)
    59 __PF(HDLC,hdlc)
    60 __PF(LAPB,lapb)
     157    ARPHRD_HWX25,       /* "hwx25" "\0" */
     158#endif
     159    ARPHRD_HDLC,        /* "hdlc" "\0" */
     160    ARPHRD_LAPB,        /* "lapb" "\0" */
    61161#ifdef ARPHRD_DDCMP
    62 __PF(DDCMP,ddcmp)
    63 __PF(RAWHDLC,rawhdlc)
    64 #endif
    65 
    66 __PF(TUNNEL,ipip)
    67 __PF(TUNNEL6,tunnel6)
    68 __PF(FRAD,frad)
    69 __PF(SKIP,skip)
    70 __PF(LOOPBACK,loopback)
    71 __PF(LOCALTLK,ltalk)
    72 __PF(FDDI,fddi)
    73 __PF(BIF,bif)
    74 __PF(SIT,sit)
    75 __PF(IPDDP,ip/ddp)
    76 __PF(IPGRE,gre)
    77 __PF(PIMREG,pimreg)
    78 __PF(HIPPI,hippi)
    79 __PF(ASH,ash)
    80 __PF(ECONET,econet)
    81 __PF(IRDA,irda)
    82 __PF(FCPP,fcpp)
    83 __PF(FCAL,fcal)
    84 __PF(FCPL,fcpl)
    85 __PF(FCFABRIC,fcfb0)
    86 __PF(FCFABRIC+1,fcfb1)
    87 __PF(FCFABRIC+2,fcfb2)
    88 __PF(FCFABRIC+3,fcfb3)
    89 __PF(FCFABRIC+4,fcfb4)
    90 __PF(FCFABRIC+5,fcfb5)
    91 __PF(FCFABRIC+6,fcfb6)
    92 __PF(FCFABRIC+7,fcfb7)
    93 __PF(FCFABRIC+8,fcfb8)
    94 __PF(FCFABRIC+9,fcfb9)
    95 __PF(FCFABRIC+10,fcfb10)
    96 __PF(FCFABRIC+11,fcfb11)
    97 __PF(FCFABRIC+12,fcfb12)
    98 #ifdef ARPHRD_IEEE802_TR
    99 __PF(IEEE802_TR,tr)
    100 #endif
    101 #ifdef ARPHRD_IEEE80211
    102 __PF(IEEE80211,ieee802.11)
    103 #endif
    104 #ifdef ARPHRD_VOID
    105 __PF(VOID,void)
    106 #endif
    107 };
    108 #undef __PF
    109 
    110     int i;
    111     for (i = 0; i < ARRAY_SIZE(arphrd_names); i++) {
    112          if (arphrd_names[i].type == type)
    113             return arphrd_names[i].name;
     162    ARPHRD_DDCMP,       /* "ddcmp" "\0" */
     163    ARPHRD_RAWHDLC,     /* "rawhdlc" "\0" */
     164#endif
     165    ARPHRD_FRAD,        /* "frad" "\0" */
     166    ARPHRD_SKIP,        /* "skip" "\0" */
     167    ARPHRD_LOCALTLK,    /* "ltalk" "\0" */
     168    ARPHRD_FDDI,        /* "fddi" "\0" */
     169    ARPHRD_BIF,         /* "bif" "\0" */
     170    ARPHRD_IPDDP,       /* "ip/ddp" "\0" */
     171    ARPHRD_PIMREG,      /* "pimreg" "\0" */
     172    ARPHRD_HIPPI,       /* "hippi" "\0" */
     173    ARPHRD_ASH,         /* "ash" "\0" */
     174    ARPHRD_ECONET,      /* "econet" "\0" */
     175    ARPHRD_FCPP,        /* "fcpp" "\0" */
     176    ARPHRD_FCAL,        /* "fcal" "\0" */
     177    ARPHRD_FCPL,        /* "fcpl" "\0" */
     178    ARPHRD_FCFABRIC,    /* "fcfb0" "\0" */
     179    ARPHRD_FCFABRIC+1,  /* "fcfb1" "\0" */
     180    ARPHRD_FCFABRIC+2,  /* "fcfb2" "\0" */
     181    ARPHRD_FCFABRIC+3,  /* "fcfb3" "\0" */
     182    ARPHRD_FCFABRIC+4,  /* "fcfb4" "\0" */
     183    ARPHRD_FCFABRIC+5,  /* "fcfb5" "\0" */
     184    ARPHRD_FCFABRIC+6,  /* "fcfb6" "\0" */
     185    ARPHRD_FCFABRIC+7,  /* "fcfb7" "\0" */
     186    ARPHRD_FCFABRIC+8,  /* "fcfb8" "\0" */
     187    ARPHRD_FCFABRIC+9,  /* "fcfb9" "\0" */
     188    ARPHRD_FCFABRIC+10, /* "fcfb10" "\0" */
     189    ARPHRD_FCFABRIC+11, /* "fcfb11" "\0" */
     190    ARPHRD_FCFABRIC+12, /* "fcfb12" "\0" */
     191#endif /* FEATURE_IP_RARE_PROTOCOLS */
     192    };
     193
     194    unsigned i;
     195    const char *aname = arphrd_name;
     196    for (i = 0; i < ARRAY_SIZE(arphrd_type); i++) {
     197        if (arphrd_type[i] == type)
     198            return aname;
     199        aname += strlen(aname) + 1;
    114200    }
    115     snprintf(buf, len, "[%d]", type);
     201    sprintf(buf, "[%d]", type);
    116202    return buf;
    117203}
  • branches/2.2.9/mindi-busybox/networking/libiproute/rt_names.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * rt_names.c       rtnetlink names DB.
     3 * This program is free software; you can redistribute it and/or
     4 * modify it under the terms of the GNU General Public License
     5 * as published by the Free Software Foundation; either version
     6 * 2 of the License, or (at your option) any later version.
    47 *
    5  *      This program is free software; you can redistribute it and/or
    6  *      modify it under the terms of the GNU General Public License
    7  *      as published by the Free Software Foundation; either version
    8  *      2 of the License, or (at your option) any later version.
    9  *
    10  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
     8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    119 */
    12 
    1310#include "libbb.h"
    1411#include "rt_names.h"
    1512
    16 static void rtnl_tab_initialize(const char *file, const char **tab, int size)
    17 {
    18     char buf[512];
    19     FILE *fp;
    20 
    21     fp = fopen(file, "r");
    22     if (!fp)
    23         return;
    24     while (fgets(buf, sizeof(buf), fp)) {
    25         char *p = buf;
    26         int id;
    27         char namebuf[512];
    28 
    29         while (*p == ' ' || *p == '\t')
    30             p++;
    31         if (*p == '#' || *p == '\n' || *p == 0)
    32             continue;
    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
     13typedef struct rtnl_tab_t {
     14    const char *cached_str;
     15    unsigned cached_result;
     16    const char *tab[256];
     17} rtnl_tab_t;
     18
     19static void rtnl_tab_initialize(const char *file, const char **tab)
     20{
     21    char *token[2];
     22    parser_t *parser = config_open2(file, fopen_for_read);
     23
     24    while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) {
     25        unsigned id = bb_strtou(token[0], NULL, 0);
     26        if (id > 256) {
     27            bb_error_msg("database %s is corrupted at line %d",
     28                file, parser->lineno);
     29            break;
     30        }
     31        tab[id] = xstrdup(token[1]);
     32    }
     33    config_close(parser);
     34}
     35
     36static int rtnl_a2n(rtnl_tab_t *tab, uint32_t *id, const char *arg, int base)
     37{
     38    unsigned i;
     39
     40    if (tab->cached_str && strcmp(tab->cached_str, arg) == 0) {
     41        *id = tab->cached_result;
     42        return 0;
     43    }
     44
     45    for (i = 0; i < 256; i++) {
     46        if (tab->tab[i]
     47         && strcmp(tab->tab[i], arg) == 0
    3748        ) {
    38             bb_error_msg("database %s is corrupted at %s",
    39                 file, p);
    40             return;
     49            tab->cached_str = tab->tab[i];
     50            tab->cached_result = i;
     51            *id = i;
     52            return 0;
    4153        }
    42 
    43         if (id < 0 || id > size)
    44             continue;
    45 
    46         tab[id] = xstrdup(namebuf);
    47     }
    48     fclose(fp);
    49 }
    50 
    51 
    52 static const char **rtnl_rtprot_tab; /* [256] */
     54    }
     55
     56    i = bb_strtou(arg, NULL, base);
     57    if (i > 255)
     58        return -1;
     59    *id = i;
     60    return 0;
     61}
     62
     63
     64static rtnl_tab_t *rtnl_rtprot_tab;
    5365
    5466static void rtnl_rtprot_initialize(void)
     
    6981        "bird",
    7082    };
    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));
    74     rtnl_tab_initialize("/etc/iproute2/rt_protos",
    75                 rtnl_rtprot_tab, 256);
    76 }
    77 
    78 
    79 const char* rtnl_rtprot_n2a(int id, char *buf, int len)
    80 {
    81     if (id < 0 || id >= 256) {
    82         snprintf(buf, len, "%d", id);
     83
     84    if (rtnl_rtprot_tab)
     85        return;
     86    rtnl_rtprot_tab = xzalloc(sizeof(*rtnl_rtprot_tab));
     87    memcpy(rtnl_rtprot_tab->tab, init_tab, sizeof(init_tab));
     88    rtnl_tab_initialize("/etc/iproute2/rt_protos", rtnl_rtprot_tab->tab);
     89}
     90
     91const char* FAST_FUNC rtnl_rtprot_n2a(int id, char *buf)
     92{
     93    if (id < 0 || id >= 256) {
     94        sprintf(buf, "%d", id);
    8395        return buf;
    8496    }
     
    8698    rtnl_rtprot_initialize();
    8799
    88     if (rtnl_rtprot_tab[id])
    89         return rtnl_rtprot_tab[id];
    90     snprintf(buf, len, "%d", id);
    91     return buf;
    92 }
    93 
    94 int rtnl_rtprot_a2n(uint32_t *id, char *arg)
    95 {
    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 
     100    if (rtnl_rtprot_tab->tab[id])
     101        return rtnl_rtprot_tab->tab[id];
     102    /* buf is SPRINT_BSIZE big */
     103    sprintf(buf, "%d", id);
     104    return buf;
     105}
     106
     107int FAST_FUNC rtnl_rtprot_a2n(uint32_t *id, char *arg)
     108{
    105109    rtnl_rtprot_initialize();
    106 
    107     for (i = 0; i < 256; i++) {
    108         if (rtnl_rtprot_tab[i] &&
    109             strcmp(rtnl_rtprot_tab[i], arg) == 0) {
    110             cache = rtnl_rtprot_tab[i];
    111             res = i;
    112             *id = res;
    113             return 0;
    114         }
    115     }
    116 
    117     res = bb_strtoul(arg, NULL, 0);
    118     if (errno || res > 255)
    119         return -1;
    120     *id = res;
    121     return 0;
    122 }
    123 
    124 
    125 static const char **rtnl_rtscope_tab; /* [256] */
     110    return rtnl_a2n(rtnl_rtprot_tab, id, arg, 0);
     111}
     112
     113
     114static rtnl_tab_t *rtnl_rtscope_tab;
    126115
    127116static void rtnl_rtscope_initialize(void)
    128117{
    129     if (rtnl_rtscope_tab) return;
    130     rtnl_rtscope_tab = xzalloc(256 * sizeof(rtnl_rtscope_tab[0]));
    131     rtnl_rtscope_tab[0] = "global";
    132     rtnl_rtscope_tab[255] = "nowhere";
    133     rtnl_rtscope_tab[254] = "host";
    134     rtnl_rtscope_tab[253] = "link";
    135     rtnl_rtscope_tab[200] = "site";
    136     rtnl_tab_initialize("/etc/iproute2/rt_scopes",
    137                 rtnl_rtscope_tab, 256);
    138 }
    139 
    140 
    141 const char* rtnl_rtscope_n2a(int id, char *buf, int len)
    142 {
    143     if (id < 0 || id >= 256) {
    144         snprintf(buf, len, "%d", id);
     118    if (rtnl_rtscope_tab)
     119        return;
     120    rtnl_rtscope_tab = xzalloc(sizeof(*rtnl_rtscope_tab));
     121    rtnl_rtscope_tab->tab[0] = "global";
     122    rtnl_rtscope_tab->tab[255] = "nowhere";
     123    rtnl_rtscope_tab->tab[254] = "host";
     124    rtnl_rtscope_tab->tab[253] = "link";
     125    rtnl_rtscope_tab->tab[200] = "site";
     126    rtnl_tab_initialize("/etc/iproute2/rt_scopes", rtnl_rtscope_tab->tab);
     127}
     128
     129const char* FAST_FUNC rtnl_rtscope_n2a(int id, char *buf)
     130{
     131    if (id < 0 || id >= 256) {
     132        sprintf(buf, "%d", id);
    145133        return buf;
    146134    }
     
    148136    rtnl_rtscope_initialize();
    149137
    150     if (rtnl_rtscope_tab[id])
    151         return rtnl_rtscope_tab[id];
    152     snprintf(buf, len, "%d", id);
    153     return buf;
    154 }
    155 
    156 int rtnl_rtscope_a2n(uint32_t *id, char *arg)
    157 {
    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 
     138    if (rtnl_rtscope_tab->tab[id])
     139        return rtnl_rtscope_tab->tab[id];
     140    /* buf is SPRINT_BSIZE big */
     141    sprintf(buf, "%d", id);
     142    return buf;
     143}
     144
     145int FAST_FUNC rtnl_rtscope_a2n(uint32_t *id, char *arg)
     146{
    167147    rtnl_rtscope_initialize();
    168 
    169     for (i = 0; i < 256; i++) {
    170         if (rtnl_rtscope_tab[i] &&
    171             strcmp(rtnl_rtscope_tab[i], arg) == 0) {
    172             cache = rtnl_rtscope_tab[i];
    173             res = i;
    174             *id = res;
    175             return 0;
    176         }
    177     }
    178 
    179     res = bb_strtoul(arg, NULL, 0);
    180     if (errno || res > 255)
    181         return -1;
    182     *id = res;
    183     return 0;
    184 }
    185 
    186 
    187 static const char **rtnl_rtrealm_tab; /* [256] */
     148    return rtnl_a2n(rtnl_rtscope_tab, id, arg, 0);
     149}
     150
     151
     152static rtnl_tab_t *rtnl_rtrealm_tab;
    188153
    189154static void rtnl_rtrealm_initialize(void)
    190155{
    191156    if (rtnl_rtrealm_tab) return;
    192     rtnl_rtrealm_tab = xzalloc(256 * sizeof(rtnl_rtrealm_tab[0]));
    193     rtnl_rtrealm_tab[0] = "unknown";
    194     rtnl_tab_initialize("/etc/iproute2/rt_realms",
    195                 rtnl_rtrealm_tab, 256);
    196 }
    197 
    198 
    199 int rtnl_rtrealm_a2n(uint32_t *id, char *arg)
    200 {
    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 
     157    rtnl_rtrealm_tab = xzalloc(sizeof(*rtnl_rtrealm_tab));
     158    rtnl_rtrealm_tab->tab[0] = "unknown";
     159    rtnl_tab_initialize("/etc/iproute2/rt_realms", rtnl_rtrealm_tab->tab);
     160}
     161
     162int FAST_FUNC rtnl_rtrealm_a2n(uint32_t *id, char *arg)
     163{
    210164    rtnl_rtrealm_initialize();
    211 
    212     for (i = 0; i < 256; i++) {
    213         if (rtnl_rtrealm_tab[i] &&
    214             strcmp(rtnl_rtrealm_tab[i], arg) == 0) {
    215             cache = rtnl_rtrealm_tab[i];
    216             res = i;
    217             *id = res;
    218             return 0;
    219         }
    220     }
    221 
    222     res = bb_strtoul(arg, NULL, 0);
    223     if (errno || res > 255)
    224         return -1;
    225     *id = res;
    226     return 0;
     165    return rtnl_a2n(rtnl_rtrealm_tab, id, arg, 0);
    227166}
    228167
    229168#if ENABLE_FEATURE_IP_RULE
    230 const char* rtnl_rtrealm_n2a(int id, char *buf, int len)
    231 {
    232     if (id < 0 || id >= 256) {
    233         snprintf(buf, len, "%d", id);
     169const char* FAST_FUNC rtnl_rtrealm_n2a(int id, char *buf)
     170{
     171    if (id < 0 || id >= 256) {
     172        sprintf(buf, "%d", id);
    234173        return buf;
    235174    }
     
    237176    rtnl_rtrealm_initialize();
    238177
    239     if (rtnl_rtrealm_tab[id])
    240         return rtnl_rtrealm_tab[id];
    241     snprintf(buf, len, "%d", id);
     178    if (rtnl_rtrealm_tab->tab[id])
     179        return rtnl_rtrealm_tab->tab[id];
     180    /* buf is SPRINT_BSIZE big */
     181    sprintf(buf, "%d", id);
    242182    return buf;
    243183}
     
    245185
    246186
    247 static const char **rtnl_rtdsfield_tab; /* [256] */
     187static rtnl_tab_t *rtnl_rtdsfield_tab;
    248188
    249189static void rtnl_rtdsfield_initialize(void)
    250190{
    251191    if (rtnl_rtdsfield_tab) return;
    252     rtnl_rtdsfield_tab = xzalloc(256 * sizeof(rtnl_rtdsfield_tab[0]));
    253     rtnl_rtdsfield_tab[0] = "0";
    254     rtnl_tab_initialize("/etc/iproute2/rt_dsfield",
    255                 rtnl_rtdsfield_tab, 256);
    256 }
    257 
    258 
    259 const char * rtnl_dsfield_n2a(int id, char *buf, int len)
    260 {
    261     if (id < 0 || id >= 256) {
    262         snprintf(buf, len, "%d", id);
     192    rtnl_rtdsfield_tab = xzalloc(sizeof(*rtnl_rtdsfield_tab));
     193    rtnl_rtdsfield_tab->tab[0] = "0";
     194    rtnl_tab_initialize("/etc/iproute2/rt_dsfield", rtnl_rtdsfield_tab->tab);
     195}
     196
     197const char* FAST_FUNC rtnl_dsfield_n2a(int id, char *buf)
     198{
     199    if (id < 0 || id >= 256) {
     200        sprintf(buf, "%d", id);
    263201        return buf;
    264202    }
     
    266204    rtnl_rtdsfield_initialize();
    267205
    268     if (rtnl_rtdsfield_tab[id])
    269         return rtnl_rtdsfield_tab[id];
    270     snprintf(buf, len, "0x%02x", id);
    271     return buf;
    272 }
    273 
    274 
    275 int rtnl_dsfield_a2n(uint32_t *id, char *arg)
    276 {
    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 
     206    if (rtnl_rtdsfield_tab->tab[id])
     207        return rtnl_rtdsfield_tab->tab[id];
     208    /* buf is SPRINT_BSIZE big */
     209    sprintf(buf, "0x%02x", id);
     210    return buf;
     211}
     212
     213int FAST_FUNC rtnl_dsfield_a2n(uint32_t *id, char *arg)
     214{
    286215    rtnl_rtdsfield_initialize();
    287 
    288     for (i = 0; i < 256; i++) {
    289         if (rtnl_rtdsfield_tab[i] &&
    290             strcmp(rtnl_rtdsfield_tab[i], arg) == 0) {
    291             cache = rtnl_rtdsfield_tab[i];
    292             res = i;
    293             *id = res;
    294             return 0;
    295         }
    296     }
    297 
    298     res = bb_strtoul(arg, NULL, 16);
    299     if (errno || res > 255)
    300         return -1;
    301     *id = res;
    302     return 0;
     216    return rtnl_a2n(rtnl_rtdsfield_tab, id, arg, 16);
    303217}
    304218
    305219
    306220#if ENABLE_FEATURE_IP_RULE
    307 static const char **rtnl_rttable_tab; /* [256] */
     221static rtnl_tab_t *rtnl_rttable_tab;
    308222
    309223static void rtnl_rttable_initialize(void)
    310224{
    311225    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 
    321 const char *rtnl_rttable_n2a(int id, char *buf, int len)
    322 {
    323     if (id < 0 || id >= 256) {
    324         snprintf(buf, len, "%d", id);
     226    rtnl_rttable_tab = xzalloc(sizeof(*rtnl_rttable_tab));
     227    rtnl_rttable_tab->tab[0] = "unspec";
     228    rtnl_rttable_tab->tab[255] = "local";
     229    rtnl_rttable_tab->tab[254] = "main";
     230    rtnl_rttable_tab->tab[253] = "default";
     231    rtnl_tab_initialize("/etc/iproute2/rt_tables", rtnl_rttable_tab->tab);
     232}
     233
     234const char* FAST_FUNC rtnl_rttable_n2a(int id, char *buf)
     235{
     236    if (id < 0 || id >= 256) {
     237        sprintf(buf, "%d", id);
    325238        return buf;
    326239    }
     
    328241    rtnl_rttable_initialize();
    329242
    330     if (rtnl_rttable_tab[id])
    331         return rtnl_rttable_tab[id];
    332     snprintf(buf, len, "%d", id);
    333     return buf;
    334 }
    335 
    336 int 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 
     243    if (rtnl_rttable_tab->tab[id])
     244        return rtnl_rttable_tab->tab[id];
     245    /* buf is SPRINT_BSIZE big */
     246    sprintf(buf, "%d", id);
     247    return buf;
     248}
     249
     250int FAST_FUNC rtnl_rttable_a2n(uint32_t *id, char *arg)
     251{
    347252    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;
     253    return rtnl_a2n(rtnl_rttable_tab, id, arg, 0);
    363254}
    364255
  • branches/2.2.9/mindi-busybox/networking/libiproute/rt_names.h

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    2 #ifndef RT_NAMES_H_
    3 #define RT_NAMES_H_ 1
     2#ifndef RT_NAMES_H
     3#define RT_NAMES_H 1
    44
    5 #include <stdint.h>
     5PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
    66
    7 extern const char* rtnl_rtprot_n2a(int id, char *buf, int len);
    8 extern const char* rtnl_rtscope_n2a(int id, char *buf, int len);
    9 extern const char* rtnl_rtrealm_n2a(int id, char *buf, int len);
    10 extern const char* rtnl_dsfield_n2a(int id, char *buf, int len);
    11 extern const char* rtnl_rttable_n2a(int id, char *buf, int len);
    12 extern int rtnl_rtprot_a2n(uint32_t *id, char *arg);
    13 extern int rtnl_rtscope_a2n(uint32_t *id, char *arg);
    14 extern int rtnl_rtrealm_a2n(uint32_t *id, char *arg);
    15 extern int rtnl_dsfield_a2n(uint32_t *id, char *arg);
    16 extern int rtnl_rttable_a2n(uint32_t *id, char *arg);
     7/* buf is SPRINT_BSIZE big */
     8extern const char* rtnl_rtprot_n2a(int id, char *buf) FAST_FUNC;
     9extern const char* rtnl_rtscope_n2a(int id, char *buf) FAST_FUNC;
     10extern const char* rtnl_rtrealm_n2a(int id, char *buf) FAST_FUNC;
     11extern const char* rtnl_dsfield_n2a(int id, char *buf) FAST_FUNC;
     12extern const char* rtnl_rttable_n2a(int id, char *buf) FAST_FUNC;
     13extern int rtnl_rtprot_a2n(uint32_t *id, char *arg) FAST_FUNC;
     14extern int rtnl_rtscope_a2n(uint32_t *id, char *arg) FAST_FUNC;
     15extern int rtnl_rtrealm_a2n(uint32_t *id, char *arg) FAST_FUNC;
     16extern int rtnl_dsfield_a2n(uint32_t *id, char *arg) FAST_FUNC;
     17extern int rtnl_rttable_a2n(uint32_t *id, char *arg) FAST_FUNC;
    1718
    18 
    19 extern const char* ll_type_n2a(int type, char *buf, int len);
     19extern const char* ll_type_n2a(int type, char *buf) FAST_FUNC;
    2020
    2121extern const char* ll_addr_n2a(unsigned char *addr, int alen, int type,
    22                 char *buf, int blen);
    23 extern int ll_addr_a2n(unsigned char *lladdr, int len, char *arg);
     22                char *buf, int blen) FAST_FUNC;
     23extern int ll_addr_a2n(unsigned char *lladdr, int len, char *arg) FAST_FUNC;
    2424
    25 extern const char* ll_proto_n2a(unsigned short id, char *buf, int len);
    26 extern int ll_proto_a2n(unsigned short *id, char *buf);
     25extern const char* ll_proto_n2a(unsigned short id, char *buf, int len) FAST_FUNC;
     26extern int ll_proto_a2n(unsigned short *id, char *buf) FAST_FUNC;
     27
     28POP_SAVED_FUNCTION_VISIBILITY
    2729
    2830#endif
  • branches/2.2.9/mindi-busybox/networking/libiproute/rtm_map.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * rtm_map.c
     3 * This program is free software; you can redistribute it and/or
     4 * modify it under the terms of the GNU General Public License
     5 * as published by the Free Software Foundation; either version
     6 * 2 of the License, or (at your option) any later version.
    47 *
    5  *      This program is free software; you can redistribute it and/or
    6  *      modify it under the terms of the GNU General Public License
    7  *      as published by the Free Software Foundation; either version
    8  *      2 of the License, or (at your option) any later version.
    9  *
    10  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    11  *
     8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    129 */
    1310
     
    1613#include "utils.h"
    1714
    18 const char *rtnl_rtntype_n2a(int id, char *buf, int len)
     15const char* FAST_FUNC rtnl_rtntype_n2a(int id, char *buf)
    1916{
    2017    switch (id) {
     
    4441        return "xresolve";
    4542    default:
    46         snprintf(buf, len, "%d", id);
     43        /* buf is SPRINT_BSIZE big */
     44        sprintf(buf, "%d", id);
    4745        return buf;
    4846    }
     
    5048
    5149
    52 int rtnl_rtntype_a2n(int *id, char *arg)
     50int FAST_FUNC rtnl_rtntype_a2n(int *id, char *arg)
    5351{
    5452    static const char keywords[] ALIGN1 =
     
    8987    else {
    9088        res = strtoul(arg, &end, 0);
    91         if (!end || end == arg || *end || res > 255)
     89        if (end == arg || *end || res > 255)
    9290            return -1;
    9391    }
     
    9694}
    9795
    98 int get_rt_realms(uint32_t *realms, char *arg)
     96int FAST_FUNC get_rt_realms(uint32_t *realms, char *arg)
    9997{
    10098    uint32_t realm = 0;
  • branches/2.2.9/mindi-busybox/networking/libiproute/rtm_map.h

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    2 #ifndef __RTM_MAP_H__
    3 #define __RTM_MAP_H__ 1
     2#ifndef RTM_MAP_H
     3#define RTM_MAP_H 1
    44
    5 const char *rtnl_rtntype_n2a(int id, char *buf, int len);
    6 int rtnl_rtntype_a2n(int *id, char *arg);
     5PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
    76
    8 int get_rt_realms(uint32_t *realms, char *arg);
     7const char *rtnl_rtntype_n2a(int id, char *buf) FAST_FUNC;
     8int rtnl_rtntype_a2n(int *id, char *arg) FAST_FUNC;
    99
     10int get_rt_realms(uint32_t *realms, char *arg) FAST_FUNC;
    1011
    11 #endif /* __RTM_MAP_H__ */
     12POP_SAVED_FUNCTION_VISIBILITY
     13
     14#endif
  • branches/2.2.9/mindi-busybox/networking/libiproute/utils.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * utils.c
     3 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    44 *
    5  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
    6  *
    7  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
     5 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    86 *
    97 * Changes:
    108 *
    11  * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
     9 * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
    1210 */
    1311
     
    1614#include "inet_common.h"
    1715
    18 int get_integer(int *val, char *arg, int base)
    19 {
    20     long res;
    21     char *ptr;
    22 
    23     if (!arg || !*arg)
    24         return -1;
    25     res = strtol(arg, &ptr, base);
    26     if (!ptr || ptr == arg || *ptr || res > INT_MAX || res < INT_MIN)
    27         return -1;
    28     *val = res;
    29     return 0;
    30 }
    31 //XXX: FIXME: use some libbb function instead
    32 int get_unsigned(unsigned *val, char *arg, int base)
     16unsigned get_unsigned(char *arg, const char *errmsg)
    3317{
    3418    unsigned long res;
    3519    char *ptr;
    3620
    37     if (!arg || !*arg)
    38         return -1;
    39     res = strtoul(arg, &ptr, base);
    40     if (!ptr || ptr == arg || *ptr || res > UINT_MAX)
    41         return -1;
    42     *val = res;
    43     return 0;
    44 }
    45 
    46 int get_u32(uint32_t * val, char *arg, int base)
     21    if (*arg) {
     22        res = strtoul(arg, &ptr, 0);
     23//FIXME: "" will be accepted too, is it correct?!
     24        if (!*ptr && res <= UINT_MAX) {
     25            return res;
     26        }
     27    }
     28    invarg(arg, errmsg); /* does not return */
     29}
     30
     31uint32_t get_u32(char *arg, const char *errmsg)
    4732{
    4833    unsigned long res;
    4934    char *ptr;
    5035
    51     if (!arg || !*arg)
    52         return -1;
    53     res = strtoul(arg, &ptr, base);
    54     if (!ptr || ptr == arg || *ptr || res > 0xFFFFFFFFUL)
    55         return -1;
    56     *val = res;
    57     return 0;
    58 }
    59 
    60 int get_u16(uint16_t * val, char *arg, int base)
     36    if (*arg) {
     37        res = strtoul(arg, &ptr, 0);
     38//FIXME: "" will be accepted too, is it correct?!
     39        if (!*ptr && res <= 0xFFFFFFFFUL) {
     40            return res;
     41        }
     42    }
     43    invarg(arg, errmsg); /* does not return */
     44}
     45
     46uint16_t get_u16(char *arg, const char *errmsg)
    6147{
    6248    unsigned long res;
    6349    char *ptr;
    6450
    65     if (!arg || !*arg)
    66         return -1;
    67     res = strtoul(arg, &ptr, base);
    68     if (!ptr || ptr == arg || *ptr || res > 0xFFFF)
    69         return -1;
    70     *val = res;
    71     return 0;
    72 }
    73 
    74 int get_u8(uint8_t * val, char *arg, int base)
    75 {
    76     unsigned long res;
    77     char *ptr;
    78 
    79     if (!arg || !*arg)
    80         return -1;
    81     res = strtoul(arg, &ptr, base);
    82     if (!ptr || ptr == arg || *ptr || res > 0xFF)
    83         return -1;
    84     *val = res;
    85     return 0;
    86 }
    87 
    88 int get_s16(int16_t * val, char *arg, int base)
    89 {
    90     long res;
    91     char *ptr;
    92 
    93     if (!arg || !*arg)
    94         return -1;
    95     res = strtol(arg, &ptr, base);
    96     if (!ptr || ptr == arg || *ptr || res > 0x7FFF || res < -0x8000)
    97         return -1;
    98     *val = res;
    99     return 0;
    100 }
    101 
    102 int get_s8(int8_t * val, char *arg, int base)
    103 {
    104     long res;
    105     char *ptr;
    106 
    107     if (!arg || !*arg)
    108         return -1;
    109     res = strtol(arg, &ptr, base);
    110     if (!ptr || ptr == arg || *ptr || res > 0x7F || res < -0x80)
    111         return -1;
    112     *val = res;
    113     return 0;
    114 }
    115 
    116 int get_addr_1(inet_prefix * addr, char *name, int family)
    117 {
    118     char *cp;
    119     unsigned char *ap = (unsigned char *) addr->data;
    120     int i;
    121 
     51    if (*arg) {
     52        res = strtoul(arg, &ptr, 0);
     53//FIXME: "" will be accepted too, is it correct?!
     54        if (!*ptr && res <= 0xFFFF) {
     55            return res;
     56        }
     57    }
     58    invarg(arg, errmsg); /* does not return */
     59}
     60
     61int get_addr_1(inet_prefix *addr, char *name, int family)
     62{
    12263    memset(addr, 0, sizeof(*addr));
    12364
    124     if (strcmp(name, bb_str_default) == 0 ||
    125         strcmp(name, "all") == 0 || strcmp(name, "any") == 0) {
     65    if (strcmp(name, "default") == 0
     66     || strcmp(name, "all") == 0
     67     || strcmp(name, "any") == 0
     68    ) {
    12669        addr->family = family;
    12770        addr->bytelen = (family == AF_INET6 ? 16 : 4);
     
    14487    if (family != AF_UNSPEC && family != AF_INET)
    14588        return -1;
     89    if (inet_pton(AF_INET, name, addr->data) <= 0)
     90        return -1;
    14691    addr->bytelen = 4;
    14792    addr->bitlen = -1;
    148     for (cp = name, i = 0; *cp; cp++) {
    149         if (*cp <= '9' && *cp >= '0') {
    150             ap[i] = 10 * ap[i] + (*cp - '0');
    151             continue;
    152         }
    153         if (*cp == '.' && ++i <= 3)
    154             continue;
    155         return -1;
    156     }
    157     return 0;
    158 }
    159 
    160 int get_prefix_1(inet_prefix * dst, char *arg, int family)
     93    return 0;
     94}
     95
     96static int get_prefix_1(inet_prefix *dst, char *arg, int family)
    16197{
    16298    int err;
    163     int plen;
     99    unsigned plen;
    164100    char *slash;
    165101
    166102    memset(dst, 0, sizeof(*dst));
    167103
    168     if (strcmp(arg, bb_str_default) == 0 || strcmp(arg, "any") == 0) {
     104    if (strcmp(arg, "default") == 0
     105     || strcmp(arg, "all") == 0
     106     || strcmp(arg, "any") == 0
     107    ) {
    169108        dst->family = family;
    170         dst->bytelen = 0;
    171         dst->bitlen = 0;
     109        /*dst->bytelen = 0; - done by memset */
     110        /*dst->bitlen = 0;*/
    172111        return 0;
    173112    }
     
    178117    err = get_addr_1(dst, arg, family);
    179118    if (err == 0) {
    180         switch (dst->family) {
    181         case AF_INET6:
    182             dst->bitlen = 128;
    183             break;
    184         default:
    185         case AF_INET:
    186             dst->bitlen = 32;
    187         }
     119        dst->bitlen = (dst->family == AF_INET6) ? 128 : 32;
    188120        if (slash) {
    189             if (get_integer(&plen, slash + 1, 0) || plen > dst->bitlen) {
     121            inet_prefix netmask_pfx;
     122
     123            netmask_pfx.family = AF_UNSPEC;
     124            plen = bb_strtou(slash + 1, NULL, 0);
     125            if ((errno || plen > dst->bitlen)
     126             && (get_addr_1(&netmask_pfx, slash + 1, family)))
    190127                err = -1;
    191                 goto done;
     128            else if (netmask_pfx.family == AF_INET) {
     129                /* fill in prefix length of dotted quad */
     130                uint32_t mask = ntohl(netmask_pfx.data[0]);
     131                uint32_t host = ~mask;
     132
     133                /* a valid netmask must be 2^n - 1 */
     134                if (!(host & (host + 1))) {
     135                    for (plen = 0; mask; mask <<= 1)
     136                        ++plen;
     137                    if (plen <= dst->bitlen) {
     138                        dst->bitlen = plen;
     139                        /* dst->flags |= PREFIXLEN_SPECIFIED; */
     140                    } else
     141                        err = -1;
     142                } else
     143                    err = -1;
     144            } else {
     145                /* plain prefix */
     146                dst->bitlen = plen;
    192147            }
    193             dst->bitlen = plen;
    194         }
    195     }
    196  done:
     148        }
     149    }
    197150    if (slash)
    198151        *slash = '/';
     
    200153}
    201154
    202 int get_addr(inet_prefix * dst, char *arg, int family)
     155int get_addr(inet_prefix *dst, char *arg, int family)
    203156{
    204157    if (family == AF_PACKET) {
    205         bb_error_msg_and_die("\"%s\" may be inet address, but it is not allowed in this context", arg);
     158        bb_error_msg_and_die("\"%s\" may be inet %s, but it is not allowed in this context", arg, "address");
    206159    }
    207160    if (get_addr_1(dst, arg, family)) {
    208         bb_error_msg_and_die("an inet address is expected rather than \"%s\"", arg);
    209     }
    210     return 0;
    211 }
    212 
    213 int get_prefix(inet_prefix * dst, char *arg, int family)
     161        bb_error_msg_and_die("an %s %s is expected rather than \"%s\"", "inet", "address", arg);
     162    }
     163    return 0;
     164}
     165
     166int get_prefix(inet_prefix *dst, char *arg, int family)
    214167{
    215168    if (family == AF_PACKET) {
    216         bb_error_msg_and_die("\"%s\" may be inet address, but it is not allowed in this context", arg);
     169        bb_error_msg_and_die("\"%s\" may be inet %s, but it is not allowed in this context", arg, "prefix");
    217170    }
    218171    if (get_prefix_1(dst, arg, family)) {
    219         bb_error_msg_and_die("an inet address is expected rather than \"%s\"", arg);
     172        bb_error_msg_and_die("an %s %s is expected rather than \"%s\"", "inet", "prefix", arg);
    220173    }
    221174    return 0;
     
    227180
    228181    if (get_addr_1(&addr, name, AF_INET)) {
    229         bb_error_msg_and_die("an IP address is expected rather than \"%s\"", name);
     182        bb_error_msg_and_die("an %s %s is expected rather than \"%s\"", "IP", "address", name);
    230183    }
    231184    return addr.data[0];
     
    252205}
    253206
    254 int inet_addr_match(inet_prefix * a, inet_prefix * b, int bits)
     207int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits)
    255208{
    256209    uint32_t *a1 = a->data;
    257210    uint32_t *a2 = b->data;
    258     int words = bits >> 0x05;
     211    int words = bits >> 5;
    259212
    260213    bits &= 0x1f;
     
    280233}
    281234
    282 const char *rt_addr_n2a(int af, int ATTRIBUTE_UNUSED len,
     235const char *rt_addr_n2a(int af,
    283236        void *addr, char *buf, int buflen)
    284237{
     
    292245}
    293246
    294 
     247#ifdef RESOLVE_HOSTNAMES
    295248const char *format_host(int af, int len, void *addr, char *buf, int buflen)
    296249{
    297 #ifdef RESOLVE_HOSTNAMES
    298250    if (resolve_hosts) {
    299251        struct hostent *h_ent;
     
    318270        }
    319271    }
     272    return rt_addr_n2a(af, addr, buf, buflen);
     273}
    320274#endif
    321     return rt_addr_n2a(af, len, addr, buf, buflen);
    322 }
  • branches/2.2.9/mindi-busybox/networking/libiproute/utils.h

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    2 #ifndef __UTILS_H__
    3 #define __UTILS_H__ 1
     2#ifndef UTILS_H
     3#define UTILS_H 1
    44
    55#include "libnetlink.h"
     
    77#include "rtm_map.h"
    88
    9 extern int preferred_family;
     9PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
     10
     11extern family_t preferred_family;
    1012extern smallint show_stats;    /* UNUSED */
    1113extern smallint show_details;  /* UNUSED */
     
    1618
    1719#ifndef IPPROTO_ESP
    18 #define IPPROTO_ESP 50
     20#define IPPROTO_ESP  50
    1921#endif
    2022#ifndef IPPROTO_AH
    21 #define IPPROTO_AH  51
     23#define IPPROTO_AH  51
    2224#endif
    2325
    2426#define SPRINT_BSIZE 64
    25 #define SPRINT_BUF(x)   char x[SPRINT_BSIZE]
     27#define SPRINT_BUF(x)  char x[SPRINT_BSIZE]
    2628
    27 extern void incomplete_command(void) ATTRIBUTE_NORETURN;
     29extern void incomplete_command(void) NORETURN;
    2830
    29 #define NEXT_ARG() do { argv++; if (--argc <= 0) incomplete_command(); } while (0)
     31#define NEXT_ARG() do { if (!*++argv) incomplete_command(); } while (0)
    3032
    31 typedef struct
    32 {
     33typedef struct {
    3334    uint8_t family;
    3435    uint8_t bytelen;
     
    3637    uint32_t data[4];
    3738} inet_prefix;
     39
     40#define PREFIXLEN_SPECIFIED 1
    3841
    3942#define DN_MAXADDL 20
     
    4346
    4447struct dn_naddr {
    45     unsigned short          a_len;
    46     unsigned char a_addr[DN_MAXADDL];
     48    unsigned short a_len;
     49    unsigned char  a_addr[DN_MAXADDL];
    4750};
    4851
     
    5659extern uint32_t get_addr32(char *name);
    5760extern int get_addr_1(inet_prefix *dst, char *arg, int family);
    58 extern int get_prefix_1(inet_prefix *dst, char *arg, int family);
     61/*extern int get_prefix_1(inet_prefix *dst, char *arg, int family);*/
    5962extern int get_addr(inet_prefix *dst, char *arg, int family);
    6063extern int get_prefix(inet_prefix *dst, char *arg, int family);
    6164
    62 extern int get_integer(int *val, char *arg, int base);
    63 extern int get_unsigned(unsigned *val, char *arg, int base);
    64 #define get_byte get_u8
    65 #define get_ushort get_u16
    66 #define get_short get_s16
    67 extern int get_u32(uint32_t *val, char *arg, int base);
    68 extern int get_u16(uint16_t *val, char *arg, int base);
    69 extern int get_s16(int16_t *val, char *arg, int base);
    70 extern int get_u8(uint8_t *val, char *arg, int base);
    71 extern int get_s8(int8_t *val, char *arg, int base);
     65extern unsigned get_unsigned(char *arg, const char *errmsg);
     66extern uint32_t get_u32(char *arg, const char *errmsg);
     67extern uint16_t get_u16(char *arg, const char *errmsg);
    7268
     69extern const char *rt_addr_n2a(int af, void *addr, char *buf, int buflen);
     70#ifdef RESOLVE_HOSTNAMES
    7371extern const char *format_host(int af, int len, void *addr, char *buf, int buflen);
    74 extern const char *rt_addr_n2a(int af, int len, void *addr, char *buf, int buflen);
     72#else
     73#define format_host(af, len, addr, buf, buflen) \
     74    rt_addr_n2a(af, addr, buf, buflen)
     75#endif
    7576
    76 void invarg(const char *, const char *) ATTRIBUTE_NORETURN;
    77 void duparg(const char *, const char *) ATTRIBUTE_NORETURN;
    78 void duparg2(const char *, const char *) ATTRIBUTE_NORETURN;
     77void invarg(const char *, const char *) NORETURN;
     78void duparg(const char *, const char *) NORETURN;
     79void duparg2(const char *, const char *) NORETURN;
    7980int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits);
    8081
     
    8586int ipx_pton(int af, const char *src, void *addr);
    8687
    87 #endif /* __UTILS_H__ */
     88POP_SAVED_FUNCTION_VISIBILITY
     89
     90#endif
Note: See TracChangeset for help on using the changeset viewer.