]> git.proxmox.com Git - mirror_iproute2.git/blame - lib/rt_names.c
iproute2: support listing devices by group
[mirror_iproute2.git] / lib / rt_names.c
CommitLineData
aba5acdf
SH
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>
b88fd9f4
SH
19#include <sys/socket.h>
20
21#include <asm/types.h>
22#include <linux/rtnetlink.h>
23
24#include "rt_names.h"
aba5acdf 25
9c47d877
PM
26struct rtnl_hash_entry {
27 struct rtnl_hash_entry *next;
28 char * name;
29 unsigned int id;
30};
31
32static void
33rtnl_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
aba5acdf
SH
71static 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
aba5acdf 105static char * rtnl_rtprot_tab[256] = {
b88fd9f4
SH
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",
40b6c62c 119 [RTPROT_NTK] = "ntk",
1e659af3 120 [RTPROT_DHCP] = "dhcp",
aba5acdf
SH
121};
122
123
124
125static int rtnl_rtprot_init;
126
127static 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
134char * 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
150int 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
184static char * rtnl_rtscope_tab[256] = {
185 "global",
186};
187
188static int rtnl_rtscope_init;
189
190static 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
201char * 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
217int 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
251static char * rtnl_rtrealm_tab[256] = {
252 "unknown",
253};
254
255static int rtnl_rtrealm_init;
256
257static 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
264char * 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
281int 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
9c47d877
PM
314static struct rtnl_hash_entry dflt_table_entry = { .id = 253, .name = "default" };
315static struct rtnl_hash_entry main_table_entry = { .id = 254, .name = "main" };
316static struct rtnl_hash_entry local_table_entry = { .id = 255, .name = "local" };
aba5acdf 317
9c47d877
PM
318static struct rtnl_hash_entry * rtnl_rttable_hash[256] = {
319 [253] = &dflt_table_entry,
320 [254] = &main_table_entry,
321 [255] = &local_table_entry,
aba5acdf
SH
322};
323
324static int rtnl_rttable_init;
325
326static void rtnl_rttable_initialize(void)
327{
328 rtnl_rttable_init = 1;
9c47d877
PM
329 rtnl_hash_initialize("/etc/iproute2/rt_tables",
330 rtnl_rttable_hash, 256);
aba5acdf
SH
331}
332
34e95647 333char * rtnl_rttable_n2a(__u32 id, char *buf, int len)
aba5acdf 334{
9c47d877
PM
335 struct rtnl_hash_entry *entry;
336
887a5d00 337 if (id > RT_TABLE_MAX) {
9c47d877 338 snprintf(buf, len, "%u", id);
aba5acdf
SH
339 return buf;
340 }
9c47d877
PM
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);
aba5acdf
SH
349 return buf;
350}
351
352int rtnl_rttable_a2n(__u32 *id, char *arg)
353{
354 static char *cache = NULL;
355 static unsigned long res;
9c47d877 356 struct rtnl_hash_entry *entry;
aba5acdf 357 char *end;
34e95647 358 __u32 i;
aba5acdf
SH
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++) {
9c47d877
PM
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;
aba5acdf
SH
375 *id = res;
376 return 0;
377 }
378 }
379
380 i = strtoul(arg, &end, 0);
9c47d877 381 if (!end || end == arg || *end || i > RT_TABLE_MAX)
aba5acdf
SH
382 return -1;
383 *id = i;
384 return 0;
385}
386
387
388static char * rtnl_rtdsfield_tab[256] = {
389 "0",
390};
391
392static int rtnl_rtdsfield_init;
393
394static 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
401char * 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
418int 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
ac694c33
VD
450
451static struct rtnl_hash_entry dflt_group_entry = { .id = 0, .name = "default" };
452
453static struct rtnl_hash_entry * rtnl_group_hash[256] = {
454 [0] = &dflt_group_entry,
455};
456
457static int rtnl_group_init;
458
459static void rtnl_group_initialize(void)
460{
461 rtnl_group_init = 1;
462 rtnl_hash_initialize("/etc/iproute2/group",
463 rtnl_group_hash, 256);
464}
465
466int rtnl_group_a2n(int *id, char *arg)
467{
468 static char *cache = NULL;
469 static unsigned long res;
470 struct rtnl_hash_entry *entry;
471 char *end;
472 int i;
473
474 if (cache && strcmp(cache, arg) == 0) {
475 *id = res;
476 return 0;
477 }
478
479 if (!rtnl_group_init)
480 rtnl_group_initialize();
481
482 for (i=0; i<256; i++) {
483 entry = rtnl_group_hash[i];
484 while (entry && strcmp(entry->name, arg))
485 entry = entry->next;
486 if (entry) {
487 cache = entry->name;
488 res = entry->id;
489 *id = res;
490 return 0;
491 }
492 }
493
494 i = strtol(arg, &end, 0);
495 if (!end || end == arg || *end || i < 0)
496 return -1;
497 *id = i;
498 return 0;
499}