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