#include "CSnmpPDU.h"
#include<string.h>
#include<iostream>
CSnmpPDU::CSnmpPDU()
{
versionLength=0;
communityLength=0;
requestIDLength=0;
varBindLength=0;
snmpMessageLength=0;
PDUtype=-1; //PDU类型,初始化为无效类型
value[0]='\0'; //变量值
version[0]='\0'; //存放版本号
community[0]='\0'; //存放共同体
requestID[0]='\0'; //存放requestID
varBind[0]='\0'; //存放变量绑定
snmpMessage[0]='\0'; //存放SNMP消息
}
CSnmpPDU::~CSnmpPDU(){}
void CSnmpPDU::setVersion()
{
version[0]=0x02;
version[1]=0x01;
version[2]=0x00;
versionLength=version[1]+2; //version总长度为0x03
}
void CSnmpPDU::setCommunity()
{
//默认community是“public”
community[0]=0x04;
community[1]=0x06;
community[2]=0x70;
community[3]=0x75;
community[4]=0x62;
community[5]=0x6C;
community[6]=0x69;
community[7]=0x63;
communityLength=community[1]+2; //community总长度为0x08
}
void CSnmpPDU::setPDUtype(BYTE usrPDUtype)
{
PDUtype=usrPDUtype; //传入PDU类型
}
void CSnmpPDU::setRequestID()
{
requestID[0]=0x02;
requestID[1]=0x01;
requestID[2]=0x00;
requestIDLength=requestID[1]+2; //requestID总长度为0x03
}
void CSnmpPDU::setErrorStatus(int usrErrorStatus)
{
errorStatus[0]=0x02;
errorStatus[1]=0x01;
switch(usrErrorStatus)
{
case 0:
errorStatus[2]=0x00; //noError(0)
break;
case 1:
errorStatus[2]=0x01; //tooBig(1)
break;
case 2:
errorStatus[2]=0x02; //noSuchName(2)
break;
case 3:
errorStatus[2]=0x03; //badValue(3)
break;
case 4:
errorStatus[2]=0x04; //readOnly(4)
break;
case 5:
errorStatus[2]=0x05; //genErr(5)
break;
default:
printf("errorStatus is error!!\n\n");
break;
}
errorStatusLength=errorStatus[1]+2; //errorStatus总长度为0x03
}
void CSnmpPDU::setErrorIndex(int usrErrorIndex)
{
errorIndex[0]=0x02;
errorIndex[1]=0x01;
errorIndex[2]=0x00;
errorIndexLength=errorIndex[1]+2; //errorIndex总长度为0x03
}
void CSnmpPDU::setValue(char usrValue[]) //usrValue是字符串
{
/*int i=0;
char *pChar=usrValue;
while(*pChar!='\0'){
value[i++]=*pChar;
pChar++;
}*/
strcpy(value,usrValue);
}
void CSnmpPDU::setVarBind(char usrOID[])
{
//.1.3.6.1.4.1 enterprise
//.1.3.6.1.4.1.1 myMIB
int index=0; //记录usrOID中数字的个数
BYTE temp[128]; //将usrOID中的数字串接过来
int len=strlen(usrOID); //取得usrOID长度
for(int i=0;i<len;i++)
{
if(usrOID[i]!='.')
temp[index++]=usrOID[i]-'0'; //循环结束,index的数值就是OID长度,不包括圆点
}
//varBind
//整个varBind开始
varBind[0]=0x30;
varBind[1]=0x00; //需要回填varBind长度
//第1个变量名和变量值:name1 value1开始
varBind[2]=0x30;
varBind[3]=0x00; //需要回填name1 value1长度
//name1开始
varBind[4]=0x06;
varBind[5]=0x00; //需要回填name1长度
varBind[6]=0x2B; //1.3
for(int j=0;j<index-1-1;j++) //index为OID个数,index-1-1表1.3合为一个,1.3已记入
varBind[j+7]=temp[j+2]; //从temp数组中的第2号开始记入
//回填name1长度
varBind[5]=index-1; //BER编码时,1.3合为0x2B,所以长度为index-1
//value1开始
if(value[0]=='\0') //如果value数组为空,即值为空
{
varBind[(index-1-1)+7]=0x05; //0x05 0x00表示空值
varBind[(index-1-1)+8]=0x00;
}
else{
int len=strlen(value);
varBind[(index-1-1)+7]=0x04; //通用简单类型OCTET STRING
varBind[(index-1-1)+8]=len;
for(int k=0;k<len;k++)
{
varBind[(index-1-1)+9+k]=(BYTE)value[k];
}
}
//回填name1 value1长度
varBind[3]=varBind[5]+2+varBind[(index-1-1)+8]+2; //varBind[5]+2为name1总长度;varBind[(index-1-1)+8]+2为value1总长度
//回填varBind长度
varBind[1]=varBind[3]+2;
//varBind总长度,即variable-bindings的总长度
varBindLength=varBind[1]+2;
}
void CSnmpPDU::enSnmpPDU()
{
int i=0; //做为循环控制变量
int index=0; //记录当前字节顺序号
//SNMP报文
//SNMP报文开始部分
snmpMessage[0]=0x30;
snmpMessage[1]=0x00; //需要回填SNMP报文长度
//version开始
for(i=0;i<versionLength;i++)
snmpMessage[2+i]=version[i];
index=2+(versionLength-1); //当前填充到的字节顺序号为index
//community开始
for(i=0;i<communityLength;i++)
snmpMessage[(index+1)+i]=community[i];
index=(index+1)+(communityLength-1);
//SNMP PDU开始
//PDUtype开始
switch(PDUtype)
{
case 0:
snmpMessage[index+1]=0xa0; //GetRequestPDU
break;
case 1:
snmpMessage[index+1]=0xa1; //GetNextRequestPDU
break;
case 2:
snmpMessage[index+1]=0xa2; //GetResponsePDU
break;
case 3:
snmpMessage[index+1]=0xa3; //SetRequestPDU
break;
case 4:
snmpMessage[index+1]=0xa4; //TrapPDU
break;
default:
fputs("PDUtype error!\n\n",stdout);
}
index=index+1;
//SNMP PDU长度,指requestID+errorStatus+errorIndex+varBind的长度
snmpMessage[index+1]=requestIDLength+3+3+varBindLength; //SNMP PDU长度
//SNMP PDU总长度为snmpMessage[index+1]+2
index=index+1;
//requestID开始
for(i=0;i<requestIDLength;i++)
snmpMessage[(index+1)+i]=requestID[i];
index=(index+1)+(requestIDLength-1);
//errorStatus开始
//snmpMessage[index+1]=0x02;
//snmpMessage[index+2]=0x01;
//snmpMessage[index+3]=0x00;
for(i=0;i<errorStatusLength;i++)
snmpMessage[(index+1)+i]=errorStatus[i];
index=(index+1)+(errorStatusLength-1);
//index=index+3;
//errorIndex开始
//snmpMessage[index+1]=0x02;
//snmpMessage[index+2]=0x01;
//snmpMessage[index+3]=0x00;
for(i=0;i<errorIndexLength;i++)
snmpMessage[(index+1)+i]=errorIndex[i];
index=(index+1)+(errorIndexLength-1);
//index=index+3;
//varBind开始
for(i=0;i<varBindLength;i++)
snmpMessage[(index+1)+i]=varBind[i];
index=(index+1)+(varBindLength-1);
//回填SNMP报文长度
snmpMessage[1]=index-1;
//SNMP消息总长度
snmpMessageLength=snmpMessage[1]+2;
}
void CSnmpPDU::deSnmpPDU(unsigned char usrBuffer[])
{
//usrBuffer[]是接收过来的SNMP消息报文
int i=0,j=0; //用循环控制
int pos=0; //用于定位
pos=pos+1; //该点存放SNMP消息报文长度
int msgLength=usrBuffer[pos]+2; //记录SNMP消息报文总长度
//测试用
//printf("接收到消息总长度:%d\n",msgLength); //测试正常
//测试用,测试usrBuffer
//for(i=0;i<msgLength;i++)
// printf("%x ",usrBuffer[i]); //测试正常:测试传入的SNMP消息报文
pos=pos+2; //该点存放version长度
versionLength=usrBuffer[pos]+2;
for(i=0;i<versionLength;i++)
version[i]=usrBuffer[pos-1+i]; //setVersion
//测试用
//for(i=0;i<versionLength;i++)
// printf("version :%x\n",version[i]); //测试正常
pos=pos+(versionLength-2)+2; //该点存放community长度;(versionLength-2)表示version长度
communityLength=usrBuffer[pos]+2; //community长度
//测试用
//printf("community总长度:%d\n",communityLength); //测试正常
for(i=0;i<communityLength;i++)
community[i]=usrBuffer[pos-1+i]; //setCommunity
//测试用
//for(i=0;i<communityLength;i++)
// printf("community :%x\n",community[i]); //测试正常
pos=pos+(communityLength-2)+1; //该点存放PDUtype类型
//测试用
//printf("接收PDUtype :%x\n",usrBuffer[pos]); //测试正常
switch(usrBuffer[pos]) //setPDUtype,传出PDUtype
{
case 0xa0:
PDUtype=0;
break;
case 0xa1:
PDUtype=1;
break;
case 0xa2:
PDUtype=2;
break;
case 0xa3:
PDUtype=3;
break;
case 0xa4:
PDUtype=4;
break;
}
//测试用
//printf("PDUtype :%x\n",PDUtype); //测试正常
pos=pos+1+2; //pos+1点存放SNMP PDU长度;pos+1+2点存放requestID长度
requestIDLength=usrBuffer[pos]+2;
for(i=0;i<requestIDLength;i++)
requestID[i]=usrBuffer[pos-1+i]; //setRequestID
//测试用
//for(i=0;i<requestIDLength;i++)
// printf("接收requestID :%x\n",requestID[i]); //测试正常
//pos=pos+(requestIDLength-2)+3+3+2; //+3-errorStatus长度;+3-errorIndex长度;+2-varBind长度;
pos=pos+(requestIDLength-2)+2; //该点存放errorStatus长度
errorStatusLength=usrBuffer[pos]+2;
for(i=0;i<errorStatusLength;i++)
errorStatus[i]=usrBuffer[pos-1+i]; //setRequestID
//