Webserver+3d print

Dependents:   Nucleo

Committer:
Sergunb
Date:
Sat Feb 04 18:15:49 2017 +0000
Revision:
0:8918a71cdbe9
nothing else

Who changed what in which revision?

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