Snmp.cpp
上传用户:qiye66692
上传日期:2022-04-25
资源大小:72k
文件大小:7k
源码类别:

SNMP编程

开发平台:

Visual C++

  1. #include "StdAfx.h"
  2. #include ".snmp.h"
  3. #include ".Mib.h"
  4. #include ".func.h"
  5. CSnmp::CSnmp( LPCSTR ip, LPCSTR community )
  6. {
  7. this->ip = ip;
  8. this->community.len = strlen(community);
  9. this->community.ptr = (smiLPBYTE)community;
  10. m_event.ResetEvent();
  11. }
  12. CSnmp::~CSnmp(void)
  13. {
  14. }
  15. bool CSnmp::Prepare()
  16. {
  17. smiUINT32 nMajorVersion;  // major version number of the WinSNMP API
  18.     smiUINT32 nMinorVersion;  // minor version number of the WinSNMP API
  19.     smiUINT32 nLevel;         // level of SNMP the implementation supports
  20.     smiUINT32 nTranslateMode; // default entity/context translation mode
  21.     smiUINT32 nRetransmitMode; // default retransmission mode 
  22. //加载snmp
  23. if( SNMPAPI_FAILURE == SnmpStartup( &nMajorVersion, &nMinorVersion, &nLevel, &nTranslateMode, &nRetransmitMode) )
  24. //五个参数作为接收参数返回SNMP的主版本号,副版本号,支持最高的操作标准,
  25. //默认的实体/上下文传输模式,默认的重发机制
  26. {
  27. AfxMessageBox("Startup SNMP Failed");
  28. return FALSE;
  29. }
  30. //建立会话
  31. hSession = SnmpCreateSession( NULL, NULL, CSnmp::Callback, (LPVOID)this );
  32. if( hSession == SNMPAPI_FAILURE )
  33. {
  34. AfxMessageBox("Create Session Failed");
  35. return FALSE;
  36. }
  37. //建立上下文句柄
  38. hContext = SnmpStrToContext( hSession, &community );
  39. if( hContext == SNMPAPI_FAILURE )
  40. {
  41. AfxMessageBox("Get Context Failed");
  42. return FALSE;
  43. }
  44. return TRUE;
  45. }
  46. bool CSnmp::GetTable( CStringArray* string, CRouter* router )
  47. {
  48. HSNMP_VBL hVbl;
  49. smiOID    oid_send;
  50. smiOID    oid_recv;
  51. smiVALUE  value;
  52. int  count;
  53. char buf[100];
  54. while(TRUE)
  55. {
  56. if( Send(string) == FALSE ) //string即请求列表
  57. {
  58. router->m_strName = "unknown";
  59. return FALSE;
  60. }
  61. if( Receive(hVbl) == FALSE )
  62. {
  63. router->m_strName = "unknown";
  64. return FALSE;
  65. }
  66. //计算返回列表数
  67. count = SnmpCountVbl( hVbl );
  68. for( int i = 0; i < count; i ++ )
  69. {
  70. //取回返回结果
  71. if( SNMPAPI_FAILURE == SnmpGetVb( hVbl, i+1, &oid_recv, &value ) )
  72. {
  73. AfxMessageBox("Get vb failed");
  74. return FALSE;
  75. }
  76. if( value.syntax == SNMP_SYNTAX_IPADDR ) //32位的internet地址
  77. {
  78. CString ip;
  79. ip.Format("%d.%d.%d.%d", value.value.string.ptr[0], value.value.string.ptr[1], value.value.string.ptr[2], value.value.string.ptr[3] );
  80. if( string->GetAt(i).Find(ipAdEntAddr) != -1 ) //ip
  81. {
  82. router->m_IpArray.Add( ip );
  83. }
  84. if( string->GetAt(i).Find(ipAdEntNetMask) != -1 ) //掩码
  85. {
  86. router->m_IpMaskArray.Add( ip );
  87. }
  88. //路由表中
  89. if( string->GetAt(i).Find(ipRouteDest) != -1 ) //目的
  90. {
  91. if( string->GetAt(i).Left(21) != ipRouteMask )
  92. router->m_DestArray.Add( ip );
  93. }
  94. if( string->GetAt(i).Find(ipRouteNextHop) != -1 ) //下一跳
  95. {
  96. router->m_NextHopArray.Add( ip );
  97. }
  98. if( string->GetAt(i).Find(ipRouteMask) != -1 ) //掩码
  99. {
  100. router->m_NetMaskArray.Add( ip );
  101. }
  102. }
  103. if( value.syntax == SNMP_SYNTAX_OCTETS ) //是串
  104. {
  105. if( string->GetAt(i).Find(sysName) != -1 )
  106. {
  107. router->m_strName = value.value.string.ptr;
  108. router->m_strName = router->m_strName.Left(value.value.string.len);
  109. }
  110. if( string->GetAt(i).Find(sysDescr) != -1 )
  111. {
  112. router->m_strDescr = value.value.string.ptr;
  113. router->m_strDescr = router->m_strDescr.Left(value.value.string.len);
  114. }
  115. }
  116. if( value.syntax == SNMP_SYNTAX_TIMETICKS )
  117. {
  118. int nHours, nMinutes, nSeconds;
  119. long nUpTime;
  120. nUpTime = value.value.uNumber / 100;
  121. nHours = (int)(nUpTime / 3600);
  122. nMinutes = (int)((nUpTime % 3600) / 60);
  123. nSeconds = (int)(nUpTime % 60);
  124. router->m_strUpTime.Format("%dhours, %dminutes, %dseconds", nHours, nMinutes, nSeconds );
  125. }
  126. SnmpStrToOid( string->GetAt(i), &oid_send );
  127. SnmpOidToStr( &oid_recv, 100, buf );
  128. string->SetAt( i, buf );
  129. }
  130. long result;
  131. SnmpOidCompare( &oid_send, &oid_recv, 10, &result ); //判断格式是否一致,决定是否继续循环
  132. if( result != 0 )
  133. return TRUE;
  134. }
  135. SnmpFreeVbl( hVbl );
  136. return TRUE;
  137. }
  138. bool CSnmp::Send( CStringArray* string )
  139. {
  140. HSNMP_VBL hVbl;
  141. HSNMP_PDU hPdu;
  142. HSNMP_ENTITY hSrcEntity, hDestEntity;
  143. smiOID oid;
  144. //创建变量捆绑列表
  145. hVbl = SnmpCreateVbl( hSession, NULL, NULL );
  146. if( hVbl == SNMPAPI_FAILURE )
  147. {
  148. return FALSE;
  149. }
  150. //for循环把请求列表reqList中的项都绑定好
  151. for( int i = 0; i < string->GetSize(); i ++ )
  152. {
  153. //converts the dotted numeric string format of an SNMP object identifierto its internal binary representation. 
  154. SnmpStrToOid( string->GetAt(i), &oid );
  155. //appends new variable binding entries to an existing variable bindings list. 
  156. SnmpSetVb(hVbl,0,&oid,NULL);
  157. }
  158. //按照特定pdu格式发送,该程序返回一个pdu句柄
  159. hPdu = SnmpCreatePdu( hSession, SNMP_PDU_GETNEXT, 0, NULL, NULL, hVbl);
  160. if( hPdu == SNMPAPI_FAILURE )
  161. {
  162. return FALSE;
  163. }
  164. // returns a handle to information about an SNMP management entity that is specific
  165. // to the Microsoft WinSNMP implementation
  166. hSrcEntity = SnmpStrToEntity( hSession, (LPCSTR)GetLocalIP() ); //源
  167. hDestEntity = SnmpStrToEntity( hSession, ip ); //目的
  168. if( hSrcEntity==SNMPAPI_FAILURE || hDestEntity==SNMPAPI_FAILURE ) 
  169. {
  170. return FALSE;
  171. }
  172. //发送
  173. if( SNMPAPI_FAILURE == SnmpSendMsg( hSession, hSrcEntity, hDestEntity, hContext, hPdu ) )
  174. {
  175. return FALSE;
  176. }
  177. //释放句柄
  178. SnmpFreeEntity( hSrcEntity );
  179. SnmpFreeEntity( hDestEntity );
  180. SnmpFreePdu( hPdu );
  181. SnmpFreeVbl( hVbl );
  182. return TRUE;
  183. }
  184. bool CSnmp::Receive(HSNMP_VBL& hVbl)
  185. {
  186. WaitForSingleObject( m_event, INFINITE);
  187. m_event.ResetEvent();
  188. HSNMP_ENTITY hSrcEntity;
  189. HSNMP_ENTITY hDestEntity;
  190. HSNMP_CONTEXT hContext;
  191. HSNMP_PDU hPdu;
  192. if( SNMPAPI_FAILURE == SnmpRecvMsg( hSession, &hSrcEntity, &hDestEntity, &hContext, &hPdu ) )
  193. {
  194. return FALSE;
  195. }
  196. smiINT PDU_type;
  197. smiINT error_status;
  198. smiINT error_index;
  199. if( SNMPAPI_FAILURE == SnmpGetPduData( hPdu, &PDU_type, NULL,//提取数据报
  200. &error_status, &error_index, &hVbl) )
  201. {
  202. return FALSE;
  203. }
  204. return TRUE;
  205. }
  206. bool CSnmp::Close()
  207. {
  208. SnmpFreeContext( hContext );
  209. SnmpClose( hSession );
  210. return TRUE;
  211. }
  212. SNMPAPI_STATUS CALLBACK CSnmp::Callback(
  213. HSNMP_SESSION hSession,  // handle to the WinSNMP session
  214. HWND hWnd,               // handle to the notification window
  215. UINT wMsg,               // window notification message number
  216. WPARAM wParam,           // type of notification
  217. LPARAM lParam,           // request identifier of PDU
  218. LPVOID lpClientData      // optional application-defined data
  219. )
  220. {
  221. ((CSnmp *)lpClientData)->m_event.SetEvent();
  222. return 1;
  223. }