Added GetBulkRequest, snmpWalk() for V2c
parent
138fe5eca3
commit
1b4c13e5f5
|
@ -27,6 +27,12 @@ namespace ln.snmp
|
|||
private bool shutdown = false;
|
||||
private Thread ReceiverThread { get; set; }
|
||||
|
||||
public SNMPEngine()
|
||||
{
|
||||
LocalEndpoint = new UdpClient();
|
||||
ReceiverThread = new Thread(Receiver);
|
||||
ReceiverThread.Start();
|
||||
}
|
||||
public SNMPEngine(IPEndPoint localEndpoint)
|
||||
{
|
||||
LocalEndpoint = new UdpClient(localEndpoint);
|
||||
|
|
138
SNMPInterface.cs
138
SNMPInterface.cs
|
@ -4,6 +4,8 @@ using System.Net;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ln.snmp.channel;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ln.snmp
|
||||
{
|
||||
public enum SnmpVersion : int { V1 = 0, V2c = 1, V3 = 3 }
|
||||
|
@ -25,24 +27,29 @@ namespace ln.snmp
|
|||
|
||||
private List<Sequence> snmpRequest<T>(IEnumerable<ObjectIdentifier> objectIdentifiers) where T: PDU, new()
|
||||
{
|
||||
T pdu = new T();
|
||||
PDU pdu = new T();
|
||||
foreach (ObjectIdentifier oid in objectIdentifiers)
|
||||
{
|
||||
pdu.Add(new Sequence(new Variable[] { oid, NullValue.Instance }));
|
||||
}
|
||||
|
||||
GetResponse responsePDU = PDUChannel.RequestResponse(pdu, RemoteEndpoint) as GetResponse;
|
||||
PDU responsePDU = snmpRequest(pdu);
|
||||
Sequence varBinds = responsePDU.VarBinds as Sequence;
|
||||
List<Sequence> results = new List<Sequence>();
|
||||
|
||||
List<Sequence> results = new List<Sequence>();
|
||||
foreach (Variable varBind in varBinds.Items)
|
||||
{
|
||||
results.Add(varBind as Sequence);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
private PDU snmpRequest(PDU pdu)
|
||||
{
|
||||
GetResponse responsePDU = PDUChannel.RequestResponse(pdu, RemoteEndpoint) as GetResponse;
|
||||
return responsePDU;
|
||||
}
|
||||
|
||||
public List<Sequence> snmpGet(IEnumerable<ObjectIdentifier> objectIdentifiers)
|
||||
{
|
||||
return snmpRequest<GetRequest>(objectIdentifiers);
|
||||
|
@ -77,6 +84,83 @@ namespace ln.snmp
|
|||
return snmpGetNext(objectIdentifiers.Select((x) => new ObjectIdentifier(x)));
|
||||
}
|
||||
|
||||
private PDU TryBulk(GetBulkRequest bulkRequest)
|
||||
{
|
||||
try
|
||||
{
|
||||
return snmpRequest(bulkRequest);
|
||||
} 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;
|
||||
inTree = false;
|
||||
|
||||
for (int n = 0; n < nchunk; n++)
|
||||
{
|
||||
Sequence[] row = new Sequence[ncolumns];
|
||||
for (int c = 0; c < ncolumns; c++)
|
||||
{
|
||||
Sequence v = values[(n * ncolumns) + c] as Sequence;
|
||||
if (OIDs[c].Contains(v.Items[0] as ObjectIdentifier))
|
||||
{
|
||||
row[c] = v;
|
||||
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();
|
||||
}
|
||||
|
||||
public List<Sequence> snmpGetBulk(ObjectIdentifier objectIdentifier)
|
||||
{
|
||||
|
@ -107,6 +191,52 @@ namespace ln.snmp
|
|||
}
|
||||
|
||||
|
||||
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];
|
||||
}
|
||||
else
|
||||
{
|
||||
row[n] = null;
|
||||
}
|
||||
}
|
||||
results.Add(row);
|
||||
}
|
||||
return results.ToArray();
|
||||
}
|
||||
else if (SnmpVersion == SnmpVersion.V2c)
|
||||
{
|
||||
return snmpGetBulk(objectIdentifiers);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
public Sequence[][] snmpWalk(IEnumerable<String> objectIdentifiers)
|
||||
{
|
||||
return snmpWalk(objectIdentifiers.Select((x) => new ObjectIdentifier(x)));
|
||||
}
|
||||
|
||||
public List<Sequence> snmpWalk(ObjectIdentifier objectIdentifier)
|
||||
{
|
||||
|
|
|
@ -39,7 +39,8 @@ namespace ln.snmp.channel
|
|||
|
||||
if (responsePDU.Error.LongValue != 0)
|
||||
{
|
||||
throw new SnmpError(responsePDU.Error, responsePDU.ErrorIndex, ((pdu.VarBinds.Items[(int)responsePDU.ErrorIndex - 1] as Sequence).Items[0] as ObjectIdentifier).AsString);
|
||||
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);
|
||||
}
|
||||
|
||||
return responsePDU;
|
||||
|
|
|
@ -28,9 +28,6 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="SharpSnmpLib">
|
||||
<HintPath>..\packages\Lextm.SharpSnmpLib.11.1.0\lib\net452\SharpSnmpLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Configuration" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -53,9 +50,6 @@
|
|||
<Compile Include="channel\SnmpV1Channel.cs" />
|
||||
<Compile Include="channel\SnmpV2Channel.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="types\" />
|
||||
<Folder Include="channel\" />
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Lextm.SharpSnmpLib" version="11.1.0" targetFramework="net47" />
|
||||
</packages>
|
Loading…
Reference in New Issue