157 lines
4.9 KiB
C#
157 lines
4.9 KiB
C#
// /**
|
|
// * 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<int, SnmpMessage> queuedRequests = new Dictionary<int, SnmpMessage>();
|
|
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;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|