367 lines
11 KiB
C
367 lines
11 KiB
C
/*++
|
|
|
|
Copyright (c) 1999, Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
sample\mibmanager.c
|
|
|
|
Abstract:
|
|
|
|
The file contains IP Sample's MIB implementation.
|
|
|
|
Revision History:
|
|
|
|
MohitT June-15-1999 Created
|
|
|
|
--*/
|
|
|
|
#include "pchsample.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
MM_MibSet (
|
|
IN PIPSAMPLE_MIB_SET_INPUT_DATA pimsid)
|
|
/*++
|
|
|
|
Routine Description
|
|
Set IPSAMPLE's global or interface configuration.
|
|
|
|
Locks
|
|
Acquires shared (g_ce.pneNetworkEntry)->rwlLock
|
|
Releases (g_ce.pneNetworkEntry)->rwlLock
|
|
|
|
Arguments
|
|
pimsid input data, contains global/interface configuration
|
|
|
|
Return Value
|
|
NO_ERROR success
|
|
Error Code o/w
|
|
|
|
--*/
|
|
{
|
|
DWORD dwErr = NO_ERROR;
|
|
ROUTING_PROTOCOL_EVENTS rpeEvent;
|
|
MESSAGE mMessage = {0, 0, 0};
|
|
PINTERFACE_ENTRY pie;
|
|
|
|
if (!ENTER_SAMPLE_API()) { return ERROR_CAN_NOT_COMPLETE; }
|
|
|
|
do // breakout loop
|
|
{
|
|
// set global configuration
|
|
if (pimsid->IMSID_TypeID is IPSAMPLE_GLOBAL_CONFIG_ID)
|
|
{
|
|
if (pimsid->IMSID_BufferSize < sizeof(IPSAMPLE_GLOBAL_CONFIG))
|
|
{
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
dwErr = CM_SetGlobalInfo((PVOID) pimsid->IMSID_Buffer);
|
|
if (dwErr != NO_ERROR)
|
|
break;
|
|
|
|
rpeEvent = SAVE_GLOBAL_CONFIG_INFO;
|
|
}
|
|
// set interface configuration
|
|
else if (pimsid->IMSID_TypeID is IPSAMPLE_IF_CONFIG_ID)
|
|
{
|
|
if (pimsid->IMSID_BufferSize < sizeof(IPSAMPLE_IF_CONFIG))
|
|
{
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
dwErr = NM_SetInterfaceInfo(pimsid->IMSID_IfIndex,
|
|
(PVOID) pimsid->IMSID_Buffer);
|
|
if (dwErr != NO_ERROR)
|
|
break;
|
|
|
|
rpeEvent = SAVE_INTERFACE_CONFIG_INFO;
|
|
mMessage.InterfaceIndex = pimsid->IMSID_IfIndex;
|
|
}
|
|
// error, unexpected type
|
|
else
|
|
{
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
// notify router manager
|
|
if (EnqueueEvent(rpeEvent, mMessage) is NO_ERROR)
|
|
SetEvent(g_ce.hMgrNotificationEvent);
|
|
|
|
} while(FALSE);
|
|
|
|
|
|
LEAVE_SAMPLE_API();
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
MM_MibGet (
|
|
IN PIPSAMPLE_MIB_GET_INPUT_DATA pimgid,
|
|
OUT PIPSAMPLE_MIB_GET_OUTPUT_DATA pimgod,
|
|
IN OUT PULONG pulOutputSize,
|
|
IN MODE mMode)
|
|
/*++
|
|
|
|
Routine Description
|
|
Handles the structure accesses required to read MIB data. Supports
|
|
three modes of querying: EXACT, FIRST, and NEXT, which correspond to
|
|
MibGet(), MibGetFirst(), and MibGetNext() respectively.
|
|
|
|
Locks
|
|
Acquires shared (g_ce.pneNetworkEntry)->rwlLock
|
|
Releases (g_ce.pneNetworkEntry)->rwlLock
|
|
|
|
Arguments
|
|
pimgid input data
|
|
pimgod output buffer
|
|
pulOutputSize IN size of output buffer given
|
|
OUT size of output buffer needed
|
|
mMode query type
|
|
|
|
Return Value
|
|
NO_ERROR success
|
|
Error Code o/w
|
|
|
|
--*/
|
|
{
|
|
DWORD dwErr = NO_ERROR;
|
|
ULONG ulSizeGiven = 0;
|
|
ULONG ulSizeNeeded = 0;
|
|
PINTERFACE_ENTRY pie;
|
|
|
|
|
|
if (!ENTER_SAMPLE_API()) { return ERROR_CAN_NOT_COMPLETE; }
|
|
|
|
// compute the size of the buffer available for storing
|
|
// returned structures (the size of IMGOD_Buffer)
|
|
if (*pulOutputSize < sizeof(IPSAMPLE_MIB_GET_OUTPUT_DATA))
|
|
ulSizeGiven = 0;
|
|
else
|
|
ulSizeGiven = *pulOutputSize - sizeof(IPSAMPLE_MIB_GET_OUTPUT_DATA);
|
|
|
|
switch (pimgid->IMGID_TypeID)
|
|
{
|
|
// the global statistics struct is fixed-length.
|
|
// there is a single instance.
|
|
case IPSAMPLE_GLOBAL_STATS_ID:
|
|
{
|
|
PIPSAMPLE_GLOBAL_STATS pigsdst, pigssrc;
|
|
|
|
// only GET_EXACT and GET_FIRST are valid for the
|
|
// global stats object since there is only one entry
|
|
if (mMode is GET_NEXT)
|
|
{
|
|
dwErr = ERROR_NO_MORE_ITEMS;
|
|
break;
|
|
}
|
|
|
|
// set the output size required for this entry
|
|
ulSizeNeeded = sizeof(IPSAMPLE_GLOBAL_STATS);
|
|
|
|
// check that the output buffer is big enough
|
|
if (ulSizeGiven < ulSizeNeeded)
|
|
{
|
|
dwErr = ERROR_INSUFFICIENT_BUFFER;
|
|
break;
|
|
}
|
|
|
|
pimgod->IMGOD_TypeID = IPSAMPLE_GLOBAL_STATS_ID;
|
|
|
|
// since access to this structure is synchronized through
|
|
// locked increments/decrements, we must copy it field by field
|
|
pigssrc = &(g_ce.igsStats);
|
|
pigsdst = (PIPSAMPLE_GLOBAL_STATS) pimgod->IMGOD_Buffer;
|
|
|
|
pigsdst->ulNumInterfaces = pigssrc->ulNumInterfaces;
|
|
|
|
break;
|
|
}
|
|
|
|
// the global configuration structure may be of variable size.
|
|
// there is a single instance.
|
|
case IPSAMPLE_GLOBAL_CONFIG_ID:
|
|
{
|
|
// only GET_EXACT and GET_FIRST are valid for the
|
|
// global configuration object since there is only one entry
|
|
if (mMode is GET_NEXT)
|
|
{
|
|
dwErr = ERROR_NO_MORE_ITEMS;
|
|
break;
|
|
}
|
|
|
|
// CM_GetGlobalInfo() decides whether the buffer size is
|
|
// sufficient. if so, it retrieves the global configuration.
|
|
// either case it sets the required output buffer size.
|
|
dwErr = CM_GetGlobalInfo ((PVOID) pimgod->IMGOD_Buffer,
|
|
&ulSizeGiven,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
ulSizeNeeded = ulSizeGiven;
|
|
|
|
// check that the output buffer was big enough
|
|
if (dwErr != NO_ERROR)
|
|
break;
|
|
|
|
pimgod->IMGOD_TypeID = IPSAMPLE_GLOBAL_CONFIG_ID;
|
|
|
|
break;
|
|
}
|
|
|
|
// the interface statistics struct is fixed-length.
|
|
// there may be multiple instances.
|
|
case IPSAMPLE_IF_STATS_ID:
|
|
{
|
|
PIPSAMPLE_IF_STATS piisdst, piissrc;
|
|
|
|
ACQUIRE_READ_LOCK(&(g_ce.pneNetworkEntry)->rwlLock);
|
|
|
|
do // breakout loop
|
|
{
|
|
// retrieve the interface whose stats are to be read
|
|
dwErr = IE_GetIndex(pimgid->IMGID_IfIndex,
|
|
mMode,
|
|
&pie);
|
|
if (dwErr != NO_ERROR)
|
|
break;
|
|
|
|
// set the output size required for this entry
|
|
ulSizeNeeded = sizeof(IPSAMPLE_IF_STATS);
|
|
|
|
// check that the output buffer is big enough
|
|
if (ulSizeGiven < ulSizeNeeded)
|
|
{
|
|
dwErr = ERROR_INSUFFICIENT_BUFFER;
|
|
break;
|
|
}
|
|
|
|
pimgod->IMGOD_TypeID = IPSAMPLE_IF_STATS_ID;
|
|
pimgod->IMGOD_IfIndex = pie->dwIfIndex;
|
|
|
|
// access to this structure is synchronized through locked
|
|
// increments/decrements, so we copy it field by field
|
|
piissrc = &(pie->iisStats);
|
|
piisdst = (PIPSAMPLE_IF_STATS) pimgod->IMGOD_Buffer;
|
|
|
|
piisdst->ulNumPackets = piissrc->ulNumPackets;
|
|
} while (FALSE);
|
|
|
|
RELEASE_READ_LOCK(&(g_ce.pneNetworkEntry)->rwlLock);
|
|
|
|
break;
|
|
}
|
|
|
|
// the interface configuration structure may be of variable size.
|
|
// there may be multiple instances.
|
|
case IPSAMPLE_IF_CONFIG_ID:
|
|
{
|
|
// get the queried interface's index
|
|
ACQUIRE_READ_LOCK(&(g_ce.pneNetworkEntry)->rwlLock);
|
|
|
|
do // breakout loop
|
|
{
|
|
dwErr = IE_GetIndex(pimgid->IMGID_IfIndex,
|
|
mMode,
|
|
&pie);
|
|
if (dwErr != NO_ERROR)
|
|
break;
|
|
|
|
// read lock acuired again, which is fine :)
|
|
dwErr = NM_GetInterfaceInfo(pie->dwIfIndex,
|
|
(PVOID) pimgod->IMGOD_Buffer,
|
|
&ulSizeGiven,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
ulSizeNeeded = ulSizeGiven;
|
|
|
|
// check that the output buffer was big enough
|
|
if (dwErr != NO_ERROR)
|
|
break;
|
|
|
|
pimgod->IMGOD_TypeID = IPSAMPLE_IF_CONFIG_ID;
|
|
pimgod->IMGOD_IfIndex = pie->dwIfIndex;
|
|
} while (FALSE);
|
|
|
|
RELEASE_READ_LOCK(&(g_ce.pneNetworkEntry)->rwlLock);
|
|
|
|
break;
|
|
}
|
|
|
|
// the interface binding structure is of variable size.
|
|
// there may be multiple instances.
|
|
case IPSAMPLE_IF_BINDING_ID:
|
|
{
|
|
PIPSAMPLE_IF_BINDING piib;
|
|
PIPSAMPLE_IP_ADDRESS piia;
|
|
|
|
ACQUIRE_READ_LOCK(&(g_ce.pneNetworkEntry)->rwlLock);
|
|
|
|
do // breakout loop
|
|
{
|
|
// retrieve the interface whose stats are to be read
|
|
dwErr = IE_GetIndex(pimgid->IMGID_IfIndex,
|
|
mMode,
|
|
&pie);
|
|
if (dwErr != NO_ERROR)
|
|
break;
|
|
|
|
// set the output size required for this entry
|
|
ulSizeNeeded = sizeof(IPSAMPLE_IF_BINDING) +
|
|
pie->ulNumBindings * sizeof(IPSAMPLE_IP_ADDRESS);
|
|
|
|
// check that the output buffer is big enough
|
|
if (ulSizeGiven < ulSizeNeeded)
|
|
{
|
|
dwErr = ERROR_INSUFFICIENT_BUFFER;
|
|
break;
|
|
}
|
|
|
|
pimgod->IMGOD_TypeID = IPSAMPLE_IF_BINDING_ID;
|
|
pimgod->IMGOD_IfIndex = pie->dwIfIndex;
|
|
|
|
piib = (PIPSAMPLE_IF_BINDING) pimgod->IMGOD_Buffer;
|
|
piia = IPSAMPLE_IF_ADDRESS_TABLE(piib);
|
|
|
|
if (INTERFACE_IS_ACTIVE(pie))
|
|
piib->dwState |= IPSAMPLE_STATE_ACTIVE;
|
|
|
|
if (INTERFACE_IS_BOUND(pie))
|
|
piib->dwState |= IPSAMPLE_STATE_BOUND;
|
|
|
|
piib->ulCount = pie->ulNumBindings;
|
|
CopyMemory((PVOID) piia, // address,mask pairs
|
|
(PVOID) pie->pbeBindingTable, // ditto
|
|
pie->ulNumBindings * sizeof(IPSAMPLE_IP_ADDRESS));
|
|
} while (FALSE);
|
|
|
|
RELEASE_READ_LOCK(&(g_ce.pneNetworkEntry)->rwlLock);
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
}
|
|
|
|
*pulOutputSize = sizeof(IPSAMPLE_MIB_GET_OUTPUT_DATA) + ulSizeNeeded;
|
|
|
|
LEAVE_SAMPLE_API();
|
|
|
|
return dwErr;
|
|
}
|