1 /* vi: set sw=4 ts=4: */
2 /*
3  * This program is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU General Public License
5  * as published by the Free Software Foundation; either version
6  * 2 of the License, or (at your option) any later version.
7  *
8  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
9  */
10 #include "libbb.h"
11 #include "rt_names.h"
12 #include "utils.h"
13 
14 static const char keywords[] ALIGN1 =
15 	"local\0""nat\0""broadcast\0""brd\0""anycast\0"
16 	"multicast\0""prohibit\0""unreachable\0""blackhole\0"
17 	"xresolve\0""unicast\0""throw\0";
18 enum {
19 	ARG_local = 1, ARG_nat, ARG_broadcast, ARG_brd, ARG_anycast,
20 	ARG_multicast, ARG_prohibit, ARG_unreachable, ARG_blackhole,
21 	ARG_xresolve, ARG_unicast, ARG_throw
22 };
23 #define str_local       keywords
24 #define str_nat         (str_local       + sizeof("local"))
25 #define str_broadcast   (str_nat         + sizeof("nat"))
26 #define str_brd         (str_broadcast   + sizeof("broadcast"))
27 #define str_anycast     (str_brd         + sizeof("brd"))
28 #define str_multicast   (str_anycast     + sizeof("anycast"))
29 #define str_prohibit    (str_multicast   + sizeof("multicast"))
30 #define str_unreachable (str_prohibit    + sizeof("prohibit"))
31 #define str_blackhole   (str_unreachable + sizeof("unreachable"))
32 #define str_xresolve    (str_blackhole   + sizeof("blackhole"))
33 #define str_unicast     (str_xresolve    + sizeof("xresolve"))
34 #define str_throw       (str_unicast     + sizeof("unicast"))
35 
rtnl_rtntype_n2a(int id)36 const char* FAST_FUNC rtnl_rtntype_n2a(int id)
37 {
38 	switch (id) {
39 	case RTN_UNSPEC:
40 		return "none";
41 	case RTN_UNICAST:
42 		return str_unicast;
43 	case RTN_LOCAL:
44 		return str_local;
45 	case RTN_BROADCAST:
46 		return str_broadcast;
47 	case RTN_ANYCAST:
48 		return str_anycast;
49 	case RTN_MULTICAST:
50 		return str_multicast;
51 	case RTN_BLACKHOLE:
52 		return str_blackhole;
53 	case RTN_UNREACHABLE:
54 		return str_unreachable;
55 	case RTN_PROHIBIT:
56 		return str_prohibit;
57 	case RTN_THROW:
58 		return str_throw;
59 	case RTN_NAT:
60 		return str_nat;
61 	case RTN_XRESOLVE:
62 		return str_xresolve;
63 	default:
64 		return itoa(id);
65 	}
66 }
67 
rtnl_rtntype_a2n(int * id,char * arg)68 int FAST_FUNC rtnl_rtntype_a2n(int *id, char *arg)
69 {
70 	const smalluint key = index_in_substrings(keywords, arg) + 1;
71 	char *end;
72 	unsigned long res;
73 
74 	if (key == ARG_local)
75 		res = RTN_LOCAL;
76 	else if (key == ARG_nat)
77 		res = RTN_NAT;
78 	else if (key == ARG_broadcast || key == ARG_brd)
79 		res = RTN_BROADCAST;
80 	else if (key == ARG_anycast)
81 		res = RTN_ANYCAST;
82 	else if (key == ARG_multicast)
83 		res = RTN_MULTICAST;
84 	else if (key == ARG_prohibit)
85 		res = RTN_PROHIBIT;
86 	else if (key == ARG_unreachable)
87 		res = RTN_UNREACHABLE;
88 	else if (key == ARG_blackhole)
89 		res = RTN_BLACKHOLE;
90 	else if (key == ARG_xresolve)
91 		res = RTN_XRESOLVE;
92 	else if (key == ARG_unicast)
93 		res = RTN_UNICAST;
94 	else if (key == ARG_throw)
95 		res = RTN_THROW;
96 	else {
97 		res = strtoul(arg, &end, 0);
98 		if (end == arg || *end || res > 255)
99 			return -1;
100 	}
101 	*id = res;
102 	return 0;
103 }
104 
get_rt_realms(uint32_t * realms,char * arg)105 int FAST_FUNC get_rt_realms(uint32_t *realms, char *arg)
106 {
107 	uint32_t realm = 0;
108 	char *p = strchr(arg, '/');
109 
110 	*realms = 0;
111 	if (p) {
112 		*p = 0;
113 		if (rtnl_rtrealm_a2n(realms, arg)) {
114 			*p = '/';
115 			return -1;
116 		}
117 		*realms <<= 16;
118 		*p = '/';
119 		arg = p+1;
120 	}
121 	if (*arg && rtnl_rtrealm_a2n(&realm, arg))
122 		return -1;
123 	*realms |= realm;
124 	return 0;
125 }
126