1、计算机网络管理课程设计引言简单网络管理协议(SNMP)首先是由 Internet工程任务组织(Internet Engineering Task Force)(IETF)的研究小组为了解决 Internet上的路由器管理问题而提出的。 SNMP 被设计成与协议无关,所以它可以在 IP,IPX,AppleTalk,OSI 以及其他用到的传输协议上被使用。它具有简单性,易于扩展性的特点。SNMP 是一系列协议组和规范(见下表),它们提供了一种从网络上的设备中收集网络管理信息的方法。SNMP 也为设备向网络管理工作站报告问题和错误提供了一种方法。名字 说明MIB 管理信息库SMI 管理信息的结构和标
2、识SNMP 简单网络管理协议从被管理设备中收集数据有两种方法:一种是只轮询(polling-only)的方法,另一种是基于中断(interrupt-based)的方法。Snmp 发展到现在共有三个版本,本课程设计是基于 snmpv1版本。2.设计任务及思想2.1 任务:设计一个 Manager。Manager 可以向华为网络设备发送 get和 set报文,并获得有效操作结果,实现版本为 SNMPv1.开发工具:VC+(Win32)内容: Socket网络通信、 BER 编码、BER 解码、SNMP 报文构造、SNMP 报文解析、用户输入/输出。2.2 思想:根据 snmp协议,分析抓包软件抓出
3、的结果。Manager 在进行操作时,先对要发送的报文进行构造,然后对要发送的报文各数据类型依据 asn.1进行编码再发送。agent 接收到报文后,进行报文解析,再解码。看 manager的要求是什么,然后回应一个报文,即response报文,manager 即对回应的报文进行解析解码,整个过程由 socket通信完成,snmp报文封装在 udp中发送。3 设计过程2.1 BER 编码和解码Ber编码是整个设计过程中的极为重要的部分,一个报文有很多段组成,每段的数据类型都不尽相同。对每一种数据类型都要进行编码,即编成 tlv。计算机只认识 0和 1;在编码时,我们考虑把它编成一个字节一个字节
4、的形式发送,便于解析处理。下面列出常用的几种数据类型的编码以及代码:整型:要考虑多种情况。void Integer_TLV(unsigned char *TLV,int tlv=TLV;tlv0=INTEGER;/TLV_T stack s;if (value=0) if(value128 convert(s,value,2);int length=(s.top-s.base)%8);if(length=0)/ int num_8=(s.top-s.base)/8;tlv1=num_8+1;/TLV_Llen=2+num_8+1;tlv2=0;/valuefor(int k=num_8;k=1
5、;-k) int sum_8=0;int local=k*8-1;int lastlocal=0;for(int j=0;j=1;-k1)int sum_8_bit=0;int local_8=k1*8-1;int lastlocal=0;for(int j=0;jMSG.community;coutinput;while(input!=“send“) MSG.pdu.variable_bindingsi+.name=input;cininput; MSG.version=0;/MSG.community=“public“;MSG.pdu.error_index=0;MSG.pdu.error
6、_status=0;MSG.pdu.request_id=abs(rand();/90 .32767MessSequence_TLV(return_tlv_message,return_tlv_message_len,MSG);leng_buffer=return_tlv_message_len;for(int l=0;lreturn_tlv_message_len;l+) cout(int)return_tlv_messagel“ “;Bufferl=return_tlv_messagel;/(int)/cout(int)Bufferl“ “; coutendl; coutendl; 解析和
7、解码代码如下:void strcpyTLV( char temp_INTEGER, char get_pdu,int k,int len)/字符串拷贝,拷贝 value 部分 int begin=k;for(int p=0;plen;p+) temp_INTEGERp=get_pdubegin+;temp_INTEGERlen=0;void prinout( char temp_INTEGER,bool change_line)/输出整数 value 部分 if(change_line) std:cout(int)temp_INTEGER0endl; else std:cout(int)tem
8、p_INTEGER0; void printout_OBJE( char temp_name,int len)/输出标识符 std:cout“1.3.“;int i=1; while(ilen) std:cout(int)temp_namei+“.“; std:coutendl; void Dcode_version( char temp_INTEGER,int len)/version 解析 std:cout“version: “INTEGER“ “len“ “;prinout(temp_INTEGER,true); void Dcode_OCTETSTRING( char temp_OCT
9、ETSTRING,int len)/community 解析 std:cout“community: “OCTETSTRING “ “len“ “temp_OCTETSTRINGendl; void Dcode_PDUTYPE(int Tlv_T)/pdutype 解析 std:cout“pdutype: “Tlv_T endl; void Dcode_resid( char temp_INTEGER,int len)/requestid 解析 for(int g=0;glen;g+) temp_INTEGERg=(len-1-g)*8; int sum=temp_INTEGER0;for(i
10、nt h=1;hlen;h+) sum|=temp_INTEGERh;std:cout“requestid: “INTEGER“ “len“ “sumendl; void Dcode_errorstatus(char temp_INTEGER,int len)/errorstatus 解析 std:cout“errorstatus: “INTEGER“ “len“ “;prinout(temp_INTEGER,false);switch (temp_INTEGER0) case 0:std:cout“ NoError“endl;break; case 1:std:cout“ TooBig“en
11、dl;break; case 2:std:cout“ NoSuchname“endl;break;case 3:std:cout“ BadValue“endl;break;case 4:std:cout“ ReadOnly“endl;break; case 5:std:cout“ genErr“endl;break;default:break; void Dcode_errorindex( char temp_INTEGER,int len)/errorindex 解析 std:cout“errorindex: “INTEGER“ “len“ “;prinout(temp_INTEGER,fa
12、lse);if(temp_INTEGER0!=0) std:cout“ The“(int)temp_INTEGER0“name is wrong“endl; else std:coutendl;void Dcode_name( char temp_name,int total_name,int len)/标识符解析 std:cout“name: “OBER“ “len“ “;printout_OBJE(temp_name,len); void Dcode_value_INTEGER( char temp_INTEGER,int total_name,int len)/value 解析 std:
13、cout“value: “INTEGER“ “len“ “;prinout(temp_INTEGER,true); void Dcode_Null(int len)/Null 类型解析 std:cout“value: “Null“ “len“ “endl; void Dcode_IpAddress( char temp_ipaddress,int len)/ipaddress 解析 std:cout“Ipaddress: “IpAddress“ “len; for(int mm=0;mmlen;mm+) std:couttemp_ipaddressmm“.“; void Decode_pdu(
14、char get_pdu)/主函数 std:cout“parasing “type“ “len“ “value“ “endl; int total_length=get_pdu1;/长度int total_INTEGER=0; int total_name=0;int len=0;int len1=0;int len2=0;int len3=0;int len4=0;/定义各 length 值int len7=0;int len6=0;int len5=0;int len8=0;int i=2; while(itotal_length+2) int Tlv_T=0;Tlv_T=(int)get
15、_pdui;switch (Tlv_T) case INTEGER :/ 2+total_INTEGER;if(total_INTEGER=1)/vertionlen=(int)get_pdui+1;char temp_INTEGER10;/strcpyTLV(temp_INTEGER,get_pdu,i+2,len);Dcode_version(temp_INTEGER,len);i=i+len+1;/i=i+len+1+1; else if(total_INTEGER=2)/requestId len1=(int)get_pdui+1;char temp_INTEGER100;/strcp
16、yTLV(temp_INTEGER,get_pdu,i+2,len1);Dcode_resid(temp_INTEGER,len1); i=i+len1+1; else if(total_INTEGER=3)/errorstatus len2=(int)get_pdui+1;char temp_INTEGER5;/strcpyTLV(temp_INTEGER,get_pdu,i+2,len2);Dcode_errorstatus(temp_INTEGER,len2);i=i+len2+1; else if(total_INTEGER=4)/errorIndex len3=(int)get_pd
17、ui+1;char temp_INTEGER5;/strcpyTLV(temp_INTEGER,get_pdu,i+2,len3);Dcode_errorindex(temp_INTEGER,len3);i=i+len3+1; else /其他 len4=(int)get_pdui+1;char temp_INTEGER100;/strcpyTLV(temp_INTEGER,get_pdu,i+2,len4);Dcode_value_INTEGER(temp_INTEGER,total_name,len4);i=i+len4+1;/ break;case OCTETSTRING:/ 4 字符l
18、en5=(int)get_pdui+1;char temp_OCTETSTRING50;/strcpyTLV(temp_OCTETSTRING,get_pdu,i+2,len5);Dcode_OCTETSTRING(temp_OCTETSTRING,len5);i=i+len5+1;break; case GetResponse:/pdutype/int len=get_pdui+1;Dcode_PDUTYPE(Tlv_T); i=i+2-1;break; case Trap:/int len=get_pdui+1;Dcode_PDUTYPE(Tlv_T);i=i+2-1;break;case
19、 SEQ:/seq 型if(total_name=0) i=i+2-1; else i=i+2-1; +total_name;break;case OBER:/标识符len6=(int)get_pdui+1; char temp_name100;/strcpyTLV(temp_name,get_pdu,i+2,len6); Dcode_name(temp_name,total_name,len6);i=i+len6+1;break;case Null:/空类型len7=(int)get_pdui+1; temp_namek10;/len;/strcpyTLV(temp_namek,get_pdu,i+2,len7); / Dcode_Null(temp_namek,total_name,len7); Dcode_Null(len7); i=i+1;break;case IpAddress:/ip 地址len8=(int)get_pdui+1; char temp_ipaddress50;/strcpyTLV(temp_ipaddress,get_pdu,i+2,len8);Dcode_IpAddress(temp_ipaddress,len8);i=i+len8+1;break; default: break; i+;