Csharp/C Sharp/Network/SNMP

Материал из .Net Framework эксперт
Перейти к: навигация, поиск

Simple SNMP

<source lang="csharp"> /* C# Network Programming by Richard Blum Publisher: Sybex ISBN: 0782141765

  • /

using System; using System.Text; using System.Net; using System.Net.Sockets;

public class SimpleSNMP {

  public static void Main(string[] argv)
  {
     int commlength, miblength, datatype, datalength, datastart;
     int uptime = 0;
     string output;
     SNMP conn = new SNMP();
     byte[] response = new byte[1024];
     Console.WriteLine("Device SNMP information:");
     // Send sysName SNMP request
     response = conn.get("get", argv[0], argv[1], "1.3.6.1.2.1.1.5.0");
     if (response[0] == 0xff)
     {
        Console.WriteLine("No response from {0}", argv[0]);
        return;
     }
     // If response, get the community name and MIB lengths
     commlength = Convert.ToInt16(response[6]);
     miblength = Convert.ToInt16(response[23 + commlength]);
     // Extract the MIB data from the SNMP response
     datatype = Convert.ToInt16(response[24 + commlength + miblength]);
     datalength = Convert.ToInt16(response[25 + commlength + miblength]);
     datastart = 26 + commlength + miblength;
     output = Encoding.ASCII.GetString(response, datastart, datalength);
     Console.WriteLine("  sysName - Datatype: {0}, Value: {1}",
             datatype, output);
     // Send a sysLocation SNMP request
     response = conn.get("get", argv[0], argv[1], "1.3.6.1.2.1.1.6.0");
     if (response[0] == 0xff)
     {
        Console.WriteLine("No response from {0}", argv[0]);
        return;
     }
     // If response, get the community name and MIB lengths
     commlength = Convert.ToInt16(response[6]);
     miblength = Convert.ToInt16(response[23 + commlength]);
     // Extract the MIB data from the SNMP response
     datatype = Convert.ToInt16(response[24 + commlength + miblength]);
     datalength = Convert.ToInt16(response[25 + commlength + miblength]);
     datastart = 26 + commlength + miblength;
     output = Encoding.ASCII.GetString(response, datastart, datalength);
     Console.WriteLine("  sysLocation - Datatype: {0}, Value: {1}", datatype, output);
     // Send a sysContact SNMP request
     response = conn.get("get", argv[0], argv[1], "1.3.6.1.2.1.1.4.0");
     if (response[0] == 0xff)
     {
        Console.WriteLine("No response from {0}", argv[0]);
        return;
     }
     // Get the community and MIB lengths
     commlength = Convert.ToInt16(response[6]);
     miblength = Convert.ToInt16(response[23 + commlength]);
     // Extract the MIB data from the SNMP response
     datatype = Convert.ToInt16(response[24 + commlength + miblength]);
     datalength = Convert.ToInt16(response[25 + commlength + miblength]);
     datastart = 26 + commlength + miblength;
     output = Encoding.ASCII.GetString(response, datastart, datalength);
     Console.WriteLine("  sysContact - Datatype: {0}, Value: {1}",
             datatype, output);
     
     // Send a SysUptime SNMP request
     response = conn.get("get", argv[0], argv[1], "1.3.6.1.2.1.1.3.0");
     if (response[0] == 0xff)
     {
        Console.WriteLine("No response from {0}", argv[0]);
        return;
     }
     // Get the community and MIB lengths of the response
     commlength = Convert.ToInt16(response[6]);
     miblength = Convert.ToInt16(response[23 + commlength]);
     // Extract the MIB data from the SNMp response
     datatype = Convert.ToInt16(response[24 + commlength + miblength]);
     datalength = Convert.ToInt16(response[25 + commlength + miblength]);
     datastart = 26 + commlength + miblength;
     // The sysUptime value may by a multi-byte integer
     // Each byte read must be shifted to the higher byte order
     while(datalength > 0)
     {
        uptime = (uptime << 8) + response[datastart++];
        datalength--;
     }
     Console.WriteLine("  sysUptime - Datatype: {0}, Value: {1}",
            datatype, uptime);
  }

}

class SNMP {

  public 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, i;
     int orgmiblen = miblen;
     int pos = 0;
     // Convert the string MIB into a byte array of integer values
     // Unfortunately, values over 128 require multiple bytes
     // which also increases the MIB length
     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;  //Length of entire SNMP packet
     //The SNMP sequence start
     packet[pos++] = 0x30; //Sequence start
     packet[pos++] = Convert.ToByte(snmplen - 2);  //sequence size
     //SNMP version
     packet[pos++] = 0x02; //Integer type
     packet[pos++] = 0x01; //length
     packet[pos++] = 0x00; //SNMP version 1
     //Community name
     packet[pos++] = 0x04; // String type
     packet[pos++] = Convert.ToByte(comlen); //length
     //Convert community name to byte array
     byte[] data = Encoding.ASCII.GetBytes(community);
     for (i = 0; i < data.Length; i++)
     {
        packet[pos++] = data[i];
     }
     //Add GetRequest or GetNextRequest value
     if (request == "get")
        packet[pos++] = 0xA0;
     else
        packet[pos++] = 0xA1;
     packet[pos++] = Convert.ToByte(20 + miblen - 1); //Size of total MIB
     //Request ID
     packet[pos++] = 0x02; //Integer type
     packet[pos++] = 0x04; //length
     packet[pos++] = 0x00; //SNMP request ID
     packet[pos++] = 0x00;
     packet[pos++] = 0x00;
     packet[pos++] = 0x01;
     //Error status
     packet[pos++] = 0x02; //Integer type
     packet[pos++] = 0x01; //length
     packet[pos++] = 0x00; //SNMP error status
     //Error index
     packet[pos++] = 0x02; //Integer type
     packet[pos++] = 0x01; //length
     packet[pos++] = 0x00; //SNMP error index
     //Start of variable bindings
     packet[pos++] = 0x30; //Start of variable bindings sequence
     packet[pos++] = Convert.ToByte(6 + miblen - 1); // Size of variable binding
     packet[pos++] = 0x30; //Start of first variable bindings sequence
     packet[pos++] = Convert.ToByte(6 + miblen - 1 - 2); // size
     packet[pos++] = 0x06; //Object type
     packet[pos++] = Convert.ToByte(miblen - 1); //length
     //Start of MIB
     packet[pos++] = 0x2b;
     //Place MIB array in packet
     for(i = 2; i < miblen; i++)
        packet[pos++] = Convert.ToByte(mib[i]);
     packet[pos++] = 0x05; //Null object value
     packet[pos++] = 0x00; //Null
     //Send packet to destination
     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);
     //Receive response from packet
     try
     {
        int recv = sock.ReceiveFrom(packet, ref ep);
     } catch (SocketException)
     {
        packet[0] = 0xff;
     }
     return packet;
  }
  public string getnextMIB(byte[] mibin)
  {
     string output = "1.3";
     int commlength = mibin[6];
     int mibstart = 6 + commlength + 17; //find the start of the mib section
     //The MIB length is the length defined in the SNMP packet
    // minus 1 to remove the ending .0, which is not used
     int miblength = mibin[mibstart] - 1;
     mibstart += 2; //skip over the length and 0x2b values
     int mibvalue;
     for(int i = mibstart; i < mibstart + miblength; i++)
     {
        mibvalue = Convert.ToInt16(mibin[i]);
        if (mibvalue > 128)
        {
           mibvalue = (mibvalue/128)*128 + Convert.ToInt16(mibin[i+1]);
           i++;
        }
        output += "." + mibvalue;
     }
     return output;
  }

}


      </source>