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_mib2_ip.c
00001 /** 00002 * @file 00003 * Management Information Base II (RFC1213) IP 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/stats.h" 00043 #include "lwip/netif.h" 00044 #include "lwip/ip.h" 00045 #include "lwip/etharp.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 #if LWIP_IPV4 00059 /* --- ip .1.3.6.1.2.1.4 ----------------------------------------------------- */ 00060 00061 static s16_t 00062 ip_get_value (struct snmp_node_instance* instance, void* value) 00063 { 00064 s32_t* sint_ptr = (s32_t*)value; 00065 u32_t* uint_ptr = (u32_t*)value; 00066 00067 switch (instance->node->oid) { 00068 case 1: /* ipForwarding */ 00069 #if IP_FORWARD 00070 /* forwarding */ 00071 *sint_ptr = 1; 00072 #else 00073 /* not-forwarding */ 00074 *sint_ptr = 2; 00075 #endif 00076 return sizeof(*sint_ptr); 00077 case 2: /* ipDefaultTTL */ 00078 *sint_ptr = IP_DEFAULT_TTL; 00079 return sizeof(*sint_ptr); 00080 case 3: /* ipInReceives */ 00081 *uint_ptr = STATS_GET(mib2.ipinreceives); 00082 return sizeof(*uint_ptr); 00083 case 4: /* ipInHdrErrors */ 00084 *uint_ptr = STATS_GET(mib2.ipinhdrerrors); 00085 return sizeof(*uint_ptr); 00086 case 5: /* ipInAddrErrors */ 00087 *uint_ptr = STATS_GET(mib2.ipinaddrerrors); 00088 return sizeof(*uint_ptr); 00089 case 6: /* ipForwDatagrams */ 00090 *uint_ptr = STATS_GET(mib2.ipforwdatagrams); 00091 return sizeof(*uint_ptr); 00092 case 7: /* ipInUnknownProtos */ 00093 *uint_ptr = STATS_GET(mib2.ipinunknownprotos); 00094 return sizeof(*uint_ptr); 00095 case 8: /* ipInDiscards */ 00096 *uint_ptr = STATS_GET(mib2.ipindiscards); 00097 return sizeof(*uint_ptr); 00098 case 9: /* ipInDelivers */ 00099 *uint_ptr = STATS_GET(mib2.ipindelivers); 00100 return sizeof(*uint_ptr); 00101 case 10: /* ipOutRequests */ 00102 *uint_ptr = STATS_GET(mib2.ipoutrequests); 00103 return sizeof(*uint_ptr); 00104 case 11: /* ipOutDiscards */ 00105 *uint_ptr = STATS_GET(mib2.ipoutdiscards); 00106 return sizeof(*uint_ptr); 00107 case 12: /* ipOutNoRoutes */ 00108 *uint_ptr = STATS_GET(mib2.ipoutnoroutes); 00109 return sizeof(*uint_ptr); 00110 case 13: /* ipReasmTimeout */ 00111 #if IP_REASSEMBLY 00112 *sint_ptr = IP_REASS_MAXAGE; 00113 #else 00114 *sint_ptr = 0; 00115 #endif 00116 return sizeof(*sint_ptr); 00117 case 14: /* ipReasmReqds */ 00118 *uint_ptr = STATS_GET(mib2.ipreasmreqds); 00119 return sizeof(*uint_ptr); 00120 case 15: /* ipReasmOKs */ 00121 *uint_ptr = STATS_GET(mib2.ipreasmoks); 00122 return sizeof(*uint_ptr); 00123 case 16: /* ipReasmFails */ 00124 *uint_ptr = STATS_GET(mib2.ipreasmfails); 00125 return sizeof(*uint_ptr); 00126 case 17: /* ipFragOKs */ 00127 *uint_ptr = STATS_GET(mib2.ipfragoks); 00128 return sizeof(*uint_ptr); 00129 case 18: /* ipFragFails */ 00130 *uint_ptr = STATS_GET(mib2.ipfragfails); 00131 return sizeof(*uint_ptr); 00132 case 19: /* ipFragCreates */ 00133 *uint_ptr = STATS_GET(mib2.ipfragcreates); 00134 return sizeof(*uint_ptr); 00135 case 23: /* ipRoutingDiscards: not supported -> always 0 */ 00136 *uint_ptr = 0; 00137 return sizeof(*uint_ptr); 00138 default: 00139 LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_value(): unknown id: %"S32_F"\n", instance->node->oid)); 00140 break; 00141 } 00142 00143 return 0; 00144 } 00145 00146 /** 00147 * Test ip object value before setting. 00148 * 00149 * @param od is the object definition 00150 * @param len return value space (in bytes) 00151 * @param value points to (varbind) space to copy value from. 00152 * 00153 * @note we allow set if the value matches the hardwired value, 00154 * otherwise return badvalue. 00155 */ 00156 static snmp_err_t 00157 ip_set_test(struct snmp_node_instance* instance, u16_t len, void *value) 00158 { 00159 snmp_err_t ret = SNMP_ERR_WRONGVALUE; 00160 s32_t *sint_ptr = (s32_t*)value; 00161 00162 LWIP_UNUSED_ARG(len); 00163 switch (instance->node->oid) { 00164 case 1: /* ipForwarding */ 00165 #if IP_FORWARD 00166 /* forwarding */ 00167 if (*sint_ptr == 1) 00168 #else 00169 /* not-forwarding */ 00170 if (*sint_ptr == 2) 00171 #endif 00172 { 00173 ret = SNMP_ERR_NOERROR; 00174 } 00175 break; 00176 case 2: /* ipDefaultTTL */ 00177 if (*sint_ptr == IP_DEFAULT_TTL) { 00178 ret = SNMP_ERR_NOERROR; 00179 } 00180 break; 00181 default: 00182 LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_set_test(): unknown id: %"S32_F"\n", instance->node->oid)); 00183 break; 00184 } 00185 00186 return ret; 00187 } 00188 00189 static snmp_err_t 00190 ip_set_value(struct snmp_node_instance* instance, u16_t len, void *value) 00191 { 00192 LWIP_UNUSED_ARG(instance); 00193 LWIP_UNUSED_ARG(len); 00194 LWIP_UNUSED_ARG(value); 00195 /* nothing to do here because in set_test we only accept values being the same as our own stored value -> no need to store anything */ 00196 return SNMP_ERR_NOERROR; 00197 } 00198 00199 /* --- ipAddrTable --- */ 00200 00201 /* list of allowed value ranges for incoming OID */ 00202 static const struct snmp_oid_range ip_AddrTable_oid_ranges[] = { 00203 { 0, 0xff }, /* IP A */ 00204 { 0, 0xff }, /* IP B */ 00205 { 0, 0xff }, /* IP C */ 00206 { 0, 0xff } /* IP D */ 00207 }; 00208 00209 static snmp_err_t 00210 ip_AddrTable_get_cell_value_core (struct netif *netif, const u32_t* column, union snmp_variant_value* value, u32_t* value_len) 00211 { 00212 LWIP_UNUSED_ARG(value_len); 00213 00214 switch (*column) { 00215 case 1: /* ipAdEntAddr */ 00216 value->u32 = netif_ip4_addr(netif)->addr; 00217 break; 00218 case 2: /* ipAdEntIfIndex */ 00219 value->u32 = netif_to_num(netif); 00220 break; 00221 case 3: /* ipAdEntNetMask */ 00222 value->u32 = netif_ip4_netmask(netif)->addr; 00223 break; 00224 case 4: /* ipAdEntBcastAddr */ 00225 /* lwIP oddity, there's no broadcast 00226 address in the netif we can rely on */ 00227 value->u32 = IPADDR_BROADCAST & 1; 00228 break; 00229 case 5: /* ipAdEntReasmMaxSize */ 00230 #if IP_REASSEMBLY 00231 /* @todo The theoretical maximum is IP_REASS_MAX_PBUFS * size of the pbufs, 00232 * but only if receiving one fragmented packet at a time. 00233 * The current solution is to calculate for 2 simultaneous packets... 00234 */ 00235 value->u32 = (IP_HLEN + ((IP_REASS_MAX_PBUFS/2) * 00236 (PBUF_POOL_BUFSIZE - PBUF_LINK_ENCAPSULATION_HLEN - PBUF_LINK_HLEN - IP_HLEN))); 00237 #else 00238 /** @todo returning MTU would be a bad thing and 00239 returning a wild guess like '576' isn't good either */ 00240 value->u32 = 0; 00241 #endif 00242 break; 00243 default: 00244 return SNMP_ERR_NOSUCHINSTANCE; 00245 } 00246 00247 return SNMP_ERR_NOERROR; 00248 } 00249 00250 static snmp_err_t 00251 ip_AddrTable_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) 00252 { 00253 ip4_addr_t ip; 00254 struct netif *netif; 00255 00256 /* check if incoming OID length and if values are in plausible range */ 00257 if (!snmp_oid_in_range(row_oid, row_oid_len, ip_AddrTable_oid_ranges, LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges))) { 00258 return SNMP_ERR_NOSUCHINSTANCE; 00259 } 00260 00261 /* get IP from incoming OID */ 00262 snmp_oid_to_ip4(&row_oid[0], &ip); /* we know it succeeds because of oid_in_range check above */ 00263 00264 /* find netif with requested ip */ 00265 netif = netif_list; 00266 while (netif != NULL) { 00267 if (ip4_addr_cmp(&ip, netif_ip4_addr(netif))) { 00268 /* fill in object properties */ 00269 return ip_AddrTable_get_cell_value_core (netif, column, value, value_len); 00270 } 00271 00272 netif = netif->next; 00273 } 00274 00275 /* not found */ 00276 return SNMP_ERR_NOSUCHINSTANCE; 00277 } 00278 00279 static snmp_err_t 00280 ip_AddrTable_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) 00281 { 00282 struct netif *netif; 00283 struct snmp_next_oid_state state; 00284 u32_t result_temp[LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges)]; 00285 00286 /* init struct to search next oid */ 00287 snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges)); 00288 00289 /* iterate over all possible OIDs to find the next one */ 00290 netif = netif_list; 00291 while (netif != NULL) { 00292 u32_t test_oid[LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges)]; 00293 snmp_ip4_to_oid(netif_ip4_addr(netif), &test_oid[0]); 00294 00295 /* check generated OID: is it a candidate for the next one? */ 00296 snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges), netif); 00297 00298 netif = netif->next; 00299 } 00300 00301 /* did we find a next one? */ 00302 if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { 00303 snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); 00304 /* fill in object properties */ 00305 return ip_AddrTable_get_cell_value_core ((struct netif*)state.reference, column, value, value_len); 00306 } 00307 00308 /* not found */ 00309 return SNMP_ERR_NOSUCHINSTANCE; 00310 } 00311 00312 /* --- ipRouteTable --- */ 00313 00314 /* list of allowed value ranges for incoming OID */ 00315 static const struct snmp_oid_range ip_RouteTable_oid_ranges[] = { 00316 { 0, 0xff }, /* IP A */ 00317 { 0, 0xff }, /* IP B */ 00318 { 0, 0xff }, /* IP C */ 00319 { 0, 0xff }, /* IP D */ 00320 }; 00321 00322 static snmp_err_t 00323 ip_RouteTable_get_cell_value_core(struct netif *netif, u8_t default_route, const u32_t* column, union snmp_variant_value* value, u32_t* value_len) 00324 { 00325 switch (*column) { 00326 case 1: /* ipRouteDest */ 00327 if (default_route) { 00328 /* default rte has 0.0.0.0 dest */ 00329 value->u32 = IP4_ADDR_ANY->addr; 00330 } else { 00331 /* netifs have netaddress dest */ 00332 ip4_addr_t tmp; 00333 ip4_addr_get_network(&tmp, netif_ip4_addr(netif), netif_ip4_netmask(netif)); 00334 value->u32 = tmp.addr; 00335 } 00336 break; 00337 case 2: /* ipRouteIfIndex */ 00338 value->u32 = netif_to_num(netif); 00339 break; 00340 case 3: /* ipRouteMetric1 */ 00341 if (default_route) { 00342 value->s32 = 1; /* default */ 00343 } else { 00344 value->s32 = 0; /* normal */ 00345 } 00346 break; 00347 case 4: /* ipRouteMetric2 */ 00348 case 5: /* ipRouteMetric3 */ 00349 case 6: /* ipRouteMetric4 */ 00350 value->s32 = -1; /* none */ 00351 break; 00352 case 7: /* ipRouteNextHop */ 00353 if (default_route) { 00354 /* default rte: gateway */ 00355 value->u32 = netif_ip4_gw(netif)->addr; 00356 } else { 00357 /* other rtes: netif ip_addr */ 00358 value->u32 = netif_ip4_addr(netif)->addr; 00359 } 00360 break; 00361 case 8: /* ipRouteType */ 00362 if (default_route) { 00363 /* default rte is indirect */ 00364 value->u32 = 4; /* indirect */ 00365 } else { 00366 /* other rtes are direct */ 00367 value->u32 = 3; /* direct */ 00368 } 00369 break; 00370 case 9: /* ipRouteProto */ 00371 /* locally defined routes */ 00372 value->u32 = 2; /* local */ 00373 break; 00374 case 10: /* ipRouteAge */ 00375 /* @todo (sysuptime - timestamp last change) / 100 */ 00376 value->u32 = 0; 00377 break; 00378 case 11: /* ipRouteMask */ 00379 if (default_route) { 00380 /* default rte use 0.0.0.0 mask */ 00381 value->u32 = IP4_ADDR_ANY->addr; 00382 } else { 00383 /* other rtes use netmask */ 00384 value->u32 = netif_ip4_netmask(netif)->addr; 00385 } 00386 break; 00387 case 12: /* ipRouteMetric5 */ 00388 value->s32 = -1; /* none */ 00389 break; 00390 case 13: /* ipRouteInfo */ 00391 value->const_ptr = snmp_zero_dot_zero.id; 00392 *value_len = snmp_zero_dot_zero.len * sizeof(u32_t); 00393 break; 00394 default: 00395 return SNMP_ERR_NOSUCHINSTANCE; 00396 } 00397 00398 return SNMP_ERR_NOERROR; 00399 } 00400 00401 static snmp_err_t 00402 ip_RouteTable_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) 00403 { 00404 ip4_addr_t test_ip; 00405 struct netif *netif; 00406 00407 /* check if incoming OID length and if values are in plausible range */ 00408 if (!snmp_oid_in_range(row_oid, row_oid_len, ip_RouteTable_oid_ranges, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges))) { 00409 return SNMP_ERR_NOSUCHINSTANCE; 00410 } 00411 00412 /* get IP and port from incoming OID */ 00413 snmp_oid_to_ip4(&row_oid[0], &test_ip); /* we know it succeeds because of oid_in_range check above */ 00414 00415 /* default route is on default netif */ 00416 if (ip4_addr_isany_val(test_ip) && (netif_default != NULL)) { 00417 /* fill in object properties */ 00418 return ip_RouteTable_get_cell_value_core(netif_default, 1, column, value, value_len); 00419 } 00420 00421 /* find netif with requested route */ 00422 netif = netif_list; 00423 while (netif != NULL) { 00424 ip4_addr_t dst; 00425 ip4_addr_get_network(&dst, netif_ip4_addr(netif), netif_ip4_netmask(netif)); 00426 00427 if (ip4_addr_cmp(&dst, &test_ip)) { 00428 /* fill in object properties */ 00429 return ip_RouteTable_get_cell_value_core(netif, 0, column, value, value_len); 00430 } 00431 00432 netif = netif->next; 00433 } 00434 00435 /* not found */ 00436 return SNMP_ERR_NOSUCHINSTANCE; 00437 } 00438 00439 static snmp_err_t 00440 ip_RouteTable_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) 00441 { 00442 struct netif *netif; 00443 struct snmp_next_oid_state state; 00444 u32_t result_temp[LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges)]; 00445 u32_t test_oid[LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges)]; 00446 00447 /* init struct to search next oid */ 00448 snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges)); 00449 00450 /* check default route */ 00451 if (netif_default != NULL) { 00452 snmp_ip4_to_oid(IP4_ADDR_ANY, &test_oid[0]); 00453 snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges), netif_default); 00454 } 00455 00456 /* iterate over all possible OIDs to find the next one */ 00457 netif = netif_list; 00458 while (netif != NULL) { 00459 ip4_addr_t dst; 00460 ip4_addr_get_network(&dst, netif_ip4_addr(netif), netif_ip4_netmask(netif)); 00461 00462 /* check generated OID: is it a candidate for the next one? */ 00463 if (!ip4_addr_isany_val(dst)) { 00464 snmp_ip4_to_oid(&dst, &test_oid[0]); 00465 snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges), netif); 00466 } 00467 00468 netif = netif->next; 00469 } 00470 00471 /* did we find a next one? */ 00472 if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { 00473 ip4_addr_t dst; 00474 snmp_oid_to_ip4(&result_temp[0], &dst); 00475 snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); 00476 /* fill in object properties */ 00477 return ip_RouteTable_get_cell_value_core((struct netif*)state.reference, ip4_addr_isany_val(dst), column, value, value_len); 00478 } else { 00479 /* not found */ 00480 return SNMP_ERR_NOSUCHINSTANCE; 00481 } 00482 } 00483 00484 #if LWIP_ARP && LWIP_IPV4 00485 /* --- ipNetToMediaTable --- */ 00486 00487 /* list of allowed value ranges for incoming OID */ 00488 static const struct snmp_oid_range ip_NetToMediaTable_oid_ranges[] = { 00489 { 1, 0xff }, /* IfIndex */ 00490 { 0, 0xff }, /* IP A */ 00491 { 0, 0xff }, /* IP B */ 00492 { 0, 0xff }, /* IP C */ 00493 { 0, 0xff } /* IP D */ 00494 }; 00495 00496 static snmp_err_t 00497 ip_NetToMediaTable_get_cell_value_core(u8_t arp_table_index, const u32_t* column, union snmp_variant_value* value, u32_t* value_len) 00498 { 00499 ip4_addr_t *ip; 00500 struct netif *netif; 00501 struct eth_addr *ethaddr; 00502 00503 etharp_get_entry(arp_table_index, &ip, &netif, ðaddr); 00504 00505 /* value */ 00506 switch (*column) { 00507 case 1: /* atIfIndex / ipNetToMediaIfIndex */ 00508 value->u32 = netif_to_num(netif); 00509 break; 00510 case 2: /* atPhysAddress / ipNetToMediaPhysAddress */ 00511 value->ptr = ethaddr; 00512 *value_len = sizeof(*ethaddr); 00513 break; 00514 case 3: /* atNetAddress / ipNetToMediaNetAddress */ 00515 value->u32 = ip->addr; 00516 break; 00517 case 4: /* ipNetToMediaType */ 00518 value->u32 = 3; /* dynamic*/ 00519 break; 00520 default: 00521 return SNMP_ERR_NOSUCHINSTANCE; 00522 } 00523 00524 return SNMP_ERR_NOERROR; 00525 } 00526 00527 static snmp_err_t 00528 ip_NetToMediaTable_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) 00529 { 00530 ip4_addr_t ip_in; 00531 u8_t netif_index; 00532 u8_t i; 00533 00534 /* check if incoming OID length and if values are in plausible range */ 00535 if (!snmp_oid_in_range(row_oid, row_oid_len, ip_NetToMediaTable_oid_ranges, LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges))) { 00536 return SNMP_ERR_NOSUCHINSTANCE; 00537 } 00538 00539 /* get IP from incoming OID */ 00540 netif_index = (u8_t)row_oid[0]; 00541 snmp_oid_to_ip4(&row_oid[1], &ip_in); /* we know it succeeds because of oid_in_range check above */ 00542 00543 /* find requested entry */ 00544 for (i=0; i<ARP_TABLE_SIZE; i++) { 00545 ip4_addr_t *ip; 00546 struct netif *netif; 00547 struct eth_addr *ethaddr; 00548 00549 if (etharp_get_entry(i, &ip, &netif, ðaddr)) { 00550 if ((netif_index == netif_to_num(netif)) && ip4_addr_cmp(&ip_in, ip)) { 00551 /* fill in object properties */ 00552 return ip_NetToMediaTable_get_cell_value_core(i, column, value, value_len); 00553 } 00554 } 00555 } 00556 00557 /* not found */ 00558 return SNMP_ERR_NOSUCHINSTANCE; 00559 } 00560 00561 static snmp_err_t 00562 ip_NetToMediaTable_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) 00563 { 00564 u8_t i; 00565 struct snmp_next_oid_state state; 00566 u32_t result_temp[LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges)]; 00567 00568 /* init struct to search next oid */ 00569 snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges)); 00570 00571 /* iterate over all possible OIDs to find the next one */ 00572 for (i=0; i<ARP_TABLE_SIZE; i++) { 00573 ip4_addr_t *ip; 00574 struct netif *netif; 00575 struct eth_addr *ethaddr; 00576 00577 if (etharp_get_entry(i, &ip, &netif, ðaddr)) { 00578 u32_t test_oid[LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges)]; 00579 00580 test_oid[0] = netif_to_num(netif); 00581 snmp_ip4_to_oid(ip, &test_oid[1]); 00582 00583 /* check generated OID: is it a candidate for the next one? */ 00584 snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges), (void*)(size_t)i); 00585 } 00586 } 00587 00588 /* did we find a next one? */ 00589 if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { 00590 snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); 00591 /* fill in object properties */ 00592 return ip_NetToMediaTable_get_cell_value_core((u8_t)(size_t)state.reference, column, value, value_len); 00593 } 00594 00595 /* not found */ 00596 return SNMP_ERR_NOSUCHINSTANCE; 00597 } 00598 00599 #endif /* LWIP_ARP && LWIP_IPV4 */ 00600 00601 static const struct snmp_scalar_node ip_Forwarding = SNMP_SCALAR_CREATE_NODE(1, SNMP_NODE_INSTANCE_READ_WRITE, SNMP_ASN1_TYPE_INTEGER, ip_get_value , ip_set_test, ip_set_value); 00602 static const struct snmp_scalar_node ip_DefaultTTL = SNMP_SCALAR_CREATE_NODE(2, SNMP_NODE_INSTANCE_READ_WRITE, SNMP_ASN1_TYPE_INTEGER, ip_get_value , ip_set_test, ip_set_value); 00603 static const struct snmp_scalar_node ip_InReceives = SNMP_SCALAR_CREATE_NODE_READONLY(3, SNMP_ASN1_TYPE_COUNTER, ip_get_value ); 00604 static const struct snmp_scalar_node ip_InHdrErrors = SNMP_SCALAR_CREATE_NODE_READONLY(4, SNMP_ASN1_TYPE_COUNTER, ip_get_value ); 00605 static const struct snmp_scalar_node ip_InAddrErrors = SNMP_SCALAR_CREATE_NODE_READONLY(5, SNMP_ASN1_TYPE_COUNTER, ip_get_value ); 00606 static const struct snmp_scalar_node ip_ForwDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(6, SNMP_ASN1_TYPE_COUNTER, ip_get_value ); 00607 static const struct snmp_scalar_node ip_InUnknownProtos = SNMP_SCALAR_CREATE_NODE_READONLY(7, SNMP_ASN1_TYPE_COUNTER, ip_get_value ); 00608 static const struct snmp_scalar_node ip_InDiscards = SNMP_SCALAR_CREATE_NODE_READONLY(8, SNMP_ASN1_TYPE_COUNTER, ip_get_value ); 00609 static const struct snmp_scalar_node ip_InDelivers = SNMP_SCALAR_CREATE_NODE_READONLY(9, SNMP_ASN1_TYPE_COUNTER, ip_get_value ); 00610 static const struct snmp_scalar_node ip_OutRequests = SNMP_SCALAR_CREATE_NODE_READONLY(10, SNMP_ASN1_TYPE_COUNTER, ip_get_value ); 00611 static const struct snmp_scalar_node ip_OutDiscards = SNMP_SCALAR_CREATE_NODE_READONLY(11, SNMP_ASN1_TYPE_COUNTER, ip_get_value ); 00612 static const struct snmp_scalar_node ip_OutNoRoutes = SNMP_SCALAR_CREATE_NODE_READONLY(12, SNMP_ASN1_TYPE_COUNTER, ip_get_value ); 00613 static const struct snmp_scalar_node ip_ReasmTimeout = SNMP_SCALAR_CREATE_NODE_READONLY(13, SNMP_ASN1_TYPE_INTEGER, ip_get_value ); 00614 static const struct snmp_scalar_node ip_ReasmReqds = SNMP_SCALAR_CREATE_NODE_READONLY(14, SNMP_ASN1_TYPE_COUNTER, ip_get_value ); 00615 static const struct snmp_scalar_node ip_ReasmOKs = SNMP_SCALAR_CREATE_NODE_READONLY(15, SNMP_ASN1_TYPE_COUNTER, ip_get_value ); 00616 static const struct snmp_scalar_node ip_ReasmFails = SNMP_SCALAR_CREATE_NODE_READONLY(16, SNMP_ASN1_TYPE_COUNTER, ip_get_value ); 00617 static const struct snmp_scalar_node ip_FragOKs = SNMP_SCALAR_CREATE_NODE_READONLY(17, SNMP_ASN1_TYPE_COUNTER, ip_get_value ); 00618 static const struct snmp_scalar_node ip_FragFails = SNMP_SCALAR_CREATE_NODE_READONLY(18, SNMP_ASN1_TYPE_COUNTER, ip_get_value ); 00619 static const struct snmp_scalar_node ip_FragCreates = SNMP_SCALAR_CREATE_NODE_READONLY(19, SNMP_ASN1_TYPE_COUNTER, ip_get_value ); 00620 static const struct snmp_scalar_node ip_RoutingDiscards = SNMP_SCALAR_CREATE_NODE_READONLY(23, SNMP_ASN1_TYPE_COUNTER, ip_get_value ); 00621 00622 static const struct snmp_table_simple_col_def ip_AddrTable_columns[] = { 00623 { 1, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipAdEntAddr */ 00624 { 2, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipAdEntIfIndex */ 00625 { 3, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipAdEntNetMask */ 00626 { 4, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipAdEntBcastAddr */ 00627 { 5, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 } /* ipAdEntReasmMaxSize */ 00628 }; 00629 00630 static const struct snmp_table_simple_node ip_AddrTable = SNMP_TABLE_CREATE_SIMPLE(20, ip_AddrTable_columns, ip_AddrTable_get_cell_value, ip_AddrTable_get_next_cell_instance_and_value); 00631 00632 static const struct snmp_table_simple_col_def ip_RouteTable_columns[] = { 00633 { 1, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteDest */ 00634 { 2, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteIfIndex */ 00635 { 3, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_S32 }, /* ipRouteMetric1 */ 00636 { 4, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_S32 }, /* ipRouteMetric2 */ 00637 { 5, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_S32 }, /* ipRouteMetric3 */ 00638 { 6, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_S32 }, /* ipRouteMetric4 */ 00639 { 7, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteNextHop */ 00640 { 8, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteType */ 00641 { 9, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteProto */ 00642 { 10, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteAge */ 00643 { 11, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipRouteMask */ 00644 { 12, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_S32 }, /* ipRouteMetric5 */ 00645 { 13, SNMP_ASN1_TYPE_OBJECT_ID, SNMP_VARIANT_VALUE_TYPE_PTR } /* ipRouteInfo */ 00646 }; 00647 00648 static const struct snmp_table_simple_node ip_RouteTable = SNMP_TABLE_CREATE_SIMPLE(21, ip_RouteTable_columns, ip_RouteTable_get_cell_value, ip_RouteTable_get_next_cell_instance_and_value); 00649 #endif /* LWIP_IPV4 */ 00650 00651 #if LWIP_ARP && LWIP_IPV4 00652 static const struct snmp_table_simple_col_def ip_NetToMediaTable_columns[] = { 00653 { 1, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipNetToMediaIfIndex */ 00654 { 2, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_VARIANT_VALUE_TYPE_PTR }, /* ipNetToMediaPhysAddress */ 00655 { 3, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* ipNetToMediaNetAddress */ 00656 { 4, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 } /* ipNetToMediaType */ 00657 }; 00658 00659 static const struct snmp_table_simple_node ip_NetToMediaTable = SNMP_TABLE_CREATE_SIMPLE(22, ip_NetToMediaTable_columns, ip_NetToMediaTable_get_cell_value, ip_NetToMediaTable_get_next_cell_instance_and_value); 00660 #endif /* LWIP_ARP && LWIP_IPV4 */ 00661 00662 #if LWIP_IPV4 00663 /* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */ 00664 CREATE_LWIP_SYNC_NODE( 1, ip_Forwarding) 00665 CREATE_LWIP_SYNC_NODE( 2, ip_DefaultTTL) 00666 CREATE_LWIP_SYNC_NODE( 3, ip_InReceives) 00667 CREATE_LWIP_SYNC_NODE( 4, ip_InHdrErrors) 00668 CREATE_LWIP_SYNC_NODE( 5, ip_InAddrErrors) 00669 CREATE_LWIP_SYNC_NODE( 6, ip_ForwDatagrams) 00670 CREATE_LWIP_SYNC_NODE( 7, ip_InUnknownProtos) 00671 CREATE_LWIP_SYNC_NODE( 8, ip_InDiscards) 00672 CREATE_LWIP_SYNC_NODE( 9, ip_InDelivers) 00673 CREATE_LWIP_SYNC_NODE(10, ip_OutRequests) 00674 CREATE_LWIP_SYNC_NODE(11, ip_OutDiscards) 00675 CREATE_LWIP_SYNC_NODE(12, ip_OutNoRoutes) 00676 CREATE_LWIP_SYNC_NODE(13, ip_ReasmTimeout) 00677 CREATE_LWIP_SYNC_NODE(14, ip_ReasmReqds) 00678 CREATE_LWIP_SYNC_NODE(15, ip_ReasmOKs) 00679 CREATE_LWIP_SYNC_NODE(15, ip_ReasmFails) 00680 CREATE_LWIP_SYNC_NODE(17, ip_FragOKs) 00681 CREATE_LWIP_SYNC_NODE(18, ip_FragFails) 00682 CREATE_LWIP_SYNC_NODE(19, ip_FragCreates) 00683 CREATE_LWIP_SYNC_NODE(20, ip_AddrTable) 00684 CREATE_LWIP_SYNC_NODE(21, ip_RouteTable) 00685 #if LWIP_ARP 00686 CREATE_LWIP_SYNC_NODE(22, ip_NetToMediaTable) 00687 #endif /* LWIP_ARP */ 00688 CREATE_LWIP_SYNC_NODE(23, ip_RoutingDiscards) 00689 00690 static const struct snmp_node* const ip_nodes[] = { 00691 &SYNC_NODE_NAME(ip_Forwarding).node.node, 00692 &SYNC_NODE_NAME(ip_DefaultTTL).node.node, 00693 &SYNC_NODE_NAME(ip_InReceives).node.node, 00694 &SYNC_NODE_NAME(ip_InHdrErrors).node.node, 00695 &SYNC_NODE_NAME(ip_InAddrErrors).node.node, 00696 &SYNC_NODE_NAME(ip_ForwDatagrams).node.node, 00697 &SYNC_NODE_NAME(ip_InUnknownProtos).node.node, 00698 &SYNC_NODE_NAME(ip_InDiscards).node.node, 00699 &SYNC_NODE_NAME(ip_InDelivers).node.node, 00700 &SYNC_NODE_NAME(ip_OutRequests).node.node, 00701 &SYNC_NODE_NAME(ip_OutDiscards).node.node, 00702 &SYNC_NODE_NAME(ip_OutNoRoutes).node.node, 00703 &SYNC_NODE_NAME(ip_ReasmTimeout).node.node, 00704 &SYNC_NODE_NAME(ip_ReasmReqds).node.node, 00705 &SYNC_NODE_NAME(ip_ReasmOKs).node.node, 00706 &SYNC_NODE_NAME(ip_ReasmFails).node.node, 00707 &SYNC_NODE_NAME(ip_FragOKs).node.node, 00708 &SYNC_NODE_NAME(ip_FragFails).node.node, 00709 &SYNC_NODE_NAME(ip_FragCreates).node.node, 00710 &SYNC_NODE_NAME(ip_AddrTable).node.node, 00711 &SYNC_NODE_NAME(ip_RouteTable).node.node, 00712 #if LWIP_ARP 00713 &SYNC_NODE_NAME(ip_NetToMediaTable).node.node, 00714 #endif /* LWIP_ARP */ 00715 &SYNC_NODE_NAME(ip_RoutingDiscards).node.node 00716 }; 00717 00718 const struct snmp_tree_node snmp_mib2_ip_root = SNMP_CREATE_TREE_NODE(4, ip_nodes); 00719 #endif /* LWIP_IPV4 */ 00720 00721 /* --- at .1.3.6.1.2.1.3 ----------------------------------------------------- */ 00722 00723 #if LWIP_ARP && LWIP_IPV4 00724 /* at node table is a subset of ip_nettomedia table (same rows but less columns) */ 00725 static const struct snmp_table_simple_col_def at_Table_columns[] = { 00726 { 1, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* atIfIndex */ 00727 { 2, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_VARIANT_VALUE_TYPE_PTR }, /* atPhysAddress */ 00728 { 3, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 } /* atNetAddress */ 00729 }; 00730 00731 static const struct snmp_table_simple_node at_Table = SNMP_TABLE_CREATE_SIMPLE(1, at_Table_columns, ip_NetToMediaTable_get_cell_value, ip_NetToMediaTable_get_next_cell_instance_and_value); 00732 00733 /* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */ 00734 CREATE_LWIP_SYNC_NODE(1, at_Table) 00735 00736 static const struct snmp_node* const at_nodes[] = { 00737 &SYNC_NODE_NAME(at_Table).node.node 00738 }; 00739 00740 const struct snmp_tree_node snmp_mib2_at_root = SNMP_CREATE_TREE_NODE(3, at_nodes); 00741 #endif /* LWIP_ARP && LWIP_IPV4 */ 00742 00743 #endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */
Generated on Tue Jul 12 2022 13:15:54 by
