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.
520 lines
12 KiB
520 lines
12 KiB
/*++
|
|
|
|
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",
|
|
"IPv6 IF Lock",
|
|
"IPv6 Neighbor Lock",
|
|
"IPv6 Route Lock",
|
|
"ICMP 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,
|
|
IPV6_IF_CACHE_TIMEOUT,
|
|
IPV6_NEIGHBOR_CACHE_TIMEOUT,
|
|
IPV6_ROUTE_TABLE_TIMEOUT,
|
|
ICMP_CACHE_TIMEOUT};
|
|
|
|
PFNLOAD_FUNCTION g_pfnLoadFunctionTable[] = { LoadSystem,
|
|
LoadIfTable,
|
|
LoadIpAddrTable,
|
|
LoadIpForwardTable,
|
|
LoadIpNetTable,
|
|
LoadTcpTable,
|
|
LoadUdpTable,
|
|
LoadTcp6Table,
|
|
LoadUdp6ListenerTable,
|
|
LoadIpv6IfTable,
|
|
LoadIpv6NetToMediaTable,
|
|
LoadIpv6RouteTable,
|
|
LoadInetIcmpTable};
|
|
|
|
//
|
|
// Implicitly zero all cache fields. We only explicitly zero one.
|
|
//
|
|
MIB_CACHE g_Cache = {0};
|
|
|
|
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);
|
|
|
|
}
|