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_udp.c
00001 /** 00002 * @file 00003 * Management Information Base II (RFC1213) UDP 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/udp.h" 00043 #include "lwip/stats.h" 00044 00045 #include <string.h> 00046 00047 #if LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_UDP 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 /* --- udp .1.3.6.1.2.1.7 ----------------------------------------------------- */ 00059 00060 static s16_t 00061 udp_get_value(struct snmp_node_instance* instance, void* value) 00062 { 00063 u32_t *uint_ptr = (u32_t*)value; 00064 00065 switch (instance->node->oid) { 00066 case 1: /* udpInDatagrams */ 00067 *uint_ptr = STATS_GET(mib2.udpindatagrams); 00068 return sizeof(*uint_ptr); 00069 case 2: /* udpNoPorts */ 00070 *uint_ptr = STATS_GET(mib2.udpnoports); 00071 return sizeof(*uint_ptr); 00072 case 3: /* udpInErrors */ 00073 *uint_ptr = STATS_GET(mib2.udpinerrors); 00074 return sizeof(*uint_ptr); 00075 case 4: /* udpOutDatagrams */ 00076 *uint_ptr = STATS_GET(mib2.udpoutdatagrams); 00077 return sizeof(*uint_ptr); 00078 case 8: /* udpHCInDatagrams */ 00079 memset(value, 0, 2*sizeof(u32_t)); /* not supported */ 00080 return 2*sizeof(u32_t); 00081 case 9: /* udpHCOutDatagrams */ 00082 memset(value, 0, 2*sizeof(u32_t)); /* not supported */ 00083 return 2*sizeof(u32_t); 00084 default: 00085 LWIP_DEBUGF(SNMP_MIB_DEBUG,("udp_get_value(): unknown id: %"S32_F"\n", instance->node->oid)); 00086 break; 00087 } 00088 00089 return 0; 00090 } 00091 00092 /* --- udpEndpointTable --- */ 00093 00094 static snmp_err_t 00095 udp_endpointTable_get_cell_value_core(const u32_t* column, union snmp_variant_value* value) 00096 { 00097 /* all items except udpEndpointProcess are declared as not-accessible */ 00098 switch (*column) { 00099 case 8: /* udpEndpointProcess */ 00100 value->u32 = 0; /* not supported */ 00101 break; 00102 default: 00103 return SNMP_ERR_NOSUCHINSTANCE; 00104 } 00105 00106 return SNMP_ERR_NOERROR; 00107 } 00108 00109 static snmp_err_t 00110 udp_endpointTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) 00111 { 00112 ip_addr_t local_ip, remote_ip; 00113 u16_t local_port, remote_port; 00114 struct udp_pcb *pcb; 00115 u8_t idx = 0; 00116 00117 LWIP_UNUSED_ARG(value_len); 00118 00119 /* udpEndpointLocalAddressType + udpEndpointLocalAddress + udpEndpointLocalPort */ 00120 idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len-idx, &local_ip, &local_port); 00121 if (idx == 0) { 00122 return SNMP_ERR_NOSUCHINSTANCE; 00123 } 00124 00125 /* udpEndpointRemoteAddressType + udpEndpointRemoteAddress + udpEndpointRemotePort */ 00126 idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len-idx, &remote_ip, &remote_port); 00127 if (idx == 0) { 00128 return SNMP_ERR_NOSUCHINSTANCE; 00129 } 00130 00131 /* udpEndpointInstance */ 00132 if (row_oid_len < (idx+1)) { 00133 return SNMP_ERR_NOSUCHINSTANCE; 00134 } 00135 if (row_oid[idx] != 0) { 00136 return SNMP_ERR_NOSUCHINSTANCE; 00137 } 00138 00139 /* find udp_pcb with requested ip and port*/ 00140 pcb = udp_pcbs; 00141 while (pcb != NULL) { 00142 if (ip_addr_cmp(&local_ip, &pcb->local_ip) && 00143 (local_port == pcb->local_port) && 00144 ip_addr_cmp(&remote_ip, &pcb->remote_ip) && 00145 (remote_port == pcb->remote_port)) { 00146 /* fill in object properties */ 00147 return udp_endpointTable_get_cell_value_core(column, value); 00148 } 00149 pcb = pcb->next; 00150 } 00151 00152 /* not found */ 00153 return SNMP_ERR_NOSUCHINSTANCE; 00154 } 00155 00156 static snmp_err_t 00157 udp_endpointTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len) 00158 { 00159 struct udp_pcb *pcb; 00160 struct snmp_next_oid_state state; 00161 /* 1x udpEndpointLocalAddressType + 1x OID len + 16x udpEndpointLocalAddress + 1x udpEndpointLocalPort + 00162 * 1x udpEndpointRemoteAddressType + 1x OID len + 16x udpEndpointRemoteAddress + 1x udpEndpointRemotePort + 00163 * 1x udpEndpointInstance = 39 00164 */ 00165 u32_t result_temp[39]; 00166 00167 LWIP_UNUSED_ARG(value_len); 00168 00169 /* init struct to search next oid */ 00170 snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(result_temp)); 00171 00172 /* iterate over all possible OIDs to find the next one */ 00173 pcb = udp_pcbs; 00174 while (pcb != NULL) { 00175 u32_t test_oid[LWIP_ARRAYSIZE(result_temp)]; 00176 u8_t idx = 0; 00177 00178 /* udpEndpointLocalAddressType + udpEndpointLocalAddress + udpEndpointLocalPort */ 00179 idx += snmp_ip_port_to_oid(&pcb->local_ip, pcb->local_port, &test_oid[idx]); 00180 00181 /* udpEndpointRemoteAddressType + udpEndpointRemoteAddress + udpEndpointRemotePort */ 00182 idx += snmp_ip_port_to_oid(&pcb->remote_ip, pcb->remote_port, &test_oid[idx]); 00183 00184 test_oid[idx] = 0; /* udpEndpointInstance */ 00185 idx++; 00186 00187 /* check generated OID: is it a candidate for the next one? */ 00188 snmp_next_oid_check(&state, test_oid, idx, NULL); 00189 00190 pcb = pcb->next; 00191 } 00192 00193 /* did we find a next one? */ 00194 if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { 00195 snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); 00196 /* fill in object properties */ 00197 return udp_endpointTable_get_cell_value_core(column, value); 00198 } else { 00199 /* not found */ 00200 return SNMP_ERR_NOSUCHINSTANCE; 00201 } 00202 } 00203 00204 /* --- udpTable --- */ 00205 00206 #if LWIP_IPV4 00207 00208 /* list of allowed value ranges for incoming OID */ 00209 static const struct snmp_oid_range udp_Table_oid_ranges[] = { 00210 { 0, 0xff }, /* IP A */ 00211 { 0, 0xff }, /* IP B */ 00212 { 0, 0xff }, /* IP C */ 00213 { 0, 0xff }, /* IP D */ 00214 { 1, 0xffff } /* Port */ 00215 }; 00216 00217 static snmp_err_t 00218 udp_Table_get_cell_value_core(struct udp_pcb *pcb, const u32_t* column, union snmp_variant_value* value, u32_t* value_len) 00219 { 00220 LWIP_UNUSED_ARG(value_len); 00221 00222 switch (*column) { 00223 case 1: /* udpLocalAddress */ 00224 /* set reference to PCB local IP and return a generic node that copies IP4 addresses */ 00225 value->u32 = ip_2_ip4(&pcb->local_ip)->addr; 00226 break; 00227 case 2: /* udpLocalPort */ 00228 /* set reference to PCB local port and return a generic node that copies u16_t values */ 00229 value->u32 = pcb->local_port; 00230 break; 00231 default: 00232 return SNMP_ERR_NOSUCHINSTANCE; 00233 } 00234 00235 return SNMP_ERR_NOERROR; 00236 } 00237 00238 static snmp_err_t 00239 udp_Table_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) 00240 { 00241 ip4_addr_t ip; 00242 u16_t port; 00243 struct udp_pcb *pcb; 00244 00245 /* check if incoming OID length and if values are in plausible range */ 00246 if (!snmp_oid_in_range(row_oid, row_oid_len, udp_Table_oid_ranges, LWIP_ARRAYSIZE(udp_Table_oid_ranges))) { 00247 return SNMP_ERR_NOSUCHINSTANCE; 00248 } 00249 00250 /* get IP and port from incoming OID */ 00251 snmp_oid_to_ip4(&row_oid[0], &ip); /* we know it succeeds because of oid_in_range check above */ 00252 port = (u16_t)row_oid[4]; 00253 00254 /* find udp_pcb with requested ip and port*/ 00255 pcb = udp_pcbs; 00256 while (pcb != NULL) { 00257 if (IP_IS_V4_VAL(pcb->local_ip)) { 00258 if (ip4_addr_cmp(&ip, ip_2_ip4(&pcb->local_ip)) && (port == pcb->local_port)) { 00259 /* fill in object properties */ 00260 return udp_Table_get_cell_value_core(pcb, column, value, value_len); 00261 } 00262 } 00263 pcb = pcb->next; 00264 } 00265 00266 /* not found */ 00267 return SNMP_ERR_NOSUCHINSTANCE; 00268 } 00269 00270 static snmp_err_t 00271 udp_Table_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len) 00272 { 00273 struct udp_pcb *pcb; 00274 struct snmp_next_oid_state state; 00275 u32_t result_temp[LWIP_ARRAYSIZE(udp_Table_oid_ranges)]; 00276 00277 /* init struct to search next oid */ 00278 snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(udp_Table_oid_ranges)); 00279 00280 /* iterate over all possible OIDs to find the next one */ 00281 pcb = udp_pcbs; 00282 while (pcb != NULL) { 00283 u32_t test_oid[LWIP_ARRAYSIZE(udp_Table_oid_ranges)]; 00284 00285 if (IP_IS_V4_VAL(pcb->local_ip)) { 00286 snmp_ip4_to_oid(ip_2_ip4(&pcb->local_ip), &test_oid[0]); 00287 test_oid[4] = pcb->local_port; 00288 00289 /* check generated OID: is it a candidate for the next one? */ 00290 snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(udp_Table_oid_ranges), pcb); 00291 } 00292 00293 pcb = pcb->next; 00294 } 00295 00296 /* did we find a next one? */ 00297 if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { 00298 snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); 00299 /* fill in object properties */ 00300 return udp_Table_get_cell_value_core((struct udp_pcb*)state.reference, column, value, value_len); 00301 } else { 00302 /* not found */ 00303 return SNMP_ERR_NOSUCHINSTANCE; 00304 } 00305 } 00306 00307 #endif /* LWIP_IPV4 */ 00308 00309 static const struct snmp_scalar_node udp_inDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(1, SNMP_ASN1_TYPE_COUNTER, udp_get_value); 00310 static const struct snmp_scalar_node udp_noPorts = SNMP_SCALAR_CREATE_NODE_READONLY(2, SNMP_ASN1_TYPE_COUNTER, udp_get_value); 00311 static const struct snmp_scalar_node udp_inErrors = SNMP_SCALAR_CREATE_NODE_READONLY(3, SNMP_ASN1_TYPE_COUNTER, udp_get_value); 00312 static const struct snmp_scalar_node udp_outDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(4, SNMP_ASN1_TYPE_COUNTER, udp_get_value); 00313 static const struct snmp_scalar_node udp_HCInDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(8, SNMP_ASN1_TYPE_COUNTER64, udp_get_value); 00314 static const struct snmp_scalar_node udp_HCOutDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(9, SNMP_ASN1_TYPE_COUNTER64, udp_get_value); 00315 00316 #if LWIP_IPV4 00317 static const struct snmp_table_simple_col_def udp_Table_columns[] = { 00318 { 1, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* udpLocalAddress */ 00319 { 2, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 } /* udpLocalPort */ 00320 }; 00321 static const struct snmp_table_simple_node udp_Table = SNMP_TABLE_CREATE_SIMPLE(5, udp_Table_columns, udp_Table_get_cell_value, udp_Table_get_next_cell_instance_and_value); 00322 #endif /* LWIP_IPV4 */ 00323 00324 static const struct snmp_table_simple_col_def udp_endpointTable_columns[] = { 00325 /* all items except udpEndpointProcess are declared as not-accessible */ 00326 { 8, SNMP_ASN1_TYPE_UNSIGNED32, SNMP_VARIANT_VALUE_TYPE_U32 } /* udpEndpointProcess */ 00327 }; 00328 00329 static const struct snmp_table_simple_node udp_endpointTable = SNMP_TABLE_CREATE_SIMPLE(7, udp_endpointTable_columns, udp_endpointTable_get_cell_value, udp_endpointTable_get_next_cell_instance_and_value); 00330 00331 /* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */ 00332 CREATE_LWIP_SYNC_NODE(1, udp_inDatagrams) 00333 CREATE_LWIP_SYNC_NODE(2, udp_noPorts) 00334 CREATE_LWIP_SYNC_NODE(3, udp_inErrors) 00335 CREATE_LWIP_SYNC_NODE(4, udp_outDatagrams) 00336 #if LWIP_IPV4 00337 CREATE_LWIP_SYNC_NODE(5, udp_Table) 00338 #endif /* LWIP_IPV4 */ 00339 CREATE_LWIP_SYNC_NODE(7, udp_endpointTable) 00340 CREATE_LWIP_SYNC_NODE(8, udp_HCInDatagrams) 00341 CREATE_LWIP_SYNC_NODE(9, udp_HCOutDatagrams) 00342 00343 static const struct snmp_node* const udp_nodes[] = { 00344 &SYNC_NODE_NAME(udp_inDatagrams).node.node, 00345 &SYNC_NODE_NAME(udp_noPorts).node.node, 00346 &SYNC_NODE_NAME(udp_inErrors).node.node, 00347 &SYNC_NODE_NAME(udp_outDatagrams).node.node, 00348 #if LWIP_IPV4 00349 &SYNC_NODE_NAME(udp_Table).node.node, 00350 #endif /* LWIP_IPV4 */ 00351 &SYNC_NODE_NAME(udp_endpointTable).node.node, 00352 &SYNC_NODE_NAME(udp_HCInDatagrams).node.node, 00353 &SYNC_NODE_NAME(udp_HCOutDatagrams).node.node 00354 }; 00355 00356 const struct snmp_tree_node snmp_mib2_udp_root = SNMP_CREATE_TREE_NODE(7, udp_nodes); 00357 #endif /* LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_UDP */
Generated on Fri Jul 22 2022 04:53:53 by
 1.7.2
 1.7.2 
    