You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ll_map.c 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /*
  2. * ll_map.c
  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. * Alpt: Added ll_first_up_if
  13. */
  14. #include "includes.h"
  15. #include "libnetlink.h"
  16. #include "ll_map.h"
  17. #include "xmalloc.h"
  18. #include "log.h"
  19. struct idxmap {
  20. struct idxmap *next;
  21. int index;
  22. int type;
  23. int alen;
  24. unsigned flags;
  25. unsigned char addr[8];
  26. char name[16];
  27. };
  28. static struct idxmap *idxmap[16];
  29. void
  30. ll_free_index(void)
  31. {
  32. struct idxmap *im, **imp;
  33. int i;
  34. for (i = 0; i < 16; i++)
  35. for (imp = &idxmap[i]; (im = *imp) != NULL;) {
  36. imp = &im->next;
  37. xfree(im);
  38. }
  39. }
  40. int
  41. ll_remember_index(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
  42. {
  43. int h;
  44. struct ifinfomsg *ifi = NLMSG_DATA(n);
  45. struct idxmap *im, **imp;
  46. struct rtattr *tb[IFLA_MAX + 1];
  47. if (n->nlmsg_type != RTM_NEWLINK)
  48. return 0;
  49. if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
  50. return -1;
  51. memset(tb, 0, sizeof(tb));
  52. parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n));
  53. if (tb[IFLA_IFNAME] == NULL)
  54. return 0;
  55. h = ifi->ifi_index & 0xF;
  56. for (imp = &idxmap[h]; (im = *imp) != NULL; imp = &im->next)
  57. if (im->index == ifi->ifi_index)
  58. break;
  59. if (im == NULL) {
  60. im = xmalloc(sizeof(*im));
  61. if (im == NULL)
  62. return 0;
  63. im->next = *imp;
  64. im->index = ifi->ifi_index;
  65. *imp = im;
  66. }
  67. im->type = ifi->ifi_type;
  68. im->flags = ifi->ifi_flags;
  69. if (tb[IFLA_ADDRESS]) {
  70. int alen;
  71. im->alen = alen = RTA_PAYLOAD(tb[IFLA_ADDRESS]);
  72. if (alen > sizeof(im->addr))
  73. alen = sizeof(im->addr);
  74. memcpy(im->addr, RTA_DATA(tb[IFLA_ADDRESS]), alen);
  75. } else {
  76. im->alen = 0;
  77. memset(im->addr, 0, sizeof(im->addr));
  78. }
  79. strcpy(im->name, RTA_DATA(tb[IFLA_IFNAME]));
  80. return 0;
  81. }
  82. const char *
  83. ll_idx_n2a(int idx, char *buf)
  84. {
  85. struct idxmap *im;
  86. if (idx == 0)
  87. return "*";
  88. for (im = idxmap[idx & 0xF]; im; im = im->next)
  89. if (im->index == idx)
  90. return im->name;
  91. snprintf(buf, 16, "if%d", idx);
  92. return buf;
  93. }
  94. const char *
  95. ll_index_to_name(int idx)
  96. {
  97. static char nbuf[16];
  98. return ll_idx_n2a(idx, nbuf);
  99. }
  100. int
  101. ll_index_to_type(int idx)
  102. {
  103. struct idxmap *im;
  104. if (idx == 0)
  105. return -1;
  106. for (im = idxmap[idx & 0xF]; im; im = im->next)
  107. if (im->index == idx)
  108. return im->type;
  109. return -1;
  110. }
  111. unsigned
  112. ll_index_to_flags(int idx)
  113. {
  114. struct idxmap *im;
  115. if (idx == 0)
  116. return 0;
  117. for (im = idxmap[idx & 0xF]; im; im = im->next)
  118. if (im->index == idx)
  119. return im->flags;
  120. return 0;
  121. }
  122. int
  123. ll_name_to_index(const char *name)
  124. {
  125. static char ncache[16];
  126. static int icache;
  127. struct idxmap *im;
  128. int i;
  129. if (name == NULL)
  130. return 0;
  131. if (icache && strcmp(name, ncache) == 0)
  132. return icache;
  133. for (i = 0; i < 16; i++) {
  134. for (im = idxmap[i]; im; im = im->next) {
  135. if (strcmp(im->name, name) == 0) {
  136. icache = im->index;
  137. strcpy(ncache, name);
  138. return im->index;
  139. }
  140. }
  141. }
  142. return 0;
  143. }
  144. /* It returns the idx of the `n'th interface it finds up in the map */
  145. int
  146. ll_nth_up_if(int n)
  147. {
  148. unsigned char i, found;
  149. unsigned flags;
  150. if (n <= 0)
  151. fatal("%s:%d: Bad argument given", ERROR_POS);
  152. for (found = 0, i = 1; i <= 16; i++) {
  153. flags = ll_index_to_flags(i);
  154. if ((flags & IFF_UP) && !(flags & IFF_LOOPBACK)) {
  155. found++;
  156. if (found == n)
  157. return i;
  158. }
  159. }
  160. return -1;
  161. }
  162. /* It returns the first the idx of the first interface it finds up in the map */
  163. int
  164. ll_first_up_if(void)
  165. {
  166. return ll_nth_up_if(1);
  167. }
  168. int
  169. ll_init_map(struct rtnl_handle *rth)
  170. {
  171. if (rtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK) < 0)
  172. fatal("%s:%d: Cannot send dump request", ERROR_POS);
  173. if (rtnl_dump_filter
  174. (rth, (rtnl_filter_t) ll_remember_index, &idxmap, NULL, NULL) < 0)
  175. fatal(ERROR_MSG "Dump terminated", ERROR_POS);
  176. return 0;
  177. }