www.pudn.com > SNMP范例源代码.zip > Agent.c


#include 

/* globals */
extern xdata mib_object_t *MibRoot;
extern xdata union netcard rxdnet;
extern xdata union netcard txdnet;

u32 snmpAuthEnable = AGENT_AUTH_DISABLE;	/* enable/disable snmp authentication */

/* space allocated for snmp hosts/communities for authentication purposes */
struct snmpComm_t authComms[AUTH_MAX_COMMS];	/* space for all communities allowed */
struct snmpHost_t authHosts[AUTH_MAX_HOSTS];	/* space for all hosts allowed       */

/* space allocated for snmp hosts/communities for traps */
struct snmpComm_t trapComms[TRAP_MAX_COMMS];	/* space for all communities allowed */
struct snmpHost_t trapHosts[TRAP_MAX_HOSTS];	/* space for all hosts allowed       */

u32 snmpAuthMaxComms = AUTH_MAX_COMMS;	/* max communities for auth group */
u32 snmpAuthMaxHosts = AUTH_MAX_HOSTS;	/* max hosts for auth group       */
u32 snmpTrapMaxComms = TRAP_MAX_COMMS;	/* max communities for trap group */
u32 snmpTrapMaxHosts = TRAP_MAX_HOSTS;	/* max hosts for trap group       */

/**************************************************
SNMP proc parameters
**************************************************/

xdata system_t system;
xdata txfxDevice_t txfxDevice;
xdata txfxModule_t modules[MAX_MOUDLE_NUM];	

// insert here SNMP modules in order to find the faults

/* defines */

#define SNMP_IPA    0			/* Ipaddress, APPLICATION (0) */
#define SNMP_CNT    1			/* Counter,   APPLICATION (1) */
#define SNMP_GGE    2			/* Gauge,     APPLICATION (2) */
#define SNMP_TIT    3			/* TimeTicks  APPLICATION (3) */
#define SNMP_OPQ    4			/* Opaque,    APPLICATION (4) */

/* typedefs */

typedef struct snmp_cnv_s snmp_cnv_t;

struct snmp_cnv_s
{
	u32 Class;
	u32 Tag;
	i32 Syntax;
};

/* globals */

i32 snmpErrStatus = SNMP_NOERROR;
i32 snmpErrIndex = 0;

asn1_sck_t snmpErrAsn1Status;
asn1_sck_t snmpErrAsn1Index;
asn1_sck_t snmpErrAsn1Resp;

snmp_stat_t SnmpStat;

const i8 *SnmpTrap[] =
{
	"cold start",
	"warm start",
	"link down",
	"link up",
	"authentication failure",
	"neighbor loss",
	"enterprise specific"
};

/* locals */

static snmp_cnv_t SnmpCnv[] =
{
	{ASN1_UNI, ASN1_NUL, SNMP_NULL},
	{ASN1_UNI, ASN1_INT, SNMP_INTEGER},
	{ASN1_UNI, ASN1_OTS, SNMP_OCTETSTR},
	{ASN1_UNI, ASN1_OTS, SNMP_DISPLAYSTR},
	{ASN1_UNI, ASN1_OJI, SNMP_OBJECTID},
	{ASN1_APL, SNMP_IPA, SNMP_IPADDR},
	{ASN1_APL, SNMP_CNT, SNMP_COUNTER},
	{ASN1_APL, SNMP_GGE, SNMP_GAUGE},
	{ASN1_APL, SNMP_TIT, SNMP_TIMETICKS},
	{ASN1_APL, SNMP_OPQ, SNMP_OPAQUE},
	{0, 0, -1}
};

/* forward declarations */

