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

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