2 * rt_names.c rtnetlink names DB.
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.
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
19 #include <sys/socket.h>
21 #include <asm/types.h>
22 #include <linux/rtnetlink.h>
27 #define CONFDIR "/etc/iproute2"
30 struct rtnl_hash_entry
{
31 struct rtnl_hash_entry
*next
;
37 rtnl_hash_initialize(const char *file
, struct rtnl_hash_entry
**hash
, int size
)
39 struct rtnl_hash_entry
*entry
;
43 fp
= fopen(file
, "r");
46 while (fgets(buf
, sizeof(buf
), fp
)) {
51 while (*p
== ' ' || *p
== '\t')
53 if (*p
== '#' || *p
== '\n' || *p
== 0)
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",
67 entry
= malloc(sizeof(*entry
));
69 entry
->name
= strdup(namebuf
);
70 entry
->next
= hash
[id
& (size
- 1)];
71 hash
[id
& (size
- 1)] = entry
;
76 static void rtnl_tab_initialize(const char *file
, char **tab
, int size
)
81 fp
= fopen(file
, "r");
84 while (fgets(buf
, sizeof(buf
), fp
)) {
89 while (*p
== ' ' || *p
== '\t')
91 if (*p
== '#' || *p
== '\n' || *p
== 0)
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",
106 tab
[id
] = strdup(namebuf
);
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",
118 [RTPROT_GATED
] = "gated",
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",
130 static int rtnl_rtprot_init
;
132 static void rtnl_rtprot_initialize(void)
134 rtnl_rtprot_init
= 1;
135 rtnl_tab_initialize(CONFDIR
"/rt_protos",
136 rtnl_rtprot_tab
, 256);
139 const char * rtnl_rtprot_n2a(int id
, char *buf
, int len
)
141 if (id
<0 || id
>=256) {
142 snprintf(buf
, len
, "%u", id
);
145 if (!rtnl_rtprot_tab
[id
]) {
146 if (!rtnl_rtprot_init
)
147 rtnl_rtprot_initialize();
149 if (rtnl_rtprot_tab
[id
])
150 return rtnl_rtprot_tab
[id
];
151 snprintf(buf
, len
, "%u", id
);
155 int rtnl_rtprot_a2n(__u32
*id
, const char *arg
)
157 static char *cache
= NULL
;
158 static unsigned long res
;
162 if (cache
&& strcmp(cache
, arg
) == 0) {
167 if (!rtnl_rtprot_init
)
168 rtnl_rtprot_initialize();
170 for (i
=0; i
<256; i
++) {
171 if (rtnl_rtprot_tab
[i
] &&
172 strcmp(rtnl_rtprot_tab
[i
], arg
) == 0) {
173 cache
= rtnl_rtprot_tab
[i
];
180 res
= strtoul(arg
, &end
, 0);
181 if (!end
|| end
== arg
|| *end
|| res
> 255)
188 static char * rtnl_rtscope_tab
[256] = {
192 static int rtnl_rtscope_init
;
194 static void rtnl_rtscope_initialize(void)
196 rtnl_rtscope_init
= 1;
197 rtnl_rtscope_tab
[255] = "nowhere";
198 rtnl_rtscope_tab
[254] = "host";
199 rtnl_rtscope_tab
[253] = "link";
200 rtnl_rtscope_tab
[200] = "site";
201 rtnl_tab_initialize(CONFDIR
"/rt_scopes",
202 rtnl_rtscope_tab
, 256);
205 const char *rtnl_rtscope_n2a(int id
, char *buf
, int len
)
207 if (id
<0 || id
>=256) {
208 snprintf(buf
, len
, "%d", id
);
211 if (!rtnl_rtscope_tab
[id
]) {
212 if (!rtnl_rtscope_init
)
213 rtnl_rtscope_initialize();
215 if (rtnl_rtscope_tab
[id
])
216 return rtnl_rtscope_tab
[id
];
217 snprintf(buf
, len
, "%d", id
);
221 int rtnl_rtscope_a2n(__u32
*id
, const char *arg
)
223 static const char *cache
= NULL
;
224 static unsigned long res
;
228 if (cache
&& strcmp(cache
, arg
) == 0) {
233 if (!rtnl_rtscope_init
)
234 rtnl_rtscope_initialize();
236 for (i
=0; i
<256; i
++) {
237 if (rtnl_rtscope_tab
[i
] &&
238 strcmp(rtnl_rtscope_tab
[i
], arg
) == 0) {
239 cache
= rtnl_rtscope_tab
[i
];
246 res
= strtoul(arg
, &end
, 0);
247 if (!end
|| end
== arg
|| *end
|| res
> 255)
254 static char * rtnl_rtrealm_tab
[256] = {
258 static int rtnl_rtrealm_init
;
260 static void rtnl_rtrealm_initialize(void)
262 rtnl_rtrealm_init
= 1;
263 rtnl_tab_initialize(CONFDIR
"/rt_realms",
264 rtnl_rtrealm_tab
, 256);
267 const char *rtnl_rtrealm_n2a(int id
, char *buf
, int len
)
269 if (id
<0 || id
>=256) {
270 snprintf(buf
, len
, "%d", id
);
273 if (!rtnl_rtrealm_tab
[id
]) {
274 if (!rtnl_rtrealm_init
)
275 rtnl_rtrealm_initialize();
277 if (rtnl_rtrealm_tab
[id
])
278 return rtnl_rtrealm_tab
[id
];
279 snprintf(buf
, len
, "%d", id
);
284 int rtnl_rtrealm_a2n(__u32
*id
, const char *arg
)
286 static char *cache
= NULL
;
287 static unsigned long res
;
291 if (cache
&& strcmp(cache
, arg
) == 0) {
296 if (!rtnl_rtrealm_init
)
297 rtnl_rtrealm_initialize();
299 for (i
=0; i
<256; i
++) {
300 if (rtnl_rtrealm_tab
[i
] &&
301 strcmp(rtnl_rtrealm_tab
[i
], arg
) == 0) {
302 cache
= rtnl_rtrealm_tab
[i
];
309 res
= strtoul(arg
, &end
, 0);
310 if (!end
|| end
== arg
|| *end
|| res
> 255)
317 static struct rtnl_hash_entry dflt_table_entry
= { .id
= 253, .name
= "default" };
318 static struct rtnl_hash_entry main_table_entry
= { .id
= 254, .name
= "main" };
319 static struct rtnl_hash_entry local_table_entry
= { .id
= 255, .name
= "local" };
321 static struct rtnl_hash_entry
* rtnl_rttable_hash
[256] = {
322 [253] = &dflt_table_entry
,
323 [254] = &main_table_entry
,
324 [255] = &local_table_entry
,
327 static int rtnl_rttable_init
;
329 static void rtnl_rttable_initialize(void)
331 rtnl_rttable_init
= 1;
332 rtnl_hash_initialize(CONFDIR
"/rt_tables",
333 rtnl_rttable_hash
, 256);
336 const char * rtnl_rttable_n2a(__u32 id
, char *buf
, int len
)
338 struct rtnl_hash_entry
*entry
;
340 if (id
> RT_TABLE_MAX
) {
341 snprintf(buf
, len
, "%u", id
);
344 if (!rtnl_rttable_init
)
345 rtnl_rttable_initialize();
346 entry
= rtnl_rttable_hash
[id
& 255];
347 while (entry
&& entry
->id
!= id
)
351 snprintf(buf
, len
, "%u", id
);
355 int rtnl_rttable_a2n(__u32
*id
, const char *arg
)
357 static const char *cache
= NULL
;
358 static unsigned long res
;
359 struct rtnl_hash_entry
*entry
;
363 if (cache
&& strcmp(cache
, arg
) == 0) {
368 if (!rtnl_rttable_init
)
369 rtnl_rttable_initialize();
371 for (i
=0; i
<256; i
++) {
372 entry
= rtnl_rttable_hash
[i
];
373 while (entry
&& strcmp(entry
->name
, arg
))
383 i
= strtoul(arg
, &end
, 0);
384 if (!end
|| end
== arg
|| *end
|| i
> RT_TABLE_MAX
)
391 static char * rtnl_rtdsfield_tab
[256] = {
395 static int rtnl_rtdsfield_init
;
397 static void rtnl_rtdsfield_initialize(void)
399 rtnl_rtdsfield_init
= 1;
400 rtnl_tab_initialize(CONFDIR
"/rt_dsfield",
401 rtnl_rtdsfield_tab
, 256);
404 const char *rtnl_dsfield_n2a(int id
, char *buf
, int len
)
406 if (id
<0 || id
>=256) {
407 snprintf(buf
, len
, "%d", id
);
410 if (!rtnl_rtdsfield_tab
[id
]) {
411 if (!rtnl_rtdsfield_init
)
412 rtnl_rtdsfield_initialize();
414 if (rtnl_rtdsfield_tab
[id
])
415 return rtnl_rtdsfield_tab
[id
];
416 snprintf(buf
, len
, "0x%02x", id
);
421 int rtnl_dsfield_a2n(__u32
*id
, const char *arg
)
423 static char *cache
= NULL
;
424 static unsigned long res
;
428 if (cache
&& strcmp(cache
, arg
) == 0) {
433 if (!rtnl_rtdsfield_init
)
434 rtnl_rtdsfield_initialize();
436 for (i
=0; i
<256; i
++) {
437 if (rtnl_rtdsfield_tab
[i
] &&
438 strcmp(rtnl_rtdsfield_tab
[i
], arg
) == 0) {
439 cache
= rtnl_rtdsfield_tab
[i
];
446 res
= strtoul(arg
, &end
, 16);
447 if (!end
|| end
== arg
|| *end
|| res
> 255)
454 static struct rtnl_hash_entry dflt_group_entry
= { .id
= 0, .name
= "default" };
456 static struct rtnl_hash_entry
* rtnl_group_hash
[256] = {
457 [0] = &dflt_group_entry
,
460 static int rtnl_group_init
;
462 static void rtnl_group_initialize(void)
465 rtnl_hash_initialize("/etc/iproute2/group",
466 rtnl_group_hash
, 256);
469 int rtnl_group_a2n(int *id
, const char *arg
)
471 static const char *cache
= NULL
;
472 static unsigned long res
;
473 struct rtnl_hash_entry
*entry
;
477 if (cache
&& strcmp(cache
, arg
) == 0) {
482 if (!rtnl_group_init
)
483 rtnl_group_initialize();
485 for (i
=0; i
<256; i
++) {
486 entry
= rtnl_group_hash
[i
];
487 while (entry
&& strcmp(entry
->name
, arg
))
497 i
= strtol(arg
, &end
, 0);
498 if (!end
|| end
== arg
|| *end
|| i
< 0)
504 const char *rtnl_group_n2a(int id
, char *buf
, int len
)
506 struct rtnl_hash_entry
*entry
;
509 if (!rtnl_group_init
)
510 rtnl_group_initialize();
512 for (i
=0; i
<256; i
++) {
513 entry
= rtnl_group_hash
[i
];
514 if (entry
&& entry
->id
== id
) {
519 snprintf(buf
, len
, "%d", id
);