// /** // * File: MyClass.cs // * Author: haraldwolff // * // * This file and it's content is copyrighted by the Author and / or copyright holder. // * Any use wihtout proper permission is illegal and may lead to legal actions. // * // * // **/ using System; using System.Collections.Generic; using ln.snmp.types; using System.Net.Sockets; using System.Net; using System.Threading; using ln.snmp.asn1; using ln.logging; using ln.snmp.endpoint; namespace ln.snmp { public class SNMPEngine : IDisposable { public static bool DEBUG = false; private static SNMPEngine __default = null; public static SNMPEngine DefaultEngine { get { if (__default == null) __default = new SNMPEngine(); return __default; } set => __default = value; } public UdpClient LocalEndpoint { get; private set; } public int Timeout { get; set; } = 750; private Dictionary queuedRequests = new Dictionary(); private bool shutdown = false; private Thread ReceiverThread { get; set; } private Dictionary currentEndpoints = new Dictionary(); private int nextMessageID = (int)DateTimeOffset.Now.ToUnixTimeSeconds(); public int NextMessageID => nextMessageID++; public SNMPEngine() { LocalEndpoint = new UdpClient(); ReceiverThread = new Thread(Receiver); ReceiverThread.IsBackground = true; ReceiverThread.Start(); } public SNMPEngine(IPEndPoint localEndpoint) { LocalEndpoint = new UdpClient(localEndpoint); ReceiverThread = new Thread(Receiver); ReceiverThread.IsBackground = true; ReceiverThread.Start(); } public void Close() { shutdown = true; LocalEndpoint.Close(); ReceiverThread.Interrupt(); } private void Receiver() { while (!shutdown) { try { IPEndPoint remoteEndpoint = new IPEndPoint(IPAddress.Any, 0); byte[] datagram = LocalEndpoint.Receive(ref remoteEndpoint); if (DEBUG) Logging.Log(LogLevel.DEBUGDETAIL,"SNMPClient: Received: {0}", BitConverter.ToString(datagram)); ASN1Value asn = new ASN1Value(datagram); SnmpMessage snmpMessage = asn; if (currentEndpoints.ContainsKey(remoteEndpoint)) { SnmpEndpoint snmpEndpoint = currentEndpoints[remoteEndpoint]; snmpEndpoint.Received(snmpMessage); } else { Logging.Log(LogLevel.WARNING, "SnmpEngine.Receiver(): Received message from unknown endpoint ({0})",remoteEndpoint); } } catch (SocketException) { } catch (Exception e) { Logging.Log(e); } } } public void SendMessage(IPEndPoint remoteEndpoint,SnmpMessage message) { ASN1Value snmpMessage = message; byte[] snmpMessageBytes = snmpMessage.AsByteArray; lock (LocalEndpoint) { LocalEndpoint.Send(snmpMessageBytes, snmpMessageBytes.Length, remoteEndpoint); } } //public SnmpMessage SNMPRequest(IPEndPoint remoteEndpoint,SnmpMessage snmpMessage,int timeout) //{ // lock (queuedRequests) // { // ASN1Value snmpRequest = snmpMessage; // byte[] snmpRequestBytes = snmpRequest.AsByteArray; // queuedRequests.Add(snmpMessage.MessageID, snmpMessage); // Logging.Log(LogLevel.DEBUG,"SNMPClient: Send: {0}", BitConverter.ToString(snmpRequestBytes)); // Logging.Log(LogLevel.DEBUG,"sent snmpMessage with MessageID {0} ( 0x{0:x8} )",snmpMessage.MessageID); // snmpMessage.Dump(); // LocalEndpoint.Send(snmpRequestBytes, snmpRequestBytes.Length, remoteEndpoint); // lock (snmpMessage) // { // Monitor.Exit(queuedRequests); // bool success = Monitor.Wait(snmpMessage, timeout); // Monitor.Enter(queuedRequests); // if (!success) // { // queuedRequests.Remove(snmpMessage.MessageID); // throw new TimeoutException(); // } // } // SnmpMessage responseMessage = queuedRequests[snmpMessage.MessageID]; // queuedRequests.Remove(snmpMessage.MessageID); // return responseMessage; // } //} public void RegisterEndpoint(SnmpEndpoint intf) { lock (currentEndpoints) { if (currentEndpoints.ContainsKey(intf.RemoteEndpoint)) { currentEndpoints[intf.RemoteEndpoint].Close(); } currentEndpoints.Add(intf.RemoteEndpoint,intf); } } public void UnregisterEndpoint(SnmpEndpoint intf) { lock (currentEndpoints) { currentEndpoints.Remove(intf.RemoteEndpoint); } } public void Dispose() { if (ReceiverThread != null) { if (ReceiverThread.IsAlive) { Close(); if (!ReceiverThread.Join(250)) { ReceiverThread.Abort(); } } ReceiverThread = null; } } } }