Leaked source code of windows server 2003
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.
 
 
 
 
 
 

371 lines
10 KiB

// wsnmp_pd.c
//
// WinSNMP PDU Functions and helpers
// Copyright 1995-1997 ACE*COMM Corp
// Rleased to Microsoft under Contract
// Beta 1 version, 970228
// Bob Natale ([email protected])
//
// Removed extraneous functions
//
#include "winsnmp.inc"
LPVARBIND SnmpCopyVbl (LPVARBIND);
// PDU Functions
// SnmpCreatePdu
HSNMP_PDU SNMPAPI_CALL
SnmpCreatePdu (IN HSNMP_SESSION hSession,
IN smiINT PDU_type,
IN smiINT32 request_id,
IN smiINT error_status,
IN smiINT error_index,
IN HSNMP_VBL hVbl)
{
DWORD nPdu;
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;
}
// We have a valid session at this point...
lSession = hSession; // save it for possible error return
if (hVbl)
{
if (!snmpValidTableEntry(&VBLsDescr, HandleToUlong(hVbl)-1))
{
lError = SNMPAPI_VBL_INVALID;
goto ERROR_OUT;
}
}
if (!PDU_type) // NULL is allowed and defaults to SNMP_PDU_GETNEXT
PDU_type = SNMP_PDU_GETNEXT;
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:
break;
case SNMP_PDU_V1TRAP:
default:
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);
// Initialize new PDU components
pPdu->Session = hSession;
pPdu->type = PDU_type;
pPdu->errStatus = error_status;
pPdu->errIndex = error_index;
// If RequestID=0 at this point, assign one (which may be 0)
pPdu->appReqId = (request_id) ? request_id : ++(TaskData.nLastReqId);
pPdu->VBL_addr = NULL;
pPdu->VBL = (hVbl) ? hVbl : 0;
ERROR_PRECHECK:
LeaveCriticalSection (&cs_PDU);
if (lError == SNMPAPI_SUCCESS)
return ((HSNMP_PDU) ULongToPtr(nPdu+1));
else
ERROR_OUT:
return ((HSNMP_PDU) ULongToPtr(SaveError(lSession, lError)));
} // end_SnmpCreatePdu
// SnmpGetPduData
SNMPAPI_STATUS SNMPAPI_CALL
SnmpGetPduData (IN HSNMP_PDU hPdu,
OUT smiLPINT PDU_type,
OUT smiLPINT32 request_id,
OUT smiLPINT error_status,
OUT smiLPINT error_index,
OUT LPHSNMP_VBL hVbl)
{
DWORD nPdu = HandleToUlong(hPdu) - 1;
DWORD done = 0;
HSNMP_SESSION hSession;
SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
HSNMP_SESSION lSession = 0;
LPPDUS pPdu;
LPVBLS pVbl;
if (TaskData.hTask == 0)
{
lError = SNMPAPI_NOT_INITIALIZED;
goto ERROR_OUT;
}
if (!snmpValidTableEntry(&PDUsDescr, nPdu))
{
lError = SNMPAPI_PDU_INVALID;
goto ERROR_OUT;
}
pPdu = snmpGetTableEntry(&PDUsDescr, nPdu);
// Use PDU's session for (possibly) creating hVbl later
hSession = pPdu->Session;
if (!snmpValidTableEntry(&SessDescr, HandleToUlong(hSession)-1))
{
lError = SNMPAPI_SESSION_INVALID;
goto ERROR_OUT;
}
lSession = hSession; // Save for possible error return
if (PDU_type)
{
*PDU_type = pPdu->type;
done++;
}
if (request_id)
{
*request_id = pPdu->appReqId;
done++;
}
if (error_status)
{
*error_status = pPdu->errStatus;
done++;
}
if (error_index)
{
*error_index = pPdu->errIndex;
done++;
}
if (hVbl)
{
DWORD nVbl; // Important control variable
*hVbl = 0;
EnterCriticalSection (&cs_VBL);
// First case is on a created (not received) PDU
// which has not yet been assigned a VBL
if ((!pPdu->VBL) && (!pPdu->VBL_addr))
goto DONE_VBL;
// If there is a VBL already assinged to the PDU,
// then duplicate it
if (pPdu->VBL)
{ // Per policy, create a new hVbl resource for the calling app
if (!(*hVbl = SnmpDuplicateVbl (hSession, pPdu->VBL)))
{
lError = SNMPAPI_VBL_INVALID;
goto ERROR_PRECHECK;
}
goto DONE_VBL;
}
// This must be a received PDU and
// the first call to extract the VBL
lError = snmpAllocTableEntry(&VBLsDescr, &nVbl);
if (lError != SNMPAPI_SUCCESS)
goto ERROR_PRECHECK;
pVbl = snmpGetTableEntry(&VBLsDescr, nVbl);
pVbl->Session = hSession;
pVbl->vbList = pPdu->VBL_addr;
// Clear received vbList address...IMPORTANT!
pPdu->VBL_addr = NULL;
*hVbl = pPdu->VBL = (HSNMP_VBL) ULongToPtr(nVbl+1);
DONE_VBL:
done++;
ERROR_PRECHECK:
LeaveCriticalSection (&cs_VBL);
} // end_if vbl
if (done == 0)
lError = SNMPAPI_NOOP;
if (lError == SNMPAPI_SUCCESS)
return (SNMPAPI_SUCCESS);
ERROR_OUT:
return (SaveError (lSession, lError));
} // end_SnmpGetPduData
// SnmpSetPduData
SNMPAPI_STATUS SNMPAPI_CALL
SnmpSetPduData (IN HSNMP_PDU hPdu,
IN const smiINT FAR *PDU_type,
IN const smiINT32 FAR *request_id,
IN const smiINT FAR *non_repeaters,
IN const smiINT FAR *max_repetitions,
IN const HSNMP_VBL FAR *hVbl)
{
DWORD nPdu = HandleToUlong(hPdu) - 1;
DWORD done = 0;
SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
HSNMP_SESSION lSession = 0;
LPPDUS pPdu;
if (TaskData.hTask == 0)
{
lError = SNMPAPI_NOT_INITIALIZED;
goto ERROR_OUT;
}
if (!snmpValidTableEntry(&PDUsDescr, nPdu))
{
lError = SNMPAPI_PDU_INVALID;
goto ERROR_OUT;
}
pPdu = snmpGetTableEntry(&PDUsDescr, nPdu);
lSession = pPdu->Session; // Save for possible error return
EnterCriticalSection (&cs_PDU);
if (!IsBadReadPtr((LPVOID)PDU_type, sizeof(smiINT)))
{
if (*PDU_type == SNMP_PDU_V1TRAP)
{
lError = SNMPAPI_PDU_INVALID;
goto ERROR_OUT;
}
pPdu->type = *PDU_type;
done++;
}
if (!IsBadReadPtr((LPVOID)request_id, sizeof(smiINT32)))
{
pPdu->appReqId = *request_id;
done++;
}
if (!IsBadReadPtr((LPVOID)non_repeaters, sizeof(smiINT)))
{
pPdu->errStatus = *non_repeaters;
done++;
}
if (!IsBadReadPtr((LPVOID)max_repetitions, sizeof(smiINT)))
{
pPdu->errIndex = *max_repetitions;
done++;
}
if (!IsBadReadPtr((LPVOID)hVbl, sizeof(HSNMP_VBL)))
{ // Assign new vbl
HSNMP_VBL tVbl = *hVbl;
// Check for validity
if (!snmpValidTableEntry(&VBLsDescr, HandleToUlong(tVbl)-1))
{ // If not, disallow operation
lError = SNMPAPI_VBL_INVALID;
goto ERROR_PRECHECK;
}
pPdu->VBL = tVbl;
// Following case can happen if a a vbl is assigned to a
// response pdu which never had its vbl dereferenced...
if (pPdu->VBL_addr) //...then is must be freed
FreeVarBindList (pPdu->VBL_addr);
pPdu->VBL_addr = NULL;
done++;
} // end_if vbl
ERROR_PRECHECK:
LeaveCriticalSection (&cs_PDU);
if (done == 0)
lError = ((PDU_type == NULL) &&
(request_id == NULL) &&
(non_repeaters == NULL) &&
(max_repetitions == NULL) &&
(hVbl == NULL)) ? SNMPAPI_NOOP : SNMPAPI_ALLOC_ERROR;
if (lError == SNMPAPI_SUCCESS)
return (SNMPAPI_SUCCESS);
ERROR_OUT:
return (SaveError (lSession, lError));
} // end_SnmpSetPduData
// SnmpDuplicatePdu
HSNMP_PDU SNMPAPI_CALL
SnmpDuplicatePdu (IN HSNMP_SESSION hSession,
IN HSNMP_PDU hPdu)
{
DWORD lPdu = HandleToUlong(hPdu) - 1;
DWORD nPdu;
SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
HSNMP_SESSION lSession = 0;
LPPDUS pOldPdu, pNewPdu;
if (TaskData.hTask == 0)
{
lError = SNMPAPI_NOT_INITIALIZED;
goto ERROR_OUT;
}
if (!snmpValidTableEntry(&SessDescr, HandleToUlong(hSession)-1))
{
lError = SNMPAPI_SESSION_INVALID;
goto ERROR_OUT;
}
lSession = hSession; // save for possible error return
if (!snmpValidTableEntry(&PDUsDescr, lPdu) ||
(pOldPdu = snmpGetTableEntry(&PDUsDescr, lPdu))->type == SNMP_PDU_V1TRAP)
{
lError = SNMPAPI_PDU_INVALID;
goto ERROR_OUT;
}
EnterCriticalSection (&cs_PDU);
lError = snmpAllocTableEntry(&PDUsDescr, &nPdu);
if (lError != SNMPAPI_SUCCESS)
goto ERROR_PRECHECK;
pNewPdu = snmpGetTableEntry(&PDUsDescr, nPdu);
CopyMemory (pNewPdu, pOldPdu, sizeof(PDUS));
pNewPdu->Session = hSession; // Can be different
// Setting the VBL value in the duplicated PDU is "tricky"...
// If there is a VBL value, just replicate it and that's that.
// If VBL = 0 and there is no VBL_addr attached to the pdu_ptr,
// then the VBL value is 0 and is already set from the original PDU.
// Otherwise, this is a received PDU from which the varbindlist has
// not yet been extracted and must, therefore, be re-produced.
// This third case is covered in the next *2* lines.
if ((!pOldPdu->VBL) && pOldPdu->VBL_addr)
{
if (!(pNewPdu->VBL_addr = SnmpCopyVbl (pOldPdu->VBL_addr)))
{
lError = SNMPAPI_ALLOC_ERROR;
}
}
ERROR_PRECHECK:
LeaveCriticalSection (&cs_PDU);
if (lError == SNMPAPI_SUCCESS)
return ((HSNMP_PDU) ULongToPtr(nPdu+1));
ERROR_OUT:
return ((HSNMP_PDU) ULongToPtr(SaveError(lSession, lError)));
} // end_SnmpDuplicatePdu
// SnmpFreePdu
SNMPAPI_STATUS SNMPAPI_CALL
SnmpFreePdu (IN HSNMP_PDU hPdu)
{
DWORD nPdu = HandleToUlong(hPdu) - 1;
SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
LPPDUS pPdu;
if (TaskData.hTask == 0)
{
lError = SNMPAPI_NOT_INITIALIZED;
goto ERROR_OUT;
}
if (!snmpValidTableEntry(&PDUsDescr, nPdu))
{
lError = SNMPAPI_PDU_INVALID;
goto ERROR_OUT;
}
pPdu = snmpGetTableEntry(&PDUsDescr, nPdu);
EnterCriticalSection (&cs_PDU);
if (pPdu->VBL_addr)
FreeVarBindList (pPdu->VBL_addr);
if (pPdu->v1Trap)
FreeV1Trap (pPdu->v1Trap);
snmpFreeTableEntry(&PDUsDescr, nPdu);
LeaveCriticalSection (&cs_PDU);
return (SNMPAPI_SUCCESS);
ERROR_OUT:
return (SaveError (0, lError));
} // end_SnmpfreePdu