]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lwip.git/commitdiff
MIB-2 object values near to completion, just committing for keeping the flame alive.
authorchristiaans <christiaans>
Fri, 11 Aug 2006 14:16:36 +0000 (14:16 +0000)
committerchristiaans <christiaans>
Fri, 11 Aug 2006 14:16:36 +0000 (14:16 +0000)
doc/snmp_agent.txt
src/core/snmp/mib2.c
src/core/snmp/mib_structs.c
src/core/snmp/msg_in.c
src/include/lwip/snmp.h
src/include/lwip/snmp_msg.h
src/include/lwip/snmp_structs.h

index 4e3a745e3414818a5722d5deab61561914f02c60..b08c26ee5825724d5f9f8657ba3c51ec9d3f10a0 100644 (file)
@@ -50,6 +50,20 @@ Running the agent
 The following function calls must be made in your program to
 actually get the SNMP agent running.
 
+Before starting the agent you should supply pointers
+to non-volatile memory for sysContact, sysLocation,
+and snmpEnableAuthenTraps. You can do this by calling
+
+snmp_set_syscontact()
+snmp_set_syslocation()
+snmp_set_snmpenableauthentraps()
+
+Additionally you may want to set
+
+snmp_set_sysdescr()
+snmp_set_sysobjid() (if you have a private MIB)
+snmp_set_sysname()
+
 In the lwIP initialisation sequence call snmp_init() just after
 the call to udp_init().
 
@@ -57,14 +71,6 @@ Exactly every 10 msec the SNMP uptime timestamp must be updated with
 snmp_inc_sysuptime(). You should call this from a timer interrupt
 or a timer signal handler depending on your runtime environment.
 
-You _must_ create the following support functions for non-volatile storage
-since lwIP does not have notion of files or other non-volatile memories.
-
-void snmp_store_syscontact(u8_t* ocstr, u8_t ocstrlen);
-void snmp_store_sysname(u8_t* ocstr, u8_t ocstrlen);
-void snmp_store_syslocation(u8_t* ocstr, u8_t ocstrlen);
-
-
 
 Private MIBs
 ============
index 6037588e58dce9dbe0dd6b5ce9599946b74c5fd6..854eb504c43f10484e6c409e5ac7be782371773a 100644 (file)
 #include "lwip/opt.h"
 #include "lwip/snmp.h"
 #include "lwip/netif.h"
+#include "netif/etharp.h"
+#include "lwip/ip.h"
+#include "lwip/ip_frag.h"
+#include "lwip/udp.h"
 #include "lwip/snmp_asn1.h"
 #include "lwip/snmp_structs.h"
 
 #define SNMP_SYSSERVICES ((1 << 6) | (1 << 3) | ((IP_FORWARD) << 2))
 #endif
 
-/** @todo publish this in snmp.h (for use in private mib) */
+/** @todo export this in snmp_structs.h (for use in private mib) */
 void noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
-void noleafs_get_value(u8_t ident_len, s32_t *ident, u16_t len, void *value);
+void noleafs_get_value(struct obj_def *od, u16_t len, void *value);
 
 static void system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
-static void system_get_value(u8_t ident_len, s32_t *ident, u16_t len, void *value);
+static void system_get_value(struct obj_def *od, u16_t len, void *value);
 static void interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
-static void interfaces_get_value(u8_t ident_len, s32_t *ident, u16_t len, void *value);
+static void interfaces_get_value(struct obj_def *od, u16_t len, void *value);
 static void ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
-static void ifentry_get_value(u8_t ident_len, s32_t *ident, u16_t len, void *value);
+static void ifentry_get_value(struct obj_def *od, u16_t len, void *value);
+static void atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void atentry_get_value(struct obj_def *od, u16_t len, void *value);
+static void ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void ip_get_value(struct obj_def *od, u16_t len, void *value);
+static void ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void ip_addrentry_get_value(struct obj_def *od, u16_t len, void *value);
+static void ip_rteentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value);
+static void ip_ntomentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value);
+static void icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void icmp_get_value(struct obj_def *od, u16_t len, void *value);
+#if LWIP_TCP
+static void tcp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void tcp_get_value(struct obj_def *od, u16_t len, void *value);
+static void tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void tcpconnentry_get_value(struct obj_def *od, u16_t len, void *value);
+#endif
+static void udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void udp_get_value(struct obj_def *od, u16_t len, void *value);
+static void udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void udpentry_get_value(struct obj_def *od, u16_t len, void *value);
+static void snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od);
+static void snmp_get_value(struct obj_def *od, u16_t len, void *value);
 
 /* snmp .1.3.6.1.2.1.11 */
-const s32_t snmp_ids[29] = {
-  1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
-  16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30
+const s32_t snmp_ids[28] = {
+  1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+  17, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30
 };
-struct mib_node* const snmp_nodes[29] = {
-  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+struct mib_node* const snmp_nodes[28] = {
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
 const struct mib_array_node snmp = {
-  &noleafs_get_object_def,
-  &noleafs_get_value,
+  &snmp_get_object_def,
+  &snmp_get_value,
   MIB_NODE_AR,
-  29,
+  28,
   snmp_ids,
   snmp_nodes 
 };
@@ -96,13 +124,37 @@ const struct mib_array_node snmp = {
 /* lwIP has no EGP, thus may not implement it. (egp .1.3.6.1.2.1.8) */
 
 /* udp .1.3.6.1.2.1.7 */
+const s32_t udpentry_ids[2] = { 1, 2 };
+struct mib_node* const udpentry_nodes[2] = {
+  NULL, NULL,
+};
+const struct mib_array_node udpentry = {
+  &udpentry_get_object_def,
+  &udpentry_get_value,
+  MIB_NODE_AR,
+  2,
+  udpentry_ids,
+  udpentry_nodes
+};
+
+const s32_t udptable_id = 1;
+struct mib_node* const udptable_node = (struct mib_node* const)&udpentry;
+const struct mib_array_node udptable = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  MIB_NODE_AR,
+  1,
+  &udptable_id,
+  &udptable_node
+};
+
 const s32_t udp_ids[5] = { 1, 2, 3, 4, 5 };
 struct mib_node* const udp_nodes[5] = {
-  NULL, NULL, NULL, NULL, /** @todo udpTable */ NULL
+  NULL, NULL, NULL, NULL, (struct mib_node* const)&udptable
 };
 const struct mib_array_node udp = {
-  &noleafs_get_object_def,
-  &noleafs_get_value,
+  &udp_get_object_def,
+  &udp_get_value,
   MIB_NODE_AR,
   5,
   udp_ids,
@@ -110,19 +162,46 @@ const struct mib_array_node udp = {
 };
 
 /* tcp .1.3.6.1.2.1.6 */
+#if LWIP_TCP
+/* only if the TCP protocol is available may implement this group */
+const s32_t tcpconnentry_ids[5] = { 1, 2, 3, 4, 5 };
+struct mib_node* const tcpconnentry_nodes[5] = {
+  NULL, NULL, NULL, NULL, NULL
+};
+const struct mib_array_node tcpconnentry = {
+  &tcpconnentry_get_object_def,
+  &tcpconnentry_get_value,
+  MIB_NODE_AR,
+  5,
+  tcpconnentry_ids,
+  tcpconnentry_nodes
+};
+
+const s32_t tcpconntable_id = 1;
+struct mib_node* const tcpconntable_node = (struct mib_node* const)&tcpconnentry;
+const struct mib_array_node tcpconntable = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  MIB_NODE_AR,
+  1,
+  &tcpconntable_id,
+  &tcpconntable_node
+};
+
 const s32_t tcp_ids[15] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
 struct mib_node* const tcp_nodes[15] = {
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-  /** @todo tcpConnTable */ NULL, NULL, NULL
+  (struct mib_node* const)&tcpconntable, NULL, NULL
 };
 const struct mib_array_node tcp = {
-  &noleafs_get_object_def,
-  &noleafs_get_value,
+  &tcp_get_object_def,
+  &tcp_get_value,
   MIB_NODE_AR,
   15,
   tcp_ids,
   tcp_nodes
 };
+#endif
 
 /* icmp .1.3.6.1.2.1.5 */
 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 };
@@ -131,39 +210,137 @@ struct mib_node* const icmp_nodes[26] = {
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
 const struct mib_array_node icmp = {
-  &noleafs_get_object_def,
-  &noleafs_get_value,
+  &icmp_get_object_def,
+  &icmp_get_value,
   MIB_NODE_AR,
   26,
   icmp_ids,
   icmp_nodes
 };
 
+const s32_t ipntomentry_ids[4] = { 1, 2, 3, 4 };
+struct mib_node* const ipntomentry_nodes[4] = {
+  NULL, NULL, NULL, NULL
+};
+const struct mib_array_node ipntomentry = {
+  &ip_ntomentry_get_object_def,
+  &ip_ntomentry_get_value,
+  MIB_NODE_AR,
+  4,
+  ipntomentry_ids,
+  ipntomentry_nodes
+};
+
+const s32_t ipntomtable_id = 1;
+struct mib_node* const ipntomtable_node = (struct mib_node* const)&ipntomentry;
+const struct mib_array_node ipntomtable = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  MIB_NODE_AR,
+  1,
+  &ipntomtable_id,
+  &ipntomtable_node
+};
+
+const s32_t iprteentry_ids[13] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
+struct mib_node* const iprteentry_nodes[13] = {
+  NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+  NULL, NULL, NULL, NULL, NULL, NULL
+};
+const struct mib_array_node iprteentry = {
+  &ip_rteentry_get_object_def,
+  &ip_rteentry_get_value,
+  MIB_NODE_AR,
+  13,
+  iprteentry_ids,
+  iprteentry_nodes
+};
+
+const s32_t iprtetable_id = 1;
+struct mib_node* const iprtetable_node = (struct mib_node* const)&iprteentry;
+const struct mib_array_node iprtetable = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  MIB_NODE_AR,
+  1,
+  &iprtetable_id,
+  &iprtetable_node
+};
+
+const s32_t ipaddrentry_ids[5] = { 1, 2, 3, 4, 5 };
+struct mib_node* const ipaddrentry_nodes[5] = {
+  NULL, NULL, NULL, NULL, NULL
+};
+const struct mib_array_node ipaddrentry = {
+  &ip_addrentry_get_object_def,
+  &ip_addrentry_get_value,
+  MIB_NODE_AR,
+  5,
+  ipaddrentry_ids,
+  ipaddrentry_nodes
+};
+
+const s32_t ipaddrtable_id = 1;
+struct mib_node* const ipaddrtable_node = (struct mib_node* const)&ipaddrentry;
+const struct mib_array_node ipaddrtable = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  MIB_NODE_AR,
+  1,
+  &ipaddrtable_id,
+  &ipaddrtable_node
+};
+
 /* ip .1.3.6.1.2.1.4 */
 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 };
 struct mib_node* const ip_nodes[23] = {
   NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-  NULL, NULL, NULL, NULL, NULL, NULL, NULL, /** @todo ipAddrTable */ NULL, /** @todo ipRouteTable */ NULL, /** @todo ipNetToMediaTable */ NULL, NULL
+  NULL, NULL, NULL, NULL, NULL, NULL, NULL, (struct mib_node* const)&ipaddrtable,
+  (struct mib_node* const)&iprtetable, (struct mib_node* const)&ipntomtable, NULL
 };
 const struct mib_array_node ip = {
-  &noleafs_get_object_def,
-  &noleafs_get_value,
+  &ip_get_object_def,
+  &ip_get_value,
   MIB_NODE_AR,
   23,
   ip_ids,
   ip_nodes
 };
 
+const s32_t atentry_ids[3] = { 1, 2, 3 };
+struct mib_node* const atentry_nodes[3] = {
+  NULL, NULL, NULL
+};
+const struct mib_array_node atentry = {
+  &atentry_get_object_def,
+  &atentry_get_value,
+  MIB_NODE_AR,
+  3,
+  atentry_ids,
+  atentry_nodes
+};
+
+const s32_t attable_id = 1;
+struct mib_node* const attable_node = (struct mib_node* const)&atentry;
+const struct mib_array_node attable = {
+  &noleafs_get_object_def,
+  &noleafs_get_value,
+  MIB_NODE_AR,
+  1,
+  &attable_id,
+  &attable_node
+};
+
 /* at .1.3.6.1.2.1.3 */
-const s32_t at_ids[1] = { 1 };
-struct mib_node* const at_nodes[1] = { /** @todo atTable*/ NULL };
+const s32_t at_id = 1;
+struct mib_node* const at_node = (struct mib_node* const)&attable;
 const struct mib_array_node at = {
   &noleafs_get_object_def,
   &noleafs_get_value,
   MIB_NODE_AR,
   1,
-  at_ids,
-  at_nodes
+  &at_id,
+  &at_node
 };
 
 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 };
@@ -218,22 +395,42 @@ const struct mib_array_node sys_tem = {
 };
 
 /* mib-2 .1.3.6.1.2.1 */
-const s32_t mib2_ids[8] = { 1, 2, 3, 4, 5, 6, 7, 11 };
-struct mib_node* const mib2_nodes[8] = {
+#if LWIP_TCP
+#define MIB2_GROUPS 8
+#else
+#define MIB2_GROUPS 7
+#endif
+const s32_t mib2_ids[MIB2_GROUPS] =
+{ 
+  1,
+  2,
+  3,
+  4,
+  5,
+#if LWIP_TCP
+  6,
+#endif
+  7,
+  11
+};
+struct mib_node* const mib2_nodes[MIB2_GROUPS] = {
   (struct mib_node* const)&sys_tem,
   (struct mib_node* const)&interfaces,
   (struct mib_node* const)&at,
   (struct mib_node* const)&ip,
   (struct mib_node* const)&icmp,
+#if LWIP_TCP
   (struct mib_node* const)&tcp,
+#endif
   (struct mib_node* const)&udp,
   (struct mib_node* const)&snmp
 };
+
 const struct mib_array_node mib2 = {
   &noleafs_get_object_def,
   &noleafs_get_value,
   MIB_NODE_AR,
-  8,
+  MIB2_GROUPS,
   mib2_ids,
   mib2_nodes
 };
@@ -275,35 +472,64 @@ const struct mib_array_node internet = {
 };
 #endif
 
-/** .iso.org.dod.internet.mgmt.mib-2.sysObjectID  */
+/** mib-2.system.sysObjectID  */
 static struct snmp_obj_id sysobjid = {SNMP_SYSOBJID_LEN, SNMP_SYSOBJID};
 /** enterprise ID for generic TRAPs, .iso.org.dod.internet.mgmt.mib-2.snmp */
 static struct snmp_obj_id snmpgrp_id = {7,{1,3,6,1,2,1,11}};
-/** .iso.org.dod.internet.mgmt.mib-2.sysServices */
+/** mib-2.system.sysServices */
 static const s32_t sysservices = SNMP_SYSSERVICES;
 
-/** .iso.org.dod.internet.mgmt.mib-2.sysDescr */
-static u8_t sysdescr_len = 4;
-static u8_t sysdescr[255] = "lwIP";
-static u8_t syscontact_len = 0;
-static u8_t syscontact[255];
-static u8_t sysname_len = 0;
-static u8_t sysname[255];
-static u8_t syslocation_len = 0;
-static u8_t syslocation[255];
-/** .iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifSpecific (zeroDotZero) */
+/** mib-2.system.sysDescr */
+static const u8_t sysdescr_len_default = 4;
+static const u8_t sysdescr_default[] = "lwIP";
+static u8_t* sysdescr_len_ptr = (u8_t*)&sysdescr_len_default;
+static u8_t* sysdescr_ptr = (u8_t*)&sysdescr_default[0];
+/** mib-2.system.sysContact */
+static const u8_t syscontact_len_default = 0;
+static const u8_t syscontact_default[] = "";
+static u8_t* syscontact_len_ptr = (u8_t*)&syscontact_len_default;
+static u8_t* syscontact_ptr = (u8_t*)&syscontact_default[0];
+/** mib-2.system.sysName */
+static const u8_t sysname_len_default = 8;
+static const u8_t sysname_default[] = "FQDN-unk";
+static u8_t* sysname_len_ptr = (u8_t*)&sysname_len_default;
+static u8_t* sysname_ptr = (u8_t*)&sysname_default[0];
+/** mib-2.system.sysLocation */
+static const u8_t syslocation_len_default = 0;
+static const u8_t syslocation_default[] = "";
+static u8_t* syslocation_len_ptr = (u8_t*)&syslocation_len_default;
+static u8_t* syslocation_ptr = (u8_t*)&syslocation_default[0];
+/** mib-2.snmp.snmpEnableAuthenTraps */
+static const u8_t snmpenableauthentraps_default = 2; /* disabled */
+static u8_t* snmpenableauthentraps_ptr = (u8_t*)&snmpenableauthentraps_default;
+
+/** mib-2.interfaces.ifTable.ifEntry.ifSpecific (zeroDotZero) */
 static const struct snmp_obj_id ifspecific = {2, {0, 0}};
+/** mib-2.ip.ipRouteTable.ipRouteEntry.ipRouteInfo (zeroDotZero) */
+static const struct snmp_obj_id iprouteinfo = {2, {0, 0}};
+/** mib-2.snmp.snmpEnableAuthenTraps 1 = enabled 2 = disabled */
 
 /* mib-2.system counter(s) */
 static u32_t sysuptime = 0;
 
 /* mib-2.ip counter(s) */
-static u32_t ipindelivers = 0,
-             ipinreceives = 0,
+static u32_t ipinreceives = 0,
+             ipinhdrerrors = 0,
+             ipinaddrerrors = 0,
+             ipforwdatagrams = 0,
+             ipinunknownprotos = 0,
              ipindiscards = 0,
-             ipoutdiscards = 0,
+             ipindelivers = 0,
              ipoutrequests = 0,
-             ipunknownprotos = 0;
+             ipoutdiscards = 0,
+             ipoutnoroutes = 0,
+             ipreasmreqds = 0,
+             ipreasmoks = 0,
+             ipreasmfails = 0,
+             ipfragoks = 0,
+             ipfragfails = 0,
+             ipfragcreates = 0,
+             iproutingdiscards = 0;
 /* mib-2.icmp counter(s) */
 static u32_t icmpinmsgs = 0,
              icmpinerrors = 0,
@@ -412,17 +638,17 @@ void objectidncpy(s32_t *dst, s32_t *src, u8_t n)
 }
 
 /**
- * Initializes sysDescr value.
+ * Initializes sysDescr pointers.
  *
- * @param str if non-NULL then copy str
- * @param strlen string length, excluding zero terminator
+ * @param str if non-NULL then copy str pointer
+ * @param strlen points to string length, excluding zero terminator
  */
-void snmp_set_sysdesr(u8_t* str, u8_t strlen)
+void snmp_set_sysdesr(u8_t *str, u8_t *strlen)
 {
   if (str != NULL)
   {
-    strlen = ((strlen < sizeof(sysdescr))?(strlen):(sizeof(sysdescr)));
-    ocstrncpy(sysdescr, str, strlen);
+    sysdescr_ptr = str;
+    sysdescr_len_ptr = strlen;
   }
 }
 
@@ -456,47 +682,50 @@ void snmp_get_sysuptime(u32_t *value)
 }
 
 /**
- * Initializes sysContact value (from lwIP external non-volatile memory).
+ * Initializes sysContact pointers,
+ * e.g. ptrs to non-volatile memory external to lwIP.
  *
- * @param str if non-NULL then copy str
- * @param strlen string length, excluding zero terminator
+ * @param str if non-NULL then copy str pointer
+ * @param strlen points to string length, excluding zero terminator
  */
-void snmp_set_syscontact(u8_t *ocstr, u8_t ocstrlen)
+void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen)
 {
   if (ocstr != NULL)
   {
-    ocstrlen = ((ocstrlen < sizeof(syscontact))?(ocstrlen):(sizeof(syscontact)));
-    ocstrncpy(syscontact, ocstr, ocstrlen);
+    syscontact_ptr = ocstr;
+    syscontact_len_ptr = ocstrlen;
   }
 }
 
 /**
- * Initializes sysName value (from lwIP external non-volatile memory).
+ * Initializes sysName pointers,
+ * e.g. ptrs to non-volatile memory external to lwIP.
  *
- * @param str if non-NULL then copy str
- * @param strlen string length, excluding zero terminator
+ * @param str if non-NULL then copy str pointer
+ * @param strlen points to string length, excluding zero terminator
  */
-void snmp_set_sysname(u8_t *ocstr, u8_t ocstrlen)
+void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen)
 {
   if (ocstr != NULL)
   {
-    ocstrlen = ((ocstrlen < sizeof(sysname))?(ocstrlen):(sizeof(sysname)));
-    ocstrncpy(sysname, ocstr, ocstrlen);
+    sysname_ptr = ocstr;
+    sysname_len_ptr = ocstrlen;
   }
 }
 
 /**
- * Initializes sysLocation value (from lwIP external non-volatile memory).
+ * Initializes sysLocation pointers,
+ * e.g. ptrs to non-volatile memory external to lwIP.
  *
- * @param str if non-NULL then copy str
- * @param strlen string length, excluding zero terminator
+ * @param str if non-NULL then copy str pointer
+ * @param strlen points to string length, excluding zero terminator
  */
-void snmp_set_syslocation(u8_t *ocstr, u8_t ocstrlen)
+void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen)
 {
   if (ocstr != NULL)
   {
-    ocstrlen = ((ocstrlen < sizeof(syslocation))?(ocstrlen):(sizeof(syslocation)));
-    ocstrncpy(syslocation, ocstr, ocstrlen);
+    syslocation_ptr = ocstr;
+    syslocation_len_ptr = ocstrlen;
   }
 }
 
@@ -541,14 +770,29 @@ void snmp_inc_ifoutdiscards(struct netif *ni)
   (ni->ifoutdiscards)++;
 }
 
-void snmp_inc_ipindelivers(void)
+void snmp_inc_ipinreceives(void)
 {
-  ipindelivers++;
+  ipinreceives++;
 }
 
-void snmp_inc_ipinreceives(void)
+void snmp_inc_ipinhdrerrors(void)
 {
-  ipinreceives++;
+  ipinhdrerrors++;
+}
+
+void snmp_inc_ipinaddrerrors(void)
+{
+  ipinaddrerrors++;
+}
+
+void snmp_inc_ipforwdatagrams(void)
+{
+  ipforwdatagrams++;
+}
+
+void snmp_inc_ipinunknownprotos(void)
+{
+  ipinunknownprotos++;
 }
 
 void snmp_inc_ipindiscards(void)
@@ -556,9 +800,9 @@ void snmp_inc_ipindiscards(void)
   ipindiscards++;
 }
 
-void snmp_inc_ipoutdiscards(void)
+void snmp_inc_ipindelivers(void)
 {
-  ipoutdiscards++;
+  ipindelivers++;
 }
 
 void snmp_inc_ipoutrequests(void)
@@ -566,9 +810,49 @@ void snmp_inc_ipoutrequests(void)
   ipoutrequests++;
 }
 
-void snmp_inc_ipunknownprotos(void)
+void snmp_inc_ipoutdiscards(void)
+{
+  ipoutdiscards++;
+}
+
+void snmp_inc_ipoutnoroutes(void)
+{
+  ipoutnoroutes++;
+}
+
+void snmp_inc_ipreasmreqds(void)
+{
+  ipreasmreqds++;
+}
+
+void snmp_inc_ipreasmoks(void)
+{
+  ipreasmoks++;
+}
+
+void snmp_inc_ipreasmfails(void)
+{
+  ipreasmfails++;
+}
+
+void snmp_inc_ipfragoks(void)
+{
+  ipfragoks++;
+}
+
+void snmp_inc_ipfragfails(void)
+{
+  ipfragfails++;
+}
+
+void snmp_inc_ipfragcreates(void)
+{
+  ipfragcreates++;
+}
+
+void snmp_inc_iproutingdiscards(void)
 {
-  ipunknownprotos++;
+  iproutingdiscards++;
 }
 
 
@@ -912,22 +1196,28 @@ void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid)
   *oid = &snmpgrp_id;
 }
 
+void snmp_set_snmpenableauthentraps(u8_t *value)
+{
+  if (value != NULL)
+  {
+    snmpenableauthentraps_ptr = value;
+  }
+}
 
 void
 noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
 {
-  if(ident_len){}
-  if(ident){}
+  if (ident_len){}
+  if (ident){}
   od->instance = MIB_OBJECT_NONE;
 }
 
 void                                                  
-noleafs_get_value(u8_t ident_len, s32_t *ident, u16_t len, void *value)
+noleafs_get_value(struct obj_def *od, u16_t len, void *value)
 {
-  if(ident_len){}
-  if(ident){}
-  if(len){}
-  if(value){}
+  if (od){}
+  if (len){}
+  if (value){}
 }
 
 
@@ -958,7 +1248,7 @@ system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
         od->instance = MIB_OBJECT_SCALAR;
         od->access = MIB_OBJECT_READ_ONLY;
         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
-        od->v_len = sysdescr_len;
+        od->v_len = *sysdescr_len_ptr;
         break;
       case 2: /* sysObjectID */
         od->instance = MIB_OBJECT_SCALAR;
@@ -976,19 +1266,19 @@ system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
         od->instance = MIB_OBJECT_SCALAR;
         od->access = MIB_OBJECT_READ_WRITE;
         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
-        od->v_len = syscontact_len;
+        od->v_len = *syscontact_len_ptr;
         break;
       case 5: /* sysName */
         od->instance = MIB_OBJECT_SCALAR;
         od->access = MIB_OBJECT_READ_WRITE;
         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
-        od->v_len = sysname_len;
+        od->v_len = *sysname_len_ptr;
         break;
       case 6: /* sysLocation */
         od->instance = MIB_OBJECT_SCALAR;
         od->access = MIB_OBJECT_READ_WRITE;
         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
-        od->v_len = syslocation_len;
+        od->v_len = *syslocation_len_ptr;
         break;
       case 7: /* sysServices */
         od->instance = MIB_OBJECT_SCALAR;
@@ -997,6 +1287,7 @@ system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
         od->v_len = sizeof(s32_t);
         break;
       default:
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_object_def: no such object"));
         od->instance = MIB_OBJECT_NONE;
         break;
     };
@@ -1017,48 +1308,41 @@ system_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
  * @param value points to (varbind) space to copy value into.
  */
 static void                                                  
-system_get_value(u8_t ident_len, s32_t *ident, u16_t len, void *value)
+system_get_value(struct obj_def *od, u16_t len, void *value)
 {
   u8_t id;
 
-  id = ident[0];
+  id = od->id_inst_ptr[0];
   switch (id)
   {
     case 1: /* sysDescr */
-      ocstrncpy(value,sysdescr,len);
+      ocstrncpy(value,sysdescr_ptr,len);
       break;
     case 2: /* sysObjectID */
       objectidncpy((s32_t*)value,(s32_t*)sysobjid.id,len / sizeof(s32_t));
       break;
     case 3: /* sysUpTime */
-      if (len == sizeof(u32_t))
       {
         u32_t *uint_ptr = value;
-
         *uint_ptr = sysuptime;
       }
       break;
     case 4: /* sysContact */
-      ocstrncpy(value,syscontact,len);
+      ocstrncpy(value,syscontact_ptr,len);
       break;
     case 5: /* sysName */
-      ocstrncpy(value,sysname,len);
+      ocstrncpy(value,sysname_ptr,len);
       break;
     case 6: /* sysLocation */
-      ocstrncpy(value,syslocation,len);
+      ocstrncpy(value,syslocation_ptr,len);
       break;
     case 7: /* sysServices */
-      if (len == sizeof(s32_t))
       {
         s32_t *sint_ptr = value;
-
         *sint_ptr = sysservices;
       }
       break;
-    default:
-      break;
   };
-  if (ident_len){}
 }
 
 /**
@@ -1086,7 +1370,6 @@ interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
     LWIP_DEBUGF(SNMP_MIB_DEBUG,("interfaces_get_object_def: no scalar"));
     od->instance = MIB_OBJECT_NONE;
   }
-  if (ident_len){}
 }
 
 /**
@@ -1098,17 +1381,14 @@ interfaces_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
  * @param value points to (varbind) space to copy value into.
  */
 static void                                                  
-interfaces_get_value(u8_t ident_len, s32_t *ident, u16_t len, void *value)
+interfaces_get_value(struct obj_def *od, u16_t len, void *value)
 {
-  if (ident[0] == 1)
+  if (len){}
+  if (od->id_inst_ptr[0] == 1)
   {
-    if (len == sizeof(s32_t))
-    {
-      s32_t *sint_ptr = value;
-      *sint_ptr = netif_cnt;
-    }
+    s32_t *sint_ptr = value;
+    *sint_ptr = netif_cnt;
   }
-  if (ident_len){}
 }
 
 /**
@@ -1147,12 +1427,14 @@ ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
         break;
       case 3: /* ifType */
       case 4: /* ifMtu */
+      case 8: /* ifOperStatus */
         od->instance = MIB_OBJECT_TAB;
         od->access = MIB_OBJECT_READ_ONLY;
         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
         od->v_len = sizeof(s32_t);
         break;
       case 5: /* ifSpeed */
+      case 21: /* ifOutQLen */
         od->instance = MIB_OBJECT_TAB;
         od->access = MIB_OBJECT_READ_ONLY;
         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE);
@@ -1182,12 +1464,6 @@ ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
         od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
         od->v_len = sizeof(s32_t);
         break;
-      case 8: /* ifOperStatus */
-        od->instance = MIB_OBJECT_TAB;
-        od->access = MIB_OBJECT_READ_ONLY;
-        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
-        od->v_len = sizeof(s32_t);
-        break;
       case 9: /* ifLastChange */
         od->instance = MIB_OBJECT_TAB;
         od->access = MIB_OBJECT_READ_ONLY;
@@ -1210,12 +1486,6 @@ ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
         od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
         od->v_len = sizeof(u32_t);
         break;
-      case 21: /* ifOutQLen */
-        od->instance = MIB_OBJECT_TAB;
-        od->access = MIB_OBJECT_READ_ONLY;
-        od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_GAUGE);
-        od->v_len = sizeof(u32_t);
-        break;
       case 22: /* ifSpecific */
         /** @note returning zeroDotZero (0.0) no media specific MIB support */
         od->instance = MIB_OBJECT_TAB;
@@ -1224,6 +1494,7 @@ ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
         od->v_len = ifspecific.len * sizeof(s32_t);
         break;
       default:
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("ifentry_get_object_def: no such object"));
         od->instance = MIB_OBJECT_NONE;
         break;
     };
@@ -1244,48 +1515,44 @@ ifentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
  * @param value points to (varbind) space to copy value into.
  */
 static void                                                  
-ifentry_get_value(u8_t ident_len, s32_t *ident, u16_t len, void *value)
+ifentry_get_value(struct obj_def *od, u16_t len, void *value)
 {
   struct netif *netif = netif_list;
   u16_t i, ifidx;
   u8_t id;
 
-  ifidx = ident[1] - 1;
+  ifidx = od->id_inst_ptr[1] - 1;
   i = 0;
   while ((netif != NULL) && (i < ifidx))
   {
     netif = netif->next;
     i++;
   }
-  id = ident[0];
+  id = od->id_inst_ptr[0];
   switch (id)
   {
     case 1: /* ifIndex */
-      if (len == sizeof(s32_t))
       {
         s32_t *sint_ptr = value;
-        *sint_ptr = ident[1];
+        *sint_ptr = od->id_inst_ptr[1];
       }
       break;
     case 2: /* ifDescr */
       ocstrncpy(value,(u8_t*)netif->name,len);
       break;
     case 3: /* ifType */
-      if (len == sizeof(s32_t))
       {
         s32_t *sint_ptr = value;
         *sint_ptr = netif->link_type;
       }
       break;
     case 4: /* ifMtu */
-      if (len == sizeof(s32_t))
       {
         s32_t *sint_ptr = value;
         *sint_ptr = netif->mtu;
       }
       break;
     case 5: /* ifSpeed */
-      if (len == sizeof(u32_t))
       {
         u32_t *uint_ptr = value;
         *uint_ptr = netif->link_speed;
@@ -1296,7 +1563,6 @@ ifentry_get_value(u8_t ident_len, s32_t *ident, u16_t len, void *value)
       break;
     case 7: /* ifAdminStatus */
     case 8: /* ifOperStatus */
-      if (len == sizeof(s32_t))
       {
         s32_t *sint_ptr = value;
         if (netif_is_up(netif))
@@ -1310,35 +1576,30 @@ ifentry_get_value(u8_t ident_len, s32_t *ident, u16_t len, void *value)
       }
       break;
     case 9: /* ifLastChange */
-      if (len == sizeof(u32_t))
       {
         u32_t *uint_ptr = value;
         *uint_ptr = netif->ts;
       }
       break;
     case 10: /* ifInOctets */
-      if (len == sizeof(u32_t))
       {
         u32_t *uint_ptr = value;
         *uint_ptr = netif->ifinoctets;
       }
       break;
     case 11: /* ifInUcastPkts */
-      if (len == sizeof(u32_t))
       {
         u32_t *uint_ptr = value;
         *uint_ptr = netif->ifinucastpkts;
       }
       break;
     case 12: /* ifInNUcastPkts */
-      if (len == sizeof(u32_t))
       {
         u32_t *uint_ptr = value;
         *uint_ptr = netif->ifinnucastpkts;
       }
       break;
     case 13: /* ifInDiscarts */
-      if (len == sizeof(u32_t))
       {
         u32_t *uint_ptr = value;
         *uint_ptr = netif->ifindiscards;
@@ -1347,35 +1608,30 @@ ifentry_get_value(u8_t ident_len, s32_t *ident, u16_t len, void *value)
     case 14: /* ifInErrors */
     case 15: /* ifInUnkownProtos */
       /** @todo add these counters! */
-      if (len == sizeof(u32_t))
       {
         u32_t *uint_ptr = value;
         *uint_ptr = 0;
       }
       break;
     case 16: /* ifOutOctets */
-      if (len == sizeof(u32_t))
       {
         u32_t *uint_ptr = value;
         *uint_ptr = netif->ifoutoctets;
       }
       break;
     case 17: /* ifOutUcastPkts */
-      if (len == sizeof(u32_t))
       {
         u32_t *uint_ptr = value;
         *uint_ptr = netif->ifoutucastpkts;
       }
       break;
     case 18: /* ifOutNUcastPkts */
-      if (len == sizeof(u32_t))
       {
         u32_t *uint_ptr = value;
         *uint_ptr = netif->ifoutnucastpkts;
       }
       break;
     case 19: /* ifOutDiscarts */
-      if (len == sizeof(u32_t))
       {
         u32_t *uint_ptr = value;
         *uint_ptr = netif->ifoutdiscards;
@@ -1383,7 +1639,6 @@ ifentry_get_value(u8_t ident_len, s32_t *ident, u16_t len, void *value)
       break;
     case 20: /* ifOutErrors */
        /** @todo add this counter! */
-      if (len == sizeof(u32_t))
       {
         u32_t *uint_ptr = value;
         *uint_ptr = 0;
@@ -1391,7 +1646,6 @@ ifentry_get_value(u8_t ident_len, s32_t *ident, u16_t len, void *value)
       break;
     case 21: /* ifOutQLen */
       /** @todo figure out if this must be 0 (no queue) or 1? */
-      if (len == sizeof(u32_t))
       {
         u32_t *uint_ptr = value;
         *uint_ptr = 0;
@@ -1400,10 +1654,1276 @@ ifentry_get_value(u8_t ident_len, s32_t *ident, u16_t len, void *value)
     case 22: /* ifSpecific */
       objectidncpy((s32_t*)value,(s32_t*)ifspecific.id,len / sizeof(s32_t));
       break;
-    default:
-      break;
   };
-  if (ident_len){}
+}
+
+/**
+ * Returns atentry object definitions.
+ *
+ * @param ident_len the address length (6)
+ * @param ident points to objectname.atifindex.atnetaddress
+ * @param od points to object definition.
+ *
+ * @todo std says objects are writeable, can we ignore it?
+ */
+static void
+atentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  if ((ident_len == 6) && 
+      (ident[1] > 0) && (ident[1] <= netif_cnt))
+  {
+    struct eth_addr* ethaddr_ret;
+    struct ip_addr* ipaddr_ret;
+    struct ip_addr ip;
+    struct netif *netif = netif_list;
+    u16_t i, ifidx;
+
+    ifidx = ident[1] - 1;
+    i = 0;
+    while ((netif != NULL) && (i < ifidx))
+    {
+      netif = netif->next;
+      i++;
+    }
+    ip.addr = ident[2];
+    ip.addr <<= 8;
+    ip.addr |= ident[3];
+    ip.addr <<= 8;
+    ip.addr |= ident[4];
+    ip.addr <<= 8;
+    ip.addr |= ident[5];
+    ip.addr = htonl(ip.addr);
+    
+    if (etharp_find_addr(netif, &ip, &ethaddr_ret, &ipaddr_ret) > -1)
+    {
+      od->id_inst_len = ident_len;
+      od->id_inst_ptr = ident;
+
+      switch (ident[0])
+      {
+        case 1: /* atIfIndex */
+          od->instance = MIB_OBJECT_TAB;
+          od->access = MIB_OBJECT_READ_WRITE;
+          od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+          od->v_len = sizeof(s32_t);
+          od->addr = NULL;
+          break;
+        case 2: /* atPhysAddress */
+          od->instance = MIB_OBJECT_TAB;
+          od->access = MIB_OBJECT_READ_WRITE;
+          od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
+          od->v_len = sizeof(struct eth_addr);
+          od->addr = ethaddr_ret;
+          break;
+        case 3: /* atNetAddress */
+          od->instance = MIB_OBJECT_TAB;
+          od->access = MIB_OBJECT_READ_WRITE;
+          od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
+          od->v_len = 4;
+          od->addr = ipaddr_ret;
+          break;
+        default:
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no such object"));
+          od->instance = MIB_OBJECT_NONE;
+          break;
+      }
+    }
+    else
+    {
+      LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no scalar"));
+      od->instance = MIB_OBJECT_NONE;
+    }
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("atentry_get_object_def: no scalar"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+atentry_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  u8_t id;
+
+  if (len) {}
+  id = od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 1: /* atIfIndex */
+      {
+        s32_t *sint_ptr = value;
+        *sint_ptr = od->id_inst_ptr[1];
+      }
+      break;
+    case 2: /* atPhysAddress */
+      {
+        struct eth_addr *dst = value;
+        struct eth_addr *src = od->addr;
+
+        *dst = *src;
+      }
+      break;
+    case 3: /* atNetAddress */
+      {
+        struct ip_addr *dst = value;
+        struct ip_addr *src = od->addr;
+
+        *dst = *src;
+      }
+      break;
+  }
+}
+
+
+static void
+ip_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  u8_t id;
+
+  if ((ident_len == 2) && (ident[1] == 0))
+  { 
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+    
+    id = ident[0];
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("get_object_def ip.%"U16_F".0",(u16_t)id));
+    switch (id)
+    {
+      case 1: /* ipForwarding */
+      case 2: /* ipDefaultTTL */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_WRITE;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      case 3: /* ipInReceives */
+      case 4: /* ipInHdrErrors */
+      case 5: /* ipInAddrErrors */
+      case 6: /* ipForwDatagrams */
+      case 7: /* ipInUnknownProtos */
+      case 8: /* ipInDiscards */
+      case 9: /* ipInDelivers */
+      case 10: /* ipOutRequests */
+      case 11: /* ipOutDiscards */
+      case 12: /* ipOutNoRoutes */
+      case 14: /* ipReasmReqds */
+      case 15: /* ipReasmOKs */
+      case 16: /* ipReasmFails */
+      case 17: /* ipFragOKs */
+      case 18: /* ipFragFails */
+      case 19: /* ipFragCreates */
+      case 23: /* ipRoutingDiscards */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
+        od->v_len = sizeof(u32_t);
+        break;
+      case 13: /* ipReasmTimeout */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      default:
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no such object"));
+        od->instance = MIB_OBJECT_NONE;
+        break;
+    };
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_object_def: no scalar"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+/** @todo ipForwarding is writeable, but we may return badValue,
+          in lwIP this is a compile-time switch
+          we will also return a badvalue for wring a default TTL
+          which differs from our compile time default */
+static void
+ip_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  u8_t id;
+
+  if (len) {}
+  id = od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 1: /* ipForwarding */
+      {
+        s32_t *sint_ptr = value;
+#if IP_FORWARD
+        /* forwarding */
+        *sint_ptr = 1;
+#else
+        /* not-forwarding */
+        *sint_ptr = 2;
+#endif
+      }
+      break;
+    case 2: /* ipDefaultTTL */
+      {
+        s32_t *sint_ptr = value;
+        *sint_ptr = IP_DEFAULT_TTL;
+      }
+      break;
+    case 3: /* ipInReceives */
+      {
+        u32_t *uint_ptr = value;
+        *uint_ptr = ipinreceives;
+      }
+      break;
+    case 4: /* ipInHdrErrors */
+      {
+        u32_t *uint_ptr = value;
+        *uint_ptr = ipinhdrerrors;
+      }
+      break;
+    case 5: /* ipInAddrErrors */
+      {
+        u32_t *uint_ptr = value;
+        *uint_ptr = ipinaddrerrors;
+      }
+      break;
+    case 6: /* ipForwDatagrams */
+      {
+        u32_t *uint_ptr = value;
+        *uint_ptr = ipforwdatagrams;
+      }
+      break;
+    case 7: /* ipInUnknownProtos */
+      {
+        u32_t *uint_ptr = value;
+        *uint_ptr = ipinunknownprotos;
+      }
+      break;
+    case 8: /* ipInDiscards */
+      {
+        u32_t *uint_ptr = value;
+        *uint_ptr = ipindiscards;
+      }
+      break;
+    case 9: /* ipInDelivers */
+      {
+        u32_t *uint_ptr = value;
+        *uint_ptr = ipindelivers;
+      }
+      break;
+    case 10: /* ipOutRequests */
+      {
+        u32_t *uint_ptr = value;
+        *uint_ptr = ipoutrequests;
+      }
+      break;
+    case 11: /* ipOutDiscards */
+      {
+        u32_t *uint_ptr = value;
+        *uint_ptr = ipoutdiscards;
+      }
+      break;
+    case 12: /* ipOutNoRoutes */
+      {
+        u32_t *uint_ptr = value;
+        *uint_ptr = ipoutnoroutes;
+      }
+      break;
+    case 13: /* ipReasmTimeout */
+      {
+        s32_t *sint_ptr = value;
+#if IP_REASSEMBLY
+        *sint_ptr = IP_REASS_MAXAGE;
+#else
+        *sint_ptr = 0;
+#endif
+      }
+      break;
+    case 14: /* ipReasmReqds */
+      {
+        u32_t *uint_ptr = value;
+        *uint_ptr = ipreasmreqds;
+      }
+      break;
+    case 15: /* ipReasmOKs */
+      {
+        u32_t *uint_ptr = value;
+        *uint_ptr = ipreasmoks;
+      }
+      break;
+    case 16: /* ipReasmFails */
+      {
+        u32_t *uint_ptr = value;
+        *uint_ptr = ipreasmfails;
+      }
+      break;
+    case 17: /* ipFragOKs */
+      {
+        u32_t *uint_ptr = value;
+        *uint_ptr = ipfragoks;
+      }
+      break;
+    case 18: /* ipFragFails */
+      {
+        u32_t *uint_ptr = value;
+        *uint_ptr = ipfragfails;
+      }
+      break;
+    case 19: /* ipFragCreates */
+      {
+        u32_t *uint_ptr = value;
+        *uint_ptr = ipfragcreates;
+      }
+      break;
+    case 23: /* ipRoutingDiscards */
+      /** @todo can lwIP discard routes at all?? hardwire this to 0?? */
+      {
+        u32_t *uint_ptr = value;
+        *uint_ptr = iproutingdiscards;
+      }
+      break;
+  };
+}
+
+static void
+ip_addrentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  if (ident_len == 5)
+  {
+    struct ip_addr ip;
+    struct netif *netif = netif_list;
+
+    ip.addr = ident[1];
+    ip.addr <<= 8;
+    ip.addr |= ident[2];
+    ip.addr <<= 8;
+    ip.addr |= ident[3];
+    ip.addr <<= 8;
+    ip.addr |= ident[4];
+    ip.addr = htonl(ip.addr);
+
+    while ((netif != NULL) && !ip_addr_cmp(&ip, &netif->ip_addr))
+    {
+      netif = netif->next;
+    }
+    
+    if (netif != NULL)
+    {
+      u8_t id;
+
+      od->id_inst_len = ident_len;
+      od->id_inst_ptr = ident;
+      od->addr = netif;
+
+      id = ident[0];
+      switch (id)
+      {
+        case 1: /* ipAdEntAddr */
+        case 3: /* ipAdEntNetMask */
+          od->instance = MIB_OBJECT_TAB;
+          od->access = MIB_OBJECT_READ_ONLY;
+          od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
+          od->v_len = 4;
+          break;
+        case 2: /* ipAdEntIfIndex */
+        case 4: /* ipAdEntBcastAddr */
+        case 5: /* ipAdEntReasmMaxSize */
+          od->instance = MIB_OBJECT_TAB;
+          od->access = MIB_OBJECT_READ_ONLY;
+          od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+          od->v_len = sizeof(s32_t);
+          break;
+        default:
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no such object"));
+          od->instance = MIB_OBJECT_NONE;
+          break;
+      }
+    }
+    else
+    {
+      LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no scalar"));
+      od->instance = MIB_OBJECT_NONE;
+    }
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_addrentry_get_object_def: no scalar"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+ip_addrentry_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  u8_t id;
+
+  if (len) {}
+  id = od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 1: /* ipAdEntAddr */
+      {
+        struct ip_addr *dst = value;
+        struct netif *netif;
+        struct ip_addr *src;
+
+        netif = od->addr;
+        src = &netif->ip_addr;
+        *dst = *src;
+      }
+      break;
+    case 2: /* ipAdEntIfIndex */
+      {
+        s32_t *sint_ptr = value;
+        struct netif *netif = netif_list;
+        u16_t i;
+
+        i = 0;
+        while ((netif != NULL) && (netif != od->addr))
+        {
+          netif = netif->next;
+          i++;
+        }
+        *sint_ptr = i + 1;
+      }
+      break;
+    case 3: /* ipAdEntNetMask */
+      {
+        struct ip_addr *dst = value;
+        struct netif *netif;
+        struct ip_addr *src;
+
+        netif = od->addr;
+        src = &netif->netmask;
+        *dst = *src;
+      }
+      break;
+    case 4: /* ipAdEntBcastAddr */
+      {
+        s32_t *sint_ptr = value;      
+
+        /* lwIP oddity, there's no broadcast
+          address in the netif we can rely on */
+        *sint_ptr = ip_addr_broadcast.addr & 1;
+      }
+      break;
+    case 5: /* ipAdEntReasmMaxSize */
+      {
+        s32_t *sint_ptr = value;      
+#if IP_REASSEMBLY
+        *sint_ptr = (IP_HLEN + IP_REASS_BUFSIZE);
+#else
+        /** @todo returning MTU would be a bad thing and
+           returning a wild guess like '576' isn't good either */
+        *sint_ptr = 0;
+#endif
+      }
+      break;
+  }
+}
+
+/** 
+ * @note
+ * lwIP IP routing is currently using the network addresses in netif_list.
+ * if no suitable network IP is found in netif_list, the default_netif is used.
+ */
+static void
+ip_rteentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  u8_t id;
+
+  if (ident_len == 5)
+  {
+    struct ip_addr dest;
+    struct netif *netif;
+
+    dest.addr = ident[1];
+    dest.addr <<= 8;
+    dest.addr |= ident[2];
+    dest.addr <<= 8;
+    dest.addr |= ident[3];
+    dest.addr <<= 8;
+    dest.addr |= ident[4];
+    dest.addr = htonl(dest.addr);
+
+    if (dest.addr == 0)
+    {
+      /* ip_route() uses default netif for default route */
+      netif = netif_default;
+    }
+    else
+    {
+      /* not using ip_route(), need exact match! */
+      netif = netif_list;
+      while ((netif != NULL) && 
+              !ip_addr_netcmp(&dest, &(netif->ip_addr), &(netif->netmask)) )
+      {      
+        netif = netif->next;
+      }
+    }    
+    if (netif != NULL)
+    {
+      od->id_inst_len = ident_len;
+      od->id_inst_ptr = ident;
+      od->addr = netif;
+
+      id = ident[0];
+      switch (id)
+      {
+        case 1: /* ipRouteDest */
+        case 7: /* ipRouteNextHop */
+        case 11: /* ipRouteMask */
+          od->instance = MIB_OBJECT_TAB;
+          od->access = MIB_OBJECT_READ_WRITE;
+          od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
+          od->v_len = 4;
+          break;
+        case 2: /* ipRouteIfIndex */
+        case 3: /* ipRouteMetric1 */
+        case 4: /* ipRouteMetric2 */
+        case 5: /* ipRouteMetric3 */
+        case 6: /* ipRouteMetric4 */
+        case 8: /* ipRouteType */
+        case 10: /* ipRouteAge */
+        case 12: /* ipRouteMetric5 */
+          od->instance = MIB_OBJECT_TAB;
+          od->access = MIB_OBJECT_READ_WRITE;
+          od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+          od->v_len = sizeof(s32_t);
+          break;
+        case 9: /* ipRouteProto */
+          od->instance = MIB_OBJECT_TAB;
+          od->access = MIB_OBJECT_READ_ONLY;
+          od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+          od->v_len = sizeof(s32_t);
+          break;
+        case 13: /* ipRouteInfo */
+          /** @note returning zeroDotZero (0.0) no routing protocol specific MIB */
+          od->instance = MIB_OBJECT_TAB;
+          od->access = MIB_OBJECT_READ_ONLY;
+          od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OBJ_ID);
+          od->v_len = iprouteinfo.len * sizeof(s32_t);
+          break;
+        default:
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no such object"));
+          od->instance = MIB_OBJECT_NONE;
+          break;
+      }
+    }
+    else
+    {
+      LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no scalar"));
+      od->instance = MIB_OBJECT_NONE;
+    }
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_rteentry_get_object_def: no scalar"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+ip_rteentry_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  struct netif *netif;
+  struct ip_addr dest;
+  s32_t *ident;
+  u8_t id;
+
+  netif = od->addr;
+  ident = od->id_inst_ptr;
+  dest.addr = ident[1];
+  dest.addr <<= 8;
+  dest.addr |= ident[2];
+  dest.addr <<= 8;
+  dest.addr |= ident[3];
+  dest.addr <<= 8;
+  dest.addr |= ident[4];
+  dest.addr = htonl(dest.addr);
+
+  id = ident[0];
+  switch (id)
+  {
+    case 1: /* ipRouteDest */
+      {
+        struct ip_addr *dst = value;
+
+        if (dest.addr == 0)
+        {
+          /* default rte has 0.0.0.0 dest */
+          dst->addr = 0;
+        }
+        else
+        {
+          /* netifs have netaddress dest */
+          dst->addr = netif->ip_addr.addr & netif->netmask.addr;
+        }
+      }
+      break;
+    case 2: /* ipRouteIfIndex */
+      {
+        struct netif *ni = netif_list;
+        s32_t *sint_ptr = value;
+        u16_t i;
+
+        i = 0;
+        while ((ni != NULL) && (ni != netif))
+        {
+          ni = ni->next;
+          i++;
+        }
+        *sint_ptr = i + 1;
+      }
+      break;
+    case 3: /* ipRouteMetric1 */         
+      {
+        s32_t *sint_ptr = value;
+
+        if (dest.addr == 0)
+        {
+          /* default rte has metric 1 */
+          *sint_ptr = 1;
+        }
+        else
+        {
+          /* other rtes have metric 0 */
+          *sint_ptr = 0;
+        }
+      }
+      break;
+    case 4: /* ipRouteMetric2 */
+    case 5: /* ipRouteMetric3 */
+    case 6: /* ipRouteMetric4 */
+    case 12: /* ipRouteMetric5 */
+      {
+        s32_t *sint_ptr = value;
+        /* not used */
+        *sint_ptr = -1;
+      }
+      break;
+    case 7: /* ipRouteNextHop */
+      {
+        struct ip_addr *dst = value;
+
+        if (dest.addr == 0)
+        {
+          /* default rte: gateway */
+          *dst = netif->gw;
+        }
+        else
+        {
+          /* other rtes: netif ip_addr  */
+          *dst = netif->ip_addr;
+        }
+      }
+      break;
+    case 8: /* ipRouteType */
+      {
+        s32_t *sint_ptr = value;
+
+        if (dest.addr == 0)
+        {
+          /* default rte is indirect */
+          *sint_ptr = 4;
+        }
+        else
+        {
+          /* other rtes are direct */
+          *sint_ptr = 3;
+        }
+      }
+      break;
+    case 9: /* ipRouteProto */
+      {
+        s32_t *sint_ptr = value;
+        /* locally defined routes */
+        *sint_ptr = 2;
+      }
+      break;
+    case 10: /* ipRouteAge */
+      {
+        s32_t *sint_ptr = value;
+        /** @todo (sysuptime - timestamp last change) / 100 */
+        *sint_ptr = 0;
+      }
+      break;
+    case 11: /* ipRouteMask */
+      {
+        struct ip_addr *dst = value;
+
+        if (dest.addr == 0)
+        {
+          /* default rte use 0.0.0.0 mask */
+          dst->addr = 0;
+        }
+        else
+        {
+          /* other rtes use netmask */
+          *dst = netif->netmask;
+        }
+      }
+      break;
+    case 13: /* ipRouteInfo */
+      objectidncpy((s32_t*)value,(s32_t*)iprouteinfo.id,len / sizeof(s32_t));
+      break;
+  }
+}
+
+static void
+ip_ntomentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  if ((ident_len == 6) && 
+      (ident[1] > 0) && (ident[1] <= netif_cnt))
+  {
+    struct eth_addr* ethaddr_ret;
+    struct ip_addr* ipaddr_ret;
+    struct ip_addr ip;
+    struct netif *netif = netif_list;
+    u16_t i, ifidx;
+
+    ifidx = ident[1] - 1;
+    i = 0;
+    while ((netif != NULL) && (i < ifidx))
+    {
+      netif = netif->next;
+      i++;
+    }
+    ip.addr = ident[2];
+    ip.addr <<= 8;
+    ip.addr |= ident[3];
+    ip.addr <<= 8;
+    ip.addr |= ident[4];
+    ip.addr <<= 8;
+    ip.addr |= ident[5];
+    ip.addr = htonl(ip.addr);
+    
+    if (etharp_find_addr(netif, &ip, &ethaddr_ret, &ipaddr_ret) > -1)
+    {
+      u8_t id;
+
+      od->id_inst_len = ident_len;
+      od->id_inst_ptr = ident;
+
+      id = ident[0];
+      switch (id)
+      {
+        case 1: /* ipNetToMediaIfIndex */
+        case 4: /* ipNetToMediaType */
+          od->instance = MIB_OBJECT_TAB;
+          od->access = MIB_OBJECT_READ_WRITE;
+          od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+          od->v_len = sizeof(s32_t);
+          od->addr = NULL;
+          break;
+        case 2: /* ipNetToMediaPhysAddress */
+          od->instance = MIB_OBJECT_TAB;
+          od->access = MIB_OBJECT_READ_WRITE;
+          od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR);
+          od->v_len = sizeof(struct eth_addr);
+          od->addr = ethaddr_ret;
+          break;
+        case 3: /* ipNetToMediaNetAddress */
+          od->instance = MIB_OBJECT_TAB;
+          od->access = MIB_OBJECT_READ_WRITE;
+          od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
+          od->v_len = 4;
+          od->addr = ipaddr_ret;
+          break;
+        default:
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no such object"));
+          od->instance = MIB_OBJECT_NONE;
+          break;
+      }
+    }
+    else
+    {
+      LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no scalar"));
+      od->instance = MIB_OBJECT_NONE;
+    }
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_ntomentry_get_object_def: no scalar"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+ip_ntomentry_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  u8_t id;
+
+  if (len){}
+  id = od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 1: /* ipNetToMediaIfIndex */
+      {
+        s32_t *sint_ptr = value;
+        *sint_ptr = od->id_inst_ptr[1];
+      }
+      break;
+    case 2: /* ipNetToMediaPhysAddress */
+      {
+        struct eth_addr *dst = value;
+        struct eth_addr *src = od->addr;
+
+        *dst = *src;
+      }
+      break;
+    case 3: /* ipNetToMediaNetAddress */
+      {
+        struct ip_addr *dst = value;
+        struct ip_addr *src = od->addr;
+
+        *dst = *src;
+      }
+      break;
+    case 4: /* ipNetToMediaType */
+      {
+        s32_t *sint_ptr = value;
+        /* dynamic (?) */
+        *sint_ptr = 3;
+      }
+      break;
+  }
+}
+
+static void
+icmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  if ((ident_len == 2) && (ident[1] == 0) &&
+      (ident[0] > 0) && (ident[0] < 27))
+  {
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+
+    od->instance = MIB_OBJECT_SCALAR;
+    od->access = MIB_OBJECT_READ_ONLY;
+    od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
+    od->v_len = sizeof(u32_t);
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("icmp_get_object_def: no scalar"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+icmp_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  u32_t *uint_ptr = value;
+  u8_t id;
+
+  if (len){}
+  id = od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 1: /* icmpInMsgs */
+      *uint_ptr = icmpinmsgs;
+      break;
+    case 2: /* icmpInErrors */
+      *uint_ptr = icmpinerrors;
+      break;
+    case 3: /* icmpInDestUnreachs */
+      *uint_ptr = icmpindestunreachs;
+      break;
+    case 4: /* icmpInTimeExcds */
+      *uint_ptr = icmpintimeexcds;
+      break;
+    case 5: /* icmpInParmProbs */
+      *uint_ptr = icmpinparmprobs;
+      break;
+    case 6: /* icmpInSrcQuenchs */
+      *uint_ptr = icmpinsrcquenchs;
+      break;
+    case 7: /* icmpInRedirects */
+      *uint_ptr = icmpinredirects;
+      break;
+    case 8: /* icmpInEchos */
+      *uint_ptr = icmpinechos;
+      break;
+    case 9: /* icmpInEchoReps */
+      *uint_ptr = icmpinechoreps;
+      break;
+    case 10: /* icmpInTimestamps */
+      *uint_ptr = icmpintimestamps;
+      break;
+    case 11: /* icmpInTimestampReps */
+      *uint_ptr = icmpintimestampreps;
+      break;
+    case 12: /* icmpInAddrMasks */
+      *uint_ptr = icmpinaddrmasks;
+      break;
+    case 13: /* icmpInAddrMaskReps */
+      *uint_ptr = icmpinaddrmaskreps;
+      break;
+    case 14: /* icmpOutMsgs */
+      *uint_ptr = icmpoutmsgs; 
+      break;
+    case 15: /* icmpOutErrors */
+      *uint_ptr = icmpouterrors;
+      break;
+    case 16: /* icmpOutDestUnreachs */
+      *uint_ptr = icmpoutdestunreachs;
+      break;
+    case 17: /* icmpOutTimeExcds */
+      *uint_ptr = icmpouttimeexcds;
+      break;
+    case 18: /* icmpOutParmProbs */
+      *uint_ptr = icmpoutparmprobs;
+      break;
+    case 19: /* icmpOutSrcQuenchs */
+      *uint_ptr = icmpoutsrcquenchs;
+      break;
+    case 20: /* icmpOutRedirects */
+      *uint_ptr = icmpoutredirects;
+      break;
+    case 21: /* icmpOutEchos */
+      *uint_ptr = icmpoutechos;
+      break;
+    case 22: /* icmpOutEchoReps */
+      *uint_ptr = icmpoutechoreps;
+      break;
+    case 23: /* icmpOutTimestamps */
+      *uint_ptr = icmpouttimestamps;
+      break;
+    case 24: /* icmpOutTimestampReps */
+      *uint_ptr = icmpouttimestampreps;
+      break;
+    case 25: /* icmpOutAddrMasks */
+      *uint_ptr = icmpoutaddrmasks;
+      break;
+    case 26: /* icmpOutAddrMaskReps */
+      *uint_ptr = icmpoutaddrmaskreps;
+      break;
+  }
+}
+
+#if LWIP_TCP
+/** @todo tcp grp */
+static void
+tcp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+}
+
+static void
+tcp_get_value(struct obj_def *od, u16_t len, void *value)
+{
+}
+
+static void
+tcpconnentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+}
+
+static void
+tcpconnentry_get_value(struct obj_def *od, u16_t len, void *value)
+{
+}
+#endif
+
+static void
+udp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  if ((ident_len == 2) && (ident[1] == 0) &&
+      (ident[0] > 0) && (ident[0] < 6))
+  {
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+
+    od->instance = MIB_OBJECT_SCALAR;
+    od->access = MIB_OBJECT_READ_ONLY;
+    od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
+    od->v_len = sizeof(u32_t);
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("udp_get_object_def: no scalar"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+udp_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  u32_t *uint_ptr = value;
+  u8_t id;
+
+  if (len){}
+  id = od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 1: /* udpInDatagrams */
+      *uint_ptr = udpindatagrams;
+      break;
+    case 2: /* udpNoPorts */
+      *uint_ptr = udpnoports;
+      break;
+    case 3: /* udpInErrors */
+      *uint_ptr = udpinerrors;
+      break;
+    case 4: /* udpOutDatagrams */
+      *uint_ptr = udpoutdatagrams;
+      break;
+  }
+}
+
+static void
+udpentry_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  if (ident_len == 6)
+  {
+    struct udp_pcb *pcb;
+    struct ip_addr ip;
+    u16_t port;
+
+    ip.addr = ident[1];
+    ip.addr <<= 8;
+    ip.addr |= ident[2];
+    ip.addr <<= 8;
+    ip.addr |= ident[3];
+    ip.addr <<= 8;
+    ip.addr |= ident[4];
+    ip.addr = htonl(ip.addr);
+
+    port = ident[5];
+
+    pcb = udp_pcbs;
+    while ((pcb != NULL) &&
+            (pcb->local_ip.addr != ip.addr) &&
+            (pcb->local_port != port))
+    {      
+      pcb = pcb->next;
+    }
+    
+    if (pcb != NULL)
+    {
+      od->id_inst_len = ident_len;
+      od->id_inst_ptr = ident;
+      od->addr = pcb;
+
+      switch (ident[0])
+      {
+        case 1: /* udpLocalAddress */
+          od->instance = MIB_OBJECT_TAB;
+          od->access = MIB_OBJECT_READ_WRITE;
+          od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_IPADDR);
+          od->v_len = 4;
+          break;
+        case 2: /* udpLocalPort */
+          od->instance = MIB_OBJECT_TAB;
+          od->access = MIB_OBJECT_READ_WRITE;
+          od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+          od->v_len = sizeof(s32_t);
+          break;
+        default:
+          LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no such object"));
+          od->instance = MIB_OBJECT_NONE;
+          break;
+      }
+    }
+    else
+    {
+      LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no scalar"));
+      od->instance = MIB_OBJECT_NONE;
+    }
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("udpentry_get_object_def: no scalar"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+udpentry_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  struct udp_pcb *pcb;
+  u8_t id;
+
+  if (len){}
+  pcb = od->addr;
+  id = od->id_inst_ptr[0];
+  switch (id)
+  {
+    case 1: /* udpLocalAddress */
+      {
+        struct ip_addr *dst = value;
+        struct ip_addr *src = &pcb->local_ip;
+        *dst = *src;
+      }
+      break;
+    case 2: /* udpLocalPort */
+      {
+        s32_t *sint_ptr = value;
+        *sint_ptr = pcb->local_port;
+      }
+      break;
+  }
+}
+
+static void
+snmp_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
+{
+  if ((ident_len == 2) && (ident[1] == 0))
+  {
+    u8_t id;
+
+    od->id_inst_len = ident_len;
+    od->id_inst_ptr = ident;
+
+    id = ident[0];
+    switch (id)
+    {
+      case 1: /* snmpInPkts */
+      case 2: /* snmpOutPkts */
+      case 3: /* snmpInBadVersions */
+      case 4: /* snmpInBadCommunityNames */
+      case 5: /* snmpInBadCommunityUses */
+      case 6: /* snmpInASNParseErrs */
+      case 8: /* snmpInTooBigs */
+      case 9: /* snmpInNoSuchNames */
+      case 10: /* snmpInBadValues */
+      case 11: /* snmpInReadOnlys */
+      case 12: /* snmpInGenErrs */
+      case 13: /* snmpInTotalReqVars */
+      case 14: /* snmpInTotalSetVars */
+      case 15: /* snmpInGetRequests */
+      case 16: /* snmpInGetNexts */
+      case 17: /* snmpInSetRequests */
+      case 18: /* snmpInGetResponses */
+      case 19: /* snmpInTraps */
+      case 20: /* snmpOutTooBigs */
+      case 21: /* snmpOutNoSuchNames */
+      case 22: /* snmpOutBadValues */
+      case 24: /* snmpOutGenErrs */
+      case 25: /* snmpOutGetRequests */
+      case 26: /* snmpOutGetNexts */
+      case 27: /* snmpOutSetRequests */
+      case 28: /* snmpOutGetResponses */
+      case 29: /* snmpOutTraps */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_ONLY;
+        od->asn_type = (SNMP_ASN1_APPLIC | SNMP_ASN1_PRIMIT | SNMP_ASN1_COUNTER);
+        od->v_len = sizeof(u32_t);
+        break;
+      case 30: /* snmpEnableAuthenTraps */
+        od->instance = MIB_OBJECT_SCALAR;
+        od->access = MIB_OBJECT_READ_WRITE;
+        od->asn_type = (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG);
+        od->v_len = sizeof(s32_t);
+        break;
+      default:
+        LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no such object"));
+        od->instance = MIB_OBJECT_NONE;
+        break;
+    };
+  }
+  else
+  {
+    LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_object_def: no scalar"));
+    od->instance = MIB_OBJECT_NONE;
+  }
+}
+
+static void
+snmp_get_value(struct obj_def *od, u16_t len, void *value)
+{
+  u32_t *uint_ptr = value;
+  u8_t id;
+
+  if (len){}
+  id = od->id_inst_ptr[0];
+  switch (id)
+  {
+      case 1: /* snmpInPkts */
+        *uint_ptr = snmpinpkts;
+        break;
+      case 2: /* snmpOutPkts */
+        *uint_ptr = snmpoutpkts;
+        break;
+      case 3: /* snmpInBadVersions */
+        *uint_ptr = snmpinbadversions;
+        break;
+      case 4: /* snmpInBadCommunityNames */
+        *uint_ptr = snmpinbadcommunitynames;
+        break;
+      case 5: /* snmpInBadCommunityUses */
+        *uint_ptr = snmpinbadcommunityuses;
+        break;
+      case 6: /* snmpInASNParseErrs */
+        *uint_ptr = snmpinasnparseerrs;
+        break;
+      case 8: /* snmpInTooBigs */
+        *uint_ptr = snmpintoobigs;
+        break;
+      case 9: /* snmpInNoSuchNames */
+        *uint_ptr = snmpinnosuchnames;
+        break;
+      case 10: /* snmpInBadValues */
+        *uint_ptr = snmpinbadvalues;
+        break;
+      case 11: /* snmpInReadOnlys */
+        *uint_ptr = snmpinreadonlys;
+        break;
+      case 12: /* snmpInGenErrs */
+        *uint_ptr = snmpingenerrs;
+        break;
+      case 13: /* snmpInTotalReqVars */
+        *uint_ptr = snmpintotalreqvars;
+        break;
+      case 14: /* snmpInTotalSetVars */
+        *uint_ptr = snmpintotalsetvars;
+        break;
+      case 15: /* snmpInGetRequests */
+        *uint_ptr = snmpingetrequests;
+        break;
+      case 16: /* snmpInGetNexts */
+        *uint_ptr = snmpingetnexts;
+        break;
+      case 17: /* snmpInSetRequests */
+        *uint_ptr = snmpinsetrequests;
+        break;
+      case 18: /* snmpInGetResponses */
+        *uint_ptr = snmpingetresponses;
+        break;
+      case 19: /* snmpInTraps */
+        *uint_ptr = snmpintraps;
+        break;
+      case 20: /* snmpOutTooBigs */
+        *uint_ptr = snmpouttoobigs;
+        break;
+      case 21: /* snmpOutNoSuchNames */
+        *uint_ptr = snmpoutnosuchnames;
+        break;
+      case 22: /* snmpOutBadValues */
+        *uint_ptr = snmpoutbadvalues;
+        break;
+      case 24: /* snmpOutGenErrs */
+        *uint_ptr = snmpoutgenerrs;
+        break;
+      case 25: /* snmpOutGetRequests */
+        *uint_ptr = snmpoutgetrequests;
+        break;
+      case 26: /* snmpOutGetNexts */
+        *uint_ptr = snmpoutgetnexts;
+        break;
+      case 27: /* snmpOutSetRequests */
+        *uint_ptr = snmpoutsetrequests;
+        break;
+      case 28: /* snmpOutGetResponses */
+        *uint_ptr = snmpoutgetresponses;
+        break;
+      case 29: /* snmpOutTraps */
+        *uint_ptr = snmpouttraps;
+        break;
+      case 30: /* snmpEnableAuthenTraps */
+        *uint_ptr = *snmpenableauthentraps_ptr;
+        break;
+  };
 }
 
 #endif /* LWIP_SNMP */
\ No newline at end of file
index 0d2dfd8e6e3c5b2354fd6405c853c7759839db7b..0325cd6a299fca264d576a65679b2ff658938e5f 100644 (file)
@@ -221,4 +221,26 @@ snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct obj
   return NULL;
 }
 
+/**
+ * Test object identifier for the iso.org.dod.internet prefix.
+ *
+ * @param ident_len the length of the supplied object identifier
+ * @param ident points to the array of sub identifiers
+ * @return 1 if it matches, 0 otherwise
+ */
+u8_t
+snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident)
+{
+  if ((ident_len > 3) &&
+      (ident[0] == 1) && (ident[1] == 3) &&
+      (ident[2] == 6) && (ident[3] == 1))
+  {
+    return 1;
+  }
+  else
+  {
+    return 0;
+  }
+}
+
 #endif /* LWIP_SNMP */
index eb3857f7ef226b5f840ca79e397b3ae310bbff48..095ab91949a08b495d91dec44545e0c019143c6c 100644 (file)
@@ -46,7 +46,6 @@
 #include "lwip/snmp.h"
 #include "lwip/snmp_asn1.h"
 #include "lwip/snmp_msg.h"
-
 #include "lwip/snmp_structs.h"
 
 #if LWIP_SNMP
@@ -74,9 +73,7 @@ static void snmp_varbind_list_free(struct snmp_varbind_root *root);
 static void snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb);
 static struct snmp_varbind* snmp_varbind_tail_remove(struct snmp_varbind_root *root);
 
-/** @todo: move this to  header */
-extern const struct mib_array_node internet;
-extern const struct mib_array_node sys_tem; /* test only */
+
 
 /**
  * Starts SNMP Agent.
@@ -106,11 +103,81 @@ snmp_init(void)
 }
 
 /**
- *
+ * called for each variable binding (also for the fist one)
  */
 void
-snmp_msg_event(void)
+snmp_msg_event(struct snmp_msg_pstat *msg_ps)
 {
+  struct mib_node *mn;
+  struct obj_def object_def;
+
+  if (msg_ps->state == SNMP_MSG_DEMUX)
+  {
+    if (msg_ps->vb_idx == 0)
+    {
+      msg_ps->vb_ptr = msg_ps->invb.head;
+    }
+    else
+    {
+      msg_ps->vb_ptr = msg_ps->vb_ptr->next;
+      msg_ps->vb_idx += 1;
+    }
+    if (msg_ps->rt == SNMP_ASN1_PDU_GET_REQ)
+    { 
+      /** test object identifier for .iso.org.dod.internet prefix */
+      if (snmp_iso_prefix_tst(msg_ps->vb_ptr->ident_len,  msg_ps->vb_ptr->ident))
+      {
+        mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->vb_ptr->ident_len - 4,
+                               msg_ps->vb_ptr->ident + 4, &object_def);
+      }
+      else
+      {
+        mn = NULL;
+      }
+      if (mn != NULL)
+      {
+        if (mn->node_type == MIB_NODE_EX)
+        {
+          /* external object */
+          msg_ps->state = SNMP_MSG_EXTERNAL;
+        }
+        else
+        {
+          /* internal object */
+          msg_ps->state = SNMP_MSG_INTERNAL;
+        }
+      }
+      else
+      {
+        /* mn == NULL, noSuchName */
+        msg_ps->error_status = SNMP_ES_NOSUCHNAME;
+        msg_ps->error_index = 1 + msg_ps->vb_idx;
+        msg_ps->outvb.head = NULL;
+        msg_ps->outvb.tail = NULL;
+        msg_ps->outvb.count = 0;
+        msg_ps->outvb.seqlen = 0;
+        msg_ps->outvb.seqlenlen = 1;
+        snmp_send_response(msg_ps);
+        msg_ps->state = SNMP_MSG_EMPTY;
+      }
+    }
+    else if (msg_ps->rt == SNMP_ASN1_PDU_GET_NEXT_REQ)
+    {
+    }
+    else if (msg_ps->rt == SNMP_ASN1_PDU_SET_REQ)
+    {
+    }
+    else
+    {
+      /** @todo not a request, return generror?? */
+    }
+  }
+  else if (msg_ps->state == SNMP_MSG_INTERNAL)
+  {
+  }
+  else if (msg_ps->state == SNMP_MSG_EXTERNAL)
+  {
+  }
 }
 
 /* lwIP UDP receive callback function */