static int SnmpSyn2TagCls(u32 * Tag, u32 * Cls, i32 Syn);
static int SnmpTagCls2Syn(u32 Tag, u32 Cls, u16 * Syn);
static int SnmpObjEnc(asn1_sck_t * Asn1, snmp_object_t * Obj);
static int SnmpObjDec(asn1_sck_t * Asn1, snmp_object_t * Obj);
static int SnmpLstEnc(asn1_sck_t * Asn1, snmp_object_t * Lst, u32 LstLen);
static int SnmpLstDec(asn1_sck_t * Asn1, snmp_object_t * Lst, u32 LstSze, u32 * LstLen);
static int SnmpRqsEnc(asn1_sck_t * Asn1, snmp_pdu_t * Rqs);
static int SnmpRqsDec(asn1_sck_t * Asn1, snmp_pdu_t * Rqs);
static int SnmpPduEnc(asn1_sck_t * Asn1, snmp_pdu_t * Pdu, snmp_object_t * Lst, u32 LstLen);
static int SnmpPduDec(asn1_sck_t * Asn1, snmp_pdu_t * Pdu, snmp_object_t * Lst, u32 LstSze, u32 * LstLen);


int SnmpSyn2TagCls
    (
    u32 * Tag, 
    u32 * Cls, 
    i32   Syn
    )
{
	snmp_cnv_t *Cnv;

	Cnv = SnmpCnv;
	while (Cnv->Syntax != -1)
	{
		if (Cnv->Syntax == Syn)
		{
			*Tag = Cnv->Tag;
			*Cls = Cnv->Class;
			return TRUE;
		}
		Cnv++;
	}
	snmpErrStatus = SNMP_BADVALUE;
	SnmpStat.OutBadValues++;
	return FALSE;
}


int SnmpTagCls2Syn
    (
    u32   Tag, 
    u32   Cls, 
    u16 * Syn
    )
{
	snmp_cnv_t *Cnv;

	Cnv = SnmpCnv;
	while (Cnv->Syntax != -1)
	{
		if (Cnv->Tag == Tag && Cnv->Class == Cls)
		{
			*Syn = (u16) Cnv->Syntax;
			return TRUE;
		}
		Cnv++;
	}
	snmpErrStatus = SNMP_BADVALUE;
	SnmpStat.OutBadValues++;
	return FALSE;
}


int SnmpObjEnc
    (
    asn1_sck_t *    Asn1, 
    snmp_object_t * Obj
    )
{
	u32 Cls, Tag;
	u8 *Eoc, *End;

	if (!Asn1EocEnc(Asn1, &Eoc))
	{
		return FALSE;
	}
	switch (Obj->Type)
	{
	case SNMP_INTEGER:
		if (!Asn1IntEncLng(Asn1, &End, Obj->Syntax.LngInt))
		{
			return FALSE;
		}
		break;
	case SNMP_OCTETSTR:
	case SNMP_OPAQUE:
		if (!Asn1OtsEnc(Asn1, &End, Obj->Syntax.BufChr, Obj->SyntaxLen))
		{
			return FALSE;
		}
		break;
	case SNMP_NULL:
		if (!Asn1NulEnc(Asn1, &End))
		{
			return FALSE;
		}
		break;
	case SNMP_OBJECTID:
		if (!Asn1OjiEnc(Asn1, &End, (u32 *) Obj->Syntax.BufInt, Obj->SyntaxLen))
		{
			return FALSE;
		}
		break;
	case SNMP_IPADDR:
		if (!Asn1OtsEnc(Asn1, &End, (u8 *) & Obj->Syntax.LngUns, 4))
		{
			return FALSE;
		}
		break;
	case SNMP_COUNTER:
	case SNMP_GAUGE:
	case SNMP_TIMETICKS:
		if (!Asn1IntEncLngUns(Asn1, &End, Obj->Syntax.LngUns))
		{
			return FALSE;
		}
		break;
	default:
		snmpErrStatus = SNMP_BADVALUE;
		SnmpStat.OutBadValues++;
		return FALSE;
	}
	if (!SnmpSyn2TagCls(&Tag, &Cls, Obj->Type))
	{
		return FALSE;
	}
	if (!Asn1HdrEnc(Asn1, End, Cls, ASN1_PRI, Tag))
	{
		return FALSE;
	}
	if (!Asn1OjiEnc(Asn1, &End, (u32 *) Obj->Id, Obj->IdLen))
	{
		return FALSE;
	}
	if (!Asn1HdrEnc(Asn1, End, ASN1_UNI, ASN1_PRI, ASN1_OJI))
	{
		return FALSE;
	}
	if (!Asn1HdrEnc(Asn1, Eoc, ASN1_UNI, ASN1_CON, ASN1_SEQ))
	{
		return FALSE;
	}
	return TRUE;
}


