snmp_mib.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * Copyright 1998-2007 by egnite Software GmbH
  3. * Copyright 1988, 1989, 1991, 1992 by Carnegie Mellon University
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the copyright holders nor the names of
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  21. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  22. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  23. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  24. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  25. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  26. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  27. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  28. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. * SUCH DAMAGE.
  30. *
  31. * For additional information see http://www.ethernut.de/
  32. */
  33. #include <sys/types.h>
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #ifndef WIN32
  37. #include <memdebug.h>
  38. #endif
  39. #include <pro/snmp.h>
  40. #include <pro/snmp_api.h>
  41. #include <pro/snmp_mib.h>
  42. /*!
  43. * \addtogroup xgSNMP
  44. */
  45. /*@{*/
  46. /*
  47. * The subtree structure contains a subtree prefix which applies to
  48. * all variables in the associated variable list.
  49. *
  50. * No subtree may be a subtree of another subtree in this list.
  51. * i.e.: 1.2
  52. * 1.2.0
  53. */
  54. typedef struct _SUBTREE {
  55. /*! \brief Pointer to the next branch. */
  56. struct _SUBTREE *sub_next;
  57. /*! \brief Number of variables. */
  58. int sub_numvars;
  59. /*! \brief Pointer to the array of variables. */
  60. SNMPVAR *sub_vars;
  61. /*! \brief Length of the base name. */
  62. size_t sub_namelen;
  63. /*! \brief Base name of this branch. */
  64. OID sub_name[MAX_OID_LEN];
  65. } SUBTREE;
  66. static SUBTREE *mibtree;
  67. /*!
  68. * \brief Register MIB variables.
  69. */
  70. int SnmpMibRegister(OID basename[], size_t baselen, SNMPVAR * vars, int num)
  71. {
  72. SUBTREE **tpp;
  73. SUBTREE *branch;
  74. /* Create a new branch. */
  75. if ((branch = malloc(sizeof(SUBTREE))) == NULL) {
  76. return -1;
  77. }
  78. branch->sub_numvars = num;
  79. branch->sub_vars = vars;
  80. branch->sub_namelen = baselen;
  81. memcpy(branch->sub_name, basename, baselen * sizeof(OID));
  82. /* Locate the new branch's insertion point. */
  83. for (tpp = &mibtree; *tpp; tpp = &(*tpp)->sub_next) {
  84. if (SnmpOidCmp((*tpp)->sub_name, (*tpp)->sub_namelen, branch->sub_name, branch->sub_namelen) > 0) {
  85. break;
  86. }
  87. }
  88. /* Insert the branch. */
  89. branch->sub_next = *tpp;
  90. *tpp = branch;
  91. return 0;
  92. }
  93. /*!
  94. * \brief Find MIB variable.
  95. *
  96. * \param name
  97. * \param namelen
  98. * \param type
  99. * \param len
  100. * \param acl
  101. * \param exact
  102. * \param wmethod
  103. * \param no_obj
  104. */
  105. uint8_t *SnmpMibFind(OID * name, size_t * namelen, uint8_t * type, size_t * len, uint16_t * acl, int exact, WMETHOD ** wmethod,
  106. int *no_obj)
  107. {
  108. SUBTREE *tp;
  109. SNMPVAR *vp = 0;
  110. int i;
  111. uint8_t *access = NULL;
  112. int rc;
  113. OID *suffix;
  114. size_t sufflen;
  115. OID *ori_oid = NULL;
  116. size_t ori_len = 0;
  117. int found = 0;
  118. /*
  119. * If not looking for an exact match, keep a copy of the original name.
  120. */
  121. if (!exact) {
  122. if ((ori_oid = malloc(*namelen * sizeof(OID))) == NULL) {
  123. return NULL;
  124. }
  125. memcpy(ori_oid, name, *namelen * sizeof(OID));
  126. ori_len = *namelen;
  127. }
  128. *wmethod = NULL;
  129. /*
  130. * Walk along the linked list of subtrees.
  131. */
  132. for (tp = mibtree; tp; tp = tp->sub_next) {
  133. /*
  134. * Check if name is part of this subtree. Or, if we don't need an exact match,
  135. * if the name is in front of the subtree.
  136. */
  137. rc = SnmpOidTreeCmp(name, *namelen, tp->sub_name, tp->sub_namelen);
  138. if (rc == 0 || (rc < 0 && !exact)) {
  139. sufflen = *namelen - tp->sub_namelen;
  140. suffix = name + tp->sub_namelen;
  141. for (i = 0, vp = tp->sub_vars; i < tp->sub_numvars; i++, vp++) {
  142. if (vp->var_namelen && (exact || rc >= 0)) {
  143. rc = SnmpOidTreeCmp(suffix, sufflen, vp->var_name, vp->var_namelen);
  144. }
  145. if ((exact && rc == 0) || (!exact && rc <= 0) || vp->var_namelen == 0) {
  146. access = (*(vp->var_get)) (vp, name, namelen, exact, len, wmethod);
  147. if (wmethod) {
  148. *acl = vp->var_acl;
  149. }
  150. if (exact) {
  151. found = 1;
  152. }
  153. if (access) {
  154. break;
  155. }
  156. }
  157. if (exact && rc <= 0) {
  158. *type = vp->var_type;
  159. *acl = vp->var_acl;
  160. *no_obj = !found;
  161. return NULL;
  162. }
  163. }
  164. if (access) {
  165. break;
  166. }
  167. }
  168. }
  169. if (tp == NULL) {
  170. if (!access && !exact) {
  171. memcpy(name, ori_oid, ori_len * sizeof(OID));
  172. *namelen = ori_len;
  173. free(ori_oid);
  174. }
  175. *no_obj = !found;
  176. return NULL;
  177. }
  178. if (ori_oid) {
  179. free(ori_oid);
  180. }
  181. /*
  182. * vp now points to the approprate struct.
  183. */
  184. *type = vp->var_type;
  185. *acl = vp->var_acl;
  186. return access;
  187. }
  188. /*@}*/