windows-nt/Source/XPSP1/NT/net/rras/rtmv2/rtmmgmt.c
2020-09-26 16:20:57 +08:00

408 lines
9.1 KiB
C

/*++
Copyright (c) 1997 - 98, Microsoft Corporation
Module Name:
rtmmgmt.c
Abstract:
Routines used to perform various management
functions on the Routing Table Manager v2.
Author:
Chaitanya Kodeboyina (chaitk) 17-Aug-1998
Revision History:
--*/
#include "pchrtm.h"
#pragma hdrstop
#include "rtmmgmt.h"
DWORD
WINAPI
RtmGetInstances (
IN OUT PUINT NumInstances,
OUT PRTM_INSTANCE_INFO InstanceInfos
)
/*++
Routine Description:
Enumerates all active RTM instances with their infos.
Arguments:
NumInstances - Num of Instance Info slots in the input
buffer is passed in, and the total number
of active RTM instances is returned.
RtmInstances - Instance Infos that are active in RTMv2.
Return Value:
Status of the operation
--*/
{
PINSTANCE_INFO Instance;
PLIST_ENTRY Instances, p;
UINT i, j;
DWORD Status;
CHECK_FOR_RTM_API_INITIALIZED();
TraceEnter("RtmGetInstances");
ACQUIRE_INSTANCES_READ_LOCK();
//
// Get next instance in table and copy info to output
//
for (i = j = 0; (i < INSTANCE_TABLE_SIZE) && (j < *NumInstances); i++)
{
Instances = &RtmGlobals.InstanceTable[i];
for (p = Instances->Flink; p != Instances; p = p->Flink)
{
Instance = CONTAINING_RECORD(p, INSTANCE_INFO, InstTableLE);
// Copy all relevant Instance information to output
InstanceInfos[j].RtmInstanceId = Instance->RtmInstanceId;
InstanceInfos[j].NumAddressFamilies = Instance->NumAddrFamilies;
if (++j == *NumInstances)
{
break;
}
}
}
Status = (*NumInstances >= RtmGlobals.NumInstances)
? NO_ERROR
: ERROR_INSUFFICIENT_BUFFER;
*NumInstances = RtmGlobals.NumInstances;
RELEASE_INSTANCES_READ_LOCK();
TraceLeave("RtmGetInstances");
return Status;
}
VOID
CopyAddrFamilyInfo(
IN USHORT RtmInstanceId,
IN PADDRFAM_INFO AddrFamilyBlock,
OUT PRTM_ADDRESS_FAMILY_INFO AddrFamilyInfo
)
/*++
Routine Description:
Copies all public information from an address family
to the output buffer.
Arguments:
RtmInstanceId - Instance for this addr family info
AddrFamilyBlock - Actual address family info block
AddrFamilyInfo - Address family info is copied here
Return Value:
None
Locks :
The global instances lock is held to get a consistent
view of the address family info in the instance.
--*/
{
TraceEnter("CopyAddrFamilyInfo");
AddrFamilyInfo->RtmInstanceId = RtmInstanceId;
AddrFamilyInfo->AddressFamily = AddrFamilyBlock->AddressFamily;
AddrFamilyInfo->ViewsSupported = AddrFamilyBlock->ViewsSupported;
AddrFamilyInfo->MaxHandlesInEnum = AddrFamilyBlock->MaxHandlesInEnum;
AddrFamilyInfo->MaxNextHopsInRoute = AddrFamilyBlock->MaxNextHopsInRoute;
AddrFamilyInfo->MaxOpaquePtrs = AddrFamilyBlock->MaxOpaquePtrs;
AddrFamilyInfo->NumOpaquePtrs = AddrFamilyBlock->NumOpaquePtrs;
AddrFamilyInfo->NumEntities = AddrFamilyBlock->NumEntities;
AddrFamilyInfo->NumDests = AddrFamilyBlock->NumDests;
AddrFamilyInfo->NumRoutes = AddrFamilyBlock->NumRoutes;
AddrFamilyInfo->MaxChangeNotifs = AddrFamilyBlock->MaxChangeNotifs;
AddrFamilyInfo->NumChangeNotifs = AddrFamilyBlock->NumChangeNotifs;
TraceLeave("CopyAddrFamilyInfo");
return;
}
DWORD
WINAPI
RtmGetInstanceInfo (
IN USHORT RtmInstanceId,
OUT PRTM_INSTANCE_INFO InstanceInfo,
IN OUT PUINT NumAddrFamilies,
OUT PRTM_ADDRESS_FAMILY_INFO AddrFamilyInfos OPTIONAL
)
/*++
Routine Description:
Get config and run time information of an RTM instance.
Arguments:
RtmInstanceId - ID identifying the RTM instance,
InstanceInfo - Buffer to return supported address families,
NumAddrFamilies - Number of input address family info slots,
Actual number of address families is retd.
AddrFamilyInfos - Address family infos are copied here.
Return Value:
Status of the operation
--*/
{
PINSTANCE_INFO Instance;
PADDRFAM_INFO AddrFamilyBlock;
PLIST_ENTRY AddrFamilies, q;
UINT i;
DWORD Status;
CHECK_FOR_RTM_API_INITIALIZED();
TraceEnter("RtmGetInstanceInfo");
ACQUIRE_INSTANCES_READ_LOCK();
do
{
//
// Search for the instance with input instance id
//
Status = GetInstance(RtmInstanceId, FALSE, &Instance);
if (Status != NO_ERROR)
{
break;
}
//
// Copy RTM instance information to output
//
InstanceInfo->RtmInstanceId = RtmInstanceId;
InstanceInfo->NumAddressFamilies = Instance->NumAddrFamilies;
//
// Copy address family infomation if reqd
//
if (ARGUMENT_PRESENT(AddrFamilyInfos))
{
if (*NumAddrFamilies < Instance->NumAddrFamilies)
{
Status = ERROR_INSUFFICIENT_BUFFER;
}
//
// Copy info for as many addr families as possible
//
AddrFamilies = &Instance->AddrFamilyTable;
for (q = AddrFamilies->Flink, i = 0;
(q != AddrFamilies) && (i < *NumAddrFamilies);
q = q->Flink)
{
AddrFamilyBlock =CONTAINING_RECORD(q, ADDRFAM_INFO, AFTableLE);
CopyAddrFamilyInfo(RtmInstanceId,
AddrFamilyBlock,
&AddrFamilyInfos[i++]);
}
}
*NumAddrFamilies = Instance->NumAddrFamilies;
}
while (FALSE);
RELEASE_INSTANCES_READ_LOCK();
TraceLeave("RtmGetInstanceInfo");
return Status;
}
DWORD
WINAPI
RtmGetAddressFamilyInfo (
IN USHORT RtmInstanceId,
IN USHORT AddressFamily,
OUT PRTM_ADDRESS_FAMILY_INFO AddrFamilyInfo,
IN OUT PUINT NumEntities,
OUT PRTM_ENTITY_INFO EntityInfos OPTIONAL
)
/*++
Routine Description:
Get config and run time information of an address family
in an RTM instance.
Arguments:
RtmInstanceId - ID identifying the RTM instance
AddressFamily - Address family that we are interested in
AddrFamilyInfo - Buffer to return output information in
NumEntities - Number of slots in the EntityIds buffer and
filled with num of regd entities on return.
EntityInfos - IDs of all registered entities is retd here.
Return Value:
Status of the operation
--*/
{
PINSTANCE_INFO Instance;
PADDRFAM_INFO AddrFamilyBlock;
PENTITY_INFO Entity;
PLIST_ENTRY Entities, r;
UINT i, j;
DWORD Status;
CHECK_FOR_RTM_API_INITIALIZED();
TraceEnter("RtmGetAddressFamilyInfo");
ACQUIRE_INSTANCES_READ_LOCK();
do
{
//
// Search for an instance with the input RtmInstanceId
//
Status = GetInstance(RtmInstanceId, FALSE, &Instance);
if (Status != NO_ERROR)
{
break;
}
//
// Search for an address family info with input family
//
Status = GetAddressFamily(Instance,
AddressFamily,
FALSE,
&AddrFamilyBlock);
if (Status != NO_ERROR)
{
break;
}
//
// Copy relevant address family information
//
CopyAddrFamilyInfo(RtmInstanceId, AddrFamilyBlock, AddrFamilyInfo);
//
// Is caller interested in entity info too ?
//
if (ARGUMENT_PRESENT(EntityInfos))
{
if (*NumEntities < AddrFamilyBlock->NumEntities)
{
Status = ERROR_INSUFFICIENT_BUFFER;
}
//
// Copy all relevant entity information to output
//
for (i = j = 0; (i < ENTITY_TABLE_SIZE) && (j < *NumEntities); i++)
{
Entities = &AddrFamilyBlock->EntityTable[i];
for (r = Entities->Flink; r != Entities; r = r->Flink)
{
Entity = CONTAINING_RECORD(r, ENTITY_INFO, EntityTableLE);
EntityInfos[j].RtmInstanceId = RtmInstanceId;
EntityInfos[j].AddressFamily = AddressFamily;
EntityInfos[j].EntityId = Entity->EntityId;
if (++j == *NumEntities)
{
break;
}
}
}
}
*NumEntities = AddrFamilyBlock->NumEntities;
}
while (FALSE);
RELEASE_INSTANCES_READ_LOCK();
TraceLeave("RtmGetAddressFamilyInfo");
return Status;
}