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
  13#define CONFDIR          CONFIG_FEATURE_IP_ROUTE_DIR
  14
  15typedef struct rtnl_tab_t {
  16        const char *cached_str;
  17        unsigned cached_result;
  18        /* upstream version switched to a hash table and removed
  19         * id < 256 limit. For now bbox bumps this array size from 256
  20         * to 1024. If you plan to change this to a hash table,
  21         * consider merging several hash tables we have (for example,
  22         * awk has resizable one!
  23         */
  24#define RT_TABLE_MAX 1023
  25        const char *tab[RT_TABLE_MAX+1];
  26} rtnl_tab_t;
  27
  28static void rtnl_tab_initialize(const char *file, const char **tab)
  29{
  30        char *token[2];
  31        char fullname[sizeof(CONFDIR"/rt_dsfield") + 8];
  32        parser_t *parser;
  33
  34        sprintf(fullname, CONFDIR"/rt_%s", file);
  35        parser = config_open2(fullname, fopen_for_read);
  36        while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) {
  37                unsigned id = bb_strtou(token[0], NULL, 0);
  38                if (id > RT_TABLE_MAX) {
  39                        bb_error_msg("database %s is corrupted at line %d",
  40                                file, parser->lineno);
  41                        break;
  42                }
  43                tab[id] = xstrdup(token[1]);
  44        }
  45        config_close(parser);
  46}
  47
  48static int rtnl_a2n(rtnl_tab_t *tab, uint32_t *id, const char *arg, int base)
  49{
  50        unsigned i;
  51
  52        if (tab->cached_str && strcmp(tab->cached_str, arg) == 0) {
  53                *id = tab->cached_result;
  54                return 0;
  55        }
  56
  57        for (i = 0; i <= RT_TABLE_MAX; i++) {
  58                if (tab->tab[i]
  59                 && strcmp(tab->tab[i], arg) == 0
  60                ) {
  61                        tab->cached_str = tab->tab[i];
  62                        tab->cached_result = i;
  63                        *id = i;
  64                        return 0;
  65                }
  66        }
  67
  68        i = bb_strtou(arg, NULL, base);
  69        if (i > RT_TABLE_MAX)
  70                return -1;
  71        *id = i;
  72        return 0;
  73}
  74
  75
  76static rtnl_tab_t *rtnl_rtprot_tab;
  77
  78static void rtnl_rtprot_initialize(void)
  79{
  80        static const char *const init_tab[] = {
  81                "none",
  82                "redirect",
  83                "kernel",
  84                "boot",
  85                "static",
  86                NULL,
  87                NULL,
  88                NULL,
  89                "gated",
  90                "ra",
  91                "mrt",
  92                "zebra",
  93                "bird",
  94        };
  95
  96        if (rtnl_rtprot_tab)
  97                return;
  98        rtnl_rtprot_tab = xzalloc(sizeof(*rtnl_rtprot_tab));
  99        memcpy(rtnl_rtprot_tab->tab, init_tab, sizeof(init_tab));
 100        rtnl_tab_initialize("protos", rtnl_rtprot_tab->tab);
 101}
 102
 103#if 0 /* UNUSED */
 104const char* FAST_FUNC rtnl_rtprot_n2a(int id)
 105{
 106        if (id < 0 || id > RT_TABLE_MAX) {
 107                return itoa(id);
 108        }
 109
 110        rtnl_rtprot_initialize();
 111
 112        if (rtnl_rtprot_tab->tab[id])
 113                return rtnl_rtprot_tab->tab[id];
 114        return itoa(id);
 115}
 116#endif
 117
 118int FAST_FUNC rtnl_rtprot_a2n(uint32_t *id, char *arg)
 119{
 120        rtnl_rtprot_initialize();
 121        return rtnl_a2n(rtnl_rtprot_tab, id, arg, 0);
 122}
 123
 124
 125static rtnl_tab_t *rtnl_rtscope_tab;
 126
 127static void rtnl_rtscope_initialize(void)
 128{
 129        if (rtnl_rtscope_tab)
 130                return;
 131        rtnl_rtscope_tab = xzalloc(sizeof(*rtnl_rtscope_tab));
 132        rtnl_rtscope_tab->tab[0] = "global";
 133        rtnl_rtscope_tab->tab[255] = "nowhere";
 134        rtnl_rtscope_tab->tab[254] = "host";
 135        rtnl_rtscope_tab->tab[253] = "link";
 136        rtnl_rtscope_tab->tab[200] = "site";
 137        rtnl_tab_initialize("scopes", rtnl_rtscope_tab->tab);
 138}
 139
 140const char* FAST_FUNC rtnl_rtscope_n2a(int id)
 141{
 142        if (id < 0 || id > RT_TABLE_MAX) {
 143                return itoa(id);
 144        }
 145
 146        rtnl_rtscope_initialize();
 147
 148        if (rtnl_rtscope_tab->tab[id])
 149                return rtnl_rtscope_tab->tab[id];
 150        return itoa(id);
 151}
 152
 153int FAST_FUNC rtnl_rtscope_a2n(uint32_t *id, char *arg)
 154{
 155        rtnl_rtscope_initialize();
 156        return rtnl_a2n(rtnl_rtscope_tab, id, arg, 0);
 157}
 158
 159
 160static rtnl_tab_t *rtnl_rtrealm_tab;
 161
 162static void rtnl_rtrealm_initialize(void)
 163{
 164        if (rtnl_rtrealm_tab) return;
 165        rtnl_rtrealm_tab = xzalloc(sizeof(*rtnl_rtrealm_tab));
 166        rtnl_rtrealm_tab->tab[0] = "unknown";
 167        rtnl_tab_initialize("realms", rtnl_rtrealm_tab->tab);
 168}
 169
 170int FAST_FUNC rtnl_rtrealm_a2n(uint32_t *id, char *arg)
 171{
 172        rtnl_rtrealm_initialize();
 173        return rtnl_a2n(rtnl_rtrealm_tab, id, arg, 0);
 174}
 175
 176#if ENABLE_FEATURE_IP_RULE
 177const char* FAST_FUNC rtnl_rtrealm_n2a(int id)
 178{
 179        if (id < 0 || id > RT_TABLE_MAX) {
 180                return itoa(id);
 181        }
 182
 183        rtnl_rtrealm_initialize();
 184
 185        if (rtnl_rtrealm_tab->tab[id])
 186                return rtnl_rtrealm_tab->tab[id];
 187        return itoa(id);
 188}
 189#endif
 190
 191
 192static rtnl_tab_t *rtnl_rtdsfield_tab;
 193
 194static void rtnl_rtdsfield_initialize(void)
 195{
 196        if (rtnl_rtdsfield_tab) return;
 197        rtnl_rtdsfield_tab = xzalloc(sizeof(*rtnl_rtdsfield_tab));
 198        rtnl_rtdsfield_tab->tab[0] = "0";
 199        rtnl_tab_initialize("dsfield", rtnl_rtdsfield_tab->tab);
 200}
 201
 202const char* FAST_FUNC rtnl_dsfield_n2a(int id)
 203{
 204        if (id < 0 || id > RT_TABLE_MAX) {
 205                return itoa(id);
 206        }
 207
 208        rtnl_rtdsfield_initialize();
 209
 210        if (rtnl_rtdsfield_tab->tab[id])
 211                return rtnl_rtdsfield_tab->tab[id];
 212        return itoa(id);
 213}
 214
 215int FAST_FUNC rtnl_dsfield_a2n(uint32_t *id, char *arg)
 216{
 217        rtnl_rtdsfield_initialize();
 218        return rtnl_a2n(rtnl_rtdsfield_tab, id, arg, 16);
 219}
 220
 221
 222#if ENABLE_FEATURE_IP_RULE
 223static rtnl_tab_t *rtnl_rttable_tab;
 224
 225static void rtnl_rttable_initialize(void)
 226{
 227        if (rtnl_rttable_tab)
 228                return;
 229
 230        rtnl_rttable_tab = xzalloc(sizeof(*rtnl_rttable_tab));
 231        rtnl_rttable_tab->tab[0] = "unspec";
 232        rtnl_rttable_tab->tab[255] = "local";
 233        rtnl_rttable_tab->tab[254] = "main";
 234        rtnl_rttable_tab->tab[253] = "default";
 235        rtnl_tab_initialize("tables", rtnl_rttable_tab->tab);
 236}
 237
 238const char* FAST_FUNC rtnl_rttable_n2a(int id)
 239{
 240        if (id < 0 || id > RT_TABLE_MAX) {
 241                return itoa(id);
 242        }
 243
 244        rtnl_rttable_initialize();
 245
 246        if (rtnl_rttable_tab->tab[id])
 247                return rtnl_rttable_tab->tab[id];
 248        return itoa(id);
 249}
 250
 251int FAST_FUNC rtnl_rttable_a2n(uint32_t *id, char *arg)
 252{
 253        rtnl_rttable_initialize();
 254        return rtnl_a2n(rtnl_rttable_tab, id, arg, 0);
 255}
 256
 257#endif
 258