Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-os by
lwip_snmp_table.c
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 Tue Jul 12 2022 13:15:54 by