int SnmpObjDec
    (
    asn1_sck_t *    Asn1, 
    snmp_object_t * Obj
    )
{
	u32 Cls, Con, Tag;
	u8 *Eoc, *End;

	if (!Asn1HdrDec(Asn1, &Eoc, &Cls, &Con, &Tag))
		return FALSE;
	if (Cls != ASN1_UNI || Con != ASN1_CON || Tag != ASN1_SEQ)
		return FALSE;
	if (!Asn1HdrDec(Asn1, &End, &Cls, &Con, &Tag))
		return FALSE;
	if (Cls != ASN1_UNI || Con != ASN1_PRI || Tag != ASN1_OJI)
		return FALSE;
	if (!Asn1OjiDec(Asn1, End, (u32 *) Obj->Id, SNMP_SIZE_OBJECTID, &Obj->IdLen))
		return FALSE;
	if (!Asn1HdrDec(Asn1, &End, &Cls, &Con, &Tag))
		return FALSE;
	if (Con != ASN1_PRI)
	{
		snmpErrStatus = SNMP_BADVALUE;
		SnmpStat.OutBadValues++;
		return FALSE;
	}
	if (!SnmpTagCls2Syn(Tag, Cls, &Obj->Type))
		return FALSE;
	switch (Obj->Type)
	{
	case SNMP_INTEGER:
		if (!Asn1IntDecLng(Asn1, End, (i32 *) & Obj->Syntax.LngInt))
			return FALSE;
		break;
	case SNMP_OCTETSTR:
	case SNMP_OPAQUE:
		if (!Asn1OtsDec(Asn1, End, Obj->Syntax.BufChr, SNMP_SIZE_BUFCHR,
						&Obj->SyntaxLen))
			return FALSE;
		break;
	case SNMP_NULL:
		if (!Asn1NulDec(Asn1, End))
			return FALSE;
		break;
	case SNMP_OBJECTID:
		if (!Asn1OjiDec(Asn1, End, (u32 *) Obj->Syntax.BufInt, SNMP_SIZE_BUFINT,
						&Obj->SyntaxLen))
			return FALSE;
		break;
	case SNMP_IPADDR:
		if (!Asn1OtsDec(Asn1, End, (u8 *) & Obj->Syntax.LngUns, 4,
						&Obj->SyntaxLen))
			return FALSE;
		if (Obj->SyntaxLen != 4)
			return FALSE;
		break;
	case SNMP_COUNTER:
	case SNMP_GAUGE:
	case SNMP_TIMETICKS:
		if (!Asn1IntDecLngUns(Asn1, End, (u32 *) & Obj->Syntax.LngUns))
			return FALSE;
		break;
	default:
		snmpErrStatus = SNMP_BADVALUE;
		SnmpStat.OutBadValues++;
		return FALSE;
	}
	if (!Asn1EocDec(Asn1, Eoc))
		return FALSE;
	return TRUE;
}


int SnmpLstEnc
    (
    asn1_sck_t *    Asn1, 
    snmp_object_t * Lst, 
    u32             LstLen
    )
{
	u8 *Eoc;

	if (!Asn1EocEnc(Asn1, &Eoc))
	{
		return FALSE;
	}
	Lst += LstLen;
	while (LstLen-- > 0)
	{
		if (!SnmpObjEnc(Asn1, --Lst))
		{
			return FALSE;
		}
	}
	if (!Asn1HdrEnc(Asn1, Eoc, ASN1_UNI, ASN1_CON, ASN1_SEQ))
	{
		return FALSE;
	}
	return TRUE;
}


int SnmpLstDec
    (
    asn1_sck_t *    Asn1, 
    snmp_object_t * Lst, 
    u32             LstSze, 
    u32 *           LstLen
    )
{
	u32 Cls, Con, Tag;
	u8 *Eoc;

	if (!Asn1HdrDec(Asn1, &Eoc, &Cls, &Con, &Tag))
		return FALSE;
	if (Cls != ASN1_UNI || Con != ASN1_CON || Tag != ASN1_SEQ)
		return FALSE;
	*LstLen = 0;
	while (!Asn1Eoc(Asn1, Eoc))
	{
		if (++(*LstLen) > LstSze)
		{
			snmpErrStatus = SNMP_TOOBIG;
			SnmpStat.OutTooBigs++;
			return FALSE;
		}
		if (!SnmpObjDec(Asn1, Lst++))
		{
			snmpErrIndex = (i32) * LstLen;
			return FALSE;
		}
	}
	if (!Asn1EocDec(Asn1, Eoc))
		return FALSE;
	return TRUE;
}

int SnmpRqsEnc
    (
    asn1_sck_t *     Asn1, 
    snmp_pdu_t * Rqs
    )
{
	u8 *End;

	if (!Asn1IntEncUns(Asn1, &End, Rqs->ErrorIndex))
		return FALSE;
	if (!Asn1HdrEnc(Asn1, End, ASN1_UNI, ASN1_PRI, ASN1_INT))
		return FALSE;
	if (!Asn1IntEncUns(Asn1, &End, Rqs->ErrorStatus))
		return FALSE;
	if (!Asn1HdrEnc(Asn1, End, ASN1_UNI, ASN1_PRI, ASN1_INT))
		return FALSE;
	if (!Asn1IntEncLngUns(Asn1, &End, Rqs->Id))
		return FALSE;
	if (!Asn1HdrEnc(Asn1, End, ASN1_UNI, ASN1_PRI, ASN1_INT))
		return FALSE;
	return TRUE;
}


int SnmpRqsDec
    (
    asn1_sck_t *     Asn1, 
    snmp_pdu_t * Rqs
    )
{
	u32 Cls, Con, Tag;
	u8 *End;

	if (!Asn1HdrDec(Asn1, &End, &Cls, &Con, &Tag))
		return FALSE;
	if (Cls != ASN1_UNI || Con != ASN1_PRI || Tag != ASN1_INT)
		return FALSE;
	if (!Asn1IntDecLngUns(Asn1, End, (u32 *) & Rqs->Id))
		return FALSE;
	if (!Asn1HdrDec(Asn1, &End, &Cls, &Con, &Tag))
		return FALSE;
	if (Cls != ASN1_UNI || Con != ASN1_PRI || Tag != ASN1_INT)
		return FALSE;
	if (!Asn1IntDecUns(Asn1, End, &Rqs->ErrorStatus))
		return FALSE;
	memcpy(&snmpErrAsn1Status, Asn1, sizeof(asn1_sck_t));
	if (!Asn1HdrDec(Asn1, &End, &Cls, &Con, &Tag))
		return FALSE;
	if (Cls != ASN1_UNI || Con != ASN1_PRI || Tag != ASN1_INT)
		return FALSE;
	if (!Asn1IntDecUns(Asn1, End, &Rqs->ErrorIndex))
		return FALSE;
	/*
	 * Should not receive any error status
	 */
	if (Rqs->ErrorStatus != SNMP_NOERROR)
	{
		switch (Rqs->ErrorStatus)
		{
		case SNMP_TOOBIG:
			SnmpStat.InTooBigs++;
			break;
		case SNMP_NOSUCHNAME:
			SnmpStat.InNoSuchNames++;
			break;
		case SNMP_BADVALUE:
			SnmpStat.InBadValues++;
			break;
		case SNMP_READONLY:
			SnmpStat.InReadOnlys++;
			break;
		default:
			SnmpStat.InGenErrs++;
			break;
		}
		return FALSE;
	}
#if 0
	if (!Asn1HdrDec(Asn1, &End, &Cls, &Con, &Tag))
		return FALSE;
	if (Cls != ASN1_UNI || Con != ASN1_PRI || Tag != ASN1_INT)
		return FALSE;
	if (!Asn1IntDecUns(Asn1, End, &Rqs->ErrorIndex))
		return FALSE;
#endif
	memcpy(&snmpErrAsn1Index, Asn1, sizeof(asn1_sck_t));
	return TRUE;
}


