/// <summary> /// Perform SNMP version 3 discovery operation. This is the first operation that needs to be /// performed on a newly accessed agent to retrieve agentId, agentBoots and agentTime values, critical /// for further authentication and privacy operations. /// </summary> /// <param name="param"><see cref="SecureAgentParameters"/> class instance that will be updated /// with discovered agent values. This class with be reset to its defaults prior to agent /// discovered values so do not store any critical information in it prior to calling the /// discovery method</param> /// <returns>True if discovery operation was a success, otherwise false</returns> public bool Discovery(SecureAgentParameters param) { param.Reset(); param.SecurityName.Set(""); param.Reportable = true; Pdu pdu = new Pdu(); // just leave everything at default. SnmpV3Packet inpkt = (SnmpV3Packet)Request(pdu, param); if (inpkt != null) { if (inpkt.USM.EngineBoots == 0 && inpkt.USM.EngineTime == 0) { inpkt = (SnmpV3Packet)Request(pdu, param); if (inpkt != null) { return(true); } } else { return(true); } } return(false); }
/// <summary> /// Validate that incoming packet has arrived from the correct engine id and is using a correct /// combination of privacy and authentication values. /// </summary> /// <param name="packet">Received and parsed SNMP version 3 packet.</param> /// <returns>True if packet is valid, otherwise false.</returns> /// <exception cref="SnmpException">Thrown on following errors with ErrorCode: /// * ErrorCode = 0: SecureAgentParameters was updated after request was made but before reply was received (this is not allowed) /// * SnmpException.InvalidAuthoritativeEngineId: engine id in the reply does not match request /// * SnmpException.InvalidSecurityName: security name mismatch between request and reply packets /// * SnmpException.ReportOnNoReports: report packet received when we had reportable set to false in the request /// * SnmpException.UnsupportedNoAuthPriv: noAuthPriv is not supported /// </exception> /// <exception cref="SnmpPrivacyException">Thrown when configured privacy passwords in this class and in the packet class do not match</exception> /// <exception cref="SnmpAuthenticationException">Thrown when configured authentication passwords in this class and in the packet class do not match</exception> public bool ValidateIncomingPacket(SnmpV3Packet packet) { // First check if this is a report packet. if (packet.Pdu.Type == PduType.Report) { if (!_reportable) { // we do not expect report packets so dump it throw new SnmpException(SnmpException.ReportOnNoReports, "Unexpected report packet received."); // return false; } if (packet.MsgFlags.Authentication == false && packet.MsgFlags.Privacy) { // no authentication and no privacy allowed in report packets throw new SnmpException(SnmpException.UnsupportedNoAuthPriv, "Authentication and privacy combination is not supported."); // return false; } // the rest will not be checked, there is no point } else { if (packet.USM.EngineId != _engineId) { // different engine id is not allowed throw new SnmpException(SnmpException.InvalidAuthoritativeEngineId, "EngineId mismatch."); // return false; } if (packet.USM.Authentication != _authenticationProtocol || packet.USM.Privacy != _privacyProtocol) { // we have to have the same authentication and privacy protocol - no last minute changes throw new SnmpException("Agent parameters updated after request was made."); // return false; } if (packet.USM.Authentication != AuthenticationDigests.None) { if (packet.USM.AuthenticationSecret != _authenticationSecret) { // authentication secret has to match throw new SnmpAuthenticationException("Authentication secret in the packet class does not match the IAgentParameter secret."); // return false; } } if (packet.USM.Privacy != PrivacyProtocols.None) { if (packet.USM.PrivacySecret != _privacySecret) { // privacy secret has to match throw new SnmpPrivacyException("Privacy secret in the packet class does not match the IAgentParameters secret."); // return false; } } if (packet.USM.SecurityName != _securityName) { throw new SnmpException(SnmpException.InvalidSecurityName, "Security name mismatch."); // return false; } } return(true); }
/// <summary> /// Build SNMP RESPONSE packet for the INFORM packet class. /// </summary> /// <param name="informPacket">SNMP INFORM packet</param> /// <returns>SNMP version 3 packet containing RESPONSE to the INFORM packet contained in the parameter.</returns> /// <exception cref="SnmpInvalidPduTypeException">Parameter is not an INFORM SNMP version 3 packet class</exception> /// <exception cref="SnmpInvalidVersionException">Parameter is not a SNMP version 3 packet</exception> public static SnmpV3Packet BuildInformResponse(SnmpV3Packet informPacket) { if (informPacket.Version != SnmpVersion.Ver3) throw new SnmpInvalidVersionException("INFORM packet can only be parsed from an SNMP version 3 packet."); if (informPacket.Pdu.Type != PduType.Inform) throw new SnmpInvalidPduTypeException("Inform response can only be built for INFORM packets."); SnmpV3Packet response = new SnmpV3Packet(informPacket.ScopedPdu); response.MessageId = informPacket.MessageId; response.USM.SecurityName.Set(informPacket.USM.SecurityName); response.USM.EngineTime = informPacket.USM.EngineTime; response.USM.EngineBoots = informPacket.USM.EngineBoots; response.USM.EngineId.Set(informPacket.USM.EngineId); response.USM.Authentication = informPacket.USM.Authentication; if (response.USM.Authentication != AuthenticationDigests.None) response.USM.AuthenticationSecret.Set(informPacket.USM.AuthenticationSecret); else response.USM.AuthenticationSecret.Reset(); response.USM.Privacy = informPacket.USM.Privacy; if (response.USM.Privacy != PrivacyProtocols.None) response.USM.PrivacySecret.Set(informPacket.USM.PrivacySecret); else response.USM.PrivacySecret.Reset(); response.MsgFlags.Authentication = informPacket.MsgFlags.Authentication; response.MsgFlags.Privacy = informPacket.MsgFlags.Privacy; response.MsgFlags.Reportable = informPacket.MsgFlags.Reportable; response.ScopedPdu.ContextEngineId.Set(informPacket.ScopedPdu.ContextEngineId); response.ScopedPdu.ContextName.Set(informPacket.ScopedPdu.ContextName); response.Pdu.Type = PduType.Response; response.Pdu.TrapObjectID.Set(informPacket.Pdu.TrapObjectID); response.Pdu.TrapSysUpTime.Value = informPacket.Pdu.TrapSysUpTime.Value; response.Pdu.RequestId = informPacket.Pdu.RequestId; return response; }
/// <summary> /// Build an SNMP version 3 packet suitable for use in discovery process. /// </summary> /// <returns>Discovery process prepared SNMP version 3 packet.</returns> public static SnmpV3Packet DiscoveryRequest() { SnmpV3Packet packet = new SnmpV3Packet(new ScopedPdu()); // with a blank scoped pdu // looking through other implementation, null (length 0) user name is used // packet.USM.SecurityName.Set("initial"); // set user name to initial, as described in RFCs return packet; // return packet }
/// <summary>Construct and send SNMP v3 authPriv Trap</summary> /// <param name="receiver">Trap receiver IP address</param> /// <param name="receiverPort">Trap receiver UDP port number</param> /// <param name="engineId">Sender SNMP engineId</param> /// <param name="senderEngineBoots">Sender SNMP engine boots</param> /// <param name="senderEngineTime">Sender SNMP engine time</param> /// <param name="senderUserName">Security (user) name</param> /// <param name="senderUpTime">Sender upTime</param> /// <param name="trapObjectID">Trap object ID</param> /// <param name="varList">Variable binding list</param> /// <param name="authDigest"> /// Authentication digest. See <see cref="AuthenticationDigests"/> enumeration for /// available digests /// </param> /// <param name="authSecret">Authentication secret</param> /// <param name="privProtocol"> /// Privacy protocol. See <see cref="EPrivacyProtocols"/> enumeration for /// available privacy protocols. /// </param> /// <param name="privSecret">Privacy secret</param> public void SendV3Trap( IpAddress receiver, int receiverPort, byte[] engineId, int senderEngineBoots, int senderEngineTime, string senderUserName, uint senderUpTime, Oid trapObjectID, VbCollection varList, AuthenticationDigests authDigest, byte[] authSecret, EPrivacyProtocols privProtocol, byte[] privSecret ) { SnmpV3Packet packet = new SnmpV3Packet(); packet.Pdu.Type = EPduType.V2Trap; packet.AuthPriv(Encoding.UTF8.GetBytes(senderUserName), authSecret, authDigest, privSecret, privProtocol); packet.SetEngineId(engineId); packet.SetEngineTime(senderEngineBoots, senderEngineTime); packet.ScopedPdu.TrapObjectID.Set(trapObjectID); packet.ScopedPdu.TrapSysUpTime.Value = senderUpTime; packet.ScopedPdu.VbList.Add(varList); packet.MessageFlags.Reportable = false; SendV3Trap(packet, receiver, receiverPort); }
/// <summary> /// Send SNMP version 3 Trap notification /// </summary> /// <param name="packet">SNMP v3 Trap packet class</param> /// <param name="peer">Manager (receiver) IP address</param> /// <param name="port">Manager (receiver) UDP port number</param> public void SendV3Trap(SnmpV3Packet packet, IpAddress peer, int port) { if (packet.Pdu.Type != PduType.V2Trap) { throw new SnmpInvalidPduTypeException("Invalid Pdu type."); } byte[] outBuffer = packet.encode(); _sock.SendTo(outBuffer, new IPEndPoint((IPAddress)peer, port)); }
/// <summary> /// Build SNMP discovery response packet. /// </summary> /// <remarks> /// Manager application has to be able to respond to discovery requests to be able to handle /// SNMPv3 INFORM notifications. /// /// In an INFORM packet, engineId value is set to the manager stations id (unlike all other requests /// where agent is the authoritative SNMP engine). For the agent to discover appropriate manager engine /// id, boots and time values (required for authentication and privacy packet handling), manager has to /// be able to respond to the discovery request. /// </remarks> /// <param name="messageId">Message id from the received discovery packet</param> /// <param name="requestId">Request id from the received discovery packets Pdu</param> /// <param name="engineId">Local engine id</param> /// <param name="engineBoots">Number of times local SNMP engine has been restarted</param> /// <param name="engineTime">Time since the engine was started in seconds</param> /// <param name="unknownEngineIdCount">Number of discovery packets received by the local SNMP engine</param> /// <returns>SNMP v3 packet properly formatted as a response to a discovery request</returns> public static SnmpV3Packet DiscoveryResponse(int messageId, int requestId, OctetString engineId, int engineBoots, int engineTime, int unknownEngineIdCount) { SnmpV3Packet packet = new SnmpV3Packet(); packet.Pdu.Type = PduType.Report; packet.Pdu.RequestId = requestId; packet.Pdu.VbList.Add(SnmpConstants.usmStatsUnknownEngineIDs, new Integer32(unknownEngineIdCount)); // discovery response is a report packet. We don't want to receive reports about a report packet.MsgFlags.Reportable = false; packet.SetEngineId(engineId); packet.MessageId = messageId; packet.USM.EngineBoots = engineBoots; packet.USM.EngineTime = engineTime; return packet; }
/// <summary> /// Construct and send SNMP v3 noAuthNoPriv Trap /// </summary> /// <param name="receiver">Trap receiver IP address</param> /// <param name="receiverPort">Trap receiver UDP port number</param> /// <param name="engineId">Sender SNMP engineId</param> /// <param name="senderEngineBoots">Sender SNMP engine boots</param> /// <param name="senderEngineTime">Sender SNMP engine time</param> /// <param name="senderUserName">Security (user) name</param> /// <param name="senderUpTime">Sender upTime</param> /// <param name="trapObjectID">Trap object ID</param> /// <param name="varList">Variable binding list</param> public void SendV3Trap(IpAddress receiver, int receiverPort, byte[] engineId, Int32 senderEngineBoots, Int32 senderEngineTime, string senderUserName, UInt32 senderUpTime, Oid trapObjectID, VbCollection varList) { SnmpV3Packet packet = new SnmpV3Packet(); packet.Pdu.Type = PduType.V2Trap; packet.NoAuthNoPriv(ASCIIEncoding.UTF8.GetBytes(senderUserName)); packet.SetEngineId(engineId); packet.SetEngineTime(senderEngineBoots, senderEngineTime); packet.ScopedPdu.TrapObjectID.Set(trapObjectID); packet.ScopedPdu.TrapSysUpTime.Value = senderUpTime; packet.ScopedPdu.VbList.Add(varList); packet.MsgFlags.Reportable = false; SendV3Trap(packet, receiver, receiverPort); }
/// <summary> /// Update class values with SNMP version 3 discovery values from the supplied <see cref="SnmpV3Packet"/> /// class. Values updated are EngineId, EngineTime and EngineBoots. /// </summary> /// <param name="packet"><see cref="SnmpV3Packet"/> class cast as <see cref="SnmpPacket"/></param> /// <exception cref="SnmpInvalidVersionException">Thrown when SNMP packet class other then version 3 /// is passed as parameter</exception> public void UpdateDiscoveryValues(SnmpPacket packet) { if (packet is SnmpV3Packet) { SnmpV3Packet pkt = (SnmpV3Packet)packet; _engineId.Set(pkt.USM.EngineId); _engineTime.Value = pkt.USM.EngineTime; _engineBoots.Value = pkt.USM.EngineBoots; UpdateTimeStamp(); _contextEngineId.Set(pkt.ScopedPdu.ContextEngineId); _contextName.Set(pkt.ScopedPdu.ContextName); } else { throw new SnmpInvalidVersionException("Invalid SNMP version."); } }
/// <summary> /// InitializePacket SNMP packet with values from this class. Works only on SNMP version 3 packets. /// </summary> /// <param name="packet">Instance of <see cref="SnmpV3Packet"/></param> /// <exception cref="SnmpInvalidVersionException">Thrown when parameter packet is not SnmpV3Packet</exception> public void InitializePacket(SnmpPacket packet) { if (packet is SnmpV3Packet) { SnmpV3Packet pkt = (SnmpV3Packet)packet; bool isAuth = (_authenticationProtocol == AuthenticationDigests.None) ? false : true; bool isPriv = (_privacyProtocol == PrivacyProtocols.None) ? false : true; if (isAuth && isPriv) { pkt.authPriv(_securityName, _authenticationSecret, _authenticationProtocol, _privacySecret, _privacyProtocol); } else if (isAuth && !isPriv) { pkt.authNoPriv(_securityName, _authenticationSecret, _authenticationProtocol); } else { pkt.NoAuthNoPriv(_securityName); } pkt.USM.EngineId.Set(_engineId); pkt.USM.EngineBoots = _engineBoots.Value; pkt.USM.EngineTime = GetCurrentEngineTime(); pkt.MaxMessageSize = _maxMessageSize.Value; pkt.MsgFlags.Reportable = _reportable; if (_contextEngineId.Length > 0) { pkt.ScopedPdu.ContextEngineId.Set(_contextEngineId); } else { pkt.ScopedPdu.ContextEngineId.Set(_engineId); } if (_contextName.Length > 0) { pkt.ScopedPdu.ContextName.Set(_contextName); } else { pkt.ScopedPdu.ContextName.Reset(); } } 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 is SnmpV3Packet) { SnmpV3Packet pkt = (SnmpV3Packet)packet; bool isAuth = (_authenticationProtocol == AuthenticationDigests.None) ? false : true; bool isPriv = (_privacyProtocol == PrivacyProtocols.None) ? false : true; if (isAuth && isPriv) { pkt.authPriv(_securityName, _authenticationSecret, _authenticationProtocol, _privacySecret, _privacyProtocol); } else if (isAuth && !isPriv) { pkt.authNoPriv(_securityName, _authenticationSecret, _authenticationProtocol); } else { pkt.NoAuthNoPriv(_securityName); } pkt.USM.EngineId.Set(_engineId); pkt.USM.EngineBoots = _engineBoots.Value; pkt.USM.EngineTime = GetCurrentEngineTime(); pkt.MaxMessageSize = _maxMessageSize.Value; pkt.MsgFlags.Reportable = _reportable; if (_contextEngineId.Length > 0) { pkt.ScopedPdu.ContextEngineId.Set(_contextEngineId); } else { pkt.ScopedPdu.ContextEngineId.Set(_engineId); } if (_contextName.Length > 0) { pkt.ScopedPdu.ContextName.Set(_contextName); } else { pkt.ScopedPdu.ContextName.Reset(); } } return(false); }
/// <summary> /// Copy all relevant values from the SnmpV3Packet class. Do not use this class for /// updating the SNMP version 3 discovery process results because secret name, authentication /// and privacy values are updated as well which discovery process doesn't use. /// </summary> /// <param name="packet"><see cref="SnmpV3Packet"/> cast as <see cref="SnmpPacket"/></param> /// <exception cref="SnmpInvalidVersionException">Thrown when SNMP packet class other then version 3 /// is passed as parameter</exception> public void UpdateValues(SnmpPacket packet) { if (packet is SnmpV3Packet) { SnmpV3Packet pkt = (SnmpV3Packet)packet; _authenticationProtocol = pkt.USM.Authentication; _privacyProtocol = pkt.USM.Privacy; _authenticationSecret.Set(pkt.USM.AuthenticationSecret); _privacySecret.Set(pkt.USM.PrivacySecret); _securityName.Set(pkt.USM.SecurityName); if (pkt.MaxMessageSize < _maxMessageSize.Value) { _maxMessageSize.Value = pkt.MaxMessageSize; } UpdateDiscoveryValues(pkt); } else { throw new SnmpInvalidVersionException("Invalid SNMP version."); } }
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</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; }
/// <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); }
/// <summary> /// Send SNMP version 3 Trap notification /// </summary> /// <param name="packet">SNMP v3 Trap packet class</param> /// <param name="peer">Manager (receiver) IP address</param> /// <param name="port">Manager (receiver) UDP port number</param> public void SendV3Trap(SnmpV3Packet packet, IpAddress peer, int port) { if( packet.Pdu.Type != PduType.V2Trap ) throw new SnmpInvalidPduTypeException("Invalid Pdu type."); byte[] outBuffer = packet.encode(); _sock.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> /// Build an SNMP version 3 packet suitable for use in discovery process. /// </summary> /// <returns>Discovery process prepared SNMP version 3 packet.</returns> public static SnmpV3Packet DiscoveryRequest() { SnmpV3Packet packet = new SnmpV3Packet(new ScopedPdu()); // with a blank scoped pdu // looking through other implementation, null (length 0) user name is used // packet.USM.SecurityName.Set("initial"); // set user name to initial, as described in RFCs return packet; // return packet }
/// <summary> /// Build SNMP RESPONSE packet for the INFORM packet class. /// </summary> /// <param name="informPacket">SNMP INFORM packet</param> /// <returns>SNMP version 3 packet containing RESPONSE to the INFORM packet contained in the parameter.</returns> /// <exception cref="SnmpInvalidPduTypeException">Parameter is not an INFORM SNMP version 3 packet class</exception> /// <exception cref="SnmpInvalidVersionException">Parameter is not a SNMP version 3 packet</exception> public static SnmpV3Packet BuildInformResponse(SnmpV3Packet informPacket) { if (informPacket.Version != SnmpVersion.Ver3) throw new SnmpInvalidVersionException("INFORM packet can only be parsed from an SNMP version 3 packet."); if (informPacket.Pdu.Type != PduType.Inform) throw new SnmpInvalidPduTypeException("Inform response can only be built for INFORM packets."); SnmpV3Packet response = new SnmpV3Packet(informPacket.ScopedPdu); response.MessageId = informPacket.MessageId; response.USM.SecurityName.Set(informPacket.USM.SecurityName); response.USM.EngineTime = informPacket.USM.EngineTime; response.USM.EngineBoots = informPacket.USM.EngineBoots; response.USM.EngineId.Set(informPacket.USM.EngineId); response.USM.Authentication = informPacket.USM.Authentication; if( response.USM.Authentication != AuthenticationDigests.None ) response.USM.AuthenticationSecret.Set(informPacket.USM.AuthenticationSecret); else response.USM.AuthenticationSecret.Reset(); response.USM.Privacy = informPacket.USM.Privacy; if (response.USM.Privacy != PrivacyProtocols.None) response.USM.PrivacySecret.Set(informPacket.USM.PrivacySecret); else response.USM.PrivacySecret.Reset(); response.MsgFlags.Authentication = informPacket.MsgFlags.Authentication; response.MsgFlags.Privacy = informPacket.MsgFlags.Privacy; response.MsgFlags.Reportable = informPacket.MsgFlags.Reportable; response.ScopedPdu.ContextEngineId.Set(informPacket.ScopedPdu.ContextEngineId); response.ScopedPdu.ContextName.Set(informPacket.ScopedPdu.ContextName); response.Pdu.Type = PduType.Response; response.Pdu.TrapObjectID.Set(informPacket.Pdu.TrapObjectID); response.Pdu.TrapSysUpTime.Value = informPacket.Pdu.TrapSysUpTime.Value; response.Pdu.RequestId = informPacket.Pdu.RequestId; return response; }
/// <summary> /// Construct and send SNMP v3 authPriv Trap /// </summary> /// <param name="receiver">Trap receiver IP address</param> /// <param name="receiverPort">Trap receiver UDP port number</param> /// <param name="engineId">Sender SNMP engineId</param> /// <param name="senderEngineBoots">Sender SNMP engine boots</param> /// <param name="senderEngineTime">Sender SNMP engine time</param> /// <param name="senderUserName">Security (user) name</param> /// <param name="senderUpTime">Sender upTime</param> /// <param name="trapObjectID">Trap object ID</param> /// <param name="varList">Variable binding list</param> /// <param name="authDigest">Authentication digest. See <see cref="AuthenticationDigests"/> enumeration for /// available digests</param> /// <param name="authSecret">Authentication secret</param> /// <param name="privProtocol">Privacy protocol. See <see cref="PrivacyProtocols"/> enumeration for /// available privacy protocols.</param> /// <param name="privSecret">Privacy secret</param> public void SendV3Trap(IpAddress receiver, int receiverPort, byte[] engineId, Int32 senderEngineBoots, Int32 senderEngineTime, string senderUserName, UInt32 senderUpTime, Oid trapObjectID, VbCollection varList, AuthenticationDigests authDigest, byte[] authSecret, PrivacyProtocols privProtocol, byte[] privSecret) { SnmpV3Packet packet = new SnmpV3Packet(); packet.Pdu.Type = PduType.V2Trap; packet.authPriv(ASCIIEncoding.UTF8.GetBytes(senderUserName), authSecret, authDigest,privSecret, privProtocol); packet.SetEngineId(engineId); packet.SetEngineTime(senderEngineBoots, senderEngineTime); packet.ScopedPdu.TrapObjectID.Set(trapObjectID); packet.ScopedPdu.TrapSysUpTime.Value = senderUpTime; packet.ScopedPdu.VbList.Add(varList); packet.MsgFlags.Reportable = false; SendV3Trap(packet, receiver, receiverPort); }
/// <summary> /// Construct and send SNMP v3 noAuthNoPriv Trap /// </summary> /// <param name="receiver">Trap receiver IP address</param> /// <param name="receiverPort">Trap receiver UDP port number</param> /// <param name="engineId">Sender SNMP engineId</param> /// <param name="senderEngineBoots">Sender SNMP engine boots</param> /// <param name="senderEngineTime">Sender SNMP engine time</param> /// <param name="senderUserName">Security (user) name</param> /// <param name="senderUpTime">Sender upTime</param> /// <param name="trapObjectID">Trap object ID</param> /// <param name="varList">Variable binding list</param> public void SendV3Trap(IpAddress receiver, int receiverPort, byte[] engineId, Int32 senderEngineBoots, Int32 senderEngineTime, string senderUserName, UInt32 senderUpTime, Oid trapObjectID, VbCollection varList) { SnmpV3Packet packet = new SnmpV3Packet(); packet.Pdu.Type = PduType.V2Trap; packet.NoAuthNoPriv(ASCIIEncoding.UTF8.GetBytes(senderUserName)); packet.SetEngineId(engineId); packet.SetEngineTime(senderEngineBoots, senderEngineTime); packet.ScopedPdu.TrapObjectID.Set(trapObjectID); packet.ScopedPdu.TrapSysUpTime.Value = senderUpTime; packet.ScopedPdu.VbList.Add(varList); packet.MsgFlags.Reportable = false; SendV3Trap(packet, receiver, receiverPort); }
/// <summary> /// Build SNMP discovery response packet. /// </summary> /// <remarks> /// Manager application has to be able to respond to discovery requests to be able to handle /// SNMPv3 INFORM notifications. /// /// In an INFORM packet, engineId value is set to the manager stations id (unlike all other requests /// where agent is the authoritative SNMP engine). For the agent to discover appropriate manager engine /// id, boots and time values (required for authentication and privacy packet handling), manager has to /// be able to respond to the discovery request. /// </remarks> /// <param name="messageId">Message id from the received discovery packet</param> /// <param name="requestId">Request id from the received discovery packets Pdu</param> /// <param name="engineId">Local engine id</param> /// <param name="engineBoots">Number of times local SNMP engine has been restarted</param> /// <param name="engineTime">Time since the engine was started in seconds</param> /// <param name="unknownEngineIdCount">Number of discovery packets received by the local SNMP engine</param> /// <returns>SNMP v3 packet properly formatted as a response to a discovery request</returns> public static SnmpV3Packet DiscoveryResponse(Int32 messageId, Int32 requestId, OctetString engineId, Int32 engineBoots, Int32 engineTime, Int32 unknownEngineIdCount) { SnmpV3Packet packet = new SnmpV3Packet(); packet.Pdu.Type = PduType.Report; packet.Pdu.RequestId = requestId; packet.Pdu.VbList.Add(SnmpConstants.usmStatsUnknownEngineIDs, new Integer32(unknownEngineIdCount)); // discovery response is a report packet. We don't want to receive reports about a report packet.MsgFlags.Reportable = false; packet.SetEngineId(engineId); packet.MessageId = messageId; packet.USM.EngineBoots = engineBoots; packet.USM.EngineTime = engineTime; return packet; }
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> /// Validate that incoming packet has arrived from the correct engine id and is using a correct /// combination of privacy and authentication values. /// </summary> /// <param name="packet">Received and parsed SNMP version 3 packet.</param> /// <returns>True if packet is valid, otherwise false.</returns> /// <exception cref="SnmpException">Thrown on following errors with ErrorCode: /// * ErrorCode = 0: SecureAgentParameters was updated after request was made but before reply was received (this is not allowed) /// * SnmpException.InvalidAuthoritativeEngineId: engine id in the reply does not match request /// * SnmpException.InvalidSecurityName: security name mismatch between request and reply packets /// * SnmpException.ReportOnNoReports: report packet received when we had reportable set to false in the request /// * SnmpException.UnsupportedNoAuthPriv: noAuthPriv is not supported /// </exception> /// <exception cref="SnmpPrivacyException">Thrown when configured privacy passwords in this class and in the packet class do not match</exception> /// <exception cref="SnmpAuthenticationException">Thrown when configured authentication passwords in this class and in the packet class do not match</exception> public bool ValidateIncomingPacket(SnmpV3Packet packet) { // First check if this is a report packet. if (packet.Pdu.Type == PduType.Report) { if (!_reportable) { // we do not expect report packets so dump it throw new SnmpException(SnmpException.ReportOnNoReports, "Unexpected report packet received."); // return false; } if (packet.MsgFlags.Authentication == false && packet.MsgFlags.Privacy) { // no authentication and no privacy allowed in report packets throw new SnmpException(SnmpException.UnsupportedNoAuthPriv, "Authentication and privacy combination is not supported."); // return false; } // the rest will not be checked, there is no point } else { if (packet.USM.EngineId != _engineId) { // different engine id is not allowed throw new SnmpException(SnmpException.InvalidAuthoritativeEngineId, "EngineId mismatch."); // return false; } if (packet.USM.Authentication != _authenticationProtocol || packet.USM.Privacy != _privacyProtocol) { // we have to have the same authentication and privacy protocol - no last minute changes throw new SnmpException("Agent parameters updated after request was made."); // return false; } if (packet.USM.Authentication != AuthenticationDigests.None) { if (packet.USM.AuthenticationSecret != _authenticationSecret) { // authentication secret has to match throw new SnmpAuthenticationException("Authentication secret in the packet class does not match the IAgentParameter secret."); // return false; } } if (packet.USM.Privacy != PrivacyProtocols.None) { if (packet.USM.PrivacySecret != _privacySecret) { // privacy secret has to match throw new SnmpPrivacyException("Privacy secret in the packet class does not match the IAgentParameters secret."); // return false; } } if (packet.USM.SecurityName != _securityName) { throw new SnmpException(SnmpException.InvalidSecurityName, "Security name mismatch."); // return false; } } return true; }
/// <summary> /// Build SNMP RESPONSE packet for the received INFORM packet. /// </summary> /// <returns>SNMP version 3 packet containing RESPONSE to the INFORM packet contained in the class instance.</returns> public SnmpV3Packet BuildInformResponse() { return(SnmpV3Packet.BuildInformResponse(this)); }