Leaked source code of windows server 2003
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

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