|
|
/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
net\ip\rtrmgr\info.c
Abstract: All info structure related code lives here
Revision History:
Gurdeep Singh Pall 6/15/95 Created
--*/
#include "allinc.h"
PRTR_TOC_ENTRY GetPointerToTocEntry( DWORD dwType, PRTR_INFO_BLOCK_HEADER pInfoHdr )
/*++
Routine Description
Given a pointer to an InfoBlock, this returns a pointer to the TOC of a given type
Locks
None
Arguments
dwType InfoType for TOC pInfoHdr Pointer to the InfoBlock header Return Value
NULL if the structure was not found Pointer to TOC other wise
--*/
{ DWORD i;
if(pInfoHdr is NULL) { return NULL; }
for(i = 0; i < pInfoHdr->TocEntriesCount; i++) { if(pInfoHdr->TocEntry[i].InfoType is dwType) { return &(pInfoHdr->TocEntry[i]); } }
return NULL; }
DWORD GetSizeOfInterfaceConfig( PICB picb )
/*++
Routine Description
This function figures out the size of interface configuration
Locks
ICB_LIST lock taken as READER Takes the PROTOCOL_CB_LIST lock as reader Arguments
picb ICB for the interface
Return Value
None
--*/
{ DWORD dwRoutProtInfoSize,dwRouteCount; PLIST_ENTRY pleNode; DWORD dwSize = 0, dwNumFilters; DWORD dwResult; DWORD dwInfoSize, i; ULONG ulStructureSize, ulStructureVersion, ulStructureCount; TraceEnter("GetSizeOfInterfaceConfig");
//
// Start with just the header (no TOC entry)
//
dwSize = FIELD_OFFSET(RTR_INFO_BLOCK_HEADER, TocEntry[0]); //
// Static Routes:
// Get the count, figure out the size needed to hold those, add the
// size of a TOC and an ALIGN_SIZE added for alignment
//
dwRouteCount = GetNumStaticRoutes(picb); dwSize += (SIZEOF_ROUTEINFO(dwRouteCount) + sizeof(RTR_TOC_ENTRY) + ALIGN_SIZE);
//
// Router Discovery info
//
dwSize += (sizeof(RTR_DISC_INFO) + sizeof(RTR_TOC_ENTRY) + ALIGN_SIZE);
//
// Interface Status info
//
dwSize += (sizeof(INTERFACE_STATUS_INFO) + sizeof(RTR_TOC_ENTRY) + ALIGN_SIZE);
#ifdef KSL_IPINIP
//
// If this is an ip in ip interface, add that info
//
if(picb->ritType is ROUTER_IF_TYPE_TUNNEL1) { dwSize += (sizeof(IPINIP_CONFIG_INFO) + sizeof(RTR_TOC_ENTRY) + ALIGN_SIZE); } #endif //KSL_IPINIP
for(i = 0; i < NUM_INFO_CBS; i++) { if (!g_rgicInfoCb[i].pfnGetInterfaceInfo) continue;
dwInfoSize = 0;
dwResult = g_rgicInfoCb[i].pfnGetInterfaceInfo(picb, NULL, NULL, NULL, NULL, &dwInfoSize);
if((dwResult isnot NO_ERROR) and (dwResult isnot ERROR_INSUFFICIENT_BUFFER)) { //
// The only errors which will tell us the size needed are
// NO_ERROR and ERROR_INSUFFICIENT_BUFFER. Anything else means
// we didnt get the right size
//
Trace2(ERR, "GetSizeOfInterfaceConfig: Error %d in GetIfInfo for %s\n", dwResult, g_rgicInfoCb[i].pszInfoName); continue; }
dwSize += (dwInfoSize + sizeof(RTR_TOC_ENTRY) + ALIGN_SIZE); }
//
// Information for all routing protocols ON THIS interface
//
ENTER_READER(PROTOCOL_CB_LIST);
for(pleNode = picb->leProtocolList.Flink; pleNode isnot &(picb->leProtocolList); pleNode = pleNode->Flink) { PIF_PROTO pProto; pProto = CONTAINING_RECORD(pleNode,IF_PROTO,leIfProtoLink); if(pProto->bPromiscuous) { //
// This interface was added merely because of promiscuous mode
//
continue; }
//
// Call the routing protocol's GetInterfaceConfigInfo() entrypoint
// with a NULL buffer. This will cause it to tell us the size of
// its config
//
dwRoutProtInfoSize = 0;
dwResult = (pProto->pActiveProto->pfnGetInterfaceInfo)( picb->dwIfIndex, NULL, &dwRoutProtInfoSize, &ulStructureVersion, &ulStructureSize, &ulStructureCount); if((dwResult isnot NO_ERROR) and (dwResult isnot ERROR_INSUFFICIENT_BUFFER)) { //
// The only errors which will tell us the size needed are
// NO_ERROR and ERROR_INSUFFICIENT_BUFFER. Anything else means
// we didnt get the right size
//
Trace2(ERR, "GetSizeOfInterfaceConfig: Error %d in GetIfInfo for %S\n", dwResult, pProto->pActiveProto->pwszDisplayName); continue; } dwSize += (dwRoutProtInfoSize + sizeof(RTR_TOC_ENTRY) + ALIGN_SIZE); }
EXIT_LOCK(PROTOCOL_CB_LIST);
//
// If we have filters on this interface, add that info
//
if(picb->pInFilter) { dwNumFilters = picb->pInFilter->dwNumFilters;
dwSize += (sizeof(RTR_TOC_ENTRY) + FIELD_OFFSET(FILTER_DESCRIPTOR, fiFilter[0]) + (dwNumFilters * sizeof(FILTER_INFO)) + ALIGN_SIZE); }
if(picb->pOutFilter) { dwNumFilters = picb->pOutFilter->dwNumFilters;
dwSize += (sizeof(RTR_TOC_ENTRY) + FIELD_OFFSET(FILTER_DESCRIPTOR, fiFilter[0]) + (dwNumFilters * sizeof(FILTER_INFO)) + ALIGN_SIZE); }
//
// Always report the fragmentation filter.
//
dwSize += (sizeof(IFFILTER_INFO) + sizeof(RTR_TOC_ENTRY) + ALIGN_SIZE);
if(picb->pDemandFilter) { dwNumFilters = picb->pDemandFilter->dwNumFilters;
dwSize += (sizeof(RTR_TOC_ENTRY) + FIELD_OFFSET(FILTER_DESCRIPTOR, fiFilter[0]) + (dwNumFilters * sizeof(FILTER_INFO)) + ALIGN_SIZE); }
return dwSize; }
DWORD GetInterfaceConfiguration( PICB picb, PRTR_INFO_BLOCK_HEADER pInfoHdrAndBuffer, DWORD dwInfoSize ) { DWORD i,dwErr, dwRet; DWORD dwTocIndex; PBYTE pbyDataPtr , pbyEndPtr; DWORD dwNumTocEntries; LONG lSize; PLIST_ENTRY pleNode;
TraceEnter("GetInterfaceConfiguration"); dwRet = NO_ERROR; //
// First calculate number of TOCs
//
//
// for static routes, router discovery, interface info and frag info
//
dwNumTocEntries = TOCS_ALWAYS_IN_INTERFACE_INFO;
//
// One TOC for each filter that exists
//
if(picb->pInFilter) { dwNumTocEntries++; }
if(picb->pOutFilter) { dwNumTocEntries++; }
if(picb->pDemandFilter) { dwNumTocEntries++; }
#ifdef KSL_IPINIP
if(picb->ritType is ROUTER_IF_TYPE_TUNNEL1) { dwNumTocEntries++; } #endif //KSL_IPINIP
for(i = 0; i < NUM_INFO_CBS; i++) { if (!g_rgicInfoCb[i].pfnGetInterfaceInfo) continue;
lSize = 0;
dwErr = g_rgicInfoCb[i].pfnGetInterfaceInfo(picb, NULL, &dwNumTocEntries, NULL, NULL, &lSize); }
//
// One TOC for each configured protocol
//
// *** Exclusion Begin ***
ENTER_READER(PROTOCOL_CB_LIST);
for(pleNode = picb->leProtocolList.Flink; pleNode isnot &(picb->leProtocolList); pleNode = pleNode->Flink) { PIF_PROTO pProto;
pProto = CONTAINING_RECORD(pleNode,IF_PROTO,leIfProtoLink);
if(pProto->bPromiscuous) { continue; }
dwNumTocEntries++; }
//
// fill in RTR_INFO_BLOCK_HEADER
//
dwTocIndex = 0;
pInfoHdrAndBuffer->Version = IP_ROUTER_MANAGER_VERSION; pInfoHdrAndBuffer->TocEntriesCount = dwNumTocEntries; pInfoHdrAndBuffer->Size = dwInfoSize; //
// Data begins after TocEntry[dwNumTocEntries - 1]
//
pbyDataPtr = ((PBYTE) &(pInfoHdrAndBuffer->TocEntry[dwNumTocEntries]));
//
// Align to an 8byte boundary
//
ALIGN_POINTER(pbyDataPtr); pbyEndPtr = (PBYTE)pInfoHdrAndBuffer + dwInfoSize; //
// So the size of buffer left for information is
//
lSize = (LONG)(pbyEndPtr - pbyDataPtr); //
// fill in routing protocol info
//
for(pleNode = picb->leProtocolList.Flink; pleNode isnot &(picb->leProtocolList); pleNode = pleNode->Flink) { PIF_PROTO pProto; pProto = CONTAINING_RECORD(pleNode,IF_PROTO,leIfProtoLink); if(pProto->bPromiscuous) { //
// This interface was added merely because of promiscuous mode
//
continue; }
if(lSize <= 0) { Trace0(ERR, "GetInterfaceConfiguration: There is no more space left to fill in config info even though there are more protocols");
break; } dwErr = GetInterfaceRoutingProtoInfo( picb, pProto->pActiveProto, &pInfoHdrAndBuffer->TocEntry[dwTocIndex++], pbyDataPtr, pInfoHdrAndBuffer, &lSize); if(dwErr isnot NO_ERROR) { Trace2(ERR, "GetInterfaceConfiguration: Info from %S. Error %d", pProto->pActiveProto->pwszDisplayName, dwErr);
dwRet = ERROR_MORE_DATA; } else { pbyDataPtr += lSize; ALIGN_POINTER(pbyDataPtr); } lSize = (LONG)(pbyEndPtr - pbyDataPtr); }
EXIT_LOCK(PROTOCOL_CB_LIST);
if(lSize <= 0) { Trace0(ERR, "GetInterfaceConfiguration: There is no more space left to fill in config info"); return ERROR_MORE_DATA; }
for(i = 0; i < NUM_INFO_CBS; i++) { if (!g_rgicInfoCb[i].pfnGetInterfaceInfo) continue;
dwErr = g_rgicInfoCb[i].pfnGetInterfaceInfo(picb, &pInfoHdrAndBuffer->TocEntry[dwTocIndex], &dwTocIndex, pbyDataPtr, pInfoHdrAndBuffer, &lSize);
if(dwErr isnot NO_ERROR) { Trace2(ERR, "GetInterfaceConfiguration: Error %d getting %s info.", dwErr, g_rgicInfoCb[i].pszInfoName);
if(dwErr isnot ERROR_NO_DATA) { dwRet = ERROR_MORE_DATA; } } else { pbyDataPtr += lSize;
ALIGN_POINTER(pbyDataPtr); }
lSize = (LONG) (pbyEndPtr - pbyDataPtr); }
#ifdef KSL_IPINIP
if(picb->ritType is ROUTER_IF_TYPE_TUNNEL1) { dwErr = GetInterfaceIpIpInfo(picb, &pInfoHdrAndBuffer->TocEntry[dwTocIndex++], pbyDataPtr, pInfoHdrAndBuffer, &lSize);
if(dwErr isnot NO_ERROR) { Trace1(ERR, "GetInterfaceConfiguration: Couldnt ipip info. Error %d", dwErr);
if(dwErr isnot ERROR_NO_DATA) { dwRet = ERROR_MORE_DATA; } } else { pbyDataPtr += lSize;
ALIGN_POINTER(pbyDataPtr); }
lSize = (LONG) (pbyEndPtr - pbyDataPtr); } #endif //KSL_IPINIP
//
// fill in route info
//
dwErr = GetInterfaceRouteInfo(picb, &pInfoHdrAndBuffer->TocEntry[dwTocIndex++], pbyDataPtr, pInfoHdrAndBuffer, &lSize); if(dwErr isnot NO_ERROR) { Trace1(ERR, "GetInterfaceConfiguration: Couldnt Interface route info. Error %d", dwErr);
if(dwErr isnot ERROR_NO_DATA) { dwRet = ERROR_MORE_DATA; } } else { pbyDataPtr += lSize; ALIGN_POINTER(pbyDataPtr); } lSize = (LONG) (pbyEndPtr - pbyDataPtr);
if(lSize <= 0) { Trace0(ERR, "GetInterfaceConfiguration: There is no more space left to fill in config info"); return ERROR_MORE_DATA; } //
// Fill in the status info
//
dwErr = GetInterfaceStatusInfo(picb, &pInfoHdrAndBuffer->TocEntry[dwTocIndex++], pbyDataPtr, pInfoHdrAndBuffer, &lSize);
if(dwErr isnot NO_ERROR) { Trace1(ERR, "GetInterfaceConfiguration: Error %d getting Interface status", dwErr);
if(dwErr isnot ERROR_NO_DATA) { dwRet = ERROR_MORE_DATA; } } else { pbyDataPtr += lSize;
ALIGN_POINTER(pbyDataPtr); }
lSize = (LONG) (pbyEndPtr - pbyDataPtr);
if(lSize <= 0) { Trace0(ERR, "GetInterfaceConfiguration: There is no more space left to fill in config info"); return ERROR_MORE_DATA; } //
// Fill in the Router Discovery information
//
dwErr = GetInterfaceRouterDiscoveryInfo( picb, &pInfoHdrAndBuffer->TocEntry[dwTocIndex++], pbyDataPtr, pInfoHdrAndBuffer, &lSize);
if(dwErr isnot NO_ERROR) { Trace1(ERR, "GetInterfaceConfiguration: Couldnt Interface router discovery info. Error %d", dwErr);
if(dwErr isnot ERROR_NO_DATA) { dwRet = ERROR_MORE_DATA; } } else { pbyDataPtr += lSize;
ALIGN_POINTER(pbyDataPtr); }
lSize = (LONG) (pbyEndPtr - pbyDataPtr);
if(lSize <= 0) { Trace0(ERR, "GetInterfaceConfiguration: There is no more space left to fill in config info"); return ERROR_MORE_DATA; } if(picb->pInFilter) { dwErr = GetInFilters(picb, &pInfoHdrAndBuffer->TocEntry[dwTocIndex], pbyDataPtr, pInfoHdrAndBuffer, &lSize); if(dwErr is NO_ERROR) { dwTocIndex++; pbyDataPtr += lSize; ALIGN_POINTER(pbyDataPtr); } else { if(dwErr isnot ERROR_NO_DATA) { dwRet = ERROR_MORE_DATA; } } lSize = (LONG) (pbyEndPtr - pbyDataPtr);
if(lSize <= 0) { Trace0(ERR, "GetInterfaceConfiguration: There is no more space left to fill in config info"); return ERROR_MORE_DATA; } } if(picb->pOutFilter) { dwErr = GetOutFilters(picb, &pInfoHdrAndBuffer->TocEntry[dwTocIndex], pbyDataPtr, pInfoHdrAndBuffer, &lSize); if(dwErr is NO_ERROR) { dwTocIndex++; pbyDataPtr += lSize; ALIGN_POINTER(pbyDataPtr); } else { if(dwErr isnot ERROR_NO_DATA) { dwRet = ERROR_MORE_DATA; } } lSize = (LONG) (pbyEndPtr - pbyDataPtr);
if(lSize <= 0) { Trace0(ERR, "GetInterfaceConfiguration: There is no more space left to fill in config info"); return ERROR_MORE_DATA; } } if((picb->ritType isnot ROUTER_IF_TYPE_INTERNAL) and (picb->ritType isnot ROUTER_IF_TYPE_LOOPBACK) and (picb->ritType isnot ROUTER_IF_TYPE_CLIENT)) { dwErr = GetGlobalFilterOnIf(picb, &pInfoHdrAndBuffer->TocEntry[dwTocIndex], pbyDataPtr, pInfoHdrAndBuffer, &lSize);
if(dwErr is NO_ERROR) { dwTocIndex++;
pbyDataPtr += lSize;
ALIGN_POINTER(pbyDataPtr); } else { if(dwErr isnot ERROR_NO_DATA) { dwRet = ERROR_MORE_DATA; } }
lSize = (LONG) (pbyEndPtr - pbyDataPtr);
if(lSize <= 0) { Trace0(ERR, "GetInterfaceConfiguration: There is no more space left to fill in config info");
return ERROR_MORE_DATA; } }
if(picb->pDemandFilter) { dwErr = GetDemandFilters(picb, &pInfoHdrAndBuffer->TocEntry[dwTocIndex], pbyDataPtr, pInfoHdrAndBuffer, &lSize); if(dwErr is NO_ERROR) { dwTocIndex++; pbyDataPtr += lSize; ALIGN_POINTER(pbyDataPtr); } else { if(dwErr isnot ERROR_NO_DATA) { dwRet = ERROR_MORE_DATA; } } lSize = (LONG) (pbyEndPtr - pbyDataPtr); }
if(pInfoHdrAndBuffer->TocEntriesCount != dwTocIndex) { pInfoHdrAndBuffer->TocEntriesCount = dwTocIndex; }
return dwRet; }
DWORD GetInterfaceRoutingProtoInfo( PICB picb, PPROTO_CB pProtoCbPtr, PRTR_TOC_ENTRY pToc, PBYTE pbyDataPtr, PRTR_INFO_BLOCK_HEADER pInfoHdrAndBuffer, PDWORD pdwSize ) { ULONG ulStructureSize, ulStructureCount, ulStructureVersion; DWORD dwError = NO_ERROR;
TraceEnter("GetInterfaceRoutingProtoInfo"); dwError = (pProtoCbPtr->pfnGetInterfaceInfo)(picb->dwIfIndex, pbyDataPtr, pdwSize, &ulStructureVersion, &ulStructureSize, &ulStructureCount); if(dwError isnot NO_ERROR) { Trace1(ERR, "GetInterfaceRoutingProtoInfo: GetIfConfigInfo() failed for protocol %S", pProtoCbPtr->pwszDisplayName);
return dwError; }
//IpRtAssert(*pdwSize is (ulStructureSize * ulStructureCount));
pToc->InfoSize = ulStructureSize; pToc->InfoType = pProtoCbPtr->dwProtocolId; pToc->Count = ulStructureCount; pToc->Offset = (ULONG)(pbyDataPtr - (PBYTE)pInfoHdrAndBuffer); //pToc->InfoVersion = ulStructureVersion;
return NO_ERROR; }
DWORD GetGlobalConfiguration( PRTR_INFO_BLOCK_HEADER pInfoHdrAndBuffer, DWORD dwInfoSize ) { DWORD dwRoutProtInfoSize; PPROTO_CB pProtoCbPtr; DWORD dwNumTocEntries, i; DWORD dwTocIndex,dwResult; DWORD dwBufferRemaining,dwSize,dwIndex; PBYTE pbyDataPtr, pbyEndPtr; PLIST_ENTRY pleNode; PGLOBAL_INFO pGlobalInfo; ULONG ulStructureVersion, ulStructureSize, ulStructureCount; TraceEnter("GetGlobalConfiguration");
//
// First calculate number of TOCs
//
dwNumTocEntries = TotalRoutingProtocols + TOCS_ALWAYS_IN_GLOBAL_INFO; for(i = 0; i < NUM_INFO_CBS; i++) { if (!g_rgicInfoCb[i].pfnGetGlobalInfo) continue;
dwSize = 0;
dwResult = g_rgicInfoCb[i].pfnGetGlobalInfo(NULL, &dwNumTocEntries, NULL, NULL, &dwSize); } //
// Fill Header, RTR_TOC_ENTRYs for global, priority and each of the protos
//
pInfoHdrAndBuffer->Version = IP_ROUTER_MANAGER_VERSION; pInfoHdrAndBuffer->TocEntriesCount = dwNumTocEntries;
//
// Fill in TOCs. Data starts after the last TOC
//
pbyDataPtr = (PBYTE)&(pInfoHdrAndBuffer->TocEntry[pInfoHdrAndBuffer->TocEntriesCount]);
pbyEndPtr = (PBYTE)pInfoHdrAndBuffer + dwInfoSize;
ALIGN_POINTER(pbyDataPtr); dwTocIndex = 0; dwBufferRemaining = (DWORD)(pbyEndPtr - pbyDataPtr);
//
// Fill in Routing Protocol Priority infoblock
//
dwRoutProtInfoSize = dwBufferRemaining;
dwResult = GetPriorityInfo(pbyDataPtr, &dwRoutProtInfoSize); //pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoVersion = dwRoutProtInfoSize;
pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoSize = dwRoutProtInfoSize; pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoType = IP_PROT_PRIORITY_INFO; pInfoHdrAndBuffer->TocEntry[dwTocIndex].Count = 1; pInfoHdrAndBuffer->TocEntry[dwTocIndex].Offset = (ULONG)(pbyDataPtr - (PBYTE)pInfoHdrAndBuffer); dwTocIndex++; pbyDataPtr += dwRoutProtInfoSize; ALIGN_POINTER(pbyDataPtr);
dwBufferRemaining = (DWORD)(pbyEndPtr - pbyDataPtr);
for(i = 0; i < NUM_INFO_CBS; i++) { if (!g_rgicInfoCb[i].pfnGetGlobalInfo) continue;
dwSize = dwBufferRemaining;
dwResult = g_rgicInfoCb[i].pfnGetGlobalInfo( &pInfoHdrAndBuffer->TocEntry[dwTocIndex], &dwTocIndex, pbyDataPtr, pInfoHdrAndBuffer, &dwSize);
pbyDataPtr += dwSize; ALIGN_POINTER(pbyDataPtr);
dwBufferRemaining = (DWORD)(pbyEndPtr - pbyDataPtr); }
dwSize = sizeof(GLOBAL_INFO);
pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoSize = dwSize; pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoType = IP_GLOBAL_INFO; pInfoHdrAndBuffer->TocEntry[dwTocIndex].Count = 1; //pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoVersion = 1;
pInfoHdrAndBuffer->TocEntry[dwTocIndex].Offset = (ULONG)(pbyDataPtr - (PBYTE) pInfoHdrAndBuffer); pGlobalInfo = (PGLOBAL_INFO)pbyDataPtr;
//
// unused
//
pGlobalInfo->bFilteringOn = 0; pGlobalInfo->dwLoggingLevel = g_dwLoggingLevel; dwTocIndex++; pbyDataPtr += dwSize; ALIGN_POINTER(pbyDataPtr);
dwBufferRemaining = (DWORD)(pbyEndPtr - pbyDataPtr); //
// fill in global info for all routing protocols
//
for(pleNode = g_leProtoCbList.Flink; pleNode != &g_leProtoCbList; pleNode = pleNode->Flink) { pProtoCbPtr = CONTAINING_RECORD(pleNode, PROTO_CB, leList);
if(pProtoCbPtr->posOpState isnot RTR_STATE_RUNNING) { //
// if the protocol is in the process of stopping
// skip it
//
continue; } dwRoutProtInfoSize = dwBufferRemaining;
dwResult = (pProtoCbPtr->pfnGetGlobalInfo)(pbyDataPtr, &dwRoutProtInfoSize, &ulStructureVersion, &ulStructureSize, &ulStructureCount); if(dwResult isnot NO_ERROR) { Trace2(ERR, "GetGlobalConfiguration: Error %d getting global info from %s", dwResult, pProtoCbPtr->pwszDllName); continue; } // pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoVersion = ulStructureVersion;
pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoSize = ulStructureSize; pInfoHdrAndBuffer->TocEntry[dwTocIndex].InfoType = pProtoCbPtr->dwProtocolId; pInfoHdrAndBuffer->TocEntry[dwTocIndex].Offset = (ULONG)(pbyDataPtr - (PBYTE)pInfoHdrAndBuffer);
pInfoHdrAndBuffer->TocEntry[dwTocIndex].Count = ulStructureCount;
dwTocIndex++; pbyDataPtr += dwRoutProtInfoSize;
ALIGN_POINTER(pbyDataPtr);
dwBufferRemaining = (DWORD)(pbyEndPtr - pbyDataPtr); }
pInfoHdrAndBuffer->Size = (ULONG) ((ULONG_PTR)pbyDataPtr - (ULONG_PTR)pInfoHdrAndBuffer);
return NO_ERROR; }
DWORD GetSizeOfGlobalInfo( VOID ) { DWORD dwSize = 0, dwResult; DWORD dwRoutProtInfoSize; PICB picb; PPROTO_CB pProtoCbPtr; PLIST_ENTRY pleNode; DWORD dwInfoSize, i; ULONG ulStructureVersion, ulStructureSize, ulStructureCount;
TraceEnter("GetSizeOfGlobalInfo"); dwSize = sizeof(RTR_INFO_BLOCK_HEADER) - sizeof(RTR_TOC_ENTRY); //
// get size of Routing Protocol Priority info
//
dwRoutProtInfoSize = 0; GetPriorityInfo(NULL, &dwRoutProtInfoSize); //
// ALIGN_SIZE added for alignment
//
dwSize += (dwRoutProtInfoSize + sizeof(RTR_TOC_ENTRY) + ALIGN_SIZE);
for(i = 0; i < NUM_INFO_CBS; i++) { if (!g_rgicInfoCb[i].pfnGetGlobalInfo) continue;
dwInfoSize = 0;
dwResult = g_rgicInfoCb[i].pfnGetGlobalInfo(NULL, NULL, NULL, NULL, &dwInfoSize);
if((dwResult isnot NO_ERROR) and (dwResult isnot ERROR_INSUFFICIENT_BUFFER)) { //
// The only errors which will tell us the size needed are
// NO_ERROR and ERROR_INSUFFICIENT_BUFFER. Anything else means
// we didnt get the right size
//
Trace2(ERR, "GetSizeOfGlobalInfo: Error %d in GetGlobInfo for %s\n", dwResult, g_rgicInfoCb[i].pszInfoName); continue; }
dwSize += (dwInfoSize + sizeof(RTR_TOC_ENTRY) + ALIGN_SIZE); }
//
// The names of the Dlls - part of Global Info
//
dwSize += (sizeof(GLOBAL_INFO) + sizeof(RTR_TOC_ENTRY) + ALIGN_SIZE); //
// get size of infoblocks for all routing protocols
//
for(pleNode = g_leProtoCbList.Flink; pleNode isnot &g_leProtoCbList; pleNode = pleNode->Flink) { pProtoCbPtr = CONTAINING_RECORD(pleNode, PROTO_CB, leList); if(pProtoCbPtr->posOpState isnot RTR_STATE_RUNNING) { //
// if the protocol is in the process of stopping
// skip it
//
continue; } //
// Call the routing protocol's GetGlobalConfigInfo() entrypoint
// with NULL. This should return the buffer size needed
//
dwRoutProtInfoSize = 0;
dwResult = (pProtoCbPtr->pfnGetGlobalInfo)(NULL, &dwRoutProtInfoSize, &ulStructureVersion, &ulStructureSize, &ulStructureCount);
if((dwResult is NO_ERROR) or (dwResult is ERROR_INSUFFICIENT_BUFFER)) { dwSize += (dwRoutProtInfoSize + sizeof(RTR_TOC_ENTRY) + ALIGN_SIZE); } }
return dwSize; }
|