Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2365 lines
57 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
net\ip\rtrmgr\init.c
Abstract:
IP Router Manager code
Revision History:
Gurdeep Singh Pall 6/14/95 Created
--*/
#include "allinc.h"
DWORD
RtrMgrMIBEntryCreate(
IN DWORD dwRoutingPid,
IN DWORD dwEntrySize,
IN LPVOID lpEntry
);
DWORD
RtrMgrMIBEntryDelete(
IN DWORD dwRoutingPid,
IN DWORD dwEntrySize,
IN LPVOID lpEntry
);
DWORD
RtrMgrMIBEntryGet(
IN DWORD dwRoutingPid,
IN DWORD dwInEntrySize,
IN LPVOID lpInEntry,
IN OUT LPDWORD lpOutEntrySize,
OUT LPVOID lpOutEntry
);
DWORD
RtrMgrMIBEntryGetFirst(
IN DWORD dwRoutingPid,
IN DWORD dwInEntrySize,
IN LPVOID lpInEntry,
IN OUT LPDWORD lpOutEntrySize,
OUT LPVOID lpOutEntry
);
DWORD
RtrMgrMIBEntryGetNext(
IN DWORD dwRoutingPid,
IN DWORD dwInEntrySize,
IN LPVOID lpInEntry,
IN OUT LPDWORD lpOutEntrySize,
OUT LPVOID lpOutEntry
);
DWORD
RtrMgrMIBEntrySet(
IN DWORD dwRoutingPid,
IN DWORD dwEntrySize,
IN LPVOID lpEntry
);
DWORD
InitRouter(
PRTR_INFO_BLOCK_HEADER pGlobalInfo
)
/*++
Routine Description:
Loads routing protocols, loads bootp agent, opens the approp. drivers,
and starts the worker thread.
Arguments:
GlobalInfo passed in by DIM
Return Value:
NO_ERROR or some error code
--*/
{
HANDLE hThread;
DWORD dwResult, dwTid, i;
PGLOBAL_INFO pInfo;
PRTR_TOC_ENTRY pToc;
IPSNMPInfo ipsiInfo;
RTM_ENTITY_INFO entityInfo;
PIP_NAT_GLOBAL_INFO pNatInfo;
PMIB_IPFORWARDTABLE pInitRouteTable;
PROUTE_LIST_ENTRY prl;
MGM_CALLBACKS mgmCallbacks;
ROUTER_MANAGER_CONFIG mgmConfig;
TraceEnter("InitRouter");
//
// Initialize all the locks (MIB handlers and ICB_LIST/PROTOCOL_CB_LIST)
// VERY IMPORTANT, since we break out of this and try and do a cleanup
// which needs the lists and the locks, WE MUST initialize the lists
// and the locks BEFORE the first abnormal exit from this function
//
for(i = 0; i < NUM_LOCKS; i++)
{
RtlInitializeResource(&g_LockTable[i]);
}
//
// Init the list head for interfaces
//
InitializeListHead(&ICBList);
//
// Initialize ICB Hash lookup table and the Adapter to Interface Hash
//
for (i=0; i<ICB_HASH_TABLE_SIZE; i++)
{
InitializeListHead(&ICBHashLookup[i]);
InitializeListHead(&ICBSeqNumLookup[i]);
}
InitHashTables();
//
// Initialize Routing protocol List
//
InitializeListHead(&g_leProtoCbList);
//
// Initialize the Router Discovery Timer Queue
//
InitializeListHead(&g_leTimerQueueHead);
pToc = GetPointerToTocEntry(IP_GLOBAL_INFO, pGlobalInfo);
if(!pToc or (pToc->InfoSize is 0))
{
LogErr0(NO_GLOBAL_INFO,
ERROR_NO_DATA);
Trace0(ERR,
"InitRouter: No Global Info - can not start router");
TraceLeave("InitRouter");
return ERROR_CAN_NOT_COMPLETE;
}
pInfo = (PGLOBAL_INFO)GetInfoFromTocEntry(pGlobalInfo,
pToc);
if(pInfo is NULL)
{
LogErr0(NO_GLOBAL_INFO,
ERROR_NO_DATA);
Trace0(ERR,
"InitRouter: No Global Info - can not start router");
TraceLeave("InitRouter");
return ERROR_CAN_NOT_COMPLETE;
}
#pragma warning(push)
#pragma warning(disable:4296)
if((pInfo->dwLoggingLevel > IPRTR_LOGGING_INFO) or
(pInfo->dwLoggingLevel < IPRTR_LOGGING_NONE))
#pragma warning(pop)
{
Trace1(ERR,
"InitRouter: Global info has invalid logging level of %d",
pInfo->dwLoggingLevel);
g_dwLoggingLevel = IPRTR_LOGGING_INFO;
}
else
{
g_dwLoggingLevel = pInfo->dwLoggingLevel;
}
//
// Allocate private heap
//
IPRouterHeap = HeapCreate(0, 5000, 0);
if(IPRouterHeap is NULL)
{
dwResult = GetLastError() ;
Trace1(ERR,
"InitRouter: Error %d creating IPRouterHeap",
dwResult) ;
TraceLeave("InitRouter");
return dwResult ;
}
//
// Create the events needed to talk to the routing protocols,
// DIM and WANARP
//
g_hRoutingProtocolEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
g_hStopRouterEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
g_hSetForwardingEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
g_hForwardingChangeEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
g_hDemandDialEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
g_hIpInIpEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
g_hStackChangeEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
g_hRtrDiscSocketEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
g_hMHbeatSocketEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
g_hMcMiscSocketEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
g_hMzapSocketEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
for(i = 0; i < NUM_MCAST_IRPS; i++)
{
g_hMcastEvents[i] = CreateEvent(NULL,FALSE,FALSE,NULL);
}
for(i = 0; i < NUM_ROUTE_CHANGE_IRPS; i++)
{
g_hRouteChangeEvents[i] = CreateEvent(NULL,FALSE,FALSE,NULL);
}
g_hRtrDiscTimer = CreateWaitableTimer(NULL,
FALSE,
NULL);
g_hRasAdvTimer = CreateWaitableTimer(NULL,
FALSE,
NULL);
g_hMzapTimer = CreateWaitableTimer(NULL,
FALSE,
NULL);
if((g_hRoutingProtocolEvent is NULL) or
(g_hStopRouterEvent is NULL) or
(g_hSetForwardingEvent is NULL) or
(g_hForwardingChangeEvent is NULL) or
(g_hDemandDialEvent is NULL) or
(g_hIpInIpEvent is NULL) or
(g_hStackChangeEvent is NULL) or
(g_hRtrDiscSocketEvent is NULL) or
(g_hRtrDiscTimer is NULL) or
(g_hRasAdvTimer is NULL) or
(g_hMcMiscSocketEvent is NULL) or
(g_hMzapSocketEvent is NULL) or
(g_hMHbeatSocketEvent is NULL))
{
Trace0(ERR,
"InitRouter: Couldnt create the needed events and timer");
TraceLeave("InitRouter");
return ERROR_CAN_NOT_COMPLETE;
}
for(i = 0; i < NUM_MCAST_IRPS; i++)
{
if(g_hMcastEvents[i] is NULL)
{
Trace0(ERR,
"InitRouter: Couldnt create the mcast events");
TraceLeave("InitRouter");
return ERROR_CAN_NOT_COMPLETE;
}
}
for(i = 0; i < NUM_ROUTE_CHANGE_IRPS; i++)
{
if(g_hRouteChangeEvents[i] is NULL)
{
Trace0(ERR,
"InitRouter: Couldnt create the mcast events");
TraceLeave("InitRouter");
return ERROR_CAN_NOT_COMPLETE;
}
}
Trace0(GLOBAL,
"InitRouter: Created necessary events and timer");
dwResult = MprConfigServerConnect(NULL,
&g_hMprConfig);
if(dwResult isnot NO_ERROR)
{
Trace1(ERR,
"InitRouter: Error %d calling MprConfigServerConnect",
dwResult);
return dwResult;
}
g_sinAllSystemsAddr.sin_family = AF_INET;
g_sinAllSystemsAddr.sin_addr.s_addr = ALL_SYSTEMS_MULTICAST_GROUP;
g_sinAllSystemsAddr.sin_port = 0;
g_pIpHeader = (PIP_HEADER)g_pdwIpAndIcmpBuf;
g_wsaIpRcvBuf.buf = (PBYTE)g_pIpHeader;
g_wsaIpRcvBuf.len = ICMP_RCV_BUFFER_LEN * sizeof(DWORD);
g_wsaMcRcvBuf.buf = g_byMcMiscBuffer;
g_wsaMcRcvBuf.len = sizeof(g_byMcMiscBuffer);
//
// Get all the routes that are in the stack and store them away
//
pInitRouteTable = NULL;
InitializeListHead( &g_leStackRoutesToRestore );
dwResult = AllocateAndGetIpForwardTableFromStack(&pInitRouteTable,
FALSE,
IPRouterHeap,
0);
if(dwResult isnot NO_ERROR)
{
Trace1(ERR,
"InitRouter: Couldnt get initial routes. Error %d",
dwResult);
}
else
{
if(pInitRouteTable->dwNumEntries isnot 0)
{
TraceRoute0( ROUTE, "Init. table routes\n" );
for ( i = 0; i < pInitRouteTable-> dwNumEntries; i++ )
{
if (pInitRouteTable->table[i].dwForwardProto !=
MIB_IPPROTO_NETMGMT)
{
continue;
}
TraceRoute3(
ROUTE, "%d.%d.%d.%d/%d.%d.%d.%d, type 0x%x",
PRINT_IPADDR( pInitRouteTable-> table[i].dwForwardDest ),
PRINT_IPADDR( pInitRouteTable-> table[i].dwForwardMask ),
pInitRouteTable-> table[i].dwForwardType
);
//
// Allocate and store route in a linked list
//
prl = HeapAlloc(
IPRouterHeap, HEAP_ZERO_MEMORY,
sizeof(ROUTE_LIST_ENTRY)
);
if (prl is NULL)
{
Trace2(
ERR,
"InitRouter: error %d allocating %d bytes "
"for stack route entry",
ERROR_NOT_ENOUGH_MEMORY,
sizeof(ROUTE_LIST_ENTRY)
);
dwResult = ERROR_NOT_ENOUGH_MEMORY;
break;
}
InitializeListHead( &prl->leRouteList );
prl->mibRoute = pInitRouteTable-> table[i];
InsertTailList(
&g_leStackRoutesToRestore, &prl->leRouteList
);
}
if (dwResult isnot NO_ERROR)
{
while (!IsListEmpty(&g_leStackRoutesToRestore))
{
prl = (PROUTE_LIST_ENTRY) RemoveHeadList(
&g_leStackRoutesToRestore
);
HeapFree(IPRouterHeap, 0, prl);
}
}
}
HeapFree(IPRouterHeap, 0, pInitRouteTable);
pInitRouteTable = NULL;
}
//
// The route table is created implicitly by RTM at the
// time of the first registration call (see call below)
//
//
// Setup common params for all registrations with RTMv2
//
entityInfo.RtmInstanceId = 0; // routerId;
entityInfo.AddressFamily = AF_INET;
entityInfo.EntityId.EntityInstanceId = 0;
//
// Register with RTM using the appropriate proto ids
//
//
// This 1st registration is also used for performing
// RTM operations common for all these registrations,
// As an example it is used to get any changed dests.
//
entityInfo.EntityId.EntityProtocolId = PROTO_IP_LOCAL;
dwResult = RtmRegisterEntity(&entityInfo,
NULL,
RtmEventCallback,
FALSE,
&g_rtmProfile,
&g_hLocalRoute);
if(dwResult isnot NO_ERROR)
{
Trace1(ERR,
"InitRouter: RtmRegisterClient for local routes failed %d",
dwResult) ;
TraceLeave("InitRouter");
return dwResult ;
}
// Also register for dest change notifications
dwResult = RtmRegisterForChangeNotification(g_hLocalRoute,
RTM_VIEW_MASK_UCAST,
RTM_CHANGE_TYPE_FORWARDING,
NULL,
&g_hNotification);
if (dwResult isnot NO_ERROR)
{
Trace1(ERR,
"InitRouter: RtmRegisterForChangeNotificaition failed %d",
dwResult) ;
TraceLeave("InitRouter");
return dwResult ;
}
//
// Register more times for each type of route
//
entityInfo.EntityId.EntityProtocolId = PROTO_IP_NT_AUTOSTATIC;
dwResult = RtmRegisterEntity(&entityInfo,
NULL,
NULL,
FALSE,
&g_rtmProfile,
&g_hAutoStaticRoute);
if(dwResult isnot NO_ERROR)
{
Trace1(ERR,
"InitRouter: RtmRegisterClient for AutoStatic routes failed %d",
dwResult) ;
TraceLeave("InitRouter");
return dwResult ;
}
entityInfo.EntityId.EntityProtocolId = PROTO_IP_NT_STATIC;
dwResult = RtmRegisterEntity(&entityInfo,
NULL,
NULL,
FALSE,
&g_rtmProfile,
&g_hStaticRoute);
if(dwResult isnot NO_ERROR)
{
Trace1(ERR,
"InitRouter: RtmRegisterClient for Static routes failed %d",
dwResult) ;
TraceLeave("InitRouter");
return dwResult ;
}
entityInfo.EntityId.EntityProtocolId = PROTO_IP_NT_STATIC_NON_DOD;
dwResult = RtmRegisterEntity(&entityInfo,
NULL,
NULL,
FALSE,
&g_rtmProfile,
&g_hNonDodRoute);
if(dwResult isnot NO_ERROR)
{
Trace1(ERR,
"InitRouter: RtmRegisterClient for DOD routes failed %d",
dwResult) ;
TraceLeave("InitRouter");
return dwResult ;
}
entityInfo.EntityId.EntityProtocolId = PROTO_IP_NETMGMT;
dwResult = RtmRegisterEntity(&entityInfo,
NULL,
RtmEventCallback,
FALSE,
&g_rtmProfile,
&g_hNetMgmtRoute);
if(dwResult isnot NO_ERROR)
{
Trace1(ERR,
"InitRouter: RtmRegisterClient for NetMgmt routes failed %d",
dwResult) ;
TraceLeave("InitRouter");
return dwResult ;
}
// Also register for marked dest change notifications
dwResult = RtmRegisterForChangeNotification(g_hNetMgmtRoute,
RTM_VIEW_MASK_UCAST,
RTM_CHANGE_TYPE_ALL |
RTM_NOTIFY_ONLY_MARKED_DESTS,
NULL,
&g_hDefaultRouteNotification);
if (dwResult isnot NO_ERROR)
{
Trace1(ERR,
"InitRouter: RtmRegisterForChangeNotificaition failed %d",
dwResult) ;
TraceLeave("InitRouter");
return dwResult ;
}
g_rgRtmHandles[0].dwProtoId = PROTO_IP_LOCAL;
g_rgRtmHandles[0].hRouteHandle = g_hLocalRoute;
g_rgRtmHandles[0].bStatic = FALSE;
g_rgRtmHandles[1].dwProtoId = PROTO_IP_NT_AUTOSTATIC;
g_rgRtmHandles[1].hRouteHandle = g_hAutoStaticRoute;
g_rgRtmHandles[1].bStatic = TRUE;
g_rgRtmHandles[2].dwProtoId = PROTO_IP_NT_STATIC;
g_rgRtmHandles[2].hRouteHandle = g_hStaticRoute;
g_rgRtmHandles[2].bStatic = TRUE;
g_rgRtmHandles[3].dwProtoId = PROTO_IP_NT_STATIC_NON_DOD;
g_rgRtmHandles[3].hRouteHandle = g_hNonDodRoute;
g_rgRtmHandles[3].bStatic = TRUE;
g_rgRtmHandles[4].dwProtoId = PROTO_IP_NETMGMT;
g_rgRtmHandles[4].hRouteHandle = g_hNetMgmtRoute;
g_rgRtmHandles[4].bStatic = FALSE;
//
// Initialize MGM
//
mgmConfig.dwLogLevel = g_dwLoggingLevel;
mgmConfig.dwIfTableSize = MGM_IF_TABLE_SIZE;
mgmConfig.dwGrpTableSize = MGM_GROUP_TABLE_SIZE;
mgmConfig.dwSrcTableSize = MGM_SOURCE_TABLE_SIZE;
mgmConfig.pfnAddMfeCallback = SetMfe;
mgmConfig.pfnDeleteMfeCallback = DeleteMfe;
mgmConfig.pfnGetMfeCallback = GetMfe;
mgmConfig.pfnHasBoundaryCallback = RmHasBoundary;
dwResult = MgmInitialize(&mgmConfig,
&mgmCallbacks);
if(dwResult isnot NO_ERROR)
{
Trace1(ERR,
"InitRouter: Error %d initializing MGM\n",
dwResult);
TraceLeave("InitRouter");
return dwResult;
}
//
// Store callbacks into MGM
//
g_pfnMgmMfeDeleted = mgmCallbacks.pfnMfeDeleteIndication;
g_pfnMgmNewPacket = mgmCallbacks.pfnNewPacketIndication;
g_pfnMgmBlockGroups = mgmCallbacks.pfnBlockGroups;
g_pfnMgmUnBlockGroups = mgmCallbacks.pfnUnBlockGroups;
g_pfnMgmWrongIf = mgmCallbacks.pfnWrongIfIndication;
if(OpenIPDriver() isnot NO_ERROR)
{
Trace0(ERR,
"InitRouter: Couldnt open IP driver");
TraceLeave("InitRouter");
return ERROR_OPEN_FAILED;
}
//
// Do the multicast initialization
//
dwResult = OpenMulticastDriver();
if(dwResult isnot NO_ERROR)
{
Trace0(ERR,
"InitRoute: Could not open IP Multicast device");
//
// not an error, just continue;
//
}
else
{
//
// Find if we are in multicast mode
//
dwResult = StartMulticast();
if(dwResult isnot NO_ERROR)
{
Trace0(ERR,
"InitRoute: Could not start multicast");
}
}
if(!RouterRoleLanOnly)
{
if((dwResult = InitializeWanArp()) isnot NO_ERROR)
{
Trace0(ERR,
"InitRouter: Couldnt open WanArp driver");
TraceLeave("InitRouter");
return dwResult;
}
}
SetPriorityInfo(pGlobalInfo);
SetScopeInfo(pGlobalInfo);
if((dwResult = InitializeMibHandler()) isnot NO_ERROR)
{
Trace1(ERR,
"InitRouter: InitializeMibHandler failed, returned %d",
dwResult);
TraceLeave("InitRouter");
return dwResult;
}
//
// Create Worker thread
//
hThread = CreateThread(NULL,
0,
(PVOID) WorkerThread,
pGlobalInfo,
0,
&dwTid) ;
if(hThread is NULL)
{
dwResult = GetLastError () ;
Trace1(ERR,
"InitRouter: CreateThread failed %d",
dwResult);
TraceLeave("InitRouter");
return dwResult ;
}
else
{
CloseHandle(hThread);
}
dwResult = OpenIpIpKey();
if(dwResult isnot NO_ERROR)
{
Trace1(ERR,
"InitRouter: Error %d opening ipinip key",
dwResult);
return ERROR_CAN_NOT_COMPLETE;
}
//
// We load are routing protocols after all our own initialization,
// since we dont know how they will interact with us
//
ENTER_WRITER(ICB_LIST);
ENTER_WRITER(PROTOCOL_CB_LIST);
LoadRoutingProtocols (pGlobalInfo);
EXIT_LOCK(PROTOCOL_CB_LIST);
EXIT_LOCK(ICB_LIST);
TraceLeave("InitRouter");
return NO_ERROR;
}
DWORD
LoadRoutingProtocols(
PRTR_INFO_BLOCK_HEADER pGlobalInfo
)
/*++
Routine Description:
Loads and initializes all the routing protocols configured
Called with ICBListLock and RoutingProcotoclCBListLock held
Arguments
GlobalInfo passed in by DIM
Return Value:
NO_ERROR or some error code
--*/
{
DWORD i, j, dwSize, dwNumProtoEntries, dwResult;
PPROTO_CB pNewProtocolCb;
PWCHAR pwszDllNames ; // array of dll names
MPR_PROTOCOL_0 *pmpProtocolInfo;
PVOID pvInfo;
BOOL bFound;
TraceEnter("LoadRoutingProtocols");
dwResult = MprSetupProtocolEnum(PID_IP,
(PBYTE *)(&pmpProtocolInfo),
&dwNumProtoEntries);
if(dwResult isnot NO_ERROR)
{
Trace1(ERR,
"LoadRoutingProtocols: Error %d loading protocol info from registry",
dwResult);
TraceLeave("LoadRoutingProtocols");
return dwResult;
}
for(i=0; i < pGlobalInfo->TocEntriesCount; i++)
{
ULONG ulStructureVersion, ulStructureSize, ulStructureCount;
DWORD dwType;
//
// Read each TOC and see if it is PROTO_TYPE_UCAST/MCAST
// If it does it is a loadable protocol and we get its info
// from the registry
//
dwType = TYPE_FROM_PROTO_ID(pGlobalInfo->TocEntry[i].InfoType);
if((dwType < PROTO_TYPE_MS1) and
(pGlobalInfo->TocEntry[i].InfoSize > 0))
{
bFound = FALSE;
for(j = 0; j < dwNumProtoEntries; j ++)
{
if(pmpProtocolInfo[j].dwProtocolId is pGlobalInfo->TocEntry[i].InfoType)
{
//
// well great, we have found it
//
bFound = TRUE;
break;
}
}
if(!bFound)
{
Trace1(ERR,
"LoadRoutingProtocols: Couldnt find information for protocol ID %d",
pGlobalInfo->TocEntry[i].InfoType);
continue;
}
//
// load library on the dll name provided
//
dwSize = (wcslen(pmpProtocolInfo[j].wszProtocol) +
wcslen(pmpProtocolInfo[j].wszDLLName) + 2) * sizeof(WCHAR) +
sizeof(PROTO_CB);
pNewProtocolCb = HeapAlloc(IPRouterHeap,
HEAP_ZERO_MEMORY,
dwSize);
if (pNewProtocolCb is NULL)
{
Trace2(ERR,
"LoadRoutingProtocols: Error allocating %d bytes for %S",
dwSize,
pmpProtocolInfo[j].wszProtocol);
continue ;
}
pvInfo = GetInfoFromTocEntry(pGlobalInfo,
&(pGlobalInfo->TocEntry[i]));
//ulStructureVersion = pGlobalInfo->TocEntry[i].InfoVersion;
ulStructureVersion = 0x500;
ulStructureSize = pGlobalInfo->TocEntry[i].InfoSize;
ulStructureCount = pGlobalInfo->TocEntry[i].Count;
dwResult = LoadProtocol(&(pmpProtocolInfo[j]),
pNewProtocolCb,
pvInfo,
ulStructureVersion,
ulStructureSize,
ulStructureCount);
if(dwResult isnot NO_ERROR)
{
Trace2(ERR,
"LoadRoutingProtocols: %S failed to load: %d",
pmpProtocolInfo[j].wszProtocol,
dwResult);
HeapFree (IPRouterHeap, 0, pNewProtocolCb) ;
}
else
{
pNewProtocolCb->posOpState = RTR_STATE_RUNNING ;
//
// Insert this routing protocol in the list of routing
// protocols
//
InsertTailList(&g_leProtoCbList,
&pNewProtocolCb->leList) ;
Trace1(GLOBAL,
"LoadRoutingProtocols: %S successfully initialized",
pmpProtocolInfo[j].wszProtocol) ;
TotalRoutingProtocols++ ;
}
}
}
MprSetupProtocolFree(pmpProtocolInfo);
TraceLeave("LoadRoutingProtocols");
return NO_ERROR ;
}
DWORD
StartDriverAndOpenHandle(
PCHAR pszServiceName,
PWCHAR pwszDriverName,
PHANDLE phDevice
)
/*++
Routine Description:
Creates a handle to the IP NAT service on the local machine
Then tries to start the service. Loops till the service starts.
Can potentially loop forever.
Then creates a handle to the device.
Arguments
None
Return Value:
NO_ERROR or some error code
--*/
{
NTSTATUS status;
UNICODE_STRING nameString;
IO_STATUS_BLOCK ioStatusBlock;
OBJECT_ATTRIBUTES objectAttributes;
SC_HANDLE schSCManager, schService;
DWORD dwErr;
SERVICE_STATUS ssStatus;
BOOL bErr, bRet;
ULONG ulCount;
TraceEnter("StartDriver");
schSCManager = OpenSCManager(NULL,
NULL,
SC_MANAGER_ALL_ACCESS);
if (schSCManager is NULL)
{
dwErr = GetLastError();
Trace2(ERR,
"StartDriver: Error %d opening svc controller for %s",
dwErr,
pszServiceName);
TraceLeave("StartDriver");
return ERROR_OPEN_FAILED;
}
schService = OpenService(schSCManager,
pszServiceName,
SERVICE_ALL_ACCESS);
if(schService is NULL)
{
dwErr = GetLastError();
Trace2(ERR,
"StartDriver: Error %d opening %s",
dwErr,
pszServiceName);
CloseServiceHandle(schSCManager);
TraceLeave("StartDriver");
return ERROR_OPEN_FAILED;
}
__try
{
bRet = FALSE;
bErr = QueryServiceStatus(schService,
&ssStatus);
if(!bErr)
{
dwErr = GetLastError();
Trace2(ERR,
"StartDriver: Error %d querying %s status to see if it is already running",
dwErr,
pszServiceName);
__leave;
}
//
// If the driver is running, we shut it down. This forces a
// cleanup of all its internal data structures.
//
if(ssStatus.dwCurrentState isnot SERVICE_STOPPED)
{
if(!ControlService(schService,
SERVICE_CONTROL_STOP,
&ssStatus))
{
dwErr = GetLastError();
Trace2(ERR,
"StartDriver: %s was running at init time. Attempts to stop it caused error %d",
pszServiceName,
dwErr);
}
else
{
Sleep(1000);
//
// Now loop for 10 seconds waiting for the service to stop
//
ulCount = 0;
while(ulCount < 5)
{
bErr = QueryServiceStatus(schService,
&ssStatus);
if(!bErr)
{
dwErr = GetLastError();
break;
}
else
{
if (ssStatus.dwCurrentState is SERVICE_STOPPED)
{
break;
}
else
{
ulCount++;
Sleep(2000);
}
}
}
if(ssStatus.dwCurrentState isnot SERVICE_STOPPED)
{
if(ulCount is 5)
{
dwErr = ERROR_SERVICE_REQUEST_TIMEOUT;
}
Trace2(ERR,
"StartDriver: Error %d stopping %s which was running at init time",
dwErr,
pszServiceName);
__leave;
}
}
}
//
// Query the service status one more time to see
// if it is now stopped (because it was never running
// or because it was started and we managed to stop
// it successfully
//
bErr = QueryServiceStatus(schService,
&ssStatus);
if(!bErr)
{
dwErr = GetLastError();
Trace2(ERR,
"StartDriver: Error %d querying %s status to see if it is stopped",
dwErr,
pszServiceName);
__leave;
}
if(ssStatus.dwCurrentState is SERVICE_STOPPED)
{
//
// Ok so at this time the service is stopped, lets start the
// service
//
if(!StartService(schService, 0, NULL))
{
dwErr = GetLastError();
Trace2(ERR,
"StartDriver: Error %d starting %s",
dwErr,
pszServiceName);
__leave;
}
//
// Sleep for 1 second to avoid loop
//
Sleep(1000);
ulCount = 0;
//
// We will wait for 30 seconds for the driver to start
//
while(ulCount < 6)
{
bErr = QueryServiceStatus(schService,
&ssStatus);
if(!bErr)
{
dwErr = GetLastError();
break;
}
else
{
if (ssStatus.dwCurrentState is SERVICE_RUNNING)
{
break;
}
else
{
ulCount++;
Sleep(5000);
}
}
}
if(ssStatus.dwCurrentState isnot SERVICE_RUNNING)
{
if(ulCount is 6)
{
dwErr = ERROR_SERVICE_REQUEST_TIMEOUT;
}
Trace2(ERR,
"StartDriver: Error %d starting %s",
dwErr,
pszServiceName);
__leave;
}
}
//
// Now the service is definitely up and running
//
RtlInitUnicodeString(&nameString,
pwszDriverName);
InitializeObjectAttributes(&objectAttributes,
&nameString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
status = NtCreateFile(phDevice,
SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
&objectAttributes,
&ioStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN_IF,
0,
NULL,
0);
if(!NT_SUCCESS(status))
{
Trace2(ERR,
"StartDriver: NtStatus %x creating handle to %S",
status,
pwszDriverName);
__leave;
}
bRet = TRUE;
}
__finally
{
CloseServiceHandle(schSCManager);
CloseServiceHandle(schService);
TraceLeave("StartDriver");
}
if(!bRet) {
return ERROR_OPEN_FAILED;
} else {
return NO_ERROR;
}
}
DWORD
OpenIPDriver(
VOID
)
/*++
Routine Description:
Opens a handle to the IP Driver
Arguments
None
Return Value:
NO_ERROR or some error code
--*/
{
NTSTATUS status;
UNICODE_STRING nameString;
IO_STATUS_BLOCK ioStatusBlock;
OBJECT_ATTRIBUTES objectAttributes;
DWORD dwResult = NO_ERROR;
TraceEnter("OpenIPDriver");
do
{
RtlInitUnicodeString(&nameString, DD_IP_DEVICE_NAME);
InitializeObjectAttributes(&objectAttributes, &nameString,
OBJ_CASE_INSENSITIVE, NULL, NULL);
status = NtCreateFile(&g_hIpDevice,
SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
&objectAttributes,
&ioStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN_IF,
0,
NULL,
0);
if(!NT_SUCCESS(status))
{
Trace1(ERR,
"OpenIPDriver: Couldnt create IP driver handle. NtStatus %x",
status);
dwResult = ERROR_OPEN_FAILED;
break;
}
//
// Open change notification handle to TCPIP stack
//
ZeroMemory(&ioStatusBlock, sizeof(IO_STATUS_BLOCK));
#if 1
status = NtCreateFile(
&g_hIpRouteChangeDevice,
GENERIC_EXECUTE,
&objectAttributes,
&ioStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN_IF,
0,
NULL,
0
);
#else
g_hIpRouteChangeDevice = CreateFile(
TEXT("\\\\.\\Ip"),
GENERIC_EXECUTE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL |
FILE_ATTRIBUTE_OVERLAPPED,
NULL
);
if (g_hIpRouteChangeDevice is NULL)
#endif
if (!NT_SUCCESS(status))
{
Trace1(
ERR,
"OpenIPDriver: Couldnt create change notificatio handle."
"NtStatus %x",
status
);
dwResult = ERROR_OPEN_FAILED;
CloseHandle( g_hIpDevice );
g_hIpDevice = NULL;
}
g_IpNotifyData.Version = IPNotifySynchronization;
g_IpNotifyData.Add = 0;
} while( FALSE );
TraceLeave("OpenIPDriver");
return dwResult;
}
DWORD
OpenMulticastDriver(
VOID
)
{
NTSTATUS status;
UNICODE_STRING nameString;
IO_STATUS_BLOCK ioStatusBlock;
OBJECT_ATTRIBUTES objectAttributes;
DWORD i;
TraceEnter("OpenMulticastDriver");
RtlInitUnicodeString(&nameString,
DD_IPMCAST_DEVICE_NAME);
InitializeObjectAttributes(&objectAttributes,
&nameString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
status = NtCreateFile(&g_hMcastDevice,
SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
&objectAttributes,
&ioStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN_IF,
0,
NULL,
0);
if(status isnot STATUS_SUCCESS)
{
Trace2(MCAST,
"OpenMulticastDriver: Device Name %S could not be opened -> error code %d\n",
DD_IPMCAST_DEVICE_NAME,
status);
g_hMcastDevice = NULL;
return ERROR_OPEN_FAILED;
}
TraceLeave("OpenMulticastDriver");
return NO_ERROR;
}
DWORD
EnableNetbtBcastForwarding(
DWORD dwEnable
)
/*++
Routine description:
Sets the NETBT proxy mode to enable NETBT broadcast forwarding.
This enables RAS clients to resolve names (and consequently)
access resources on the networks (LANs) connected to the RAS
server without having WINS/DNS configured.
Arguements :
Return Value :
NO_ERROR
--*/
{
HKEY hkWanarpAdapter = NULL, hkNetbtParameters = NULL,
hkNetbtInterface = NULL;
DWORD dwSize = 0, dwResult, dwType = 0, dwMode = 0, dwFlags;
PBYTE pbBuffer = NULL;
PWCHAR pwcGuid;
WCHAR wszNetbtInterface[256] = L"\0";
TraceEnter("EnableNetbtBcastForwarding");
do
{
//
// Step I
// Query appropriate WANARP regsitry keys to find GUID
// corresponding to Internal (RAS server adapter)
//
dwResult = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Adapters\\NdisWanIP",
0,
KEY_READ,
&hkWanarpAdapter
);
if (dwResult isnot NO_ERROR)
{
Trace1(
ERR,
"EnableNetbtBcastForwarding : error %d opening"
"NdisWanIP key\n",
dwResult
);
break;
}
//
// query size of buffer required.
//
dwResult = RegQueryValueExW(
hkWanarpAdapter,
L"IpConfig",
NULL,
&dwType,
(PBYTE)NULL,
&dwSize
);
if (dwResult isnot NO_ERROR)
{
Trace1(
ERR,
"EnableNetbtBcastForwarding : error %d querying"
"IPConfig value\n",
dwResult
);
break;
}
//
// Allocate buffer for value
//
pbBuffer = (PBYTE) HeapAlloc(
GetProcessHeap(),
0,
dwSize
);
if ( pbBuffer == NULL )
{
dwResult = GetLastError();
Trace2(
ERR,
"EnableNetbtBcastForwarding : error %d allocating buffer of"
"size %d for IPConfig value",
dwResult, dwSize
);
break;
}
//
// query registry value of IPConfig
//
dwResult = RegQueryValueExW(
hkWanarpAdapter,
L"IpConfig",
NULL,
&dwType,
(PBYTE)pbBuffer,
&dwSize
);
if ( (dwResult isnot NO_ERROR) || (dwType != REG_MULTI_SZ) )
{
Trace1(
ERR,
"EnableNetbtBcastForwarding : error %d querying"
"IPConfig value\n",
dwResult
);
break;
}
//
// Extract the GUID of the Internal (RAS Server) adapter
//
pwcGuid = wcschr( (PWCHAR)pbBuffer, '{' );
Trace1(
INIT, "Internal adapter GUID is %lS",
pwcGuid
);
//
// Step II
//
// Save the old setting for NETBT PROXY mode. This will be restored
// when the RRAS server is stopped. and set the new PROXY mode
//
//
// open NETBT Key
//
dwResult = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Services\\Netbt\\Parameters",
0,
KEY_READ | KEY_WRITE,
&hkNetbtParameters
);
if (dwResult isnot NO_ERROR)
{
Trace1(
ERR,
"EnableNetbtBcastForwarding : error %d opening"
"Netbt\\Parameters key\n",
dwResult
);
break;
}
//
// query EnableProxy mode
//
dwSize = sizeof( DWORD );
dwMode = 0;
dwResult = RegQueryValueExW(
hkNetbtParameters,
L"EnableProxy",
NULL,
&dwType,
(PBYTE)&dwMode,
&dwSize
);
if (dwResult isnot NO_ERROR)
{
//
// It is possible the key is not present esp. if this
// is the first time you are running RRAS or if the
// key has been manually deleted
// In this case assume proxy is set to 0 (disabled)
//
g_dwOldNetbtProxyMode = 0;
}
else
{
g_dwOldNetbtProxyMode = dwMode;
}
Trace1(
INIT,
"Netbt Proxy mode in registry is %d",
dwMode
);
//
// Set the NETBT proxy mode to enable/disable broadcast forwarding
//
//
// if NETBT broadcast fwdg is disabled, make sure
// the the EnableProxy setting matches that
//
if ( dwEnable == 0 )
{
//
// Netbt broadcast fwd'g is disabled
//
if ( dwMode == 2 )
{
//
// But the registry setting does not reflect this
//
g_dwOldNetbtProxyMode = 0;
dwMode = 0;
Trace1(
INIT,
"Forcing Netbt Proxy mode to be %d",
g_dwOldNetbtProxyMode
);
}
}
else
{
//
// Note: Need a #define value for netbt proxy mode
//
dwMode = 2;
}
Trace2(
INIT,
"Old Netbt Proxy mode is %d, New Nebt Proxy Mode is %d",
g_dwOldNetbtProxyMode, dwMode
);
dwResult = RegSetValueExW(
hkNetbtParameters,
L"EnableProxy",
0,
REG_DWORD,
(PBYTE) &dwMode,
dwSize
);
if ( dwResult != NO_ERROR )
{
Trace1(
ERR,
"EnableNetbtBcastForwarding : error %d setting"
"EnableProxy value\n",
dwResult
);
break;
}
//
// Step III:
//
// Check for RASFlags under NETBT_TCPIP_{RAS_SERVER_GUID} key
//
//
// Open interface key under NETBT
//
wcscpy(
wszNetbtInterface,
L"System\\CurrentControlSet\\Services\\Netbt\\Parameters\\Interfaces\\Tcpip_"
);
wcscat(
wszNetbtInterface,
pwcGuid
);
dwResult = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
wszNetbtInterface,
0,
KEY_READ | KEY_WRITE,
&hkNetbtInterface
);
if (dwResult isnot NO_ERROR)
{
Trace2(
ERR,
"EnableNetbtBcastForwarding : error %d opening"
"%ls key\n",
dwResult, wszNetbtInterface
);
break;
}
//
// query RASFlags value
//
// If present
// leave as is.
// else
// create and set it to 0x00000001 to disable NETBT
// broadcasts on WAN.
//
dwFlags = 0;
dwResult = RegQueryValueExW(
hkNetbtInterface,
L"RASFlags",
NULL,
&dwType,
(PBYTE)&dwFlags,
&dwSize
);
if (dwResult isnot NO_ERROR)
{
//
// It is possible the key is not present esp. if this
// is the first time you are running RRAS or if the
// key has been manually deleted
// In this case set RASFlags to 1 (default behavior).
//
dwFlags = 1;
dwResult = RegSetValueExW(
hkNetbtInterface,
L"RASFlags",
0,
REG_DWORD,
(PBYTE) &dwFlags,
sizeof( DWORD )
);
if ( dwResult != NO_ERROR )
{
Trace1(
ERR,
"error %d setting RASFlags",
dwResult
);
}
}
else
{
//
// RASFlags value is already present. leave it as is.
//
Trace1(
INIT,
"RASFlags already present with value %d",
dwFlags
);
}
//
// Close NETBT keys. Doing so to avoid any contention issues
// with the NETBT.SYS driver trying to read them in the following
// function
//
RegCloseKey( hkNetbtParameters );
hkNetbtParameters = NULL;
RegCloseKey( hkNetbtInterface );
hkNetbtInterface = NULL;
dwResult = ForceNetbtRegistryRead();
} while (FALSE);
if ( hkWanarpAdapter )
{
RegCloseKey( hkWanarpAdapter );
}
if ( hkNetbtParameters )
{
RegCloseKey( hkNetbtParameters );
}
if ( hkNetbtInterface )
{
RegCloseKey( hkNetbtInterface );
}
if ( pbBuffer )
{
HeapFree( GetProcessHeap(), 0, pbBuffer );
}
TraceLeave("EnableNetbtBcastForwarding");
return dwResult;
}
DWORD
RestoreNetbtBcastForwardingMode(
VOID
)
/*++
Routine description:
Return the NETBT proxy mode setting to its original setting
Arguements :
Return Value :
--*/
{
DWORD dwResult, dwSize = 0;
HKEY hkNetbtParameters = NULL;
TraceEnter("RestoreNetbtBcastForwardingMode");
do
{
//
// open NETBT Key
//
dwResult = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Services\\Netbt\\Parameters",
0,
KEY_READ | KEY_WRITE,
&hkNetbtParameters
);
if (dwResult isnot NO_ERROR)
{
Trace1(
ERR,
"EnableNetbtBcastForwarding : error %d opening"
"Netbt\\Parameters key\n",
dwResult
);
break;
}
//
// restore EnableProxy mode
//
dwSize = sizeof( DWORD );
dwResult = RegSetValueExW(
hkNetbtParameters,
L"EnableProxy",
0,
REG_DWORD,
(PBYTE) &g_dwOldNetbtProxyMode,
dwSize
);
if ( dwResult != NO_ERROR )
{
Trace1(
ERR,
"EnableNetbtBcastForwarding : error %d setting"
"EnableProxy value\n",
dwResult
);
break;
}
dwResult = ForceNetbtRegistryRead();
} while (FALSE);
TraceLeave("RestoreNetbtBcastForwardingMode");
return dwResult;
}
DWORD
ForceNetbtRegistryRead(
VOID
)
/*++
Routine description:
Issue IOCTL to NETBT to re-read its registry setting.
Arguements :
Return Value :
--*/
{
DWORD dwErr = NO_ERROR;
NTSTATUS status;
UNICODE_STRING nameString;
IO_STATUS_BLOCK ioStatusBlock;
OBJECT_ATTRIBUTES objectAttributes;
HANDLE hNetbtDevice = NULL;
TraceEnter("ForceNetbtRegistryRead");
do
{
//
// Step I:
//
// Open NETBT driver
//
RtlInitUnicodeString(
&nameString,
L"\\Device\\NetbiosSmb"
);
InitializeObjectAttributes(
&objectAttributes,
&nameString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
status = NtCreateFile(
&hNetbtDevice,
SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
&objectAttributes,
&ioStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN_IF,
0,
NULL,
0
);
if (!NT_SUCCESS(status))
{
Trace1(
ERR,
"ForceNetbtRegistryRead: Couldnt create NETBT driver handle. NtStatus %x",
status
);
dwErr = ERROR_OPEN_FAILED;
break;
}
//
// Issue IOCTL to re-read registry
//
status = NtDeviceIoControlFile(
hNetbtDevice,
NULL,
NULL,
NULL,
&ioStatusBlock,
IOCTL_NETBT_REREAD_REGISTRY,
NULL,
0,
NULL,
0
);
if (!NT_SUCCESS(status))
{
Trace1(
ERR,
"ForceNetbtRegistryRead: Failed IOCTL call to NETBT, status %x",
status
);
dwErr = ERROR_UNKNOWN;
break;
}
} while ( FALSE );
//
// Close NETBT driver
//
CloseHandle( hNetbtDevice );
TraceLeave("ForceNetbtRegistryRead");
return dwErr;
}
DWORD
InitializeMibHandler(
VOID
)
/*++
Routine Description:
Initalizes the heaps and Locks needed by the MIB handling code
Arguments:
None
Return Value:
NO_ERROR or some error code
--*/
{
DWORD i,dwResult, dwIpIfSize, dwMibSize;
BOOL fUpdate;
TraceEnter("InitializeMibHandler");
//
// Assert the size of MIB to stack mappings for which direct copy is
// being done
//
dwIpIfSize = IFE_FIXED_SIZE + MAX_IFDESCR_LEN;
dwMibSize = sizeof(MIB_IFROW) - FIELD_OFFSET(MIB_IFROW, dwIndex);
IpRtAssert(dwIpIfSize is dwMibSize);
IpRtAssert(sizeof(MIB_ICMP) is sizeof(ICMPSNMPInfo));
IpRtAssert(sizeof(MIB_UDPSTATS) is sizeof(UDPStats));
IpRtAssert(sizeof(MIB_UDPROW) is sizeof(UDPEntry));
IpRtAssert(sizeof(MIB_TCPSTATS) is sizeof(TCPStats));
IpRtAssert(sizeof(MIB_TCPROW) is sizeof(TCPConnTableEntry));
IpRtAssert(sizeof(MIB_IPSTATS) is sizeof(IPSNMPInfo));
IpRtAssert(sizeof(MIB_IPADDRROW) is sizeof(IPAddrEntry));
IpRtAssert(sizeof(MIB_IPNETROW) is sizeof(IPNetToMediaEntry));
g_dwStartTime = GetCurrentTime();
__try
{
//
// We dont initialize the locks since we do it in one shot at the
// beginning of StartRouter
//
//
// Now Create the heaps. Since only writers Alloc from the heap we
// are already guaranteed serialization, so lets not ask for it again
// Let all initial size be 1K, this doesnt really cost any thing
// since the memory is not committed
// We will just allocate a minimum size for the cache tables so
// that the startup doesnt barf
//
#define INIT_TABLE_SIZE 10
g_hIfHeap = HeapCreate(HEAP_NO_SERIALIZE,1000,0);
if(g_hIfHeap is NULL)
{
dwResult = GetLastError();
Trace1(ERR,
"InitializeMibHandler: Couldnt allocate IF Heap. Error %d",
dwResult);
__leave;
}
g_hUdpHeap = HeapCreate(HEAP_NO_SERIALIZE,1000,0);
if(g_hUdpHeap is NULL)
{
dwResult = GetLastError();
Trace1(ERR,
"InitializeMibHandler: Couldnt allocate UDP Heap. Error %d",
dwResult);
__leave;
}
g_UdpInfo.pUdpTable = HeapAlloc(g_hUdpHeap,
HEAP_NO_SERIALIZE,
SIZEOF_UDPTABLE(INIT_TABLE_SIZE));
if(g_UdpInfo.pUdpTable is NULL)
{
dwResult = ERROR_NOT_ENOUGH_MEMORY;
Trace0(ERR,
"InitializeMibHandler: Couldnt allocate UDP table");
__leave;
}
g_UdpInfo.dwTotalEntries = INIT_TABLE_SIZE;
g_hTcpHeap = HeapCreate(HEAP_NO_SERIALIZE,1000,0);
if(g_hTcpHeap is NULL)
{
dwResult = GetLastError();
Trace1(ERR,
"InitializeMibHandler: Couldnt allocate TCP Heap. Error %d",
dwResult);
__leave;
}
g_TcpInfo.pTcpTable = HeapAlloc(g_hTcpHeap,
HEAP_NO_SERIALIZE,
SIZEOF_TCPTABLE(INIT_TABLE_SIZE));
if(g_TcpInfo.pTcpTable is NULL)
{
dwResult = ERROR_NOT_ENOUGH_MEMORY;
Trace0(ERR,
"InitializeMibHandler: Couldnt allocate TCP table");
__leave;
}
g_TcpInfo.dwTotalEntries = INIT_TABLE_SIZE;
g_hIpAddrHeap = HeapCreate(HEAP_NO_SERIALIZE,1000,0);
if(g_hIpAddrHeap is NULL)
{
dwResult = GetLastError();
Trace1(ERR,
"InitializeMibHandler: Couldnt allocate IP Addr Heap. Error %d",
dwResult);
__leave;
}
g_IpInfo.pAddrTable = HeapAlloc(g_hIpAddrHeap,
HEAP_NO_SERIALIZE,
SIZEOF_IPADDRTABLE(INIT_TABLE_SIZE));
if(g_IpInfo.pAddrTable is NULL)
{
dwResult = ERROR_NOT_ENOUGH_MEMORY;
Trace0(ERR,
"InitializeMibHandler: Couldnt allocate IP Addr table.");
__leave;
}
g_IpInfo.dwTotalAddrEntries = INIT_TABLE_SIZE;
g_hIpForwardHeap = HeapCreate(HEAP_NO_SERIALIZE,1000,0);
if(g_hIpForwardHeap is NULL)
{
dwResult = GetLastError();
Trace1(ERR,
"InitializeMibHandler: Couldnt allocate IP Forward Heap. Error %d",
dwResult);
__leave;
}
g_IpInfo.pForwardTable = HeapAlloc(g_hIpForwardHeap,
HEAP_NO_SERIALIZE,
SIZEOF_IPFORWARDTABLE(INIT_TABLE_SIZE));
if(g_IpInfo.pForwardTable is NULL)
{
dwResult = ERROR_NOT_ENOUGH_MEMORY;
Trace0(ERR,
"InitializeMibHandler: Couldnt allocate IP Forward table");
__leave;
}
g_IpInfo.dwTotalForwardEntries = INIT_TABLE_SIZE;
g_hIpNetHeap = HeapCreate(HEAP_NO_SERIALIZE,1000,0);
if(g_hIpNetHeap is NULL)
{
dwResult = GetLastError();
Trace1(ERR,
"InitializeMibHandler: Couldnt allocate IP Net Heap. Error %d",
dwResult);
__leave;
}
g_IpInfo.pNetTable = HeapAlloc(g_hIpNetHeap,
HEAP_NO_SERIALIZE,
SIZEOF_IPNETTABLE(INIT_TABLE_SIZE));
if(g_IpInfo.pNetTable is NULL)
{
dwResult = ERROR_NOT_ENOUGH_MEMORY;
Trace0(ERR,
"InitializeMibHandler: Couldnt allocate IP Net table");
__leave;
}
g_IpInfo.dwTotalNetEntries = INIT_TABLE_SIZE;
//
// Now set up the caches
//
for(i = 0; i < NUM_CACHE; i++)
{
g_LastUpdateTable[i] = 0;
if(UpdateCache(i,&fUpdate) isnot NO_ERROR)
{
Trace1(ERR,
"InitializeMibHandler: Couldnt update %s Cache",
CacheToA(i));
//__leave;
}
}
dwResult = NO_ERROR;
}
__finally
{
TraceLeave("InitializeMibHandler");
}
return dwResult;
}