blob: 1a2d52e86161007f04ac213e1acff5bc89aa9d73 [file] [log] [blame]
"Robert P. J. Day"63fc1a92006-07-02 19:47:05 +00001/* vi: set sw=4 ts=4: */
Glenn L McGrath9a2d2722002-11-10 01:33:55 +00002/*
3 * rt_names.c rtnetlink names DB.
4 *
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 */
Glenn L McGrath275be872002-12-16 07:37:21 +000012
Denis Vlasenkod1a302b2006-12-31 20:40:20 +000013#include "libbb.h"
Bernhard Reutner-Fischer1d62d3b2005-10-08 20:47:15 +000014#include "rt_names.h"
Glenn L McGrath9a2d2722002-11-10 01:33:55 +000015
Denis Vlasenko0f99d492008-07-24 23:38:04 +000016/* so far all callers have size == 256 */
17#define rtnl_tab_initialize(file, tab, size) rtnl_tab_initialize(file, tab)
18#define size 256
Denis Vlasenkoab2aea42007-01-29 22:51:58 +000019static void rtnl_tab_initialize(const char *file, const char **tab, int size)
Glenn L McGrath9a2d2722002-11-10 01:33:55 +000020{
Denis Vlasenko0f99d492008-07-24 23:38:04 +000021 char *token[2];
22 parser_t *parser = config_open2(file, fopen_for_read);
23 if (!parser)
Glenn L McGrath9a2d2722002-11-10 01:33:55 +000024 return;
Denis Vlasenko0f99d492008-07-24 23:38:04 +000025 while (config_read(parser, token, 2, 2, "# \t", 0)) {
26 int id = bb_strtou(token[0], NULL, 0);
27 if (id < 0 || id > size) {
28 bb_error_msg("database %s is corrupted at line %d",
29 file, parser->lineno);
30 break;
Glenn L McGrath9a2d2722002-11-10 01:33:55 +000031 }
Denis Vlasenko0f99d492008-07-24 23:38:04 +000032 tab[id] = xstrdup(token[1]);
Glenn L McGrath9a2d2722002-11-10 01:33:55 +000033 }
Denis Vlasenko0f99d492008-07-24 23:38:04 +000034 config_close(parser);
Glenn L McGrath9a2d2722002-11-10 01:33:55 +000035}
Denis Vlasenko0f99d492008-07-24 23:38:04 +000036#undef size
Glenn L McGrath9a2d2722002-11-10 01:33:55 +000037
Denis Vlasenkod1a302b2006-12-31 20:40:20 +000038static const char **rtnl_rtprot_tab; /* [256] */
Glenn L McGrath9a2d2722002-11-10 01:33:55 +000039
40static void rtnl_rtprot_initialize(void)
41{
Denis Vlasenkod1a302b2006-12-31 20:40:20 +000042 static const char *const init_tab[] = {
43 "none",
44 "redirect",
45 "kernel",
46 "boot",
47 "static",
48 NULL,
49 NULL,
50 NULL,
51 "gated",
52 "ra",
53 "mrt",
54 "zebra",
55 "bird",
56 };
57 if (rtnl_rtprot_tab) return;
58 rtnl_rtprot_tab = xzalloc(256 * sizeof(rtnl_rtprot_tab[0]));
59 memcpy(rtnl_rtprot_tab, init_tab, sizeof(init_tab));
Glenn L McGrath9a2d2722002-11-10 01:33:55 +000060 rtnl_tab_initialize("/etc/iproute2/rt_protos",
61 rtnl_rtprot_tab, 256);
62}
63
Denis Vlasenkod1a302b2006-12-31 20:40:20 +000064
65const char* rtnl_rtprot_n2a(int id, char *buf, int len)
Glenn L McGrath9a2d2722002-11-10 01:33:55 +000066{
Denis Vlasenkod1a302b2006-12-31 20:40:20 +000067 if (id < 0 || id >= 256) {
Glenn L McGrath9a2d2722002-11-10 01:33:55 +000068 snprintf(buf, len, "%d", id);
69 return buf;
70 }
Denis Vlasenkod1a302b2006-12-31 20:40:20 +000071
72 rtnl_rtprot_initialize();
73
Glenn L McGrath9a2d2722002-11-10 01:33:55 +000074 if (rtnl_rtprot_tab[id])
75 return rtnl_rtprot_tab[id];
76 snprintf(buf, len, "%d", id);
77 return buf;
78}
79
80int rtnl_rtprot_a2n(uint32_t *id, char *arg)
81{
Denis Vlasenko981b24d2006-09-28 22:36:23 +000082 static const char *cache = NULL;
Glenn L McGrath9a2d2722002-11-10 01:33:55 +000083 static unsigned long res;
Glenn L McGrath9a2d2722002-11-10 01:33:55 +000084 int i;
85
86 if (cache && strcmp(cache, arg) == 0) {
87 *id = res;
88 return 0;
89 }
90
Denis Vlasenkod1a302b2006-12-31 20:40:20 +000091 rtnl_rtprot_initialize();
Glenn L McGrath9a2d2722002-11-10 01:33:55 +000092
Denis Vlasenkod1a302b2006-12-31 20:40:20 +000093 for (i = 0; i < 256; i++) {
Glenn L McGrath9a2d2722002-11-10 01:33:55 +000094 if (rtnl_rtprot_tab[i] &&
95 strcmp(rtnl_rtprot_tab[i], arg) == 0) {
96 cache = rtnl_rtprot_tab[i];
97 res = i;
98 *id = res;
99 return 0;
100 }
101 }
102
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000103 res = bb_strtoul(arg, NULL, 0);
104 if (errno || res > 255)
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000105 return -1;
106 *id = res;
107 return 0;
108}
109
110
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000111static const char **rtnl_rtscope_tab; /* [256] */
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000112
113static void rtnl_rtscope_initialize(void)
114{
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000115 if (rtnl_rtscope_tab) return;
116 rtnl_rtscope_tab = xzalloc(256 * sizeof(rtnl_rtscope_tab[0]));
117 rtnl_rtscope_tab[0] = "global";
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000118 rtnl_rtscope_tab[255] = "nowhere";
119 rtnl_rtscope_tab[254] = "host";
120 rtnl_rtscope_tab[253] = "link";
121 rtnl_rtscope_tab[200] = "site";
122 rtnl_tab_initialize("/etc/iproute2/rt_scopes",
123 rtnl_rtscope_tab, 256);
124}
125
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000126
127const char* rtnl_rtscope_n2a(int id, char *buf, int len)
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000128{
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000129 if (id < 0 || id >= 256) {
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000130 snprintf(buf, len, "%d", id);
131 return buf;
132 }
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000133
134 rtnl_rtscope_initialize();
135
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000136 if (rtnl_rtscope_tab[id])
137 return rtnl_rtscope_tab[id];
138 snprintf(buf, len, "%d", id);
139 return buf;
140}
141
142int rtnl_rtscope_a2n(uint32_t *id, char *arg)
143{
Denis Vlasenko981b24d2006-09-28 22:36:23 +0000144 static const char *cache = NULL;
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000145 static unsigned long res;
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000146 int i;
147
148 if (cache && strcmp(cache, arg) == 0) {
149 *id = res;
150 return 0;
151 }
152
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000153 rtnl_rtscope_initialize();
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000154
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000155 for (i = 0; i < 256; i++) {
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000156 if (rtnl_rtscope_tab[i] &&
157 strcmp(rtnl_rtscope_tab[i], arg) == 0) {
158 cache = rtnl_rtscope_tab[i];
159 res = i;
160 *id = res;
161 return 0;
162 }
163 }
164
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000165 res = bb_strtoul(arg, NULL, 0);
166 if (errno || res > 255)
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000167 return -1;
168 *id = res;
169 return 0;
170}
171
172
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000173static const char **rtnl_rtrealm_tab; /* [256] */
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000174
175static void rtnl_rtrealm_initialize(void)
176{
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000177 if (rtnl_rtrealm_tab) return;
178 rtnl_rtrealm_tab = xzalloc(256 * sizeof(rtnl_rtrealm_tab[0]));
179 rtnl_rtrealm_tab[0] = "unknown";
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000180 rtnl_tab_initialize("/etc/iproute2/rt_realms",
181 rtnl_rtrealm_tab, 256);
182}
183
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000184
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000185int rtnl_rtrealm_a2n(uint32_t *id, char *arg)
186{
Denis Vlasenko981b24d2006-09-28 22:36:23 +0000187 static const char *cache = NULL;
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000188 static unsigned long res;
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000189 int i;
190
191 if (cache && strcmp(cache, arg) == 0) {
192 *id = res;
193 return 0;
194 }
195
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000196 rtnl_rtrealm_initialize();
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000197
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000198 for (i = 0; i < 256; i++) {
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000199 if (rtnl_rtrealm_tab[i] &&
200 strcmp(rtnl_rtrealm_tab[i], arg) == 0) {
201 cache = rtnl_rtrealm_tab[i];
202 res = i;
203 *id = res;
204 return 0;
205 }
206 }
207
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000208 res = bb_strtoul(arg, NULL, 0);
209 if (errno || res > 255)
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000210 return -1;
211 *id = res;
212 return 0;
213}
214
Bernhard Reutner-Fischer921f5df2006-11-21 15:36:08 +0000215#if ENABLE_FEATURE_IP_RULE
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000216const char* rtnl_rtrealm_n2a(int id, char *buf, int len)
Bernhard Reutner-Fischer921f5df2006-11-21 15:36:08 +0000217{
Denis Vlasenkoe27f1562007-01-01 06:00:38 +0000218 if (id < 0 || id >= 256) {
Bernhard Reutner-Fischer921f5df2006-11-21 15:36:08 +0000219 snprintf(buf, len, "%d", id);
220 return buf;
221 }
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000222
223 rtnl_rtrealm_initialize();
224
Bernhard Reutner-Fischer921f5df2006-11-21 15:36:08 +0000225 if (rtnl_rtrealm_tab[id])
226 return rtnl_rtrealm_tab[id];
227 snprintf(buf, len, "%d", id);
228 return buf;
229}
230#endif
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000231
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000232
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000233static const char **rtnl_rtdsfield_tab; /* [256] */
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000234
235static void rtnl_rtdsfield_initialize(void)
236{
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000237 if (rtnl_rtdsfield_tab) return;
238 rtnl_rtdsfield_tab = xzalloc(256 * sizeof(rtnl_rtdsfield_tab[0]));
239 rtnl_rtdsfield_tab[0] = "0";
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000240 rtnl_tab_initialize("/etc/iproute2/rt_dsfield",
241 rtnl_rtdsfield_tab, 256);
242}
243
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000244
Eric Andersen14f5c8d2005-04-16 19:39:00 +0000245const char * rtnl_dsfield_n2a(int id, char *buf, int len)
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000246{
Denis Vlasenkoe27f1562007-01-01 06:00:38 +0000247 if (id < 0 || id >= 256) {
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000248 snprintf(buf, len, "%d", id);
249 return buf;
250 }
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000251
252 rtnl_rtdsfield_initialize();
253
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000254 if (rtnl_rtdsfield_tab[id])
255 return rtnl_rtdsfield_tab[id];
256 snprintf(buf, len, "0x%02x", id);
257 return buf;
258}
259
260
261int rtnl_dsfield_a2n(uint32_t *id, char *arg)
262{
Denis Vlasenko981b24d2006-09-28 22:36:23 +0000263 static const char *cache = NULL;
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000264 static unsigned long res;
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000265 int i;
266
267 if (cache && strcmp(cache, arg) == 0) {
268 *id = res;
269 return 0;
270 }
271
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000272 rtnl_rtdsfield_initialize();
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000273
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000274 for (i = 0; i < 256; i++) {
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000275 if (rtnl_rtdsfield_tab[i] &&
276 strcmp(rtnl_rtdsfield_tab[i], arg) == 0) {
277 cache = rtnl_rtdsfield_tab[i];
278 res = i;
279 *id = res;
280 return 0;
281 }
282 }
283
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000284 res = bb_strtoul(arg, NULL, 16);
285 if (errno || res > 255)
Glenn L McGrath9a2d2722002-11-10 01:33:55 +0000286 return -1;
287 *id = res;
288 return 0;
289}
Bernhard Reutner-Fischer921f5df2006-11-21 15:36:08 +0000290
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000291
Bernhard Reutner-Fischer921f5df2006-11-21 15:36:08 +0000292#if ENABLE_FEATURE_IP_RULE
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000293static const char **rtnl_rttable_tab; /* [256] */
294
Bernhard Reutner-Fischer921f5df2006-11-21 15:36:08 +0000295static void rtnl_rttable_initialize(void)
296{
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000297 if (rtnl_rtdsfield_tab) return;
298 rtnl_rttable_tab = xzalloc(256 * sizeof(rtnl_rttable_tab[0]));
299 rtnl_rttable_tab[0] = "unspec";
Bernhard Reutner-Fischer921f5df2006-11-21 15:36:08 +0000300 rtnl_rttable_tab[255] = "local";
301 rtnl_rttable_tab[254] = "main";
302 rtnl_rttable_tab[253] = "default";
303 rtnl_tab_initialize("/etc/iproute2/rt_tables", rtnl_rttable_tab, 256);
304}
305
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000306
Bernhard Reutner-Fischer921f5df2006-11-21 15:36:08 +0000307const char *rtnl_rttable_n2a(int id, char *buf, int len)
308{
309 if (id < 0 || id >= 256) {
310 snprintf(buf, len, "%d", id);
311 return buf;
312 }
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000313
314 rtnl_rttable_initialize();
315
Bernhard Reutner-Fischer921f5df2006-11-21 15:36:08 +0000316 if (rtnl_rttable_tab[id])
317 return rtnl_rttable_tab[id];
318 snprintf(buf, len, "%d", id);
319 return buf;
320}
321
322int rtnl_rttable_a2n(uint32_t * id, char *arg)
323{
324 static char *cache = NULL;
325 static unsigned long res;
Bernhard Reutner-Fischer921f5df2006-11-21 15:36:08 +0000326 int i;
327
328 if (cache && strcmp(cache, arg) == 0) {
329 *id = res;
330 return 0;
331 }
332
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000333 rtnl_rttable_initialize();
Bernhard Reutner-Fischer921f5df2006-11-21 15:36:08 +0000334
335 for (i = 0; i < 256; i++) {
336 if (rtnl_rttable_tab[i] && strcmp(rtnl_rttable_tab[i], arg) == 0) {
337 cache = (char*)rtnl_rttable_tab[i];
338 res = i;
339 *id = res;
340 return 0;
341 }
342 }
343
Denis Vlasenkod1a302b2006-12-31 20:40:20 +0000344 i = bb_strtoul(arg, NULL, 0);
345 if (errno || i > 255)
Bernhard Reutner-Fischer921f5df2006-11-21 15:36:08 +0000346 return -1;
347 *id = i;
348 return 0;
349}
350
351#endif