int SnmpPduEnc
    (
    asn1_sck_t *    Asn1, 
    snmp_pdu_t *    Pdu, 
    snmp_object_t * Lst, 
    u32             LstLen
    )
{
	u8 *Eoc;

	if (!Asn1EocEnc(Asn1, &Eoc))
	{
		return FALSE;
	}
	if (!SnmpLstEnc(Asn1, Lst, LstLen))
	{
		return FALSE;
	}
	switch (Pdu->Type)
	{
	case SNMP_PDU_GET:
	case SNMP_PDU_NEXT:
	case SNMP_PDU_RESPONSE:
	case SNMP_PDU_SET:
	case SNMP_PDU_TRAP:
		if (!SnmpRqsEnc(Asn1, Pdu))
		{
			return FALSE;
		}
		break;
	
	default:
		return FALSE;
	}
	if (!Asn1HdrEnc(Asn1, Eoc, ASN1_CTX, ASN1_CON, Pdu->Type))
	{
		return FALSE;
	}
	return TRUE;
}


int SnmpPduDec
    (
    asn1_sck_t *    Asn1, 
    snmp_pdu_t *    Pdu, 
    snmp_object_t * Lst, 
    u32             LstSze, 
    u32 *           LstLen
    )
{
	u32 Cls, Con;
	u8 *Eoc;

	if (!Asn1HdrDec(Asn1, &Eoc, &Cls, &Con, &Pdu->Type))
		return FALSE;

	memcpy(&snmpErrAsn1Resp, Asn1, sizeof(asn1_sck_t));

	if (Cls != ASN1_CTX || Con != ASN1_CON)
		return FALSE;
	switch (Pdu->Type)
	{
	case SNMP_PDU_GET:
	case SNMP_PDU_NEXT:
	case SNMP_PDU_RESPONSE:
	case SNMP_PDU_SET:
	case SNMP_PDU_TRAP:
		if (!SnmpRqsDec(Asn1, Pdu))
			return FALSE;
		break;
	default:
		SnmpStat.InBadTypes++;
		return FALSE;
	}
	if (!SnmpLstDec(Asn1, Lst, LstSze, LstLen))
		return FALSE;
	if (!Asn1EocDec(Asn1, Eoc))
		return FALSE;
	return TRUE;
}


int SnmpMsgEnc
    (
    asn1_sck_t *    Asn1, 
    snmp_pdu_t *    Pdu, 
    u8 *            Com, 
    u32             ComLen, 
    snmp_object_t * Lst, 
    u32             LstLen
    )
{
	u8 *Eoc, *End;

	if (!Asn1EocEnc(Asn1, &Eoc))
	{
		return FALSE;
	}
	if (!SnmpPduEnc(Asn1, Pdu, Lst, LstLen))
	{
		return FALSE;
	}
	if (!Asn1OtsEnc(Asn1, &End, Com, ComLen))
	{
		return FALSE;
	}
	if (!Asn1HdrEnc(Asn1, End, ASN1_UNI, ASN1_PRI, ASN1_OTS))
	{
		return FALSE;
	}
	if (!Asn1IntEncUns(Asn1, &End, SNMP_VERSION))
	{
		return FALSE;
	}
	if (!Asn1HdrEnc(Asn1, End, ASN1_UNI, ASN1_PRI, ASN1_INT))
	{
		return FALSE;
	}
	if (!Asn1HdrEnc(Asn1, Eoc, ASN1_UNI, ASN1_CON, ASN1_SEQ))
	{
		return FALSE;
	}
	return TRUE;
}


