Lorcan Smith / Mbed 2 deprecated Enet_SPI

Dependencies:   mbed

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