Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
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 */
Generated on Sun Jul 17 2022 08:25:25 by 1.7.2