snmp_agent_misc.c
Go to the documentation of this file.
1 /**
2  * @file snmp_agent_misc.c
3  * @brief Helper functions for SNMP agent
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 <limits.h>
34 #include "core/net.h"
35 #include "snmp/snmp_agent.h"
36 #include "snmp/snmp_agent_misc.h"
37 #include "snmp/snmp_agent_object.h"
38 #include "mibs/mib2_module.h"
39 #include "core/crypto.h"
40 #include "encoding/asn1.h"
41 #include "encoding/oid.h"
42 #include "debug.h"
43 
44 //Check TCP/IP stack configuration
45 #if (SNMP_AGENT_SUPPORT == ENABLED)
46 
47 //sysUpTime.0 object (1.3.6.1.2.1.1.3.0)
48 static const uint8_t sysUpTimeObject[] = {43, 6, 1, 2, 1, 1, 3, 0};
49 //snmpTrapOID.0 object (1.3.6.1.6.3.1.1.4.1.0)
50 static const uint8_t snmpTrapOidObject[] = {43, 6, 1, 6, 3, 1, 1, 4, 1, 0};
51 //snmpTraps object (1.3.6.1.6.3.1.1.5)
52 static const uint8_t snmpTrapsObject[] = {43, 6, 1, 6, 3, 1, 1, 5};
53 
54 
55 /**
56  * @brief Lock MIB bases
57  * @param[in] context Pointer to the SNMP agent context
58  **/
59 
61 {
62  uint_t i;
63  bool_t flag;
64 
65  //Initialize flag
66  flag = FALSE;
67 
68  //Loop through MIBs
69  for(i = 0; i < SNMP_AGENT_MAX_MIBS; i++)
70  {
71  //Valid MIB?
72  if(context->mibTable[i] != NULL)
73  {
74  //Any registered callback?
75  if(context->mibTable[i]->lock != NULL)
76  {
77  //Lock access to the MIB
78  context->mibTable[i]->lock();
79  }
80  else
81  {
82  //The MIB does not feature any lock/unlock mechanism
83  flag = TRUE;
84  }
85  }
86  }
87 
88  //Default lock/unlock sequence?
89  if(flag)
90  {
91  //Get exclusive access
93  }
94 }
95 
96 
97 /**
98  * @brief Unlock MIB bases
99  * @param[in] context Pointer to the SNMP agent context
100  **/
101 
103 {
104  uint_t i;
105  bool_t flag;
106 
107  //Initialize flag
108  flag = FALSE;
109 
110  //Loop through MIBs
111  for(i = 0; i < SNMP_AGENT_MAX_MIBS; i++)
112  {
113  //Valid MIB?
114  if(context->mibTable[i] != NULL)
115  {
116  //Any registered callback?
117  if(context->mibTable[i]->unlock != NULL)
118  {
119  //Unlock access to the MIB
120  context->mibTable[i]->unlock();
121  }
122  else
123  {
124  //The MIB does not feature any lock/unlock mechanism
125  flag = TRUE;
126  }
127  }
128  }
129 
130  //Default lock/unlock sequence?
131  if(flag)
132  {
133  //Release exclusive access
135  }
136 }
137 
138 
139 /**
140  * @brief Create a new community entry
141  * @param[in] context Pointer to the SNMP agent context
142  * @return Pointer to the newly created entry
143  **/
144 
146 {
147  SnmpUserEntry *entry;
148 
149  //Initialize pointer
150  entry = NULL;
151 
152 #if (SNMP_V1_SUPPORT == ENABLED || SNMP_V2C_SUPPORT == ENABLED)
153  //Sanity check
154  if(context != NULL)
155  {
156  uint_t i;
157 
158  //Loop through the list of community strings
159  for(i = 0; i < SNMP_AGENT_MAX_COMMUNITIES; i++)
160  {
161  //Check current status
162  if(context->communityTable[i].status == MIB_ROW_STATUS_UNUSED)
163  {
164  //An unused entry has been found
165  entry = &context->communityTable[i];
166  //We are done
167  break;
168  }
169  }
170 
171  //Check whether the table runs out of space
172  if(entry == NULL)
173  {
174  //Loop through the list of community strings
175  for(i = 0; i < SNMP_AGENT_MAX_COMMUNITIES; i++)
176  {
177  //Check current status
178  if(context->communityTable[i].status == MIB_ROW_STATUS_NOT_READY)
179  {
180  //Reuse the current entry
181  entry = &context->communityTable[i];
182  //We are done
183  break;
184  }
185  }
186  }
187  }
188 #endif
189 
190  //Return a pointer to the newly created entry
191  return entry;
192 }
193 
194 
195 /**
196  * @brief Search the community table for a given community string
197  * @param[in] context Pointer to the SNMP agent context
198  * @param[in] community Pointer to the community string
199  * @param[in] length Length of the community string
200  * @return Pointer to the matching entry
201  **/
202 
204  const char_t *community, size_t length)
205 {
206  SnmpUserEntry *entry;
207 
208  //Initialize pointer
209  entry = NULL;
210 
211 #if (SNMP_V1_SUPPORT == ENABLED || SNMP_V2C_SUPPORT == ENABLED)
212  //Sanity check
213  if(context != NULL && community != NULL)
214  {
215  uint_t i;
216 
217  //Loop through the list of community string
218  for(i = 0; i < SNMP_AGENT_MAX_COMMUNITIES; i++)
219  {
220  //Check current status
221  if(context->communityTable[i].status != MIB_ROW_STATUS_UNUSED)
222  {
223  //Check the length of the community string
224  if(strlen(context->communityTable[i].name) == length)
225  {
226  //Compare community strings
227  if(!strncmp(context->communityTable[i].name, community, length))
228  {
229  //A matching entry has been found
230  entry = &context->communityTable[i];
231  //We are done
232  break;
233  }
234  }
235  }
236  }
237  }
238 #endif
239 
240  //Return a pointer to the matching entry
241  return entry;
242 }
243 
244 
245 /**
246  * @brief Parse variable binding
247  * @param[in] p Input stream where to read the variable binding
248  * @param[in] length Number of bytes available in the input stream
249  * @param[out] var Variable binding
250  * @param[out] consumed Total number of bytes that have been consumed
251  * @return Error code
252  **/
253 
255  size_t length, SnmpVarBind *var, size_t *consumed)
256 {
257  error_t error;
258  Asn1Tag tag;
259 
260  //The variable binding is encapsulated within a sequence
261  error = asn1ReadTag(p, length, &tag);
262  //Failed to decode ASN.1 tag?
263  if(error)
264  return error;
265 
266  //Enforce encoding, class and type
268  //The tag does not match the criteria?
269  if(error)
270  return error;
271 
272  //Total number of bytes that have been consumed
273  *consumed = tag.totalLength;
274 
275  //Point to the first item of the sequence
276  p = tag.value;
277  length = tag.length;
278 
279  //Read object name
280  error = asn1ReadTag(p, length, &tag);
281  //Failed to decode ASN.1 tag?
282  if(error)
283  return error;
284 
285  //Enforce encoding, class and type
287  //The tag does not match the criteria?
288  if(error)
289  return error;
290 
291  //Save object identifier
292  var->oid = tag.value;
293  var->oidLen = tag.length;
294 
295  //Point to the next item
296  p += tag.totalLength;
297  length -= tag.totalLength;
298 
299  //Read object value
300  error = asn1ReadTag(p, length, &tag);
301  //Failed to decode ASN.1 tag?
302  if(error)
303  return error;
304 
305  //Make sure that the tag is valid
306  if(tag.constructed)
307  return ERROR_INVALID_TAG;
308 
309  //Save object class
310  var->objClass = tag.objClass;
311  //Save object type
312  var->objType = tag.objType;
313  //Save object value
314  var->value = tag.value;
315  var->valueLen = tag.length;
316 
317  //Successful processing
318  return NO_ERROR;
319 }
320 
321 
322 /**
323  * @brief Write variable binding
324  * @param[in] context Pointer to the SNMP agent context
325  * @param[in] var Variable binding
326  * @return Error code
327  **/
328 
330 {
331  error_t error;
332  size_t m;
333  size_t n;
334  uint8_t *p;
335  Asn1Tag tag;
336 
337  //The object's name is encoded in ASN.1 format
338  tag.constructed = FALSE;
341  tag.length = var->oidLen;
342  tag.value = var->oid;
343 
344  //Calculate the total length of the ASN.1 tag
345  error = asn1WriteTag(&tag, FALSE, NULL, &m);
346  //Any error to report?
347  if(error)
348  return error;
349 
350  //The object's value is encoded in ASN.1 format
351  tag.constructed = FALSE;
352  tag.objClass = var->objClass;
353  tag.objType = var->objType;
354  tag.length = var->valueLen;
355  tag.value = var->value;
356 
357  //Calculate the total length of the ASN.1 tag
358  error = asn1WriteTag(&tag, FALSE, NULL, &n);
359  //Any error to report?
360  if(error)
361  return error;
362 
363  //The variable binding is encapsulated within a sequence
364  tag.constructed = TRUE;
367  tag.length = m + n;
368  tag.value = NULL;
369 
370  //The first pass computes the total length of the sequence
371  error = asn1WriteTag(&tag, FALSE, NULL, NULL);
372  //Any error to report?
373  if(error)
374  return error;
375 
376  //Make sure the buffer is large enough to hold the whole sequence
377  if((context->response.varBindListLen + tag.totalLength) >
378  context->response.varBindListMaxLen)
379  {
380  //Report an error
381  return ERROR_BUFFER_OVERFLOW;
382  }
383 
384  //The second pass encodes the sequence in reverse order
385  p = context->response.varBindList + context->response.varBindListLen +
386  tag.totalLength;
387 
388  //Encode the object's value using ASN.1
389  tag.constructed = FALSE;
390  tag.objClass = var->objClass;
391  tag.objType = var->objType;
392  tag.length = var->valueLen;
393  tag.value = var->value;
394 
395  //Write the corresponding ASN.1 tag
396  error = asn1WriteTag(&tag, TRUE, p, &m);
397  //Any error to report?
398  if(error)
399  return error;
400 
401  //Move backward
402  p -= m;
403 
404  //Encode the object's name using ASN.1
405  tag.constructed = FALSE;
408  tag.length = var->oidLen;
409  tag.value = var->oid;
410 
411  //Write the corresponding ASN.1 tag
412  error = asn1WriteTag(&tag, TRUE, p, &n);
413  //Any error to report?
414  if(error)
415  return error;
416 
417  //Move backward
418  p -= n;
419 
420  //The variable binding is encapsulated within a sequence
421  tag.constructed = TRUE;
424  tag.length = m + n;
425  tag.value = NULL;
426 
427  //Write the corresponding ASN.1 tag
428  error = asn1WriteTag(&tag, TRUE, p, NULL);
429  //Any error to report?
430  if(error)
431  return error;
432 
433  //Update the length of the list
434  context->response.varBindListLen += tag.totalLength;
435 
436  //Successful processing
437  return NO_ERROR;
438 }
439 
440 
441 /**
442  * @brief Copy the list of variable bindings
443  * @param[in] context Pointer to the SNMP agent context
444  * @return Error code
445  **/
446 
448 {
449  //Sanity check
450  if(context->request.varBindListLen > context->response.varBindListMaxLen)
451  return ERROR_BUFFER_OVERFLOW;
452 
453  //Copy the list of variable bindings to the response buffer
454  memcpy(context->response.varBindList, context->request.varBindList,
455  context->request.varBindListLen);
456 
457  //Save the length of the list
458  context->response.varBindListLen = context->request.varBindListLen;
459 
460  //Successful processing
461  return NO_ERROR;
462 }
463 
464 
465 /**
466  * @brief Format the variable binding list for Trap-PDU or SNMPv2-Trap-PDU
467  * @param[in] context Pointer to the SNMP agent context
468  * @param[in] genericTrapType Generic trap type
469  * @param[in] specificTrapCode Specific code
470  * @param[in] objectList List of object names
471  * @param[in] objectListSize Number of entries in the list
472  * @return Error code
473  **/
474 
476  uint_t genericTrapType, uint_t specificTrapCode,
477  const SnmpTrapObject *objectList, uint_t objectListSize)
478 {
479  error_t error;
480  uint_t i;
481  size_t n;
482  systime_t time;
484  SnmpVarBind var;
485 
486  //Point to the SNMP message
487  message = &context->response;
488 
489 #if (SNMP_V2C_SUPPORT == ENABLED || SNMP_V3_SUPPORT == ENABLED)
490  //SNMPv2c or SNMPv3 version?
491  if(message->version == SNMP_VERSION_2C || message->version == SNMP_VERSION_3)
492  {
493  //Get current time
494  time = osGetSystemTime() / 10;
495 
496  //Encode the object value using ASN.1 rules
497  error = snmpEncodeUnsignedInt32(time, message->buffer, &n);
498  //Any error to report?
499  if(error)
500  return error;
501 
502  //The first two variable bindings in the variable binding list of an
503  //SNMPv2-Trap-PDU are sysUpTime.0 and snmpTrapOID.0 respectively
504  var.oid = sysUpTimeObject;
505  var.oidLen = sizeof(sysUpTimeObject);
508  var.value = message->buffer;
509  var.valueLen = n;
510 
511  //Append sysUpTime.0 to the variable binding list
512  error = snmpWriteVarBinding(context, &var);
513  //Any error to report?
514  if(error)
515  return error;
516 
517  //Generic or enterprise-specific trap?
518  if(genericTrapType < SNMP_TRAP_ENTERPRISE_SPECIFIC)
519  {
520  //Retrieve the length of the snmpTraps OID
521  n = sizeof(snmpTrapsObject);
522  //Copy the OID
523  memcpy(message->buffer, snmpTrapsObject, n);
524 
525  //For generic traps, the SNMPv2 snmpTrapOID parameter shall be
526  //the corresponding trap as defined in section 2 of RFC 3418
527  message->buffer[n] = genericTrapType + 1;
528 
529  //Update the length of the snmpTrapOID parameter
530  n++;
531  }
532  else
533  {
534  //Retrieve the length of the enterprise OID
535  n = context->enterpriseOidLen;
536 
537  //For enterprise specific traps, the SNMPv2 snmpTrapOID parameter shall
538  //be the concatenation of the SNMPv1 enterprise OID and two additional
539  //sub-identifiers, '0' and the SNMPv1 specific trap parameter. Refer
540  //to RFC 3584, section 3.1 and RFC 2578, section 8.5
541  memcpy(message->buffer, context->enterpriseOid, n);
542 
543  //Concatenate the '0' sub-identifier
544  message->buffer[n++] = 0;
545 
546  //Concatenate the specific trap parameter
547  message->buffer[n] = specificTrapCode % 128;
548 
549  //Loop as long as necessary
550  for(i = 1; specificTrapCode > 128; i++)
551  {
552  //Split the binary representation into 7 bit chunks
553  specificTrapCode /= 128;
554  //Make room for the new chunk
555  memmove(message->buffer + n + 1, message->buffer + n, i);
556  //Set the most significant bit in the current chunk
557  message->buffer[n] = OID_MORE_FLAG | (specificTrapCode % 128);
558  }
559 
560  //Update the length of the snmpTrapOID parameter
561  n += i;
562  }
563 
564  //The snmpTrapOID.0 variable occurs as the second variable
565  //binding in every SNMPv2-Trap-PDU
566  var.oid = snmpTrapOidObject;
567  var.oidLen = sizeof(snmpTrapOidObject);
570  var.value = message->buffer;
571  var.valueLen = n;
572 
573  //Append snmpTrapOID.0 to the variable binding list
574  error = snmpWriteVarBinding(context, &var);
575  //Any error to report?
576  if(error)
577  return error;
578  }
579 #endif
580 
581  //Loop through the list of objects
582  for(i = 0; i < objectListSize; i++)
583  {
584  //Get object identifier
585  var.oid = objectList[i].oid;
586  var.oidLen = objectList[i].oidLen;
587 
588  //Retrieve object value
589  error = snmpGetObjectValue(context, message, &var);
590  //Any error to report?
591  if(error)
592  return error;
593 
594  //Append variable binding to the list
595  error = snmpWriteVarBinding(context, &var);
596  //Any error to report?
597  if(error)
598  return error;
599  }
600 
601  //Successful processing
602  return NO_ERROR;
603 }
604 
605 
606 /**
607  * @brief Translate status code
608  * @param[in,out] message Pointer to the outgoing SNMP message
609  * @param[in] status Status code
610  * @param[in] index Index of the variable binding in the list that caused an exception
611  * @return error code
612  **/
613 
615 {
616  //SNMPv1 version?
617  if(message->version == SNMP_VERSION_1)
618  {
619  //Set error-status and error-index fields (refer to RFC 2576, section 4.3)
620  switch(status)
621  {
622  case NO_ERROR:
623  //Return noError status code
624  message->errorStatus = SNMP_ERROR_NONE;
625  message->errorIndex = 0;
626  break;
627 
629  //Return tooBig status code
630  message->errorStatus = SNMP_ERROR_TOO_BIG;
631  message->errorIndex = 0;
632 
633  //Total number of SNMP PDUs which were generated by the SNMP protocol
634  //entity and for which the value of the error-status field is tooBig
635  MIB2_INC_COUNTER32(snmpGroup.snmpOutTooBigs, 1);
636  break;
637 
640  case ERROR_ACCESS_DENIED:
642  //Return noSuchName status code
643  message->errorStatus = SNMP_ERROR_NO_SUCH_NAME;
644  message->errorIndex = index;
645 
646  //Total number of SNMP PDUs which were generated by the SNMP protocol
647  //entity and for which the value of the error-status field is noSuchName
648  MIB2_INC_COUNTER32(snmpGroup.snmpOutNoSuchNames, 1);
649  break;
650 
651  case ERROR_WRONG_TYPE:
652  case ERROR_WRONG_LENGTH:
654  case ERROR_WRONG_VALUE:
656  //Return badValue status code
657  message->errorStatus = SNMP_ERROR_BAD_VALUE;
658  message->errorIndex = index;
659 
660  //Total number of SNMP PDUs which were generated by the SNMP protocol
661  //entity and for which the value of the error-status field is badValue
662  MIB2_INC_COUNTER32(snmpGroup.snmpOutBadValues, 1);
663  break;
664 
665  case ERROR_READ_FAILED:
666  case ERROR_WRITE_FAILED:
667  case ERROR_NOT_WRITABLE:
668  //Return genError status code
669  message->errorStatus = SNMP_ERROR_GENERIC;
670  message->errorIndex = index;
671 
672  //Total number of SNMP PDUs which were generated by the SNMP protocol
673  //entity and for which the value of the error-status field is genError
674  MIB2_INC_COUNTER32(snmpGroup.snmpOutGenErrs, 1);
675  break;
676 
677  default:
678  //If the parsing of the request fails, the SNMP agent discards
679  //the message and performs no further actions
680  return status;
681  }
682  }
683  //SNMPv2c or SNMPv3 version?
684  else
685  {
686  //Set error-status and error-index fields
687  switch(status)
688  {
689  case NO_ERROR:
690  //Return noError status code
691  message->errorStatus = SNMP_ERROR_NONE;
692  message->errorIndex = 0;
693  break;
694 
696  //Return tooBig status code
697  message->errorStatus = SNMP_ERROR_TOO_BIG;
698  message->errorIndex = 0;
699 
700  //Total number of SNMP PDUs which were generated by the SNMP protocol
701  //entity and for which the value of the error-status field is tooBig
702  MIB2_INC_COUNTER32(snmpGroup.snmpOutTooBigs, 1);
703  break;
704 
705  case ERROR_READ_FAILED:
706  case ERROR_WRITE_FAILED:
707  //Return genError status code
708  message->errorStatus = SNMP_ERROR_GENERIC;
709  message->errorIndex = index;
710 
711  //Total number of SNMP PDUs which were generated by the SNMP protocol
712  //entity and for which the value of the error-status field is genError
713  MIB2_INC_COUNTER32(snmpGroup.snmpOutGenErrs, 1);
714  break;
715 
718  case ERROR_ACCESS_DENIED:
719  //Return noAccess status code
720  message->errorStatus = SNMP_ERROR_NO_ACCESS;
721  message->errorIndex = index;
722  break;
723 
724  case ERROR_WRONG_TYPE:
725  //Return wrongType status code
726  message->errorStatus = SNMP_ERROR_WRONG_TYPE;
727  message->errorIndex = index;
728  break;
729 
730  case ERROR_WRONG_LENGTH:
731  //Return wrongLength status code
732  message->errorStatus = SNMP_ERROR_WRONG_LENGTH;
733  message->errorIndex = index;
734  break;
735 
737  //Return wrongEncoding status code
738  message->errorStatus = SNMP_ERROR_WRONG_ENCODING;
739  message->errorIndex = index;
740  break;
741 
742  case ERROR_WRONG_VALUE:
743  //Return wrongValue status code
744  message->errorStatus = SNMP_ERROR_WRONG_VALUE;
745  message->errorIndex = index;
746  break;
747 
749  //Return inconsistentValue status code
750  message->errorStatus = SNMP_ERROR_INCONSISTENT_VALUE;
751  message->errorIndex = index;
752  break;
753 
755  //Return authorizationError status code
756  message->errorStatus = SNMP_ERROR_AUTHORIZATION;
757  message->errorIndex = 0;
758  break;
759 
760  case ERROR_NOT_WRITABLE:
761  //Return notWritable status code
762  message->errorStatus = SNMP_ERROR_NOT_WRITABLE;
763  message->errorIndex = index;
764  break;
765 
766  default:
767  //If the parsing of the request fails, the SNMP agent discards
768  //the message and performs no further actions
769  return status;
770  }
771  }
772 
773  //Successful processing
774  return NO_ERROR;
775 }
776 
777 #endif
uint_t objType
Definition: asn1.h:98
SnmpUserEntry * snmpCreateCommunityEntry(SnmpAgentContext *context)
Create a new community entry.
uint32_t systime_t
Definition: compiler_port.h:44
char char_t
Definition: compiler_port.h:41
systime_t osGetSystemTime(void)
Retrieve system time.
uint32_t time
TCP/IP stack core.
Debugging facilities.
uint8_t p
Definition: ndp.h:295
size_t totalLength
Definition: asn1.h:101
uint8_t message[]
Definition: chap.h:150
MIB-II module.
General definitions for cryptographic algorithms.
SnmpUserEntry * snmpFindCommunityEntry(SnmpAgentContext *context, const char_t *community, size_t length)
Search the community table for a given community string.
const uint8_t * value
#define MIB2_INC_COUNTER32(name, value)
Definition: mib2_module.h:154
User table entry.
uint8_t m
Definition: ndp.h:299
const uint8_t * oid
uint8_t oid[SNMP_MAX_OID_SIZE]
error_t snmpWriteVarBinding(SnmpAgentContext *context, const SnmpVarBind *var)
Write variable binding.
Variable binding.
OID (Object Identifier)
error_t snmpCopyVarBindingList(SnmpAgentContext *context)
Copy the list of variable bindings.
ASN.1 tag.
Definition: asn1.h:94
error_t snmpTranslateStatusCode(SnmpMessage *message, error_t status, uint_t index)
Translate status code.
#define TRUE
Definition: os_port.h:48
error_t asn1WriteTag(Asn1Tag *tag, bool_t reverse, uint8_t *data, size_t *written)
Write an ASN.1 tag.
Definition: asn1.c:234
error_t asn1CheckTag(const Asn1Tag *tag, bool_t constructed, uint_t objClass, uint_t objType)
Enforce the type of a specified tag.
Definition: asn1.c:426
MIB object access.
ASN.1 (Abstract Syntax Notation One)
#define ASN1_CLASS_APPLICATION
Definition: asn1.h:46
SNMP agent (Simple Network Management Protocol)
#define SNMP_AGENT_MAX_MIBS
Definition: snmp_agent.h:67
Helper functions for SNMP agent.
void snmpUnlockMib(SnmpAgentContext *context)
Unlock MIB bases.
error_t snmpEncodeUnsignedInt32(uint32_t value, uint8_t *dest, size_t *length)
Encode a 32-bit unsigned integer.
error_t asn1ReadTag(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 tag from the input stream.
Definition: asn1.c:50
size_t length
Definition: asn1.h:99
bool_t constructed
Definition: asn1.h:96
#define OID_MORE_FLAG
Definition: oid.h:36
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.
unsigned int uint_t
Definition: compiler_port.h:43
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
Object descriptor for trap notifications.
#define SNMP_AGENT_MAX_COMMUNITIES
Definition: snmp_agent.h:74
uint_t objClass
Definition: asn1.h:97
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:45
#define SnmpAgentContext
Definition: snmp_agent.h:34
OsMutex netMutex
Definition: net.c:70
error_t snmpParseVarBinding(const uint8_t *p, size_t length, SnmpVarBind *var, size_t *consumed)
Parse variable binding.
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
#define FALSE
Definition: os_port.h:44
void snmpLockMib(SnmpAgentContext *context)
Lock MIB bases.
int bool_t
Definition: compiler_port.h:47
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
const uint8_t * value
Definition: asn1.h:100
error_t snmpWriteTrapVarBindingList(SnmpAgentContext *context, uint_t genericTrapType, uint_t specificTrapCode, const SnmpTrapObject *objectList, uint_t objectListSize)
Format the variable binding list for Trap-PDU or SNMPv2-Trap-PDU.