📄 a_encode.c
字号:
#include "snmptype.h"
#include "snmpdef.h"
#include "a_localio.h"
#include "stdio.h"
static _UINT16 encodePointer=0;
/****************************************************************************
A_SizeOfSubId -- Compute the number of bytes required to hold a
subidentifier from an object id.
ASN.1 encoded (tag and length fields are not included)
Parameters: _UINT32
Returns: _UINT16 Number of octets needed in ASN.1 encoding
****************************************************************************/
#define A_SizeOfSubId(I) (_UINT16)((_UINT32)(I) <= 0x7F ? 1 : ((_UINT32)(I) <= 0x3FFF ? 2 : ((_UINT32)(I) <= 0x1FFFFFL ? 3 : ((_UINT32)(I) <= 0x0FFFFFFFL ? 4 : 5))))
void A_EncodeStart()
{
encodePointer=0;
}
/****************************************************************************
NAME: A_EncodeHelper
PURPOSE: Collect encoded data from the ASN.1 encoding routines and
place it into a buffer.
PAREMETERS:
EBUFFER_T * The "opaque" parameter (ebuffp) passed to the encoding
routines.
_UINT8 * The buffer where the encoded data resides
_UINT16 The number of encoded octets in the buffer.
RETURNS: Returns the number of octets consumed, zero is returned if
no more data is desired. (This may not, however, prevent
subsequent calls.)
RESTRICTIONS: Can not handle length > 64K
BUGS:
****************************************************************************/
_UINT16 A_EncodeHelper(_UINT8 *ebp, _UINT8 * bp, _UINT16 leng)
{
switch (leng)
{
case 0:
break;
case 1:
ebp[encodePointer++] = *bp;
break;
case 2:
ebp[encodePointer++] = *bp++;
ebp[encodePointer++] = *bp;
break;
default:
(void) memcpy(&ebp[encodePointer], bp, leng);
encodePointer += (_UINT16) leng;
break;
}
return (leng);
}
/****************************************************************************
A_SizeOfInt -- Return total size that an integer would occupy when
ASN.1 encoded (tag and length fields are not included).
Parameters: _INT32 The integer (signed 32 bit)
Returns: _UINT16 Number of octets the integer would occupy if in ASN.1 encoding
****************************************************************************/
_UINT16 A_SizeOfInt(_INT32 i)
{
if(i >= 0L)
return (i <= 0x0000007FL ? 1 : /* <= 127 */
(i <= 0x00007FFFL ? 2 : /* <= 32767 */
(i <= 0x007FFFFFL ? 3 : /* <= 8388607 */
4))); /* > 8388607 */
else
return (i >= (_INT32) 0xFFFFFF80L ? 1 : /* >= -128 */
(i >= (_INT32) 0XFFFF8000L ? 2 : /* >= -32768 */
(i >= (_INT32) 0XFF800000L ? 3 : /* >= -8388608 */
4))); /* < -8388608 */
}
/****************************************************************************
A_SizeOfUnsignedInt -- Return total size that an unsigned integer would
occupy when ASN.1 encoded (tag and length fields
are not included).
Parameters: _UINT32 The integer (unsigned 32 bit)
Returns: _UINT16 Number of octets the integer would occupy if in ASN.1 encoding
****************************************************************************/
_UINT16 A_SizeOfUnsignedInt(_UINT32 i)
{
return (i <= 0x0000007FL ? 1 : /* <= 127 */
(i <= 0x00007FFFL ? 2 : /* <= 32768 */
(i <= 0x007FFFFFL ? 3 : /* <= 8388607 */
(i <= 0x7FFFFFFFL ? 4 : /* <= 2147483647 */
5)))); /* > 2147483647 */
}
/****************************************************************************
A_SizeOfObjectId -- Return total size that an object ID would occupy when
ASN.1 encoded (tag and length fields are not included)
Parameters: OBJ_ID_T * Pointer to the internal object Id structure
Returns: _UINT16 Number of octets the object ID would occupy if in ASN.1 encoding
Note: It is assumed by this routine that the object identifier has at least two components.
****************************************************************************/
_UINT16 A_SizeOfObjectId(OBJ_ID_T * objp)
{
_UINT16 leng;
_UINT32 *cp = objp->component_list;
_UINT16 i;
_UINT32 x;
if(objp->num_components == 0)
return 0;
/* Compute the value of the first subidentifier from the values of the */
/* first two components. */
{
x = *cp++;
x = x * 40 + *cp++;
leng = A_SizeOfSubId(x);
}
for(i = 2; i < objp->num_components; i++)
{
x = *cp++;
leng += A_SizeOfSubId(x);
}
return leng;
}
/****************************************************************************
A_SizeOfUnsignedInt64 -- Return total size that a big unsigned integer would
occupy when ASN.1 encoded (tag and length fields
are not included).
Parameters: UINT64_T * The integer (unsigned 64 bit)
Returns: _UINT16 Number of octets the integer would occupy if in ASN.1 encoding
****************************************************************************/
_UINT16 A_SizeOfUnsignedInt64(UINT64_T * i)
{
if(i->high == 0)
return (i->low <= 0x0000007FL ? 1 : /* <= 127 */
(i->low <= 0x00007FFFL ? 2 : /* <= 32768 */
(i->low <= 0x007FFFFFL ? 3 : /* <= 8388607 */
(i->low <= 0x7FFFFFFFL ? 4 : /* <= 2147483647 */
5)))); /* > 2147483647 */
else
return (i->high <= 0x0000007FL ? 5 : /* <= 127 */
(i->high <= 0x00007FFFL ? 6 : /* <= 32768 */
(i->high <= 0x007FFFFFL ? 7 : /* <= 8388607 */
(i->high <= 0x7FFFFFFFL ? 8 : /* <= 2147483647 */
9)))); /* > 2147483647 */
}
/****************************************************************************
A_EncodeType -- Encode an ASN.1 type field into buffer.
Parameters:
_UINT16 The type value
_UINT8 A_IDCF_MASK flag values
_UINT16 (*f()) Function to be called to take generated data
_UINT8 * Parameter to be passed unchanged to the function.
Notes: The function whose address is passed as a parameter is called zero
or more times to take away some accumulated data. The function is called
with these parameters:
_UINT8 * The parameter (ebuffp) passed to this routine
_UINT8 * The buffer where the data resides
_UINT16 The number of octets in the buffer.
The function should return the number of octets consumed, type _UINT16.
The function should return a zero if it has taken all the data it wants.
Returns: nothing
****************************************************************************/
void A_EncodeType(_UINT16 id, _UINT8 flags, _UINT8 * ebuffp)
{
_UINT8 buff[5], reverse[4]; /* Can't handle more than 4 octets */
_UINT8 *bp = buff;
_UINT8 *rp = reverse;
_UINT16 count = 0; /* Should never exceed 4 */
_UINT16 cnt;
flags &= A_IDCF_MASK;
if(id <= (_UINT16) 30)
{
_UINT8 c;
c = flags | (_UINT8) id;
(void)A_EncodeHelper (ebuffp, &c, (_UINT16) sizeof(_UINT8));
}
else
{
/* Build a partial reverse order version of the result and then */
/* reverse it again back to correct order */
*bp++ = (_UINT8) ((flags & A_IDCF_MASK) | 0x1F);
while(id > 0)
{
*rp++ = (_UINT8) (id & 0x7F);
id >>= 7;
count++;
}
cnt = count + 1;
while((count--) > 1)
{
*bp++ = (_UINT8) (*(--rp) | 0x80);
}
*bp++ = *(--rp);
(void)A_EncodeHelper(ebuffp, buff, cnt);
}
}
/****************************************************************************
A_EncodeLength -- Encode an ASN.1 definite form length field into buffer.
Parameters:
_UINT16 Length to be encoded
_UINT16 (*f()) Function to be called to take generated data
_UINT8 * Parameter to be passed unchanged to the function.
Notes: The function whose address is passed as a parameter is called zero
or more times to take away some accumulated data. The function is called
with these parameters:
_UINT8 * The parameter (ebuffp) passed to this routine
_UINT8 * The buffer where the data resides
_UINT16 The number of octets in the buffer.
The function should return the number of octets consumed, type _UINT16.
The function should return a zero if it has taken all the data it wants.
Returns: nothing
****************************************************************************/
void A_EncodeLength(_UINT16 leng,_UINT8 * ebuffp)
{
_UINT8 buff[OCTETS_PER_INT32 + 1];
_UINT8 reverse[OCTETS_PER_INT32];
_UINT8 *bp = buff;
_UINT8 *rp = reverse;
_UINT16 count = 0; /* Never exceeds OCTETS_PER_INT32 */
_UINT16 cnt;
if(leng <= (_UINT16) 127)
{
_UINT8 c;
c = (_UINT8) leng;
(void)A_EncodeHelper(ebuffp, &c, (_UINT16) sizeof(_UINT8));
}
else
{
while(leng > 0)
{
*rp++ = (_UINT8) leng;
/*lint -e704 */
leng >>= 8;
/*lint +e704 */
count++;
}
*bp++ = (_UINT8) (((_UINT8) count) | (_UINT8) 0x80);
cnt = count + 1;
while((count--) > 0)
{
*bp++ = *(--rp);
}
(void)A_EncodeHelper(ebuffp, buff, cnt);
}
}
/****************************************************************************
A_EncodeInt -- generate ASN.1 format of integer (WITH TYPE & LENGTH)
Parameters:
_UINT16 The type value
_UINT8 A_IDC_MASK flag values
_INT32 The integer to convert (signed 32 bit)
_UINT16 (*f()) Function to be called to take generated data
_UINT8 * Parameter to be passed unchanged to the function.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -