From 8559f3e583fb9a9953a66ba9b85b2997d236b0a1 Mon Sep 17 00:00:00 2001 From: christiaans Date: Fri, 11 Aug 2006 14:16:36 +0000 Subject: [PATCH] MIB-2 object values near to completion, just committing for keeping the flame alive. --- doc/snmp_agent.txt | 22 +- src/core/snmp/mib2.c | 1818 ++++++++++++++++++++++++++++--- src/core/snmp/mib_structs.c | 22 + src/core/snmp/msg_in.c | 183 ++-- src/include/lwip/snmp.h | 61 +- src/include/lwip/snmp_msg.h | 9 +- src/include/lwip/snmp_structs.h | 18 +- 7 files changed, 1872 insertions(+), 261 deletions(-) diff --git a/doc/snmp_agent.txt b/doc/snmp_agent.txt index 4e3a745e..b08c26ee 100644 --- a/doc/snmp_agent.txt +++ b/doc/snmp_agent.txt @@ -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 ============ diff --git a/src/core/snmp/mib2.c b/src/core/snmp/mib2.c index 6037588e..854eb504 100644 --- a/src/core/snmp/mib2.c +++ b/src/core/snmp/mib2.c @@ -36,6 +36,10 @@ #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" @@ -62,31 +66,55 @@ #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,33 +124,84 @@ 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 udp_ids[5] = { 1, 2, 3, 4, 5 }; -struct mib_node* const udp_nodes[5] = { - NULL, NULL, NULL, NULL, /** @todo udpTable */ NULL +const s32_t udpentry_ids[2] = { 1, 2 }; +struct mib_node* const udpentry_nodes[2] = { + NULL, NULL, }; -const struct mib_array_node udp = { +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, (struct mib_node* const)&udptable +}; +const struct mib_array_node udp = { + &udp_get_object_def, + &udp_get_value, + MIB_NODE_AR, 5, udp_ids, udp_nodes }; /* 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,24 +770,39 @@ void snmp_inc_ifoutdiscards(struct netif *ni) (ni->ifoutdiscards)++; } -void snmp_inc_ipindelivers(void) -{ - ipindelivers++; -} - void snmp_inc_ipinreceives(void) { ipinreceives++; } +void snmp_inc_ipinhdrerrors(void) +{ + ipinhdrerrors++; +} + +void snmp_inc_ipinaddrerrors(void) +{ + ipinaddrerrors++; +} + +void snmp_inc_ipforwdatagrams(void) +{ + ipforwdatagrams++; +} + +void snmp_inc_ipinunknownprotos(void) +{ + ipinunknownprotos++; +} + 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) { - ipunknownprotos++; + 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) +{ + 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: + }; +} + +/** + * 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, ðaddr_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; }; - if (ident_len){} +} + +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, ðaddr_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 diff --git a/src/core/snmp/mib_structs.c b/src/core/snmp/mib_structs.c index 0d2dfd8e..0325cd6a 100644 --- a/src/core/snmp/mib_structs.c +++ b/src/core/snmp/mib_structs.c @@ -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 */ diff --git a/src/core/snmp/msg_in.c b/src/core/snmp/msg_in.c index eb3857f7..095ab919 100644 --- a/src/core/snmp/msg_in.c +++ b/src/core/snmp/msg_in.c @@ -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; } diff --git a/src/include/lwip/snmp.h b/src/include/lwip/snmp.h index 7fc0fda1..d93332be 100644 --- a/src/include/lwip/snmp.h +++ b/src/include/lwip/snmp.h @@ -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_ipindiscards(void); -void snmp_inc_ipoutdiscards(void); -void snmp_inc_ipoutrequests(void); -void snmp_inc_ipunknownprotos(void); -void snmp_inc_ipnoroutes(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_ipindelivers(void); +void snmp_inc_ipoutrequests(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_ipindiscards() -#define snmp_inc_ipoutdiscards() -#define snmp_inc_ipoutrequests() -#define snmp_inc_ipunknownprotos() -#define snmp_inc_ipnoroutes() +#define snmp_inc_ipinhdrerrors() +#define snmp_inc_ipinaddrerrors() #define snmp_inc_ipforwdatagrams() +#define snmp_inc_ipinunknownprotos() +#define snmp_inc_ipindiscards() +#define snmp_inc_ipindelivers() +#define snmp_inc_ipoutrequests() +#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 diff --git a/src/include/lwip/snmp_msg.h b/src/include/lwip/snmp_msg.h index 1b61cc2f..de51e10d 100644 --- a/src/include/lwip/snmp_msg.h +++ b/src/include/lwip/snmp_msg.h @@ -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); diff --git a/src/include/lwip/snmp_structs.h b/src/include/lwip/snmp_structs.h index c5de341e..cf910522 100644 --- a/src/include/lwip/snmp_structs.h +++ b/src/include/lwip/snmp_structs.h @@ -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