⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snmpencode.c

📁 VxWorks操作系统下的SNMP协议以及MIB协议的实现源码,并且实现了HP标准打印类的MIB框架.
💻 C
字号:


#include "VxWorks.h"
#include "sockLib.h"
#include "inetLib.h"
#include "taskLib.h"
#include "stdioLib.h"
#include "strLib.h"
#include "ioLib.h"
#include "fioLib.h"

#include "snmp.h"

int PrepareRC(SNMP_PDU *snmp,char **buf,int *packetlen)
{
	
	int buflen;
	if(Encode_bindlist(snmp,buf,(int *)&buflen) == ERROR)
	{
		snmpFree(buf);
		return ERROR;
	}
	if(Encode_ErrorIndex(snmp,buf,(int*)&buflen) == ERROR)
	{
		snmpFree((*buf));
		snmpFree(buf);
		return ERROR;
	}
	if(Encode_ErrorStatus(snmp,buf,(int*)&buflen) == ERROR)
	{
		snmpFree((*buf));
		snmpFree(buf);
		return ERROR;
	}
	if(Encode_RequestID(snmp,buf,(int*)&buflen) == ERROR)
	{
		snmpFree((*buf));
		snmpFree(buf);
		return ERROR;
	}
	if(Encode_PDUfield(snmp,buf,(int*)&buflen) == ERROR)
	{
		snmpFree((*buf));
		snmpFree(buf);
		return ERROR;
	}
	if(Encode_wrapper(snmp,buf,(int*)&buflen) == ERROR)
	{
		snmpFree((*buf));
		snmpFree(buf);
		return ERROR;
	}
	(*packetlen) = buflen;
	return OK;
}

int Encode_bindlist(SNMP_PDU *snmp,char **buf,int *buflen)
{
	char 	**buf1;
	char 	**buf2;
	int 	buf1len,buf2len;
	int 	templen,resultlen;

	char 	*temp,*result;
	VARLIST *vartemp;
	
	(*buf) = temp = NULL;
	
	buf1 = snmpMalloc(sizeof(char *));
	buf2 = snmpMalloc(sizeof(char *));
	//循环将所有OID及VALUE打包
	for(vartemp = snmp->variables;vartemp != NULL;vartemp = vartemp->next)
	{
		if(packet(TAG_OBJIDT,vartemp->oid_len,vartemp->oid,buf1,(int *)&buf1len) == ERROR)
		{
			snmpFree(buf1);
			snmpFree(buf2);
			return ERROR;
		}
		if(packet(vartemp->type,vartemp->value_len,vartemp->value,buf2,(int *)&buf2len) == ERROR)
		{
			snmpFree(buf1);
			snmpFree(buf2);
			return ERROR;
		}
		resultlen = buf1len + buf2len;
		result = snmpMalloc(resultlen);
		memcpy(result,*buf1,buf1len);
		memcpy(result+buf1len,*buf2,buf2len);
		snmpFree((*buf1));
		snmpFree((*buf2));
		//将一个OID与它的VALUE打包
		if(packet(TAG_SEQUENCE,resultlen,result,buf1,(int *)&buf1len) == ERROR)
		{
			snmpFree(result);
			snmpFree(buf1);
			snmpFree(buf2);
			return ERROR;
		}
		snmpFree(result);
		if((*buf) == NULL)
		{
			(*buf) = (*buf1);
			(*buflen) = buf1len;
		}
		else
		{
			templen = (*buflen) + buf1len;
			temp = snmpMalloc(templen);
			memcpy(temp,(*buf),(*buflen));
			memcpy(temp+(*buflen),(*buf1),buf1len);
			snmpFree((*buf1));
			snmpFree((*buf));
			(*buf) = temp;
			(*buflen) = templen;
		}
	}
	//将上面打包好的数据作为VARBINDLIST的VALUE再打包
	if(packet(TAG_SEQUENCE,(*buflen),(*buf),buf1,(int *)&buf1len) == ERROR)
	{
		snmpFree((*buf));
		snmpFree(buf1);
		snmpFree(buf2);
		return ERROR;
	}
	snmpFree((*buf));
	(*buf) = (*buf1);
	(*buflen) = buf1len;
	snmpFree(buf1);
	snmpFree(buf2);
	return TRUE;
}

