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