/// <summary>Validate received reply</summary> /// <param name="packet">Received SNMP packet</param> /// <returns>True if packet is validated, otherwise false</returns> public bool ValidateReceivedPacket(SnmpPacket packet) { if (packet.Version != version) { return(false); } if (version == ESnmpVersion.Ver1) { SnmpV1Packet pkt = packet as SnmpV1Packet; if (pkt.Community.Equals(community)) { return(true); } } if (version == ESnmpVersion.Ver2) { SnmpV2Packet pkt = packet as SnmpV2Packet; if (pkt.Community.Equals(community)) { return(true); } } return(false); }
/// <summary> /// Initialize SNMP packet class with agent parameters. In this class, SNMP community name is /// set in SNMPv1 and SNMPv2 packets. /// </summary> /// <param name="packet">Packet class to initialize</param> public void InitializePacket(SnmpPacket packet) { if (packet is SnmpV1Packet) { SnmpV1Packet pkt = (SnmpV1Packet)packet; pkt.Community.Set(_community); } else if (packet is SnmpV2Packet) { SnmpV2Packet pkt = (SnmpV2Packet)packet; pkt.Community.Set(_community); } else { throw new SnmpInvalidVersionException("Invalid SNMP version."); } }
/// <summary> /// Prepare packet for transmission by filling target specific information in the packet. /// </summary> /// <param name="packet">SNMP packet class for the required version</param> /// <returns>True if packet values are correctly set, otherwise false.</returns> public bool PreparePacketForTransmission(SnmpPacket packet) { if (packet.Version != _version) { return(false); } if (_version == SnmpVersion.Ver1) { SnmpV1Packet pkt = (SnmpV1Packet)packet; pkt.Community.Set(_community); return(true); } else if (_version == SnmpVersion.Ver2) { SnmpV2Packet pkt = (SnmpV2Packet)packet; pkt.Community.Set(_community); return(true); } return(false); }
/// <summary>Prepare packet for transmission by filling target specific information in the packet.</summary> /// <param name="packet">SNMP packet class for the required version</param> /// <returns>True if packet values are correctly set, otherwise false.</returns> public bool PreparePacketForTransmission(SnmpPacket packet) { if (packet.Version != version) { return(false); } if (version == ESnmpVersion.Ver1) { SnmpV1Packet pkt = packet as SnmpV1Packet; pkt.Community.Set(community); return(true); } if (version == ESnmpVersion.Ver2) { SnmpV2Packet pkt = packet as SnmpV2Packet; pkt.Community.Set(community); return(true); } return(false); }
/// <summary> /// Validate received reply /// </summary> /// <param name="packet">Received SNMP packet</param> /// <returns>True if packet is validated, otherwise false</returns> public bool ValidateReceivedPacket(SnmpPacket packet) { if (packet.Version != _version) { return(false); } if (_version == SnmpVersion.Ver1) { SnmpV1Packet pkt = (SnmpV1Packet)packet; if (pkt.Community.Equals(_community)) { return(true); } } else if (_version == SnmpVersion.Ver2) { SnmpV2Packet pkt = (SnmpV2Packet)packet; if (pkt.Community.Equals(_community)) { return(true); } } return(false); }
/// <summary> /// Thread Functions which does all the SNMP Agent job /// </summary> public void ListenerThread() { mSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); mSock.ReceiveTimeout = 2000; IPEndPoint vEndPoint = new IPEndPoint(IPAddress.Any, 16100); mSock.Bind(vEndPoint); Debug.Log ("Agent: thread started"); byte[] vBuff = new byte[4096]; int vLen = 0; while (true) { if (this.mSock.Available > 0) { EndPoint vSender = (EndPoint)new IPEndPoint(IPAddress.Any, 0); vLen = mSock.ReceiveFrom(vBuff, ref vSender); //Debug.Log ("Agent: Data received (bytes): " + vLen); SnmpPacket vPacket = new SnmpV1Packet("" + "public"); vPacket.decode(vBuff, vLen); //Debug.Log("Agent: PDU decoded: " + vPacket.Pdu.VbCount); Oid vOid = null; responsePacket = new SnmpV1Packet("" + "public"); responsePacket.Pdu.ErrorStatus = 0; // no error if (vPacket.Pdu != null && vPacket.Pdu.VbList != null) { foreach (Vb vVb in vPacket.Pdu.VbList) { Debug.Log(vVb.ToString()); vOid = vVb.Oid; if (vPacket.Pdu.Type == PduType.Set) ProcessSetRequest(vOid,vVb); if (vPacket.Pdu.Type == PduType.GetNext){ GetNext(vOid); break; } ProcessGetRequest(vOid); } } //Debug.Log(vOid.ToString()); responsePacket.Pdu.Type = PduType.Response; responsePacket.Pdu.RequestId = vPacket.Pdu.RequestId; byte[] vOutBuff = responsePacket.encode(); mSock.SendTo(vOutBuff, vSender); callPrint = true; } Thread.Sleep(1000); } }
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 _response(AsyncRequestResult.NoError, packet); } } } }
/// <summary> /// 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. /// </summary> /// <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> /// <param name="responseCallback">Callback that receives the result of the async operation.</param> /// <returns>True if async request was successfully initiated, otherwise false.</returns> public bool RequestAsync(Pdu pdu, IAgentParameters agentParameters, SnmpAsyncResponse responseCallback) { if (IsBusy) { return(false); // class is busy } _response = null; _response += responseCallback; _agentParameters = agentParameters; byte[] outPacket; if (agentParameters.Version == SnmpVersion.Ver3) { SecureAgentParameters secparams = (SecureAgentParameters)agentParameters; if (secparams.Authentication != AuthenticationDigests.None && secparams.AuthenticationSecret.Length <= 0) { // _response(AsyncRequestResult.AuthenticationError, null); return(false); } if (secparams.Privacy != PrivacyProtocols.None && secparams.PrivacySecret.Length <= 0) { // _response(AsyncRequestResult.PrivacyError, null); return(false); } _noSourceCheck = false; // this option is not valid for SNMP v3 requests ScopedPdu outPdu = new ScopedPdu(pdu); outPdu.ContextEngineId.Set(secparams.EngineId); outPdu.ContextName.Set(secparams.ContextName); SnmpV3Packet packet = new SnmpV3Packet(outPdu); secparams.InitializePacket(packet); try { if (secparams.HasCachedKeys) { outPacket = packet.encode(secparams.AuthenticationKey, secparams.PrivacyKey); } else { outPacket = packet.encode(); } } catch (Exception ex) { ex.GetType(); _response(AsyncRequestResult.EncodeError, packet); return(false); } } else if (agentParameters.Version == (int)SnmpVersion.Ver1) { AgentParameters param = (AgentParameters)agentParameters; _noSourceCheck = param.DisableReplySourceCheck; SnmpV1Packet packet = new SnmpV1Packet(); packet.Pdu.Set(pdu); packet.Community.Set(param.Community); try { outPacket = packet.encode(); } catch (Exception ex) { ex.GetType(); _response(AsyncRequestResult.EncodeError, packet); return(false); } } else if (agentParameters.Version == SnmpVersion.Ver2) { AgentParameters param = (AgentParameters)agentParameters; _noSourceCheck = param.DisableReplySourceCheck; SnmpV2Packet packet = new SnmpV2Packet(); packet.Pdu.Set(pdu); packet.Community.Set(param.Community); try { outPacket = packet.encode(); } catch (Exception ex) { ex.GetType(); _response(AsyncRequestResult.EncodeError, packet); return(false); } } else { throw new SnmpInvalidVersionException("Unsupported SNMP version."); } if (!base.RequestAsync(_address, _port, outPacket, outPacket.Length, _timeout, _retry, new SnmpAsyncCallback(AsyncResponse))) { return(false); } return(true); }
/// <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); }
private static bool WalkGetNext(IPAddress agent, string community, string oid, Func <Vb, bool> handleValue) { // SNMP community name OctetString communityString = new OctetString(community); // Define agent parameters class AgentParameters param = new AgentParameters(communityString) { // Set SNMP version to 1 Version = SnmpVersion.Ver1 }; // Construct target UdpTarget target = new UdpTarget(agent, 161, 2000, 1); // Define Oid that is the root of the MIB // tree you wish to retrieve Oid rootOid = new Oid(oid); // ifDescr // This Oid represents last Oid returned by // the SNMP agent Oid lastOid = (Oid)rootOid.Clone(); // Pdu class used for all requests Pdu pdu = new Pdu(PduType.GetNext); // Loop through results while (lastOid != null) { // When Pdu class is first constructed, RequestId is set to a random value // that needs to be incremented on subsequent requests made using the // same instance of the Pdu class. if (pdu.RequestId != 0) { pdu.RequestId += 1; } // Clear Oids from the Pdu class. pdu.VbList.Clear(); // Initialize request PDU with the last retrieved Oid pdu.VbList.Add(lastOid); // Make SNMP request SnmpV1Packet result = (SnmpV1Packet)target.Request(pdu, param); // You should catch exceptions in the Request if using in real application. // If result is null then agent didn't reply or we couldn't parse the reply. if (result != null) { // ErrorStatus other then 0 is an error returned by // the Agent - see SnmpConstants for error definitions if (result.Pdu.ErrorStatus != 0) { // agent reported an error with the request //System.Diagnostics.Debug.WriteLine("Error in SNMP reply. Error {0} index {1}", // result.Pdu.ErrorStatus, // result.Pdu.ErrorIndex); lastOid = null; break; } else { // Walk through returned variable bindings foreach (Vb v in result.Pdu.VbList) { // Check that retrieved Oid is "child" of the root OID if (rootOid.IsRootOf(v.Oid)) { //System.Diagnostics.Debug.WriteLine("{0} ({1}): {2}", // v.Oid.ToString(), // SnmpConstants.GetTypeName(v.Value.Type), // v.Value.ToString()); handleValue(v); lastOid = v.Oid; } else { // we have reached the end of the requested // MIB tree. Set lastOid to null and exit loop lastOid = null; } } } } else { //System.Diagnostics.Debug.WriteLine("No response received from SNMP agent."); } } target.Close(); return(true); }
/// <summary> /// Prints the packets /// </summary> /// <param name="result"></param> public void PrintPacketRecv(SnmpV1Packet result) { // ErrorStatus other then 0 is an error returned by // the Agent - see SnmpConstants for error definitions if (result.Pdu.Type == PduType.Set) { PacketPrinterRcv.text = "Set "; } if (result.Pdu.Type == PduType.Get) { PacketPrinterRcv.text = "Get "; } if (result.Pdu.ErrorStatus != 0) { // agent reported an error with the request PacketPrinterRcv.text = "Error: status " + result.Pdu.ErrorStatus + " Index " + result.Pdu.ErrorIndex; } else { // Reply variables are returned in the same order as they were added // to the VbList foreach (Vb VarBind in result.Pdu.VbList) { PacketPrinterRcv.text = "Request OID: " + VarBind.Oid.ToString() + " Type " + SnmpConstants.GetTypeName(VarBind.Value.Type) + " Value " + VarBind.Value.ToString(); } } }
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 _response(AsyncRequestResult.NoError, packet); } } } }
/// <summary> /// 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. /// </summary> /// <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> /// <param name="responseCallback">Callback that receives the result of the async operation.</param> /// <returns>True if async request was successfully initiated, otherwise false.</returns> public bool RequestAsync(Pdu pdu, IAgentParameters agentParameters, SnmpAsyncResponse responseCallback) { if (IsBusy) { return false; // class is busy } _response = null; _response += responseCallback; _agentParameters = agentParameters; byte[] outPacket; if (agentParameters.Version == SnmpVersion.Ver3) { SecureAgentParameters secparams = (SecureAgentParameters)agentParameters; if (secparams.Authentication != AuthenticationDigests.None && secparams.AuthenticationSecret.Length <= 0) { // _response(AsyncRequestResult.AuthenticationError, null); return false; } if (secparams.Privacy != PrivacyProtocols.None && secparams.PrivacySecret.Length <= 0) { // _response(AsyncRequestResult.PrivacyError, null); return false; } _noSourceCheck = false; // this option is not valid for SNMP v3 requests ScopedPdu outPdu = new ScopedPdu(pdu); outPdu.ContextEngineId.Set(secparams.EngineId); outPdu.ContextName.Set(secparams.ContextName); SnmpV3Packet packet = new SnmpV3Packet(outPdu); secparams.InitializePacket(packet); try { if (secparams.HasCachedKeys) outPacket = packet.encode(secparams.AuthenticationKey, secparams.PrivacyKey); else outPacket = packet.encode(); } catch( Exception ex ) { ex.GetType(); _response(AsyncRequestResult.EncodeError, packet); return false; } } else if (agentParameters.Version == (int)SnmpVersion.Ver1) { AgentParameters param = (AgentParameters)agentParameters; _noSourceCheck = param.DisableReplySourceCheck; SnmpV1Packet packet = new SnmpV1Packet(); packet.Pdu.Set(pdu); packet.Community.Set(param.Community); try { outPacket = packet.encode(); } catch( Exception ex) { ex.GetType(); _response(AsyncRequestResult.EncodeError, packet); return false; } } else if (agentParameters.Version == SnmpVersion.Ver2) { AgentParameters param = (AgentParameters)agentParameters; _noSourceCheck = param.DisableReplySourceCheck; SnmpV2Packet packet = new SnmpV2Packet(); packet.Pdu.Set(pdu); packet.Community.Set(param.Community); try { outPacket = packet.encode(); } catch( Exception ex ) { ex.GetType(); _response(AsyncRequestResult.EncodeError, packet); return false; } } else { throw new SnmpInvalidVersionException("Unsupported SNMP version."); } if( ! base.RequestAsync(_address, _port, outPacket, outPacket.Length, _timeout, _retry, new SnmpAsyncCallback(AsyncResponse) ) ) { return false; } return true; }
/// <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) { return null; } // 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; }