]> rtime.felk.cvut.cz Git - lisovros/iproute2_canprio.git/blob - lib/rt_names.c
Add DHCP as routing protocol
[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 struct rtnl_hash_entry {
27         struct rtnl_hash_entry *next;
28         char *                  name;
29         unsigned int            id;
30 };
31
32 static void
33 rtnl_hash_initialize(char *file, struct rtnl_hash_entry **hash, int size)
34 {
35         struct rtnl_hash_entry *entry;
36         char buf[512];
37         FILE *fp;
38
39         fp = fopen(file, "r");
40         if (!fp)
41                 return;
42         while (fgets(buf, sizeof(buf), fp)) {
43                 char *p = buf;
44                 int id;
45                 char namebuf[512];
46
47                 while (*p == ' ' || *p == '\t')
48                         p++;
49                 if (*p == '#' || *p == '\n' || *p == 0)
50                         continue;
51                 if (sscanf(p, "0x%x %s\n", &id, namebuf) != 2 &&
52                     sscanf(p, "0x%x %s #", &id, namebuf) != 2 &&
53                     sscanf(p, "%d %s\n", &id, namebuf) != 2 &&
54                     sscanf(p, "%d %s #", &id, namebuf) != 2) {
55                         fprintf(stderr, "Database %s is corrupted at %s\n",
56                                 file, p);
57                         return;
58                 }
59
60                 if (id<0)
61                         continue;
62                 entry = malloc(sizeof(*entry));
63                 entry->id   = id;
64                 entry->name = strdup(namebuf);
65                 entry->next = hash[id & (size - 1)];
66                 hash[id & (size - 1)] = entry;
67         }
68         fclose(fp);
69 }
70
71 static void rtnl_tab_initialize(char *file, char **tab, int size)
72 {
73         char buf[512];
74         FILE *fp;
75
76         fp = fopen(file, "r");
77         if (!fp)
78                 return;
79         while (fgets(buf, sizeof(buf), fp)) {
80                 char *p = buf;
81                 int id;
82                 char namebuf[512];
83
84                 while (*p == ' ' || *p == '\t')
85                         p++;
86                 if (*p == '#' || *p == '\n' || *p == 0)
87                         continue;
88                 if (sscanf(p, "0x%x %s\n", &id, namebuf) != 2 &&
89                     sscanf(p, "0x%x %s #", &id, namebuf) != 2 &&
90                     sscanf(p, "%d %s\n", &id, namebuf) != 2 &&
91                     sscanf(p, "%d %s #", &id, namebuf) != 2) {
92                         fprintf(stderr, "Database %s is corrupted at %s\n",
93                                 file, p);
94                         return;
95                 }
96
97                 if (id<0 || id>size)
98                         continue;
99
100                 tab[id] = strdup(namebuf);
101         }
102         fclose(fp);
103 }
104
105 static char * rtnl_rtprot_tab[256] = {
106         [RTPROT_UNSPEC] = "none",
107         [RTPROT_REDIRECT] ="redirect",
108         [RTPROT_KERNEL] = "kernel",
109         [RTPROT_BOOT] = "boot",
110         [RTPROT_STATIC] = "static",
111
112         [RTPROT_GATED] = "gated",
113         [RTPROT_RA] = "ra",
114         [RTPROT_MRT] =  "mrt",
115         [RTPROT_ZEBRA] ="zebra",
116         [RTPROT_BIRD] = "bird",
117         [RTPROT_DNROUTED] = "dnrouted",
118         [RTPROT_XORP] = "xorp",
119         [RTPROT_NTK] = "ntk",
120         [RTPROT_DHCP] = "dhcp",
121 };
122
123
124
125 static int rtnl_rtprot_init;
126
127 static void rtnl_rtprot_initialize(void)
128 {
129         rtnl_rtprot_init = 1;
130         rtnl_tab_initialize("/etc/iproute2/rt_protos",
131                             rtnl_rtprot_tab, 256);
132 }
133
134 char * rtnl_rtprot_n2a(int id, char *buf, int len)
135 {
136         if (id<0 || id>=256) {
137                 snprintf(buf, len, "%d", id);
138                 return buf;
139         }
140         if (!rtnl_rtprot_tab[id]) {
141                 if (!rtnl_rtprot_init)
142                         rtnl_rtprot_initialize();
143         }
144         if (rtnl_rtprot_tab[id])
145                 return rtnl_rtprot_tab[id];
146         snprintf(buf, len, "%d", id);
147         return buf;
148 }
149
150 int rtnl_rtprot_a2n(__u32 *id, char *arg)
151 {
152         static char *cache = NULL;
153         static unsigned long res;
154         char *end;
155         int i;
156
157         if (cache && strcmp(cache, arg) == 0) {
158                 *id = res;
159                 return 0;
160         }
161
162         if (!rtnl_rtprot_init)
163                 rtnl_rtprot_initialize();
164
165         for (i=0; i<256; i++) {
166                 if (rtnl_rtprot_tab[i] &&
167                     strcmp(rtnl_rtprot_tab[i], arg) == 0) {
168                         cache = rtnl_rtprot_tab[i];
169                         res = i;
170                         *id = res;
171                         return 0;
172                 }
173         }
174
175         res = strtoul(arg, &end, 0);
176         if (!end || end == arg || *end || res > 255)
177                 return -1;
178         *id = res;
179         return 0;
180 }
181
182
183
184 static char * rtnl_rtscope_tab[256] = {
185         "global",
186 };
187
188 static int rtnl_rtscope_init;
189
190 static void rtnl_rtscope_initialize(void)
191 {
192         rtnl_rtscope_init = 1;
193         rtnl_rtscope_tab[255] = "nowhere";
194         rtnl_rtscope_tab[254] = "host";
195         rtnl_rtscope_tab[253] = "link";
196         rtnl_rtscope_tab[200] = "site";
197         rtnl_tab_initialize("/etc/iproute2/rt_scopes",
198                             rtnl_rtscope_tab, 256);
199 }
200
201 char * rtnl_rtscope_n2a(int id, char *buf, int len)
202 {
203         if (id<0 || id>=256) {
204                 snprintf(buf, len, "%d", id);
205                 return buf;
206         }
207         if (!rtnl_rtscope_tab[id]) {
208                 if (!rtnl_rtscope_init)
209                         rtnl_rtscope_initialize();
210         }
211         if (rtnl_rtscope_tab[id])
212                 return rtnl_rtscope_tab[id];
213         snprintf(buf, len, "%d", id);
214         return buf;
215 }
216
217 int rtnl_rtscope_a2n(__u32 *id, char *arg)
218 {
219         static char *cache = NULL;
220         static unsigned long res;
221         char *end;
222         int i;
223
224         if (cache && strcmp(cache, arg) == 0) {
225                 *id = res;
226                 return 0;
227         }
228
229         if (!rtnl_rtscope_init)
230                 rtnl_rtscope_initialize();
231
232         for (i=0; i<256; i++) {
233                 if (rtnl_rtscope_tab[i] &&
234                     strcmp(rtnl_rtscope_tab[i], arg) == 0) {
235                         cache = rtnl_rtscope_tab[i];
236                         res = i;
237                         *id = res;
238                         return 0;
239                 }
240         }
241
242         res = strtoul(arg, &end, 0);
243         if (!end || end == arg || *end || res > 255)
244                 return -1;
245         *id = res;
246         return 0;
247 }
248
249
250
251 static char * rtnl_rtrealm_tab[256] = {
252         "unknown",
253 };
254
255 static int rtnl_rtrealm_init;
256
257 static void rtnl_rtrealm_initialize(void)
258 {
259         rtnl_rtrealm_init = 1;
260         rtnl_tab_initialize("/etc/iproute2/rt_realms",
261                             rtnl_rtrealm_tab, 256);
262 }
263
264 char * rtnl_rtrealm_n2a(int id, char *buf, int len)
265 {
266         if (id<0 || id>=256) {
267                 snprintf(buf, len, "%d", id);
268                 return buf;
269         }
270         if (!rtnl_rtrealm_tab[id]) {
271                 if (!rtnl_rtrealm_init)
272                         rtnl_rtrealm_initialize();
273         }
274         if (rtnl_rtrealm_tab[id])
275                 return rtnl_rtrealm_tab[id];
276         snprintf(buf, len, "%d", id);
277         return buf;
278 }
279
280
281 int rtnl_rtrealm_a2n(__u32 *id, char *arg)
282 {
283         static char *cache = NULL;
284         static unsigned long res;
285         char *end;
286         int i;
287
288         if (cache && strcmp(cache, arg) == 0) {
289                 *id = res;
290                 return 0;
291         }
292
293         if (!rtnl_rtrealm_init)
294                 rtnl_rtrealm_initialize();
295
296         for (i=0; i<256; i++) {
297                 if (rtnl_rtrealm_tab[i] &&
298                     strcmp(rtnl_rtrealm_tab[i], arg) == 0) {
299                         cache = rtnl_rtrealm_tab[i];
300                         res = i;
301                         *id = res;
302                         return 0;
303                 }
304         }
305
306         res = strtoul(arg, &end, 0);
307         if (!end || end == arg || *end || res > 255)
308                 return -1;
309         *id = res;
310         return 0;
311 }
312
313
314 static struct rtnl_hash_entry dflt_table_entry  = { .id = 253, .name = "default" };
315 static struct rtnl_hash_entry main_table_entry  = { .id = 254, .name = "main" };
316 static struct rtnl_hash_entry local_table_entry = { .id = 255, .name = "local" };
317
318 static struct rtnl_hash_entry * rtnl_rttable_hash[256] = {
319         [253] = &dflt_table_entry,
320         [254] = &main_table_entry,
321         [255] = &local_table_entry,
322 };
323
324 static int rtnl_rttable_init;
325
326 static void rtnl_rttable_initialize(void)
327 {
328         rtnl_rttable_init = 1;
329         rtnl_hash_initialize("/etc/iproute2/rt_tables",
330                              rtnl_rttable_hash, 256);
331 }
332
333 char * rtnl_rttable_n2a(__u32 id, char *buf, int len)
334 {
335         struct rtnl_hash_entry *entry;
336
337         if (id > RT_TABLE_MAX) {
338                 snprintf(buf, len, "%u", id);
339                 return buf;
340         }
341         if (!rtnl_rttable_init)
342                 rtnl_rttable_initialize();
343         entry = rtnl_rttable_hash[id & 255];
344         while (entry && entry->id != id)
345                 entry = entry->next;
346         if (entry)
347                 return entry->name;
348         snprintf(buf, len, "%u", id);
349         return buf;
350 }
351
352 int rtnl_rttable_a2n(__u32 *id, char *arg)
353 {
354         static char *cache = NULL;
355         static unsigned long res;
356         struct rtnl_hash_entry *entry;
357         char *end;
358         __u32 i;
359
360         if (cache && strcmp(cache, arg) == 0) {
361                 *id = res;
362                 return 0;
363         }
364
365         if (!rtnl_rttable_init)
366                 rtnl_rttable_initialize();
367
368         for (i=0; i<256; i++) {
369                 entry = rtnl_rttable_hash[i];
370                 while (entry && strcmp(entry->name, arg))
371                         entry = entry->next;
372                 if (entry) {
373                         cache = entry->name;
374                         res = entry->id;
375                         *id = res;
376                         return 0;
377                 }
378         }
379
380         i = strtoul(arg, &end, 0);
381         if (!end || end == arg || *end || i > RT_TABLE_MAX)
382                 return -1;
383         *id = i;
384         return 0;
385 }
386
387
388 static char * rtnl_rtdsfield_tab[256] = {
389         "0",
390 };
391
392 static int rtnl_rtdsfield_init;
393
394 static void rtnl_rtdsfield_initialize(void)
395 {
396         rtnl_rtdsfield_init = 1;
397         rtnl_tab_initialize("/etc/iproute2/rt_dsfield",
398                             rtnl_rtdsfield_tab, 256);
399 }
400
401 char * rtnl_dsfield_n2a(int id, char *buf, int len)
402 {
403         if (id<0 || id>=256) {
404                 snprintf(buf, len, "%d", id);
405                 return buf;
406         }
407         if (!rtnl_rtdsfield_tab[id]) {
408                 if (!rtnl_rtdsfield_init)
409                         rtnl_rtdsfield_initialize();
410         }
411         if (rtnl_rtdsfield_tab[id])
412                 return rtnl_rtdsfield_tab[id];
413         snprintf(buf, len, "0x%02x", id);
414         return buf;
415 }
416
417
418 int rtnl_dsfield_a2n(__u32 *id, char *arg)
419 {
420         static char *cache = NULL;
421         static unsigned long res;
422         char *end;
423         int i;
424
425         if (cache && strcmp(cache, arg) == 0) {
426                 *id = res;
427                 return 0;
428         }
429
430         if (!rtnl_rtdsfield_init)
431                 rtnl_rtdsfield_initialize();
432
433         for (i=0; i<256; i++) {
434                 if (rtnl_rtdsfield_tab[i] &&
435                     strcmp(rtnl_rtdsfield_tab[i], arg) == 0) {
436                         cache = rtnl_rtdsfield_tab[i];
437                         res = i;
438                         *id = res;
439                         return 0;
440                 }
441         }
442
443         res = strtoul(arg, &end, 16);
444         if (!end || end == arg || *end || res > 255)
445                 return -1;
446         *id = res;
447         return 0;
448 }
449