ll_map.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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 <net/if.h> /* struct ifreq and co. */
  11. #include "libbb.h"
  12. #include "libnetlink.h"
  13. #include "ll_map.h"
  14. struct idxmap {
  15. struct idxmap *next;
  16. int index;
  17. int type;
  18. int alen;
  19. unsigned flags;
  20. unsigned char addr[8];
  21. char name[16];
  22. };
  23. static struct idxmap **idxmap; /* treat as *idxmap[16] */
  24. static struct idxmap *find_by_index(int idx)
  25. {
  26. struct idxmap *im;
  27. if (idxmap)
  28. for (im = idxmap[idx & 0xF]; im; im = im->next)
  29. if (im->index == idx)
  30. return im;
  31. return NULL;
  32. }
  33. int FAST_FUNC ll_remember_index(const struct sockaddr_nl *who UNUSED_PARAM,
  34. struct nlmsghdr *n,
  35. void *arg UNUSED_PARAM)
  36. {
  37. int h;
  38. struct ifinfomsg *ifi = NLMSG_DATA(n);
  39. struct idxmap *im, **imp;
  40. struct rtattr *tb[IFLA_MAX+1];
  41. if (n->nlmsg_type != RTM_NEWLINK)
  42. return 0;
  43. if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
  44. return -1;
  45. memset(tb, 0, sizeof(tb));
  46. parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n));
  47. if (tb[IFLA_IFNAME] == NULL)
  48. return 0;
  49. if (!idxmap)
  50. idxmap = xzalloc(sizeof(idxmap[0]) * 16);
  51. h = ifi->ifi_index & 0xF;
  52. for (imp = &idxmap[h]; (im = *imp) != NULL; imp = &im->next)
  53. if (im->index == ifi->ifi_index)
  54. goto found;
  55. im = xmalloc(sizeof(*im));
  56. im->next = *imp;
  57. im->index = ifi->ifi_index;
  58. *imp = im;
  59. found:
  60. im->type = ifi->ifi_type;
  61. im->flags = ifi->ifi_flags;
  62. if (tb[IFLA_ADDRESS]) {
  63. int alen;
  64. im->alen = alen = RTA_PAYLOAD(tb[IFLA_ADDRESS]);
  65. if (alen > (int)sizeof(im->addr))
  66. alen = sizeof(im->addr);
  67. memcpy(im->addr, RTA_DATA(tb[IFLA_ADDRESS]), alen);
  68. } else {
  69. im->alen = 0;
  70. memset(im->addr, 0, sizeof(im->addr));
  71. }
  72. strcpy(im->name, RTA_DATA(tb[IFLA_IFNAME]));
  73. return 0;
  74. }
  75. static
  76. const char FAST_FUNC *ll_idx_n2a(int idx/*, char *buf*/)
  77. {
  78. struct idxmap *im;
  79. if (idx == 0)
  80. return "*";
  81. im = find_by_index(idx);
  82. if (im)
  83. return im->name;
  84. //snprintf(buf, 16, "if%d", idx);
  85. //return buf;
  86. return auto_string(xasprintf("if%d", idx));
  87. }
  88. const char FAST_FUNC *ll_index_to_name(int idx)
  89. {
  90. //static char nbuf[16];
  91. return ll_idx_n2a(idx/*, nbuf*/);
  92. }
  93. #ifdef UNUSED
  94. int ll_index_to_type(int idx)
  95. {
  96. struct idxmap *im;
  97. if (idx == 0)
  98. return -1;
  99. im = find_by_index(idx);
  100. if (im)
  101. return im->type;
  102. return -1;
  103. }
  104. #endif
  105. unsigned FAST_FUNC ll_index_to_flags(int idx)
  106. {
  107. struct idxmap *im;
  108. if (idx == 0)
  109. return 0;
  110. im = find_by_index(idx);
  111. if (im)
  112. return im->flags;
  113. return 0;
  114. }
  115. int FAST_FUNC xll_name_to_index(const char *name)
  116. {
  117. int ret = 0;
  118. /* caching is not warranted - no users which repeatedly call it */
  119. #ifdef UNUSED
  120. static char ncache[16];
  121. static int icache;
  122. struct idxmap *im;
  123. int i;
  124. if (name == NULL)
  125. goto out;
  126. if (icache && strcmp(name, ncache) == 0) {
  127. ret = icache;
  128. goto out;
  129. }
  130. if (idxmap) {
  131. for (i = 0; i < 16; i++) {
  132. for (im = idxmap[i]; im; im = im->next) {
  133. if (strcmp(im->name, name) == 0) {
  134. icache = im->index;
  135. strcpy(ncache, name);
  136. ret = im->index;
  137. goto out;
  138. }
  139. }
  140. }
  141. }
  142. #endif
  143. ret = if_nametoindex(name);
  144. /* out:*/
  145. if (ret <= 0)
  146. bb_error_msg_and_die("can't find device '%s'", name);
  147. return ret;
  148. }
  149. int FAST_FUNC ll_init_map(struct rtnl_handle *rth)
  150. {
  151. xrtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK);
  152. xrtnl_dump_filter(rth, ll_remember_index, NULL);
  153. return 0;
  154. }