/// <summary>SNMP WALK operation</summary> /// <remarks> /// When using SNMP version 1, walk is performed using GET-NEXT calls. When using SNMP version 2, /// walk is performed using GET-BULK calls. /// </remarks> /// <example>Example SNMP walk operation using SNMP version 1: /// <code> /// String snmpAgent = "10.10.10.1"; /// String snmpCommunity = "private"; /// SimpleSnmp snmp = new SimpleSnmp(snmpAgent, snmpCommunity); /// Dictionary<Oid, AsnType> result = snmp.Walk(SnmpVersion.Ver1, "1.3.6.1.2.1.1"); /// if( result == null ) { /// Console.WriteLine("Request failed."); /// } else { /// foreach (KeyValuePair<Oid, AsnType> entry in result) /// { /// Console.WriteLine("{0} = {1}: {2}", entry.Key.ToString(), SnmpConstants.GetTypeName(entry.Value.Type), /// entry.Value.ToString()); /// } /// </code> /// Will return: /// <code> /// 1.3.6.1.2.1.1.1.0 = OctetString: "Dual core Intel notebook" /// 1.3.6.1.2.1.1.2.0 = ObjectId: 1.3.6.1.9.233233.1.1 /// 1.3.6.1.2.1.1.3.0 = TimeTicks: 0d 0h 0m 1s 420ms /// 1.3.6.1.2.1.1.4.0 = OctetString: "*****@*****.**" /// 1.3.6.1.2.1.1.5.0 = OctetString: "milans-nbook" /// 1.3.6.1.2.1.1.6.0 = OctetString: "Developer home" /// 1.3.6.1.2.1.1.8.0 = TimeTicks: 0d 0h 0m 0s 10ms /// </code> /// /// To use SNMP version 2, change snmp.Set() method call first parameter to SnmpVersion.Ver2. /// </example> /// <param name="version">SNMP protocol version. Acceptable values are SnmpVersion.Ver1 and /// SnmpVersion.Ver2</param> /// <param name="rootOid">OID to start WALK operation from. Only child OIDs of the rootOid will be /// retrieved and returned</param> /// <returns>Oid => AsnType value mappings on success, empty dictionary if no data was found or /// null on error</returns> public Dictionary <Oid, AsnType> Walk(SnmpVersion version, string rootOid) { if (rootOid.Length < 2) { return(null); } Oid root = new Oid(rootOid); if (root.Length <= 0) { return(null); // unable to parse root oid } Oid lastOid = (Oid)root.Clone(); Dictionary <Oid, AsnType> result = new Dictionary <Oid, AsnType>(); while (lastOid != null && root.IsRootOf(lastOid)) { Dictionary <Oid, AsnType> val = null; if (version == SnmpVersion.Ver1) { val = GetNext(version, new string[] { lastOid.ToString() }); } else { val = GetBulk(new string[] { lastOid.ToString() }); } // check that we have a result if (val == null) { // error of some sort happened. abort... return(null); } foreach (KeyValuePair <Oid, AsnType> entry in val) { if (root.IsRootOf(entry.Key)) { result.Add(entry.Key, entry.Value); lastOid = (Oid)entry.Key.Clone(); } else { // it's faster to check if variable is null then checking IsRootOf lastOid = null; break; } } } return(result); }
/// <summary> /// Return child components of the leaf OID. /// </summary> /// <param name="root">Root Oid</param> /// <param name="leaf">Leaf Oid</param> /// <returns>Returns int array of child OIDs, if there was an error or no child IDs are present, returns null.</returns> public static uint[] GetChildIdentifiers(Oid root, Oid leaf) { uint[] tmp; if ((object)leaf == null || leaf.IsNull) { return(null); } if (((object)root == null || root.IsNull) && (object)leaf != null) { tmp = new uint[leaf.Length]; Array.Copy(leaf.GetData(), tmp, leaf.Length); return(tmp); } if (!root.IsRootOf(leaf)) { return(null); } if (leaf.Length <= root.Length) { return(null); // There are not child ids if this oid is longer } var leafLen = leaf.Length - root.Length; tmp = new uint[leafLen]; Array.Copy(leaf.GetData(), root.Length, tmp, 0, leafLen); return(tmp); }
/// <summary> /// Return child components of the leaf OID. /// </summary> /// <param name="root">Root Oid</param> /// <param name="leaf">Leaf Oid</param> /// <returns>Returns int array of child OIDs, if there was an error or no child IDs are present, returns null.</returns> public static UInt32[] GetChildIdentifiers(Oid root, Oid leaf) { UInt32[] tmp; if (((Object)leaf) == null || leaf.IsNull) { return(null); } else if ((((Object)root) == null || root.IsNull) && ((Object)leaf) != null) { tmp = new UInt32[leaf.Length]; Array.Copy(leaf.GetData(), tmp, leaf.Length); return(tmp); } if (!root.IsRootOf(leaf)) { // Has to be a child OID return(null); } if (leaf.Length <= root.Length) { return(null); // There are not child ids if this oid is longer } int leafLen = leaf.Length - root.Length; tmp = new UInt32[leafLen]; Array.Copy(leaf.GetData(), root.Length, tmp, 0, leafLen); return(tmp); }
/// <summary> /// Return child components of the leaf OID. /// </summary> /// <param name="root">Root Oid</param> /// <param name="leaf">Leaf Oid</param> /// <returns>Returns int array of child OIDs, if there was an error or no child IDs are present, returns null.</returns> public static int[] GetChildIdentifiers(Oid root, Oid leaf) { if (!root.IsRootOf(leaf)) { // Has to be a child OID return(null); } if (leaf.Length <= root.Length) { return(null); // There are not child ids if this oid is longer } int leafLen = leaf.Length - root.Length; int[] tmp = new int[leafLen]; Array.Copy(leaf.GetData(), root.Length, tmp, 0, leafLen); return(tmp); }
/// <summary>SNMP WALK operation</summary> /// <remarks> /// When using SNMP version 1, walk is performed using GET-NEXT calls. When using SNMP version 2, /// walk is performed using GET-BULK calls. /// </remarks> /// <example>Example SNMP walk operation using SNMP version 1: /// <code> /// String snmpAgent = "10.10.10.1"; /// String snmpCommunity = "private"; /// SimpleSnmp snmp = new SimpleSnmp(snmpAgent, snmpCommunity); /// Dictionary<Oid, AsnType> result = snmp.Walk(SnmpVersion.Ver1, "1.3.6.1.2.1.1"); /// if( result == null ) { /// Console.WriteLine("Request failed."); /// } else { /// foreach (KeyValuePair<Oid, AsnType> entry in result) /// { /// Console.WriteLine("{0} = {1}: {2}", entry.Key.ToString(), SnmpConstants.GetTypeName(entry.Value.Type), /// entry.Value.ToString()); /// } /// </code> /// Will return: /// <code> /// 1.3.6.1.2.1.1.1.0 = OctetString: "Dual core Intel notebook" /// 1.3.6.1.2.1.1.2.0 = ObjectId: 1.3.6.1.9.233233.1.1 /// 1.3.6.1.2.1.1.3.0 = TimeTicks: 0d 0h 0m 1s 420ms /// 1.3.6.1.2.1.1.4.0 = OctetString: "*****@*****.**" /// 1.3.6.1.2.1.1.5.0 = OctetString: "milans-nbook" /// 1.3.6.1.2.1.1.6.0 = OctetString: "Developer home" /// 1.3.6.1.2.1.1.8.0 = TimeTicks: 0d 0h 0m 0s 10ms /// </code> /// /// To use SNMP version 2, change snmp.Set() method call first parameter to SnmpVersion.Ver2. /// </example> /// <param name="version">SNMP protocol version. Acceptable values are SnmpVersion.Ver1 and /// SnmpVersion.Ver2</param> /// <param name="rootOid">OID to start WALK operation from. Only child OIDs of the rootOid will be /// retrieved and returned</param> /// <returns>Oid => AsnType value mappings on success, empty dictionary if no data was found or /// null on error</returns> public Dictionary <Oid, AsnType> Walk(SnmpVersion version, string rootOid) { if (!Valid) { if (!_suppressExceptions) { throw new SnmpException("SimpleSnmp class is not valid."); } return(null); } // function only works on SNMP version 1 and SNMP version 2 requests if (version != SnmpVersion.Ver1 && version != SnmpVersion.Ver2) { if (!_suppressExceptions) { throw new SnmpInvalidVersionException("SimpleSnmp support SNMP version 1 and 2 only."); } return(null); } if (rootOid.Length < 2) { if (!_suppressExceptions) { throw new SnmpException(SnmpException.InvalidOid, "RootOid is not a valid Oid"); } return(null); } Oid root = new Oid(rootOid); if (root.Length <= 0) { return(null); // unable to parse root oid } Oid lastOid = (Oid)root.Clone(); Dictionary <Oid, AsnType> result = new Dictionary <Oid, AsnType>(); while (lastOid != null && root.IsRootOf(lastOid)) { Dictionary <Oid, AsnType> val = null; if (version == SnmpVersion.Ver1) { val = GetNext(version, new string[] { lastOid.ToString() }); } else { val = GetBulk(new string[] { lastOid.ToString() }); } // check that we have a result if (val == null) { // error of some sort happened. abort... return(null); } foreach (KeyValuePair <Oid, AsnType> entry in val) { if (root.IsRootOf(entry.Key)) { if (result.ContainsKey(entry.Key)) { if (result[entry.Key].Type != entry.Value.Type) { throw new SnmpException(SnmpException.OidValueTypeChanged, "OID value type changed for OID: " + entry.Key.ToString()); } else { result[entry.Key] = entry.Value; } } else { result.Add(entry.Key, entry.Value); } lastOid = (Oid)entry.Key.Clone(); } else { // it's faster to check if variable is null then checking IsRootOf lastOid = null; break; } } } return(result); }
private static async Task <bool> WalkGetBulkAsync(IPAddress agent, string community, string oid, Func <Vb, bool> handleValue) { OctetString communityString = new OctetString(community); // Define agent parameters class AgentParameters param = new AgentParameters(communityString); // Set SNMP version to 2 (GET-BULK only works with SNMP ver 2 and 3) param.Version = SnmpVersion.Ver2; // Construct target UdpTarget target = new UdpTarget(agent, 161, 2000, 1); // Define Oid that is the root of the MIB // tree you wish to retrieve Oid rootOid = new Oid(oid); // 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 NonRepeaters = 0, // MaxRepetitions tells the agent how many Oid/Value pairs to return // in the response. 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 //var result = (SnmpV1Packet)target.Request(pdu, param); SnmpV2Packet result = (SnmpV2Packet)(await target.RequestAsync(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 //System.Diagnostics.Debug.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)) { //System.Diagnostics.Debug.WriteLine("{0} ({1}): {2}", // v.Oid.ToString(), // SnmpConstants.GetTypeName(v.Value.Type), // v.Value.ToString()); handleValue(v); 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 { //System.Diagnostics.Debug.WriteLine("No response received from SNMP agent."); } } target.Close(); return(true); }
private static bool WalkGetNext(IPAddress agent, string community, string oid, Func <Vb, bool> handleValue) { // SNMP community name OctetString communityString = new OctetString(community); // Define agent parameters class AgentParameters param = new AgentParameters(communityString) { // Set SNMP version to 1 Version = SnmpVersion.Ver1 }; // Construct target UdpTarget target = new UdpTarget(agent, 161, 2000, 1); // Define Oid that is the root of the MIB // tree you wish to retrieve Oid rootOid = new Oid(oid); // 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 //System.Diagnostics.Debug.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)) { //System.Diagnostics.Debug.WriteLine("{0} ({1}): {2}", // v.Oid.ToString(), // SnmpConstants.GetTypeName(v.Value.Type), // v.Value.ToString()); handleValue(v); lastOid = v.Oid; } else { // we have reached the end of the requested // MIB tree. Set lastOid to null and exit loop lastOid = null; } } } } else { //System.Diagnostics.Debug.WriteLine("No response received from SNMP agent."); } } target.Close(); return(true); }