?? snmp_encode.c
字號:
#include "snmptype.h"
#if SNMP_WANTED==1
#include "snmpdef.h"
#include "snmpfunc.h"
/****************************************************************************
NAME: Get_Vb_Size
PURPOSE: Compute and set the internal length of a var bind
PARAMETERS:VB_T * The VarBind to be sized.
RETURNS: _UINT16 The number of octets the Var Bind would
use if ASN.1 encoded, including the var bind sequence
****************************************************************************/
_UINT16 Get_Vb_Size(VB_T * vbp)
{
_UINT16 vb_size; /* Accumulator of size of VarBind sequence */
_UINT16 obj_size;
obj_size = A_SizeOfObjectId((OBJ_ID_T *)&(vbp->vb_obj_id));
vb_size = 1 /* The object ID tag is always 1 octet long */
+ A_SizeOfLength(obj_size) + obj_size;
switch (vbp->vb_data_flags_n_type)
{
case VT_NUMBER:
vbp->vb_data_length = A_SizeOfInt(vbp->value_u.v_number);
break;
case VT_COUNTER:
case VT_GAUGE:
case VT_TIMETICKS:
vbp->vb_data_length = A_SizeOfUnsignedInt(vbp->value_u.v_counter);
break;
case VT_STRING:
case VT_OPAQUE:
/*vbp->vb_data_length = strlen(vbp->value_u.v_string);*/
break;
case VT_OBJECT:
vbp->vb_data_length = A_SizeOfObjectId(&(vbp->value_u.v_object));
break;
case VT_NOSUCHINS:
case VT_NOSUCHOBJ:
case VT_ENDOFMIB:
case VT_EMPTY:
vbp->vb_data_length = 0;
break;
case VT_IPADDRESS:
vbp->vb_data_length = 4;
break;
/* We only include the following cases if v2 types are installed */
#if 1
case VT_COUNTER64:
vbp->vb_data_length = A_SizeOfUnsignedInt64(&(vbp->value_u.v_counter64));
break;
#endif
default:
break;
}
vbp->vb_seq_size = vb_size + 1 /* The data tag is always 1 octet */
+ A_SizeOfLength(vbp->vb_data_length) + vbp->vb_data_length;
return (1/* The sequence tag is always 1 octet */
+ A_SizeOfLength(vbp->vb_seq_size) + vbp->vb_seq_size);
}
/****************************************************************************
NAME: Set_Vbl_Sizes
PURPOSE: Scan a VarBindList, setting the internal lengths and computing
the total length.
PARAMETERS:
VB_T * The VarBindList structure to be scanned and set
RETURNS: _UINT16 The number of octets the VarBindList contents would
use if ASN.1 encoded, including the list sequence
****************************************************************************/
_UINT16 Set_Vbl_Sizes(SNMP_PKT_T * rp)
{
_INT16 i=0;
VB_T *vbp;
_UINT16 vblist_size=0;
if(rp->pdu_type==TRAP_PDU)
i=1;
else
i=0;
for(;i<rp->pdu.vb_count;i++)
{
vbp=(VB_T *)(&(rp->pdu.vb_obj[i]));
vblist_size += Get_Vb_Size(vbp);
}
rp->pdu.vbl_length = vblist_size;
return (1/* Size of tag on VarBindList sequence */
+ A_SizeOfLength(vblist_size) + vblist_size);
}
/****************************************************************************
NAME: Set_Pdu_Size
PURPOSE: Set the length of the pdu, this will cause the var bind list
to be scanned and have it's lengths set as well
PARAMETERS:
SNMP_PKT_T * The packet to be scanned and set
RETURNS: _UINT16 The number of octets the pdu contents would
use if ASN.1 encoded, including the pdu sequence
****************************************************************************/
_UINT16 Set_Pdu_Size(SNMP_PKT_T * rp)
{
rp->pdu_length = 2 /* Tag and length of request_id (an integer) */
+ A_SizeOfInt(rp->pdu.request_id) + 2 /* Tag and length of error_status (an integer) */
+ A_SizeOfInt(rp->pdu.error_status) + 2 /* Tag and length of error_index (an integer) */
+ A_SizeOfInt(rp->pdu.error_index) + Set_Vbl_Sizes(rp);
return (1/* Size of tag on pdu sequence */
+ A_SizeOfLength(rp->pdu_length) + rp->pdu_length);
}
/****************************************************************************
BUFSIZE_FOR_NORMAL_PKT
****************************************************************************/
_UINT16 Bufsize_For_Normal_Pkt(SNMP_PKT_T * rp)
{
_UINT16 alength;
_UINT16 buffer_needed;
alength = A_SizeOfOctetString(strlen(rp->community));
rp->overall_length = Set_Pdu_Size(rp) + 2 /* Tag and length of snmp_version (an integer) */
+ A_SizeOfInt(rp->snmp_version) + 1 /* Tag for the community octetstring */
+ A_SizeOfLength(alength) + alength;
buffer_needed = rp->overall_length + 1 /* Size of tag for overall Message sequence */
+ A_SizeOfLength(rp->overall_length);
return buffer_needed;
}
_UINT16 Bufsize_For_Trap_pkt(SNMP_PKT_T * rp)
{
_UINT16 alength;
rp->pdu_length =
2 /* Tag and length of request_id (an integer) */
+ A_SizeOfObjectId(&(rp->pdu.vb_obj[0].vb_obj_id)) +
2 /* Tag and length of net_address (a string) */
+ 4/* Size of IP address in SMI */
+ 2/* Tag and length of generic_trap (an integer) */
+ A_SizeOfInt(rp->pdu.error_status) /*generic_trap*/
+ 2 /* Tag and length of specific_trap (an integer) */
+ A_SizeOfInt(rp->pdu.error_index)
+2 /* Tag and length of trap_time_ticks (an uinteger) */
+ A_SizeOfUnsignedInt(0)/*time tick*/
+ Set_Vbl_Sizes(rp);
alength = A_SizeOfOctetString(strlen(rp->community));
rp->overall_length = 1 /* Size of tag on the PDU sequences */
+ A_SizeOfLength(rp->pdu_length) + rp->pdu_length + 2 /* Tag and length of snmp_version (an integer) */
+ A_SizeOfInt(rp->snmp_version) + 1 /* Tag for the community octetstring */
+ A_SizeOfLength(alength) + alength;
alength = rp->overall_length + 1 /* Size of tag for overall Message sequence */
+ A_SizeOfLength(rp->overall_length);
return alength;
}
/****************************************************************************
NAME: SNMP_Encode_Var_Bind_List
PURPOSE: Encode a VarBindList
PARAMETERS:
_UINT8 * Pointer to the packet
VB_T * The VarBindList to be encoded
RETURNS: Nothing
****************************************************************************/
void SNMP_Encode_Var_Bind_List(SNMP_PKT_T * rp,_UINT8 *ebuffp)
{
/*VB_T *vbp;*/
_INT16 i=0;
VB_T * vbp;
/* Generate the VarBindList sequence header */
(void)A_EncodeType(A_SEQUENCE, A_UNIVERSAL | A_CONSTRUCTOR,(_UINT8 *) ebuffp);
(void)A_EncodeLength(rp->pdu.vbl_length, (_UINT8 *) ebuffp);
if(rp->pdu_type==TRAP_PDU)
i=1;
else
i=0;
for(; i < rp->pdu.vb_count; i++)
{
vbp=(VB_T *)(&(rp->pdu.vb_obj[i]));
(void)A_EncodeType(A_SEQUENCE, A_UNIVERSAL | A_CONSTRUCTOR,(_UINT8 *) ebuffp);
(void)A_EncodeLength(vbp->vb_seq_size, (_UINT8 *) ebuffp);
(void)A_EncodeObjectId(A_OBJECTID, A_UNIVERSAL | A_PRIMITIVE,&(vbp->vb_obj_id), (_UINT8 *) ebuffp);
switch (vbp->vb_data_flags_n_type)
{
case VT_NUMBER:
(void)A_EncodeInt(VT_NUMBER & ~A_IDCF_MASK,
VT_NUMBER & A_IDCF_MASK,
vbp->value_u.v_number, (_UINT8 *) ebuffp);
break;
case VT_COUNTER:
(void)A_EncodeUnsignedInt(VT_COUNTER & ~A_IDCF_MASK,
VT_COUNTER & A_IDCF_MASK,
vbp->value_u.v_counter,
(_UINT8 *) ebuffp);
break;
case VT_GAUGE:
(void)A_EncodeUnsignedInt(VT_GAUGE & ~A_IDCF_MASK,
VT_GAUGE & A_IDCF_MASK,
vbp->value_u.v_counter,
(_UINT8 *) ebuffp);
break;
case VT_TIMETICKS:
(void)A_EncodeUnsignedInt(VT_TIMETICKS & ~A_IDCF_MASK,
VT_TIMETICKS & A_IDCF_MASK,
vbp->value_u.v_counter,
(_UINT8 *) ebuffp);
break;
case VT_STRING:
(void)A_EncodeOctetString(VT_STRING & ~A_IDCF_MASK,
VT_STRING & A_IDCF_MASK,
vbp->value_u.v_string,
vbp->vb_data_length,
(_UINT8 *) ebuffp);
break;
case VT_OPAQUE:
(void)A_EncodeOctetString(VT_OPAQUE & ~A_IDCF_MASK,
VT_OPAQUE & A_IDCF_MASK,
vbp->value_u.v_string,
vbp->vb_data_length,
(_UINT8 *) ebuffp);
break;
case VT_OBJECT:
(void)A_EncodeObjectId(A_OBJECTID, A_UNIVERSAL | A_PRIMITIVE,
&(vbp->value_u.v_object),
(_UINT8 *) ebuffp);
break;
case VT_EMPTY:
(void)A_EncodeType(VT_EMPTY & ~A_IDCF_MASK,
VT_EMPTY & A_IDCF_MASK, (_UINT8 *) ebuffp);
(void)A_EncodeLength(0, (_UINT8 *) ebuffp);
break;
case VT_IPADDRESS:
(void)A_EncodeOctetString(VT_IPADDRESS & ~A_IDCF_MASK,
VT_IPADDRESS & A_IDCF_MASK,
vbp->value_u.v_network_address,
4, (_UINT8 *) ebuffp);
break;
case VT_NOSUCHOBJ:
case VT_NOSUCHINS:
case VT_ENDOFMIB:
(void)A_EncodeType((_UINT16) (vbp->vb_data_flags_n_type & ~A_IDCF_MASK),
(_UINT8) (vbp->vb_data_flags_n_type & A_IDCF_MASK),
(_UINT8 *) ebuffp);
(void)A_EncodeLength(0, (_UINT8 *) ebuffp);
break;
/* We only do include the following cases if v2 types are installed */
case VT_COUNTER64:
(void)A_EncodeUnsignedInt64(VT_COUNTER64 & ~A_IDCF_MASK,
VT_COUNTER64 & A_IDCF_MASK,
&(vbp->value_u.v_counter64),
(_UINT8 *) ebuffp);
break;
default:
break;
}
}
}
void SNMP_Encode_Trap_Pdu(SNMP_PKT_T * rp,_UINT8 *ebuffp)
{
/* Generate the PDU header */
A_EncodeType(rp->pdu_type, A_DEFAULT_SCOPE | A_CONSTRUCTOR, (_UINT8 *) ebuffp);
A_EncodeLength(rp->pdu_length, (_UINT8 *) ebuffp);
/* Encode enterprise */
A_EncodeObjectId(A_OBJECTID, A_UNIVERSAL | A_PRIMITIVE,
(&(rp->pdu.vb_obj[0].vb_obj_id)), (_UINT8 *) ebuffp);
/* Encode agent-addr */
A_EncodeOctetString(VT_IPADDRESS & ~A_IDCF_MASK,
VT_IPADDRESS & A_IDCF_MASK,
&(rp->localip),4, (_UINT8 *) ebuffp);
/* Encode generic-trap */
A_EncodeInt(A_INTEGER, A_UNIVERSAL | A_PRIMITIVE,
rp->pdu.error_status, (_UINT8 *) ebuffp);
/* Encode specific-trap */
A_EncodeInt(A_INTEGER, A_UNIVERSAL | A_PRIMITIVE,
rp->pdu.error_index, (_UINT8 *) ebuffp);
/* Encode time-stamp */
A_EncodeUnsignedInt(VT_TIMETICKS & ~A_IDCF_MASK,
VT_TIMETICKS & A_IDCF_MASK,
0, (_UINT8 *) ebuffp);
SNMP_Encode_Var_Bind_List(rp,ebuffp);
}
void SNMP_Encode_Normal_Pdu(SNMP_PKT_T * rp,_UINT8 *ebuffp)
{
/* Generate the PDU header */
(void)A_EncodeType(rp->pdu_type, A_DEFAULT_SCOPE | A_CONSTRUCTOR, (_UINT8 *) ebuffp);
(void)A_EncodeLength(rp->pdu_length, (_UINT8 *) ebuffp);
/* Encode request-id */
(void)A_EncodeInt(A_INTEGER, A_UNIVERSAL | A_PRIMITIVE, rp->pdu.request_id,(_UINT8 *) ebuffp);
/* Encode error-status */
(void)A_EncodeInt(A_INTEGER, A_UNIVERSAL | A_PRIMITIVE, rp->pdu.error_status,(_UINT8 *) ebuffp);
/* Encode error-index */
(void)A_EncodeInt(A_INTEGER, A_UNIVERSAL | A_PRIMITIVE, rp->pdu.error_index,(_UINT8 *) ebuffp);
(void)SNMP_Encode_Var_Bind_List(rp,ebuffp);
}
void SNMP_Encode_Common(_UINT8 * ebuffp,_UINT16 overall_length, _INT16 snmp_version, _UINT8 * community)
{
/* Generate the Message sequence header */
(void)A_EncodeType(A_SEQUENCE, A_UNIVERSAL | A_CONSTRUCTOR, (_UINT8 *) ebuffp);
(void)A_EncodeLength(overall_length,(_UINT8 *) ebuffp);
(void)A_EncodeInt(A_INTEGER, A_UNIVERSAL | A_PRIMITIVE,(_INT32)snmp_version,(_UINT8 *) ebuffp);
(void)A_EncodeOctetString(A_OCTETSTRING, A_UNIVERSAL | A_PRIMITIVE,community,strlen(community),(_UINT8 *)ebuffp);
}
/****************************************************************************
NAME: SNMP_Bufsize_For_Packet
PURPOSE: Compute how much buffer space is needed to hold a packet if
it were encoded.
PARAMETERS:
SNMP_PKT_T * SNMP Packet structure
RETURNS: unsigned int The buffer size required.
0 in the case that the packet has a version that the code doesn't
understand, either a completely bad version or one that the code
hasn't been compiled for.
NOTE: This routine does not account for any size differences which may
occur due to any special authentication encoding.
****************************************************************************/
_UINT16 SNMP_Bufsize_For_Packet(SNMP_PKT_T * rp)
{
if(rp->pdu_type != TRAP_PDU)
return Bufsize_For_Normal_Pkt(rp);
else
return Bufsize_For_Trap_pkt(rp);
return (0);
}
/****************************************************************************
NAME: SNMP_Encode_Pkt_With_Siz
PURPOSE: Encode an SNMP packet, with the size as one of the arguments.
PARAMETERS:
SNMP_PKT_T * SNMP Packet structure
_UINT8 * Pointer to the packet
RETURNS: TRUE Packet processed without error
FALSE Error encountered during packet processing
On a sucessful return, the ebuffer passed as a parameter will
contain the encoded packet.
****************************************************************************/
_INT16 SNMP_Encode_Pkt_With_Siz(SNMP_PKT_T * rp,_UINT8 *ebuffp,_UINT16 need)
{
/* Sanity check the space required variable */
if(need == 0)
return (-1);
/* figure out what version we have and call the proper routines to
* do the encoding */
(void)A_EncodeStart();
switch (rp->snmp_version)
{
case SNMP_VERSION_1:
/* encode the common header */
SNMP_Encode_Common(ebuffp, rp->overall_length, rp->snmp_version, rp->community);
/* encode the pdu */
if(rp->pdu_type != TRAP_PDU)
(void)SNMP_Encode_Normal_Pdu(rp, ebuffp);
else
(void)SNMP_Encode_Trap_Pdu(rp, ebuffp);
return 0;
case SNMP_VERSION_2:
/* encode the common header */
(void)SNMP_Encode_Common(ebuffp, rp->overall_length, rp->snmp_version, rp->community);
/* encode the pdu */
(void)SNMP_Encode_Normal_Pdu(rp, ebuffp);
return 0;
default:
/* incorrect version number */
return (-1);
}
}
SNMP_PKT_T *SNMP_Create_Trap_V1(SNMP_PKT_T *rp,OBJ_ID_T *trapOid,_UINT32 specfic)
{
rp->snmp_version = SNMP_VERSION_1;
rp->pdu_type = TRAP_PDU;
strcpy(rp->community,"public");
rp->pdu.request_id = 0;
rp->pdu.error_status = 6;
rp->pdu.error_index = specfic;
rp->pdu.vb_count=0;
if(trapOid!=0)
{
rp->pdu.vb_count=1;
rp->pdu.vb_obj[0].vb_obj_id.num_components=trapOid->num_components;
memcpy(rp->pdu.vb_obj[0].vb_obj_id.component_list,trapOid->component_list,sizeof(trapOid->component_list));
}
else
{
rp->pdu.error_status = specfic;
rp->pdu.error_index = 0;
}
}
#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -