error_t snmpProcessPdu(SnmpAgentContext *context) { error_t error; //Parse PDU header error = snmpParsePduHeader(&context->request); //Any error to report? if(error) return error; //Check PDU type switch(context->request.pduType) { case SNMP_PDU_GET_REQUEST: case SNMP_PDU_GET_NEXT_REQUEST: //Process GetRequest-PDU or GetNextRequest-PDU error = snmpProcessGetRequestPdu(context); break; case SNMP_PDU_GET_BULK_REQUEST: //Process GetBulkRequest-PDU error = snmpProcessGetBulkRequestPdu(context); break; case SNMP_PDU_SET_REQUEST: //Process SetRequest-PDU error = snmpProcessSetRequestPdu(context); break; default: //Invalid PDU type error = ERROR_INVALID_TYPE; break; } //Check status code if(!error) { //Total number of SNMP Get-Response PDUs which have been generated //by the SNMP protocol entity MIB2_INC_COUNTER32(mib2Base.snmpGroup.snmpOutGetResponses, 1); //Format PDU header error = snmpWritePduHeader(&context->response); } //Return status code return error; }
error_t snmpParseGetRequestPdu(SnmpAgentContext *context, const uint8_t *p, size_t length) { error_t error; size_t n; uint_t index; SnmpVarBind var; //Debug message if(context->request.pduType == SNMP_PDU_GET_REQUEST) { TRACE_INFO("Parsing GetRequest-PDU...\r\n"); } else if(context->request.pduType == SNMP_PDU_GET_NEXT_REQUEST) { TRACE_INFO("Parsing GetNextRequest-PDU...\r\n"); } //Verify community name error = snmpCheckCommunity(context, MIB_ACCESS_READ_ONLY); //Wrong community name? if(error) return error; //Parse PDU header error = snmpParsePduHeader(context, p, length); //Failed to parse PDU header? if(error) return error; //Point to the first variable binding of the request p = context->request.varBindList; length = context->request.varBindListLen; //Lock access to MIB bases snmpLockMib(context); //Loop through the list for(index = 1; length > 0; index++) { //Parse variable binding error = snmpParseVarBinding(p, length, &var, &n); //Failed to parse variable binding? if(error) break; //GetRequest-PDU? if(context->request.pduType == SNMP_PDU_GET_REQUEST) { //Retrieve object value error = snmpGetObjectValue(context, &var); } //GetNextRequest-PDU? else { //Search the MIB for the next object error = snmpGetNextObject(context, &var); //SNMPv1 version? if(context->version == SNMP_VERSION_1) { //Check status code if(error == NO_ERROR) { //Retrieve object value error = snmpGetObjectValue(context, &var); } else { //Stop immediately break; } } //SNMPv2c version? else { //Check status code if(error == NO_ERROR) { //Retrieve object value error = snmpGetObjectValue(context, &var); } else if(error == ERROR_OBJECT_NOT_FOUND) { //The variable binding's value field is set to endOfMibView var.class = ASN1_CLASS_CONTEXT_SPECIFIC; var.type = SNMP_EXCEPTION_END_OF_MIB_VIEW; var.valueLen = 0; //Catch exception error = NO_ERROR; } else { //Stop immediately break; } } }