//ErrorIndex与VARBINDLIST是同级的,无需打包,只要简单的合并即可
int	Encode_ErrorIndex(SNMP_PDU *snmp,char **buf,int *buflen)
{
	char 	*data;
	int 	datalen;
	datalen = (*buflen) + 3;
	data = snmpMalloc(datalen);
	data[0] = TAG_INTERGER;
	data[1] = 0x1;								//length always = 1
	data[2] = snmp->errindex;
	memcpy(data+3,(*buf),(*buflen));
	snmpFree((*buf));
	(*buf) = data;
	(*buflen) = datalen;
}
//ErrorStatus与ErrorIndex,VARBINDLIST是同级的,无需打包,只要简单的合并即可
int	Encode_ErrorStatus(SNMP_PDU *snmp,char **buf,int *buflen)
{
	char 	*data;
	int 	datalen;
	datalen = (*buflen) + 3;
	data = snmpMalloc(datalen);
	data[0] = TAG_INTERGER;
	data[1] = 0x1;				//length always = 1
	data[2] = snmp->errstat;				//No Error = 0
	memcpy(data+3,(*buf),(*buflen));
	snmpFree((*buf));
	(*buf) = data;
	(*buflen) = datalen;
}

//RequestID与ErrorStatus,ErrorIndex,VARBINDLIST是同级的,无需打包,只要简单的合并即可
int	Encode_RequestID(SNMP_PDU *snmp,char **buf,int *buflen)
{
	char 	*data;
	int 	datalen;
	datalen = (*buflen) + 2 + sizeof(long);
	data = snmpMalloc(datalen);
	data[0] = TAG_INTERGER;
	data[1] = sizeof(long);
	memcpy(data+2,&(snmp->reqid),sizeof(long));
	memcpy(data+2 + sizeof(long),(*buf),(*buflen));
	snmpFree((*buf));
	(*buf) = data;
	(*buflen) = datalen;
}

int	Encode_PDUfield(SNMP_PDU *snmp,char **buf,int *buflen)
{
	char 	**data;
	int 	datalen;
	
	data = 	snmpMalloc(sizeof(char *));
	if(packet(TAG_GETRESPONSE,(*buflen),(*buf),data,(int *)&datalen) == ERROR)
	{
		return ERROR;
	}
	snmpFree((*buf));
	(*buf) = (*data);
	snmpFree(data);
	(*buflen) = datalen;
	return TRUE;
}

int	Encode_wrapper(SNMP_PDU *snmp,char **buf,int *buflen)
{
	char 	**data;
	int 	datalen;
	char 	*final;
	int 	finalen;
	data	=	snmpMalloc(sizeof(char *));
	//创建COMMUNITY NAME数据包
	if(packet(TAG_OCTET,snmp->community_len,snmp->community,data,(int *)&datalen) == ERROR)
	{
		snmpFree(data);
		return ERROR;
	}
	//直接与VERSION以及PDU数据包合并
	finalen  = 3 + datalen + (*buflen);
	final 	 = snmpMalloc(finalen);
	final[0] = TAG_INTERGER;
	final[1] = 1;
	final[2] = 0;				//version = 0 means snmpV1
	memcpy(final+3,(*data),datalen);
	memcpy(final+3+datalen,(*buf),(*buflen));
	snmpFree((*buf));
	snmpFree((*data));
	//最外围的包裹
	if(packet(TAG_SEQUENCE,finalen,final,data,(int *)&datalen) == ERROR)
	{
		snmpFree(final);
		snmpFree(data);
		return ERROR;
	}
	snmpFree(final);	
	(*buf) 	  = (*data);
	(*buflen) = datalen;
	snmpFree(data);
	return TRUE;
}


//下面的函数是为TRAP PDU打包用的

//time stamp与VARBINDLIST是同级的,无需打包,只要简单的合并即可
int	Encode_TimeStamp(SNMP_PDU *snmp,char **buf,int *buflen)
{
	char 	*data;
	int 	datalen;
	datalen = (*buflen) + 2 + sizeof(long);
	data = snmpMalloc(datalen);
	data[0] = TAG_TIMETICK;
	data[1] = sizeof(long);								//length always = 1
	memcpy(data+2,&(snmp->time),sizeof(long));
	memcpy(data+2 + sizeof(long),(*buf),(*buflen));
	snmpFree((*buf));
	(*buf) = data;
	(*buflen) = datalen;
}
//specific trap与VARBINDLIST是同级的,无需打包,只要简单的合并即可
int	Encode_SpecTrap(SNMP_PDU *snmp,char **buf,int *buflen)
{
	char 	*data;
	int 	datalen;
	datalen = (*buflen) + 2 + sizeof(long);
	data = snmpMalloc(datalen);
	data[0] = TAG_INTERGER;
	data[1] = sizeof(long);								//length always = 1
	memcpy(data+2,&(snmp->specific_type),sizeof(long));
	memcpy(data+2 + sizeof(long),(*buf),(*buflen));
	snmpFree((*buf));
	(*buf) = data;
	(*buflen) = datalen;
}

