snmp_mib_impl.c
Go to the documentation of this file.
1 /**
2  * @file snmp_mib_impl.c
3  * @brief SNMP MIB module implementation
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneTCP Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL SNMP_TRACE_LEVEL
31 
32 //Dependencies
33 #include "core/net.h"
34 #include "mibs/mib_common.h"
35 #include "mibs/snmp_mib_module.h"
36 #include "mibs/snmp_mib_impl.h"
37 #include "snmp/snmp_agent.h"
38 #include "core/crypto.h"
39 #include "encoding/asn1.h"
40 #include "encoding/oid.h"
41 #include "debug.h"
42 
43 //Check TCP/IP stack configuration
44 #if (SNMP_MIB_SUPPORT == ENABLED)
45 
46 
47 /**
48  * @brief SNMP MIB module initialization
49  * @return Error code
50  **/
51 
53 {
54  SnmpMibSysGroup *sysGroup;
55  SnmpMibSetGroup *setGroup;
56 
57  //Debug message
58  TRACE_INFO("Initializing SNMP-MIB base...\r\n");
59 
60  //Clear SNMP MIB base
61  memset(&snmpMibBase, 0, sizeof(snmpMibBase));
62 
63  //Point to the system group
64  sysGroup = &snmpMibBase.sysGroup;
65 
66 #if (SNMP_MIB_SYS_DESCR_SIZE > 0)
67  //sysDescr object
68  strcpy(sysGroup->sysDescr, "Description");
69  sysGroup->sysDescrLen = strlen(sysGroup->sysDescr);
70 #endif
71 
72 #if (SNMP_MIB_SYS_OBJECT_ID_SIZE > 0)
73  //sysObjectID object
74  sysGroup->sysObjectID[0] = 0;
75  sysGroup->sysObjectIDLen = 1;
76 #endif
77 
78 #if (SNMP_MIB_SYS_CONTACT_SIZE > 0)
79  //sysContact object
80  strcpy(sysGroup->sysContact, "Contact");
81  sysGroup->sysContactLen = strlen(sysGroup->sysContact);
82 #endif
83 
84 #if (SNMP_MIB_SYS_NAME_SIZE > 0)
85  //sysName object
86  strcpy(sysGroup->sysName, "Name");
87  sysGroup->sysNameLen = strlen(sysGroup->sysName);
88 #endif
89 
90 #if (SNMP_MIB_SYS_LOCATION_SIZE > 0)
91  //sysLocation object
92  strcpy(sysGroup->sysLocation, "Location");
93  sysGroup->sysLocationLen = strlen(sysGroup->sysLocation);
94 #endif
95 
96  //sysServices object
98 
99  //Point to the set group
100  setGroup = &snmpMibBase.setGroup;
101 
102  //snmpSetSerialNo object
103  setGroup->snmpSetSerialNo = netGetRandRange(1, INT32_MAX);
104 
105  //Successful processing
106  return NO_ERROR;
107 }
108 
109 
110 /**
111  * @brief Load SNMP MIB module
112  * @param[in] context Pointer to the SNMP agent context
113  * @return Error code
114  **/
115 
116 error_t snmpMibLoad(void *context)
117 {
118  //Register SNMP agent context
119  snmpMibBase.context = context;
120 
121  //Successful processing
122  return NO_ERROR;
123 }
124 
125 
126 /**
127  * @brief Unload SNMP MIB module
128  * @param[in] context Pointer to the SNMP agent context
129  **/
130 
131 void snmpMibUnload(void *context)
132 {
133  //Unregister SNMP agent context
134  snmpMibBase.context = NULL;
135 }
136 
137 
138 /**
139  * @brief Lock SNMP MIB base
140  **/
141 
142 void snmpMibLock(void)
143 {
144 }
145 
146 
147 /**
148  * @brief Unlock SNMP MIB base
149  **/
150 
151 void snmpMibUnlock(void)
152 {
153 }
154 
155 
156 /**
157  * @brief Get sysUpTime object value
158  * @param[in] object Pointer to the MIB object descriptor
159  * @param[in] oid Object identifier (object name and instance identifier)
160  * @param[in] oidLen Length of the OID, in bytes
161  * @param[out] value Object value
162  * @param[in,out] valueLen Length of the object value, in bytes
163  * @return Error code
164  **/
165 
166 error_t snmpMibGetSysUpTime(const MibObject *object, const uint8_t *oid,
167  size_t oidLen, MibVariant *value, size_t *valueLen)
168 {
169  //Get object value
170  value->timeTicks = osGetSystemTime() / 10;
171 
172  //Successful processing
173  return NO_ERROR;
174 }
175 
176 
177 /**
178  * @brief Get sysOREntry object value
179  * @param[in] object Pointer to the MIB object descriptor
180  * @param[in] oid Object identifier (object name and instance identifier)
181  * @param[in] oidLen Length of the OID, in bytes
182  * @param[out] value Object value
183  * @param[in,out] valueLen Length of the object value, in bytes
184  * @return Error code
185  **/
186 
187 error_t snmpMibGetSysOREntry(const MibObject *object, const uint8_t *oid,
188  size_t oidLen, MibVariant *value, size_t *valueLen)
189 {
190  error_t error;
191  size_t n;
192  uint_t index;
193  SnmpAgentContext *context;
194  const MibModule *mibModule;
195 
196  //Point to the instance identifier
197  n = object->oidLen;
198 
199  //sysORIndex is used as instance identifier
200  error = mibDecodeIndex(oid, oidLen, &n, &index);
201  //Invalid instance identifier?
202  if(error)
203  return error;
204 
205  //Sanity check
206  if(n != oidLen)
208 
209  //Check index range
210  if(index < 1 || index > SNMP_AGENT_MAX_MIBS)
212 
213  //Point to the SNMP agent context
214  context = (SnmpAgentContext *) snmpMibBase.context;
215  //Sanity check
216  if(context == NULL)
218 
219  //Point to the MIB
220  mibModule = context->mibTable[index - 1];
221  //Make sure the MIB is properly loaded
222  if(mibModule == NULL)
224 
225  //sysORID object?
226  if(!strcmp(object->name, "sysORID"))
227  {
228  //Make sure the buffer is large enough to hold the entire object
229  if(*valueLen >= mibModule->oidLen)
230  {
231  //Copy object value
232  memcpy(value->octetString, mibModule->oid, mibModule->oidLen);
233  //Return object length
234  *valueLen = mibModule->oidLen;
235  }
236  else
237  {
238  //Report an error
239  error = ERROR_BUFFER_OVERFLOW;
240  }
241  }
242  //sysORDescr object?
243  else if(!strcmp(object->name, "sysORDescr"))
244  {
245  //Retrieve the length of the MIB name
246  n = strlen(mibModule->name);
247 
248  //Make sure the buffer is large enough to hold the entire object
249  if(*valueLen >= n)
250  {
251  //Copy object value
252  memcpy(value->octetString, mibModule->name, n);
253  //Return object length
254  *valueLen = n;
255  }
256  else
257  {
258  //Report an error
259  error = ERROR_BUFFER_OVERFLOW;
260  }
261  }
262  //sysORUpTime object?
263  else if(!strcmp(object->name, "sysORUpTime"))
264  {
265  //Get object value
266  value->timeTicks = 0;
267  }
268  //Unknown object?
269  else
270  {
271  //The specified object does not exist
272  error = ERROR_OBJECT_NOT_FOUND;
273  }
274 
275  //Return status code
276  return error;
277 }
278 
279 
280 /**
281  * @brief Get next sysOREntry object
282  * @param[in] object Pointer to the MIB object descriptor
283  * @param[in] oid Object identifier
284  * @param[in] oidLen Length of the OID, in bytes
285  * @param[out] nextOid OID of the next object in the MIB
286  * @param[out] nextOidLen Length of the next object identifier, in bytes
287  * @return Error code
288  **/
289 
290 error_t snmpMibGetNextSysOREntry(const MibObject *object, const uint8_t *oid,
291  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
292 {
293  error_t error;
294  size_t n;
295  uint_t index;
296  SnmpAgentContext *context;
297 
298  //Point to the SNMP agent context
299  context = (SnmpAgentContext *) snmpMibBase.context;
300  //Sanity check
301  if(context == NULL)
302  return ERROR_OBJECT_NOT_FOUND;
303 
304  //Make sure the buffer is large enough to hold the OID prefix
305  if(*nextOidLen < object->oidLen)
306  return ERROR_BUFFER_OVERFLOW;
307 
308  //Copy OID prefix
309  memcpy(nextOid, object->oid, object->oidLen);
310 
311  //Loop through existing MIBs
312  for(index = 1; index <= SNMP_AGENT_MAX_MIBS; index++)
313  {
314  //Make sure the MIB is properly loaded
315  if(context->mibTable[index - 1] != NULL)
316  {
317  //Append the instance identifier to the OID prefix
318  n = object->oidLen;
319 
320  //sysORIndex is used as instance identifier
321  error = mibEncodeIndex(nextOid, *nextOidLen, &n, index);
322  //Any error to report?
323  if(error)
324  return error;
325 
326  //Check whether the resulting object identifier lexicographically
327  //follows the specified OID
328  if(oidComp(nextOid, n, oid, oidLen) > 0)
329  {
330  //Save the length of the resulting object identifier
331  *nextOidLen = n;
332  //Next object found
333  return NO_ERROR;
334  }
335  }
336  }
337 
338  //The specified OID does not lexicographically precede the name
339  //of some object
340  return ERROR_OBJECT_NOT_FOUND;
341 }
342 
343 
344 /**
345  * @brief Get snmpTrapOID object value
346  * @param[in] object Pointer to the MIB object descriptor
347  * @param[in] oid Object identifier (object name and instance identifier)
348  * @param[in] oidLen Length of the OID, in bytes
349  * @param[out] value Object value
350  * @param[in,out] valueLen Length of the object value, in bytes
351  * @return Error code
352  **/
353 
354 error_t snmpv2MibGetSnmpTrapOID(const MibObject *object, const uint8_t *oid,
355  size_t oidLen, MibVariant *value, size_t *valueLen)
356 {
357  //Not implemented
358  *valueLen = 0;
359 
360  //Return status code
361  return NO_ERROR;
362 }
363 
364 
365 /**
366  * @brief Get snmpTrapEnterprise object value
367  * @param[in] object Pointer to the MIB object descriptor
368  * @param[in] oid Object identifier (object name and instance identifier)
369  * @param[in] oidLen Length of the OID, in bytes
370  * @param[out] value Object value
371  * @param[in,out] valueLen Length of the object value, in bytes
372  * @return Error code
373  **/
374 
375 error_t snmpv2MibGetSnmpTrapEnterprise(const MibObject *object, const uint8_t *oid,
376  size_t oidLen, MibVariant *value, size_t *valueLen)
377 {
378  SnmpAgentContext *context;
379 
380  //Point to the SNMP agent context
381  context = (SnmpAgentContext *) snmpMibBase.context;
382  //Sanity check
383  if(context == NULL)
384  return ERROR_OBJECT_NOT_FOUND;
385 
386  //Make sure the buffer is large enough to hold the enterprise OID
387  if(*valueLen < context->enterpriseOidLen)
388  return ERROR_BUFFER_OVERFLOW;
389 
390  //Copy enterprise OID
391  memcpy(value->octetString, context->enterpriseOid,
392  context->enterpriseOidLen);
393 
394  //Return object length
395  *valueLen = context->enterpriseOidLen;
396 
397  //Return status code
398  return NO_ERROR;
399 }
400 
401 
402 /**
403  * @brief Set snmpSetSerialNo object value
404  * @param[in] object Pointer to the MIB object descriptor
405  * @param[in] oid Object identifier (object name and instance identifier)
406  * @param[in] oidLen Length of the OID, in bytes
407  * @param[in] value Object value
408  * @param[in] valueLen Length of the object value, in bytes
409  * @param[in] commit This flag tells whether the changes shall be committed
410  * to the MIB base
411  * @return Error code
412  **/
413 
414 error_t snmpMibSetSnmpSetSerialNo(const MibObject *object, const uint8_t *oid,
415  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
416 {
417  //Test and increment spin lock
419  value->integer, commit);
420 }
421 
422 
423 /**
424  * @brief Get snmpSetSerialNo object value
425  * @param[in] object Pointer to the MIB object descriptor
426  * @param[in] oid Object identifier (object name and instance identifier)
427  * @param[in] oidLen Length of the OID, in bytes
428  * @param[out] value Object value
429  * @param[in,out] valueLen Length of the object value, in bytes
430  * @return Error code
431  **/
432 
433 error_t snmpMibGetSnmpSetSerialNo(const MibObject *object, const uint8_t *oid,
434  size_t oidLen, MibVariant *value, size_t *valueLen)
435 {
436  //Get the current value of the spin lock
438 
439  //Return status code
440  return NO_ERROR;
441 }
442 
443 #endif
SNMP MIB module implementation.
char_t sysContact[SNMP_MIB_SYS_CONTACT_SIZE]
error_t mibDecodeIndex(const uint8_t *oid, size_t oidLen, size_t *pos, uint_t *index)
Decode instance identifier (index)
Definition: mib_common.c:62
systime_t osGetSystemTime(void)
Retrieve system time.
size_t oidLen
Definition: mib_common.h:289
TCP/IP stack core.
uint8_t oid[MIB_MAX_OID_SIZE]
Definition: mib_common.h:288
Debugging facilities.
#define MibObject
Definition: mib_common.h:44
General definitions for cryptographic algorithms.
SnmpMibSetGroup setGroup
error_t snmpMibGetNextSysOREntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next sysOREntry object.
char_t sysLocation[SNMP_MIB_SYS_LOCATION_SIZE]
SNMP MIB module.
OID (Object Identifier)
error_t snmpMibInit(void)
SNMP MIB module initialization.
Definition: snmp_mib_impl.c:52
ASN.1 (Abstract Syntax Notation One)
SNMP agent (Simple Network Management Protocol)
error_t snmpv2MibGetSnmpTrapEnterprise(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get snmpTrapEnterprise object value.
#define SNMP_AGENT_MAX_MIBS
Definition: snmp_agent.h:67
error_t snmpMibGetSysOREntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get sysOREntry object value.
void snmpMibUnload(void *context)
Unload SNMP MIB module.
error_t snmpMibGetSnmpSetSerialNo(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get snmpSetSerialNo object value.
error_t snmpMibGetSysUpTime(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get sysUpTime object value.
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:99
char_t sysDescr[SNMP_MIB_SYS_DESCR_SIZE]
error_t snmpv2MibGetSnmpTrapOID(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get snmpTrapOID object value.
error_t snmpMibLoad(void *context)
Load SNMP MIB module.
#define TRACE_INFO(...)
Definition: debug.h:86
Success.
Definition: error.h:42
int32_t netGetRandRange(int32_t min, int32_t max)
Get a random value in the specified range.
Definition: net.c:1554
error_t
Error codes.
Definition: error.h:40
__start_packed struct @208 MibVariant
Variant data type.
unsigned int uint_t
Definition: compiler_port.h:43
SnmpAgentContext * context
SnmpMibSysGroup sysGroup
uint8_t value[]
Definition: dtls_misc.h:141
Common definitions for MIB modules.
void snmpMibUnlock(void)
Unlock SNMP MIB base.
error_t snmpMibSetSnmpSetSerialNo(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set snmpSetSerialNo object value.
const char_t * name
Definition: mib_common.h:287
SnmpMibBase snmpMibBase
SNMP MIB base.
#define SnmpAgentContext
Definition: snmp_agent.h:34
MIB module.
Definition: mib_common.h:285
char_t sysName[SNMP_MIB_SYS_NAME_SIZE]
System group.
error_t mibEncodeIndex(uint8_t *oid, size_t maxOidLen, size_t *pos, uint_t index)
Encode instance identifier (index)
Definition: mib_common.c:45
error_t mibTestAndIncSpinLock(int32_t *spinLock, int32_t value, bool_t commit)
Test and increment spin lock.
Definition: mib_common.c:939
uint8_t n
uint8_t oid[1]
Definition: mib_common.h:184
void snmpMibLock(void)
Lock SNMP MIB base.
int bool_t
Definition: compiler_port.h:47
uint8_t sysObjectID[SNMP_MIB_SYS_OBJECT_ID_SIZE]