snmp_agent_pdu.c
Go to the documentation of this file.
1 /**
2  * @file snmp_agent_pdu.c
3  * @brief SNMP agent (PDU processing)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 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 1.9.6
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_pdu.h"
38 #include "snmp/snmp_agent_misc.h"
39 #include "snmp/snmp_agent_object.h"
40 #include "mibs/mib2_module.h"
41 #include "mibs/snmp_mib_module.h"
43 #include "core/crypto.h"
44 #include "encoding/asn1.h"
45 #include "encoding/oid.h"
46 #include "debug.h"
47 
48 //Check TCP/IP stack configuration
49 #if (SNMP_AGENT_SUPPORT == ENABLED)
50 
51 //snmpUnavailableContexts.0 object (1.3.6.1.6.3.12.1.4.0)
52 static const uint8_t snmpUnavailableContextsObject[9] = {43, 6, 1, 6, 3, 12, 1, 4, 0};
53 //snmpUnknownContexts.0 object (1.3.6.1.6.3.12.1.5.0)
54 static const uint8_t snmpUnknownContextsObject[9] = {43, 6, 1, 6, 3, 12, 1, 5, 0};
55 
56 
57 /**
58  * @brief Process PDU
59  * @param[in] context Pointer to the SNMP agent context
60  * @return Error code
61  **/
62 
64 {
65  error_t error;
66 
67  //Parse PDU header
68  error = snmpParsePduHeader(&context->request);
69  //Any error to report?
70  if(error)
71  return error;
72 
73  //Initialize response message
74  snmpInitMessage(&context->response);
75 
76  //Check PDU type
77  switch(context->request.pduType)
78  {
81  //Process GetRequest-PDU or GetNextRequest-PDU
82  error = snmpProcessGetRequestPdu(context);
83  break;
85  //Process GetBulkRequest-PDU
86  error = snmpProcessGetBulkRequestPdu(context);
87  break;
89  //Process SetRequest-PDU
90  error = snmpProcessSetRequestPdu(context);
91  break;
92 #if (SNMP_AGENT_INFORM_SUPPORT == ENABLED)
94  //Process GetResponse-PDU
95  error = snmpProcessGetResponsePdu(context);
96  break;
97  case SNMP_PDU_REPORT:
98  //Process Report-PDU
99  error = snmpProcessReportPdu(context);
100  break;
101 #endif
102  default:
103  //Invalid PDU type
104  error = ERROR_INVALID_TYPE;
105  break;
106  }
107 
108  //Check status code
109  if(!error)
110  {
111  //A GetResponse-PDU is generated by a protocol entity only upon receipt
112  //of the GetRequest-PDU, GetNextRequest-PDU, GetBulkRequest-PDU or
113  //SetRequest-PDU
114  if(context->request.pduType == SNMP_PDU_GET_REQUEST ||
115  context->request.pduType == SNMP_PDU_GET_NEXT_REQUEST ||
116  context->request.pduType == SNMP_PDU_GET_BULK_REQUEST ||
117  context->request.pduType == SNMP_PDU_SET_REQUEST)
118  {
119  //Total number of SNMP Get-Response PDUs which have been generated
120  //by the SNMP protocol entity
121  MIB2_INC_COUNTER32(snmpGroup.snmpOutGetResponses, 1);
122 
123  //Format PDU header
124  error = snmpWritePduHeader(&context->response);
125  }
126  }
127 
128  //Return status code
129  return error;
130 }
131 
132 
133 /**
134  * @brief Process GetRequest-PDU or GetNextRequest-PDU
135  * @param[in] context Pointer to the SNMP agent context
136  * @return Error code
137  **/
138 
140 {
141  error_t error;
142  int_t index;
143  size_t n;
144  size_t length;
145  const uint8_t *p;
146  SnmpVarBind var;
147 
148  //Check PDU type
149  if(context->request.pduType == SNMP_PDU_GET_REQUEST)
150  {
151  //Debug message
152  TRACE_INFO("Parsing GetRequest-PDU...\r\n");
153 
154  //Total number of SNMP Get-Request PDUs which have been accepted and
155  //processed by the SNMP protocol entity
156  MIB2_INC_COUNTER32(snmpGroup.snmpInGetRequests, 1);
157  }
158  else if(context->request.pduType == SNMP_PDU_GET_NEXT_REQUEST)
159  {
160  //Debug message
161  TRACE_INFO("Parsing GetNextRequest-PDU...\r\n");
162 
163  //Total number of SNMP Get-NextRequest PDUs which have been accepted
164  //and processed by the SNMP protocol entity
165  MIB2_INC_COUNTER32(snmpGroup.snmpInGetNexts, 1);
166  }
167 
168  //Enforce access policy
169  if(context->user.mode != SNMP_ACCESS_READ_ONLY &&
170  context->user.mode != SNMP_ACCESS_READ_WRITE)
171  {
172  //Total number of SNMP messages delivered to the SNMP protocol entity
173  //which represented an SNMP operation which was not allowed by the SNMP
174  MIB2_INC_COUNTER32(snmpGroup.snmpInBadCommunityUses, 1);
175  SNMP_MIB_INC_COUNTER32(snmpGroup.snmpInBadCommunityUses, 1);
176 
177  //Report an error
178  return ERROR_ACCESS_DENIED;
179  }
180 
181  //Initialize response message
182  error = snmpInitResponse(context);
183  //Any error to report?
184  if(error)
185  return error;
186 
187  //Point to the first variable binding of the request
188  p = context->request.varBindList;
189  length = context->request.varBindListLen;
190 
191  //Lock access to MIB bases
192  snmpLockMib(context);
193 
194  //Loop through the list
195  for(index = 1; length > 0; index++)
196  {
197  //Parse variable binding
198  error = snmpParseVarBinding(p, length, &var, &n);
199  //Failed to parse variable binding?
200  if(error)
201  break;
202 
203  //Make sure that the object identifier is valid
204  error = oidCheck(var.oid, var.oidLen);
205  //Invalid object identifier?
206  if(error)
207  break;
208 
209  //GetRequest-PDU?
210  if(context->request.pduType == SNMP_PDU_GET_REQUEST)
211  {
212  //Retrieve object value
213  error = snmpGetObjectValue(context, &context->request, &var);
214  }
215  //GetNextRequest-PDU?
216  else
217  {
218  //Search the MIB for the next object
219  error = snmpGetNextObject(context, &context->request, &var);
220 
221  //SNMPv1 version?
222  if(context->request.version == SNMP_VERSION_1)
223  {
224  //Check status code
225  if(error == NO_ERROR)
226  {
227  //Retrieve object value
228  error = snmpGetObjectValue(context, &context->request, &var);
229  }
230  else
231  {
232  //Stop immediately
233  break;
234  }
235  }
236  //SNMPv2c or SNMPv3 version?
237  else
238  {
239  //Check status code
240  if(error == NO_ERROR)
241  {
242  //Retrieve object value
243  error = snmpGetObjectValue(context, &context->request, &var);
244  }
245  else if(error == ERROR_OBJECT_NOT_FOUND)
246  {
247  //The variable binding's value field is set to endOfMibView
250  var.valueLen = 0;
251 
252  //Catch exception
253  error = NO_ERROR;
254  }
255  else
256  {
257  //Stop immediately
258  break;
259  }
260  }
261  }
262 
263  //Failed to retrieve object value?
264  if(error)
265  {
266  //SNMPv1 version?
267  if(context->request.version == SNMP_VERSION_1)
268  {
269  //Stop immediately
270  break;
271  }
272  //SNMPv2c or SNMPv3 version?
273  else
274  {
275  //Catch exception
276  if(error == ERROR_ACCESS_DENIED ||
277  error == ERROR_OBJECT_NOT_FOUND)
278  {
279  //The variable binding's value field is set to noSuchObject
282  var.valueLen = 0;
283  }
284  else if(error == ERROR_INSTANCE_NOT_FOUND)
285  {
286  //The variable binding's value field is set to noSuchInstance
289  var.valueLen = 0;
290  }
291  else
292  {
293  //Stop immediately
294  break;
295  }
296  }
297  }
298  else
299  {
300  //Total number of MIB objects which have been retrieved successfully
301  //by the SNMP protocol entity as the result of receiving valid SNMP
302  //Get-Request and Get-NextRequest PDUs
303  MIB2_INC_COUNTER32(snmpGroup.snmpInTotalReqVars, 1);
304  }
305 
306  //Append variable binding to the list
307  error = snmpWriteVarBinding(context, &var);
308  //Any error to report?
309  if(error)
310  break;
311 
312  //Advance data pointer
313  p += n;
314  length -= n;
315  }
316 
317  //Unlock access to MIB bases
318  snmpUnlockMib(context);
319 
320  //Check status code
321  if(error)
322  {
323  //Set error-status and error-index fields
324  error = snmpTranslateStatusCode(&context->response, error, index);
325  //If the parsing of the request fails, the SNMP agent discards the message
326  if(error)
327  return error;
328 
329  //Check whether an alternate Response-PDU should be sent
330  if(context->response.version != SNMP_VERSION_1 &&
331  context->response.errorStatus == SNMP_ERROR_TOO_BIG)
332  {
333  //The alternate Response-PDU is formatted with the same value in its
334  //request-id field as the received GetRequest-PDU and an empty
335  //variable-bindings field
336  context->response.varBindListLen = 0;
337  }
338  else
339  {
340  //The Response-PDU is re-formatted with the same values in its request-id
341  //and variable-bindings fields as the received GetRequest-PDU
342  error = snmpCopyVarBindingList(context);
343  //Any error to report?
344  if(error)
345  return error;
346  }
347  }
348 
349  //Successful processing
350  return NO_ERROR;
351 }
352 
353 
354 /**
355  * @brief Process GetBulkRequest-PDU
356  * @param[in] context Pointer to the SNMP agent context
357  * @return Error code
358  **/
359 
361 {
362 #if (SNMP_V2C_SUPPORT == ENABLED || SNMP_V3_SUPPORT == ENABLED)
363  error_t error;
364  int_t index;
365  size_t n;
366  size_t m;
367  size_t length;
368  bool_t endOfMibView;
369  const uint8_t *p;
370  const uint8_t *next;
371  SnmpVarBind var;
372 
373  //Debug message
374  TRACE_INFO("Parsing GetBulkRequest-PDU...\r\n");
375 
376  //Make sure the SNMP version identifier is valid
377  if(context->request.version == SNMP_VERSION_1)
378  {
379  //The SNMP version is not acceptable
380  return ERROR_INVALID_TYPE;
381  }
382 
383  //Enforce access policy
384  if(context->user.mode != SNMP_ACCESS_READ_ONLY &&
385  context->user.mode != SNMP_ACCESS_READ_WRITE)
386  {
387  //Total number of SNMP messages delivered to the SNMP protocol entity
388  //which represented an SNMP operation which was not allowed by the SNMP
389  MIB2_INC_COUNTER32(snmpGroup.snmpInBadCommunityUses, 1);
390  SNMP_MIB_INC_COUNTER32(snmpGroup.snmpInBadCommunityUses, 1);
391 
392  //Report an error
393  return ERROR_ACCESS_DENIED;
394  }
395 
396  //Initialize response message
397  error = snmpInitResponse(context);
398  //Any error to report?
399  if(error)
400  return error;
401 
402  //Point to the first variable binding of the request
403  p = context->request.varBindList;
404  length = context->request.varBindListLen;
405 
406  //Lock access to MIB bases
407  snmpLockMib(context);
408 
409  //Loop through the list
410  for(index = 1; length > 0; index++)
411  {
412  //The non-repeaters field specifies the number of non-repeating objects
413  //at the start of the variable binding list
414  if((index - 1) == context->request.nonRepeaters)
415  {
416  //Pointer to the first variable binding that will be processed during
417  //the next iteration
418  next = context->response.varBindList + context->response.varBindListLen;
419 
420  //Actual size of the variable binding list
421  m = context->response.varBindListLen;
422 
423  //This flag tells whether all variable bindings have the value field
424  //set to endOfMibView for a given iteration
425  endOfMibView = TRUE;
426 
427  //If the max-repetitions field is zero, the list is trimmed to the
428  //first non-repeating variable bindings
429  if(context->request.maxRepetitions == 0)
430  break;
431  }
432 
433  //Parse variable binding
434  error = snmpParseVarBinding(p, length, &var, &n);
435  //Failed to parse variable binding?
436  if(error)
437  break;
438 
439  //Make sure that the object identifier is valid
440  error = oidCheck(var.oid, var.oidLen);
441  //Invalid object identifier?
442  if(error)
443  break;
444 
445  //Search the MIB for the next object
446  error = snmpGetNextObject(context, &context->request, &var);
447 
448  //Check status code
449  if(error == NO_ERROR)
450  {
451  //Next object found
452  endOfMibView = FALSE;
453  //Retrieve object value
454  error = snmpGetObjectValue(context, &context->request, &var);
455  }
456  else if(error == ERROR_OBJECT_NOT_FOUND)
457  {
458  //The variable binding's value field is set to endOfMibView
461  var.valueLen = 0;
462 
463  //Catch exception
464  error = NO_ERROR;
465  }
466  else
467  {
468  //Stop immediately
469  break;
470  }
471 
472  //Failed to retrieve object value?
473  if(error)
474  {
475  //Catch exception
476  if(error == ERROR_ACCESS_DENIED ||
477  error == ERROR_OBJECT_NOT_FOUND)
478  {
479  //The variable binding's value field is set to noSuchObject
482  var.valueLen = 0;
483  }
484  else if(error == ERROR_INSTANCE_NOT_FOUND)
485  {
486  //The variable binding's value field is set to noSuchInstance
489  var.valueLen = 0;
490  }
491  else
492  {
493  //Stop immediately
494  break;
495  }
496  }
497  else
498  {
499  //Total number of MIB objects which have been retrieved successfully
500  //by the SNMP protocol entity as the result of receiving valid SNMP
501  //Get-Request and Get-NextRequest PDUs
502  MIB2_INC_COUNTER32(snmpGroup.snmpInTotalReqVars, 1);
503  }
504 
505  //Append variable binding to the list
506  error = snmpWriteVarBinding(context, &var);
507  //Any error to report?
508  if(error)
509  break;
510 
511  //Advance data pointer
512  p += n;
513  length -= n;
514 
515  //Next iteration?
516  if(length == 0 && index > context->request.nonRepeaters)
517  {
518  //Decrement repeat counter
519  context->request.maxRepetitions--;
520 
521  //Last iteration?
522  if(!context->request.maxRepetitions)
523  break;
524  //All variable bindings have the value field set to endOfMibView?
525  if(endOfMibView)
526  break;
527 
528  //Point to the first variable binding to be processed
529  p = next;
530  //Number of bytes to be processed
531  length = context->response.varBindListLen - m;
532  //Rewind index
533  index = context->request.nonRepeaters;
534  }
535  }
536 
537  //Unlock access to MIB bases
538  snmpUnlockMib(context);
539 
540  //Check status code
541  if(error == ERROR_BUFFER_OVERFLOW)
542  {
543  //If the size of the message containing the requested number of variable
544  //bindings would be greater than the maximum message size, then the
545  //response is generated with a lesser number of variable bindings
546  }
547  else if(error)
548  {
549  //Set error-status and error-index fields
550  error = snmpTranslateStatusCode(&context->response, error, index);
551  //If the parsing of the request fails, the SNMP agent discards the message
552  if(error)
553  return error;
554 
555  //The Response-PDU is re-formatted with the same values in its request-id
556  //and variable-bindings fields as the received GetRequest-PDU
557  error = snmpCopyVarBindingList(context);
558  //Any error to report?
559  if(error)
560  return error;
561  }
562 
563  //Successful processing
564  return NO_ERROR;
565 #else
566  //Not implemented
567  return ERROR_NOT_IMPLEMENTED;
568 #endif
569 }
570 
571 
572 /**
573  * @brief Process SetRequest-PDU
574  * @param[in] context Pointer to the SNMP agent context
575  * @return Error code
576  **/
577 
579 {
580  error_t error;
581  int_t index;
582  size_t n;
583  size_t length;
584  const uint8_t *p;
585  SnmpVarBind var;
586 
587  //Debug message
588  TRACE_INFO("Parsing SetRequest-PDU...\r\n");
589 
590  //Total number of SNMP Set-Request PDUs which have been accepted and
591  //processed by the SNMP protocol entity
592  MIB2_INC_COUNTER32(snmpGroup.snmpInSetRequests, 1);
593 
594  //Enforce access policy
595  if(context->user.mode != SNMP_ACCESS_WRITE_ONLY &&
596  context->user.mode != SNMP_ACCESS_READ_WRITE)
597  {
598  //Total number of SNMP messages delivered to the SNMP protocol entity
599  //which represented an SNMP operation which was not allowed by the SNMP
600  MIB2_INC_COUNTER32(snmpGroup.snmpInBadCommunityUses, 1);
601  SNMP_MIB_INC_COUNTER32(snmpGroup.snmpInBadCommunityUses, 1);
602 
603  //Report an error
604  return ERROR_ACCESS_DENIED;
605  }
606 
607  //Initialize response message
608  error = snmpInitResponse(context);
609  //Any error to report?
610  if(error)
611  return error;
612 
613  //The variable bindings are processed as a two phase operation. In the
614  //first phase, each variable binding is validated
615  p = context->request.varBindList;
616  length = context->request.varBindListLen;
617 
618  //Lock access to MIB bases
619  snmpLockMib(context);
620 
621  //Loop through the list
622  for(index = 1; length > 0; index++)
623  {
624  //Parse variable binding
625  error = snmpParseVarBinding(p, length, &var, &n);
626  //Failed to parse variable binding?
627  if(error)
628  break;
629 
630  //Assign object value
631  error = snmpSetObjectValue(context, &context->request, &var, FALSE);
632  //Any error to report?
633  if(error)
634  break;
635 
636  //Advance data pointer
637  p += n;
638  length -= n;
639  }
640 
641  //If all validations are successful, then each variable is altered in
642  //the second phase
643  if(!error)
644  {
645  //The changes are committed to the MIB base during the second phase
646  p = context->request.varBindList;
647  length = context->request.varBindListLen;
648 
649  //Loop through the list
650  for(index = 1; length > 0; index++)
651  {
652  //Parse variable binding
653  error = snmpParseVarBinding(p, length, &var, &n);
654  //Failed to parse variable binding?
655  if(error)
656  break;
657 
658  //Assign object value
659  error = snmpSetObjectValue(context, &context->request, &var, TRUE);
660  //Any error to report?
661  if(error)
662  break;
663 
664  //Total number of MIB objects which have been altered successfully
665  //by the SNMP protocol entity as the result of receiving valid
666  //SNMP Set-Request PDUs
667  MIB2_INC_COUNTER32(snmpGroup.snmpInTotalSetVars, 1);
668 
669  //Advance data pointer
670  p += n;
671  length -= n;
672  }
673  }
674 
675  //Unlock access to MIB bases
676  snmpUnlockMib(context);
677 
678  //Any error to report?
679  if(error)
680  {
681  //Set error-status and error-index fields
682  error = snmpTranslateStatusCode(&context->response, error, index);
683  //If the parsing of the request fails, the SNMP agent discards the message
684  if(error)
685  return error;
686  }
687 
688  //The SNMP agent sends back a GetResponse-PDU of identical form
689  error = snmpCopyVarBindingList(context);
690  //Return status code
691  return error;
692 }
693 
694 
695 /**
696  * @brief Format Report-PDU
697  * @param[in] context Pointer to the SNMP agent context
698  * @param[in] errorIndication Error indication
699  * @return Error code
700  **/
701 
703 {
704  error_t error;
705 
706 #if (SNMP_V3_SUPPORT == ENABLED)
707  size_t n;
708  uint32_t counter;
709  SnmpVarBind var;
710 
711  //Initialize SNMP message
712  snmpInitMessage(&context->response);
713 
714  //SNMP version identifier
715  context->response.version = context->request.version;
716 
717  //Message identifier
718  context->response.msgId = context->request.msgId;
719  //Maximum message size supported by the sender
720  context->response.msgMaxSize = SNMP_MAX_MSG_SIZE;
721  //Bit fields which control processing of the message
722  context->response.msgFlags = 0;
723  //Security model used by the sender
724  context->response.msgSecurityModel = SNMP_SECURITY_MODEL_USM;
725 
726  //Authoritative engine identifier
727  context->response.msgAuthEngineId = context->contextEngine;
728  context->response.msgAuthEngineIdLen = context->contextEngineLen;
729 
730  //Number of times the SNMP engine has rebooted
731  context->response.msgAuthEngineBoots = context->engineBoots;
732  //Number of seconds since last reboot
733  context->response.msgAuthEngineTime = context->engineTime;
734 
735  //Context engine identifier
736  context->response.contextEngineId = context->contextEngine;
737  context->response.contextEngineIdLen = context->contextEngineLen;
738 
739  //Context name
740  context->response.contextName = context->contextName;
741  context->response.contextNameLen = strlen(context->contextName);
742 
743  //PDU type
744  context->response.pduType = SNMP_PDU_REPORT;
745  //Request identifier
746  context->response.requestId = context->request.requestId;
747 
748  //If the message is considered to be outside of the time window, the error
749  //must be reported with a securityLevel of authNoPriv (refer to RFC 3414,
750  //section 3.2)
751  if(errorIndication == ERROR_NOT_IN_TIME_WINDOW)
752  {
753  //Bit fields which control processing of the message
754  context->response.msgFlags = context->request.msgFlags &
756 
757  //User name
758  context->response.msgUserName = context->request.msgUserName;
759  context->response.msgUserNameLen = context->request.msgUserNameLen;
760 
761  //Authentication parameters
762  context->response.msgAuthParameters = NULL;
763  context->response.msgAuthParametersLen = context->request.msgAuthParametersLen;
764 
765  //Privacy parameters
766  context->response.msgPrivParameters = context->privParameters;
767  context->response.msgPrivParametersLen = context->request.msgPrivParametersLen;
768  }
769 
770  //Make room for the message header at the beginning of the buffer
771  error = snmpComputeMessageOverhead(&context->response);
772  //Any error to report?
773  if(error)
774  return error;
775 
776  //Initialize counter value
777  counter = 1;
778 
779  //Check error indication
780  switch(errorIndication)
781  {
783  //Total number of packets received by the SNMP engine which were dropped
784  //because they requested a securityLevel that was unknown to the SNMP
785  //engine or otherwise unavailable
786  SNMP_USM_MIB_INC_COUNTER32(usmStatsUnsupportedSecLevels , 1);
787  SNMP_USM_MIB_GET_COUNTER32(counter, usmStatsUnsupportedSecLevels);
788 
789  //Add the usmStatsUnsupportedSecLevels counter in the varBindList
792  break;
793 
795  //Total number of packets received by the SNMP engine which were dropped
796  //because they appeared outside of the authoritative SNMP engine's window
797  SNMP_USM_MIB_INC_COUNTER32(usmStatsNotInTimeWindows , 1);
798  SNMP_USM_MIB_GET_COUNTER32(counter, usmStatsNotInTimeWindows);
799 
800  //Add the usmStatsNotInTimeWindows counter in the varBindList
803  break;
804 
806  //Total number of packets received by the SNMP engine which were dropped
807  //because they referenced a user that was not known to the SNMP engine
808  SNMP_USM_MIB_INC_COUNTER32(usmStatsUnknownUserNames , 1);
809  SNMP_USM_MIB_GET_COUNTER32(counter, usmStatsUnknownUserNames);
810 
811  //Add the usmStatsUnknownUserNames counter in the varBindList
814  break;
815 
817  //Total number of packets received by the SNMP engine which were dropped
818  //because they referenced an snmpEngineID that was not known to the SNMP
819  //engine
820  SNMP_USM_MIB_INC_COUNTER32(usmStatsUnknownEngineIDs , 1);
821  SNMP_USM_MIB_GET_COUNTER32(counter, usmStatsUnknownEngineIDs);
822 
823  //Add the usmStatsUnknownEngineIDs counter in the varBindList
826  break;
827 
829  //Total number of packets received by the SNMP engine which were dropped
830  //because they didn't contain the expected digest value
831  SNMP_USM_MIB_INC_COUNTER32(usmStatsWrongDigests , 1);
832  SNMP_USM_MIB_GET_COUNTER32(counter, usmStatsWrongDigests);
833 
834  //Add the usmStatsWrongDigests counter in the varBindList
836  var.oidLen = sizeof(usmStatsWrongDigestsObject);
837  break;
838 
840  //Total number of packets received by the SNMP engine which were dropped
841  //because they could not be decrypted
842  SNMP_USM_MIB_INC_COUNTER32(usmStatsDecryptionErrors , 1);
843  SNMP_USM_MIB_GET_COUNTER32(counter, usmStatsDecryptionErrors);
844 
845  //Add the usmStatsDecryptionErrors counter in the varBindList
848  break;
849 
851  //Total number of packets received by the SNMP engine which were dropped
852  //because the context contained in the message was unavailable
853  counter = 1;
854 
855  //Add the snmpUnavailableContexts counter in the varBindList
856  var.oid = snmpUnavailableContextsObject;
857  var.oidLen = sizeof(snmpUnavailableContextsObject);
858  break;
859 
861  //Total number of packets received by the SNMP engine which were dropped
862  //because the context contained in the message was unknown
863  counter = 1;
864 
865  //Add the snmpUnknownContexts counter in the varBindList
866  var.oid = snmpUnknownContextsObject;
867  var.oidLen = sizeof(snmpUnknownContextsObject);
868  break;
869 
870  default:
871  //Just for sanity's sake...
872  var.oid = NULL;
873  var.oidLen = 0;
874  break;
875  }
876 
877  //Encode the object value using ASN.1 rules
878  error = snmpEncodeUnsignedInt32(counter, context->response.buffer, &n);
879  //Any error to report?
880  if(error)
881  return error;
882 
883  //The counter is encoded in ASN.1 format
886  var.value = context->response.buffer;
887  var.valueLen = n;
888 
889  //Append the variable binding list to the varBindList
890  error = snmpWriteVarBinding(context, &var);
891  //Any error to report?
892  if(error)
893  return error;
894 
895  //Format PDU header
896  error = snmpWritePduHeader(&context->response);
897 #else
898  //SNMPv3 is not supported
899  error = ERROR_NOT_IMPLEMENTED;
900 #endif
901 
902  //Return status code
903  return error;
904 }
905 
906 #endif
@ ERROR_UNKNOWN_ENGINE_ID
Definition: error.h:255
MIB-II module.
error_t snmpProcessReportPdu(SnmpAgentContext *context)
Process Report-PDU.
uint8_t length
Definition: dtls_misc.h:149
error_t snmpProcessPdu(SnmpAgentContext *context)
Process PDU.
@ ERROR_UNKNOWN_USER_NAME
Definition: error.h:256
int bool_t
Definition: compiler_port.h:49
#define SNMP_USM_MIB_INC_COUNTER32(name, value)
@ SNMP_PDU_GET_REQUEST
Definition: snmp_common.h:150
error_t snmpEncodeUnsignedInt32(uint32_t value, uint8_t *dest, size_t *length)
Encode a 32-bit unsigned integer.
@ ERROR_UNKNOWN_CONTEXT
Definition: error.h:257
const uint8_t * value
@ SNMP_ACCESS_READ_WRITE
Variable binding.
signed int int_t
Definition: compiler_port.h:44
@ SNMP_EXCEPTION_END_OF_MIB_VIEW
Definition: snmp_common.h:214
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:140
@ SNMP_ERROR_TOO_BIG
Definition: snmp_common.h:185
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
@ ERROR_DECRYPTION_FAILED
Definition: error.h:236
OID (Object Identifier)
uint8_t p
Definition: ndp.h:298
@ SNMP_PDU_GET_RESPONSE
Definition: snmp_common.h:152
@ SNMP_PDU_SET_REQUEST
Definition: snmp_common.h:153
#define SNMP_USM_MIB_GET_COUNTER32(value, name)
#define TRUE
Definition: os_port.h:50
error_t snmpParsePduHeader(SnmpMessage *message)
Parse PDU header.
error_t snmpCopyVarBindingList(SnmpAgentContext *context)
Copy the list of variable bindings.
error_t snmpSetObjectValue(SnmpAgentContext *context, const SnmpMessage *message, SnmpVarBind *var, bool_t commit)
Assign object value.
@ SNMP_SECURITY_MODEL_USM
User-based security model.
@ SNMP_EXCEPTION_NO_SUCH_OBJECT
Definition: snmp_common.h:212
#define SNMP_MIB_INC_COUNTER32(name, value)
error_t snmpProcessGetRequestPdu(SnmpAgentContext *context)
Process GetRequest-PDU or GetNextRequest-PDU.
SNMP MIB module.
SNMP agent (Simple Network Management Protocol)
@ SNMP_MSG_FLAG_PRIV
error_t snmpTranslateStatusCode(SnmpMessage *message, error_t status, uint_t index)
Translate status code.
error_t snmpFormatReportPdu(SnmpAgentContext *context, error_t errorIndication)
Format Report-PDU.
const uint8_t usmStatsNotInTimeWindowsObject[10]
error_t snmpWriteVarBinding(SnmpAgentContext *context, const SnmpVarBind *var)
Write variable binding.
#define FALSE
Definition: os_port.h:46
@ MIB_TYPE_COUNTER32
Definition: mib_common.h:61
error_t snmpInitResponse(SnmpAgentContext *context)
Initialize a GetResponse-PDU.
const uint8_t * oid
error_t
Error codes.
Definition: error.h:42
@ SNMP_ACCESS_READ_ONLY
@ ERROR_INSTANCE_NOT_FOUND
Definition: error.h:251
error_t snmpGetNextObject(SnmpAgentContext *context, const SnmpMessage *message, SnmpVarBind *var)
Search MIBs for the next object.
@ ERROR_UNAVAILABLE_CONTEXT
Definition: error.h:258
@ ERROR_NOT_IN_TIME_WINDOW
Definition: error.h:260
@ SNMP_PDU_GET_BULK_REQUEST
Definition: snmp_common.h:155
General definitions for cryptographic algorithms.
const uint8_t usmStatsWrongDigestsObject[10]
Helper functions for SNMP agent.
const uint8_t usmStatsUnknownEngineIdsObject[10]
void snmpLockMib(SnmpAgentContext *context)
Lock MIB bases.
@ ERROR_ACCESS_DENIED
Definition: error.h:146
@ ERROR_INVALID_TYPE
Definition: error.h:113
@ SNMP_MSG_FLAG_AUTH
#define TRACE_INFO(...)
Definition: debug.h:94
error_t snmpProcessSetRequestPdu(SnmpAgentContext *context)
Process SetRequest-PDU.
@ SNMP_ACCESS_WRITE_ONLY
@ SNMP_PDU_GET_NEXT_REQUEST
Definition: snmp_common.h:151
@ SNMP_EXCEPTION_NO_SUCH_INSTANCE
Definition: snmp_common.h:213
error_t oidCheck(const uint8_t *oid, size_t oidLen)
Check whether the specified object identifier is valid.
Definition: oid.c:50
@ SNMP_PDU_REPORT
Definition: snmp_common.h:158
uint8_t m
Definition: ndp.h:302
#define SNMP_MAX_MSG_SIZE
Definition: snmp_common.h:60
uint8_t n
error_t snmpParseVarBinding(const uint8_t *p, size_t length, SnmpVarBind *var, size_t *consumed)
Parse variable binding.
const uint8_t usmStatsDecryptionErrorsObject[10]
@ ERROR_AUTHENTICATION_FAILED
Definition: error.h:69
error_t snmpWritePduHeader(SnmpMessage *message)
Format PDU header.
@ ERROR_OBJECT_NOT_FOUND
Definition: error.h:250
#define ASN1_CLASS_CONTEXT_SPECIFIC
Definition: asn1.h:50
#define MIB2_INC_COUNTER32(name, value)
Definition: mib2_module.h:156
@ SNMP_VERSION_1
Definition: snmp_common.h:138
error_t snmpProcessGetResponsePdu(SnmpAgentContext *context)
Process GetResponse-PDU.
#define SnmpAgentContext
Definition: snmp_agent.h:36
MIB object access.
error_t snmpGetObjectValue(SnmpAgentContext *context, const SnmpMessage *message, SnmpVarBind *var)
Retrieve object value.
SNMP USM MIB module.
SNMP agent (PDU processing)
error_t snmpComputeMessageOverhead(SnmpMessage *message)
Compute SNMP message overhead.
const uint8_t usmStatsUnsupportedSecLevelsObject[10]
error_t snmpProcessGetBulkRequestPdu(SnmpAgentContext *context)
Process GetBulkRequest-PDU.
TCP/IP stack core.
#define ASN1_CLASS_APPLICATION
Definition: asn1.h:49
uint16_t next
Definition: ipv4_frag.h:97
void snmpUnlockMib(SnmpAgentContext *context)
Unlock MIB bases.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
ASN.1 (Abstract Syntax Notation One)
void snmpInitMessage(SnmpMessage *message)
Initialize a SNMP message.
const uint8_t usmStatsUnknownUserNamesObject[10]
@ ERROR_UNSUPPORTED_SECURITY_LEVEL
Definition: error.h:259