"Walk" is not a strictly speaking an SNMP operation. When you talk about "walking the MIB" you are talking about sequentially retrieving values from the MIB. To sequentially retrieve MIB values, you can use:
"Walk" is not a strictly speaking an SNMP operation. When you talk about "walking the MIB" you are talking about sequentially retrieving values from the MIB. To sequentially retrieve MIB values, you can use:
takes an OID and returns the OID following the requested MIB with the value associated with it
also takes an OID and then returns MaxRepetitions number of MIB entries following the requested OID
If you have any choice at all, you should always use GET-BULK. It results in fewer requests and much better retrieval speed.
using System; using System.Net; using SnmpSharpNet; namespace sharpwalk { class Program { static void Main(string[] args) { // SNMP community name OctetString community = new OctetString("public"); // Define agent parameters class AgentParameters param = new AgentParameters(community); // Set SNMP version to 1 param.Version = SnmpVersion.Ver1; // Construct the agent address object // IpAddress class is easy to use here because // it will try to resolve constructor parameter if it doesn't // parse to an IP address IpAddress agent = new IpAddress("127.0.0.1"); // Construct target UdpTarget target = new UdpTarget((IPAddress)agent, 161, 2000, 1); // Define Oid that is the root of the MIB // tree you wish to retrieve Oid rootOid = new Oid("1.3.6.1.2.1.2.2.1.2"); // ifDescr // This Oid represents last Oid returned by // the SNMP agent Oid lastOid = (Oid)rootOid.Clone(); // Pdu class used for all requests Pdu pdu = new Pdu(PduType.GetNext); // Loop through results while (lastOid != null) { // When Pdu class is first constructed, RequestId is set to a random value // that needs to be incremented on subsequent requests made using the // same instance of the Pdu class. if (pdu.RequestId != 0) { pdu.RequestId += 1; } // Clear Oids from the Pdu class. pdu.VbList.Clear(); // Initialize request PDU with the last retrieved Oid pdu.VbList.Add(lastOid); // Make SNMP request SnmpV1Packet result = (SnmpV1Packet)target.Request(pdu, param); // You should catch exceptions in the Request if using in real application. // If result is null then agent didn't reply or we couldn't parse the reply. if (result != null) { // ErrorStatus other then 0 is an error returned by // the Agent - see SnmpConstants for error definitions if (result.Pdu.ErrorStatus != 0) { // agent reported an error with the request Console.WriteLine("Error in SNMP reply. Error {0} index {1}", result.Pdu.ErrorStatus, result.Pdu.ErrorIndex); lastOid = null; break; } else { // Walk through returned variable bindings foreach (Vb v in result.Pdu.VbList) { // Check that retrieved Oid is "child" of the root OID if (rootOid.IsRootOf(v.Oid)) { Console.WriteLine("{0} ({1}): {2}", v.Oid.ToString(), SnmpConstants.GetTypeName(v.Value.Type), v.Value.ToString()); lastOid = v.Oid; } else { // we have reached the end of the requested // MIB tree. Set lastOid to null and exit loop lastOid = null; } } } } else { Console.WriteLine("No response received from SNMP agent."); } } target.Close(); } } } </pre> <h2>SNMP Version 2 GET-BULK Example</h2> <pre xml:lang="csharp">using System; using System.Net; using SnmpSharpNet; namespace sharpwalk { class Program { static void Main(string[] args) { // SNMP community name OctetString community = new OctetString("public"); // Define agent parameters class AgentParameters param = new AgentParameters(community); // Set SNMP version to 2 (GET-BULK only works with SNMP ver 2 and 3) param.Version = SnmpVersion.Ver2; // Construct the agent address object // IpAddress class is easy to use here because // it will try to resolve constructor parameter if it doesn't // parse to an IP address IpAddress agent = new IpAddress("127.0.0.1"); // Construct target UdpTarget target = new UdpTarget((IPAddress)agent, 161, 2000, 1); // Define Oid that is the root of the MIB // tree you wish to retrieve Oid rootOid = new Oid("1.3.6.1.2.1.2.2.1.2"); // ifDescr // This Oid represents last Oid returned by // the SNMP agent Oid lastOid = (Oid)rootOid.Clone(); // Pdu class used for all requests Pdu pdu = new Pdu(PduType.GetBulk); // In this example, set NonRepeaters value to 0 pdu.NonRepeaters = 0; // MaxRepetitions tells the agent how many Oid/Value pairs to return // in the response. pdu.MaxRepetitions = 5; // Loop through results while (lastOid != null) { // When Pdu class is first constructed, RequestId is set to 0 // and during encoding id will be set to the random value // for subsequent requests, id will be set to a value that // needs to be incremented to have unique request ids for each // packet if (pdu.RequestId != 0) { pdu.RequestId += 1; } // Clear Oids from the Pdu class. pdu.VbList.Clear(); // Initialize request PDU with the last retrieved Oid pdu.VbList.Add(lastOid); // Make SNMP request SnmpV2Packet result = (SnmpV2Packet)target.Request(pdu, param); // You should catch exceptions in the Request if using in real application. // If result is null then agent didn't reply or we couldn't parse the reply. if (result != null) { // ErrorStatus other then 0 is an error returned by // the Agent - see SnmpConstants for error definitions if (result.Pdu.ErrorStatus != 0) { // agent reported an error with the request Console.WriteLine("Error in SNMP reply. Error {0} index {1}", result.Pdu.ErrorStatus, result.Pdu.ErrorIndex); lastOid = null; break; } else { // Walk through returned variable bindings foreach (Vb v in result.Pdu.VbList) { // Check that retrieved Oid is "child" of the root OID if (rootOid.IsRootOf(v.Oid)) { Console.WriteLine("{0} ({1}): {2}", v.Oid.ToString(), SnmpConstants.GetTypeName(v.Value.Type), v.Value.ToString()); if (v.Value.Type == SnmpConstants.SMI_ENDOFMIBVIEW) lastOid = null; else lastOid = v.Oid; } else { // we have reached the end of the requested // MIB tree. Set lastOid to null and exit loop lastOid = null; } } } } else { Console.WriteLine("No response received from SNMP agent."); } } target.Close(); } } }
When I run either of the above examples on my notebook, I get following output:
1.3.6.1.2.1.2.2.1.2.1 (OctetString): Software Loopback Interface 1
1.3.6.1.2.1.2.2.1.2.2 (OctetString): WAN Miniport (L2TP)
1.3.6.1.2.1.2.2.1.2.3 (OctetString): WAN Miniport (PPTP)
1.3.6.1.2.1.2.2.1.2.4 (OctetString): WAN Miniport (PPPOE)
1.3.6.1.2.1.2.2.1.2.5 (OctetString): WAN Miniport (IPv6)
1.3.6.1.2.1.2.2.1.2.6 (OctetString): WAN Miniport (IP)
1.3.6.1.2.1.2.2.1.2.7 (OctetString): RAS Async Adapter
1.3.6.1.2.1.2.2.1.2.8 (OctetString): WAN Miniport (SSTP)
1.3.6.1.2.1.2.2.1.2.9 (OctetString): WAN Miniport (Network Monitor)
1.3.6.1.2.1.2.2.1.2.10 (OctetString): Realtek RTL8101E Family PCI-E FE NIC
1.3.6.1.2.1.2.2.1.2.11 (OctetString): Intel(R) PRO/Wireless 3945ABG Network Connection
1.3.6.1.2.1.2.2.1.2.12 (OctetString): Teredo Tunneling Pseudo-Interface
1.3.6.1.2.1.2.2.1.2.13 (OctetString): VMware Virtual Ethernet Adapter for VMnet1
1.3.6.1.2.1.2.2.1.2.14 (OctetString): isatap.{5D34A036-E8DD-4344-9CE3-58B461D1CB2A}
1.3.6.1.2.1.2.2.1.2.15 (OctetString): VMware Virtual Ethernet Adapter for VMnet8
1.3.6.1.2.1.2.2.1.2.16 (OctetString): isatap.{9195335D-923C-42BB-AC88-F54BC4501539}
1.3.6.1.2.1.2.2.1.2.17 (OctetString): isatap.hsd1.il.comcast.net.
1.3.6.1.2.1.2.2.1.2.18 (OctetString): Microsoft 6to4 Adapter
1.3.6.1.2.1.2.2.1.2.19 (OctetString): Microsoft ISATAP Adapter
1.3.6.1.2.1.2.2.1.2.20 (OctetString): WAN Miniport (IPv6)-QoS Packet Scheduler-0000
1.3.6.1.2.1.2.2.1.2.21 (OctetString): WAN Miniport (IP)-QoS Packet Scheduler-0000
1.3.6.1.2.1.2.2.1.2.22 (OctetString): WAN Miniport (Network Monitor)-QoS Packet Scheduler-0000
1.3.6.1.2.1.2.2.1.2.23 (OctetString): Realtek RTL8101E Family PCI-E FE NIC-QoS Packet Scheduler-0000
1.3.6.1.2.1.2.2.1.2.24 (OctetString): Intel(R) PRO/Wireless 3945ABG Network Connection-QoS [..]
1.3.6.1.2.1.2.2.1.2.25 (OctetString): Intel(R) PRO/Wireless 3945ABG Network Connection-Native [...]
Comments
No return result Bulk Get
Re: No return result Bulk Get
MY MISTAKE!
There is a bug in the static function Pdu.GetBulkPdu() method. It is fixed in version 0.7.5.
The exception you are getting is generated when Pdu type used for the request is not GetBulk.
I have created a small test utility that performs the same operation and it is working ok. Here is the code:
Check for SMI_ENDOFMIBVIEW in second sample
thanks very much for all your efforts on this library.
I needed to add a check to the v2 sample (possibly also required for v1?) to check for SMI_ENDOFMIBVIEW when walking a device with the incorrect community string. Without this, the code looped forever. The change is to the "Walk through returned variable bindings" section;
foreach (Vb v in result.Pdu.VbList) { // Check that retrieved Oid is "child" of the root OID if (rootOid.IsRootOf(v.Oid)) { strings.Add(string.Format("{0} ({1}): {2}", v.Oid.ToString(), SnmpConstants.GetTypeName(v.Value.Type), v.Value.ToString())); lastOid = v.Oid; if (v.Value.Type == SnmpConstants.SMI_ENDOFMIBVIEW) lastOid = null; }Fixed the example
Thanks Scott!
I have updated the above example with the appropriate fix.
EndOfMibView is a variable type specific to v2 and v3 so it will not apply to v1 requests.
-milans