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 #define NAME_MAX_LEN 512
32 struct rtnl_hash_entry
{
33 struct rtnl_hash_entry
*next
;
38 static int fread_id_name(FILE *fp
, int *id
, char *namebuf
)
40 char buf
[NAME_MAX_LEN
];
42 while (fgets(buf
, sizeof(buf
), fp
)) {
45 while (*p
== ' ' || *p
== '\t')
48 if (*p
== '#' || *p
== '\n' || *p
== 0)
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) {
64 rtnl_hash_initialize(const char *file
, struct rtnl_hash_entry
**hash
, int size
)
66 struct rtnl_hash_entry
*entry
;
69 char namebuf
[NAME_MAX_LEN
] = {0};
72 fp
= fopen(file
, "r");
76 while ((ret
= fread_id_name(fp
, &id
, &namebuf
[0]))) {
78 fprintf(stderr
, "Database %s is corrupted at %s\n",
87 entry
= malloc(sizeof(*entry
));
89 entry
->name
= strdup(namebuf
);
90 entry
->next
= hash
[id
& (size
- 1)];
91 hash
[id
& (size
- 1)] = entry
;
96 static void rtnl_tab_initialize(const char *file
, char **tab
, int size
)
100 char namebuf
[NAME_MAX_LEN
] = {0};
103 fp
= fopen(file
, "r");
107 while ((ret
= fread_id_name(fp
, &id
, &namebuf
[0]))) {
109 fprintf(stderr
, "Database %s is corrupted at %s\n",
117 tab
[id
] = strdup(namebuf
);
122 static char * rtnl_rtprot_tab
[256] = {
123 [RTPROT_UNSPEC
] = "none",
124 [RTPROT_REDIRECT
] ="redirect",
125 [RTPROT_KERNEL
] = "kernel",
126 [RTPROT_BOOT
] = "boot",
127 [RTPROT_STATIC
] = "static",
129 [RTPROT_GATED
] = "gated",
131 [RTPROT_MRT
] = "mrt",
132 [RTPROT_ZEBRA
] ="zebra",
133 [RTPROT_BIRD
] = "bird",
134 [RTPROT_BABEL
] = "babel",
135 [RTPROT_DNROUTED
] = "dnrouted",
136 [RTPROT_XORP
] = "xorp",
137 [RTPROT_NTK
] = "ntk",
138 [RTPROT_DHCP
] = "dhcp",
142 static int rtnl_rtprot_init
;
144 static void rtnl_rtprot_initialize(void)
146 rtnl_rtprot_init
= 1;
147 rtnl_tab_initialize(CONFDIR
"/rt_protos",
148 rtnl_rtprot_tab
, 256);
151 const char * rtnl_rtprot_n2a(int id
, char *buf
, int len
)
153 if (id
<0 || id
>=256) {
154 snprintf(buf
, len
, "%u", id
);
157 if (!rtnl_rtprot_tab
[id
]) {
158 if (!rtnl_rtprot_init
)
159 rtnl_rtprot_initialize();
161 if (rtnl_rtprot_tab
[id
])
162 return rtnl_rtprot_tab
[id
];
163 snprintf(buf
, len
, "%u", id
);
167 int rtnl_rtprot_a2n(__u32
*id
, const char *arg
)
169 static char *cache
= NULL
;
170 static unsigned long res
;
174 if (cache
&& strcmp(cache
, arg
) == 0) {
179 if (!rtnl_rtprot_init
)
180 rtnl_rtprot_initialize();
182 for (i
=0; i
<256; i
++) {
183 if (rtnl_rtprot_tab
[i
] &&
184 strcmp(rtnl_rtprot_tab
[i
], arg
) == 0) {
185 cache
= rtnl_rtprot_tab
[i
];
192 res
= strtoul(arg
, &end
, 0);
193 if (!end
|| end
== arg
|| *end
|| res
> 255)
199 static char * rtnl_rtscope_tab
[256] = {
203 static int rtnl_rtscope_init
;
205 static void rtnl_rtscope_initialize(void)
207 rtnl_rtscope_init
= 1;
208 rtnl_rtscope_tab
[RT_SCOPE_NOWHERE
] = "nowhere";
209 rtnl_rtscope_tab
[RT_SCOPE_HOST
] = "host";
210 rtnl_rtscope_tab
[RT_SCOPE_LINK
] = "link";
211 rtnl_rtscope_tab
[RT_SCOPE_SITE
] = "site";
212 rtnl_tab_initialize(CONFDIR
"/rt_scopes",
213 rtnl_rtscope_tab
, 256);
216 const char *rtnl_rtscope_n2a(int id
, char *buf
, int len
)
218 if (id
<0 || id
>=256) {
219 snprintf(buf
, len
, "%d", id
);
222 if (!rtnl_rtscope_tab
[id
]) {
223 if (!rtnl_rtscope_init
)
224 rtnl_rtscope_initialize();
226 if (rtnl_rtscope_tab
[id
])
227 return rtnl_rtscope_tab
[id
];
228 snprintf(buf
, len
, "%d", id
);
232 int rtnl_rtscope_a2n(__u32
*id
, const char *arg
)
234 static const char *cache
= NULL
;
235 static unsigned long res
;
239 if (cache
&& strcmp(cache
, arg
) == 0) {
244 if (!rtnl_rtscope_init
)
245 rtnl_rtscope_initialize();
247 for (i
=0; i
<256; i
++) {
248 if (rtnl_rtscope_tab
[i
] &&
249 strcmp(rtnl_rtscope_tab
[i
], arg
) == 0) {
250 cache
= rtnl_rtscope_tab
[i
];
257 res
= strtoul(arg
, &end
, 0);
258 if (!end
|| end
== arg
|| *end
|| res
> 255)
265 static char * rtnl_rtrealm_tab
[256] = {
269 static int rtnl_rtrealm_init
;
271 static void rtnl_rtrealm_initialize(void)
273 rtnl_rtrealm_init
= 1;
274 rtnl_tab_initialize(CONFDIR
"/rt_realms",
275 rtnl_rtrealm_tab
, 256);
278 const char *rtnl_rtrealm_n2a(int id
, char *buf
, int len
)
280 if (id
<0 || id
>=256) {
281 snprintf(buf
, len
, "%d", id
);
284 if (!rtnl_rtrealm_tab
[id
]) {
285 if (!rtnl_rtrealm_init
)
286 rtnl_rtrealm_initialize();
288 if (rtnl_rtrealm_tab
[id
])
289 return rtnl_rtrealm_tab
[id
];
290 snprintf(buf
, len
, "%d", id
);
295 int rtnl_rtrealm_a2n(__u32
*id
, const char *arg
)
297 static char *cache
= NULL
;
298 static unsigned long res
;
302 if (cache
&& strcmp(cache
, arg
) == 0) {
307 if (!rtnl_rtrealm_init
)
308 rtnl_rtrealm_initialize();
310 for (i
=0; i
<256; i
++) {
311 if (rtnl_rtrealm_tab
[i
] &&
312 strcmp(rtnl_rtrealm_tab
[i
], arg
) == 0) {
313 cache
= rtnl_rtrealm_tab
[i
];
320 res
= strtoul(arg
, &end
, 0);
321 if (!end
|| end
== arg
|| *end
|| res
> 255)
328 static struct rtnl_hash_entry dflt_table_entry
= { .name
= "default" };
329 static struct rtnl_hash_entry main_table_entry
= { .name
= "main" };
330 static struct rtnl_hash_entry local_table_entry
= { .name
= "local" };
332 static struct rtnl_hash_entry
* rtnl_rttable_hash
[256] = {
333 [RT_TABLE_DEFAULT
] = &dflt_table_entry
,
334 [RT_TABLE_MAIN
] = &main_table_entry
,
335 [RT_TABLE_LOCAL
] = &local_table_entry
,
338 static int rtnl_rttable_init
;
340 static void rtnl_rttable_initialize(void)
344 rtnl_rttable_init
= 1;
345 for (i
= 0; i
< 256; i
++) {
346 if (rtnl_rttable_hash
[i
])
347 rtnl_rttable_hash
[i
]->id
= i
;
349 rtnl_hash_initialize(CONFDIR
"/rt_tables",
350 rtnl_rttable_hash
, 256);
353 const char * rtnl_rttable_n2a(__u32 id
, char *buf
, int len
)
355 struct rtnl_hash_entry
*entry
;
357 if (id
> RT_TABLE_MAX
) {
358 snprintf(buf
, len
, "%u", id
);
361 if (!rtnl_rttable_init
)
362 rtnl_rttable_initialize();
363 entry
= rtnl_rttable_hash
[id
& 255];
364 while (entry
&& entry
->id
!= id
)
368 snprintf(buf
, len
, "%u", id
);
372 int rtnl_rttable_a2n(__u32
*id
, const char *arg
)
374 static const char *cache
= NULL
;
375 static unsigned long res
;
376 struct rtnl_hash_entry
*entry
;
380 if (cache
&& strcmp(cache
, arg
) == 0) {
385 if (!rtnl_rttable_init
)
386 rtnl_rttable_initialize();
388 for (i
=0; i
<256; i
++) {
389 entry
= rtnl_rttable_hash
[i
];
390 while (entry
&& strcmp(entry
->name
, arg
))
400 i
= strtoul(arg
, &end
, 0);
401 if (!end
|| end
== arg
|| *end
|| i
> RT_TABLE_MAX
)
408 static char * rtnl_rtdsfield_tab
[256] = {
412 static int rtnl_rtdsfield_init
;
414 static void rtnl_rtdsfield_initialize(void)
416 rtnl_rtdsfield_init
= 1;
417 rtnl_tab_initialize(CONFDIR
"/rt_dsfield",
418 rtnl_rtdsfield_tab
, 256);
421 const char *rtnl_dsfield_n2a(int id
, char *buf
, int len
)
423 if (id
<0 || id
>=256) {
424 snprintf(buf
, len
, "%d", id
);
427 if (!rtnl_rtdsfield_tab
[id
]) {
428 if (!rtnl_rtdsfield_init
)
429 rtnl_rtdsfield_initialize();
431 if (rtnl_rtdsfield_tab
[id
])
432 return rtnl_rtdsfield_tab
[id
];
433 snprintf(buf
, len
, "0x%02x", id
);
438 int rtnl_dsfield_a2n(__u32
*id
, const char *arg
)
440 static char *cache
= NULL
;
441 static unsigned long res
;
445 if (cache
&& strcmp(cache
, arg
) == 0) {
450 if (!rtnl_rtdsfield_init
)
451 rtnl_rtdsfield_initialize();
453 for (i
=0; i
<256; i
++) {
454 if (rtnl_rtdsfield_tab
[i
] &&
455 strcmp(rtnl_rtdsfield_tab
[i
], arg
) == 0) {
456 cache
= rtnl_rtdsfield_tab
[i
];
463 res
= strtoul(arg
, &end
, 16);
464 if (!end
|| end
== arg
|| *end
|| res
> 255)
471 static struct rtnl_hash_entry dflt_group_entry
= { .id
= 0, .name
= "default" };
473 static struct rtnl_hash_entry
* rtnl_group_hash
[256] = {
474 [0] = &dflt_group_entry
,
477 static int rtnl_group_init
;
479 static void rtnl_group_initialize(void)
482 rtnl_hash_initialize(CONFDIR
"/group",
483 rtnl_group_hash
, 256);
486 int rtnl_group_a2n(int *id
, const char *arg
)
488 static const char *cache
= NULL
;
489 static unsigned long res
;
490 struct rtnl_hash_entry
*entry
;
494 if (cache
&& strcmp(cache
, arg
) == 0) {
499 if (!rtnl_group_init
)
500 rtnl_group_initialize();
502 for (i
=0; i
<256; i
++) {
503 entry
= rtnl_group_hash
[i
];
504 while (entry
&& strcmp(entry
->name
, arg
))
514 i
= strtol(arg
, &end
, 0);
515 if (!end
|| end
== arg
|| *end
|| i
< 0)
521 const char *rtnl_group_n2a(int id
, char *buf
, int len
)
523 struct rtnl_hash_entry
*entry
;
526 if (!rtnl_group_init
)
527 rtnl_group_initialize();
529 for (i
=0; i
<256; i
++) {
530 entry
= rtnl_group_hash
[i
];
531 if (entry
&& entry
->id
== id
) {
536 snprintf(buf
, len
, "%d", id
);
540 static char *nl_proto_tab
[256] = {
541 [NETLINK_ROUTE
] = "rtnl",
542 [NETLINK_UNUSED
] = "unused",
543 [NETLINK_USERSOCK
] = "usersock",
544 [NETLINK_FIREWALL
] = "fw",
545 [NETLINK_SOCK_DIAG
] = "tcpdiag",
546 [NETLINK_NFLOG
] = "nflog",
547 [NETLINK_XFRM
] = "xfrm",
548 [NETLINK_SELINUX
] = "selinux",
549 [NETLINK_ISCSI
] = "iscsi",
550 [NETLINK_AUDIT
] = "audit",
551 [NETLINK_FIB_LOOKUP
] = "fiblookup",
552 [NETLINK_CONNECTOR
] = "connector",
553 [NETLINK_NETFILTER
] = "nft",
554 [NETLINK_IP6_FW
] = "ip6fw",
555 [NETLINK_DNRTMSG
] = "dec-rt",
556 [NETLINK_KOBJECT_UEVENT
] = "uevent",
557 [NETLINK_GENERIC
] = "genl",
558 [NETLINK_SCSITRANSPORT
] = "scsi-trans",
559 [NETLINK_ECRYPTFS
] = "ecryptfs",
560 [NETLINK_RDMA
] = "rdma",
561 [NETLINK_CRYPTO
] = "crypto",
564 static int nl_proto_init
;
566 static void nl_proto_initialize(void)
569 rtnl_tab_initialize(CONFDIR
"/nl_protos",
573 const char *nl_proto_n2a(int id
, char *buf
, int len
)
575 if (id
< 0 || id
>= 256) {
576 snprintf(buf
, len
, "%u", id
);
581 nl_proto_initialize();
583 if (nl_proto_tab
[id
])
584 return nl_proto_tab
[id
];
586 snprintf(buf
, len
, "%u", id
);
590 int nl_proto_a2n(__u32
*id
, const char *arg
)
592 static char *cache
= NULL
;
593 static unsigned long res
;
597 if (cache
&& strcmp(cache
, arg
) == 0) {
603 nl_proto_initialize();
605 for (i
= 0; i
< 256; i
++) {
606 if (nl_proto_tab
[i
] &&
607 strcmp(nl_proto_tab
[i
], arg
) == 0) {
608 cache
= nl_proto_tab
[i
];
615 res
= strtoul(arg
, &end
, 0);
616 if (!end
|| end
== arg
|| *end
|| res
> 255)