Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lwip_snmp_scalar.c Source File

lwip_snmp_scalar.c

Go to the documentation of this file.
00001 /**
00002  * @file
00003  * SNMP scalar node support implementation.
00004  */
00005 
00006 /*
00007  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
00008  * All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without modification,
00011  * are permitted provided that the following conditions are met:
00012  *
00013  * 1. Redistributions of source code must retain the above copyright notice,
00014  *    this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright notice,
00016  *    this list of conditions and the following disclaimer in the documentation
00017  *    and/or other materials provided with the distribution.
00018  * 3. The name of the author may not be used to endorse or promote products
00019  *    derived from this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00022  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00023  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00024  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00025  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00026  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00027  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00028  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00029  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00030  * OF SUCH DAMAGE.
00031  *
00032  * This file is part of the lwIP TCP/IP stack.
00033  *
00034  * Author: Martin Hentschel <info@cl-soft.de>
00035  *
00036  */
00037 
00038 #include "lwip/apps/snmp_opts.h"
00039 
00040 #if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
00041 
00042 #include "lwip/apps/snmp_scalar.h"
00043 #include "lwip/apps/snmp_core.h"
00044 
00045 static s16_t snmp_scalar_array_get_value(struct snmp_node_instance* instance, void* value);
00046 static snmp_err_t  snmp_scalar_array_set_test(struct snmp_node_instance* instance, u16_t value_len, void* value);
00047 static snmp_err_t  snmp_scalar_array_set_value(struct snmp_node_instance* instance, u16_t value_len, void* value);
00048 
00049 snmp_err_t 
00050 snmp_scalar_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
00051 {
00052   const struct snmp_scalar_node* scalar_node = (const struct snmp_scalar_node*)(const void*)instance->node;
00053 
00054   LWIP_UNUSED_ARG(root_oid);
00055   LWIP_UNUSED_ARG(root_oid_len);
00056 
00057   /* scalar only has one dedicated instance: .0 */
00058   if ((instance->instance_oid.len != 1) || (instance->instance_oid.id[0] != 0)) {
00059     return SNMP_ERR_NOSUCHINSTANCE;
00060   }
00061 
00062   instance->access    = scalar_node->access;
00063   instance->asn1_type = scalar_node->asn1_type;
00064   instance->get_value = scalar_node->get_value;
00065   instance->set_test  = scalar_node->set_test;
00066   instance->set_value = scalar_node->set_value;
00067   return SNMP_ERR_NOERROR;
00068 }
00069 
00070 snmp_err_t 
00071 snmp_scalar_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
00072 {
00073   /* because our only instance is .0 we can only return a next instance if no instance oid is passed */
00074   if (instance->instance_oid.len == 0) {
00075     instance->instance_oid.len   = 1;
00076     instance->instance_oid.id[0] = 0;
00077 
00078     return snmp_scalar_get_instance(root_oid, root_oid_len, instance);
00079   }
00080 
00081   return SNMP_ERR_NOSUCHINSTANCE;
00082 }
00083 
00084 
00085 snmp_err_t
00086 snmp_scalar_array_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
00087 {
00088   LWIP_UNUSED_ARG(root_oid);
00089   LWIP_UNUSED_ARG(root_oid_len);
00090 
00091   if ((instance->instance_oid.len == 2) && (instance->instance_oid.id[1] == 0)) {
00092     const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node;
00093     const struct snmp_scalar_array_node_def* array_node_def = array_node->array_nodes;
00094     u32_t i = 0;
00095 
00096     while (i < array_node->array_node_count) {
00097       if (array_node_def->oid == instance->instance_oid.id[0]) {
00098         break;
00099       }
00100 
00101       array_node_def++;
00102       i++;
00103     }
00104 
00105     if (i < array_node->array_node_count) {
00106       instance->access              = array_node_def->access;
00107       instance->asn1_type           = array_node_def->asn1_type;
00108       instance->get_value           = snmp_scalar_array_get_value;
00109       instance->set_test            = snmp_scalar_array_set_test;
00110       instance->set_value           = snmp_scalar_array_set_value;
00111       instance->reference.const_ptr = array_node_def;
00112 
00113       return SNMP_ERR_NOERROR;
00114     }
00115   }
00116 
00117   return SNMP_ERR_NOSUCHINSTANCE;
00118 }
00119 
00120 snmp_err_t
00121 snmp_scalar_array_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
00122 {
00123   const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node;
00124   const struct snmp_scalar_array_node_def* array_node_def = array_node->array_nodes;
00125   const struct snmp_scalar_array_node_def* result = NULL;
00126 
00127   LWIP_UNUSED_ARG(root_oid);
00128   LWIP_UNUSED_ARG(root_oid_len);
00129 
00130   if ((instance->instance_oid.len == 0) && (array_node->array_node_count > 0)) {
00131     /* return node with lowest OID */
00132     u16_t i = 0;
00133     
00134     result = array_node_def;
00135     array_node_def++;
00136 
00137     for (i = 1; i < array_node->array_node_count; i++) {
00138       if (array_node_def->oid < result->oid) {
00139         result = array_node_def;
00140       }
00141       array_node_def++;
00142     }
00143   } else if (instance->instance_oid.len >= 1) {
00144     if (instance->instance_oid.len == 1) {
00145       /* if we have the requested OID we return its instance, otherwise we search for the next available */    
00146       u16_t i = 0;
00147       while (i < array_node->array_node_count) {
00148         if (array_node_def->oid == instance->instance_oid.id[0]) {
00149           result = array_node_def;
00150           break;
00151         }
00152 
00153         array_node_def++;
00154         i++;
00155       }
00156     }
00157     if (result == NULL) {
00158       u32_t oid_dist = 0xFFFFFFFFUL;
00159       u16_t i        = 0;
00160       array_node_def = array_node->array_nodes; /* may be already at the end when if case before was executed without result -> reinitialize to start */
00161       while (i < array_node->array_node_count) {
00162         if ((array_node_def->oid > instance->instance_oid.id[0]) &&
00163             ((u32_t)(array_node_def->oid - instance->instance_oid.id[0]) < oid_dist)) {
00164           result   = array_node_def;
00165           oid_dist = array_node_def->oid - instance->instance_oid.id[0];
00166         }
00167 
00168         array_node_def++;
00169         i++;
00170       }
00171     }
00172   }
00173 
00174   if (result == NULL) {
00175     /* nothing to return */
00176     return SNMP_ERR_NOSUCHINSTANCE;
00177   }
00178 
00179   instance->instance_oid.len   = 2;
00180   instance->instance_oid.id[0] = result->oid;
00181   instance->instance_oid.id[1] = 0;
00182   
00183   instance->access              = result->access;
00184   instance->asn1_type           = result->asn1_type;
00185   instance->get_value           = snmp_scalar_array_get_value;
00186   instance->set_test            = snmp_scalar_array_set_test;
00187   instance->set_value           = snmp_scalar_array_set_value;
00188   instance->reference.const_ptr = result;
00189 
00190   return SNMP_ERR_NOERROR;
00191 }
00192 
00193 static s16_t
00194 snmp_scalar_array_get_value(struct snmp_node_instance* instance, void* value)
00195 {
00196   const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node;
00197   const struct snmp_scalar_array_node_def* array_node_def = (const struct snmp_scalar_array_node_def*)instance->reference.const_ptr;
00198 
00199   return array_node->get_value(array_node_def, value);
00200 }
00201 
00202 static snmp_err_t
00203 snmp_scalar_array_set_test(struct snmp_node_instance* instance, u16_t value_len, void* value)
00204 {
00205   const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node;
00206   const struct snmp_scalar_array_node_def* array_node_def = (const struct snmp_scalar_array_node_def*)instance->reference.const_ptr;
00207 
00208   return array_node->set_test(array_node_def, value_len, value);
00209 }
00210 
00211 static snmp_err_t
00212 snmp_scalar_array_set_value(struct snmp_node_instance* instance, u16_t value_len, void* value)
00213 {
00214   const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node;
00215   const struct snmp_scalar_array_node_def* array_node_def = (const struct snmp_scalar_array_node_def*)instance->reference.const_ptr;
00216 
00217   return array_node->set_value(array_node_def, value_len, value);
00218 }
00219 
00220 #endif /* LWIP_SNMP */