📄 wsnmp_bn.c
字号:
// wsnmp_bn.c
//
// WinSNMP Low-Level SNMP/ASN.1/BER Functions and helpers
// Copyright 1995-1997 ACE*COMM Corp
// Rleased to Microsoft under Contract
// Beta 1 version, 970228
// Bob Natale (bnatale@acecomm.com)
//
// 980424 - Received msgLen may be larger than pduLen
// - ParsePduHdr() and ParseMessage() now accommodate this.
// 980420 - Mods related to ParseCntr64() inspired by
// MS bug ID 127357 (removal of temp64 variable)
// - Mod to ParseOID() for MS bug ID 127353
// (reset os_ptr->ptr to NULL on error)
//
// 970310 - Typographical changes
//
#include "winsnmp.inc"
long FindLenVarBind (LPVARBIND vb_ptr);
long FindLenVALUE (smiLPVALUE);
long FindLenOctetString (smiLPOCTETS os_ptr);
long FindLenOID (smiLPCOID oid_ptr);
long FindLenUInt (smiUINT32 value);
long FindLenInt (smiINT32 value);
long FindLenCntr64 (smiLPCNTR64 value);
long DoLenLen (smiINT32 len);
void AddLen (smiLPBYTE *tmpPtr, smiINT32 lenlen, smiINT32 data_len);
long AddVarBind (smiLPBYTE *tmpPtr, LPVARBIND vb_ptr);
long AddOctetString (smiLPBYTE *tmpPtr, int type, smiLPOCTETS os_ptr);
long AddOID (smiLPBYTE *tmpPtr, smiLPOID oid_ptr);
long AddUInt (smiLPBYTE *tmpPtr, int type, smiUINT32 value);
long AddInt (smiLPBYTE *tmpPtr, smiINT32 value);
long AddCntr64 (smiLPBYTE *tmpPtr, smiLPCNTR64 value);
void AddNull (smiLPBYTE *tmpPtr, int type);
LPVARBIND ParseVarBind (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen);
BOOL ParseOctetString (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen, smiLPOCTETS os_ptr);
BOOL ParseOID (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen, smiLPOID oid_ptr);
BOOL ParseCntr64 (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen, smiLPCNTR64 cntr64_ptr);
BOOL ParseUInt (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen, smiLPUINT32 value);
BOOL ParseInt (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen, smiLPINT value);
BOOL ParseNull (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen);
BOOL ParseSequence (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen);
smiINT32 ParseType (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen);
smiINT32 ParseLength (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen);
void FreeOctetString (smiLPOCTETS os_ptr)
{
if (os_ptr)
{
if (os_ptr->ptr)
GlobalFree (os_ptr->ptr);
GlobalFree (os_ptr);
}
return;
}
void FreeVarBindList (LPVARBIND vb_ptr)
{
if (vb_ptr)
{ // NULLs are handled by downstream call
FreeVarBindList (vb_ptr->next_var);
FreeVarBind (vb_ptr);
}
return;
}
void FreeVarBind (LPVARBIND vb_ptr)
{
if (vb_ptr)
{
if (vb_ptr->name.ptr)
GlobalFree (vb_ptr->name.ptr);
switch (vb_ptr->value.syntax)
{
case SNMP_SYNTAX_OID:
if (vb_ptr->value.value.oid.ptr)
GlobalFree (vb_ptr->value.value.oid.ptr);
break;
case SNMP_SYNTAX_OCTETS:
case SNMP_SYNTAX_IPADDR:
case SNMP_SYNTAX_OPAQUE:
if (vb_ptr->value.value.string.ptr)
GlobalFree (vb_ptr->value.value.string.ptr);
break;
default: // Remaining types do not have 'ptr' members
break;
} // end_switch
GlobalFree (vb_ptr);
} // end_if (vb_ptr)
return;
} // end_FreeVarBind
void FreeV1Trap (LPV1TRAP v1Trap_ptr)
{
if (v1Trap_ptr)
{
if (v1Trap_ptr->enterprise.ptr)
GlobalFree (v1Trap_ptr->enterprise.ptr);
if (v1Trap_ptr->agent_addr.ptr)
GlobalFree (v1Trap_ptr->agent_addr.ptr);
GlobalFree (v1Trap_ptr);
}
} // end_FreeV1Trap
void AddLen (smiLPBYTE *tmpPtr, long lenlen, long data_len)
{
long i;
if (lenlen == 1)
*(*tmpPtr)++ = (smiBYTE)data_len;
else
{
*(*tmpPtr)++ = (smiBYTE)(0x80 + lenlen - 1);
for (i = 1; i < lenlen; i++)
{
*(*tmpPtr)++ = (smiBYTE)((data_len >>
(8 * (lenlen - i - 1))) & 0xFF);
} // end_for
} // end_else
return;
} // end_AddLen
long AddVarBind (smiLPBYTE *tmpPtr, LPVARBIND vb_ptr)
{
long lenlen;
if (vb_ptr == NULL)
return (0);
if ((lenlen = DoLenLen(vb_ptr->data_length)) == -1)
return (-1);
*(*tmpPtr)++ = SNMP_SYNTAX_SEQUENCE;
AddLen (tmpPtr, lenlen, vb_ptr->data_length);
if (AddOID (tmpPtr, &vb_ptr->name) == -1)
return (-1);
switch (vb_ptr->value.syntax)
{
case SNMP_SYNTAX_CNTR32:
case SNMP_SYNTAX_GAUGE32:
case SNMP_SYNTAX_TIMETICKS:
case SNMP_SYNTAX_UINT32:
AddUInt (tmpPtr, (int)vb_ptr->value.syntax, vb_ptr->value.value.uNumber);
break;
case SNMP_SYNTAX_INT:
AddInt (tmpPtr, vb_ptr->value.value.sNumber);
break;
case SNMP_SYNTAX_OID:
if (AddOID (tmpPtr, (smiLPOID)&(vb_ptr->value.value.oid)) == -1)
return (-1);
break;
case SNMP_SYNTAX_CNTR64:
AddCntr64 (tmpPtr, (smiLPCNTR64)&(vb_ptr->value.value.hNumber));
break;
case SNMP_SYNTAX_OCTETS:
case SNMP_SYNTAX_IPADDR:
case SNMP_SYNTAX_OPAQUE:
if (AddOctetString (tmpPtr, (int)vb_ptr->value.syntax,
(smiLPOCTETS)&(vb_ptr->value.value.string)) == -1)
return -1;
break;
case SNMP_SYNTAX_NULL:
case SNMP_SYNTAX_NOSUCHOBJECT:
case SNMP_SYNTAX_NOSUCHINSTANCE:
case SNMP_SYNTAX_ENDOFMIBVIEW:
AddNull (tmpPtr, (int)vb_ptr->value.syntax);
break;
default:
return (-1);
} // end_switch
return (AddVarBind (tmpPtr, vb_ptr->next_var));
}
long AddOctetString (smiLPBYTE *tmpPtr, int type, smiLPOCTETS os_ptr)
{
UINT i;
long lenlen;
if ((lenlen = DoLenLen ((long)os_ptr->len)) == -1)
return (-1);
*(*tmpPtr)++ = (smiBYTE)(0xFF & type);
AddLen (tmpPtr, lenlen, os_ptr->len);
for (i = 0; i < os_ptr->len; i++)
*(*tmpPtr)++ = os_ptr->ptr[i];
return (0);
}
long AddOID (smiLPBYTE *tmpPtr, smiLPOID oid_ptr)
{
UINT i;
long lenlen = 0;
long encoded_len;
encoded_len = 1; // for first two SID's
for (i = 2; i < oid_ptr->len; i++)
{
if (oid_ptr->ptr[i] < 0x80) // 0 - 0x7F
encoded_len += 1;
else if (oid_ptr->ptr[i] < 0x4000) // 0x80 - 0x3FFF
encoded_len += 2;
else if (oid_ptr->ptr[i] < 0x200000) // 0x4000 - 0x1FFFFF
encoded_len += 3;
else if (oid_ptr->ptr[i] < 0x10000000) // 0x200000 - 0xFFFFFFF
encoded_len += 4;
else
encoded_len += 5;
}
if ((lenlen = DoLenLen (encoded_len)) == -1)
return (-1);
*(*tmpPtr)++ = (smiBYTE)(0xFF & SNMP_SYNTAX_OID);
AddLen (tmpPtr, lenlen, encoded_len);
if (oid_ptr->len < 2)
*(*tmpPtr)++ = (smiBYTE)(oid_ptr->ptr[0] * 40);
else
*(*tmpPtr)++ = (smiBYTE)((oid_ptr->ptr[0] * 40) + oid_ptr->ptr[1]);
for (i = 2; i < oid_ptr->len; i++)
{
if (oid_ptr->ptr[i] < 0x80)
{ // 0 - 0x7F
*(*tmpPtr)++ = (smiBYTE)oid_ptr->ptr[i];
}
else if (oid_ptr->ptr[i] < 0x4000)
{ // 0x80 - 0x3FFF
*(*tmpPtr)++ = (smiBYTE)
(((oid_ptr->ptr[i]) >> 7) | 0x80); // set high bit
*(*tmpPtr)++ = (smiBYTE)(oid_ptr->ptr[i] & 0x7f);
}
else if (oid_ptr->ptr[i] < 0x200000)
{ // 0x4000 - 0x1FFFFF
*(*tmpPtr)++ = (smiBYTE)
(((oid_ptr->ptr[i]) >> 14) | 0x80); // set high bit
*(*tmpPtr)++ = (smiBYTE)
(((oid_ptr->ptr[i]) >> 7) | 0x80); // set high bit
*(*tmpPtr)++ = (smiBYTE)(oid_ptr->ptr[i] & 0x7f);
}
else if (oid_ptr->ptr[i] < 0x10000000)
{ // 0x200000 - 0xFFFFFFF
*(*tmpPtr)++ = (smiBYTE)
(((oid_ptr->ptr[i]) >> 21) | 0x80); // set high bit
*(*tmpPtr)++ = (smiBYTE)
(((oid_ptr->ptr[i]) >> 14) | 0x80); // set high bit
*(*tmpPtr)++ = (smiBYTE)
(((oid_ptr->ptr[i]) >> 7) | 0x80); // set high bit
*(*tmpPtr)++ = (smiBYTE)(oid_ptr->ptr[i] & 0x7f);
}
else
{
*(*tmpPtr)++ = (smiBYTE)
(((oid_ptr->ptr[i]) >> 28) | 0x80); // set high bit
*(*tmpPtr)++ = (smiBYTE)
(((oid_ptr->ptr[i]) >> 21) | 0x80); // set high bit
*(*tmpPtr)++ = (smiBYTE)
(((oid_ptr->ptr[i]) >> 14) | 0x80); // set high bit
*(*tmpPtr)++ = (smiBYTE)
(((oid_ptr->ptr[i]) >> 7) | 0x80); // set high bit
*(*tmpPtr)++ = (smiBYTE)(oid_ptr->ptr[i] & 0x7f);
}
} // end_for
return (0);
} // end_AddOID
long AddUInt (smiLPBYTE *tmpPtr, int type, smiUINT32 value)
{
long i;
long datalen;
long lenlen;
// if high bit one, must use 5 octets (first with 00)
if (((value >> 24) & 0xFF) != 0)
datalen = 4;
else if (((value >> 16) & 0xFF) != 0)
datalen = 3;
else if (((value >> 8) & 0xFF) != 0)
datalen = 2;
else
datalen = 1;
if (((value >> (8 * (datalen - 1))) & 0x80) != 0)
datalen++;
lenlen = 1; // < 127 octets
*(*tmpPtr)++ = (smiBYTE)(0xFF & type);
AddLen(tmpPtr, lenlen, datalen);
if (datalen == 5)
{ // gotta put a 00 in first octet
*(*tmpPtr)++ = (smiBYTE)0;
for (i = 1; i < datalen; i++)
{
*(*tmpPtr)++ = (smiBYTE)(value >>
(8 * ((datalen - 1) - i) & 0xFF));
}
} // end_if
else
{
for (i = 0; i < datalen; i++)
{
*(*tmpPtr)++ = (smiBYTE)(value >>
(8 * ((datalen - 1) - i) & 0xFF));
}
} // end_else
return (0);
} // end_AddUInt
long AddInt (smiLPBYTE *tmpPtr, smiINT32 value)
{
long i;
long datalen;
long lenlen;
switch ((smiBYTE) ((value >> 24) & 0xFF))
{
case 0x00:
if (((value >> 16) & 0xFF) != 0)
datalen = 3;
else if (((value >> 8) & 0xFF) != 0)
datalen = 2;
else
datalen = 1;
if (((value >> (8 * (datalen - 1))) & 0x80) != 0)
datalen++;
break;
case 0xFF:
if (((value >> 16) & 0xFF) != 0xFF)
datalen = 3;
else if (((value >> 8) & 0xFF) != 0xFF)
datalen = 2;
else
datalen = 1;
if (((value >> (8 * (datalen - 1))) & 0x80) == 0)
datalen++;
break;
default:
datalen = 4;
} // end_switch
lenlen = 1; // < 127 octets
*(*tmpPtr)++ = (smiBYTE)(0xFF & SNMP_SYNTAX_INT);
AddLen(tmpPtr, lenlen, datalen);
for (i = 0; i < datalen; i++)
{
*(*tmpPtr)++ = (smiBYTE) (value >>
(8 * ((datalen - 1) - i) & 0xFF));
}
return (0);
} // end_AddInt()
long AddCntr64 (smiLPBYTE *tmpPtr, smiLPCNTR64 value)
{
long i;
long datalen;
long lenlen;
datalen = FindLenCntr64(value) - 2;
lenlen = 1; // < 127 octets
*(*tmpPtr)++ = (smiBYTE)(0xFF & SNMP_SYNTAX_CNTR64);
AddLen(tmpPtr, lenlen, datalen);
if (datalen == 9)
{ // gotta put a 00 in first octet
*(*tmpPtr)++ = (smiBYTE)0;
datalen--;
}
for (i = datalen; i > 4; i--)
{
*(*tmpPtr)++ = (smiBYTE)(value->hipart >>
(8 * (i - 5) & 0xFF));
}
for (; i > 0; i--)
{
*(*tmpPtr)++ = (smiBYTE)(value->lopart >>
(8 * (i - 1) & 0xFF));
}
return (0);
}
long FindLenVarBind (LPVARBIND vb_ptr)
{
long lenlen;
long tot_so_far;
if (!vb_ptr) return (0);
tot_so_far = FindLenVarBind (vb_ptr->next_var);
if (tot_so_far == -1)
return (-1);
vb_ptr->data_length = FindLenOID (&vb_ptr->name) +
FindLenVALUE (&vb_ptr->value);
if ((lenlen = DoLenLen (vb_ptr->data_length)) == -1)
return (-1);
return (1 + lenlen + vb_ptr->data_length + tot_so_far);
} // end_FindLenVarBind
long FindLenVALUE (smiLPVALUE value_ptr)
{
if (value_ptr)
{
switch (value_ptr->syntax)
{
case SNMP_SYNTAX_OCTETS:
case SNMP_SYNTAX_IPADDR:
case SNMP_SYNTAX_OPAQUE:
return (FindLenOctetString (&value_ptr->value.string));
case SNMP_SYNTAX_OID:
return (FindLenOID (&value_ptr->value.oid));
case SNMP_SYNTAX_NULL:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -