SNMP管理器编程.doc_第1页
SNMP管理器编程.doc_第2页
SNMP管理器编程.doc_第3页
SNMP管理器编程.doc_第4页
SNMP管理器编程.doc_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

一、课程设计目的以及要求1) 课程设计目的 随着网络规模的不断扩大,网络结构也变得越来越复杂。用户对网络应用的需求不断提高,企业和用户对计算机网络的依赖程度也越来越高。在这种情况下,企业的管理者和用户对网络的性能、运行状况以及安全性也越来越重视。一个有效且实用的网络每时每刻都离不开网络管理。 网络管理是监督、组织和控制网络通信服务和信息处理所必需的各种活动的总称。除了专门的标准化组织制定了一些标准外,一些网络发展比较早的机构与厂家也制定了一些在各自网络上应用的管理标准,其中应用最广泛的是简单网络管理协议(Simple Network Management Protocol,SNMP)。 SNMP 是由 IETF 提出的面向 Internet的管理协议,其管理对象包括网桥、路由器、交换机等内存和处理能力有限的网络互连设备。SNMP 由于其简单性得到了业界广泛的支持,成为目前最流行的网络管理协议。 本课程设计的目的是通过编程实现 SNMP 协议,从而加深对 SNMP 协议的理解。 2) 课程设计要求 熟悉 SNMP 协议后,按如下要求编写程序,实现 SNMP 协议,获取路由器中的相关信息。 A)采用 VC 6.0 进行编程。 B)根据某路由器的 IP 及共同体名,获得该路由器的系统信息。 C)获取路由器的 IP 地址信息以及路由表信息;2、 原理分析 网管系统是指课管理真个网络及其中的网络设备的软件系统。网管系统设计4个方面的内容:网管功能、资源、信息及结构。其中,网管功能由ISO网络管理功能域定义:网管资源的表示涉及资源的表示方法,主要包括网络中硬件,软件与服务等资源;网管信息的表示方法与传输方式,由网管系统采用的网络管理协议决定;网管系统的结构主要包括两层结构与三层结构。SNMP网管系统采用客户机/服务器工作模式。SNMP网管系统包括两个组成部分:SNMP客户机与SNMP服务器。其中,SNMP客户机是SNMP服务的请求者,他安装在网管管理工作站中,通常被称为SNMP管理器:SNMP服务器是SNMP服务的响应者,它安装在支持SNMP服务的网络设备中,通常被称为SNMP代理。管理信息保存在SNMP代理的MIB中。SNMP服务在传输层采用UDP协议,在传输管理信息之前不需要先建立连接。需要注意的是,SNMP代理主动发送Trap信息给SNMP管理器。3、 基本思路及关键问题的解决方法显示相关信息 结束开始实例化CSnmp,并用IP和团体名初始化调用CSnmp类中的Prepare函数,完成SNMP的加载、会话的建立等填充请求列表,列表中存放的实际上是objectID调用CSnmp类中的GetTable函数,根据请求列表查路由表信息,放到一个CRouter类里释放资源1)程序流程图 程序流程图如图1所示: 图1 程序流程图 2)基本思路 首先,加载SNMP(包括SNMP主版本号、SNMP副版本号、支持的最高操作标准、默认的实体/上下文传输模式以及默认的重发机制);建立会话,在此过程中得到的会话句柄非常重要;设置传输模式SnmpSetTranslateMode和重传模式SnmpSetRetransmitMode,这两个函数的参数就是加载SNMP时使用的传输模式以及重发机制;创建实体HSNMP_ENTITY,第一个参数是步骤2中得到的句柄。IP可以是发送消息的网络设备的IP地址或接收消息的管理设备的IP地址,通过需要具体创建实体hSrcEntity、hDestEntity;对源实体和目的实体设置超时时间和重传次数SnmpSetTimeout、SnmpSetRetry;建立上下文句柄HSNMP_CONTEXT、hContext;建立变量捆绑列表;设置PDU格式,要正确发送数据必须采用特定的PDU格式;发送SNMP命令SnmpSendMsg;接收SNMP响应;等到响应成功就释放资源。3)关键问题及解决方案 1.如何设置PDU格式 PDU是SNMP数据包的一个部分,它包括请求标识符、错误状态、错误索引以及捆绑的变量名称。因此设置PDU格式是此程序的关键部分。HSNMP_PDU hPdu;hPdu=SnmpCreatePdu(hSession,SNMP_PDU_GETNEXT,0,NULL,NULL,hVbl) 第二个参数是PDU类型,有多种操作方式:SNMP_PDU_GETNEXT用来在不了解该表时获取第一个组值,SNMP_PDU_GET用来获得某个对象某个对象标识符的值;SNMP_PDU_SET用来修改某个对象标识符的值。 2.如何接收和响应SNMP 要接收和响应SNMP就先得创建实体,然后SNMP管理器调用函数,接收从SNMP代理返回的SNMP响应,SNMP管理器需要解析SNMP响应数据包,对各个字段逐个进行分析与判断,SNMP管理器需要分析错误类型字段,判断是否成功完成对管理对象的操作。 hSrcEntity = SnmpStrToEntity (hSession,(LPCSTR)GetLocalIP()); hDestEntity = SnmpStrToEntity(hSession,ip);4、 源代码#include winsock2.h#include Winsnmp.h#include #include #include #include #pragma comment(lib,wsnmp32.lib)#pragma comment(lib,ws2_32.lib)using namespace std;typedef vector strvec;typedef vector strvec_vec;class CManagerpublic:CManager(string strIP,string strCommunity); /构造函数CManager(); /析构函数string ValueToString(smiVALUE sValue); /返回值转换 bool InitSnmp(); /用于加载SNMPbool Send(const strvec& strOIDArray,smiINT sPDUType=SNMP_PDU_GETNEXT);bool Receive(HSNMP_VBL& hVbl); /接收应答包bool GetAValue(const string& strOID,string& strResult); /获取ObjectID值bool GetTable(strvec strOIDArray,strvec_vec& strResultTable); string GetLocalIP(); /获取本机IP地址void ErrorMessage(string strMessage); /输出错误信息void SetEvent(); protected:HSNMP_SESSION m_hSession; /会话句柄HSNMP_CONTEXT m_hContext; /上下文句柄static SNMPAPI_STATUS CALLBACK Callback( HSNMP_SESSION hSession, /WinSNMP会话句柄 HWND hWnd, /处理通知窗口的句柄 UINT wMsg, /窗口消息通知码 WPARAM wParam, /消息类型 LPARAM lParam, /PDU的请求标识符 LPVOID lpClientData /可选的自定义数据);private:smiUINT32 m_nMajorVersion; /WinSNMP API主版本smiUINT32 m_nMinorVersion; /WinSNMP API副版本smiUINT32 m_nLevel; /支持最高的操作标准smiUINT32 m_nTranslateMode; /默认实体/上下文模式smiUINT32 m_nRetransmitMode; /默认的重发机制string m_IP; /IP地址smiOCTETS m_Community; /团体名HANDLE m_hEvent;/ 构造函数CManager:CManager(string strIP,string strCommunity):m_nMajorVersion(0),m_nMinorVersion(0),m_nLevel(0),m_nTranslateMode(0),m_nRetransmitMode(0),m_IP(strIP)m_Community.len=strCommunity.length(); m_Community.ptr=new smiBYTEstrCommunity.length(); memcpy(m_Community.ptr,strCommunity.c_str(),strCommunity.length(); m_hEvent=CreateEvent(NULL,true,false,NULL);/析构函数CManager:CManager()SnmpFreeContext(m_hContext); SnmpClose(m_hSession); SnmpCleanup(); delete m_Community.ptr;/SNMP初始化函数bool CManager:InitSnmp()/加载SNMP if(SnmpStartup(&m_nMajorVersion,&m_nMinorVersion,&m_nLevel,&m_nTranslateMode,&m_nRetransmitMode)=SNMPAPI_FAILURE) ErrorMessage(startup SNMP error!); return false; /设置传输模式 if (SnmpSetTranslateMode(m_nTranslateMode)=SNMPAPI_FAILURE) ErrorMessage(Set transfer mode error!); return false; /设置重传模式 if (SnmpSetRetransmitMode(m_nRetransmitMode)=SNMPAPI_FAILURE) ErrorMessage(Set retransmission mode error!); return false; /建立会话 m_hSession=SnmpCreateSession(NULL,NULL,CManager:Callback,(LPVOID)this); if(m_hSession=SNMPAPI_FAILURE) ErrorMessage(Set conversation error!); return false; /建立实体 HSNMP_ENTITY hEntity; if(hEntity=SnmpStrToEntity(m_hSession,m_IP.c_str()=SNMPAPI_FAILURE) ErrorMessage(Creat entity error!); return false; /建立上下文句柄 if(m_hContext=SnmpStrToContext(m_hSession,&m_Community)=SNMPAPI_FAILURE) ErrorMessage(Create context handle error!); return false; /设置超时时间 if (SnmpSetTimeout(hEntity,10)=SNMPAPI_FAILURE) ErrorMessage(Set timeout error!); return false; /设置重传次数 if (SnmpSetRetry(hEntity,1)=SNMPAPI_FAILURE) ErrorMessage(Set retransmissions error!); return false; return true;/SNMP消息发送函数bool CManager:Send(const strvec& strOIDArray,smiINT sPDUType)HSNMP_VBL hVbl;HSNMP_PDU hPdu;smiOID sOid;HSNMP_ENTITY hSrcEntity,hDestEntity;/创建源主机和目的主机实体句柄hSrcEntity = SnmpStrToEntity(m_hSession,GetLocalIP().c_str();hDestEntity = SnmpStrToEntity(m_hSession,m_IP.c_str();/创建变量绑定列表if(hVbl = SnmpCreateVbl(m_hSession,NULL,NULL) = SNMPAPI_FAILURE)return false;/点分十进制串转换成二进制格式for(strvec:const_iterator it=strOIDArray.begin();it!=strOIDArray.end();it+)SnmpStrToOid(*it).c_str(),&sOid);SnmpSetVb(hVbl,0,&sOid,NULL);/将数据转换成特定PDU格式if(hPdu = SnmpCreatePdu(m_hSession,sPDUType,0,NULL,NULL,hVbl) = SNMPAPI_FAILURE)return false;/发送PDUif(SnmpSendMsg(m_hSession,hSrcEntity,hDestEntity,m_hContext,hPdu) = SNMPAPI_FAILURE)return false;/释放句柄SnmpFreeEntity(hSrcEntity);SnmpFreeEntity(hDestEntity);SnmpFreePdu(hPdu);SnmpFreePdu(hVbl);return true;/SNMP消息接收函数bool CManager:Receive(HSNMP_VBL& hVbl)WaitForSingleObject(m_hEvent,INFINITE);ResetEvent(m_hEvent);HSNMP_ENTITY hSrcEntity;HSNMP_ENTITY hDestEntity;HSNMP_CONTEXT hContext;HSNMP_PDU hPdu;/接收到消息if(SnmpRecvMsg(m_hSession,&hSrcEntity,&hDestEntity,&hContext,&hPdu) = SNMPAPI_FAILURE)return false;smiINT PDU_type;smiINT error_status;smiINT error_index;/提取PDU中的数据if(SnmpGetPduData(hPdu,&PDU_type,NULL,&error_status,&error_index,&hVbl) = SNMPAPI_FAILURE)return false;return true;/SNMP数值转换函数string CManager:ValueToString(smiVALUE sValue)char cBuffer1500;memset(cBuffer,0,1500);switch(sValue.syntax)case SNMP_SYNTAX_NSAPADDR:case SNMP_SYNTAX_IPADDR:sprintf(cBuffer,%d.%d.%d.%d,sValue.value.string.ptr0,sValue.value.string.ptr1,sValue.value.string.ptr2,sValue.value.string.ptr3);break;case SNMP_SYNTAX_OPAQUE:case SNMP_SYNTAX_OCTETS:if(sValue.value.string.len=0)sprintf(cBuffer,OCTETS NULL);elsememset(sValue.value.string.ptr+sValue.value.string.len,0,1);sprintf(cBuffer,%s,sValue.value.string.ptr);break;case SNMP_SYNTAX_TIMETICKS:int iHours,iMinutes,iSeconds;long lUptime;lUptime=sValue.value.uNumber/100;iHours=(int)(lUptime/3600);iMinutes=(int)(lUptime%3600)/60);iSeconds=(int)(lUptime%60);sprintf(cBuffer,%d时,%d分,%d秒,iHours,iMinutes,iSeconds);break;case SNMP_SYNTAX_INT:sprintf(cBuffer,%d,sValue.value.sNumber);break;case SNMP_SYNTAX_UINT32:case SNMP_SYNTAX_CNTR32:case SNMP_SYNTAX_GAUGE32:sprintf(cBuffer,%U,sValue.value.uNumber);break;default:sprintf(cBuffer,NULL);break;return string(cBuffer);/获得路由器信息函数bool CManager:GetAValue(const string& strOID,string& strResult)HSNMP_VBL hVbl;smiOID sOIDRecv;smiVALUE sValue;int iCount;strvec strOIDArray;strOIDArray.push_back(strOID+.0);/发送请求列表string没有成功if(!Send(strOIDArray,SNMP_PDU_GET)return false;/没有接收到应答if(!Receive(hVbl)return false;/计算返回Vbl的行数iCount = SnmpCountVbl(hVbl);if(iCount!=1)strResult=SnmpCounVbl error!;return false;/取返回结果if(SnmpGetVb(hVbl,1,&sOIDRecv,&sValue) = SNMPAPI_FAILURE)strResult=SnmpGetVb error!;return false;strResult=ValueToString(sValue);SnmpFreeVbl(hVbl);return true;/获得路由表信息函数bool CManager:GetTable(strvec strOIDArray, strvec_vec& strResultTable)long lIfEnd;HSNMP_VBL hVbl;smiOID sOIDSend;smiOID sOIDRecv;smiVALUE sValue;int iCount,iOIDLen;char cBuffer100;if (strOIDArray.empty()return false;/计算OID标识符的长度iOIDLen=count(strOIDArray0).begin(),(strOIDArray0).end(),.)+1;while(true)/发送请求列表string没有成功if(!Send(strOIDArray)return false;/没有接收到应答if(!Receive (hVbl)return false;/计算返回Vbl的行数iCount = SnmpCountVbl(hVbl);for(int i=0;ih_addr_list0);return HostIP;/错误信息函数void CManager:ErrorMessage(string strMessage)coutstrMessageSetEvent();return 1;/ Main.CPP: 主函数的实现/#include Manager.hvoid main(int argc,char *argv)/检查输入命令格式if(argc!=3)coutPlease input command:SnmpManager ip_address communityendl;return;/初始化CManger对象 CManager cManger(argv1,argv2);bool Status=cManger.InitSnmp();/输出路由器的基本信息cout-GetValue Text-endl;string Result;if(Status=cManger.GetAValue(1.3.6.1.2.1.1.1,Result)=false)cout

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论