.NET环境下的SNMP编程
下面的例子是通过SNMP获取指定IP的机器名。
运行结果如下图:
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace ConsoleSNMP
{
public class Program
{
static void Main()
{
string host = "192.168.1.1";
string communityName = "public";
SNMP conn = new SNMP();
byte[] response = new byte[1024];
Console.WriteLine("Device SNMP information:");
response = conn.get("GetRequest", host, communityName, "1.3.6.1.2.1.1.5.0");
if (response[0] == 0xff)
{
Console.WriteLine("No response from {0}", host);
return;
}
int commlength = Convert.ToInt16(response[6]);
int miblength = Convert.ToInt16(response[23 + commlength]);
int datatype = Convert.ToInt16(response[24 + commlength + miblength]);
int datalength = Convert.ToInt16(response[25 + commlength + miblength]);
int datastart = 26 + commlength + miblength;
string output = Encoding.ASCII.GetString(response, datastart, datalength);
Console.WriteLine(" 机器名: - Datatype: {0}, Value: {1}",
datatype, output);
Console.ReadLine();
}
}
class SNMP
{
public byte[] get(string request, string host, string community, string mibstring)
{
byte[] packet = new byte[1024];
byte[] mib = new byte[1024];
int snmplen;
int comlen = community.Length;
string[] mibvals = mibstring.Split('.');
int miblen = mibvals.Length;
int cnt = 0, temp=0, i=0;
int orgmiblen = miblen;
int pos = 0;
//将mib字符串格式转换为整数格式,如果值大于128需要多个字节空间保存,同时增加mib库的长度
for (i = 0; i < orgmiblen; i++)
{
temp = Convert.ToInt16(mibvals[i]);
if (temp > 127)
{
mib[cnt] = Convert.ToByte(128 + (temp / 128));
mib[cnt + 1] = Convert.ToByte(temp - ((temp / 128) * 128));
cnt += 2;
miblen++;
}
else
{
mib[cnt] = Convert.ToByte(temp);
cnt++;
}
}
snmplen = 29 + comlen + miblen - 1;
//snmp包序列开始
packet[pos++] = 0x30;
packet[pos++] = Convert.ToByte(snmplen - 2);
//snmp版本号
packet[pos++] = 0x02;//整数类型
packet[pos++] = 0x01;//长度
packet[pos++] = 0x01;//snmp 版本1
//团体名称
packet[pos++] = 0x04;//字符串类型
packet[pos++] = Convert.ToByte(comlen);//团体名称长度
byte[] data = Encoding.ASCII.GetBytes(community);
for (i = 0; i < data.Length; i++)
{
packet[pos++] = data[i];//转化团体名称到包中
}
//添加GetRequest 或是GetNextRequest 值
if (request == "GetRequest")
{
packet[pos++] = 0xA0;
}
else
{
packet[pos++] = 0xA1;
}
packet[pos++] = Convert.ToByte(20 + miblen - 1);
//Request ID
packet[pos++] = 0x02;//整数类型
packet[pos++] = 0x04;//长度
packet[pos++] = 0x00;//SNMP request ID
packet[pos++] = 0x00;
packet[pos++] = 0x00;
packet[pos++] = 0x01;
//错误状态
packet[pos++] = 0x02;//整数类型
packet[pos++] = 0x01;//长度
packet[pos++] = 0x00;//SNMP错误类型
//错误索引
packet[pos++] = 0x02;//整数类型
packet[pos++] = 0x01;//长度
packet[pos++] = 0x00;//SNMP错误索引
packet[pos++] = 0x30;//不同对象序列开始标志
packet[pos++] = Convert.ToByte(6 + miblen - 1);//不同对象的长度
packet[pos++] = 0x30;//对象序列的开始
packet[pos++] = Convert.ToByte(6 + miblen - 1 - 2);//尺寸
packet[pos++] = 0x06;//对象类型
packet[pos++] = Convert.ToByte(miblen - 1);//长度
//MIB信息开始位置
packet[pos++] = 0x2b;
//把MIB数字放入包中
for (i = 2; i < miblen; i++)
{
packet[pos++] = Convert.ToByte(mib[i]);
}
packet[pos++] = 0x05;//空对象值
packet[pos++] = 0x00;//空
//通过Socket把包送到指定机器
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000);
IPHostEntry ihe = Dns.Resolve(host);
IPEndPoint iep = new IPEndPoint(ihe.AddressList[0], 161);
EndPoint ep = (EndPoint)iep;
sock.SendTo(packet, snmplen, SocketFlags.None, iep);
try
{
int recv = sock.ReceiveFrom(packet, ref ep);//接受返回数据
}
catch (SocketException)
{
packet[0] = 0xff;
}
return packet;
}
}
}
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace ConsoleSNMP
{
public class Program
{
static void Main()
{
string host = "192.168.1.1";
string communityName = "public";
SNMP conn = new SNMP();
byte[] response = new byte[1024];
Console.WriteLine("Device SNMP information:");
response = conn.get("GetRequest", host, communityName, "1.3.6.1.2.1.1.5.0");
if (response[0] == 0xff)
{
Console.WriteLine("No response from {0}", host);
return;
}
int commlength = Convert.ToInt16(response[6]);
int miblength = Convert.ToInt16(response[23 + commlength]);
int datatype = Convert.ToInt16(response[24 + commlength + miblength]);
int datalength = Convert.ToInt16(response[25 + commlength + miblength]);
int datastart = 26 + commlength + miblength;
string output = Encoding.ASCII.GetString(response, datastart, datalength);
Console.WriteLine(" 机器名: - Datatype: {0}, Value: {1}",
datatype, output);
Console.ReadLine();
}
}
class SNMP
{
public byte[] get(string request, string host, string community, string mibstring)
{
byte[] packet = new byte[1024];
byte[] mib = new byte[1024];
int snmplen;
int comlen = community.Length;
string[] mibvals = mibstring.Split('.');
int miblen = mibvals.Length;
int cnt = 0, temp=0, i=0;
int orgmiblen = miblen;
int pos = 0;
//将mib字符串格式转换为整数格式,如果值大于128需要多个字节空间保存,同时增加mib库的长度
for (i = 0; i < orgmiblen; i++)
{
temp = Convert.ToInt16(mibvals[i]);
if (temp > 127)
{
mib[cnt] = Convert.ToByte(128 + (temp / 128));
mib[cnt + 1] = Convert.ToByte(temp - ((temp / 128) * 128));
cnt += 2;
miblen++;
}
else
{
mib[cnt] = Convert.ToByte(temp);
cnt++;
}
}
snmplen = 29 + comlen + miblen - 1;
//snmp包序列开始
packet[pos++] = 0x30;
packet[pos++] = Convert.ToByte(snmplen - 2);
//snmp版本号
packet[pos++] = 0x02;//整数类型
packet[pos++] = 0x01;//长度
packet[pos++] = 0x01;//snmp 版本1
//团体名称
packet[pos++] = 0x04;//字符串类型
packet[pos++] = Convert.ToByte(comlen);//团体名称长度
byte[] data = Encoding.ASCII.GetBytes(community);
for (i = 0; i < data.Length; i++)
{
packet[pos++] = data[i];//转化团体名称到包中
}
//添加GetRequest 或是GetNextRequest 值
if (request == "GetRequest")
{
packet[pos++] = 0xA0;
}
else
{
packet[pos++] = 0xA1;
}
packet[pos++] = Convert.ToByte(20 + miblen - 1);
//Request ID
packet[pos++] = 0x02;//整数类型
packet[pos++] = 0x04;//长度
packet[pos++] = 0x00;//SNMP request ID
packet[pos++] = 0x00;
packet[pos++] = 0x00;
packet[pos++] = 0x01;
//错误状态
packet[pos++] = 0x02;//整数类型
packet[pos++] = 0x01;//长度
packet[pos++] = 0x00;//SNMP错误类型
//错误索引
packet[pos++] = 0x02;//整数类型
packet[pos++] = 0x01;//长度
packet[pos++] = 0x00;//SNMP错误索引
packet[pos++] = 0x30;//不同对象序列开始标志
packet[pos++] = Convert.ToByte(6 + miblen - 1);//不同对象的长度
packet[pos++] = 0x30;//对象序列的开始
packet[pos++] = Convert.ToByte(6 + miblen - 1 - 2);//尺寸
packet[pos++] = 0x06;//对象类型
packet[pos++] = Convert.ToByte(miblen - 1);//长度
//MIB信息开始位置
packet[pos++] = 0x2b;
//把MIB数字放入包中
for (i = 2; i < miblen; i++)
{
packet[pos++] = Convert.ToByte(mib[i]);
}
packet[pos++] = 0x05;//空对象值
packet[pos++] = 0x00;//空
//通过Socket把包送到指定机器
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 5000);
IPHostEntry ihe = Dns.Resolve(host);
IPEndPoint iep = new IPEndPoint(ihe.AddressList[0], 161);
EndPoint ep = (EndPoint)iep;
sock.SendTo(packet, snmplen, SocketFlags.None, iep);
try
{
int recv = sock.ReceiveFrom(packet, ref ep);//接受返回数据
}
catch (SocketException)
{
packet[0] = 0xff;
}
return packet;
}
}
}
运行结果如下图:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述