Ethernetwebsoc

Dependencies:   C12832_lcd LM75B WebSocketClient mbed-rtos mbed Socket lwip-eth lwip-sys lwip

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mib2.c Source File

mib2.c

Go to the documentation of this file.
00001 /**
00002  * @file
00003  * Management Information Base II (RFC1213) objects and functions.
00004  *
00005  * @note the object identifiers for this MIB-2 and private MIB tree
00006  * must be kept in sorted ascending order. This to ensure correct getnext operation.
00007  */
00008 
00009 /*
00010  * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without modification,
00014  * are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  * 2. Redistributions in binary form must reproduce the above copyright notice,
00019  *    this list of conditions and the following disclaimer in the documentation
00020  *    and/or other materials provided with the distribution.
00021  * 3. The name of the author may not be used to endorse or promote products
00022  *    derived from this software without specific prior written permission.
00023  *
00024  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00025  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00026  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00027  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00028  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00029  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00032  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00033  * OF SUCH DAMAGE.
00034  *
00035  * Author: Christiaan Simons <christiaan.simons@axon.tv>
00036  */
00037 
00038 #include "lwip/opt.h"
00039 
00040 #if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
00041 
00042 #include "lwip/snmp.h"
00043 #include "lwip/netif.h"
00044 #include "lwip/ip.h"
00045 #include "lwip/ip_frag.h"
00046 #include "lwip/mem.h"
00047 #include "lwip/tcp_impl.h"
00048 #include "lwip/udp.h"
00049 #include "lwip/snmp_asn1.h"
00050 #include "lwip/snmp_structs.h"
00051 #include "lwip/sys.h"
00052 #include "netif/etharp.h"
00053 
00054 /**
00055  * IANA assigned enterprise ID for lwIP is 26381
00056  * @see http://www.iana.org/assignments/enterprise-numbers
00057  *
00058  * @note this enterprise ID is assigned to the lwIP project,
00059  * all object identifiers living under this ID are assigned
00060  * by the lwIP maintainers (contact Christiaan Simons)!
00061  * @note don't change this define, use snmp_set_sysobjid()
00062  *
00063  * If you need to create your own private MIB you'll need
00064  * to apply for your own enterprise ID with IANA:
00065  * http://www.iana.org/numbers.html
00066  */
00067 #define SNMP_ENTERPRISE_ID 26381
00068 #define SNMP_SYSOBJID_LEN 7
00069 #define SNMP_SYSOBJID {1, 3, 6, 1, 4, 1, SNMP_ENTERPRISE_ID}
00070 
00071 #ifndef SNMP_SYSSERVICES
00072 #define SNMP_SYSSERVICES ((1 << 6) | (1 << 3) | ((IP_FORWARD) << 2))
00073 #endif
00074 
00075 #ifndef SNMP_GET_SYSUPTIME
00076 #define SNMP_GET_SYSUPTIME(sysuptime)
00077 #endif
00078 
00079 static void system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
00080 static void system_get_value(struct obj_def *od, u16_t len, void *value);
00081 static u8_t system_set_test(struct obj_def *od, u16_t len, void *value);
00082 static void system_set_value(struct obj_def *od, u16_t len, void *value);
00083 static void interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
00084 static void interfaces_get_value(struct obj_def *od, u16_t len, void *value);
00085 static void ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
00086 static void ifentry_get_value(struct obj_def *od, u16_t len, void *value);
00087 #if !SNMP_SAFE_REQUESTS
00088 static u8_t ifentry_set_test (struct obj_def *od, u16_t len, void *value);
00089 static void ifentry_set_value (struct obj_def *od, u16_t len, void *value);
00090 #endif /* SNMP_SAFE_REQUESTS */
00091 static void atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
00092 static void atentry_get_value(struct obj_def *od, u16_t len, void *value);
00093 static void ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
00094 static void ip_get_value (struct obj_def *od, u16_t len, void *value);
00095 static u8_t ip_set_test(struct obj_def *od, u16_t len, void *value);
00096 static void ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
00097 static void ip_addrentry_get_value (struct obj_def *od, u16_t len, void *value);
00098 static void ip_rteentry_get_object_def (u8_t ident_len, s32_t *ident, struct obj_def *od);
00099 static void ip_rteentry_get_value (struct obj_def *od, u16_t len, void *value);
00100 static void ip_ntomentry_get_object_def (u8_t ident_len, s32_t *ident, struct obj_def *od);
00101 static void ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value);
00102 static void icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
00103 static void icmp_get_value(struct obj_def *od, u16_t len, void *value);
00104 #if LWIP_TCP
00105 static void tcp_get_object_def (u8_t ident_len, s32_t *ident, struct obj_def *od);
00106 static void tcp_get_value(struct obj_def *od, u16_t len, void *value);
00107 #ifdef THIS_SEEMS_UNUSED
00108 static void tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
00109 static void tcpconnentry_get_value (struct obj_def *od, u16_t len, void *value);
00110 #endif
00111 #endif
00112 static void udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
00113 static void udp_get_value(struct obj_def *od, u16_t len, void *value);
00114 static void udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
00115 static void udpentry_get_value(struct obj_def *od, u16_t len, void *value);
00116 static void snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
00117 static void snmp_get_value(struct obj_def *od, u16_t len, void *value);
00118 static u8_t snmp_set_test(struct obj_def *od, u16_t len, void *value);
00119 static void snmp_set_value(struct obj_def *od, u16_t len, void *value);
00120 
00121 
00122 /* snmp .1.3.6.1.2.1.11 */
00123 const mib_scalar_node snmp_scalar = {
00124   &snmp_get_object_def,
00125   &snmp_get_value,
00126   &snmp_set_test,
00127   &snmp_set_value,
00128   MIB_NODE_SC,
00129   0
00130 };
00131 const s32_t snmp_ids[28] = {
00132   1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16,
00133   17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30
00134 };
00135 struct mib_node* const snmp_nodes[28] = {
00136   (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
00137   (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
00138   (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
00139   (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
00140   (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
00141   (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
00142   (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
00143   (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
00144   (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
00145   (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
00146   (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
00147   (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
00148   (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar,
00149   (struct mib_node*)&snmp_scalar, (struct mib_node*)&snmp_scalar
00150 };
00151 const struct mib_array_node snmp = {
00152   &noleafs_get_object_def,
00153   &noleafs_get_value,
00154   &noleafs_set_test,
00155   &noleafs_set_value,
00156   MIB_NODE_AR,
00157   28,
00158   snmp_ids,
00159   snmp_nodes
00160 };
00161 
00162 /* dot3 and EtherLike MIB not planned. (transmission .1.3.6.1.2.1.10) */
00163 /* historical (some say hysterical). (cmot .1.3.6.1.2.1.9) */
00164 /* lwIP has no EGP, thus may not implement it. (egp .1.3.6.1.2.1.8) */
00165 
00166 /* udp .1.3.6.1.2.1.7 */
00167 /** index root node for udpTable */
00168 struct mib_list_rootnode udp_root = {
00169   &noleafs_get_object_def,
00170   &noleafs_get_value,
00171   &noleafs_set_test,
00172   &noleafs_set_value,
00173   MIB_NODE_LR,
00174   0,
00175   NULL,
00176   NULL,
00177   0
00178 };
00179 const s32_t udpentry_ids[2] = { 1, 2 };
00180 struct mib_node* const udpentry_nodes[2] = {
00181   (struct mib_node*)&udp_root, (struct mib_node*)&udp_root,
00182 };
00183 const struct mib_array_node udpentry = {
00184   &noleafs_get_object_def,
00185   &noleafs_get_value,
00186   &noleafs_set_test,
00187   &noleafs_set_value,
00188   MIB_NODE_AR,
00189   2,
00190   udpentry_ids,
00191   udpentry_nodes
00192 };
00193 
00194 s32_t udptable_id = 1;
00195 struct mib_node* udptable_node = (struct mib_node*)&udpentry;
00196 struct mib_ram_array_node udptable = {
00197   &noleafs_get_object_def,
00198   &noleafs_get_value,
00199   &noleafs_set_test,
00200   &noleafs_set_value,
00201   MIB_NODE_RA,
00202   0,
00203   &udptable_id,
00204   &udptable_node
00205 };
00206 
00207 const mib_scalar_node udp_scalar = {
00208   &udp_get_object_def,
00209   &udp_get_value,
00210   &noleafs_set_test,
00211   &noleafs_set_value,
00212   MIB_NODE_SC,
00213   0
00214 };
00215 const s32_t udp_ids[5] = { 1, 2, 3, 4, 5 };
00216 struct mib_node* const udp_nodes[5] = {
00217   (struct mib_node*)&udp_scalar, (struct mib_node*)&udp_scalar,
00218   (struct mib_node*)&udp_scalar, (struct mib_node*)&udp_scalar,
00219   (struct mib_node*)&udptable
00220 };
00221 const struct mib_array_node udp = {
00222   &noleafs_get_object_def,
00223   &noleafs_get_value,
00224   &noleafs_set_test,
00225   &noleafs_set_value,
00226   MIB_NODE_AR,
00227   5,
00228   udp_ids,
00229   udp_nodes
00230 };
00231 
00232 /* tcp .1.3.6.1.2.1.6 */
00233 #if LWIP_TCP
00234 /* only if the TCP protocol is available may implement this group */
00235 /** index root node for tcpConnTable */
00236 struct mib_list_rootnode tcpconntree_root = {
00237   &noleafs_get_object_def,
00238   &noleafs_get_value,
00239   &noleafs_set_test,
00240   &noleafs_set_value,
00241   MIB_NODE_LR,
00242   0,
00243   NULL,
00244   NULL,
00245   0
00246 };
00247 const s32_t tcpconnentry_ids[5] = { 1, 2, 3, 4, 5 };
00248 struct mib_node* const tcpconnentry_nodes[5] = {
00249   (struct mib_node*)&tcpconntree_root, (struct mib_node*)&tcpconntree_root,
00250   (struct mib_node*)&tcpconntree_root, (struct mib_node*)&tcpconntree_root,
00251   (struct mib_node*)&tcpconntree_root
00252 };
00253 const struct mib_array_node tcpconnentry = {
00254   &noleafs_get_object_def,
00255   &noleafs_get_value,
00256   &noleafs_set_test,
00257   &noleafs_set_value,
00258   MIB_NODE_AR,
00259   5,
00260   tcpconnentry_ids,
00261   tcpconnentry_nodes
00262 };
00263 
00264 s32_t tcpconntable_id = 1;
00265 struct mib_node* tcpconntable_node = (struct mib_node*)&tcpconnentry;
00266 struct mib_ram_array_node tcpconntable = {
00267   &noleafs_get_object_def,
00268   &noleafs_get_value,
00269   &noleafs_set_test,
00270   &noleafs_set_value,
00271   MIB_NODE_RA,
00272 /** @todo update maxlength when inserting / deleting from table
00273    0 when table is empty, 1 when more than one entry */
00274   0,
00275   &tcpconntable_id,
00276   &tcpconntable_node
00277 };
00278 
00279 const mib_scalar_node tcp_scalar = {
00280   &tcp_get_object_def ,
00281   &tcp_get_value,
00282   &noleafs_set_test,
00283   &noleafs_set_value,
00284   MIB_NODE_SC,
00285   0
00286 };
00287 const s32_t tcp_ids[15] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
00288 struct mib_node* const tcp_nodes[15] = {
00289   (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar,
00290   (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar,
00291   (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar,
00292   (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar,
00293   (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar,
00294   (struct mib_node*)&tcp_scalar, (struct mib_node*)&tcp_scalar,
00295   (struct mib_node*)&tcpconntable, (struct mib_node*)&tcp_scalar,
00296   (struct mib_node*)&tcp_scalar
00297 };
00298 const struct mib_array_node tcp = {
00299   &noleafs_get_object_def,
00300   &noleafs_get_value,
00301   &noleafs_set_test,
00302   &noleafs_set_value,
00303   MIB_NODE_AR,
00304   15,
00305   tcp_ids,
00306   tcp_nodes
00307 };
00308 #endif
00309 
00310 /* icmp .1.3.6.1.2.1.5 */
00311 const mib_scalar_node icmp_scalar = {
00312   &icmp_get_object_def,
00313   &icmp_get_value,
00314   &noleafs_set_test,
00315   &noleafs_set_value,
00316   MIB_NODE_SC,
00317   0
00318 };
00319 const s32_t icmp_ids[26] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 };
00320 struct mib_node* const icmp_nodes[26] = {
00321   (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
00322   (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
00323   (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
00324   (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
00325   (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
00326   (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
00327   (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
00328   (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
00329   (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
00330   (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
00331   (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
00332   (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar,
00333   (struct mib_node*)&icmp_scalar, (struct mib_node*)&icmp_scalar
00334 };
00335 const struct mib_array_node icmp = {
00336   &noleafs_get_object_def,
00337   &noleafs_get_value,
00338   &noleafs_set_test,
00339   &noleafs_set_value,
00340   MIB_NODE_AR,
00341   26,
00342   icmp_ids,
00343   icmp_nodes
00344 };
00345 
00346 /** index root node for ipNetToMediaTable */
00347 struct mib_list_rootnode ipntomtree_root = {
00348   &noleafs_get_object_def,
00349   &noleafs_get_value,
00350   &noleafs_set_test,
00351   &noleafs_set_value,
00352   MIB_NODE_LR,
00353   0,
00354   NULL,
00355   NULL,
00356   0
00357 };
00358 const s32_t ipntomentry_ids[4] = { 1, 2, 3, 4 };
00359 struct mib_node* const ipntomentry_nodes[4] = {
00360   (struct mib_node*)&ipntomtree_root, (struct mib_node*)&ipntomtree_root,
00361   (struct mib_node*)&ipntomtree_root, (struct mib_node*)&ipntomtree_root
00362 };
00363 const struct mib_array_node ipntomentry = {
00364   &noleafs_get_object_def,
00365   &noleafs_get_value,
00366   &noleafs_set_test,
00367   &noleafs_set_value,
00368   MIB_NODE_AR,
00369   4,
00370   ipntomentry_ids,
00371   ipntomentry_nodes
00372 };
00373 
00374 s32_t ipntomtable_id = 1;
00375 struct mib_node* ipntomtable_node = (struct mib_node*)&ipntomentry;
00376 struct mib_ram_array_node ipntomtable = {
00377   &noleafs_get_object_def,
00378   &noleafs_get_value,
00379   &noleafs_set_test,
00380   &noleafs_set_value,
00381   MIB_NODE_RA,
00382   0,
00383   &ipntomtable_id,
00384   &ipntomtable_node
00385 };
00386 
00387 /** index root node for ipRouteTable */
00388 struct mib_list_rootnode iprtetree_root = {
00389   &noleafs_get_object_def,
00390   &noleafs_get_value,
00391   &noleafs_set_test,
00392   &noleafs_set_value,
00393   MIB_NODE_LR,
00394   0,
00395   NULL,
00396   NULL,
00397   0
00398 };
00399 const s32_t iprteentry_ids[13] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
00400 struct mib_node* const iprteentry_nodes[13] = {
00401   (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root,
00402   (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root,
00403   (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root,
00404   (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root,
00405   (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root,
00406   (struct mib_node*)&iprtetree_root, (struct mib_node*)&iprtetree_root,
00407   (struct mib_node*)&iprtetree_root
00408 };
00409 const struct mib_array_node iprteentry = {
00410   &noleafs_get_object_def,
00411   &noleafs_get_value,
00412   &noleafs_set_test,
00413   &noleafs_set_value,
00414   MIB_NODE_AR,
00415   13,
00416   iprteentry_ids,
00417   iprteentry_nodes
00418 };
00419 
00420 s32_t iprtetable_id = 1;
00421 struct mib_node* iprtetable_node = (struct mib_node*)&iprteentry;
00422 struct mib_ram_array_node iprtetable = {
00423   &noleafs_get_object_def,
00424   &noleafs_get_value,
00425   &noleafs_set_test,
00426   &noleafs_set_value,
00427   MIB_NODE_RA,
00428   0,
00429   &iprtetable_id,
00430   &iprtetable_node
00431 };
00432 
00433 /** index root node for ipAddrTable */
00434 struct mib_list_rootnode ipaddrtree_root = {
00435   &noleafs_get_object_def,
00436   &noleafs_get_value,
00437   &noleafs_set_test,
00438   &noleafs_set_value,
00439   MIB_NODE_LR,
00440   0,
00441   NULL,
00442   NULL,
00443   0
00444 };
00445 const s32_t ipaddrentry_ids[5] = { 1, 2, 3, 4, 5 };
00446 struct mib_node* const ipaddrentry_nodes[5] = {
00447   (struct mib_node*)&ipaddrtree_root,
00448   (struct mib_node*)&ipaddrtree_root,
00449   (struct mib_node*)&ipaddrtree_root,
00450   (struct mib_node*)&ipaddrtree_root,
00451   (struct mib_node*)&ipaddrtree_root
00452 };
00453 const struct mib_array_node ipaddrentry = {
00454   &noleafs_get_object_def,
00455   &noleafs_get_value,
00456   &noleafs_set_test,
00457   &noleafs_set_value,
00458   MIB_NODE_AR,
00459   5,
00460   ipaddrentry_ids,
00461   ipaddrentry_nodes
00462 };
00463 
00464 s32_t ipaddrtable_id = 1;
00465 struct mib_node* ipaddrtable_node = (struct mib_node*)&ipaddrentry;
00466 struct mib_ram_array_node ipaddrtable = {
00467   &noleafs_get_object_def,
00468   &noleafs_get_value,
00469   &noleafs_set_test,
00470   &noleafs_set_value,
00471   MIB_NODE_RA,
00472   0,
00473   &ipaddrtable_id,
00474   &ipaddrtable_node
00475 };
00476 
00477 /* ip .1.3.6.1.2.1.4 */
00478 const mib_scalar_node ip_scalar = {
00479   &ip_get_object_def,
00480   &ip_get_value ,
00481   &ip_set_test,
00482   &noleafs_set_value,
00483   MIB_NODE_SC,
00484   0
00485 };
00486 const s32_t ip_ids[23] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 };
00487 struct mib_node* const ip_nodes[23] = {
00488   (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
00489   (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
00490   (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
00491   (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
00492   (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
00493   (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
00494   (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
00495   (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
00496   (struct mib_node*)&ip_scalar, (struct mib_node*)&ip_scalar,
00497   (struct mib_node*)&ip_scalar, (struct mib_node*)&ipaddrtable,
00498   (struct mib_node*)&iprtetable, (struct mib_node*)&ipntomtable,
00499   (struct mib_node*)&ip_scalar
00500 };
00501 const struct mib_array_node mib2_ip = {
00502   &noleafs_get_object_def,
00503   &noleafs_get_value,
00504   &noleafs_set_test,
00505   &noleafs_set_value,
00506   MIB_NODE_AR,
00507   23,
00508   ip_ids,
00509   ip_nodes
00510 };
00511 
00512 /** index root node for atTable */
00513 struct mib_list_rootnode arptree_root = {
00514   &noleafs_get_object_def,
00515   &noleafs_get_value,
00516   &noleafs_set_test,
00517   &noleafs_set_value,
00518   MIB_NODE_LR,
00519   0,
00520   NULL,
00521   NULL,
00522   0
00523 };
00524 const s32_t atentry_ids[3] = { 1, 2, 3 };
00525 struct mib_node* const atentry_nodes[3] = {
00526   (struct mib_node*)&arptree_root,
00527   (struct mib_node*)&arptree_root,
00528   (struct mib_node*)&arptree_root
00529 };
00530 const struct mib_array_node atentry = {
00531   &noleafs_get_object_def,
00532   &noleafs_get_value,
00533   &noleafs_set_test,
00534   &noleafs_set_value,
00535   MIB_NODE_AR,
00536   3,
00537   atentry_ids,
00538   atentry_nodes
00539 };
00540 
00541 const s32_t attable_id = 1;
00542 struct mib_node* const attable_node = (struct mib_node*)&atentry;
00543 const struct mib_array_node attable = {
00544   &noleafs_get_object_def,
00545   &noleafs_get_value,
00546   &noleafs_set_test,
00547   &noleafs_set_value,
00548   MIB_NODE_AR,
00549   1,
00550   &attable_id,
00551   &attable_node
00552 };
00553 
00554 /* at .1.3.6.1.2.1.3 */
00555 s32_t at_id = 1;
00556 struct mib_node* mib2_at_node = (struct mib_node*)&attable;
00557 struct mib_ram_array_node at = {
00558   &noleafs_get_object_def,
00559   &noleafs_get_value,
00560   &noleafs_set_test,
00561   &noleafs_set_value,
00562   MIB_NODE_RA,
00563   0,
00564   &at_id,
00565   &mib2_at_node
00566 };
00567 
00568 /** index root node for ifTable */
00569 struct mib_list_rootnode iflist_root = {
00570   &ifentry_get_object_def,
00571   &ifentry_get_value,
00572 #if SNMP_SAFE_REQUESTS
00573   &noleafs_set_test,
00574   &noleafs_set_value,
00575 #else /* SNMP_SAFE_REQUESTS */
00576   &ifentry_set_test,
00577   &ifentry_set_value,
00578 #endif /* SNMP_SAFE_REQUESTS */
00579   MIB_NODE_LR,
00580   0,
00581   NULL,
00582   NULL,
00583   0
00584 };
00585 const s32_t ifentry_ids[22] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 };
00586 struct mib_node* const ifentry_nodes[22] = {
00587   (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
00588   (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
00589   (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
00590   (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
00591   (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
00592   (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
00593   (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
00594   (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
00595   (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
00596   (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root,
00597   (struct mib_node*)&iflist_root, (struct mib_node*)&iflist_root
00598 };
00599 const struct mib_array_node ifentry = {
00600   &noleafs_get_object_def,
00601   &noleafs_get_value,
00602   &noleafs_set_test,
00603   &noleafs_set_value,
00604   MIB_NODE_AR,
00605   22,
00606   ifentry_ids,
00607   ifentry_nodes
00608 };
00609 
00610 s32_t iftable_id = 1;
00611 struct mib_node* iftable_node = (struct mib_node*)&ifentry;
00612 struct mib_ram_array_node iftable = {
00613   &noleafs_get_object_def,
00614   &noleafs_get_value,
00615   &noleafs_set_test,
00616   &noleafs_set_value,
00617   MIB_NODE_RA,
00618   0,
00619   &iftable_id,
00620   &iftable_node
00621 };
00622 
00623 /* interfaces .1.3.6.1.2.1.2 */
00624 const mib_scalar_node interfaces_scalar = {
00625   &interfaces_get_object_def,
00626   &interfaces_get_value,
00627   &noleafs_set_test,
00628   &noleafs_set_value,
00629   MIB_NODE_SC,
00630   0
00631 };
00632 const s32_t interfaces_ids[2] = { 1, 2 };
00633 struct mib_node* const interfaces_nodes[2] = {
00634   (struct mib_node*)&interfaces_scalar, (struct mib_node*)&iftable
00635 };
00636 const struct mib_array_node interfaces = {
00637   &noleafs_get_object_def,
00638   &noleafs_get_value,
00639   &noleafs_set_test,
00640   &noleafs_set_value,
00641   MIB_NODE_AR,
00642   2,
00643   interfaces_ids,
00644   interfaces_nodes
00645 };
00646 
00647 
00648 /*             0 1 2 3 4 5 6 */
00649 /* system .1.3.6.1.2.1.1 */
00650 const mib_scalar_node sys_tem_scalar = {
00651   &system_get_object_def,
00652   &system_get_value,
00653   &system_set_test,
00654   &system_set_value,
00655   MIB_NODE_SC,
00656   0
00657 };
00658 const s32_t sys_tem_ids[7] = { 1, 2, 3, 4, 5, 6, 7 };
00659 struct mib_node* const sys_tem_nodes[7] = {
00660   (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar,
00661   (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar,
00662   (struct mib_node*)&sys_tem_scalar, (struct mib_node*)&sys_tem_scalar,
00663   (struct mib_node*)&sys_tem_scalar
00664 };
00665 /* work around name issue with 'sys_tem', some compiler(s?) seem to reserve 'system' */
00666 const struct mib_array_node sys_tem = {
00667   &noleafs_get_object_def,
00668   &noleafs_get_value,
00669   &noleafs_set_test,
00670   &noleafs_set_value,
00671   MIB_NODE_AR,
00672   7,
00673   sys_tem_ids,
00674   sys_tem_nodes
00675 };
00676 
00677 /* mib-2 .1.3.6.1.2.1 */
00678 #if LWIP_TCP
00679 #define MIB2_GROUPS 8
00680 #else
00681 #define MIB2_GROUPS 7
00682 #endif
00683 const s32_t mib2_ids[MIB2_GROUPS] =
00684 {
00685   1,
00686   2,
00687   3,
00688   4,
00689   5,
00690 #if LWIP_TCP
00691   6,
00692 #endif
00693   7,
00694   11
00695 };
00696 struct mib_node* const mib2_nodes[MIB2_GROUPS] = {
00697   (struct mib_node*)&sys_tem,
00698   (struct mib_node*)&interfaces,
00699   (struct mib_node*)&at,
00700   (struct mib_node*)&mib2_ip,
00701   (struct mib_node*)&icmp,
00702 #if LWIP_TCP
00703   (struct mib_node*)&tcp,
00704 #endif
00705   (struct mib_node*)&udp,
00706   (struct mib_node*)&snmp
00707 };
00708 
00709 const struct mib_array_node mib2 = {
00710   &noleafs_get_object_def,
00711   &noleafs_get_value,
00712   &noleafs_set_test,
00713   &noleafs_set_value,
00714   MIB_NODE_AR,
00715   MIB2_GROUPS,
00716   mib2_ids,
00717   mib2_nodes
00718 };
00719 
00720 /* mgmt .1.3.6.1.2 */
00721 const s32_t mgmt_ids[1] = { 1 };
00722 struct mib_node* const mgmt_nodes[1] = { (struct mib_node*)&mib2 };
00723 const struct mib_array_node mgmt = {
00724   &noleafs_get_object_def,
00725   &noleafs_get_value,
00726   &noleafs_set_test,
00727   &noleafs_set_value,
00728   MIB_NODE_AR,
00729   1,
00730   mgmt_ids,
00731   mgmt_nodes
00732 };
00733 
00734 /* internet .1.3.6.1 */
00735 #if SNMP_PRIVATE_MIB
00736 /* When using a private MIB, you have to create a file 'private_mib.h' that contains
00737  * a 'struct mib_array_node mib_private' which contains your MIB. */
00738 s32_t internet_ids[2] = { 2, 4 };
00739 struct mib_node* const internet_nodes[2] = { (struct mib_node*)&mgmt, (struct mib_node*)&mib_private };
00740 const struct mib_array_node internet = {
00741   &noleafs_get_object_def,
00742   &noleafs_get_value,
00743   &noleafs_set_test,
00744   &noleafs_set_value,
00745   MIB_NODE_AR,
00746   2,
00747   internet_ids,
00748   internet_nodes
00749 };
00750 #else
00751 const s32_t internet_ids[1] = { 2 };
00752 struct mib_node* const internet_nodes[1] = { (struct mib_node*)&mgmt };
00753 const struct mib_array_node internet = {
00754   &noleafs_get_object_def,
00755   &noleafs_get_value,
00756   &noleafs_set_test,
00757   &noleafs_set_value,
00758   MIB_NODE_AR,
00759   1,
00760   internet_ids,
00761   internet_nodes
00762 };
00763 #endif
00764 
00765 /** mib-2.system.sysObjectID  */
00766 static struct snmp_obj_id sysobjid = {SNMP_SYSOBJID_LEN, SNMP_SYSOBJID};
00767 /** enterprise ID for generic TRAPs, .iso.org.dod.internet.mgmt.mib-2.snmp */
00768 static struct snmp_obj_id snmpgrp_id = {7,{1,3,6,1,2,1,11}};
00769 /** mib-2.system.sysServices */
00770 static const s32_t sysservices = SNMP_SYSSERVICES;
00771 
00772 /** mib-2.system.sysDescr */
00773 static const u8_t sysdescr_len_default = 4;
00774 static const u8_t sysdescr_default[] = "lwIP";
00775 static u8_t* sysdescr_len_ptr = (u8_t*)&sysdescr_len_default;
00776 static u8_t* sysdescr_ptr = (u8_t*)&sysdescr_default[0];
00777 /** mib-2.system.sysContact */
00778 static const u8_t syscontact_len_default = 0;
00779 static const u8_t syscontact_default[] = "";
00780 static u8_t* syscontact_len_ptr = (u8_t*)&syscontact_len_default;
00781 static u8_t* syscontact_ptr = (u8_t*)&syscontact_default[0];
00782 /** mib-2.system.sysName */
00783 static const u8_t sysname_len_default = 8;
00784 static const u8_t sysname_default[] = "FQDN-unk";
00785 static u8_t* sysname_len_ptr = (u8_t*)&sysname_len_default;
00786 static u8_t* sysname_ptr = (u8_t*)&sysname_default[0];
00787 /** mib-2.system.sysLocation */
00788 static const u8_t syslocation_len_default = 0;
00789 static const u8_t syslocation_default[] = "";
00790 static u8_t* syslocation_len_ptr = (u8_t*)&syslocation_len_default;
00791 static u8_t* syslocation_ptr = (u8_t*)&syslocation_default[0];
00792 /** mib-2.snmp.snmpEnableAuthenTraps */
00793 static const u8_t snmpenableauthentraps_default = 2; /* disabled */
00794 static u8_t* snmpenableauthentraps_ptr = (u8_t*)&snmpenableauthentraps_default;
00795 
00796 /** mib-2.interfaces.ifTable.ifEntry.ifSpecific (zeroDotZero) */
00797 static const struct snmp_obj_id ifspecific = {2, {0, 0}};
00798 /** mib-2.ip.ipRouteTable.ipRouteEntry.ipRouteInfo (zeroDotZero) */
00799 static const struct snmp_obj_id iprouteinfo = {2, {0, 0}};
00800 
00801 
00802 
00803 /* mib-2.system counter(s) */
00804 static u32_t sysuptime = 0;
00805 
00806 /* mib-2.ip counter(s) */
00807 static u32_t ipinreceives = 0,
00808              ipinhdrerrors = 0,
00809              ipinaddrerrors = 0,
00810              ipforwdatagrams = 0,
00811              ipinunknownprotos = 0,
00812              ipindiscards = 0,
00813              ipindelivers = 0,
00814              ipoutrequests = 0,
00815              ipoutdiscards = 0,
00816              ipoutnoroutes = 0,
00817              ipreasmreqds = 0,
00818              ipreasmoks = 0,
00819              ipreasmfails = 0,
00820              ipfragoks = 0,
00821              ipfragfails = 0,
00822              ipfragcreates = 0,
00823              iproutingdiscards = 0;
00824 /* mib-2.icmp counter(s) */
00825 static u32_t icmpinmsgs = 0,
00826              icmpinerrors = 0,
00827              icmpindestunreachs = 0,
00828              icmpintimeexcds = 0,
00829              icmpinparmprobs = 0,
00830              icmpinsrcquenchs = 0,
00831              icmpinredirects = 0,
00832              icmpinechos = 0,
00833              icmpinechoreps = 0,
00834              icmpintimestamps = 0,
00835              icmpintimestampreps = 0,
00836              icmpinaddrmasks = 0,
00837              icmpinaddrmaskreps = 0,
00838              icmpoutmsgs = 0,
00839              icmpouterrors = 0,
00840              icmpoutdestunreachs = 0,
00841              icmpouttimeexcds = 0,
00842              icmpoutparmprobs = 0,
00843              icmpoutsrcquenchs = 0,
00844              icmpoutredirects = 0,
00845              icmpoutechos = 0,
00846              icmpoutechoreps = 0,
00847              icmpouttimestamps = 0,
00848              icmpouttimestampreps = 0,
00849              icmpoutaddrmasks = 0,
00850              icmpoutaddrmaskreps = 0;
00851 /* mib-2.tcp counter(s) */
00852 static u32_t tcpactiveopens = 0,
00853              tcppassiveopens = 0,
00854              tcpattemptfails = 0,
00855              tcpestabresets = 0,
00856              tcpinsegs = 0,
00857              tcpoutsegs = 0,
00858              tcpretranssegs = 0,
00859              tcpinerrs = 0,
00860              tcpoutrsts = 0;
00861 /* mib-2.udp counter(s) */
00862 static u32_t udpindatagrams = 0,
00863              udpnoports = 0,
00864              udpinerrors = 0,
00865              udpoutdatagrams = 0;
00866 /* mib-2.snmp counter(s) */
00867 static u32_t snmpinpkts = 0,
00868              snmpoutpkts = 0,
00869              snmpinbadversions = 0,
00870              snmpinbadcommunitynames = 0,
00871              snmpinbadcommunityuses = 0,
00872              snmpinasnparseerrs = 0,
00873              snmpintoobigs = 0,
00874              snmpinnosuchnames = 0,
00875              snmpinbadvalues = 0,
00876              snmpinreadonlys = 0,
00877              snmpingenerrs = 0,
00878              snmpintotalreqvars = 0,
00879              snmpintotalsetvars = 0,
00880              snmpingetrequests = 0,
00881              snmpingetnexts = 0,
00882              snmpinsetrequests = 0,
00883              snmpingetresponses = 0,
00884              snmpintraps = 0,
00885              snmpouttoobigs = 0,
00886              snmpoutnosuchnames = 0,
00887              snmpoutbadvalues = 0,
00888              snmpoutgenerrs = 0,
00889              snmpoutgetrequests = 0,
00890              snmpoutgetnexts = 0,
00891              snmpoutsetrequests = 0,
00892              snmpoutgetresponses = 0,
00893              snmpouttraps = 0;
00894 
00895 
00896 
00897 /* prototypes of the following functions are in lwip/src/include/lwip/snmp.h */
00898 /**
00899  * Copy octet string.
00900  *
00901  * @param dst points to destination
00902  * @param src points to source
00903  * @param n number of octets to copy.
00904  */
00905 static void ocstrncpy(u8_t *dst, u8_t *src, u16_t n)
00906 {
00907   u16_t i = n;
00908   while (i > 0) {
00909     i--;
00910     *dst++ = *src++;
00911   }
00912 }
00913 
00914 /**
00915  * Copy object identifier (s32_t) array.
00916  *
00917  * @param dst points to destination
00918  * @param src points to source
00919  * @param n number of sub identifiers to copy.
00920  */
00921 void objectidncpy(s32_t *dst, s32_t *src, u8_t n)
00922 {
00923   u8_t i = n;
00924   while(i > 0) {
00925     i--;
00926     *dst++ = *src++;
00927   }
00928 }
00929 
00930 /**
00931  * Initializes sysDescr pointers.
00932  *
00933  * @param str if non-NULL then copy str pointer
00934  * @param len points to string length, excluding zero terminator
00935  */
00936 void snmp_set_sysdesr(u8_t *str, u8_t *len)
00937 {
00938   if (str != NULL)
00939   {
00940     sysdescr_ptr = str;
00941     sysdescr_len_ptr = len;
00942   }
00943 }
00944 
00945 void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid)
00946 {
00947   *oid = &sysobjid;
00948 }
00949 
00950 /**
00951  * Initializes sysObjectID value.
00952  *
00953  * @param oid points to stuct snmp_obj_id to copy
00954  */
00955 void snmp_set_sysobjid(struct snmp_obj_id *oid)
00956 {
00957   sysobjid = *oid;
00958 }
00959 
00960 /**
00961  * Must be called at regular 10 msec interval from a timer interrupt
00962  * or signal handler depending on your runtime environment.
00963  */
00964 void snmp_inc_sysuptime(void)
00965 {
00966   sysuptime++;
00967 }
00968 
00969 void snmp_add_sysuptime(u32_t value)
00970 {
00971   sysuptime+=value;
00972 }
00973 
00974 void snmp_get_sysuptime(u32_t *value)
00975 {
00976   SNMP_GET_SYSUPTIME(sysuptime);
00977   *value = sysuptime;
00978 }
00979 
00980 /**
00981  * Initializes sysContact pointers,
00982  * e.g. ptrs to non-volatile memory external to lwIP.
00983  *
00984  * @param ocstr if non-NULL then copy str pointer
00985  * @param ocstrlen points to string length, excluding zero terminator
00986  */
00987 void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen)
00988 {
00989   if (ocstr != NULL)
00990   {
00991     syscontact_ptr = ocstr;
00992     syscontact_len_ptr = ocstrlen;
00993   }
00994 }
00995 
00996 /**
00997  * Initializes sysName pointers,
00998  * e.g. ptrs to non-volatile memory external to lwIP.
00999  *
01000  * @param ocstr if non-NULL then copy str pointer
01001  * @param ocstrlen points to string length, excluding zero terminator
01002  */
01003 void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen)
01004 {
01005   if (ocstr != NULL)
01006   {
01007     sysname_ptr = ocstr;
01008     sysname_len_ptr = ocstrlen;
01009   }
01010 }
01011 
01012 /**
01013  * Initializes sysLocation pointers,
01014  * e.g. ptrs to non-volatile memory external to lwIP.
01015  *
01016  * @param ocstr if non-NULL then copy str pointer
01017  * @param ocstrlen points to string length, excluding zero terminator
01018  */
01019 void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen)
01020 {
01021   if (ocstr != NULL)
01022   {
01023     syslocation_ptr = ocstr;
01024     syslocation_len_ptr = ocstrlen;
01025   }
01026 }
01027 
01028 
01029 void snmp_add_ifinoctets(struct netif *ni, u32_t value)
01030 {
01031   ni->ifinoctets += value;
01032 }
01033 
01034 void snmp_inc_ifinucastpkts(struct netif *ni)
01035 {
01036   (ni->ifinucastpkts)++;
01037 }
01038 
01039 void snmp_inc_ifinnucastpkts(struct netif *ni)
01040 {
01041   (ni->ifinnucastpkts)++;
01042 }
01043 
01044 void snmp_inc_ifindiscards(struct netif *ni)
01045 {
01046   (ni->ifindiscards)++;
01047 }
01048 
01049 void snmp_add_ifoutoctets(struct netif *ni, u32_t value)
01050 {
01051   ni->ifoutoctets += value;
01052 }
01053 
01054 void snmp_inc_ifoutucastpkts(struct netif *ni)
01055 {
01056   (ni->ifoutucastpkts)++;
01057 }
01058 
01059 void snmp_inc_ifoutnucastpkts(struct netif *ni)
01060 {
01061   (ni->ifoutnucastpkts)++;
01062 }
01063 
01064 void snmp_inc_ifoutdiscards(struct netif *ni)
01065 {
01066   (ni->ifoutdiscards)++;
01067 }
01068 
01069 void snmp_inc_iflist(void)
01070 {
01071   struct mib_list_node *if_node = NULL;
01072 
01073   snmp_mib_node_insert(&iflist_root, iflist_root.count + 1, &if_node);
01074   /* enable getnext traversal on filled table */
01075   iftable.maxlength = 1;
01076 }
01077 
01078 void snmp_dec_iflist(void)
01079 {
01080   snmp_mib_node_delete(&iflist_root, iflist_root.tail);
01081   /* disable getnext traversal on empty table */
01082   if(iflist_root.count == 0) iftable.maxlength = 0;
01083 }
01084 
01085 /**
01086  * Inserts ARP table indexes (.xIfIndex.xNetAddress)
01087  * into arp table index trees (both atTable and ipNetToMediaTable).
01088  */
01089 void snmp_insert_arpidx_tree(struct netif *ni, ip_addr_t *ip)
01090 {
01091   struct mib_list_rootnode *at_rn;
01092   struct mib_list_node *at_node;
01093   s32_t arpidx[5];
01094   u8_t level, tree;
01095 
01096   LWIP_ASSERT("ni != NULL", ni != NULL);
01097   snmp_netiftoifindex(ni, &arpidx[0]);
01098   snmp_iptooid(ip, &arpidx[1]);
01099 
01100   for (tree = 0; tree < 2; tree++)
01101   {
01102     if (tree == 0)
01103     {
01104       at_rn = &arptree_root;
01105     }
01106     else
01107     {
01108       at_rn = &ipntomtree_root;
01109     }
01110     for (level = 0; level < 5; level++)
01111     {
01112       at_node = NULL;
01113       snmp_mib_node_insert(at_rn, arpidx[level], &at_node);
01114       if ((level != 4) && (at_node != NULL))
01115       {
01116         if (at_node->nptr == NULL)
01117         {
01118           at_rn = snmp_mib_lrn_alloc();
01119           at_node->nptr = (struct mib_node*)at_rn;
01120           if (at_rn != NULL)
01121           {
01122             if (level == 3)
01123             {
01124               if (tree == 0)
01125               {
01126                 at_rn->get_object_def = atentry_get_object_def;
01127                 at_rn->get_value = atentry_get_value;
01128               }
01129               else
01130               {
01131                 at_rn->get_object_def = ip_ntomentry_get_object_def ;
01132                 at_rn->get_value = ip_ntomentry_get_value;
01133               }
01134               at_rn->set_test = noleafs_set_test;
01135               at_rn->set_value = noleafs_set_value;
01136             }
01137           }
01138           else
01139           {
01140             /* at_rn == NULL, malloc failure */
01141             LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_arpidx_tree() insert failed, mem full"));
01142             break;
01143           }
01144         }
01145         else
01146         {
01147           at_rn = (struct mib_list_rootnode*)at_node->nptr;
01148         }
01149       }
01150     }
01151   }
01152   /* enable getnext traversal on filled tables */
01153   at.maxlength = 1;
01154   ipntomtable.maxlength = 1;
01155 }
01156 
01157 /**
01158  * Removes ARP table indexes (.xIfIndex.xNetAddress)
01159  * from arp table index trees.
01160  */
01161 void snmp_delete_arpidx_tree(struct netif *ni, ip_addr_t *ip)
01162 {
01163   struct mib_list_rootnode *at_rn, *next, *del_rn[5];
01164   struct mib_list_node *at_n, *del_n[5];
01165   s32_t arpidx[5];
01166   u8_t fc, tree, level, del_cnt;
01167 
01168   snmp_netiftoifindex(ni, &arpidx[0]);
01169   snmp_iptooid(ip, &arpidx[1]);
01170 
01171   for (tree = 0; tree < 2; tree++)
01172   {
01173     /* mark nodes for deletion */
01174     if (tree == 0)
01175     {
01176       at_rn = &arptree_root;
01177     }
01178     else
01179     {
01180       at_rn = &ipntomtree_root;
01181     }
01182     level = 0;
01183     del_cnt = 0;
01184     while ((level < 5) && (at_rn != NULL))
01185     {
01186       fc = snmp_mib_node_find(at_rn, arpidx[level], &at_n);
01187       if (fc == 0)
01188       {
01189         /* arpidx[level] does not exist */
01190         del_cnt = 0;
01191         at_rn = NULL;
01192       }
01193       else if (fc == 1)
01194       {
01195         del_rn[del_cnt] = at_rn;
01196         del_n[del_cnt] = at_n;
01197         del_cnt++;
01198         at_rn = (struct mib_list_rootnode*)(at_n->nptr);
01199       }
01200       else if (fc == 2)
01201       {
01202         /* reset delete (2 or more childs) */
01203         del_cnt = 0;
01204         at_rn = (struct mib_list_rootnode*)(at_n->nptr);
01205       }
01206       level++;
01207     }
01208     /* delete marked index nodes */
01209     while (del_cnt > 0)
01210     {
01211       del_cnt--;
01212 
01213       at_rn = del_rn[del_cnt];
01214       at_n = del_n[del_cnt];
01215 
01216       next = snmp_mib_node_delete(at_rn, at_n);
01217       if (next != NULL)
01218       {
01219         LWIP_ASSERT("next_count == 0",next->count == 0);
01220         snmp_mib_lrn_free(next);
01221       }
01222     }
01223   }
01224   /* disable getnext traversal on empty tables */
01225   if(arptree_root.count == 0) at.maxlength = 0;
01226   if(ipntomtree_root.count == 0) ipntomtable.maxlength = 0;
01227 }
01228 
01229 void snmp_inc_ipinreceives(void)
01230 {
01231   ipinreceives++;
01232 }
01233 
01234 void snmp_inc_ipinhdrerrors(void)
01235 {
01236   ipinhdrerrors++;
01237 }
01238 
01239 void snmp_inc_ipinaddrerrors(void)
01240 {
01241   ipinaddrerrors++;
01242 }
01243 
01244 void snmp_inc_ipforwdatagrams(void)
01245 {
01246   ipforwdatagrams++;
01247 }
01248 
01249 void snmp_inc_ipinunknownprotos(void)
01250 {
01251   ipinunknownprotos++;
01252 }
01253 
01254 void snmp_inc_ipindiscards(void)
01255 {
01256   ipindiscards++;
01257 }
01258 
01259 void snmp_inc_ipindelivers(void)
01260 {
01261   ipindelivers++;
01262 }
01263 
01264 void snmp_inc_ipoutrequests(void)
01265 {
01266   ipoutrequests++;
01267 }
01268 
01269 void snmp_inc_ipoutdiscards(void)
01270 {
01271   ipoutdiscards++;
01272 }
01273 
01274 void snmp_inc_ipoutnoroutes(void)
01275 {
01276   ipoutnoroutes++;
01277 }
01278 
01279 void snmp_inc_ipreasmreqds(void)
01280 {
01281   ipreasmreqds++;
01282 }
01283 
01284 void snmp_inc_ipreasmoks(void)
01285 {
01286   ipreasmoks++;
01287 }
01288 
01289 void snmp_inc_ipreasmfails(void)
01290 {
01291   ipreasmfails++;
01292 }
01293 
01294 void snmp_inc_ipfragoks(void)
01295 {
01296   ipfragoks++;
01297 }
01298 
01299 void snmp_inc_ipfragfails(void)
01300 {
01301   ipfragfails++;
01302 }
01303 
01304 void snmp_inc_ipfragcreates(void)
01305 {
01306   ipfragcreates++;
01307 }
01308 
01309 void snmp_inc_iproutingdiscards(void)
01310 {
01311   iproutingdiscards++;
01312 }
01313 
01314 /**
01315  * Inserts ipAddrTable indexes (.ipAdEntAddr)
01316  * into index tree.
01317  */
01318 void snmp_insert_ipaddridx_tree(struct netif *ni)
01319 {
01320   struct mib_list_rootnode *ipa_rn;
01321   struct mib_list_node *ipa_node;
01322   s32_t ipaddridx[4];
01323   u8_t level;
01324 
01325   LWIP_ASSERT("ni != NULL", ni != NULL);
01326   snmp_iptooid(&ni->ip_addr, &ipaddridx[0]);
01327 
01328   level = 0;
01329   ipa_rn = &ipaddrtree_root;
01330   while (level < 4)
01331   {
01332     ipa_node = NULL;
01333     snmp_mib_node_insert(ipa_rn, ipaddridx[level], &ipa_node);
01334     if ((level != 3) && (ipa_node != NULL))
01335     {
01336       if (ipa_node->nptr == NULL)
01337       {
01338         ipa_rn = snmp_mib_lrn_alloc();
01339         ipa_node->nptr = (struct mib_node*)ipa_rn;
01340         if (ipa_rn != NULL)
01341         {
01342           if (level == 2)
01343           {
01344             ipa_rn->get_object_def = ip_addrentry_get_object_def;
01345             ipa_rn->get_value = ip_addrentry_get_value ;
01346             ipa_rn->set_test = noleafs_set_test;
01347             ipa_rn->set_value = noleafs_set_value;
01348           }
01349         }
01350         else
01351         {
01352           /* ipa_rn == NULL, malloc failure */
01353           LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_ipaddridx_tree() insert failed, mem full"));
01354           break;
01355         }
01356       }
01357       else
01358       {
01359         ipa_rn = (struct mib_list_rootnode*)ipa_node->nptr;
01360       }
01361     }
01362     level++;
01363   }
01364   /* enable getnext traversal on filled table */
01365   ipaddrtable.maxlength = 1;
01366 }
01367 
01368 /**
01369  * Removes ipAddrTable indexes (.ipAdEntAddr)
01370  * from index tree.
01371  */
01372 void snmp_delete_ipaddridx_tree(struct netif *ni)
01373 {
01374   struct mib_list_rootnode *ipa_rn, *next, *del_rn[4];
01375   struct mib_list_node *ipa_n, *del_n[4];
01376   s32_t ipaddridx[4];
01377   u8_t fc, level, del_cnt;
01378 
01379   LWIP_ASSERT("ni != NULL", ni != NULL);
01380   snmp_iptooid(&ni->ip_addr, &ipaddridx[0]);
01381 
01382   /* mark nodes for deletion */
01383   level = 0;
01384   del_cnt = 0;
01385   ipa_rn = &ipaddrtree_root;
01386   while ((level < 4) && (ipa_rn != NULL))
01387   {
01388     fc = snmp_mib_node_find(ipa_rn, ipaddridx[level], &ipa_n);
01389     if (fc == 0)
01390     {
01391       /* ipaddridx[level] does not exist */
01392       del_cnt = 0;
01393       ipa_rn = NULL;
01394     }
01395     else if (fc == 1)
01396     {
01397       del_rn[del_cnt] = ipa_rn;
01398       del_n[del_cnt] = ipa_n;
01399       del_cnt++;
01400       ipa_rn = (struct mib_list_rootnode*)(ipa_n->nptr);
01401     }
01402     else if (fc == 2)
01403     {
01404       /* reset delete (2 or more childs) */
01405       del_cnt = 0;
01406       ipa_rn = (struct mib_list_rootnode*)(ipa_n->nptr);
01407     }
01408     level++;
01409   }
01410   /* delete marked index nodes */
01411   while (del_cnt > 0)
01412   {
01413     del_cnt--;
01414 
01415     ipa_rn = del_rn[del_cnt];
01416     ipa_n = del_n[del_cnt];
01417 
01418     next = snmp_mib_node_delete(ipa_rn, ipa_n);
01419     if (next != NULL)
01420     {
01421       LWIP_ASSERT("next_count == 0",next->count == 0);
01422       snmp_mib_lrn_free(next);
01423     }
01424   }
01425   /* disable getnext traversal on empty table */
01426   if (ipaddrtree_root.count == 0) ipaddrtable.maxlength = 0;
01427 }
01428 
01429 /**
01430  * Inserts ipRouteTable indexes (.ipRouteDest)
01431  * into index tree.
01432  *
01433  * @param dflt non-zero for the default rte, zero for network rte
01434  * @param ni points to network interface for this rte
01435  *
01436  * @todo record sysuptime for _this_ route when it is installed
01437  *   (needed for ipRouteAge) in the netif.
01438  */
01439 void snmp_insert_iprteidx_tree(u8_t dflt, struct netif *ni)
01440 {
01441   u8_t insert = 0;
01442   ip_addr_t dst;
01443 
01444   if (dflt != 0)
01445   {
01446     /* the default route 0.0.0.0 */
01447     ip_addr_set_any(&dst);
01448     insert = 1;
01449   }
01450   else
01451   {
01452     /* route to the network address */
01453     ip_addr_get_network(&dst, &ni->ip_addr, &ni->netmask);
01454     /* exclude 0.0.0.0 network (reserved for default rte) */
01455     if (!ip_addr_isany(&dst)) {
01456       insert = 1;
01457     }
01458   }
01459   if (insert)
01460   {
01461     struct mib_list_rootnode *iprte_rn;
01462     struct mib_list_node *iprte_node;
01463     s32_t iprteidx[4];
01464     u8_t level;
01465 
01466     snmp_iptooid(&dst, &iprteidx[0]);
01467     level = 0;
01468     iprte_rn = &iprtetree_root;
01469     while (level < 4)
01470     {
01471       iprte_node = NULL;
01472       snmp_mib_node_insert(iprte_rn, iprteidx[level], &iprte_node);
01473       if ((level != 3) && (iprte_node != NULL))
01474       {
01475         if (iprte_node->nptr == NULL)
01476         {
01477           iprte_rn = snmp_mib_lrn_alloc();
01478           iprte_node->nptr = (struct mib_node*)iprte_rn;
01479           if (iprte_rn != NULL)
01480           {
01481             if (level == 2)
01482             {
01483               iprte_rn->get_object_def = ip_rteentry_get_object_def ;
01484               iprte_rn->get_value = ip_rteentry_get_value ;
01485               iprte_rn->set_test = noleafs_set_test;
01486               iprte_rn->set_value = noleafs_set_value;
01487             }
01488           }
01489           else
01490           {
01491             /* iprte_rn == NULL, malloc failure */
01492             LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_iprteidx_tree() insert failed, mem full"));
01493             break;
01494           }
01495         }
01496         else
01497         {
01498           iprte_rn = (struct mib_list_rootnode*)iprte_node->nptr;
01499         }
01500       }
01501       level++;
01502     }
01503   }
01504   /* enable getnext traversal on filled table */
01505   iprtetable.maxlength = 1;
01506 }
01507 
01508 /**
01509  * Removes ipRouteTable indexes (.ipRouteDest)
01510  * from index tree.
01511  *
01512  * @param dflt non-zero for the default rte, zero for network rte
01513  * @param ni points to network interface for this rte or NULL
01514  *   for default route to be removed.
01515  */
01516 void snmp_delete_iprteidx_tree(u8_t dflt, struct netif *ni)
01517 {
01518   u8_t del = 0;
01519   ip_addr_t dst;
01520 
01521   if (dflt != 0)
01522   {
01523     /* the default route 0.0.0.0 */
01524     ip_addr_set_any(&dst);
01525     del = 1;
01526   }
01527   else
01528   {
01529     /* route to the network address */
01530     ip_addr_get_network(&dst, &ni->ip_addr, &ni->netmask);
01531     /* exclude 0.0.0.0 network (reserved for default rte) */
01532     if (!ip_addr_isany(&dst)) {
01533       del = 1;
01534     }
01535   }
01536   if (del)
01537   {
01538     struct mib_list_rootnode *iprte_rn, *next, *del_rn[4];
01539     struct mib_list_node *iprte_n, *del_n[4];
01540     s32_t iprteidx[4];
01541     u8_t fc, level, del_cnt;
01542 
01543     snmp_iptooid(&dst, &iprteidx[0]);
01544     /* mark nodes for deletion */
01545     level = 0;
01546     del_cnt = 0;
01547     iprte_rn = &iprtetree_root;
01548     while ((level < 4) && (iprte_rn != NULL))
01549     {
01550       fc = snmp_mib_node_find(iprte_rn, iprteidx[level], &iprte_n);
01551       if (fc == 0)
01552       {
01553         /* iprteidx[level] does not exist */
01554         del_cnt = 0;
01555         iprte_rn = NULL;
01556       }
01557       else if (fc == 1)
01558       {
01559         del_rn[del_cnt] = iprte_rn;
01560         del_n[del_cnt] = iprte_n;
01561         del_cnt++;
01562         iprte_rn = (struct mib_list_rootnode*)(iprte_n->nptr);
01563       }
01564       else if (fc == 2)
01565       {
01566         /* reset delete (2 or more childs) */
01567         del_cnt = 0;
01568         iprte_rn = (struct mib_list_rootnode*)(iprte_n->nptr);
01569       }
01570       level++;
01571     }
01572     /* delete marked index nodes */
01573     while (del_cnt > 0)
01574     {
01575       del_cnt--;
01576 
01577       iprte_rn = del_rn[del_cnt];
01578       iprte_n = del_n[del_cnt];
01579 
01580       next = snmp_mib_node_delete(iprte_rn, iprte_n);
01581       if (next != NULL)
01582       {
01583         LWIP_ASSERT("next_count == 0",next->count == 0);
01584         snmp_mib_lrn_free(next);
01585       }
01586     }
01587   }
01588   /* disable getnext traversal on empty table */
01589   if (iprtetree_root.count == 0) iprtetable.maxlength = 0;
01590 }
01591 
01592 
01593 void snmp_inc_icmpinmsgs(void)
01594 {
01595   icmpinmsgs++;
01596 }
01597 
01598 void snmp_inc_icmpinerrors(void)
01599 {
01600   icmpinerrors++;
01601 }
01602 
01603 void snmp_inc_icmpindestunreachs(void)
01604 {
01605   icmpindestunreachs++;
01606 }
01607 
01608 void snmp_inc_icmpintimeexcds(void)
01609 {
01610   icmpintimeexcds++;
01611 }
01612 
01613 void snmp_inc_icmpinparmprobs(void)
01614 {
01615   icmpinparmprobs++;
01616 }
01617 
01618 void snmp_inc_icmpinsrcquenchs(void)
01619 {
01620   icmpinsrcquenchs++;
01621 }
01622 
01623 void snmp_inc_icmpinredirects(void)
01624 {
01625   icmpinredirects++;
01626 }
01627 
01628 void snmp_inc_icmpinechos(void)
01629 {
01630   icmpinechos++;
01631 }
01632 
01633 void snmp_inc_icmpinechoreps(void)
01634 {
01635   icmpinechoreps++;
01636 }
01637 
01638 void snmp_inc_icmpintimestamps(void)
01639 {
01640   icmpintimestamps++;
01641 }
01642 
01643 void snmp_inc_icmpintimestampreps(void)
01644 {
01645   icmpintimestampreps++;
01646 }
01647 
01648 void snmp_inc_icmpinaddrmasks(void)
01649 {
01650   icmpinaddrmasks++;
01651 }
01652 
01653 void snmp_inc_icmpinaddrmaskreps(void)
01654 {
01655   icmpinaddrmaskreps++;
01656 }
01657 
01658 void snmp_inc_icmpoutmsgs(void)
01659 {
01660   icmpoutmsgs++;
01661 }
01662 
01663 void snmp_inc_icmpouterrors(void)
01664 {
01665   icmpouterrors++;
01666 }
01667 
01668 void snmp_inc_icmpoutdestunreachs(void)
01669 {
01670   icmpoutdestunreachs++;
01671 }
01672 
01673 void snmp_inc_icmpouttimeexcds(void)
01674 {
01675   icmpouttimeexcds++;
01676 }
01677 
01678 void snmp_inc_icmpoutparmprobs(void)
01679 {
01680   icmpoutparmprobs++;
01681 }
01682 
01683 void snmp_inc_icmpoutsrcquenchs(void)
01684 {
01685   icmpoutsrcquenchs++;
01686 }
01687 
01688 void snmp_inc_icmpoutredirects(void)
01689 {
01690   icmpoutredirects++;
01691 }
01692 
01693 void snmp_inc_icmpoutechos(void)
01694 {
01695   icmpoutechos++;
01696 }
01697 
01698 void snmp_inc_icmpoutechoreps(void)
01699 {
01700   icmpoutechoreps++;
01701 }
01702 
01703 void snmp_inc_icmpouttimestamps(void)
01704 {
01705   icmpouttimestamps++;
01706 }
01707 
01708 void snmp_inc_icmpouttimestampreps(void)
01709 {
01710   icmpouttimestampreps++;
01711 }
01712 
01713 void snmp_inc_icmpoutaddrmasks(void)
01714 {
01715   icmpoutaddrmasks++;
01716 }
01717 
01718 void snmp_inc_icmpoutaddrmaskreps(void)
01719 {
01720   icmpoutaddrmaskreps++;
01721 }
01722 
01723 void snmp_inc_tcpactiveopens(void)
01724 {
01725   tcpactiveopens++;
01726 }
01727 
01728 void snmp_inc_tcppassiveopens(void)
01729 {
01730   tcppassiveopens++;
01731 }
01732 
01733 void snmp_inc_tcpattemptfails(void)
01734 {
01735   tcpattemptfails++;
01736 }
01737 
01738 void snmp_inc_tcpestabresets(void)
01739 {
01740   tcpestabresets++;
01741 }
01742 
01743 void snmp_inc_tcpinsegs(void)
01744 {
01745   tcpinsegs++;
01746 }
01747 
01748 void snmp_inc_tcpoutsegs(void)
01749 {
01750   tcpoutsegs++;
01751 }
01752 
01753 void snmp_inc_tcpretranssegs(void)
01754 {
01755   tcpretranssegs++;
01756 }
01757 
01758 void snmp_inc_tcpinerrs(void)
01759 {
01760   tcpinerrs++;
01761 }
01762 
01763 void snmp_inc_tcpoutrsts(void)
01764 {
01765   tcpoutrsts++;
01766 }
01767 
01768 void snmp_inc_udpindatagrams(void)
01769 {
01770   udpindatagrams++;
01771 }
01772 
01773 void snmp_inc_udpnoports(void)
01774 {
01775   udpnoports++;
01776 }
01777 
01778 void snmp_inc_udpinerrors(void)
01779 {
01780   udpinerrors++;
01781 }
01782 
01783 void snmp_inc_udpoutdatagrams(void)
01784 {
01785   udpoutdatagrams++;
01786 }
01787 
01788 /**
01789  * Inserts udpTable indexes (.udpLocalAddress.udpLocalPort)
01790  * into index tree.
01791  */
01792 void snmp_insert_udpidx_tree(struct udp_pcb *pcb)
01793 {
01794   struct mib_list_rootnode *udp_rn;
01795   struct mib_list_node *udp_node;
01796   s32_t udpidx[5];
01797   u8_t level;
01798 
01799   LWIP_ASSERT("pcb != NULL", pcb != NULL);
01800   snmp_iptooid(&pcb->local_ip, &udpidx[0]);
01801   udpidx[4] = pcb->local_port;
01802 
01803   udp_rn = &udp_root;
01804   for (level = 0; level < 5; level++)
01805   {
01806     udp_node = NULL;
01807     snmp_mib_node_insert(udp_rn, udpidx[level], &udp_node);
01808     if ((level != 4) && (udp_node != NULL))
01809     {
01810       if (udp_node->nptr == NULL)
01811       {
01812         udp_rn = snmp_mib_lrn_alloc();
01813         udp_node->nptr = (struct mib_node*)udp_rn;
01814         if (udp_rn != NULL)
01815         {
01816           if (level == 3)
01817           {
01818             udp_rn->get_object_def = udpentry_get_object_def;
01819             udp_rn->get_value = udpentry_get_value;
01820             udp_rn->set_test = noleafs_set_test;
01821             udp_rn->set_value = noleafs_set_value;
01822           }
01823         }
01824         else
01825         {
01826           /* udp_rn == NULL, malloc failure */
01827           LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_udpidx_tree() insert failed, mem full"));
01828           break;
01829         }
01830       }
01831       else
01832       {
01833         udp_rn = (struct mib_list_rootnode*)udp_node->nptr;
01834       }
01835     }
01836   }
01837   udptable.maxlength = 1;
01838 }
01839 
01840 /**
01841  * Removes udpTable indexes (.udpLocalAddress.udpLocalPort)
01842  * from index tree.
01843  */
01844 void snmp_delete_udpidx_tree(struct udp_pcb *pcb)
01845 {
01846   struct udp_pcb *npcb;
01847   struct mib_list_rootnode *udp_rn, *next, *del_rn[5];
01848   struct mib_list_node *udp_n, *del_n[5];
01849   s32_t udpidx[5];
01850   u8_t bindings, fc, level, del_cnt;
01851 
01852   LWIP_ASSERT("pcb != NULL", pcb != NULL);
01853   snmp_iptooid(&pcb->local_ip, &udpidx[0]);
01854   udpidx[4] = pcb->local_port;
01855 
01856   /* count PCBs for a given binding
01857      (e.g. when reusing ports or for temp output PCBs) */
01858   bindings = 0;
01859   npcb = udp_pcbs;
01860   while ((npcb != NULL))
01861   {
01862     if (ip_addr_cmp(&npcb->local_ip, &pcb->local_ip) &&
01863         (npcb->local_port == udpidx[4]))
01864     {
01865       bindings++;
01866     }
01867     npcb = npcb->next;
01868   }
01869   if (bindings == 1)
01870   {
01871     /* selectively remove */
01872     /* mark nodes for deletion */
01873     level = 0;
01874     del_cnt = 0;
01875     udp_rn = &udp_root;
01876     while ((level < 5) && (udp_rn != NULL))
01877     {
01878       fc = snmp_mib_node_find(udp_rn, udpidx[level], &udp_n);
01879       if (fc == 0)
01880       {
01881         /* udpidx[level] does not exist */
01882         del_cnt = 0;
01883         udp_rn = NULL;
01884       }
01885       else if (fc == 1)
01886       {
01887         del_rn[del_cnt] = udp_rn;
01888         del_n[del_cnt] = udp_n;
01889         del_cnt++;
01890         udp_rn = (struct mib_list_rootnode*)(udp_n->nptr);
01891       }
01892       else if (fc == 2)
01893       {
01894         /* reset delete (2 or more childs) */
01895         del_cnt = 0;
01896         udp_rn = (struct mib_list_rootnode*)(udp_n->nptr);
01897       }
01898       level++;
01899     }
01900     /* delete marked index nodes */
01901     while (del_cnt > 0)
01902     {
01903       del_cnt--;
01904 
01905       udp_rn = del_rn[del_cnt];
01906       udp_n = del_n[del_cnt];
01907 
01908       next = snmp_mib_node_delete(udp_rn, udp_n);
01909       if (next != NULL)
01910       {
01911         LWIP_ASSERT("next_count == 0",next->count == 0);
01912         snmp_mib_lrn_free(next);
01913       }
01914     }
01915   }
01916   /* disable getnext traversal on empty table */
01917   if (udp_root.count == 0) udptable.maxlength = 0;
01918 }
01919 
01920 
01921 void snmp_inc_snmpinpkts(void)
01922 {
01923   snmpinpkts++;
01924 }
01925 
01926 void snmp_inc_snmpoutpkts(void)
01927 {
01928   snmpoutpkts++;
01929 }
01930 
01931 void snmp_inc_snmpinbadversions(void)
01932 {
01933   snmpinbadversions++;
01934 }
01935 
01936 void snmp_inc_snmpinbadcommunitynames(void)
01937 {
01938   snmpinbadcommunitynames++;
01939 }
01940 
01941 void snmp_inc_snmpinbadcommunityuses(void)
01942 {
01943   snmpinbadcommunityuses++;
01944 }
01945 
01946 void snmp_inc_snmpinasnparseerrs(void)
01947 {
01948   snmpinasnparseerrs++;
01949 }
01950 
01951 void snmp_inc_snmpintoobigs(void)
01952 {
01953   snmpintoobigs++;
01954 }
01955 
01956 void snmp_inc_snmpinnosuchnames(void)
01957 {
01958   snmpinnosuchnames++;
01959 }
01960 
01961 void snmp_inc_snmpinbadvalues(void)
01962 {
01963   snmpinbadvalues++;
01964 }
01965 
01966 void snmp_inc_snmpinreadonlys(void)
01967 {
01968   snmpinreadonlys++;
01969 }
01970 
01971 void snmp_inc_snmpingenerrs(void)
01972 {
01973   snmpingenerrs++;
01974 }
01975 
01976 void snmp_add_snmpintotalreqvars(u8_t value)
01977 {
01978   snmpintotalreqvars += value;
01979 }
01980 
01981 void snmp_add_snmpintotalsetvars(u8_t value)
01982 {
01983   snmpintotalsetvars += value;
01984 }
01985 
01986 void snmp_inc_snmpingetrequests(void)
01987 {
01988   snmpingetrequests++;
01989 }
01990 
01991 void snmp_inc_snmpingetnexts(void)
01992 {
01993   snmpingetnexts++;
01994 }
01995 
01996 void snmp_inc_snmpinsetrequests(void)
01997 {
01998   snmpinsetrequests++;
01999 }
02000 
02001 void snmp_inc_snmpingetresponses(void)
02002 {
02003   snmpingetresponses++;
02004 }
02005 
02006 void snmp_inc_snmpintraps(void)
02007 {
02008   snmpintraps++;
02009 }
02010 
02011 void snmp_inc_snmpouttoobigs(void)
02012 {
02013   snmpouttoobigs++;
02014 }
02015 
02016 void snmp_inc_snmpoutnosuchnames(void)
02017 {
02018   snmpoutnosuchnames++;
02019 }
02020 
02021 void snmp_inc_snmpoutbadvalues(void)
02022 {
02023   snmpoutbadvalues++;
02024 }
02025 
02026 void snmp_inc_snmpoutgenerrs(void)
02027 {
02028   snmpoutgenerrs++;
02029 }
02030 
02031 void snmp_inc_snmpoutgetrequests(void)
02032 {
02033   snmpoutgetrequests++;
02034 }
02035 
02036 void snmp_inc_snmpoutgetnexts(void)
02037 {
02038   snmpoutgetnexts++;
02039 }
02040 
02041 void snmp_inc_snmpoutsetrequests(void)
02042 {
02043   snmpoutsetrequests++;
02044 }
02045 
02046 void snmp_inc_snmpoutgetresponses(void)
02047 {
02048   snmpoutgetresponses++;
02049 }
02050 
02051 void snmp_inc_snmpouttraps(void)
02052 {
02053   snmpouttraps++;
02054 }
02055 
02056 void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid)
02057 {
02058   *oid = &snmpgrp_id;
02059 }
02060 
02061 void snmp_set_snmpenableauthentraps(u8_t *value)
02062 {
02063   if (value != NULL)
02064   {
02065     snmpenableauthentraps_ptr = value;
02066   }
02067 }
02068 
02069 void snmp_get_snmpenableauthentraps(u8_t *value)
02070 {
02071   *value = *snmpenableauthentraps_ptr;
02072 }
02073 
02074 void
02075 noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
02076 {
02077   LWIP_UNUSED_ARG(ident_len);
02078   LWIP_UNUSED_ARG(ident);
02079   od->instance = MIB_OBJECT_NONE;
02080 }
02081 
02082 void
02083 noleafs_get_value(struct obj_def *od, u16_t len, void *value)
02084 {
02085   LWIP_UNUSED_ARG(od);
02086   LWIP_UNUSED_ARG(len);
02087   LWIP_UNUSED_ARG(value);
02088 }
02089 
02090 u8_t
02091 noleafs_set_test(struct obj_def *od, u16_t len, void *value)
02092 {
02093   LWIP_UNUSED_ARG(od);
02094   LWIP_UNUSED_ARG(len);
02095   LWIP_UNUSED_ARG(value);
02096   /* can't set */
02097   return 0;
02098 }
02099 
02100 void
02101 noleafs_set_value(struct obj_def *od, u16_t len, void *value)
02102 {
02103   LWIP_UNUSED_ARG(od);
02104   LWIP_UNUSED_ARG(len);
02105   LWIP_UNUSED_ARG(value);
02106 }
02107 
02108 
02109 /**
02110  * Returns systems object definitions.
02111  *
02112  * @param ident_len the address length (2)
02113  * @param ident points to objectname.0 (object id trailer)
02114  * @param od points to object definition.
02115  */
02116 static void
02117 system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
02118 {
02119   u8_t id;
02120 
02121   /* return to object name, adding index depth (1) */
02122   ident_len += 1;
02123   ident -= 1;
02124   if (ident_len == 2)
02125   {
02126     od->id_inst_len = ident_len;
02127     od->id_inst_ptr = ident;
02128 
02129     LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
02130     id = (u8_t)ident[0];
02131     LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def system.%"U16_F".0\n",(u16_t)id));
02132     switch (id)
02133     {
02134       case 1: /* sysDescr */
02135         od->instance = MIB_OBJECT_SCALAR;
02136         od->access = MIB_OBJECT_READ_ONLY;
02137         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
02138         od->v_len = *sysdescr_len_ptr;
02139         break;
02140       case 2: /* sysObjectID */
02141         od->instance = MIB_OBJECT_SCALAR;
02142         od->access = MIB_OBJECT_READ_ONLY;
02143         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID);
02144         od->v_len = sysobjid.len * sizeof(s32_t);
02145         break;
02146       case 3: /* sysUpTime */
02147         od->instance = MIB_OBJECT_SCALAR;
02148         od->access = MIB_OBJECT_READ_ONLY;
02149         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS);
02150         od->v_len = sizeof(u32_t);
02151         break;
02152       case 4: /* sysContact */
02153         od->instance = MIB_OBJECT_SCALAR;
02154         od->access = MIB_OBJECT_READ_WRITE;
02155         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
02156         od->v_len = *syscontact_len_ptr;
02157         break;
02158       case 5: /* sysName */
02159         od->instance = MIB_OBJECT_SCALAR;
02160         od->access = MIB_OBJECT_READ_WRITE;
02161         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
02162         od->v_len = *sysname_len_ptr;
02163         break;
02164       case 6: /* sysLocation */
02165         od->instance = MIB_OBJECT_SCALAR;
02166         od->access = MIB_OBJECT_READ_WRITE;
02167         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
02168         od->v_len = *syslocation_len_ptr;
02169         break;
02170       case 7: /* sysServices */
02171         od->instance = MIB_OBJECT_SCALAR;
02172         od->access = MIB_OBJECT_READ_ONLY;
02173         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
02174         od->v_len = sizeof(s32_t);
02175         break;
02176       default:
02177         LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_object_def: no such object\n"));
02178         od->instance = MIB_OBJECT_NONE;
02179         break;
02180     };
02181   }
02182   else
02183   {
02184     LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_object_def: no scalar\n"));
02185     od->instance = MIB_OBJECT_NONE;
02186   }
02187 }
02188 
02189 /**
02190  * Returns system object value.
02191  *
02192  * @param ident_len the address length (2)
02193  * @param ident points to objectname.0 (object id trailer)
02194  * @param len return value space (in bytes)
02195  * @param value points to (varbind) space to copy value into.
02196  */
02197 static void
02198 system_get_value(struct obj_def *od, u16_t len, void *value)
02199 {
02200   u8_t id;
02201 
02202   LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
02203   id = (u8_t)od->id_inst_ptr[0];
02204   switch (id)
02205   {
02206     case 1: /* sysDescr */
02207       ocstrncpy((u8_t*)value, sysdescr_ptr, len);
02208       break;
02209     case 2: /* sysObjectID */
02210       objectidncpy((s32_t*)value, (s32_t*)sysobjid.id, (u8_t)(len / sizeof(s32_t)));
02211       break;
02212     case 3: /* sysUpTime */
02213       {
02214         snmp_get_sysuptime((u32_t*)value);
02215       }
02216       break;
02217     case 4: /* sysContact */
02218       ocstrncpy((u8_t*)value, syscontact_ptr, len);
02219       break;
02220     case 5: /* sysName */
02221       ocstrncpy((u8_t*)value, sysname_ptr, len);
02222       break;
02223     case 6: /* sysLocation */
02224       ocstrncpy((u8_t*)value, syslocation_ptr, len);
02225       break;
02226     case 7: /* sysServices */
02227       {
02228         s32_t *sint_ptr = (s32_t*)value;
02229         *sint_ptr = sysservices;
02230       }
02231       break;
02232   };
02233 }
02234 
02235 static u8_t
02236 system_set_test(struct obj_def *od, u16_t len, void *value)
02237 {
02238   u8_t id, set_ok;
02239 
02240   LWIP_UNUSED_ARG(value);
02241   set_ok = 0;
02242   LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
02243   id = (u8_t)od->id_inst_ptr[0];
02244   switch (id)
02245   {
02246     case 4: /* sysContact */
02247       if ((syscontact_ptr != syscontact_default) &&
02248           (len <= 255))
02249       {
02250         set_ok = 1;
02251       }
02252       break;
02253     case 5: /* sysName */
02254       if ((sysname_ptr != sysname_default) &&
02255           (len <= 255))
02256       {
02257         set_ok = 1;
02258       }
02259       break;
02260     case 6: /* sysLocation */
02261       if ((syslocation_ptr != syslocation_default) &&
02262           (len <= 255))
02263       {
02264         set_ok = 1;
02265       }
02266       break;
02267   };
02268   return set_ok;
02269 }
02270 
02271 static void
02272 system_set_value(struct obj_def *od, u16_t len, void *value)
02273 {
02274   u8_t id;
02275 
02276   LWIP_ASSERT("invalid len", len <= 0xff);
02277   LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
02278   id = (u8_t)od->id_inst_ptr[0];
02279   switch (id)
02280   {
02281     case 4: /* sysContact */
02282       ocstrncpy(syscontact_ptr, (u8_t*)value, len);
02283       *syscontact_len_ptr = (u8_t)len;
02284       break;
02285     case 5: /* sysName */
02286       ocstrncpy(sysname_ptr, (u8_t*)value, len);
02287       *sysname_len_ptr = (u8_t)len;
02288       break;
02289     case 6: /* sysLocation */
02290       ocstrncpy(syslocation_ptr, (u8_t*)value, len);
02291       *syslocation_len_ptr = (u8_t)len;
02292       break;
02293   };
02294 }
02295 
02296 /**
02297  * Returns interfaces.ifnumber object definition.
02298  *
02299  * @param ident_len the address length (2)
02300  * @param ident points to objectname.index
02301  * @param od points to object definition.
02302  */
02303 static void
02304 interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
02305 {
02306   /* return to object name, adding index depth (1) */
02307   ident_len += 1;
02308   ident -= 1;
02309   if (ident_len == 2)
02310   {
02311     od->id_inst_len = ident_len;
02312     od->id_inst_ptr = ident;
02313 
02314     od->instance = MIB_OBJECT_SCALAR;
02315     od->access = MIB_OBJECT_READ_ONLY;
02316     od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
02317     od->v_len = sizeof(s32_t);
02318   }
02319   else
02320   {
02321     LWIP_DEBUGF(SNMP_MIB_DEBUG,("interfaces_get_object_def: no scalar\n"));
02322     od->instance = MIB_OBJECT_NONE;
02323   }
02324 }
02325 
02326 /**
02327  * Returns interfaces.ifnumber object value.
02328  *
02329  * @param ident_len the address length (2)
02330  * @param ident points to objectname.0 (object id trailer)
02331  * @param len return value space (in bytes)
02332  * @param value points to (varbind) space to copy value into.
02333  */
02334 static void
02335 interfaces_get_value(struct obj_def *od, u16_t len, void *value)
02336 {
02337   LWIP_UNUSED_ARG(len);
02338   if (od->id_inst_ptr[0] == 1)
02339   {
02340     s32_t *sint_ptr = (s32_t*)value;
02341     *sint_ptr = iflist_root.count;
02342   }
02343 }
02344 
02345 /**
02346  * Returns ifentry object definitions.
02347  *
02348  * @param ident_len the address length (2)
02349  * @param ident points to objectname.index
02350  * @param od points to object definition.
02351  */
02352 static void
02353 ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
02354 {
02355   u8_t id;
02356 
02357   /* return to object name, adding index depth (1) */
02358   ident_len += 1;
02359   ident -= 1;
02360   if (ident_len == 2)
02361   {
02362     od->id_inst_len = ident_len;
02363     od->id_inst_ptr = ident;
02364 
02365     LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
02366     id = (u8_t)ident[0];
02367     LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def ifentry.%"U16_F"\n",(u16_t)id));
02368     switch (id)
02369     {
02370       case 1: /* ifIndex */
02371       case 3: /* ifType */
02372       case 4: /* ifMtu */
02373       case 8: /* ifOperStatus */
02374         od->instance = MIB_OBJECT_TAB;
02375         od->access = MIB_OBJECT_READ_ONLY;
02376         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
02377         od->v_len = sizeof(s32_t);
02378         break;
02379       case 2: /* ifDescr */
02380         od->instance = MIB_OBJECT_TAB;
02381         od->access = MIB_OBJECT_READ_ONLY;
02382         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
02383         /** @todo this should be some sort of sizeof(struct netif.name) */
02384         od->v_len = 2;
02385         break;
02386       case 5: /* ifSpeed */
02387       case 21: /* ifOutQLen */
02388         od->instance = MIB_OBJECT_TAB;
02389         od->access = MIB_OBJECT_READ_ONLY;
02390         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE);
02391         od->v_len = sizeof(u32_t);
02392         break;
02393       case 6: /* ifPhysAddress */
02394         {
02395           struct netif *netif;
02396 
02397           snmp_ifindextonetif(ident[1], &netif);
02398           od->instance = MIB_OBJECT_TAB;
02399           od->access = MIB_OBJECT_READ_ONLY;
02400           od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
02401           od->v_len = netif->hwaddr_len;
02402         }
02403         break;
02404       case 7: /* ifAdminStatus */
02405         od->instance = MIB_OBJECT_TAB;
02406         od->access = MIB_OBJECT_READ_WRITE;
02407         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
02408         od->v_len = sizeof(s32_t);
02409         break;
02410       case 9: /* ifLastChange */
02411         od->instance = MIB_OBJECT_TAB;
02412         od->access = MIB_OBJECT_READ_ONLY;
02413         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS);
02414         od->v_len = sizeof(u32_t);
02415         break;
02416       case 10: /* ifInOctets */
02417       case 11: /* ifInUcastPkts */
02418       case 12: /* ifInNUcastPkts */
02419       case 13: /* ifInDiscarts */
02420       case 14: /* ifInErrors */
02421       case 15: /* ifInUnkownProtos */
02422       case 16: /* ifOutOctets */
02423       case 17: /* ifOutUcastPkts */
02424       case 18: /* ifOutNUcastPkts */
02425       case 19: /* ifOutDiscarts */
02426       case 20: /* ifOutErrors */
02427         od->instance = MIB_OBJECT_TAB;
02428         od->access = MIB_OBJECT_READ_ONLY;
02429         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
02430         od->v_len = sizeof(u32_t);
02431         break;
02432       case 22: /* ifSpecific */
02433         /** @note returning zeroDotZero (0.0) no media specific MIB support */
02434         od->instance = MIB_OBJECT_TAB;
02435         od->access = MIB_OBJECT_READ_ONLY;
02436         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID);
02437         od->v_len = ifspecific.len * sizeof(s32_t);
02438         break;
02439       default:
02440         LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_object_def: no such object\n"));
02441         od->instance = MIB_OBJECT_NONE;
02442         break;
02443     };
02444   }
02445   else
02446   {
02447     LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_object_def: no scalar\n"));
02448     od->instance = MIB_OBJECT_NONE;
02449   }
02450 }
02451 
02452 /**
02453  * Returns ifentry object value.
02454  *
02455  * @param ident_len the address length (2)
02456  * @param ident points to objectname.0 (object id trailer)
02457  * @param len return value space (in bytes)
02458  * @param value points to (varbind) space to copy value into.
02459  */
02460 static void
02461 ifentry_get_value(struct obj_def *od, u16_t len, void *value)
02462 {
02463   struct netif *netif;
02464   u8_t id;
02465 
02466   snmp_ifindextonetif(od->id_inst_ptr[1], &netif);
02467   LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
02468   id = (u8_t)od->id_inst_ptr[0];
02469   switch (id)
02470   {
02471     case 1: /* ifIndex */
02472       {
02473         s32_t *sint_ptr = (s32_t*)value;
02474         *sint_ptr = od->id_inst_ptr[1];
02475       }
02476       break;
02477     case 2: /* ifDescr */
02478       ocstrncpy((u8_t*)value, (u8_t*)netif->name, len);
02479       break;
02480     case 3: /* ifType */
02481       {
02482         s32_t *sint_ptr = (s32_t*)value;
02483         *sint_ptr = netif->link_type;
02484       }
02485       break;
02486     case 4: /* ifMtu */
02487       {
02488         s32_t *sint_ptr = (s32_t*)value;
02489         *sint_ptr = netif->mtu;
02490       }
02491       break;
02492     case 5: /* ifSpeed */
02493       {
02494         u32_t *uint_ptr = (u32_t*)value;
02495         *uint_ptr = netif->link_speed;
02496       }
02497       break;
02498     case 6: /* ifPhysAddress */
02499       ocstrncpy((u8_t*)value, netif->hwaddr, len);
02500       break;
02501     case 7: /* ifAdminStatus */
02502       {
02503         s32_t *sint_ptr = (s32_t*)value;
02504         if (netif_is_up(netif))
02505         {
02506           if (netif_is_link_up(netif))
02507           {
02508             *sint_ptr = 1; /* up */
02509           }
02510           else
02511           {
02512             *sint_ptr = 7; /* lowerLayerDown */
02513           }
02514         }
02515         else
02516         {
02517           *sint_ptr = 2; /* down */
02518         }
02519       }
02520       break;
02521     case 8: /* ifOperStatus */
02522       {
02523         s32_t *sint_ptr = (s32_t*)value;
02524         if (netif_is_up(netif))
02525         {
02526           *sint_ptr = 1;
02527         }
02528         else
02529         {
02530           *sint_ptr = 2;
02531         }
02532       }
02533       break;
02534     case 9: /* ifLastChange */
02535       {
02536         u32_t *uint_ptr = (u32_t*)value;
02537         *uint_ptr = netif->ts;
02538       }
02539       break;
02540     case 10: /* ifInOctets */
02541       {
02542         u32_t *uint_ptr = (u32_t*)value;
02543         *uint_ptr = netif->ifinoctets;
02544       }
02545       break;
02546     case 11: /* ifInUcastPkts */
02547       {
02548         u32_t *uint_ptr = (u32_t*)value;
02549         *uint_ptr = netif->ifinucastpkts;
02550       }
02551       break;
02552     case 12: /* ifInNUcastPkts */
02553       {
02554         u32_t *uint_ptr = (u32_t*)value;
02555         *uint_ptr = netif->ifinnucastpkts;
02556       }
02557       break;
02558     case 13: /* ifInDiscarts */
02559       {
02560         u32_t *uint_ptr = (u32_t*)value;
02561         *uint_ptr = netif->ifindiscards;
02562       }
02563       break;
02564     case 14: /* ifInErrors */
02565     case 15: /* ifInUnkownProtos */
02566       /** @todo add these counters! */
02567       {
02568         u32_t *uint_ptr = (u32_t*)value;
02569         *uint_ptr = 0;
02570       }
02571       break;
02572     case 16: /* ifOutOctets */
02573       {
02574         u32_t *uint_ptr = (u32_t*)value;
02575         *uint_ptr = netif->ifoutoctets;
02576       }
02577       break;
02578     case 17: /* ifOutUcastPkts */
02579       {
02580         u32_t *uint_ptr = (u32_t*)value;
02581         *uint_ptr = netif->ifoutucastpkts;
02582       }
02583       break;
02584     case 18: /* ifOutNUcastPkts */
02585       {
02586         u32_t *uint_ptr = (u32_t*)value;
02587         *uint_ptr = netif->ifoutnucastpkts;
02588       }
02589       break;
02590     case 19: /* ifOutDiscarts */
02591       {
02592         u32_t *uint_ptr = (u32_t*)value;
02593         *uint_ptr = netif->ifoutdiscards;
02594       }
02595       break;
02596     case 20: /* ifOutErrors */
02597        /** @todo add this counter! */
02598       {
02599         u32_t *uint_ptr = (u32_t*)value;
02600         *uint_ptr = 0;
02601       }
02602       break;
02603     case 21: /* ifOutQLen */
02604       /** @todo figure out if this must be 0 (no queue) or 1? */
02605       {
02606         u32_t *uint_ptr = (u32_t*)value;
02607         *uint_ptr = 0;
02608       }
02609       break;
02610     case 22: /* ifSpecific */
02611       objectidncpy((s32_t*)value, (s32_t*)ifspecific.id, (u8_t)(len / sizeof(s32_t)));
02612       break;
02613   };
02614 }
02615 
02616 #if !SNMP_SAFE_REQUESTS
02617 static u8_t
02618 ifentry_set_test(struct obj_def *od, u16_t len, void *value)
02619 {
02620   struct netif *netif;
02621   u8_t id, set_ok;
02622   LWIP_UNUSED_ARG(len);
02623 
02624   set_ok = 0;
02625   snmp_ifindextonetif(od->id_inst_ptr[1], &netif);
02626   id = (u8_t)od->id_inst_ptr[0];
02627   switch (id)
02628   {
02629     case 7: /* ifAdminStatus */
02630       {
02631         s32_t *sint_ptr = (s32_t*)value;
02632         if (*sint_ptr == 1 || *sint_ptr == 2)
02633           set_ok = 1;
02634       }
02635       break;
02636   }
02637   return set_ok;
02638 }
02639 
02640 static void
02641 ifentry_set_value(struct obj_def *od, u16_t len, void *value)
02642 {
02643   struct netif *netif;
02644   u8_t id;
02645   LWIP_UNUSED_ARG(len);
02646 
02647   snmp_ifindextonetif(od->id_inst_ptr[1], &netif);
02648   id = (u8_t)od->id_inst_ptr[0];
02649   switch (id)
02650   {
02651     case 7: /* ifAdminStatus */
02652       {
02653         s32_t *sint_ptr = (s32_t*)value;
02654         if (*sint_ptr == 1)
02655         {
02656           netif_set_up(netif);
02657         }
02658         else if (*sint_ptr == 2)
02659         {
02660           netif_set_down(netif);
02661          }
02662       }
02663       break;
02664   }
02665 }
02666 #endif /* SNMP_SAFE_REQUESTS */
02667 
02668 /**
02669  * Returns atentry object definitions.
02670  *
02671  * @param ident_len the address length (6)
02672  * @param ident points to objectname.atifindex.atnetaddress
02673  * @param od points to object definition.
02674  */
02675 static void
02676 atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
02677 {
02678   /* return to object name, adding index depth (5) */
02679   ident_len += 5;
02680   ident -= 5;
02681 
02682   if (ident_len == 6)
02683   {
02684     od->id_inst_len = ident_len;
02685     od->id_inst_ptr = ident;
02686 
02687     switch (ident[0])
02688     {
02689       case 1: /* atIfIndex */
02690         od->instance = MIB_OBJECT_TAB;
02691         od->access = MIB_OBJECT_READ_WRITE;
02692         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
02693         od->v_len = sizeof(s32_t);
02694         break;
02695       case 2: /* atPhysAddress */
02696         od->instance = MIB_OBJECT_TAB;
02697         od->access = MIB_OBJECT_READ_WRITE;
02698         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
02699         od->v_len = 6; /** @todo try to use netif::hwaddr_len */
02700         break;
02701       case 3: /* atNetAddress */
02702         od->instance = MIB_OBJECT_TAB;
02703         od->access = MIB_OBJECT_READ_WRITE;
02704         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
02705         od->v_len = 4;
02706         break;
02707       default:
02708         LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no such object\n"));
02709         od->instance = MIB_OBJECT_NONE;
02710         break;
02711     }
02712   }
02713   else
02714   {
02715     LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no scalar\n"));
02716     od->instance = MIB_OBJECT_NONE;
02717   }
02718 }
02719 
02720 static void
02721 atentry_get_value(struct obj_def *od, u16_t len, void *value)
02722 {
02723 #if LWIP_ARP
02724   u8_t id;
02725   struct eth_addr* ethaddr_ret;
02726   ip_addr_t* ipaddr_ret;
02727 #endif /* LWIP_ARP */
02728   ip_addr_t ip;
02729   struct netif *netif;
02730 
02731   LWIP_UNUSED_ARG(len);
02732   LWIP_UNUSED_ARG(value);/* if !LWIP_ARP */
02733 
02734   snmp_ifindextonetif(od->id_inst_ptr[1], &netif);
02735   snmp_oidtoip(&od->id_inst_ptr[2], &ip);
02736 
02737 #if LWIP_ARP /** @todo implement a netif_find_addr */
02738   if (etharp_find_addr(netif, &ip, &ethaddr_ret, &ipaddr_ret) > -1)
02739   {
02740     LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
02741     id = (u8_t)od->id_inst_ptr[0];
02742     switch (id)
02743     {
02744       case 1: /* atIfIndex */
02745         {
02746           s32_t *sint_ptr = (s32_t*)value;
02747           *sint_ptr = od->id_inst_ptr[1];
02748         }
02749         break;
02750       case 2: /* atPhysAddress */
02751         {
02752           struct eth_addr *dst = (struct eth_addr*)value;
02753 
02754           *dst = *ethaddr_ret;
02755         }
02756         break;
02757       case 3: /* atNetAddress */
02758         {
02759           ip_addr_t *dst = (ip_addr_t*)value;
02760 
02761           *dst = *ipaddr_ret;
02762         }
02763         break;
02764     }
02765   }
02766 #endif /* LWIP_ARP */
02767 }
02768 
02769 static void
02770 ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
02771 {
02772   u8_t id;
02773 
02774   /* return to object name, adding index depth (1) */
02775   ident_len += 1;
02776   ident -= 1;
02777   if (ident_len == 2)
02778   {
02779     od->id_inst_len = ident_len;
02780     od->id_inst_ptr = ident;
02781 
02782     LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
02783     id = (u8_t)ident[0];
02784     LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def ip.%"U16_F".0\n",(u16_t)id));
02785     switch (id)
02786     {
02787       case 1: /* ipForwarding */
02788       case 2: /* ipDefaultTTL */
02789         od->instance = MIB_OBJECT_SCALAR;
02790         od->access = MIB_OBJECT_READ_WRITE;
02791         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
02792         od->v_len = sizeof(s32_t);
02793         break;
02794       case 3: /* ipInReceives */
02795       case 4: /* ipInHdrErrors */
02796       case 5: /* ipInAddrErrors */
02797       case 6: /* ipForwDatagrams */
02798       case 7: /* ipInUnknownProtos */
02799       case 8: /* ipInDiscards */
02800       case 9: /* ipInDelivers */
02801       case 10: /* ipOutRequests */
02802       case 11: /* ipOutDiscards */
02803       case 12: /* ipOutNoRoutes */
02804       case 14: /* ipReasmReqds */
02805       case 15: /* ipReasmOKs */
02806       case 16: /* ipReasmFails */
02807       case 17: /* ipFragOKs */
02808       case 18: /* ipFragFails */
02809       case 19: /* ipFragCreates */
02810       case 23: /* ipRoutingDiscards */
02811         od->instance = MIB_OBJECT_SCALAR;
02812         od->access = MIB_OBJECT_READ_ONLY;
02813         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
02814         od->v_len = sizeof(u32_t);
02815         break;
02816       case 13: /* ipReasmTimeout */
02817         od->instance = MIB_OBJECT_SCALAR;
02818         od->access = MIB_OBJECT_READ_ONLY;
02819         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
02820         od->v_len = sizeof(s32_t);
02821         break;
02822       default:
02823         LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no such object\n"));
02824         od->instance = MIB_OBJECT_NONE;
02825         break;
02826     };
02827   }
02828   else
02829   {
02830     LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no scalar\n"));
02831     od->instance = MIB_OBJECT_NONE;
02832   }
02833 }
02834 
02835 static void
02836 ip_get_value (struct obj_def *od, u16_t len, void *value)
02837 {
02838   u8_t id;
02839 
02840   LWIP_UNUSED_ARG(len);
02841   LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
02842   id = (u8_t)od->id_inst_ptr[0];
02843   switch (id)
02844   {
02845     case 1: /* ipForwarding */
02846       {
02847         s32_t *sint_ptr = (s32_t*)value;
02848 #if IP_FORWARD
02849         /* forwarding */
02850         *sint_ptr = 1;
02851 #else
02852         /* not-forwarding */
02853         *sint_ptr = 2;
02854 #endif
02855       }
02856       break;
02857     case 2: /* ipDefaultTTL */
02858       {
02859         s32_t *sint_ptr = (s32_t*)value;
02860         *sint_ptr = IP_DEFAULT_TTL;
02861       }
02862       break;
02863     case 3: /* ipInReceives */
02864       {
02865         u32_t *uint_ptr = (u32_t*)value;
02866         *uint_ptr = ipinreceives;
02867       }
02868       break;
02869     case 4: /* ipInHdrErrors */
02870       {
02871         u32_t *uint_ptr = (u32_t*)value;
02872         *uint_ptr = ipinhdrerrors;
02873       }
02874       break;
02875     case 5: /* ipInAddrErrors */
02876       {
02877         u32_t *uint_ptr = (u32_t*)value;
02878         *uint_ptr = ipinaddrerrors;
02879       }
02880       break;
02881     case 6: /* ipForwDatagrams */
02882       {
02883         u32_t *uint_ptr = (u32_t*)value;
02884         *uint_ptr = ipforwdatagrams;
02885       }
02886       break;
02887     case 7: /* ipInUnknownProtos */
02888       {
02889         u32_t *uint_ptr = (u32_t*)value;
02890         *uint_ptr = ipinunknownprotos;
02891       }
02892       break;
02893     case 8: /* ipInDiscards */
02894       {
02895         u32_t *uint_ptr = (u32_t*)value;
02896         *uint_ptr = ipindiscards;
02897       }
02898       break;
02899     case 9: /* ipInDelivers */
02900       {
02901         u32_t *uint_ptr = (u32_t*)value;
02902         *uint_ptr = ipindelivers;
02903       }
02904       break;
02905     case 10: /* ipOutRequests */
02906       {
02907         u32_t *uint_ptr = (u32_t*)value;
02908         *uint_ptr = ipoutrequests;
02909       }
02910       break;
02911     case 11: /* ipOutDiscards */
02912       {
02913         u32_t *uint_ptr = (u32_t*)value;
02914         *uint_ptr = ipoutdiscards;
02915       }
02916       break;
02917     case 12: /* ipOutNoRoutes */
02918       {
02919         u32_t *uint_ptr = (u32_t*)value;
02920         *uint_ptr = ipoutnoroutes;
02921       }
02922       break;
02923     case 13: /* ipReasmTimeout */
02924       {
02925         s32_t *sint_ptr = (s32_t*)value;
02926 #if IP_REASSEMBLY
02927         *sint_ptr = IP_REASS_MAXAGE;
02928 #else
02929         *sint_ptr = 0;
02930 #endif
02931       }
02932       break;
02933     case 14: /* ipReasmReqds */
02934       {
02935         u32_t *uint_ptr = (u32_t*)value;
02936         *uint_ptr = ipreasmreqds;
02937       }
02938       break;
02939     case 15: /* ipReasmOKs */
02940       {
02941         u32_t *uint_ptr = (u32_t*)value;
02942         *uint_ptr = ipreasmoks;
02943       }
02944       break;
02945     case 16: /* ipReasmFails */
02946       {
02947         u32_t *uint_ptr = (u32_t*)value;
02948         *uint_ptr = ipreasmfails;
02949       }
02950       break;
02951     case 17: /* ipFragOKs */
02952       {
02953         u32_t *uint_ptr = (u32_t*)value;
02954         *uint_ptr = ipfragoks;
02955       }
02956       break;
02957     case 18: /* ipFragFails */
02958       {
02959         u32_t *uint_ptr = (u32_t*)value;
02960         *uint_ptr = ipfragfails;
02961       }
02962       break;
02963     case 19: /* ipFragCreates */
02964       {
02965         u32_t *uint_ptr = (u32_t*)value;
02966         *uint_ptr = ipfragcreates;
02967       }
02968       break;
02969     case 23: /* ipRoutingDiscards */
02970       /** @todo can lwIP discard routes at all?? hardwire this to 0?? */
02971       {
02972         u32_t *uint_ptr = (u32_t*)value;
02973         *uint_ptr = iproutingdiscards;
02974       }
02975       break;
02976   };
02977 }
02978 
02979 /**
02980  * Test ip object value before setting.
02981  *
02982  * @param od is the object definition
02983  * @param len return value space (in bytes)
02984  * @param value points to (varbind) space to copy value from.
02985  *
02986  * @note we allow set if the value matches the hardwired value,
02987  *   otherwise return badvalue.
02988  */
02989 static u8_t
02990 ip_set_test(struct obj_def *od, u16_t len, void *value)
02991 {
02992   u8_t id, set_ok;
02993   s32_t *sint_ptr = (s32_t*)value;
02994 
02995   LWIP_UNUSED_ARG(len);
02996   set_ok = 0;
02997   LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
02998   id = (u8_t)od->id_inst_ptr[0];
02999   switch (id)
03000   {
03001     case 1: /* ipForwarding */
03002 #if IP_FORWARD
03003       /* forwarding */
03004       if (*sint_ptr == 1)
03005 #else
03006       /* not-forwarding */
03007       if (*sint_ptr == 2)
03008 #endif
03009       {
03010         set_ok = 1;
03011       }
03012       break;
03013     case 2: /* ipDefaultTTL */
03014       if (*sint_ptr == IP_DEFAULT_TTL)
03015       {
03016         set_ok = 1;
03017       }
03018       break;
03019   };
03020   return set_ok;
03021 }
03022 
03023 static void
03024 ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
03025 {
03026   /* return to object name, adding index depth (4) */
03027   ident_len += 4;
03028   ident -= 4;
03029 
03030   if (ident_len == 5)
03031   {
03032     u8_t id;
03033 
03034     od->id_inst_len = ident_len;
03035     od->id_inst_ptr = ident;
03036 
03037     LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
03038     id = (u8_t)ident[0];
03039     switch (id)
03040     {
03041       case 1: /* ipAdEntAddr */
03042       case 3: /* ipAdEntNetMask */
03043         od->instance = MIB_OBJECT_TAB;
03044         od->access = MIB_OBJECT_READ_ONLY;
03045         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
03046         od->v_len = 4;
03047         break;
03048       case 2: /* ipAdEntIfIndex */
03049       case 4: /* ipAdEntBcastAddr */
03050       case 5: /* ipAdEntReasmMaxSize */
03051         od->instance = MIB_OBJECT_TAB;
03052         od->access = MIB_OBJECT_READ_ONLY;
03053         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
03054         od->v_len = sizeof(s32_t);
03055         break;
03056       default:
03057         LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no such object\n"));
03058         od->instance = MIB_OBJECT_NONE;
03059         break;
03060     }
03061   }
03062   else
03063   {
03064     LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no scalar\n"));
03065     od->instance = MIB_OBJECT_NONE;
03066   }
03067 }
03068 
03069 static void
03070 ip_addrentry_get_value (struct obj_def *od, u16_t len, void *value)
03071 {
03072   u8_t id;
03073   u16_t ifidx;
03074   ip_addr_t ip;
03075   struct netif *netif = netif_list;
03076 
03077   LWIP_UNUSED_ARG(len);
03078   snmp_oidtoip(&od->id_inst_ptr[1], &ip);
03079   ifidx = 0;
03080   while ((netif != NULL) && !ip_addr_cmp(&ip, &netif->ip_addr))
03081   {
03082     netif = netif->next;
03083     ifidx++;
03084   }
03085 
03086   if (netif != NULL)
03087   {
03088     LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
03089     id = (u8_t)od->id_inst_ptr[0];
03090     switch (id)
03091     {
03092       case 1: /* ipAdEntAddr */
03093         {
03094           ip_addr_t *dst = (ip_addr_t*)value;
03095           *dst = netif->ip_addr;
03096         }
03097         break;
03098       case 2: /* ipAdEntIfIndex */
03099         {
03100           s32_t *sint_ptr = (s32_t*)value;
03101           *sint_ptr = ifidx + 1;
03102         }
03103         break;
03104       case 3: /* ipAdEntNetMask */
03105         {
03106           ip_addr_t *dst = (ip_addr_t*)value;
03107           *dst = netif->netmask;
03108         }
03109         break;
03110       case 4: /* ipAdEntBcastAddr */
03111         {
03112           s32_t *sint_ptr = (s32_t*)value;
03113 
03114           /* lwIP oddity, there's no broadcast
03115             address in the netif we can rely on */
03116           *sint_ptr = IPADDR_BROADCAST & 1;
03117         }
03118         break;
03119       case 5: /* ipAdEntReasmMaxSize */
03120         {
03121           s32_t *sint_ptr = (s32_t*)value;
03122 #if IP_REASSEMBLY
03123           /* @todo The theoretical maximum is IP_REASS_MAX_PBUFS * size of the pbufs,
03124            * but only if receiving one fragmented packet at a time.
03125            * The current solution is to calculate for 2 simultaneous packets...
03126            */
03127           *sint_ptr = (IP_HLEN + ((IP_REASS_MAX_PBUFS/2) *
03128             (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN - IP_HLEN)));
03129 #else
03130           /** @todo returning MTU would be a bad thing and
03131              returning a wild guess like '576' isn't good either */
03132           *sint_ptr = 0;
03133 #endif
03134         }
03135         break;
03136     }
03137   }
03138 }
03139 
03140 /**
03141  * @note
03142  * lwIP IP routing is currently using the network addresses in netif_list.
03143  * if no suitable network IP is found in netif_list, the default_netif is used.
03144  */
03145 static void
03146 ip_rteentry_get_object_def (u8_t ident_len, s32_t *ident, struct obj_def *od)
03147 {
03148   u8_t id;
03149 
03150   /* return to object name, adding index depth (4) */
03151   ident_len += 4;
03152   ident -= 4;
03153 
03154   if (ident_len == 5)
03155   {
03156     od->id_inst_len = ident_len;
03157     od->id_inst_ptr = ident;
03158 
03159     LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
03160     id = (u8_t)ident[0];
03161     switch (id)
03162     {
03163       case 1: /* ipRouteDest */
03164       case 7: /* ipRouteNextHop */
03165       case 11: /* ipRouteMask */
03166         od->instance = MIB_OBJECT_TAB;
03167         od->access = MIB_OBJECT_READ_WRITE;
03168         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
03169         od->v_len = 4;
03170         break;
03171       case 2: /* ipRouteIfIndex */
03172       case 3: /* ipRouteMetric1 */
03173       case 4: /* ipRouteMetric2 */
03174       case 5: /* ipRouteMetric3 */
03175       case 6: /* ipRouteMetric4 */
03176       case 8: /* ipRouteType */
03177       case 10: /* ipRouteAge */
03178       case 12: /* ipRouteMetric5 */
03179         od->instance = MIB_OBJECT_TAB;
03180         od->access = MIB_OBJECT_READ_WRITE;
03181         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
03182         od->v_len = sizeof(s32_t);
03183         break;
03184       case 9: /* ipRouteProto */
03185         od->instance = MIB_OBJECT_TAB;
03186         od->access = MIB_OBJECT_READ_ONLY;
03187         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
03188         od->v_len = sizeof(s32_t);
03189         break;
03190       case 13: /* ipRouteInfo */
03191         /** @note returning zeroDotZero (0.0) no routing protocol specific MIB */
03192         od->instance = MIB_OBJECT_TAB;
03193         od->access = MIB_OBJECT_READ_ONLY;
03194         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID);
03195         od->v_len = iprouteinfo.len * sizeof(s32_t);
03196         break;
03197       default:
03198         LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no such object\n"));
03199         od->instance = MIB_OBJECT_NONE;
03200         break;
03201     }
03202   }
03203   else
03204   {
03205     LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no scalar\n"));
03206     od->instance = MIB_OBJECT_NONE;
03207   }
03208 }
03209 
03210 static void
03211 ip_rteentry_get_value (struct obj_def *od, u16_t len, void *value)
03212 {
03213   struct netif *netif;
03214   ip_addr_t dest;
03215   s32_t *ident;
03216   u8_t id;
03217 
03218   ident = od->id_inst_ptr;
03219   snmp_oidtoip(&ident[1], &dest);
03220 
03221   if (ip_addr_isany(&dest))
03222   {
03223     /* ip_route() uses default netif for default route */
03224     netif = netif_default;
03225   }
03226   else
03227   {
03228     /* not using ip_route(), need exact match! */
03229     netif = netif_list;
03230     while ((netif != NULL) &&
03231             !ip_addr_netcmp(&dest, &(netif->ip_addr), &(netif->netmask)) )
03232     {
03233       netif = netif->next;
03234     }
03235   }
03236   if (netif != NULL)
03237   {
03238     LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
03239     id = (u8_t)ident[0];
03240     switch (id)
03241     {
03242       case 1: /* ipRouteDest */
03243         {
03244           ip_addr_t *dst = (ip_addr_t*)value;
03245 
03246           if (ip_addr_isany(&dest))
03247           {
03248             /* default rte has 0.0.0.0 dest */
03249             ip_addr_set_zero(dst);
03250           }
03251           else
03252           {
03253             /* netifs have netaddress dest */
03254             ip_addr_get_network(dst, &netif->ip_addr, &netif->netmask);
03255           }
03256         }
03257         break;
03258       case 2: /* ipRouteIfIndex */
03259         {
03260           s32_t *sint_ptr = (s32_t*)value;
03261 
03262           snmp_netiftoifindex(netif, sint_ptr);
03263         }
03264         break;
03265       case 3: /* ipRouteMetric1 */
03266         {
03267           s32_t *sint_ptr = (s32_t*)value;
03268 
03269           if (ip_addr_isany(&dest))
03270           {
03271             /* default rte has metric 1 */
03272             *sint_ptr = 1;
03273           }
03274           else
03275           {
03276             /* other rtes have metric 0 */
03277             *sint_ptr = 0;
03278           }
03279         }
03280         break;
03281       case 4: /* ipRouteMetric2 */
03282       case 5: /* ipRouteMetric3 */
03283       case 6: /* ipRouteMetric4 */
03284       case 12: /* ipRouteMetric5 */
03285         {
03286           s32_t *sint_ptr = (s32_t*)value;
03287           /* not used */
03288           *sint_ptr = -1;
03289         }
03290         break;
03291       case 7: /* ipRouteNextHop */
03292         {
03293           ip_addr_t *dst = (ip_addr_t*)value;
03294 
03295           if (ip_addr_isany(&dest))
03296           {
03297             /* default rte: gateway */
03298             *dst = netif->gw;
03299           }
03300           else
03301           {
03302             /* other rtes: netif ip_addr  */
03303             *dst = netif->ip_addr;
03304           }
03305         }
03306         break;
03307       case 8: /* ipRouteType */
03308         {
03309           s32_t *sint_ptr = (s32_t*)value;
03310 
03311           if (ip_addr_isany(&dest))
03312           {
03313             /* default rte is indirect */
03314             *sint_ptr = 4;
03315           }
03316           else
03317           {
03318             /* other rtes are direct */
03319             *sint_ptr = 3;
03320           }
03321         }
03322         break;
03323       case 9: /* ipRouteProto */
03324         {
03325           s32_t *sint_ptr = (s32_t*)value;
03326           /* locally defined routes */
03327           *sint_ptr = 2;
03328         }
03329         break;
03330       case 10: /* ipRouteAge */
03331         {
03332           s32_t *sint_ptr = (s32_t*)value;
03333           /** @todo (sysuptime - timestamp last change) / 100
03334               @see snmp_insert_iprteidx_tree() */
03335           *sint_ptr = 0;
03336         }
03337         break;
03338       case 11: /* ipRouteMask */
03339         {
03340           ip_addr_t *dst = (ip_addr_t*)value;
03341 
03342           if (ip_addr_isany(&dest))
03343           {
03344             /* default rte use 0.0.0.0 mask */
03345             ip_addr_set_zero(dst);
03346           }
03347           else
03348           {
03349             /* other rtes use netmask */
03350             *dst = netif->netmask;
03351           }
03352         }
03353         break;
03354       case 13: /* ipRouteInfo */
03355         objectidncpy((s32_t*)value, (s32_t*)iprouteinfo.id, (u8_t)(len / sizeof(s32_t)));
03356         break;
03357     }
03358   }
03359 }
03360 
03361 static void
03362 ip_ntomentry_get_object_def (u8_t ident_len, s32_t *ident, struct obj_def *od)
03363 {
03364   /* return to object name, adding index depth (5) */
03365   ident_len += 5;
03366   ident -= 5;
03367 
03368   if (ident_len == 6)
03369   {
03370     u8_t id;
03371 
03372     od->id_inst_len = ident_len;
03373     od->id_inst_ptr = ident;
03374 
03375     LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
03376     id = (u8_t)ident[0];
03377     switch (id)
03378     {
03379       case 1: /* ipNetToMediaIfIndex */
03380       case 4: /* ipNetToMediaType */
03381         od->instance = MIB_OBJECT_TAB;
03382         od->access = MIB_OBJECT_READ_WRITE;
03383         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
03384         od->v_len = sizeof(s32_t);
03385         break;
03386       case 2: /* ipNetToMediaPhysAddress */
03387         od->instance = MIB_OBJECT_TAB;
03388         od->access = MIB_OBJECT_READ_WRITE;
03389         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
03390         od->v_len = 6; /** @todo try to use netif::hwaddr_len */
03391         break;
03392       case 3: /* ipNetToMediaNetAddress */
03393         od->instance = MIB_OBJECT_TAB;
03394         od->access = MIB_OBJECT_READ_WRITE;
03395         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
03396         od->v_len = 4;
03397         break;
03398       default:
03399         LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no such object\n"));
03400         od->instance = MIB_OBJECT_NONE;
03401         break;
03402     }
03403   }
03404   else
03405   {
03406     LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no scalar\n"));
03407     od->instance = MIB_OBJECT_NONE;
03408   }
03409 }
03410 
03411 static void
03412 ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value)
03413 {
03414 #if LWIP_ARP
03415   u8_t id;
03416   struct eth_addr* ethaddr_ret;
03417   ip_addr_t* ipaddr_ret;
03418 #endif /* LWIP_ARP */
03419   ip_addr_t ip;
03420   struct netif *netif;
03421 
03422   LWIP_UNUSED_ARG(len);
03423   LWIP_UNUSED_ARG(value);/* if !LWIP_ARP */
03424 
03425   snmp_ifindextonetif(od->id_inst_ptr[1], &netif);
03426   snmp_oidtoip(&od->id_inst_ptr[2], &ip);
03427 
03428 #if LWIP_ARP /** @todo implement a netif_find_addr */
03429   if (etharp_find_addr(netif, &ip, &ethaddr_ret, &ipaddr_ret) > -1)
03430   {
03431     LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
03432     id = (u8_t)od->id_inst_ptr[0];
03433     switch (id)
03434     {
03435       case 1: /* ipNetToMediaIfIndex */
03436         {
03437           s32_t *sint_ptr = (s32_t*)value;
03438           *sint_ptr = od->id_inst_ptr[1];
03439         }
03440         break;
03441       case 2: /* ipNetToMediaPhysAddress */
03442         {
03443           struct eth_addr *dst = (struct eth_addr*)value;
03444 
03445           *dst = *ethaddr_ret;
03446         }
03447         break;
03448       case 3: /* ipNetToMediaNetAddress */
03449         {
03450           ip_addr_t *dst = (ip_addr_t*)value;
03451 
03452           *dst = *ipaddr_ret;
03453         }
03454         break;
03455       case 4: /* ipNetToMediaType */
03456         {
03457           s32_t *sint_ptr = (s32_t*)value;
03458           /* dynamic (?) */
03459           *sint_ptr = 3;
03460         }
03461         break;
03462     }
03463   }
03464 #endif /* LWIP_ARP */
03465 }
03466 
03467 static void
03468 icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
03469 {
03470   /* return to object name, adding index depth (1) */
03471   ident_len += 1;
03472   ident -= 1;
03473   if ((ident_len == 2) &&
03474       (ident[0] > 0) && (ident[0] < 27))
03475   {
03476     od->id_inst_len = ident_len;
03477     od->id_inst_ptr = ident;
03478 
03479     od->instance = MIB_OBJECT_SCALAR;
03480     od->access = MIB_OBJECT_READ_ONLY;
03481     od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
03482     od->v_len = sizeof(u32_t);
03483   }
03484   else
03485   {
03486     LWIP_DEBUGF(SNMP_MIB_DEBUG,("icmp_get_object_def: no scalar\n"));
03487     od->instance = MIB_OBJECT_NONE;
03488   }
03489 }
03490 
03491 static void
03492 icmp_get_value(struct obj_def *od, u16_t len, void *value)
03493 {
03494   u32_t *uint_ptr = (u32_t*)value;
03495   u8_t id;
03496 
03497   LWIP_UNUSED_ARG(len);
03498   LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
03499   id = (u8_t)od->id_inst_ptr[0];
03500   switch (id)
03501   {
03502     case 1: /* icmpInMsgs */
03503       *uint_ptr = icmpinmsgs;
03504       break;
03505     case 2: /* icmpInErrors */
03506       *uint_ptr = icmpinerrors;
03507       break;
03508     case 3: /* icmpInDestUnreachs */
03509       *uint_ptr = icmpindestunreachs;
03510       break;
03511     case 4: /* icmpInTimeExcds */
03512       *uint_ptr = icmpintimeexcds;
03513       break;
03514     case 5: /* icmpInParmProbs */
03515       *uint_ptr = icmpinparmprobs;
03516       break;
03517     case 6: /* icmpInSrcQuenchs */
03518       *uint_ptr = icmpinsrcquenchs;
03519       break;
03520     case 7: /* icmpInRedirects */
03521       *uint_ptr = icmpinredirects;
03522       break;
03523     case 8: /* icmpInEchos */
03524       *uint_ptr = icmpinechos;
03525       break;
03526     case 9: /* icmpInEchoReps */
03527       *uint_ptr = icmpinechoreps;
03528       break;
03529     case 10: /* icmpInTimestamps */
03530       *uint_ptr = icmpintimestamps;
03531       break;
03532     case 11: /* icmpInTimestampReps */
03533       *uint_ptr = icmpintimestampreps;
03534       break;
03535     case 12: /* icmpInAddrMasks */
03536       *uint_ptr = icmpinaddrmasks;
03537       break;
03538     case 13: /* icmpInAddrMaskReps */
03539       *uint_ptr = icmpinaddrmaskreps;
03540       break;
03541     case 14: /* icmpOutMsgs */
03542       *uint_ptr = icmpoutmsgs;
03543       break;
03544     case 15: /* icmpOutErrors */
03545       *uint_ptr = icmpouterrors;
03546       break;
03547     case 16: /* icmpOutDestUnreachs */
03548       *uint_ptr = icmpoutdestunreachs;
03549       break;
03550     case 17: /* icmpOutTimeExcds */
03551       *uint_ptr = icmpouttimeexcds;
03552       break;
03553     case 18: /* icmpOutParmProbs */
03554       *uint_ptr = icmpoutparmprobs;
03555       break;
03556     case 19: /* icmpOutSrcQuenchs */
03557       *uint_ptr = icmpoutsrcquenchs;
03558       break;
03559     case 20: /* icmpOutRedirects */
03560       *uint_ptr = icmpoutredirects;
03561       break;
03562     case 21: /* icmpOutEchos */
03563       *uint_ptr = icmpoutechos;
03564       break;
03565     case 22: /* icmpOutEchoReps */
03566       *uint_ptr = icmpoutechoreps;
03567       break;
03568     case 23: /* icmpOutTimestamps */
03569       *uint_ptr = icmpouttimestamps;
03570       break;
03571     case 24: /* icmpOutTimestampReps */
03572       *uint_ptr = icmpouttimestampreps;
03573       break;
03574     case 25: /* icmpOutAddrMasks */
03575       *uint_ptr = icmpoutaddrmasks;
03576       break;
03577     case 26: /* icmpOutAddrMaskReps */
03578       *uint_ptr = icmpoutaddrmaskreps;
03579       break;
03580   }
03581 }
03582 
03583 #if LWIP_TCP
03584 /** @todo tcp grp */
03585 static void
03586 tcp_get_object_def (u8_t ident_len, s32_t *ident, struct obj_def *od)
03587 {
03588   u8_t id;
03589 
03590   /* return to object name, adding index depth (1) */
03591   ident_len += 1;
03592   ident -= 1;
03593   if (ident_len == 2)
03594   {
03595     od->id_inst_len = ident_len;
03596     od->id_inst_ptr = ident;
03597 
03598     LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
03599     id = (u8_t)ident[0];
03600     LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def tcp.%"U16_F".0\n",(u16_t)id));
03601 
03602     switch (id)
03603     {
03604       case 1: /* tcpRtoAlgorithm */
03605       case 2: /* tcpRtoMin */
03606       case 3: /* tcpRtoMax */
03607       case 4: /* tcpMaxConn */
03608         od->instance = MIB_OBJECT_SCALAR;
03609         od->access = MIB_OBJECT_READ_ONLY;
03610         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
03611         od->v_len = sizeof(s32_t);
03612         break;
03613       case 5: /* tcpActiveOpens */
03614       case 6: /* tcpPassiveOpens */
03615       case 7: /* tcpAttemptFails */
03616       case 8: /* tcpEstabResets */
03617       case 10: /* tcpInSegs */
03618       case 11: /* tcpOutSegs */
03619       case 12: /* tcpRetransSegs */
03620       case 14: /* tcpInErrs */
03621       case 15: /* tcpOutRsts */
03622         od->instance = MIB_OBJECT_SCALAR;
03623         od->access = MIB_OBJECT_READ_ONLY;
03624         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
03625         od->v_len = sizeof(u32_t);
03626         break;
03627       case 9: /* tcpCurrEstab */
03628         od->instance = MIB_OBJECT_TAB;
03629         od->access = MIB_OBJECT_READ_ONLY;
03630         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE);
03631         od->v_len = sizeof(u32_t);
03632         break;
03633       default:
03634         LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_object_def: no such object\n"));
03635         od->instance = MIB_OBJECT_NONE;
03636         break;
03637     };
03638   }
03639   else
03640   {
03641     LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_object_def: no scalar\n"));
03642     od->instance = MIB_OBJECT_NONE;
03643   }
03644 }
03645 
03646 static void
03647 tcp_get_value(struct obj_def *od, u16_t len, void *value)
03648 {
03649   u32_t *uint_ptr = (u32_t*)value;
03650   s32_t *sint_ptr = (s32_t*)value;
03651   u8_t id;
03652 
03653   LWIP_UNUSED_ARG(len);
03654   LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
03655   id = (u8_t)od->id_inst_ptr[0];
03656   switch (id)
03657   {
03658     case 1: /* tcpRtoAlgorithm, vanj(4) */
03659       *sint_ptr = 4;
03660       break;
03661     case 2: /* tcpRtoMin */
03662       /* @todo not the actual value, a guess,
03663           needs to be calculated */
03664       *sint_ptr = 1000;
03665       break;
03666     case 3: /* tcpRtoMax */
03667       /* @todo not the actual value, a guess,
03668          needs to be calculated */
03669       *sint_ptr = 60000;
03670       break;
03671     case 4: /* tcpMaxConn */
03672       *sint_ptr = MEMP_NUM_TCP_PCB;
03673       break;
03674     case 5: /* tcpActiveOpens */
03675       *uint_ptr = tcpactiveopens;
03676       break;
03677     case 6: /* tcpPassiveOpens */
03678       *uint_ptr = tcppassiveopens;
03679       break;
03680     case 7: /* tcpAttemptFails */
03681       *uint_ptr = tcpattemptfails;
03682       break;
03683     case 8: /* tcpEstabResets */
03684       *uint_ptr = tcpestabresets;
03685       break;
03686     case 9: /* tcpCurrEstab */
03687       {
03688         u16_t tcpcurrestab = 0;
03689         struct tcp_pcb *pcb = tcp_active_pcbs;
03690         while (pcb != NULL)
03691         {
03692           if ((pcb->state == ESTABLISHED) ||
03693               (pcb->state == CLOSE_WAIT))
03694           {
03695             tcpcurrestab++;
03696           }
03697           pcb = pcb->next;
03698         }
03699         *uint_ptr = tcpcurrestab;
03700       }
03701       break;
03702     case 10: /* tcpInSegs */
03703       *uint_ptr = tcpinsegs;
03704       break;
03705     case 11: /* tcpOutSegs */
03706       *uint_ptr = tcpoutsegs;
03707       break;
03708     case 12: /* tcpRetransSegs */
03709       *uint_ptr = tcpretranssegs;
03710       break;
03711     case 14: /* tcpInErrs */
03712       *uint_ptr = tcpinerrs;
03713       break;
03714     case 15: /* tcpOutRsts */
03715       *uint_ptr = tcpoutrsts;
03716       break;
03717   }
03718 }
03719 #ifdef THIS_SEEMS_UNUSED
03720 static void
03721 tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
03722 {
03723   /* return to object name, adding index depth (10) */
03724   ident_len += 10;
03725   ident -= 10;
03726 
03727   if (ident_len == 11)
03728   {
03729     u8_t id;
03730 
03731     od->id_inst_len = ident_len;
03732     od->id_inst_ptr = ident;
03733 
03734     id = ident[0];
03735     LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def tcp.%"U16_F".0\n",(u16_t)id));
03736 
03737     switch (id)
03738     {
03739       case 1: /* tcpConnState */
03740         od->instance = MIB_OBJECT_TAB;
03741         od->access = MIB_OBJECT_READ_WRITE;
03742         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
03743         od->v_len = sizeof(s32_t);
03744         break;
03745       case 2: /* tcpConnLocalAddress */
03746       case 4: /* tcpConnRemAddress */
03747         od->instance = MIB_OBJECT_TAB;
03748         od->access = MIB_OBJECT_READ_ONLY;
03749         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
03750         od->v_len = 4;
03751         break;
03752       case 3: /* tcpConnLocalPort */
03753       case 5: /* tcpConnRemPort */
03754         od->instance = MIB_OBJECT_TAB;
03755         od->access = MIB_OBJECT_READ_ONLY;
03756         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
03757         od->v_len = sizeof(s32_t);
03758         break;
03759       default:
03760         LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object\n"));
03761         od->instance = MIB_OBJECT_NONE;
03762         break;
03763     };
03764   }
03765   else
03766   {
03767     LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object\n"));
03768     od->instance = MIB_OBJECT_NONE;
03769   }
03770 }
03771 
03772 static void
03773 tcpconnentry_get_value (struct obj_def *od, u16_t len, void *value)
03774 {
03775   ip_addr_t lip, rip;
03776   u16_t lport, rport;
03777   s32_t *ident;
03778 
03779   ident = od->id_inst_ptr;
03780   snmp_oidtoip(&ident[1], &lip);
03781   lport = ident[5];
03782   snmp_oidtoip(&ident[6], &rip);
03783   rport = ident[10];
03784 
03785   /** @todo find matching PCB */
03786 }
03787 #endif /* if 0 */
03788 #endif
03789 
03790 static void
03791 udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
03792 {
03793   /* return to object name, adding index depth (1) */
03794   ident_len += 1;
03795   ident -= 1;
03796   if ((ident_len == 2) &&
03797       (ident[0] > 0) && (ident[0] < 6))
03798   {
03799     od->id_inst_len = ident_len;
03800     od->id_inst_ptr = ident;
03801 
03802     od->instance = MIB_OBJECT_SCALAR;
03803     od->access = MIB_OBJECT_READ_ONLY;
03804     od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
03805     od->v_len = sizeof(u32_t);
03806   }
03807   else
03808   {
03809     LWIP_DEBUGF(SNMP_MIB_DEBUG,("udp_get_object_def: no scalar\n"));
03810     od->instance = MIB_OBJECT_NONE;
03811   }
03812 }
03813 
03814 static void
03815 udp_get_value(struct obj_def *od, u16_t len, void *value)
03816 {
03817   u32_t *uint_ptr = (u32_t*)value;
03818   u8_t id;
03819 
03820   LWIP_UNUSED_ARG(len);
03821   LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
03822   id = (u8_t)od->id_inst_ptr[0];
03823   switch (id)
03824   {
03825     case 1: /* udpInDatagrams */
03826       *uint_ptr = udpindatagrams;
03827       break;
03828     case 2: /* udpNoPorts */
03829       *uint_ptr = udpnoports;
03830       break;
03831     case 3: /* udpInErrors */
03832       *uint_ptr = udpinerrors;
03833       break;
03834     case 4: /* udpOutDatagrams */
03835       *uint_ptr = udpoutdatagrams;
03836       break;
03837   }
03838 }
03839 
03840 static void
03841 udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
03842 {
03843   /* return to object name, adding index depth (5) */
03844   ident_len += 5;
03845   ident -= 5;
03846 
03847   if (ident_len == 6)
03848   {
03849     od->id_inst_len = ident_len;
03850     od->id_inst_ptr = ident;
03851 
03852     switch (ident[0])
03853     {
03854       case 1: /* udpLocalAddress */
03855         od->instance = MIB_OBJECT_TAB;
03856         od->access = MIB_OBJECT_READ_ONLY;
03857         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
03858         od->v_len = 4;
03859         break;
03860       case 2: /* udpLocalPort */
03861         od->instance = MIB_OBJECT_TAB;
03862         od->access = MIB_OBJECT_READ_ONLY;
03863         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
03864         od->v_len = sizeof(s32_t);
03865         break;
03866       default:
03867         LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no such object\n"));
03868         od->instance = MIB_OBJECT_NONE;
03869         break;
03870     }
03871   }
03872   else
03873   {
03874     LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no scalar\n"));
03875     od->instance = MIB_OBJECT_NONE;
03876   }
03877 }
03878 
03879 static void
03880 udpentry_get_value(struct obj_def *od, u16_t len, void *value)
03881 {
03882   u8_t id;
03883   struct udp_pcb *pcb;
03884   ip_addr_t ip;
03885   u16_t port;
03886 
03887   LWIP_UNUSED_ARG(len);
03888   snmp_oidtoip(&od->id_inst_ptr[1], &ip);
03889   LWIP_ASSERT("invalid port", (od->id_inst_ptr[5] >= 0) && (od->id_inst_ptr[5] <= 0xffff));
03890   port = (u16_t)od->id_inst_ptr[5];
03891 
03892   pcb = udp_pcbs;
03893   while ((pcb != NULL) &&
03894          !(ip_addr_cmp(&pcb->local_ip, &ip) &&
03895            (pcb->local_port == port)))
03896   {
03897     pcb = pcb->next;
03898   }
03899 
03900   if (pcb != NULL)
03901   {
03902     LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
03903     id = (u8_t)od->id_inst_ptr[0];
03904     switch (id)
03905     {
03906       case 1: /* udpLocalAddress */
03907         {
03908           ip_addr_t *dst = (ip_addr_t*)value;
03909           *dst = pcb->local_ip;
03910         }
03911         break;
03912       case 2: /* udpLocalPort */
03913         {
03914           s32_t *sint_ptr = (s32_t*)value;
03915           *sint_ptr = pcb->local_port;
03916         }
03917         break;
03918     }
03919   }
03920 }
03921 
03922 static void
03923 snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
03924 {
03925   /* return to object name, adding index depth (1) */
03926   ident_len += 1;
03927   ident -= 1;
03928   if (ident_len == 2)
03929   {
03930     u8_t id;
03931 
03932     od->id_inst_len = ident_len;
03933     od->id_inst_ptr = ident;
03934 
03935     LWIP_ASSERT("invalid id", (ident[0] >= 0) && (ident[0] <= 0xff));
03936     id = (u8_t)ident[0];
03937     switch (id)
03938     {
03939       case 1: /* snmpInPkts */
03940       case 2: /* snmpOutPkts */
03941       case 3: /* snmpInBadVersions */
03942       case 4: /* snmpInBadCommunityNames */
03943       case 5: /* snmpInBadCommunityUses */
03944       case 6: /* snmpInASNParseErrs */
03945       case 8: /* snmpInTooBigs */
03946       case 9: /* snmpInNoSuchNames */
03947       case 10: /* snmpInBadValues */
03948       case 11: /* snmpInReadOnlys */
03949       case 12: /* snmpInGenErrs */
03950       case 13: /* snmpInTotalReqVars */
03951       case 14: /* snmpInTotalSetVars */
03952       case 15: /* snmpInGetRequests */
03953       case 16: /* snmpInGetNexts */
03954       case 17: /* snmpInSetRequests */
03955       case 18: /* snmpInGetResponses */
03956       case 19: /* snmpInTraps */
03957       case 20: /* snmpOutTooBigs */
03958       case 21: /* snmpOutNoSuchNames */
03959       case 22: /* snmpOutBadValues */
03960       case 24: /* snmpOutGenErrs */
03961       case 25: /* snmpOutGetRequests */
03962       case 26: /* snmpOutGetNexts */
03963       case 27: /* snmpOutSetRequests */
03964       case 28: /* snmpOutGetResponses */
03965       case 29: /* snmpOutTraps */
03966         od->instance = MIB_OBJECT_SCALAR;
03967         od->access = MIB_OBJECT_READ_ONLY;
03968         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
03969         od->v_len = sizeof(u32_t);
03970         break;
03971       case 30: /* snmpEnableAuthenTraps */
03972         od->instance = MIB_OBJECT_SCALAR;
03973         od->access = MIB_OBJECT_READ_WRITE;
03974         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
03975         od->v_len = sizeof(s32_t);
03976         break;
03977       default:
03978         LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no such object\n"));
03979         od->instance = MIB_OBJECT_NONE;
03980         break;
03981     };
03982   }
03983   else
03984   {
03985     LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no scalar\n"));
03986     od->instance = MIB_OBJECT_NONE;
03987   }
03988 }
03989 
03990 static void
03991 snmp_get_value(struct obj_def *od, u16_t len, void *value)
03992 {
03993   u32_t *uint_ptr = (u32_t*)value;
03994   u8_t id;
03995 
03996   LWIP_UNUSED_ARG(len);
03997   LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
03998   id = (u8_t)od->id_inst_ptr[0];
03999   switch (id)
04000   {
04001       case 1: /* snmpInPkts */
04002         *uint_ptr = snmpinpkts;
04003         break;
04004       case 2: /* snmpOutPkts */
04005         *uint_ptr = snmpoutpkts;
04006         break;
04007       case 3: /* snmpInBadVersions */
04008         *uint_ptr = snmpinbadversions;
04009         break;
04010       case 4: /* snmpInBadCommunityNames */
04011         *uint_ptr = snmpinbadcommunitynames;
04012         break;
04013       case 5: /* snmpInBadCommunityUses */
04014         *uint_ptr = snmpinbadcommunityuses;
04015         break;
04016       case 6: /* snmpInASNParseErrs */
04017         *uint_ptr = snmpinasnparseerrs;
04018         break;
04019       case 8: /* snmpInTooBigs */
04020         *uint_ptr = snmpintoobigs;
04021         break;
04022       case 9: /* snmpInNoSuchNames */
04023         *uint_ptr = snmpinnosuchnames;
04024         break;
04025       case 10: /* snmpInBadValues */
04026         *uint_ptr = snmpinbadvalues;
04027         break;
04028       case 11: /* snmpInReadOnlys */
04029         *uint_ptr = snmpinreadonlys;
04030         break;
04031       case 12: /* snmpInGenErrs */
04032         *uint_ptr = snmpingenerrs;
04033         break;
04034       case 13: /* snmpInTotalReqVars */
04035         *uint_ptr = snmpintotalreqvars;
04036         break;
04037       case 14: /* snmpInTotalSetVars */
04038         *uint_ptr = snmpintotalsetvars;
04039         break;
04040       case 15: /* snmpInGetRequests */
04041         *uint_ptr = snmpingetrequests;
04042         break;
04043       case 16: /* snmpInGetNexts */
04044         *uint_ptr = snmpingetnexts;
04045         break;
04046       case 17: /* snmpInSetRequests */
04047         *uint_ptr = snmpinsetrequests;
04048         break;
04049       case 18: /* snmpInGetResponses */
04050         *uint_ptr = snmpingetresponses;
04051         break;
04052       case 19: /* snmpInTraps */
04053         *uint_ptr = snmpintraps;
04054         break;
04055       case 20: /* snmpOutTooBigs */
04056         *uint_ptr = snmpouttoobigs;
04057         break;
04058       case 21: /* snmpOutNoSuchNames */
04059         *uint_ptr = snmpoutnosuchnames;
04060         break;
04061       case 22: /* snmpOutBadValues */
04062         *uint_ptr = snmpoutbadvalues;
04063         break;
04064       case 24: /* snmpOutGenErrs */
04065         *uint_ptr = snmpoutgenerrs;
04066         break;
04067       case 25: /* snmpOutGetRequests */
04068         *uint_ptr = snmpoutgetrequests;
04069         break;
04070       case 26: /* snmpOutGetNexts */
04071         *uint_ptr = snmpoutgetnexts;
04072         break;
04073       case 27: /* snmpOutSetRequests */
04074         *uint_ptr = snmpoutsetrequests;
04075         break;
04076       case 28: /* snmpOutGetResponses */
04077         *uint_ptr = snmpoutgetresponses;
04078         break;
04079       case 29: /* snmpOutTraps */
04080         *uint_ptr = snmpouttraps;
04081         break;
04082       case 30: /* snmpEnableAuthenTraps */
04083         *uint_ptr = *snmpenableauthentraps_ptr;
04084         break;
04085   };
04086 }
04087 
04088 /**
04089  * Test snmp object value before setting.
04090  *
04091  * @param od is the object definition
04092  * @param len return value space (in bytes)
04093  * @param value points to (varbind) space to copy value from.
04094  */
04095 static u8_t
04096 snmp_set_test(struct obj_def *od, u16_t len, void *value)
04097 {
04098   u8_t id, set_ok;
04099 
04100   LWIP_UNUSED_ARG(len);
04101   set_ok = 0;
04102   LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
04103   id = (u8_t)od->id_inst_ptr[0];
04104   if (id == 30)
04105   {
04106     /* snmpEnableAuthenTraps */
04107     s32_t *sint_ptr = (s32_t*)value;
04108 
04109     if (snmpenableauthentraps_ptr != &snmpenableauthentraps_default)
04110     {
04111       /* we should have writable non-volatile mem here */
04112       if ((*sint_ptr == 1) || (*sint_ptr == 2))
04113       {
04114         set_ok = 1;
04115       }
04116     }
04117     else
04118     {
04119       /* const or hardwired value */
04120       if (*sint_ptr == snmpenableauthentraps_default)
04121       {
04122         set_ok = 1;
04123       }
04124     }
04125   }
04126   return set_ok;
04127 }
04128 
04129 static void
04130 snmp_set_value(struct obj_def *od, u16_t len, void *value)
04131 {
04132   u8_t id;
04133 
04134   LWIP_UNUSED_ARG(len);
04135   LWIP_ASSERT("invalid id", (od->id_inst_ptr[0] >= 0) && (od->id_inst_ptr[0] <= 0xff));
04136   id = (u8_t)od->id_inst_ptr[0];
04137   if (id == 30)
04138   {
04139     /* snmpEnableAuthenTraps */
04140     /* @todo @fixme: which kind of pointer is 'value'? s32_t or u8_t??? */
04141     u8_t *ptr = (u8_t*)value;
04142     *snmpenableauthentraps_ptr = *ptr;
04143   }
04144 }
04145 
04146 #endif /* LWIP_SNMP */