diff --git a/src/Filelists.mk b/src/Filelists.mk index e878b2c4..01c6b6ac 100644 --- a/src/Filelists.mk +++ b/src/Filelists.mk @@ -130,6 +130,7 @@ SNMPFILES=$(LWIPDIR)/apps/snmp/snmp_asn1.c \ $(LWIPDIR)/apps/snmp/snmp_mib2_icmp.c \ $(LWIPDIR)/apps/snmp/snmp_mib2_interfaces.c \ $(LWIPDIR)/apps/snmp/snmp_mib2_snmp.c \ + $(LWIPDIR)/apps/snmp/snmp_mib2_system.c \ $(LWIPDIR)/apps/snmp/snmp_mib2_tcp.c \ $(LWIPDIR)/apps/snmp/snmp_mib2_udp.c \ $(LWIPDIR)/apps/snmp/snmp_msg.c \ diff --git a/src/apps/snmp/snmp_mib2.c b/src/apps/snmp/snmp_mib2.c index 3269f4e8..6ffd4c05 100644 --- a/src/apps/snmp/snmp_mib2.c +++ b/src/apps/snmp/snmp_mib2.c @@ -245,32 +245,16 @@ static const struct snmp_node* const at_nodes[] = { static const struct snmp_tree_node at_root = SNMP_CREATE_TREE_NODE(3, at_nodes); #endif /* LWIP_ARP && LWIP_IPV4 */ -/* --- system .1.3.6.1.2.1.1 ----------------------------------------------------- */ -static u16_t system_get_value(const struct snmp_scalar_array_node_def *node, void *value); -static snmp_err_t system_set_test(const struct snmp_scalar_array_node_def *node, u16_t len, void *value); -static snmp_err_t system_set_value(const struct snmp_scalar_array_node_def *node, u16_t len, void *value); - -static const struct snmp_scalar_array_node_def system_nodes[] = { - {1, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* sysDescr */ - {2, SNMP_ASN1_TYPE_OBJECT_ID, SNMP_NODE_INSTANCE_READ_ONLY}, /* sysObjectID */ - {3, SNMP_ASN1_TYPE_TIMETICKS, SNMP_NODE_INSTANCE_READ_ONLY}, /* sysUpTime */ - {4, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysContact */ - {5, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysName */ - {6, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysLocation */ - {7, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY} /* sysServices */ -}; - -static const struct snmp_scalar_array_node system_node = SNMP_SCALAR_CREATE_ARRAY_NODE(1, system_nodes, system_get_value, system_set_test, system_set_value); - /* --- mib-2 .1.3.6.1.2.1 ----------------------------------------------------- */ extern const struct snmp_scalar_array_node snmp_mib2_snmp_root; extern const struct snmp_tree_node snmp_mib2_udp_root; extern const struct snmp_tree_node snmp_mib2_tcp_root; extern const struct snmp_scalar_array_node snmp_mib2_icmp_root; extern const struct snmp_tree_node snmp_mib2_interface_root; +extern const struct snmp_scalar_array_node snmp_mib2_system_node; static const struct snmp_node* const mib2_nodes[] = { - &system_node.node.node, + &snmp_mib2_system_node.node.node, &snmp_mib2_interface_root.node, #if LWIP_ARP && LWIP_IPV4 &at_root.node, @@ -295,293 +279,6 @@ static const struct snmp_tree_node mib2_root = SNMP_CREATE_TREE_NODE(1, mib2_nod static const u32_t mib2_base_oid_arr[] = { 1,3,6,1,2,1 }; const struct snmp_mib mib2 = SNMP_MIB_CREATE(mib2_base_oid_arr, &mib2_root.node); -/** mib-2.system.sysDescr */ -static const u8_t sysdescr_default[] = SNMP_LWIP_MIB2_SYSDESC; -static const u8_t* sysdescr = sysdescr_default; -static const u16_t* sysdescr_len = NULL; /* use strlen for determining len */ - -/** mib-2.system.sysContact */ -static const u8_t syscontact_default[] = SNMP_LWIP_MIB2_SYSCONTACT; -static const u8_t* syscontact = syscontact_default; -static const u16_t* syscontact_len = NULL; /* use strlen for determining len */ -static u8_t* syscontact_wr = NULL; /* if writable, points to the same buffer as syscontact (required for correct constness) */ -static u16_t* syscontact_wr_len = NULL; /* if writable, points to the same buffer as syscontact_len (required for correct constness) */ -static u16_t syscontact_bufsize = 0; /* 0=not writable */ - -/** mib-2.system.sysName */ -static const u8_t sysname_default[] = SNMP_LWIP_MIB2_SYSNAME; -static const u8_t* sysname = sysname_default; -static const u16_t* sysname_len = NULL; /* use strlen for determining len */ -static u8_t* sysname_wr = NULL; /* if writable, points to the same buffer as sysname (required for correct constness) */ -static u16_t* sysname_wr_len = NULL; /* if writable, points to the same buffer as sysname_len (required for correct constness) */ -static u16_t sysname_bufsize = 0; /* 0=not writable */ - -/** mib-2.system.sysLocation */ -static const u8_t syslocation_default[] = SNMP_LWIP_MIB2_SYSLOCATION; -static const u8_t* syslocation = syslocation_default; -static const u16_t* syslocation_len = NULL; /* use strlen for determining len */ -static u8_t* syslocation_wr = NULL; /* if writable, points to the same buffer as syslocation (required for correct constness) */ -static u16_t* syslocation_wr_len = NULL; /* if writable, points to the same buffer as syslocation_len (required for correct constness) */ -static u16_t syslocation_bufsize = 0; /* 0=not writable */ - -/** - * Initializes sysDescr pointers. - * - * @param str if non-NULL then copy str pointer - * @param len points to string length, excluding zero terminator - */ -void snmp_mib2_set_sysdescr(const u8_t *str, const u16_t *len) -{ - if (str != NULL) { - sysdescr = str; - sysdescr_len = len; - } -} - -/** - * Initializes sysContact pointers, - * e.g. ptrs to non-volatile memory external to lwIP. - * - * @param ocstr if non-NULL then copy str pointer - * @param ocstrlen points to string length, excluding zero terminator. - * if set to NULL it is assumed that ocstr is NULL-terminated. - * @param bufsize size of the buffer in bytes. - * (this is required because the buffer can be overwritten by snmp-set) - * if ocstrlen is NULL buffer needs space for terminating 0 byte. - * otherwise complete buffer is used for string. - * if bufsize is set to 0, the value is regarded as read-only. - */ -void snmp_mib2_set_syscontact(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize) -{ - if (ocstr != NULL) { - syscontact = ocstr; - syscontact_wr = ocstr; - syscontact_len = ocstrlen; - syscontact_wr_len = ocstrlen; - syscontact_bufsize = bufsize; - } -} - -void snmp_mib2_set_syscontact_readonly(const u8_t *ocstr, const u16_t *ocstrlen) -{ - if (ocstr != NULL) { - syscontact = ocstr; - syscontact_len = ocstrlen; - syscontact_wr = NULL; - syscontact_wr_len = NULL; - syscontact_bufsize = 0; - } -} - - -/** - * Initializes sysName pointers, - * e.g. ptrs to non-volatile memory external to lwIP. - * - * @param ocstr if non-NULL then copy str pointer - * @param ocstrlen points to string length, excluding zero terminator. - * if set to NULL it is assumed that ocstr is NULL-terminated. - * @param bufsize size of the buffer in bytes. - * (this is required because the buffer can be overwritten by snmp-set) - * if ocstrlen is NULL buffer needs space for terminating 0 byte. - * otherwise complete buffer is used for string. - * if bufsize is set to 0, the value is regarded as read-only. - */ -void snmp_mib2_set_sysname(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize) -{ - if (ocstr != NULL) { - sysname = ocstr; - sysname_wr = ocstr; - sysname_len = ocstrlen; - sysname_wr_len = ocstrlen; - sysname_bufsize = bufsize; - } -} - -void snmp_mib2_set_sysname_readonly(const u8_t *ocstr, const u16_t *ocstrlen) -{ - if (ocstr != NULL) { - sysname = ocstr; - sysname_len = ocstrlen; - sysname_wr = NULL; - sysname_wr_len = NULL; - sysname_bufsize = 0; - } -} - -/** - * Initializes sysLocation pointers, - * e.g. ptrs to non-volatile memory external to lwIP. - * - * @param ocstr if non-NULL then copy str pointer - * @param ocstrlen points to string length, excluding zero terminator. - * if set to NULL it is assumed that ocstr is NULL-terminated. - * @param bufsize size of the buffer in bytes. - * (this is required because the buffer can be overwritten by snmp-set) - * if ocstrlen is NULL buffer needs space for terminating 0 byte. - * otherwise complete buffer is used for string. - * if bufsize is set to 0, the value is regarded as read-only. - */ -void snmp_mib2_set_syslocation(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize) -{ - if (ocstr != NULL) { - syslocation = ocstr; - syslocation_wr = ocstr; - syslocation_len = ocstrlen; - syslocation_wr_len = ocstrlen; - syslocation_bufsize = bufsize; - } -} - -void snmp_mib2_set_syslocation_readonly(const u8_t *ocstr, const u16_t *ocstrlen) -{ - if (ocstr != NULL) { - syslocation = ocstr; - syslocation_len = ocstrlen; - syslocation_wr = NULL; - syslocation_wr_len = NULL; - syslocation_bufsize = 0; - } -} - - -/* --- system .1.3.6.1.2.1.1 ----------------------------------------------------- */ - -static u16_t -system_get_value(const struct snmp_scalar_array_node_def *node, void *value) -{ - const u8_t* var = NULL; - const u16_t* var_len; - u16_t result; - - switch (node->oid) { - case 1: /* sysDescr */ - var = sysdescr; - var_len = sysdescr_len; - break; - case 2: /* sysObjectID */ - { - const struct snmp_obj_id* dev_enterprise_oid = snmp_get_device_enterprise_oid(); - MEMCPY(value, dev_enterprise_oid->id, dev_enterprise_oid->len * sizeof(u32_t)); - return dev_enterprise_oid->len * sizeof(u32_t); - } - case 3: /* sysUpTime */ - MIB2_COPY_SYSUPTIME_TO((u32_t*)value); - return sizeof(u32_t); - case 4: /* sysContact */ - var = syscontact; - var_len = syscontact_len; - break; - case 5: /* sysName */ - var = sysname; - var_len = sysname_len; - break; - case 6: /* sysLocation */ - var = syslocation; - var_len = syslocation_len; - break; - case 7: /* sysServices */ - *(s32_t*)value = SNMP_SYSSERVICES; - return sizeof(s32_t); - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_value(): unknown id: %"S32_F"\n", node->oid)); - return 0; - } - - /* handle string values (OID 1,4,5 and 6) */ - LWIP_ASSERT("", (value != NULL)); - if (var_len == NULL) { - result = (u16_t)strlen((const char*)var); - } else { - result = *var_len; - } - MEMCPY(value, var, result); - return result; -} - -static snmp_err_t -system_set_test(const struct snmp_scalar_array_node_def *node, u16_t len, void *value) -{ - snmp_err_t ret = SNMP_ERR_WRONGVALUE; - const u16_t* var_bufsize = NULL; - const u16_t* var_wr_len; - - LWIP_UNUSED_ARG(value); - - switch (node->oid) { - case 4: /* sysContact */ - var_bufsize = &syscontact_bufsize; - var_wr_len = syscontact_wr_len; - break; - case 5: /* sysName */ - var_bufsize = &sysname_bufsize; - var_wr_len = sysname_wr_len; - break; - case 6: /* sysLocation */ - var_bufsize = &syslocation_bufsize; - var_wr_len = syslocation_wr_len; - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_set_test(): unknown id: %"S32_F"\n", node->oid)); - return ret; - } - - /* check if value is writable at all */ - if (*var_bufsize > 0) { - if (var_wr_len == NULL) { - /* we have to take the terminating 0 into account */ - if (len < *var_bufsize) { - ret = SNMP_ERR_NOERROR; - } - } else { - if (len <= *var_bufsize) { - ret = SNMP_ERR_NOERROR; - } - } - } else { - ret = SNMP_ERR_NOTWRITABLE; - } - - return ret; -} - -static snmp_err_t -system_set_value(const struct snmp_scalar_array_node_def *node, u16_t len, void *value) -{ - u8_t* var_wr = NULL; - u16_t* var_wr_len; - - switch (node->oid) { - case 4: /* sysContact */ - var_wr = syscontact_wr; - var_wr_len = syscontact_wr_len; - break; - case 5: /* sysName */ - var_wr = sysname_wr; - var_wr_len = sysname_wr_len; - break; - case 6: /* sysLocation */ - var_wr = syslocation_wr; - var_wr_len = syslocation_wr_len; - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_set_value(): unknown id: %"S32_F"\n", node->oid)); - return SNMP_ERR_GENERROR; - } - - /* no need to check size of target buffer, this was already done in set_test method */ - LWIP_ASSERT("", var_wr != NULL); - MEMCPY(var_wr, value, len); - - if (var_wr_len == NULL) { - /* add terminating 0 */ - var_wr[len] = 0; - } else { - *var_wr_len = len; - } - - return SNMP_ERR_NOERROR; -} #if LWIP_IPV4 /* --- ip .1.3.6.1.2.1.4 ----------------------------------------------------- */ diff --git a/src/apps/snmp/snmp_mib2_interfaces.c b/src/apps/snmp/snmp_mib2_interfaces.c index ef0cbd2e..ac5127e2 100644 --- a/src/apps/snmp/snmp_mib2_interfaces.c +++ b/src/apps/snmp/snmp_mib2_interfaces.c @@ -39,7 +39,7 @@ #include "lwip/apps/snmp_mib2.h" #include "lwip/apps/snmp_table.h" #include "lwip/apps/snmp_scalar.h" -#include "lwip/icmp.h" +#include "lwip/netif.h" #include "lwip/stats.h" #if SNMP_USE_NETCONN diff --git a/src/apps/snmp/snmp_mib2_system.c b/src/apps/snmp/snmp_mib2_system.c new file mode 100644 index 00000000..c0f8938e --- /dev/null +++ b/src/apps/snmp/snmp_mib2_system.c @@ -0,0 +1,357 @@ +/** + * @file + * Management Information Base II (RFC1213) objects and functions. + */ + +/* + * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * Author: Dirk Ziegelmeier + * Christiaan Simons + */ + +#include "lwip/snmp.h" +#include "lwip/apps/snmp.h" +#include "lwip/apps/snmp_core.h" +#include "lwip/apps/snmp_mib2.h" +#include "lwip/apps/snmp_table.h" +#include "lwip/apps/snmp_scalar.h" + +#if SNMP_USE_NETCONN +#define SYNC_NODE_NAME(node_name) node_name ## _synced +#define CREATE_LWIP_SYNC_NODE(oid, node_name) \ + static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks); +#else +#define SYNC_NODE_NAME(node_name) node_name +#define CREATE_LWIP_SYNC_NODE(oid, node_name) +#endif + +/* --- system .1.3.6.1.2.1.1 ----------------------------------------------------- */ + +/** mib-2.system.sysDescr */ +static const u8_t sysdescr_default[] = SNMP_LWIP_MIB2_SYSDESC; +static const u8_t* sysdescr = sysdescr_default; +static const u16_t* sysdescr_len = NULL; /* use strlen for determining len */ + +/** mib-2.system.sysContact */ +static const u8_t syscontact_default[] = SNMP_LWIP_MIB2_SYSCONTACT; +static const u8_t* syscontact = syscontact_default; +static const u16_t* syscontact_len = NULL; /* use strlen for determining len */ +static u8_t* syscontact_wr = NULL; /* if writable, points to the same buffer as syscontact (required for correct constness) */ +static u16_t* syscontact_wr_len = NULL; /* if writable, points to the same buffer as syscontact_len (required for correct constness) */ +static u16_t syscontact_bufsize = 0; /* 0=not writable */ + +/** mib-2.system.sysName */ +static const u8_t sysname_default[] = SNMP_LWIP_MIB2_SYSNAME; +static const u8_t* sysname = sysname_default; +static const u16_t* sysname_len = NULL; /* use strlen for determining len */ +static u8_t* sysname_wr = NULL; /* if writable, points to the same buffer as sysname (required for correct constness) */ +static u16_t* sysname_wr_len = NULL; /* if writable, points to the same buffer as sysname_len (required for correct constness) */ +static u16_t sysname_bufsize = 0; /* 0=not writable */ + +/** mib-2.system.sysLocation */ +static const u8_t syslocation_default[] = SNMP_LWIP_MIB2_SYSLOCATION; +static const u8_t* syslocation = syslocation_default; +static const u16_t* syslocation_len = NULL; /* use strlen for determining len */ +static u8_t* syslocation_wr = NULL; /* if writable, points to the same buffer as syslocation (required for correct constness) */ +static u16_t* syslocation_wr_len = NULL; /* if writable, points to the same buffer as syslocation_len (required for correct constness) */ +static u16_t syslocation_bufsize = 0; /* 0=not writable */ + +/** + * Initializes sysDescr pointers. + * + * @param str if non-NULL then copy str pointer + * @param len points to string length, excluding zero terminator + */ +void +snmp_mib2_set_sysdescr(const u8_t *str, const u16_t *len) +{ + if (str != NULL) { + sysdescr = str; + sysdescr_len = len; + } +} + +/** + * Initializes sysContact pointers, + * e.g. ptrs to non-volatile memory external to lwIP. + * + * @param ocstr if non-NULL then copy str pointer + * @param ocstrlen points to string length, excluding zero terminator. + * if set to NULL it is assumed that ocstr is NULL-terminated. + * @param bufsize size of the buffer in bytes. + * (this is required because the buffer can be overwritten by snmp-set) + * if ocstrlen is NULL buffer needs space for terminating 0 byte. + * otherwise complete buffer is used for string. + * if bufsize is set to 0, the value is regarded as read-only. + */ +void +snmp_mib2_set_syscontact(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize) +{ + if (ocstr != NULL) { + syscontact = ocstr; + syscontact_wr = ocstr; + syscontact_len = ocstrlen; + syscontact_wr_len = ocstrlen; + syscontact_bufsize = bufsize; + } +} + +void +snmp_mib2_set_syscontact_readonly(const u8_t *ocstr, const u16_t *ocstrlen) +{ + if (ocstr != NULL) { + syscontact = ocstr; + syscontact_len = ocstrlen; + syscontact_wr = NULL; + syscontact_wr_len = NULL; + syscontact_bufsize = 0; + } +} + + +/** + * Initializes sysName pointers, + * e.g. ptrs to non-volatile memory external to lwIP. + * + * @param ocstr if non-NULL then copy str pointer + * @param ocstrlen points to string length, excluding zero terminator. + * if set to NULL it is assumed that ocstr is NULL-terminated. + * @param bufsize size of the buffer in bytes. + * (this is required because the buffer can be overwritten by snmp-set) + * if ocstrlen is NULL buffer needs space for terminating 0 byte. + * otherwise complete buffer is used for string. + * if bufsize is set to 0, the value is regarded as read-only. + */ +void +snmp_mib2_set_sysname(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize) +{ + if (ocstr != NULL) { + sysname = ocstr; + sysname_wr = ocstr; + sysname_len = ocstrlen; + sysname_wr_len = ocstrlen; + sysname_bufsize = bufsize; + } +} + +void +snmp_mib2_set_sysname_readonly(const u8_t *ocstr, const u16_t *ocstrlen) +{ + if (ocstr != NULL) { + sysname = ocstr; + sysname_len = ocstrlen; + sysname_wr = NULL; + sysname_wr_len = NULL; + sysname_bufsize = 0; + } +} + +/** + * Initializes sysLocation pointers, + * e.g. ptrs to non-volatile memory external to lwIP. + * + * @param ocstr if non-NULL then copy str pointer + * @param ocstrlen points to string length, excluding zero terminator. + * if set to NULL it is assumed that ocstr is NULL-terminated. + * @param bufsize size of the buffer in bytes. + * (this is required because the buffer can be overwritten by snmp-set) + * if ocstrlen is NULL buffer needs space for terminating 0 byte. + * otherwise complete buffer is used for string. + * if bufsize is set to 0, the value is regarded as read-only. + */ +void +snmp_mib2_set_syslocation(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize) +{ + if (ocstr != NULL) { + syslocation = ocstr; + syslocation_wr = ocstr; + syslocation_len = ocstrlen; + syslocation_wr_len = ocstrlen; + syslocation_bufsize = bufsize; + } +} + +void +snmp_mib2_set_syslocation_readonly(const u8_t *ocstr, const u16_t *ocstrlen) +{ + if (ocstr != NULL) { + syslocation = ocstr; + syslocation_len = ocstrlen; + syslocation_wr = NULL; + syslocation_wr_len = NULL; + syslocation_bufsize = 0; + } +} + + +static u16_t +system_get_value(const struct snmp_scalar_array_node_def *node, void *value) +{ + const u8_t* var = NULL; + const u16_t* var_len; + u16_t result; + + switch (node->oid) { + case 1: /* sysDescr */ + var = sysdescr; + var_len = sysdescr_len; + break; + case 2: /* sysObjectID */ + { + const struct snmp_obj_id* dev_enterprise_oid = snmp_get_device_enterprise_oid(); + MEMCPY(value, dev_enterprise_oid->id, dev_enterprise_oid->len * sizeof(u32_t)); + return dev_enterprise_oid->len * sizeof(u32_t); + } + case 3: /* sysUpTime */ + MIB2_COPY_SYSUPTIME_TO((u32_t*)value); + return sizeof(u32_t); + case 4: /* sysContact */ + var = syscontact; + var_len = syscontact_len; + break; + case 5: /* sysName */ + var = sysname; + var_len = sysname_len; + break; + case 6: /* sysLocation */ + var = syslocation; + var_len = syslocation_len; + break; + case 7: /* sysServices */ + *(s32_t*)value = SNMP_SYSSERVICES; + return sizeof(s32_t); + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_value(): unknown id: %"S32_F"\n", node->oid)); + return 0; + } + + /* handle string values (OID 1,4,5 and 6) */ + LWIP_ASSERT("", (value != NULL)); + if (var_len == NULL) { + result = (u16_t)strlen((const char*)var); + } else { + result = *var_len; + } + MEMCPY(value, var, result); + return result; +} + +static snmp_err_t +system_set_test(const struct snmp_scalar_array_node_def *node, u16_t len, void *value) +{ + snmp_err_t ret = SNMP_ERR_WRONGVALUE; + const u16_t* var_bufsize = NULL; + const u16_t* var_wr_len; + + LWIP_UNUSED_ARG(value); + + switch (node->oid) { + case 4: /* sysContact */ + var_bufsize = &syscontact_bufsize; + var_wr_len = syscontact_wr_len; + break; + case 5: /* sysName */ + var_bufsize = &sysname_bufsize; + var_wr_len = sysname_wr_len; + break; + case 6: /* sysLocation */ + var_bufsize = &syslocation_bufsize; + var_wr_len = syslocation_wr_len; + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_set_test(): unknown id: %"S32_F"\n", node->oid)); + return ret; + } + + /* check if value is writable at all */ + if (*var_bufsize > 0) { + if (var_wr_len == NULL) { + /* we have to take the terminating 0 into account */ + if (len < *var_bufsize) { + ret = SNMP_ERR_NOERROR; + } + } else { + if (len <= *var_bufsize) { + ret = SNMP_ERR_NOERROR; + } + } + } else { + ret = SNMP_ERR_NOTWRITABLE; + } + + return ret; +} + +static snmp_err_t +system_set_value(const struct snmp_scalar_array_node_def *node, u16_t len, void *value) +{ + u8_t* var_wr = NULL; + u16_t* var_wr_len; + + switch (node->oid) { + case 4: /* sysContact */ + var_wr = syscontact_wr; + var_wr_len = syscontact_wr_len; + break; + case 5: /* sysName */ + var_wr = sysname_wr; + var_wr_len = sysname_wr_len; + break; + case 6: /* sysLocation */ + var_wr = syslocation_wr; + var_wr_len = syslocation_wr_len; + break; + default: + LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_set_value(): unknown id: %"S32_F"\n", node->oid)); + return SNMP_ERR_GENERROR; + } + + /* no need to check size of target buffer, this was already done in set_test method */ + LWIP_ASSERT("", var_wr != NULL); + MEMCPY(var_wr, value, len); + + if (var_wr_len == NULL) { + /* add terminating 0 */ + var_wr[len] = 0; + } else { + *var_wr_len = len; + } + + return SNMP_ERR_NOERROR; +} + +static const struct snmp_scalar_array_node_def system_nodes[] = { + {1, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* sysDescr */ + {2, SNMP_ASN1_TYPE_OBJECT_ID, SNMP_NODE_INSTANCE_READ_ONLY}, /* sysObjectID */ + {3, SNMP_ASN1_TYPE_TIMETICKS, SNMP_NODE_INSTANCE_READ_ONLY}, /* sysUpTime */ + {4, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysContact */ + {5, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysName */ + {6, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysLocation */ + {7, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY} /* sysServices */ +}; + +const struct snmp_scalar_array_node snmp_mib2_system_node = SNMP_SCALAR_CREATE_ARRAY_NODE(1, system_nodes, system_get_value, system_set_test, system_set_value);