请选择 进入手机版 | 继续访问电脑版
查看: 664|回复: 0

[ASP.NET教程] C# 一个简单实用 SNMP 的例子

3万

主题

3万

帖子

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
100197
发表于 2015-11-23 18:11:16
SNMP 简单网络管理协议
  1. /**
  2. C# Network Programming
  3. by Richard Blum
  4. Publisher: Sybex
  5. ISBN: 0782141765
  6. */
  7. using System;
  8. using System.Text;
  9. using System.Net;
  10. using System.Net.Sockets;
  11. public class SimpleSNMP
  12. {
  13. public static void Main(string[] argv)
  14. {
  15. int commlength, miblength, datatype, datalength, datastart;
  16. int uptime = 0;
  17. string output;
  18. SNMP conn = new SNMP();
  19. byte[] response = new byte[1024];
  20. Console.WriteLine("Device SNMP information:");
  21. // Send sysName SNMP request
  22. response = conn.get("get", argv[0], argv[1], "1.3.6.1.2.1.1.5.0");
  23. if (response[0] == 0xff)
  24. {
  25. Console.WriteLine("No response from {0}", argv[0]);
  26. return;
  27. }
  28. // If response, get the community name and MIB lengths
  29. commlength = Convert.ToInt16(response[6]);
  30. miblength = Convert.ToInt16(response[23 + commlength]);
  31. // Extract the MIB data from the SNMP response
  32. datatype = Convert.ToInt16(response[24 + commlength + miblength]);
  33. datalength = Convert.ToInt16(response[25 + commlength + miblength]);
  34. datastart = 26 + commlength + miblength;
  35. output = Encoding.ASCII.GetString(response, datastart, datalength);
  36. Console.WriteLine(" sysName - Datatype: {0}, Value: 小贝",
  37. datatype, output);
  38. // Send a sysLocation SNMP request
  39. response = conn.get("get", argv[0], argv[1], "1.3.6.1.2.1.1.6.0");
  40. if (response[0] == 0xff)
  41. {
  42. Console.WriteLine("No response from {0}", argv[0]);
  43. return;
  44. }
  45. // If response, get the community name and MIB lengths
  46. commlength = Convert.ToInt16(response[6]);
  47. miblength = Convert.ToInt16(response[23 + commlength]);
  48. // Extract the MIB data from the SNMP response
  49. datatype = Convert.ToInt16(response[24 + commlength + miblength]);
  50. datalength = Convert.ToInt16(response[25 + commlength + miblength]);
  51. datastart = 26 + commlength + miblength;
  52. output = Encoding.ASCII.GetString(response, datastart, datalength);
  53. Console.WriteLine(" sysLocation - Datatype: {0}, Value: 小贝", datatype, output);
  54. // Send a sysContact SNMP request
  55. response = conn.get("get", argv[0], argv[1], "1.3.6.1.2.1.1.4.0");
  56. if (response[0] == 0xff)
  57. {
  58. Console.WriteLine("No response from {0}", argv[0]);
  59. return;
  60. }
  61. // Get the community and MIB lengths
  62. commlength = Convert.ToInt16(response[6]);
  63. miblength = Convert.ToInt16(response[23 + commlength]);
  64. // Extract the MIB data from the SNMP response
  65. datatype = Convert.ToInt16(response[24 + commlength + miblength]);
  66. datalength = Convert.ToInt16(response[25 + commlength + miblength]);
  67. datastart = 26 + commlength + miblength;
  68. output = Encoding.ASCII.GetString(response, datastart, datalength);
  69. Console.WriteLine(" sysContact - Datatype: {0}, Value: 小贝",
  70. datatype, output);
  71. // Send a SysUptime SNMP request
  72. response = conn.get("get", argv[0], argv[1], "1.3.6.1.2.1.1.3.0");
  73. if (response[0] == 0xff)
  74. {
  75. Console.WriteLine("No response from {0}", argv[0]);
  76. return;
  77. }
  78. // Get the community and MIB lengths of the response
  79. commlength = Convert.ToInt16(response[6]);
  80. miblength = Convert.ToInt16(response[23 + commlength]);
  81. // Extract the MIB data from the SNMp response
  82. datatype = Convert.ToInt16(response[24 + commlength + miblength]);
  83. datalength = Convert.ToInt16(response[25 + commlength + miblength]);
  84. datastart = 26 + commlength + miblength;
  85. // The sysUptime value may by a multi-byte integer
  86. // Each byte read must be shifted to the higher byte order
  87. while(datalength > 0)
  88. {
  89. uptime = (uptime << 8) + response[datastart++];
  90. datalength--;
  91. }
  92. Console.WriteLine(" sysUptime - Datatype: {0}, Value: 小贝",
  93. datatype, uptime);
  94. }
  95. }
  96. class SNMP
  97. {
  98. public SNMP()
  99. {
  100. }
  101. public byte[] get(string request, string host, string community, string mibstring)
  102. {
  103. byte[] packet = new byte[1024];
  104. byte[] mib = new byte[1024];
  105. int snmplen;
  106. int comlen = community.Length;
  107. string[] mibvals = mibstring.Split('.');
  108. int miblen = mibvals.Length;
  109. int cnt = 0, temp, i;
  110. int orgmiblen = miblen;
  111. int pos = 0;
  112. // Convert the string MIB into a byte array of integer values
  113. // Unfortunately, values over 128 require multiple bytes
  114. // which also increases the MIB length
  115. for (i = 0; i < orgmiblen; i++)
  116. {
  117. temp = Convert.ToInt16(mibvals[i]);
  118. if (temp > 127)
  119. {
  120. mib[cnt] = Convert.ToByte(128 + (temp / 128));
  121. mib[cnt + 1] = Convert.ToByte(temp - ((temp / 128) * 128));
  122. cnt += 2;
  123. miblen++;
  124. } else
  125. {
  126. mib[cnt] = Convert.ToByte(temp);
  127. cnt++;
  128. }
  129. }
  130. snmplen = 29 + comlen + miblen - 1; //Length of entire SNMP packet
  131. //The SNMP sequence start
  132. packet[pos++] = 0x30; //Sequence start
  133. packet[pos++] = Convert.ToByte(snmplen - 2); //sequence size
  134. //SNMP version
  135. packet[pos++] = 0x02; //Integer type
  136. packet[pos++] = 0x01; //length
  137. packet[pos++] = 0x00; //SNMP version 1
  138. //Community name
  139. packet[pos++] = 0x04; // String type
  140. packet[pos++] = Convert.ToByte(comlen); //length
  141. //Convert community name to byte array
  142. byte[] data = Encoding.ASCII.GetBytes(community);
  143. for (i = 0; i < data.Length; i++)
  144. {
  145. packet[pos++] = data[i];
  146. }
  147. //Add GetRequest or GetNextRequest value
  148. if (request == "get")
  149. packet[pos++] = 0xA0;
  150. else
  151. packet[pos++] = 0xA1;
  152. packet[pos++] = Convert.ToByte(20 + miblen - 1); //Size of total MIB
  153. //Request ID
  154. packet[pos++] = 0x02; //Integer type
  155. packet[pos++] = 0x04; //length
  156. packet[pos++] = 0x00; //SNMP request ID
  157. packet[pos++] = 0x00;
  158. packet[pos++] = 0x00;
  159. packet[pos++] = 0x01;
  160. //Error status
  161. packet[pos++] = 0x02; //Integer type
  162. packet[pos++] = 0x01; //length
  163. packet[pos++] = 0x00; //SNMP error status
  164. //Error index
  165. packet[pos++] = 0x02; //Integer type
  166. packet[pos++] = 0x01; //length
  167. packet[pos++] = 0x00; //SNMP error index
  168. //Start of variable bindings
  169. packet[pos++] = 0x30; //Start of variable bindings sequence
  170. packet[pos++] = Convert.ToByte(6 + miblen - 1); // Size of variable binding
  171. packet[pos++] = 0x30; //Start of first variable bindings sequence
  172. packet[pos++] = Convert.ToByte(6 + miblen - 1 - 2); // size
  173. packet[pos++] = 0x06; //Object type
  174. packet[pos++] = Convert.ToByte(miblen - 1); //length
  175. //Start of MIB
  176. packet[pos++] = 0x2b;
  177. //Place MIB array in packet
  178. for(i = 2; i < miblen; i++)
  179. packet[pos++] = Convert.ToByte(mib[i]);
  180. packet[pos++] = 0x05; //Null object value
  181. packet[pos++] = 0x00; //Null
  182. //Send packet to destination
  183. Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,
  184. ProtocolType.Udp);
  185. sock.SetSocketOption(SocketOptionLevel.Socket,
  186. SocketOptionName.ReceiveTimeout, 5000);
  187. IPHostEntry ihe = Dns.Resolve(host);
  188. IPEndPoint iep = new IPEndPoint(ihe.AddressList[0], 161);
  189. EndPoint ep = (EndPoint)iep;
  190. sock.SendTo(packet, snmplen, SocketFlags.None, iep);
  191. //Receive response from packet
  192. try
  193. {
  194. int recv = sock.ReceiveFrom(packet, ref ep);
  195. } catch (SocketException)
  196. {
  197. packet[0] = 0xff;
  198. }
  199. return packet;
  200. }
  201. public string getnextMIB(byte[] mibin)
  202. {
  203. string output = "1.3";
  204. int commlength = mibin[6];
  205. int mibstart = 6 + commlength + 17; //find the start of the mib section
  206. //The MIB length is the length defined in the SNMP packet
  207. // minus 1 to remove the ending .0, which is not used
  208. int miblength = mibin[mibstart] - 1;
  209. mibstart += 2; //skip over the length and 0x2b values
  210. int mibvalue;
  211. for(int i = mibstart; i < mibstart + miblength; i++)
  212. {
  213. mibvalue = Convert.ToInt16(mibin[i]);
  214. if (mibvalue > 128)
  215. {
  216. mibvalue = (mibvalue/128)*128 + Convert.ToInt16(mibin[i+1]);
  217. //ERROR here, it should be mibvalue = (mibvalue-128)*128 + Convert.ToInt16(mibin[i+1]);
  218. //for mib values greater than 128, the math is not adding up correctly
  219. i++;
  220. }
  221. output += "." + mibvalue;
  222. }
  223. return output;
  224. }
  225. }
复制代码


回复

使用道具 举报