rt_names.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * rt_names.c rtnetlink names DB.
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation; either version
  8. * 2 of the License, or (at your option) any later version.
  9. *
  10. * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
  11. */
  12. #include "libbb.h"
  13. #include "rt_names.h"
  14. static void rtnl_tab_initialize(const char *file, const char **tab, int size)
  15. {
  16. char buf[512];
  17. FILE *fp;
  18. fp = fopen(file, "r");
  19. if (!fp)
  20. return;
  21. while (fgets(buf, sizeof(buf), fp)) {
  22. char *p = buf;
  23. int id;
  24. char namebuf[512];
  25. while (*p == ' ' || *p == '\t')
  26. p++;
  27. if (*p == '#' || *p == '\n' || *p == 0)
  28. continue;
  29. if (sscanf(p, "0x%x %s\n", &id, namebuf) != 2
  30. && sscanf(p, "0x%x %s #", &id, namebuf) != 2
  31. && sscanf(p, "%d %s\n", &id, namebuf) != 2
  32. && sscanf(p, "%d %s #", &id, namebuf) != 2
  33. ) {
  34. bb_error_msg("database %s is corrupted at %s",
  35. file, p);
  36. return;
  37. }
  38. if (id < 0 || id > size)
  39. continue;
  40. tab[id] = xstrdup(namebuf);
  41. }
  42. fclose(fp);
  43. }
  44. static const char **rtnl_rtprot_tab; /* [256] */
  45. static void rtnl_rtprot_initialize(void)
  46. {
  47. static const char *const init_tab[] = {
  48. "none",
  49. "redirect",
  50. "kernel",
  51. "boot",
  52. "static",
  53. NULL,
  54. NULL,
  55. NULL,
  56. "gated",
  57. "ra",
  58. "mrt",
  59. "zebra",
  60. "bird",
  61. };
  62. if (rtnl_rtprot_tab) return;
  63. rtnl_rtprot_tab = xzalloc(256 * sizeof(rtnl_rtprot_tab[0]));
  64. memcpy(rtnl_rtprot_tab, init_tab, sizeof(init_tab));
  65. rtnl_tab_initialize("/etc/iproute2/rt_protos",
  66. rtnl_rtprot_tab, 256);
  67. }
  68. const char* rtnl_rtprot_n2a(int id, char *buf, int len)
  69. {
  70. if (id < 0 || id >= 256) {
  71. snprintf(buf, len, "%d", id);
  72. return buf;
  73. }
  74. rtnl_rtprot_initialize();
  75. if (rtnl_rtprot_tab[id])
  76. return rtnl_rtprot_tab[id];
  77. snprintf(buf, len, "%d", id);
  78. return buf;
  79. }
  80. int rtnl_rtprot_a2n(uint32_t *id, char *arg)
  81. {
  82. static const char *cache = NULL;
  83. static unsigned long res;
  84. int i;
  85. if (cache && strcmp(cache, arg) == 0) {
  86. *id = res;
  87. return 0;
  88. }
  89. rtnl_rtprot_initialize();
  90. for (i = 0; i < 256; i++) {
  91. if (rtnl_rtprot_tab[i] &&
  92. strcmp(rtnl_rtprot_tab[i], arg) == 0) {
  93. cache = rtnl_rtprot_tab[i];
  94. res = i;
  95. *id = res;
  96. return 0;
  97. }
  98. }
  99. res = bb_strtoul(arg, NULL, 0);
  100. if (errno || res > 255)
  101. return -1;
  102. *id = res;
  103. return 0;
  104. }
  105. static const char **rtnl_rtscope_tab; /* [256] */
  106. static void rtnl_rtscope_initialize(void)
  107. {
  108. if (rtnl_rtscope_tab) return;
  109. rtnl_rtscope_tab = xzalloc(256 * sizeof(rtnl_rtscope_tab[0]));
  110. rtnl_rtscope_tab[0] = "global";
  111. rtnl_rtscope_tab[255] = "nowhere";
  112. rtnl_rtscope_tab[254] = "host";
  113. rtnl_rtscope_tab[253] = "link";
  114. rtnl_rtscope_tab[200] = "site";
  115. rtnl_tab_initialize("/etc/iproute2/rt_scopes",
  116. rtnl_rtscope_tab, 256);
  117. }
  118. const char* rtnl_rtscope_n2a(int id, char *buf, int len)
  119. {
  120. if (id < 0 || id >= 256) {
  121. snprintf(buf, len, "%d", id);
  122. return buf;
  123. }
  124. rtnl_rtscope_initialize();
  125. if (rtnl_rtscope_tab[id])
  126. return rtnl_rtscope_tab[id];
  127. snprintf(buf, len, "%d", id);
  128. return buf;
  129. }
  130. int rtnl_rtscope_a2n(uint32_t *id, char *arg)
  131. {
  132. static const char *cache = NULL;
  133. static unsigned long res;
  134. int i;
  135. if (cache && strcmp(cache, arg) == 0) {
  136. *id = res;
  137. return 0;
  138. }
  139. rtnl_rtscope_initialize();
  140. for (i = 0; i < 256; i++) {
  141. if (rtnl_rtscope_tab[i] &&
  142. strcmp(rtnl_rtscope_tab[i], arg) == 0) {
  143. cache = rtnl_rtscope_tab[i];
  144. res = i;
  145. *id = res;
  146. return 0;
  147. }
  148. }
  149. res = bb_strtoul(arg, NULL, 0);
  150. if (errno || res > 255)
  151. return -1;
  152. *id = res;
  153. return 0;
  154. }
  155. static const char **rtnl_rtrealm_tab; /* [256] */
  156. static void rtnl_rtrealm_initialize(void)
  157. {
  158. if (rtnl_rtrealm_tab) return;
  159. rtnl_rtrealm_tab = xzalloc(256 * sizeof(rtnl_rtrealm_tab[0]));
  160. rtnl_rtrealm_tab[0] = "unknown";
  161. rtnl_tab_initialize("/etc/iproute2/rt_realms",
  162. rtnl_rtrealm_tab, 256);
  163. }
  164. int rtnl_rtrealm_a2n(uint32_t *id, char *arg)
  165. {
  166. static const char *cache = NULL;
  167. static unsigned long res;
  168. int i;
  169. if (cache && strcmp(cache, arg) == 0) {
  170. *id = res;
  171. return 0;
  172. }
  173. rtnl_rtrealm_initialize();
  174. for (i = 0; i < 256; i++) {
  175. if (rtnl_rtrealm_tab[i] &&
  176. strcmp(rtnl_rtrealm_tab[i], arg) == 0) {
  177. cache = rtnl_rtrealm_tab[i];
  178. res = i;
  179. *id = res;
  180. return 0;
  181. }
  182. }
  183. res = bb_strtoul(arg, NULL, 0);
  184. if (errno || res > 255)
  185. return -1;
  186. *id = res;
  187. return 0;
  188. }
  189. #if ENABLE_FEATURE_IP_RULE
  190. const char* rtnl_rtrealm_n2a(int id, char *buf, int len)
  191. {
  192. if (id < 0 || id >= 256) {
  193. snprintf(buf, len, "%d", id);
  194. return buf;
  195. }
  196. rtnl_rtrealm_initialize();
  197. if (rtnl_rtrealm_tab[id])
  198. return rtnl_rtrealm_tab[id];
  199. snprintf(buf, len, "%d", id);
  200. return buf;
  201. }
  202. #endif
  203. static const char **rtnl_rtdsfield_tab; /* [256] */
  204. static void rtnl_rtdsfield_initialize(void)
  205. {
  206. if (rtnl_rtdsfield_tab) return;
  207. rtnl_rtdsfield_tab = xzalloc(256 * sizeof(rtnl_rtdsfield_tab[0]));
  208. rtnl_rtdsfield_tab[0] = "0";
  209. rtnl_tab_initialize("/etc/iproute2/rt_dsfield",
  210. rtnl_rtdsfield_tab, 256);
  211. }
  212. const char * rtnl_dsfield_n2a(int id, char *buf, int len)
  213. {
  214. if (id < 0 || id >= 256) {
  215. snprintf(buf, len, "%d", id);
  216. return buf;
  217. }
  218. rtnl_rtdsfield_initialize();
  219. if (rtnl_rtdsfield_tab[id])
  220. return rtnl_rtdsfield_tab[id];
  221. snprintf(buf, len, "0x%02x", id);
  222. return buf;
  223. }
  224. int rtnl_dsfield_a2n(uint32_t *id, char *arg)
  225. {
  226. static const char *cache = NULL;
  227. static unsigned long res;
  228. int i;
  229. if (cache && strcmp(cache, arg) == 0) {
  230. *id = res;
  231. return 0;
  232. }
  233. rtnl_rtdsfield_initialize();
  234. for (i = 0; i < 256; i++) {
  235. if (rtnl_rtdsfield_tab[i] &&
  236. strcmp(rtnl_rtdsfield_tab[i], arg) == 0) {
  237. cache = rtnl_rtdsfield_tab[i];
  238. res = i;
  239. *id = res;
  240. return 0;
  241. }
  242. }
  243. res = bb_strtoul(arg, NULL, 16);
  244. if (errno || res > 255)
  245. return -1;
  246. *id = res;
  247. return 0;
  248. }
  249. #if ENABLE_FEATURE_IP_RULE
  250. static const char **rtnl_rttable_tab; /* [256] */
  251. static void rtnl_rttable_initialize(void)
  252. {
  253. if (rtnl_rtdsfield_tab) return;
  254. rtnl_rttable_tab = xzalloc(256 * sizeof(rtnl_rttable_tab[0]));
  255. rtnl_rttable_tab[0] = "unspec";
  256. rtnl_rttable_tab[255] = "local";
  257. rtnl_rttable_tab[254] = "main";
  258. rtnl_rttable_tab[253] = "default";
  259. rtnl_tab_initialize("/etc/iproute2/rt_tables", rtnl_rttable_tab, 256);
  260. }
  261. const char *rtnl_rttable_n2a(int id, char *buf, int len)
  262. {
  263. if (id < 0 || id >= 256) {
  264. snprintf(buf, len, "%d", id);
  265. return buf;
  266. }
  267. rtnl_rttable_initialize();
  268. if (rtnl_rttable_tab[id])
  269. return rtnl_rttable_tab[id];
  270. snprintf(buf, len, "%d", id);
  271. return buf;
  272. }
  273. int rtnl_rttable_a2n(uint32_t * id, char *arg)
  274. {
  275. static char *cache = NULL;
  276. static unsigned long res;
  277. int i;
  278. if (cache && strcmp(cache, arg) == 0) {
  279. *id = res;
  280. return 0;
  281. }
  282. rtnl_rttable_initialize();
  283. for (i = 0; i < 256; i++) {
  284. if (rtnl_rttable_tab[i] && strcmp(rtnl_rttable_tab[i], arg) == 0) {
  285. cache = (char*)rtnl_rttable_tab[i];
  286. res = i;
  287. *id = res;
  288. return 0;
  289. }
  290. }
  291. i = bb_strtoul(arg, NULL, 0);
  292. if (errno || i > 255)
  293. return -1;
  294. *id = i;
  295. return 0;
  296. }
  297. #endif