Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Release 1.0
[palacios.git] / geekos / src / lwip / core / snmp / mib2.c
1 /**
2  * @file
3  * Management Information Base II (RFC1213) objects and functions.
4  *
5  * @note the object identifiers for this MIB-2 and private MIB tree
6  * must be kept in sorted ascending order. This to ensure correct getnext operation.
7  */
8
9 /*
10  * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without modification,
14  * are permitted provided that the following conditions are met:
15  *
16  * 1. Redistributions of source code must retain the above copyright notice,
17  *    this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright notice,
19  *    this list of conditions and the following disclaimer in the documentation
20  *    and/or other materials provided with the distribution.
21  * 3. The name of the author may not be used to endorse or promote products
22  *    derived from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
25  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
27  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
29  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
33  * OF SUCH DAMAGE.
34  *
35  * Author: Christiaan Simons <christiaan.simons@axon.tv>
36  */
37
38 #include "lwip/opt.h"
39
40 #if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */
41
42 #include "lwip/snmp.h"
43 #include "lwip/netif.h"
44 #include "lwip/ip.h"
45 #include "lwip/ip_frag.h"
46 #include "lwip/tcp.h"
47 #include "lwip/udp.h"
48 #include "lwip/snmp_asn1.h"
49 #include "lwip/snmp_structs.h"
50 #include "netif/etharp.h"
51
52 /**
53  * IANA assigned enterprise ID for lwIP is 26381
54  * @see http://www.iana.org/assignments/enterprise-numbers
55  *
56  * @note this enterprise ID is assigned to the lwIP project,
57  * all object identifiers living under this ID are assigned
58  * by the lwIP maintainers (contact Christiaan Simons)!
59  * @note don't change this define, use snmp_set_sysobjid()
60  *
61  * If you need to create your own private MIB you'll need
62  * to apply for your own enterprise ID with IANA:
63  * http://www.iana.org/numbers.html
64  */
65 #define SNMP_ENTERPRISE_ID 26381
66 #define SNMP_SYSOBJID_LEN 7
67 #define SNMP_SYSOBJID {1, 3, 6, 1, 4, 1, SNMP_ENTERPRISE_ID}
68
69 #ifndef SNMP_SYSSERVICES
70 #define SNMP_SYSSERVICES ((1 << 6) | (1 << 3) | ((IP_FORWARD) << 2))
71 #endif
72
73 #ifndef SNMP_GET_SYSUPTIME
74 #define SNMP_GET_SYSUPTIME(sysuptime)
75 #endif
76
77 static void system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
78 static void system_get_value(struct obj_def *od, u16_t len, void *value);
79 static u8_t system_set_test(struct obj_def *od, u16_t len, void *value);
80 static void system_set_value(struct obj_def *od, u16_t len, void *value);
81 static void interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
82 static void interfaces_get_value(struct obj_def *od, u16_t len, void *value);
83 static void ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
84 static void ifentry_get_value(struct obj_def *od, u16_t len, void *value);
85 #if !SNMP_SAFE_REQUESTS
86 static u8_t ifentry_set_test (struct obj_def *od, u16_t len, void *value);
87 static void ifentry_set_value (struct obj_def *od, u16_t len, void *value);
88 #endif /* SNMP_SAFE_REQUESTS */
89 static void atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
90 static void atentry_get_value(struct obj_def *od, u16_t len, void *value);
91 static void ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
92 static void ip_get_value(struct obj_def *od, u16_t len, void *value);
93 static u8_t ip_set_test(struct obj_def *od, u16_t len, void *value);
94 static void ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
95 static void ip_addrentry_get_value(struct obj_def *od, u16_t len, void *value);
96 static void ip_rteentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
97 static void ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value);
98 static void ip_ntomentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
99 static void ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value);
100 static void icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
101 static void icmp_get_value(struct obj_def *od, u16_t len, void *value);
102 #if LWIP_TCP
103 static void tcp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
104 static void tcp_get_value(struct obj_def *od, u16_t len, void *value);
105 #ifdef THIS_SEEMS_UNUSED
106 static void tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
107 static void tcpconnentry_get_value(struct obj_def *od, u16_t len, void *value);
108 #endif
109 #endif
110 static void udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
111 static void udp_get_value(struct obj_def *od, u16_t len, void *value);
112 static void udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
113 static void udpentry_get_value(struct obj_def *od, u16_t len, void *value);
114 static void snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
115 static void snmp_get_value(struct obj_def *od, u16_t len, void *value);
116 static u8_t snmp_set_test(struct obj_def *od, u16_t len, void *value);
117 static void snmp_set_value(struct obj_def *od, u16_t len, void *value);
118
119
120 /* snmp .1.3.6.1.2.1.11 */
121 const mib_scalar_node snmp_scalar = {
122   &snmp_get_object_def,
123   &snmp_get_value,
124   &snmp_set_test,
125   &snmp_set_value,
126   MIB_NODE_SC,
127   0
128 };
129 const s32_t snmp_ids[28] = {
130   1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16,
131   17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30
132 };
133 struct mib_node* const snmp_nodes[28] = {
134   (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar,
135   (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar,
136   (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar,
137   (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar,
138   (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar,
139   (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar,
140   (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar,
141   (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar,
142   (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar,
143   (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar,
144   (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar,
145   (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar,
146   (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar,
147   (struct mib_node* const)&snmp_scalar, (struct mib_node* const)&snmp_scalar
148 };
149 const struct mib_array_node snmp = {
150   &noleafs_get_object_def,
151   &noleafs_get_value,
152   &noleafs_set_test,
153   &noleafs_set_value,
154   MIB_NODE_AR,
155   28,
156   snmp_ids,
157   snmp_nodes
158 };
159
160 /* dot3 and EtherLike MIB not planned. (transmission .1.3.6.1.2.1.10) */
161 /* historical (some say hysterical). (cmot .1.3.6.1.2.1.9) */
162 /* lwIP has no EGP, thus may not implement it. (egp .1.3.6.1.2.1.8) */
163
164 /* udp .1.3.6.1.2.1.7 */
165 /** index root node for udpTable */
166 struct mib_list_rootnode udp_root = {
167   &noleafs_get_object_def,
168   &noleafs_get_value,
169   &noleafs_set_test,
170   &noleafs_set_value,
171   MIB_NODE_LR,
172   0,
173   NULL,
174   NULL,
175   0
176 };
177 const s32_t udpentry_ids[2] = { 1, 2 };
178 struct mib_node* const udpentry_nodes[2] = {
179   (struct mib_node* const)&udp_root, (struct mib_node* const)&udp_root,
180 };
181 const struct mib_array_node udpentry = {
182   &noleafs_get_object_def,
183   &noleafs_get_value,
184   &noleafs_set_test,
185   &noleafs_set_value,
186   MIB_NODE_AR,
187   2,
188   udpentry_ids,
189   udpentry_nodes
190 };
191
192 s32_t udptable_id = 1;
193 struct mib_node* udptable_node = (struct mib_node* const)&udpentry;
194 struct mib_ram_array_node udptable = {
195   &noleafs_get_object_def,
196   &noleafs_get_value,
197   &noleafs_set_test,
198   &noleafs_set_value,
199   MIB_NODE_RA,
200   0,
201   &udptable_id,
202   &udptable_node
203 };
204
205 const mib_scalar_node udp_scalar = {
206   &udp_get_object_def,
207   &udp_get_value,
208   &noleafs_set_test,
209   &noleafs_set_value,
210   MIB_NODE_SC,
211   0
212 };
213 const s32_t udp_ids[5] = { 1, 2, 3, 4, 5 };
214 struct mib_node* const udp_nodes[5] = {
215   (struct mib_node* const)&udp_scalar, (struct mib_node* const)&udp_scalar,
216   (struct mib_node* const)&udp_scalar, (struct mib_node* const)&udp_scalar,
217   (struct mib_node* const)&udptable
218 };
219 const struct mib_array_node udp = {
220   &noleafs_get_object_def,
221   &noleafs_get_value,
222   &noleafs_set_test,
223   &noleafs_set_value,
224   MIB_NODE_AR,
225   5,
226   udp_ids,
227   udp_nodes
228 };
229
230 /* tcp .1.3.6.1.2.1.6 */
231 #if LWIP_TCP
232 /* only if the TCP protocol is available may implement this group */
233 /** index root node for tcpConnTable */
234 struct mib_list_rootnode tcpconntree_root = {
235   &noleafs_get_object_def,
236   &noleafs_get_value,
237   &noleafs_set_test,
238   &noleafs_set_value,
239   MIB_NODE_LR,
240   0,
241   NULL,
242   NULL,
243   0
244 };
245 const s32_t tcpconnentry_ids[5] = { 1, 2, 3, 4, 5 };
246 struct mib_node* const tcpconnentry_nodes[5] = {
247   (struct mib_node* const)&tcpconntree_root, (struct mib_node* const)&tcpconntree_root,
248   (struct mib_node* const)&tcpconntree_root, (struct mib_node* const)&tcpconntree_root,
249   (struct mib_node* const)&tcpconntree_root
250 };
251 const struct mib_array_node tcpconnentry = {
252   &noleafs_get_object_def,
253   &noleafs_get_value,
254   &noleafs_set_test,
255   &noleafs_set_value,
256   MIB_NODE_AR,
257   5,
258   tcpconnentry_ids,
259   tcpconnentry_nodes
260 };
261
262 s32_t tcpconntable_id = 1;
263 struct mib_node* tcpconntable_node = (struct mib_node* const)&tcpconnentry;
264 struct mib_ram_array_node tcpconntable = {
265   &noleafs_get_object_def,
266   &noleafs_get_value,
267   &noleafs_set_test,
268   &noleafs_set_value,
269   MIB_NODE_RA,
270 /** @todo update maxlength when inserting / deleting from table
271    0 when table is empty, 1 when more than one entry */
272   0,
273   &tcpconntable_id,
274   &tcpconntable_node
275 };
276
277 const mib_scalar_node tcp_scalar = {
278   &tcp_get_object_def,
279   &tcp_get_value,
280   &noleafs_set_test,
281   &noleafs_set_value,
282   MIB_NODE_SC,
283   0
284 };
285 const s32_t tcp_ids[15] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
286 struct mib_node* const tcp_nodes[15] = {
287   (struct mib_node* const)&tcp_scalar, (struct mib_node* const)&tcp_scalar,
288   (struct mib_node* const)&tcp_scalar, (struct mib_node* const)&tcp_scalar,
289   (struct mib_node* const)&tcp_scalar, (struct mib_node* const)&tcp_scalar,
290   (struct mib_node* const)&tcp_scalar, (struct mib_node* const)&tcp_scalar,
291   (struct mib_node* const)&tcp_scalar, (struct mib_node* const)&tcp_scalar,
292   (struct mib_node* const)&tcp_scalar, (struct mib_node* const)&tcp_scalar,
293   (struct mib_node* const)&tcpconntable, (struct mib_node* const)&tcp_scalar,
294   (struct mib_node* const)&tcp_scalar
295 };
296 const struct mib_array_node tcp = {
297   &noleafs_get_object_def,
298   &noleafs_get_value,
299   &noleafs_set_test,
300   &noleafs_set_value,
301   MIB_NODE_AR,
302   15,
303   tcp_ids,
304   tcp_nodes
305 };
306 #endif
307
308 /* icmp .1.3.6.1.2.1.5 */
309 const mib_scalar_node icmp_scalar = {
310   &icmp_get_object_def,
311   &icmp_get_value,
312   &noleafs_set_test,
313   &noleafs_set_value,
314   MIB_NODE_SC,
315   0
316 };
317 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 };
318 struct mib_node* const icmp_nodes[26] = {
319   (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar,
320   (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar,
321   (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar,
322   (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar,
323   (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar,
324   (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar,
325   (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar,
326   (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar,
327   (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar,
328   (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar,
329   (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar,
330   (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar,
331   (struct mib_node* const)&icmp_scalar, (struct mib_node* const)&icmp_scalar
332 };
333 const struct mib_array_node icmp = {
334   &noleafs_get_object_def,
335   &noleafs_get_value,
336   &noleafs_set_test,
337   &noleafs_set_value,
338   MIB_NODE_AR,
339   26,
340   icmp_ids,
341   icmp_nodes
342 };
343
344 /** index root node for ipNetToMediaTable */
345 struct mib_list_rootnode ipntomtree_root = {
346   &noleafs_get_object_def,
347   &noleafs_get_value,
348   &noleafs_set_test,
349   &noleafs_set_value,
350   MIB_NODE_LR,
351   0,
352   NULL,
353   NULL,
354   0
355 };
356 const s32_t ipntomentry_ids[4] = { 1, 2, 3, 4 };
357 struct mib_node* const ipntomentry_nodes[4] = {
358   (struct mib_node* const)&ipntomtree_root, (struct mib_node* const)&ipntomtree_root,
359   (struct mib_node* const)&ipntomtree_root, (struct mib_node* const)&ipntomtree_root
360 };
361 const struct mib_array_node ipntomentry = {
362   &noleafs_get_object_def,
363   &noleafs_get_value,
364   &noleafs_set_test,
365   &noleafs_set_value,
366   MIB_NODE_AR,
367   4,
368   ipntomentry_ids,
369   ipntomentry_nodes
370 };
371
372 s32_t ipntomtable_id = 1;
373 struct mib_node* ipntomtable_node = (struct mib_node* const)&ipntomentry;
374 struct mib_ram_array_node ipntomtable = {
375   &noleafs_get_object_def,
376   &noleafs_get_value,
377   &noleafs_set_test,
378   &noleafs_set_value,
379   MIB_NODE_RA,
380   0,
381   &ipntomtable_id,
382   &ipntomtable_node
383 };
384
385 /** index root node for ipRouteTable */
386 struct mib_list_rootnode iprtetree_root = {
387   &noleafs_get_object_def,
388   &noleafs_get_value,
389   &noleafs_set_test,
390   &noleafs_set_value,
391   MIB_NODE_LR,
392   0,
393   NULL,
394   NULL,
395   0
396 };
397 const s32_t iprteentry_ids[13] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
398 struct mib_node* const iprteentry_nodes[13] = {
399   (struct mib_node* const)&iprtetree_root, (struct mib_node* const)&iprtetree_root,
400   (struct mib_node* const)&iprtetree_root, (struct mib_node* const)&iprtetree_root,
401   (struct mib_node* const)&iprtetree_root, (struct mib_node* const)&iprtetree_root,
402   (struct mib_node* const)&iprtetree_root, (struct mib_node* const)&iprtetree_root,
403   (struct mib_node* const)&iprtetree_root, (struct mib_node* const)&iprtetree_root,
404   (struct mib_node* const)&iprtetree_root, (struct mib_node* const)&iprtetree_root,
405   (struct mib_node* const)&iprtetree_root
406 };
407 const struct mib_array_node iprteentry = {
408   &noleafs_get_object_def,
409   &noleafs_get_value,
410   &noleafs_set_test,
411   &noleafs_set_value,
412   MIB_NODE_AR,
413   13,
414   iprteentry_ids,
415   iprteentry_nodes
416 };
417
418 s32_t iprtetable_id = 1;
419 struct mib_node* iprtetable_node = (struct mib_node* const)&iprteentry;
420 struct mib_ram_array_node iprtetable = {
421   &noleafs_get_object_def,
422   &noleafs_get_value,
423   &noleafs_set_test,
424   &noleafs_set_value,
425   MIB_NODE_RA,
426   0,
427   &iprtetable_id,
428   &iprtetable_node
429 };
430
431 /** index root node for ipAddrTable */
432 struct mib_list_rootnode ipaddrtree_root = {
433   &noleafs_get_object_def,
434   &noleafs_get_value,
435   &noleafs_set_test,
436   &noleafs_set_value,
437   MIB_NODE_LR,
438   0,
439   NULL,
440   NULL,
441   0
442 };
443 const s32_t ipaddrentry_ids[5] = { 1, 2, 3, 4, 5 };
444 struct mib_node* const ipaddrentry_nodes[5] = {
445   (struct mib_node* const)&ipaddrtree_root,
446   (struct mib_node* const)&ipaddrtree_root,
447   (struct mib_node* const)&ipaddrtree_root,
448   (struct mib_node* const)&ipaddrtree_root,
449   (struct mib_node* const)&ipaddrtree_root
450 };
451 const struct mib_array_node ipaddrentry = {
452   &noleafs_get_object_def,
453   &noleafs_get_value,
454   &noleafs_set_test,
455   &noleafs_set_value,
456   MIB_NODE_AR,
457   5,
458   ipaddrentry_ids,
459   ipaddrentry_nodes
460 };
461
462 s32_t ipaddrtable_id = 1;
463 struct mib_node* ipaddrtable_node = (struct mib_node* const)&ipaddrentry;
464 struct mib_ram_array_node ipaddrtable = {
465   &noleafs_get_object_def,
466   &noleafs_get_value,
467   &noleafs_set_test,
468   &noleafs_set_value,
469   MIB_NODE_RA,
470   0,
471   &ipaddrtable_id,
472   &ipaddrtable_node
473 };
474
475 /* ip .1.3.6.1.2.1.4 */
476 const mib_scalar_node ip_scalar = {
477   &ip_get_object_def,
478   &ip_get_value,
479   &ip_set_test,
480   &noleafs_set_value,
481   MIB_NODE_SC,
482   0
483 };
484 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 };
485 struct mib_node* const ip_nodes[23] = {
486   (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar,
487   (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar,
488   (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar,
489   (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar,
490   (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar,
491   (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar,
492   (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar,
493   (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar,
494   (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ip_scalar,
495   (struct mib_node* const)&ip_scalar, (struct mib_node* const)&ipaddrtable,
496   (struct mib_node* const)&iprtetable, (struct mib_node* const)&ipntomtable,
497   (struct mib_node* const)&ip_scalar
498 };
499 const struct mib_array_node mib2_ip = {
500   &noleafs_get_object_def,
501   &noleafs_get_value,
502   &noleafs_set_test,
503   &noleafs_set_value,
504   MIB_NODE_AR,
505   23,
506   ip_ids,
507   ip_nodes
508 };
509
510 /** index root node for atTable */
511 struct mib_list_rootnode arptree_root = {
512   &noleafs_get_object_def,
513   &noleafs_get_value,
514   &noleafs_set_test,
515   &noleafs_set_value,
516   MIB_NODE_LR,
517   0,
518   NULL,
519   NULL,
520   0
521 };
522 const s32_t atentry_ids[3] = { 1, 2, 3 };
523 struct mib_node* const atentry_nodes[3] = {
524   (struct mib_node* const)&arptree_root,
525   (struct mib_node* const)&arptree_root,
526   (struct mib_node* const)&arptree_root
527 };
528 const struct mib_array_node atentry = {
529   &noleafs_get_object_def,
530   &noleafs_get_value,
531   &noleafs_set_test,
532   &noleafs_set_value,
533   MIB_NODE_AR,
534   3,
535   atentry_ids,
536   atentry_nodes
537 };
538
539 const s32_t attable_id = 1;
540 struct mib_node* const attable_node = (struct mib_node* const)&atentry;
541 const struct mib_array_node attable = {
542   &noleafs_get_object_def,
543   &noleafs_get_value,
544   &noleafs_set_test,
545   &noleafs_set_value,
546   MIB_NODE_AR,
547   1,
548   &attable_id,
549   &attable_node
550 };
551
552 /* at .1.3.6.1.2.1.3 */
553 s32_t at_id = 1;
554 struct mib_node* mib2_at_node = (struct mib_node* const)&attable;
555 struct mib_ram_array_node at = {
556   &noleafs_get_object_def,
557   &noleafs_get_value,
558   &noleafs_set_test,
559   &noleafs_set_value,
560   MIB_NODE_RA,
561   0,
562   &at_id,
563   &mib2_at_node
564 };
565
566 /** index root node for ifTable */
567 struct mib_list_rootnode iflist_root = {
568   &ifentry_get_object_def,
569   &ifentry_get_value,
570 #if SNMP_SAFE_REQUESTS
571   &noleafs_set_test,
572   &noleafs_set_value,
573 #else /* SNMP_SAFE_REQUESTS */
574   &ifentry_set_test,
575   &ifentry_set_value,
576 #endif /* SNMP_SAFE_REQUESTS */
577   MIB_NODE_LR,
578   0,
579   NULL,
580   NULL,
581   0
582 };
583 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 };
584 struct mib_node* const ifentry_nodes[22] = {
585   (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root,
586   (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root,
587   (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root,
588   (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root,
589   (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root,
590   (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root,
591   (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root,
592   (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root,
593   (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root,
594   (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root,
595   (struct mib_node* const)&iflist_root, (struct mib_node* const)&iflist_root
596 };
597 const struct mib_array_node ifentry = {
598   &noleafs_get_object_def,
599   &noleafs_get_value,
600   &noleafs_set_test,
601   &noleafs_set_value,
602   MIB_NODE_AR,
603   22,
604   ifentry_ids,
605   ifentry_nodes
606 };
607
608 s32_t iftable_id = 1;
609 struct mib_node* iftable_node = (struct mib_node* const)&ifentry;
610 struct mib_ram_array_node iftable = {
611   &noleafs_get_object_def,
612   &noleafs_get_value,
613   &noleafs_set_test,
614   &noleafs_set_value,
615   MIB_NODE_RA,
616   0,
617   &iftable_id,
618   &iftable_node
619 };
620
621 /* interfaces .1.3.6.1.2.1.2 */
622 const mib_scalar_node interfaces_scalar = {
623   &interfaces_get_object_def,
624   &interfaces_get_value,
625   &noleafs_set_test,
626   &noleafs_set_value,
627   MIB_NODE_SC,
628   0
629 };
630 const s32_t interfaces_ids[2] = { 1, 2 };
631 struct mib_node* const interfaces_nodes[2] = {
632   (struct mib_node* const)&interfaces_scalar, (struct mib_node* const)&iftable
633 };
634 const struct mib_array_node interfaces = {
635   &noleafs_get_object_def,
636   &noleafs_get_value,
637   &noleafs_set_test,
638   &noleafs_set_value,
639   MIB_NODE_AR,
640   2,
641   interfaces_ids,
642   interfaces_nodes
643 };
644
645
646 /*             0 1 2 3 4 5 6 */
647 /* system .1.3.6.1.2.1.1 */
648 const mib_scalar_node sys_tem_scalar = {
649   &system_get_object_def,
650   &system_get_value,
651   &system_set_test,
652   &system_set_value,
653   MIB_NODE_SC,
654   0
655 };
656 const s32_t sys_tem_ids[7] = { 1, 2, 3, 4, 5, 6, 7 };
657 struct mib_node* const sys_tem_nodes[7] = {
658   (struct mib_node* const)&sys_tem_scalar, (struct mib_node* const)&sys_tem_scalar,
659   (struct mib_node* const)&sys_tem_scalar, (struct mib_node* const)&sys_tem_scalar,
660   (struct mib_node* const)&sys_tem_scalar, (struct mib_node* const)&sys_tem_scalar,
661   (struct mib_node* const)&sys_tem_scalar
662 };
663 /* work around name issue with 'sys_tem', some compiler(s?) seem to reserve 'system' */
664 const struct mib_array_node sys_tem = {
665   &noleafs_get_object_def,
666   &noleafs_get_value,
667   &noleafs_set_test,
668   &noleafs_set_value,
669   MIB_NODE_AR,
670   7,
671   sys_tem_ids,
672   sys_tem_nodes
673 };
674
675 /* mib-2 .1.3.6.1.2.1 */
676 #if LWIP_TCP
677 #define MIB2_GROUPS 8
678 #else
679 #define MIB2_GROUPS 7
680 #endif
681 const s32_t mib2_ids[MIB2_GROUPS] =
682 {
683   1,
684   2,
685   3,
686   4,
687   5,
688 #if LWIP_TCP
689   6,
690 #endif
691   7,
692   11
693 };
694 struct mib_node* const mib2_nodes[MIB2_GROUPS] = {
695   (struct mib_node* const)&sys_tem,
696   (struct mib_node* const)&interfaces,
697   (struct mib_node* const)&at,
698   (struct mib_node* const)&mib2_ip,
699   (struct mib_node* const)&icmp,
700 #if LWIP_TCP
701   (struct mib_node* const)&tcp,
702 #endif
703   (struct mib_node* const)&udp,
704   (struct mib_node* const)&snmp
705 };
706
707 const struct mib_array_node mib2 = {
708   &noleafs_get_object_def,
709   &noleafs_get_value,
710   &noleafs_set_test,
711   &noleafs_set_value,
712   MIB_NODE_AR,
713   MIB2_GROUPS,
714   mib2_ids,
715   mib2_nodes
716 };
717
718 /* mgmt .1.3.6.1.2 */
719 const s32_t mgmt_ids[1] = { 1 };
720 struct mib_node* const mgmt_nodes[1] = { (struct mib_node* const)&mib2 };
721 const struct mib_array_node mgmt = {
722   &noleafs_get_object_def,
723   &noleafs_get_value,
724   &noleafs_set_test,
725   &noleafs_set_value,
726   MIB_NODE_AR,
727   1,
728   mgmt_ids,
729   mgmt_nodes
730 };
731
732 /* internet .1.3.6.1 */
733 #if SNMP_PRIVATE_MIB
734 s32_t internet_ids[2] = { 2, 4 };
735 struct mib_node* const internet_nodes[2] = { (struct mib_node* const)&mgmt, (struct mib_node* const)&private };
736 const struct mib_array_node internet = {
737   &noleafs_get_object_def,
738   &noleafs_get_value,
739   &noleafs_set_test,
740   &noleafs_set_value,
741   MIB_NODE_AR,
742   2,
743   internet_ids,
744   internet_nodes
745 };
746 #else
747 const s32_t internet_ids[1] = { 2 };
748 struct mib_node* const internet_nodes[1] = { (struct mib_node* const)&mgmt };
749 const struct mib_array_node internet = {
750   &noleafs_get_object_def,
751   &noleafs_get_value,
752   &noleafs_set_test,
753   &noleafs_set_value,
754   MIB_NODE_AR,
755   1,
756   internet_ids,
757   internet_nodes
758 };
759 #endif
760
761 /** mib-2.system.sysObjectID  */
762 static struct snmp_obj_id sysobjid = {SNMP_SYSOBJID_LEN, SNMP_SYSOBJID};
763 /** enterprise ID for generic TRAPs, .iso.org.dod.internet.mgmt.mib-2.snmp */
764 static struct snmp_obj_id snmpgrp_id = {7,{1,3,6,1,2,1,11}};
765 /** mib-2.system.sysServices */
766 static const s32_t sysservices = SNMP_SYSSERVICES;
767
768 /** mib-2.system.sysDescr */
769 static const u8_t sysdescr_len_default = 4;
770 static const u8_t sysdescr_default[] = "lwIP";
771 static u8_t* sysdescr_len_ptr = (u8_t*)&sysdescr_len_default;
772 static u8_t* sysdescr_ptr = (u8_t*)&sysdescr_default[0];
773 /** mib-2.system.sysContact */
774 static const u8_t syscontact_len_default = 0;
775 static const u8_t syscontact_default[] = "";
776 static u8_t* syscontact_len_ptr = (u8_t*)&syscontact_len_default;
777 static u8_t* syscontact_ptr = (u8_t*)&syscontact_default[0];
778 /** mib-2.system.sysName */
779 static const u8_t sysname_len_default = 8;
780 static const u8_t sysname_default[] = "FQDN-unk";
781 static u8_t* sysname_len_ptr = (u8_t*)&sysname_len_default;
782 static u8_t* sysname_ptr = (u8_t*)&sysname_default[0];
783 /** mib-2.system.sysLocation */
784 static const u8_t syslocation_len_default = 0;
785 static const u8_t syslocation_default[] = "";
786 static u8_t* syslocation_len_ptr = (u8_t*)&syslocation_len_default;
787 static u8_t* syslocation_ptr = (u8_t*)&syslocation_default[0];
788 /** mib-2.snmp.snmpEnableAuthenTraps */
789 static const u8_t snmpenableauthentraps_default = 2; /* disabled */
790 static u8_t* snmpenableauthentraps_ptr = (u8_t*)&snmpenableauthentraps_default;
791
792 /** mib-2.interfaces.ifTable.ifEntry.ifSpecific (zeroDotZero) */
793 static const struct snmp_obj_id ifspecific = {2, {0, 0}};
794 /** mib-2.ip.ipRouteTable.ipRouteEntry.ipRouteInfo (zeroDotZero) */
795 static const struct snmp_obj_id iprouteinfo = {2, {0, 0}};
796
797
798
799 /* mib-2.system counter(s) */
800 static u32_t sysuptime = 0;
801
802 /* mib-2.ip counter(s) */
803 static u32_t ipinreceives = 0,
804              ipinhdrerrors = 0,
805              ipinaddrerrors = 0,
806              ipforwdatagrams = 0,
807              ipinunknownprotos = 0,
808              ipindiscards = 0,
809              ipindelivers = 0,
810              ipoutrequests = 0,
811              ipoutdiscards = 0,
812              ipoutnoroutes = 0,
813              ipreasmreqds = 0,
814              ipreasmoks = 0,
815              ipreasmfails = 0,
816              ipfragoks = 0,
817              ipfragfails = 0,
818              ipfragcreates = 0,
819              iproutingdiscards = 0;
820 /* mib-2.icmp counter(s) */
821 static u32_t icmpinmsgs = 0,
822              icmpinerrors = 0,
823              icmpindestunreachs = 0,
824              icmpintimeexcds = 0,
825              icmpinparmprobs = 0,
826              icmpinsrcquenchs = 0,
827              icmpinredirects = 0,
828              icmpinechos = 0,
829              icmpinechoreps = 0,
830              icmpintimestamps = 0,
831              icmpintimestampreps = 0,
832              icmpinaddrmasks = 0,
833              icmpinaddrmaskreps = 0,
834              icmpoutmsgs = 0,
835              icmpouterrors = 0,
836              icmpoutdestunreachs = 0,
837              icmpouttimeexcds = 0,
838              icmpoutparmprobs = 0,
839              icmpoutsrcquenchs = 0,
840              icmpoutredirects = 0,
841              icmpoutechos = 0,
842              icmpoutechoreps = 0,
843              icmpouttimestamps = 0,
844              icmpouttimestampreps = 0,
845              icmpoutaddrmasks = 0,
846              icmpoutaddrmaskreps = 0;
847 /* mib-2.tcp counter(s) */
848 static u32_t tcpactiveopens = 0,
849              tcppassiveopens = 0,
850              tcpattemptfails = 0,
851              tcpestabresets = 0,
852              tcpinsegs = 0,
853              tcpoutsegs = 0,
854              tcpretranssegs = 0,
855              tcpinerrs = 0,
856              tcpoutrsts = 0;
857 /* mib-2.udp counter(s) */
858 static u32_t udpindatagrams = 0,
859              udpnoports = 0,
860              udpinerrors = 0,
861              udpoutdatagrams = 0;
862 /* mib-2.snmp counter(s) */
863 static u32_t snmpinpkts = 0,
864              snmpoutpkts = 0,
865              snmpinbadversions = 0,
866              snmpinbadcommunitynames = 0,
867              snmpinbadcommunityuses = 0,
868              snmpinasnparseerrs = 0,
869              snmpintoobigs = 0,
870              snmpinnosuchnames = 0,
871              snmpinbadvalues = 0,
872              snmpinreadonlys = 0,
873              snmpingenerrs = 0,
874              snmpintotalreqvars = 0,
875              snmpintotalsetvars = 0,
876              snmpingetrequests = 0,
877              snmpingetnexts = 0,
878              snmpinsetrequests = 0,
879              snmpingetresponses = 0,
880              snmpintraps = 0,
881              snmpouttoobigs = 0,
882              snmpoutnosuchnames = 0,
883              snmpoutbadvalues = 0,
884              snmpoutgenerrs = 0,
885              snmpoutgetrequests = 0,
886              snmpoutgetnexts = 0,
887              snmpoutsetrequests = 0,
888              snmpoutgetresponses = 0,
889              snmpouttraps = 0;
890
891
892
893 /* prototypes of the following functions are in lwip/src/include/lwip/snmp.h */
894 /**
895  * Copy octet string.
896  *
897  * @param dst points to destination
898  * @param src points to source
899  * @param n number of octets to copy.
900  */
901 void ocstrncpy(u8_t *dst, u8_t *src, u8_t n)
902 {
903   while (n > 0)
904   {
905     n--;
906     *dst++ = *src++;
907   }
908 }
909
910 /**
911  * Copy object identifier (s32_t) array.
912  *
913  * @param dst points to destination
914  * @param src points to source
915  * @param n number of sub identifiers to copy.
916  */
917 void objectidncpy(s32_t *dst, s32_t *src, u8_t n)
918 {
919   while(n > 0)
920   {
921     n--;
922     *dst++ = *src++;
923   }
924 }
925
926 /**
927  * Initializes sysDescr pointers.
928  *
929  * @param str if non-NULL then copy str pointer
930  * @param len points to string length, excluding zero terminator
931  */
932 void snmp_set_sysdesr(u8_t *str, u8_t *len)
933 {
934   if (str != NULL)
935   {
936     sysdescr_ptr = str;
937     sysdescr_len_ptr = len;
938   }
939 }
940
941 void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid)
942 {
943   *oid = &sysobjid;
944 }
945
946 /**
947  * Initializes sysObjectID value.
948  *
949  * @param oid points to stuct snmp_obj_id to copy
950  */
951 void snmp_set_sysobjid(struct snmp_obj_id *oid)
952 {
953   sysobjid = *oid;
954 }
955
956 /**
957  * Must be called at regular 10 msec interval from a timer interrupt
958  * or signal handler depending on your runtime environment.
959  */
960 void snmp_inc_sysuptime(void)
961 {
962   sysuptime++;
963 }
964
965 void snmp_add_sysuptime(u32_t value)
966 {
967   sysuptime+=value;
968 }
969
970 void snmp_get_sysuptime(u32_t *value)
971 {
972   SNMP_GET_SYSUPTIME(sysuptime);
973   *value = sysuptime;
974 }
975
976 /**
977  * Initializes sysContact pointers,
978  * e.g. ptrs to non-volatile memory external to lwIP.
979  *
980  * @param ocstr if non-NULL then copy str pointer
981  * @param ocstrlen points to string length, excluding zero terminator
982  */
983 void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen)
984 {
985   if (ocstr != NULL)
986   {
987     syscontact_ptr = ocstr;
988     syscontact_len_ptr = ocstrlen;
989   }
990 }
991
992 /**
993  * Initializes sysName pointers,
994  * e.g. ptrs to non-volatile memory external to lwIP.
995  *
996  * @param ocstr if non-NULL then copy str pointer
997  * @param ocstrlen points to string length, excluding zero terminator
998  */
999 void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen)
1000 {
1001   if (ocstr != NULL)
1002   {
1003     sysname_ptr = ocstr;
1004     sysname_len_ptr = ocstrlen;
1005   }
1006 }
1007
1008 /**
1009  * Initializes sysLocation pointers,
1010  * e.g. ptrs to non-volatile memory external to lwIP.
1011  *
1012  * @param ocstr if non-NULL then copy str pointer
1013  * @param ocstrlen points to string length, excluding zero terminator
1014  */
1015 void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen)
1016 {
1017   if (ocstr != NULL)
1018   {
1019     syslocation_ptr = ocstr;
1020     syslocation_len_ptr = ocstrlen;
1021   }
1022 }
1023
1024
1025 void snmp_add_ifinoctets(struct netif *ni, u32_t value)
1026 {
1027   ni->ifinoctets += value;
1028 }
1029
1030 void snmp_inc_ifinucastpkts(struct netif *ni)
1031 {
1032   (ni->ifinucastpkts)++;
1033 }
1034
1035 void snmp_inc_ifinnucastpkts(struct netif *ni)
1036 {
1037   (ni->ifinnucastpkts)++;
1038 }
1039
1040 void snmp_inc_ifindiscards(struct netif *ni)
1041 {
1042   (ni->ifindiscards)++;
1043 }
1044
1045 void snmp_add_ifoutoctets(struct netif *ni, u32_t value)
1046 {
1047   ni->ifoutoctets += value;
1048 }
1049
1050 void snmp_inc_ifoutucastpkts(struct netif *ni)
1051 {
1052   (ni->ifoutucastpkts)++;
1053 }
1054
1055 void snmp_inc_ifoutnucastpkts(struct netif *ni)
1056 {
1057   (ni->ifoutnucastpkts)++;
1058 }
1059
1060 void snmp_inc_ifoutdiscards(struct netif *ni)
1061 {
1062   (ni->ifoutdiscards)++;
1063 }
1064
1065 void snmp_inc_iflist(void)
1066 {
1067   struct mib_list_node *if_node = NULL;
1068
1069   snmp_mib_node_insert(&iflist_root, iflist_root.count + 1, &if_node);
1070   /* enable getnext traversal on filled table */
1071   iftable.maxlength = 1;
1072 }
1073
1074 void snmp_dec_iflist(void)
1075 {
1076   snmp_mib_node_delete(&iflist_root, iflist_root.tail);
1077   /* disable getnext traversal on empty table */
1078   if(iflist_root.count == 0) iftable.maxlength = 0;
1079 }
1080
1081 /**
1082  * Inserts ARP table indexes (.xIfIndex.xNetAddress)
1083  * into arp table index trees (both atTable and ipNetToMediaTable).
1084  */
1085 void snmp_insert_arpidx_tree(struct netif *ni, struct ip_addr *ip)
1086 {
1087   struct mib_list_rootnode *at_rn;
1088   struct mib_list_node *at_node;
1089   struct ip_addr hip;
1090   s32_t arpidx[5];
1091   u8_t level, tree;
1092
1093   LWIP_ASSERT("ni != NULL", ni != NULL);
1094   snmp_netiftoifindex(ni, &arpidx[0]);
1095   hip.addr = ntohl(ip->addr);
1096   snmp_iptooid(&hip, &arpidx[1]);
1097
1098   for (tree = 0; tree < 2; tree++)
1099   {
1100     if (tree == 0)
1101     {
1102       at_rn = &arptree_root;
1103     }
1104     else
1105     {
1106       at_rn = &ipntomtree_root;
1107     }
1108     for (level = 0; level < 5; level++)
1109     {
1110       at_node = NULL;
1111       snmp_mib_node_insert(at_rn, arpidx[level], &at_node);
1112       if ((level != 4) && (at_node != NULL))
1113       {
1114         if (at_node->nptr == NULL)
1115         {
1116           at_rn = snmp_mib_lrn_alloc();
1117           at_node->nptr = (struct mib_node*)at_rn;
1118           if (at_rn != NULL)
1119           {
1120             if (level == 3)
1121             {
1122               if (tree == 0)
1123               {
1124                 at_rn->get_object_def = atentry_get_object_def;
1125                 at_rn->get_value = atentry_get_value;
1126               }
1127               else
1128               {
1129                 at_rn->get_object_def = ip_ntomentry_get_object_def;
1130                 at_rn->get_value = ip_ntomentry_get_value;
1131               }
1132               at_rn->set_test = noleafs_set_test;
1133               at_rn->set_value = noleafs_set_value;
1134             }
1135           }
1136           else
1137           {
1138             /* at_rn == NULL, malloc failure */
1139             LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_arpidx_tree() insert failed, mem full"));
1140             break;
1141           }
1142         }
1143         else
1144         {
1145           at_rn = (struct mib_list_rootnode*)at_node->nptr;
1146         }
1147       }
1148     }
1149   }
1150   /* enable getnext traversal on filled tables */
1151   at.maxlength = 1;
1152   ipntomtable.maxlength = 1;
1153 }
1154
1155 /**
1156  * Removes ARP table indexes (.xIfIndex.xNetAddress)
1157  * from arp table index trees.
1158  */
1159 void snmp_delete_arpidx_tree(struct netif *ni, struct ip_addr *ip)
1160 {
1161   struct mib_list_rootnode *at_rn, *next, *del_rn[5];
1162   struct mib_list_node *at_n, *del_n[5];
1163   struct ip_addr hip;
1164   s32_t arpidx[5];
1165   u8_t fc, tree, level, del_cnt;
1166
1167   snmp_netiftoifindex(ni, &arpidx[0]);
1168   hip.addr = ntohl(ip->addr);
1169   snmp_iptooid(&hip, &arpidx[1]);
1170
1171   for (tree = 0; tree < 2; tree++)
1172   {
1173     /* mark nodes for deletion */
1174     if (tree == 0)
1175     {
1176       at_rn = &arptree_root;
1177     }
1178     else
1179     {
1180       at_rn = &ipntomtree_root;
1181     }
1182     level = 0;
1183     del_cnt = 0;
1184     while ((level < 5) && (at_rn != NULL))
1185     {
1186       fc = snmp_mib_node_find(at_rn, arpidx[level], &at_n);
1187       if (fc == 0)
1188       {
1189         /* arpidx[level] does not exist */
1190         del_cnt = 0;
1191         at_rn = NULL;
1192       }
1193       else if (fc == 1)
1194       {
1195         del_rn[del_cnt] = at_rn;
1196         del_n[del_cnt] = at_n;
1197         del_cnt++;
1198         at_rn = (struct mib_list_rootnode*)(at_n->nptr);
1199       }
1200       else if (fc == 2)
1201       {
1202         /* reset delete (2 or more childs) */
1203         del_cnt = 0;
1204         at_rn = (struct mib_list_rootnode*)(at_n->nptr);
1205       }
1206       level++;
1207     }
1208     /* delete marked index nodes */
1209     while (del_cnt > 0)
1210     {
1211       del_cnt--;
1212
1213       at_rn = del_rn[del_cnt];
1214       at_n = del_n[del_cnt];
1215
1216       next = snmp_mib_node_delete(at_rn, at_n);
1217       if (next != NULL)
1218       {
1219         LWIP_ASSERT("next_count == 0",next->count == 0);
1220         snmp_mib_lrn_free(next);
1221       }
1222     }
1223   }
1224   /* disable getnext traversal on empty tables */
1225   if(arptree_root.count == 0) at.maxlength = 0;
1226   if(ipntomtree_root.count == 0) ipntomtable.maxlength = 0;
1227 }
1228
1229 void snmp_inc_ipinreceives(void)
1230 {
1231   ipinreceives++;
1232 }
1233
1234 void snmp_inc_ipinhdrerrors(void)
1235 {
1236   ipinhdrerrors++;
1237 }
1238
1239 void snmp_inc_ipinaddrerrors(void)
1240 {
1241   ipinaddrerrors++;
1242 }
1243
1244 void snmp_inc_ipforwdatagrams(void)
1245 {
1246   ipforwdatagrams++;
1247 }
1248
1249 void snmp_inc_ipinunknownprotos(void)
1250 {
1251   ipinunknownprotos++;
1252 }
1253
1254 void snmp_inc_ipindiscards(void)
1255 {
1256   ipindiscards++;
1257 }
1258
1259 void snmp_inc_ipindelivers(void)
1260 {
1261   ipindelivers++;
1262 }
1263
1264 void snmp_inc_ipoutrequests(void)
1265 {
1266   ipoutrequests++;
1267 }
1268
1269 void snmp_inc_ipoutdiscards(void)
1270 {
1271   ipoutdiscards++;
1272 }
1273
1274 void snmp_inc_ipoutnoroutes(void)
1275 {
1276   ipoutnoroutes++;
1277 }
1278
1279 void snmp_inc_ipreasmreqds(void)
1280 {
1281   ipreasmreqds++;
1282 }
1283
1284 void snmp_inc_ipreasmoks(void)
1285 {
1286   ipreasmoks++;
1287 }
1288
1289 void snmp_inc_ipreasmfails(void)
1290 {
1291   ipreasmfails++;
1292 }
1293
1294 void snmp_inc_ipfragoks(void)
1295 {
1296   ipfragoks++;
1297 }
1298
1299 void snmp_inc_ipfragfails(void)
1300 {
1301   ipfragfails++;
1302 }
1303
1304 void snmp_inc_ipfragcreates(void)
1305 {
1306   ipfragcreates++;
1307 }
1308
1309 void snmp_inc_iproutingdiscards(void)
1310 {
1311   iproutingdiscards++;
1312 }
1313
1314 /**
1315  * Inserts ipAddrTable indexes (.ipAdEntAddr)
1316  * into index tree.
1317  */
1318 void snmp_insert_ipaddridx_tree(struct netif *ni)
1319 {
1320   struct mib_list_rootnode *ipa_rn;
1321   struct mib_list_node *ipa_node;
1322   struct ip_addr ip;
1323   s32_t ipaddridx[4];
1324   u8_t level;
1325
1326   LWIP_ASSERT("ni != NULL", ni != NULL);
1327   ip.addr = ntohl(ni->ip_addr.addr);
1328   snmp_iptooid(&ip, &ipaddridx[0]);
1329
1330   level = 0;
1331   ipa_rn = &ipaddrtree_root;
1332   while (level < 4)
1333   {
1334     ipa_node = NULL;
1335     snmp_mib_node_insert(ipa_rn, ipaddridx[level], &ipa_node);
1336     if ((level != 3) && (ipa_node != NULL))
1337     {
1338       if (ipa_node->nptr == NULL)
1339       {
1340         ipa_rn = snmp_mib_lrn_alloc();
1341         ipa_node->nptr = (struct mib_node*)ipa_rn;
1342         if (ipa_rn != NULL)
1343         {
1344           if (level == 2)
1345           {
1346             ipa_rn->get_object_def = ip_addrentry_get_object_def;
1347             ipa_rn->get_value = ip_addrentry_get_value;
1348             ipa_rn->set_test = noleafs_set_test;
1349             ipa_rn->set_value = noleafs_set_value;
1350           }
1351         }
1352         else
1353         {
1354           /* ipa_rn == NULL, malloc failure */
1355           LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_ipaddridx_tree() insert failed, mem full"));
1356           break;
1357         }
1358       }
1359       else
1360       {
1361         ipa_rn = (struct mib_list_rootnode*)ipa_node->nptr;
1362       }
1363     }
1364     level++;
1365   }
1366   /* enable getnext traversal on filled table */
1367   ipaddrtable.maxlength = 1;
1368 }
1369
1370 /**
1371  * Removes ipAddrTable indexes (.ipAdEntAddr)
1372  * from index tree.
1373  */
1374 void snmp_delete_ipaddridx_tree(struct netif *ni)
1375 {
1376   struct mib_list_rootnode *ipa_rn, *next, *del_rn[4];
1377   struct mib_list_node *ipa_n, *del_n[4];
1378   struct ip_addr ip;
1379   s32_t ipaddridx[4];
1380   u8_t fc, level, del_cnt;
1381
1382   LWIP_ASSERT("ni != NULL", ni != NULL);
1383   ip.addr = ntohl(ni->ip_addr.addr);
1384   snmp_iptooid(&ip, &ipaddridx[0]);
1385
1386   /* mark nodes for deletion */
1387   level = 0;
1388   del_cnt = 0;
1389   ipa_rn = &ipaddrtree_root;
1390   while ((level < 4) && (ipa_rn != NULL))
1391   {
1392     fc = snmp_mib_node_find(ipa_rn, ipaddridx[level], &ipa_n);
1393     if (fc == 0)
1394     {
1395       /* ipaddridx[level] does not exist */
1396       del_cnt = 0;
1397       ipa_rn = NULL;
1398     }
1399     else if (fc == 1)
1400     {
1401       del_rn[del_cnt] = ipa_rn;
1402       del_n[del_cnt] = ipa_n;
1403       del_cnt++;
1404       ipa_rn = (struct mib_list_rootnode*)(ipa_n->nptr);
1405     }
1406     else if (fc == 2)
1407     {
1408       /* reset delete (2 or more childs) */
1409       del_cnt = 0;
1410       ipa_rn = (struct mib_list_rootnode*)(ipa_n->nptr);
1411     }
1412     level++;
1413   }
1414   /* delete marked index nodes */
1415   while (del_cnt > 0)
1416   {
1417     del_cnt--;
1418
1419     ipa_rn = del_rn[del_cnt];
1420     ipa_n = del_n[del_cnt];
1421
1422     next = snmp_mib_node_delete(ipa_rn, ipa_n);
1423     if (next != NULL)
1424     {
1425       LWIP_ASSERT("next_count == 0",next->count == 0);
1426       snmp_mib_lrn_free(next);
1427     }
1428   }
1429   /* disable getnext traversal on empty table */
1430   if (ipaddrtree_root.count == 0) ipaddrtable.maxlength = 0;
1431 }
1432
1433 /**
1434  * Inserts ipRouteTable indexes (.ipRouteDest)
1435  * into index tree.
1436  *
1437  * @param dflt non-zero for the default rte, zero for network rte
1438  * @param ni points to network interface for this rte
1439  *
1440  * @todo record sysuptime for _this_ route when it is installed
1441  *   (needed for ipRouteAge) in the netif.
1442  */
1443 void snmp_insert_iprteidx_tree(u8_t dflt, struct netif *ni)
1444 {
1445   u8_t insert = 0;
1446   struct ip_addr dst;
1447
1448   if (dflt != 0)
1449   {
1450     /* the default route 0.0.0.0 */
1451     dst.addr = 0;
1452     insert = 1;
1453   }
1454   else
1455   {
1456     /* route to the network address */
1457     dst.addr = ntohl(ni->ip_addr.addr & ni->netmask.addr);
1458     /* exclude 0.0.0.0 network (reserved for default rte) */
1459     if (dst.addr != 0) insert = 1;
1460   }
1461   if (insert)
1462   {
1463     struct mib_list_rootnode *iprte_rn;
1464     struct mib_list_node *iprte_node;
1465     s32_t iprteidx[4];
1466     u8_t level;
1467
1468     snmp_iptooid(&dst, &iprteidx[0]);
1469     level = 0;
1470     iprte_rn = &iprtetree_root;
1471     while (level < 4)
1472     {
1473       iprte_node = NULL;
1474       snmp_mib_node_insert(iprte_rn, iprteidx[level], &iprte_node);
1475       if ((level != 3) && (iprte_node != NULL))
1476       {
1477         if (iprte_node->nptr == NULL)
1478         {
1479           iprte_rn = snmp_mib_lrn_alloc();
1480           iprte_node->nptr = (struct mib_node*)iprte_rn;
1481           if (iprte_rn != NULL)
1482           {
1483             if (level == 2)
1484             {
1485               iprte_rn->get_object_def = ip_rteentry_get_object_def;
1486               iprte_rn->get_value = ip_rteentry_get_value;
1487               iprte_rn->set_test = noleafs_set_test;
1488               iprte_rn->set_value = noleafs_set_value;
1489             }
1490           }
1491           else
1492           {
1493             /* iprte_rn == NULL, malloc failure */
1494             LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_iprteidx_tree() insert failed, mem full"));
1495             break;
1496           }
1497         }
1498         else
1499         {
1500           iprte_rn = (struct mib_list_rootnode*)iprte_node->nptr;
1501         }
1502       }
1503       level++;
1504     }
1505   }
1506   /* enable getnext traversal on filled table */
1507   iprtetable.maxlength = 1;
1508 }
1509
1510 /**
1511  * Removes ipRouteTable indexes (.ipRouteDest)
1512  * from index tree.
1513  *
1514  * @param dflt non-zero for the default rte, zero for network rte
1515  * @param ni points to network interface for this rte or NULL
1516  *   for default route to be removed.
1517  */
1518 void snmp_delete_iprteidx_tree(u8_t dflt, struct netif *ni)
1519 {
1520   u8_t delete = 0;
1521   struct ip_addr dst;
1522
1523   if (dflt != 0)
1524   {
1525     /* the default route 0.0.0.0 */
1526     dst.addr = 0;
1527     delete = 1;
1528   }
1529   else
1530   {
1531     /* route to the network address */
1532     dst.addr = ntohl(ni->ip_addr.addr & ni->netmask.addr);
1533     /* exclude 0.0.0.0 network (reserved for default rte) */
1534     if (dst.addr != 0) delete = 1;
1535   }
1536   if (delete)
1537   {
1538     struct mib_list_rootnode *iprte_rn, *next, *del_rn[4];
1539     struct mib_list_node *iprte_n, *del_n[4];
1540     s32_t iprteidx[4];
1541     u8_t fc, level, del_cnt;
1542
1543     snmp_iptooid(&dst, &iprteidx[0]);
1544     /* mark nodes for deletion */
1545     level = 0;
1546     del_cnt = 0;
1547     iprte_rn = &iprtetree_root;
1548     while ((level < 4) && (iprte_rn != NULL))
1549     {
1550       fc = snmp_mib_node_find(iprte_rn, iprteidx[level], &iprte_n);
1551       if (fc == 0)
1552       {
1553         /* iprteidx[level] does not exist */
1554         del_cnt = 0;
1555         iprte_rn = NULL;
1556       }
1557       else if (fc == 1)
1558       {
1559         del_rn[del_cnt] = iprte_rn;
1560         del_n[del_cnt] = iprte_n;
1561         del_cnt++;
1562         iprte_rn = (struct mib_list_rootnode*)(iprte_n->nptr);
1563       }
1564       else if (fc == 2)
1565       {
1566         /* reset delete (2 or more childs) */
1567         del_cnt = 0;
1568         iprte_rn = (struct mib_list_rootnode*)(iprte_n->nptr);
1569       }
1570       level++;
1571     }
1572     /* delete marked index nodes */
1573     while (del_cnt > 0)
1574     {
1575       del_cnt--;
1576
1577       iprte_rn = del_rn[del_cnt];
1578       iprte_n = del_n[del_cnt];
1579
1580       next = snmp_mib_node_delete(iprte_rn, iprte_n);
1581       if (next != NULL)
1582       {
1583         LWIP_ASSERT("next_count == 0",next->count == 0);
1584         snmp_mib_lrn_free(next);
1585       }
1586     }
1587   }
1588   /* disable getnext traversal on empty table */
1589   if (iprtetree_root.count == 0) iprtetable.maxlength = 0;
1590 }
1591
1592
1593 void snmp_inc_icmpinmsgs(void)
1594 {
1595   icmpinmsgs++;
1596 }
1597
1598 void snmp_inc_icmpinerrors(void)
1599 {
1600   icmpinerrors++;
1601 }
1602
1603 void snmp_inc_icmpindestunreachs(void)
1604 {
1605   icmpindestunreachs++;
1606 }
1607
1608 void snmp_inc_icmpintimeexcds(void)
1609 {
1610   icmpintimeexcds++;
1611 }
1612
1613 void snmp_inc_icmpinparmprobs(void)
1614 {
1615   icmpinparmprobs++;
1616 }
1617
1618 void snmp_inc_icmpinsrcquenchs(void)
1619 {
1620   icmpinsrcquenchs++;
1621 }
1622
1623 void snmp_inc_icmpinredirects(void)
1624 {
1625   icmpinredirects++;
1626 }
1627
1628 void snmp_inc_icmpinechos(void)
1629 {
1630   icmpinechos++;
1631 }
1632
1633 void snmp_inc_icmpinechoreps(void)
1634 {
1635   icmpinechoreps++;
1636 }
1637
1638 void snmp_inc_icmpintimestamps(void)
1639 {
1640   icmpintimestamps++;
1641 }
1642
1643 void snmp_inc_icmpintimestampreps(void)
1644 {
1645   icmpintimestampreps++;
1646 }
1647
1648 void snmp_inc_icmpinaddrmasks(void)
1649 {
1650   icmpinaddrmasks++;
1651 }
1652
1653 void snmp_inc_icmpinaddrmaskreps(void)
1654 {
1655   icmpinaddrmaskreps++;
1656 }
1657
1658 void snmp_inc_icmpoutmsgs(void)
1659 {
1660   icmpoutmsgs++;
1661 }
1662
1663 void snmp_inc_icmpouterrors(void)
1664 {
1665   icmpouterrors++;
1666 }
1667
1668 void snmp_inc_icmpoutdestunreachs(void)
1669 {
1670   icmpoutdestunreachs++;
1671 }
1672
1673 void snmp_inc_icmpouttimeexcds(void)
1674 {
1675   icmpouttimeexcds++;
1676 }
1677
1678 void snmp_inc_icmpoutparmprobs(void)
1679 {
1680   icmpoutparmprobs++;
1681 }
1682
1683 void snmp_inc_icmpoutsrcquenchs(void)
1684 {
1685   icmpoutsrcquenchs++;
1686 }
1687
1688 void snmp_inc_icmpoutredirects(void)
1689 {
1690   icmpoutredirects++;
1691 }
1692
1693 void snmp_inc_icmpoutechos(void)
1694 {
1695   icmpoutechos++;
1696 }
1697
1698 void snmp_inc_icmpoutechoreps(void)
1699 {
1700   icmpoutechoreps++;
1701 }
1702
1703 void snmp_inc_icmpouttimestamps(void)
1704 {
1705   icmpouttimestamps++;
1706 }
1707
1708 void snmp_inc_icmpouttimestampreps(void)
1709 {
1710   icmpouttimestampreps++;
1711 }
1712
1713 void snmp_inc_icmpoutaddrmasks(void)
1714 {
1715   icmpoutaddrmasks++;
1716 }
1717
1718 void snmp_inc_icmpoutaddrmaskreps(void)
1719 {
1720   icmpoutaddrmaskreps++;
1721 }
1722
1723 void snmp_inc_tcpactiveopens(void)
1724 {
1725   tcpactiveopens++;
1726 }
1727
1728 void snmp_inc_tcppassiveopens(void)
1729 {
1730   tcppassiveopens++;
1731 }
1732
1733 void snmp_inc_tcpattemptfails(void)
1734 {
1735   tcpattemptfails++;
1736 }
1737
1738 void snmp_inc_tcpestabresets(void)
1739 {
1740   tcpestabresets++;
1741 }
1742
1743 void snmp_inc_tcpinsegs(void)
1744 {
1745   tcpinsegs++;
1746 }
1747
1748 void snmp_inc_tcpoutsegs(void)
1749 {
1750   tcpoutsegs++;
1751 }
1752
1753 void snmp_inc_tcpretranssegs(void)
1754 {
1755   tcpretranssegs++;
1756 }
1757
1758 void snmp_inc_tcpinerrs(void)
1759 {
1760   tcpinerrs++;
1761 }
1762
1763 void snmp_inc_tcpoutrsts(void)
1764 {
1765   tcpoutrsts++;
1766 }
1767
1768 void snmp_inc_udpindatagrams(void)
1769 {
1770   udpindatagrams++;
1771 }
1772
1773 void snmp_inc_udpnoports(void)
1774 {
1775   udpnoports++;
1776 }
1777
1778 void snmp_inc_udpinerrors(void)
1779 {
1780   udpinerrors++;
1781 }
1782
1783 void snmp_inc_udpoutdatagrams(void)
1784 {
1785   udpoutdatagrams++;
1786 }
1787
1788 /**
1789  * Inserts udpTable indexes (.udpLocalAddress.udpLocalPort)
1790  * into index tree.
1791  */
1792 void snmp_insert_udpidx_tree(struct udp_pcb *pcb)
1793 {
1794   struct mib_list_rootnode *udp_rn;
1795   struct mib_list_node *udp_node;
1796   struct ip_addr ip;
1797   s32_t udpidx[5];
1798   u8_t level;
1799
1800   LWIP_ASSERT("pcb != NULL", pcb != NULL);
1801   ip.addr = ntohl(pcb->local_ip.addr);
1802   snmp_iptooid(&ip, &udpidx[0]);
1803   udpidx[4] = pcb->local_port;
1804
1805   udp_rn = &udp_root;
1806   for (level = 0; level < 5; level++)
1807   {
1808     udp_node = NULL;
1809     snmp_mib_node_insert(udp_rn, udpidx[level], &udp_node);
1810     if ((level != 4) && (udp_node != NULL))
1811     {
1812       if (udp_node->nptr == NULL)
1813       {
1814         udp_rn = snmp_mib_lrn_alloc();
1815         udp_node->nptr = (struct mib_node*)udp_rn;
1816         if (udp_rn != NULL)
1817         {
1818           if (level == 3)
1819           {
1820             udp_rn->get_object_def = udpentry_get_object_def;
1821             udp_rn->get_value = udpentry_get_value;
1822             udp_rn->set_test = noleafs_set_test;
1823             udp_rn->set_value = noleafs_set_value;
1824           }
1825         }
1826         else
1827         {
1828           /* udp_rn == NULL, malloc failure */
1829           LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_insert_udpidx_tree() insert failed, mem full"));
1830           break;
1831         }
1832       }
1833       else
1834       {
1835         udp_rn = (struct mib_list_rootnode*)udp_node->nptr;
1836       }
1837     }
1838   }
1839   udptable.maxlength = 1;
1840 }
1841
1842 /**
1843  * Removes udpTable indexes (.udpLocalAddress.udpLocalPort)
1844  * from index tree.
1845  */
1846 void snmp_delete_udpidx_tree(struct udp_pcb *pcb)
1847 {
1848   struct mib_list_rootnode *udp_rn, *next, *del_rn[5];
1849   struct mib_list_node *udp_n, *del_n[5];
1850   struct ip_addr ip;
1851   s32_t udpidx[5];
1852   u8_t bindings, fc, level, del_cnt;
1853
1854   LWIP_ASSERT("pcb != NULL", pcb != NULL);
1855   ip.addr = ntohl(pcb->local_ip.addr);
1856   snmp_iptooid(&ip, &udpidx[0]);
1857   udpidx[4] = pcb->local_port;
1858
1859   /* count PCBs for a given binding
1860      (e.g. when reusing ports or for temp output PCBs) */
1861   bindings = 0;
1862   pcb = udp_pcbs;
1863   while ((pcb != NULL))
1864   {
1865     if ((pcb->local_ip.addr == ip.addr) &&
1866         (pcb->local_port == udpidx[4]))
1867     {
1868       bindings++;
1869     }
1870     pcb = pcb->next;
1871   }
1872   if (bindings == 1)
1873   {
1874     /* selectively remove */
1875     /* mark nodes for deletion */
1876     level = 0;
1877     del_cnt = 0;
1878     udp_rn = &udp_root;
1879     while ((level < 5) && (udp_rn != NULL))
1880     {
1881       fc = snmp_mib_node_find(udp_rn, udpidx[level], &udp_n);
1882       if (fc == 0)
1883       {
1884         /* udpidx[level] does not exist */
1885         del_cnt = 0;
1886         udp_rn = NULL;
1887       }
1888       else if (fc == 1)
1889       {
1890         del_rn[del_cnt] = udp_rn;
1891         del_n[del_cnt] = udp_n;
1892         del_cnt++;
1893         udp_rn = (struct mib_list_rootnode*)(udp_n->nptr);
1894       }
1895       else if (fc == 2)
1896       {
1897         /* reset delete (2 or more childs) */
1898         del_cnt = 0;
1899         udp_rn = (struct mib_list_rootnode*)(udp_n->nptr);
1900       }
1901       level++;
1902     }
1903     /* delete marked index nodes */
1904     while (del_cnt > 0)
1905     {
1906       del_cnt--;
1907
1908       udp_rn = del_rn[del_cnt];
1909       udp_n = del_n[del_cnt];
1910
1911       next = snmp_mib_node_delete(udp_rn, udp_n);
1912       if (next != NULL)
1913       {
1914         LWIP_ASSERT("next_count == 0",next->count == 0);
1915         snmp_mib_lrn_free(next);
1916       }
1917     }
1918   }
1919   /* disable getnext traversal on empty table */
1920   if (udp_root.count == 0) udptable.maxlength = 0;
1921 }
1922
1923
1924 void snmp_inc_snmpinpkts(void)
1925 {
1926   snmpinpkts++;
1927 }
1928
1929 void snmp_inc_snmpoutpkts(void)
1930 {
1931   snmpoutpkts++;
1932 }
1933
1934 void snmp_inc_snmpinbadversions(void)
1935 {
1936   snmpinbadversions++;
1937 }
1938
1939 void snmp_inc_snmpinbadcommunitynames(void)
1940 {
1941   snmpinbadcommunitynames++;
1942 }
1943
1944 void snmp_inc_snmpinbadcommunityuses(void)
1945 {
1946   snmpinbadcommunityuses++;
1947 }
1948
1949 void snmp_inc_snmpinasnparseerrs(void)
1950 {
1951   snmpinasnparseerrs++;
1952 }
1953
1954 void snmp_inc_snmpintoobigs(void)
1955 {
1956   snmpintoobigs++;
1957 }
1958
1959 void snmp_inc_snmpinnosuchnames(void)
1960 {
1961   snmpinnosuchnames++;
1962 }
1963
1964 void snmp_inc_snmpinbadvalues(void)
1965 {
1966   snmpinbadvalues++;
1967 }
1968
1969 void snmp_inc_snmpinreadonlys(void)
1970 {
1971   snmpinreadonlys++;
1972 }
1973
1974 void snmp_inc_snmpingenerrs(void)
1975 {
1976   snmpingenerrs++;
1977 }
1978
1979 void snmp_add_snmpintotalreqvars(u8_t value)
1980 {
1981   snmpintotalreqvars += value;
1982 }
1983
1984 void snmp_add_snmpintotalsetvars(u8_t value)
1985 {
1986   snmpintotalsetvars += value;
1987 }
1988
1989 void snmp_inc_snmpingetrequests(void)
1990 {
1991   snmpingetrequests++;
1992 }
1993
1994 void snmp_inc_snmpingetnexts(void)
1995 {
1996   snmpingetnexts++;
1997 }
1998
1999 void snmp_inc_snmpinsetrequests(void)
2000 {
2001   snmpinsetrequests++;
2002 }
2003
2004 void snmp_inc_snmpingetresponses(void)
2005 {
2006   snmpingetresponses++;
2007 }
2008
2009 void snmp_inc_snmpintraps(void)
2010 {
2011   snmpintraps++;
2012 }
2013
2014 void snmp_inc_snmpouttoobigs(void)
2015 {
2016   snmpouttoobigs++;
2017 }
2018
2019 void snmp_inc_snmpoutnosuchnames(void)
2020 {
2021   snmpoutnosuchnames++;
2022 }
2023
2024 void snmp_inc_snmpoutbadvalues(void)
2025 {
2026   snmpoutbadvalues++;
2027 }
2028
2029 void snmp_inc_snmpoutgenerrs(void)
2030 {
2031   snmpoutgenerrs++;
2032 }
2033
2034 void snmp_inc_snmpoutgetrequests(void)
2035 {
2036   snmpoutgetrequests++;
2037 }
2038
2039 void snmp_inc_snmpoutgetnexts(void)
2040 {
2041   snmpoutgetnexts++;
2042 }
2043
2044 void snmp_inc_snmpoutsetrequests(void)
2045 {
2046   snmpoutsetrequests++;
2047 }
2048
2049 void snmp_inc_snmpoutgetresponses(void)
2050 {
2051   snmpoutgetresponses++;
2052 }
2053
2054 void snmp_inc_snmpouttraps(void)
2055 {
2056   snmpouttraps++;
2057 }
2058
2059 void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid)
2060 {
2061   *oid = &snmpgrp_id;
2062 }
2063
2064 void snmp_set_snmpenableauthentraps(u8_t *value)
2065 {
2066   if (value != NULL)
2067   {
2068     snmpenableauthentraps_ptr = value;
2069   }
2070 }
2071
2072 void snmp_get_snmpenableauthentraps(u8_t *value)
2073 {
2074   *value = *snmpenableauthentraps_ptr;
2075 }
2076
2077 void
2078 noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
2079 {
2080   if (ident_len){}
2081   if (ident){}
2082   od->instance = MIB_OBJECT_NONE;
2083 }
2084
2085 void
2086 noleafs_get_value(struct obj_def *od, u16_t len, void *value)
2087 {
2088   if (od){}
2089   if (len){}
2090   if (value){}
2091 }
2092
2093 u8_t
2094 noleafs_set_test(struct obj_def *od, u16_t len, void *value)
2095 {
2096   if (od){}
2097   if (len){}
2098   if (value){}
2099   /* can't set */
2100   return 0;
2101 }
2102
2103 void
2104 noleafs_set_value(struct obj_def *od, u16_t len, void *value)
2105 {
2106   if (od){}
2107   if (len){}
2108   if (value){}
2109 }
2110
2111
2112 /**
2113  * Returns systems object definitions.
2114  *
2115  * @param ident_len the address length (2)
2116  * @param ident points to objectname.0 (object id trailer)
2117  * @param od points to object definition.
2118  */
2119 static void
2120 system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
2121 {
2122   u8_t id;
2123
2124   /* return to object name, adding index depth (1) */
2125   ident_len += 1;
2126   ident -= 1;
2127   if (ident_len == 2)
2128   {
2129     od->id_inst_len = ident_len;
2130     od->id_inst_ptr = ident;
2131
2132     id = ident[0];
2133     LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def system.%"U16_F".0\n",(u16_t)id));
2134     switch (id)
2135     {
2136       case 1: /* sysDescr */
2137         od->instance = MIB_OBJECT_SCALAR;
2138         od->access = MIB_OBJECT_READ_ONLY;
2139         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
2140         od->v_len = *sysdescr_len_ptr;
2141         break;
2142       case 2: /* sysObjectID */
2143         od->instance = MIB_OBJECT_SCALAR;
2144         od->access = MIB_OBJECT_READ_ONLY;
2145         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID);
2146         od->v_len = sysobjid.len * sizeof(s32_t);
2147         break;
2148       case 3: /* sysUpTime */
2149         od->instance = MIB_OBJECT_SCALAR;
2150         od->access = MIB_OBJECT_READ_ONLY;
2151         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS);
2152         od->v_len = sizeof(u32_t);
2153         break;
2154       case 4: /* sysContact */
2155         od->instance = MIB_OBJECT_SCALAR;
2156         od->access = MIB_OBJECT_READ_WRITE;
2157         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
2158         od->v_len = *syscontact_len_ptr;
2159         break;
2160       case 5: /* sysName */
2161         od->instance = MIB_OBJECT_SCALAR;
2162         od->access = MIB_OBJECT_READ_WRITE;
2163         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
2164         od->v_len = *sysname_len_ptr;
2165         break;
2166       case 6: /* sysLocation */
2167         od->instance = MIB_OBJECT_SCALAR;
2168         od->access = MIB_OBJECT_READ_WRITE;
2169         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
2170         od->v_len = *syslocation_len_ptr;
2171         break;
2172       case 7: /* sysServices */
2173         od->instance = MIB_OBJECT_SCALAR;
2174         od->access = MIB_OBJECT_READ_ONLY;
2175         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
2176         od->v_len = sizeof(s32_t);
2177         break;
2178       default:
2179         LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_object_def: no such object\n"));
2180         od->instance = MIB_OBJECT_NONE;
2181         break;
2182     };
2183   }
2184   else
2185   {
2186     LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_object_def: no scalar\n"));
2187     od->instance = MIB_OBJECT_NONE;
2188   }
2189 }
2190
2191 /**
2192  * Returns system object value.
2193  *
2194  * @param ident_len the address length (2)
2195  * @param ident points to objectname.0 (object id trailer)
2196  * @param len return value space (in bytes)
2197  * @param value points to (varbind) space to copy value into.
2198  */
2199 static void
2200 system_get_value(struct obj_def *od, u16_t len, void *value)
2201 {
2202   u8_t id;
2203
2204   id = od->id_inst_ptr[0];
2205   switch (id)
2206   {
2207     case 1: /* sysDescr */
2208       ocstrncpy(value,sysdescr_ptr,len);
2209       break;
2210     case 2: /* sysObjectID */
2211       objectidncpy((s32_t*)value,(s32_t*)sysobjid.id,len / sizeof(s32_t));
2212       break;
2213     case 3: /* sysUpTime */
2214       {
2215         snmp_get_sysuptime(value);
2216       }
2217       break;
2218     case 4: /* sysContact */
2219       ocstrncpy(value,syscontact_ptr,len);
2220       break;
2221     case 5: /* sysName */
2222       ocstrncpy(value,sysname_ptr,len);
2223       break;
2224     case 6: /* sysLocation */
2225       ocstrncpy(value,syslocation_ptr,len);
2226       break;
2227     case 7: /* sysServices */
2228       {
2229         s32_t *sint_ptr = value;
2230         *sint_ptr = sysservices;
2231       }
2232       break;
2233   };
2234 }
2235
2236 static u8_t
2237 system_set_test(struct obj_def *od, u16_t len, void *value)
2238 {
2239   u8_t id, set_ok;
2240
2241   if (value) {}
2242   set_ok = 0;
2243   id = od->id_inst_ptr[0];
2244   switch (id)
2245   {
2246     case 4: /* sysContact */
2247       if ((syscontact_ptr != syscontact_default) &&
2248           (len <= 255))
2249       {
2250         set_ok = 1;
2251       }
2252       break;
2253     case 5: /* sysName */
2254       if ((sysname_ptr != sysname_default) &&
2255           (len <= 255))
2256       {
2257         set_ok = 1;
2258       }
2259       break;
2260     case 6: /* sysLocation */
2261       if ((syslocation_ptr != syslocation_default) &&
2262           (len <= 255))
2263       {
2264         set_ok = 1;
2265       }
2266       break;
2267   };
2268   return set_ok;
2269 }
2270
2271 static void
2272 system_set_value(struct obj_def *od, u16_t len, void *value)
2273 {
2274   u8_t id;
2275
2276   id = od->id_inst_ptr[0];
2277   switch (id)
2278   {
2279     case 4: /* sysContact */
2280       ocstrncpy(syscontact_ptr,value,len);
2281       *syscontact_len_ptr = len;
2282       break;
2283     case 5: /* sysName */
2284       ocstrncpy(sysname_ptr,value,len);
2285       *sysname_len_ptr = len;
2286       break;
2287     case 6: /* sysLocation */
2288       ocstrncpy(syslocation_ptr,value,len);
2289       *syslocation_len_ptr = len;
2290       break;
2291   };
2292 }
2293
2294 /**
2295  * Returns interfaces.ifnumber object definition.
2296  *
2297  * @param ident_len the address length (2)
2298  * @param ident points to objectname.index
2299  * @param od points to object definition.
2300  */
2301 static void
2302 interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
2303 {
2304   /* return to object name, adding index depth (1) */
2305   ident_len += 1;
2306   ident -= 1;
2307   if (ident_len == 2)
2308   {
2309     od->id_inst_len = ident_len;
2310     od->id_inst_ptr = ident;
2311
2312     od->instance = MIB_OBJECT_SCALAR;
2313     od->access = MIB_OBJECT_READ_ONLY;
2314     od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
2315     od->v_len = sizeof(s32_t);
2316   }
2317   else
2318   {
2319     LWIP_DEBUGF(SNMP_MIB_DEBUG,("interfaces_get_object_def: no scalar\n"));
2320     od->instance = MIB_OBJECT_NONE;
2321   }
2322 }
2323
2324 /**
2325  * Returns interfaces.ifnumber object value.
2326  *
2327  * @param ident_len the address length (2)
2328  * @param ident points to objectname.0 (object id trailer)
2329  * @param len return value space (in bytes)
2330  * @param value points to (varbind) space to copy value into.
2331  */
2332 static void
2333 interfaces_get_value(struct obj_def *od, u16_t len, void *value)
2334 {
2335   if (len){}
2336   if (od->id_inst_ptr[0] == 1)
2337   {
2338     s32_t *sint_ptr = value;
2339     *sint_ptr = iflist_root.count;
2340   }
2341 }
2342
2343 /**
2344  * Returns ifentry object definitions.
2345  *
2346  * @param ident_len the address length (2)
2347  * @param ident points to objectname.index
2348  * @param od points to object definition.
2349  */
2350 static void
2351 ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
2352 {
2353   u8_t id;
2354
2355   /* return to object name, adding index depth (1) */
2356   ident_len += 1;
2357   ident -= 1;
2358   if (ident_len == 2)
2359   {
2360     od->id_inst_len = ident_len;
2361     od->id_inst_ptr = ident;
2362
2363     id = ident[0];
2364     LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def ifentry.%"U16_F"\n",(u16_t)id));
2365     switch (id)
2366     {
2367       case 1: /* ifIndex */
2368       case 3: /* ifType */
2369       case 4: /* ifMtu */
2370       case 8: /* ifOperStatus */
2371         od->instance = MIB_OBJECT_TAB;
2372         od->access = MIB_OBJECT_READ_ONLY;
2373         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
2374         od->v_len = sizeof(s32_t);
2375         break;
2376       case 2: /* ifDescr */
2377         od->instance = MIB_OBJECT_TAB;
2378         od->access = MIB_OBJECT_READ_ONLY;
2379         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
2380         /** @todo this should be some sort of sizeof(struct netif.name) */
2381         od->v_len = 2;
2382         break;
2383       case 5: /* ifSpeed */
2384       case 21: /* ifOutQLen */
2385         od->instance = MIB_OBJECT_TAB;
2386         od->access = MIB_OBJECT_READ_ONLY;
2387         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE);
2388         od->v_len = sizeof(u32_t);
2389         break;
2390       case 6: /* ifPhysAddress */
2391         {
2392           struct netif *netif;
2393
2394           snmp_ifindextonetif(ident[1], &netif);
2395           od->instance = MIB_OBJECT_TAB;
2396           od->access = MIB_OBJECT_READ_ONLY;
2397           od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
2398           od->v_len = netif->hwaddr_len;
2399         }
2400         break;
2401       case 7: /* ifAdminStatus */
2402         od->instance = MIB_OBJECT_TAB;
2403         od->access = MIB_OBJECT_READ_WRITE;
2404         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
2405         od->v_len = sizeof(s32_t);
2406         break;
2407       case 9: /* ifLastChange */
2408         od->instance = MIB_OBJECT_TAB;
2409         od->access = MIB_OBJECT_READ_ONLY;
2410         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_TIMETICKS);
2411         od->v_len = sizeof(u32_t);
2412         break;
2413       case 10: /* ifInOctets */
2414       case 11: /* ifInUcastPkts */
2415       case 12: /* ifInNUcastPkts */
2416       case 13: /* ifInDiscarts */
2417       case 14: /* ifInErrors */
2418       case 15: /* ifInUnkownProtos */
2419       case 16: /* ifOutOctets */
2420       case 17: /* ifOutUcastPkts */
2421       case 18: /* ifOutNUcastPkts */
2422       case 19: /* ifOutDiscarts */
2423       case 20: /* ifOutErrors */
2424         od->instance = MIB_OBJECT_TAB;
2425         od->access = MIB_OBJECT_READ_ONLY;
2426         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
2427         od->v_len = sizeof(u32_t);
2428         break;
2429       case 22: /* ifSpecific */
2430         /** @note returning zeroDotZero (0.0) no media specific MIB support */
2431         od->instance = MIB_OBJECT_TAB;
2432         od->access = MIB_OBJECT_READ_ONLY;
2433         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID);
2434         od->v_len = ifspecific.len * sizeof(s32_t);
2435         break;
2436       default:
2437         LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_object_def: no such object\n"));
2438         od->instance = MIB_OBJECT_NONE;
2439         break;
2440     };
2441   }
2442   else
2443   {
2444     LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_object_def: no scalar\n"));
2445     od->instance = MIB_OBJECT_NONE;
2446   }
2447 }
2448
2449 /**
2450  * Returns ifentry object value.
2451  *
2452  * @param ident_len the address length (2)
2453  * @param ident points to objectname.0 (object id trailer)
2454  * @param len return value space (in bytes)
2455  * @param value points to (varbind) space to copy value into.
2456  */
2457 static void
2458 ifentry_get_value(struct obj_def *od, u16_t len, void *value)
2459 {
2460   struct netif *netif;
2461   u8_t id;
2462
2463   snmp_ifindextonetif(od->id_inst_ptr[1], &netif);
2464   id = od->id_inst_ptr[0];
2465   switch (id)
2466   {
2467     case 1: /* ifIndex */
2468       {
2469         s32_t *sint_ptr = value;
2470         *sint_ptr = od->id_inst_ptr[1];
2471       }
2472       break;
2473     case 2: /* ifDescr */
2474       ocstrncpy(value,(u8_t*)netif->name,len);
2475       break;
2476     case 3: /* ifType */
2477       {
2478         s32_t *sint_ptr = value;
2479         *sint_ptr = netif->link_type;
2480       }
2481       break;
2482     case 4: /* ifMtu */
2483       {
2484         s32_t *sint_ptr = value;
2485         *sint_ptr = netif->mtu;
2486       }
2487       break;
2488     case 5: /* ifSpeed */
2489       {
2490         u32_t *uint_ptr = value;
2491         *uint_ptr = netif->link_speed;
2492       }
2493       break;
2494     case 6: /* ifPhysAddress */
2495       ocstrncpy(value,netif->hwaddr,len);
2496       break;
2497     case 7: /* ifAdminStatus */
2498 #if LWIP_NETIF_LINK_CALLBACK
2499       {
2500         s32_t *sint_ptr = value;
2501         if (netif_is_up(netif))
2502         {
2503           if (netif_is_link_up(netif))
2504           {
2505             *sint_ptr = 1; /* up */
2506           }
2507           else
2508           {
2509             *sint_ptr = 7; /* lowerLayerDown */
2510           }
2511         }
2512         else
2513         {
2514           *sint_ptr = 2; /* down */
2515         }
2516       }
2517       break;
2518 #endif
2519     case 8: /* ifOperStatus */
2520       {
2521         s32_t *sint_ptr = value;
2522         if (netif_is_up(netif))
2523         {
2524           *sint_ptr = 1;
2525         }
2526         else
2527         {
2528           *sint_ptr = 2;
2529         }
2530       }
2531       break;
2532     case 9: /* ifLastChange */
2533       {
2534         u32_t *uint_ptr = value;
2535         *uint_ptr = netif->ts;
2536       }
2537       break;
2538     case 10: /* ifInOctets */
2539       {
2540         u32_t *uint_ptr = value;
2541         *uint_ptr = netif->ifinoctets;
2542       }
2543       break;
2544     case 11: /* ifInUcastPkts */
2545       {
2546         u32_t *uint_ptr = value;
2547         *uint_ptr = netif->ifinucastpkts;
2548       }
2549       break;
2550     case 12: /* ifInNUcastPkts */
2551       {
2552         u32_t *uint_ptr = value;
2553         *uint_ptr = netif->ifinnucastpkts;
2554       }
2555       break;
2556     case 13: /* ifInDiscarts */
2557       {
2558         u32_t *uint_ptr = value;
2559         *uint_ptr = netif->ifindiscards;
2560       }
2561       break;
2562     case 14: /* ifInErrors */
2563     case 15: /* ifInUnkownProtos */
2564       /** @todo add these counters! */
2565       {
2566         u32_t *uint_ptr = value;
2567         *uint_ptr = 0;
2568       }
2569       break;
2570     case 16: /* ifOutOctets */
2571       {
2572         u32_t *uint_ptr = value;
2573         *uint_ptr = netif->ifoutoctets;
2574       }
2575       break;
2576     case 17: /* ifOutUcastPkts */
2577       {
2578         u32_t *uint_ptr = value;
2579         *uint_ptr = netif->ifoutucastpkts;
2580       }
2581       break;
2582     case 18: /* ifOutNUcastPkts */
2583       {
2584         u32_t *uint_ptr = value;
2585         *uint_ptr = netif->ifoutnucastpkts;
2586       }
2587       break;
2588     case 19: /* ifOutDiscarts */
2589       {
2590         u32_t *uint_ptr = value;
2591         *uint_ptr = netif->ifoutdiscards;
2592       }
2593       break;
2594     case 20: /* ifOutErrors */
2595        /** @todo add this counter! */
2596       {
2597         u32_t *uint_ptr = value;
2598         *uint_ptr = 0;
2599       }
2600       break;
2601     case 21: /* ifOutQLen */
2602       /** @todo figure out if this must be 0 (no queue) or 1? */
2603       {
2604         u32_t *uint_ptr = value;
2605         *uint_ptr = 0;
2606       }
2607       break;
2608     case 22: /* ifSpecific */
2609       objectidncpy((s32_t*)value,(s32_t*)ifspecific.id,len / sizeof(s32_t));
2610       break;
2611   };
2612 }
2613
2614 #if !SNMP_SAFE_REQUESTS
2615 static u8_t
2616 ifentry_set_test (struct obj_def *od, u16_t len, void *value)
2617 {
2618   struct netif *netif;
2619   u8_t id, set_ok;
2620
2621   set_ok = 0;
2622   snmp_ifindextonetif(od->id_inst_ptr[1], &netif);
2623   id = od->id_inst_ptr[0];
2624   switch (id)
2625   {
2626     case 7: /* ifAdminStatus */
2627       {
2628         s32_t *sint_ptr = value;
2629         if (*sint_ptr == 1 || *sint_ptr == 2)
2630           set_ok = 1;
2631       }
2632       break;
2633   }
2634   return set_ok;
2635 }
2636
2637 static void
2638 ifentry_set_value (struct obj_def *od, u16_t len, void *value)
2639 {
2640   struct netif *netif;
2641   u8_t id;
2642
2643   snmp_ifindextonetif(od->id_inst_ptr[1], &netif);
2644   id = od->id_inst_ptr[0];
2645   switch (id)
2646   {
2647     case 7: /* ifAdminStatus */
2648       {
2649         s32_t *sint_ptr = value;
2650         if (*sint_ptr == 1)
2651         {
2652           netif_set_up(netif);
2653         }
2654         else if (*sint_ptr == 2)
2655         {
2656           netif_set_down(netif);
2657          }
2658       }
2659       break;
2660   }
2661 }
2662 #endif /* SNMP_SAFE_REQUESTS */
2663
2664 /**
2665  * Returns atentry object definitions.
2666  *
2667  * @param ident_len the address length (6)
2668  * @param ident points to objectname.atifindex.atnetaddress
2669  * @param od points to object definition.
2670  */
2671 static void
2672 atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
2673 {
2674   /* return to object name, adding index depth (5) */
2675   ident_len += 5;
2676   ident -= 5;
2677
2678   if (ident_len == 6)
2679   {
2680     od->id_inst_len = ident_len;
2681     od->id_inst_ptr = ident;
2682
2683     switch (ident[0])
2684     {
2685       case 1: /* atIfIndex */
2686         od->instance = MIB_OBJECT_TAB;
2687         od->access = MIB_OBJECT_READ_WRITE;
2688         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
2689         od->v_len = sizeof(s32_t);
2690         break;
2691       case 2: /* atPhysAddress */
2692         od->instance = MIB_OBJECT_TAB;
2693         od->access = MIB_OBJECT_READ_WRITE;
2694         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
2695         od->v_len = 6; /** @todo try to use netif::hwaddr_len */
2696         break;
2697       case 3: /* atNetAddress */
2698         od->instance = MIB_OBJECT_TAB;
2699         od->access = MIB_OBJECT_READ_WRITE;
2700         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
2701         od->v_len = 4;
2702         break;
2703       default:
2704         LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no such object\n"));
2705         od->instance = MIB_OBJECT_NONE;
2706         break;
2707     }
2708   }
2709   else
2710   {
2711     LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no scalar\n"));
2712     od->instance = MIB_OBJECT_NONE;
2713   }
2714 }
2715
2716 static void
2717 atentry_get_value(struct obj_def *od, u16_t len, void *value)
2718 {
2719 #if LWIP_ARP
2720   u8_t id;
2721   struct eth_addr* ethaddr_ret;
2722   struct ip_addr* ipaddr_ret;
2723 #endif /* LWIP_ARP */
2724   struct ip_addr ip;
2725   struct netif *netif;
2726
2727   if (len) {}
2728
2729   snmp_ifindextonetif(od->id_inst_ptr[1], &netif);
2730   snmp_oidtoip(&od->id_inst_ptr[2], &ip);
2731   ip.addr = htonl(ip.addr);
2732
2733 #if LWIP_ARP /** @todo implement a netif_find_addr */
2734   if (etharp_find_addr(netif, &ip, &ethaddr_ret, &ipaddr_ret) > -1)
2735   {
2736     id = od->id_inst_ptr[0];
2737     switch (id)
2738     {
2739       case 1: /* atIfIndex */
2740         {
2741           s32_t *sint_ptr = value;
2742           *sint_ptr = od->id_inst_ptr[1];
2743         }
2744         break;
2745       case 2: /* atPhysAddress */
2746         {
2747           struct eth_addr *dst = value;
2748
2749           *dst = *ethaddr_ret;
2750         }
2751         break;
2752       case 3: /* atNetAddress */
2753         {
2754           struct ip_addr *dst = value;
2755
2756           *dst = *ipaddr_ret;
2757         }
2758         break;
2759     }
2760   }
2761 #endif /* LWIP_ARP */
2762 }
2763
2764 static void
2765 ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
2766 {
2767   u8_t id;
2768
2769   /* return to object name, adding index depth (1) */
2770   ident_len += 1;
2771   ident -= 1;
2772   if (ident_len == 2)
2773   {
2774     od->id_inst_len = ident_len;
2775     od->id_inst_ptr = ident;
2776
2777     id = ident[0];
2778     LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def ip.%"U16_F".0\n",(u16_t)id));
2779     switch (id)
2780     {
2781       case 1: /* ipForwarding */
2782       case 2: /* ipDefaultTTL */
2783         od->instance = MIB_OBJECT_SCALAR;
2784         od->access = MIB_OBJECT_READ_WRITE;
2785         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
2786         od->v_len = sizeof(s32_t);
2787         break;
2788       case 3: /* ipInReceives */
2789       case 4: /* ipInHdrErrors */
2790       case 5: /* ipInAddrErrors */
2791       case 6: /* ipForwDatagrams */
2792       case 7: /* ipInUnknownProtos */
2793       case 8: /* ipInDiscards */
2794       case 9: /* ipInDelivers */
2795       case 10: /* ipOutRequests */
2796       case 11: /* ipOutDiscards */
2797       case 12: /* ipOutNoRoutes */
2798       case 14: /* ipReasmReqds */
2799       case 15: /* ipReasmOKs */
2800       case 16: /* ipReasmFails */
2801       case 17: /* ipFragOKs */
2802       case 18: /* ipFragFails */
2803       case 19: /* ipFragCreates */
2804       case 23: /* ipRoutingDiscards */
2805         od->instance = MIB_OBJECT_SCALAR;
2806         od->access = MIB_OBJECT_READ_ONLY;
2807         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
2808         od->v_len = sizeof(u32_t);
2809         break;
2810       case 13: /* ipReasmTimeout */
2811         od->instance = MIB_OBJECT_SCALAR;
2812         od->access = MIB_OBJECT_READ_ONLY;
2813         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
2814         od->v_len = sizeof(s32_t);
2815         break;
2816       default:
2817         LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no such object\n"));
2818         od->instance = MIB_OBJECT_NONE;
2819         break;
2820     };
2821   }
2822   else
2823   {
2824     LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no scalar\n"));
2825     od->instance = MIB_OBJECT_NONE;
2826   }
2827 }
2828
2829 static void
2830 ip_get_value(struct obj_def *od, u16_t len, void *value)
2831 {
2832   u8_t id;
2833
2834   if (len) {}
2835   id = od->id_inst_ptr[0];
2836   switch (id)
2837   {
2838     case 1: /* ipForwarding */
2839       {
2840         s32_t *sint_ptr = value;
2841 #if IP_FORWARD
2842         /* forwarding */
2843         *sint_ptr = 1;
2844 #else
2845         /* not-forwarding */
2846         *sint_ptr = 2;
2847 #endif
2848       }
2849       break;
2850     case 2: /* ipDefaultTTL */
2851       {
2852         s32_t *sint_ptr = value;
2853         *sint_ptr = IP_DEFAULT_TTL;
2854       }
2855       break;
2856     case 3: /* ipInReceives */
2857       {
2858         u32_t *uint_ptr = value;
2859         *uint_ptr = ipinreceives;
2860       }
2861       break;
2862     case 4: /* ipInHdrErrors */
2863       {
2864         u32_t *uint_ptr = value;
2865         *uint_ptr = ipinhdrerrors;
2866       }
2867       break;
2868     case 5: /* ipInAddrErrors */
2869       {
2870         u32_t *uint_ptr = value;
2871         *uint_ptr = ipinaddrerrors;
2872       }
2873       break;
2874     case 6: /* ipForwDatagrams */
2875       {
2876         u32_t *uint_ptr = value;
2877         *uint_ptr = ipforwdatagrams;
2878       }
2879       break;
2880     case 7: /* ipInUnknownProtos */
2881       {
2882         u32_t *uint_ptr = value;
2883         *uint_ptr = ipinunknownprotos;
2884       }
2885       break;
2886     case 8: /* ipInDiscards */
2887       {
2888         u32_t *uint_ptr = value;
2889         *uint_ptr = ipindiscards;
2890       }
2891       break;
2892     case 9: /* ipInDelivers */
2893       {
2894         u32_t *uint_ptr = value;
2895         *uint_ptr = ipindelivers;
2896       }
2897       break;
2898     case 10: /* ipOutRequests */
2899       {
2900         u32_t *uint_ptr = value;
2901         *uint_ptr = ipoutrequests;
2902       }
2903       break;
2904     case 11: /* ipOutDiscards */
2905       {
2906         u32_t *uint_ptr = value;
2907         *uint_ptr = ipoutdiscards;
2908       }
2909       break;
2910     case 12: /* ipOutNoRoutes */
2911       {
2912         u32_t *uint_ptr = value;
2913         *uint_ptr = ipoutnoroutes;
2914       }
2915       break;
2916     case 13: /* ipReasmTimeout */
2917       {
2918         s32_t *sint_ptr = value;
2919 #if IP_REASSEMBLY
2920         *sint_ptr = IP_REASS_MAXAGE;
2921 #else
2922         *sint_ptr = 0;
2923 #endif
2924       }
2925       break;
2926     case 14: /* ipReasmReqds */
2927       {
2928         u32_t *uint_ptr = value;
2929         *uint_ptr = ipreasmreqds;
2930       }
2931       break;
2932     case 15: /* ipReasmOKs */
2933       {
2934         u32_t *uint_ptr = value;
2935         *uint_ptr = ipreasmoks;
2936       }
2937       break;
2938     case 16: /* ipReasmFails */
2939       {
2940         u32_t *uint_ptr = value;
2941         *uint_ptr = ipreasmfails;
2942       }
2943       break;
2944     case 17: /* ipFragOKs */
2945       {
2946         u32_t *uint_ptr = value;
2947         *uint_ptr = ipfragoks;
2948       }
2949       break;
2950     case 18: /* ipFragFails */
2951       {
2952         u32_t *uint_ptr = value;
2953         *uint_ptr = ipfragfails;
2954       }
2955       break;
2956     case 19: /* ipFragCreates */
2957       {
2958         u32_t *uint_ptr = value;
2959         *uint_ptr = ipfragcreates;
2960       }
2961       break;
2962     case 23: /* ipRoutingDiscards */
2963       /** @todo can lwIP discard routes at all?? hardwire this to 0?? */
2964       {
2965         u32_t *uint_ptr = value;
2966         *uint_ptr = iproutingdiscards;
2967       }
2968       break;
2969   };
2970 }
2971
2972 /**
2973  * Test ip object value before setting.
2974  *
2975  * @param od is the object definition
2976  * @param len return value space (in bytes)
2977  * @param value points to (varbind) space to copy value from.
2978  *
2979  * @note we allow set if the value matches the hardwired value,
2980  *   otherwise return badvalue.
2981  */
2982 static u8_t
2983 ip_set_test(struct obj_def *od, u16_t len, void *value)
2984 {
2985   u8_t id, set_ok;
2986   s32_t *sint_ptr = value;
2987
2988   if (len) {}
2989   set_ok = 0;
2990   id = od->id_inst_ptr[0];
2991   switch (id)
2992   {
2993     case 1: /* ipForwarding */
2994 #if IP_FORWARD
2995       /* forwarding */
2996       if (*sint_ptr == 1)
2997 #else
2998       /* not-forwarding */
2999       if (*sint_ptr == 2)
3000 #endif
3001       {
3002         set_ok = 1;
3003       }
3004       break;
3005     case 2: /* ipDefaultTTL */
3006       if (*sint_ptr == IP_DEFAULT_TTL)
3007       {
3008         set_ok = 1;
3009       }
3010       break;
3011   };
3012   return set_ok;
3013 }
3014
3015 static void
3016 ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
3017 {
3018   /* return to object name, adding index depth (4) */
3019   ident_len += 4;
3020   ident -= 4;
3021
3022   if (ident_len == 5)
3023   {
3024     u8_t id;
3025
3026     od->id_inst_len = ident_len;
3027     od->id_inst_ptr = ident;
3028
3029     id = ident[0];
3030     switch (id)
3031     {
3032       case 1: /* ipAdEntAddr */
3033       case 3: /* ipAdEntNetMask */
3034         od->instance = MIB_OBJECT_TAB;
3035         od->access = MIB_OBJECT_READ_ONLY;
3036         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
3037         od->v_len = 4;
3038         break;
3039       case 2: /* ipAdEntIfIndex */
3040       case 4: /* ipAdEntBcastAddr */
3041       case 5: /* ipAdEntReasmMaxSize */
3042         od->instance = MIB_OBJECT_TAB;
3043         od->access = MIB_OBJECT_READ_ONLY;
3044         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
3045         od->v_len = sizeof(s32_t);
3046         break;
3047       default:
3048         LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no such object\n"));
3049         od->instance = MIB_OBJECT_NONE;
3050         break;
3051     }
3052   }
3053   else
3054   {
3055     LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no scalar\n"));
3056     od->instance = MIB_OBJECT_NONE;
3057   }
3058 }
3059
3060 static void
3061 ip_addrentry_get_value(struct obj_def *od, u16_t len, void *value)
3062 {
3063   u8_t id;
3064   u16_t ifidx;
3065   struct ip_addr ip;
3066   struct netif *netif = netif_list;
3067
3068   if (len) {}
3069   snmp_oidtoip(&od->id_inst_ptr[1], &ip);
3070   ip.addr = htonl(ip.addr);
3071   ifidx = 0;
3072   while ((netif != NULL) && !ip_addr_cmp(&ip, &netif->ip_addr))
3073   {
3074     netif = netif->next;
3075     ifidx++;
3076   }
3077
3078   if (netif != NULL)
3079   {
3080     id = od->id_inst_ptr[0];
3081     switch (id)
3082     {
3083       case 1: /* ipAdEntAddr */
3084         {
3085           struct ip_addr *dst = value;
3086           *dst = netif->ip_addr;
3087         }
3088         break;
3089       case 2: /* ipAdEntIfIndex */
3090         {
3091           s32_t *sint_ptr = value;
3092           *sint_ptr = ifidx + 1;
3093         }
3094         break;
3095       case 3: /* ipAdEntNetMask */
3096         {
3097           struct ip_addr *dst = value;
3098           *dst = netif->netmask;
3099         }
3100         break;
3101       case 4: /* ipAdEntBcastAddr */
3102         {
3103           s32_t *sint_ptr = value;
3104
3105           /* lwIP oddity, there's no broadcast
3106             address in the netif we can rely on */
3107           *sint_ptr = ip_addr_broadcast.addr & 1;
3108         }
3109         break;
3110       case 5: /* ipAdEntReasmMaxSize */
3111         {
3112           s32_t *sint_ptr = value;
3113 #if IP_REASSEMBLY
3114           /* @todo The theoretical maximum is IP_REASS_MAX_PBUFS * size of the pbufs,
3115            * but only if receiving one fragmented packet at a time.
3116            * The current solution is to calculate for 2 simultaneous packets...
3117            */
3118           *sint_ptr = (IP_HLEN + ((IP_REASS_MAX_PBUFS/2) *
3119             (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN - IP_HLEN)));
3120 #else
3121           /** @todo returning MTU would be a bad thing and
3122              returning a wild guess like '576' isn't good either */
3123           *sint_ptr = 0;
3124 #endif
3125         }
3126         break;
3127     }
3128   }
3129 }
3130
3131 /**
3132  * @note
3133  * lwIP IP routing is currently using the network addresses in netif_list.
3134  * if no suitable network IP is found in netif_list, the default_netif is used.
3135  */
3136 static void
3137 ip_rteentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
3138 {
3139   u8_t id;
3140
3141   /* return to object name, adding index depth (4) */
3142   ident_len += 4;
3143   ident -= 4;
3144
3145   if (ident_len == 5)
3146   {
3147     od->id_inst_len = ident_len;
3148     od->id_inst_ptr = ident;
3149
3150     id = ident[0];
3151     switch (id)
3152     {
3153       case 1: /* ipRouteDest */
3154       case 7: /* ipRouteNextHop */
3155       case 11: /* ipRouteMask */
3156         od->instance = MIB_OBJECT_TAB;
3157         od->access = MIB_OBJECT_READ_WRITE;
3158         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
3159         od->v_len = 4;
3160         break;
3161       case 2: /* ipRouteIfIndex */
3162       case 3: /* ipRouteMetric1 */
3163       case 4: /* ipRouteMetric2 */
3164       case 5: /* ipRouteMetric3 */
3165       case 6: /* ipRouteMetric4 */
3166       case 8: /* ipRouteType */
3167       case 10: /* ipRouteAge */
3168       case 12: /* ipRouteMetric5 */
3169         od->instance = MIB_OBJECT_TAB;
3170         od->access = MIB_OBJECT_READ_WRITE;
3171         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
3172         od->v_len = sizeof(s32_t);
3173         break;
3174       case 9: /* ipRouteProto */
3175         od->instance = MIB_OBJECT_TAB;
3176         od->access = MIB_OBJECT_READ_ONLY;
3177         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
3178         od->v_len = sizeof(s32_t);
3179         break;
3180       case 13: /* ipRouteInfo */
3181         /** @note returning zeroDotZero (0.0) no routing protocol specific MIB */
3182         od->instance = MIB_OBJECT_TAB;
3183         od->access = MIB_OBJECT_READ_ONLY;
3184         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID);
3185         od->v_len = iprouteinfo.len * sizeof(s32_t);
3186         break;
3187       default:
3188         LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no such object\n"));
3189         od->instance = MIB_OBJECT_NONE;
3190         break;
3191     }
3192   }
3193   else
3194   {
3195     LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no scalar\n"));
3196     od->instance = MIB_OBJECT_NONE;
3197   }
3198 }
3199
3200 static void
3201 ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value)
3202 {
3203   struct netif *netif;
3204   struct ip_addr dest;
3205   s32_t *ident;
3206   u8_t id;
3207
3208   ident = od->id_inst_ptr;
3209   snmp_oidtoip(&ident[1], &dest);
3210   dest.addr = htonl(dest.addr);
3211
3212   if (dest.addr == 0)
3213   {
3214     /* ip_route() uses default netif for default route */
3215     netif = netif_default;
3216   }
3217   else
3218   {
3219     /* not using ip_route(), need exact match! */
3220     netif = netif_list;
3221     while ((netif != NULL) &&
3222             !ip_addr_netcmp(&dest, &(netif->ip_addr), &(netif->netmask)) )
3223     {
3224       netif = netif->next;
3225     }
3226   }
3227   if (netif != NULL)
3228   {
3229     id = ident[0];
3230     switch (id)
3231     {
3232       case 1: /* ipRouteDest */
3233         {
3234           struct ip_addr *dst = value;
3235
3236           if (dest.addr == 0)
3237           {
3238             /* default rte has 0.0.0.0 dest */
3239             dst->addr = 0;
3240           }
3241           else
3242           {
3243             /* netifs have netaddress dest */
3244             dst->addr = netif->ip_addr.addr & netif->netmask.addr;
3245           }
3246         }
3247         break;
3248       case 2: /* ipRouteIfIndex */
3249         {
3250           s32_t *sint_ptr = value;
3251
3252           snmp_netiftoifindex(netif, sint_ptr);
3253         }
3254         break;
3255       case 3: /* ipRouteMetric1 */
3256         {
3257           s32_t *sint_ptr = value;
3258
3259           if (dest.addr == 0)
3260           {
3261             /* default rte has metric 1 */
3262             *sint_ptr = 1;
3263           }
3264           else
3265           {
3266             /* other rtes have metric 0 */
3267             *sint_ptr = 0;
3268           }
3269         }
3270         break;
3271       case 4: /* ipRouteMetric2 */
3272       case 5: /* ipRouteMetric3 */
3273       case 6: /* ipRouteMetric4 */
3274       case 12: /* ipRouteMetric5 */
3275         {
3276           s32_t *sint_ptr = value;
3277           /* not used */
3278           *sint_ptr = -1;
3279         }
3280         break;
3281       case 7: /* ipRouteNextHop */
3282         {
3283           struct ip_addr *dst = value;
3284
3285           if (dest.addr == 0)
3286           {
3287             /* default rte: gateway */
3288             *dst = netif->gw;
3289           }
3290           else
3291           {
3292             /* other rtes: netif ip_addr  */
3293             *dst = netif->ip_addr;
3294           }
3295         }
3296         break;
3297       case 8: /* ipRouteType */
3298         {
3299           s32_t *sint_ptr = value;
3300
3301           if (dest.addr == 0)
3302           {
3303             /* default rte is indirect */
3304             *sint_ptr = 4;
3305           }
3306           else
3307           {
3308             /* other rtes are direct */
3309             *sint_ptr = 3;
3310           }
3311         }
3312         break;
3313       case 9: /* ipRouteProto */
3314         {
3315           s32_t *sint_ptr = value;
3316           /* locally defined routes */
3317           *sint_ptr = 2;
3318         }
3319         break;
3320       case 10: /* ipRouteAge */
3321         {
3322           s32_t *sint_ptr = value;
3323           /** @todo (sysuptime - timestamp last change) / 100
3324               @see snmp_insert_iprteidx_tree() */
3325           *sint_ptr = 0;
3326         }
3327         break;
3328       case 11: /* ipRouteMask */
3329         {
3330           struct ip_addr *dst = value;
3331
3332           if (dest.addr == 0)
3333           {
3334             /* default rte use 0.0.0.0 mask */
3335             dst->addr = 0;
3336           }
3337           else
3338           {
3339             /* other rtes use netmask */
3340             *dst = netif->netmask;
3341           }
3342         }
3343         break;
3344       case 13: /* ipRouteInfo */
3345         objectidncpy((s32_t*)value,(s32_t*)iprouteinfo.id,len / sizeof(s32_t));
3346         break;
3347     }
3348   }
3349 }
3350
3351 static void
3352 ip_ntomentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
3353 {
3354   /* return to object name, adding index depth (5) */
3355   ident_len += 5;
3356   ident -= 5;
3357
3358   if (ident_len == 6)
3359   {
3360     u8_t id;
3361
3362     od->id_inst_len = ident_len;
3363     od->id_inst_ptr = ident;
3364
3365     id = ident[0];
3366     switch (id)
3367     {
3368       case 1: /* ipNetToMediaIfIndex */
3369       case 4: /* ipNetToMediaType */
3370         od->instance = MIB_OBJECT_TAB;
3371         od->access = MIB_OBJECT_READ_WRITE;
3372         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
3373         od->v_len = sizeof(s32_t);
3374         break;
3375       case 2: /* ipNetToMediaPhysAddress */
3376         od->instance = MIB_OBJECT_TAB;
3377         od->access = MIB_OBJECT_READ_WRITE;
3378         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
3379         od->v_len = 6; /** @todo try to use netif::hwaddr_len */
3380         break;
3381       case 3: /* ipNetToMediaNetAddress */
3382         od->instance = MIB_OBJECT_TAB;
3383         od->access = MIB_OBJECT_READ_WRITE;
3384         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
3385         od->v_len = 4;
3386         break;
3387       default:
3388         LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no such object\n"));
3389         od->instance = MIB_OBJECT_NONE;
3390         break;
3391     }
3392   }
3393   else
3394   {
3395     LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no scalar\n"));
3396     od->instance = MIB_OBJECT_NONE;
3397   }
3398 }
3399
3400 static void
3401 ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value)
3402 {
3403 #if LWIP_ARP
3404   u8_t id;
3405   struct eth_addr* ethaddr_ret;
3406   struct ip_addr* ipaddr_ret;
3407 #endif /* LWIP_ARP */
3408   struct ip_addr ip;
3409   struct netif *netif;
3410
3411   if (len) {}
3412
3413   snmp_ifindextonetif(od->id_inst_ptr[1], &netif);
3414   snmp_oidtoip(&od->id_inst_ptr[2], &ip);
3415   ip.addr = htonl(ip.addr);
3416
3417 #if LWIP_ARP /** @todo implement a netif_find_addr */
3418   if (etharp_find_addr(netif, &ip, &ethaddr_ret, &ipaddr_ret) > -1)
3419   {
3420     id = od->id_inst_ptr[0];
3421     switch (id)
3422     {
3423       case 1: /* ipNetToMediaIfIndex */
3424         {
3425           s32_t *sint_ptr = value;
3426           *sint_ptr = od->id_inst_ptr[1];
3427         }
3428         break;
3429       case 2: /* ipNetToMediaPhysAddress */
3430         {
3431           struct eth_addr *dst = value;
3432
3433           *dst = *ethaddr_ret;
3434         }
3435         break;
3436       case 3: /* ipNetToMediaNetAddress */
3437         {
3438           struct ip_addr *dst = value;
3439
3440           *dst = *ipaddr_ret;
3441         }
3442         break;
3443       case 4: /* ipNetToMediaType */
3444         {
3445           s32_t *sint_ptr = value;
3446           /* dynamic (?) */
3447           *sint_ptr = 3;
3448         }
3449         break;
3450     }
3451   }
3452 #endif /* LWIP_ARP */
3453 }
3454
3455 static void
3456 icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
3457 {
3458   /* return to object name, adding index depth (1) */
3459   ident_len += 1;
3460   ident -= 1;
3461   if ((ident_len == 2) &&
3462       (ident[0] > 0) && (ident[0] < 27))
3463   {
3464     od->id_inst_len = ident_len;
3465     od->id_inst_ptr = ident;
3466
3467     od->instance = MIB_OBJECT_SCALAR;
3468     od->access = MIB_OBJECT_READ_ONLY;
3469     od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
3470     od->v_len = sizeof(u32_t);
3471   }
3472   else
3473   {
3474     LWIP_DEBUGF(SNMP_MIB_DEBUG,("icmp_get_object_def: no scalar\n"));
3475     od->instance = MIB_OBJECT_NONE;
3476   }
3477 }
3478
3479 static void
3480 icmp_get_value(struct obj_def *od, u16_t len, void *value)
3481 {
3482   u32_t *uint_ptr = value;
3483   u8_t id;
3484
3485   if (len){}
3486   id = od->id_inst_ptr[0];
3487   switch (id)
3488   {
3489     case 1: /* icmpInMsgs */
3490       *uint_ptr = icmpinmsgs;
3491       break;
3492     case 2: /* icmpInErrors */
3493       *uint_ptr = icmpinerrors;
3494       break;
3495     case 3: /* icmpInDestUnreachs */
3496       *uint_ptr = icmpindestunreachs;
3497       break;
3498     case 4: /* icmpInTimeExcds */
3499       *uint_ptr = icmpintimeexcds;
3500       break;
3501     case 5: /* icmpInParmProbs */
3502       *uint_ptr = icmpinparmprobs;
3503       break;
3504     case 6: /* icmpInSrcQuenchs */
3505       *uint_ptr = icmpinsrcquenchs;
3506       break;
3507     case 7: /* icmpInRedirects */
3508       *uint_ptr = icmpinredirects;
3509       break;
3510     case 8: /* icmpInEchos */
3511       *uint_ptr = icmpinechos;
3512       break;
3513     case 9: /* icmpInEchoReps */
3514       *uint_ptr = icmpinechoreps;
3515       break;
3516     case 10: /* icmpInTimestamps */
3517       *uint_ptr = icmpintimestamps;
3518       break;
3519     case 11: /* icmpInTimestampReps */
3520       *uint_ptr = icmpintimestampreps;
3521       break;
3522     case 12: /* icmpInAddrMasks */
3523       *uint_ptr = icmpinaddrmasks;
3524       break;
3525     case 13: /* icmpInAddrMaskReps */
3526       *uint_ptr = icmpinaddrmaskreps;
3527       break;
3528     case 14: /* icmpOutMsgs */
3529       *uint_ptr = icmpoutmsgs;
3530       break;
3531     case 15: /* icmpOutErrors */
3532       *uint_ptr = icmpouterrors;
3533       break;
3534     case 16: /* icmpOutDestUnreachs */
3535       *uint_ptr = icmpoutdestunreachs;
3536       break;
3537     case 17: /* icmpOutTimeExcds */
3538       *uint_ptr = icmpouttimeexcds;
3539       break;
3540     case 18: /* icmpOutParmProbs */
3541       *uint_ptr = icmpoutparmprobs;
3542       break;
3543     case 19: /* icmpOutSrcQuenchs */
3544       *uint_ptr = icmpoutsrcquenchs;
3545       break;
3546     case 20: /* icmpOutRedirects */
3547       *uint_ptr = icmpoutredirects;
3548       break;
3549     case 21: /* icmpOutEchos */
3550       *uint_ptr = icmpoutechos;
3551       break;
3552     case 22: /* icmpOutEchoReps */
3553       *uint_ptr = icmpoutechoreps;
3554       break;
3555     case 23: /* icmpOutTimestamps */
3556       *uint_ptr = icmpouttimestamps;
3557       break;
3558     case 24: /* icmpOutTimestampReps */
3559       *uint_ptr = icmpouttimestampreps;
3560       break;
3561     case 25: /* icmpOutAddrMasks */
3562       *uint_ptr = icmpoutaddrmasks;
3563       break;
3564     case 26: /* icmpOutAddrMaskReps */
3565       *uint_ptr = icmpoutaddrmaskreps;
3566       break;
3567   }
3568 }
3569
3570 #if LWIP_TCP
3571 /** @todo tcp grp */
3572 static void
3573 tcp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
3574 {
3575   u8_t id;
3576
3577   /* return to object name, adding index depth (1) */
3578   ident_len += 1;
3579   ident -= 1;
3580   if (ident_len == 2)
3581   {
3582     od->id_inst_len = ident_len;
3583     od->id_inst_ptr = ident;
3584
3585     id = ident[0];
3586     LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def tcp.%"U16_F".0\n",(u16_t)id));
3587
3588     switch (id)
3589     {
3590       case 1: /* tcpRtoAlgorithm */
3591       case 2: /* tcpRtoMin */
3592       case 3: /* tcpRtoMax */
3593       case 4: /* tcpMaxConn */
3594         od->instance = MIB_OBJECT_SCALAR;
3595         od->access = MIB_OBJECT_READ_ONLY;
3596         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
3597         od->v_len = sizeof(s32_t);
3598         break;
3599       case 5: /* tcpActiveOpens */
3600       case 6: /* tcpPassiveOpens */
3601       case 7: /* tcpAttemptFails */
3602       case 8: /* tcpEstabResets */
3603       case 10: /* tcpInSegs */
3604       case 11: /* tcpOutSegs */
3605       case 12: /* tcpRetransSegs */
3606       case 14: /* tcpInErrs */
3607       case 15: /* tcpOutRsts */
3608         od->instance = MIB_OBJECT_SCALAR;
3609         od->access = MIB_OBJECT_READ_ONLY;
3610         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
3611         od->v_len = sizeof(u32_t);
3612         break;
3613       case 9: /* tcpCurrEstab */
3614         od->instance = MIB_OBJECT_TAB;
3615         od->access = MIB_OBJECT_READ_ONLY;
3616         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE);
3617         od->v_len = sizeof(u32_t);
3618         break;
3619       default:
3620         LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_object_def: no such object\n"));
3621         od->instance = MIB_OBJECT_NONE;
3622         break;
3623     };
3624   }
3625   else
3626   {
3627     LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_object_def: no scalar\n"));
3628     od->instance = MIB_OBJECT_NONE;
3629   }
3630 }
3631
3632 static void
3633 tcp_get_value(struct obj_def *od, u16_t len, void *value)
3634 {
3635   u32_t *uint_ptr = value;
3636   s32_t *sint_ptr = value;
3637   u8_t id;
3638
3639   if (len){}
3640   id = od->id_inst_ptr[0];
3641   switch (id)
3642   {
3643     case 1: /* tcpRtoAlgorithm, vanj(4) */
3644       *sint_ptr = 4;
3645       break;
3646     case 2: /* tcpRtoMin */
3647       /* @todo not the actual value, a guess,
3648           needs to be calculated */
3649       *sint_ptr = 1000;
3650       break;
3651     case 3: /* tcpRtoMax */
3652       /* @todo not the actual value, a guess,
3653          needs to be calculated */
3654       *sint_ptr = 60000;
3655       break;
3656     case 4: /* tcpMaxConn */
3657       *sint_ptr = MEMP_NUM_TCP_PCB;
3658       break;
3659     case 5: /* tcpActiveOpens */
3660       *uint_ptr = tcpactiveopens;
3661       break;
3662     case 6: /* tcpPassiveOpens */
3663       *uint_ptr = tcppassiveopens;
3664       break;
3665     case 7: /* tcpAttemptFails */
3666       *uint_ptr = tcpattemptfails;
3667       break;
3668     case 8: /* tcpEstabResets */
3669       *uint_ptr = tcpestabresets;
3670       break;
3671     case 9: /* tcpCurrEstab */
3672       {
3673         u16_t tcpcurrestab = 0;
3674         struct tcp_pcb *pcb = tcp_active_pcbs;
3675         while (pcb != NULL)
3676         {
3677           if ((pcb->state == ESTABLISHED) ||
3678               (pcb->state == CLOSE_WAIT))
3679           {
3680             tcpcurrestab++;
3681           }
3682           pcb = pcb->next;
3683         }
3684         *uint_ptr = tcpcurrestab;
3685       }
3686       break;
3687     case 10: /* tcpInSegs */
3688       *uint_ptr = tcpinsegs;
3689       break;
3690     case 11: /* tcpOutSegs */
3691       *uint_ptr = tcpoutsegs;
3692       break;
3693     case 12: /* tcpRetransSegs */
3694       *uint_ptr = tcpretranssegs;
3695       break;
3696     case 14: /* tcpInErrs */
3697       *uint_ptr = tcpinerrs;
3698       break;
3699     case 15: /* tcpOutRsts */
3700       *uint_ptr = tcpoutrsts;
3701       break;
3702   }
3703 }
3704 #ifdef THIS_SEEMS_UNUSED
3705 static void
3706 tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
3707 {
3708   /* return to object name, adding index depth (10) */
3709   ident_len += 10;
3710   ident -= 10;
3711
3712   if (ident_len == 11)
3713   {
3714     u8_t id;
3715
3716     od->id_inst_len = ident_len;
3717     od->id_inst_ptr = ident;
3718
3719     id = ident[0];
3720     LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def tcp.%"U16_F".0\n",(u16_t)id));
3721
3722     switch (id)
3723     {
3724       case 1: /* tcpConnState */
3725         od->instance = MIB_OBJECT_TAB;
3726         od->access = MIB_OBJECT_READ_WRITE;
3727         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
3728         od->v_len = sizeof(s32_t);
3729         break;
3730       case 2: /* tcpConnLocalAddress */
3731       case 4: /* tcpConnRemAddress */
3732         od->instance = MIB_OBJECT_TAB;
3733         od->access = MIB_OBJECT_READ_ONLY;
3734         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
3735         od->v_len = 4;
3736         break;
3737       case 3: /* tcpConnLocalPort */
3738       case 5: /* tcpConnRemPort */
3739         od->instance = MIB_OBJECT_TAB;
3740         od->access = MIB_OBJECT_READ_ONLY;
3741         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
3742         od->v_len = sizeof(s32_t);
3743         break;
3744       default:
3745         LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object\n"));
3746         od->instance = MIB_OBJECT_NONE;
3747         break;
3748     };
3749   }
3750   else
3751   {
3752     LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcpconnentry_get_object_def: no such object\n"));
3753     od->instance = MIB_OBJECT_NONE;
3754   }
3755 }
3756
3757 static void
3758 tcpconnentry_get_value(struct obj_def *od, u16_t len, void *value)
3759 {
3760   struct ip_addr lip, rip;
3761   u16_t lport, rport;
3762   s32_t *ident;
3763
3764   ident = od->id_inst_ptr;
3765   snmp_oidtoip(&ident[1], &lip);
3766   lip.addr = htonl(lip.addr);
3767   lport = ident[5];
3768   snmp_oidtoip(&ident[6], &rip);
3769   rip.addr = htonl(rip.addr);
3770   rport = ident[10];
3771
3772   /** @todo find matching PCB */
3773 }
3774 #endif /* if 0 */
3775 #endif
3776
3777 static void
3778 udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
3779 {
3780   /* return to object name, adding index depth (1) */
3781   ident_len += 1;
3782   ident -= 1;
3783   if ((ident_len == 2) &&
3784       (ident[0] > 0) && (ident[0] < 6))
3785   {
3786     od->id_inst_len = ident_len;
3787     od->id_inst_ptr = ident;
3788
3789     od->instance = MIB_OBJECT_SCALAR;
3790     od->access = MIB_OBJECT_READ_ONLY;
3791     od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
3792     od->v_len = sizeof(u32_t);
3793   }
3794   else
3795   {
3796     LWIP_DEBUGF(SNMP_MIB_DEBUG,("udp_get_object_def: no scalar\n"));
3797     od->instance = MIB_OBJECT_NONE;
3798   }
3799 }
3800
3801 static void
3802 udp_get_value(struct obj_def *od, u16_t len, void *value)
3803 {
3804   u32_t *uint_ptr = value;
3805   u8_t id;
3806
3807   if (len){}
3808   id = od->id_inst_ptr[0];
3809   switch (id)
3810   {
3811     case 1: /* udpInDatagrams */
3812       *uint_ptr = udpindatagrams;
3813       break;
3814     case 2: /* udpNoPorts */
3815       *uint_ptr = udpnoports;
3816       break;
3817     case 3: /* udpInErrors */
3818       *uint_ptr = udpinerrors;
3819       break;
3820     case 4: /* udpOutDatagrams */
3821       *uint_ptr = udpoutdatagrams;
3822       break;
3823   }
3824 }
3825
3826 static void
3827 udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
3828 {
3829   /* return to object name, adding index depth (5) */
3830   ident_len += 5;
3831   ident -= 5;
3832
3833   if (ident_len == 6)
3834   {
3835     od->id_inst_len = ident_len;
3836     od->id_inst_ptr = ident;
3837
3838     switch (ident[0])
3839     {
3840       case 1: /* udpLocalAddress */
3841         od->instance = MIB_OBJECT_TAB;
3842         od->access = MIB_OBJECT_READ_ONLY;
3843         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
3844         od->v_len = 4;
3845         break;
3846       case 2: /* udpLocalPort */
3847         od->instance = MIB_OBJECT_TAB;
3848         od->access = MIB_OBJECT_READ_ONLY;
3849         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
3850         od->v_len = sizeof(s32_t);
3851         break;
3852       default:
3853         LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no such object\n"));
3854         od->instance = MIB_OBJECT_NONE;
3855         break;
3856     }
3857   }
3858   else
3859   {
3860     LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no scalar\n"));
3861     od->instance = MIB_OBJECT_NONE;
3862   }
3863 }
3864
3865 static void
3866 udpentry_get_value(struct obj_def *od, u16_t len, void *value)
3867 {
3868   u8_t id;
3869   struct udp_pcb *pcb;
3870   struct ip_addr ip;
3871   u16_t port;
3872
3873   if (len){}
3874   snmp_oidtoip(&od->id_inst_ptr[1], &ip);
3875   ip.addr = htonl(ip.addr);
3876   port = od->id_inst_ptr[5];
3877
3878   pcb = udp_pcbs;
3879   while ((pcb != NULL) &&
3880          !((pcb->local_ip.addr == ip.addr) &&
3881            (pcb->local_port == port)))
3882   {
3883     pcb = pcb->next;
3884   }
3885
3886   if (pcb != NULL)
3887   {
3888     id = od->id_inst_ptr[0];
3889     switch (id)
3890     {
3891       case 1: /* udpLocalAddress */
3892         {
3893           struct ip_addr *dst = value;
3894           *dst = pcb->local_ip;
3895         }
3896         break;
3897       case 2: /* udpLocalPort */
3898         {
3899           s32_t *sint_ptr = value;
3900           *sint_ptr = pcb->local_port;
3901         }
3902         break;
3903     }
3904   }
3905 }
3906
3907 static void
3908 snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
3909 {
3910   /* return to object name, adding index depth (1) */
3911   ident_len += 1;
3912   ident -= 1;
3913   if (ident_len == 2)
3914   {
3915     u8_t id;
3916
3917     od->id_inst_len = ident_len;
3918     od->id_inst_ptr = ident;
3919
3920     id = ident[0];
3921     switch (id)
3922     {
3923       case 1: /* snmpInPkts */
3924       case 2: /* snmpOutPkts */
3925       case 3: /* snmpInBadVersions */
3926       case 4: /* snmpInBadCommunityNames */
3927       case 5: /* snmpInBadCommunityUses */
3928       case 6: /* snmpInASNParseErrs */
3929       case 8: /* snmpInTooBigs */
3930       case 9: /* snmpInNoSuchNames */
3931       case 10: /* snmpInBadValues */
3932       case 11: /* snmpInReadOnlys */
3933       case 12: /* snmpInGenErrs */
3934       case 13: /* snmpInTotalReqVars */
3935       case 14: /* snmpInTotalSetVars */
3936       case 15: /* snmpInGetRequests */
3937       case 16: /* snmpInGetNexts */
3938       case 17: /* snmpInSetRequests */
3939       case 18: /* snmpInGetResponses */
3940       case 19: /* snmpInTraps */
3941       case 20: /* snmpOutTooBigs */
3942       case 21: /* snmpOutNoSuchNames */
3943       case 22: /* snmpOutBadValues */
3944       case 24: /* snmpOutGenErrs */
3945       case 25: /* snmpOutGetRequests */
3946       case 26: /* snmpOutGetNexts */
3947       case 27: /* snmpOutSetRequests */
3948       case 28: /* snmpOutGetResponses */
3949       case 29: /* snmpOutTraps */
3950         od->instance = MIB_OBJECT_SCALAR;
3951         od->access = MIB_OBJECT_READ_ONLY;
3952         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
3953         od->v_len = sizeof(u32_t);
3954         break;
3955       case 30: /* snmpEnableAuthenTraps */
3956         od->instance = MIB_OBJECT_SCALAR;
3957         od->access = MIB_OBJECT_READ_WRITE;
3958         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
3959         od->v_len = sizeof(s32_t);
3960         break;
3961       default:
3962         LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no such object\n"));
3963         od->instance = MIB_OBJECT_NONE;
3964         break;
3965     };
3966   }
3967   else
3968   {
3969     LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no scalar\n"));
3970     od->instance = MIB_OBJECT_NONE;
3971   }
3972 }
3973
3974 static void
3975 snmp_get_value(struct obj_def *od, u16_t len, void *value)
3976 {
3977   u32_t *uint_ptr = value;
3978   u8_t id;
3979
3980   if (len){}
3981   id = od->id_inst_ptr[0];
3982   switch (id)
3983   {
3984       case 1: /* snmpInPkts */
3985         *uint_ptr = snmpinpkts;
3986         break;
3987       case 2: /* snmpOutPkts */
3988         *uint_ptr = snmpoutpkts;
3989         break;
3990       case 3: /* snmpInBadVersions */
3991         *uint_ptr = snmpinbadversions;
3992         break;
3993       case 4: /* snmpInBadCommunityNames */
3994         *uint_ptr = snmpinbadcommunitynames;
3995         break;
3996       case 5: /* snmpInBadCommunityUses */
3997         *uint_ptr = snmpinbadcommunityuses;
3998         break;
3999       case 6: /* snmpInASNParseErrs */
4000         *uint_ptr = snmpinasnparseerrs;
4001         break;
4002       case 8: /* snmpInTooBigs */
4003         *uint_ptr = snmpintoobigs;
4004         break;
4005       case 9: /* snmpInNoSuchNames */
4006         *uint_ptr = snmpinnosuchnames;
4007         break;
4008       case 10: /* snmpInBadValues */
4009         *uint_ptr = snmpinbadvalues;
4010         break;
4011       case 11: /* snmpInReadOnlys */
4012         *uint_ptr = snmpinreadonlys;
4013         break;
4014       case 12: /* snmpInGenErrs */
4015         *uint_ptr = snmpingenerrs;
4016         break;
4017       case 13: /* snmpInTotalReqVars */
4018         *uint_ptr = snmpintotalreqvars;
4019         break;
4020       case 14: /* snmpInTotalSetVars */
4021         *uint_ptr = snmpintotalsetvars;
4022         break;
4023       case 15: /* snmpInGetRequests */
4024         *uint_ptr = snmpingetrequests;
4025         break;
4026       case 16: /* snmpInGetNexts */
4027         *uint_ptr = snmpingetnexts;
4028         break;
4029       case 17: /* snmpInSetRequests */
4030         *uint_ptr = snmpinsetrequests;
4031         break;
4032       case 18: /* snmpInGetResponses */
4033         *uint_ptr = snmpingetresponses;
4034         break;
4035       case 19: /* snmpInTraps */
4036         *uint_ptr = snmpintraps;
4037         break;
4038       case 20: /* snmpOutTooBigs */
4039         *uint_ptr = snmpouttoobigs;
4040         break;
4041       case 21: /* snmpOutNoSuchNames */
4042         *uint_ptr = snmpoutnosuchnames;
4043         break;
4044       case 22: /* snmpOutBadValues */
4045         *uint_ptr = snmpoutbadvalues;
4046         break;
4047       case 24: /* snmpOutGenErrs */
4048         *uint_ptr = snmpoutgenerrs;
4049         break;
4050       case 25: /* snmpOutGetRequests */
4051         *uint_ptr = snmpoutgetrequests;
4052         break;
4053       case 26: /* snmpOutGetNexts */
4054         *uint_ptr = snmpoutgetnexts;
4055         break;
4056       case 27: /* snmpOutSetRequests */
4057         *uint_ptr = snmpoutsetrequests;
4058         break;
4059       case 28: /* snmpOutGetResponses */
4060         *uint_ptr = snmpoutgetresponses;
4061         break;
4062       case 29: /* snmpOutTraps */
4063         *uint_ptr = snmpouttraps;
4064         break;
4065       case 30: /* snmpEnableAuthenTraps */
4066         *uint_ptr = *snmpenableauthentraps_ptr;
4067         break;
4068   };
4069 }
4070
4071 /**
4072  * Test snmp object value before setting.
4073  *
4074  * @param od is the object definition
4075  * @param len return value space (in bytes)
4076  * @param value points to (varbind) space to copy value from.
4077  */
4078 static u8_t
4079 snmp_set_test(struct obj_def *od, u16_t len, void *value)
4080 {
4081   u8_t id, set_ok;
4082
4083   if (len) {}
4084   set_ok = 0;
4085   id = od->id_inst_ptr[0];
4086   if (id == 30)
4087   {
4088     /* snmpEnableAuthenTraps */
4089     s32_t *sint_ptr = value;
4090
4091     if (snmpenableauthentraps_ptr != &snmpenableauthentraps_default)
4092     {
4093       /* we should have writable non-volatile mem here */
4094       if ((*sint_ptr == 1) || (*sint_ptr == 2))
4095       {
4096         set_ok = 1;
4097       }
4098     }
4099     else
4100     {
4101       /* const or hardwired value */
4102       if (*sint_ptr == snmpenableauthentraps_default)
4103       {
4104         set_ok = 1;
4105       }
4106     }
4107   }
4108   return set_ok;
4109 }
4110
4111 static void
4112 snmp_set_value(struct obj_def *od, u16_t len, void *value)
4113 {
4114   u8_t id;
4115
4116   if (len) {}
4117   id = od->id_inst_ptr[0];
4118   if (id == 30)
4119   {
4120     /* snmpEnableAuthenTraps */
4121     s32_t *sint_ptr = value;
4122     *snmpenableauthentraps_ptr = *sint_ptr;
4123   }
4124 }
4125
4126 #endif /* LWIP_SNMP */