Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
lwip_snmp_mib2_interfaces.c
Go to the documentation of this file.
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 Sun Jul 17 2022 08:25:25 by 1.7.2