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