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