xref: /aosp_15_r20/external/iproute2/lib/rt_names.c (revision de1e4e894b0c224df933550f0afdecc354b238c4)
1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker  * rt_names.c		rtnetlink names DB.
3*de1e4e89SAndroid Build Coastguard Worker  *
4*de1e4e89SAndroid Build Coastguard Worker  *		This program is free software; you can redistribute it and/or
5*de1e4e89SAndroid Build Coastguard Worker  *		modify it under the terms of the GNU General Public License
6*de1e4e89SAndroid Build Coastguard Worker  *		as published by the Free Software Foundation; either version
7*de1e4e89SAndroid Build Coastguard Worker  *		2 of the License, or (at your option) any later version.
8*de1e4e89SAndroid Build Coastguard Worker  *
9*de1e4e89SAndroid Build Coastguard Worker  * Authors:	Alexey Kuznetsov, <[email protected]>
10*de1e4e89SAndroid Build Coastguard Worker  */
11*de1e4e89SAndroid Build Coastguard Worker 
12*de1e4e89SAndroid Build Coastguard Worker #include <stdio.h>
13*de1e4e89SAndroid Build Coastguard Worker #include <stdlib.h>
14*de1e4e89SAndroid Build Coastguard Worker #include <unistd.h>
15*de1e4e89SAndroid Build Coastguard Worker #include <syslog.h>
16*de1e4e89SAndroid Build Coastguard Worker #include <fcntl.h>
17*de1e4e89SAndroid Build Coastguard Worker #include <string.h>
18*de1e4e89SAndroid Build Coastguard Worker #include <sys/time.h>
19*de1e4e89SAndroid Build Coastguard Worker #include <sys/socket.h>
20*de1e4e89SAndroid Build Coastguard Worker #include <dirent.h>
21*de1e4e89SAndroid Build Coastguard Worker #include <limits.h>
22*de1e4e89SAndroid Build Coastguard Worker 
23*de1e4e89SAndroid Build Coastguard Worker #include <asm/types.h>
24*de1e4e89SAndroid Build Coastguard Worker #include <linux/rtnetlink.h>
25*de1e4e89SAndroid Build Coastguard Worker 
26*de1e4e89SAndroid Build Coastguard Worker #include "rt_names.h"
27*de1e4e89SAndroid Build Coastguard Worker #include "utils.h"
28*de1e4e89SAndroid Build Coastguard Worker 
29*de1e4e89SAndroid Build Coastguard Worker #define NAME_MAX_LEN 512
30*de1e4e89SAndroid Build Coastguard Worker 
31*de1e4e89SAndroid Build Coastguard Worker struct rtnl_hash_entry {
32*de1e4e89SAndroid Build Coastguard Worker 	struct rtnl_hash_entry	*next;
33*de1e4e89SAndroid Build Coastguard Worker 	const char		*name;
34*de1e4e89SAndroid Build Coastguard Worker 	unsigned int		id;
35*de1e4e89SAndroid Build Coastguard Worker };
36*de1e4e89SAndroid Build Coastguard Worker 
fread_id_name(FILE * fp,int * id,char * namebuf)37*de1e4e89SAndroid Build Coastguard Worker static int fread_id_name(FILE *fp, int *id, char *namebuf)
38*de1e4e89SAndroid Build Coastguard Worker {
39*de1e4e89SAndroid Build Coastguard Worker 	char buf[NAME_MAX_LEN];
40*de1e4e89SAndroid Build Coastguard Worker 
41*de1e4e89SAndroid Build Coastguard Worker 	while (fgets(buf, sizeof(buf), fp)) {
42*de1e4e89SAndroid Build Coastguard Worker 		char *p = buf;
43*de1e4e89SAndroid Build Coastguard Worker 
44*de1e4e89SAndroid Build Coastguard Worker 		while (*p == ' ' || *p == '\t')
45*de1e4e89SAndroid Build Coastguard Worker 			p++;
46*de1e4e89SAndroid Build Coastguard Worker 
47*de1e4e89SAndroid Build Coastguard Worker 		if (*p == '#' || *p == '\n' || *p == 0)
48*de1e4e89SAndroid Build Coastguard Worker 			continue;
49*de1e4e89SAndroid Build Coastguard Worker 
50*de1e4e89SAndroid Build Coastguard Worker 		if (sscanf(p, "0x%x %s\n", id, namebuf) != 2 &&
51*de1e4e89SAndroid Build Coastguard Worker 				sscanf(p, "0x%x %s #", id, namebuf) != 2 &&
52*de1e4e89SAndroid Build Coastguard Worker 				sscanf(p, "%d %s\n", id, namebuf) != 2 &&
53*de1e4e89SAndroid Build Coastguard Worker 				sscanf(p, "%d %s #", id, namebuf) != 2) {
54*de1e4e89SAndroid Build Coastguard Worker 			strcpy(namebuf, p);
55*de1e4e89SAndroid Build Coastguard Worker 			return -1;
56*de1e4e89SAndroid Build Coastguard Worker 		}
57*de1e4e89SAndroid Build Coastguard Worker 		return 1;
58*de1e4e89SAndroid Build Coastguard Worker 	}
59*de1e4e89SAndroid Build Coastguard Worker 	return 0;
60*de1e4e89SAndroid Build Coastguard Worker }
61*de1e4e89SAndroid Build Coastguard Worker 
62*de1e4e89SAndroid Build Coastguard Worker static void
rtnl_hash_initialize(const char * file,struct rtnl_hash_entry ** hash,int size)63*de1e4e89SAndroid Build Coastguard Worker rtnl_hash_initialize(const char *file, struct rtnl_hash_entry **hash, int size)
64*de1e4e89SAndroid Build Coastguard Worker {
65*de1e4e89SAndroid Build Coastguard Worker 	struct rtnl_hash_entry *entry;
66*de1e4e89SAndroid Build Coastguard Worker 	FILE *fp;
67*de1e4e89SAndroid Build Coastguard Worker 	int id;
68*de1e4e89SAndroid Build Coastguard Worker 	char namebuf[NAME_MAX_LEN] = {0};
69*de1e4e89SAndroid Build Coastguard Worker 	int ret;
70*de1e4e89SAndroid Build Coastguard Worker 
71*de1e4e89SAndroid Build Coastguard Worker 	fp = fopen(file, "r");
72*de1e4e89SAndroid Build Coastguard Worker 	if (!fp)
73*de1e4e89SAndroid Build Coastguard Worker 		return;
74*de1e4e89SAndroid Build Coastguard Worker 
75*de1e4e89SAndroid Build Coastguard Worker 	while ((ret = fread_id_name(fp, &id, &namebuf[0]))) {
76*de1e4e89SAndroid Build Coastguard Worker 		if (ret == -1) {
77*de1e4e89SAndroid Build Coastguard Worker 			fprintf(stderr, "Database %s is corrupted at %s\n",
78*de1e4e89SAndroid Build Coastguard Worker 					file, namebuf);
79*de1e4e89SAndroid Build Coastguard Worker 			fclose(fp);
80*de1e4e89SAndroid Build Coastguard Worker 			return;
81*de1e4e89SAndroid Build Coastguard Worker 		}
82*de1e4e89SAndroid Build Coastguard Worker 
83*de1e4e89SAndroid Build Coastguard Worker 		if (id < 0)
84*de1e4e89SAndroid Build Coastguard Worker 			continue;
85*de1e4e89SAndroid Build Coastguard Worker 
86*de1e4e89SAndroid Build Coastguard Worker 		entry = malloc(sizeof(*entry));
87*de1e4e89SAndroid Build Coastguard Worker 		entry->id   = id;
88*de1e4e89SAndroid Build Coastguard Worker 		entry->name = strdup(namebuf);
89*de1e4e89SAndroid Build Coastguard Worker 		entry->next = hash[id & (size - 1)];
90*de1e4e89SAndroid Build Coastguard Worker 		hash[id & (size - 1)] = entry;
91*de1e4e89SAndroid Build Coastguard Worker 	}
92*de1e4e89SAndroid Build Coastguard Worker 	fclose(fp);
93*de1e4e89SAndroid Build Coastguard Worker }
94*de1e4e89SAndroid Build Coastguard Worker 
rtnl_tab_initialize(const char * file,char ** tab,int size)95*de1e4e89SAndroid Build Coastguard Worker static void rtnl_tab_initialize(const char *file, char **tab, int size)
96*de1e4e89SAndroid Build Coastguard Worker {
97*de1e4e89SAndroid Build Coastguard Worker 	FILE *fp;
98*de1e4e89SAndroid Build Coastguard Worker 	int id;
99*de1e4e89SAndroid Build Coastguard Worker 	char namebuf[NAME_MAX_LEN] = {0};
100*de1e4e89SAndroid Build Coastguard Worker 	int ret;
101*de1e4e89SAndroid Build Coastguard Worker 
102*de1e4e89SAndroid Build Coastguard Worker 	fp = fopen(file, "r");
103*de1e4e89SAndroid Build Coastguard Worker 	if (!fp)
104*de1e4e89SAndroid Build Coastguard Worker 		return;
105*de1e4e89SAndroid Build Coastguard Worker 
106*de1e4e89SAndroid Build Coastguard Worker 	while ((ret = fread_id_name(fp, &id, &namebuf[0]))) {
107*de1e4e89SAndroid Build Coastguard Worker 		if (ret == -1) {
108*de1e4e89SAndroid Build Coastguard Worker 			fprintf(stderr, "Database %s is corrupted at %s\n",
109*de1e4e89SAndroid Build Coastguard Worker 					file, namebuf);
110*de1e4e89SAndroid Build Coastguard Worker 			fclose(fp);
111*de1e4e89SAndroid Build Coastguard Worker 			return;
112*de1e4e89SAndroid Build Coastguard Worker 		}
113*de1e4e89SAndroid Build Coastguard Worker 		if (id < 0 || id > size)
114*de1e4e89SAndroid Build Coastguard Worker 			continue;
115*de1e4e89SAndroid Build Coastguard Worker 
116*de1e4e89SAndroid Build Coastguard Worker 		tab[id] = strdup(namebuf);
117*de1e4e89SAndroid Build Coastguard Worker 	}
118*de1e4e89SAndroid Build Coastguard Worker 	fclose(fp);
119*de1e4e89SAndroid Build Coastguard Worker }
120*de1e4e89SAndroid Build Coastguard Worker 
121*de1e4e89SAndroid Build Coastguard Worker static char *rtnl_rtprot_tab[256] = {
122*de1e4e89SAndroid Build Coastguard Worker 	[RTPROT_UNSPEC]   = "unspec",
123*de1e4e89SAndroid Build Coastguard Worker 	[RTPROT_REDIRECT] = "redirect",
124*de1e4e89SAndroid Build Coastguard Worker 	[RTPROT_KERNEL]	  = "kernel",
125*de1e4e89SAndroid Build Coastguard Worker 	[RTPROT_BOOT]	  = "boot",
126*de1e4e89SAndroid Build Coastguard Worker 	[RTPROT_STATIC]	  = "static",
127*de1e4e89SAndroid Build Coastguard Worker 
128*de1e4e89SAndroid Build Coastguard Worker 	[RTPROT_GATED]	  = "gated",
129*de1e4e89SAndroid Build Coastguard Worker 	[RTPROT_RA]	  = "ra",
130*de1e4e89SAndroid Build Coastguard Worker 	[RTPROT_MRT]	  = "mrt",
131*de1e4e89SAndroid Build Coastguard Worker 	[RTPROT_ZEBRA]	  = "zebra",
132*de1e4e89SAndroid Build Coastguard Worker 	[RTPROT_BIRD]	  = "bird",
133*de1e4e89SAndroid Build Coastguard Worker 	[RTPROT_BABEL]	  = "babel",
134*de1e4e89SAndroid Build Coastguard Worker 	[RTPROT_DNROUTED] = "dnrouted",
135*de1e4e89SAndroid Build Coastguard Worker 	[RTPROT_XORP]	  = "xorp",
136*de1e4e89SAndroid Build Coastguard Worker 	[RTPROT_NTK]	  = "ntk",
137*de1e4e89SAndroid Build Coastguard Worker 	[RTPROT_DHCP]	  = "dhcp",
138*de1e4e89SAndroid Build Coastguard Worker };
139*de1e4e89SAndroid Build Coastguard Worker 
140*de1e4e89SAndroid Build Coastguard Worker 
141*de1e4e89SAndroid Build Coastguard Worker static int rtnl_rtprot_init;
142*de1e4e89SAndroid Build Coastguard Worker 
rtnl_rtprot_initialize(void)143*de1e4e89SAndroid Build Coastguard Worker static void rtnl_rtprot_initialize(void)
144*de1e4e89SAndroid Build Coastguard Worker {
145*de1e4e89SAndroid Build Coastguard Worker 	struct dirent *de;
146*de1e4e89SAndroid Build Coastguard Worker 	DIR *d;
147*de1e4e89SAndroid Build Coastguard Worker 
148*de1e4e89SAndroid Build Coastguard Worker 	rtnl_rtprot_init = 1;
149*de1e4e89SAndroid Build Coastguard Worker 	rtnl_tab_initialize(CONFDIR "/rt_protos",
150*de1e4e89SAndroid Build Coastguard Worker 			    rtnl_rtprot_tab, 256);
151*de1e4e89SAndroid Build Coastguard Worker 
152*de1e4e89SAndroid Build Coastguard Worker 	d = opendir(CONFDIR "/rt_protos.d");
153*de1e4e89SAndroid Build Coastguard Worker 	if (!d)
154*de1e4e89SAndroid Build Coastguard Worker 		return;
155*de1e4e89SAndroid Build Coastguard Worker 
156*de1e4e89SAndroid Build Coastguard Worker 	while ((de = readdir(d)) != NULL) {
157*de1e4e89SAndroid Build Coastguard Worker 		char path[PATH_MAX];
158*de1e4e89SAndroid Build Coastguard Worker 		size_t len;
159*de1e4e89SAndroid Build Coastguard Worker 
160*de1e4e89SAndroid Build Coastguard Worker 		if (*de->d_name == '.')
161*de1e4e89SAndroid Build Coastguard Worker 			continue;
162*de1e4e89SAndroid Build Coastguard Worker 
163*de1e4e89SAndroid Build Coastguard Worker 		/* only consider filenames ending in '.conf' */
164*de1e4e89SAndroid Build Coastguard Worker 		len = strlen(de->d_name);
165*de1e4e89SAndroid Build Coastguard Worker 		if (len <= 5)
166*de1e4e89SAndroid Build Coastguard Worker 			continue;
167*de1e4e89SAndroid Build Coastguard Worker 		if (strcmp(de->d_name + len - 5, ".conf"))
168*de1e4e89SAndroid Build Coastguard Worker 			continue;
169*de1e4e89SAndroid Build Coastguard Worker 
170*de1e4e89SAndroid Build Coastguard Worker 		snprintf(path, sizeof(path), CONFDIR "/rt_protos.d/%s",
171*de1e4e89SAndroid Build Coastguard Worker 			 de->d_name);
172*de1e4e89SAndroid Build Coastguard Worker 		rtnl_tab_initialize(path, rtnl_rtprot_tab, 256);
173*de1e4e89SAndroid Build Coastguard Worker 	}
174*de1e4e89SAndroid Build Coastguard Worker 	closedir(d);
175*de1e4e89SAndroid Build Coastguard Worker }
176*de1e4e89SAndroid Build Coastguard Worker 
rtnl_rtprot_n2a(int id,char * buf,int len)177*de1e4e89SAndroid Build Coastguard Worker const char *rtnl_rtprot_n2a(int id, char *buf, int len)
178*de1e4e89SAndroid Build Coastguard Worker {
179*de1e4e89SAndroid Build Coastguard Worker 	if (id < 0 || id >= 256) {
180*de1e4e89SAndroid Build Coastguard Worker 		snprintf(buf, len, "%u", id);
181*de1e4e89SAndroid Build Coastguard Worker 		return buf;
182*de1e4e89SAndroid Build Coastguard Worker 	}
183*de1e4e89SAndroid Build Coastguard Worker 	if (!rtnl_rtprot_tab[id]) {
184*de1e4e89SAndroid Build Coastguard Worker 		if (!rtnl_rtprot_init)
185*de1e4e89SAndroid Build Coastguard Worker 			rtnl_rtprot_initialize();
186*de1e4e89SAndroid Build Coastguard Worker 	}
187*de1e4e89SAndroid Build Coastguard Worker 	if (rtnl_rtprot_tab[id])
188*de1e4e89SAndroid Build Coastguard Worker 		return rtnl_rtprot_tab[id];
189*de1e4e89SAndroid Build Coastguard Worker 	snprintf(buf, len, "%u", id);
190*de1e4e89SAndroid Build Coastguard Worker 	return buf;
191*de1e4e89SAndroid Build Coastguard Worker }
192*de1e4e89SAndroid Build Coastguard Worker 
rtnl_rtprot_a2n(__u32 * id,const char * arg)193*de1e4e89SAndroid Build Coastguard Worker int rtnl_rtprot_a2n(__u32 *id, const char *arg)
194*de1e4e89SAndroid Build Coastguard Worker {
195*de1e4e89SAndroid Build Coastguard Worker 	static char *cache;
196*de1e4e89SAndroid Build Coastguard Worker 	static unsigned long res;
197*de1e4e89SAndroid Build Coastguard Worker 	char *end;
198*de1e4e89SAndroid Build Coastguard Worker 	int i;
199*de1e4e89SAndroid Build Coastguard Worker 
200*de1e4e89SAndroid Build Coastguard Worker 	if (cache && strcmp(cache, arg) == 0) {
201*de1e4e89SAndroid Build Coastguard Worker 		*id = res;
202*de1e4e89SAndroid Build Coastguard Worker 		return 0;
203*de1e4e89SAndroid Build Coastguard Worker 	}
204*de1e4e89SAndroid Build Coastguard Worker 
205*de1e4e89SAndroid Build Coastguard Worker 	if (!rtnl_rtprot_init)
206*de1e4e89SAndroid Build Coastguard Worker 		rtnl_rtprot_initialize();
207*de1e4e89SAndroid Build Coastguard Worker 
208*de1e4e89SAndroid Build Coastguard Worker 	for (i = 0; i < 256; i++) {
209*de1e4e89SAndroid Build Coastguard Worker 		if (rtnl_rtprot_tab[i] &&
210*de1e4e89SAndroid Build Coastguard Worker 		    strcmp(rtnl_rtprot_tab[i], arg) == 0) {
211*de1e4e89SAndroid Build Coastguard Worker 			cache = rtnl_rtprot_tab[i];
212*de1e4e89SAndroid Build Coastguard Worker 			res = i;
213*de1e4e89SAndroid Build Coastguard Worker 			*id = res;
214*de1e4e89SAndroid Build Coastguard Worker 			return 0;
215*de1e4e89SAndroid Build Coastguard Worker 		}
216*de1e4e89SAndroid Build Coastguard Worker 	}
217*de1e4e89SAndroid Build Coastguard Worker 
218*de1e4e89SAndroid Build Coastguard Worker 	res = strtoul(arg, &end, 0);
219*de1e4e89SAndroid Build Coastguard Worker 	if (!end || end == arg || *end || res > 255)
220*de1e4e89SAndroid Build Coastguard Worker 		return -1;
221*de1e4e89SAndroid Build Coastguard Worker 	*id = res;
222*de1e4e89SAndroid Build Coastguard Worker 	return 0;
223*de1e4e89SAndroid Build Coastguard Worker }
224*de1e4e89SAndroid Build Coastguard Worker 
225*de1e4e89SAndroid Build Coastguard Worker 
226*de1e4e89SAndroid Build Coastguard Worker static char *rtnl_rtscope_tab[256] = {
227*de1e4e89SAndroid Build Coastguard Worker 	[RT_SCOPE_UNIVERSE]	= "global",
228*de1e4e89SAndroid Build Coastguard Worker 	[RT_SCOPE_NOWHERE]	= "nowhere",
229*de1e4e89SAndroid Build Coastguard Worker 	[RT_SCOPE_HOST]		= "host",
230*de1e4e89SAndroid Build Coastguard Worker 	[RT_SCOPE_LINK]		= "link",
231*de1e4e89SAndroid Build Coastguard Worker 	[RT_SCOPE_SITE]		= "site",
232*de1e4e89SAndroid Build Coastguard Worker };
233*de1e4e89SAndroid Build Coastguard Worker 
234*de1e4e89SAndroid Build Coastguard Worker static int rtnl_rtscope_init;
235*de1e4e89SAndroid Build Coastguard Worker 
rtnl_rtscope_initialize(void)236*de1e4e89SAndroid Build Coastguard Worker static void rtnl_rtscope_initialize(void)
237*de1e4e89SAndroid Build Coastguard Worker {
238*de1e4e89SAndroid Build Coastguard Worker 	rtnl_rtscope_init = 1;
239*de1e4e89SAndroid Build Coastguard Worker 	rtnl_tab_initialize(CONFDIR "/rt_scopes",
240*de1e4e89SAndroid Build Coastguard Worker 			    rtnl_rtscope_tab, 256);
241*de1e4e89SAndroid Build Coastguard Worker }
242*de1e4e89SAndroid Build Coastguard Worker 
rtnl_rtscope_n2a(int id,char * buf,int len)243*de1e4e89SAndroid Build Coastguard Worker const char *rtnl_rtscope_n2a(int id, char *buf, int len)
244*de1e4e89SAndroid Build Coastguard Worker {
245*de1e4e89SAndroid Build Coastguard Worker 	if (id < 0 || id >= 256) {
246*de1e4e89SAndroid Build Coastguard Worker 		snprintf(buf, len, "%d", id);
247*de1e4e89SAndroid Build Coastguard Worker 		return buf;
248*de1e4e89SAndroid Build Coastguard Worker 	}
249*de1e4e89SAndroid Build Coastguard Worker 
250*de1e4e89SAndroid Build Coastguard Worker 	if (!rtnl_rtscope_tab[id]) {
251*de1e4e89SAndroid Build Coastguard Worker 		if (!rtnl_rtscope_init)
252*de1e4e89SAndroid Build Coastguard Worker 			rtnl_rtscope_initialize();
253*de1e4e89SAndroid Build Coastguard Worker 	}
254*de1e4e89SAndroid Build Coastguard Worker 
255*de1e4e89SAndroid Build Coastguard Worker 	if (rtnl_rtscope_tab[id])
256*de1e4e89SAndroid Build Coastguard Worker 		return rtnl_rtscope_tab[id];
257*de1e4e89SAndroid Build Coastguard Worker 
258*de1e4e89SAndroid Build Coastguard Worker 	snprintf(buf, len, "%d", id);
259*de1e4e89SAndroid Build Coastguard Worker 	return buf;
260*de1e4e89SAndroid Build Coastguard Worker }
261*de1e4e89SAndroid Build Coastguard Worker 
rtnl_rtscope_a2n(__u32 * id,const char * arg)262*de1e4e89SAndroid Build Coastguard Worker int rtnl_rtscope_a2n(__u32 *id, const char *arg)
263*de1e4e89SAndroid Build Coastguard Worker {
264*de1e4e89SAndroid Build Coastguard Worker 	static const char *cache;
265*de1e4e89SAndroid Build Coastguard Worker 	static unsigned long res;
266*de1e4e89SAndroid Build Coastguard Worker 	char *end;
267*de1e4e89SAndroid Build Coastguard Worker 	int i;
268*de1e4e89SAndroid Build Coastguard Worker 
269*de1e4e89SAndroid Build Coastguard Worker 	if (cache && strcmp(cache, arg) == 0) {
270*de1e4e89SAndroid Build Coastguard Worker 		*id = res;
271*de1e4e89SAndroid Build Coastguard Worker 		return 0;
272*de1e4e89SAndroid Build Coastguard Worker 	}
273*de1e4e89SAndroid Build Coastguard Worker 
274*de1e4e89SAndroid Build Coastguard Worker 	if (!rtnl_rtscope_init)
275*de1e4e89SAndroid Build Coastguard Worker 		rtnl_rtscope_initialize();
276*de1e4e89SAndroid Build Coastguard Worker 
277*de1e4e89SAndroid Build Coastguard Worker 	for (i = 0; i < 256; i++) {
278*de1e4e89SAndroid Build Coastguard Worker 		if (rtnl_rtscope_tab[i] &&
279*de1e4e89SAndroid Build Coastguard Worker 		    strcmp(rtnl_rtscope_tab[i], arg) == 0) {
280*de1e4e89SAndroid Build Coastguard Worker 			cache = rtnl_rtscope_tab[i];
281*de1e4e89SAndroid Build Coastguard Worker 			res = i;
282*de1e4e89SAndroid Build Coastguard Worker 			*id = res;
283*de1e4e89SAndroid Build Coastguard Worker 			return 0;
284*de1e4e89SAndroid Build Coastguard Worker 		}
285*de1e4e89SAndroid Build Coastguard Worker 	}
286*de1e4e89SAndroid Build Coastguard Worker 
287*de1e4e89SAndroid Build Coastguard Worker 	res = strtoul(arg, &end, 0);
288*de1e4e89SAndroid Build Coastguard Worker 	if (!end || end == arg || *end || res > 255)
289*de1e4e89SAndroid Build Coastguard Worker 		return -1;
290*de1e4e89SAndroid Build Coastguard Worker 	*id = res;
291*de1e4e89SAndroid Build Coastguard Worker 	return 0;
292*de1e4e89SAndroid Build Coastguard Worker }
293*de1e4e89SAndroid Build Coastguard Worker 
294*de1e4e89SAndroid Build Coastguard Worker 
295*de1e4e89SAndroid Build Coastguard Worker static char *rtnl_rtrealm_tab[256] = {
296*de1e4e89SAndroid Build Coastguard Worker 	"unknown",
297*de1e4e89SAndroid Build Coastguard Worker };
298*de1e4e89SAndroid Build Coastguard Worker 
299*de1e4e89SAndroid Build Coastguard Worker static int rtnl_rtrealm_init;
300*de1e4e89SAndroid Build Coastguard Worker 
rtnl_rtrealm_initialize(void)301*de1e4e89SAndroid Build Coastguard Worker static void rtnl_rtrealm_initialize(void)
302*de1e4e89SAndroid Build Coastguard Worker {
303*de1e4e89SAndroid Build Coastguard Worker 	rtnl_rtrealm_init = 1;
304*de1e4e89SAndroid Build Coastguard Worker 	rtnl_tab_initialize(CONFDIR "/rt_realms",
305*de1e4e89SAndroid Build Coastguard Worker 			    rtnl_rtrealm_tab, 256);
306*de1e4e89SAndroid Build Coastguard Worker }
307*de1e4e89SAndroid Build Coastguard Worker 
rtnl_rtrealm_n2a(int id,char * buf,int len)308*de1e4e89SAndroid Build Coastguard Worker const char *rtnl_rtrealm_n2a(int id, char *buf, int len)
309*de1e4e89SAndroid Build Coastguard Worker {
310*de1e4e89SAndroid Build Coastguard Worker 	if (id < 0 || id >= 256) {
311*de1e4e89SAndroid Build Coastguard Worker 		snprintf(buf, len, "%d", id);
312*de1e4e89SAndroid Build Coastguard Worker 		return buf;
313*de1e4e89SAndroid Build Coastguard Worker 	}
314*de1e4e89SAndroid Build Coastguard Worker 	if (!rtnl_rtrealm_tab[id]) {
315*de1e4e89SAndroid Build Coastguard Worker 		if (!rtnl_rtrealm_init)
316*de1e4e89SAndroid Build Coastguard Worker 			rtnl_rtrealm_initialize();
317*de1e4e89SAndroid Build Coastguard Worker 	}
318*de1e4e89SAndroid Build Coastguard Worker 	if (rtnl_rtrealm_tab[id])
319*de1e4e89SAndroid Build Coastguard Worker 		return rtnl_rtrealm_tab[id];
320*de1e4e89SAndroid Build Coastguard Worker 	snprintf(buf, len, "%d", id);
321*de1e4e89SAndroid Build Coastguard Worker 	return buf;
322*de1e4e89SAndroid Build Coastguard Worker }
323*de1e4e89SAndroid Build Coastguard Worker 
324*de1e4e89SAndroid Build Coastguard Worker 
rtnl_rtrealm_a2n(__u32 * id,const char * arg)325*de1e4e89SAndroid Build Coastguard Worker int rtnl_rtrealm_a2n(__u32 *id, const char *arg)
326*de1e4e89SAndroid Build Coastguard Worker {
327*de1e4e89SAndroid Build Coastguard Worker 	static char *cache;
328*de1e4e89SAndroid Build Coastguard Worker 	static unsigned long res;
329*de1e4e89SAndroid Build Coastguard Worker 	char *end;
330*de1e4e89SAndroid Build Coastguard Worker 	int i;
331*de1e4e89SAndroid Build Coastguard Worker 
332*de1e4e89SAndroid Build Coastguard Worker 	if (cache && strcmp(cache, arg) == 0) {
333*de1e4e89SAndroid Build Coastguard Worker 		*id = res;
334*de1e4e89SAndroid Build Coastguard Worker 		return 0;
335*de1e4e89SAndroid Build Coastguard Worker 	}
336*de1e4e89SAndroid Build Coastguard Worker 
337*de1e4e89SAndroid Build Coastguard Worker 	if (!rtnl_rtrealm_init)
338*de1e4e89SAndroid Build Coastguard Worker 		rtnl_rtrealm_initialize();
339*de1e4e89SAndroid Build Coastguard Worker 
340*de1e4e89SAndroid Build Coastguard Worker 	for (i = 0; i < 256; i++) {
341*de1e4e89SAndroid Build Coastguard Worker 		if (rtnl_rtrealm_tab[i] &&
342*de1e4e89SAndroid Build Coastguard Worker 		    strcmp(rtnl_rtrealm_tab[i], arg) == 0) {
343*de1e4e89SAndroid Build Coastguard Worker 			cache = rtnl_rtrealm_tab[i];
344*de1e4e89SAndroid Build Coastguard Worker 			res = i;
345*de1e4e89SAndroid Build Coastguard Worker 			*id = res;
346*de1e4e89SAndroid Build Coastguard Worker 			return 0;
347*de1e4e89SAndroid Build Coastguard Worker 		}
348*de1e4e89SAndroid Build Coastguard Worker 	}
349*de1e4e89SAndroid Build Coastguard Worker 
350*de1e4e89SAndroid Build Coastguard Worker 	res = strtoul(arg, &end, 0);
351*de1e4e89SAndroid Build Coastguard Worker 	if (!end || end == arg || *end || res > 255)
352*de1e4e89SAndroid Build Coastguard Worker 		return -1;
353*de1e4e89SAndroid Build Coastguard Worker 	*id = res;
354*de1e4e89SAndroid Build Coastguard Worker 	return 0;
355*de1e4e89SAndroid Build Coastguard Worker }
356*de1e4e89SAndroid Build Coastguard Worker 
357*de1e4e89SAndroid Build Coastguard Worker 
358*de1e4e89SAndroid Build Coastguard Worker static struct rtnl_hash_entry dflt_table_entry  = { .name = "default" };
359*de1e4e89SAndroid Build Coastguard Worker static struct rtnl_hash_entry main_table_entry  = { .name = "main" };
360*de1e4e89SAndroid Build Coastguard Worker static struct rtnl_hash_entry local_table_entry = { .name = "local" };
361*de1e4e89SAndroid Build Coastguard Worker 
362*de1e4e89SAndroid Build Coastguard Worker static struct rtnl_hash_entry *rtnl_rttable_hash[256] = {
363*de1e4e89SAndroid Build Coastguard Worker 	[RT_TABLE_DEFAULT] = &dflt_table_entry,
364*de1e4e89SAndroid Build Coastguard Worker 	[RT_TABLE_MAIN]    = &main_table_entry,
365*de1e4e89SAndroid Build Coastguard Worker 	[RT_TABLE_LOCAL]   = &local_table_entry,
366*de1e4e89SAndroid Build Coastguard Worker };
367*de1e4e89SAndroid Build Coastguard Worker 
368*de1e4e89SAndroid Build Coastguard Worker static int rtnl_rttable_init;
369*de1e4e89SAndroid Build Coastguard Worker 
rtnl_rttable_initialize(void)370*de1e4e89SAndroid Build Coastguard Worker static void rtnl_rttable_initialize(void)
371*de1e4e89SAndroid Build Coastguard Worker {
372*de1e4e89SAndroid Build Coastguard Worker 	struct dirent *de;
373*de1e4e89SAndroid Build Coastguard Worker 	DIR *d;
374*de1e4e89SAndroid Build Coastguard Worker 	int i;
375*de1e4e89SAndroid Build Coastguard Worker 
376*de1e4e89SAndroid Build Coastguard Worker 	rtnl_rttable_init = 1;
377*de1e4e89SAndroid Build Coastguard Worker 	for (i = 0; i < 256; i++) {
378*de1e4e89SAndroid Build Coastguard Worker 		if (rtnl_rttable_hash[i])
379*de1e4e89SAndroid Build Coastguard Worker 			rtnl_rttable_hash[i]->id = i;
380*de1e4e89SAndroid Build Coastguard Worker 	}
381*de1e4e89SAndroid Build Coastguard Worker 	rtnl_hash_initialize(CONFDIR "/rt_tables",
382*de1e4e89SAndroid Build Coastguard Worker 			     rtnl_rttable_hash, 256);
383*de1e4e89SAndroid Build Coastguard Worker 
384*de1e4e89SAndroid Build Coastguard Worker 	d = opendir(CONFDIR "/rt_tables.d");
385*de1e4e89SAndroid Build Coastguard Worker 	if (!d)
386*de1e4e89SAndroid Build Coastguard Worker 		return;
387*de1e4e89SAndroid Build Coastguard Worker 
388*de1e4e89SAndroid Build Coastguard Worker 	while ((de = readdir(d)) != NULL) {
389*de1e4e89SAndroid Build Coastguard Worker 		char path[PATH_MAX];
390*de1e4e89SAndroid Build Coastguard Worker 		size_t len;
391*de1e4e89SAndroid Build Coastguard Worker 
392*de1e4e89SAndroid Build Coastguard Worker 		if (*de->d_name == '.')
393*de1e4e89SAndroid Build Coastguard Worker 			continue;
394*de1e4e89SAndroid Build Coastguard Worker 
395*de1e4e89SAndroid Build Coastguard Worker 		/* only consider filenames ending in '.conf' */
396*de1e4e89SAndroid Build Coastguard Worker 		len = strlen(de->d_name);
397*de1e4e89SAndroid Build Coastguard Worker 		if (len <= 5)
398*de1e4e89SAndroid Build Coastguard Worker 			continue;
399*de1e4e89SAndroid Build Coastguard Worker 		if (strcmp(de->d_name + len - 5, ".conf"))
400*de1e4e89SAndroid Build Coastguard Worker 			continue;
401*de1e4e89SAndroid Build Coastguard Worker 
402*de1e4e89SAndroid Build Coastguard Worker 		snprintf(path, sizeof(path),
403*de1e4e89SAndroid Build Coastguard Worker 			 CONFDIR "/rt_tables.d/%s", de->d_name);
404*de1e4e89SAndroid Build Coastguard Worker 		rtnl_hash_initialize(path, rtnl_rttable_hash, 256);
405*de1e4e89SAndroid Build Coastguard Worker 	}
406*de1e4e89SAndroid Build Coastguard Worker 	closedir(d);
407*de1e4e89SAndroid Build Coastguard Worker }
408*de1e4e89SAndroid Build Coastguard Worker 
rtnl_rttable_n2a(__u32 id,char * buf,int len)409*de1e4e89SAndroid Build Coastguard Worker const char *rtnl_rttable_n2a(__u32 id, char *buf, int len)
410*de1e4e89SAndroid Build Coastguard Worker {
411*de1e4e89SAndroid Build Coastguard Worker 	struct rtnl_hash_entry *entry;
412*de1e4e89SAndroid Build Coastguard Worker 
413*de1e4e89SAndroid Build Coastguard Worker 	if (!rtnl_rttable_init)
414*de1e4e89SAndroid Build Coastguard Worker 		rtnl_rttable_initialize();
415*de1e4e89SAndroid Build Coastguard Worker 	entry = rtnl_rttable_hash[id & 255];
416*de1e4e89SAndroid Build Coastguard Worker 	while (entry && entry->id != id)
417*de1e4e89SAndroid Build Coastguard Worker 		entry = entry->next;
418*de1e4e89SAndroid Build Coastguard Worker 	if (entry)
419*de1e4e89SAndroid Build Coastguard Worker 		return entry->name;
420*de1e4e89SAndroid Build Coastguard Worker 	snprintf(buf, len, "%u", id);
421*de1e4e89SAndroid Build Coastguard Worker 	return buf;
422*de1e4e89SAndroid Build Coastguard Worker }
423*de1e4e89SAndroid Build Coastguard Worker 
rtnl_rttable_a2n(__u32 * id,const char * arg)424*de1e4e89SAndroid Build Coastguard Worker int rtnl_rttable_a2n(__u32 *id, const char *arg)
425*de1e4e89SAndroid Build Coastguard Worker {
426*de1e4e89SAndroid Build Coastguard Worker 	static const char *cache;
427*de1e4e89SAndroid Build Coastguard Worker 	static unsigned long res;
428*de1e4e89SAndroid Build Coastguard Worker 	struct rtnl_hash_entry *entry;
429*de1e4e89SAndroid Build Coastguard Worker 	char *end;
430*de1e4e89SAndroid Build Coastguard Worker 	unsigned long i;
431*de1e4e89SAndroid Build Coastguard Worker 
432*de1e4e89SAndroid Build Coastguard Worker 	if (cache && strcmp(cache, arg) == 0) {
433*de1e4e89SAndroid Build Coastguard Worker 		*id = res;
434*de1e4e89SAndroid Build Coastguard Worker 		return 0;
435*de1e4e89SAndroid Build Coastguard Worker 	}
436*de1e4e89SAndroid Build Coastguard Worker 
437*de1e4e89SAndroid Build Coastguard Worker 	if (!rtnl_rttable_init)
438*de1e4e89SAndroid Build Coastguard Worker 		rtnl_rttable_initialize();
439*de1e4e89SAndroid Build Coastguard Worker 
440*de1e4e89SAndroid Build Coastguard Worker 	for (i = 0; i < 256; i++) {
441*de1e4e89SAndroid Build Coastguard Worker 		entry = rtnl_rttable_hash[i];
442*de1e4e89SAndroid Build Coastguard Worker 		while (entry && strcmp(entry->name, arg))
443*de1e4e89SAndroid Build Coastguard Worker 			entry = entry->next;
444*de1e4e89SAndroid Build Coastguard Worker 		if (entry) {
445*de1e4e89SAndroid Build Coastguard Worker 			cache = entry->name;
446*de1e4e89SAndroid Build Coastguard Worker 			res = entry->id;
447*de1e4e89SAndroid Build Coastguard Worker 			*id = res;
448*de1e4e89SAndroid Build Coastguard Worker 			return 0;
449*de1e4e89SAndroid Build Coastguard Worker 		}
450*de1e4e89SAndroid Build Coastguard Worker 	}
451*de1e4e89SAndroid Build Coastguard Worker 
452*de1e4e89SAndroid Build Coastguard Worker 	i = strtoul(arg, &end, 0);
453*de1e4e89SAndroid Build Coastguard Worker 	if (!end || end == arg || *end || i > RT_TABLE_MAX)
454*de1e4e89SAndroid Build Coastguard Worker 		return -1;
455*de1e4e89SAndroid Build Coastguard Worker 	*id = i;
456*de1e4e89SAndroid Build Coastguard Worker 	return 0;
457*de1e4e89SAndroid Build Coastguard Worker }
458*de1e4e89SAndroid Build Coastguard Worker 
459*de1e4e89SAndroid Build Coastguard Worker 
460*de1e4e89SAndroid Build Coastguard Worker static char *rtnl_rtdsfield_tab[256] = {
461*de1e4e89SAndroid Build Coastguard Worker 	"0",
462*de1e4e89SAndroid Build Coastguard Worker };
463*de1e4e89SAndroid Build Coastguard Worker 
464*de1e4e89SAndroid Build Coastguard Worker static int rtnl_rtdsfield_init;
465*de1e4e89SAndroid Build Coastguard Worker 
rtnl_rtdsfield_initialize(void)466*de1e4e89SAndroid Build Coastguard Worker static void rtnl_rtdsfield_initialize(void)
467*de1e4e89SAndroid Build Coastguard Worker {
468*de1e4e89SAndroid Build Coastguard Worker 	rtnl_rtdsfield_init = 1;
469*de1e4e89SAndroid Build Coastguard Worker 	rtnl_tab_initialize(CONFDIR "/rt_dsfield",
470*de1e4e89SAndroid Build Coastguard Worker 			    rtnl_rtdsfield_tab, 256);
471*de1e4e89SAndroid Build Coastguard Worker }
472*de1e4e89SAndroid Build Coastguard Worker 
rtnl_dsfield_n2a(int id,char * buf,int len)473*de1e4e89SAndroid Build Coastguard Worker const char *rtnl_dsfield_n2a(int id, char *buf, int len)
474*de1e4e89SAndroid Build Coastguard Worker {
475*de1e4e89SAndroid Build Coastguard Worker 	if (id < 0 || id >= 256) {
476*de1e4e89SAndroid Build Coastguard Worker 		snprintf(buf, len, "%d", id);
477*de1e4e89SAndroid Build Coastguard Worker 		return buf;
478*de1e4e89SAndroid Build Coastguard Worker 	}
479*de1e4e89SAndroid Build Coastguard Worker 	if (!rtnl_rtdsfield_tab[id]) {
480*de1e4e89SAndroid Build Coastguard Worker 		if (!rtnl_rtdsfield_init)
481*de1e4e89SAndroid Build Coastguard Worker 			rtnl_rtdsfield_initialize();
482*de1e4e89SAndroid Build Coastguard Worker 	}
483*de1e4e89SAndroid Build Coastguard Worker 	if (rtnl_rtdsfield_tab[id])
484*de1e4e89SAndroid Build Coastguard Worker 		return rtnl_rtdsfield_tab[id];
485*de1e4e89SAndroid Build Coastguard Worker 	snprintf(buf, len, "0x%02x", id);
486*de1e4e89SAndroid Build Coastguard Worker 	return buf;
487*de1e4e89SAndroid Build Coastguard Worker }
488*de1e4e89SAndroid Build Coastguard Worker 
489*de1e4e89SAndroid Build Coastguard Worker 
rtnl_dsfield_a2n(__u32 * id,const char * arg)490*de1e4e89SAndroid Build Coastguard Worker int rtnl_dsfield_a2n(__u32 *id, const char *arg)
491*de1e4e89SAndroid Build Coastguard Worker {
492*de1e4e89SAndroid Build Coastguard Worker 	static char *cache;
493*de1e4e89SAndroid Build Coastguard Worker 	static unsigned long res;
494*de1e4e89SAndroid Build Coastguard Worker 	char *end;
495*de1e4e89SAndroid Build Coastguard Worker 	int i;
496*de1e4e89SAndroid Build Coastguard Worker 
497*de1e4e89SAndroid Build Coastguard Worker 	if (cache && strcmp(cache, arg) == 0) {
498*de1e4e89SAndroid Build Coastguard Worker 		*id = res;
499*de1e4e89SAndroid Build Coastguard Worker 		return 0;
500*de1e4e89SAndroid Build Coastguard Worker 	}
501*de1e4e89SAndroid Build Coastguard Worker 
502*de1e4e89SAndroid Build Coastguard Worker 	if (!rtnl_rtdsfield_init)
503*de1e4e89SAndroid Build Coastguard Worker 		rtnl_rtdsfield_initialize();
504*de1e4e89SAndroid Build Coastguard Worker 
505*de1e4e89SAndroid Build Coastguard Worker 	for (i = 0; i < 256; i++) {
506*de1e4e89SAndroid Build Coastguard Worker 		if (rtnl_rtdsfield_tab[i] &&
507*de1e4e89SAndroid Build Coastguard Worker 		    strcmp(rtnl_rtdsfield_tab[i], arg) == 0) {
508*de1e4e89SAndroid Build Coastguard Worker 			cache = rtnl_rtdsfield_tab[i];
509*de1e4e89SAndroid Build Coastguard Worker 			res = i;
510*de1e4e89SAndroid Build Coastguard Worker 			*id = res;
511*de1e4e89SAndroid Build Coastguard Worker 			return 0;
512*de1e4e89SAndroid Build Coastguard Worker 		}
513*de1e4e89SAndroid Build Coastguard Worker 	}
514*de1e4e89SAndroid Build Coastguard Worker 
515*de1e4e89SAndroid Build Coastguard Worker 	res = strtoul(arg, &end, 16);
516*de1e4e89SAndroid Build Coastguard Worker 	if (!end || end == arg || *end || res > 255)
517*de1e4e89SAndroid Build Coastguard Worker 		return -1;
518*de1e4e89SAndroid Build Coastguard Worker 	*id = res;
519*de1e4e89SAndroid Build Coastguard Worker 	return 0;
520*de1e4e89SAndroid Build Coastguard Worker }
521*de1e4e89SAndroid Build Coastguard Worker 
522*de1e4e89SAndroid Build Coastguard Worker 
523*de1e4e89SAndroid Build Coastguard Worker static struct rtnl_hash_entry dflt_group_entry = {
524*de1e4e89SAndroid Build Coastguard Worker 	.id = 0, .name = "default"
525*de1e4e89SAndroid Build Coastguard Worker };
526*de1e4e89SAndroid Build Coastguard Worker 
527*de1e4e89SAndroid Build Coastguard Worker static struct rtnl_hash_entry *rtnl_group_hash[256] = {
528*de1e4e89SAndroid Build Coastguard Worker 	[0] = &dflt_group_entry,
529*de1e4e89SAndroid Build Coastguard Worker };
530*de1e4e89SAndroid Build Coastguard Worker 
531*de1e4e89SAndroid Build Coastguard Worker static int rtnl_group_init;
532*de1e4e89SAndroid Build Coastguard Worker 
rtnl_group_initialize(void)533*de1e4e89SAndroid Build Coastguard Worker static void rtnl_group_initialize(void)
534*de1e4e89SAndroid Build Coastguard Worker {
535*de1e4e89SAndroid Build Coastguard Worker 	rtnl_group_init = 1;
536*de1e4e89SAndroid Build Coastguard Worker 	rtnl_hash_initialize(CONFDIR "/group",
537*de1e4e89SAndroid Build Coastguard Worker 			     rtnl_group_hash, 256);
538*de1e4e89SAndroid Build Coastguard Worker }
539*de1e4e89SAndroid Build Coastguard Worker 
rtnl_group_a2n(int * id,const char * arg)540*de1e4e89SAndroid Build Coastguard Worker int rtnl_group_a2n(int *id, const char *arg)
541*de1e4e89SAndroid Build Coastguard Worker {
542*de1e4e89SAndroid Build Coastguard Worker 	static const char *cache;
543*de1e4e89SAndroid Build Coastguard Worker 	static unsigned long res;
544*de1e4e89SAndroid Build Coastguard Worker 	struct rtnl_hash_entry *entry;
545*de1e4e89SAndroid Build Coastguard Worker 	char *end;
546*de1e4e89SAndroid Build Coastguard Worker 	int i;
547*de1e4e89SAndroid Build Coastguard Worker 
548*de1e4e89SAndroid Build Coastguard Worker 	if (cache && strcmp(cache, arg) == 0) {
549*de1e4e89SAndroid Build Coastguard Worker 		*id = res;
550*de1e4e89SAndroid Build Coastguard Worker 		return 0;
551*de1e4e89SAndroid Build Coastguard Worker 	}
552*de1e4e89SAndroid Build Coastguard Worker 
553*de1e4e89SAndroid Build Coastguard Worker 	if (!rtnl_group_init)
554*de1e4e89SAndroid Build Coastguard Worker 		rtnl_group_initialize();
555*de1e4e89SAndroid Build Coastguard Worker 
556*de1e4e89SAndroid Build Coastguard Worker 	for (i = 0; i < 256; i++) {
557*de1e4e89SAndroid Build Coastguard Worker 		entry = rtnl_group_hash[i];
558*de1e4e89SAndroid Build Coastguard Worker 		while (entry && strcmp(entry->name, arg))
559*de1e4e89SAndroid Build Coastguard Worker 			entry = entry->next;
560*de1e4e89SAndroid Build Coastguard Worker 		if (entry) {
561*de1e4e89SAndroid Build Coastguard Worker 			cache = entry->name;
562*de1e4e89SAndroid Build Coastguard Worker 			res = entry->id;
563*de1e4e89SAndroid Build Coastguard Worker 			*id = res;
564*de1e4e89SAndroid Build Coastguard Worker 			return 0;
565*de1e4e89SAndroid Build Coastguard Worker 		}
566*de1e4e89SAndroid Build Coastguard Worker 	}
567*de1e4e89SAndroid Build Coastguard Worker 
568*de1e4e89SAndroid Build Coastguard Worker 	i = strtol(arg, &end, 0);
569*de1e4e89SAndroid Build Coastguard Worker 	if (!end || end == arg || *end || i < 0)
570*de1e4e89SAndroid Build Coastguard Worker 		return -1;
571*de1e4e89SAndroid Build Coastguard Worker 	*id = i;
572*de1e4e89SAndroid Build Coastguard Worker 	return 0;
573*de1e4e89SAndroid Build Coastguard Worker }
574*de1e4e89SAndroid Build Coastguard Worker 
rtnl_group_n2a(int id,char * buf,int len)575*de1e4e89SAndroid Build Coastguard Worker const char *rtnl_group_n2a(int id, char *buf, int len)
576*de1e4e89SAndroid Build Coastguard Worker {
577*de1e4e89SAndroid Build Coastguard Worker 	struct rtnl_hash_entry *entry;
578*de1e4e89SAndroid Build Coastguard Worker 	int i;
579*de1e4e89SAndroid Build Coastguard Worker 
580*de1e4e89SAndroid Build Coastguard Worker 	if (!rtnl_group_init)
581*de1e4e89SAndroid Build Coastguard Worker 		rtnl_group_initialize();
582*de1e4e89SAndroid Build Coastguard Worker 
583*de1e4e89SAndroid Build Coastguard Worker 	for (i = 0; i < 256; i++) {
584*de1e4e89SAndroid Build Coastguard Worker 		entry = rtnl_group_hash[i];
585*de1e4e89SAndroid Build Coastguard Worker 
586*de1e4e89SAndroid Build Coastguard Worker 		while (entry) {
587*de1e4e89SAndroid Build Coastguard Worker 			if (entry->id == id)
588*de1e4e89SAndroid Build Coastguard Worker 				return entry->name;
589*de1e4e89SAndroid Build Coastguard Worker 			entry = entry->next;
590*de1e4e89SAndroid Build Coastguard Worker 		}
591*de1e4e89SAndroid Build Coastguard Worker 	}
592*de1e4e89SAndroid Build Coastguard Worker 
593*de1e4e89SAndroid Build Coastguard Worker 	snprintf(buf, len, "%d", id);
594*de1e4e89SAndroid Build Coastguard Worker 	return buf;
595*de1e4e89SAndroid Build Coastguard Worker }
596*de1e4e89SAndroid Build Coastguard Worker 
597*de1e4e89SAndroid Build Coastguard Worker static char *nl_proto_tab[256] = {
598*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_ROUTE]          = "rtnl",
599*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_UNUSED]         = "unused",
600*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_USERSOCK]       = "usersock",
601*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_FIREWALL]       = "fw",
602*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_SOCK_DIAG]      = "tcpdiag",
603*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_NFLOG]          = "nflog",
604*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_XFRM]           = "xfrm",
605*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_SELINUX]        = "selinux",
606*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_ISCSI]          = "iscsi",
607*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_AUDIT]          = "audit",
608*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_FIB_LOOKUP]     = "fiblookup",
609*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_CONNECTOR]      = "connector",
610*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_NETFILTER]      = "nft",
611*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_IP6_FW]         = "ip6fw",
612*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_DNRTMSG]        = "dec-rt",
613*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_KOBJECT_UEVENT] = "uevent",
614*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_GENERIC]        = "genl",
615*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_SCSITRANSPORT]  = "scsi-trans",
616*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_ECRYPTFS]       = "ecryptfs",
617*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_RDMA]           = "rdma",
618*de1e4e89SAndroid Build Coastguard Worker 	[NETLINK_CRYPTO]         = "crypto",
619*de1e4e89SAndroid Build Coastguard Worker };
620*de1e4e89SAndroid Build Coastguard Worker 
621*de1e4e89SAndroid Build Coastguard Worker static int nl_proto_init;
622*de1e4e89SAndroid Build Coastguard Worker 
nl_proto_initialize(void)623*de1e4e89SAndroid Build Coastguard Worker static void nl_proto_initialize(void)
624*de1e4e89SAndroid Build Coastguard Worker {
625*de1e4e89SAndroid Build Coastguard Worker 	nl_proto_init = 1;
626*de1e4e89SAndroid Build Coastguard Worker 	rtnl_tab_initialize(CONFDIR "/nl_protos",
627*de1e4e89SAndroid Build Coastguard Worker 			    nl_proto_tab, 256);
628*de1e4e89SAndroid Build Coastguard Worker }
629*de1e4e89SAndroid Build Coastguard Worker 
nl_proto_n2a(int id,char * buf,int len)630*de1e4e89SAndroid Build Coastguard Worker const char *nl_proto_n2a(int id, char *buf, int len)
631*de1e4e89SAndroid Build Coastguard Worker {
632*de1e4e89SAndroid Build Coastguard Worker 	if (id < 0 || id >= 256) {
633*de1e4e89SAndroid Build Coastguard Worker 		snprintf(buf, len, "%u", id);
634*de1e4e89SAndroid Build Coastguard Worker 		return buf;
635*de1e4e89SAndroid Build Coastguard Worker 	}
636*de1e4e89SAndroid Build Coastguard Worker 
637*de1e4e89SAndroid Build Coastguard Worker 	if (!nl_proto_init)
638*de1e4e89SAndroid Build Coastguard Worker 		nl_proto_initialize();
639*de1e4e89SAndroid Build Coastguard Worker 
640*de1e4e89SAndroid Build Coastguard Worker 	if (nl_proto_tab[id])
641*de1e4e89SAndroid Build Coastguard Worker 		return nl_proto_tab[id];
642*de1e4e89SAndroid Build Coastguard Worker 
643*de1e4e89SAndroid Build Coastguard Worker 	snprintf(buf, len, "%u", id);
644*de1e4e89SAndroid Build Coastguard Worker 	return buf;
645*de1e4e89SAndroid Build Coastguard Worker }
646*de1e4e89SAndroid Build Coastguard Worker 
nl_proto_a2n(__u32 * id,const char * arg)647*de1e4e89SAndroid Build Coastguard Worker int nl_proto_a2n(__u32 *id, const char *arg)
648*de1e4e89SAndroid Build Coastguard Worker {
649*de1e4e89SAndroid Build Coastguard Worker 	static char *cache;
650*de1e4e89SAndroid Build Coastguard Worker 	static unsigned long res;
651*de1e4e89SAndroid Build Coastguard Worker 	char *end;
652*de1e4e89SAndroid Build Coastguard Worker 	int i;
653*de1e4e89SAndroid Build Coastguard Worker 
654*de1e4e89SAndroid Build Coastguard Worker 	if (cache && strcmp(cache, arg) == 0) {
655*de1e4e89SAndroid Build Coastguard Worker 		*id = res;
656*de1e4e89SAndroid Build Coastguard Worker 		return 0;
657*de1e4e89SAndroid Build Coastguard Worker 	}
658*de1e4e89SAndroid Build Coastguard Worker 
659*de1e4e89SAndroid Build Coastguard Worker 	if (!nl_proto_init)
660*de1e4e89SAndroid Build Coastguard Worker 		nl_proto_initialize();
661*de1e4e89SAndroid Build Coastguard Worker 
662*de1e4e89SAndroid Build Coastguard Worker 	for (i = 0; i < 256; i++) {
663*de1e4e89SAndroid Build Coastguard Worker 		if (nl_proto_tab[i] &&
664*de1e4e89SAndroid Build Coastguard Worker 		    strcmp(nl_proto_tab[i], arg) == 0) {
665*de1e4e89SAndroid Build Coastguard Worker 			cache = nl_proto_tab[i];
666*de1e4e89SAndroid Build Coastguard Worker 			res = i;
667*de1e4e89SAndroid Build Coastguard Worker 			*id = res;
668*de1e4e89SAndroid Build Coastguard Worker 			return 0;
669*de1e4e89SAndroid Build Coastguard Worker 		}
670*de1e4e89SAndroid Build Coastguard Worker 	}
671*de1e4e89SAndroid Build Coastguard Worker 
672*de1e4e89SAndroid Build Coastguard Worker 	res = strtoul(arg, &end, 0);
673*de1e4e89SAndroid Build Coastguard Worker 	if (!end || end == arg || *end || res > 255)
674*de1e4e89SAndroid Build Coastguard Worker 		return -1;
675*de1e4e89SAndroid Build Coastguard Worker 	*id = res;
676*de1e4e89SAndroid Build Coastguard Worker 	return 0;
677*de1e4e89SAndroid Build Coastguard Worker }
678