155 lines
4.7 KiB
C#
155 lines
4.7 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;
|
|
|
|
namespace ln.snmp
|
|
{
|
|
public class SNMPClient : IDisposable
|
|
{
|
|
public static bool DEBUG = false;
|
|
|
|
public UdpClient LocalEndpoint { get; private set; }
|
|
public int Timeout { get; set; } = 1000;
|
|
|
|
private Dictionary<IPEndPoint, InternalRequest> queuedRequests = new Dictionary<IPEndPoint, InternalRequest>();
|
|
private bool shutdown = false;
|
|
private Thread ReceiverThread { get; set; }
|
|
|
|
public SNMPClient(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);
|
|
|
|
lock (queuedRequests)
|
|
{
|
|
if (queuedRequests.ContainsKey(remoteEndpoint))
|
|
{
|
|
InternalRequest internalRequest = queuedRequests[remoteEndpoint];
|
|
internalRequest.Response = datagram;
|
|
lock (internalRequest)
|
|
{
|
|
Monitor.PulseAll(internalRequest);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
catch (SocketException se)
|
|
{
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine("Receiver(): {0}", e);
|
|
}
|
|
}
|
|
}
|
|
|
|
private byte[] SendRequest(IPEndPoint remoteEndpoint,byte[] request,int timeout)
|
|
{
|
|
InternalRequest internalRequest = new InternalRequest();
|
|
internalRequest.RemoteEndpoint = remoteEndpoint;
|
|
|
|
lock(queuedRequests)
|
|
{
|
|
if (queuedRequests.ContainsKey(remoteEndpoint))
|
|
throw new ArgumentException("Already pending request exists for this remote endpoint", nameof(remoteEndpoint));
|
|
|
|
queuedRequests.Add(remoteEndpoint,internalRequest);
|
|
|
|
if (DEBUG)
|
|
Console.WriteLine("SNMPClient: Send: {0}", BitConverter.ToString(request));
|
|
|
|
LocalEndpoint.Send(request, request.Length, remoteEndpoint);
|
|
|
|
lock (internalRequest)
|
|
{
|
|
Monitor.Exit(queuedRequests);
|
|
bool success = Monitor.Wait(internalRequest, timeout);
|
|
Monitor.Enter(queuedRequests);
|
|
if (!success)
|
|
{
|
|
throw new TimeoutException();
|
|
}
|
|
}
|
|
queuedRequests.Remove(remoteEndpoint);
|
|
}
|
|
|
|
return internalRequest.Response;
|
|
}
|
|
|
|
|
|
public Variable SNMPRequest(IPEndPoint remoteEndpoint,Sequence request)
|
|
{
|
|
byte[] response = SendRequest(remoteEndpoint, request.ToBytes(), Timeout);
|
|
|
|
if (DEBUG)
|
|
Console.WriteLine("SNMPClient: Received: {0}", BitConverter.ToString(response));
|
|
|
|
Variable vreply = Variable.Read(response);
|
|
return vreply;
|
|
}
|
|
|
|
|
|
//public abstract List<Variable> Walk(ObjectIdentifier baseOID);
|
|
//public abstract List<Variable> Get(List<ObjectIdentifier> baseOID);
|
|
|
|
//public virtual Variable Get(ObjectIdentifier oid)
|
|
//{
|
|
// return Get(new List<ObjectIdentifier>(new ObjectIdentifier[] { oid }))[0];
|
|
//}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (ReceiverThread != null)
|
|
{
|
|
if (ReceiverThread.IsAlive)
|
|
{
|
|
Close();
|
|
if (!ReceiverThread.Join(250))
|
|
{
|
|
ReceiverThread.Abort();
|
|
}
|
|
}
|
|
ReceiverThread = null;
|
|
}
|
|
}
|
|
|
|
class InternalRequest
|
|
{
|
|
public IPEndPoint RemoteEndpoint;
|
|
public byte[] Response;
|
|
}
|
|
}
|
|
}
|