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-2024 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 2.4.4
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  SnmpMibSnmpGroup *snmpGroup;
58  SnmpMibSetGroup *setGroup;
59 
60  //Debug message
61  TRACE_INFO("Initializing SNMP-MIB base...\r\n");
62 
63  //Clear SNMP MIB base
64  osMemset(&snmpMibBase, 0, sizeof(snmpMibBase));
65 
66  //Point to the system group
67  sysGroup = &snmpMibBase.sysGroup;
68 
69 #if (SNMP_MIB_SYS_DESCR_SIZE > 0)
70  //sysDescr object
71  osStrcpy(sysGroup->sysDescr, "Description");
72  sysGroup->sysDescrLen = osStrlen(sysGroup->sysDescr);
73 #endif
74 
75 #if (SNMP_MIB_SYS_OBJECT_ID_SIZE > 0)
76  //sysObjectID object
77  sysGroup->sysObjectID[0] = 0;
78  sysGroup->sysObjectIDLen = 1;
79 #endif
80 
81 #if (SNMP_MIB_SYS_CONTACT_SIZE > 0)
82  //sysContact object
83  osStrcpy(sysGroup->sysContact, "Contact");
84  sysGroup->sysContactLen = osStrlen(sysGroup->sysContact);
85 #endif
86 
87 #if (SNMP_MIB_SYS_NAME_SIZE > 0)
88  //sysName object
89  osStrcpy(sysGroup->sysName, "Name");
90  sysGroup->sysNameLen = osStrlen(sysGroup->sysName);
91 #endif
92 
93 #if (SNMP_MIB_SYS_LOCATION_SIZE > 0)
94  //sysLocation object
95  osStrcpy(sysGroup->sysLocation, "Location");
96  sysGroup->sysLocationLen = osStrlen(sysGroup->sysLocation);
97 #endif
98 
99  //sysServices object
101 
102  //Point to the SNMP group
103  snmpGroup = &snmpMibBase.snmpGroup;
104  //snmpEnableAuthenTraps object
106 
107  //Point to the set group
108  setGroup = &snmpMibBase.setGroup;
109  //snmpSetSerialNo object
110  setGroup->snmpSetSerialNo = netGetRandRange(1, INT32_MAX);
111 
112  //Successful processing
113  return NO_ERROR;
114 }
115 
116 
117 /**
118  * @brief Load SNMP MIB module
119  * @param[in] context Pointer to the SNMP agent context
120  * @return Error code
121  **/
122 
123 error_t snmpMibLoad(void *context)
124 {
125  //Register SNMP agent context
126  snmpMibBase.context = context;
127 
128  //Successful processing
129  return NO_ERROR;
130 }
131 
132 
133 /**
134  * @brief Unload SNMP MIB module
135  * @param[in] context Pointer to the SNMP agent context
136  **/
137 
138 void snmpMibUnload(void *context)
139 {
140  //Unregister SNMP agent context
141  snmpMibBase.context = NULL;
142 }
143 
144 
145 /**
146  * @brief Lock SNMP MIB base
147  **/
148 
149 void snmpMibLock(void)
150 {
151 }
152 
153 
154 /**
155  * @brief Unlock SNMP MIB base
156  **/
157 
158 void snmpMibUnlock(void)
159 {
160 }
161 
162 
163 /**
164  * @brief Get sysUpTime object value
165  * @param[in] object Pointer to the MIB object descriptor
166  * @param[in] oid Object identifier (object name and instance identifier)
167  * @param[in] oidLen Length of the OID, in bytes
168  * @param[out] value Object value
169  * @param[in,out] valueLen Length of the object value, in bytes
170  * @return Error code
171  **/
172 
173 error_t snmpMibGetSysUpTime(const MibObject *object, const uint8_t *oid,
174  size_t oidLen, MibVariant *value, size_t *valueLen)
175 {
176  //Get object value
177  value->timeTicks = osGetSystemTime64() / 10;
178 
179  //Successful processing
180  return NO_ERROR;
181 }
182 
183 
184 /**
185  * @brief Get sysOREntry object value
186  * @param[in] object Pointer to the MIB object descriptor
187  * @param[in] oid Object identifier (object name and instance identifier)
188  * @param[in] oidLen Length of the OID, in bytes
189  * @param[out] value Object value
190  * @param[in,out] valueLen Length of the object value, in bytes
191  * @return Error code
192  **/
193 
194 error_t snmpMibGetSysOREntry(const MibObject *object, const uint8_t *oid,
195  size_t oidLen, MibVariant *value, size_t *valueLen)
196 {
197  error_t error;
198  size_t n;
199  uint_t index;
200  SnmpAgentContext *context;
201  const MibModule *mibModule;
202 
203  //Point to the instance identifier
204  n = object->oidLen;
205 
206  //sysORIndex is used as instance identifier
207  error = mibDecodeIndex(oid, oidLen, &n, &index);
208  //Invalid instance identifier?
209  if(error)
210  return error;
211 
212  //Sanity check
213  if(n != oidLen)
215 
216  //Check index range
217  if(index < 1 || index > SNMP_AGENT_MAX_MIBS)
219 
220  //Point to the SNMP agent context
221  context = (SnmpAgentContext *) snmpMibBase.context;
222  //Sanity check
223  if(context == NULL)
225 
226  //Point to the MIB
227  mibModule = context->mibTable[index - 1];
228  //Make sure the MIB is properly loaded
229  if(mibModule == NULL)
231 
232  //sysORID object?
233  if(osStrcmp(object->name, "sysORID") == 0)
234  {
235  //Make sure the buffer is large enough to hold the entire object
236  if(*valueLen >= mibModule->oidLen)
237  {
238  //Copy object value
239  osMemcpy(value->octetString, mibModule->oid, mibModule->oidLen);
240  //Return object length
241  *valueLen = mibModule->oidLen;
242  }
243  else
244  {
245  //Report an error
246  error = ERROR_BUFFER_OVERFLOW;
247  }
248  }
249  //sysORDescr object?
250  else if(osStrcmp(object->name, "sysORDescr") == 0)
251  {
252  //Retrieve the length of the MIB name
253  n = osStrlen(mibModule->name);
254 
255  //Make sure the buffer is large enough to hold the entire object
256  if(*valueLen >= n)
257  {
258  //Copy object value
259  osMemcpy(value->octetString, mibModule->name, n);
260  //Return object length
261  *valueLen = n;
262  }
263  else
264  {
265  //Report an error
266  error = ERROR_BUFFER_OVERFLOW;
267  }
268  }
269  //sysORUpTime object?
270  else if(osStrcmp(object->name, "sysORUpTime") == 0)
271  {
272  //Get object value
273  value->timeTicks = 0;
274  }
275  //Unknown object?
276  else
277  {
278  //The specified object does not exist
279  error = ERROR_OBJECT_NOT_FOUND;
280  }
281 
282  //Return status code
283  return error;
284 }
285 
286 
287 /**
288  * @brief Get next sysOREntry object
289  * @param[in] object Pointer to the MIB object descriptor
290  * @param[in] oid Object identifier
291  * @param[in] oidLen Length of the OID, in bytes
292  * @param[out] nextOid OID of the next object in the MIB
293  * @param[out] nextOidLen Length of the next object identifier, in bytes
294  * @return Error code
295  **/
296 
297 error_t snmpMibGetNextSysOREntry(const MibObject *object, const uint8_t *oid,
298  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
299 {
300  error_t error;
301  size_t n;
302  uint_t index;
303  SnmpAgentContext *context;
304 
305  //Point to the SNMP agent context
306  context = (SnmpAgentContext *) snmpMibBase.context;
307  //Sanity check
308  if(context == NULL)
309  return ERROR_OBJECT_NOT_FOUND;
310 
311  //Make sure the buffer is large enough to hold the OID prefix
312  if(*nextOidLen < object->oidLen)
313  return ERROR_BUFFER_OVERFLOW;
314 
315  //Copy OID prefix
316  osMemcpy(nextOid, object->oid, object->oidLen);
317 
318  //Loop through existing MIBs
319  for(index = 1; index <= SNMP_AGENT_MAX_MIBS; index++)
320  {
321  //Make sure the MIB is properly loaded
322  if(context->mibTable[index - 1] != NULL)
323  {
324  //Append the instance identifier to the OID prefix
325  n = object->oidLen;
326 
327  //sysORIndex is used as instance identifier
328  error = mibEncodeIndex(nextOid, *nextOidLen, &n, index);
329  //Any error to report?
330  if(error)
331  return error;
332 
333  //Check whether the resulting object identifier lexicographically
334  //follows the specified OID
335  if(oidComp(nextOid, n, oid, oidLen) > 0)
336  {
337  //Save the length of the resulting object identifier
338  *nextOidLen = n;
339  //Next object found
340  return NO_ERROR;
341  }
342  }
343  }
344 
345  //The specified OID does not lexicographically precede the name
346  //of some object
347  return ERROR_OBJECT_NOT_FOUND;
348 }
349 
350 
351 /**
352  * @brief Get snmpTrapOID object value
353  * @param[in] object Pointer to the MIB object descriptor
354  * @param[in] oid Object identifier (object name and instance identifier)
355  * @param[in] oidLen Length of the OID, in bytes
356  * @param[out] value Object value
357  * @param[in,out] valueLen Length of the object value, in bytes
358  * @return Error code
359  **/
360 
361 error_t snmpv2MibGetSnmpTrapOID(const MibObject *object, const uint8_t *oid,
362  size_t oidLen, MibVariant *value, size_t *valueLen)
363 {
364  //Not implemented
365  *valueLen = 0;
366 
367  //Successful processing
368  return NO_ERROR;
369 }
370 
371 
372 /**
373  * @brief Get snmpTrapEnterprise object value
374  * @param[in] object Pointer to the MIB object descriptor
375  * @param[in] oid Object identifier (object name and instance identifier)
376  * @param[in] oidLen Length of the OID, in bytes
377  * @param[out] value Object value
378  * @param[in,out] valueLen Length of the object value, in bytes
379  * @return Error code
380  **/
381 
382 error_t snmpv2MibGetSnmpTrapEnterprise(const MibObject *object, const uint8_t *oid,
383  size_t oidLen, MibVariant *value, size_t *valueLen)
384 {
385  SnmpAgentContext *context;
386 
387  //Point to the SNMP agent context
388  context = (SnmpAgentContext *) snmpMibBase.context;
389  //Sanity check
390  if(context == NULL)
391  return ERROR_OBJECT_NOT_FOUND;
392 
393  //Make sure the buffer is large enough to hold the enterprise OID
394  if(*valueLen < context->enterpriseOidLen)
395  return ERROR_BUFFER_OVERFLOW;
396 
397  //Copy enterprise OID
398  osMemcpy(value->octetString, context->enterpriseOid,
399  context->enterpriseOidLen);
400 
401  //Return object length
402  *valueLen = context->enterpriseOidLen;
403 
404  //Successful processing
405  return NO_ERROR;
406 }
407 
408 
409 /**
410  * @brief Set snmpSetSerialNo object value
411  * @param[in] object Pointer to the MIB object descriptor
412  * @param[in] oid Object identifier (object name and instance identifier)
413  * @param[in] oidLen Length of the OID, in bytes
414  * @param[in] value Object value
415  * @param[in] valueLen Length of the object value, in bytes
416  * @param[in] commit This flag tells whether the changes shall be committed
417  * to the MIB base
418  * @return Error code
419  **/
420 
421 error_t snmpMibSetSnmpSetSerialNo(const MibObject *object, const uint8_t *oid,
422  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
423 {
424  //Test and increment spin lock
426  value->integer, commit);
427 }
428 
429 
430 /**
431  * @brief Get snmpSetSerialNo object value
432  * @param[in] object Pointer to the MIB object descriptor
433  * @param[in] oid Object identifier (object name and instance identifier)
434  * @param[in] oidLen Length of the OID, in bytes
435  * @param[out] value Object value
436  * @param[in,out] valueLen Length of the object value, in bytes
437  * @return Error code
438  **/
439 
440 error_t snmpMibGetSnmpSetSerialNo(const MibObject *object, const uint8_t *oid,
441  size_t oidLen, MibVariant *value, size_t *valueLen)
442 {
443  //Get the current value of the spin lock
445 
446  //Successful processing
447  return NO_ERROR;
448 }
449 
450 #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:53
char_t sysDescr[SNMP_MIB_SYS_DESCR_SIZE]
uint32_t netGetRandRange(uint32_t min, uint32_t max)
Generate a random value in the specified range.
Definition: net.c:413
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:142
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.
#define osStrcmp(s1, s2)
Definition: os_port.h:171
#define SNMP_AGENT_MAX_MIBS
Definition: snmp_agent.h:69
#define osStrlen(s)
Definition: os_port.h:165
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:103
uint8_t oid[]
Definition: lldp_tlv.h:300
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.
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
error_t
Error codes.
Definition: error.h:43
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:257
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:293
SNMP MIB module implementation.
General definitions for cryptographic algorithms.
SnmpMibSnmpGroup snmpGroup
System group.
uint8_t sysObjectID[SNMP_MIB_SYS_OBJECT_ID_SIZE]
#define TRACE_INFO(...)
Definition: debug.h:95
MIB module.
Definition: mib_common.h:292
size_t oidLen
Definition: mib_common.h:295
SnmpMibBase snmpMibBase
SNMP MIB base.
@ SNMP_MIB_AUTHEN_TRAPS_DISABLED
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:256
void snmpMibUnload(void *context)
Unload SNMP MIB module.
int32_t snmpEnableAuthenTraps
#define MibObject
Definition: mib_common.h:46
uint8_t value[]
Definition: tcp.h:369
uint8_t oidLen
Definition: lldp_tlv.h:299
char_t sysContact[SNMP_MIB_SYS_CONTACT_SIZE]
#define osGetSystemTime64()
#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:1006
MibVariant
Definition: mib_common.h:196
unsigned int uint_t
Definition: compiler_port.h:50
uint8_t oid[MIB_MAX_OID_SIZE]
Definition: mib_common.h:294
#define osMemset(p, value, length)
Definition: os_port.h:135
TCP/IP stack core.
#define osStrcpy(s1, s2)
Definition: os_port.h:207
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
ASN.1 (Abstract Syntax Notation One)