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>
22 #include <asm/types.h>
23 #include <linux/rtnetlink.h>
28 #define CONFDIR "/etc/iproute2"
31 #define NAME_MAX_LEN 512
33 struct rtnl_hash_entry
{
34 struct rtnl_hash_entry
*next
;
39 static int fread_id_name(FILE *fp
, int *id
, char *namebuf
)
41 char buf
[NAME_MAX_LEN
];
43 while (fgets(buf
, sizeof(buf
), fp
)) {
46 while (*p
== ' ' || *p
== '\t')
49 if (*p
== '#' || *p
== '\n' || *p
== 0)
52 if (sscanf(p
, "0x%x %s\n", id
, namebuf
) != 2 &&
53 sscanf(p
, "0x%x %s #", id
, namebuf
) != 2 &&
54 sscanf(p
, "%d %s\n", id
, namebuf
) != 2 &&
55 sscanf(p
, "%d %s #", id
, namebuf
) != 2) {
65 rtnl_hash_initialize(const char *file
, struct rtnl_hash_entry
**hash
, int size
)
67 struct rtnl_hash_entry
*entry
;
70 char namebuf
[NAME_MAX_LEN
] = {0};
73 fp
= fopen(file
, "r");
77 while ((ret
= fread_id_name(fp
, &id
, &namebuf
[0]))) {
79 fprintf(stderr
, "Database %s is corrupted at %s\n",
88 entry
= malloc(sizeof(*entry
));
90 entry
->name
= strdup(namebuf
);
91 entry
->next
= hash
[id
& (size
- 1)];
92 hash
[id
& (size
- 1)] = entry
;
97 static void rtnl_tab_initialize(const char *file
, char **tab
, int size
)
101 char namebuf
[NAME_MAX_LEN
] = {0};
104 fp
= fopen(file
, "r");
108 while ((ret
= fread_id_name(fp
, &id
, &namebuf
[0]))) {
110 fprintf(stderr
, "Database %s is corrupted at %s\n",
115 if (id
< 0 || id
> size
)
118 tab
[id
] = strdup(namebuf
);
123 static char *rtnl_rtprot_tab
[256] = {
124 [RTPROT_UNSPEC
] = "none",
125 [RTPROT_REDIRECT
] = "redirect",
126 [RTPROT_KERNEL
] = "kernel",
127 [RTPROT_BOOT
] = "boot",
128 [RTPROT_STATIC
] = "static",
130 [RTPROT_GATED
] = "gated",
132 [RTPROT_MRT
] = "mrt",
133 [RTPROT_ZEBRA
] = "zebra",
134 [RTPROT_BIRD
] = "bird",
135 [RTPROT_BABEL
] = "babel",
136 [RTPROT_DNROUTED
] = "dnrouted",
137 [RTPROT_XORP
] = "xorp",
138 [RTPROT_NTK
] = "ntk",
139 [RTPROT_DHCP
] = "dhcp",
143 static int rtnl_rtprot_init
;
145 static void rtnl_rtprot_initialize(void)
147 rtnl_rtprot_init
= 1;
148 rtnl_tab_initialize(CONFDIR
"/rt_protos",
149 rtnl_rtprot_tab
, 256);
152 const char *rtnl_rtprot_n2a(int id
, char *buf
, int len
)
154 if (id
< 0 || id
>= 256) {
155 snprintf(buf
, len
, "%u", id
);
158 if (!rtnl_rtprot_tab
[id
]) {
159 if (!rtnl_rtprot_init
)
160 rtnl_rtprot_initialize();
162 if (rtnl_rtprot_tab
[id
])
163 return rtnl_rtprot_tab
[id
];
164 snprintf(buf
, len
, "%u", id
);
168 int rtnl_rtprot_a2n(__u32
*id
, const char *arg
)
171 static unsigned long res
;
175 if (cache
&& strcmp(cache
, arg
) == 0) {
180 if (!rtnl_rtprot_init
)
181 rtnl_rtprot_initialize();
183 for (i
= 0; i
< 256; i
++) {
184 if (rtnl_rtprot_tab
[i
] &&
185 strcmp(rtnl_rtprot_tab
[i
], arg
) == 0) {
186 cache
= rtnl_rtprot_tab
[i
];
193 res
= strtoul(arg
, &end
, 0);
194 if (!end
|| end
== arg
|| *end
|| res
> 255)
201 static char *rtnl_rtscope_tab
[256] = {
202 [RT_SCOPE_UNIVERSE
] = "global",
203 [RT_SCOPE_NOWHERE
] = "nowhere",
204 [RT_SCOPE_HOST
] = "host",
205 [RT_SCOPE_LINK
] = "link",
206 [RT_SCOPE_SITE
] = "site",
209 static int rtnl_rtscope_init
;
211 static void rtnl_rtscope_initialize(void)
213 rtnl_rtscope_init
= 1;
214 rtnl_tab_initialize(CONFDIR
"/rt_scopes",
215 rtnl_rtscope_tab
, 256);
218 const char *rtnl_rtscope_n2a(int id
, char *buf
, int len
)
220 if (id
< 0 || id
>= 256) {
221 snprintf(buf
, len
, "%d", id
);
225 if (!rtnl_rtscope_tab
[id
]) {
226 if (!rtnl_rtscope_init
)
227 rtnl_rtscope_initialize();
230 if (rtnl_rtscope_tab
[id
])
231 return rtnl_rtscope_tab
[id
];
233 snprintf(buf
, len
, "%d", id
);
237 int rtnl_rtscope_a2n(__u32
*id
, const char *arg
)
239 static const char *cache
;
240 static unsigned long res
;
244 if (cache
&& strcmp(cache
, arg
) == 0) {
249 if (!rtnl_rtscope_init
)
250 rtnl_rtscope_initialize();
252 for (i
= 0; i
< 256; i
++) {
253 if (rtnl_rtscope_tab
[i
] &&
254 strcmp(rtnl_rtscope_tab
[i
], arg
) == 0) {
255 cache
= rtnl_rtscope_tab
[i
];
262 res
= strtoul(arg
, &end
, 0);
263 if (!end
|| end
== arg
|| *end
|| res
> 255)
270 static char *rtnl_rtrealm_tab
[256] = {
274 static int rtnl_rtrealm_init
;
276 static void rtnl_rtrealm_initialize(void)
278 rtnl_rtrealm_init
= 1;
279 rtnl_tab_initialize(CONFDIR
"/rt_realms",
280 rtnl_rtrealm_tab
, 256);
283 const char *rtnl_rtrealm_n2a(int id
, char *buf
, int len
)
285 if (id
< 0 || id
>= 256) {
286 snprintf(buf
, len
, "%d", id
);
289 if (!rtnl_rtrealm_tab
[id
]) {
290 if (!rtnl_rtrealm_init
)
291 rtnl_rtrealm_initialize();
293 if (rtnl_rtrealm_tab
[id
])
294 return rtnl_rtrealm_tab
[id
];
295 snprintf(buf
, len
, "%d", id
);
300 int rtnl_rtrealm_a2n(__u32
*id
, const char *arg
)
303 static unsigned long res
;
307 if (cache
&& strcmp(cache
, arg
) == 0) {
312 if (!rtnl_rtrealm_init
)
313 rtnl_rtrealm_initialize();
315 for (i
= 0; i
< 256; i
++) {
316 if (rtnl_rtrealm_tab
[i
] &&
317 strcmp(rtnl_rtrealm_tab
[i
], arg
) == 0) {
318 cache
= rtnl_rtrealm_tab
[i
];
325 res
= strtoul(arg
, &end
, 0);
326 if (!end
|| end
== arg
|| *end
|| res
> 255)
333 static struct rtnl_hash_entry dflt_table_entry
= { .name
= "default" };
334 static struct rtnl_hash_entry main_table_entry
= { .name
= "main" };
335 static struct rtnl_hash_entry local_table_entry
= { .name
= "local" };
337 static struct rtnl_hash_entry
*rtnl_rttable_hash
[256] = {
338 [RT_TABLE_DEFAULT
] = &dflt_table_entry
,
339 [RT_TABLE_MAIN
] = &main_table_entry
,
340 [RT_TABLE_LOCAL
] = &local_table_entry
,
343 static int rtnl_rttable_init
;
345 static void rtnl_rttable_initialize(void)
351 rtnl_rttable_init
= 1;
352 for (i
= 0; i
< 256; i
++) {
353 if (rtnl_rttable_hash
[i
])
354 rtnl_rttable_hash
[i
]->id
= i
;
356 rtnl_hash_initialize(CONFDIR
"/rt_tables",
357 rtnl_rttable_hash
, 256);
359 d
= opendir(CONFDIR
"/rt_tables.d");
363 while ((de
= readdir(d
)) != NULL
) {
367 if (*de
->d_name
== '.')
370 /* only consider filenames ending in '.conf' */
371 len
= strlen(de
->d_name
);
374 if (strcmp(de
->d_name
+ len
- 5, ".conf"))
377 snprintf(path
, sizeof(path
),
378 CONFDIR
"/rt_tables.d/%s", de
->d_name
);
379 rtnl_hash_initialize(path
, rtnl_rttable_hash
, 256);
384 const char *rtnl_rttable_n2a(__u32 id
, char *buf
, int len
)
386 struct rtnl_hash_entry
*entry
;
388 if (id
> RT_TABLE_MAX
) {
389 snprintf(buf
, len
, "%u", id
);
392 if (!rtnl_rttable_init
)
393 rtnl_rttable_initialize();
394 entry
= rtnl_rttable_hash
[id
& 255];
395 while (entry
&& entry
->id
!= id
)
399 snprintf(buf
, len
, "%u", id
);
403 int rtnl_rttable_a2n(__u32
*id
, const char *arg
)
405 static const char *cache
;
406 static unsigned long res
;
407 struct rtnl_hash_entry
*entry
;
411 if (cache
&& strcmp(cache
, arg
) == 0) {
416 if (!rtnl_rttable_init
)
417 rtnl_rttable_initialize();
419 for (i
= 0; i
< 256; i
++) {
420 entry
= rtnl_rttable_hash
[i
];
421 while (entry
&& strcmp(entry
->name
, arg
))
431 i
= strtoul(arg
, &end
, 0);
432 if (!end
|| end
== arg
|| *end
|| i
> RT_TABLE_MAX
)
439 static char *rtnl_rtdsfield_tab
[256] = {
443 static int rtnl_rtdsfield_init
;
445 static void rtnl_rtdsfield_initialize(void)
447 rtnl_rtdsfield_init
= 1;
448 rtnl_tab_initialize(CONFDIR
"/rt_dsfield",
449 rtnl_rtdsfield_tab
, 256);
452 const char *rtnl_dsfield_n2a(int id
, char *buf
, int len
)
454 if (id
< 0 || id
>= 256) {
455 snprintf(buf
, len
, "%d", id
);
458 if (!rtnl_rtdsfield_tab
[id
]) {
459 if (!rtnl_rtdsfield_init
)
460 rtnl_rtdsfield_initialize();
462 if (rtnl_rtdsfield_tab
[id
])
463 return rtnl_rtdsfield_tab
[id
];
464 snprintf(buf
, len
, "0x%02x", id
);
469 int rtnl_dsfield_a2n(__u32
*id
, const char *arg
)
472 static unsigned long res
;
476 if (cache
&& strcmp(cache
, arg
) == 0) {
481 if (!rtnl_rtdsfield_init
)
482 rtnl_rtdsfield_initialize();
484 for (i
= 0; i
< 256; i
++) {
485 if (rtnl_rtdsfield_tab
[i
] &&
486 strcmp(rtnl_rtdsfield_tab
[i
], arg
) == 0) {
487 cache
= rtnl_rtdsfield_tab
[i
];
494 res
= strtoul(arg
, &end
, 16);
495 if (!end
|| end
== arg
|| *end
|| res
> 255)
502 static struct rtnl_hash_entry dflt_group_entry
= {
503 .id
= 0, .name
= "default"
506 static struct rtnl_hash_entry
*rtnl_group_hash
[256] = {
507 [0] = &dflt_group_entry
,
510 static int rtnl_group_init
;
512 static void rtnl_group_initialize(void)
515 rtnl_hash_initialize(CONFDIR
"/group",
516 rtnl_group_hash
, 256);
519 int rtnl_group_a2n(int *id
, const char *arg
)
521 static const char *cache
;
522 static unsigned long res
;
523 struct rtnl_hash_entry
*entry
;
527 if (cache
&& strcmp(cache
, arg
) == 0) {
532 if (!rtnl_group_init
)
533 rtnl_group_initialize();
535 for (i
= 0; i
< 256; i
++) {
536 entry
= rtnl_group_hash
[i
];
537 while (entry
&& strcmp(entry
->name
, arg
))
547 i
= strtol(arg
, &end
, 0);
548 if (!end
|| end
== arg
|| *end
|| i
< 0)
554 const char *rtnl_group_n2a(int id
, char *buf
, int len
)
556 struct rtnl_hash_entry
*entry
;
559 if (!rtnl_group_init
)
560 rtnl_group_initialize();
562 for (i
= 0; i
< 256; i
++) {
563 entry
= rtnl_group_hash
[i
];
564 if (entry
&& entry
->id
== id
)
568 snprintf(buf
, len
, "%d", id
);
572 static char *nl_proto_tab
[256] = {
573 [NETLINK_ROUTE
] = "rtnl",
574 [NETLINK_UNUSED
] = "unused",
575 [NETLINK_USERSOCK
] = "usersock",
576 [NETLINK_FIREWALL
] = "fw",
577 [NETLINK_SOCK_DIAG
] = "tcpdiag",
578 [NETLINK_NFLOG
] = "nflog",
579 [NETLINK_XFRM
] = "xfrm",
580 [NETLINK_SELINUX
] = "selinux",
581 [NETLINK_ISCSI
] = "iscsi",
582 [NETLINK_AUDIT
] = "audit",
583 [NETLINK_FIB_LOOKUP
] = "fiblookup",
584 [NETLINK_CONNECTOR
] = "connector",
585 [NETLINK_NETFILTER
] = "nft",
586 [NETLINK_IP6_FW
] = "ip6fw",
587 [NETLINK_DNRTMSG
] = "dec-rt",
588 [NETLINK_KOBJECT_UEVENT
] = "uevent",
589 [NETLINK_GENERIC
] = "genl",
590 [NETLINK_SCSITRANSPORT
] = "scsi-trans",
591 [NETLINK_ECRYPTFS
] = "ecryptfs",
592 [NETLINK_RDMA
] = "rdma",
593 [NETLINK_CRYPTO
] = "crypto",
596 static int nl_proto_init
;
598 static void nl_proto_initialize(void)
601 rtnl_tab_initialize(CONFDIR
"/nl_protos",
605 const char *nl_proto_n2a(int id
, char *buf
, int len
)
607 if (id
< 0 || id
>= 256) {
608 snprintf(buf
, len
, "%u", id
);
613 nl_proto_initialize();
615 if (nl_proto_tab
[id
])
616 return nl_proto_tab
[id
];
618 snprintf(buf
, len
, "%u", id
);
622 int nl_proto_a2n(__u32
*id
, const char *arg
)
625 static unsigned long res
;
629 if (cache
&& strcmp(cache
, arg
) == 0) {
635 nl_proto_initialize();
637 for (i
= 0; i
< 256; i
++) {
638 if (nl_proto_tab
[i
] &&
639 strcmp(nl_proto_tab
[i
], arg
) == 0) {
640 cache
= nl_proto_tab
[i
];
647 res
= strtoul(arg
, &end
, 0);
648 if (!end
|| end
== arg
|| *end
|| res
> 255)