📄 wsnmp_bn.c
字号:
if (pduLen > msgLen)
goto DONE;
errcode++; // 5
msgLen = pduLen; // Only pduLen counts now
if (!(ParseUInt (&msgPtr, &msgLen, version)))
goto DONE;
errcode++; // 5
if (*version != 0 && *version != 1) // SNMPv1 or SNMPv2c
goto DONE;
errcode++; // 6
if (!(os_ptr = GlobalAlloc (GPTR, sizeof(smiOCTETS))))
goto DONE;
errcode++; // 7
if (!(ParseOctetString (&msgPtr, &msgLen, os_ptr)))
goto DONE_OS;
errcode++; // 8
if (pdu == NULL)
goto DONE_OS;
ZeroMemory (pdu, sizeof(PDUS));
if ((pdu->type = ParseType (&msgPtr, &msgLen)) == -1)
goto DONE_PDU;
errcode++; // 9
if ((ParseLength (&msgPtr, &msgLen)) == -1)
goto DONE_PDU;
errcode++; // 10
switch (pdu->type)
{
case SNMP_PDU_GET:
case SNMP_PDU_GETNEXT:
case SNMP_PDU_RESPONSE:
case SNMP_PDU_SET:
case SNMP_PDU_GETBULK:
case SNMP_PDU_INFORM:
case SNMP_PDU_TRAP:
if (!(ParseInt (&msgPtr, &msgLen, &pdu->appReqId)))
goto DONE_PDU;
errcode++; // 11
if (!(ParseInt (&msgPtr, &msgLen, &pdu->errStatus)))
goto DONE_PDU;
errcode++; // 12
if (!(ParseInt (&msgPtr, &msgLen, &pdu->errIndex)))
goto DONE_PDU;
errcode++; // 13
break;
case SNMP_PDU_V1TRAP:
pdu->v1Trap = GlobalAlloc (GPTR, sizeof(V1TRAP));
if (pdu->v1Trap == NULL)
goto DONE_PDU;
errcode++; // 11
if (!(ParseOID (&msgPtr, &msgLen, &pdu->v1Trap->enterprise)))
goto DONE_PDU;
errcode++; // 12
if (!(ParseOctetString (&msgPtr, &msgLen, &pdu->v1Trap->agent_addr)))
goto DONE_PDU;
errcode++; // 13
if (!(ParseInt (&msgPtr, &msgLen, &pdu->v1Trap->generic_trap)))
goto DONE_PDU;
errcode++; // 14
if (!(ParseInt (&msgPtr, &msgLen, &pdu->v1Trap->specific_trap)))
goto DONE_PDU;
errcode++; // 15
if (!(ParseUInt (&msgPtr, &msgLen, &pdu->v1Trap->time_ticks)))
goto DONE_PDU;
errcode++; // 16
break;
default:
goto DONE_PDU;
} // end_switch
errcode = 20; // re-normalize
// Waste the SEQUENCE tag
if (!(ParseSequence (&msgPtr, &msgLen)))
goto DONE_PDU;
errcode++; // 21
// Parse the varbind list
pdu->VBL = 0;
pdu->VBL_addr = NULL;
while (msgLen)
{
if (!(vb_ptr = ParseVarBind (&msgPtr, &msgLen)))
goto DONE_PDU;
errcode++; // 22+
if (!pdu->VBL_addr) // Is this the first one?
vb_end_ptr = pdu->VBL_addr = vb_ptr; // If so, start a list
else
{ // tack onto end of list
vb_end_ptr->next_var = vb_ptr;
vb_end_ptr = vb_ptr;
}
} // end_while
errcode = 0;
*community = os_ptr;
goto DONE;
DONE_PDU:
FreeVarBindList (pdu->VBL_addr); // Checks for NULL
FreeV1Trap (pdu->v1Trap); // Checks for NULL
ZeroMemory (pdu, sizeof(PDUS));
DONE_OS:
FreeOctetString (os_ptr);
DONE:
return (errcode);
} // end_ParseMessage
LPVARBIND ParseVarBind (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen)
{
LPVARBIND vb_ptr;
if (!(ParseSequence (tmpPtr, tmpLen)))
return (NULL);
if ((vb_ptr = (LPVARBIND)GlobalAlloc(GPTR, sizeof(VARBIND))) == NULL)
return (NULL);
if (!(ParseOID(tmpPtr, tmpLen, &vb_ptr->name)))
goto ERROROUT;
vb_ptr->value.syntax = (smiUINT32)*(*tmpPtr);
switch (vb_ptr->value.syntax)
{
case SNMP_SYNTAX_CNTR32:
case SNMP_SYNTAX_GAUGE32:
case SNMP_SYNTAX_TIMETICKS:
case SNMP_SYNTAX_UINT32:
if (!(ParseUInt (tmpPtr, tmpLen, &vb_ptr->value.value.uNumber)))
goto ERROROUT;
break;
case SNMP_SYNTAX_INT:
if (!(ParseInt (tmpPtr, tmpLen, &vb_ptr->value.value.sNumber)))
goto ERROROUT;
break;
case SNMP_SYNTAX_OID:
if (!(ParseOID (tmpPtr, tmpLen, &vb_ptr->value.value.oid)))
goto ERROROUT;
break;
case SNMP_SYNTAX_CNTR64:
if (!(ParseCntr64 (tmpPtr, tmpLen, &vb_ptr->value.value.hNumber)))
goto ERROROUT;
break;
case SNMP_SYNTAX_OCTETS:
case SNMP_SYNTAX_IPADDR:
case SNMP_SYNTAX_OPAQUE:
if (!(ParseOctetString (tmpPtr, tmpLen, &vb_ptr->value.value.string)))
goto ERROROUT;
break;
case SNMP_SYNTAX_NULL:
case SNMP_SYNTAX_NOSUCHOBJECT:
case SNMP_SYNTAX_NOSUCHINSTANCE:
case SNMP_SYNTAX_ENDOFMIBVIEW:
if (!(ParseNull (tmpPtr, tmpLen)))
goto ERROROUT;
break;
default:
goto ERROROUT;
} // end_switch
return (vb_ptr); // Success
//
ERROROUT:
FreeVarBind(vb_ptr);
return (NULL); // Failure
} // end_ParseVarBind
BOOL ParseOctetString
(smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen, smiLPOCTETS os_ptr)
{
if (!os_ptr)
return (FALSE);
os_ptr->ptr = NULL;
os_ptr->len = 0;
if (ParseType (tmpPtr, tmpLen) == -1)
return (FALSE);
if ((os_ptr->len = ParseLength (tmpPtr, tmpLen)) == -1)
return (FALSE);
if (os_ptr->len > *tmpLen)
return (FALSE);
if (os_ptr->len)
{ // Does not allocate "string" space on "length = 0"
if (!(os_ptr->ptr = (smiLPBYTE)GlobalAlloc (GPTR, os_ptr->len)))
return (FALSE);
CopyMemory (os_ptr->ptr, *tmpPtr, os_ptr->len);
}
*tmpPtr += os_ptr->len;
*tmpLen -= os_ptr->len;
return (TRUE);
} // end_ParseOctetString
BOOL ParseOID (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen, smiLPOID oid_ptr)
{
smiINT32 length;
if (!oid_ptr)
return (FALSE);
oid_ptr->ptr = NULL;
oid_ptr->len = 0;
if (ParseType (tmpPtr, tmpLen) != SNMP_SYNTAX_OID)
return (FALSE);
length = ParseLength (tmpPtr, tmpLen);
// -1 is error return from ParseLength()
// Valid lengths are 1 thru MAXOBJIDSIZE
if (length <= 0 || length > MAXOBJIDSIZE)
return (FALSE);
if ((smiUINT32)length > *tmpLen)
return (FALSE);
// the sub-id array will by 1 longer than the ASN.1/BER array
oid_ptr->ptr = (smiLPUINT32)GlobalAlloc (GPTR, sizeof(smiUINT32) * (length+1));
if (oid_ptr->ptr == NULL)
return (FALSE);
// oid_ptr structure space is pre-zero'd via GlobalAlloc()
while (length)
{
oid_ptr->ptr[oid_ptr->len] =
(oid_ptr->ptr[oid_ptr->len] << 7) + (*(*tmpPtr) & 0x7F);
if ((*(*tmpPtr)++ & 0x80) == 0)
{ // on the last octet of this sub-id
if (oid_ptr->len == 0) // check for first sub-id
{ // ASN.1/BER packs two into it
oid_ptr->ptr[1] = oid_ptr->ptr[0];
oid_ptr->ptr[0] /= 40;
if (oid_ptr->ptr[0] > 2)
oid_ptr->ptr[0] = 2;
oid_ptr->ptr[1] -= (oid_ptr->ptr[0] * 40);
oid_ptr->len++; // extra bump
}
oid_ptr->len++;
}
length--;
(*tmpLen)--;
} // end_while (length)
return (TRUE);
} // end_ParseOID
BOOL ParseCntr64 (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen, smiLPCNTR64 Cntr64_ptr)
{
smiINT32 i;
smiINT32 length;
if (ParseType (tmpPtr, tmpLen) != SNMP_SYNTAX_CNTR64)
return (FALSE);
if ((length = ParseLength(tmpPtr, tmpLen)) == -1)
return (FALSE);
if ((smiUINT32)length > *tmpLen || length > 9 ||
(length == 9 && *(*tmpPtr) != 0x00))
return (FALSE);
while (length && *(*tmpPtr) == 0x00)
{ // leading null octet?
(*tmpPtr)++; // if so, skip it
length--; // and don't count it
(*tmpLen)--; // Adjust remaining msg length
}
Cntr64_ptr->hipart = Cntr64_ptr->lopart = 0;
for (i = 0; i < length; i++)
{
Cntr64_ptr->hipart = (Cntr64_ptr->hipart << 8) +
(Cntr64_ptr->lopart >> 24);
Cntr64_ptr->lopart = (Cntr64_ptr->lopart << 8) +
(smiUINT32) *(*tmpPtr)++;
}
*tmpLen -= length;
return (TRUE);
} // end_ParseCntr64
BOOL ParseUInt (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen, smiLPUINT32 value)
{
smiINT32 length;
smiINT32 i;
if (ParseType (tmpPtr, tmpLen) == -1)
return (FALSE);
if ((length = ParseLength(tmpPtr, tmpLen)) == -1)
return (FALSE);
if ((smiUINT32)length > *tmpLen)
return (FALSE);
if ((length > 5) || ((length > 4) && (*(*tmpPtr) != 0x00)))
return (FALSE);
while (length && *(*tmpPtr) == 0x00)
{ // leading null octet?
(*tmpPtr)++; // if so, skip it
length--; // and don't count it
(*tmpLen)--; // Adjust remaining msg length
}
*value = 0;
for (i = 0; i < length; i++)
*value = (*value << 8) + (smiUINT32)*(*tmpPtr)++;
*tmpLen -= length;
return (TRUE);
} // end_ParseUInt()
BOOL ParseInt (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen, smiLPINT value)
{
smiINT32 length;
smiINT32 i;
smiINT32 sign;
if (ParseType (tmpPtr, tmpLen) != SNMP_SYNTAX_INT)
return (FALSE);
if ((length = ParseLength (tmpPtr, tmpLen)) == -1)
return (FALSE);
if ((smiUINT32)length > *tmpLen || length > 4)
return (FALSE);
sign = ((*(*tmpPtr) & 0x80) == 0x00) ? 0x00 : 0xFF;
*value = 0;
for (i = 0; i < length; i++)
*value = (*value << 8) + (smiUINT32) *(*tmpPtr)++;
// sign-extend upper bits
for (i = length; i < 4; i++)
*value = *value + (sign << i * 8);
*tmpLen -= length;
return (TRUE);
} // end_ParseInt()
BOOL ParseNull (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen)
{
smiINT32 length;
if (ParseType (tmpPtr, tmpLen) == -1)
return (FALSE);
length = ParseLength (tmpPtr, tmpLen);
if (length != 0) // NULLs have no length
return (FALSE);
return (TRUE);
} // end_ParseNull
BOOL ParseSequence (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen)
{
if (ParseType (tmpPtr, tmpLen) != SNMP_SYNTAX_SEQUENCE)
return (FALSE);
if (ParseLength (tmpPtr, tmpLen) == -1)
return (FALSE);
return (TRUE);
} // end_ParseSequence
smiINT32 ParseType (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen)
{
// 980421 - BobN
// - replaced tmpLen logic with working_len logic
// - working_len is always checked on entry into a
// - Parse<xxx> function
smiINT32 type;
if (*tmpLen == 0)
return (-1);
type = *(*tmpPtr)++;
(*tmpLen)--; // Adjust remaining msg length
switch (type)
{
case SNMP_SYNTAX_INT:
case SNMP_SYNTAX_OCTETS:
case SNMP_SYNTAX_OID:
case SNMP_SYNTAX_SEQUENCE:
case SNMP_SYNTAX_IPADDR:
case SNMP_SYNTAX_CNTR32:
case SNMP_SYNTAX_GAUGE32:
case SNMP_SYNTAX_TIMETICKS:
case SNMP_SYNTAX_OPAQUE:
case SNMP_SYNTAX_UINT32:
case SNMP_SYNTAX_CNTR64:
case SNMP_SYNTAX_NULL:
case SNMP_SYNTAX_NOSUCHOBJECT:
case SNMP_SYNTAX_NOSUCHINSTANCE:
case SNMP_SYNTAX_ENDOFMIBVIEW:
case SNMP_PDU_GET:
case SNMP_PDU_GETNEXT:
case SNMP_PDU_RESPONSE:
case SNMP_PDU_SET:
case SNMP_PDU_V1TRAP:
case SNMP_PDU_GETBULK:
case SNMP_PDU_INFORM:
case SNMP_PDU_TRAP:
break;
default:
type = -1;
break;
}
return (type);
} // end_ParseType
smiINT32 ParseLength (smiLPBYTE *tmpPtr, smiLPUINT32 tmpLen)
{
// 980421 - BobN
// - replaced end_ptr logic with tmpLen logic
// - tmpLen is always checked on entry into a Parse<xxx>
// - function and is decremented as used therein.
smiINT32 length;
smiINT32 lenlen;
if (*tmpLen == 0)
return (-1);
length = (smiINT32) *(*tmpPtr)++;
(*tmpLen)--; // Adjust remaining msg length
// Check for short-form value
if (length < 0x80)
return (length);
// Long form
lenlen = length & 0x7F;
if ((smiUINT32)lenlen > *tmpLen || lenlen > 4 || lenlen < 1)
return (-1); // Out of bounds
*tmpLen -= lenlen; // Adjust remaining msg length
length = 0;
while (lenlen)
{
length = (length << 8) + *(*tmpPtr)++;
lenlen--;
}
return (length);
} // end_ParseLength
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -