408 lines
9.1 KiB
C
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;
|
||
|
}
|