busybox/networking/libiproute/rt_names.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   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.
   7 *
   8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
   9 */
  10#include "libbb.h"
  11#include "rt_names.h"
  12
  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
  48                ) {
  49                        tab->cached_str = tab->tab[i];
  50                        tab->cached_result = i;
  51                        *id = i;
  52                        return 0;
  53                }
  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;
  65
  66static void rtnl_rtprot_initialize(void)
  67{
  68        static const char *const init_tab[] = {
  69                "none",
  70                "redirect",
  71                "kernel",
  72                "boot",
  73                "static",
  74                NULL,
  75                NULL,
  76                NULL,
  77                "gated",
  78                "ra",
  79                "mrt",
  80                "zebra",
  81                "bird",
  82        };
  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);
  95                return buf;
  96        }
  97
  98        rtnl_rtprot_initialize();
  99
 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{
 109        rtnl_rtprot_initialize();
 110        return rtnl_a2n(rtnl_rtprot_tab, id, arg, 0);
 111}
 112
 113
 114static rtnl_tab_t *rtnl_rtscope_tab;
 115
 116static void rtnl_rtscope_initialize(void)
 117{
 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);
 133                return buf;
 134        }
 135
 136        rtnl_rtscope_initialize();
 137
 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{
 147        rtnl_rtscope_initialize();
 148        return rtnl_a2n(rtnl_rtscope_tab, id, arg, 0);
 149}
 150
 151
 152static rtnl_tab_t *rtnl_rtrealm_tab;
 153
 154static void rtnl_rtrealm_initialize(void)
 155{
 156        if (rtnl_rtrealm_tab) return;
 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{
 164        rtnl_rtrealm_initialize();
 165        return rtnl_a2n(rtnl_rtrealm_tab, id, arg, 0);
 166}
 167
 168#if ENABLE_FEATURE_IP_RULE
 169const char* FAST_FUNC rtnl_rtrealm_n2a(int id, char *buf)
 170{
 171        if (id < 0 || id >= 256) {
 172                sprintf(buf, "%d", id);
 173                return buf;
 174        }
 175
 176        rtnl_rtrealm_initialize();
 177
 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);
 182        return buf;
 183}
 184#endif
 185
 186
 187static rtnl_tab_t *rtnl_rtdsfield_tab;
 188
 189static void rtnl_rtdsfield_initialize(void)
 190{
 191        if (rtnl_rtdsfield_tab) return;
 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);
 201                return buf;
 202        }
 203
 204        rtnl_rtdsfield_initialize();
 205
 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{
 215        rtnl_rtdsfield_initialize();
 216        return rtnl_a2n(rtnl_rtdsfield_tab, id, arg, 16);
 217}
 218
 219
 220#if ENABLE_FEATURE_IP_RULE
 221static rtnl_tab_t *rtnl_rttable_tab;
 222
 223static void rtnl_rttable_initialize(void)
 224{
 225        if (rtnl_rtdsfield_tab) return;
 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);
 238                return buf;
 239        }
 240
 241        rtnl_rttable_initialize();
 242
 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{
 252        rtnl_rttable_initialize();
 253        return rtnl_a2n(rtnl_rttable_tab, id, arg, 0);
 254}
 255
 256#endif
 257