windows-nt/Source/XPSP1/NT/net/tcpip/snmp/init.c
2020-09-26 16:20:57 +08:00

512 lines
11 KiB
C

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
Abstract:
Author:
Revision History:
--*/
#include "allinc.h"
//
// Definitions for external declarations
//
DWORD g_uptimeReference;
#ifdef MIB_DEBUG
DWORD g_hTrace=INVALID_TRACEID;
#endif
HANDLE g_hPollTimer;
RTL_RESOURCE g_LockTable[NUM_LOCKS];
#ifdef DEADLOCK_DEBUG
PBYTE g_pszLockNames[NUM_LOCKS] = {"System Group Lock",
"IF Lock",
"IP Address Lock",
"Forwarding Lock",
"ARP Lock",
"TCP Lock",
"UDP Lock",
"New TCP Lock",
"UDP6 Listener Lock",
"Trap Table Lock"};
#endif // DEADLOCK_DEBUG
DWORD g_dwLastUpdateTable[NUM_CACHE] = { 0,
0,
0,
0,
0,
0,
0,
0,
0};
DWORD g_dwTimeoutTable[NUM_CACHE] = {SYSTEM_CACHE_TIMEOUT,
IF_CACHE_TIMEOUT,
IP_ADDR_CACHE_TIMEOUT,
IP_FORWARD_CACHE_TIMEOUT,
IP_NET_CACHE_TIMEOUT,
TCP_CACHE_TIMEOUT,
UDP_CACHE_TIMEOUT,
TCP_CACHE_TIMEOUT,
UDP_CACHE_TIMEOUT};
PFNLOAD_FUNCTION g_pfnLoadFunctionTable[] = { LoadSystem,
LoadIfTable,
LoadIpAddrTable,
LoadIpForwardTable,
LoadIpNetTable,
LoadTcpTable,
LoadUdpTable,
LoadTcp6Table,
LoadUdp6ListenerTable};
MIB_CACHE g_Cache = { NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL};
HANDLE g_hPrivateHeap;
SnmpTfxHandle g_tfxHandle;
UINT g_viewIndex = 0;
PMIB_IFSTATUS g_pisStatusTable;
DWORD g_dwValidStatusEntries;
DWORD g_dwTotalStatusEntries;
BOOL g_bFirstTime;
BOOL
Mib2DLLEntry(
HANDLE hInst,
DWORD ul_reason_being_called,
LPVOID lpReserved
)
{
DWORD i;
switch (ul_reason_being_called)
{
case DLL_PROCESS_ATTACH:
{
DisableThreadLibraryCalls(hInst);
g_pisStatusTable = NULL;
g_dwValidStatusEntries = 0;
g_dwTotalStatusEntries = 0;
g_hPollTimer = NULL;
g_bFirstTime = TRUE;
//
// Create the private heap. If it fails, deregister the trace
// handle
//
g_hPrivateHeap = HeapCreate(0,
4*1024,
0);
if(g_hPrivateHeap is NULL)
{
//
// Deregister the trace handle
//
#ifdef MIB_DEBUG
if(g_hTrace isnot INVALID_TRACEID)
{
TraceDeregister(g_hTrace);
g_hTrace = INVALID_TRACEID;
}
#endif
return FALSE;
}
for(i = 0; i < NUM_LOCKS; i++)
{
RtlInitializeResource(&g_LockTable[i]);
}
break ;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
{
//
// not of interest.
//
break;
}
case DLL_PROCESS_DETACH:
{
#ifdef MIB_DEBUG
if(g_hTrace isnot INVALID_TRACEID)
{
TraceDeregister(g_hTrace);
g_hTrace = INVALID_TRACEID;
}
#endif
if(g_hPrivateHeap)
{
HeapDestroy(g_hPrivateHeap);
}
if(g_hPollTimer isnot NULL)
{
//
// We had created an timer object
//
CloseHandle(g_hPollTimer);
g_hPollTimer = NULL;
}
for(i = 0; i < NUM_LOCKS; i++)
{
RtlDeleteResource(&g_LockTable[i]);
}
break;
}
}
return TRUE;
}
DWORD
GetPollTime(
VOID
)
/*++
Routine Description
This function
Locks
None
Arguments
None
Return Value
None
--*/
{
DWORD dwResult, dwSize, dwValue, dwDisposition, dwType;
HKEY hkeyPara;
WCHAR wszPollValue[256];
dwResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
REG_KEY_MIB2SUBAGENT_PARAMETERS,
0,
NULL,
0,
KEY_ALL_ACCESS,
NULL,
&hkeyPara,
&dwDisposition);
if(dwResult isnot NO_ERROR)
{
//
// Couldnt open/create key just return default value
//
return DEFAULT_POLL_TIME;
}
//
// Try and read the Poll time. If the value doesnt exist, write
// the default in
//
dwSize = sizeof(DWORD);
dwResult = RegQueryValueExW(hkeyPara,
REG_VALUE_POLL,
0,
&dwType,
(LPBYTE)(&dwValue),
&dwSize);
if((dwResult isnot NO_ERROR) or
(dwType isnot REG_DWORD) or
(dwValue < MIN_POLL_TIME))
{
//
// Registry seems to be corrupt, or key doesnt exist or
// The value is less than the minimum. Lets set things
// right
//
dwValue = DEFAULT_POLL_TIME;
wcscpy(wszPollValue,
REG_VALUE_POLL);
dwResult = RegSetValueExW(hkeyPara,
REG_VALUE_POLL,
0,
REG_DWORD,
(CONST BYTE *)(&dwValue),
sizeof(DWORD));
if(dwResult isnot NO_ERROR)
{
TRACE1("Error %d setting poll time in registry",
dwResult);
}
}
//
// At this point dwValue is a good one read out of the registry
// or is DEFAULT_POLL_TIME
//
return dwValue;
}
BOOL
SnmpExtensionInit(
IN DWORD uptimeReference,
OUT HANDLE *lpPollForTrapEvent,
OUT AsnObjectIdentifier *lpFirstSupportedView
)
{
DWORD dwResult, dwPollTime;
LARGE_INTEGER liRelTime;
//
// save the uptime reference
//
g_uptimeReference = uptimeReference;
#ifdef MIB_DEBUG
if (g_hTrace == INVALID_TRACEID)
g_hTrace = TraceRegister("MIB-II Subagent");
#endif
//
// obtain handle to subagent framework
//
g_tfxHandle = SnmpTfxOpen(NUM_VIEWS,v_mib2);
//
// validate handle
//
if (g_tfxHandle is NULL)
{
TRACE1("Error %d opening framework",
GetLastError());
//
// destroy private heap
//
HeapDestroy(g_hPrivateHeap);
//
// reinitialize
//
g_hPrivateHeap = NULL;
return FALSE;
}
//
// pass back first view identifier to master
//
g_viewIndex = 0; // make sure this is reset...
*lpFirstSupportedView = v_mib2[g_viewIndex++].viewOid;
//
// Update the IF cache. This is needed for the first poll
//
UpdateCache(MIB_II_IF);
//
// Trap is done by a polling timer
//
if(g_hPollTimer is NULL)
{
//
// Do this ONLY if we had notcreated the timer from an earlier
// initialization call
//
g_hPollTimer = CreateWaitableTimer(NULL,
FALSE,
NULL); // No name because many DLLs may load this
if(g_hPollTimer is NULL)
{
TRACE1("Error %d creating poll timer for traps",
GetLastError());
}
else
{
//
// Read poll time from the registry. If the keys dont exist this
// function will set up the keys and return the default value
//
dwPollTime = GetPollTime();
liRelTime = RtlLargeIntegerNegate(MilliSecsToSysUnits(dwPollTime));
if(!SetWaitableTimer(g_hPollTimer,
&liRelTime,
dwPollTime,
NULL,
NULL,
FALSE))
{
TRACE1("Error %d setting timer",
GetLastError());
CloseHandle(g_hPollTimer);
g_hPollTimer = NULL;
}
}
}
*lpPollForTrapEvent = g_hPollTimer;
return TRUE;
}
BOOL
SnmpExtensionInitEx(
OUT AsnObjectIdentifier *lpNextSupportedView
)
{
#ifdef MIB_DEBUG
if (g_hTrace == INVALID_TRACEID)
g_hTrace = TraceRegister("MIB-II Subagent");
#endif
//
// check if there are views to register
//
BOOL fMoreViews = (g_viewIndex < NUM_VIEWS);
if (fMoreViews)
{
//
// pass back next supported view to master
//
*lpNextSupportedView = v_mib2[g_viewIndex++].viewOid;
}
//
// report status
//
return fMoreViews;
}
BOOL
SnmpExtensionQuery(
IN BYTE requestType,
IN OUT RFC1157VarBindList *variableBindings,
OUT AsnInteger *errorStatus,
OUT AsnInteger *errorIndex
)
{
//
// forward to framework
//
return SnmpTfxQuery(g_tfxHandle,
requestType,
variableBindings,
errorStatus,
errorIndex);
}
BOOL
SnmpExtensionTrap(
OUT AsnObjectIdentifier *enterprise,
OUT AsnInteger *genericTrap,
OUT AsnInteger *specificTrap,
OUT AsnTimeticks *timeStamp,
OUT RFC1157VarBindList *variableBindings
)
{
DWORD dwResult;
enterprise->idLength = 0;
enterprise->ids = NULL; // use default enterprise oid
*timeStamp = (GetCurrentTime()/10) - g_uptimeReference;
return MibTrap(genericTrap,
specificTrap,
variableBindings);
}