snmp_agent_object.c
Go to the documentation of this file.
1 /**
2  * @file snmp_agent_object.c
3  * @brief MIB object access
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.0
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 "snmp/snmp_agent.h"
37 #include "snmp/snmp_agent_object.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_AGENT_SUPPORT == ENABLED)
45 
46 
47 /**
48  * @brief Assign object value
49  * @param[in] context Pointer to the SNMP agent context
50  * @param[in] message Pointer to the received SNMP message
51  * @param[in] var Variable binding
52  * @param[in] commit This flag specifies whether the changes should be
53  * committed to the MIB base
54  * @return Error code
55  **/
56 
58  const SnmpMessage *message, SnmpVarBind *var, bool_t commit)
59 {
60  error_t error;
61  size_t n;
63  const MibObject *object;
64 
65  //Search the MIB for the specified object
66  error = snmpFindMibObject(context, var->oid, var->oidLen, &object);
67  //Cannot found the specified object?
68  if(error)
69  return error;
70 
71  //Debug message
72  TRACE_INFO(" %s\r\n", object->name);
73 
74  //Make sure the specified object is available for set operations
75  if(object->access != MIB_ACCESS_WRITE_ONLY &&
76  object->access != MIB_ACCESS_READ_WRITE &&
77  object->access != MIB_ACCESS_READ_CREATE)
78  {
79  //Report an error
80  return ERROR_NOT_WRITABLE;
81  }
82 
83 #if (SNMP_AGENT_VACM_SUPPORT == ENABLED)
84  //Access control verification
85  error = snmpIsAccessAllowed(context, message, var->oid, var->oidLen);
86  //Access denied?
87  if(error)
88  return error;
89 #endif
90 
91  //Check class
92  if(var->objClass != object->objClass)
93  return ERROR_WRONG_TYPE;
94  //Check type
95  if(var->objType != object->objType)
96  return ERROR_WRONG_TYPE;
97 
98  //Point to the object value
99  value = (MibVariant *) var->value;
100  //Get the length of the object value
101  n = var->valueLen;
102 
103  //Check object class
104  if(object->objClass == ASN1_CLASS_UNIVERSAL)
105  {
106  //Check object type
107  if(object->objType == ASN1_TYPE_INTEGER)
108  {
109  int32_t val;
110 
111  //Integer objects use ASN.1 encoding rules
112  error = snmpDecodeInt32(var->value, n, &val);
113  //Conversion failed?
114  if(error)
115  return ERROR_WRONG_ENCODING;
116 
117  //Point to the scratch buffer
118  value = (MibVariant *) context->response.buffer;
119  //Save resulting value
120  value->integer = val;
121  //Integer size
122  n = sizeof(int32_t);
123  }
124  }
125  else if(object->objClass == ASN1_CLASS_APPLICATION)
126  {
127  //Check object type
128  if(object->objType == MIB_TYPE_IP_ADDRESS)
129  {
130  //IpAddress objects have fixed size
131  if(n != object->valueSize)
132  return ERROR_WRONG_LENGTH;
133  }
134  else if(object->objType == MIB_TYPE_COUNTER32 ||
135  object->objType == MIB_TYPE_GAUGE32 ||
136  object->objType == MIB_TYPE_TIME_TICKS)
137  {
138  uint32_t val;
139 
140  //Counter32, Gauge32 and TimeTicks objects use ASN.1 encoding rules
141  error = snmpDecodeUnsignedInt32(var->value, n, &val);
142  //Conversion failed?
143  if(error)
144  return ERROR_WRONG_ENCODING;
145 
146  //Point to the scratch buffer
147  value = (MibVariant *) context->response.buffer;
148  //Save resulting value
149  value->counter32 = val;
150  //Integer size
151  n = sizeof(uint32_t);
152  }
153  else if(object->objType == MIB_TYPE_COUNTER64)
154  {
155  uint64_t val;
156 
157 #if (SNMP_V1_SUPPORT == ENABLED)
158  //Any SNMPv1 request which contains a variable binding with a
159  //Counter64 value is ill-formed and shall be discarded (refer
160  //to RFC 3584, section 4.2.2.1)
161  if(message->version == SNMP_VERSION_1)
162  return ERROR_INVALID_TAG;
163 #endif
164  //Counter64 objects use ASN.1 encoding rules
165  error = snmpDecodeUnsignedInt64(var->value, n, &val);
166  //Conversion failed?
167  if(error)
168  return ERROR_WRONG_ENCODING;
169 
170  //Point to the scratch buffer
171  value = (MibVariant *) context->response.buffer;
172  //Save resulting value
173  value->counter64 = val;
174  //Integer size
175  n = sizeof(uint64_t);
176  }
177  }
178 
179  //Objects can be assigned a value using a callback function
180  if(object->setValue != NULL)
181  {
182  //Invoke callback function to assign object value
183  error = object->setValue(object, var->oid, var->oidLen, value, n, commit);
184  }
185  //Simple scalar objects can also be attached to a variable
186  else if(object->value != NULL)
187  {
188  //Check the length of the object
189  if(n <= object->valueSize)
190  {
191  //Check whether the changes shall be committed to the MIB base
192  if(commit)
193  {
194  //Record the length of the object value
195  if(object->valueLen != NULL)
196  {
197  *object->valueLen = n;
198  }
199 
200  //Set object value
201  osMemcpy(object->value, value, n);
202  }
203 
204  //Successful write operation
205  error = NO_ERROR;
206  }
207  else
208  {
209  //Invalid length
210  error = ERROR_WRONG_LENGTH;
211  }
212  }
213  else
214  {
215  //Report an error
216  error = ERROR_WRITE_FAILED;
217  }
218 
219  //Return status code
220  return error;
221 }
222 
223 
224 /**
225  * @brief Retrieve object value
226  * @param[in] context Pointer to the SNMP agent context
227  * @param[in] message Pointer to the received SNMP message
228  * @param[out] var Variable binding
229  * @return Error code
230  **/
231 
233  const SnmpMessage *message, SnmpVarBind *var)
234 {
235  error_t error;
236  size_t n;
237  MibVariant *value;
238  const MibObject *object;
239 
240  //Search the MIB for the specified object
241  error = snmpFindMibObject(context, var->oid, var->oidLen, &object);
242  //Cannot found the specified object?
243  if(error)
244  return error;
245 
246  //Debug message
247  TRACE_INFO(" %s\r\n", object->name);
248 
249  //Check the maximal level of access for the specified object
250  if(object->access == MIB_ACCESS_READ_ONLY ||
251  object->access == MIB_ACCESS_READ_WRITE ||
252  object->access == MIB_ACCESS_READ_CREATE)
253  {
254  //The object is available for get operations
255  }
256  else if(object->access == MIB_ACCESS_FOR_NOTIFY)
257  {
258  //The object is accessible only via a notification
259  if(message->pduType != SNMP_PDU_TRAP &&
260  message->pduType != SNMP_PDU_TRAP_V2 &&
261  message->pduType != SNMP_PDU_INFORM_REQUEST)
262  {
263  //Report an error
264  return ERROR_ACCESS_DENIED;
265  }
266  }
267  else
268  {
269  //The object is not available for get operations
270  return ERROR_ACCESS_DENIED;
271  }
272 
273 #if (SNMP_AGENT_VACM_SUPPORT == ENABLED)
274  //Access control verification
275  error = snmpIsAccessAllowed(context, message, var->oid, var->oidLen);
276  //Access denied?
277  if(error)
278  return error;
279 #endif
280 
281  //Buffer where to store the object value
282  value = (MibVariant *) (context->response.varBindList +
283  context->response.varBindListLen + context->response.oidLen);
284 
285  //Number of bytes available in the buffer
286  n = context->response.varBindListMaxLen -
287  (context->response.varBindListLen + context->response.oidLen);
288 
289  //Check object class
290  if(object->objClass == ASN1_CLASS_UNIVERSAL)
291  {
292  //Check object type
293  if(object->objType == ASN1_TYPE_INTEGER)
294  {
295  //Make sure the buffer is large enough
296  if(n < object->valueSize)
297  return ERROR_BUFFER_OVERFLOW;
298 
299  //Integer objects have fixed size
300  n = object->valueSize;
301  }
302  }
303  else if(object->objClass == ASN1_CLASS_APPLICATION)
304  {
305  //Check object type
306  if(object->objType == MIB_TYPE_IP_ADDRESS ||
307  object->objType == MIB_TYPE_COUNTER32 ||
308  object->objType == MIB_TYPE_GAUGE32 ||
309  object->objType == MIB_TYPE_TIME_TICKS ||
310  object->objType == MIB_TYPE_COUNTER64)
311  {
312  //Make sure the buffer is large enough
313  if(n < object->valueSize)
314  return ERROR_BUFFER_OVERFLOW;
315 
316  //IpAddress, Counter32, Gauge32, TimeTicks and
317  //Counter64 objects have fixed size
318  n = object->valueSize;
319  }
320  }
321 
322  //Object value can be retrieved using a callback function
323  if(object->getValue != NULL)
324  {
325  //Invoke callback function to retrieve object value
326  error = object->getValue(object, var->oid, var->oidLen, value, &n);
327  //Unable to retrieve object value?
328  if(error)
329  return error;
330  }
331  //Simple scalar objects can also be attached to a variable
332  else if(object->value != NULL)
333  {
334  //Fixed or variable-length object?
335  if(object->valueLen != NULL)
336  {
337  //Make sure the buffer is large enough
338  if(n < *object->valueLen)
339  return ERROR_BUFFER_OVERFLOW;
340 
341  //Get the length of the object value
342  n = *object->valueLen;
343  }
344 
345  //Retrieve object value
346  osMemcpy(value, object->value, n);
347  }
348  else
349  {
350  //Report an error
351  return ERROR_READ_FAILED;
352  }
353 
354  //Check object class
355  if(object->objClass == ASN1_CLASS_UNIVERSAL)
356  {
357  //Check object type
358  if(object->objType == ASN1_TYPE_INTEGER)
359  {
360  //Encode Integer objects using ASN.1 rules
361  error = snmpEncodeInt32(value->integer, (uint8_t *) value, &n);
362  }
363  else
364  {
365  //No conversion required for OctetString and ObjectIdentifier objects
366  error = NO_ERROR;
367  }
368  }
369  else if(object->objClass == ASN1_CLASS_APPLICATION)
370  {
371  //Check object type
372  if(object->objType == MIB_TYPE_COUNTER32 ||
373  object->objType == MIB_TYPE_GAUGE32 ||
374  object->objType == MIB_TYPE_TIME_TICKS)
375  {
376  //Encode Counter32, Gauge32 and TimeTicks objects using ASN.1 rules
377  error = snmpEncodeUnsignedInt32(value->counter32, (uint8_t *) value, &n);
378  }
379  else if(object->objType == MIB_TYPE_COUNTER64)
380  {
381 #if (SNMP_V1_SUPPORT == ENABLED)
382  //On receipt of an SNMPv1 GetRequest-PDU containing a variable binding
383  //whose name field points to an object instance of type Counter64, a
384  //GetResponse-PDU SHALL be returned, with an error-status of noSuchName
385  if(message->version == SNMP_VERSION_1)
386  {
387  //Report an error
388  error = ERROR_OBJECT_NOT_FOUND;
389  }
390  else
391 #endif
392  {
393  //Encode Counter64 objects using ASN.1 rules
394  error = snmpEncodeUnsignedInt64(value->counter64,
395  (uint8_t *) value, &n);
396  }
397  }
398  else
399  {
400  //No conversion required for Opaque objects
401  error = NO_ERROR;
402  }
403  }
404 
405  //Check status code
406  if(!error)
407  {
408  //Save object class and type
409  var->objClass = object->objClass;
410  var->objType = object->objType;
411 
412  //Save object value
413  var->value = (uint8_t *) value;
414  var->valueLen = n;
415  }
416 
417  //Return status code
418  return error;
419 }
420 
421 
422 /**
423  * @brief Search MIBs for the next object
424  * @param[in] context Pointer to the SNMP agent context
425  * @param[in] message Pointer to the received SNMP message
426  * @param[in] var Variable binding
427  * @return Error pointer
428  **/
429 
431  const SnmpMessage *message, SnmpVarBind *var)
432 {
433  error_t error;
434  uint_t i;
435  uint_t j;
436  size_t n;
437  uint_t numObjects;
438  size_t bufferLen;
439  uint8_t *curOid;
440  size_t curOidLen;
441  uint8_t *nextOid;
442  size_t nextOidLen;
443  uint8_t *tempOid;
444  size_t tempOidLen;
445  const MibObject *object;
446  const MibObject *nextObject;
447 
448  //Initialize status code
449  error = NO_ERROR;
450 
451  //Calculate the length of the buffer
452  bufferLen = context->response.varBindListMaxLen -
453  context->response.varBindListLen;
454 
455  //Initialize pointer
456  nextObject = NULL;
457 
458  //Buffer where to store the resulting OID
459  nextOid = context->response.varBindList + context->response.varBindListLen;
460  nextOidLen = 0;
461 
462  //Loop through MIBs
463  for(i = 0; i < SNMP_AGENT_MAX_MIBS; i++)
464  {
465  //Valid MIB?
466  if(context->mibTable[i] != NULL &&
467  context->mibTable[i]->numObjects > 0)
468  {
469  //Get the total number of objects
470  numObjects = context->mibTable[i]->numObjects;
471 
472  //Point to the last object of the MIB
473  object = &context->mibTable[i]->objects[numObjects - 1];
474 
475  //Discard instance sub-identifier
476  n = MIN(var->oidLen, object->oidLen);
477 
478  //Perform lexicographical comparison
479  if(oidComp(var->oid, n, object->oid, object->oidLen) <= 0)
480  {
481  //Sanity check
482  if((nextOidLen + var->oidLen) > bufferLen)
483  {
484  //Report an error
485  error = ERROR_BUFFER_OVERFLOW;
486  //Exit immediately
487  break;
488  }
489 
490  //Copy the OID from the specified variable binding
491  curOid = nextOid + nextOidLen;
492  curOidLen = var->oidLen;
493  osMemcpy(curOid, var->oid, var->oidLen);
494 
495  //Loop through objects
496  for(j = 0; j < numObjects; )
497  {
498  //Point to the current object
499  object = &context->mibTable[i]->objects[j];
500 
501  //Buffer where to store the OID of the next object
502  tempOid = curOid + curOidLen;
503 
504  //Make sure the current object is accessible
505  if(object->access == MIB_ACCESS_READ_ONLY ||
506  object->access == MIB_ACCESS_READ_WRITE ||
507  object->access == MIB_ACCESS_READ_CREATE)
508  {
509  //Scalar or tabular object?
510  if(object->getNext == NULL)
511  {
512  //Perform lexicographical comparison
513  if(oidComp(curOid, curOidLen, object->oid, object->oidLen) <= 0)
514  {
515  //Take in account the instance sub-identifier to determine
516  //the length of the OID
517  tempOidLen = object->oidLen + 1;
518 
519  //Make sure the buffer is large enough to hold the entire OID
520  if((nextOidLen + curOidLen + tempOidLen) <= bufferLen)
521  {
522  //Copy object identifier
523  osMemcpy(tempOid, object->oid, object->oidLen);
524  //Append instance sub-identifier
525  tempOid[tempOidLen - 1] = 0;
526 
527  //Successful processing
528  error = NO_ERROR;
529  }
530  else
531  {
532  //Report an error
533  error = ERROR_BUFFER_OVERFLOW;
534  }
535  }
536  else
537  {
538  //The specified OID does not lexicographically precede
539  //the name of the current object
540  error = ERROR_OBJECT_NOT_FOUND;
541  }
542  }
543  else
544  {
545  //Discard instance sub-identifier
546  n = MIN(curOidLen, object->oidLen);
547 
548  //Perform lexicographical comparison
549  if(oidComp(curOid, n, object->oid, object->oidLen) <= 0)
550  {
551  //Maximum acceptable size of the OID
552  tempOidLen = bufferLen - nextOidLen - curOidLen;
553 
554  //Search the MIB for the next object
555  error = object->getNext(object, curOid, curOidLen,
556  tempOid, &tempOidLen);
557  }
558  else
559  {
560  //The specified OID does not lexicographically precede
561  //the name of the current object
562  error = ERROR_OBJECT_NOT_FOUND;
563  }
564  }
565 
566 #if (SNMP_V1_SUPPORT == ENABLED)
567  //Check status code
568  if(error == NO_ERROR)
569  {
570  //On receipt of an SNMPv1 GetNextRequest-PDU, any object
571  //instance which contains a syntax of Counter64 shall be
572  //skipped (refer to RFC 3584, section 4.2.2.1)
573  if(message->version == SNMP_VERSION_1)
574  {
575  //Counter64 type?
576  if(object->objClass == ASN1_CLASS_APPLICATION &&
577  object->objType == MIB_TYPE_COUNTER64)
578  {
579  //Skip current object
580  error = ERROR_OBJECT_NOT_FOUND;
581  }
582  }
583  }
584 #endif
585 #if (SNMP_AGENT_VACM_SUPPORT == ENABLED)
586  //Check status code
587  if(error == NO_ERROR)
588  {
589  //Access control verification
590  error = snmpIsAccessAllowed(context, message, tempOid,
591  tempOidLen);
592  }
593 #endif
594  //Check status code
595  if(error == NO_ERROR)
596  {
597  //Save the closest object identifier that follows the
598  //specified OID
599  if(nextObject == NULL)
600  {
601  nextObject = object;
602  nextOidLen = tempOidLen;
603  osMemmove(nextOid, tempOid, tempOidLen);
604  }
605  else if(oidComp(tempOid, tempOidLen, nextOid, nextOidLen) < 0)
606  {
607  nextObject = object;
608  nextOidLen = tempOidLen;
609  osMemmove(nextOid, tempOid, tempOidLen);
610  }
611 
612  //We are done
613  break;
614  }
615  else if(error == ERROR_OBJECT_NOT_FOUND)
616  {
617  //Catch exception
618  error = NO_ERROR;
619 
620  //Jump to the next object in the MIB
621  j++;
622  }
623  else if(error == ERROR_UNKNOWN_CONTEXT ||
625  {
626  //Catch exception
627  error = NO_ERROR;
628 
629  //Check the next instance of the same object
630  curOidLen = tempOidLen;
631  osMemmove(curOid, tempOid, tempOidLen);
632  }
633  else
634  {
635  //Exit immediately
636  break;
637  }
638  }
639  else
640  {
641  //The current object is not accessible
642  j++;
643  }
644  }
645  }
646  }
647 
648  //Any error to report?
649  if(error)
650  break;
651  }
652 
653  //Check status code
654  if(!error)
655  {
656  //Next object found?
657  if(nextObject != NULL)
658  {
659  //Replace the original OID with the name of the next object
660  var->oid = nextOid;
661  var->oidLen = nextOidLen;
662 
663  //Save the length of the OID
664  context->response.oidLen = nextOidLen;
665  }
666  else
667  {
668  //The specified OID does not lexicographically precede the
669  //name of some object
670  error = ERROR_OBJECT_NOT_FOUND;
671  }
672  }
673 
674  //Return status code
675  return error;
676 }
677 
678 
679 /**
680  * @brief Search MIBs for the given object
681  * @param[in] context Pointer to the SNMP agent context
682  * @param[in] oid Object identifier
683  * @param[in] oidLen Length of the OID
684  * @param[out] object Pointer the MIB object descriptor
685  * @return Error code
686  **/
687 
689  const uint8_t *oid, size_t oidLen, const MibObject **object)
690 {
691  error_t error;
692  int_t left;
693  int_t right;
694  int_t mid;
695  int_t res;
696  uint_t i;
697  size_t n;
698  const MibObject *objects;
699 
700  //Initialize variables
701  res = -1;
702  mid = 0;
703  objects = NULL;
704 
705  //Loop through MIBs
706  for(i = 0; i < SNMP_AGENT_MAX_MIBS && res != 0; i++)
707  {
708  //Valid MIB?
709  if(context->mibTable[i] != NULL &&
710  context->mibTable[i]->numObjects > 0)
711  {
712  //Point to the list of objects
713  objects = context->mibTable[i]->objects;
714 
715  //Index of the first item
716  left = 0;
717  //Index of the last item
718  right = context->mibTable[i]->numObjects - 1;
719 
720  //Discard instance sub-identifier
721  n = MIN(oidLen, objects[right].oidLen);
722 
723  //Check object identifier
724  if(oidComp(oid, oidLen, objects[left].oid, objects[left].oidLen) >= 0 &&
725  oidComp(oid, n, objects[right].oid, objects[right].oidLen) <= 0)
726  {
727  //Binary search algorithm
728  while(left <= right && res != 0)
729  {
730  //Calculate the index of the middle item
731  mid = left + (right - left) / 2;
732 
733  //Discard instance sub-identifier
734  n = MIN(oidLen, objects[mid].oidLen);
735 
736  //Perform lexicographic comparison
737  res = oidComp(oid, n, objects[mid].oid, objects[mid].oidLen);
738 
739  //Check the result of the comparison
740  if(res > 0)
741  {
742  left = mid + 1;
743  }
744  else if(res < 0)
745  {
746  right = mid - 1;
747  }
748  }
749  }
750  }
751  }
752 
753  //Object identifier found?
754  if(res == 0)
755  {
756  //Scalar object?
757  if(objects[mid].getNext == NULL)
758  {
759  //The instance sub-identifier shall be 0 for scalar objects
760  if(oidLen == (objects[mid].oidLen + 1) && oid[oidLen - 1] == 0)
761  {
762  //Return a pointer to the matching object
763  *object = &objects[mid];
764  //No error to report
765  error = NO_ERROR;
766  }
767  else
768  {
769  //No such instance...
770  error = ERROR_INSTANCE_NOT_FOUND;
771  }
772  }
773  //Tabular object?
774  else
775  {
776  //Check the length of the OID
777  if(oidLen > objects[mid].oidLen)
778  {
779  //Return a pointer to the matching object
780  *object = &objects[mid];
781  //No error to report
782  error = NO_ERROR;
783  }
784  else
785  {
786  //No such instance...
787  error = ERROR_INSTANCE_NOT_FOUND;
788  }
789  }
790  }
791  else
792  {
793  //No such object...
794  error = ERROR_OBJECT_NOT_FOUND;
795  }
796 
797  //Return status code
798  return error;
799 }
800 
801 #endif
ASN.1 (Abstract Syntax Notation One)
@ ASN1_TYPE_INTEGER
Definition: asn1.h:70
#define ASN1_CLASS_APPLICATION
Definition: asn1.h:53
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:52
uint8_t valueSize
Definition: chap.h:126
uint8_t message[]
Definition: chap.h:154
uint16_t mid
Definition: coap_common.h:180
signed int int_t
Definition: compiler_port.h:49
unsigned int uint_t
Definition: compiler_port.h:50
int bool_t
Definition: compiler_port.h:53
General definitions for cryptographic algorithms.
Debugging facilities.
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t n
error_t
Error codes.
Definition: error.h:43
@ ERROR_WRONG_TYPE
Definition: error.h:121
@ ERROR_UNKNOWN_CONTEXT
Definition: error.h:262
@ ERROR_WRONG_ENCODING
Definition: error.h:122
@ ERROR_WRONG_LENGTH
Definition: error.h:120
@ ERROR_WRITE_FAILED
Definition: error.h:221
@ ERROR_OBJECT_NOT_FOUND
Definition: error.h:255
@ ERROR_INSTANCE_NOT_FOUND
Definition: error.h:256
@ ERROR_NOT_WRITABLE
Definition: error.h:149
@ ERROR_AUTHORIZATION_FAILED
Definition: error.h:266
@ ERROR_ACCESS_DENIED
Definition: error.h:148
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:142
@ ERROR_READ_FAILED
Definition: error.h:222
@ ERROR_INVALID_TAG
Definition: error.h:114
uint8_t oid[]
Definition: lldp_tlv.h:300
uint8_t oidLen
Definition: lldp_tlv.h:299
#define MibObject
Definition: mib_common.h:46
@ MIB_ACCESS_WRITE_ONLY
Definition: mib_common.h:78
@ MIB_ACCESS_READ_ONLY
Definition: mib_common.h:79
@ MIB_ACCESS_READ_CREATE
Definition: mib_common.h:81
@ MIB_ACCESS_READ_WRITE
Definition: mib_common.h:80
@ MIB_ACCESS_FOR_NOTIFY
Definition: mib_common.h:77
@ MIB_TYPE_TIME_TICKS
Definition: mib_common.h:64
@ MIB_TYPE_COUNTER32
Definition: mib_common.h:61
@ MIB_TYPE_COUNTER64
Definition: mib_common.h:66
@ MIB_TYPE_IP_ADDRESS
Definition: mib_common.h:60
@ MIB_TYPE_GAUGE32
Definition: mib_common.h:62
MibVariant
Definition: mib_common.h:196
TCP/IP stack core.
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:103
OID (Object Identifier)
#define osMemmove(dest, src, length)
Definition: os_port.h:147
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define MIN(a, b)
Definition: os_port.h:63
const uint8_t res[]
SNMP agent (Simple Network Management Protocol)
#define SnmpAgentContext
Definition: snmp_agent.h:36
#define SNMP_AGENT_MAX_MIBS
Definition: snmp_agent.h:69
error_t snmpDecodeInt32(const uint8_t *src, size_t length, int32_t *value)
Decode a 32-bit signed integer.
error_t snmpEncodeUnsignedInt64(uint64_t value, uint8_t *dest, size_t *length)
Encode a 64-bit unsigned integer.
error_t snmpDecodeUnsignedInt32(const uint8_t *src, size_t length, uint32_t *value)
Decode a 32-bit unsigned integer.
error_t snmpEncodeUnsignedInt32(uint32_t value, uint8_t *dest, size_t *length)
Encode a 32-bit unsigned integer.
error_t snmpEncodeInt32(int32_t value, uint8_t *dest, size_t *length)
Encode a 32-bit signed integer.
error_t snmpDecodeUnsignedInt64(const uint8_t *src, size_t length, uint64_t *value)
Decode a 64-bit unsigned integer.
error_t snmpGetNextObject(SnmpAgentContext *context, const SnmpMessage *message, SnmpVarBind *var)
Search MIBs for the next object.
error_t snmpSetObjectValue(SnmpAgentContext *context, const SnmpMessage *message, SnmpVarBind *var, bool_t commit)
Assign object value.
error_t snmpGetObjectValue(SnmpAgentContext *context, const SnmpMessage *message, SnmpVarBind *var)
Retrieve object value.
error_t snmpFindMibObject(SnmpAgentContext *context, const uint8_t *oid, size_t oidLen, const MibObject **object)
Search MIBs for the given object.
MIB object access.
error_t snmpIsAccessAllowed(SnmpAgentContext *context, const SnmpMessage *message, const uint8_t *oid, size_t oidLen)
Access control verification.
@ SNMP_PDU_TRAP_V2
Definition: snmp_common.h:157
@ SNMP_PDU_INFORM_REQUEST
Definition: snmp_common.h:156
@ SNMP_PDU_TRAP
Definition: snmp_common.h:154
@ SNMP_VERSION_1
Definition: snmp_common.h:138
SNMP message.
Variable binding.
const uint8_t * value
const uint8_t * oid
uint8_t value[]
Definition: tcp.h:369