/*++ 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; }