//general trap与VARBINDLIST是同级的,无需打包,只要简单的合并即可
int	Encode_GenTrap(SNMP_PDU *snmp,char **buf,int *buflen)
{
	char 	*data;
	int 	datalen;
	datalen = (*buflen) + 3;
	data = snmpMalloc(datalen);
	data[0] = TAG_INTERGER;
	data[1] = 0x1;					
	data[2] = snmp->trap_type;					//0 - 6
	memcpy(data+3,(*buf),(*buflen));
	snmpFree((*buf));
	(*buf) = data;
	(*buflen) = datalen;
}
//Agent Address与VARBINDLIST是同级的,无需打包,只要简单的合并即可
int	Encode_AgentIP(SNMP_PDU *snmp,char **buf,int *buflen)
{
	char 	*data;
	int 	datalen;
	datalen = (*buflen) + 6;
	data = snmpMalloc(datalen);
	data[0] = TAG_IP;
	data[1] = 0x4;					//IP length always = 4
	data[2] = 192;
	data[3] = 168;
	data[4] = 45;
	data[5] = 239;
	//memcpy(data+2,snmp->agent_addr,sizeof(long));
	memcpy(data+6,(*buf),(*buflen));
	snmpFree((*buf));
	(*buf) = data;
	(*buflen) = datalen;
}

//enterprise与VARBINDLIST是同级的,无需打包,只要简单的合并即可
int	Encode_SysOID(SNMP_PDU *snmp,char **buf,int *buflen)
{
	char 	*data;
	int 	datalen;
	datalen = (*buflen) + snmp->enterprise_length + 2;
	data = snmpMalloc(datalen);
	data[0] = TAG_OBJIDT;
	data[1] = snmp->enterprise_length;					//IP length always = 4
	memcpy(data + 2,snmp->enterprise,snmp->enterprise_length);
	memcpy(data + 2 + snmp->enterprise_length,(*buf),(*buflen));
	snmpFree((*buf));
	(*buf) = data;
	(*buflen) = datalen;
}

int	Encode_Trapfield(SNMP_PDU *snmp,char **buf,int *buflen)
{
	char 	**data;
	int 	datalen;
	
	data = 	snmpMalloc(sizeof(char *));
	if(packet(TAG_TRAPPDU,(*buflen),(*buf),data,(int *)&datalen) == ERROR)
	{
		return ERROR;
	}
	snmpFree((*buf));
	(*buf) = (*data);
	snmpFree(data);
	(*buflen) = datalen;
	return TRUE;
}

int packet(char type,int asnlen,char *data,char **buf,int *buflen)
{
	if(asnlen == 0)
	{
		(*buflen) = 2;
		(*buf) = snmpMalloc(2);
		(*buf)[0] = type;
		(*buf)[1] = asnlen;
	}
	else if(asnlen <= 0x7F)
	{
		//数据长度+asnlen+TAG
		(*buflen) = asnlen + 2;
		(*buf) = snmpMalloc((*buflen));
		(*buf)[0] = type;
		(*buf)[1] = asnlen;
		memcpy((*buf)+2,data,asnlen);
	}
	else if(asnlen <= 0xFF)
	{
		(*buflen) = asnlen + 3;
		(*buf) = snmpMalloc((*buflen));
		(*buf)[0] = type;
		(*buf)[1] = 0x81;
		(*buf)[2] = asnlen;
		memcpy((*buf)+3,data,asnlen);
	}
	else if(asnlen <= 0xFFFF)
	{
		(*buflen) = asnlen + 4;
		(*buf) = snmpMalloc((*buflen));
		(*buf)[0] = type;
		(*buf)[1] = 0x82;
		(*buf)[2] = (asnlen>>8);
		(*buf)[3] = (asnlen&0xff);
		memcpy((*buf)+4,data,asnlen);
	}
	else if(asnlen <= 0xFFFFFF)
	{
		(*buflen) = asnlen + 5;
		(*buf) = snmpMalloc((*buflen));
		(*buf)[0] = type;
		(*buf)[1] = 0x83;
		(*buf)[2] = (asnlen>>16);
		(*buf)[3] = ((asnlen&0xff00)>>8);
		(*buf)[4] = (asnlen&0xff);
		memcpy((*buf)+5,data,asnlen);
	}
	else if(asnlen <= 0xFFFFFFFF)
	{
		(*buflen) = asnlen + 6;
		(*buf) = snmpMalloc((*buflen));
		(*buf)[0] = type;
		(*buf)[1] = 0x84;
		(*buf)[2] = (asnlen>>24);
		(*buf)[3] = ((asnlen&0xff0000)>>16);
		(*buf)[4] = ((asnlen&0xff00)>>8);
		(*buf)[5] = (asnlen&0xff);
		memcpy(buf+5,data,asnlen);
	}
	else
		return ERROR;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -