2019-03-04 12:06:45 +01:00
|
|
|
|
using System;
|
|
|
|
|
using ln.snmp.types;
|
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
2019-03-11 15:07:34 +01:00
|
|
|
|
using ln.snmp.endpoint;
|
2019-03-04 20:48:25 +01:00
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
2019-03-04 12:06:45 +01:00
|
|
|
|
namespace ln.snmp
|
|
|
|
|
{
|
|
|
|
|
public enum SnmpVersion : int { V1 = 0, V2c = 1, V3 = 3 }
|
|
|
|
|
|
2019-03-11 15:07:34 +01:00
|
|
|
|
public abstract class SnmpInterface : IDisposable
|
2019-03-04 12:06:45 +01:00
|
|
|
|
{
|
2019-03-11 08:57:19 +01:00
|
|
|
|
public abstract SnmpVersion SnmpVersion { get; }
|
2019-03-04 12:06:45 +01:00
|
|
|
|
|
2019-03-11 15:07:34 +01:00
|
|
|
|
public SnmpInterface()
|
2019-03-04 12:06:45 +01:00
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-12 00:54:39 +01:00
|
|
|
|
public abstract PDU DispatchRequest(PDU pdu);
|
2019-03-04 12:06:45 +01:00
|
|
|
|
|
|
|
|
|
private List<Sequence> snmpRequest<T>(IEnumerable<ObjectIdentifier> objectIdentifiers) where T: PDU, new()
|
|
|
|
|
{
|
2019-03-04 20:48:25 +01:00
|
|
|
|
PDU pdu = new T();
|
2019-03-04 12:06:45 +01:00
|
|
|
|
foreach (ObjectIdentifier oid in objectIdentifiers)
|
|
|
|
|
{
|
|
|
|
|
pdu.Add(new Sequence(new Variable[] { oid, NullValue.Instance }));
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-12 00:54:39 +01:00
|
|
|
|
PDU responsePDU = DispatchRequest(pdu);
|
2019-03-11 08:57:19 +01:00
|
|
|
|
|
|
|
|
|
if (responsePDU.Error.LongValue != 0)
|
|
|
|
|
{
|
|
|
|
|
string indicator = responsePDU.ErrorIndex > 0 && responsePDU.ErrorIndex <= pdu.VarBinds.Items.Length ? ((pdu.VarBinds.Items[(int)responsePDU.ErrorIndex - 1] as Sequence).Items[0] as ObjectIdentifier).AsString : "";
|
|
|
|
|
throw new SnmpError(responsePDU.Error, responsePDU.ErrorIndex, indicator);
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-04 12:06:45 +01:00
|
|
|
|
Sequence varBinds = responsePDU.VarBinds as Sequence;
|
|
|
|
|
|
2019-03-04 20:48:25 +01:00
|
|
|
|
List<Sequence> results = new List<Sequence>();
|
2019-03-04 12:06:45 +01:00
|
|
|
|
foreach (Variable varBind in varBinds.Items)
|
|
|
|
|
{
|
2019-03-18 08:12:58 +01:00
|
|
|
|
results.Add(varBind as Sequence);
|
2019-03-04 12:06:45 +01:00
|
|
|
|
}
|
|
|
|
|
return results;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public List<Sequence> snmpGet(IEnumerable<ObjectIdentifier> objectIdentifiers)
|
|
|
|
|
{
|
|
|
|
|
return snmpRequest<GetRequest>(objectIdentifiers);
|
|
|
|
|
}
|
|
|
|
|
public Variable snmpGet(ObjectIdentifier objectIdentifier)
|
|
|
|
|
{
|
|
|
|
|
return snmpGet(new ObjectIdentifier[] { objectIdentifier })[0].Items[1];
|
|
|
|
|
}
|
|
|
|
|
public Variable snmpGet(string objectIdentifier)
|
|
|
|
|
{
|
|
|
|
|
return snmpGet(new ObjectIdentifier[] { new ObjectIdentifier(objectIdentifier) })[0].Items[1];
|
|
|
|
|
}
|
|
|
|
|
public List<Sequence> snmpGet(IEnumerable<String> objectIdentifiers)
|
|
|
|
|
{
|
|
|
|
|
return snmpGet(objectIdentifiers.Select((x) => new ObjectIdentifier(x)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public List<Sequence> snmpGetNext(IEnumerable<ObjectIdentifier> objectIdentifiers)
|
|
|
|
|
{
|
|
|
|
|
return snmpRequest<GetNextRequest>(objectIdentifiers);
|
|
|
|
|
}
|
|
|
|
|
public Sequence snmpGetNext(ObjectIdentifier objectIdentifier)
|
|
|
|
|
{
|
|
|
|
|
return snmpGetNext(new ObjectIdentifier[] { objectIdentifier })[0];
|
|
|
|
|
}
|
|
|
|
|
public Sequence snmpGetNext(string objectIdentifier)
|
|
|
|
|
{
|
|
|
|
|
return snmpGetNext(new ObjectIdentifier[] { new ObjectIdentifier(objectIdentifier) })[0];
|
|
|
|
|
}
|
|
|
|
|
public List<Sequence> snmpGetNext(IEnumerable<String> objectIdentifiers)
|
|
|
|
|
{
|
|
|
|
|
return snmpGetNext(objectIdentifiers.Select((x) => new ObjectIdentifier(x)));
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-04 20:48:25 +01:00
|
|
|
|
private PDU TryBulk(GetBulkRequest bulkRequest)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2019-03-12 00:54:39 +01:00
|
|
|
|
return DispatchRequest(bulkRequest);
|
2019-03-04 20:48:25 +01:00
|
|
|
|
} catch (SnmpError se)
|
|
|
|
|
{
|
|
|
|
|
if ((se.Error == 1)&&(bulkRequest.MaxRepetitions.LongValue > 1))
|
|
|
|
|
{
|
|
|
|
|
bulkRequest.MaxRepetitions.LongValue >>= 1;
|
|
|
|
|
return TryBulk(bulkRequest);
|
|
|
|
|
}
|
|
|
|
|
throw se;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* ToDO: Algorithm is not perfect, when receiving an inclomplete "row", the already received partial row is ignored
|
|
|
|
|
*/
|
|
|
|
|
public Sequence[][] snmpGetBulk(IEnumerable<ObjectIdentifier> objectIdentifiers, int maxRepetitions = 32)
|
|
|
|
|
{
|
|
|
|
|
ObjectIdentifier[] OIDs = objectIdentifiers.ToArray();
|
|
|
|
|
int ncolumns = OIDs.Length;
|
|
|
|
|
|
|
|
|
|
GetBulkRequest pdu = new GetBulkRequest();
|
|
|
|
|
pdu.MaxRepetitions.LongValue = maxRepetitions;
|
|
|
|
|
|
|
|
|
|
foreach (ObjectIdentifier oid in objectIdentifiers)
|
|
|
|
|
{
|
|
|
|
|
pdu.Add(new Sequence(new Variable[] { oid, NullValue.Instance }));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<Sequence[]> result = new List<Sequence[]>();
|
|
|
|
|
int nchunk;
|
|
|
|
|
bool inTree = false;
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
PDU responsePDU = TryBulk(pdu);
|
|
|
|
|
Variable[] values = responsePDU.VarBinds.Items;
|
|
|
|
|
|
|
|
|
|
nchunk = values.Length / ncolumns;
|
|
|
|
|
|
|
|
|
|
for (int n = 0; n < nchunk; n++)
|
|
|
|
|
{
|
2019-03-12 00:54:39 +01:00
|
|
|
|
inTree = false;
|
|
|
|
|
|
2019-03-04 20:48:25 +01:00
|
|
|
|
Sequence[] row = new Sequence[ncolumns];
|
|
|
|
|
for (int c = 0; c < ncolumns; c++)
|
|
|
|
|
{
|
|
|
|
|
Sequence v = values[(n * ncolumns) + c] as Sequence;
|
2019-03-12 00:54:39 +01:00
|
|
|
|
ObjectIdentifier oid = v.Items[0] as ObjectIdentifier;
|
|
|
|
|
if (OIDs[c].Contains(oid))
|
2019-03-04 20:48:25 +01:00
|
|
|
|
{
|
2019-03-21 07:43:35 +01:00
|
|
|
|
row[c] = new Sequence(new Variable[] { OIDs[c].IndexTo(oid), v.Items[1] });
|
2019-03-04 20:48:25 +01:00
|
|
|
|
inTree = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (inTree)
|
|
|
|
|
result.Add(row);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pdu.VarBinds.RemoveAll();
|
|
|
|
|
for (int c = 0; c < ncolumns; c++)
|
|
|
|
|
{
|
|
|
|
|
pdu.VarBinds.Add(new Sequence(new Variable[] { (responsePDU.VarBinds.Items[(ncolumns * (nchunk - 1)) + c] as Sequence).Items[0], NullValue.Instance }));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pdu.RequestID.LongValue++;
|
|
|
|
|
|
|
|
|
|
} while (inTree); //((nchunk == pdu.MaxRepetitions.LongValue) && inTree);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return result.ToArray();
|
|
|
|
|
}
|
2019-03-04 12:06:45 +01:00
|
|
|
|
|
|
|
|
|
public List<Sequence> snmpGetBulk(ObjectIdentifier objectIdentifier)
|
|
|
|
|
{
|
|
|
|
|
List<Sequence> results = new List<Sequence>();
|
|
|
|
|
List<Sequence> parts;
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
parts = snmpRequest<GetBulkRequest>(new ObjectIdentifier[] { objectIdentifier });
|
|
|
|
|
|
|
|
|
|
foreach (Sequence ps in parts)
|
|
|
|
|
{
|
|
|
|
|
ObjectIdentifier oid = ps.Items[0] as ObjectIdentifier;
|
|
|
|
|
if (objectIdentifier.Contains(oid))
|
2019-03-12 00:54:39 +01:00
|
|
|
|
{
|
2019-03-21 07:43:35 +01:00
|
|
|
|
results.Add(new Sequence(new Variable[] { objectIdentifier.IndexTo(oid), ps.Items[1] }));
|
2019-03-12 00:54:39 +01:00
|
|
|
|
}
|
2019-03-04 12:06:45 +01:00
|
|
|
|
else
|
|
|
|
|
return results;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} while (parts.Count >= 32);
|
|
|
|
|
|
|
|
|
|
return results;
|
|
|
|
|
}
|
|
|
|
|
public List<Sequence> snmpGetBulk(String objectIdentifier)
|
|
|
|
|
{
|
|
|
|
|
return snmpGetBulk(new ObjectIdentifier(objectIdentifier));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-03-04 20:48:25 +01:00
|
|
|
|
public Sequence[][] snmpWalk(IEnumerable<ObjectIdentifier> objectIdentifiers)
|
|
|
|
|
{
|
|
|
|
|
if (SnmpVersion == SnmpVersion.V1)
|
|
|
|
|
{
|
|
|
|
|
ObjectIdentifier[] OIDs = objectIdentifiers.ToArray();
|
|
|
|
|
ObjectIdentifier[] lastOIDs = objectIdentifiers.ToArray();
|
|
|
|
|
List<Sequence[]> results = new List<Sequence[]>();
|
|
|
|
|
|
|
|
|
|
bool cont = true;
|
|
|
|
|
while (cont)
|
|
|
|
|
{
|
|
|
|
|
cont = false;
|
|
|
|
|
List<Sequence> next = snmpGetNext(lastOIDs);
|
|
|
|
|
|
|
|
|
|
Sequence[] row = new Sequence[lastOIDs.Length];
|
|
|
|
|
|
|
|
|
|
for (int n = 0; n < lastOIDs.Length; n++)
|
|
|
|
|
{
|
|
|
|
|
lastOIDs[n] = next[n].Items[0] as ObjectIdentifier;
|
|
|
|
|
if (OIDs[n].Contains(lastOIDs[n]))
|
|
|
|
|
{
|
|
|
|
|
cont = true;
|
|
|
|
|
row[n] = next[n];
|
2019-03-18 08:12:58 +01:00
|
|
|
|
row[n].Items = new Variable[] { OIDs[n].IndexTo(lastOIDs[n]), next[n].Items[1] };
|
2019-03-04 20:48:25 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
row[n] = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-03-18 08:12:58 +01:00
|
|
|
|
if (cont)
|
|
|
|
|
results.Add(row);
|
2019-03-04 20:48:25 +01:00
|
|
|
|
}
|
|
|
|
|
return results.ToArray();
|
|
|
|
|
}
|
2019-03-11 08:57:19 +01:00
|
|
|
|
else
|
2019-03-04 20:48:25 +01:00
|
|
|
|
{
|
|
|
|
|
return snmpGetBulk(objectIdentifiers);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public Sequence[][] snmpWalk(IEnumerable<String> objectIdentifiers)
|
|
|
|
|
{
|
|
|
|
|
return snmpWalk(objectIdentifiers.Select((x) => new ObjectIdentifier(x)));
|
|
|
|
|
}
|
2019-03-04 12:06:45 +01:00
|
|
|
|
|
|
|
|
|
public List<Sequence> snmpWalk(ObjectIdentifier objectIdentifier)
|
|
|
|
|
{
|
|
|
|
|
if (SnmpVersion == SnmpVersion.V1)
|
|
|
|
|
{
|
|
|
|
|
List<Sequence> results = new List<Sequence>();
|
|
|
|
|
ObjectIdentifier oiLast = objectIdentifier;
|
|
|
|
|
|
|
|
|
|
while (objectIdentifier.Contains(oiLast))
|
|
|
|
|
{
|
|
|
|
|
Sequence next = snmpGetNext(oiLast);
|
|
|
|
|
oiLast = next.Items[0] as ObjectIdentifier;
|
|
|
|
|
if (objectIdentifier.Contains(oiLast))
|
|
|
|
|
results.Add(next);
|
|
|
|
|
}
|
|
|
|
|
return results;
|
2019-03-15 07:43:15 +01:00
|
|
|
|
} else
|
2019-03-04 12:06:45 +01:00
|
|
|
|
{
|
|
|
|
|
return snmpGetBulk(objectIdentifier);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public List<Sequence> snmpWalk(string objectIdentifier)
|
|
|
|
|
{
|
|
|
|
|
return snmpWalk(new ObjectIdentifier(objectIdentifier));
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-12 00:54:39 +01:00
|
|
|
|
|
2019-03-11 15:07:34 +01:00
|
|
|
|
public virtual void Dispose()
|
|
|
|
|
{
|
|
|
|
|
}
|
2019-03-04 12:06:45 +01:00
|
|
|
|
}
|
|
|
|
|
}
|