/user/net-snmp/agent/auto_nlist.c

https://github.com/rhuitl/uClinux · C · 236 lines · 215 code · 15 blank · 6 comment · 71 complexity · 1e458eb8dc532ba83c379271889d318b MD5 · raw file

  1. #include <net-snmp/net-snmp-config.h>
  2. #ifdef NETSNMP_CAN_USE_NLIST
  3. #if HAVE_STRING_H
  4. #include <string.h>
  5. #else
  6. #include <strings.h>
  7. #endif
  8. #if HAVE_STDLIB_H
  9. #include <stdlib.h>
  10. #endif
  11. #include <stdio.h>
  12. #include <errno.h>
  13. #include <fcntl.h>
  14. #include <netinet/in.h>
  15. #ifdef HAVE_NLIST_H
  16. #include <nlist.h>
  17. #endif
  18. #if HAVE_KVM_H
  19. #include <kvm.h>
  20. #endif
  21. #include <net-snmp/agent/auto_nlist.h>
  22. #include "autonlist.h"
  23. #include "kernel.h"
  24. #include <net-snmp/net-snmp-includes.h>
  25. #include <net-snmp/agent/ds_agent.h>
  26. struct autonlist *nlists = 0;
  27. static void init_nlist(struct nlist *);
  28. long
  29. auto_nlist_value(const char *string)
  30. {
  31. struct autonlist **ptr, *it = 0;
  32. int cmp;
  33. if (string == 0)
  34. return 0;
  35. ptr = &nlists;
  36. while (*ptr != 0 && it == 0) {
  37. cmp = strcmp((*ptr)->symbol, string);
  38. if (cmp == 0)
  39. it = *ptr;
  40. else if (cmp < 0) {
  41. ptr = &((*ptr)->left);
  42. } else {
  43. ptr = &((*ptr)->right);
  44. }
  45. }
  46. if (*ptr == 0) {
  47. *ptr = (struct autonlist *) malloc(sizeof(struct autonlist));
  48. it = *ptr;
  49. it->left = 0;
  50. it->right = 0;
  51. it->symbol = (char *) malloc(strlen(string) + 1);
  52. strcpy(it->symbol, string);
  53. /*
  54. * allocate an extra byte for inclusion of a preceding '_' later
  55. */
  56. it->nl[0].n_name = (char *) malloc(strlen(string) + 2);
  57. #if defined(aix4) || defined(aix5) || defined(aix6)
  58. strcpy(it->nl[0].n_name, string);
  59. #else
  60. sprintf(it->nl[0].n_name, "_%s", string);
  61. #endif
  62. it->nl[1].n_name = 0;
  63. init_nlist(it->nl);
  64. #if !(defined(aix4) || defined(aix5) || defined(aix6))
  65. if (it->nl[0].n_type == 0) {
  66. strcpy(it->nl[0].n_name, string);
  67. init_nlist(it->nl);
  68. }
  69. #endif
  70. if (it->nl[0].n_type == 0) {
  71. if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
  72. NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
  73. snmp_log(LOG_ERR, "nlist err: neither %s nor _%s found.\n",
  74. string, string);
  75. }
  76. return (-1);
  77. } else {
  78. DEBUGMSGTL(("auto_nlist:auto_nlist_value", "found symbol %s at %x.\n",
  79. it->symbol, it->nl[0].n_value));
  80. return (it->nl[0].n_value);
  81. }
  82. } else
  83. return (it->nl[0].n_value);
  84. }
  85. int
  86. auto_nlist(const char *string, char *var, int size)
  87. {
  88. long result;
  89. int ret;
  90. result = auto_nlist_value(string);
  91. if (result != -1) {
  92. if (var != NULL) {
  93. ret = klookup(result, var, size);
  94. if (!ret)
  95. snmp_log(LOG_ERR,
  96. "auto_nlist failed on %s at location %lx\n",
  97. string, result);
  98. return ret;
  99. } else
  100. return 1;
  101. }
  102. return 0;
  103. }
  104. static void
  105. init_nlist(struct nlist nl[])
  106. {
  107. int ret;
  108. #if HAVE_KVM_OPENFILES
  109. kvm_t *kernel;
  110. char kvm_errbuf[4096];
  111. if ((kernel = kvm_openfiles(KERNEL_LOC, NULL, NULL, O_RDONLY, kvm_errbuf))
  112. == NULL) {
  113. if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
  114. NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
  115. return;
  116. } else {
  117. snmp_log_perror("kvm_openfiles");
  118. snmp_log(LOG_ERR, "kvm_openfiles: %s\n", kvm_errbuf);
  119. exit(1);
  120. }
  121. }
  122. if ((ret = kvm_nlist(kernel, nl)) == -1) {
  123. if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
  124. NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
  125. return;
  126. } else {
  127. snmp_log_perror("kvm_nlist");
  128. exit(1);
  129. }
  130. }
  131. kvm_close(kernel);
  132. #else /* ! HAVE_KVM_OPENFILES */
  133. #if (defined(aix4) || defined(aix5) || defined(aix6)) && defined(HAVE_KNLIST)
  134. if (knlist(nl, 1, sizeof(struct nlist)) == -1) {
  135. DEBUGMSGTL(("auto_nlist:init_nlist", "knlist failed on symbol: %s\n",
  136. nl[0].n_name));
  137. if (errno == EFAULT) {
  138. nl[0].n_type = 0;
  139. nl[0].n_value = 0;
  140. } else {
  141. snmp_log_perror("knlist");
  142. if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
  143. NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
  144. return;
  145. } else {
  146. exit(1);
  147. }
  148. }
  149. }
  150. #else
  151. if ((ret = nlist(KERNEL_LOC, nl)) == -1) {
  152. if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
  153. NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
  154. return;
  155. } else {
  156. snmp_log_perror("nlist");
  157. exit(1);
  158. }
  159. }
  160. #endif /*aix4 */
  161. #endif /* ! HAVE_KVM_OPENFILES */
  162. for (ret = 0; nl[ret].n_name != NULL; ret++) {
  163. #if defined(aix4) || defined(aix5) || defined(aix6)
  164. if (nl[ret].n_type == 0 && nl[ret].n_value != 0)
  165. nl[ret].n_type = 1;
  166. #endif
  167. if (nl[ret].n_type == 0) {
  168. if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
  169. NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
  170. DEBUGMSGTL(("auto_nlist:init_nlist", "nlist err: %s not found\n",
  171. nl[ret].n_name));
  172. }
  173. } else {
  174. DEBUGMSGTL(("auto_nlist:init_nlist", "nlist: %s 0x%X\n", nl[ret].n_name,
  175. (unsigned int) nl[ret].n_value));
  176. }
  177. }
  178. }
  179. int
  180. KNLookup(struct nlist nl[], int nl_which, char *buf, int s)
  181. {
  182. struct nlist *nlp = &nl[nl_which];
  183. if (nlp->n_value == 0) {
  184. snmp_log(LOG_ERR, "Accessing non-nlisted variable: %s\n",
  185. nlp->n_name);
  186. nlp->n_value = -1; /* only one error message ... */
  187. return 0;
  188. }
  189. if (nlp->n_value == -1)
  190. return 0;
  191. return klookup(nlp->n_value, buf, s);
  192. }
  193. #ifdef TESTING
  194. void
  195. auto_nlist_print_tree(int indent, struct autonlist *ptr)
  196. {
  197. char buf[1024];
  198. if (indent == -2) {
  199. snmp_log(LOG_ERR, "nlist tree:\n");
  200. auto_nlist_print_tree(12, nlists);
  201. } else {
  202. if (ptr == 0)
  203. return;
  204. sprintf(buf, "%%%ds\n", indent);
  205. /*
  206. * DEBUGMSGTL(("auto_nlist", "buf: %s\n",buf));
  207. */
  208. DEBUGMSGTL(("auto_nlist", buf, ptr->symbol));
  209. auto_nlist_print_tree(indent + 2, ptr->left);
  210. auto_nlist_print_tree(indent + 2, ptr->right);
  211. }
  212. }
  213. #endif
  214. #else /* !NETSNMP_CAN_USE_NLIST */
  215. #include <net-snmp/agent/auto_nlist.h>
  216. int
  217. auto_nlist_noop(void)
  218. {
  219. return 0;
  220. }
  221. #endif /* NETSNMP_CAN_USE_NLIST */