Dependents:   TimeZoneDemo EthernetJackTestCode MMEx_Challenge ntp_mem ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mib2.c Source File

mib2.c

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