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.

511 lines
11 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. Author:
  6. Revision History:
  7. --*/
  8. #include "allinc.h"
  9. //
  10. // Definitions for external declarations
  11. //
  12. DWORD g_uptimeReference;
  13. #ifdef MIB_DEBUG
  14. DWORD g_hTrace=INVALID_TRACEID;
  15. #endif
  16. HANDLE g_hPollTimer;
  17. RTL_RESOURCE g_LockTable[NUM_LOCKS];
  18. #ifdef DEADLOCK_DEBUG
  19. PBYTE g_pszLockNames[NUM_LOCKS] = {"System Group Lock",
  20. "IF Lock",
  21. "IP Address Lock",
  22. "Forwarding Lock",
  23. "ARP Lock",
  24. "TCP Lock",
  25. "UDP Lock",
  26. "New TCP Lock",
  27. "UDP6 Listener Lock",
  28. "Trap Table Lock"};
  29. #endif // DEADLOCK_DEBUG
  30. DWORD g_dwLastUpdateTable[NUM_CACHE] = { 0,
  31. 0,
  32. 0,
  33. 0,
  34. 0,
  35. 0,
  36. 0,
  37. 0,
  38. 0};
  39. DWORD g_dwTimeoutTable[NUM_CACHE] = {SYSTEM_CACHE_TIMEOUT,
  40. IF_CACHE_TIMEOUT,
  41. IP_ADDR_CACHE_TIMEOUT,
  42. IP_FORWARD_CACHE_TIMEOUT,
  43. IP_NET_CACHE_TIMEOUT,
  44. TCP_CACHE_TIMEOUT,
  45. UDP_CACHE_TIMEOUT,
  46. TCP_CACHE_TIMEOUT,
  47. UDP_CACHE_TIMEOUT};
  48. PFNLOAD_FUNCTION g_pfnLoadFunctionTable[] = { LoadSystem,
  49. LoadIfTable,
  50. LoadIpAddrTable,
  51. LoadIpForwardTable,
  52. LoadIpNetTable,
  53. LoadTcpTable,
  54. LoadUdpTable,
  55. LoadTcp6Table,
  56. LoadUdp6ListenerTable};
  57. MIB_CACHE g_Cache = { NULL,
  58. NULL,
  59. NULL,
  60. NULL,
  61. NULL,
  62. NULL,
  63. NULL};
  64. HANDLE g_hPrivateHeap;
  65. SnmpTfxHandle g_tfxHandle;
  66. UINT g_viewIndex = 0;
  67. PMIB_IFSTATUS g_pisStatusTable;
  68. DWORD g_dwValidStatusEntries;
  69. DWORD g_dwTotalStatusEntries;
  70. BOOL g_bFirstTime;
  71. BOOL
  72. Mib2DLLEntry(
  73. HANDLE hInst,
  74. DWORD ul_reason_being_called,
  75. LPVOID lpReserved
  76. )
  77. {
  78. DWORD i;
  79. switch (ul_reason_being_called)
  80. {
  81. case DLL_PROCESS_ATTACH:
  82. {
  83. DisableThreadLibraryCalls(hInst);
  84. g_pisStatusTable = NULL;
  85. g_dwValidStatusEntries = 0;
  86. g_dwTotalStatusEntries = 0;
  87. g_hPollTimer = NULL;
  88. g_bFirstTime = TRUE;
  89. //
  90. // Create the private heap. If it fails, deregister the trace
  91. // handle
  92. //
  93. g_hPrivateHeap = HeapCreate(0,
  94. 4*1024,
  95. 0);
  96. if(g_hPrivateHeap is NULL)
  97. {
  98. //
  99. // Deregister the trace handle
  100. //
  101. #ifdef MIB_DEBUG
  102. if(g_hTrace isnot INVALID_TRACEID)
  103. {
  104. TraceDeregister(g_hTrace);
  105. g_hTrace = INVALID_TRACEID;
  106. }
  107. #endif
  108. return FALSE;
  109. }
  110. for(i = 0; i < NUM_LOCKS; i++)
  111. {
  112. RtlInitializeResource(&g_LockTable[i]);
  113. }
  114. break ;
  115. }
  116. case DLL_THREAD_ATTACH:
  117. case DLL_THREAD_DETACH:
  118. {
  119. //
  120. // not of interest.
  121. //
  122. break;
  123. }
  124. case DLL_PROCESS_DETACH:
  125. {
  126. #ifdef MIB_DEBUG
  127. if(g_hTrace isnot INVALID_TRACEID)
  128. {
  129. TraceDeregister(g_hTrace);
  130. g_hTrace = INVALID_TRACEID;
  131. }
  132. #endif
  133. if(g_hPrivateHeap)
  134. {
  135. HeapDestroy(g_hPrivateHeap);
  136. }
  137. if(g_hPollTimer isnot NULL)
  138. {
  139. //
  140. // We had created an timer object
  141. //
  142. CloseHandle(g_hPollTimer);
  143. g_hPollTimer = NULL;
  144. }
  145. for(i = 0; i < NUM_LOCKS; i++)
  146. {
  147. RtlDeleteResource(&g_LockTable[i]);
  148. }
  149. break;
  150. }
  151. }
  152. return TRUE;
  153. }
  154. DWORD
  155. GetPollTime(
  156. VOID
  157. )
  158. /*++
  159. Routine Description
  160. This function
  161. Locks
  162. None
  163. Arguments
  164. None
  165. Return Value
  166. None
  167. --*/
  168. {
  169. DWORD dwResult, dwSize, dwValue, dwDisposition, dwType;
  170. HKEY hkeyPara;
  171. WCHAR wszPollValue[256];
  172. dwResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  173. REG_KEY_MIB2SUBAGENT_PARAMETERS,
  174. 0,
  175. NULL,
  176. 0,
  177. KEY_ALL_ACCESS,
  178. NULL,
  179. &hkeyPara,
  180. &dwDisposition);
  181. if(dwResult isnot NO_ERROR)
  182. {
  183. //
  184. // Couldnt open/create key just return default value
  185. //
  186. return DEFAULT_POLL_TIME;
  187. }
  188. //
  189. // Try and read the Poll time. If the value doesnt exist, write
  190. // the default in
  191. //
  192. dwSize = sizeof(DWORD);
  193. dwResult = RegQueryValueExW(hkeyPara,
  194. REG_VALUE_POLL,
  195. 0,
  196. &dwType,
  197. (LPBYTE)(&dwValue),
  198. &dwSize);
  199. if((dwResult isnot NO_ERROR) or
  200. (dwType isnot REG_DWORD) or
  201. (dwValue < MIN_POLL_TIME))
  202. {
  203. //
  204. // Registry seems to be corrupt, or key doesnt exist or
  205. // The value is less than the minimum. Lets set things
  206. // right
  207. //
  208. dwValue = DEFAULT_POLL_TIME;
  209. wcscpy(wszPollValue,
  210. REG_VALUE_POLL);
  211. dwResult = RegSetValueExW(hkeyPara,
  212. REG_VALUE_POLL,
  213. 0,
  214. REG_DWORD,
  215. (CONST BYTE *)(&dwValue),
  216. sizeof(DWORD));
  217. if(dwResult isnot NO_ERROR)
  218. {
  219. TRACE1("Error %d setting poll time in registry",
  220. dwResult);
  221. }
  222. }
  223. //
  224. // At this point dwValue is a good one read out of the registry
  225. // or is DEFAULT_POLL_TIME
  226. //
  227. return dwValue;
  228. }
  229. BOOL
  230. SnmpExtensionInit(
  231. IN DWORD uptimeReference,
  232. OUT HANDLE *lpPollForTrapEvent,
  233. OUT AsnObjectIdentifier *lpFirstSupportedView
  234. )
  235. {
  236. DWORD dwResult, dwPollTime;
  237. LARGE_INTEGER liRelTime;
  238. //
  239. // save the uptime reference
  240. //
  241. g_uptimeReference = uptimeReference;
  242. #ifdef MIB_DEBUG
  243. if (g_hTrace == INVALID_TRACEID)
  244. g_hTrace = TraceRegister("MIB-II Subagent");
  245. #endif
  246. //
  247. // obtain handle to subagent framework
  248. //
  249. g_tfxHandle = SnmpTfxOpen(NUM_VIEWS,v_mib2);
  250. //
  251. // validate handle
  252. //
  253. if (g_tfxHandle is NULL)
  254. {
  255. TRACE1("Error %d opening framework",
  256. GetLastError());
  257. //
  258. // destroy private heap
  259. //
  260. HeapDestroy(g_hPrivateHeap);
  261. //
  262. // reinitialize
  263. //
  264. g_hPrivateHeap = NULL;
  265. return FALSE;
  266. }
  267. //
  268. // pass back first view identifier to master
  269. //
  270. g_viewIndex = 0; // make sure this is reset...
  271. *lpFirstSupportedView = v_mib2[g_viewIndex++].viewOid;
  272. //
  273. // Update the IF cache. This is needed for the first poll
  274. //
  275. UpdateCache(MIB_II_IF);
  276. //
  277. // Trap is done by a polling timer
  278. //
  279. if(g_hPollTimer is NULL)
  280. {
  281. //
  282. // Do this ONLY if we had notcreated the timer from an earlier
  283. // initialization call
  284. //
  285. g_hPollTimer = CreateWaitableTimer(NULL,
  286. FALSE,
  287. NULL); // No name because many DLLs may load this
  288. if(g_hPollTimer is NULL)
  289. {
  290. TRACE1("Error %d creating poll timer for traps",
  291. GetLastError());
  292. }
  293. else
  294. {
  295. //
  296. // Read poll time from the registry. If the keys dont exist this
  297. // function will set up the keys and return the default value
  298. //
  299. dwPollTime = GetPollTime();
  300. liRelTime = RtlLargeIntegerNegate(MilliSecsToSysUnits(dwPollTime));
  301. if(!SetWaitableTimer(g_hPollTimer,
  302. &liRelTime,
  303. dwPollTime,
  304. NULL,
  305. NULL,
  306. FALSE))
  307. {
  308. TRACE1("Error %d setting timer",
  309. GetLastError());
  310. CloseHandle(g_hPollTimer);
  311. g_hPollTimer = NULL;
  312. }
  313. }
  314. }
  315. *lpPollForTrapEvent = g_hPollTimer;
  316. return TRUE;
  317. }
  318. BOOL
  319. SnmpExtensionInitEx(
  320. OUT AsnObjectIdentifier *lpNextSupportedView
  321. )
  322. {
  323. #ifdef MIB_DEBUG
  324. if (g_hTrace == INVALID_TRACEID)
  325. g_hTrace = TraceRegister("MIB-II Subagent");
  326. #endif
  327. //
  328. // check if there are views to register
  329. //
  330. BOOL fMoreViews = (g_viewIndex < NUM_VIEWS);
  331. if (fMoreViews)
  332. {
  333. //
  334. // pass back next supported view to master
  335. //
  336. *lpNextSupportedView = v_mib2[g_viewIndex++].viewOid;
  337. }
  338. //
  339. // report status
  340. //
  341. return fMoreViews;
  342. }
  343. BOOL
  344. SnmpExtensionQuery(
  345. IN BYTE requestType,
  346. IN OUT RFC1157VarBindList *variableBindings,
  347. OUT AsnInteger *errorStatus,
  348. OUT AsnInteger *errorIndex
  349. )
  350. {
  351. //
  352. // forward to framework
  353. //
  354. return SnmpTfxQuery(g_tfxHandle,
  355. requestType,
  356. variableBindings,
  357. errorStatus,
  358. errorIndex);
  359. }
  360. BOOL
  361. SnmpExtensionTrap(
  362. OUT AsnObjectIdentifier *enterprise,
  363. OUT AsnInteger *genericTrap,
  364. OUT AsnInteger *specificTrap,
  365. OUT AsnTimeticks *timeStamp,
  366. OUT RFC1157VarBindList *variableBindings
  367. )
  368. {
  369. DWORD dwResult;
  370. enterprise->idLength = 0;
  371. enterprise->ids = NULL; // use default enterprise oid
  372. *timeStamp = (GetCurrentTime()/10) - g_uptimeReference;
  373. return MibTrap(genericTrap,
  374. specificTrap,
  375. variableBindings);
  376. }