int SnmpMsgDec
    (
    asn1_sck_t *    Asn1, 
    snmp_pdu_t *    Pdu, 
    u8 *            Com, 
    u32             ComSze, 
    u32 *           ComLen, 
    snmp_object_t * Lst, 
    u32             LstSze, 
    u32 *           LstLen
    )
{
	u32 Cls, Con, Tag, Ver;
	u8 *Eoc, *End;

	if (!Asn1HdrDec(Asn1, &Eoc, &Cls, &Con, &Tag))
	{
		return FALSE;
	}
	if (Cls != ASN1_UNI || Con != ASN1_CON || Tag != ASN1_SEQ)
	{
		return FALSE;
	}
	if (!Asn1HdrDec(Asn1, &End, &Cls, &Con, &Tag))
	{
		return FALSE;
	}
	if (Cls != ASN1_UNI || Con != ASN1_PRI || Tag != ASN1_INT)
	{
		return FALSE;
	}
	if (!Asn1IntDecUns(Asn1, End, &Ver))
	{
		return FALSE;
	}
	if (!Asn1HdrDec(Asn1, &End, &Cls, &Con, &Tag))
	{
		return FALSE;
	}
	if (Cls != ASN1_UNI || Con != ASN1_PRI || Tag != ASN1_OTS)
	{
		return FALSE;
	}
	if (!Asn1OtsDec(Asn1, End, Com, ComSze, ComLen))
	{
		return FALSE;
	}
	if (Ver != SNMP_VERSION)
	{
		SnmpStat.InBadVersions++;
		return FALSE;
	}
	if (!SnmpPduDec(Asn1, Pdu, Lst, LstSze, LstLen))
	{
		return FALSE;
	}
	if (!Asn1EocDec(Asn1, Eoc))
	{
		return FALSE;
	}
	return TRUE;
}


int SnmpEnc
    (
    u8 **           Snmp, 
    u32 *           SnmpLen, 
    snmp_pdu_t *    Pdu, 
    u8 *            Com, 
    u32             ComLen, 
    snmp_object_t * Lst, 
    u32             LstLen
    )
{
	static asn1_sck_t SnmpEncAsn1;

	snmpErrStatus = SNMP_NOERROR;
	snmpErrIndex = 0;

	Asn1Opn(&SnmpEncAsn1, *Snmp, *SnmpLen, ASN1_ENC);
	if (!SnmpMsgEnc(&SnmpEncAsn1, Pdu, Com, ComLen, Lst, LstLen))
	{

		if (snmpErrStatus == SNMP_NOERROR)
		{
			switch (asn1ErrStatus)
			{
			case ASN1_ERR_ENC_FULL:
			case ASN1_ERR_NOERROR:
			case ASN1_ERR_DEC_EMPTY:
			case ASN1_ERR_DEC_EOC_MISMATCH:
			case ASN1_ERR_DEC_LENGTH_MISMATCH:
			case ASN1_ERR_DEC_BADVALUE:
			case ASN1_ERR_ENC_BADVALUE:
			default:
				//PrintStr("\r\nSnmpEnc: GENERROR, asn1ErrStatus = %d", asn1ErrStatus);
				snmpErrStatus = SNMP_GENERROR;
				SnmpStat.OutGenErrs++;
				break;

			}
		}
		return FALSE;
	}

	Asn1Cls(&SnmpEncAsn1, Snmp, SnmpLen);

	SnmpStat.OutPkts++;

	switch (Pdu->Type)
	{
	case SNMP_PDU_GET:
		SnmpStat.OutGetRequests++;
		break;
	case SNMP_PDU_NEXT:
		SnmpStat.OutGetNexts++;
		break;
	case SNMP_PDU_RESPONSE:
		SnmpStat.OutGetResponses++;
		break;
	case SNMP_PDU_SET:
		SnmpStat.OutSetRequests++;
		break;
	case SNMP_PDU_TRAP:
		SnmpStat.OutTraps++;
		break;
	default:
		break;
	}

	return TRUE;
}



