internal void AsyncResponse(AsyncRequestResult result, IPEndPoint peer, byte[] buffer, int buflen) { if (result != AsyncRequestResult.NoError) { _response(result, null); } else { if (buffer == null || buffer.Length <= 0 || buflen <= 0) { _response(AsyncRequestResult.NoDataReceived, null); return; } // verify packet if (_agentParameters.Version == (int)SnmpVersion.Ver1) { SnmpV1Packet packet = new SnmpV1Packet(); try { packet.Decode(buffer, buflen); } catch (Exception ex) { ex.GetType(); // Console.WriteLine("Exception while decoding SNMP packet: " + ex.ToString()); _response(AsyncRequestResult.DecodeError, packet); return; } _response(AsyncRequestResult.NoError, packet); return; } else if (_agentParameters.Version == SnmpVersion.Ver2) { SnmpV2Packet packet = new SnmpV2Packet(); try { packet.Decode(buffer, buflen); } catch (Exception ex) { ex.GetType(); // Console.WriteLine("Exception while decoding SNMP packet: " + ex.ToString()); // MutableByte b = new MutableByte(buffer, buflen); // Console.WriteLine("Buffer length {0}", buflen); // SnmpConstants.DumpHex(b); _response(AsyncRequestResult.DecodeError, packet); return; } _response(AsyncRequestResult.NoError, packet); } else if (_agentParameters.Version == SnmpVersion.Ver3) { SnmpV3Packet packet = new SnmpV3Packet(); SecureAgentParameters secparams = (SecureAgentParameters)_agentParameters; secparams.InitializePacket(packet); try { if (secparams.HasCachedKeys) { packet.Decode(buffer, buflen, secparams.AuthenticationKey, secparams.PrivacyKey); } else { packet.Decode(buffer, buflen); } } catch { _response(AsyncRequestResult.DecodeError, packet); return; } if (!secparams.ValidateIncomingPacket(packet)) { _response(AsyncRequestResult.AuthenticationError, packet); } else { secparams.UpdateDiscoveryValues(packet); // update time, etc. values if (packet.USM.EngineId.Length > 0 && packet.USM.EngineBoots == 0 && packet.USM.EngineTime == 0) { Pdu p = new Pdu(); RequestAsync(p, _agentParameters, _response); } else { _response(AsyncRequestResult.NoError, packet); } } } } }
/// <summary>Make SNMP Request</summary> /// <remarks> /// Make SNMP request. With this method you can make blocked SNMP version 1, 2 and 3 requests of type GET, /// GET-NEXT, GET-BULK, SET and REPORT (request types have to compatible with the SNMP protocol version you /// are using). /// /// This method will pass through any exceptions thrown by parsing classes/methods so see individual packet /// classes, ASN.1 type classes, authentication, privacy, etc. classes for exceptions thrown. /// </remarks> /// <param name="pdu">Pdu class (do not pass ScopedPdu)</param> /// <param name="agentParameters">Security information for the request. Use <see cref="AgentParameters"/> /// for SNMP versions 1 and 2 requests. Use <see cref="SecureAgentParameters"/> for SNMP version 3 /// requests.</param> /// <returns>Appropriate SNMP packet class for the reply received (<see cref="SnmpV1Packet"/>, /// <see cref="SnmpV2Packet"/>, or <see cref="SnmpV3Packet"/>. Null value if there was an error /// with the request.</returns> /// <exception cref="SnmpAuthenticationException">Thrown on SNMPv3 requests when authentication password /// is not specified on authNoPriv or authPriv requests in SecureAgentParameters or if incoming packet /// authentication check failed. /// /// With SNMP ver1 and ver2c, authentication check fails when invalid community name is parsed in the reply.</exception> /// <exception cref="SnmpPrivacyException">Thrown on SNMPv3 requests when privacy password is not /// specified in SecureAgentParameters on authPriv requests.</exception> /// <exception cref="SnmpException">Thrown in following cases: /// /// * IAgentParameters.Valid() returned false. SnmpException.ErrorCode is set to SnmpException.InvalidIAgentParameters /// * No data received on request. SnmpException.ErrorCode is set to SnmpException.NoDataReceived /// * Invalid RequestId in reply. SnmpException.ErrorCode is set to SnmpException.InvalidRequestId /// </exception> public SnmpPacket Request(Pdu pdu, IAgentParameters agentParameters) { byte[] outPacket; if (agentParameters.Version == SnmpVersion.Ver3) { SecureAgentParameters secparams = (SecureAgentParameters)agentParameters; if (secparams.Authentication != AuthenticationDigests.None && secparams.AuthenticationSecret.Length <= 0) { throw new SnmpAuthenticationException("Authentication password not specified."); } if (secparams.Privacy != PrivacyProtocols.None && secparams.PrivacySecret.Length <= 0) { throw new SnmpPrivacyException("Privacy password not specified."); } _noSourceCheck = false; // this option is not valid for SNMP v3 requests ScopedPdu outPdu = new ScopedPdu(pdu); SnmpV3Packet packet = new SnmpV3Packet(outPdu); secparams.InitializePacket(packet); if (secparams.HasCachedKeys) { outPacket = packet.Encode(secparams.AuthenticationKey, secparams.PrivacyKey); } else { outPacket = packet.Encode(); } } else if (agentParameters.Version == SnmpVersion.Ver1) { AgentParameters param = (AgentParameters)agentParameters; if (!param.Valid()) { throw new SnmpException(SnmpException.InvalidIAgentParameters, "Invalid AgentParameters. Unable to process request."); } SnmpV1Packet packet = new SnmpV1Packet(); packet.Pdu.Set(pdu); packet.Community.Set(param.Community); outPacket = packet.Encode(); _noSourceCheck = param.DisableReplySourceCheck; } else if (agentParameters.Version == SnmpVersion.Ver2) { AgentParameters param = (AgentParameters)agentParameters; if (!param.Valid()) { throw new SnmpException(SnmpException.InvalidIAgentParameters, "Invalid AgentParameters. Unable to process request."); } SnmpV2Packet packet = new SnmpV2Packet(); packet.Pdu.Set(pdu); packet.Community.Set(param.Community); _noSourceCheck = param.DisableReplySourceCheck; outPacket = packet.Encode(); } else { throw new SnmpInvalidVersionException("Unsupported SNMP version."); } byte[] inBuffer = base.Request(_address, _port, outPacket, outPacket.Length, _timeout, _retry); if (inBuffer == null || inBuffer.Length <= 0) { throw new SnmpException(SnmpException.NoDataReceived, "No data received on request."); } // verify packet if (agentParameters.Version == SnmpVersion.Ver1) { SnmpV1Packet packet = new SnmpV1Packet(); AgentParameters param = (AgentParameters)agentParameters; packet.Decode(inBuffer, inBuffer.Length); if (packet.Community != param.Community) { // invalid community name received. Ignore the rest of the packet throw new SnmpAuthenticationException("Invalid community name in reply."); } if (packet.Pdu.RequestId != pdu.RequestId) { // invalid request id. unmatched response ignored throw new SnmpException(SnmpException.InvalidRequestId, "Invalid request id in reply."); } return(packet); } else if (agentParameters.Version == SnmpVersion.Ver2) { SnmpV2Packet packet = new SnmpV2Packet(); AgentParameters param = (AgentParameters)agentParameters; packet.Decode(inBuffer, inBuffer.Length); if (packet.Community != param.Community) { // invalid community name received. Ignore the rest of the packet throw new SnmpAuthenticationException("Invalid community name in reply."); } if (packet.Pdu.RequestId != pdu.RequestId) { // invalid request id. unmatched response ignored throw new SnmpException(SnmpException.InvalidRequestId, "Invalid request id in reply."); } return(packet); } else if (agentParameters.Version == SnmpVersion.Ver3) { SnmpV3Packet packet = new SnmpV3Packet(); SecureAgentParameters secparams = (SecureAgentParameters)agentParameters; secparams.InitializePacket(packet); if (secparams.HasCachedKeys) { packet.Decode(inBuffer, inBuffer.Length, secparams.AuthenticationKey, secparams.PrivacyKey); } else { packet.Decode(inBuffer, inBuffer.Length); } // first check if packet is a discovery response and process it if (packet.Pdu.Type == PduType.Report && packet.Pdu.VbCount > 0 && packet.Pdu.VbList[0].Oid.Equals(SnmpConstants.usmStatsUnknownEngineIDs)) { secparams.UpdateDiscoveryValues(packet); return(packet); } else { if (!secparams.ValidateIncomingPacket(packet)) { return(null); } else { secparams.UpdateDiscoveryValues(packet); // update time, etc. values return(packet); } } } return(null); }