Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lwip_snmp_mib2_system.c Source File

lwip_snmp_mib2_system.c

Go to the documentation of this file.
00001 /**
00002  * @file
00003  * Management Information Base II (RFC1213) SYSTEM objects and functions.
00004  */
00005 
00006 /*
00007  * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands.
00008  * All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without modification,
00011  * are permitted provided that the following conditions are met:
00012  *
00013  * 1. Redistributions of source code must retain the above copyright notice,
00014  *    this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright notice,
00016  *    this list of conditions and the following disclaimer in the documentation
00017  *    and/or other materials provided with the distribution.
00018  * 3. The name of the author may not be used to endorse or promote products
00019  *    derived from this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00022  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00023  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00024  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00025  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00026  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00027  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00028  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00029  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00030  * OF SUCH DAMAGE.
00031  *
00032  * Author: Dirk Ziegelmeier <dziegel@gmx.de>
00033  *         Christiaan Simons <christiaan.simons@axon.tv>
00034  */
00035 
00036 #include "lwip/snmp.h"
00037 #include "lwip/apps/snmp.h"
00038 #include "lwip/apps/snmp_core.h"
00039 #include "lwip/apps/snmp_mib2.h"
00040 #include "lwip/apps/snmp_table.h"
00041 #include "lwip/apps/snmp_scalar.h"
00042 #include "lwip/sys.h"
00043 
00044 #include <string.h>
00045 
00046 #if LWIP_SNMP && SNMP_LWIP_MIB2
00047 
00048 #if SNMP_USE_NETCONN
00049 #define SYNC_NODE_NAME(node_name) node_name ## _synced
00050 #define CREATE_LWIP_SYNC_NODE(oid, node_name) \
00051    static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks);
00052 #else
00053 #define SYNC_NODE_NAME(node_name) node_name
00054 #define CREATE_LWIP_SYNC_NODE(oid, node_name)
00055 #endif
00056 
00057 /* --- system .1.3.6.1.2.1.1 ----------------------------------------------------- */
00058 
00059 /** mib-2.system.sysDescr */
00060 static const u8_t   sysdescr_default[] = SNMP_LWIP_MIB2_SYSDESC;
00061 static const u8_t*  sysdescr           = sysdescr_default;
00062 static const u16_t* sysdescr_len       = NULL; /* use strlen for determining len */
00063 
00064 /** mib-2.system.sysContact */
00065 static const u8_t   syscontact_default[]     = SNMP_LWIP_MIB2_SYSCONTACT;
00066 static const u8_t*  syscontact               = syscontact_default;
00067 static const u16_t* syscontact_len           = NULL; /* use strlen for determining len */
00068 static u8_t*        syscontact_wr            = NULL; /* if writable, points to the same buffer as syscontact (required for correct constness) */
00069 static u16_t*       syscontact_wr_len        = NULL; /* if writable, points to the same buffer as syscontact_len (required for correct constness) */
00070 static u16_t        syscontact_bufsize       = 0;    /* 0=not writable */
00071 
00072 /** mib-2.system.sysName */
00073 static const u8_t   sysname_default[]        = SNMP_LWIP_MIB2_SYSNAME;
00074 static const u8_t*  sysname                  = sysname_default;
00075 static const u16_t* sysname_len              = NULL; /* use strlen for determining len */
00076 static u8_t*        sysname_wr               = NULL; /* if writable, points to the same buffer as sysname (required for correct constness) */
00077 static u16_t*       sysname_wr_len           = NULL; /* if writable, points to the same buffer as sysname_len (required for correct constness) */
00078 static u16_t        sysname_bufsize          = 0;    /* 0=not writable */
00079 
00080 /** mib-2.system.sysLocation */
00081 static const u8_t   syslocation_default[]    = SNMP_LWIP_MIB2_SYSLOCATION;
00082 static const u8_t*  syslocation              = syslocation_default;
00083 static const u16_t* syslocation_len           = NULL; /* use strlen for determining len */
00084 static u8_t*        syslocation_wr            = NULL; /* if writable, points to the same buffer as syslocation (required for correct constness) */
00085 static u16_t*       syslocation_wr_len        = NULL; /* if writable, points to the same buffer as syslocation_len (required for correct constness) */
00086 static u16_t        syslocation_bufsize       = 0;    /* 0=not writable */
00087 
00088 /**
00089  * @ingroup snmp_mib2
00090  * Initializes sysDescr pointers.
00091  *
00092  * @param str if non-NULL then copy str pointer
00093  * @param len points to string length, excluding zero terminator
00094  */
00095 void
00096 snmp_mib2_set_sysdescr(const u8_t *str, const u16_t *len)
00097 {
00098   if (str != NULL) {
00099     sysdescr     = str;
00100     sysdescr_len = len;
00101   }
00102 }
00103 
00104 /**
00105  * @ingroup snmp_mib2
00106  * Initializes sysContact pointers
00107  *
00108  * @param ocstr if non-NULL then copy str pointer
00109  * @param ocstrlen points to string length, excluding zero terminator.
00110  *        if set to NULL it is assumed that ocstr is NULL-terminated.
00111  * @param bufsize size of the buffer in bytes.
00112  *        (this is required because the buffer can be overwritten by snmp-set)
00113  *        if ocstrlen is NULL buffer needs space for terminating 0 byte.
00114  *        otherwise complete buffer is used for string.
00115  *        if bufsize is set to 0, the value is regarded as read-only.
00116  */
00117 void
00118 snmp_mib2_set_syscontact(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize)
00119 {
00120   if (ocstr != NULL) {
00121     syscontact         = ocstr;
00122     syscontact_wr      = ocstr;
00123     syscontact_len     = ocstrlen;
00124     syscontact_wr_len  = ocstrlen;
00125     syscontact_bufsize = bufsize;
00126   }
00127 }
00128 
00129 /**
00130  * @ingroup snmp_mib2
00131  * see \ref snmp_mib2_set_syscontact but set pointer to readonly memory
00132  */
00133 void
00134 snmp_mib2_set_syscontact_readonly(const u8_t *ocstr, const u16_t *ocstrlen)
00135 {
00136   if (ocstr != NULL) {
00137     syscontact         = ocstr;
00138     syscontact_len     = ocstrlen;
00139     syscontact_wr      = NULL;
00140     syscontact_wr_len  = NULL;
00141     syscontact_bufsize = 0;
00142   }
00143 }
00144 
00145 
00146 /**
00147  * @ingroup snmp_mib2
00148  * Initializes sysName pointers
00149  *
00150  * @param ocstr if non-NULL then copy str pointer
00151  * @param ocstrlen points to string length, excluding zero terminator.
00152  *        if set to NULL it is assumed that ocstr is NULL-terminated.
00153  * @param bufsize size of the buffer in bytes.
00154  *        (this is required because the buffer can be overwritten by snmp-set)
00155  *        if ocstrlen is NULL buffer needs space for terminating 0 byte.
00156  *        otherwise complete buffer is used for string.
00157  *        if bufsize is set to 0, the value is regarded as read-only.
00158  */
00159 void
00160 snmp_mib2_set_sysname(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize)
00161 {
00162   if (ocstr != NULL) {
00163     sysname         = ocstr;
00164     sysname_wr      = ocstr;
00165     sysname_len     = ocstrlen;
00166     sysname_wr_len  = ocstrlen;
00167     sysname_bufsize = bufsize;
00168   }
00169 }
00170 
00171 /**
00172  * @ingroup snmp_mib2
00173  * see \ref snmp_mib2_set_sysname but set pointer to readonly memory
00174  */
00175 void
00176 snmp_mib2_set_sysname_readonly(const u8_t *ocstr, const u16_t *ocstrlen)
00177 {
00178   if (ocstr != NULL) {
00179     sysname         = ocstr;
00180     sysname_len     = ocstrlen;
00181     sysname_wr      = NULL;
00182     sysname_wr_len  = NULL;
00183     sysname_bufsize = 0;
00184   }
00185 }
00186 
00187 /**
00188  * @ingroup snmp_mib2
00189  * Initializes sysLocation pointers
00190  *
00191  * @param ocstr if non-NULL then copy str pointer
00192  * @param ocstrlen points to string length, excluding zero terminator.
00193  *        if set to NULL it is assumed that ocstr is NULL-terminated.
00194  * @param bufsize size of the buffer in bytes.
00195  *        (this is required because the buffer can be overwritten by snmp-set)
00196  *        if ocstrlen is NULL buffer needs space for terminating 0 byte.
00197  *        otherwise complete buffer is used for string.
00198  *        if bufsize is set to 0, the value is regarded as read-only.
00199  */
00200 void
00201 snmp_mib2_set_syslocation(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize)
00202 {
00203   if (ocstr != NULL) {
00204     syslocation         = ocstr;
00205     syslocation_wr      = ocstr;
00206     syslocation_len     = ocstrlen;
00207     syslocation_wr_len  = ocstrlen;
00208     syslocation_bufsize = bufsize;
00209   }
00210 }
00211 
00212 /**
00213  * @ingroup snmp_mib2
00214  * see \ref snmp_mib2_set_syslocation but set pointer to readonly memory
00215  */
00216 void
00217 snmp_mib2_set_syslocation_readonly(const u8_t *ocstr, const u16_t *ocstrlen)
00218 {
00219   if (ocstr != NULL) {
00220     syslocation         = ocstr;
00221     syslocation_len     = ocstrlen;
00222     syslocation_wr      = NULL;
00223     syslocation_wr_len  = NULL;
00224     syslocation_bufsize = 0;
00225   }
00226 }
00227 
00228 
00229 static s16_t
00230 system_get_value(const struct snmp_scalar_array_node_def *node, void *value)
00231 {
00232   const u8_t*  var = NULL;
00233   const s16_t* var_len;
00234   u16_t result;
00235 
00236   switch (node->oid) {
00237   case 1: /* sysDescr */
00238     var     = sysdescr;
00239     var_len = (const s16_t*)sysdescr_len;
00240     break;
00241   case 2: /* sysObjectID */
00242     {
00243       const struct snmp_obj_id* dev_enterprise_oid = snmp_get_device_enterprise_oid();
00244       MEMCPY(value, dev_enterprise_oid->id, dev_enterprise_oid->len * sizeof(u32_t));
00245       return dev_enterprise_oid->len * sizeof(u32_t);
00246     }
00247   case 3: /* sysUpTime */
00248     MIB2_COPY_SYSUPTIME_TO((u32_t*)value);
00249     return sizeof(u32_t);
00250   case 4: /* sysContact */
00251     var     = syscontact;
00252     var_len = (const s16_t*)syscontact_len;
00253     break;
00254   case 5: /* sysName */
00255     var     = sysname;
00256     var_len = (const s16_t*)sysname_len;
00257     break;
00258   case 6: /* sysLocation */
00259     var     = syslocation;
00260     var_len = (const s16_t*)syslocation_len;
00261     break;
00262   case 7: /* sysServices */
00263     *(s32_t*)value = SNMP_SYSSERVICES;
00264     return sizeof(s32_t);
00265   default:
00266     LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_value(): unknown id: %"S32_F"\n", node->oid));
00267     return 0;
00268   }
00269 
00270   /* handle string values (OID 1,4,5 and 6) */
00271   LWIP_ASSERT("", (value != NULL));
00272   if (var_len == NULL) {
00273     result = (s16_t)strlen((const char*)var);
00274   } else {
00275     result = *var_len;
00276   }
00277   MEMCPY(value, var, result);
00278   return result;
00279 }
00280 
00281 static snmp_err_t
00282 system_set_test(const struct snmp_scalar_array_node_def *node, u16_t len, void *value)
00283 {
00284   snmp_err_t ret = SNMP_ERR_WRONGVALUE;
00285   const u16_t* var_bufsize  = NULL;
00286   const u16_t* var_wr_len;
00287 
00288   LWIP_UNUSED_ARG(value);
00289 
00290   switch (node->oid) {
00291   case 4: /* sysContact */
00292     var_bufsize  = &syscontact_bufsize;
00293     var_wr_len   = syscontact_wr_len;
00294     break;
00295   case 5: /* sysName */
00296     var_bufsize  = &sysname_bufsize;
00297     var_wr_len   = sysname_wr_len;
00298     break;
00299   case 6: /* sysLocation */
00300     var_bufsize  = &syslocation_bufsize;
00301     var_wr_len   = syslocation_wr_len;
00302     break;
00303   default:
00304     LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_set_test(): unknown id: %"S32_F"\n", node->oid));
00305     return ret;
00306   }
00307 
00308   /* check if value is writable at all */
00309   if (*var_bufsize > 0) {
00310     if (var_wr_len == NULL) {
00311       /* we have to take the terminating 0 into account */
00312       if (len < *var_bufsize) {
00313         ret = SNMP_ERR_NOERROR;
00314       }
00315     } else {
00316       if (len <= *var_bufsize) {
00317         ret = SNMP_ERR_NOERROR;
00318       }
00319     }
00320   } else {
00321     ret = SNMP_ERR_NOTWRITABLE;
00322   }
00323 
00324   return ret;
00325 }
00326 
00327 static snmp_err_t
00328 system_set_value(const struct snmp_scalar_array_node_def *node, u16_t len, void *value)
00329 {
00330   u8_t*  var_wr = NULL;
00331   u16_t* var_wr_len;
00332 
00333   switch (node->oid) {
00334   case 4: /* sysContact */
00335     var_wr     = syscontact_wr;
00336     var_wr_len = syscontact_wr_len;
00337     break;
00338   case 5: /* sysName */
00339     var_wr     = sysname_wr;
00340     var_wr_len = sysname_wr_len;
00341     break;
00342   case 6: /* sysLocation */
00343     var_wr     = syslocation_wr;
00344     var_wr_len = syslocation_wr_len;
00345     break;
00346   default:
00347     LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_set_value(): unknown id: %"S32_F"\n", node->oid));
00348     return SNMP_ERR_GENERROR;
00349   }
00350 
00351   /* no need to check size of target buffer, this was already done in set_test method */
00352   LWIP_ASSERT("", var_wr != NULL);
00353   MEMCPY(var_wr, value, len);
00354   
00355   if (var_wr_len == NULL) {
00356     /* add terminating 0 */
00357     var_wr[len] = 0;
00358   } else {
00359     *var_wr_len = len;
00360   }
00361 
00362   return SNMP_ERR_NOERROR;
00363 }
00364 
00365 static const struct snmp_scalar_array_node_def system_nodes[] = {
00366   {1, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY},  /* sysDescr */
00367   {2, SNMP_ASN1_TYPE_OBJECT_ID,    SNMP_NODE_INSTANCE_READ_ONLY},  /* sysObjectID */
00368   {3, SNMP_ASN1_TYPE_TIMETICKS,    SNMP_NODE_INSTANCE_READ_ONLY},  /* sysUpTime */
00369   {4, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysContact */
00370   {5, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysName */
00371   {6, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysLocation */
00372   {7, SNMP_ASN1_TYPE_INTEGER,      SNMP_NODE_INSTANCE_READ_ONLY}   /* sysServices */
00373 };
00374 
00375 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);
00376 
00377 #endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */