2019-03-04 06:50:05 +01:00
|
|
|
|
// /**
|
|
|
|
|
// * 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;
|
2019-03-04 12:06:45 +01:00
|
|
|
|
using ln.snmp.types;
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Threading;
|
2019-03-11 08:57:19 +01:00
|
|
|
|
using ln.snmp.asn1;
|
|
|
|
|
using ln.logging;
|
2019-03-11 15:07:34 +01:00
|
|
|
|
using ln.snmp.endpoint;
|
2019-03-04 06:50:05 +01:00
|
|
|
|
|
|
|
|
|
namespace ln.snmp
|
|
|
|
|
{
|
2019-03-04 13:01:59 +01:00
|
|
|
|
public class SNMPEngine : IDisposable
|
2019-03-04 06:50:05 +01:00
|
|
|
|
{
|
2019-03-04 12:06:45 +01:00
|
|
|
|
public static bool DEBUG = false;
|
|
|
|
|
|
|
|
|
|
public UdpClient LocalEndpoint { get; private set; }
|
|
|
|
|
public int Timeout { get; set; } = 1000;
|
|
|
|
|
|
2019-03-11 08:57:19 +01:00
|
|
|
|
private Dictionary<int, SnmpMessage> queuedRequests = new Dictionary<int, SnmpMessage>();
|
2019-03-04 12:06:45 +01:00
|
|
|
|
private bool shutdown = false;
|
|
|
|
|
private Thread ReceiverThread { get; set; }
|
|
|
|
|
|
2019-03-11 15:07:34 +01:00
|
|
|
|
private Dictionary<IPEndPoint, SnmpEndpoint> currentEndpoints = new Dictionary<IPEndPoint, SnmpEndpoint>();
|
|
|
|
|
|
2019-03-11 08:57:19 +01:00
|
|
|
|
|
|
|
|
|
private int nextMessageID = (int)DateTimeOffset.Now.ToUnixTimeSeconds();
|
|
|
|
|
public int NextMessageID => nextMessageID++;
|
|
|
|
|
|
2019-03-04 20:48:25 +01:00
|
|
|
|
public SNMPEngine()
|
|
|
|
|
{
|
|
|
|
|
LocalEndpoint = new UdpClient();
|
|
|
|
|
ReceiverThread = new Thread(Receiver);
|
|
|
|
|
ReceiverThread.Start();
|
|
|
|
|
}
|
2019-03-04 13:01:59 +01:00
|
|
|
|
public SNMPEngine(IPEndPoint localEndpoint)
|
2019-03-04 06:50:05 +01:00
|
|
|
|
{
|
2019-03-04 12:06:45 +01:00
|
|
|
|
LocalEndpoint = new UdpClient(localEndpoint);
|
|
|
|
|
ReceiverThread = new Thread(Receiver);
|
|
|
|
|
ReceiverThread.Start();
|
|
|
|
|
}
|
2019-03-04 06:50:05 +01:00
|
|
|
|
|
2019-03-04 12:06:45 +01:00
|
|
|
|
public void Close()
|
|
|
|
|
{
|
|
|
|
|
shutdown = true;
|
|
|
|
|
LocalEndpoint.Close();
|
2019-03-04 06:50:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
2019-03-04 12:06:45 +01:00
|
|
|
|
private void Receiver()
|
|
|
|
|
{
|
|
|
|
|
while (!shutdown)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
IPEndPoint remoteEndpoint = null;
|
|
|
|
|
byte[] datagram = LocalEndpoint.Receive(ref remoteEndpoint);
|
|
|
|
|
|
2019-03-11 08:57:19 +01:00
|
|
|
|
Logging.Log(LogLevel.DEBUG,"SNMPClient: Received: {0}", BitConverter.ToString(datagram));
|
|
|
|
|
|
|
|
|
|
ASN1Value asn = new ASN1Value(datagram);
|
|
|
|
|
SnmpMessage snmpMessage = asn;
|
|
|
|
|
|
2019-03-12 00:54:39 +01:00
|
|
|
|
if (currentEndpoints.ContainsKey(remoteEndpoint))
|
2019-03-04 12:06:45 +01:00
|
|
|
|
{
|
2019-03-12 00:54:39 +01:00
|
|
|
|
SnmpEndpoint snmpEndpoint = currentEndpoints[remoteEndpoint];
|
|
|
|
|
snmpEndpoint.Received(snmpMessage);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Logging.Log(LogLevel.WARNING, "SnmpEngine.Receiver(): Received message from unknown endpoint ({0})",remoteEndpoint);
|
2019-03-04 12:06:45 +01:00
|
|
|
|
}
|
2019-03-04 06:50:05 +01:00
|
|
|
|
|
2019-03-04 12:06:45 +01:00
|
|
|
|
}
|
|
|
|
|
catch (SocketException se)
|
|
|
|
|
{
|
2019-03-12 00:54:39 +01:00
|
|
|
|
//Logging.Log(se);
|
2019-03-04 12:06:45 +01:00
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
2019-03-11 08:57:19 +01:00
|
|
|
|
Logging.Log(e);
|
2019-03-04 12:06:45 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-11 15:07:34 +01:00
|
|
|
|
public void SendMessage(IPEndPoint remoteEndpoint,SnmpMessage message)
|
|
|
|
|
{
|
|
|
|
|
ASN1Value snmpMessage = message;
|
|
|
|
|
byte[] snmpMessageBytes = snmpMessage.AsByteArray;
|
|
|
|
|
|
|
|
|
|
lock (LocalEndpoint)
|
|
|
|
|
{
|
|
|
|
|
LocalEndpoint.Send(snmpMessageBytes, snmpMessageBytes.Length, remoteEndpoint);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-12 00:54:39 +01:00
|
|
|
|
//public SnmpMessage SNMPRequest(IPEndPoint remoteEndpoint,SnmpMessage snmpMessage,int timeout)
|
|
|
|
|
//{
|
|
|
|
|
// lock (queuedRequests)
|
|
|
|
|
// {
|
|
|
|
|
// ASN1Value snmpRequest = snmpMessage;
|
|
|
|
|
// byte[] snmpRequestBytes = snmpRequest.AsByteArray;
|
2019-03-04 12:06:45 +01:00
|
|
|
|
|
2019-03-12 00:54:39 +01:00
|
|
|
|
// queuedRequests.Add(snmpMessage.MessageID, snmpMessage);
|
2019-03-04 12:06:45 +01:00
|
|
|
|
|
2019-03-12 00:54:39 +01:00
|
|
|
|
// 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();
|
2019-03-04 12:06:45 +01:00
|
|
|
|
|
2019-03-12 00:54:39 +01:00
|
|
|
|
// LocalEndpoint.Send(snmpRequestBytes, snmpRequestBytes.Length, remoteEndpoint);
|
2019-03-04 12:06:45 +01:00
|
|
|
|
|
2019-03-12 00:54:39 +01:00
|
|
|
|
// lock (snmpMessage)
|
|
|
|
|
// {
|
|
|
|
|
// Monitor.Exit(queuedRequests);
|
|
|
|
|
// bool success = Monitor.Wait(snmpMessage, timeout);
|
|
|
|
|
// Monitor.Enter(queuedRequests);
|
2019-03-11 08:57:19 +01:00
|
|
|
|
|
2019-03-12 00:54:39 +01:00
|
|
|
|
// if (!success)
|
|
|
|
|
// {
|
|
|
|
|
// queuedRequests.Remove(snmpMessage.MessageID);
|
|
|
|
|
// throw new TimeoutException();
|
|
|
|
|
// }
|
|
|
|
|
// }
|
2019-03-04 12:06:45 +01:00
|
|
|
|
|
2019-03-12 00:54:39 +01:00
|
|
|
|
// SnmpMessage responseMessage = queuedRequests[snmpMessage.MessageID];
|
|
|
|
|
// queuedRequests.Remove(snmpMessage.MessageID);
|
2019-03-04 12:06:45 +01:00
|
|
|
|
|
2019-03-12 00:54:39 +01:00
|
|
|
|
// return responseMessage;
|
|
|
|
|
// }
|
|
|
|
|
//}
|
2019-03-04 06:50:05 +01:00
|
|
|
|
|
2019-03-11 15:07:34 +01:00
|
|
|
|
public void RegisterEndpoint(SnmpEndpoint intf)
|
|
|
|
|
{
|
|
|
|
|
lock (currentEndpoints)
|
|
|
|
|
{
|
|
|
|
|
currentEndpoints.Add(intf.RemoteEndpoint,intf);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public void UnregisterEndpoint(SnmpEndpoint intf)
|
|
|
|
|
{
|
|
|
|
|
lock (currentEndpoints)
|
|
|
|
|
{
|
|
|
|
|
currentEndpoints.Remove(intf.RemoteEndpoint);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-03-04 12:06:45 +01:00
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
if (ReceiverThread != null)
|
|
|
|
|
{
|
|
|
|
|
if (ReceiverThread.IsAlive)
|
|
|
|
|
{
|
|
|
|
|
Close();
|
|
|
|
|
if (!ReceiverThread.Join(250))
|
|
|
|
|
{
|
|
|
|
|
ReceiverThread.Abort();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ReceiverThread = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-04 06:50:05 +01:00
|
|
|
|
}
|
|
|
|
|
}
|