📄 wsnmp_bn.c
字号:
case SNMP_SYNTAX_NOSUCHOBJECT:
case SNMP_SYNTAX_NOSUCHINSTANCE:
case SNMP_SYNTAX_ENDOFMIBVIEW:
return (2);
case SNMP_SYNTAX_INT:
return (FindLenInt (value_ptr->value.sNumber));
case SNMP_SYNTAX_CNTR32:
case SNMP_SYNTAX_GAUGE32:
case SNMP_SYNTAX_TIMETICKS:
case SNMP_SYNTAX_UINT32:
return (FindLenUInt (value_ptr->value.uNumber));
case SNMP_SYNTAX_CNTR64:
return (FindLenCntr64 (&value_ptr->value.hNumber));
} // end_switch
} // end_if
return (-1);
} // end_FindLenVALUE
long FindLenOctetString (smiLPOCTETS os_ptr)
{
long lenlen;
if (!os_ptr) return (-1);
if ((lenlen = DoLenLen (os_ptr->len)) == -1)
return (-1);
return (1 + lenlen + os_ptr->len);
}
long FindLenOID (smiLPCOID oid_ptr)
{
long lenlen;
UINT i;
UINT encoded_len;
encoded_len = 1; // for first two Sub-IDs
// beware of i = 2
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;
} // end_for
if ((lenlen = DoLenLen (encoded_len)) == -1)
return (-1);
return (1 + lenlen + encoded_len);
} // end_FindLenOID
long FindLenUInt (smiUINT32 value)
{
long datalen;
// 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++;
// length of length < 127 octets
return (1 + 1 + datalen);
}
long FindLenInt (smiINT32 value)
{
long datalen;
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
return (1 + 1 + datalen);
}
long FindLenCntr64 (smiLPCNTR64 value)
{
long datalen;
// if high bit one, must use 5 octets (first with 00)
if (((value->hipart >> 24) & 0xFF) != 0)
{
datalen = 8;
if (((value->hipart >> 24) & 0x80) != 0) datalen++;
}
else if (((value->hipart >> 16) & 0xFF) != 0)
{
datalen = 7;
if (((value->hipart >> 16) & 0x80) != 0) datalen++;
}
else if (((value->hipart >> 8) & 0xFF) != 0)
{
datalen = 6;
if (((value->hipart >> 8) & 0x80) != 0) datalen++;
}
else if (((value->hipart) & 0xFF) != 0)
{
datalen = 5;
if (((value->hipart) & 0x80) != 0) datalen++;
}
else if (((value->lopart>> 24) & 0xFF) != 0)
{
datalen = 4;
if (((value->lopart >> 24) & 0x80) != 0) datalen++;
}
else if (((value->lopart >> 16) & 0xFF) != 0)
{
datalen = 3;
if (((value->lopart >> 16) & 0x80) != 0) datalen++;
}
else if (((value->lopart >> 8) & 0xFF) != 0)
{
datalen = 2;
if (((value->lopart >> 8) & 0x80) != 0) datalen++;
}
else
{
datalen = 1;
if (((value->lopart) & 0x80) != 0) datalen++;
}
// length of length < 127 octets
return (1 + 1 + datalen);
}
long DoLenLen (long len)
{
// short form?
if (len < 128) return (1);
if (len < 0x100) return (2);
if (len < 0x10000) return (3);
if (len < 0x1000000) return (4);
return (-1);
}
void AddNull (smiLPBYTE *tmpPtr, int type)
{
*(*tmpPtr)++ = (smiBYTE)(0xFF & type);
*(*tmpPtr)++ = 0x00;
return;
}
BOOL BuildMessage (smiUINT32 version, smiLPOCTETS community,
LPPDUS pdu, smiINT32 requestId,
smiLPBYTE *msgAddr, smiLPUINT32 msgSize)
{
LPVARBIND vbList = NULL;
long nVbDataLen, nVbLenLen, nVbTotalLen;
long nPduDataLen, nPduLenLen, nPduTotalLen;
long nMsgDataLen, nMsgLenLen, nMsgTotalLen;
long nTmpDataLen;
smiLPBYTE tmpPtr = NULL;
*msgAddr = NULL;
*msgSize = 0;
if (pdu == NULL || community == NULL)
return (FALSE);
// Determine length of VarBind list part
vbList = pdu->VBL_addr;
if (vbList == NULL && pdu->VBL != 0)
vbList = ((LPVBLS)snmpGetTableEntry(&VBLsDescr, HandleToUlong(pdu->VBL)-1))->vbList;
// vbList == NULL is ok
if ((nVbDataLen = FindLenVarBind (vbList)) == -1)
return (FALSE);
if ((nVbLenLen = DoLenLen (nVbDataLen)) == -1)
return (FALSE);
nVbTotalLen = 1 + nVbLenLen + nVbDataLen;
// Determine length of PDU overhead part
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:
nPduDataLen = FindLenInt (requestId)
+ FindLenInt (pdu->errStatus)
+ FindLenInt (pdu->errIndex)
+ nVbTotalLen;
break;
case SNMP_PDU_V1TRAP:
if (!pdu->v1Trap)
return (FALSE);
nPduDataLen = FindLenInt (pdu->v1Trap->generic_trap)
+ FindLenInt (pdu->v1Trap->specific_trap)
+ FindLenUInt (pdu->v1Trap->time_ticks)
+ nVbTotalLen;
if ((nTmpDataLen = FindLenOID (&pdu->v1Trap->enterprise)) == -1)
return (FALSE);
nPduDataLen += nTmpDataLen;
if ((nTmpDataLen = FindLenOctetString (&pdu->v1Trap->agent_addr)) == -1)
return (FALSE);
nPduDataLen += nTmpDataLen;
break;
default:
return (FALSE);
} // end_switch
if ((nPduLenLen = DoLenLen(nPduDataLen)) == -1)
return (FALSE);
nPduTotalLen = 1 + nPduLenLen + nPduDataLen;
nMsgDataLen = FindLenUInt (version)
+ FindLenOctetString (community)
+ nPduTotalLen;
nMsgLenLen = DoLenLen (nMsgDataLen);
nMsgTotalLen = 1 + nMsgLenLen + nMsgDataLen;
// Allocate the necessary memory for the message
tmpPtr = GlobalAlloc (GPTR, nMsgTotalLen);
if (tmpPtr == NULL)
return (FALSE);
*msgAddr = tmpPtr;
*msgSize = nMsgTotalLen;
// Now plug in the values in the message bytes
*tmpPtr++ = SNMP_SYNTAX_SEQUENCE;
// Wrapper portion
AddLen (&tmpPtr, nMsgLenLen, nMsgDataLen);
AddInt (&tmpPtr, version);
AddOctetString (&tmpPtr, SNMP_SYNTAX_OCTETS, community);
// PDU header portion
// "Downgrade" GetBulk to GetNext if target is SNMPv1
if (pdu->type == SNMP_PDU_GETBULK && version == 0)
*tmpPtr++ = SNMP_PDU_GETNEXT;
else
*tmpPtr++ = (BYTE) pdu->type;
AddLen (&tmpPtr, nPduLenLen, nPduDataLen);
switch (pdu->type)
{
case SNMP_PDU_GET:
case SNMP_PDU_GETNEXT:
case SNMP_PDU_RESPONSE:
case SNMP_PDU_SET:
case SNMP_PDU_INFORM:
case SNMP_PDU_TRAP:
case SNMP_PDU_GETBULK:
AddInt (&tmpPtr, requestId);
AddInt (&tmpPtr, pdu->errStatus);
AddInt (&tmpPtr, pdu->errIndex);
break;
case SNMP_PDU_V1TRAP:
if (AddOID (&tmpPtr, &pdu->v1Trap->enterprise)== -1)
goto error_out;
if (AddOctetString (&tmpPtr, SNMP_SYNTAX_IPADDR, &pdu->v1Trap->agent_addr) == -1)
goto error_out;
AddInt (&tmpPtr, pdu->v1Trap->generic_trap);
AddInt (&tmpPtr, pdu->v1Trap->specific_trap);
AddUInt (&tmpPtr, SNMP_SYNTAX_TIMETICKS, pdu->v1Trap->time_ticks);
break;
default:
goto error_out;
} // end_switch
// VarBindList portion
*tmpPtr++ = SNMP_SYNTAX_SEQUENCE;
AddLen (&tmpPtr, nVbLenLen, nVbDataLen);
if (AddVarBind (&tmpPtr, vbList) == -1)
{
error_out:
if (*msgAddr)
GlobalFree (*msgAddr);
*msgAddr = NULL;
*msgSize = 0;
return (FALSE);
}
// Success
return (TRUE);
} // end_BuildMessage()
BOOL SetPduType (smiLPBYTE msgPtr, smiUINT32 msgLen, int pduType)
{
smiLPBYTE tmpPtr;
smiUINT32 tmp;
if (!(tmpPtr = msgPtr)) // Deliberate assignment
return (FALSE);
if (!(ParseSequence (&tmpPtr, &msgLen))) // sequence
return (FALSE);
if (!(ParseUInt (&tmpPtr, &msgLen, &tmp))) // version
return (FALSE);
// Jump over communityString...not needed here
if (ParseType (&tmpPtr, &msgLen) == -1)
return (FALSE);
if ((tmp = ParseLength (&tmpPtr, &msgLen)) == -1)
return (FALSE);
if (tmp > msgLen)
return (FALSE);
tmpPtr += tmp; // Jump!
// Set the PDU type byte
*tmpPtr = (smiBYTE)pduType;
return (TRUE);
} // End_SetPduType()
smiUINT32 ParsePduHdr (smiLPBYTE msgPtr, smiUINT32 msgLen,
smiLPUINT32 version, smiLPINT32 type, smiLPUINT32 reqID)
{
// This is a private function (not exported via WinSNMP)
// It is called only once by msgNotify() (another private function)
// to "peek ahead" at certain PDU attributes to determine the next
// procesing steps.
smiUINT32 pduLen;
smiUINT32 length;
long errcode = 1;
if (msgPtr == NULL)
goto DONE;
errcode++; // 2
// Parse initial Sequence field...
if (ParseType (&msgPtr, &msgLen) != SNMP_SYNTAX_SEQUENCE)
goto DONE;
errcode++; // 3
// ...to get the remaining pduLen out of it
if ((pduLen = ParseLength (&msgPtr, &msgLen)) == -1)
goto DONE;
errcode++; // 4
if (pduLen > msgLen)
goto DONE;
errcode++; // 5
msgLen = pduLen; // Only pduLen counts now
if (!(ParseUInt (&msgPtr, &msgLen, version)))
goto DONE;
errcode++; // 6
// Jump over communityString...not needed here
if (ParseType (&msgPtr, &msgLen) == -1)
goto DONE;
errcode++; // 7
if ((length = ParseLength (&msgPtr, &msgLen)) == -1)
goto DONE;
errcode++; // 8
if (length > msgLen)
goto DONE;
errcode++; // 9
msgPtr += length; // Jump!
msgLen -= length;
// Get PDU type
if ((*type = ParseType (&msgPtr, &msgLen)) == -1)
goto DONE;
errcode++; // 10
// Check PDU type for requestID semantics
if (*type == SNMP_PDU_V1TRAP)
*reqID = 0; // No requestID on v1 trapPDU
else // Not a v1 trapPDU, therefore
{ // must get requestID
if ((ParseLength (&msgPtr, &msgLen)) == -1)
goto DONE;
errcode++; // 11
if (!(ParseInt (&msgPtr, &msgLen, reqID)))
goto DONE;
}
errcode = 0;
DONE:
return (errcode);
} // end_ParsePduHdr
smiUINT32 ParseMessage (smiLPBYTE msgPtr, smiUINT32 msgLen,
smiLPUINT32 version, smiLPOCTETS *community, LPPDUS pdu)
{
smiUINT32 pduLen;
smiLPOCTETS os_ptr;
LPVARBIND vb_ptr;
LPVARBIND vb_end_ptr;
long errcode = 1;
if (msgPtr == NULL)
goto DONE;
errcode++; // 2
// Parse initial Sequence field...
if (ParseType (&msgPtr, &msgLen) != SNMP_SYNTAX_SEQUENCE)
goto DONE;
errcode++; // 3
// ...to get the remaining pduLen out of it
if ((pduLen = ParseLength (&msgPtr, &msgLen)) == -1)
goto DONE;
errcode++; // 4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -