9 |
* |
* |
10 |
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> |
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> |
11 |
*/ |
*/ |
|
|
|
12 |
#include "libbb.h" |
#include "libbb.h" |
13 |
#include "rt_names.h" |
#include "rt_names.h" |
14 |
|
|
15 |
/* so far all callers have size == 256 */ |
typedef struct rtnl_tab_t { |
16 |
#define rtnl_tab_initialize(file, tab, size) rtnl_tab_initialize(file, tab) |
const char *cached_str; |
17 |
#define size 256 |
unsigned cached_result; |
18 |
static void rtnl_tab_initialize(const char *file, const char **tab, int size) |
const char *tab[256]; |
19 |
|
} rtnl_tab_t; |
20 |
|
|
21 |
|
static void rtnl_tab_initialize(const char *file, const char **tab) |
22 |
{ |
{ |
23 |
char *token[2]; |
char *token[2]; |
24 |
parser_t *parser = config_open2(file, fopen_for_read); |
parser_t *parser = config_open2(file, fopen_for_read); |
25 |
|
|
26 |
while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) { |
while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) { |
27 |
int id = bb_strtou(token[0], NULL, 0); |
unsigned id = bb_strtou(token[0], NULL, 0); |
28 |
if (id < 0 || id > size) { |
if (id > 256) { |
29 |
bb_error_msg("database %s is corrupted at line %d", |
bb_error_msg("database %s is corrupted at line %d", |
30 |
file, parser->lineno); |
file, parser->lineno); |
31 |
break; |
break; |
34 |
} |
} |
35 |
config_close(parser); |
config_close(parser); |
36 |
} |
} |
|
#undef size |
|
37 |
|
|
38 |
static const char **rtnl_rtprot_tab; /* [256] */ |
static int rtnl_a2n(rtnl_tab_t *tab, uint32_t *id, const char *arg, int base) |
39 |
|
{ |
40 |
|
unsigned i; |
41 |
|
|
42 |
|
if (tab->cached_str && strcmp(tab->cached_str, arg) == 0) { |
43 |
|
*id = tab->cached_result; |
44 |
|
return 0; |
45 |
|
} |
46 |
|
|
47 |
|
for (i = 0; i < 256; i++) { |
48 |
|
if (tab->tab[i] |
49 |
|
&& strcmp(tab->tab[i], arg) == 0 |
50 |
|
) { |
51 |
|
tab->cached_str = tab->tab[i]; |
52 |
|
tab->cached_result = i; |
53 |
|
*id = i; |
54 |
|
return 0; |
55 |
|
} |
56 |
|
} |
57 |
|
|
58 |
|
i = bb_strtou(arg, NULL, base); |
59 |
|
if (i > 255) |
60 |
|
return -1; |
61 |
|
*id = i; |
62 |
|
return 0; |
63 |
|
} |
64 |
|
|
65 |
|
|
66 |
|
static rtnl_tab_t *rtnl_rtprot_tab; |
67 |
|
|
68 |
static void rtnl_rtprot_initialize(void) |
static void rtnl_rtprot_initialize(void) |
69 |
{ |
{ |
82 |
"zebra", |
"zebra", |
83 |
"bird", |
"bird", |
84 |
}; |
}; |
|
if (rtnl_rtprot_tab) return; |
|
|
rtnl_rtprot_tab = xzalloc(256 * sizeof(rtnl_rtprot_tab[0])); |
|
|
memcpy(rtnl_rtprot_tab, init_tab, sizeof(init_tab)); |
|
|
rtnl_tab_initialize("/etc/iproute2/rt_protos", |
|
|
rtnl_rtprot_tab, 256); |
|
|
} |
|
85 |
|
|
86 |
|
if (rtnl_rtprot_tab) |
87 |
|
return; |
88 |
|
rtnl_rtprot_tab = xzalloc(sizeof(*rtnl_rtprot_tab)); |
89 |
|
memcpy(rtnl_rtprot_tab->tab, init_tab, sizeof(init_tab)); |
90 |
|
rtnl_tab_initialize("/etc/iproute2/rt_protos", rtnl_rtprot_tab->tab); |
91 |
|
} |
92 |
|
|
93 |
const char* rtnl_rtprot_n2a(int id, char *buf, int len) |
const char* FAST_FUNC rtnl_rtprot_n2a(int id, char *buf) |
94 |
{ |
{ |
95 |
if (id < 0 || id >= 256) { |
if (id < 0 || id >= 256) { |
96 |
snprintf(buf, len, "%d", id); |
sprintf(buf, "%d", id); |
97 |
return buf; |
return buf; |
98 |
} |
} |
99 |
|
|
100 |
rtnl_rtprot_initialize(); |
rtnl_rtprot_initialize(); |
101 |
|
|
102 |
if (rtnl_rtprot_tab[id]) |
if (rtnl_rtprot_tab->tab[id]) |
103 |
return rtnl_rtprot_tab[id]; |
return rtnl_rtprot_tab->tab[id]; |
104 |
snprintf(buf, len, "%d", id); |
/* buf is SPRINT_BSIZE big */ |
105 |
|
sprintf(buf, "%d", id); |
106 |
return buf; |
return buf; |
107 |
} |
} |
108 |
|
|
109 |
int rtnl_rtprot_a2n(uint32_t *id, char *arg) |
int FAST_FUNC rtnl_rtprot_a2n(uint32_t *id, char *arg) |
110 |
{ |
{ |
|
static const char *cache = NULL; |
|
|
static unsigned long res; |
|
|
int i; |
|
|
|
|
|
if (cache && strcmp(cache, arg) == 0) { |
|
|
*id = res; |
|
|
return 0; |
|
|
} |
|
|
|
|
111 |
rtnl_rtprot_initialize(); |
rtnl_rtprot_initialize(); |
112 |
|
return rtnl_a2n(rtnl_rtprot_tab, id, arg, 0); |
|
for (i = 0; i < 256; i++) { |
|
|
if (rtnl_rtprot_tab[i] && |
|
|
strcmp(rtnl_rtprot_tab[i], arg) == 0) { |
|
|
cache = rtnl_rtprot_tab[i]; |
|
|
res = i; |
|
|
*id = res; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
res = bb_strtoul(arg, NULL, 0); |
|
|
if (errno || res > 255) |
|
|
return -1; |
|
|
*id = res; |
|
|
return 0; |
|
113 |
} |
} |
114 |
|
|
115 |
|
|
116 |
static const char **rtnl_rtscope_tab; /* [256] */ |
static rtnl_tab_t *rtnl_rtscope_tab; |
117 |
|
|
118 |
static void rtnl_rtscope_initialize(void) |
static void rtnl_rtscope_initialize(void) |
119 |
{ |
{ |
120 |
if (rtnl_rtscope_tab) return; |
if (rtnl_rtscope_tab) |
121 |
rtnl_rtscope_tab = xzalloc(256 * sizeof(rtnl_rtscope_tab[0])); |
return; |
122 |
rtnl_rtscope_tab[0] = "global"; |
rtnl_rtscope_tab = xzalloc(sizeof(*rtnl_rtscope_tab)); |
123 |
rtnl_rtscope_tab[255] = "nowhere"; |
rtnl_rtscope_tab->tab[0] = "global"; |
124 |
rtnl_rtscope_tab[254] = "host"; |
rtnl_rtscope_tab->tab[255] = "nowhere"; |
125 |
rtnl_rtscope_tab[253] = "link"; |
rtnl_rtscope_tab->tab[254] = "host"; |
126 |
rtnl_rtscope_tab[200] = "site"; |
rtnl_rtscope_tab->tab[253] = "link"; |
127 |
rtnl_tab_initialize("/etc/iproute2/rt_scopes", |
rtnl_rtscope_tab->tab[200] = "site"; |
128 |
rtnl_rtscope_tab, 256); |
rtnl_tab_initialize("/etc/iproute2/rt_scopes", rtnl_rtscope_tab->tab); |
129 |
} |
} |
130 |
|
|
131 |
|
const char* FAST_FUNC rtnl_rtscope_n2a(int id, char *buf) |
|
const char* rtnl_rtscope_n2a(int id, char *buf, int len) |
|
132 |
{ |
{ |
133 |
if (id < 0 || id >= 256) { |
if (id < 0 || id >= 256) { |
134 |
snprintf(buf, len, "%d", id); |
sprintf(buf, "%d", id); |
135 |
return buf; |
return buf; |
136 |
} |
} |
137 |
|
|
138 |
rtnl_rtscope_initialize(); |
rtnl_rtscope_initialize(); |
139 |
|
|
140 |
if (rtnl_rtscope_tab[id]) |
if (rtnl_rtscope_tab->tab[id]) |
141 |
return rtnl_rtscope_tab[id]; |
return rtnl_rtscope_tab->tab[id]; |
142 |
snprintf(buf, len, "%d", id); |
/* buf is SPRINT_BSIZE big */ |
143 |
|
sprintf(buf, "%d", id); |
144 |
return buf; |
return buf; |
145 |
} |
} |
146 |
|
|
147 |
int rtnl_rtscope_a2n(uint32_t *id, char *arg) |
int FAST_FUNC rtnl_rtscope_a2n(uint32_t *id, char *arg) |
148 |
{ |
{ |
|
static const char *cache = NULL; |
|
|
static unsigned long res; |
|
|
int i; |
|
|
|
|
|
if (cache && strcmp(cache, arg) == 0) { |
|
|
*id = res; |
|
|
return 0; |
|
|
} |
|
|
|
|
149 |
rtnl_rtscope_initialize(); |
rtnl_rtscope_initialize(); |
150 |
|
return rtnl_a2n(rtnl_rtscope_tab, id, arg, 0); |
|
for (i = 0; i < 256; i++) { |
|
|
if (rtnl_rtscope_tab[i] && |
|
|
strcmp(rtnl_rtscope_tab[i], arg) == 0) { |
|
|
cache = rtnl_rtscope_tab[i]; |
|
|
res = i; |
|
|
*id = res; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
res = bb_strtoul(arg, NULL, 0); |
|
|
if (errno || res > 255) |
|
|
return -1; |
|
|
*id = res; |
|
|
return 0; |
|
151 |
} |
} |
152 |
|
|
153 |
|
|
154 |
static const char **rtnl_rtrealm_tab; /* [256] */ |
static rtnl_tab_t *rtnl_rtrealm_tab; |
155 |
|
|
156 |
static void rtnl_rtrealm_initialize(void) |
static void rtnl_rtrealm_initialize(void) |
157 |
{ |
{ |
158 |
if (rtnl_rtrealm_tab) return; |
if (rtnl_rtrealm_tab) return; |
159 |
rtnl_rtrealm_tab = xzalloc(256 * sizeof(rtnl_rtrealm_tab[0])); |
rtnl_rtrealm_tab = xzalloc(sizeof(*rtnl_rtrealm_tab)); |
160 |
rtnl_rtrealm_tab[0] = "unknown"; |
rtnl_rtrealm_tab->tab[0] = "unknown"; |
161 |
rtnl_tab_initialize("/etc/iproute2/rt_realms", |
rtnl_tab_initialize("/etc/iproute2/rt_realms", rtnl_rtrealm_tab->tab); |
|
rtnl_rtrealm_tab, 256); |
|
162 |
} |
} |
163 |
|
|
164 |
|
int FAST_FUNC rtnl_rtrealm_a2n(uint32_t *id, char *arg) |
|
int rtnl_rtrealm_a2n(uint32_t *id, char *arg) |
|
165 |
{ |
{ |
|
static const char *cache = NULL; |
|
|
static unsigned long res; |
|
|
int i; |
|
|
|
|
|
if (cache && strcmp(cache, arg) == 0) { |
|
|
*id = res; |
|
|
return 0; |
|
|
} |
|
|
|
|
166 |
rtnl_rtrealm_initialize(); |
rtnl_rtrealm_initialize(); |
167 |
|
return rtnl_a2n(rtnl_rtrealm_tab, id, arg, 0); |
|
for (i = 0; i < 256; i++) { |
|
|
if (rtnl_rtrealm_tab[i] && |
|
|
strcmp(rtnl_rtrealm_tab[i], arg) == 0) { |
|
|
cache = rtnl_rtrealm_tab[i]; |
|
|
res = i; |
|
|
*id = res; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
res = bb_strtoul(arg, NULL, 0); |
|
|
if (errno || res > 255) |
|
|
return -1; |
|
|
*id = res; |
|
|
return 0; |
|
168 |
} |
} |
169 |
|
|
170 |
#if ENABLE_FEATURE_IP_RULE |
#if ENABLE_FEATURE_IP_RULE |
171 |
const char* rtnl_rtrealm_n2a(int id, char *buf, int len) |
const char* FAST_FUNC rtnl_rtrealm_n2a(int id, char *buf) |
172 |
{ |
{ |
173 |
if (id < 0 || id >= 256) { |
if (id < 0 || id >= 256) { |
174 |
snprintf(buf, len, "%d", id); |
sprintf(buf, "%d", id); |
175 |
return buf; |
return buf; |
176 |
} |
} |
177 |
|
|
178 |
rtnl_rtrealm_initialize(); |
rtnl_rtrealm_initialize(); |
179 |
|
|
180 |
if (rtnl_rtrealm_tab[id]) |
if (rtnl_rtrealm_tab->tab[id]) |
181 |
return rtnl_rtrealm_tab[id]; |
return rtnl_rtrealm_tab->tab[id]; |
182 |
snprintf(buf, len, "%d", id); |
/* buf is SPRINT_BSIZE big */ |
183 |
|
sprintf(buf, "%d", id); |
184 |
return buf; |
return buf; |
185 |
} |
} |
186 |
#endif |
#endif |
187 |
|
|
188 |
|
|
189 |
static const char **rtnl_rtdsfield_tab; /* [256] */ |
static rtnl_tab_t *rtnl_rtdsfield_tab; |
190 |
|
|
191 |
static void rtnl_rtdsfield_initialize(void) |
static void rtnl_rtdsfield_initialize(void) |
192 |
{ |
{ |
193 |
if (rtnl_rtdsfield_tab) return; |
if (rtnl_rtdsfield_tab) return; |
194 |
rtnl_rtdsfield_tab = xzalloc(256 * sizeof(rtnl_rtdsfield_tab[0])); |
rtnl_rtdsfield_tab = xzalloc(sizeof(*rtnl_rtdsfield_tab)); |
195 |
rtnl_rtdsfield_tab[0] = "0"; |
rtnl_rtdsfield_tab->tab[0] = "0"; |
196 |
rtnl_tab_initialize("/etc/iproute2/rt_dsfield", |
rtnl_tab_initialize("/etc/iproute2/rt_dsfield", rtnl_rtdsfield_tab->tab); |
|
rtnl_rtdsfield_tab, 256); |
|
197 |
} |
} |
198 |
|
|
199 |
|
const char* FAST_FUNC rtnl_dsfield_n2a(int id, char *buf) |
|
const char * rtnl_dsfield_n2a(int id, char *buf, int len) |
|
200 |
{ |
{ |
201 |
if (id < 0 || id >= 256) { |
if (id < 0 || id >= 256) { |
202 |
snprintf(buf, len, "%d", id); |
sprintf(buf, "%d", id); |
203 |
return buf; |
return buf; |
204 |
} |
} |
205 |
|
|
206 |
rtnl_rtdsfield_initialize(); |
rtnl_rtdsfield_initialize(); |
207 |
|
|
208 |
if (rtnl_rtdsfield_tab[id]) |
if (rtnl_rtdsfield_tab->tab[id]) |
209 |
return rtnl_rtdsfield_tab[id]; |
return rtnl_rtdsfield_tab->tab[id]; |
210 |
snprintf(buf, len, "0x%02x", id); |
/* buf is SPRINT_BSIZE big */ |
211 |
|
sprintf(buf, "0x%02x", id); |
212 |
return buf; |
return buf; |
213 |
} |
} |
214 |
|
|
215 |
|
int FAST_FUNC rtnl_dsfield_a2n(uint32_t *id, char *arg) |
|
int rtnl_dsfield_a2n(uint32_t *id, char *arg) |
|
216 |
{ |
{ |
|
static const char *cache = NULL; |
|
|
static unsigned long res; |
|
|
int i; |
|
|
|
|
|
if (cache && strcmp(cache, arg) == 0) { |
|
|
*id = res; |
|
|
return 0; |
|
|
} |
|
|
|
|
217 |
rtnl_rtdsfield_initialize(); |
rtnl_rtdsfield_initialize(); |
218 |
|
return rtnl_a2n(rtnl_rtdsfield_tab, id, arg, 16); |
|
for (i = 0; i < 256; i++) { |
|
|
if (rtnl_rtdsfield_tab[i] && |
|
|
strcmp(rtnl_rtdsfield_tab[i], arg) == 0) { |
|
|
cache = rtnl_rtdsfield_tab[i]; |
|
|
res = i; |
|
|
*id = res; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
res = bb_strtoul(arg, NULL, 16); |
|
|
if (errno || res > 255) |
|
|
return -1; |
|
|
*id = res; |
|
|
return 0; |
|
219 |
} |
} |
220 |
|
|
221 |
|
|
222 |
#if ENABLE_FEATURE_IP_RULE |
#if ENABLE_FEATURE_IP_RULE |
223 |
static const char **rtnl_rttable_tab; /* [256] */ |
static rtnl_tab_t *rtnl_rttable_tab; |
224 |
|
|
225 |
static void rtnl_rttable_initialize(void) |
static void rtnl_rttable_initialize(void) |
226 |
{ |
{ |
227 |
if (rtnl_rtdsfield_tab) return; |
if (rtnl_rtdsfield_tab) return; |
228 |
rtnl_rttable_tab = xzalloc(256 * sizeof(rtnl_rttable_tab[0])); |
rtnl_rttable_tab = xzalloc(sizeof(*rtnl_rttable_tab)); |
229 |
rtnl_rttable_tab[0] = "unspec"; |
rtnl_rttable_tab->tab[0] = "unspec"; |
230 |
rtnl_rttable_tab[255] = "local"; |
rtnl_rttable_tab->tab[255] = "local"; |
231 |
rtnl_rttable_tab[254] = "main"; |
rtnl_rttable_tab->tab[254] = "main"; |
232 |
rtnl_rttable_tab[253] = "default"; |
rtnl_rttable_tab->tab[253] = "default"; |
233 |
rtnl_tab_initialize("/etc/iproute2/rt_tables", rtnl_rttable_tab, 256); |
rtnl_tab_initialize("/etc/iproute2/rt_tables", rtnl_rttable_tab->tab); |
234 |
} |
} |
235 |
|
|
236 |
|
const char* FAST_FUNC rtnl_rttable_n2a(int id, char *buf) |
|
const char *rtnl_rttable_n2a(int id, char *buf, int len) |
|
237 |
{ |
{ |
238 |
if (id < 0 || id >= 256) { |
if (id < 0 || id >= 256) { |
239 |
snprintf(buf, len, "%d", id); |
sprintf(buf, "%d", id); |
240 |
return buf; |
return buf; |
241 |
} |
} |
242 |
|
|
243 |
rtnl_rttable_initialize(); |
rtnl_rttable_initialize(); |
244 |
|
|
245 |
if (rtnl_rttable_tab[id]) |
if (rtnl_rttable_tab->tab[id]) |
246 |
return rtnl_rttable_tab[id]; |
return rtnl_rttable_tab->tab[id]; |
247 |
snprintf(buf, len, "%d", id); |
/* buf is SPRINT_BSIZE big */ |
248 |
|
sprintf(buf, "%d", id); |
249 |
return buf; |
return buf; |
250 |
} |
} |
251 |
|
|
252 |
int rtnl_rttable_a2n(uint32_t * id, char *arg) |
int FAST_FUNC rtnl_rttable_a2n(uint32_t *id, char *arg) |
253 |
{ |
{ |
|
static char *cache = NULL; |
|
|
static unsigned long res; |
|
|
int i; |
|
|
|
|
|
if (cache && strcmp(cache, arg) == 0) { |
|
|
*id = res; |
|
|
return 0; |
|
|
} |
|
|
|
|
254 |
rtnl_rttable_initialize(); |
rtnl_rttable_initialize(); |
255 |
|
return rtnl_a2n(rtnl_rttable_tab, id, arg, 0); |
|
for (i = 0; i < 256; i++) { |
|
|
if (rtnl_rttable_tab[i] && strcmp(rtnl_rttable_tab[i], arg) == 0) { |
|
|
cache = (char*)rtnl_rttable_tab[i]; |
|
|
res = i; |
|
|
*id = res; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
i = bb_strtoul(arg, NULL, 0); |
|
|
if (errno || i > 255) |
|
|
return -1; |
|
|
*id = i; |
|
|
return 0; |
|
256 |
} |
} |
257 |
|
|
258 |
#endif |
#endif |