]> rtime.felk.cvut.cz Git - lisovros/iproute2_canprio.git/blob - lib/rt_names.c
iproute2 - Fix up and simplify variables pointing to install directories
[lisovros/iproute2_canprio.git] / lib / rt_names.c
1 /*
2  * rt_names.c           rtnetlink names DB.
3  *
4  *              This program is free software; you can redistribute it and/or
5  *              modify it under the terms of the GNU General Public License
6  *              as published by the Free Software Foundation; either version
7  *              2 of the License, or (at your option) any later version.
8  *
9  * Authors:     Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10  */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <syslog.h>
16 #include <fcntl.h>
17 #include <string.h>
18 #include <sys/time.h>
19 #include <sys/socket.h>
20
21 #include <asm/types.h>
22 #include <linux/rtnetlink.h>
23
24 #include "rt_names.h"
25
26 #ifndef CONFDIR
27 #define CONFDIR "/etc/iproute2"
28 #endif
29
30 struct rtnl_hash_entry {
31         struct rtnl_hash_entry *next;
32         char *                  name;
33         unsigned int            id;
34 };
35
36 static void
37 rtnl_hash_initialize(char *file, struct rtnl_hash_entry **hash, int size)
38 {
39         struct rtnl_hash_entry *entry;
40         char buf[512];
41         FILE *fp;
42
43         fp = fopen(file, "r");
44         if (!fp)
45                 return;
46         while (fgets(buf, sizeof(buf), fp)) {
47                 char *p = buf;
48                 int id;
49                 char namebuf[512];
50
51                 while (*p == ' ' || *p == '\t')
52                         p++;
53                 if (*p == '#' || *p == '\n' || *p == 0)
54                         continue;
55                 if (sscanf(p, "0x%x %s\n", &id, namebuf) != 2 &&
56                     sscanf(p, "0x%x %s #", &id, namebuf) != 2 &&
57                     sscanf(p, "%d %s\n", &id, namebuf) != 2 &&
58                     sscanf(p, "%d %s #", &id, namebuf) != 2) {
59                         fprintf(stderr, "Database %s is corrupted at %s\n",
60                                 file, p);
61                         fclose(fp);
62                         return;
63                 }
64
65                 if (id<0)
66                         continue;
67                 entry = malloc(sizeof(*entry));
68                 entry->id   = id;
69                 entry->name = strdup(namebuf);
70                 entry->next = hash[id & (size - 1)];
71                 hash[id & (size - 1)] = entry;
72         }
73         fclose(fp);
74 }
75
76 static void rtnl_tab_initialize(char *file, char **tab, int size)
77 {
78         char buf[512];
79         FILE *fp;
80
81         fp = fopen(file, "r");
82         if (!fp)
83                 return;
84         while (fgets(buf, sizeof(buf), fp)) {
85                 char *p = buf;
86                 int id;
87                 char namebuf[512];
88
89                 while (*p == ' ' || *p == '\t')
90                         p++;
91                 if (*p == '#' || *p == '\n' || *p == 0)
92                         continue;
93                 if (sscanf(p, "0x%x %s\n", &id, namebuf) != 2 &&
94                     sscanf(p, "0x%x %s #", &id, namebuf) != 2 &&
95                     sscanf(p, "%d %s\n", &id, namebuf) != 2 &&
96                     sscanf(p, "%d %s #", &id, namebuf) != 2) {
97                         fprintf(stderr, "Database %s is corrupted at %s\n",
98                                 file, p);
99                         fclose(fp);
100                         return;
101                 }
102
103                 if (id<0 || id>size)
104                         continue;
105
106                 tab[id] = strdup(namebuf);
107         }
108         fclose(fp);
109 }
110
111 static char * rtnl_rtprot_tab[256] = {
112         [RTPROT_UNSPEC] = "none",
113         [RTPROT_REDIRECT] ="redirect",
114         [RTPROT_KERNEL] = "kernel",
115         [RTPROT_BOOT] = "boot",
116         [RTPROT_STATIC] = "static",
117
118         [RTPROT_GATED] = "gated",
119         [RTPROT_RA] = "ra",
120         [RTPROT_MRT] =  "mrt",
121         [RTPROT_ZEBRA] ="zebra",
122         [RTPROT_BIRD] = "bird",
123         [RTPROT_DNROUTED] = "dnrouted",
124         [RTPROT_XORP] = "xorp",
125         [RTPROT_NTK] = "ntk",
126         [RTPROT_DHCP] = "dhcp",
127 };
128
129
130
131 static int rtnl_rtprot_init;
132
133 static void rtnl_rtprot_initialize(void)
134 {
135         rtnl_rtprot_init = 1;
136         rtnl_tab_initialize(CONFDIR "/rt_protos",
137                             rtnl_rtprot_tab, 256);
138 }
139
140 char * rtnl_rtprot_n2a(int id, char *buf, int len)
141 {
142         if (id<0 || id>=256) {
143                 snprintf(buf, len, "%d", id);
144                 return buf;
145         }
146         if (!rtnl_rtprot_tab[id]) {
147                 if (!rtnl_rtprot_init)
148                         rtnl_rtprot_initialize();
149         }
150         if (rtnl_rtprot_tab[id])
151                 return rtnl_rtprot_tab[id];
152         snprintf(buf, len, "%d", id);
153         return buf;
154 }
155
156 int rtnl_rtprot_a2n(__u32 *id, char *arg)
157 {
158         static char *cache = NULL;
159         static unsigned long res;
160         char *end;
161         int i;
162
163         if (cache && strcmp(cache, arg) == 0) {
164                 *id = res;
165                 return 0;
166         }
167
168         if (!rtnl_rtprot_init)
169                 rtnl_rtprot_initialize();
170
171         for (i=0; i<256; i++) {
172                 if (rtnl_rtprot_tab[i] &&
173                     strcmp(rtnl_rtprot_tab[i], arg) == 0) {
174                         cache = rtnl_rtprot_tab[i];
175                         res = i;
176                         *id = res;
177                         return 0;
178                 }
179         }
180
181         res = strtoul(arg, &end, 0);
182         if (!end || end == arg || *end || res > 255)
183                 return -1;
184         *id = res;
185         return 0;
186 }
187
188
189
190 static char * rtnl_rtscope_tab[256] = {
191         "global",
192 };
193
194 static int rtnl_rtscope_init;
195
196 static void rtnl_rtscope_initialize(void)
197 {
198         rtnl_rtscope_init = 1;
199         rtnl_rtscope_tab[255] = "nowhere";
200         rtnl_rtscope_tab[254] = "host";
201         rtnl_rtscope_tab[253] = "link";
202         rtnl_rtscope_tab[200] = "site";
203         rtnl_tab_initialize(CONFDIR "/rt_scopes",
204                             rtnl_rtscope_tab, 256);
205 }
206
207 char * rtnl_rtscope_n2a(int id, char *buf, int len)
208 {
209         if (id<0 || id>=256) {
210                 snprintf(buf, len, "%d", id);
211                 return buf;
212         }
213         if (!rtnl_rtscope_tab[id]) {
214                 if (!rtnl_rtscope_init)
215                         rtnl_rtscope_initialize();
216         }
217         if (rtnl_rtscope_tab[id])
218                 return rtnl_rtscope_tab[id];
219         snprintf(buf, len, "%d", id);
220         return buf;
221 }
222
223 int rtnl_rtscope_a2n(__u32 *id, char *arg)
224 {
225         static char *cache = NULL;
226         static unsigned long res;
227         char *end;
228         int i;
229
230         if (cache && strcmp(cache, arg) == 0) {
231                 *id = res;
232                 return 0;
233         }
234
235         if (!rtnl_rtscope_init)
236                 rtnl_rtscope_initialize();
237
238         for (i=0; i<256; i++) {
239                 if (rtnl_rtscope_tab[i] &&
240                     strcmp(rtnl_rtscope_tab[i], arg) == 0) {
241                         cache = rtnl_rtscope_tab[i];
242                         res = i;
243                         *id = res;
244                         return 0;
245                 }
246         }
247
248         res = strtoul(arg, &end, 0);
249         if (!end || end == arg || *end || res > 255)
250                 return -1;
251         *id = res;
252         return 0;
253 }
254
255
256
257 static char * rtnl_rtrealm_tab[256] = {
258         "unknown",
259 };
260
261 static int rtnl_rtrealm_init;
262
263 static void rtnl_rtrealm_initialize(void)
264 {
265         rtnl_rtrealm_init = 1;
266         rtnl_tab_initialize(CONFDIR "/rt_realms",
267                             rtnl_rtrealm_tab, 256);
268 }
269
270 char * rtnl_rtrealm_n2a(int id, char *buf, int len)
271 {
272         if (id<0 || id>=256) {
273                 snprintf(buf, len, "%d", id);
274                 return buf;
275         }
276         if (!rtnl_rtrealm_tab[id]) {
277                 if (!rtnl_rtrealm_init)
278                         rtnl_rtrealm_initialize();
279         }
280         if (rtnl_rtrealm_tab[id])
281                 return rtnl_rtrealm_tab[id];
282         snprintf(buf, len, "%d", id);
283         return buf;
284 }
285
286
287 int rtnl_rtrealm_a2n(__u32 *id, char *arg)
288 {
289         static char *cache = NULL;
290         static unsigned long res;
291         char *end;
292         int i;
293
294         if (cache && strcmp(cache, arg) == 0) {
295                 *id = res;
296                 return 0;
297         }
298
299         if (!rtnl_rtrealm_init)
300                 rtnl_rtrealm_initialize();
301
302         for (i=0; i<256; i++) {
303                 if (rtnl_rtrealm_tab[i] &&
304                     strcmp(rtnl_rtrealm_tab[i], arg) == 0) {
305                         cache = rtnl_rtrealm_tab[i];
306                         res = i;
307                         *id = res;
308                         return 0;
309                 }
310         }
311
312         res = strtoul(arg, &end, 0);
313         if (!end || end == arg || *end || res > 255)
314                 return -1;
315         *id = res;
316         return 0;
317 }
318
319
320 static struct rtnl_hash_entry dflt_table_entry  = { .id = 253, .name = "default" };
321 static struct rtnl_hash_entry main_table_entry  = { .id = 254, .name = "main" };
322 static struct rtnl_hash_entry local_table_entry = { .id = 255, .name = "local" };
323
324 static struct rtnl_hash_entry * rtnl_rttable_hash[256] = {
325         [253] = &dflt_table_entry,
326         [254] = &main_table_entry,
327         [255] = &local_table_entry,
328 };
329
330 static int rtnl_rttable_init;
331
332 static void rtnl_rttable_initialize(void)
333 {
334         rtnl_rttable_init = 1;
335         rtnl_hash_initialize(CONFDIR "/rt_tables",
336                              rtnl_rttable_hash, 256);
337 }
338
339 char * rtnl_rttable_n2a(__u32 id, char *buf, int len)
340 {
341         struct rtnl_hash_entry *entry;
342
343         if (id > RT_TABLE_MAX) {
344                 snprintf(buf, len, "%u", id);
345                 return buf;
346         }
347         if (!rtnl_rttable_init)
348                 rtnl_rttable_initialize();
349         entry = rtnl_rttable_hash[id & 255];
350         while (entry && entry->id != id)
351                 entry = entry->next;
352         if (entry)
353                 return entry->name;
354         snprintf(buf, len, "%u", id);
355         return buf;
356 }
357
358 int rtnl_rttable_a2n(__u32 *id, char *arg)
359 {
360         static char *cache = NULL;
361         static unsigned long res;
362         struct rtnl_hash_entry *entry;
363         char *end;
364         __u32 i;
365
366         if (cache && strcmp(cache, arg) == 0) {
367                 *id = res;
368                 return 0;
369         }
370
371         if (!rtnl_rttable_init)
372                 rtnl_rttable_initialize();
373
374         for (i=0; i<256; i++) {
375                 entry = rtnl_rttable_hash[i];
376                 while (entry && strcmp(entry->name, arg))
377                         entry = entry->next;
378                 if (entry) {
379                         cache = entry->name;
380                         res = entry->id;
381                         *id = res;
382                         return 0;
383                 }
384         }
385
386         i = strtoul(arg, &end, 0);
387         if (!end || end == arg || *end || i > RT_TABLE_MAX)
388                 return -1;
389         *id = i;
390         return 0;
391 }
392
393
394 static char * rtnl_rtdsfield_tab[256] = {
395         "0",
396 };
397
398 static int rtnl_rtdsfield_init;
399
400 static void rtnl_rtdsfield_initialize(void)
401 {
402         rtnl_rtdsfield_init = 1;
403         rtnl_tab_initialize(CONFDIR "/rt_dsfield",
404                             rtnl_rtdsfield_tab, 256);
405 }
406
407 char * rtnl_dsfield_n2a(int id, char *buf, int len)
408 {
409         if (id<0 || id>=256) {
410                 snprintf(buf, len, "%d", id);
411                 return buf;
412         }
413         if (!rtnl_rtdsfield_tab[id]) {
414                 if (!rtnl_rtdsfield_init)
415                         rtnl_rtdsfield_initialize();
416         }
417         if (rtnl_rtdsfield_tab[id])
418                 return rtnl_rtdsfield_tab[id];
419         snprintf(buf, len, "0x%02x", id);
420         return buf;
421 }
422
423
424 int rtnl_dsfield_a2n(__u32 *id, char *arg)
425 {
426         static char *cache = NULL;
427         static unsigned long res;
428         char *end;
429         int i;
430
431         if (cache && strcmp(cache, arg) == 0) {
432                 *id = res;
433                 return 0;
434         }
435
436         if (!rtnl_rtdsfield_init)
437                 rtnl_rtdsfield_initialize();
438
439         for (i=0; i<256; i++) {
440                 if (rtnl_rtdsfield_tab[i] &&
441                     strcmp(rtnl_rtdsfield_tab[i], arg) == 0) {
442                         cache = rtnl_rtdsfield_tab[i];
443                         res = i;
444                         *id = res;
445                         return 0;
446                 }
447         }
448
449         res = strtoul(arg, &end, 16);
450         if (!end || end == arg || *end || res > 255)
451                 return -1;
452         *id = res;
453         return 0;
454 }
455
456
457 static struct rtnl_hash_entry dflt_group_entry  = { .id = 0, .name = "default" };
458
459 static struct rtnl_hash_entry * rtnl_group_hash[256] = {
460         [0] = &dflt_group_entry,
461 };
462
463 static int rtnl_group_init;
464
465 static void rtnl_group_initialize(void)
466 {
467         rtnl_group_init = 1;
468         rtnl_hash_initialize("/etc/iproute2/group",
469                              rtnl_group_hash, 256);
470 }
471
472 int rtnl_group_a2n(int *id, char *arg)
473 {
474         static char *cache = NULL;
475         static unsigned long res;
476         struct rtnl_hash_entry *entry;
477         char *end;
478         int i;
479
480         if (cache && strcmp(cache, arg) == 0) {
481                 *id = res;
482                 return 0;
483         }
484
485         if (!rtnl_group_init)
486                 rtnl_group_initialize();
487
488         for (i=0; i<256; i++) {
489                 entry = rtnl_group_hash[i];
490                 while (entry && strcmp(entry->name, arg))
491                         entry = entry->next;
492                 if (entry) {
493                         cache = entry->name;
494                         res = entry->id;
495                         *id = res;
496                         return 0;
497                 }
498         }
499
500         i = strtol(arg, &end, 0);
501         if (!end || end == arg || *end || i < 0)
502                 return -1;
503         *id = i;
504         return 0;
505 }