/// <summary>Send SNMP version 2 Trap notification</summary> /// <param name="packet">SNMP v2 Trap packet class</param> /// <param name="peer">Manager (receiver) IP address</param> /// <param name="port">Manager (receiver) UDP port number</param> public void SendV2Trap(SnmpV2Packet packet, IpAddress peer, int port) { if (packet.Pdu.Type != EPduType.V2Trap) { throw new SnmpInvalidPduTypeException("Invalid Pdu type."); } byte[] outBuffer = packet.Encode(); socket.SendTo(outBuffer, new IPEndPoint((IPAddress)peer, port)); }
/// <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); }