@@ -156,6 +223,8 @@ snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
       msg_ps->sp = port;
       /* demultiplex variable bindings */
       msg_ps->state = SNMP_MSG_DEMUX;
+      /* first variable binding from list to inspect */
+      msg_ps->vb_idx = 0;
       /* read UDP payload length from UDP header */
       payload_len = ntohs(udphdr->len) - UDP_HLEN;
 
@@ -171,7 +240,7 @@ snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
        /* Builds a list of variable bindings. Copy the varbinds from the pbuf
          chain to glue them when these are divided over two or more pbuf's. */
         err_ret = snmp_pdu_dec_varbindlist(p, varbind_ofs, &varbind_ofs, msg_ps);
-        if (err_ret == ERR_OK)
+        if ((err_ret == ERR_OK) && (msg_ps->invb.count > 0))
         {          
           struct mib_node *mn;
           struct obj_def object_def;
@@ -183,14 +252,18 @@ snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
 
           if (msg_ps->rt == SNMP_ASN1_PDU_GET_REQ)
           { 
-            /** @todo check if count > 0 and if we got .iso.dod.internet  and iterate from vb 0 .. count-1 */
-            mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->invb.head->ident_len - 2 /* trim iso.dod.internet */,
-                                   msg_ps->invb.head->ident + 2, &object_def);
+            /** test object identifier for .iso.org.dod.internet prefix */
+            if (snmp_iso_prefix_tst(msg_ps->invb.head->ident_len, msg_ps->invb.head->ident))
+            {
+              mn = snmp_search_tree((struct mib_node*)&internet, msg_ps->invb.head->ident_len - 4,
+                                     msg_ps->invb.head->ident + 4, &object_def);
+            }
+            else
+            {
+              mn = NULL;
+            }
             if (mn != NULL)
             {
-              LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv mn=%p sys_tem=%p node_typ=%"U16_F,
-                                            (void*)mn,(void*)&sys_tem,(u16_t)mn->node_type));
-          
               if (msg_ps->invb.head->value != NULL)
               {
                 LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_recv free value before vb recycle"));
@@ -201,7 +274,7 @@ snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
               msg_ps->invb.head->value = mem_malloc(object_def.v_len);
               if (msg_ps->invb.head->value != NULL)
               {
-                mn->get_value(object_def.id_inst_len, object_def.id_inst_ptr, object_def.v_len, msg_ps->invb.head->value);
+                mn->get_value(&object_def, object_def.v_len, msg_ps->invb.head->value);
               }
               else
               {
@@ -213,8 +286,7 @@ snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
             {
               /* mn == NULL, noSuchName */
               msg_ps->error_status = SNMP_ES_NOSUCHNAME;
-              /** @todo current varbind index */
-              msg_ps->error_index = 1;
+              msg_ps->error_index = 1 + msg_ps->vb_idx;
               msg_ps->outvb.head = NULL;
               msg_ps->outvb.tail = NULL;
               msg_ps->outvb.count = 0;
@@ -232,6 +304,10 @@ snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
             msg_ps->error_index = 0;
           }
 
+/* when more variable bindings left msg_ps->state = SNMP_MSG_DEMUX */
+
+
+/* when completed transaction */
           err_ret = snmp_send_response(msg_ps);
           if (err_ret == ERR_MEM)
           {
@@ -247,13 +323,21 @@ snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr,
           /* free varbinds (if available) */
           snmp_varbind_list_free(&msg_ps->invb);
           msg_ps->state = SNMP_MSG_EMPTY;
+
         }
         else
         {
-          /* varbind-list decode failed! */
+          /* varbind-list decode failed, or varbind list empty (silly cmd for agent) */
           pbuf_free(p);
-          /** @todo should  we return SNMP_ES_GENERROR here ? */
           LWIP_DEBUGF(SNMP_MSG_DEBUG, ("snmp_pdu_dec_varbindlist() failed"));
+          msg_ps->error_status = SNMP_ES_GENERROR;
+          msg_ps->error_index = 0;
+          msg_ps->outvb.head = NULL;
+          msg_ps->outvb.tail = NULL;
+          msg_ps->outvb.count = 0;
+          msg_ps->outvb.seqlen = 0;
+          msg_ps->outvb.seqlenlen = 1;
+          snmp_send_response(msg_ps);
         }
       }
       else
@@ -306,14 +390,7 @@ snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret,
     snmp_inc_snmpinasnparseerrs();
     return ERR_ARG;
   }
-  if (type & SNMP_ASN1_CONSTR)
-  {
-    ofs += (1 + len_octets);
-  }
-  else
-  {
-    ofs += (1 + len_octets + len);
-  }
+  ofs += (1 + len_octets);
   snmp_asn1_dec_type(p, ofs, &type);
   derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
   if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
@@ -335,14 +412,7 @@ snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret,
     snmp_inc_snmpinbadversions();
     return ERR_ARG;
   }
-  if (type & SNMP_ASN1_CONSTR)
-  {
-    ofs += (1 + len_octets);
-  }
-  else
-  {
-    ofs += (1 + len_octets + len);
-  }
+  ofs += (1 + len_octets + len);
   snmp_asn1_dec_type(p, ofs, &type);
   derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
   if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_OC_STR)))
@@ -369,14 +439,7 @@ snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret,
     /** @todo: send authentication failure trap, if we have a trap destination */
     return ERR_ARG;
   }
-  if (type & SNMP_ASN1_CONSTR)
-  {
-    ofs += (1 + len_octets);
-  }
-  else
-  {
-    ofs += (1 + len_octets + len);
-  }
+  ofs += (1 + len_octets + len);
   snmp_asn1_dec_type(p, ofs, &type);
   derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
   if (derr != ERR_OK)
@@ -422,14 +485,7 @@ snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret,
     return ERR_ARG;
   }
   m_stat->rt = type & 0x1F;
