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 OmniWheels by
lwip_snmp_mib2_interfaces.c
00001 /** 00002 * @file 00003 * Management Information Base II (RFC1213) INTERFACES objects and functions. 00004 */ 00005 00006 /* 00007 * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. 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 * Author: Dirk Ziegelmeier <dziegel@gmx.de> 00033 * Christiaan Simons <christiaan.simons@axon.tv> 00034 */ 00035 00036 #include "lwip/snmp.h" 00037 #include "lwip/apps/snmp.h" 00038 #include "lwip/apps/snmp_core.h" 00039 #include "lwip/apps/snmp_mib2.h" 00040 #include "lwip/apps/snmp_table.h" 00041 #include "lwip/apps/snmp_scalar.h" 00042 #include "lwip/netif.h" 00043 #include "lwip/stats.h" 00044 00045 #include <string.h> 00046 00047 #if LWIP_SNMP && SNMP_LWIP_MIB2 00048 00049 #if SNMP_USE_NETCONN 00050 #define SYNC_NODE_NAME(node_name) node_name ## _synced 00051 #define CREATE_LWIP_SYNC_NODE(oid, node_name) \ 00052 static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks); 00053 #else 00054 #define SYNC_NODE_NAME(node_name) node_name 00055 #define CREATE_LWIP_SYNC_NODE(oid, node_name) 00056 #endif 00057 00058 00059 /* --- interfaces .1.3.6.1.2.1.2 ----------------------------------------------------- */ 00060 00061 static s16_t 00062 interfaces_get_value(struct snmp_node_instance* instance, void* value) 00063 { 00064 if (instance->node->oid == 1) { 00065 s32_t *sint_ptr = (s32_t*)value; 00066 s32_t num_netifs = 0; 00067 00068 struct netif *netif = netif_list; 00069 while (netif != NULL) { 00070 num_netifs++; 00071 netif = netif->next; 00072 } 00073 00074 *sint_ptr = num_netifs; 00075 return sizeof(*sint_ptr); 00076 } 00077 00078 return 0; 00079 } 00080 00081 /* list of allowed value ranges for incoming OID */ 00082 static const struct snmp_oid_range interfaces_Table_oid_ranges[] = { 00083 { 1, 0xff } /* netif->num is u8_t */ 00084 }; 00085 00086 static const u8_t iftable_ifOutQLen = 0; 00087 00088 static const u8_t iftable_ifOperStatus_up = 1; 00089 static const u8_t iftable_ifOperStatus_down = 2; 00090 00091 static const u8_t iftable_ifAdminStatus_up = 1; 00092 static const u8_t iftable_ifAdminStatus_lowerLayerDown = 7; 00093 static const u8_t iftable_ifAdminStatus_down = 2; 00094 00095 static snmp_err_t 00096 interfaces_Table_get_cell_instance(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, struct snmp_node_instance* cell_instance) 00097 { 00098 u32_t ifIndex; 00099 struct netif *netif; 00100 00101 LWIP_UNUSED_ARG(column); 00102 00103 /* check if incoming OID length and if values are in plausible range */ 00104 if (!snmp_oid_in_range(row_oid, row_oid_len, interfaces_Table_oid_ranges, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges))) { 00105 return SNMP_ERR_NOSUCHINSTANCE; 00106 } 00107 00108 /* get netif index from incoming OID */ 00109 ifIndex = row_oid[0]; 00110 00111 /* find netif with index */ 00112 netif = netif_list; 00113 while (netif != NULL) { 00114 if (netif_to_num(netif) == ifIndex) { 00115 /* store netif pointer for subsequent operations (get/test/set) */ 00116 cell_instance->reference.ptr = netif; 00117 return SNMP_ERR_NOERROR; 00118 } 00119 netif = netif->next; 00120 } 00121 00122 /* not found */ 00123 return SNMP_ERR_NOSUCHINSTANCE; 00124 } 00125 00126 static snmp_err_t 00127 interfaces_Table_get_next_cell_instance(const u32_t* column, struct snmp_obj_id* row_oid, struct snmp_node_instance* cell_instance) 00128 { 00129 struct netif *netif; 00130 struct snmp_next_oid_state state; 00131 u32_t result_temp[LWIP_ARRAYSIZE(interfaces_Table_oid_ranges)]; 00132 00133 LWIP_UNUSED_ARG(column); 00134 00135 /* init struct to search next oid */ 00136 snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges)); 00137 00138 /* iterate over all possible OIDs to find the next one */ 00139 netif = netif_list; 00140 while (netif != NULL) { 00141 u32_t test_oid[LWIP_ARRAYSIZE(interfaces_Table_oid_ranges)]; 00142 test_oid[0] = netif_to_num(netif); 00143 00144 /* check generated OID: is it a candidate for the next one? */ 00145 snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges), netif); 00146 00147 netif = netif->next; 00148 } 00149 00150 /* did we find a next one? */ 00151 if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { 00152 snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); 00153 /* store netif pointer for subsequent operations (get/test/set) */ 00154 cell_instance->reference.ptr = /* (struct netif*) */state.reference; 00155 return SNMP_ERR_NOERROR; 00156 } 00157 00158 /* not found */ 00159 return SNMP_ERR_NOSUCHINSTANCE; 00160 } 00161 00162 static s16_t 00163 interfaces_Table_get_value (struct snmp_node_instance* instance, void* value) 00164 { 00165 struct netif *netif = (struct netif*)instance->reference.ptr; 00166 u32_t* value_u32 = (u32_t*)value; 00167 s32_t* value_s32 = (s32_t*)value; 00168 u16_t value_len; 00169 00170 switch (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id)) 00171 { 00172 case 1: /* ifIndex */ 00173 *value_s32 = netif_to_num(netif); 00174 value_len = sizeof(*value_s32); 00175 break; 00176 case 2: /* ifDescr */ 00177 value_len = sizeof(netif->name); 00178 MEMCPY(value, netif->name, value_len); 00179 break; 00180 case 3: /* ifType */ 00181 *value_s32 = netif->link_type; 00182 value_len = sizeof(*value_s32); 00183 break; 00184 case 4: /* ifMtu */ 00185 *value_s32 = netif->mtu; 00186 value_len = sizeof(*value_s32); 00187 break; 00188 case 5: /* ifSpeed */ 00189 *value_u32 = netif->link_speed; 00190 value_len = sizeof(*value_u32); 00191 break; 00192 case 6: /* ifPhysAddress */ 00193 value_len = sizeof(netif->hwaddr); 00194 MEMCPY(value, &netif->hwaddr, value_len); 00195 break; 00196 case 7: /* ifAdminStatus */ 00197 if (netif_is_up(netif)) { 00198 *value_s32 = iftable_ifOperStatus_up; 00199 } else { 00200 *value_s32 = iftable_ifOperStatus_down; 00201 } 00202 value_len = sizeof(*value_s32); 00203 break; 00204 case 8: /* ifOperStatus */ 00205 if (netif_is_up(netif)) { 00206 if (netif_is_link_up(netif)) { 00207 *value_s32 = iftable_ifAdminStatus_up; 00208 } else { 00209 *value_s32 = iftable_ifAdminStatus_lowerLayerDown; 00210 } 00211 } else { 00212 *value_s32 = iftable_ifAdminStatus_down; 00213 } 00214 value_len = sizeof(*value_s32); 00215 break; 00216 case 9: /* ifLastChange */ 00217 *value_u32 = netif->ts; 00218 value_len = sizeof(*value_u32); 00219 break; 00220 case 10: /* ifInOctets */ 00221 *value_u32 = netif->mib2_counters.ifinoctets; 00222 value_len = sizeof(*value_u32); 00223 break; 00224 case 11: /* ifInUcastPkts */ 00225 *value_u32 = netif->mib2_counters.ifinucastpkts; 00226 value_len = sizeof(*value_u32); 00227 break; 00228 case 12: /* ifInNUcastPkts */ 00229 *value_u32 = netif->mib2_counters.ifinnucastpkts; 00230 value_len = sizeof(*value_u32); 00231 break; 00232 case 13: /* ifInDiscards */ 00233 *value_u32 = netif->mib2_counters.ifindiscards; 00234 value_len = sizeof(*value_u32); 00235 break; 00236 case 14: /* ifInErrors */ 00237 *value_u32 = netif->mib2_counters.ifinerrors; 00238 value_len = sizeof(*value_u32); 00239 break; 00240 case 15: /* ifInUnkownProtos */ 00241 *value_u32 = netif->mib2_counters.ifinunknownprotos; 00242 value_len = sizeof(*value_u32); 00243 break; 00244 case 16: /* ifOutOctets */ 00245 *value_u32 = netif->mib2_counters.ifoutoctets; 00246 value_len = sizeof(*value_u32); 00247 break; 00248 case 17: /* ifOutUcastPkts */ 00249 *value_u32 = netif->mib2_counters.ifoutucastpkts; 00250 value_len = sizeof(*value_u32); 00251 break; 00252 case 18: /* ifOutNUcastPkts */ 00253 *value_u32 = netif->mib2_counters.ifoutnucastpkts; 00254 value_len = sizeof(*value_u32); 00255 break; 00256 case 19: /* ifOutDiscarts */ 00257 *value_u32 = netif->mib2_counters.ifoutdiscards; 00258 value_len = sizeof(*value_u32); 00259 break; 00260 case 20: /* ifOutErrors */ 00261 *value_u32 = netif->mib2_counters.ifouterrors; 00262 value_len = sizeof(*value_u32); 00263 break; 00264 case 21: /* ifOutQLen */ 00265 *value_u32 = iftable_ifOutQLen; 00266 value_len = sizeof(*value_u32); 00267 break; 00268 /** @note returning zeroDotZero (0.0) no media specific MIB support */ 00269 case 22: /* ifSpecific */ 00270 value_len = snmp_zero_dot_zero.len * sizeof(u32_t); 00271 MEMCPY(value, snmp_zero_dot_zero.id, value_len); 00272 break; 00273 default: 00274 return 0; 00275 } 00276 00277 return value_len; 00278 } 00279 00280 #if !SNMP_SAFE_REQUESTS 00281 00282 static snmp_err_t 00283 interfaces_Table_set_test(struct snmp_node_instance* instance, u16_t len, void *value) 00284 { 00285 s32_t *sint_ptr = (s32_t*)value; 00286 00287 /* stack should never call this method for another column, 00288 because all other columns are set to readonly */ 00289 LWIP_ASSERT("Invalid column", (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id) == 7)); 00290 LWIP_UNUSED_ARG(len); 00291 00292 if (*sint_ptr == 1 || *sint_ptr == 2) { 00293 return SNMP_ERR_NOERROR; 00294 } 00295 00296 return SNMP_ERR_WRONGVALUE; 00297 } 00298 00299 static snmp_err_t 00300 interfaces_Table_set_value(struct snmp_node_instance* instance, u16_t len, void *value) 00301 { 00302 struct netif *netif = (struct netif*)instance->reference.ptr; 00303 s32_t *sint_ptr = (s32_t*)value; 00304 00305 /* stack should never call this method for another column, 00306 because all other columns are set to readonly */ 00307 LWIP_ASSERT("Invalid column", (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id) == 7)); 00308 LWIP_UNUSED_ARG(len); 00309 00310 if (*sint_ptr == 1) { 00311 netif_set_up(netif); 00312 } else if (*sint_ptr == 2) { 00313 netif_set_down(netif); 00314 } 00315 00316 return SNMP_ERR_NOERROR; 00317 } 00318 00319 #endif /* SNMP_SAFE_REQUESTS */ 00320 00321 static const struct snmp_scalar_node interfaces_Number = SNMP_SCALAR_CREATE_NODE_READONLY(1, SNMP_ASN1_TYPE_INTEGER, interfaces_get_value); 00322 00323 static const struct snmp_table_col_def interfaces_Table_columns[] = { 00324 { 1, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifIndex */ 00325 { 2, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifDescr */ 00326 { 3, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifType */ 00327 { 4, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifMtu */ 00328 { 5, SNMP_ASN1_TYPE_GAUGE, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifSpeed */ 00329 { 6, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifPhysAddress */ 00330 #if !SNMP_SAFE_REQUESTS 00331 { 7, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_WRITE }, /* ifAdminStatus */ 00332 #else 00333 { 7, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifAdminStatus */ 00334 #endif 00335 { 8, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOperStatus */ 00336 { 9, SNMP_ASN1_TYPE_TIMETICKS, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifLastChange */ 00337 { 10, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInOctets */ 00338 { 11, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInUcastPkts */ 00339 { 12, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInNUcastPkts */ 00340 { 13, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInDiscarts */ 00341 { 14, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInErrors */ 00342 { 15, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInUnkownProtos */ 00343 { 16, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutOctets */ 00344 { 17, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutUcastPkts */ 00345 { 18, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutNUcastPkts */ 00346 { 19, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutDiscarts */ 00347 { 20, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutErrors */ 00348 { 21, SNMP_ASN1_TYPE_GAUGE, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutQLen */ 00349 { 22, SNMP_ASN1_TYPE_OBJECT_ID, SNMP_NODE_INSTANCE_READ_ONLY } /* ifSpecific */ 00350 }; 00351 00352 #if !SNMP_SAFE_REQUESTS 00353 static const struct snmp_table_node interfaces_Table = SNMP_TABLE_CREATE( 00354 2, interfaces_Table_columns, 00355 interfaces_Table_get_cell_instance, interfaces_Table_get_next_cell_instance, 00356 interfaces_Table_get_value , interfaces_Table_set_test, interfaces_Table_set_value); 00357 #else 00358 static const struct snmp_table_node interfaces_Table = SNMP_TABLE_CREATE( 00359 2, interfaces_Table_columns, 00360 interfaces_Table_get_cell_instance, interfaces_Table_get_next_cell_instance, 00361 interfaces_Table_get_value , NULL, NULL); 00362 #endif 00363 00364 /* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */ 00365 CREATE_LWIP_SYNC_NODE(1, interfaces_Number) 00366 CREATE_LWIP_SYNC_NODE(2, interfaces_Table) 00367 00368 static const struct snmp_node* const interface_nodes[] = { 00369 &SYNC_NODE_NAME(interfaces_Number).node.node, 00370 &SYNC_NODE_NAME(interfaces_Table).node.node 00371 }; 00372 00373 const struct snmp_tree_node snmp_mib2_interface_root = SNMP_CREATE_TREE_NODE(2, interface_nodes); 00374 00375 #endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */
Generated on Fri Jul 22 2022 04:53:53 by
1.7.2
