snmp_scalar.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /**
  2. * @file
  3. * SNMP scalar node support implementation.
  4. */
  5. /*
  6. * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
  7. * All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without modification,
  10. * are permitted provided that the following conditions are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright notice,
  13. * this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright notice,
  15. * this list of conditions and the following disclaimer in the documentation
  16. * and/or other materials provided with the distribution.
  17. * 3. The name of the author may not be used to endorse or promote products
  18. * derived from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  21. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  22. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
  23. * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  24. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  25. * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  28. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  29. * OF SUCH DAMAGE.
  30. *
  31. * This file is part of the lwIP TCP/IP stack.
  32. *
  33. * Author: Martin Hentschel <info@cl-soft.de>
  34. *
  35. */
  36. #include "lwip/apps/snmp_opts.h"
  37. #if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
  38. #include "lwip/apps/snmp_scalar.h"
  39. #include "lwip/apps/snmp_core.h"
  40. static s16_t snmp_scalar_array_get_value(struct snmp_node_instance* instance, void* value);
  41. static snmp_err_t snmp_scalar_array_set_test(struct snmp_node_instance* instance, u16_t value_len, void* value);
  42. static snmp_err_t snmp_scalar_array_set_value(struct snmp_node_instance* instance, u16_t value_len, void* value);
  43. snmp_err_t
  44. snmp_scalar_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
  45. {
  46. const struct snmp_scalar_node* scalar_node = (const struct snmp_scalar_node*)(const void*)instance->node;
  47. LWIP_UNUSED_ARG(root_oid);
  48. LWIP_UNUSED_ARG(root_oid_len);
  49. /* scalar only has one dedicated instance: .0 */
  50. if ((instance->instance_oid.len != 1) || (instance->instance_oid.id[0] != 0)) {
  51. return SNMP_ERR_NOSUCHINSTANCE;
  52. }
  53. instance->access = scalar_node->access;
  54. instance->asn1_type = scalar_node->asn1_type;
  55. instance->get_value = scalar_node->get_value;
  56. instance->set_test = scalar_node->set_test;
  57. instance->set_value = scalar_node->set_value;
  58. return SNMP_ERR_NOERROR;
  59. }
  60. snmp_err_t
  61. snmp_scalar_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
  62. {
  63. /* because our only instance is .0 we can only return a next instance if no instance oid is passed */
  64. if (instance->instance_oid.len == 0) {
  65. instance->instance_oid.len = 1;
  66. instance->instance_oid.id[0] = 0;
  67. return snmp_scalar_get_instance(root_oid, root_oid_len, instance);
  68. }
  69. return SNMP_ERR_NOSUCHINSTANCE;
  70. }
  71. snmp_err_t
  72. snmp_scalar_array_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
  73. {
  74. LWIP_UNUSED_ARG(root_oid);
  75. LWIP_UNUSED_ARG(root_oid_len);
  76. if ((instance->instance_oid.len == 2) && (instance->instance_oid.id[1] == 0)) {
  77. const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node;
  78. const struct snmp_scalar_array_node_def* array_node_def = array_node->array_nodes;
  79. u32_t i = 0;
  80. while (i < array_node->array_node_count) {
  81. if (array_node_def->oid == instance->instance_oid.id[0]) {
  82. break;
  83. }
  84. array_node_def++;
  85. i++;
  86. }
  87. if (i < array_node->array_node_count) {
  88. instance->access = array_node_def->access;
  89. instance->asn1_type = array_node_def->asn1_type;
  90. instance->get_value = snmp_scalar_array_get_value;
  91. instance->set_test = snmp_scalar_array_set_test;
  92. instance->set_value = snmp_scalar_array_set_value;
  93. instance->reference.const_ptr = array_node_def;
  94. return SNMP_ERR_NOERROR;
  95. }
  96. }
  97. return SNMP_ERR_NOSUCHINSTANCE;
  98. }
  99. snmp_err_t
  100. snmp_scalar_array_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
  101. {
  102. const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node;
  103. const struct snmp_scalar_array_node_def* array_node_def = array_node->array_nodes;
  104. const struct snmp_scalar_array_node_def* result = NULL;
  105. LWIP_UNUSED_ARG(root_oid);
  106. LWIP_UNUSED_ARG(root_oid_len);
  107. if ((instance->instance_oid.len == 0) && (array_node->array_node_count > 0)) {
  108. /* return node with lowest OID */
  109. u16_t i = 0;
  110. result = array_node_def;
  111. array_node_def++;
  112. for (i = 1; i < array_node->array_node_count; i++) {
  113. if (array_node_def->oid < result->oid) {
  114. result = array_node_def;
  115. }
  116. array_node_def++;
  117. }
  118. } else if (instance->instance_oid.len >= 1) {
  119. if (instance->instance_oid.len == 1) {
  120. /* if we have the requested OID we return its instance, otherwise we search for the next available */
  121. u16_t i = 0;
  122. while (i < array_node->array_node_count) {
  123. if (array_node_def->oid == instance->instance_oid.id[0]) {
  124. result = array_node_def;
  125. break;
  126. }
  127. array_node_def++;
  128. i++;
  129. }
  130. }
  131. if (result == NULL) {
  132. u32_t oid_dist = 0xFFFFFFFFUL;
  133. u16_t i = 0;
  134. array_node_def = array_node->array_nodes; /* may be already at the end when if case before was executed without result -> reinitialize to start */
  135. while (i < array_node->array_node_count) {
  136. if ((array_node_def->oid > instance->instance_oid.id[0]) &&
  137. ((u32_t)(array_node_def->oid - instance->instance_oid.id[0]) < oid_dist)) {
  138. result = array_node_def;
  139. oid_dist = array_node_def->oid - instance->instance_oid.id[0];
  140. }
  141. array_node_def++;
  142. i++;
  143. }
  144. }
  145. }
  146. if (result == NULL) {
  147. /* nothing to return */
  148. return SNMP_ERR_NOSUCHINSTANCE;
  149. }
  150. instance->instance_oid.len = 2;
  151. instance->instance_oid.id[0] = result->oid;
  152. instance->instance_oid.id[1] = 0;
  153. instance->access = result->access;
  154. instance->asn1_type = result->asn1_type;
  155. instance->get_value = snmp_scalar_array_get_value;
  156. instance->set_test = snmp_scalar_array_set_test;
  157. instance->set_value = snmp_scalar_array_set_value;
  158. instance->reference.const_ptr = result;
  159. return SNMP_ERR_NOERROR;
  160. }
  161. static s16_t
  162. snmp_scalar_array_get_value(struct snmp_node_instance* instance, void* value)
  163. {
  164. const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node;
  165. const struct snmp_scalar_array_node_def* array_node_def = (const struct snmp_scalar_array_node_def*)instance->reference.const_ptr;
  166. return array_node->get_value(array_node_def, value);
  167. }
  168. static snmp_err_t
  169. snmp_scalar_array_set_test(struct snmp_node_instance* instance, u16_t value_len, void* value)
  170. {
  171. const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node;
  172. const struct snmp_scalar_array_node_def* array_node_def = (const struct snmp_scalar_array_node_def*)instance->reference.const_ptr;
  173. return array_node->set_test(array_node_def, value_len, value);
  174. }
  175. static snmp_err_t
  176. snmp_scalar_array_set_value(struct snmp_node_instance* instance, u16_t value_len, void* value)
  177. {
  178. const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node;
  179. const struct snmp_scalar_array_node_def* array_node_def = (const struct snmp_scalar_array_node_def*)instance->reference.const_ptr;
  180. return array_node->set_value(array_node_def, value_len, value);
  181. }
  182. #endif /* LWIP_SNMP */