You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
659 lines
17 KiB
659 lines
17 KiB
// wsnmp_ut.c
|
|
//
|
|
// WinSNMP Utility Functions and helpers
|
|
// Copyright 1995-1997 ACE*COMM Corp
|
|
// Rleased to Microsoft under Contract
|
|
// Beta 1 version, 970228
|
|
// Bob Natale ([email protected])
|
|
//
|
|
// 980424 - BobN
|
|
// - Mods to SnmpStrToIpxAddress() to permit '.' char
|
|
// - as netnum/nodenum separator
|
|
// 970310 - Removed extraneous functions
|
|
//
|
|
#include "winsnmp.inc"
|
|
|
|
SNMPAPI_STATUS SNMPAPI_CALL
|
|
SnmpGetLastError (IN HSNMP_SESSION hSession)
|
|
{
|
|
DWORD nSes;
|
|
|
|
if (TaskData.hTask == 0)
|
|
return (SNMPAPI_NOT_INITIALIZED);
|
|
nSes = HandleToUlong(hSession) - 1;
|
|
if (snmpValidTableEntry(&SessDescr, nSes))
|
|
{
|
|
LPSESSION pSession = snmpGetTableEntry(&SessDescr, nSes);
|
|
return pSession->nLastError;
|
|
}
|
|
else
|
|
return (TaskData.nLastError);
|
|
} // end_SnmpGetLastError
|
|
|
|
SNMPAPI_STATUS SNMPAPI_CALL
|
|
SnmpStrToOid (IN LPCSTR string,
|
|
OUT smiLPOID dstOID)
|
|
{
|
|
smiUINT32 i;
|
|
smiUINT32 compIdx;
|
|
SNMPAPI_STATUS lError;
|
|
CHAR c;
|
|
LPSTR pSep;
|
|
|
|
// Must be initialized
|
|
if (TaskData.hTask == 0)
|
|
{
|
|
lError = SNMPAPI_NOT_INITIALIZED;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
// use __try, __except to figure out if 'string' is a
|
|
// valid pointer. We cannot use IsBadReadPtr() here, as far as
|
|
// we have no idea for how many octets we should look.
|
|
__try
|
|
{
|
|
smiUINT32 sLen;
|
|
|
|
sLen = strlen(string);
|
|
if (sLen == 0 || sLen >= MAXOBJIDSTRSIZE)
|
|
{
|
|
lError = SNMPAPI_OID_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
lError = SNMPAPI_ALLOC_ERROR;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
// see if the dstOID pointer provided by the caller points to
|
|
// a valid memory range. If null is provided, there is nothing
|
|
// the API was requested to do!
|
|
if (IsBadWritePtr (dstOID, sizeof(smiOID)))
|
|
{
|
|
lError = (dstOID == NULL) ? SNMPAPI_NOOP : SNMPAPI_ALLOC_ERROR;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
// Ignore initial '.' in string (UNIX-ism)
|
|
if (string[0] == '.')
|
|
string++;
|
|
|
|
// figure out how many components this OID has
|
|
// count the number of '.' in the string. The OID should
|
|
// contain this count + 1 components
|
|
dstOID->len = 0;
|
|
pSep = (LPSTR)string;
|
|
while((pSep = strchr(pSep, '.')) != NULL)
|
|
{
|
|
pSep++;
|
|
dstOID->len++;
|
|
}
|
|
dstOID->len++;
|
|
|
|
// don't allow less than 2 components
|
|
if (dstOID->len < 2)
|
|
{
|
|
lError = SNMPAPI_OID_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
// allocate memory for holding the numeric OID components
|
|
// this should be released by the caller, through 'SnmpFreeDescriptor()'
|
|
dstOID->ptr = (smiLPUINT32)GlobalAlloc(GPTR, dstOID->len * sizeof(smiUINT32));
|
|
if (dstOID->ptr == NULL)
|
|
{
|
|
lError = SNMPAPI_ALLOC_ERROR;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
compIdx = 0;
|
|
// when entering the loop, 'string' doesn't have a heading '.'
|
|
// NOTE: 123. will be accepted as 123.0
|
|
// (123.. a12.3.4 1234....5.6) are considered as invalid OIDs instead
|
|
// of truncated to (123.0 0 1234.0).
|
|
while (*string != '\0')
|
|
{
|
|
dstOID->ptr[compIdx++] = strtoul(string, &pSep, 10);
|
|
|
|
// if one of the components was overflowing, release the memory and bail out.
|
|
if (errno == ERANGE)
|
|
{
|
|
errno = 0;
|
|
lError = SNMPAPI_OID_INVALID;
|
|
GlobalFree(dstOID->ptr);
|
|
dstOID->ptr = NULL;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
// if strtoul did not make any progress on the string (two successive dots)
|
|
// or it was blocked on something else than a separator or null-termination, then
|
|
// there was an error. The OID is invalid. API return failure
|
|
if (pSep == string ||
|
|
(*pSep != '.' && *pSep != '\0'))
|
|
{
|
|
lError = SNMPAPI_OID_INVALID; // invalid char in sequence
|
|
if (GlobalFree (dstOID->ptr)) // returns not-NULL on error
|
|
{
|
|
lError = SNMPAPI_OTHER_ERROR;
|
|
goto ERROR_OUT;
|
|
}
|
|
dstOID->ptr = NULL;
|
|
dstOID->len = 0;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
// pSep can point only to '.' or '\0'
|
|
if (*pSep == '.')
|
|
pSep++;
|
|
|
|
// restart with string from this point
|
|
string = pSep;
|
|
}
|
|
|
|
if (dstOID->len < 2)
|
|
{
|
|
GlobalFree(dstOID->ptr);
|
|
dstOID->ptr = NULL;
|
|
lError = SNMPAPI_OID_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
return dstOID->len;
|
|
|
|
ERROR_OUT:
|
|
return (SaveError (0, lError));
|
|
} // end_SnmpStrToOid()
|
|
|
|
SNMPAPI_STATUS SNMPAPI_CALL
|
|
SnmpOidToStr (IN smiLPCOID srcOID,
|
|
IN smiUINT32 strLen,
|
|
OUT LPSTR strPtr)
|
|
{
|
|
SNMPAPI_STATUS lError;
|
|
smiUINT32 retLen = 0; // used for successful return
|
|
smiUINT32 oidIdx = 0; // max subids is 128
|
|
smiUINT32 tmpLen; // used for size of decoded string (with '.')
|
|
LPSTR tmpPtr = strPtr; // used for advancing strPtr
|
|
char tmpBuf[64]; // enough room for 1 32-bit decode and '.'
|
|
if (TaskData.hTask == 0)
|
|
{
|
|
lError = SNMPAPI_NOT_INITIALIZED;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
if (!strLen)
|
|
{
|
|
lError = SNMPAPI_SIZE_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
if (IsBadReadPtr(srcOID, sizeof(smiOID)) ||
|
|
IsBadWritePtr(strPtr, strLen))
|
|
{
|
|
lError = (strPtr == NULL) ? SNMPAPI_NOOP : SNMPAPI_ALLOC_ERROR;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
if (srcOID->len == 0 || srcOID->len > 128 ||
|
|
IsBadReadPtr (srcOID->ptr, srcOID->len * sizeof(smiUINT32)))
|
|
{
|
|
lError = SNMPAPI_OID_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
while (oidIdx < srcOID->len)
|
|
{
|
|
_ultoa (srcOID->ptr[oidIdx++], tmpBuf, 10);
|
|
lstrcat (tmpBuf, ".");
|
|
tmpLen = lstrlen (tmpBuf);
|
|
if (strLen < (tmpLen + 1))
|
|
{
|
|
tmpBuf[strLen] = '\0';
|
|
lstrcpy (tmpPtr, tmpBuf);
|
|
lError = SNMPAPI_OUTPUT_TRUNCATED;
|
|
goto ERROR_OUT;
|
|
}
|
|
lstrcpy (tmpPtr, tmpBuf);
|
|
strLen -= tmpLen;
|
|
tmpPtr += tmpLen;
|
|
retLen += tmpLen;
|
|
} // end_while
|
|
*(--tmpPtr) = '\0';
|
|
return (retLen);
|
|
//
|
|
ERROR_OUT:
|
|
return (SaveError (0, lError));
|
|
} // end_SnmpOidToStr
|
|
|
|
SNMPAPI_STATUS SNMPAPI_CALL
|
|
SnmpOidCopy (IN smiLPCOID srcOID,
|
|
OUT smiLPOID dstOID)
|
|
{
|
|
SNMPAPI_STATUS lError;
|
|
if (TaskData.hTask == 0)
|
|
{
|
|
lError = SNMPAPI_NOT_INITIALIZED;
|
|
goto ERROR_OUT;
|
|
}
|
|
if (IsBadReadPtr (srcOID, sizeof(smiOID)) ||
|
|
IsBadReadPtr (srcOID->ptr, srcOID->len) ||
|
|
IsBadWritePtr (dstOID, sizeof(smiOID)))
|
|
{
|
|
lError = (dstOID == NULL) ? SNMPAPI_NOOP : SNMPAPI_ALLOC_ERROR;
|
|
goto ERROR_OUT;
|
|
}
|
|
// Check input OID size
|
|
if ((srcOID->len == 0) ||(srcOID->len > MAXOBJIDSIZE))
|
|
{
|
|
lError = SNMPAPI_OID_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
// Using dstOID-> temporarily for byte count
|
|
dstOID->len = srcOID->len * sizeof(smiUINT32);
|
|
// App must free following alloc via SnmpFreeDescriptor()
|
|
if (!(dstOID->ptr = (smiLPUINT32)GlobalAlloc (GPTR, dstOID->len)))
|
|
{
|
|
lError = SNMPAPI_ALLOC_ERROR;
|
|
goto ERROR_OUT;
|
|
}
|
|
CopyMemory (dstOID->ptr, srcOID->ptr, dstOID->len);
|
|
// Now make dstOID->len mean the right thing
|
|
dstOID->len = srcOID->len;
|
|
return (dstOID->len);
|
|
//
|
|
ERROR_OUT:
|
|
return (SaveError (0, lError));
|
|
} // end_SnmpOidCopy()
|
|
|
|
SNMPAPI_STATUS SNMPAPI_CALL
|
|
SnmpFreeDescriptor (IN smiUINT32 syntax,
|
|
IN smiLPOPAQUE ptr)
|
|
{
|
|
SNMPAPI_STATUS lError;
|
|
if (TaskData.hTask == 0)
|
|
{
|
|
lError = SNMPAPI_NOT_INITIALIZED;
|
|
goto ERROR_OUT;
|
|
}
|
|
if (!syntax || !ptr || !ptr->ptr)
|
|
{
|
|
lError = SNMPAPI_OPERATION_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
switch (syntax)
|
|
{
|
|
case SNMP_SYNTAX_OCTETS:
|
|
case SNMP_SYNTAX_IPADDR:
|
|
case SNMP_SYNTAX_OPAQUE:
|
|
case SNMP_SYNTAX_OID:
|
|
if (GlobalFree (ptr->ptr)) // returns not-NULL on error
|
|
{
|
|
lError = SNMPAPI_OTHER_ERROR;
|
|
goto ERROR_OUT;
|
|
}
|
|
ptr->ptr = NULL;
|
|
ptr->len = 0;
|
|
break;
|
|
|
|
default:
|
|
lError = SNMPAPI_SYNTAX_INVALID;
|
|
goto ERROR_OUT;
|
|
} // end_switch
|
|
return (SNMPAPI_SUCCESS);
|
|
//
|
|
ERROR_OUT:
|
|
return (SaveError (0, lError));
|
|
} // end_SnmpFreeDescriptor
|
|
|
|
// SnmpOidCompare
|
|
//
|
|
// Re-worked by 3/17/95 BobN
|
|
SNMPAPI_STATUS SNMPAPI_CALL
|
|
SnmpOidCompare (IN smiLPCOID xOID,
|
|
IN smiLPCOID yOID,
|
|
IN smiUINT32 maxlen,
|
|
OUT smiLPINT result)
|
|
{
|
|
smiUINT32 i = 0;
|
|
smiUINT32 j = 0;
|
|
SNMPAPI_STATUS lError;
|
|
if (TaskData.hTask == 0)
|
|
{
|
|
lError = SNMPAPI_NOT_INITIALIZED;
|
|
goto ERROR_OUT;
|
|
}
|
|
if (maxlen > MAXOBJIDSIZE)
|
|
{
|
|
lError = SNMPAPI_SIZE_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
if (IsBadReadPtr (xOID, sizeof(smiOID)) ||
|
|
IsBadReadPtr (yOID, sizeof(smiOID)))
|
|
{
|
|
lError = SNMPAPI_ALLOC_ERROR;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
if (IsBadReadPtr (xOID->ptr, xOID->len * sizeof(UINT)) ||
|
|
IsBadReadPtr (yOID->ptr, yOID->len * sizeof(UINT)))
|
|
{
|
|
lError = SNMPAPI_OID_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
// Test input pointers for readability
|
|
if (IsBadWritePtr (result, sizeof(smiINT)))
|
|
{
|
|
lError = (result == NULL) ? SNMPAPI_NOOP : SNMPAPI_ALLOC_ERROR;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
j = min(xOID->len, yOID->len);
|
|
if (maxlen) j = min(j, maxlen);
|
|
while (i < j)
|
|
{
|
|
if (*result = xOID->ptr[i] - yOID->ptr[i]) // deliberate assignment
|
|
return (SNMPAPI_SUCCESS); // not equal...got a winner!
|
|
i++;
|
|
}
|
|
if (j == maxlen) // asked for a limit
|
|
return (SNMPAPI_SUCCESS); // and...got a draw!
|
|
*result = xOID->len - yOID->len; // size matters!
|
|
return SNMPAPI_SUCCESS;
|
|
//
|
|
ERROR_OUT:
|
|
return (SaveError (0, lError));
|
|
} // end_SnmpOidCompare
|
|
|
|
SNMPAPI_STATUS SNMPAPI_CALL
|
|
SnmpEncodeMsg (IN HSNMP_SESSION hSession,
|
|
IN HSNMP_ENTITY hSrc,
|
|
IN HSNMP_ENTITY hDst,
|
|
IN HSNMP_CONTEXT hCtx,
|
|
IN HSNMP_PDU hPdu,
|
|
IN OUT smiLPOCTETS msgBufDesc)
|
|
{
|
|
smiUINT32 version = 0;
|
|
DWORD nCtx;
|
|
DWORD nPdu;
|
|
DWORD nVbl;
|
|
smiOCTETS tmpContext;
|
|
smiLPBYTE msgAddr = NULL;
|
|
smiUINT32 lError = SNMPAPI_SUCCESS;
|
|
HSNMP_SESSION lSession = 0;
|
|
LPPDUS pPdu;
|
|
LPENTITY pEntSrc, pEntDst;
|
|
LPCTXT pCtxt;
|
|
|
|
// Basic error checks
|
|
if (TaskData.hTask == 0)
|
|
{
|
|
lError = SNMPAPI_NOT_INITIALIZED;
|
|
goto ERROR_OUT;
|
|
}
|
|
if (!snmpValidTableEntry(&SessDescr, HandleToUlong(hSession)-1))
|
|
{
|
|
lError = SNMPAPI_SESSION_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
// We have a valid session at this point...
|
|
lSession = hSession; // save it for possible error return
|
|
// Check for writable output buffer
|
|
if (IsBadWritePtr (msgBufDesc, sizeof(smiOCTETS)))
|
|
{
|
|
lError = (msgBufDesc == NULL) ? SNMPAPI_NOOP : SNMPAPI_ALLOC_ERROR;
|
|
goto ERROR_OUT;
|
|
}
|
|
// srcEntity not currently used
|
|
if (hSrc)
|
|
{
|
|
if (!snmpValidTableEntry(&EntsDescr, HandleToUlong(hSrc)-1))
|
|
{
|
|
lError = SNMPAPI_ENTITY_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
pEntSrc = snmpGetTableEntry(&EntsDescr, HandleToUlong(hSrc)-1);
|
|
}
|
|
// dstEntity is required for *accurate* msg version info
|
|
if (hDst)
|
|
{
|
|
if (!snmpValidTableEntry(&EntsDescr, HandleToUlong(hDst)-1))
|
|
{
|
|
lError = SNMPAPI_ENTITY_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
pEntDst = snmpGetTableEntry(&EntsDescr, HandleToUlong(hDst)-1);
|
|
version = pEntDst->version-1;
|
|
}
|
|
nCtx = HandleToUlong(hCtx) - 1;
|
|
if (!snmpValidTableEntry(&CntxDescr, nCtx))
|
|
{
|
|
lError = SNMPAPI_CONTEXT_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
pCtxt = snmpGetTableEntry(&CntxDescr, nCtx);
|
|
|
|
nPdu = HandleToUlong(hPdu) - 1;
|
|
if (!snmpValidTableEntry(&PDUsDescr, nPdu))
|
|
{
|
|
ERROR_PDU:
|
|
lError = SNMPAPI_PDU_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
pPdu = snmpGetTableEntry(&PDUsDescr, nPdu);
|
|
|
|
// Necessary PDU data checks
|
|
nVbl = HandleToUlong(pPdu->VBL);
|
|
if (!snmpValidTableEntry(&VBLsDescr, nVbl-1))
|
|
goto ERROR_PDU;
|
|
// Check out for SNMPv1 Trap PDU type...uses different PDU structure!
|
|
// ???
|
|
// Check for SNMPv2c PDU types
|
|
if (pPdu->type == SNMP_PDU_TRAP ||
|
|
pPdu->type == SNMP_PDU_INFORM)
|
|
version = 1;
|
|
// Now Build it
|
|
tmpContext.len = pCtxt->commLen;
|
|
tmpContext.ptr = pCtxt->commStr;
|
|
if (!(BuildMessage (version, &tmpContext,
|
|
pPdu, pPdu->appReqId,
|
|
&msgAddr, &msgBufDesc->len)))
|
|
goto ERROR_PDU;
|
|
// Copy Snmp message to caller's buffer...
|
|
// App must free following alloc via SnmpFreeDescriptor()
|
|
if (!(msgBufDesc->ptr = (smiLPBYTE)GlobalAlloc (GPTR, msgBufDesc->len)))
|
|
lError = SNMPAPI_ALLOC_ERROR;
|
|
else // SUCCESS
|
|
CopyMemory (msgBufDesc->ptr, msgAddr, msgBufDesc->len);
|
|
ERROR_OUT:
|
|
// Clean up
|
|
if (msgAddr)
|
|
GlobalFree (msgAddr);
|
|
if (lError == SNMPAPI_SUCCESS)
|
|
return (msgBufDesc->len);
|
|
else // Failure cases
|
|
return (SaveError (lSession, lError));
|
|
}
|
|
|
|
SNMPAPI_STATUS SNMPAPI_CALL
|
|
SnmpDecodeMsg (IN HSNMP_SESSION hSession,
|
|
OUT LPHSNMP_ENTITY hSrc,
|
|
OUT LPHSNMP_ENTITY hDst,
|
|
OUT LPHSNMP_CONTEXT hCtx,
|
|
OUT LPHSNMP_PDU hPdu,
|
|
IN smiLPCOCTETS msgPtr)
|
|
{
|
|
DWORD nPdu;
|
|
smiLPOCTETS community;
|
|
smiUINT32 version;
|
|
SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
|
|
HSNMP_SESSION lSession = 0;
|
|
LPPDUS pPdu;
|
|
|
|
if (TaskData.hTask == 0)
|
|
{
|
|
lError = SNMPAPI_NOT_INITIALIZED;
|
|
goto ERROR_OUT;
|
|
}
|
|
if (!snmpValidTableEntry(&SessDescr, HandleToUlong(hSession)-1))
|
|
{
|
|
lError = SNMPAPI_SESSION_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
// Valid session...save for possible error return
|
|
lSession = hSession;
|
|
|
|
if (IsBadReadPtr(msgPtr, sizeof(smiOCTETS)) ||
|
|
IsBadReadPtr(msgPtr->ptr, msgPtr->len))
|
|
{
|
|
lError = SNMPAPI_ALLOC_ERROR;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
if (hSrc == NULL && hDst == NULL && hCtx == NULL && hPdu == NULL)
|
|
{
|
|
lError = SNMPAPI_NOOP;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
if ((hDst != NULL && IsBadWritePtr(hDst, sizeof(HSNMP_ENTITY))) ||
|
|
(hSrc != NULL && IsBadWritePtr(hSrc, sizeof(HSNMP_ENTITY))))
|
|
{
|
|
lError = SNMPAPI_ENTITY_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
if (hCtx != NULL && IsBadWritePtr(hCtx, sizeof(HSNMP_CONTEXT)))
|
|
{
|
|
lError = SNMPAPI_CONTEXT_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
if (IsBadWritePtr(hPdu, sizeof(HSNMP_PDU)))
|
|
{
|
|
lError = SNMPAPI_PDU_INVALID;
|
|
goto ERROR_OUT;
|
|
}
|
|
|
|
EnterCriticalSection (&cs_PDU);
|
|
lError = snmpAllocTableEntry(&PDUsDescr, &nPdu);
|
|
if (lError != SNMPAPI_SUCCESS)
|
|
goto ERROR_PRECHECK;
|
|
pPdu = snmpGetTableEntry(&PDUsDescr, nPdu);
|
|
|
|
if (ParseMessage (msgPtr->ptr, msgPtr->len, &version, &community, pPdu))
|
|
{ // non-zero = some error code
|
|
lError = SNMPAPI_MESSAGE_INVALID;
|
|
SnmpFreePdu((HSNMP_PDU) ULongToPtr(nPdu+1));
|
|
goto ERROR_PRECHECK;
|
|
}
|
|
if (hDst != NULL) *hDst = 0;
|
|
if (hSrc != NULL) *hSrc = 0;
|
|
if (hCtx != NULL)
|
|
{
|
|
smiUINT32 nMode;
|
|
EnterCriticalSection (&cs_XMODE);
|
|
SnmpGetTranslateMode (&nMode);
|
|
SnmpSetTranslateMode (SNMPAPI_UNTRANSLATED_V1);
|
|
if ((*hCtx = SnmpStrToContext (hSession, community)) == SNMPAPI_FAILURE)
|
|
{
|
|
LeaveCriticalSection (&cs_XMODE);
|
|
lError = SNMPAPI_OTHER_ERROR;
|
|
FreeOctetString (community);
|
|
SnmpFreePdu((HSNMP_PDU) ULongToPtr(nPdu+1));
|
|
goto ERROR_PRECHECK;
|
|
}
|
|
SnmpSetTranslateMode (nMode);
|
|
LeaveCriticalSection (&cs_XMODE);
|
|
}
|
|
FreeOctetString (community);
|
|
pPdu->Session = hSession;
|
|
if (hPdu != NULL)
|
|
*hPdu = (HSNMP_PDU) ULongToPtr(nPdu+1);
|
|
else
|
|
SnmpFreePdu((HSNMP_PDU) ULongToPtr(nPdu+1));
|
|
|
|
ERROR_PRECHECK:
|
|
LeaveCriticalSection (&cs_PDU);
|
|
if (lError == SNMPAPI_SUCCESS)
|
|
{
|
|
SaveError(lSession, lError);
|
|
return (msgPtr->len);
|
|
}
|
|
|
|
ERROR_OUT:
|
|
return (SaveError (lSession, lError));
|
|
} // end_SnmpDecodeMsg()
|
|
|
|
#define NETLEN 4
|
|
#define NODELEN 6
|
|
char *cHexDigits = "0123456789ABCDEF";
|
|
SNMPAPI_STATUS SNMPAPI_CALL
|
|
SnmpStrToIpxAddress (LPCSTR str, LPBYTE netnum, LPBYTE nodenum)
|
|
{
|
|
LPSTR netPtr, nodePtr, pStr;
|
|
DWORD i, j;
|
|
char tmpStr[24+1];
|
|
BYTE c1, c2;
|
|
if (!str || !netnum || !nodenum)
|
|
return (SNMPAPI_FAILURE);
|
|
strncpy (tmpStr, str,24);
|
|
tmpStr[24] = '\0';
|
|
netPtr = strtok (tmpStr, "-:.");
|
|
if (netPtr == NULL)
|
|
return (SNMPAPI_FAILURE);
|
|
if (lstrlen (netPtr) != NETLEN*2)
|
|
return (SNMPAPI_FAILURE);
|
|
nodePtr = netPtr + (NETLEN*2) + 1;
|
|
if (lstrlen (nodePtr) != NODELEN*2)
|
|
return (SNMPAPI_FAILURE);
|
|
_strupr (netPtr);
|
|
for (i = 0, j = 0; j < NETLEN; j++)
|
|
{
|
|
pStr = strchr (cHexDigits, netPtr[i++]);
|
|
if (pStr == NULL)
|
|
return (SNMPAPI_FAILURE);
|
|
c1 = (BYTE)(pStr - cHexDigits);
|
|
pStr = strchr (cHexDigits, netPtr[i++]);
|
|
if (pStr == NULL)
|
|
return (SNMPAPI_FAILURE);
|
|
c2 = (BYTE)(pStr - cHexDigits);
|
|
netnum[j] = c2 | c1 << 4;
|
|
}
|
|
_strupr (nodePtr);
|
|
for (i = 0, j = 0; j < NODELEN; j++)
|
|
{
|
|
pStr = strchr (cHexDigits, nodePtr[i++]);
|
|
if (pStr == NULL)
|
|
return (SNMPAPI_FAILURE);
|
|
c1 = (BYTE)(pStr - cHexDigits);
|
|
pStr = strchr (cHexDigits, nodePtr[i++]);
|
|
if (pStr == NULL)
|
|
return (SNMPAPI_FAILURE);
|
|
c2 = (BYTE)(pStr - cHexDigits);
|
|
nodenum[j] = c2 | c1 << 4;
|
|
}
|
|
return (SNMPAPI_SUCCESS);
|
|
}
|
|
|
|
SNMPAPI_STATUS SNMPAPI_CALL
|
|
SnmpIpxAddressToStr (LPBYTE netnum, LPBYTE nodenum, LPSTR str)
|
|
{
|
|
DWORD i, j;
|
|
for (i = 0, j = 0; i < NETLEN; i++)
|
|
{
|
|
str[j++] = cHexDigits[(netnum[i] & 0xF0) >> 4];
|
|
str[j++] = cHexDigits[netnum[i] & 0x0F];
|
|
}
|
|
str[j++] = ':';
|
|
for (i = 0; i < NODELEN; i++)
|
|
{
|
|
str[j++] = cHexDigits[(nodenum[i] & 0xF0) >> 4];
|
|
str[j++] = cHexDigits[nodenum[i] & 0x0F];
|
|
}
|
|
str[j] = '\0';
|
|
return (SNMPAPI_SUCCESS);
|
|
}
|