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 NAME_MAX_LEN 512
30 struct rtnl_hash_entry
{
31 struct rtnl_hash_entry
*next
;
36 static int fread_id_name(FILE *fp
, int *id
, char *namebuf
)
38 char buf
[NAME_MAX_LEN
];
40 while (fgets(buf
, sizeof(buf
), fp
)) {
43 while (*p
== ' ' || *p
== '\t')
46 if (*p
== '#' || *p
== '\n' || *p
== 0)
49 if (sscanf(p
, "0x%x %s\n", id
, namebuf
) != 2 &&
50 sscanf(p
, "0x%x %s #", id
, namebuf
) != 2 &&
51 sscanf(p
, "%d %s\n", id
, namebuf
) != 2 &&
52 sscanf(p
, "%d %s #", id
, namebuf
) != 2) {
62 rtnl_hash_initialize(const char *file
, struct rtnl_hash_entry
**hash
, int size
)
64 struct rtnl_hash_entry
*entry
;
67 char namebuf
[NAME_MAX_LEN
] = {0};
70 fp
= fopen(file
, "r");
74 while ((ret
= fread_id_name(fp
, &id
, &namebuf
[0]))) {
76 fprintf(stderr
, "Database %s is corrupted at %s\n",
85 entry
= malloc(sizeof(*entry
));
87 entry
->name
= strdup(namebuf
);
88 entry
->next
= hash
[id
& (size
- 1)];
89 hash
[id
& (size
- 1)] = entry
;
94 static void rtnl_tab_initialize(const char *file
, char **tab
, int size
)
98 char namebuf
[NAME_MAX_LEN
] = {0};
101 fp
= fopen(file
, "r");
105 while ((ret
= fread_id_name(fp
, &id
, &namebuf
[0]))) {
107 fprintf(stderr
, "Database %s is corrupted at %s\n",
112 if (id
< 0 || id
> size
)
115 tab
[id
] = strdup(namebuf
);
120 static char *rtnl_rtprot_tab
[256] = {
121 [RTPROT_UNSPEC
] = "none",
122 [RTPROT_REDIRECT
] = "redirect",
123 [RTPROT_KERNEL
] = "kernel",
124 [RTPROT_BOOT
] = "boot",
125 [RTPROT_STATIC
] = "static",
127 [RTPROT_GATED
] = "gated",
129 [RTPROT_MRT
] = "mrt",
130 [RTPROT_ZEBRA
] = "zebra",
131 [RTPROT_BIRD
] = "bird",
132 [RTPROT_BABEL
] = "babel",
133 [RTPROT_DNROUTED
] = "dnrouted",
134 [RTPROT_XORP
] = "xorp",
135 [RTPROT_NTK
] = "ntk",
136 [RTPROT_DHCP
] = "dhcp",
140 static int rtnl_rtprot_init
;
142 static void rtnl_rtprot_initialize(void)
144 rtnl_rtprot_init
= 1;
145 rtnl_tab_initialize(CONFDIR
"/rt_protos",
146 rtnl_rtprot_tab
, 256);
149 const char *rtnl_rtprot_n2a(int id
, char *buf
, int len
)
151 if (id
< 0 || id
>= 256) {
152 snprintf(buf
, len
, "%u", id
);
155 if (!rtnl_rtprot_tab
[id
]) {
156 if (!rtnl_rtprot_init
)
157 rtnl_rtprot_initialize();
159 if (rtnl_rtprot_tab
[id
])
160 return rtnl_rtprot_tab
[id
];
161 snprintf(buf
, len
, "%u", id
);
165 int rtnl_rtprot_a2n(__u32
*id
, const char *arg
)
168 static unsigned long res
;
172 if (cache
&& strcmp(cache
, arg
) == 0) {
177 if (!rtnl_rtprot_init
)
178 rtnl_rtprot_initialize();
180 for (i
= 0; i
< 256; i
++) {
181 if (rtnl_rtprot_tab
[i
] &&
182 strcmp(rtnl_rtprot_tab
[i
], arg
) == 0) {
183 cache
= rtnl_rtprot_tab
[i
];
190 res
= strtoul(arg
, &end
, 0);
191 if (!end
|| end
== arg
|| *end
|| res
> 255)
198 static char *rtnl_rtscope_tab
[256] = {
199 [RT_SCOPE_UNIVERSE
] = "global",
200 [RT_SCOPE_NOWHERE
] = "nowhere",
201 [RT_SCOPE_HOST
] = "host",
202 [RT_SCOPE_LINK
] = "link",
203 [RT_SCOPE_SITE
] = "site",
206 static int rtnl_rtscope_init
;
208 static void rtnl_rtscope_initialize(void)
210 rtnl_rtscope_init
= 1;
211 rtnl_tab_initialize(CONFDIR
"/rt_scopes",
212 rtnl_rtscope_tab
, 256);
215 const char *rtnl_rtscope_n2a(int id
, char *buf
, int len
)
217 if (id
< 0 || id
>= 256) {
218 snprintf(buf
, len
, "%d", id
);
222 if (!rtnl_rtscope_tab
[id
]) {
223 if (!rtnl_rtscope_init
)
224 rtnl_rtscope_initialize();
227 if (rtnl_rtscope_tab
[id
])
228 return rtnl_rtscope_tab
[id
];
230 snprintf(buf
, len
, "%d", id
);
234 int rtnl_rtscope_a2n(__u32
*id
, const char *arg
)
236 static const char *cache
;
237 static unsigned long res
;
241 if (cache
&& strcmp(cache
, arg
) == 0) {
246 if (!rtnl_rtscope_init
)
247 rtnl_rtscope_initialize();
249 for (i
= 0; i
< 256; i
++) {
250 if (rtnl_rtscope_tab
[i
] &&
251 strcmp(rtnl_rtscope_tab
[i
], arg
) == 0) {
252 cache
= rtnl_rtscope_tab
[i
];
259 res
= strtoul(arg
, &end
, 0);
260 if (!end
|| end
== arg
|| *end
|| res
> 255)
267 static char *rtnl_rtrealm_tab
[256] = {
271 static int rtnl_rtrealm_init
;
273 static void rtnl_rtrealm_initialize(void)
275 rtnl_rtrealm_init
= 1;
276 rtnl_tab_initialize(CONFDIR
"/rt_realms",
277 rtnl_rtrealm_tab
, 256);
280 const char *rtnl_rtrealm_n2a(int id
, char *buf
, int len
)
282 if (id
< 0 || id
>= 256) {
283 snprintf(buf
, len
, "%d", id
);
286 if (!rtnl_rtrealm_tab
[id
]) {
287 if (!rtnl_rtrealm_init
)
288 rtnl_rtrealm_initialize();
290 if (rtnl_rtrealm_tab
[id
])
291 return rtnl_rtrealm_tab
[id
];
292 snprintf(buf
, len
, "%d", id
);
297 int rtnl_rtrealm_a2n(__u32
*id
, const char *arg
)
300 static unsigned long res
;
304 if (cache
&& strcmp(cache
, arg
) == 0) {
309 if (!rtnl_rtrealm_init
)
310 rtnl_rtrealm_initialize();
312 for (i
= 0; i
< 256; i
++) {
313 if (rtnl_rtrealm_tab
[i
] &&
314 strcmp(rtnl_rtrealm_tab
[i
], arg
) == 0) {
315 cache
= rtnl_rtrealm_tab
[i
];
322 res
= strtoul(arg
, &end
, 0);
323 if (!end
|| end
== arg
|| *end
|| res
> 255)
330 static struct rtnl_hash_entry dflt_table_entry
= { .name
= "default" };
331 static struct rtnl_hash_entry main_table_entry
= { .name
= "main" };
332 static struct rtnl_hash_entry local_table_entry
= { .name
= "local" };
334 static struct rtnl_hash_entry
*rtnl_rttable_hash
[256] = {
335 [RT_TABLE_DEFAULT
] = &dflt_table_entry
,
336 [RT_TABLE_MAIN
] = &main_table_entry
,
337 [RT_TABLE_LOCAL
] = &local_table_entry
,
340 static int rtnl_rttable_init
;
342 static void rtnl_rttable_initialize(void)
348 rtnl_rttable_init
= 1;
349 for (i
= 0; i
< 256; i
++) {
350 if (rtnl_rttable_hash
[i
])
351 rtnl_rttable_hash
[i
]->id
= i
;
353 rtnl_hash_initialize(CONFDIR
"/rt_tables",
354 rtnl_rttable_hash
, 256);
356 d
= opendir(CONFDIR
"/rt_tables.d");
360 while ((de
= readdir(d
)) != NULL
) {
364 if (*de
->d_name
== '.')
367 /* only consider filenames ending in '.conf' */
368 len
= strlen(de
->d_name
);
371 if (strcmp(de
->d_name
+ len
- 5, ".conf"))
374 snprintf(path
, sizeof(path
),
375 CONFDIR
"/rt_tables.d/%s", de
->d_name
);
376 rtnl_hash_initialize(path
, rtnl_rttable_hash
, 256);
381 const char *rtnl_rttable_n2a(__u32 id
, char *buf
, int len
)
383 struct rtnl_hash_entry
*entry
;
385 if (id
> RT_TABLE_MAX
) {
386 snprintf(buf
, len
, "%u", id
);
389 if (!rtnl_rttable_init
)
390 rtnl_rttable_initialize();
391 entry
= rtnl_rttable_hash
[id
& 255];
392 while (entry
&& entry
->id
!= id
)
396 snprintf(buf
, len
, "%u", id
);
400 int rtnl_rttable_a2n(__u32
*id
, const char *arg
)
402 static const char *cache
;
403 static unsigned long res
;
404 struct rtnl_hash_entry
*entry
;
408 if (cache
&& strcmp(cache
, arg
) == 0) {
413 if (!rtnl_rttable_init
)
414 rtnl_rttable_initialize();
416 for (i
= 0; i
< 256; i
++) {
417 entry
= rtnl_rttable_hash
[i
];
418 while (entry
&& strcmp(entry
->name
, arg
))
428 i
= strtoul(arg
, &end
, 0);
429 if (!end
|| end
== arg
|| *end
|| i
> RT_TABLE_MAX
)
436 static char *rtnl_rtdsfield_tab
[256] = {
440 static int rtnl_rtdsfield_init
;
442 static void rtnl_rtdsfield_initialize(void)
444 rtnl_rtdsfield_init
= 1;
445 rtnl_tab_initialize(CONFDIR
"/rt_dsfield",
446 rtnl_rtdsfield_tab
, 256);
449 const char *rtnl_dsfield_n2a(int id
, char *buf
, int len
)
451 if (id
< 0 || id
>= 256) {
452 snprintf(buf
, len
, "%d", id
);
455 if (!rtnl_rtdsfield_tab
[id
]) {
456 if (!rtnl_rtdsfield_init
)
457 rtnl_rtdsfield_initialize();
459 if (rtnl_rtdsfield_tab
[id
])
460 return rtnl_rtdsfield_tab
[id
];
461 snprintf(buf
, len
, "0x%02x", id
);
466 int rtnl_dsfield_a2n(__u32
*id
, const char *arg
)
469 static unsigned long res
;
473 if (cache
&& strcmp(cache
, arg
) == 0) {
478 if (!rtnl_rtdsfield_init
)
479 rtnl_rtdsfield_initialize();
481 for (i
= 0; i
< 256; i
++) {
482 if (rtnl_rtdsfield_tab
[i
] &&
483 strcmp(rtnl_rtdsfield_tab
[i
], arg
) == 0) {
484 cache
= rtnl_rtdsfield_tab
[i
];
491 res
= strtoul(arg
, &end
, 16);
492 if (!end
|| end
== arg
|| *end
|| res
> 255)
499 static struct rtnl_hash_entry dflt_group_entry
= {
500 .id
= 0, .name
= "default"
503 static struct rtnl_hash_entry
*rtnl_group_hash
[256] = {
504 [0] = &dflt_group_entry
,
507 static int rtnl_group_init
;
509 static void rtnl_group_initialize(void)
512 rtnl_hash_initialize(CONFDIR
"/group",
513 rtnl_group_hash
, 256);
516 int rtnl_group_a2n(int *id
, const char *arg
)
518 static const char *cache
;
519 static unsigned long res
;
520 struct rtnl_hash_entry
*entry
;
524 if (cache
&& strcmp(cache
, arg
) == 0) {
529 if (!rtnl_group_init
)
530 rtnl_group_initialize();
532 for (i
= 0; i
< 256; i
++) {
533 entry
= rtnl_group_hash
[i
];
534 while (entry
&& strcmp(entry
->name
, arg
))
544 i
= strtol(arg
, &end
, 0);
545 if (!end
|| end
== arg
|| *end
|| i
< 0)
551 const char *rtnl_group_n2a(int id
, char *buf
, int len
)
553 struct rtnl_hash_entry
*entry
;
556 if (!rtnl_group_init
)
557 rtnl_group_initialize();
559 for (i
= 0; i
< 256; i
++) {
560 entry
= rtnl_group_hash
[i
];
561 if (entry
&& entry
->id
== id
)
565 snprintf(buf
, len
, "%d", id
);
569 static char *nl_proto_tab
[256] = {
570 [NETLINK_ROUTE
] = "rtnl",
571 [NETLINK_UNUSED
] = "unused",
572 [NETLINK_USERSOCK
] = "usersock",
573 [NETLINK_FIREWALL
] = "fw",
574 [NETLINK_SOCK_DIAG
] = "tcpdiag",
575 [NETLINK_NFLOG
] = "nflog",
576 [NETLINK_XFRM
] = "xfrm",
577 [NETLINK_SELINUX
] = "selinux",
578 [NETLINK_ISCSI
] = "iscsi",
579 [NETLINK_AUDIT
] = "audit",
580 [NETLINK_FIB_LOOKUP
] = "fiblookup",
581 [NETLINK_CONNECTOR
] = "connector",
582 [NETLINK_NETFILTER
] = "nft",
583 [NETLINK_IP6_FW
] = "ip6fw",
584 [NETLINK_DNRTMSG
] = "dec-rt",
585 [NETLINK_KOBJECT_UEVENT
] = "uevent",
586 [NETLINK_GENERIC
] = "genl",
587 [NETLINK_SCSITRANSPORT
] = "scsi-trans",
588 [NETLINK_ECRYPTFS
] = "ecryptfs",
589 [NETLINK_RDMA
] = "rdma",
590 [NETLINK_CRYPTO
] = "crypto",
593 static int nl_proto_init
;
595 static void nl_proto_initialize(void)
598 rtnl_tab_initialize(CONFDIR
"/nl_protos",
602 const char *nl_proto_n2a(int id
, char *buf
, int len
)
604 if (id
< 0 || id
>= 256) {
605 snprintf(buf
, len
, "%u", id
);
610 nl_proto_initialize();
612 if (nl_proto_tab
[id
])
613 return nl_proto_tab
[id
];
615 snprintf(buf
, len
, "%u", id
);
619 int nl_proto_a2n(__u32
*id
, const char *arg
)
622 static unsigned long res
;
626 if (cache
&& strcmp(cache
, arg
) == 0) {
632 nl_proto_initialize();
634 for (i
= 0; i
< 256; i
++) {
635 if (nl_proto_tab
[i
] &&
636 strcmp(nl_proto_tab
[i
], arg
) == 0) {
637 cache
= nl_proto_tab
[i
];
644 res
= strtoul(arg
, &end
, 0);
645 if (!end
|| end
== arg
|| *end
|| res
> 255)