int SnmpDec
    (
    u8 *            Snmp, 
    u32             SnmpLen, 
    snmp_pdu_t *    Pdu, 
    u8 *            Com, 
    u32             ComSze, 
    u32 *           ComLen, 
    snmp_object_t * Lst, 
    u32             LstSze, 
    u32 *           LstLen
    )
{
	static asn1_sck_t SnmpDecAsn1;

	snmpErrStatus = SNMP_NOERROR;
	snmpErrIndex = 0;

	Asn1Opn(&SnmpDecAsn1, Snmp, SnmpLen, ASN1_DEC);
	if (!SnmpMsgDec(&SnmpDecAsn1, Pdu, Com, ComSze, ComLen, Lst, LstSze, LstLen))
	{
		if (snmpErrStatus == SNMP_NOERROR)
		{
			switch (asn1ErrStatus)
			{
			case ASN1_ERR_DEC_BADVALUE:
			case ASN1_ERR_DEC_EOC_MISMATCH:
			case ASN1_ERR_DEC_LENGTH_MISMATCH:
			case ASN1_ERR_DEC_EMPTY:
				snmpErrStatus = SNMP_BADVALUE;
				SnmpStat.OutBadValues++;
				SnmpStat.InASNParseErrs++;
				break;
			case ASN1_ERR_ENC_FULL:
			case ASN1_ERR_NOERROR:
			case ASN1_ERR_ENC_BADVALUE:
			default:
				snmpErrStatus = SNMP_GENERROR;
				SnmpStat.OutGenErrs++;
				break;
			}
		}
		return FALSE;
	}

	Asn1Cls(&SnmpDecAsn1, &Snmp, &SnmpLen);

	SnmpStat.InPkts++;
	switch (Pdu->Type)
	{
	case SNMP_PDU_GET:
		SnmpStat.InGetRequests++;
		break;
	case SNMP_PDU_NEXT:
		SnmpStat.InGetNexts++;
		break;
	case SNMP_PDU_RESPONSE:
		SnmpStat.InGetResponses++;
		break;
	case SNMP_PDU_SET:
		SnmpStat.InSetRequests++;
		break;
	case SNMP_PDU_TRAP:
		SnmpStat.InTraps++;
		break;
	default:
		break;
	}

	return TRUE;
}



int SnmpErrEnc
    (
    snmp_pdu_t * Rqs
    )
{
	u8 *End;
/* asn1_sck_t *Asn1 = &snmpErrAsn1; */

	if (!Asn1IntEncUns(&snmpErrAsn1Index, &End, Rqs->ErrorIndex))
		return FALSE;
	if (!Asn1HdrEnc(&snmpErrAsn1Index, End, ASN1_UNI, ASN1_PRI, ASN1_INT))
		return FALSE;

	if (!Asn1IntEncUns(&snmpErrAsn1Status, &End, Rqs->ErrorStatus))
		return FALSE;
	if (!Asn1HdrEnc(&snmpErrAsn1Status, End, ASN1_UNI, ASN1_PRI, ASN1_INT))
		return FALSE;

/*    if(!Asn1IntEncLngUns(&snmpErrAsn1Status, &End, Rqs->Id))
 * return FALSE;
 * if(!Asn1HdrEnc(Asn1, End, ASN1_UNI, ASN1_PRI, ASN1_INT))
 * return FALSE; 
 */

	if (!Asn1HdrEnc(&snmpErrAsn1Resp, snmpErrAsn1Resp.End, ASN1_CTX, ASN1_CON, Rqs->Type))
		return FALSE;
	return TRUE;
}


// all above from SNMP.c file
static 
int MsgRequest(u8 * rqsBuffer, u32 rqsLen,u8 ** rspBuffer,u32 * rspLen,ul32  addr);

void dword2mem
    (
    u8 * mem, 
    ul32 val
    )
{
	*(ul32 *) mem = val;
}

