// /** // * 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; namespace ln.snmp { public class SNMPEngine : IDisposable { public static bool DEBUG = false; public UdpClient LocalEndpoint { get; private set; } public int Timeout { get; set; } = 1000; private Dictionary queuedRequests = new Dictionary(); private bool shutdown = false; private Thread ReceiverThread { get; set; } private int nextMessageID = (int)DateTimeOffset.Now.ToUnixTimeSeconds(); public int NextMessageID => nextMessageID++; public SNMPEngine() { LocalEndpoint = new UdpClient(); ReceiverThread = new Thread(Receiver); ReceiverThread.Start(); } public SNMPEngine(IPEndPoint localEndpoint) { LocalEndpoint = new UdpClient(localEndpoint); ReceiverThread = new Thread(Receiver); ReceiverThread.Start(); } public void Close() { shutdown = true; LocalEndpoint.Close(); } private void Receiver() { while (!shutdown) { try { IPEndPoint remoteEndpoint = null; byte[] datagram = LocalEndpoint.Receive(ref remoteEndpoint); Logging.Log(LogLevel.DEBUG,"SNMPClient: Received: {0}", BitConverter.ToString(datagram)); ASN1Value asn = new ASN1Value(datagram); asn.Dump(); SnmpMessage snmpMessage = asn; snmpMessage.Dump(); lock (queuedRequests) { if (queuedRequests.ContainsKey(snmpMessage.MessageID)) { SnmpMessage snmpRequestMessage = queuedRequests[snmpMessage.MessageID]; lock (snmpRequestMessage) { queuedRequests[snmpMessage.MessageID] = snmpMessage; Monitor.PulseAll(snmpRequestMessage); } } else { Logging.Log(LogLevel.WARNING, "SnmpEngine.Receiver(): Can't find pending request with MessageID {0} ( 0x{0:x8} )",snmpMessage.MessageID); } } } catch (SocketException se) { Logging.Log(se); } catch (Exception e) { Logging.Log(e); } } } 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 Dispose() { if (ReceiverThread != null) { if (ReceiverThread.IsAlive) { Close(); if (!ReceiverThread.Join(250)) { ReceiverThread.Abort(); } } ReceiverThread = null; } } } }