想实现功能:作一个企业局域网网络设备管理的软件。
比如通过交换机的管理IP,无需telnet登录,也无需登录密码,直接查看交换机状态。网上找了很多资料,大多推荐使用snmp协议,C#开发可使用SnmpSharpNet组件来做。
但仍然无从下手。
网上搜索的代码如下,主要是通过已知的交换机管理IP和交换机的OID来查询实现,但大多数时候交换机的OID信息是未知的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Net;
using SnmpSharpNet;namespace 交换机snmp.ClassFile
{
/// <summary>
/// 通过snmp获取交换机信息(需指定OID)
/// </summary>
class SnmpWork
{
public SnmpWork()
{
//
//TODO: 在此处添加构造函数逻辑
//
} #region 通过oid字符数组获得相应的值
public static Dictionary<string, string> getOIDValue(string host, string[] oid)
{
//返回变量
Dictionary<string, string> dic = new Dictionary<string, string>(); // SNMP community name
OctetString community = new OctetString("public"); // Define agent parameters class
AgentParameters param = new AgentParameters(community);
// Set SNMP version to 1 (or 2)
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(host); // Construct target
UdpTarget target = new UdpTarget((IPAddress)agent, 161, 2000, 1); // Pdu class used for all requests
Pdu pdu = new Pdu(PduType.Get); foreach (string singleoid in oid)
{
pdu.VbList.Add(singleoid);
} // Make SNMP request
SnmpV1Packet result = (SnmpV1Packet)target.Request(pdu, param); // 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)
{
for (int i = 0; i < result.Pdu.VbList.Count; i++)
{
dic.Add(result.Pdu.VbList[i].Oid.ToString(), result.Pdu.VbList[i].Value.ToString());
}
// Reply variables are returned in the same order as they were added
// to the VbList
}
}
target.Close();
return dic;
}
#endregion #region 通过snmpwalk返回oid根下面的所有值
public static Dictionary<string, string> getWalkValue(string host, string irootOid)
{
Dictionary<string, string> dic = new Dictionary<string, string>();
// 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(host); // 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(irootOid); // 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)
{
// 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))
{
dic.Add(v.Oid.ToString(), v.Value.ToString());
}
else
{
// we have reached the end of the requested
// MIB tree. Set lastOid to null and exit loop
lastOid = null;
}
}
}
}
}
target.Close();
return dic;
}
#endregion
}
}
昨天在网上找了一个小软件,名字叫“getif”。
经过测试,输入交换机的管理IP,能把交换机的OID信息、端口状态(up或者down)、以及交换机中mac-address-table中的信息都读了出来。
不明白其原理,希望大家能介绍点经验。
比如通过交换机的管理IP,无需telnet登录,也无需登录密码,直接查看交换机状态。网上找了很多资料,大多推荐使用snmp协议,C#开发可使用SnmpSharpNet组件来做。
但仍然无从下手。
网上搜索的代码如下,主要是通过已知的交换机管理IP和交换机的OID来查询实现,但大多数时候交换机的OID信息是未知的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Net;
using SnmpSharpNet;namespace 交换机snmp.ClassFile
{
/// <summary>
/// 通过snmp获取交换机信息(需指定OID)
/// </summary>
class SnmpWork
{
public SnmpWork()
{
//
//TODO: 在此处添加构造函数逻辑
//
} #region 通过oid字符数组获得相应的值
public static Dictionary<string, string> getOIDValue(string host, string[] oid)
{
//返回变量
Dictionary<string, string> dic = new Dictionary<string, string>(); // SNMP community name
OctetString community = new OctetString("public"); // Define agent parameters class
AgentParameters param = new AgentParameters(community);
// Set SNMP version to 1 (or 2)
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(host); // Construct target
UdpTarget target = new UdpTarget((IPAddress)agent, 161, 2000, 1); // Pdu class used for all requests
Pdu pdu = new Pdu(PduType.Get); foreach (string singleoid in oid)
{
pdu.VbList.Add(singleoid);
} // Make SNMP request
SnmpV1Packet result = (SnmpV1Packet)target.Request(pdu, param); // 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)
{
for (int i = 0; i < result.Pdu.VbList.Count; i++)
{
dic.Add(result.Pdu.VbList[i].Oid.ToString(), result.Pdu.VbList[i].Value.ToString());
}
// Reply variables are returned in the same order as they were added
// to the VbList
}
}
target.Close();
return dic;
}
#endregion #region 通过snmpwalk返回oid根下面的所有值
public static Dictionary<string, string> getWalkValue(string host, string irootOid)
{
Dictionary<string, string> dic = new Dictionary<string, string>();
// 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(host); // 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(irootOid); // 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)
{
// 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))
{
dic.Add(v.Oid.ToString(), v.Value.ToString());
}
else
{
// we have reached the end of the requested
// MIB tree. Set lastOid to null and exit loop
lastOid = null;
}
}
}
}
}
target.Close();
return dic;
}
#endregion
}
}
昨天在网上找了一个小软件,名字叫“getif”。
经过测试,输入交换机的管理IP,能把交换机的OID信息、端口状态(up或者down)、以及交换机中mac-address-table中的信息都读了出来。
不明白其原理,希望大家能介绍点经验。
Dictionary<string, string> dic_switch = ClassFiles.SnmpSwitchOid.getWalkValue(cbb_ip.Text.Trim(), ttx_oid.Text.Trim());
在public static Dictionary<string, string> getWalkValue(string host, string irootOid)
中,报错:“已添加了具有相同键的项”,说明Dictionary泛型值有重复的。
看来网上给的这段代码还是有问题的。
哎,竟没有一个回复啊。
呵呵,无言郁闷中...
string[] Str_oid = { "1.3.6.1.2.1.1.1.0", "1.3.6.1.2.1.1.2.0", "1.3.6.1.2.1.1.3.0", "1.3.6.1.2.1.1.4.0", "1.3.6.1.2.1.1.5.0", "1.3.6.1.2.1.1.7.0" };
Dictionary<string, string> dic_switch = ClassFiles.SnmpSwitchOid.getOIDValue(cbb_ip.Text.Trim(), Str_oid);
而这里的“getOIDValue”就是我上面贴的一个方法。
现在已经可以通过这些OID得到交换机的SysDescr、sysObjectId、sysUpTime、sysContact、sysName、
sysServices,但就是不知道获取交换机端口状态的oid是什么。
网上查了一些,比如:1.3.6.1.2.1.2.2.1.8,调不出来
将企业内用户IP等信息存在数据库,通过查看交换机的mac-address-table
可以防止IP冲突
随时浏览交换机状况
都很有好处
现在只从网上down了一个软件可以实现,但还是想自己做啊。
oid具体所代表的意思,就要你去查看MIB文件啦,里面有详细描述。建议:使用第三方软件先对你的交换机进行访问,分析后再在自己的程序里实现会好一些。 我用的第三方软件是SNMPc network manager有问题可以email我,尽量帮忙
尽管没有达到理想的效果,但还是谢谢rqx110,给了我很多启发。
最近比较忙,如果能做出来,我会把代码在这里贴出来,希望对其他朋友有所帮助。
以下是我修改后的代码。这是一个类,可以方便调用和修改
using System;
using System.Collections.Generic;
//using System.Web;
using System.Net;
using SnmpSharpNet;
/// <summary>
///SimpleSnmp 的摘要说明
/// </summary>
public class MySimpleSnmp
{
public MySimpleSnmp()
{
//
//TODO: 在此处添加构造函数逻辑
//
} #region 通过oid字符数组获得相应的值
public static Dictionary<string,string> getOIDValue(string host, string[] oid) {
//返回变量
Dictionary<string, string> dic = new Dictionary<string, string>(); // SNMP community name
OctetString community = new OctetString("public"); // Define agent parameters class
AgentParameters param = new AgentParameters(community);
// Set SNMP version to 1 (or 2)
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(host); // Construct target
UdpTarget target = new UdpTarget((IPAddress)agent, 161, 2000, 1); // Pdu class used for all requests
Pdu pdu = new Pdu(PduType.Get); foreach (string singleoid in oid) {
pdu.VbList.Add(singleoid);
} // Make SNMP request
SnmpV1Packet result = (SnmpV1Packet)target.Request(pdu, param); // 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)
{
for (int i = 0; i < result.Pdu.VbList.Count;i++ )
{
dic.Add(result.Pdu.VbList[i].Oid.ToString(), result.Pdu.VbList[i].Value.ToString());
}
// Reply variables are returned in the same order as they were added
// to the VbList
}
}
target.Close();
return dic;
}
#endregion #region 通过snmpwalk返回oid根下面的所有值
public static Dictionary<string, string> getWalkValue(string host,string irootOid) {
Dictionary<string, string> dic = new Dictionary<string, string>();
// 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(host); // Construct target
UdpTarget target = new UdpTarget((IPAddress)agent, 161, 2000, 5); // Define Oid that is the root of the MIB
// tree you wish to retrieve
Oid rootOid = new Oid(irootOid); // 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; int i = 1;//额外加个头
// 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)
{
// 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))
{
//dic.Add(v.Oid.ToString(), v.Value.ToString());
dic.Add(i.ToString(), v.Value.ToString());
i += 1;
}
else
{
// we have reached the end of the requested
// MIB tree. Set lastOid to null and exit loop
lastOid = null;
}
}
}
}
}
target.Close();
return dic;
}
#endregion
}目前还有个严重问题我还没解决,如果返回的值很多,就很容易超时或者过大什么的,我改了时间和重试次数都不行,请各位指教!
谢谢!