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