1/* 2 * rt_names.c rtnetlink names DB. 3 * 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. 8 * 9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 10 */ 11 12#include <stdio.h> 13#include <stdlib.h> 14#include <unistd.h> 15#include <syslog.h> 16#include <fcntl.h> 17#include <string.h> 18#include <sys/time.h> 19#include <sys/socket.h> 20 21#include <asm/types.h> 22#include <linux/rtnetlink.h> 23 24#include "rt_names.h" 25 26static void rtnl_tab_initialize(char *file, char **tab, int size) 27{ 28 char buf[512]; 29 FILE *fp; 30 31 fp = fopen(file, "r"); 32 if (!fp) 33 return; 34 while (fgets(buf, sizeof(buf), fp)) { 35 char *p = buf; 36 int id; 37 char namebuf[512]; 38 39 while (*p == ' ' || *p == '\t') 40 p++; 41 if (*p == '#' || *p == '\n' || *p == 0) 42 continue; 43 if (sscanf(p, "0x%x %s\n", &id, namebuf) != 2 && 44 sscanf(p, "0x%x %s #", &id, namebuf) != 2 && 45 sscanf(p, "%d %s\n", &id, namebuf) != 2 && 46 sscanf(p, "%d %s #", &id, namebuf) != 2) { 47 fprintf(stderr, "Database %s is corrupted at %s\n", 48 file, p); 49 return; 50 } 51 52 if (id<0 || id>size) 53 continue; 54 55 tab[id] = strdup(namebuf); 56 } 57 fclose(fp); 58} 59 60 61static char * rtnl_rtprot_tab[256] = { 62 [RTPROT_UNSPEC] = "none", 63 [RTPROT_REDIRECT] ="redirect", 64 [RTPROT_KERNEL] = "kernel", 65 [RTPROT_BOOT] = "boot", 66 [RTPROT_STATIC] = "static", 67 68 [RTPROT_GATED] = "gated", 69 [RTPROT_RA] = "ra", 70 [RTPROT_MRT] = "mrt", 71 [RTPROT_ZEBRA] ="zebra", 72 [RTPROT_BIRD] = "bird", 73 [RTPROT_DNROUTED] = "dnrouted", 74#ifdef RTPROT_XORP 75 [RTPROT_XORP] = "xorp", 76#endif 77}; 78 79 80 81static int rtnl_rtprot_init; 82 83static void rtnl_rtprot_initialize(void) 84{ 85 rtnl_rtprot_init = 1; 86 rtnl_tab_initialize("/etc/iproute2/rt_protos", 87 rtnl_rtprot_tab, 256); 88} 89 90char * rtnl_rtprot_n2a(int id, char *buf, int len) 91{ 92 if (id<0 || id>=256) { 93 snprintf(buf, len, "%d", id); 94 return buf; 95 } 96 if (!rtnl_rtprot_tab[id]) { 97 if (!rtnl_rtprot_init) 98 rtnl_rtprot_initialize(); 99 } 100 if (rtnl_rtprot_tab[id]) 101 return rtnl_rtprot_tab[id]; 102 snprintf(buf, len, "%d", id); 103 return buf; 104} 105 106int rtnl_rtprot_a2n(__u32 *id, char *arg) 107{ 108 static char *cache = NULL; 109 static unsigned long res; 110 char *end; 111 int i; 112 113 if (cache && strcmp(cache, arg) == 0) { 114 *id = res; 115 return 0; 116 } 117 118 if (!rtnl_rtprot_init) 119 rtnl_rtprot_initialize(); 120 121 for (i=0; i<256; i++) { 122 if (rtnl_rtprot_tab[i] && 123 strcmp(rtnl_rtprot_tab[i], arg) == 0) { 124 cache = rtnl_rtprot_tab[i]; 125 res = i; 126 *id = res; 127 return 0; 128 } 129 } 130 131 res = strtoul(arg, &end, 0); 132 if (!end || end == arg || *end || res > 255) 133 return -1; 134 *id = res; 135 return 0; 136} 137 138 139 140static char * rtnl_rtscope_tab[256] = { 141 "global", 142}; 143 144static int rtnl_rtscope_init; 145 146static void rtnl_rtscope_initialize(void) 147{ 148 rtnl_rtscope_init = 1; 149 rtnl_rtscope_tab[255] = "nowhere"; 150 rtnl_rtscope_tab[254] = "host"; 151 rtnl_rtscope_tab[253] = "link"; 152 rtnl_rtscope_tab[200] = "site"; 153 rtnl_tab_initialize("/etc/iproute2/rt_scopes", 154 rtnl_rtscope_tab, 256); 155} 156 157char * rtnl_rtscope_n2a(int id, char *buf, int len) 158{ 159 if (id<0 || id>=256) { 160 snprintf(buf, len, "%d", id); 161 return buf; 162 } 163 if (!rtnl_rtscope_tab[id]) { 164 if (!rtnl_rtscope_init) 165 rtnl_rtscope_initialize(); 166 } 167 if (rtnl_rtscope_tab[id]) 168 return rtnl_rtscope_tab[id]; 169 snprintf(buf, len, "%d", id); 170 return buf; 171} 172 173int rtnl_rtscope_a2n(__u32 *id, char *arg) 174{ 175 static char *cache = NULL; 176 static unsigned long res; 177 char *end; 178 int i; 179 180 if (cache && strcmp(cache, arg) == 0) { 181 *id = res; 182 return 0; 183 } 184 185 if (!rtnl_rtscope_init) 186 rtnl_rtscope_initialize(); 187 188 for (i=0; i<256; i++) { 189 if (rtnl_rtscope_tab[i] && 190 strcmp(rtnl_rtscope_tab[i], arg) == 0) { 191 cache = rtnl_rtscope_tab[i]; 192 res = i; 193 *id = res; 194 return 0; 195 } 196 } 197 198 res = strtoul(arg, &end, 0); 199 if (!end || end == arg || *end || res > 255) 200 return -1; 201 *id = res; 202 return 0; 203} 204 205 206 207static char * rtnl_rtrealm_tab[256] = { 208 "unknown", 209}; 210 211static int rtnl_rtrealm_init; 212 213static void rtnl_rtrealm_initialize(void) 214{ 215 rtnl_rtrealm_init = 1; 216 rtnl_tab_initialize("/etc/iproute2/rt_realms", 217 rtnl_rtrealm_tab, 256); 218} 219 220char * rtnl_rtrealm_n2a(int id, char *buf, int len) 221{ 222 if (id<0 || id>=256) { 223 snprintf(buf, len, "%d", id); 224 return buf; 225 } 226 if (!rtnl_rtrealm_tab[id]) { 227 if (!rtnl_rtrealm_init) 228 rtnl_rtrealm_initialize(); 229 } 230 if (rtnl_rtrealm_tab[id]) 231 return rtnl_rtrealm_tab[id]; 232 snprintf(buf, len, "%d", id); 233 return buf; 234} 235 236 237int rtnl_rtrealm_a2n(__u32 *id, char *arg) 238{ 239 static char *cache = NULL; 240 static unsigned long res; 241 char *end; 242 int i; 243 244 if (cache && strcmp(cache, arg) == 0) { 245 *id = res; 246 return 0; 247 } 248 249 if (!rtnl_rtrealm_init) 250 rtnl_rtrealm_initialize(); 251 252 for (i=0; i<256; i++) { 253 if (rtnl_rtrealm_tab[i] && 254 strcmp(rtnl_rtrealm_tab[i], arg) == 0) { 255 cache = rtnl_rtrealm_tab[i]; 256 res = i; 257 *id = res; 258 return 0; 259 } 260 } 261 262 res = strtoul(arg, &end, 0); 263 if (!end || end == arg || *end || res > 255) 264 return -1; 265 *id = res; 266 return 0; 267} 268 269 270 271static char * rtnl_rttable_tab[256] = { 272 "unspec", 273}; 274 275static int rtnl_rttable_init; 276 277static void rtnl_rttable_initialize(void) 278{ 279 rtnl_rttable_init = 1; 280 rtnl_rttable_tab[255] = "local"; 281 rtnl_rttable_tab[254] = "main"; 282 rtnl_rttable_tab[253] = "default"; 283 rtnl_tab_initialize("/etc/iproute2/rt_tables", 284 rtnl_rttable_tab, 256); 285} 286 287char * rtnl_rttable_n2a(int id, char *buf, int len) 288{ 289 if (id<0 || id>=256) { 290 snprintf(buf, len, "%d", id); 291 return buf; 292 } 293 if (!rtnl_rttable_tab[id]) { 294 if (!rtnl_rttable_init) 295 rtnl_rttable_initialize(); 296 } 297 if (rtnl_rttable_tab[id]) 298 return rtnl_rttable_tab[id]; 299 snprintf(buf, len, "%d", id); 300 return buf; 301} 302 303int rtnl_rttable_a2n(__u32 *id, char *arg) 304{ 305 static char *cache = NULL; 306 static unsigned long res; 307 char *end; 308 int i; 309 310 if (cache && strcmp(cache, arg) == 0) { 311 *id = res; 312 return 0; 313 } 314 315 if (!rtnl_rttable_init) 316 rtnl_rttable_initialize(); 317 318 for (i=0; i<256; i++) { 319 if (rtnl_rttable_tab[i] && 320 strcmp(rtnl_rttable_tab[i], arg) == 0) { 321 cache = rtnl_rttable_tab[i]; 322 res = i; 323 *id = res; 324 return 0; 325 } 326 } 327 328 i = strtoul(arg, &end, 0); 329 if (!end || end == arg || *end || i > 255) 330 return -1; 331 *id = i; 332 return 0; 333} 334 335 336static char * rtnl_rtdsfield_tab[256] = { 337 "0", 338}; 339 340static int rtnl_rtdsfield_init; 341 342static void rtnl_rtdsfield_initialize(void) 343{ 344 rtnl_rtdsfield_init = 1; 345 rtnl_tab_initialize("/etc/iproute2/rt_dsfield", 346 rtnl_rtdsfield_tab, 256); 347} 348 349char * rtnl_dsfield_n2a(int id, char *buf, int len) 350{ 351 if (id<0 || id>=256) { 352 snprintf(buf, len, "%d", id); 353 return buf; 354 } 355 if (!rtnl_rtdsfield_tab[id]) { 356 if (!rtnl_rtdsfield_init) 357 rtnl_rtdsfield_initialize(); 358 } 359 if (rtnl_rtdsfield_tab[id]) 360 return rtnl_rtdsfield_tab[id]; 361 snprintf(buf, len, "0x%02x", id); 362 return buf; 363} 364 365 366int rtnl_dsfield_a2n(__u32 *id, char *arg) 367{ 368 static char *cache = NULL; 369 static unsigned long res; 370 char *end; 371 int i; 372 373 if (cache && strcmp(cache, arg) == 0) { 374 *id = res; 375 return 0; 376 } 377 378 if (!rtnl_rtdsfield_init) 379 rtnl_rtdsfield_initialize(); 380 381 for (i=0; i<256; i++) { 382 if (rtnl_rtdsfield_tab[i] && 383 strcmp(rtnl_rtdsfield_tab[i], arg) == 0) { 384 cache = rtnl_rtdsfield_tab[i]; 385 res = i; 386 *id = res; 387 return 0; 388 } 389 } 390 391 res = strtoul(arg, &end, 16); 392 if (!end || end == arg || *end || res > 255) 393 return -1; 394 *id = res; 395 return 0; 396} 397 398