snmp_agent_message.c
Go to the documentation of this file.
1/**
2 * @file snmp_message.c
3 * @brief SNMP message formatting and parsing
4 *
5 * @section License
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 *
9 * Copyright (C) 2010-2021 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.1.2
29 **/
30
31//Switch to the appropriate trace level
32#define TRACE_LEVEL SNMP_TRACE_LEVEL
33
34//Dependencies
35#include "core/net.h"
36#include "snmp/snmp_agent.h"
39#include "core/crypto.h"
40#include "encoding/asn1.h"
41#include "debug.h"
42
43//Check TCP/IP stack configuration
44#if (SNMP_AGENT_SUPPORT == ENABLED)
45
46
47/**
48 * @brief Initialize a SNMP message
49 * @param[in] message Pointer to the SNMP message
50 **/
51
53{
54 //Current position in the message
55 message->pos = NULL;
56 //Length of the message
57 message->length = 0;
58
59 //SNMP version identifier
60 message->version = SNMP_VERSION_1;
61
62#if (SNMP_V1_SUPPORT == ENABLED || SNMP_V2C_SUPPORT == ENABLED)
63 //Initialize community name
64 message->community = NULL;
65 message->communityLen = 0;
66#endif
67
68#if (SNMP_V3_SUPPORT == ENABLED)
69 //Initialize msgGlobalData fields
70 message->msgId = 0;
71 message->msgMaxSize = 0;
72 message->msgFlags = 0;
73 message->msgSecurityModel = 0;
74
75 //Initialize msgSecurityParameters fields
76 message->msgAuthEngineId = NULL;
77 message->msgAuthEngineIdLen = 0;
78 message->msgAuthEngineBoots = 0;
79 message->msgAuthEngineTime = 0;
80 message->msgUserName = NULL;
81 message->msgUserNameLen = 0;
82 message->msgAuthParameters = NULL;
83 message->msgAuthParametersLen = 0;
84 message->msgPrivParameters = NULL;
85 message->msgPrivParametersLen = 0;
86
87 //Initialize scopedPDU fields
88 message->contextEngineId = NULL;
89 message->contextEngineIdLen = 0;
90 message->contextName = NULL;
91 message->contextNameLen = 0;
92#endif
93
94 //Initialize PDU fields
96 message->requestId = 0;
97 message->errorStatus = SNMP_ERROR_NONE;
98 message->errorIndex = 0;
99
100#if (SNMP_V1_SUPPORT == ENABLED)
101 message->enterpriseOid = NULL;
102 message->enterpriseOidLen = 0;
103 message->agentAddr = IPV4_UNSPECIFIED_ADDR;
104 message->genericTrapType = 0;
105 message->specificTrapCode = 0;
106 message->timestamp = 0;
107#endif
108
109#if (SNMP_V2C_SUPPORT == ENABLED || SNMP_V3_SUPPORT == ENABLED)
110 message->nonRepeaters = 0;
111 message->maxRepetitions = 0;
112#endif
113
114 //Initialize the list of variable bindings
115 message->varBindList = NULL;
116 message->varBindListLen = 0;
117 message->varBindListMaxLen = 0;
118 message->oidLen = 0;
119}
120
121
122/**
123 * @brief Initialize a GetResponse-PDU
124 * @param[in] context Pointer to the SNMP agent context
125 * @return Error code
126 **/
127
129{
130 error_t error;
131
132 //SNMP version identifier
133 context->response.version = context->request.version;
134
135#if (SNMP_V1_SUPPORT == ENABLED || SNMP_V2C_SUPPORT == ENABLED)
136 //Community name
137 context->response.community = context->request.community;
138 context->response.communityLen = context->request.communityLen;
139#endif
140
141#if (SNMP_V3_SUPPORT == ENABLED)
142 //Message identifier
143 context->response.msgId = context->request.msgId;
144 //Maximum message size supported by the sender
145 context->response.msgMaxSize = SNMP_MAX_MSG_SIZE;
146
147 //Bit fields which control processing of the message
148 context->response.msgFlags = context->request.msgFlags &
150
151 //Security model used by the sender
152 context->response.msgSecurityModel = context->request.msgSecurityModel;
153
154 //Authoritative engine identifier
155 context->response.msgAuthEngineId = context->contextEngine;
156 context->response.msgAuthEngineIdLen = context->contextEngineLen;
157
158 //Number of times the SNMP engine has rebooted
159 context->response.msgAuthEngineBoots = context->engineBoots;
160 //Number of seconds since last reboot
161 context->response.msgAuthEngineTime = context->engineTime;
162
163 //User name
164 context->response.msgUserName = context->request.msgUserName;
165 context->response.msgUserNameLen = context->request.msgUserNameLen;
166
167 //Authentication parameters
168 context->response.msgAuthParameters = NULL;
169 context->response.msgAuthParametersLen = context->request.msgAuthParametersLen;
170
171 //Privacy parameters
172 context->response.msgPrivParameters = context->privParameters;
173 context->response.msgPrivParametersLen = context->request.msgPrivParametersLen;
174
175 //Context engine identifier
176 context->response.contextEngineId = context->contextEngine;
177 context->response.contextEngineIdLen = context->contextEngineLen;
178
179 //Context name
180 context->response.contextName = context->request.contextName;
181 context->response.contextNameLen = context->request.contextNameLen;
182#endif
183
184 //PDU type
185 context->response.pduType = SNMP_PDU_GET_RESPONSE;
186 //Request identifier
187 context->response.requestId = context->request.requestId;
188
189 //Make room for the message header at the beginning of the buffer
190 error = snmpComputeMessageOverhead(&context->response);
191 //Return status code
192 return error;
193}
194
195
196/**
197 * @brief Compute SNMP message overhead
198 * @param[in] message Pointer to the SNMP message
199 **/
200
202{
203 size_t n;
204
205#if (SNMP_V1_SUPPORT == ENABLED)
206 //SNMPv1 version?
207 if(message->version == SNMP_VERSION_1)
208 {
209 //SNMPv1 message header overhead
211 //Take into consideration variable-length fields
212 n += message->communityLen + message->enterpriseOidLen;
213 }
214 else
215#endif
216#if (SNMP_V2C_SUPPORT == ENABLED)
217 //SNMPv2c version?
218 if(message->version == SNMP_VERSION_2C)
219 {
220 //SNMPv2c message header overhead
222 //Take into consideration variable-length fields
223 n += message->communityLen;
224 }
225 else
226#endif
227#if (SNMP_V3_SUPPORT == ENABLED)
228 //SNMPv3 version?
229 if(message->version == SNMP_VERSION_3)
230 {
231 //SNMPv3 message header overhead
233
234 //Take into consideration variable-length fields
235 n += message->msgAuthEngineIdLen + message->msgUserNameLen +
236 message->msgAuthParametersLen + message->msgPrivParametersLen +
237 message->contextEngineIdLen + message->contextNameLen;
238 }
239 else
240#endif
241 //Invalid SNMP version?
242 {
243 //Report an error
245 }
246
247 //Sanity check
249 return ERROR_FAILURE;
250
251 //Make room for the message header at the beginning of the buffer
252 message->varBindList = message->buffer + n;
253 //Maximum length of the variable binding list
254 message->varBindListMaxLen = (SNMP_MAX_MSG_SIZE - SNMP_MSG_ENCRYPTION_OVERHEAD) - n;
255
256 //Successful processing
257 return NO_ERROR;
258}
259
260
261/**
262 * @brief Parse SNMP message header
263 * @param[in,out] message Pointer to the incoming SNMP message
264 * @return Error code
265 **/
266
268{
269 error_t error;
270 size_t length;
271 const uint8_t *p;
272 Asn1Tag tag;
273
274 //Point to the first byte of the SNMP message
275 p = message->buffer;
276 //Retrieve the length of the SNMP message
277 length = message->bufferLen;
278
279 //The SNMP message is encapsulated within a sequence
280 error = asn1ReadSequence(p, length, &tag);
281 //Failed to decode ASN.1 tag?
282 if(error)
283 return error;
284
285 //Point to the first field of the sequence
286 p = tag.value;
287 length = tag.length;
288
289 //Read version identifier
290 error = asn1ReadInt32(p, length, &tag, &message->version);
291 //Failed to decode ASN.1 tag?
292 if(error)
293 return error;
294
295 //Make sure the SNMP version identifier is valid
296 if(message->version != SNMP_VERSION_1 &&
297 message->version != SNMP_VERSION_2C &&
298 message->version != SNMP_VERSION_3)
299 {
300 //The SNMP version is not acceptable
302 }
303
304 //Advance data pointer
305 message->pos = (uint8_t *) p + tag.totalLength;
306 //Remaining bytes to process
307 message->length = length - tag.totalLength;
308
309 //Successful processing
310 return NO_ERROR;
311}
312
313
314/**
315 * @brief Format SNMP message header
316 * @param[in,out] message Pointer to the outgoing SNMP message
317 * @return Error code
318 **/
319
321{
322 error_t error;
323 size_t n;
324 Asn1Tag tag;
325
326 //SNMPv1 or SNMPv2c version?
327 if(message->version == SNMP_VERSION_1 ||
328 message->version == SNMP_VERSION_2C)
329 {
330 //Write the community name
332 //Any error to report?
333 if(error)
334 return error;
335 }
336 //SNMPv3 version?
337 else if(message->version == SNMP_VERSION_3)
338 {
339 //Write msgSecurityParameters field
341 //Any error to report?
342 if(error)
343 return error;
344
345 //Write msgGlobalData field
347 //Any error to report?
348 if(error)
349 return error;
350 }
351 //Invalid version?
352 else
353 {
354 //Report an error
356 }
357
358 //Write version identifier
359 error = asn1WriteInt32(message->version, TRUE, message->pos, &n);
360 //Any error to report?
361 if(error)
362 return error;
363
364 //Move backward
365 message->pos -= n;
366 //Update the length of the message
367 message->length += n;
368
369 //The SNMP message is encapsulated within a sequence
370 tag.constructed = TRUE;
373 tag.length = message->length;
374 tag.value = NULL;
375
376 //Write the corresponding ASN.1 tag
377 error = asn1WriteTag(&tag, TRUE, message->pos, &n);
378 //Any error to report?
379 if(error)
380 return error;
381
382 //Move backward
383 message->pos -= n;
384 //Total length of the SNMP message
385 message->length += n;
386
387 //Successful processing
388 return NO_ERROR;
389}
390
391
392/**
393 * @brief Parse community name
394 * @param[in,out] message Pointer to the incoming SNMP message
395 * @return Error code
396 **/
397
399{
400#if (SNMP_V1_SUPPORT == ENABLED || SNMP_V2C_SUPPORT == ENABLED)
401 error_t error;
402 Asn1Tag tag;
403
404 //Read community name
405 error = asn1ReadTag(message->pos, message->length, &tag);
406 //Failed to decode ASN.1 tag?
407 if(error)
408 return error;
409
410 //Enforce encoding, class and type
412 //The tag does not match the criteria?
413 if(error)
414 return error;
415
416 //Save community name
417 message->community = (char_t *) tag.value;
418 message->communityLen = tag.length;
419
420 //Advance data pointer
421 message->pos += tag.totalLength;
422 //Remaining bytes to process
423 message->length -= tag.totalLength;
424
425 //No error to report
426 return NO_ERROR;
427#else
428 //Not implemented
430#endif
431}
432
433
434/**
435 * @brief Format community name
436 * @param[in,out] message Pointer to the outgoing SNMP message
437 * @return Error code
438 **/
439
441{
442#if (SNMP_V1_SUPPORT == ENABLED || SNMP_V2C_SUPPORT == ENABLED)
443 error_t error;
444 size_t n;
445 Asn1Tag tag;
446
447 //The community name is an octet string
448 tag.constructed = FALSE;
451 tag.length = message->communityLen;
452 tag.value = (uint8_t *) message->community;
453
454 //Write the corresponding ASN.1 tag
455 error = asn1WriteTag(&tag, TRUE, message->pos, &n);
456 //Any error to report?
457 if(error)
458 return error;
459
460 //Point to the first byte of the community name
461 message->pos -= n;
462 //Total length of the message
463 message->length += n;
464
465 //Successful processing
466 return NO_ERROR;
467#else
468 //Not implemented
470#endif
471}
472
473
474/**
475 * @brief Parse msgGlobalData field
476 * @param[in,out] message Pointer to the incoming SNMP message
477 * @return Error code
478 **/
479
481{
482#if (SNMP_V3_SUPPORT == ENABLED)
483 error_t error;
484 size_t length;
485 const uint8_t *p;
486 Asn1Tag tag;
487
488 //Read the msgGlobalData field
489 error = asn1ReadSequence(message->pos, message->length, &tag);
490 //Failed to decode ASN.1 tag?
491 if(error)
492 return error;
493
494 //Advance pointer over the msgGlobalData field
495 message->pos += tag.totalLength;
496 //Remaining bytes to process
497 message->length -= tag.totalLength;
498
499 //Point to the first field of the sequence
500 p = tag.value;
501 length = tag.length;
502
503 //The msgID is used between two SNMP entities to coordinate request
504 //messages and responses
505 error = asn1ReadInt32(p, length, &tag, &message->msgId);
506 //Failed to decode ASN.1 tag?
507 if(error)
508 return error;
509
510 //Make sure the value is in the range 0..2147483647
511 if(message->msgId < 0)
513
514 //Point to the next field
515 p += tag.totalLength;
516 length -= tag.totalLength;
517
518 //The msgMaxSize field of the message conveys the maximum message size
519 //supported by the sender of the message
520 error = asn1ReadInt32(p, length, &tag, &message->msgMaxSize);
521 //Failed to decode ASN.1 tag?
522 if(error)
523 return error;
524
525 //Make sure the value is in the range 484..2147483647
526 if(message->msgMaxSize < 484)
528
529 //Point to the next field
530 p += tag.totalLength;
531 length -= tag.totalLength;
532
533 //The msgFlags field of the message contains several bit fields which
534 //control processing of the message
535 error = asn1ReadTag(p, length, &tag);
536 //Failed to decode ASN.1 tag?
537 if(error)
538 return error;
539
540 //Enforce encoding, class and type
542 //The tag does not match the criteria?
543 if(error)
544 return error;
545
546 //The msgFlags field consists of a single byte
547 if(tag.length != sizeof(uint8_t))
549
550 //Save the bit field
551 message->msgFlags = tag.value[0];
552
553 //If the authFlag is not set and privFlag is set, then the snmpInvalidMsgs
554 //counter is incremented and the message is silently discarded
555 if((message->msgFlags & SNMP_MSG_FLAG_AUTH) == 0 &&
556 (message->msgFlags & SNMP_MSG_FLAG_PRIV) != 0)
557 {
558 //Total number of packets received by the SNMP engine which were dropped
559 //because there were invalid or inconsistent components in the message
560 SNMP_MPD_MIB_INC_COUNTER32(snmpInvalidMsgs, 1);
561
562 //The message is discarded without further processing
563 return ERROR_FAILURE;
564 }
565
566 //Point to the next field
567 p += tag.totalLength;
568 length -= tag.totalLength;
569
570 //The msgSecurityModel field identifies which security model was used
571 //by the sender to generate the message
572 error = asn1ReadInt32(p, length, &tag, &message->msgSecurityModel);
573 //Failed to decode ASN.1 tag?
574 if(error)
575 return error;
576
577 //Make sure the value is in the range 1..2147483647
578 if(message->msgSecurityModel < 1)
580
581 //Successful processing
582 return NO_ERROR;
583#else
584 //Not implemented
586#endif
587}
588
589
590/**
591 * @brief Format msgGlobalData field
592 * @param[in,out] message Pointer to the outgoing SNMP message
593 * @return Error code
594 **/
595
597{
598#if (SNMP_V3_SUPPORT == ENABLED)
599 error_t error;
600 size_t n;
601 size_t length;
602 uint8_t *p;
603 Asn1Tag tag;
604
605 //The msgGlobalData field is encoded in reverse order
606 p = message->pos;
607 //Length of the msgGlobalData field
608 length = 0;
609
610 //Write msgSecurityModel field
611 error = asn1WriteInt32(message->msgSecurityModel, TRUE, p, &n);
612 //Any error to report?
613 if(error)
614 return error;
615
616 //Move backward
617 p -= n;
618 //Update the length of the msgGlobalData field
619 length += n;
620
621 //The msgFlags field consists of a single byte
622 tag.constructed = FALSE;
625 tag.length = sizeof(uint8_t);
626 tag.value = &message->msgFlags;
627
628 //Write the corresponding ASN.1 tag
629 error = asn1WriteTag(&tag, TRUE, p, &n);
630 //Any error to report?
631 if(error)
632 return error;
633
634 //Move backward
635 p -= n;
636 //Update the length of the msgGlobalData field
637 length += n;
638
639 //Write msgMaxSize field
640 error = asn1WriteInt32(message->msgMaxSize, TRUE, p, &n);
641 //Any error to report?
642 if(error)
643 return error;
644
645 //Move backward
646 p -= n;
647 //Update the length of the msgGlobalData field
648 length += n;
649
650 //Write msgID field
651 error = asn1WriteInt32(message->msgId, TRUE, p, &n);
652 //Any error to report?
653 if(error)
654 return error;
655
656 //Move backward
657 p -= n;
658 //Update the length of the msgGlobalData field
659 length += n;
660
661 //The parameters are encapsulated within a sequence
662 tag.constructed = TRUE;
665 tag.length = length;
666 tag.value = NULL;
667
668 //Write the corresponding ASN.1 tag
669 error = asn1WriteTag(&tag, TRUE, p, &n);
670 //Any error to report?
671 if(error)
672 return error;
673
674 //Point to the first byte of the msgGlobalData field
675 message->pos = p - n;
676 //Total length of the message
677 message->length += length + n;
678
679 //Successful processing
680 return NO_ERROR;
681#else
682 //Not implemented
684#endif
685}
686
687
688/**
689 * @brief Parse msgSecurityParameters field
690 * @param[in,out] message Pointer to the incoming SNMP message
691 * @return Error code
692 **/
693
695{
696#if (SNMP_V3_SUPPORT == ENABLED)
697 error_t error;
698 size_t length;
699 const uint8_t *p;
700 Asn1Tag tag;
701
702 //Read the msgSecurityParameters field
703 error = asn1ReadTag(message->pos, message->length, &tag);
704 //Failed to decode ASN.1 tag?
705 if(error)
706 return error;
707
708 //Enforce encoding, class and type
710 //The tag does not match the criteria?
711 if(error)
712 return error;
713
714 //Advance pointer over the msgSecurityParameters field
715 message->pos += tag.totalLength;
716 //Remaining bytes to process
717 message->length -= tag.totalLength;
718
719 //Point to the very first field of the sequence
720 p = tag.value;
721 length = tag.length;
722
723 //User-based security model?
724 if(message->msgSecurityModel == SNMP_SECURITY_MODEL_USM)
725 {
726 //The USM security parameters are encapsulated within a sequence
727 error = asn1ReadSequence(p, length, &tag);
728 //Failed to decode ASN.1 tag?
729 if(error)
730 return error;
731
732 //Point to the first field of the sequence
733 p = tag.value;
734 length = tag.length;
735
736 //Read the msgAuthoritativeEngineID field
737 error = asn1ReadTag(p, length, &tag);
738 //Failed to decode ASN.1 tag?
739 if(error)
740 return error;
741
742 //Enforce encoding, class and type
744 //The tag does not match the criteria?
745 if(error)
746 return error;
747
748 //Save authoritative engine identifier
749 message->msgAuthEngineId = tag.value;
750 message->msgAuthEngineIdLen = tag.length;
751
752 //Point to the next field
753 p += tag.totalLength;
754 length -= tag.totalLength;
755
756 //Read the msgAuthoritativeEngineBoots field
757 error = asn1ReadInt32(p, length, &tag,
758 &message->msgAuthEngineBoots);
759 //Failed to decode ASN.1 tag?
760 if(error)
761 return error;
762
763 //Point to the next field
764 p += tag.totalLength;
765 length -= tag.totalLength;
766
767 //Read the msgAuthoritativeEngineTime field
768 error = asn1ReadInt32(p, length, &tag,
769 &message->msgAuthEngineTime);
770 //Failed to decode ASN.1 tag?
771 if(error)
772 return error;
773
774 //Point to the next field
775 p += tag.totalLength;
776 length -= tag.totalLength;
777
778 //Read the msgUserName field
779 error = asn1ReadTag(p, length, &tag);
780 //Failed to decode ASN.1 tag?
781 if(error)
782 return error;
783
784 //Enforce encoding, class and type
786 //The tag does not match the criteria?
787 if(error)
788 return error;
789
790 //Check the length of the user name
791 if(tag.length > 32)
793
794 //Save user name
795 message->msgUserName = (char_t *) tag.value;
796 message->msgUserNameLen = tag.length;
797
798 //Point to the next field
799 p += tag.totalLength;
800 length -= tag.totalLength;
801
802 //Read the msgAuthenticationParameters field
803 error = asn1ReadTag(p, length, &tag);
804 //Failed to decode ASN.1 tag?
805 if(error)
806 return error;
807
808 //Enforce encoding, class and type
810 //The tag does not match the criteria?
811 if(error)
812 return error;
813
814 //Save authentication parameters
815 message->msgAuthParameters = (uint8_t *) tag.value;
816 message->msgAuthParametersLen = tag.length;
817
818 //Point to the next field
819 p += tag.totalLength;
820 length -= tag.totalLength;
821
822 //Read the msgPrivacyParameters field
823 error = asn1ReadTag(p, length, &tag);
824 //Failed to decode ASN.1 tag?
825 if(error)
826 return error;
827
828 //Enforce encoding, class and type
830 //The tag does not match the criteria?
831 if(error)
832 return error;
833
834 //Save privacy parameters
835 message->msgPrivParameters = tag.value;
836 message->msgPrivParametersLen = tag.length;
837 }
838 else
839 {
840 //Total number of packets received by the SNMP engine which were dropped
841 //because they referenced a securityModel that was not known to or
842 //supported by the SNMP engine
843 SNMP_MPD_MIB_INC_COUNTER32(snmpUnknownSecurityModels, 1);
844
845 //The message is discarded without further processing
846 return ERROR_FAILURE;
847 }
848
849 //Successful processing
850 return NO_ERROR;
851#else
852 //Not implemented
854#endif
855}
856
857
858/**
859 * @brief Format msgSecurityParameters field
860 * @param[in,out] message Pointer to the outgoing SNMP message
861 * @return Error code
862 **/
863
865{
866#if (SNMP_V3_SUPPORT == ENABLED)
867 error_t error;
868 size_t n;
869 size_t length;
870 uint8_t *p;
871 Asn1Tag tag;
872
873 //The msgSecurityParameters field is encoded in reverse order
874 p = message->pos;
875 //Length of the msgSecurityParameters field
876 length = 0;
877
878 //User-based security model?
879 if(message->msgSecurityModel == SNMP_SECURITY_MODEL_USM)
880 {
881 //Encode the msgPrivacyParameters field as an octet string
882 tag.constructed = FALSE;
885 tag.length = message->msgPrivParametersLen;
886 tag.value = message->msgPrivParameters;
887
888 //Write the corresponding ASN.1 tag
889 error = asn1WriteTag(&tag, TRUE, p, &n);
890 //Any error to report?
891 if(error)
892 return error;
893
894 //Move backward
895 p -= n;
896 //Update the length of the msgSecurityParameters field
897 length += n;
898
899 //Authentication required?
900 if(message->msgAuthParametersLen > 0)
901 {
902 //Make room for the message digest
903 p -= message->msgAuthParametersLen;
904 //Update the length of the msgSecurityParameters field
905 length += message->msgAuthParametersLen;
906
907 //Clear the message digest
908 osMemset(p, 0, message->msgAuthParametersLen);
909 }
910
911 //Save the location of the msgAuthenticationParameters field
912 message->msgAuthParameters = p;
913
914 //Encoded the msgAuthenticationParameters field as an octet string
915 tag.constructed = FALSE;
918 tag.length = message->msgAuthParametersLen;
919 tag.value = NULL;
920
921 //Write the corresponding ASN.1 tag
922 error = asn1WriteTag(&tag, TRUE, p, &n);
923 //Any error to report?
924 if(error)
925 return error;
926
927 //Move backward
928 p -= n;
929 //Update the length of the msgSecurityParameters field
930 length += n;
931
932 //Encode the msgUserName field as an octet string
933 tag.constructed = FALSE;
936 tag.length = message->msgUserNameLen;
937 tag.value = (uint8_t *) message->msgUserName;
938
939 //Write the corresponding ASN.1 tag
940 error = asn1WriteTag(&tag, TRUE, p, &n);
941 //Any error to report?
942 if(error)
943 return error;
944
945 //Move backward
946 p -= n;
947 //Update the length of the msgSecurityParameters field
948 length += n;
949
950 //Write the msgAuthoritativeEngineTime field
951 error = asn1WriteInt32(message->msgAuthEngineTime, TRUE, p, &n);
952 //Any error to report?
953 if(error)
954 return error;
955
956 //Move backward
957 p -= n;
958 //Update the length of the msgSecurityParameters field
959 length += n;
960
961 //Write the msgAuthoritativeEngineBoots field
962 error = asn1WriteInt32(message->msgAuthEngineBoots, TRUE, p, &n);
963 //Any error to report?
964 if(error)
965 return error;
966
967 //Move backward
968 p -= n;
969 //Update the length of the msgSecurityParameters field
970 length += n;
971
972 //The msgAuthoritativeEngineID field is an octet string
973 tag.constructed = FALSE;
976 tag.length = message->msgAuthEngineIdLen;
977 tag.value = message->msgAuthEngineId;
978
979 //Write the corresponding ASN.1 tag
980 error = asn1WriteTag(&tag, TRUE, p, &n);
981 //Any error to report?
982 if(error)
983 return error;
984
985 //Move backward
986 p -= n;
987 //Update the length of the msgSecurityParameters field
988 length += n;
989
990 //The USM security parameters are encapsulated within a sequence
991 tag.constructed = TRUE;
994 tag.length = length;
995 tag.value = NULL;
996
997 //Write the corresponding ASN.1 tag
998 error = asn1WriteTag(&tag, TRUE, p, &n);
999 //Any error to report?
1000 if(error)
1001 return error;
1002
1003 //Move backward
1004 p -= n;
1005 //Update the length of the msgSecurityParameters field
1006 length += n;
1007 }
1008 else
1009 {
1010 //The security model is not supported
1011 return ERROR_FAILURE;
1012 }
1013
1014 //The security parameters are encapsulated within an octet string
1015 tag.constructed = FALSE;
1018 tag.length = length;
1019 tag.value = NULL;
1020
1021 //Write the corresponding ASN.1 tag
1022 error = asn1WriteTag(&tag, TRUE, p, &n);
1023 //Any error to report?
1024 if(error)
1025 return error;
1026
1027 //Point to the first byte of the msgSecurityParameters field
1028 message->pos = p - n;
1029 //Total length of the message
1030 message->length += length + n;
1031
1032 //Successful processing
1033 return NO_ERROR;
1034#else
1035 //Not implemented
1036 return ERROR_NOT_IMPLEMENTED;
1037#endif
1038}
1039
1040
1041/**
1042 * @brief Parse scopedPDU field
1043 * @param[in,out] message Pointer to the incoming SNMP message
1044 * @return Error code
1045 **/
1046
1048{
1049#if (SNMP_V3_SUPPORT == ENABLED)
1050 error_t error;
1051 size_t length;
1052 const uint8_t *p;
1053 Asn1Tag tag;
1054
1055 //Read the scopedPDU field
1056 error = asn1ReadSequence(message->pos, message->length, &tag);
1057 //Failed to decode ASN.1 tag?
1058 if(error)
1059 return error;
1060
1061 //Point to the first field of the sequence
1062 p = tag.value;
1063 length = tag.length;
1064
1065 //Read contextEngineID field
1066 error = asn1ReadTag(p, length, &tag);
1067 //Failed to decode ASN.1 tag?
1068 if(error)
1069 return error;
1070
1071 //Enforce encoding, class and type
1073 //The tag does not match the criteria?
1074 if(error)
1075 return error;
1076
1077 //Save context engine identifier
1078 message->contextEngineId = tag.value;
1079 message->contextEngineIdLen = tag.length;
1080
1081 //Point to the next field
1082 p += tag.totalLength;
1083 length -= tag.totalLength;
1084
1085 //Read contextName field
1086 error = asn1ReadTag(p, length, &tag);
1087 //Failed to decode ASN.1 tag?
1088 if(error)
1089 return error;
1090
1091 //Enforce encoding, class and type
1093 //The tag does not match the criteria?
1094 if(error)
1095 return error;
1096
1097 //Save context name
1098 message->contextName = (char_t *) tag.value;
1099 message->contextNameLen = tag.length;
1100
1101 //Point to the first byte of the PDU
1102 message->pos = (uint8_t *) p + tag.totalLength;
1103 //Length of the PDU
1104 message->length = length - tag.totalLength;
1105
1106 //Return status code
1107 return error;
1108#else
1109 //Not implemented
1110 return ERROR_NOT_IMPLEMENTED;
1111#endif
1112}
1113
1114
1115/**
1116 * @brief Format scopedPDU
1117 * @param[in,out] message Pointer to the outgoing SNMP message
1118 * @return Error code
1119 **/
1120
1122{
1123#if (SNMP_V3_SUPPORT == ENABLED)
1124 error_t error;
1125 size_t n;
1126 size_t length;
1127 uint8_t *p;
1128 Asn1Tag tag;
1129
1130 //Point to the first byte of the PDU
1131 p = message->pos;
1132 //Retrieve the length of the PDU
1133 length = message->length;
1134
1135 //The contextName is an octet string
1136 tag.constructed = FALSE;
1139 tag.length = message->contextNameLen;
1140 tag.value = (uint8_t *) message->contextName;
1141
1142 //Write the corresponding ASN.1 tag
1143 error = asn1WriteTag(&tag, TRUE, p, &n);
1144 //Any error to report?
1145 if(error)
1146 return error;
1147
1148 //Move backward
1149 p -= n;
1150 //Update the length of the scopedPduData
1151 length += n;
1152
1153 //The contextEngineID is an octet string
1154 tag.constructed = FALSE;
1157 tag.length = message->contextEngineIdLen;
1158 tag.value = message->contextEngineId;
1159
1160 //Write the corresponding ASN.1 tag
1161 error = asn1WriteTag(&tag, TRUE, p, &n);
1162 //Any error to report?
1163 if(error)
1164 return error;
1165
1166 //Move backward
1167 p -= n;
1168 //Update the length of the scopedPduData
1169 length += n;
1170
1171 //The scopedPduData is encapsulated within a sequence
1172 tag.constructed = TRUE;
1175 tag.length = length;
1176 tag.value = NULL;
1177
1178 //Write the corresponding ASN.1 tag
1179 error = asn1WriteTag(&tag, TRUE, p, &n);
1180 //Any error to report?
1181 if(error)
1182 return error;
1183
1184 //Point to the first byte of the scopedPDU
1185 message->pos = p - n;
1186 //Length of the scopedPDU
1187 message->length = length + n;
1188
1189 //Successful processing
1190 return NO_ERROR;
1191#else
1192 //Not implemented
1193 return ERROR_NOT_IMPLEMENTED;
1194#endif
1195}
1196
1197
1198/**
1199 * @brief Parse PDU header
1200 * @param[in,out] message Pointer to the incoming SNMP message
1201 * @return Error code
1202 **/
1203
1205{
1206 error_t error;
1207 size_t length;
1208 const uint8_t *p;
1209 Asn1Tag tag;
1210
1211 //The PDU is encapsulated within a sequence
1212 error = asn1ReadTag(message->pos, message->length, &tag);
1213 //Failed to decode ASN.1 tag?
1214 if(error)
1215 return error;
1216
1217 //Check encoding
1218 if(tag.constructed != TRUE)
1219 return ERROR_WRONG_ENCODING;
1220 //Enforce class
1222 return ERROR_INVALID_CLASS;
1223
1224 //Save PDU type
1225 message->pduType = (SnmpPduType) tag.objType;
1226
1227 //Point to the first field
1228 p = tag.value;
1229 //Remaining bytes to process
1230 length = tag.length;
1231
1232 //Read request-id field
1233 error = asn1ReadInt32(p, length, &tag, &message->requestId);
1234 //Failed to decode ASN.1 tag?
1235 if(error)
1236 return error;
1237
1238 //Point to the next field
1239 p += tag.totalLength;
1240 length -= tag.totalLength;
1241
1242#if (SNMP_V2C_SUPPORT == ENABLED || SNMP_V3_SUPPORT == ENABLED)
1243 //GetBulkRequest-PDU?
1244 if(message->pduType == SNMP_PDU_GET_BULK_REQUEST)
1245 {
1246 //Read non-repeaters field
1247 error = asn1ReadInt32(p, length, &tag, &message->nonRepeaters);
1248 //Failed to decode ASN.1 tag?
1249 if(error)
1250 return error;
1251
1252 //If the value in the non-repeaters field is less than zero, then the
1253 //value of the field is set to zero
1254 if(message->nonRepeaters < 0)
1255 message->nonRepeaters = 0;
1256
1257 //Point to the next field
1258 p += tag.totalLength;
1259 length -= tag.totalLength;
1260
1261 //Read max-repetitions field
1262 error = asn1ReadInt32(p, length, &tag, &message->maxRepetitions);
1263 //Failed to decode ASN.1 tag?
1264 if(error)
1265 return error;
1266
1267 //If the value in the max-repetitions field is less than zero, then the
1268 //value of the field is set to zero
1269 if(message->maxRepetitions < 0)
1270 message->maxRepetitions = 0;
1271 }
1272 else
1273#endif
1274 {
1275 //Read error-status field
1276 error = asn1ReadInt32(p, length, &tag, &message->errorStatus);
1277 //Failed to decode ASN.1 tag?
1278 if(error)
1279 return error;
1280
1281 //Point to the next field
1282 p += tag.totalLength;
1283 length -= tag.totalLength;
1284
1285 //Read error-index field
1286 error = asn1ReadInt32(p, length, &tag, &message->errorIndex);
1287 //Failed to decode ASN.1 tag?
1288 if(error)
1289 return error;
1290 }
1291
1292 //Point to the next field
1293 p += tag.totalLength;
1294 length -= tag.totalLength;
1295
1296 //The variable bindings are encapsulated within a sequence
1297 error = asn1ReadSequence(p, length, &tag);
1298 //Failed to decode ASN.1 tag?
1299 if(error)
1300 return error;
1301
1302 //Save the location of the variable binding list
1303 message->varBindList = (uint8_t *) tag.value;
1304 message->varBindListLen = tag.length;
1305
1306 //Successful processing
1307 return NO_ERROR;
1308}
1309
1310
1311/**
1312 * @brief Format PDU header
1313 * @param[in,out] message Pointer to the outgoing SNMP message
1314 * @return Error code
1315 **/
1316
1318{
1319 error_t error;
1320 size_t n;
1321 size_t length;
1322 uint8_t *p;
1323 Asn1Tag tag;
1324
1325 //The PDU header will be encoded in reverse order...
1326 p = message->varBindList;
1327 //Length of the PDU
1328 length = message->varBindListLen;
1329
1330 //The variable bindings are encapsulated within a sequence
1331 tag.constructed = TRUE;
1334 tag.length = length;
1335 tag.value = NULL;
1336
1337 //Write the corresponding ASN.1 tag
1338 error = asn1WriteTag(&tag, TRUE, p, &n);
1339 //Any error to report?
1340 if(error)
1341 return error;
1342
1343 //Move backward
1344 p -= n;
1345 //Update the length of the PDU
1346 length += n;
1347
1348 //GetRequest-PDU, GetResponse-PDU, InformRequest-PDU, SNMPv2-Trap-PDU
1349 //or Report-PDU?
1350 if(message->pduType == SNMP_PDU_GET_REQUEST ||
1351 message->pduType == SNMP_PDU_GET_RESPONSE ||
1352 message->pduType == SNMP_PDU_INFORM_REQUEST ||
1353 message->pduType == SNMP_PDU_TRAP_V2 ||
1354 message->pduType == SNMP_PDU_REPORT)
1355 {
1356 //Write error index
1357 error = asn1WriteInt32(message->errorIndex, TRUE, p, &n);
1358 //Any error to report?
1359 if(error)
1360 return error;
1361
1362 //Move backward
1363 p -= n;
1364 //Update the length of the PDU
1365 length += n;
1366
1367 //Write error status
1368 error = asn1WriteInt32(message->errorStatus, TRUE, p, &n);
1369 //Any error to report?
1370 if(error)
1371 return error;
1372
1373 //Move backward
1374 p -= n;
1375 //Update the length of the PDU
1376 length += n;
1377
1378 //Write request identifier
1379 error = asn1WriteInt32(message->requestId, TRUE, p, &n);
1380 //Any error to report?
1381 if(error)
1382 return error;
1383
1384 //Move backward
1385 p -= n;
1386 //Update the length of the PDU
1387 length += n;
1388 }
1389#if (SNMP_V1_SUPPORT == ENABLED)
1390 //Trap-PDU?
1391 else if(message->pduType == SNMP_PDU_TRAP)
1392 {
1393 //Encode the object value using ASN.1 rules
1394 error = snmpEncodeUnsignedInt32(message->timestamp, message->buffer, &n);
1395 //Any error to report?
1396 if(error)
1397 return error;
1398
1399 //The time stamp is encoded in ASN.1 format
1400 tag.constructed = FALSE;
1403 tag.length = n;
1404 tag.value = message->buffer;
1405
1406 //Write the corresponding ASN.1 tag
1407 error = asn1WriteTag(&tag, TRUE, p, &n);
1408 //Any error to report?
1409 if(error)
1410 return error;
1411
1412 //Move backward
1413 p -= n;
1414 //Update the length of the PDU
1415 length += n;
1416
1417 //Write specific trap code
1418 error = asn1WriteInt32(message->specificTrapCode, TRUE, p, &n);
1419 //Any error to report?
1420 if(error)
1421 return error;
1422
1423 //Move backward
1424 p -= n;
1425 //Update the length of the PDU
1426 length += n;
1427
1428 //Write generic trap type
1429 error = asn1WriteInt32(message->genericTrapType, TRUE, p, &n);
1430 //Any error to report?
1431 if(error)
1432 return error;
1433
1434 //Move backward
1435 p -= n;
1436 //Update the length of the PDU
1437 length += n;
1438
1439 //The agent address is encoded in ASN.1 format
1440 tag.constructed = FALSE;
1443 tag.length = sizeof(Ipv4Addr);
1444 tag.value = (uint8_t *) &message->agentAddr;
1445
1446 //Write the corresponding ASN.1 tag
1447 error = asn1WriteTag(&tag, TRUE, p, &n);
1448 //Any error to report?
1449 if(error)
1450 return error;
1451
1452 //Move backward
1453 p -= n;
1454 //Update the length of the PDU
1455 length += n;
1456
1457 //The enterprise OID is encoded in ASN.1 format
1458 tag.constructed = FALSE;
1461 tag.length = message->enterpriseOidLen;
1462 tag.value = message->enterpriseOid;
1463
1464 //Write the corresponding ASN.1 tag
1465 error = asn1WriteTag(&tag, TRUE, p, &n);
1466 //Any error to report?
1467 if(error)
1468 return error;
1469
1470 //Move backward
1471 p -= n;
1472 //Update the length of the PDU
1473 length += n;
1474 }
1475#endif
1476 //Unknown PDU type?
1477 else
1478 {
1479 //Report an error
1480 return ERROR_FAILURE;
1481 }
1482
1483 //The PDU is encapsulated within a sequence
1484 tag.constructed = TRUE;
1486 tag.objType = message->pduType;
1487 tag.length = length;
1488 tag.value = NULL;
1489
1490 //Write the corresponding ASN.1 tag
1491 error = asn1WriteTag(&tag, TRUE, p, &n);
1492 //Any error to report?
1493 if(error)
1494 return error;
1495
1496 //Point to the first byte of the PDU
1497 message->pos = p - n;
1498 //Total length of the PDU
1499 message->length = length + n;
1500
1501 //Successful processing
1502 return NO_ERROR;
1503}
1504
1505
1506/**
1507 * @brief Encode a 32-bit signed integer
1508 * @param[in] value Integer value
1509 * @param[out] dest Buffer where to encode the integer
1510 * @param[out] length Total number of bytes that have been written
1511 * @return Error code
1512 **/
1513
1514error_t snmpEncodeInt32(int32_t value, uint8_t *dest, size_t *length)
1515{
1516 size_t i;
1517 size_t j;
1518 uint8_t *src;
1519
1520 //Check parameters
1521 if(dest == NULL || length == NULL)
1523
1524 //The integer is encoded MSB first
1525 value = (int32_t) htobe32(value);
1526 //Cast the integer to byte array
1527 src = (uint8_t *) &value;
1528
1529 //An integer value is always encoded in the smallest possible number of octets
1530 for(i = 0; i < 3; i++)
1531 {
1532 //The upper 9 bits shall not have the same value (all 0 or all 1)
1533 if((src[i] != 0x00 || (src[i + 1] & 0x80) != 0x00) &&
1534 (src[i] != 0xFF || (src[i + 1] & 0x80) != 0x80))
1535 {
1536 break;
1537 }
1538 }
1539
1540 //Point to the beginning of the output buffer
1541 j = 0;
1542
1543 //Copy integer value
1544 while(i < 4)
1545 {
1546 dest[j++] = src[i++];
1547 }
1548
1549 //Total number of bytes that have been written
1550 *length = j;
1551
1552 //Successful processing
1553 return NO_ERROR;
1554}
1555
1556
1557/**
1558 * @brief Encode a 32-bit unsigned integer
1559 * @param[in] value Integer value
1560 * @param[out] dest Buffer where to encode the integer
1561 * @param[out] length Total number of bytes that have been written
1562 * @return Error code
1563 **/
1564
1565error_t snmpEncodeUnsignedInt32(uint32_t value, uint8_t *dest, size_t *length)
1566{
1567 size_t i;
1568 size_t j;
1569 uint8_t *src;
1570
1571 //Check parameters
1572 if(dest == NULL || length == NULL)
1574
1575 //The integer is encoded MSB first
1576 value = htobe32(value);
1577 //Cast the integer to byte array
1578 src = (uint8_t *) &value;
1579
1580 //An integer value is always encoded in the smallest possible number of octets
1581 for(i = 0; i < 3; i++)
1582 {
1583 //Check the upper 8 bits
1584 if(src[i] != 0x00)
1585 break;
1586 }
1587
1588 //Point to the beginning of the output buffer
1589 j = 0;
1590
1591 //Check the most significant bit
1592 if(src[i] & 0x80)
1593 dest[j++] = 0;
1594
1595 //Copy integer value
1596 while(i < 4)
1597 {
1598 dest[j++] = src[i++];
1599 }
1600
1601 //Total number of bytes that have been written
1602 *length = j;
1603
1604 //Successful processing
1605 return NO_ERROR;
1606}
1607
1608
1609/**
1610 * @brief Encode a 64-bit unsigned integer
1611 * @param[in] value Integer value
1612 * @param[out] dest Buffer where to encode the integer
1613 * @param[out] length Total number of bytes that have been written
1614 * @return Error code
1615 **/
1616
1617error_t snmpEncodeUnsignedInt64(uint64_t value, uint8_t *dest, size_t *length)
1618{
1619 size_t i;
1620 size_t j;
1621 uint8_t *src;
1622
1623 //Check parameters
1624 if(dest == NULL || length == NULL)
1626
1627 //The integer is encoded MSB first
1628 value = htobe64(value);
1629 //Cast the integer to byte array
1630 src = (uint8_t *) &value;
1631
1632 //An integer value is always encoded in the smallest possible number of octets
1633 for(i = 0; i < 7; i++)
1634 {
1635 //Check the upper 8 bits
1636 if(src[i] != 0x00)
1637 break;
1638 }
1639
1640 //Point to the beginning of the output buffer
1641 j = 0;
1642
1643 //Check the most significant bit
1644 if(src[i] & 0x80)
1645 {
1646 dest[j++] = 0;
1647 }
1648
1649 //Copy integer value
1650 while(i < 8)
1651 {
1652 dest[j++] = src[i++];
1653 }
1654
1655 //Total number of bytes that have been written
1656 *length = j;
1657
1658 //Successful processing
1659 return NO_ERROR;
1660}
1661
1662
1663/**
1664 * @brief Decode a 32-bit signed integer
1665 * @param[in] src Buffer that contains the encoded value
1666 * @param[in] length Number of bytes to be processed
1667 * @param[out] value Resulting integer value
1668 * @return Error code
1669 **/
1670
1671error_t snmpDecodeInt32(const uint8_t *src, size_t length, int32_t *value)
1672{
1673 size_t i;
1674
1675 //Check parameters
1676 if(src == NULL || value == NULL)
1678 if(length < 1)
1680
1681 //The contents octets shall be a two's complement binary
1682 //number equal to the integer value
1683 *value = (src[0] & 0x80) ? -1 : 0;
1684
1685 //Process contents octets
1686 for(i = 0; i < length; i++)
1687 {
1688 //Rotate left operation
1689 *value <<= 8;
1690 //Reconstruct integer value
1691 *value |= src[i];
1692 }
1693
1694 //Successful processing
1695 return NO_ERROR;
1696}
1697
1698
1699/**
1700 * @brief Decode a 32-bit unsigned integer
1701 * @param[in] src Buffer that contains the encoded value
1702 * @param[in] length Number of bytes to be processed
1703 * @param[out] value Resulting integer value
1704 * @return Error code
1705 **/
1706
1707error_t snmpDecodeUnsignedInt32(const uint8_t *src, size_t length, uint32_t *value)
1708{
1709 size_t i;
1710
1711 //Check parameters
1712 if(src == NULL || value == NULL)
1714 if(length < 1)
1716
1717 //Only accept non-negative numbers
1718 if(src[0] & 0x80)
1719 return ERROR_FAILURE;
1720
1721 //Initialize integer value
1722 *value = 0;
1723
1724 //Process contents octets
1725 for(i = 0; i < length; i++)
1726 {
1727 //Rotate left operation
1728 *value <<= 8;
1729 //Reconstruct integer value
1730 *value |= src[i];
1731 }
1732
1733 //Successful processing
1734 return NO_ERROR;
1735}
1736
1737
1738/**
1739 * @brief Decode a 64-bit unsigned integer
1740 * @param[in] src Buffer that contains the encoded value
1741 * @param[in] length Number of bytes to be processed
1742 * @param[out] value Resulting integer value
1743 * @return Error code
1744 **/
1745
1746error_t snmpDecodeUnsignedInt64(const uint8_t *src, size_t length, uint64_t *value)
1747{
1748 size_t i;
1749
1750 //Check parameters
1751 if(src == NULL || value == NULL)
1753 if(length < 1)
1755
1756 //Only accept non-negative numbers
1757 if(src[0] & 0x80)
1758 return ERROR_FAILURE;
1759
1760 //Initialize integer value
1761 *value = 0;
1762
1763 //Process contents octets
1764 for(i = 0; i < length; i++)
1765 {
1766 //Rotate left operation
1767 *value <<= 8;
1768 //Reconstruct integer value
1769 *value |= src[i];
1770 }
1771
1772 //Successful processing
1773 return NO_ERROR;
1774}
1775
1776#endif
error_t asn1WriteInt32(int32_t value, bool_t reverse, uint8_t *data, size_t *written)
Write a 32-bit integer to the output stream.
Definition: asn1.c:495
error_t asn1ReadTag(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 tag from the input stream.
Definition: asn1.c:52
error_t asn1WriteTag(Asn1Tag *tag, bool_t reverse, uint8_t *data, size_t *written)
Write an ASN.1 tag.
Definition: asn1.c:334
error_t asn1ReadSequence(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 sequence from the input stream.
Definition: asn1.c:163
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:653
error_t asn1ReadInt32(const uint8_t *data, size_t length, Asn1Tag *tag, int32_t *value)
Read a 32-bit integer from the input stream.
Definition: asn1.c:285
ASN.1 (Abstract Syntax Notation One)
@ ASN1_TYPE_OBJECT_IDENTIFIER
Definition: asn1.h:74
@ ASN1_TYPE_OCTET_STRING
Definition: asn1.h:72
@ ASN1_TYPE_SEQUENCE
Definition: asn1.h:80
#define ASN1_CLASS_APPLICATION
Definition: asn1.h:53
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:52
#define ASN1_CLASS_CONTEXT_SPECIFIC
Definition: asn1.h:54
uint8_t message[]
Definition: chap.h:152
char char_t
Definition: compiler_port.h:43
#define htobe64(value)
Definition: cpu_endian.h:447
#define htobe32(value)
Definition: cpu_endian.h:446
General definitions for cryptographic algorithms.
Debugging facilities.
uint8_t n
uint8_t value[]
Definition: dtls_misc.h:150
error_t
Error codes.
Definition: error.h:43
@ ERROR_INVALID_CLASS
Definition: error.h:116
@ ERROR_WRONG_ENCODING
Definition: error.h:121
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
@ ERROR_INVALID_VERSION
Definition: error.h:117
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:239
#define IPV4_UNSPECIFIED_ADDR
Definition: ipv4.h:104
@ MIB_TYPE_TIME_TICKS
Definition: mib_common.h:64
@ MIB_TYPE_IP_ADDRESS
Definition: mib_common.h:60
uint8_t p
Definition: ndp.h:298
TCP/IP stack core.
#define osMemset(p, value, length)
Definition: os_port.h:128
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
uint32_t length
Definition: sftp_common.h:214
SNMP agent (Simple Network Management Protocol)
#define SnmpAgentContext
Definition: snmp_agent.h:36
void snmpInitMessage(SnmpMessage *message)
Initialize a SNMP message.
error_t snmpParseMessageHeader(SnmpMessage *message)
Parse SNMP message header.
error_t snmpParseCommunity(SnmpMessage *message)
Parse community name.
error_t snmpWriteSecurityParameters(SnmpMessage *message)
Format msgSecurityParameters field.
error_t snmpParseSecurityParameters(SnmpMessage *message)
Parse msgSecurityParameters field.
error_t snmpWriteScopedPdu(SnmpMessage *message)
Format scopedPDU.
error_t snmpDecodeInt32(const uint8_t *src, size_t length, int32_t *value)
Decode a 32-bit signed integer.
error_t snmpWriteCommunity(SnmpMessage *message)
Format community name.
error_t snmpWriteGlobalData(SnmpMessage *message)
Format msgGlobalData field.
error_t snmpComputeMessageOverhead(SnmpMessage *message)
Compute SNMP message overhead.
error_t snmpEncodeUnsignedInt64(uint64_t value, uint8_t *dest, size_t *length)
Encode a 64-bit unsigned integer.
error_t snmpWritePduHeader(SnmpMessage *message)
Format PDU header.
error_t snmpDecodeUnsignedInt32(const uint8_t *src, size_t length, uint32_t *value)
Decode a 32-bit unsigned integer.
error_t snmpParseGlobalData(SnmpMessage *message)
Parse msgGlobalData field.
error_t snmpEncodeUnsignedInt32(uint32_t value, uint8_t *dest, size_t *length)
Encode a 32-bit unsigned integer.
error_t snmpParseScopedPdu(SnmpMessage *message)
Parse scopedPDU field.
error_t snmpInitResponse(SnmpAgentContext *context)
Initialize a GetResponse-PDU.
error_t snmpEncodeInt32(int32_t value, uint8_t *dest, size_t *length)
Encode a 32-bit signed integer.
error_t snmpParsePduHeader(SnmpMessage *message)
Parse PDU header.
error_t snmpWriteMessageHeader(SnmpMessage *message)
Format SNMP message header.
error_t snmpDecodeUnsignedInt64(const uint8_t *src, size_t length, uint64_t *value)
Decode a 64-bit unsigned integer.
#define SNMP_V1_MSG_HEADER_OVERHEAD
#define SNMP_V3_MSG_HEADER_OVERHEAD
#define SNMP_V2C_MSG_HEADER_OVERHEAD
#define SNMP_MSG_ENCRYPTION_OVERHEAD
@ SNMP_SECURITY_MODEL_USM
User-based security model.
@ SNMP_MSG_FLAG_PRIV
@ SNMP_MSG_FLAG_AUTH
SnmpPduType
SNMP PDU types.
Definition: snmp_common.h:149
@ SNMP_PDU_TRAP_V2
Definition: snmp_common.h:157
@ SNMP_PDU_GET_REQUEST
Definition: snmp_common.h:150
@ SNMP_PDU_GET_RESPONSE
Definition: snmp_common.h:152
@ SNMP_PDU_INFORM_REQUEST
Definition: snmp_common.h:156
@ SNMP_PDU_TRAP
Definition: snmp_common.h:154
@ SNMP_PDU_REPORT
Definition: snmp_common.h:158
@ SNMP_PDU_GET_BULK_REQUEST
Definition: snmp_common.h:155
@ SNMP_VERSION_1
Definition: snmp_common.h:138
@ SNMP_VERSION_3
Definition: snmp_common.h:140
@ SNMP_VERSION_2C
Definition: snmp_common.h:139
#define SNMP_MAX_MSG_SIZE
Definition: snmp_common.h:60
@ SNMP_ERROR_NONE
Definition: snmp_common.h:184
SNMP MPD MIB module.
#define SNMP_MPD_MIB_INC_COUNTER32(name, value)
ASN.1 tag.
Definition: asn1.h:102
size_t totalLength
Definition: asn1.h:108
const uint8_t * value
Definition: asn1.h:107
uint_t objClass
Definition: asn1.h:104
uint_t objType
Definition: asn1.h:105
bool_t constructed
Definition: asn1.h:103
size_t length
Definition: asn1.h:106
SNMP message.