-  if (type & SNMP_ASN1_CONSTR)
-  {
-    ofs += (1 + len_octets);
-  }
-  else
-  {
-    ofs += (1 + len_octets + len);
-  }
+  ofs += (1 + len_octets);
   snmp_asn1_dec_type(p, ofs, &type);
   derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
   if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
@@ -445,14 +501,7 @@ snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret,
     snmp_inc_snmpinasnparseerrs();
     return ERR_ARG;
   }
-  if (type & SNMP_ASN1_CONSTR)
-  {
-    ofs += (1 + len_octets);
-  }
-  else
-  {
-    ofs += (1 + len_octets + len);
-  }
+  ofs += (1 + len_octets + len);
   snmp_asn1_dec_type(p, ofs, &type);
   derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
   if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
@@ -488,14 +537,7 @@ snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret,
       snmp_inc_snmpingenerrs();
       break;
   }
-  if (type & SNMP_ASN1_CONSTR)
-  {
-    ofs += (1 + len_octets);
-  }
-  else
-  {
-    ofs += (1 + len_octets + len);
-  }
+  ofs += (1 + len_octets + len);
   snmp_asn1_dec_type(p, ofs, &type);
   derr = snmp_asn1_dec_length(p, ofs+1, &len_octets, &len);
   if ((derr != ERR_OK) || (type != (SNMP_ASN1_UNIV | SNMP_ASN1_PRIMIT | SNMP_ASN1_INTEG)))
@@ -505,14 +547,7 @@ snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret,
     return ERR_ARG;
   }
   /* skip 'error-index', usually 0 for incoming requests */
-  if (type & SNMP_ASN1_CONSTR)
-  {
-    ofs += (1 + len_octets);
-  }
-  else
-  {
-    ofs += (1 + len_octets + len);
-  }
+  ofs += (1 + len_octets + len);
   *ofs_ret = ofs;
   return ERR_OK;
 }
index 7fc0fda1991215b1c91d8dee9151bcd42080a306..d93332be5876486b94627100c8ff39ed61b3fa1f 100644 (file)
@@ -49,19 +49,14 @@ struct snmp_obj_id
 };
 
 /* system */
-void snmp_set_sysdesr(u8_t* str, u8_t strlen);
+void snmp_set_sysdesr(u8_t* str, u8_t* strlen);
 void snmp_set_sysobjid(struct snmp_obj_id *oid);
 void snmp_get_sysobjid_ptr(struct snmp_obj_id **oid);
 void snmp_inc_sysuptime(void);
 void snmp_get_sysuptime(u32_t *value);
-void snmp_set_syscontact(u8_t *ocstr, u8_t ocstrlen);
-void snmp_set_sysname(u8_t *ocstr, u8_t ocstrlen);
-void snmp_set_syslocation(u8_t *ocstr, u8_t ocstrlen);
-/** externally supplied system functions 
-    @see lwip/doc/snmp_agent.txt */
-void snmp_store_syscontact(u8_t* ocstr, u8_t ocstrlen);
-void snmp_store_sysname(u8_t* ocstr, u8_t ocstrlen);
-void snmp_store_syslocation(u8_t* ocstr, u8_t ocstrlen);
+void snmp_set_syscontact(u8_t *ocstr, u8_t *ocstrlen);
+void snmp_set_sysname(u8_t *ocstr, u8_t *ocstrlen);
+void snmp_set_syslocation(u8_t *ocstr, u8_t *ocstrlen);
 
 /* network interface */
 void snmp_add_ifinoctets(struct netif *ni, u32_t value); 
@@ -75,13 +70,22 @@ void snmp_inc_ifoutdiscards(struct netif *ni);
 
 /* IP */
 void snmp_inc_ipinreceives(void);
-void snmp_inc_ipindelivers(void);
+void snmp_inc_ipinhdrerrors(void);
+void snmp_inc_ipinaddrerrors(void);
+void snmp_inc_ipforwdatagrams(void);
+void snmp_inc_ipinunknownprotos(void);
 void snmp_inc_ipindiscards(void);
-void snmp_inc_ipoutdiscards(void);
+void snmp_inc_ipindelivers(void);
 void snmp_inc_ipoutrequests(void);
-void snmp_inc_ipunknownprotos(void);
-void snmp_inc_ipnoroutes(void);
-void snmp_inc_ipforwdatagrams(void);
+void snmp_inc_ipoutdiscards(void);
+void snmp_inc_ipoutnoroutes(void);
+void snmp_inc_ipreasmreqds(void);
+void snmp_inc_ipreasmoks(void);
+void snmp_inc_ipreasmfails(void);
+void snmp_inc_ipfragoks(void);
+void snmp_inc_ipfragfails(void);
+void snmp_inc_ipfragcreates(void);
+void snmp_inc_iproutingdiscards(void);
 
 /* ICMP */
 void snmp_inc_icmpinmsgs(void);
@@ -158,15 +162,18 @@ void snmp_inc_snmpoutsetrequests(void);
 void snmp_inc_snmpoutgetresponses(void);
 void snmp_inc_snmpouttraps(void);
 void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid);
+void snmp_set_snmpenableauthentraps(u8_t *value);
 
 /* LWIP_SNMP support not available */
 /* define everything to be empty */
 #else
 
 /* system */
+#define snmp_set_sysdesr(str, strlen)
+#define snmp_get_sysobjid_ptr(oid)
 #define snmp_inc_sysuptime()
 #define snmp_get_sysuptime(value)
-#define snmp_get_sysobjid_ptr(oid)
+
 
 /* network interface */
 #define snmp_add_ifinoctets(ni,value) 
@@ -180,13 +187,22 @@ void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid);
 
 /* IP */
 #define snmp_inc_ipinreceives()
-#define snmp_inc_ipindelivers()
+#define snmp_inc_ipinhdrerrors()
+#define snmp_inc_ipinaddrerrors()
+#define snmp_inc_ipforwdatagrams()
+#define snmp_inc_ipinunknownprotos()
 #define snmp_inc_ipindiscards()
-#define snmp_inc_ipoutdiscards()
+#define snmp_inc_ipindelivers()
 #define snmp_inc_ipoutrequests()
-#define snmp_inc_ipunknownprotos()
-#define snmp_inc_ipnoroutes()
-#define snmp_inc_ipforwdatagrams()
+#define snmp_inc_ipoutdiscards()
+#define snmp_inc_ipoutnoroutes()
+#define snmp_inc_ipreasmreqds()
+#define snmp_inc_ipreasmoks()
+#define snmp_inc_ipreasmfails()
+#define snmp_inc_ipfragoks()
+#define snmp_inc_ipfragfails()
+#define snmp_inc_ipfragcreates()
+#define snmp_inc_iproutingdiscards()
 
 /* ICMP */
 #define snmp_inc_icmpinmsgs()
@@ -262,6 +278,7 @@ void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid);
 #define snmp_inc_snmpoutgetresponses()
 #define snmp_inc_snmpouttraps()
 #define snmp_get_snmpgrpid_ptr(oid)
+#define snmp_set_snmpenableauthentraps(value)
 
 #endif
 
index 1b61cc2fe4e55201f8a054297cb7915f96d96a46..de51e10d23fcebc079f32f7852cd0c5850e3f1b0 100644 (file)
@@ -208,8 +208,12 @@ struct snmp_msg_pstat
   u8_t community[SNMP_COMMUNITY_STR_LEN + 1];
   /* community string length (exclusive zero term) */
   u8_t com_strlen;
-  /* one out of MSG_EMPTY, MSG_DEMUX, MSG_MGMT, MSG_PRIVATE */
+  /* one out of MSG_EMPTY, MSG_DEMUX, MSG_INTERNAL, MSG_EXTERNAL */
   u8_t state;
+  /* index into input variable binding list */
+  u8_t vb_idx;
+  /* ptr into input variable binding list */
+  struct snmp_varbind *vb_ptr;
   /* list of variable bindings from input */
   struct snmp_varbind_root invb;
   /* list of variable bindings to output */
@@ -260,7 +264,8 @@ extern struct snmp_msg_trap trap_msg;
 
 /** Agent setup, start listening to port 161. */
 void snmp_init(void);
-
+/** Handles internal/external events. */
+void snmp_msg_event(struct snmp_msg_pstat *msg_ps);
 err_t snmp_send_response(struct snmp_msg_pstat *m_stat);
 err_t snmp_send_trap(struct ip_addr *dst, s8_t generic_trap, s32_t specific_trap);
 
index c5de341e6a9fdcc2dae6861b889683dab82b170d..cf910522f454ec4976ef50b3df2980c92f33cb1c 100644 (file)
@@ -70,6 +70,8 @@ struct obj_def
   u8_t  id_inst_len;
   /* instance part of supplied object identifier */
   s32_t *id_inst_ptr; 
+  /* optional value address hint */
+  void *addr;
 };
 
 /** MIB const array node */
@@ -88,7 +90,7 @@ struct mib_node
   void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
   /** returns object value for the given object identifier,
      @note the caller must allocate at least len bytes for the value */
-  void (*get_value)(u8_t ident_len, s32_t *ident, u16_t len, void *value);
+  void (*get_value)(struct obj_def *od, u16_t len, void *value);
   /** @todo set_value() */
   /** One out of MIB_NODE_AR, MIB_NODE_LR or MIB_NODE_EX */
   const u8_t node_type;
@@ -102,7 +104,7 @@ struct mib_array_node
 {
   /* inherited "base class" */
   const void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
-  const void (*get_value)(u8_t ident_len, s32_t *ident, u16_t len, void *value);
+  const void (*get_value)(struct obj_def *od, u16_t len, void *value);
   const u8_t node_type;
   const u16_t maxlength;
 
@@ -117,7 +119,7 @@ struct mib_ram_array_node
 {
   /* inherited "base class" */
   void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
-  void (*get_value)(u8_t ident_len, s32_t *ident, u16_t len, void *value);
+  void (*get_value)(struct obj_def *od, u16_t len, void *value);
   u8_t node_type;
   u16_t maxlength;
 
@@ -140,7 +142,7 @@ struct mib_list_rootnode
 {
   /* inherited "base class" */
   void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
-  void (*get_value)(u8_t ident_len, s32_t *ident, u16_t len, void *value);
+  void (*get_value)(struct obj_def *od, u16_t len, void *value);
   u8_t node_type;
   u16_t maxlength;
 
@@ -157,13 +159,13 @@ struct mib_external_node
 {
   /* inherited "base class" */
   void (*get_object_def)(u8_t ident_len, s32_t *ident, struct obj_def *od);
-  void (*get_value)(u8_t ident_len, s32_t *ident, u16_t len, void *value);
+  void (*get_value)(struct obj_def *od, u16_t len, void *value);
   u8_t node_type;
   u16_t maxlength;
 
   /* aditional struct members */
   void (*req_object_def)(u8_t ident_len, s32_t *ident);
-  void (*getreq_value)(u8_t ident_len, s32_t *ident);
+  void (*getreq_value)(struct obj_def *od);
 
   /** compares object sub identifier with externally available id
       return zero when equal, nonzero when unequal */
@@ -174,6 +176,10 @@ struct mib_external_node
   u16_t count;
 };
 
+/** export MIB tree from mib2.c */
+extern const struct mib_array_node internet;
+
 struct mib_node* snmp_search_tree(struct mib_node *node, u8_t ident_len, s32_t *ident, struct obj_def *object_def);
+u8_t snmp_iso_prefix_tst(u8_t ident_len, s32_t *ident);
 
 #endif