User login

Walk operation with SNMP version 1 and 2c

"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:

  • GET-NEXT requests in protocol versions 1, 2 or 3
  • "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:

    • GET-NEXT requests in protocol versions 1, 2 or 3
    • takes an OID and returns the OID following the requested MIB with the value associated with it

    • GET-BULK requests in protocol versions 2 and 3
    • 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.

    SNMP Version 1 GET-NEXT Example

    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();
            }
        }
    }

    Result of both examples

    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

Hi, First of all many thanks for a great Snmp library! I ran into the following problem: When I do an Snmp v2 bulk get on the OID 1.3.6.1.4.1.9.9.13.1.3.1.2 (for temperature sensors in a Cisco switch) I dont get any results. Whe I use an ordinary MIB Browser it does return results when querying this OID. The folowing error always seems to be thrown: NonRepeaters property is only available in GET-BULK PDU type Thanks! Vincent

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:

Pdu pdu = new Pdu();
pdu.Type = PduType.GetBulk;
pdu.NonRepeaters = 0;
pdu.MaxRepetitions = 200;
pdu.VbList.Add("1.3.6.1.4.1.9.9.13.1.3.1.2");
UdpTarget target = new UdpTarget(IPAddress.Parse("10.10.10.10"));
AgentParameters param = new AgentParameters(SnmpVersion.Ver2, new OctetString("public"));
SnmpV2Packet result = null;
try
{
	result = (SnmpV2Packet)target.Request(pdu, param);
}
catch (Exception ex)
{
	Console.WriteLine("Exception: {0}", ex.Message);
	target.Close();
	return;
}
if (result.Pdu.ErrorStatus != 0)
{
	Console.WriteLine("SNMP error {0} index {1}", result.Pdu.ErrorStatus, result.Pdu.ErrorIndex);
} else {
	foreach( Vb v in result.Pdu.VbList ) {
		if (v.Value.Type == SnmpConstants.SMI_ENDOFMIBVIEW)
			break;
		if (pdu.VbList[0].Oid.IsRootOf(v.Oid))
		{
			int[] subid = Oid.GetChildIdentifiers(pdu.VbList[0].Oid, v.Oid);
			if (subid.Length <= 0)
				break;
			Console.WriteLine("Instance {0}: {1}", subid[0].ToString(), v.Value.ToString());
		}
		else
			break;
	}
}
target.Close();
Hope this helps. Regards, MilanS

Check for SMI_ENDOFMIBVIEW in second sample

Hi there

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;
                            }
Thanks, Scott

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