/// <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>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 pkt) { bool isAuth = (authenticationProtocol == AuthenticationDigests.None) ? false : true; bool isPriv = (privacyProtocol == EPrivacyProtocols.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.MessageFlags.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> /// 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 pkt) { pkt.Community.Set(community); } else if (packet is SnmpV2Packet pktV2) { pktV2.Community.Set(community); } else { throw new SnmpInvalidVersionException("Invalid SNMP version."); } }
/// <summary> /// SNMP GET-BULK request /// </summary> /// <remarks> /// GetBulk request type is only available with SNMP v2c agents. SNMP v3 also supports the request itself /// but that version of the protocol is not supported by SimpleSnmp. /// /// GetBulk method will return a dictionary of Oid to value mapped values as returned form a /// single GetBulk request to the agent. You can change how the request itself is made by changing the /// SimpleSnmp.NonRepeaters and SimpleSnmp.MaxRepetitions values. SimpleSnmp properties are only used /// when values in the parameter Pdu are set to 0. /// </remarks> /// <example>SNMP GET-BULK request: /// <code> /// String snmpAgent = "10.10.10.1"; /// String snmpCommunity = "private"; /// SimpleSnmp snmp = new SimpleSnmp(snmpAgent, snmpCommunity); /// // Create a request Pdu /// Pdu pdu = new Pdu(); /// pdu.Type = SnmpConstants.GETBULK; // type GETBULK /// pdu.VbList.Add("1.3.6.1.2.1.1"); /// pdu.NonRepeaters = 0; /// pdu.MaxRepetitions = 10; /// Dictionary<Oid, AsnType> result = snmp.GetBulk(pdu); /// if( result == null ) { /// Console.WriteLine("Request failed."); /// } else { /// foreach (KeyValuePair<Oid, AsnType> entry in result) /// { /// Console.WriteLine("{0} = {1}: {2}", entry.Key.ToString(), SnmpConstants.GetTypeName(entry.Value.Type), /// entry.Value.ToString()); /// } /// } /// </code> /// Will return: /// <code> /// 1.3.6.1.2.1.1.1.0 = OctetString: "Dual core Intel notebook" /// 1.3.6.1.2.1.1.2.0 = ObjectId: 1.3.6.1.9.233233.1.1 /// 1.3.6.1.2.1.1.3.0 = TimeTicks: 0d 0h 0m 1s 420ms /// 1.3.6.1.2.1.1.4.0 = OctetString: "*****@*****.**" /// 1.3.6.1.2.1.1.5.0 = OctetString: "milans-nbook" /// 1.3.6.1.2.1.1.6.0 = OctetString: "Developer home" /// 1.3.6.1.2.1.1.8.0 = TimeTicks: 0d 0h 0m 0s 10ms /// </code> /// </example> /// <param name="pdu">Request Protocol Data Unit</param> /// <returns>Result of the SNMP request in a dictionary format with Oid => AsnType values</returns> public Dictionary <Oid, AsnType> GetBulk(Pdu pdu) { if (!Valid) { return(null); // class is not fully initialized. } try { if (pdu.NonRepeaters == 0) { pdu.NonRepeaters = _nonRepeaters; } if (pdu.MaxRepetitions == 0) { pdu.MaxRepetitions = _maxRepetitions; } _target = new UdpTarget(_peerIP, _peerPort, _timeout, _retry); AgentParameters param = new AgentParameters(SnmpVersion.Ver2, new OctetString(_community)); SnmpPacket result = _target.Request(pdu, param); if (result != null) { if (result.Pdu.ErrorStatus == 0) { Dictionary <Oid, AsnType> res = new Dictionary <Oid, AsnType>(); foreach (Vb v in result.Pdu.VbList) { if ( (v.Value.Type == SnmpConstants.SMI_ENDOFMIBVIEW) || (v.Value.Type == SnmpConstants.SMI_NOSUCHINSTANCE) || (v.Value.Type == SnmpConstants.SMI_NOSUCHOBJECT)) { break; } res.Add(v.Oid, v.Value); } _target.Close(); _target = null; return(res); } } } catch { } _target.Close(); _target = null; return(null); }
/// <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 pkt) { _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>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 pkt) { bool isAuth = (authenticationProtocol == AuthenticationDigests.None) ? false : true; bool isPriv = (privacyProtocol == EPrivacyProtocols.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 = maximumMessageSize.Value; pkt.MessageFlags.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> /// SNMP GET-NEXT request /// </summary> /// <example>SNMP GET-NEXT request: /// <code> /// String snmpAgent = "10.10.10.1"; /// String snmpCommunity = "private"; /// SimpleSnmp snmp = new SimpleSnmp(snmpAgent, snmpCommunity); /// // Create a request Pdu /// Pdu pdu = new Pdu(); /// pdu.Type = SnmpConstants.GETNEXT; // type GETNEXT /// pdu.VbList.Add("1.3.6.1.2.1.1"); /// Dictionary<Oid, AsnType> result = snmp.GetNext(pdu); /// if( result == null ) { /// Console.WriteLine("Request failed."); /// } else { /// foreach (KeyValuePair<Oid, AsnType> entry in result) /// { /// Console.WriteLine("{0} = {1}: {2}", entry.Key.ToString(), SnmpConstants.GetTypeName(entry.Value.Type), /// entry.Value.ToString()); /// } /// } /// </code> /// Will return: /// <code> /// 1.3.6.1.2.1.1.1.0 = OctetString: "Dual core Intel notebook" /// </code> /// </example> /// <param name="version">SNMP protocol version. Acceptable values are SnmpVersion.Ver1 and SnmpVersion.Ver2</param> /// <param name="pdu">Request Protocol Data Unit</param> /// <returns>Result of the SNMP request in a dictionary format with Oid => AsnType values</returns> public Dictionary <Oid, AsnType> GetNext(SnmpVersion version, Pdu pdu) { if (!Valid) { return(null); // class is not fully initialized. } // function only works on SNMP version 1 and SNMP version 2 requests if (version != SnmpVersion.Ver1 && version != SnmpVersion.Ver2) { return(null); } try { _target = new UdpTarget(_peerIP, _peerPort, _timeout, _retry); AgentParameters param = new AgentParameters(version, new OctetString(_community)); SnmpPacket result = _target.Request(pdu, param); if (result != null) { if (result.Pdu.ErrorStatus == 0) { Dictionary <Oid, AsnType> res = new Dictionary <Oid, AsnType>(); foreach (Vb v in result.Pdu.VbList) { if (version == SnmpVersion.Ver2 && (v.Value.Type == SnmpConstants.SMI_ENDOFMIBVIEW) || (v.Value.Type == SnmpConstants.SMI_NOSUCHINSTANCE) || (v.Value.Type == SnmpConstants.SMI_NOSUCHOBJECT)) { break; } res.Add(v.Oid, v.Value); } _target.Close(); _target = null; return(res); } } } catch (Exception ex) { ex.GetType(); // just to stop a warning } _target.Close(); _target = null; return(null); }
/// <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> /// Send SNMP Trap notification /// </summary> /// <remarks> /// Helper function to allow for seamless sending of SNMP notifications for all protocol versions. /// /// packet parameter should be appropriately formatted SNMP notification in SnmpV1TrapPacket, /// SnmpV2Packet or SnmpV3Packet class cast as SnmpPacket class. /// /// Function will determine which version of the notification is to be used by checking the type /// of the packet parameter and call appropriate TrapAgent member function to send it. /// </remarks> /// <param name="packet">SNMP trap packet</param> /// <param name="peer">Manager (receiver) IP address</param> /// <param name="port">Manager (receiver) UDP port number</param> public static void SendTrap(SnmpPacket packet, IpAddress peer, int port) { TrapAgent agent = new TrapAgent(); if (packet is SnmpV1TrapPacket) { agent.SendV1Trap((SnmpV1TrapPacket)packet, peer, port); } else if (packet is SnmpV2Packet) { agent.SendV2Trap((SnmpV2Packet)packet, peer, port); } else if (packet is SnmpV3Packet) { agent.SendV3Trap((SnmpV3Packet)packet, peer, port); } else { throw new SnmpException("Invalid SNMP packet type."); } }
/// <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 pkt) { _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."); } }
/// <summary> /// SNMP SET request /// </summary> /// <example>Set operation in SNMP version 1: /// <code> /// String snmpAgent = "10.10.10.1"; /// String snmpCommunity = "private"; /// SimpleSnmp snmp = new SimpleSnmp(snmpAgent, snmpCommunity); /// // Create a request Pdu /// Pdu pdu = new Pdu(); /// pdu.Type = SnmpConstants.SET; // type SET /// Oid setOid = new Oid("1.3.6.1.2.1.1.1.0"); // sysDescr.0 /// OctetString setValue = new OctetString("My personal toy"); /// pdu.VbList.Add(setOid, setValue); /// Dictionary<Oid, AsnType> result = snmp.Set(SnmpVersion.Ver1, pdu); /// if( result == null ) { /// Console.WriteLine("Request failed."); /// } else { /// Console.WriteLine("Success!"); /// } /// </code> /// /// To use SNMP version 2, change snmp.Set() method call first parameter to SnmpVersion.Ver2. /// </example> /// <param name="version">SNMP protocol version number. Acceptable values are SnmpVersion.Ver1 and SnmpVersion.Ver2</param> /// <param name="pdu">Request Protocol Data Unit</param> /// <returns>Result of the SNMP request in a dictionary format with Oid => AsnType values</returns> public Dictionary <Oid, AsnType> Set(SnmpVersion version, Pdu pdu) { if (!Valid) { return(null); // class is not fully initialized. } // function only works on SNMP version 1 and SNMP version 2 requests if (version != SnmpVersion.Ver1 && version != SnmpVersion.Ver2) { return(null); } try { _target = new UdpTarget(_peerIP, _peerPort, _timeout, _retry); AgentParameters param = new AgentParameters(version, new OctetString(_community)); SnmpPacket result = _target.Request(pdu, param); if (result != null) { if (result.Pdu.ErrorStatus == 0) { Dictionary <Oid, AsnType> res = new Dictionary <Oid, AsnType>(); foreach (Vb v in result.Pdu.VbList) { res.Add(v.Oid, v.Value); } _target.Close(); _target = null; return(res); } } } catch { } _target.Close(); _target = null; return(null); }
/// <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> /// Validate received reply /// </summary> /// <param name="packet">Received SNMP packet</param> /// <returns>True if packet is validated, 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 ValidateReceivedPacket(SnmpPacket packet) { if (! (packet is SnmpV3Packet)) return false; SnmpV3Packet pkt = (SnmpV3Packet)packet; // First check if this is a report packet. if (pkt.Pdu.Type == PduType.Response) { if (!_reportable) { // we do not expect report packets so dump it throw new SnmpException(SnmpException.ReportOnNoReports, "Unexpected report packet received."); // return false; } if (pkt.MsgFlags.Authentication == false && pkt.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 (pkt.USM.EngineId != _engineId) { // different engine id is not allowed throw new SnmpException(SnmpException.InvalidAuthoritativeEngineId, "EngineId mismatch."); // return false; } if (pkt.USM.Authentication != _authenticationProtocol || pkt.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 (pkt.USM.Authentication != AuthenticationDigests.None) { if (pkt.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 (pkt.USM.Privacy != PrivacyProtocols.None) { if (pkt.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 (pkt.USM.SecurityName != _securityName) { throw new SnmpException(SnmpException.InvalidSecurityName, "Security name mismatch."); // return false; } } return true; }
/// <summary> /// Send SNMP Trap notification /// </summary> /// <remarks> /// Helper function to allow for seamless sending of SNMP notifications for all protocol versions. /// /// packet parameter should be appropriately formatted SNMP notification in SnmpV1TrapPacket, /// SnmpV2Packet or SnmpV3Packet class cast as SnmpPacket class. /// /// Function will determine which version of the notification is to be used by checking the type /// of the packet parameter and call appropriate TrapAgent member function to send it. /// </remarks> /// <param name="packet">SNMP trap packet</param> /// <param name="peer">Manager (receiver) IP address</param> /// <param name="port">Manager (receiver) UDP port number</param> public static void SendTrap(SnmpPacket packet, IpAddress peer, int port) { TrapAgent agent = new TrapAgent(); if (packet is SnmpV1TrapPacket) agent.SendV1Trap((SnmpV1TrapPacket)packet, peer, port); else if (packet is SnmpV2Packet) agent.SendV2Trap((SnmpV2Packet)packet, peer, port); else if (packet is SnmpV3Packet) agent.SendV3Trap((SnmpV3Packet)packet, peer, port); else throw new SnmpException("Invalid SNMP packet type."); }
/// <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> /// 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); } }
/// <summary> /// SNMP SET request /// </summary> /// <example>Set operation in SNMP version 1: /// <code> /// String snmpAgent = "10.10.10.1"; /// String snmpCommunity = "private"; /// SimpleSnmp snmp = new SimpleSnmp(snmpAgent, snmpCommunity); /// // Create a request Pdu /// Pdu pdu = new Pdu(); /// pdu.Type = SnmpConstants.SET; // type SET /// Oid setOid = new Oid("1.3.6.1.2.1.1.1.0"); // sysDescr.0 /// OctetString setValue = new OctetString("My personal toy"); /// pdu.VbList.Add(setOid, setValue); /// Dictionary<Oid, AsnType> result = snmp.Set(SnmpVersion.Ver1, pdu); /// if( result == null ) { /// Console.WriteLine("Request failed."); /// } else { /// Console.WriteLine("Success!"); /// } /// </code> /// /// To use SNMP version 2, change snmp.Set() method call first parameter to SnmpVersion.Ver2. /// </example> /// <param name="version">SNMP protocol version number. Acceptable values are SnmpVersion.Ver1 and SnmpVersion.Ver2</param> /// <param name="pdu">Request Protocol Data Unit</param> /// <returns>Result of the SNMP request in a dictionary format with Oid => AsnType values</returns> public Dictionary <Oid, AsnType> Set(SnmpVersion version, Pdu pdu) { if (!Valid) { if (!_suppressExceptions) { throw new SnmpException("SimpleSnmp class is not valid."); } return(null); // class is not fully initialized. } // function only works on SNMP version 1 and SNMP version 2 requests if (version != SnmpVersion.Ver1 && version != SnmpVersion.Ver2) { if (!_suppressExceptions) { throw new SnmpInvalidVersionException("SimpleSnmp support SNMP version 1 and 2 only."); } return(null); } try { _target = new UdpTarget(_peerIP, _peerPort, _timeout, _retry); } catch (Exception ex) { _target = null; if (!_suppressExceptions) { throw ex; } } if (_target == null) { return(null); } try { AgentParameters param = new AgentParameters(version, new OctetString(_community)); SnmpPacket result = _target.Request(pdu, param); if (result != null) { if (result.Pdu.ErrorStatus == 0) { Dictionary <Oid, AsnType> res = new Dictionary <Oid, AsnType>(); foreach (Vb v in result.Pdu.VbList) { if (res.ContainsKey(v.Oid)) { if (res[v.Oid].Type != v.Value.Type) { throw new SnmpException(SnmpException.OidValueTypeChanged, "OID value type changed for OID: " + v.Oid.ToString()); } else { res[v.Oid] = v.Value; } } else { res.Add(v.Oid, v.Value); } } _target.Close(); _target = null; return(res); } else { if (!_suppressExceptions) { throw new SnmpErrorStatusException("Agent responded with an error", result.Pdu.ErrorStatus, result.Pdu.ErrorIndex); } } } } catch (Exception ex) { if (!_suppressExceptions) { _target.Close(); _target = null; throw ex; } } _target.Close(); _target = null; return(null); }
/// <summary> /// SNMP GET request /// </summary> /// <example>SNMP GET request: /// <code> /// String snmpAgent = "10.10.10.1"; /// String snmpCommunity = "public"; /// SimpleSnmp snmp = new SimpleSnmp(snmpAgent, snmpCommunity); /// // Create a request Pdu /// Pdu pdu = new Pdu(); /// pdu.Type = SnmpConstants.GET; // type GET /// pdu.VbList.Add("1.3.6.1.2.1.1.1.0"); /// Dictionary<Oid, AsnType> result = snmp.GetNext(SnmpVersion.Ver1, pdu); /// if( result == null ) { /// Console.WriteLine("Request failed."); /// } else { /// foreach (KeyValuePair<Oid, AsnType> entry in result) /// { /// Console.WriteLine("{0} = {1}: {2}", entry.Key.ToString(), SnmpConstants.GetTypeName(entry.Value.Type), /// entry.Value.ToString()); /// } /// } /// </code> /// Will return: /// <code> /// 1.3.6.1.2.1.1.1.0 = OctetString: "Dual core Intel notebook" /// </code> /// </example> /// <param name="version">SNMP protocol version. Acceptable values are SnmpVersion.Ver1 and SnmpVersion.Ver2</param> /// <param name="pdu">Request Protocol Data Unit</param> /// <returns>Result of the SNMP request in a dictionary format with Oid => AsnType values</returns> public Dictionary <Oid, AsnType> Get(SnmpVersion version, Pdu pdu) { if (!Valid) { if (!_suppressExceptions) { throw new SnmpException("SimpleSnmp class is not valid."); } return(null); // class is not fully initialized. } // function only works on SNMP version 1 and SNMP version 2 requests if (version != SnmpVersion.Ver1 && version != SnmpVersion.Ver2) { if (!_suppressExceptions) { throw new SnmpInvalidVersionException("SimpleSnmp support SNMP version 1 and 2 only."); } return(null); } try { _target = new UdpTarget(_peerIP, _peerPort, _timeout, _retry); } catch (Exception ex) { _target = null; if (!_suppressExceptions) { throw ex; } } if (_target == null) { return(null); } try { AgentParameters param = new AgentParameters(version, new OctetString(_community)); SnmpPacket result = _target.Request(pdu, param); if (result != null) { if (result.Pdu.ErrorStatus == 0) { Dictionary <Oid, AsnType> res = new Dictionary <Oid, AsnType>(); foreach (Vb v in result.Pdu.VbList) { if (version == SnmpVersion.Ver2 && (v.Value.Type == SnmpConstants.SMI_NOSUCHINSTANCE || v.Value.Type == SnmpConstants.SMI_NOSUCHOBJECT)) { if (!res.ContainsKey(v.Oid)) { res.Add(v.Oid, new Null()); } else { res.Add(Oid.NullOid(), v.Value); } } else { if (!res.ContainsKey(v.Oid)) { res.Add(v.Oid, v.Value); } else { if (res[v.Oid].Type == v.Value.Type) { res[v.Oid] = v.Value; // update value of the existing Oid entry } else { throw new SnmpException(SnmpException.OidValueTypeChanged, string.Format("Value type changed from {0} to {1}", res[v.Oid].Type, v.Value.Type)); } } } } _target.Close(); _target = null; return(res); } else { if (!_suppressExceptions) { throw new SnmpErrorStatusException("Agent responded with an error", result.Pdu.ErrorStatus, result.Pdu.ErrorIndex); } } } } catch (Exception ex) { if (!_suppressExceptions) { _target.Close(); _target = null; throw ex; } } _target.Close(); _target = null; return(null); }
/// <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> /// SNMP GET-BULK request /// </summary> /// <remarks> /// GetBulk request type is only available with SNMP v2c agents. SNMP v3 also supports the request itself /// but that version of the protocol is not supported by SimpleSnmp. /// /// GetBulk method will return a dictionary of Oid to value mapped values as returned form a /// single GetBulk request to the agent. You can change how the request itself is made by changing the /// SimpleSnmp.NonRepeaters and SimpleSnmp.MaxRepetitions values. SimpleSnmp properties are only used /// when values in the parameter Pdu are set to 0. /// </remarks> /// <example>SNMP GET-BULK request: /// <code> /// String snmpAgent = "10.10.10.1"; /// String snmpCommunity = "private"; /// SimpleSnmp snmp = new SimpleSnmp(snmpAgent, snmpCommunity); /// // Create a request Pdu /// Pdu pdu = new Pdu(); /// pdu.Type = SnmpConstants.GETBULK; // type GETBULK /// pdu.VbList.Add("1.3.6.1.2.1.1"); /// pdu.NonRepeaters = 0; /// pdu.MaxRepetitions = 10; /// Dictionary<Oid, AsnType> result = snmp.GetBulk(pdu); /// if( result == null ) { /// Console.WriteLine("Request failed."); /// } else { /// foreach (KeyValuePair<Oid, AsnType> entry in result) /// { /// Console.WriteLine("{0} = {1}: {2}", entry.Key.ToString(), SnmpConstants.GetTypeName(entry.Value.Type), /// entry.Value.ToString()); /// } /// } /// </code> /// Will return: /// <code> /// 1.3.6.1.2.1.1.1.0 = OctetString: "Dual core Intel notebook" /// 1.3.6.1.2.1.1.2.0 = ObjectId: 1.3.6.1.9.233233.1.1 /// 1.3.6.1.2.1.1.3.0 = TimeTicks: 0d 0h 0m 1s 420ms /// 1.3.6.1.2.1.1.4.0 = OctetString: "*****@*****.**" /// 1.3.6.1.2.1.1.5.0 = OctetString: "milans-nbook" /// 1.3.6.1.2.1.1.6.0 = OctetString: "Developer home" /// 1.3.6.1.2.1.1.8.0 = TimeTicks: 0d 0h 0m 0s 10ms /// </code> /// </example> /// <param name="pdu">Request Protocol Data Unit</param> /// <returns>Result of the SNMP request in a dictionary format with Oid => AsnType values</returns> public Dictionary <Oid, AsnType> GetBulk(Pdu pdu) { if (!Valid) { if (!_suppressExceptions) { throw new SnmpException("SimpleSnmp class is not valid."); } return(null); // class is not fully initialized. } try { pdu.NonRepeaters = _nonRepeaters; pdu.MaxRepetitions = _maxRepetitions; _target = new UdpTarget(_peerIP, _peerPort, _timeout, _retry); } catch (Exception ex) { _target = null; if (!_suppressExceptions) { throw ex; } } if (_target == null) { return(null); } try { AgentParameters param = new AgentParameters(SnmpVersion.Ver2, new OctetString(_community)); SnmpPacket result = _target.Request(pdu, param); if (result != null) { if (result.Pdu.ErrorStatus == 0) { Dictionary <Oid, AsnType> res = new Dictionary <Oid, AsnType>(); foreach (Vb v in result.Pdu.VbList) { if ( (v.Value.Type == SnmpConstants.SMI_ENDOFMIBVIEW) || (v.Value.Type == SnmpConstants.SMI_NOSUCHINSTANCE) || (v.Value.Type == SnmpConstants.SMI_NOSUCHOBJECT) ) { break; } if (res.ContainsKey(v.Oid)) { if (res[v.Oid].Type != v.Value.Type) { throw new SnmpException(SnmpException.OidValueTypeChanged, "OID value type changed for OID: " + v.Oid.ToString()); } else { res[v.Oid] = v.Value; } } else { res.Add(v.Oid, v.Value); } } _target.Close(); _target = null; return(res); } else { if (!_suppressExceptions) { throw new SnmpErrorStatusException("Agent responded with an error", result.Pdu.ErrorStatus, result.Pdu.ErrorIndex); } } } } catch (Exception ex) { if (!_suppressExceptions) { _target.Close(); _target = null; throw ex; } } _target.Close(); _target = null; return(null); }
/// <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> /// 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> /// 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> /// Validate received reply /// </summary> /// <param name="packet">Received SNMP packet</param> /// <returns>True if packet is validated, 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 ValidateReceivedPacket(SnmpPacket packet) { if (!(packet is SnmpV3Packet)) { return(false); } SnmpV3Packet pkt = (SnmpV3Packet)packet; // First check if this is a report packet. if (pkt.Pdu.Type == PduType.Response) { if (!_reportable) { // we do not expect report packets so dump it throw new SnmpException(SnmpException.ReportOnNoReports, "Unexpected report packet received."); // return false; } if (pkt.MsgFlags.Authentication == false && pkt.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 (pkt.USM.EngineId != _engineId) { // different engine id is not allowed throw new SnmpException(SnmpException.InvalidAuthoritativeEngineId, "EngineId mismatch."); // return false; } if (pkt.USM.Authentication != _authenticationProtocol || pkt.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 (pkt.USM.Authentication != AuthenticationDigests.None) { if (pkt.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 (pkt.USM.Privacy != PrivacyProtocols.None) { if (pkt.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 (pkt.USM.SecurityName != _securityName) { throw new SnmpException(SnmpException.InvalidSecurityName, "Security name mismatch."); // return false; } } return(true); }
/// <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."); }
/// <summary>SNMP GET-BULK request</summary> /// <remarks> /// GetBulk request type is only available with SNMP v2c agents. SNMP v3 also supports the request itself /// but that version of the protocol is not supported by SimpleSnmp. /// /// GetBulk method will return a dictionary of Oid to value mapped values as returned form a /// single GetBulk request to the agent. You can change how the request itself is made by changing the /// SimpleSnmp.NonRepeaters and SimpleSnmp.MaxRepetitions values. SimpleSnmp properties are only used /// when values in the parameter Pdu are set to 0. /// </remarks> /// <example>SNMP GET-BULK request: /// <code> /// string snmpAgent = "10.10.10.1"; /// string snmpCommunity = "private"; /// SimpleSnmp snmp = new SimpleSnmp(snmpAgent, snmpCommunity); /// // Create a request Pdu /// Pdu pdu = new Pdu(); /// pdu.Type = SnmpConstants.GETBULK; // type GETBULK /// pdu.VbList.Add("1.3.6.1.2.1.1"); /// pdu.NonRepeaters = 0; /// pdu.MaxRepetitions = 10; /// Dictionary<Oid, AsnType> result = snmp.GetBulk(pdu); /// if( result == null ) { /// Console.WriteLine("Request failed."); /// } else { /// foreach (KeyValuePair<Oid, AsnType> entry in result) /// { /// Console.WriteLine("{0} = {1}: {2}", entry.Key.ToString(), SnmpConstants.GetTypeName(entry.Value.Type), /// entry.Value.ToString()); /// } /// } /// </code> /// Will return: /// <code> /// 1.3.6.1.2.1.1.1.0 = OctetString: "Dual core Intel notebook" /// 1.3.6.1.2.1.1.2.0 = ObjectId: 1.3.6.1.9.233233.1.1 /// 1.3.6.1.2.1.1.3.0 = TimeTicks: 0d 0h 0m 1s 420ms /// 1.3.6.1.2.1.1.4.0 = OctetString: "*****@*****.**" /// 1.3.6.1.2.1.1.5.0 = OctetString: "milans-nbook" /// 1.3.6.1.2.1.1.6.0 = OctetString: "Developer home" /// 1.3.6.1.2.1.1.8.0 = TimeTicks: 0d 0h 0m 0s 10ms /// </code> /// </example> /// <param name="pdu">Request Protocol Data Unit</param> /// <returns>Result of the SNMP request in a dictionary format with Oid => AsnType values</returns> public Dictionary <Oid, AsnType> GetBulk(Pdu pdu) { if (!Valid) { if (!suppressExceptions) { throw new SnmpException("SimpleSnmp class is not valid."); } return(null); // class is not fully initialized. } try { pdu.NonRepeaters = nonRepeaters; pdu.MaxRepetitions = maxRepetitions; target = new UdpTarget(peerIP, peerPort, timeout, retry); } catch (System.Exception ex) { target = null; if (!suppressExceptions) { throw ex; } } if (target == null) { return(null); } try { AgentParameters param = new AgentParameters(ESnmpVersion.Ver2, new OctetString(community)); SnmpPacket result = target.Request(pdu, param); if (result != null) { if (result.Pdu.ErrorStatus == 0) { Dictionary <Oid, AsnType> res = new Dictionary <Oid, AsnType>(); foreach (Vb v in result.Pdu.VbList) { if ( (v.Value.Type == SnmpConstants.SmiEndOfMIBView) || (v.Value.Type == SnmpConstants.SmiNoSuchInstance) || (v.Value.Type == SnmpConstants.SmiNoSuchObject)) { break; } if (res.ContainsKey(v.Oid)) { if (res[v.Oid].Type != v.Value.Type) { throw new SnmpException(SnmpException.EErrorCode.OidValueTypeChanged, "OID value type changed for OID: " + v.Oid.ToString()); } else { res[v.Oid] = v.Value; } } else { res.Add(v.Oid, v.Value); } } target.Close(); target = null; return(res); } if (!suppressExceptions) { throw new SnmpErrorStatusException("Agent responded with an error", result.Pdu.ErrorStatus, result.Pdu.ErrorIndex); } } } catch (System.Exception ex) { if (!suppressExceptions) { target.Close(); target = null; throw ex; } } target.Close(); target = null; return(null); }