.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;
        }
    }
}

运行结果如下图:

posted @ 2008-01-20 22:07  李华星  阅读(2000)  评论(0编辑  收藏  举报