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.

434 lines
10 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. Revision History:
  6. Amritansh Raghav
  7. --*/
  8. #include "inc.h"
  9. #pragma hdrstop
  10. int
  11. TCPQueryInformationEx(
  12. DWORD Family,
  13. void *InBuf,
  14. ulong *InBufLen,
  15. void *OutBuf,
  16. ulong *OutBufLen
  17. );
  18. int
  19. TCPSetInformationEx(
  20. void *InBuf,
  21. ULONG *InBufLen,
  22. void *OutBuf,
  23. ULONG *OutBufLen
  24. );
  25. TDIEntityID*
  26. GetTdiEntityCount(
  27. PULONG pulNumEntities
  28. );
  29. VOID
  30. InitAdapterMappingTable(VOID)
  31. {
  32. DWORD i;
  33. for(i = 0; i < MAP_HASH_SIZE; i++)
  34. {
  35. InitializeListHead(&g_pAdapterMappingTable[i]);
  36. }
  37. }
  38. VOID
  39. UnInitAdapterMappingTable(VOID)
  40. {
  41. DWORD i;
  42. for(i = 0; i < MAP_HASH_SIZE; i++)
  43. {
  44. PLIST_ENTRY pleHead = &g_pAdapterMappingTable[i];
  45. while(!IsListEmpty(pleHead))
  46. {
  47. PLIST_ENTRY pleNode;
  48. LPAIHASH lpAIBlock;
  49. pleNode = RemoveHeadList(pleHead);
  50. lpAIBlock = CONTAINING_RECORD(pleNode,AIHASH,leList);
  51. HeapFree(g_hPrivateHeap,0,lpAIBlock);
  52. }
  53. }
  54. }
  55. DWORD
  56. StoreAdapterToATInstanceMap(
  57. DWORD dwAdapterIndex,
  58. DWORD dwATInst
  59. )
  60. {
  61. LPAIHASH lpAIBlock;
  62. if((lpAIBlock = LookUpAdapterMap(dwAdapterIndex)) isnot NULL)
  63. {
  64. lpAIBlock->dwATInstance = dwATInst;
  65. return NO_ERROR;
  66. }
  67. //
  68. // Wasnt found
  69. //
  70. if((lpAIBlock = HeapAlloc(g_hPrivateHeap,0,sizeof(AIHASH))) is NULL)
  71. {
  72. return ERROR_NOT_ENOUGH_MEMORY;
  73. }
  74. //
  75. // New one so make everything else unmapped to avoid nasty surprises
  76. //
  77. lpAIBlock->dwAdapterIndex = dwAdapterIndex;
  78. lpAIBlock->dwATInstance = dwATInst;
  79. lpAIBlock->dwIFInstance = INVALID_IF_INSTANCE;
  80. InsertAdapterMap(lpAIBlock);
  81. return NO_ERROR;
  82. }
  83. DWORD
  84. StoreAdapterToIFInstanceMap(
  85. DWORD dwAdapterIndex,
  86. DWORD dwIFInst
  87. )
  88. {
  89. LPAIHASH lpAIBlock;
  90. if((lpAIBlock = LookUpAdapterMap(dwAdapterIndex)) isnot NULL)
  91. {
  92. lpAIBlock->dwIFInstance = dwIFInst;
  93. return NO_ERROR;
  94. }
  95. //
  96. // Wasnt found
  97. //
  98. if((lpAIBlock = HeapAlloc(g_hPrivateHeap,0,sizeof(AIHASH))) is NULL)
  99. {
  100. return ERROR_NOT_ENOUGH_MEMORY;
  101. }
  102. //
  103. // New one so make everything else unmapped to avoid nasty surprises
  104. //
  105. lpAIBlock->dwAdapterIndex = dwAdapterIndex;
  106. lpAIBlock->dwATInstance = INVALID_AT_INSTANCE;
  107. lpAIBlock->dwIFInstance = dwIFInst;
  108. InsertAdapterMap(lpAIBlock);
  109. return NO_ERROR;
  110. }
  111. DWORD
  112. GetIFInstanceFromAdapter(
  113. DWORD dwAdapterIndex
  114. )
  115. {
  116. LPAIHASH lpAIBlock;
  117. if((lpAIBlock = LookUpAdapterMap(dwAdapterIndex)) isnot NULL)
  118. {
  119. return lpAIBlock->dwIFInstance;
  120. }
  121. return INVALID_IF_INSTANCE;
  122. }
  123. DWORD
  124. GetATInstanceFromAdapter(
  125. DWORD dwAdapterIndex
  126. )
  127. {
  128. LPAIHASH lpAIBlock;
  129. if((lpAIBlock = LookUpAdapterMap(dwAdapterIndex)) isnot NULL)
  130. {
  131. return lpAIBlock->dwATInstance;
  132. }
  133. return INVALID_IF_INSTANCE;
  134. }
  135. LPAIHASH
  136. LookUpAdapterMap(
  137. DWORD dwAdapterIndex
  138. )
  139. {
  140. DWORD dwHashIndex;
  141. LPAIHASH lpAIBlock;
  142. PLIST_ENTRY lpleCurrent;
  143. dwHashIndex = dwAdapterIndex % MAP_HASH_SIZE;
  144. //
  145. // The list is not ordered, travel the whole hash bucket
  146. //
  147. for(lpleCurrent = g_pAdapterMappingTable[dwHashIndex].Flink;
  148. lpleCurrent isnot &g_pAdapterMappingTable[dwHashIndex];
  149. lpleCurrent = lpleCurrent->Flink)
  150. {
  151. lpAIBlock = CONTAINING_RECORD(lpleCurrent,AIHASH,leList);
  152. if(lpAIBlock->dwAdapterIndex is dwAdapterIndex)
  153. {
  154. return lpAIBlock;
  155. }
  156. }
  157. return NULL;
  158. }
  159. VOID
  160. InsertAdapterMap(
  161. LPAIHASH lpaiBlock
  162. )
  163. {
  164. DWORD dwHashIndex;
  165. dwHashIndex = lpaiBlock->dwAdapterIndex % MAP_HASH_SIZE;
  166. InsertHeadList(&g_pAdapterMappingTable[dwHashIndex],&lpaiBlock->leList);
  167. }
  168. DWORD
  169. UpdateAdapterToIFInstanceMapping(
  170. VOID
  171. )
  172. {
  173. DWORD dwResult;
  174. DWORD dwOutBufLen;
  175. DWORD dwInBufLen;
  176. TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
  177. TDIObjectID *ID;
  178. BYTE *Context;
  179. MIB_IFROW maxIfEntry;
  180. DWORD i;
  181. ULONG ulNumEntities;
  182. TDIEntityID *entityList;
  183. TDIEntityID *pEntity = NULL;
  184. entityList = GetTdiEntityCount(&ulNumEntities);
  185. if(entityList == NULL)
  186. {
  187. Trace0(ERR,
  188. "UpdateAdapterToIFInstanceMapping: Couldnt get num entities\n");
  189. return ERROR_GEN_FAILURE;
  190. }
  191. dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
  192. ID = &(trqiInBuf.ID);
  193. Context = (BYTE *) &(trqiInBuf.Context[0]);
  194. ID->toi_entity.tei_entity = IF_ENTITY;
  195. ID->toi_class = INFO_CLASS_PROTOCOL;
  196. ID->toi_type = INFO_TYPE_PROVIDER;
  197. ID->toi_id = IF_MIB_STATS_ID;
  198. //
  199. // First go through and invalidate all the mappings
  200. //
  201. for(i = 0; i < MAP_HASH_SIZE; i ++)
  202. {
  203. PLIST_ENTRY pCurrentNode;
  204. LPAIHASH lpAIBlock;
  205. for(pCurrentNode = g_pAdapterMappingTable[i].Flink;
  206. pCurrentNode isnot &(g_pAdapterMappingTable[i]);
  207. pCurrentNode = pCurrentNode->Flink)
  208. {
  209. lpAIBlock = CONTAINING_RECORD(pCurrentNode,AIHASH,leList);
  210. lpAIBlock->dwIFInstance = INVALID_IF_INSTANCE;
  211. }
  212. }
  213. //
  214. // Read the interface entry items
  215. //
  216. for ( i = 0, pEntity = entityList; i < ulNumEntities ; ++i, ++pEntity)
  217. {
  218. if (pEntity->tei_entity == IF_ENTITY)
  219. {
  220. dwOutBufLen = sizeof(MIB_IFROW) - FIELD_OFFSET(MIB_IFROW, dwIndex);
  221. ID->toi_entity.tei_instance = pEntity->tei_instance;
  222. ZeroMemory(Context,CONTEXT_SIZE);
  223. dwResult = TCPQueryInformationEx(AF_INET,
  224. &trqiInBuf,
  225. &dwInBufLen,
  226. (LPVOID)&(maxIfEntry.dwIndex),
  227. &dwOutBufLen );
  228. if (dwResult isnot NO_ERROR)
  229. {
  230. Trace1(ERR,
  231. "Error %x querying information from stack. Continuing",
  232. dwResult);
  233. continue;
  234. }
  235. StoreAdapterToIFInstanceMap(maxIfEntry.dwIndex,
  236. pEntity->tei_instance);
  237. }
  238. }
  239. //
  240. // Now delete the blocks that have invalid mappings
  241. //
  242. for(i = 0; i < MAP_HASH_SIZE; i ++)
  243. {
  244. PLIST_ENTRY pCurrentNode;
  245. LPAIHASH lpAIBlock;
  246. pCurrentNode = g_pAdapterMappingTable[i].Flink;
  247. while(pCurrentNode isnot &(g_pAdapterMappingTable[i]))
  248. {
  249. PLIST_ENTRY pTempNode;
  250. pTempNode = pCurrentNode;
  251. pCurrentNode = pCurrentNode->Flink;
  252. lpAIBlock = CONTAINING_RECORD(pTempNode,
  253. AIHASH,
  254. leList);
  255. if(lpAIBlock->dwIFInstance is INVALID_IF_INSTANCE)
  256. {
  257. //
  258. // Delete it
  259. //
  260. RemoveEntryList(&(lpAIBlock->leList));
  261. HeapFree(g_hPrivateHeap,
  262. 0,
  263. lpAIBlock);
  264. }
  265. }
  266. }
  267. g_dwLastIfUpdateTime = GetCurrentTime();
  268. HeapFree(g_hPrivateHeap,0, entityList);
  269. return NO_ERROR;
  270. }
  271. DWORD
  272. UpdateAdapterToATInstanceMapping(
  273. VOID
  274. )
  275. {
  276. DWORD dwResult;
  277. DWORD dwInBufLen;
  278. DWORD i;
  279. TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
  280. TDIObjectID *ID;
  281. UCHAR *Context;
  282. DWORD dwSize;
  283. AddrXlatInfo AXI;
  284. //
  285. // When we update the mapping, we also update the ArpEntities
  286. // Infact we use the same function to do both
  287. //
  288. if(g_pdwArpEntTable)
  289. {
  290. HeapFree(g_hPrivateHeap,
  291. HEAP_NO_SERIALIZE,
  292. g_pdwArpEntTable);
  293. g_pdwArpEntTable = NULL;
  294. }
  295. dwResult = AllocateAndGetArpEntTableFromStack(&g_pdwArpEntTable,
  296. &g_dwNumArpEntEntries,
  297. g_hPrivateHeap,
  298. 0,
  299. 0);
  300. if(dwResult isnot NO_ERROR)
  301. {
  302. Trace1(ERR,
  303. "UpdateAdapterToATInstanceMapping: Couldnt get ArpEntTable. Error %d",
  304. dwResult);
  305. g_pdwArpEntTable = NULL;
  306. return ERROR_CAN_NOT_COMPLETE;
  307. }
  308. dwInBufLen = sizeof( TCP_REQUEST_QUERY_INFORMATION_EX );
  309. Context = (BYTE *) &(trqiInBuf.Context[0]);
  310. ID = &(trqiInBuf.ID);
  311. for (i = 0; i < g_dwNumArpEntEntries; i++ )
  312. {
  313. ID->toi_entity.tei_entity = AT_ENTITY;
  314. ID->toi_type = INFO_TYPE_PROVIDER;
  315. ID->toi_class = INFO_CLASS_PROTOCOL;
  316. ID->toi_id = AT_MIB_ADDRXLAT_INFO_ID;
  317. ID->toi_entity.tei_instance = g_pdwArpEntTable[i];
  318. dwSize = sizeof(AXI);
  319. ZeroMemory(Context, CONTEXT_SIZE);
  320. dwResult = TCPQueryInformationEx(AF_INET,
  321. &trqiInBuf,
  322. &dwInBufLen,
  323. &AXI,
  324. &dwSize );
  325. if(dwResult isnot NO_ERROR)
  326. {
  327. Trace1(ERR,
  328. "UpdateAdapterToATInstanceMapping: Error %x querying stack",
  329. dwResult);
  330. return dwResult;
  331. }
  332. StoreAdapterToATInstanceMap(AXI.axi_index,g_pdwArpEntTable[i]);
  333. }
  334. g_dwLastArpUpdateTime = GetCurrentTime();
  335. return NO_ERROR;
  336. }