Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lwip_snmp_table.c Source File

lwip_snmp_table.c

Go to the documentation of this file.
00001 /**
00002  * @file
00003  * SNMP table 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_core.h"
00043 #include "lwip/apps/snmp_table.h"
00044 #include <string.h>
00045 
00046 snmp_err_t snmp_table_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
00047 {
00048   snmp_err_t ret = SNMP_ERR_NOSUCHINSTANCE;
00049   const struct snmp_table_node* table_node = (const struct snmp_table_node*)(const void*)instance->node;
00050 
00051   LWIP_UNUSED_ARG(root_oid);
00052   LWIP_UNUSED_ARG(root_oid_len);
00053 
00054   /* check min. length (fixed row entry definition, column, row instance oid with at least one entry */
00055   /* fixed row entry always has oid 1 */
00056   if ((instance->instance_oid.len >= 3) && (instance->instance_oid.id[0] == 1)) {
00057     /* search column */
00058     const struct snmp_table_col_def* col_def = table_node->columns;
00059     u16_t i = table_node->column_count;
00060     while (i > 0) {
00061       if (col_def->index == instance->instance_oid.id[1]) {
00062         break;
00063       }
00064       
00065       col_def++;
00066       i--;
00067     }
00068 
00069     if (i > 0) {
00070       /* everything may be overwritten by get_cell_instance_method() in order to implement special handling for single columns/cells */
00071       instance->asn1_type = col_def->asn1_type;
00072       instance->access    = col_def->access;
00073       instance->get_value = table_node->get_value;
00074       instance->set_test  = table_node->set_test;
00075       instance->set_value = table_node->set_value;
00076 
00077       ret = table_node->get_cell_instance(
00078         &(instance->instance_oid.id[1]),
00079         &(instance->instance_oid.id[2]),
00080         instance->instance_oid.len-2,
00081         instance);
00082     }
00083   }
00084 
00085   return ret;
00086 }
00087 
00088 snmp_err_t snmp_table_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
00089 {
00090   const struct snmp_table_node* table_node = (const struct snmp_table_node*)(const void*)instance->node;
00091   const struct snmp_table_col_def* col_def;
00092   struct snmp_obj_id row_oid;
00093   u32_t column = 0;
00094   snmp_err_t result;
00095 
00096   LWIP_UNUSED_ARG(root_oid);
00097   LWIP_UNUSED_ARG(root_oid_len);
00098 
00099   /* check that first part of id is 0 or 1, referencing fixed row entry */
00100   if ((instance->instance_oid.len > 0) && (instance->instance_oid.id[0] > 1)) {
00101     return SNMP_ERR_NOSUCHINSTANCE;
00102   }
00103   if (instance->instance_oid.len > 1) {
00104     column = instance->instance_oid.id[1];
00105   }
00106   if (instance->instance_oid.len > 2) {
00107     snmp_oid_assign(&row_oid, &(instance->instance_oid.id[2]), instance->instance_oid.len - 2);
00108   } else {
00109     row_oid.len = 0;
00110   }
00111 
00112   instance->get_value    = table_node->get_value;
00113   instance->set_test     = table_node->set_test;
00114   instance->set_value    = table_node->set_value;
00115 
00116   /* resolve column and value */
00117   do {
00118     u16_t i;
00119     const struct snmp_table_col_def* next_col_def = NULL;
00120     col_def = table_node->columns;
00121 
00122     for (i = 0; i < table_node->column_count; i++) {
00123       if (col_def->index == column) {
00124         next_col_def = col_def;
00125         break;
00126       } else if ((col_def->index > column) && ((next_col_def == NULL) || (col_def->index < next_col_def->index))) {
00127         next_col_def = col_def;
00128       }
00129       col_def++;
00130     }
00131 
00132     if (next_col_def == NULL) {
00133       /* no further column found */
00134       return SNMP_ERR_NOSUCHINSTANCE;
00135     }
00136 
00137     instance->asn1_type          = next_col_def->asn1_type;
00138     instance->access             = next_col_def->access;
00139 
00140     result = table_node->get_next_cell_instance(
00141       &next_col_def->index,
00142       &row_oid,
00143       instance);
00144 
00145     if (result == SNMP_ERR_NOERROR) {
00146       col_def = next_col_def;
00147       break;
00148     }
00149 
00150     row_oid.len = 0; /* reset row_oid because we switch to next column and start with the first entry there */
00151     column = next_col_def->index + 1;
00152   } while (1);
00153 
00154   /* build resulting oid */
00155   instance->instance_oid.len   = 2;
00156   instance->instance_oid.id[0] = 1;
00157   instance->instance_oid.id[1] = col_def->index;
00158   snmp_oid_append(&instance->instance_oid, row_oid.id, row_oid.len);
00159 
00160   return SNMP_ERR_NOERROR;
00161 }
00162 
00163 
00164 snmp_err_t snmp_table_simple_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
00165 {
00166   snmp_err_t ret = SNMP_ERR_NOSUCHINSTANCE;
00167   const struct snmp_table_simple_node* table_node = (const struct snmp_table_simple_node*)(const void*)instance->node;
00168 
00169   LWIP_UNUSED_ARG(root_oid);
00170   LWIP_UNUSED_ARG(root_oid_len);
00171 
00172   /* check min. length (fixed row entry definition, column, row instance oid with at least one entry */
00173   /* fixed row entry always has oid 1 */
00174   if ((instance->instance_oid.len >= 3) && (instance->instance_oid.id[0] == 1)) {
00175     ret = table_node->get_cell_value(
00176       &(instance->instance_oid.id[1]),
00177       &(instance->instance_oid.id[2]),
00178       instance->instance_oid.len-2,
00179       &instance->reference,
00180       &instance->reference_len);
00181 
00182     if (ret == SNMP_ERR_NOERROR) {
00183       /* search column */
00184       const struct snmp_table_simple_col_def* col_def = table_node->columns;
00185       u32_t i = table_node->column_count;
00186       while (i > 0) {
00187         if (col_def->index == instance->instance_oid.id[1]) {
00188           break;
00189         }
00190 
00191         col_def++;
00192         i--;
00193       }
00194 
00195       if (i > 0) {
00196         instance->asn1_type = col_def->asn1_type;
00197         instance->access    = SNMP_NODE_INSTANCE_READ_ONLY;
00198         instance->set_test  = NULL;
00199         instance->set_value = NULL;
00200 
00201         switch (col_def->data_type) {
00202           case SNMP_VARIANT_VALUE_TYPE_U32:
00203             instance->get_value = snmp_table_extract_value_from_u32ref;
00204             break;
00205           case SNMP_VARIANT_VALUE_TYPE_S32:
00206             instance->get_value = snmp_table_extract_value_from_s32ref;
00207             break;
00208           case SNMP_VARIANT_VALUE_TYPE_PTR: /* fall through */
00209           case SNMP_VARIANT_VALUE_TYPE_CONST_PTR:
00210             instance->get_value = snmp_table_extract_value_from_refconstptr;
00211             break;
00212           default:
00213             LWIP_DEBUGF(SNMP_DEBUG, ("snmp_table_simple_get_instance(): unknown column data_type: %d\n", col_def->data_type));
00214             return SNMP_ERR_GENERROR;
00215         }        
00216 
00217         ret = SNMP_ERR_NOERROR;
00218       } else {
00219         ret = SNMP_ERR_NOSUCHINSTANCE;
00220       }
00221     } 
00222   }
00223 
00224   return ret;
00225 }
00226 
00227 snmp_err_t snmp_table_simple_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance)
00228 {
00229   const struct snmp_table_simple_node* table_node = (const struct snmp_table_simple_node*)(const void*)instance->node;
00230   const struct snmp_table_simple_col_def* col_def;
00231   struct snmp_obj_id row_oid;
00232   u32_t column = 0;
00233   snmp_err_t result;
00234 
00235   LWIP_UNUSED_ARG(root_oid);
00236   LWIP_UNUSED_ARG(root_oid_len);
00237 
00238   /* check that first part of id is 0 or 1, referencing fixed row entry */
00239   if ((instance->instance_oid.len > 0) && (instance->instance_oid.id[0] > 1)) {
00240     return SNMP_ERR_NOSUCHINSTANCE;
00241   }
00242   if (instance->instance_oid.len > 1) {
00243     column = instance->instance_oid.id[1];
00244   }
00245   if (instance->instance_oid.len > 2) {
00246     snmp_oid_assign(&row_oid, &(instance->instance_oid.id[2]), instance->instance_oid.len - 2);
00247   } else {
00248     row_oid.len = 0;
00249   }
00250 
00251   /* resolve column and value */
00252   do {
00253     u32_t i;
00254     const struct snmp_table_simple_col_def* next_col_def = NULL;
00255     col_def = table_node->columns;
00256 
00257     for (i = 0; i < table_node->column_count; i++) {
00258       if (col_def->index == column) {
00259         next_col_def = col_def;
00260         break;
00261       } else if ((col_def->index > column) && ((next_col_def == NULL) ||
00262                  (col_def->index < next_col_def->index))) {
00263         next_col_def = col_def;
00264       }
00265       col_def++;
00266     }
00267 
00268     if (next_col_def == NULL) {
00269       /* no further column found */
00270       return SNMP_ERR_NOSUCHINSTANCE;
00271     }
00272 
00273     result = table_node->get_next_cell_instance_and_value(
00274       &next_col_def->index,
00275       &row_oid,
00276       &instance->reference,
00277       &instance->reference_len);
00278 
00279     if (result == SNMP_ERR_NOERROR) {
00280       col_def = next_col_def;
00281       break;
00282     }
00283 
00284     row_oid.len = 0; /* reset row_oid because we switch to next column and start with the first entry there */
00285     column = next_col_def->index + 1;
00286   }
00287   while (1);
00288 
00289   instance->asn1_type = col_def->asn1_type;
00290   instance->access    = SNMP_NODE_INSTANCE_READ_ONLY;
00291   instance->set_test  = NULL;
00292   instance->set_value = NULL;
00293 
00294   switch (col_def->data_type) {
00295     case SNMP_VARIANT_VALUE_TYPE_U32:
00296       instance->get_value = snmp_table_extract_value_from_u32ref;
00297       break;
00298     case SNMP_VARIANT_VALUE_TYPE_S32:
00299       instance->get_value = snmp_table_extract_value_from_s32ref;
00300       break;
00301     case SNMP_VARIANT_VALUE_TYPE_PTR: /* fall through */
00302     case SNMP_VARIANT_VALUE_TYPE_CONST_PTR:
00303       instance->get_value = snmp_table_extract_value_from_refconstptr;
00304       break;
00305     default:
00306       LWIP_DEBUGF(SNMP_DEBUG, ("snmp_table_simple_get_instance(): unknown column data_type: %d\n", col_def->data_type));
00307       return SNMP_ERR_GENERROR;
00308   }
00309 
00310   /* build resulting oid */
00311   instance->instance_oid.len   = 2;
00312   instance->instance_oid.id[0] = 1;
00313   instance->instance_oid.id[1] = col_def->index;
00314   snmp_oid_append(&instance->instance_oid, row_oid.id, row_oid.len);
00315 
00316   return SNMP_ERR_NOERROR;
00317 }
00318 
00319 
00320 s16_t
00321 snmp_table_extract_value_from_s32ref(struct snmp_node_instance* instance, void* value)
00322 {
00323   s32_t *dst = (s32_t*)value;
00324   *dst = instance->reference.s32;
00325   return sizeof(*dst);
00326 }
00327 
00328 s16_t
00329 snmp_table_extract_value_from_u32ref(struct snmp_node_instance* instance, void* value)
00330 {
00331   u32_t *dst = (u32_t*)value;
00332   *dst = instance->reference.u32;
00333   return sizeof(*dst);
00334 }
00335 
00336 s16_t
00337 snmp_table_extract_value_from_refconstptr(struct snmp_node_instance* instance, void* value)
00338 {
00339   MEMCPY(value, instance->reference.const_ptr, instance->reference_len);
00340   return (u16_t)instance->reference_len;
00341 }
00342 
00343 #endif /* LWIP_SNMP */