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_agent_pdu.c
Sergunb 0:8918a71cdbe9 3 * @brief SNMP agent (PDU processing)
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_agent_pdu.h"
Sergunb 0:8918a71cdbe9 36 #include "snmp/snmp_agent_misc.h"
Sergunb 0:8918a71cdbe9 37 #include "mibs/mib2_module.h"
Sergunb 0:8918a71cdbe9 38 #include "crypto.h"
Sergunb 0:8918a71cdbe9 39 #include "asn1.h"
Sergunb 0:8918a71cdbe9 40 #include "oid.h"
Sergunb 0:8918a71cdbe9 41 #include "debug.h"
Sergunb 0:8918a71cdbe9 42
Sergunb 0:8918a71cdbe9 43 //Check TCP/IP stack configuration
Sergunb 0:8918a71cdbe9 44 #if (SNMP_AGENT_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 45
Sergunb 0:8918a71cdbe9 46 //sysUpTime.0 object (1.3.6.1.2.1.1.3.0)
Sergunb 0:8918a71cdbe9 47 static const uint8_t sysUpTimeObject[] = {43, 6, 1, 2, 1, 1, 3, 0};
Sergunb 0:8918a71cdbe9 48 //snmpTrapOID.0 object (1.3.6.1.6.3.1.1.4.1.0)
Sergunb 0:8918a71cdbe9 49 static const uint8_t snmpTrapOidObject[] = {43, 6, 1, 6, 3, 1, 1, 4, 1, 0};
Sergunb 0:8918a71cdbe9 50 //snmpTraps object (1.3.6.1.6.3.1.1.5)
Sergunb 0:8918a71cdbe9 51 static const uint8_t snmpTrapsObject[] = {43, 6, 1, 6, 3, 1, 1, 5};
Sergunb 0:8918a71cdbe9 52
Sergunb 0:8918a71cdbe9 53
Sergunb 0:8918a71cdbe9 54 /**
Sergunb 0:8918a71cdbe9 55 * @brief Process PDU
Sergunb 0:8918a71cdbe9 56 * @param[in] context Pointer to the SNMP agent context
Sergunb 0:8918a71cdbe9 57 * @return Error code
Sergunb 0:8918a71cdbe9 58 **/
Sergunb 0:8918a71cdbe9 59
Sergunb 0:8918a71cdbe9 60 error_t snmpProcessPdu(SnmpAgentContext *context)
Sergunb 0:8918a71cdbe9 61 {
Sergunb 0:8918a71cdbe9 62 error_t error;
Sergunb 0:8918a71cdbe9 63
Sergunb 0:8918a71cdbe9 64 //Parse PDU header
Sergunb 0:8918a71cdbe9 65 error = snmpParsePduHeader(&context->request);
Sergunb 0:8918a71cdbe9 66 //Any error to report?
Sergunb 0:8918a71cdbe9 67 if(error)
Sergunb 0:8918a71cdbe9 68 return error;
Sergunb 0:8918a71cdbe9 69
Sergunb 0:8918a71cdbe9 70 //Check PDU type
Sergunb 0:8918a71cdbe9 71 switch(context->request.pduType)
Sergunb 0:8918a71cdbe9 72 {
Sergunb 0:8918a71cdbe9 73 case SNMP_PDU_GET_REQUEST:
Sergunb 0:8918a71cdbe9 74 case SNMP_PDU_GET_NEXT_REQUEST:
Sergunb 0:8918a71cdbe9 75 //Process GetRequest-PDU or GetNextRequest-PDU
Sergunb 0:8918a71cdbe9 76 error = snmpProcessGetRequestPdu(context);
Sergunb 0:8918a71cdbe9 77 break;
Sergunb 0:8918a71cdbe9 78 case SNMP_PDU_GET_BULK_REQUEST:
Sergunb 0:8918a71cdbe9 79 //Process GetBulkRequest-PDU
Sergunb 0:8918a71cdbe9 80 error = snmpProcessGetBulkRequestPdu(context);
Sergunb 0:8918a71cdbe9 81 break;
Sergunb 0:8918a71cdbe9 82 case SNMP_PDU_SET_REQUEST:
Sergunb 0:8918a71cdbe9 83 //Process SetRequest-PDU
Sergunb 0:8918a71cdbe9 84 error = snmpProcessSetRequestPdu(context);
Sergunb 0:8918a71cdbe9 85 break;
Sergunb 0:8918a71cdbe9 86 default:
Sergunb 0:8918a71cdbe9 87 //Invalid PDU type
Sergunb 0:8918a71cdbe9 88 error = ERROR_INVALID_TYPE;
Sergunb 0:8918a71cdbe9 89 break;
Sergunb 0:8918a71cdbe9 90 }
Sergunb 0:8918a71cdbe9 91
Sergunb 0:8918a71cdbe9 92 //Check status code
Sergunb 0:8918a71cdbe9 93 if(!error)
Sergunb 0:8918a71cdbe9 94 {
Sergunb 0:8918a71cdbe9 95 //Total number of SNMP Get-Response PDUs which have been generated
Sergunb 0:8918a71cdbe9 96 //by the SNMP protocol entity
Sergunb 0:8918a71cdbe9 97 MIB2_INC_COUNTER32(mib2Base.snmpGroup.snmpOutGetResponses, 1);
Sergunb 0:8918a71cdbe9 98
Sergunb 0:8918a71cdbe9 99 //Format PDU header
Sergunb 0:8918a71cdbe9 100 error = snmpWritePduHeader(&context->response);
Sergunb 0:8918a71cdbe9 101 }
Sergunb 0:8918a71cdbe9 102
Sergunb 0:8918a71cdbe9 103 //Return status code
Sergunb 0:8918a71cdbe9 104 return error;
Sergunb 0:8918a71cdbe9 105 }
Sergunb 0:8918a71cdbe9 106
Sergunb 0:8918a71cdbe9 107
Sergunb 0:8918a71cdbe9 108 /**
Sergunb 0:8918a71cdbe9 109 * @brief Process GetRequest-PDU or GetNextRequest-PDU
Sergunb 0:8918a71cdbe9 110 * @param[in] context Pointer to the SNMP agent context
Sergunb 0:8918a71cdbe9 111 * @return Error code
Sergunb 0:8918a71cdbe9 112 **/
Sergunb 0:8918a71cdbe9 113
Sergunb 0:8918a71cdbe9 114 error_t snmpProcessGetRequestPdu(SnmpAgentContext *context)
Sergunb 0:8918a71cdbe9 115 {
Sergunb 0:8918a71cdbe9 116 error_t error;
Sergunb 0:8918a71cdbe9 117 int_t index;
Sergunb 0:8918a71cdbe9 118 size_t n;
Sergunb 0:8918a71cdbe9 119 size_t length;
Sergunb 0:8918a71cdbe9 120 const uint8_t *p;
Sergunb 0:8918a71cdbe9 121 SnmpVarBind var;
Sergunb 0:8918a71cdbe9 122
Sergunb 0:8918a71cdbe9 123 //Check PDU type
Sergunb 0:8918a71cdbe9 124 if(context->request.pduType == SNMP_PDU_GET_REQUEST)
Sergunb 0:8918a71cdbe9 125 {
Sergunb 0:8918a71cdbe9 126 //Debug message
Sergunb 0:8918a71cdbe9 127 TRACE_INFO("Parsing GetRequest-PDU...\r\n");
Sergunb 0:8918a71cdbe9 128
Sergunb 0:8918a71cdbe9 129 //Total number of SNMP Get-Request PDUs which have been accepted and
Sergunb 0:8918a71cdbe9 130 //processed by the SNMP protocol entity
Sergunb 0:8918a71cdbe9 131 MIB2_INC_COUNTER32(mib2Base.snmpGroup.snmpInGetRequests, 1);
Sergunb 0:8918a71cdbe9 132 }
Sergunb 0:8918a71cdbe9 133 else if(context->request.pduType == SNMP_PDU_GET_NEXT_REQUEST)
Sergunb 0:8918a71cdbe9 134 {
Sergunb 0:8918a71cdbe9 135 //Debug message
Sergunb 0:8918a71cdbe9 136 TRACE_INFO("Parsing GetNextRequest-PDU...\r\n");
Sergunb 0:8918a71cdbe9 137
Sergunb 0:8918a71cdbe9 138 //Total number of SNMP Get-NextRequest PDUs which have been accepted
Sergunb 0:8918a71cdbe9 139 //and processed by the SNMP protocol entity
Sergunb 0:8918a71cdbe9 140 MIB2_INC_COUNTER32(mib2Base.snmpGroup.snmpInGetNexts, 1);
Sergunb 0:8918a71cdbe9 141 }
Sergunb 0:8918a71cdbe9 142
Sergunb 0:8918a71cdbe9 143 //Enforce access policy
Sergunb 0:8918a71cdbe9 144 if(context->user->mode != SNMP_ACCESS_READ_ONLY &&
Sergunb 0:8918a71cdbe9 145 context->user->mode != SNMP_ACCESS_READ_WRITE)
Sergunb 0:8918a71cdbe9 146 {
Sergunb 0:8918a71cdbe9 147 //Total number of SNMP messages delivered to the SNMP protocol entity
Sergunb 0:8918a71cdbe9 148 //which represented an SNMP operation which was not allowed by the SNMP
Sergunb 0:8918a71cdbe9 149 MIB2_INC_COUNTER32(mib2Base.snmpGroup.snmpInBadCommunityUses, 1);
Sergunb 0:8918a71cdbe9 150
Sergunb 0:8918a71cdbe9 151 //Report an error
Sergunb 0:8918a71cdbe9 152 return ERROR_ACCESS_DENIED;
Sergunb 0:8918a71cdbe9 153 }
Sergunb 0:8918a71cdbe9 154
Sergunb 0:8918a71cdbe9 155 //Initialize response message
Sergunb 0:8918a71cdbe9 156 error = snmpInitResponse(context);
Sergunb 0:8918a71cdbe9 157 //Any error to report?
Sergunb 0:8918a71cdbe9 158 if(error)
Sergunb 0:8918a71cdbe9 159 return error;
Sergunb 0:8918a71cdbe9 160
Sergunb 0:8918a71cdbe9 161 //Point to the first variable binding of the request
Sergunb 0:8918a71cdbe9 162 p = context->request.varBindList;
Sergunb 0:8918a71cdbe9 163 length = context->request.varBindListLen;
Sergunb 0:8918a71cdbe9 164
Sergunb 0:8918a71cdbe9 165 //Lock access to MIB bases
Sergunb 0:8918a71cdbe9 166 snmpLockMib(context);
Sergunb 0:8918a71cdbe9 167
Sergunb 0:8918a71cdbe9 168 //Loop through the list
Sergunb 0:8918a71cdbe9 169 for(index = 1; length > 0; index++)
Sergunb 0:8918a71cdbe9 170 {
Sergunb 0:8918a71cdbe9 171 //Parse variable binding
Sergunb 0:8918a71cdbe9 172 error = snmpParseVarBinding(p, length, &var, &n);
Sergunb 0:8918a71cdbe9 173 //Failed to parse variable binding?
Sergunb 0:8918a71cdbe9 174 if(error)
Sergunb 0:8918a71cdbe9 175 break;
Sergunb 0:8918a71cdbe9 176
Sergunb 0:8918a71cdbe9 177 //Make sure that the object identifier is valid
Sergunb 0:8918a71cdbe9 178 error = oidCheck(var.oid, var.oidLen);
Sergunb 0:8918a71cdbe9 179 //Invalid object identifier?
Sergunb 0:8918a71cdbe9 180 if(error)
Sergunb 0:8918a71cdbe9 181 break;
Sergunb 0:8918a71cdbe9 182
Sergunb 0:8918a71cdbe9 183 //GetRequest-PDU?
Sergunb 0:8918a71cdbe9 184 if(context->request.pduType == SNMP_PDU_GET_REQUEST)
Sergunb 0:8918a71cdbe9 185 {
Sergunb 0:8918a71cdbe9 186 //Retrieve object value
Sergunb 0:8918a71cdbe9 187 error = snmpGetObjectValue(context, &var);
Sergunb 0:8918a71cdbe9 188 }
Sergunb 0:8918a71cdbe9 189 //GetNextRequest-PDU?
Sergunb 0:8918a71cdbe9 190 else
Sergunb 0:8918a71cdbe9 191 {
Sergunb 0:8918a71cdbe9 192 //Search the MIB for the next object
Sergunb 0:8918a71cdbe9 193 error = snmpGetNextObject(context, &var);
Sergunb 0:8918a71cdbe9 194
Sergunb 0:8918a71cdbe9 195 //SNMPv1 version?
Sergunb 0:8918a71cdbe9 196 if(context->request.version == SNMP_VERSION_1)
Sergunb 0:8918a71cdbe9 197 {
Sergunb 0:8918a71cdbe9 198 //Check status code
Sergunb 0:8918a71cdbe9 199 if(error == NO_ERROR)
Sergunb 0:8918a71cdbe9 200 {
Sergunb 0:8918a71cdbe9 201 //Retrieve object value
Sergunb 0:8918a71cdbe9 202 error = snmpGetObjectValue(context, &var);
Sergunb 0:8918a71cdbe9 203 }
Sergunb 0:8918a71cdbe9 204 else
Sergunb 0:8918a71cdbe9 205 {
Sergunb 0:8918a71cdbe9 206 //Stop immediately
Sergunb 0:8918a71cdbe9 207 break;
Sergunb 0:8918a71cdbe9 208 }
Sergunb 0:8918a71cdbe9 209 }
Sergunb 0:8918a71cdbe9 210 //SNMPv2c or SNMPv3 version?
Sergunb 0:8918a71cdbe9 211 else
Sergunb 0:8918a71cdbe9 212 {
Sergunb 0:8918a71cdbe9 213 //Check status code
Sergunb 0:8918a71cdbe9 214 if(error == NO_ERROR)
Sergunb 0:8918a71cdbe9 215 {
Sergunb 0:8918a71cdbe9 216 //Retrieve object value
Sergunb 0:8918a71cdbe9 217 error = snmpGetObjectValue(context, &var);
Sergunb 0:8918a71cdbe9 218 }
Sergunb 0:8918a71cdbe9 219 else if(error == ERROR_OBJECT_NOT_FOUND)
Sergunb 0:8918a71cdbe9 220 {
Sergunb 0:8918a71cdbe9 221 //The variable binding's value field is set to endOfMibView
Sergunb 0:8918a71cdbe9 222 var.objClass = ASN1_CLASS_CONTEXT_SPECIFIC;
Sergunb 0:8918a71cdbe9 223 var.objType = SNMP_EXCEPTION_END_OF_MIB_VIEW;
Sergunb 0:8918a71cdbe9 224 var.valueLen = 0;
Sergunb 0:8918a71cdbe9 225
Sergunb 0:8918a71cdbe9 226 //Catch exception
Sergunb 0:8918a71cdbe9 227 error = NO_ERROR;
Sergunb 0:8918a71cdbe9 228 }
Sergunb 0:8918a71cdbe9 229 else
Sergunb 0:8918a71cdbe9 230 {
Sergunb 0:8918a71cdbe9 231 //Stop immediately
Sergunb 0:8918a71cdbe9 232 break;
Sergunb 0:8918a71cdbe9 233 }
Sergunb 0:8918a71cdbe9 234 }
Sergunb 0:8918a71cdbe9 235 }
Sergunb 0:8918a71cdbe9 236
Sergunb 0:8918a71cdbe9 237 //Failed to retrieve object value?
Sergunb 0:8918a71cdbe9 238 if(error)
Sergunb 0:8918a71cdbe9 239 {
Sergunb 0:8918a71cdbe9 240 //SNMPv1 version?
Sergunb 0:8918a71cdbe9 241 if(context->request.version == SNMP_VERSION_1)
Sergunb 0:8918a71cdbe9 242 {
Sergunb 0:8918a71cdbe9 243 //Stop immediately
Sergunb 0:8918a71cdbe9 244 break;
Sergunb 0:8918a71cdbe9 245 }
Sergunb 0:8918a71cdbe9 246 //SNMPv2c or SNMPv3 version?
Sergunb 0:8918a71cdbe9 247 else
Sergunb 0:8918a71cdbe9 248 {
Sergunb 0:8918a71cdbe9 249 //Catch exception
Sergunb 0:8918a71cdbe9 250 if(error == ERROR_ACCESS_DENIED ||
Sergunb 0:8918a71cdbe9 251 error == ERROR_OBJECT_NOT_FOUND)
Sergunb 0:8918a71cdbe9 252 {
Sergunb 0:8918a71cdbe9 253 //The variable binding's value field is set to noSuchObject
Sergunb 0:8918a71cdbe9 254 var.objClass = ASN1_CLASS_CONTEXT_SPECIFIC;
Sergunb 0:8918a71cdbe9 255 var.objType = SNMP_EXCEPTION_NO_SUCH_OBJECT;
Sergunb 0:8918a71cdbe9 256 var.valueLen = 0;
Sergunb 0:8918a71cdbe9 257 }
Sergunb 0:8918a71cdbe9 258 else if(error == ERROR_INSTANCE_NOT_FOUND)
Sergunb 0:8918a71cdbe9 259 {
Sergunb 0:8918a71cdbe9 260 //The variable binding's value field is set to noSuchInstance
Sergunb 0:8918a71cdbe9 261 var.objClass = ASN1_CLASS_CONTEXT_SPECIFIC;
Sergunb 0:8918a71cdbe9 262 var.objType = SNMP_EXCEPTION_NO_SUCH_INSTANCE;
Sergunb 0:8918a71cdbe9 263 var.valueLen = 0;
Sergunb 0:8918a71cdbe9 264 }
Sergunb 0:8918a71cdbe9 265 else
Sergunb 0:8918a71cdbe9 266 {
Sergunb 0:8918a71cdbe9 267 //Stop immediately
Sergunb 0:8918a71cdbe9 268 break;
Sergunb 0:8918a71cdbe9 269 }
Sergunb 0:8918a71cdbe9 270 }
Sergunb 0:8918a71cdbe9 271 }
Sergunb 0:8918a71cdbe9 272 else
Sergunb 0:8918a71cdbe9 273 {
Sergunb 0:8918a71cdbe9 274 //Total number of MIB objects which have been retrieved successfully
Sergunb 0:8918a71cdbe9 275 //by the SNMP protocol entity as the result of receiving valid SNMP
Sergunb 0:8918a71cdbe9 276 //Get-Request and Get-NextRequest PDUs
Sergunb 0:8918a71cdbe9 277 MIB2_INC_COUNTER32(mib2Base.snmpGroup.snmpInTotalReqVars, 1);
Sergunb 0:8918a71cdbe9 278 }
Sergunb 0:8918a71cdbe9 279
Sergunb 0:8918a71cdbe9 280 //Append variable binding to the list
Sergunb 0:8918a71cdbe9 281 error = snmpWriteVarBinding(context, &var);
Sergunb 0:8918a71cdbe9 282 //Any error to report?
Sergunb 0:8918a71cdbe9 283 if(error)
Sergunb 0:8918a71cdbe9 284 break;
Sergunb 0:8918a71cdbe9 285
Sergunb 0:8918a71cdbe9 286 //Advance data pointer
Sergunb 0:8918a71cdbe9 287 p += n;
Sergunb 0:8918a71cdbe9 288 length -= n;
Sergunb 0:8918a71cdbe9 289 }
Sergunb 0:8918a71cdbe9 290
Sergunb 0:8918a71cdbe9 291 //Unlock access to MIB bases
Sergunb 0:8918a71cdbe9 292 snmpUnlockMib(context);
Sergunb 0:8918a71cdbe9 293
Sergunb 0:8918a71cdbe9 294 //Check status code
Sergunb 0:8918a71cdbe9 295 if(error)
Sergunb 0:8918a71cdbe9 296 {
Sergunb 0:8918a71cdbe9 297 //Set error-status and error-index fields
Sergunb 0:8918a71cdbe9 298 error = snmpTranslateStatusCode(&context->response, error, index);
Sergunb 0:8918a71cdbe9 299 //If the parsing of the request fails, the SNMP agent discards the message
Sergunb 0:8918a71cdbe9 300 if(error)
Sergunb 0:8918a71cdbe9 301 return error;
Sergunb 0:8918a71cdbe9 302
Sergunb 0:8918a71cdbe9 303 //Check whether an alternate Response-PDU should be sent
Sergunb 0:8918a71cdbe9 304 if(context->response.version != SNMP_VERSION_1 &&
Sergunb 0:8918a71cdbe9 305 context->response.errorStatus == SNMP_ERROR_TOO_BIG)
Sergunb 0:8918a71cdbe9 306 {
Sergunb 0:8918a71cdbe9 307 //The alternate Response-PDU is formatted with the same value in its
Sergunb 0:8918a71cdbe9 308 //request-id field as the received GetRequest-PDU and an empty
Sergunb 0:8918a71cdbe9 309 //variable-bindings field
Sergunb 0:8918a71cdbe9 310 context->response.varBindListLen = 0;
Sergunb 0:8918a71cdbe9 311 }
Sergunb 0:8918a71cdbe9 312 else
Sergunb 0:8918a71cdbe9 313 {
Sergunb 0:8918a71cdbe9 314 //The Response-PDU is re-formatted with the same values in its request-id
Sergunb 0:8918a71cdbe9 315 //and variable-bindings fields as the received GetRequest-PDU
Sergunb 0:8918a71cdbe9 316 error = snmpCopyVarBindingList(context);
Sergunb 0:8918a71cdbe9 317 //Any error to report?
Sergunb 0:8918a71cdbe9 318 if(error)
Sergunb 0:8918a71cdbe9 319 return error;
Sergunb 0:8918a71cdbe9 320 }
Sergunb 0:8918a71cdbe9 321 }
Sergunb 0:8918a71cdbe9 322
Sergunb 0:8918a71cdbe9 323 //Successful processing
Sergunb 0:8918a71cdbe9 324 return NO_ERROR;
Sergunb 0:8918a71cdbe9 325 }
Sergunb 0:8918a71cdbe9 326
Sergunb 0:8918a71cdbe9 327
Sergunb 0:8918a71cdbe9 328 /**
Sergunb 0:8918a71cdbe9 329 * @brief Process GetBulkRequest-PDU
Sergunb 0:8918a71cdbe9 330 * @param[in] context Pointer to the SNMP agent context
Sergunb 0:8918a71cdbe9 331 * @return Error code
Sergunb 0:8918a71cdbe9 332 **/
Sergunb 0:8918a71cdbe9 333
Sergunb 0:8918a71cdbe9 334 error_t snmpProcessGetBulkRequestPdu(SnmpAgentContext *context)
Sergunb 0:8918a71cdbe9 335 {
Sergunb 0:8918a71cdbe9 336 #if (SNMP_V2C_SUPPORT == ENABLED || SNMP_V3_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 337 error_t error;
Sergunb 0:8918a71cdbe9 338 int_t index;
Sergunb 0:8918a71cdbe9 339 size_t n;
Sergunb 0:8918a71cdbe9 340 size_t m;
Sergunb 0:8918a71cdbe9 341 size_t length;
Sergunb 0:8918a71cdbe9 342 bool_t endOfMibView;
Sergunb 0:8918a71cdbe9 343 const uint8_t *p;
Sergunb 0:8918a71cdbe9 344 const uint8_t *next;
Sergunb 0:8918a71cdbe9 345 SnmpVarBind var;
Sergunb 0:8918a71cdbe9 346
Sergunb 0:8918a71cdbe9 347 //Debug message
Sergunb 0:8918a71cdbe9 348 TRACE_INFO("Parsing GetBulkRequest-PDU...\r\n");
Sergunb 0:8918a71cdbe9 349
Sergunb 0:8918a71cdbe9 350 //Make sure the SNMP version identifier is valid
Sergunb 0:8918a71cdbe9 351 if(context->request.version == SNMP_VERSION_1)
Sergunb 0:8918a71cdbe9 352 {
Sergunb 0:8918a71cdbe9 353 //The SNMP version is not acceptable
Sergunb 0:8918a71cdbe9 354 return ERROR_INVALID_TYPE;
Sergunb 0:8918a71cdbe9 355 }
Sergunb 0:8918a71cdbe9 356
Sergunb 0:8918a71cdbe9 357 //Enforce access policy
Sergunb 0:8918a71cdbe9 358 if(context->user->mode != SNMP_ACCESS_READ_ONLY &&
Sergunb 0:8918a71cdbe9 359 context->user->mode != SNMP_ACCESS_READ_WRITE)
Sergunb 0:8918a71cdbe9 360 {
Sergunb 0:8918a71cdbe9 361 //Total number of SNMP messages delivered to the SNMP protocol entity
Sergunb 0:8918a71cdbe9 362 //which represented an SNMP operation which was not allowed by the SNMP
Sergunb 0:8918a71cdbe9 363 MIB2_INC_COUNTER32(mib2Base.snmpGroup.snmpInBadCommunityUses, 1);
Sergunb 0:8918a71cdbe9 364
Sergunb 0:8918a71cdbe9 365 //Report an error
Sergunb 0:8918a71cdbe9 366 return ERROR_ACCESS_DENIED;
Sergunb 0:8918a71cdbe9 367 }
Sergunb 0:8918a71cdbe9 368
Sergunb 0:8918a71cdbe9 369 //Initialize response message
Sergunb 0:8918a71cdbe9 370 error = snmpInitResponse(context);
Sergunb 0:8918a71cdbe9 371 //Any error to report?
Sergunb 0:8918a71cdbe9 372 if(error)
Sergunb 0:8918a71cdbe9 373 return error;
Sergunb 0:8918a71cdbe9 374
Sergunb 0:8918a71cdbe9 375 //Point to the first variable binding of the request
Sergunb 0:8918a71cdbe9 376 p = context->request.varBindList;
Sergunb 0:8918a71cdbe9 377 length = context->request.varBindListLen;
Sergunb 0:8918a71cdbe9 378
Sergunb 0:8918a71cdbe9 379 //Lock access to MIB bases
Sergunb 0:8918a71cdbe9 380 snmpLockMib(context);
Sergunb 0:8918a71cdbe9 381
Sergunb 0:8918a71cdbe9 382 //Loop through the list
Sergunb 0:8918a71cdbe9 383 for(index = 1; length > 0; index++)
Sergunb 0:8918a71cdbe9 384 {
Sergunb 0:8918a71cdbe9 385 //The non-repeaters field specifies the number of non-repeating objects
Sergunb 0:8918a71cdbe9 386 //at the start of the variable binding list
Sergunb 0:8918a71cdbe9 387 if((index - 1) == context->request.nonRepeaters)
Sergunb 0:8918a71cdbe9 388 {
Sergunb 0:8918a71cdbe9 389 //Pointer to the first variable binding that will be processed during
Sergunb 0:8918a71cdbe9 390 //the next iteration
Sergunb 0:8918a71cdbe9 391 next = context->response.varBindList + context->response.varBindListLen;
Sergunb 0:8918a71cdbe9 392
Sergunb 0:8918a71cdbe9 393 //Actual size of the variable binding list
Sergunb 0:8918a71cdbe9 394 m = context->response.varBindListLen;
Sergunb 0:8918a71cdbe9 395
Sergunb 0:8918a71cdbe9 396 //This flag tells whether all variable bindings have the value field
Sergunb 0:8918a71cdbe9 397 //set to endOfMibView for a given iteration
Sergunb 0:8918a71cdbe9 398 endOfMibView = TRUE;
Sergunb 0:8918a71cdbe9 399
Sergunb 0:8918a71cdbe9 400 //If the max-repetitions field is zero, the list is trimmed to the
Sergunb 0:8918a71cdbe9 401 //first non-repeating variable bindings
Sergunb 0:8918a71cdbe9 402 if(context->request.maxRepetitions == 0)
Sergunb 0:8918a71cdbe9 403 break;
Sergunb 0:8918a71cdbe9 404 }
Sergunb 0:8918a71cdbe9 405
Sergunb 0:8918a71cdbe9 406 //Parse variable binding
Sergunb 0:8918a71cdbe9 407 error = snmpParseVarBinding(p, length, &var, &n);
Sergunb 0:8918a71cdbe9 408 //Failed to parse variable binding?
Sergunb 0:8918a71cdbe9 409 if(error)
Sergunb 0:8918a71cdbe9 410 break;
Sergunb 0:8918a71cdbe9 411
Sergunb 0:8918a71cdbe9 412 //Make sure that the object identifier is valid
Sergunb 0:8918a71cdbe9 413 error = oidCheck(var.oid, var.oidLen);
Sergunb 0:8918a71cdbe9 414 //Invalid object identifier?
Sergunb 0:8918a71cdbe9 415 if(error)
Sergunb 0:8918a71cdbe9 416 break;
Sergunb 0:8918a71cdbe9 417
Sergunb 0:8918a71cdbe9 418 //Search the MIB for the next object
Sergunb 0:8918a71cdbe9 419 error = snmpGetNextObject(context, &var);
Sergunb 0:8918a71cdbe9 420
Sergunb 0:8918a71cdbe9 421 //Check status code
Sergunb 0:8918a71cdbe9 422 if(error == NO_ERROR)
Sergunb 0:8918a71cdbe9 423 {
Sergunb 0:8918a71cdbe9 424 //Next object found
Sergunb 0:8918a71cdbe9 425 endOfMibView = FALSE;
Sergunb 0:8918a71cdbe9 426 //Retrieve object value
Sergunb 0:8918a71cdbe9 427 error = snmpGetObjectValue(context, &var);
Sergunb 0:8918a71cdbe9 428 }
Sergunb 0:8918a71cdbe9 429 else if(error == ERROR_OBJECT_NOT_FOUND)
Sergunb 0:8918a71cdbe9 430 {
Sergunb 0:8918a71cdbe9 431 //The variable binding's value field is set to endOfMibView
Sergunb 0:8918a71cdbe9 432 var.objClass = ASN1_CLASS_CONTEXT_SPECIFIC;
Sergunb 0:8918a71cdbe9 433 var.objType = SNMP_EXCEPTION_END_OF_MIB_VIEW;
Sergunb 0:8918a71cdbe9 434 var.valueLen = 0;
Sergunb 0:8918a71cdbe9 435
Sergunb 0:8918a71cdbe9 436 //Catch exception
Sergunb 0:8918a71cdbe9 437 error = NO_ERROR;
Sergunb 0:8918a71cdbe9 438 }
Sergunb 0:8918a71cdbe9 439 else
Sergunb 0:8918a71cdbe9 440 {
Sergunb 0:8918a71cdbe9 441 //Stop immediately
Sergunb 0:8918a71cdbe9 442 break;
Sergunb 0:8918a71cdbe9 443 }
Sergunb 0:8918a71cdbe9 444
Sergunb 0:8918a71cdbe9 445 //Failed to retrieve object value?
Sergunb 0:8918a71cdbe9 446 if(error)
Sergunb 0:8918a71cdbe9 447 {
Sergunb 0:8918a71cdbe9 448 //Catch exception
Sergunb 0:8918a71cdbe9 449 if(error == ERROR_ACCESS_DENIED ||
Sergunb 0:8918a71cdbe9 450 error == ERROR_OBJECT_NOT_FOUND)
Sergunb 0:8918a71cdbe9 451 {
Sergunb 0:8918a71cdbe9 452 //The variable binding's value field is set to noSuchObject
Sergunb 0:8918a71cdbe9 453 var.objClass = ASN1_CLASS_CONTEXT_SPECIFIC;
Sergunb 0:8918a71cdbe9 454 var.objType = SNMP_EXCEPTION_NO_SUCH_OBJECT;
Sergunb 0:8918a71cdbe9 455 var.valueLen = 0;
Sergunb 0:8918a71cdbe9 456 }
Sergunb 0:8918a71cdbe9 457 else if(error == ERROR_INSTANCE_NOT_FOUND)
Sergunb 0:8918a71cdbe9 458 {
Sergunb 0:8918a71cdbe9 459 //The variable binding's value field is set to noSuchInstance
Sergunb 0:8918a71cdbe9 460 var.objClass = ASN1_CLASS_CONTEXT_SPECIFIC;
Sergunb 0:8918a71cdbe9 461 var.objType = SNMP_EXCEPTION_NO_SUCH_INSTANCE;
Sergunb 0:8918a71cdbe9 462 var.valueLen = 0;
Sergunb 0:8918a71cdbe9 463 }
Sergunb 0:8918a71cdbe9 464 else
Sergunb 0:8918a71cdbe9 465 {
Sergunb 0:8918a71cdbe9 466 //Stop immediately
Sergunb 0:8918a71cdbe9 467 break;
Sergunb 0:8918a71cdbe9 468 }
Sergunb 0:8918a71cdbe9 469 }
Sergunb 0:8918a71cdbe9 470 else
Sergunb 0:8918a71cdbe9 471 {
Sergunb 0:8918a71cdbe9 472 //Total number of MIB objects which have been retrieved successfully
Sergunb 0:8918a71cdbe9 473 //by the SNMP protocol entity as the result of receiving valid SNMP
Sergunb 0:8918a71cdbe9 474 //Get-Request and Get-NextRequest PDUs
Sergunb 0:8918a71cdbe9 475 MIB2_INC_COUNTER32(mib2Base.snmpGroup.snmpInTotalReqVars, 1);
Sergunb 0:8918a71cdbe9 476 }
Sergunb 0:8918a71cdbe9 477
Sergunb 0:8918a71cdbe9 478 //Append variable binding to the list
Sergunb 0:8918a71cdbe9 479 error = snmpWriteVarBinding(context, &var);
Sergunb 0:8918a71cdbe9 480 //Any error to report?
Sergunb 0:8918a71cdbe9 481 if(error)
Sergunb 0:8918a71cdbe9 482 break;
Sergunb 0:8918a71cdbe9 483
Sergunb 0:8918a71cdbe9 484 //Advance data pointer
Sergunb 0:8918a71cdbe9 485 p += n;
Sergunb 0:8918a71cdbe9 486 length -= n;
Sergunb 0:8918a71cdbe9 487
Sergunb 0:8918a71cdbe9 488 //Next iteration?
Sergunb 0:8918a71cdbe9 489 if(length == 0 && index > context->request.nonRepeaters)
Sergunb 0:8918a71cdbe9 490 {
Sergunb 0:8918a71cdbe9 491 //Decrement repeat counter
Sergunb 0:8918a71cdbe9 492 context->request.maxRepetitions--;
Sergunb 0:8918a71cdbe9 493
Sergunb 0:8918a71cdbe9 494 //Last iteration?
Sergunb 0:8918a71cdbe9 495 if(!context->request.maxRepetitions)
Sergunb 0:8918a71cdbe9 496 break;
Sergunb 0:8918a71cdbe9 497 //All variable bindings have the value field set to endOfMibView?
Sergunb 0:8918a71cdbe9 498 if(endOfMibView)
Sergunb 0:8918a71cdbe9 499 break;
Sergunb 0:8918a71cdbe9 500
Sergunb 0:8918a71cdbe9 501 //Point to the first variable binding to be processed
Sergunb 0:8918a71cdbe9 502 p = next;
Sergunb 0:8918a71cdbe9 503 //Number of bytes to be processed
Sergunb 0:8918a71cdbe9 504 length = context->response.varBindListLen - m;
Sergunb 0:8918a71cdbe9 505 //Rewind index
Sergunb 0:8918a71cdbe9 506 index = context->request.nonRepeaters;
Sergunb 0:8918a71cdbe9 507 }
Sergunb 0:8918a71cdbe9 508 }
Sergunb 0:8918a71cdbe9 509
Sergunb 0:8918a71cdbe9 510 //Unlock access to MIB bases
Sergunb 0:8918a71cdbe9 511 snmpUnlockMib(context);
Sergunb 0:8918a71cdbe9 512
Sergunb 0:8918a71cdbe9 513 //Check status code
Sergunb 0:8918a71cdbe9 514 if(error == ERROR_BUFFER_OVERFLOW)
Sergunb 0:8918a71cdbe9 515 {
Sergunb 0:8918a71cdbe9 516 //If the size of the message containing the requested number of variable
Sergunb 0:8918a71cdbe9 517 //bindings would be greater than the maximum message size, then the
Sergunb 0:8918a71cdbe9 518 //response is generated with a lesser number of variable bindings
Sergunb 0:8918a71cdbe9 519 }
Sergunb 0:8918a71cdbe9 520 else if(error)
Sergunb 0:8918a71cdbe9 521 {
Sergunb 0:8918a71cdbe9 522 //Set error-status and error-index fields
Sergunb 0:8918a71cdbe9 523 error = snmpTranslateStatusCode(&context->response, error, index);
Sergunb 0:8918a71cdbe9 524 //If the parsing of the request fails, the SNMP agent discards the message
Sergunb 0:8918a71cdbe9 525 if(error)
Sergunb 0:8918a71cdbe9 526 return error;
Sergunb 0:8918a71cdbe9 527
Sergunb 0:8918a71cdbe9 528 //The Response-PDU is re-formatted with the same values in its request-id
Sergunb 0:8918a71cdbe9 529 //and variable-bindings fields as the received GetRequest-PDU
Sergunb 0:8918a71cdbe9 530 error = snmpCopyVarBindingList(context);
Sergunb 0:8918a71cdbe9 531 //Any error to report?
Sergunb 0:8918a71cdbe9 532 if(error)
Sergunb 0:8918a71cdbe9 533 return error;
Sergunb 0:8918a71cdbe9 534 }
Sergunb 0:8918a71cdbe9 535
Sergunb 0:8918a71cdbe9 536 //Successful processing
Sergunb 0:8918a71cdbe9 537 return NO_ERROR;
Sergunb 0:8918a71cdbe9 538 #else
Sergunb 0:8918a71cdbe9 539 //Not implemented
Sergunb 0:8918a71cdbe9 540 return ERROR_NOT_IMPLEMENTED;
Sergunb 0:8918a71cdbe9 541 #endif
Sergunb 0:8918a71cdbe9 542 }
Sergunb 0:8918a71cdbe9 543
Sergunb 0:8918a71cdbe9 544
Sergunb 0:8918a71cdbe9 545 /**
Sergunb 0:8918a71cdbe9 546 * @brief Process SetRequest-PDU
Sergunb 0:8918a71cdbe9 547 * @param[in] context Pointer to the SNMP agent context
Sergunb 0:8918a71cdbe9 548 * @return Error code
Sergunb 0:8918a71cdbe9 549 **/
Sergunb 0:8918a71cdbe9 550
Sergunb 0:8918a71cdbe9 551 error_t snmpProcessSetRequestPdu(SnmpAgentContext *context)
Sergunb 0:8918a71cdbe9 552 {
Sergunb 0:8918a71cdbe9 553 error_t error;
Sergunb 0:8918a71cdbe9 554 int_t index;
Sergunb 0:8918a71cdbe9 555 size_t n;
Sergunb 0:8918a71cdbe9 556 size_t length;
Sergunb 0:8918a71cdbe9 557 const uint8_t *p;
Sergunb 0:8918a71cdbe9 558 SnmpVarBind var;
Sergunb 0:8918a71cdbe9 559
Sergunb 0:8918a71cdbe9 560 //Debug message
Sergunb 0:8918a71cdbe9 561 TRACE_INFO("Parsing SetRequest-PDU...\r\n");
Sergunb 0:8918a71cdbe9 562
Sergunb 0:8918a71cdbe9 563 //Total number of SNMP Set-Request PDUs which have been accepted and
Sergunb 0:8918a71cdbe9 564 //processed by the SNMP protocol entity
Sergunb 0:8918a71cdbe9 565 MIB2_INC_COUNTER32(mib2Base.snmpGroup.snmpInSetRequests, 1);
Sergunb 0:8918a71cdbe9 566
Sergunb 0:8918a71cdbe9 567 //Enforce access policy
Sergunb 0:8918a71cdbe9 568 if(context->user->mode != SNMP_ACCESS_WRITE_ONLY &&
Sergunb 0:8918a71cdbe9 569 context->user->mode != SNMP_ACCESS_READ_WRITE)
Sergunb 0:8918a71cdbe9 570 {
Sergunb 0:8918a71cdbe9 571 //Total number of SNMP messages delivered to the SNMP protocol entity
Sergunb 0:8918a71cdbe9 572 //which represented an SNMP operation which was not allowed by the SNMP
Sergunb 0:8918a71cdbe9 573 MIB2_INC_COUNTER32(mib2Base.snmpGroup.snmpInBadCommunityUses, 1);
Sergunb 0:8918a71cdbe9 574
Sergunb 0:8918a71cdbe9 575 //Report an error
Sergunb 0:8918a71cdbe9 576 return ERROR_ACCESS_DENIED;
Sergunb 0:8918a71cdbe9 577 }
Sergunb 0:8918a71cdbe9 578
Sergunb 0:8918a71cdbe9 579 //Initialize response message
Sergunb 0:8918a71cdbe9 580 error = snmpInitResponse(context);
Sergunb 0:8918a71cdbe9 581 //Any error to report?
Sergunb 0:8918a71cdbe9 582 if(error)
Sergunb 0:8918a71cdbe9 583 return error;
Sergunb 0:8918a71cdbe9 584
Sergunb 0:8918a71cdbe9 585 //The variable bindings are processed as a two phase operation. In the
Sergunb 0:8918a71cdbe9 586 //first phase, each variable binding is validated
Sergunb 0:8918a71cdbe9 587 p = context->request.varBindList;
Sergunb 0:8918a71cdbe9 588 length = context->request.varBindListLen;
Sergunb 0:8918a71cdbe9 589
Sergunb 0:8918a71cdbe9 590 //Loop through the list
Sergunb 0:8918a71cdbe9 591 for(index = 1; length > 0; index++)
Sergunb 0:8918a71cdbe9 592 {
Sergunb 0:8918a71cdbe9 593 //Parse variable binding
Sergunb 0:8918a71cdbe9 594 error = snmpParseVarBinding(p, length, &var, &n);
Sergunb 0:8918a71cdbe9 595 //Failed to parse variable binding?
Sergunb 0:8918a71cdbe9 596 if(error)
Sergunb 0:8918a71cdbe9 597 break;
Sergunb 0:8918a71cdbe9 598
Sergunb 0:8918a71cdbe9 599 //Assign object value
Sergunb 0:8918a71cdbe9 600 error = snmpSetObjectValue(context, &var, FALSE);
Sergunb 0:8918a71cdbe9 601 //Any error to report?
Sergunb 0:8918a71cdbe9 602 if(error)
Sergunb 0:8918a71cdbe9 603 break;
Sergunb 0:8918a71cdbe9 604
Sergunb 0:8918a71cdbe9 605 //Advance data pointer
Sergunb 0:8918a71cdbe9 606 p += n;
Sergunb 0:8918a71cdbe9 607 length -= n;
Sergunb 0:8918a71cdbe9 608 }
Sergunb 0:8918a71cdbe9 609
Sergunb 0:8918a71cdbe9 610 //If all validations are successful, then each variable is altered in
Sergunb 0:8918a71cdbe9 611 //the second phase
Sergunb 0:8918a71cdbe9 612 if(!error)
Sergunb 0:8918a71cdbe9 613 {
Sergunb 0:8918a71cdbe9 614 //The changes are committed to the MIB base during the second phase
Sergunb 0:8918a71cdbe9 615 p = context->request.varBindList;
Sergunb 0:8918a71cdbe9 616 length = context->request.varBindListLen;
Sergunb 0:8918a71cdbe9 617
Sergunb 0:8918a71cdbe9 618 //Lock access to MIB bases
Sergunb 0:8918a71cdbe9 619 snmpLockMib(context);
Sergunb 0:8918a71cdbe9 620
Sergunb 0:8918a71cdbe9 621 //Loop through the list
Sergunb 0:8918a71cdbe9 622 for(index = 1; length > 0; index++)
Sergunb 0:8918a71cdbe9 623 {
Sergunb 0:8918a71cdbe9 624 //Parse variable binding
Sergunb 0:8918a71cdbe9 625 error = snmpParseVarBinding(p, length, &var, &n);
Sergunb 0:8918a71cdbe9 626 //Failed to parse variable binding?
Sergunb 0:8918a71cdbe9 627 if(error)
Sergunb 0:8918a71cdbe9 628 break;
Sergunb 0:8918a71cdbe9 629
Sergunb 0:8918a71cdbe9 630 //Assign object value
Sergunb 0:8918a71cdbe9 631 error = snmpSetObjectValue(context, &var, TRUE);
Sergunb 0:8918a71cdbe9 632 //Any error to report?
Sergunb 0:8918a71cdbe9 633 if(error)
Sergunb 0:8918a71cdbe9 634 break;
Sergunb 0:8918a71cdbe9 635
Sergunb 0:8918a71cdbe9 636 //Total number of MIB objects which have been altered successfully
Sergunb 0:8918a71cdbe9 637 //by the SNMP protocol entity as the result of receiving valid
Sergunb 0:8918a71cdbe9 638 //SNMP Set-Request PDUs
Sergunb 0:8918a71cdbe9 639 MIB2_INC_COUNTER32(mib2Base.snmpGroup.snmpInTotalSetVars, 1);
Sergunb 0:8918a71cdbe9 640
Sergunb 0:8918a71cdbe9 641 //Advance data pointer
Sergunb 0:8918a71cdbe9 642 p += n;
Sergunb 0:8918a71cdbe9 643 length -= n;
Sergunb 0:8918a71cdbe9 644 }
Sergunb 0:8918a71cdbe9 645
Sergunb 0:8918a71cdbe9 646 //Unlock access to MIB bases
Sergunb 0:8918a71cdbe9 647 snmpUnlockMib(context);
Sergunb 0:8918a71cdbe9 648 }
Sergunb 0:8918a71cdbe9 649
Sergunb 0:8918a71cdbe9 650 //Any error to report?
Sergunb 0:8918a71cdbe9 651 if(error)
Sergunb 0:8918a71cdbe9 652 {
Sergunb 0:8918a71cdbe9 653 //Set error-status and error-index fields
Sergunb 0:8918a71cdbe9 654 error = snmpTranslateStatusCode(&context->response, error, index);
Sergunb 0:8918a71cdbe9 655 //If the parsing of the request fails, the SNMP agent discards the message
Sergunb 0:8918a71cdbe9 656 if(error)
Sergunb 0:8918a71cdbe9 657 return error;
Sergunb 0:8918a71cdbe9 658 }
Sergunb 0:8918a71cdbe9 659
Sergunb 0:8918a71cdbe9 660 //The SNMP agent sends back a GetResponse-PDU of identical form
Sergunb 0:8918a71cdbe9 661 error = snmpCopyVarBindingList(context);
Sergunb 0:8918a71cdbe9 662 //Return status code
Sergunb 0:8918a71cdbe9 663 return error;
Sergunb 0:8918a71cdbe9 664 }
Sergunb 0:8918a71cdbe9 665
Sergunb 0:8918a71cdbe9 666
Sergunb 0:8918a71cdbe9 667 /**
Sergunb 0:8918a71cdbe9 668 * @brief Format Trap-PDU or SNMPv2-Trap-PDU
Sergunb 0:8918a71cdbe9 669 * @param[in] context Pointer to the SNMP agent context
Sergunb 0:8918a71cdbe9 670 * @param[in] version SNMP version identifier
Sergunb 0:8918a71cdbe9 671 * @param[in] username User name or community name
Sergunb 0:8918a71cdbe9 672 * @param[in] genericTrapType Generic trap type
Sergunb 0:8918a71cdbe9 673 * @param[in] specificTrapCode Specific code
Sergunb 0:8918a71cdbe9 674 * @param[in] objectList List of object names
Sergunb 0:8918a71cdbe9 675 * @param[in] objectListSize Number of entries in the list
Sergunb 0:8918a71cdbe9 676 * @return Error code
Sergunb 0:8918a71cdbe9 677 **/
Sergunb 0:8918a71cdbe9 678
Sergunb 0:8918a71cdbe9 679 error_t snmpFormatTrapPdu(SnmpAgentContext *context, SnmpVersion version,
Sergunb 0:8918a71cdbe9 680 const char_t *username, uint_t genericTrapType, uint_t specificTrapCode,
Sergunb 0:8918a71cdbe9 681 const SnmpTrapObject *objectList, uint_t objectListSize)
Sergunb 0:8918a71cdbe9 682 {
Sergunb 0:8918a71cdbe9 683 error_t error;
Sergunb 0:8918a71cdbe9 684 uint_t i;
Sergunb 0:8918a71cdbe9 685 size_t n;
Sergunb 0:8918a71cdbe9 686 systime_t time;
Sergunb 0:8918a71cdbe9 687 SnmpMessage *message;
Sergunb 0:8918a71cdbe9 688 SnmpVarBind var;
Sergunb 0:8918a71cdbe9 689
Sergunb 0:8918a71cdbe9 690 //Point to the SNMP message
Sergunb 0:8918a71cdbe9 691 message = &context->response;
Sergunb 0:8918a71cdbe9 692 //Initialize SNMP message
Sergunb 0:8918a71cdbe9 693 snmpInitMessage(message);
Sergunb 0:8918a71cdbe9 694
Sergunb 0:8918a71cdbe9 695 //SNMP version identifier
Sergunb 0:8918a71cdbe9 696 message->version = version;
Sergunb 0:8918a71cdbe9 697
Sergunb 0:8918a71cdbe9 698 #if (SNMP_V1_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 699 //SNMPv1 version?
Sergunb 0:8918a71cdbe9 700 if(version == SNMP_VERSION_1)
Sergunb 0:8918a71cdbe9 701 {
Sergunb 0:8918a71cdbe9 702 #if (IPV4_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 703 NetInterface *interface;
Sergunb 0:8918a71cdbe9 704
Sergunb 0:8918a71cdbe9 705 //Point to the underlying network interface
Sergunb 0:8918a71cdbe9 706 interface = context->settings.interface;
Sergunb 0:8918a71cdbe9 707 #endif
Sergunb 0:8918a71cdbe9 708
Sergunb 0:8918a71cdbe9 709 //Community name
Sergunb 0:8918a71cdbe9 710 message->community = username;
Sergunb 0:8918a71cdbe9 711 message->communityLen = strlen(username);
Sergunb 0:8918a71cdbe9 712
Sergunb 0:8918a71cdbe9 713 //Prepare to send a Trap-PDU
Sergunb 0:8918a71cdbe9 714 message->pduType = SNMP_PDU_TRAP;
Sergunb 0:8918a71cdbe9 715 //Type of object generating trap
Sergunb 0:8918a71cdbe9 716 message->enterpriseOid = context->enterpriseOid;
Sergunb 0:8918a71cdbe9 717 message->enterpriseOidLen = context->enterpriseOidLen;
Sergunb 0:8918a71cdbe9 718
Sergunb 0:8918a71cdbe9 719 #if (IPV4_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 720 //Address of object generating trap
Sergunb 0:8918a71cdbe9 721 if(interface != NULL)
Sergunb 0:8918a71cdbe9 722 message->agentAddr = interface->ipv4Context.addr;
Sergunb 0:8918a71cdbe9 723 #endif
Sergunb 0:8918a71cdbe9 724
Sergunb 0:8918a71cdbe9 725 //Generic trap type
Sergunb 0:8918a71cdbe9 726 message->genericTrapType = genericTrapType;
Sergunb 0:8918a71cdbe9 727 //Specific trap code
Sergunb 0:8918a71cdbe9 728 message->specificTrapCode = specificTrapCode;
Sergunb 0:8918a71cdbe9 729 //Timestamp
Sergunb 0:8918a71cdbe9 730 message->timestamp = osGetSystemTime() / 10;
Sergunb 0:8918a71cdbe9 731 }
Sergunb 0:8918a71cdbe9 732 else
Sergunb 0:8918a71cdbe9 733 #endif
Sergunb 0:8918a71cdbe9 734 #if (SNMP_V2C_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 735 //SNMPv2c version?
Sergunb 0:8918a71cdbe9 736 if(version == SNMP_VERSION_2C)
Sergunb 0:8918a71cdbe9 737 {
Sergunb 0:8918a71cdbe9 738 //Community name
Sergunb 0:8918a71cdbe9 739 message->community = username;
Sergunb 0:8918a71cdbe9 740 message->communityLen = strlen(username);
Sergunb 0:8918a71cdbe9 741
Sergunb 0:8918a71cdbe9 742 //Prepare to send a SNMPv2-Trap-PDU
Sergunb 0:8918a71cdbe9 743 message->pduType = SNMP_PDU_TRAP_V2;
Sergunb 0:8918a71cdbe9 744 }
Sergunb 0:8918a71cdbe9 745 else
Sergunb 0:8918a71cdbe9 746 #endif
Sergunb 0:8918a71cdbe9 747 #if (SNMP_V3_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 748 //SNMPv3 version?
Sergunb 0:8918a71cdbe9 749 if(version == SNMP_VERSION_3)
Sergunb 0:8918a71cdbe9 750 {
Sergunb 0:8918a71cdbe9 751 //Maximum message size supported by the sender
Sergunb 0:8918a71cdbe9 752 message->msgMaxSize = SNMP_MAX_MSG_SIZE;
Sergunb 0:8918a71cdbe9 753
Sergunb 0:8918a71cdbe9 754 //Bit fields which control processing of the message
Sergunb 0:8918a71cdbe9 755 if(context->user->authProtocol != SNMP_AUTH_PROTOCOL_NONE)
Sergunb 0:8918a71cdbe9 756 message->msgFlags |= SNMP_MSG_FLAG_AUTH;
Sergunb 0:8918a71cdbe9 757 if(context->user->privProtocol != SNMP_PRIV_PROTOCOL_NONE)
Sergunb 0:8918a71cdbe9 758 message->msgFlags |= SNMP_MSG_FLAG_PRIV;
Sergunb 0:8918a71cdbe9 759
Sergunb 0:8918a71cdbe9 760 //Security model used by the sender
Sergunb 0:8918a71cdbe9 761 message->msgSecurityModel = SNMP_SECURITY_MODEL_USM;
Sergunb 0:8918a71cdbe9 762
Sergunb 0:8918a71cdbe9 763 //Authoritative engine identifier
Sergunb 0:8918a71cdbe9 764 message->msgAuthEngineId = context->contextEngine;
Sergunb 0:8918a71cdbe9 765 message->msgAuthEngineIdLen = context->contextEngineLen;
Sergunb 0:8918a71cdbe9 766 //Number of times the SNMP engine has rebooted
Sergunb 0:8918a71cdbe9 767 message->msgAuthEngineBoots = context->engineBoots;
Sergunb 0:8918a71cdbe9 768 //Number of seconds since last reboot
Sergunb 0:8918a71cdbe9 769 message->msgAuthEngineTime = context->engineTime;
Sergunb 0:8918a71cdbe9 770 //User name
Sergunb 0:8918a71cdbe9 771 message->msgUserName = username;
Sergunb 0:8918a71cdbe9 772 message->msgUserNameLen = strlen(username);
Sergunb 0:8918a71cdbe9 773 //Authentication parameters
Sergunb 0:8918a71cdbe9 774 message->msgAuthParameters = NULL;
Sergunb 0:8918a71cdbe9 775
Sergunb 0:8918a71cdbe9 776 //Length of the authentication parameters
Sergunb 0:8918a71cdbe9 777 if(context->user->authProtocol == SNMP_AUTH_PROTOCOL_MD5)
Sergunb 0:8918a71cdbe9 778 message->msgAuthParametersLen = 12;
Sergunb 0:8918a71cdbe9 779 else if(context->user->authProtocol == SNMP_AUTH_PROTOCOL_SHA1)
Sergunb 0:8918a71cdbe9 780 message->msgAuthParametersLen = 12;
Sergunb 0:8918a71cdbe9 781 else if(context->user->authProtocol == SNMP_AUTH_PROTOCOL_SHA224)
Sergunb 0:8918a71cdbe9 782 message->msgAuthParametersLen = 16;
Sergunb 0:8918a71cdbe9 783 else if(context->user->authProtocol == SNMP_AUTH_PROTOCOL_SHA256)
Sergunb 0:8918a71cdbe9 784 message->msgAuthParametersLen = 24;
Sergunb 0:8918a71cdbe9 785 else if(context->user->authProtocol == SNMP_AUTH_PROTOCOL_SHA384)
Sergunb 0:8918a71cdbe9 786 message->msgAuthParametersLen = 32;
Sergunb 0:8918a71cdbe9 787 else if(context->user->authProtocol == SNMP_AUTH_PROTOCOL_SHA512)
Sergunb 0:8918a71cdbe9 788 message->msgAuthParametersLen = 48;
Sergunb 0:8918a71cdbe9 789 else
Sergunb 0:8918a71cdbe9 790 message->msgAuthParametersLen = 0;
Sergunb 0:8918a71cdbe9 791
Sergunb 0:8918a71cdbe9 792 //Privacy parameters
Sergunb 0:8918a71cdbe9 793 message->msgPrivParameters = context->privParameters;
Sergunb 0:8918a71cdbe9 794
Sergunb 0:8918a71cdbe9 795 //Length of the privacy parameters
Sergunb 0:8918a71cdbe9 796 if(context->user->privProtocol == SNMP_PRIV_PROTOCOL_DES)
Sergunb 0:8918a71cdbe9 797 message->msgPrivParametersLen = 8;
Sergunb 0:8918a71cdbe9 798 else if(context->user->privProtocol == SNMP_PRIV_PROTOCOL_AES)
Sergunb 0:8918a71cdbe9 799 message->msgPrivParametersLen = 8;
Sergunb 0:8918a71cdbe9 800 else
Sergunb 0:8918a71cdbe9 801 message->msgPrivParametersLen = 0;
Sergunb 0:8918a71cdbe9 802
Sergunb 0:8918a71cdbe9 803 //Context engine identifier
Sergunb 0:8918a71cdbe9 804 message->contextEngineId = context->contextEngine;
Sergunb 0:8918a71cdbe9 805 message->contextEngineIdLen = context->contextEngineLen;
Sergunb 0:8918a71cdbe9 806 //Context name
Sergunb 0:8918a71cdbe9 807 message->contextName = (uint8_t *) context->contextName;
Sergunb 0:8918a71cdbe9 808 message->contextNameLen = strlen(context->contextName);
Sergunb 0:8918a71cdbe9 809
Sergunb 0:8918a71cdbe9 810 //Prepare to send a SNMPv2-Trap-PDU
Sergunb 0:8918a71cdbe9 811 message->pduType = SNMP_PDU_TRAP_V2;
Sergunb 0:8918a71cdbe9 812 }
Sergunb 0:8918a71cdbe9 813 else
Sergunb 0:8918a71cdbe9 814 #endif
Sergunb 0:8918a71cdbe9 815 //Invalid SNMP version?
Sergunb 0:8918a71cdbe9 816 {
Sergunb 0:8918a71cdbe9 817 //Report an error
Sergunb 0:8918a71cdbe9 818 return ERROR_INVALID_VERSION;
Sergunb 0:8918a71cdbe9 819 }
Sergunb 0:8918a71cdbe9 820
Sergunb 0:8918a71cdbe9 821 //Make room for the message header at the beginning of the buffer
Sergunb 0:8918a71cdbe9 822 error = snmpComputeMessageOverhead(&context->response);
Sergunb 0:8918a71cdbe9 823 //Any error to report?
Sergunb 0:8918a71cdbe9 824 if(error)
Sergunb 0:8918a71cdbe9 825 return error;
Sergunb 0:8918a71cdbe9 826
Sergunb 0:8918a71cdbe9 827 #if (SNMP_V2C_SUPPORT == ENABLED || SNMP_V3_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 828 //SNMPv2c or SNMPv3 version?
Sergunb 0:8918a71cdbe9 829 if(version == SNMP_VERSION_2C || version == SNMP_VERSION_3)
Sergunb 0:8918a71cdbe9 830 {
Sergunb 0:8918a71cdbe9 831 //Get current time
Sergunb 0:8918a71cdbe9 832 time = osGetSystemTime() / 10;
Sergunb 0:8918a71cdbe9 833
Sergunb 0:8918a71cdbe9 834 //Encode the object value using ASN.1 rules
Sergunb 0:8918a71cdbe9 835 error = snmpEncodeUnsignedInt32(time, message->buffer, &n);
Sergunb 0:8918a71cdbe9 836 //Any error to report?
Sergunb 0:8918a71cdbe9 837 if(error)
Sergunb 0:8918a71cdbe9 838 return error;
Sergunb 0:8918a71cdbe9 839
Sergunb 0:8918a71cdbe9 840 //The first two variable bindings in the variable binding list of an
Sergunb 0:8918a71cdbe9 841 //SNMPv2-Trap-PDU are sysUpTime.0 and snmpTrapOID.0 respectively
Sergunb 0:8918a71cdbe9 842 var.oid = sysUpTimeObject;
Sergunb 0:8918a71cdbe9 843 var.oidLen = sizeof(sysUpTimeObject);
Sergunb 0:8918a71cdbe9 844 var.objClass = ASN1_CLASS_APPLICATION;
Sergunb 0:8918a71cdbe9 845 var.objType = MIB_TYPE_TIME_TICKS;
Sergunb 0:8918a71cdbe9 846 var.value = message->buffer;
Sergunb 0:8918a71cdbe9 847 var.valueLen = n;
Sergunb 0:8918a71cdbe9 848
Sergunb 0:8918a71cdbe9 849 //Append sysUpTime.0 to the variable binding list
Sergunb 0:8918a71cdbe9 850 error = snmpWriteVarBinding(context, &var);
Sergunb 0:8918a71cdbe9 851 //Any error to report?
Sergunb 0:8918a71cdbe9 852 if(error)
Sergunb 0:8918a71cdbe9 853 return error;
Sergunb 0:8918a71cdbe9 854
Sergunb 0:8918a71cdbe9 855 //Generic or enterprise-specific trap?
Sergunb 0:8918a71cdbe9 856 if(genericTrapType < SNMP_TRAP_ENTERPRISE_SPECIFIC)
Sergunb 0:8918a71cdbe9 857 {
Sergunb 0:8918a71cdbe9 858 //Retrieve the length of the snmpTraps OID
Sergunb 0:8918a71cdbe9 859 n = sizeof(snmpTrapsObject);
Sergunb 0:8918a71cdbe9 860 //Copy the OID
Sergunb 0:8918a71cdbe9 861 memcpy(message->buffer, snmpTrapsObject, n);
Sergunb 0:8918a71cdbe9 862
Sergunb 0:8918a71cdbe9 863 //For generic traps, the SNMPv2 snmpTrapOID parameter shall be
Sergunb 0:8918a71cdbe9 864 //the corresponding trap as defined in section 2 of 3418
Sergunb 0:8918a71cdbe9 865 message->buffer[n] = genericTrapType + 1;
Sergunb 0:8918a71cdbe9 866
Sergunb 0:8918a71cdbe9 867 //Update the length of the snmpTrapOID parameter
Sergunb 0:8918a71cdbe9 868 n++;
Sergunb 0:8918a71cdbe9 869 }
Sergunb 0:8918a71cdbe9 870 else
Sergunb 0:8918a71cdbe9 871 {
Sergunb 0:8918a71cdbe9 872 //Retrieve the length of the enterprise OID
Sergunb 0:8918a71cdbe9 873 n = context->enterpriseOidLen;
Sergunb 0:8918a71cdbe9 874
Sergunb 0:8918a71cdbe9 875 //For enterprise specific traps, the SNMPv2 snmpTrapOID parameter shall
Sergunb 0:8918a71cdbe9 876 //be the concatenation of the SNMPv1 enterprise OID and two additional
Sergunb 0:8918a71cdbe9 877 //sub-identifiers: '0' and the SNMPv1 specific trap parameter
Sergunb 0:8918a71cdbe9 878 memcpy(message->buffer, context->enterpriseOid, n);
Sergunb 0:8918a71cdbe9 879
Sergunb 0:8918a71cdbe9 880 //Concatenate the '0' sub-identifier
Sergunb 0:8918a71cdbe9 881 message->buffer[n++] = 0;
Sergunb 0:8918a71cdbe9 882
Sergunb 0:8918a71cdbe9 883 //Concatenate the specific trap parameter
Sergunb 0:8918a71cdbe9 884 message->buffer[n] = specificTrapCode % 128;
Sergunb 0:8918a71cdbe9 885
Sergunb 0:8918a71cdbe9 886 //Loop as long as necessary
Sergunb 0:8918a71cdbe9 887 for(i = 1; specificTrapCode > 128; i++)
Sergunb 0:8918a71cdbe9 888 {
Sergunb 0:8918a71cdbe9 889 //Split the binary representation into 7 bit chunks
Sergunb 0:8918a71cdbe9 890 specificTrapCode /= 128;
Sergunb 0:8918a71cdbe9 891 //Make room for the new chunk
Sergunb 0:8918a71cdbe9 892 memmove(message->buffer + n + 1, message->buffer + n, i);
Sergunb 0:8918a71cdbe9 893 //Set the most significant bit in the current chunk
Sergunb 0:8918a71cdbe9 894 message->buffer[n] = OID_MORE_FLAG | (specificTrapCode % 128);
Sergunb 0:8918a71cdbe9 895 }
Sergunb 0:8918a71cdbe9 896
Sergunb 0:8918a71cdbe9 897 //Update the length of the snmpTrapOID parameter
Sergunb 0:8918a71cdbe9 898 n += i;
Sergunb 0:8918a71cdbe9 899 }
Sergunb 0:8918a71cdbe9 900
Sergunb 0:8918a71cdbe9 901 //The snmpTrapOID.0 variable occurs as the second variable
Sergunb 0:8918a71cdbe9 902 //binding in every SNMPv2-Trap-PDU
Sergunb 0:8918a71cdbe9 903 var.oid = snmpTrapOidObject;
Sergunb 0:8918a71cdbe9 904 var.oidLen = sizeof(snmpTrapOidObject);
Sergunb 0:8918a71cdbe9 905 var.objClass = ASN1_CLASS_UNIVERSAL;
Sergunb 0:8918a71cdbe9 906 var.objType = ASN1_TYPE_OBJECT_IDENTIFIER;
Sergunb 0:8918a71cdbe9 907 var.value = message->buffer;
Sergunb 0:8918a71cdbe9 908 var.valueLen = n;
Sergunb 0:8918a71cdbe9 909
Sergunb 0:8918a71cdbe9 910 //Append snmpTrapOID.0 to the variable binding list
Sergunb 0:8918a71cdbe9 911 error = snmpWriteVarBinding(context, &var);
Sergunb 0:8918a71cdbe9 912 //Any error to report?
Sergunb 0:8918a71cdbe9 913 if(error)
Sergunb 0:8918a71cdbe9 914 return error;
Sergunb 0:8918a71cdbe9 915 }
Sergunb 0:8918a71cdbe9 916 #endif
Sergunb 0:8918a71cdbe9 917
Sergunb 0:8918a71cdbe9 918 //Loop through the list of objects
Sergunb 0:8918a71cdbe9 919 for(i = 0; i < objectListSize; i++)
Sergunb 0:8918a71cdbe9 920 {
Sergunb 0:8918a71cdbe9 921 //Get object identifier
Sergunb 0:8918a71cdbe9 922 var.oid = objectList[i].oid;
Sergunb 0:8918a71cdbe9 923 var.oidLen = objectList[i].oidLen;
Sergunb 0:8918a71cdbe9 924
Sergunb 0:8918a71cdbe9 925 //Retrieve object value
Sergunb 0:8918a71cdbe9 926 error = snmpGetObjectValue(context, &var);
Sergunb 0:8918a71cdbe9 927 //Any error to report?
Sergunb 0:8918a71cdbe9 928 if(error)
Sergunb 0:8918a71cdbe9 929 return error;
Sergunb 0:8918a71cdbe9 930
Sergunb 0:8918a71cdbe9 931 //Append variable binding to the list
Sergunb 0:8918a71cdbe9 932 error = snmpWriteVarBinding(context, &var);
Sergunb 0:8918a71cdbe9 933 //Any error to report?
Sergunb 0:8918a71cdbe9 934 if(error)
Sergunb 0:8918a71cdbe9 935 return error;
Sergunb 0:8918a71cdbe9 936 }
Sergunb 0:8918a71cdbe9 937
Sergunb 0:8918a71cdbe9 938 //Total number of SNMP Trap PDUs which have been generated by
Sergunb 0:8918a71cdbe9 939 //the SNMP protocol entity
Sergunb 0:8918a71cdbe9 940 MIB2_INC_COUNTER32(mib2Base.snmpGroup.snmpOutTraps, 1);
Sergunb 0:8918a71cdbe9 941
Sergunb 0:8918a71cdbe9 942 //Format PDU header
Sergunb 0:8918a71cdbe9 943 error = snmpWritePduHeader(&context->response);
Sergunb 0:8918a71cdbe9 944 //Return status code
Sergunb 0:8918a71cdbe9 945 return error;
Sergunb 0:8918a71cdbe9 946 }
Sergunb 0:8918a71cdbe9 947
Sergunb 0:8918a71cdbe9 948
Sergunb 0:8918a71cdbe9 949 /**
Sergunb 0:8918a71cdbe9 950 * @brief Format Report-PDU
Sergunb 0:8918a71cdbe9 951 * @param[in] context Pointer to the SNMP agent context
Sergunb 0:8918a71cdbe9 952 * @param[in] errorIndication Error indication
Sergunb 0:8918a71cdbe9 953 * @return Error code
Sergunb 0:8918a71cdbe9 954 **/
Sergunb 0:8918a71cdbe9 955
Sergunb 0:8918a71cdbe9 956 error_t snmpFormatReportPdu(SnmpAgentContext *context, error_t errorIndication)
Sergunb 0:8918a71cdbe9 957 {
Sergunb 0:8918a71cdbe9 958 error_t error;
Sergunb 0:8918a71cdbe9 959
Sergunb 0:8918a71cdbe9 960 #if (SNMP_V3_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 961 size_t n;
Sergunb 0:8918a71cdbe9 962 SnmpVarBind var;
Sergunb 0:8918a71cdbe9 963
Sergunb 0:8918a71cdbe9 964 //Initialize SNMP message
Sergunb 0:8918a71cdbe9 965 snmpInitMessage(&context->response);
Sergunb 0:8918a71cdbe9 966
Sergunb 0:8918a71cdbe9 967 //SNMP version identifier
Sergunb 0:8918a71cdbe9 968 context->response.version = context->request.version;
Sergunb 0:8918a71cdbe9 969
Sergunb 0:8918a71cdbe9 970 //Message identifier
Sergunb 0:8918a71cdbe9 971 context->response.msgId = context->request.msgId;
Sergunb 0:8918a71cdbe9 972 //Maximum message size supported by the sender
Sergunb 0:8918a71cdbe9 973 context->response.msgMaxSize = SNMP_MAX_MSG_SIZE;
Sergunb 0:8918a71cdbe9 974 //Bit fields which control processing of the message
Sergunb 0:8918a71cdbe9 975 context->response.msgFlags = 0;
Sergunb 0:8918a71cdbe9 976 //Security model used by the sender
Sergunb 0:8918a71cdbe9 977 context->response.msgSecurityModel = SNMP_SECURITY_MODEL_USM;
Sergunb 0:8918a71cdbe9 978
Sergunb 0:8918a71cdbe9 979 //Authoritative engine identifier
Sergunb 0:8918a71cdbe9 980 context->response.msgAuthEngineId = context->contextEngine;
Sergunb 0:8918a71cdbe9 981 context->response.msgAuthEngineIdLen = context->contextEngineLen;
Sergunb 0:8918a71cdbe9 982 //Number of times the SNMP engine has rebooted
Sergunb 0:8918a71cdbe9 983 context->response.msgAuthEngineBoots = context->engineBoots;
Sergunb 0:8918a71cdbe9 984 //Number of seconds since last reboot
Sergunb 0:8918a71cdbe9 985 context->response.msgAuthEngineTime = context->engineTime;
Sergunb 0:8918a71cdbe9 986
Sergunb 0:8918a71cdbe9 987 //Context engine identifier
Sergunb 0:8918a71cdbe9 988 context->response.contextEngineId = context->contextEngine;
Sergunb 0:8918a71cdbe9 989 context->response.contextEngineIdLen = context->contextEngineLen;
Sergunb 0:8918a71cdbe9 990 //Context name
Sergunb 0:8918a71cdbe9 991 context->response.contextName = (uint8_t *) context->contextName;
Sergunb 0:8918a71cdbe9 992 context->response.contextNameLen = strlen(context->contextName);
Sergunb 0:8918a71cdbe9 993
Sergunb 0:8918a71cdbe9 994 //PDU type
Sergunb 0:8918a71cdbe9 995 context->response.pduType = SNMP_PDU_REPORT;
Sergunb 0:8918a71cdbe9 996 //Request identifier
Sergunb 0:8918a71cdbe9 997 context->response.requestId = context->request.requestId;
Sergunb 0:8918a71cdbe9 998
Sergunb 0:8918a71cdbe9 999 //Make room for the message header at the beginning of the buffer
Sergunb 0:8918a71cdbe9 1000 error = snmpComputeMessageOverhead(&context->response);
Sergunb 0:8918a71cdbe9 1001 //Any error to report?
Sergunb 0:8918a71cdbe9 1002 if(error)
Sergunb 0:8918a71cdbe9 1003 return error;
Sergunb 0:8918a71cdbe9 1004
Sergunb 0:8918a71cdbe9 1005 //Encode the object value using ASN.1 rules
Sergunb 0:8918a71cdbe9 1006 error = snmpEncodeUnsignedInt32(1, context->response.buffer, &n);
Sergunb 0:8918a71cdbe9 1007 //Any error to report?
Sergunb 0:8918a71cdbe9 1008 if(error)
Sergunb 0:8918a71cdbe9 1009 return error;
Sergunb 0:8918a71cdbe9 1010
Sergunb 0:8918a71cdbe9 1011 //Check error indication
Sergunb 0:8918a71cdbe9 1012 switch(errorIndication)
Sergunb 0:8918a71cdbe9 1013 {
Sergunb 0:8918a71cdbe9 1014 case ERROR_UNSUPPORTED_SECURITY_LEVEL:
Sergunb 0:8918a71cdbe9 1015 //Add the usmStatsUnsupportedSecLevels counter in the varBindList
Sergunb 0:8918a71cdbe9 1016 var.oid = usmStatsUnsupportedSecLevelsObject;
Sergunb 0:8918a71cdbe9 1017 var.oidLen = sizeof(usmStatsUnsupportedSecLevelsObject);
Sergunb 0:8918a71cdbe9 1018 break;
Sergunb 0:8918a71cdbe9 1019 case ERROR_NOT_IN_TIME_WINDOW:
Sergunb 0:8918a71cdbe9 1020 //Add the usmStatsNotInTimeWindows counter in the varBindList
Sergunb 0:8918a71cdbe9 1021 var.oid = usmStatsNotInTimeWindowsObject;
Sergunb 0:8918a71cdbe9 1022 var.oidLen = sizeof(usmStatsNotInTimeWindowsObject);
Sergunb 0:8918a71cdbe9 1023 break;
Sergunb 0:8918a71cdbe9 1024 case ERROR_UNKNOWN_USER_NAME:
Sergunb 0:8918a71cdbe9 1025 //Add the usmStatsUnknownUserNames counter in the varBindList
Sergunb 0:8918a71cdbe9 1026 var.oid = usmStatsUnknownUserNamesObject;
Sergunb 0:8918a71cdbe9 1027 var.oidLen = sizeof(usmStatsUnknownUserNamesObject);
Sergunb 0:8918a71cdbe9 1028 break;
Sergunb 0:8918a71cdbe9 1029 case ERROR_UNKNOWN_ENGINE_ID:
Sergunb 0:8918a71cdbe9 1030 //Add the usmStatsUnknownEngineIDs counter in the varBindList
Sergunb 0:8918a71cdbe9 1031 var.oid = usmStatsUnknownEngineIdsObject;
Sergunb 0:8918a71cdbe9 1032 var.oidLen = sizeof(usmStatsUnknownEngineIdsObject);
Sergunb 0:8918a71cdbe9 1033 break;
Sergunb 0:8918a71cdbe9 1034 case ERROR_AUTHENTICATION_FAILED:
Sergunb 0:8918a71cdbe9 1035 //Add the usmStatsWrongDigests counter in the varBindList
Sergunb 0:8918a71cdbe9 1036 var.oid = usmStatsWrongDigestsObject;
Sergunb 0:8918a71cdbe9 1037 var.oidLen = sizeof(usmStatsWrongDigestsObject);
Sergunb 0:8918a71cdbe9 1038 break;
Sergunb 0:8918a71cdbe9 1039 case ERROR_DECRYPTION_FAILED:
Sergunb 0:8918a71cdbe9 1040 //Add the usmStatsDecryptionErrors counter in the varBindList
Sergunb 0:8918a71cdbe9 1041 var.oid = usmStatsDecryptionErrorsObject;
Sergunb 0:8918a71cdbe9 1042 var.oidLen = sizeof(usmStatsDecryptionErrorsObject);
Sergunb 0:8918a71cdbe9 1043 break;
Sergunb 0:8918a71cdbe9 1044 default:
Sergunb 0:8918a71cdbe9 1045 //Just for sanity's sake...
Sergunb 0:8918a71cdbe9 1046 var.oid = NULL;
Sergunb 0:8918a71cdbe9 1047 var.oidLen = 0;
Sergunb 0:8918a71cdbe9 1048 break;
Sergunb 0:8918a71cdbe9 1049 }
Sergunb 0:8918a71cdbe9 1050
Sergunb 0:8918a71cdbe9 1051 //The counter is encoded in ASN.1 format
Sergunb 0:8918a71cdbe9 1052 var.objClass = ASN1_CLASS_APPLICATION;
Sergunb 0:8918a71cdbe9 1053 var.objType = MIB_TYPE_COUNTER32;
Sergunb 0:8918a71cdbe9 1054 var.value = context->response.buffer;
Sergunb 0:8918a71cdbe9 1055 var.valueLen = n;
Sergunb 0:8918a71cdbe9 1056
Sergunb 0:8918a71cdbe9 1057 //Append the variable binding list to the varBindList
Sergunb 0:8918a71cdbe9 1058 error = snmpWriteVarBinding(context, &var);
Sergunb 0:8918a71cdbe9 1059 //Any error to report?
Sergunb 0:8918a71cdbe9 1060 if(error)
Sergunb 0:8918a71cdbe9 1061 return error;
Sergunb 0:8918a71cdbe9 1062
Sergunb 0:8918a71cdbe9 1063 //Format PDU header
Sergunb 0:8918a71cdbe9 1064 error = snmpWritePduHeader(&context->response);
Sergunb 0:8918a71cdbe9 1065 #else
Sergunb 0:8918a71cdbe9 1066 //SNMPv3 is not supported
Sergunb 0:8918a71cdbe9 1067 error = ERROR_NOT_IMPLEMENTED;
Sergunb 0:8918a71cdbe9 1068 #endif
Sergunb 0:8918a71cdbe9 1069
Sergunb 0:8918a71cdbe9 1070 //Return status code
Sergunb 0:8918a71cdbe9 1071 return error;
Sergunb 0:8918a71cdbe9 1072 }
Sergunb 0:8918a71cdbe9 1073
Sergunb 0:8918a71cdbe9 1074 #endif
Sergunb 0:8918a71cdbe9 1075