void bzero(u8* str, i32 len)
{
	i32 i;
	for(i=0;iType = SNMP_PDU_RESPONSE;
		rqs->ErrorStatus = (u32) snmpErrStatus;
		rqs->ErrorIndex = (u32) snmpErrIndex;

		if (!SnmpErrEnc(rqs))
		{
			return (FALSE);
		}

		memcpy(*rspBuffer, rqsBuffer, rqsLen);
		*rspLen = rqsLen;
		return (TRUE);
	}																																			

	if (Requestpdu.Type != SNMP_PDU_GET &&
		Requestpdu.Type != SNMP_PDU_NEXT &&
		Requestpdu.Type != SNMP_PDU_SET)
	{
		PrintStr("SNMP, unknown PDU\n");
		return (FALSE);
	}

	if (snmpAuthEnable == AGENT_AUTH_ENABLE)
	{
		int p=0;
		RequestComm[commLen] = '\0';
		p = authCommFind(RequestComm);

		if (p)
			perm = authComms[--p].access;
		else
			perm = 0;

		if (perm == 0)
		{
			memcpy((i8 *) RequestComm, (i8 *) & Requestbuf[0], commLen);
			SendENTTrap(SNMP_TRAP_AUTFAILURE, 0, 0);
			return (FALSE);
		}
		if (authHostInComm(authComms[p].name, addr) == ERROR)
		{
			dword2mem(Requestaddress, (ul32)addr);
			memcpy((i8 *) RequestComm, (i8 *) & Requestbuf[0], commLen);
			SendENTTrap(SNMP_TRAP_AUTFAILURE, 0, 0);
			return (FALSE);
		}
		switch (Requestpdu.Type)
		{
		    case SNMP_PDU_NEXT:
		    case SNMP_PDU_GET:

			    break;
		    case SNMP_PDU_SET:
			    if ((perm & (u16) MIB_WRITE) == 0)
			    {
			    SendENTTrap(SNMP_TRAP_AUTFAILURE,0, 0);
				    return (FALSE);
			    }
			    break;
		    default:
			    break;
		}
	}

	for (aindex = 0; aindex < listLen; aindex++)
	{
		RequestList[aindex].Request = (u16) Requestpdu.Type;
	}
/*	status = MibRequest(listLen, RequestList, &aindex);

	if (status != SNMP_NOERROR)
	{
		rqs->Type = SNMP_PDU_RESPONSE;
		rqs->ErrorStatus = status;
		rqs->ErrorIndex = aindex;

		if (!SnmpErrEnc(rqs))
		{
			return (FALSE);
		}

		memcpy(*rspBuffer, rqsBuffer, rqsLen);
		*rspLen = rqsLen;
		return (TRUE);
	}
*/
	rqs->Type = SNMP_PDU_RESPONSE;
	rqs->ErrorStatus = SNMP_NOERROR;
	rqs->ErrorIndex = 0;

	if (!SnmpEnc(rspBuffer, rspLen, &Requestpdu, RequestComm, commLen, RequestList, listLen))
	{
		rqs->Type = SNMP_PDU_RESPONSE;
		rqs->ErrorStatus = (u32) snmpErrStatus;
		rqs->ErrorIndex = (u32) snmpErrIndex;

		if (!SnmpErrEnc(rqs))
		{
			return (FALSE);
		}

		memcpy(*rspBuffer, rqsBuffer, rqsLen);
		*rspLen = rqsLen;
		return (TRUE);
	}
	return (TRUE);
}

void snmpcycle()
{
	;//do nothing here
}
void udp_recv()
{
	int status,i;
	int rqsLen,rspLen;
	char rspBuffer[AGENT_BUFFER_SIZE];
	char rqsBuffer[AGENT_BUFFER_SIZE];
	u8 * rsp = rspBuffer;
	ul32 addr = rxdnet.ipframe.sourceip; //目标IP地址
	int port = rxdnet.udpframe.sourceport; // 目的端口号
	rqsLen = rxdnet.udpframe.length-8;
	
	PrintStr("\nSNMP Message begin");
			
	PrintStr("\nUDP: dest_Port=");
	PrintWord(rxdnet.udpframe.destport);
						
	PrintStr("  source_Port=");
	PrintWord(rxdnet.udpframe.sourceport);

	PrintStr("  length=");
	PrintWord(rxdnet.udpframe.length);

	for(i=0;i