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.

716 lines
12 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. net\routing\ip\rtrmgr\map.c
  5. Abstract:
  6. Utility functions for various lookups and mappings
  7. Revision History:
  8. Amritansh Raghav 10/6/95 Created
  9. --*/
  10. #include "allinc.h"
  11. VOID
  12. InitHashTables(
  13. VOID
  14. )
  15. /*++
  16. Routine Description
  17. This function initializes the various mapping tables
  18. Locks
  19. None. Called at init time
  20. Arguments
  21. None
  22. Return Value
  23. None
  24. --*/
  25. {
  26. DWORD i;
  27. TraceEnter("InitHashTables");
  28. /*
  29. for(i = 0; i < ADAPTER_HASH_TABLE_SIZE; i++)
  30. {
  31. InitializeListHead(&(g_rgleAdapterMapTable[i]));
  32. }
  33. */
  34. for(i = 0; i < BINDING_HASH_TABLE_SIZE; i++)
  35. {
  36. InitializeListHead(&g_leBindingTable[i]);
  37. }
  38. g_ulNumBindings = 0;
  39. TraceLeave("InitHashTables");
  40. }
  41. VOID
  42. UnInitHashTables(
  43. VOID
  44. )
  45. /*++
  46. Routine Description
  47. Undo whatever was done in InitHasTables()
  48. Locks
  49. None
  50. Arguments
  51. None
  52. Return Value
  53. None
  54. --*/
  55. {
  56. DWORD i;
  57. PLIST_ENTRY pleHead;
  58. PLIST_ENTRY pleNode;
  59. TraceEnter("UnInitHashTables");
  60. /*
  61. for(i = 0; i < ADAPTER_HASH_TABLE_SIZE; i++)
  62. {
  63. pleHead = &g_rgleAdapterMapTable[i];
  64. while(!IsListEmpty(pleHead))
  65. {
  66. PADAPTER_MAP pAIBlock;
  67. pleNode = RemoveHeadList(pleHead);
  68. pAIBlock = CONTAINING_RECORD(pleNode,ADAPTER_MAP,leHashLink);
  69. HeapFree(GetProcessHeap(),0,pAIBlock);
  70. }
  71. }
  72. */
  73. for(i = 0; i < BINDING_HASH_TABLE_SIZE; i++)
  74. {
  75. pleHead = &g_leBindingTable[i];
  76. while(!IsListEmpty(pleHead))
  77. {
  78. PADAPTER_INFO pBinding;
  79. pleNode = RemoveHeadList(pleHead);
  80. pBinding = CONTAINING_RECORD(pleNode, ADAPTER_INFO, leHashLink);
  81. Trace1(ERR,
  82. "UnInitHashTables: Binding found for %d",
  83. pBinding->dwIfIndex);
  84. HeapFree(IPRouterHeap,
  85. 0,
  86. pBinding);
  87. }
  88. }
  89. g_ulNumBindings = 0;
  90. TraceLeave("UnInitHashTables");
  91. }
  92. VOID
  93. AddBinding(
  94. PICB picb
  95. )
  96. /*++
  97. Routine Description
  98. Adds a binding info node to the hash table. Increments the
  99. g_ulNumBindings to track the number of addresses on the system
  100. Locks
  101. ICB lock as writer
  102. BINDING lock as writer
  103. Arguments
  104. picb The ICB of the interface whose bindings need to be added
  105. to the binding list.
  106. Return Value
  107. None
  108. --*/
  109. {
  110. PADAPTER_INFO pBinding;
  111. DWORD i, dwNumAddr;
  112. #if DBG
  113. PLIST_ENTRY pleNode;
  114. #endif
  115. IpRtAssert(picb->pibBindings isnot NULL);
  116. IpRtAssert(picb->bBound);
  117. //
  118. // adapter info always has space for one address/mask. This is needed
  119. // for the address table
  120. //
  121. dwNumAddr = picb->dwNumAddresses ? picb->dwNumAddresses : 1;
  122. pBinding = HeapAlloc(IPRouterHeap,
  123. HEAP_ZERO_MEMORY,
  124. SIZEOF_ADAPTER_INFO(picb->dwNumAddresses));
  125. if(pBinding is NULL)
  126. {
  127. Trace1(ERR,
  128. "AddBinding: Error %d allocating memory",
  129. GetLastError());
  130. IpRtAssert(FALSE);
  131. return;
  132. }
  133. pBinding->pInterfaceCB = picb;
  134. pBinding->bBound = picb->bBound;
  135. pBinding->dwIfIndex = picb->dwIfIndex;
  136. pBinding->dwNumAddresses = picb->dwNumAddresses;
  137. pBinding->dwRemoteAddress = picb->dwRemoteAddress;
  138. pBinding->dwBCastBit = picb->dwBCastBit;
  139. pBinding->dwReassemblySize = picb->dwReassemblySize;
  140. pBinding->ritType = picb->ritType;
  141. for(i = 0; i < picb->dwNumAddresses; i++)
  142. {
  143. //
  144. // structure assignment
  145. //
  146. pBinding->rgibBinding[i] = picb->pibBindings[i];
  147. }
  148. #if DBG
  149. for(pleNode = g_leBindingTable[BIND_HASH(picb->dwIfIndex)].Flink;
  150. pleNode isnot &g_leBindingTable[BIND_HASH(picb->dwIfIndex)];
  151. pleNode = pleNode->Flink)
  152. {
  153. PADAPTER_INFO pTempBind;
  154. pTempBind = CONTAINING_RECORD(pleNode,
  155. ADAPTER_INFO,
  156. leHashLink);
  157. IpRtAssert(pTempBind->dwIfIndex isnot picb->dwIfIndex);
  158. }
  159. #endif
  160. InsertHeadList(&g_leBindingTable[BIND_HASH(picb->dwIfIndex)],
  161. &(pBinding->leHashLink));
  162. g_ulNumBindings += (picb->dwNumAddresses ? picb->dwNumAddresses : 1);
  163. g_LastUpdateTable[IPADDRCACHE] = 0;
  164. return;
  165. }
  166. VOID
  167. RemoveBinding(
  168. PICB picb
  169. )
  170. /*++
  171. Routine Description
  172. Called to remove the bindings associated with an interface
  173. Locks
  174. ICB lock held as WRITER
  175. BINDING list lock held as WRITER
  176. Arguments
  177. picb ICB of the interface whose bindings need to be removed
  178. Return Value
  179. None
  180. --*/
  181. {
  182. PADAPTER_INFO pBind;
  183. pBind = GetInterfaceBinding(picb->dwIfIndex);
  184. if(pBind isnot NULL)
  185. {
  186. RemoveEntryList(&(pBind->leHashLink));
  187. g_ulNumBindings -= (pBind->dwNumAddresses? pBind->dwNumAddresses : 1);
  188. HeapFree(IPRouterHeap,
  189. 0,
  190. pBind);
  191. g_LastUpdateTable[IPADDRCACHE] = 0;
  192. return;
  193. }
  194. Trace0(ERR,
  195. "RemoveBinding: BINDING NOT FOUND");
  196. IpRtAssert(FALSE);
  197. }
  198. PADAPTER_INFO
  199. GetInterfaceBinding(
  200. DWORD dwIfIndex
  201. )
  202. /*++
  203. Routine Description
  204. Retrieves a pointer to the binding info from hash table
  205. Locks
  206. BINDING lock held atleast as READER
  207. Arguments
  208. dwIfIndex Interface Index for the interface whose bindings need
  209. to be looked up
  210. Return Value
  211. Pointer to binding information if the binding was found
  212. NULL if binding was not found
  213. --*/
  214. {
  215. PLIST_ENTRY pleNode;
  216. PADAPTER_INFO pBinding;
  217. for(pleNode = g_leBindingTable[BIND_HASH(dwIfIndex)].Flink;
  218. pleNode isnot &g_leBindingTable[BIND_HASH(dwIfIndex)];
  219. pleNode = pleNode->Flink)
  220. {
  221. pBinding = CONTAINING_RECORD(pleNode,ADAPTER_INFO,leHashLink);
  222. if(pBinding->dwIfIndex is dwIfIndex)
  223. {
  224. return pBinding;
  225. }
  226. }
  227. Trace0(ERR,
  228. "GetInterfaceBinding: BINDING NOT FOUND");
  229. return NULL;
  230. }
  231. #if DBG
  232. VOID
  233. CheckBindingConsistency(
  234. PICB picb
  235. )
  236. /*++
  237. Routine Description
  238. This
  239. Locks
  240. None
  241. Arguments
  242. None
  243. Return Value
  244. None
  245. --*/
  246. {
  247. }
  248. #endif
  249. //
  250. // The following are the set of various mapping functions
  251. // They require that you already possess the dwLock before you call them
  252. //
  253. #if 0
  254. DWORD
  255. StoreAdapterToInterfaceMap(
  256. DWORD dwAdapterId,
  257. DWORD dwIfIndex
  258. )
  259. {
  260. PADAPTER_MAP pAIBlock;
  261. if((pAIBlock = LookUpAdapterHash(dwAdapterId)) isnot NULL)
  262. {
  263. pAIBlock->dwIfIndex = dwIfIndex;
  264. return NO_ERROR;
  265. }
  266. //
  267. // Wasnt found
  268. //
  269. if((pAIBlock = HeapAlloc(GetProcessHeap(),0,sizeof(ADAPTER_MAP))) is NULL)
  270. {
  271. return ERROR_NOT_ENOUGH_MEMORY;
  272. }
  273. pAIBlock->dwAdapterId = dwAdapterId;
  274. pAIBlock->dwIfIndex = dwIfIndex;
  275. InsertAdapterHash(pAIBlock);
  276. return NO_ERROR;
  277. }
  278. DWORD
  279. DeleteAdapterToInterfaceMap(
  280. DWORD dwAdapterId
  281. )
  282. {
  283. PADAPTER_MAP pAIBlock;
  284. if((pAIBlock = LookUpAdapterHash(dwAdapterId)) isnot NULL)
  285. {
  286. pAIBlock->dwIfIndex = INVALID_IF_INDEX;
  287. return NO_ERROR;
  288. }
  289. return INVALID_ADAPTER_ID;
  290. }
  291. DWORD
  292. GetInterfaceFromAdapter(
  293. DWORD dwAdapterId
  294. )
  295. {
  296. PADAPTER_MAP pAIBlock;
  297. if((pAIBlock = LookUpAdapterHash(dwAdapterId)) isnot NULL)
  298. {
  299. return pAIBlock->dwIfIndex;
  300. }
  301. return INVALID_ADAPTER_ID;
  302. }
  303. PADAPTER_MAP
  304. LookUpAdapterHash(
  305. DWORD dwAdapterId
  306. )
  307. {
  308. DWORD dwHashIndex;
  309. PADAPTER_MAP pAIBlock;
  310. PLIST_ENTRY pleCurrent;
  311. dwHashIndex = ADAPTER_HASH(dwAdapterId);
  312. //
  313. // The list is not ordered, travel the whole hash bucket
  314. //
  315. for(pleCurrent = g_rgleAdapterMapTable[dwHashIndex].Flink;
  316. pleCurrent isnot &g_rgleAdapterMapTable[dwHashIndex];
  317. pleCurrent = pleCurrent->Flink)
  318. {
  319. pAIBlock = CONTAINING_RECORD(pleCurrent,ADAPTER_MAP,leHashLink);
  320. if(pAIBlock->dwAdapterId is dwAdapterId)
  321. {
  322. return pAIBlock;
  323. }
  324. }
  325. return NULL;
  326. }
  327. VOID
  328. InsertAdapterHash(
  329. PADAPTER_MAP paiBlock
  330. )
  331. {
  332. DWORD dwHashIndex;
  333. dwHashIndex = ADAPTER_HASH(paiBlock->dwAdapterId);
  334. InsertHeadList(&g_rgleAdapterMapTable[dwHashIndex],
  335. &paiBlock->leHashLink);
  336. }
  337. DWORD
  338. GetAdapterFromInterface(
  339. DWORD dwIfIndex
  340. )
  341. {
  342. PICB picb;
  343. picb = InterfaceLookupByIfIndex(dwIfIndex);
  344. CheckBindingConsistency(picb);
  345. if(!picb)
  346. {
  347. Trace0(ERR,
  348. "GetAdapterFromInterface: Unable to map interface to adapter since the interface id was not found!");
  349. return INVALID_IF_INDEX;
  350. }
  351. if((picb->dwOperationalState is CONNECTED) or
  352. (picb->dwOperationalState is OPERATIONAL))
  353. {
  354. return picb->dwAdapterId;
  355. }
  356. Trace1(IF,
  357. "GetAdapterFromInterface: Unable to map interface to adapter since its operational state was %d",
  358. picb->dwOperationalState);
  359. return INVALID_IF_INDEX;
  360. }
  361. #endif
  362. // AddInterfaceLookup()
  363. //
  364. // Function: Adds the given interface to the hash table used for quick look up given
  365. // an interface id.
  366. //
  367. // Returns: Nothing
  368. //
  369. VOID
  370. AddInterfaceLookup(
  371. PICB picb
  372. )
  373. {
  374. PLIST_ENTRY ple;
  375. PICB pIcbHash;
  376. InsertHeadList(&ICBHashLookup[picb->dwIfIndex % ICB_HASH_TABLE_SIZE],
  377. &picb->leHashLink);
  378. for (
  379. ple = ICBSeqNumLookup[picb->dwSeqNumber % ICB_HASH_TABLE_SIZE].Flink;
  380. ple != &ICBSeqNumLookup[picb->dwSeqNumber % ICB_HASH_TABLE_SIZE];
  381. ple = ple->Flink
  382. )
  383. {
  384. pIcbHash = CONTAINING_RECORD(ple, ICB, leICBHashLink );
  385. if (pIcbHash->dwSeqNumber > picb->dwSeqNumber)
  386. {
  387. break;
  388. }
  389. }
  390. InsertTailList(ple, &picb->leICBHashLink);
  391. }
  392. // RemoveInterfaceLookup()
  393. //
  394. // Function: Removes the given interface from the hash table used for quick look up given
  395. // an interface id.
  396. //
  397. // Returns: Nothing
  398. //
  399. VOID
  400. RemoveInterfaceLookup(
  401. PICB picb
  402. )
  403. {
  404. RemoveEntryList(&picb->leHashLink);
  405. picb->leHashLink.Flink = NULL;
  406. picb->leHashLink.Blink = NULL;
  407. RemoveEntryList(&picb->leICBHashLink);
  408. InitializeListHead(&picb->leICBHashLink);
  409. }
  410. // InterfaceLookupByICBSeqNumber()
  411. //
  412. // Function: Returns a pointer to ICB given the sequence number
  413. //
  414. // Returns: PICB if found - NULL otherwise.
  415. //
  416. PICB
  417. InterfaceLookupByICBSeqNumber(
  418. DWORD dwSeqNumber
  419. )
  420. {
  421. PICB picb;
  422. PLIST_ENTRY pleNode;
  423. for(pleNode = ICBSeqNumLookup[dwSeqNumber % ICB_HASH_TABLE_SIZE].Flink;
  424. pleNode isnot &ICBSeqNumLookup[dwSeqNumber % ICB_HASH_TABLE_SIZE];
  425. pleNode = pleNode->Flink)
  426. {
  427. picb = CONTAINING_RECORD(pleNode, ICB, leICBHashLink);
  428. if (picb->dwSeqNumber < dwSeqNumber)
  429. {
  430. continue;
  431. }
  432. if (picb->dwSeqNumber == dwSeqNumber)
  433. {
  434. return picb;
  435. }
  436. else
  437. {
  438. break;
  439. }
  440. }
  441. return NULL;
  442. }
  443. //
  444. // InterfaceLookupByIfIndex()
  445. //
  446. // Function: Returns a pointer to ICB given the interfaceid
  447. //
  448. // Returns: PICB if found - NULL otherwise.
  449. //
  450. PICB
  451. InterfaceLookupByIfIndex(
  452. DWORD dwIfIndex
  453. )
  454. {
  455. PICB picb;
  456. PLIST_ENTRY pleNode;
  457. for(pleNode = ICBHashLookup[dwIfIndex % ICB_HASH_TABLE_SIZE].Flink;
  458. pleNode isnot &ICBHashLookup[dwIfIndex % ICB_HASH_TABLE_SIZE];
  459. pleNode = pleNode->Flink)
  460. {
  461. picb = CONTAINING_RECORD(pleNode, ICB, leHashLink);
  462. if (picb->dwIfIndex is dwIfIndex)
  463. {
  464. return picb;
  465. }
  466. }
  467. return NULL;
  468. }
  469. DWORD
  470. MapInterfaceToAdapter(
  471. DWORD Index
  472. )
  473. {
  474. return Index;
  475. #if 0
  476. ENTER_READER(ICB_LIST);
  477. Index = GetAdapterFromInterface(Index);
  478. EXIT_LOCK(ICB_LIST);
  479. return Index;
  480. #endif
  481. }
  482. DWORD
  483. MapInterfaceToRouterIfType(
  484. DWORD Index
  485. )
  486. {
  487. DWORD dwIfType = ROUTER_IF_TYPE_INTERNAL;
  488. PICB picb;
  489. ENTER_READER(ICB_LIST);
  490. picb = InterfaceLookupByIfIndex(Index);
  491. if (picb) { dwIfType = picb->ritType; }
  492. EXIT_LOCK(ICB_LIST);
  493. return dwIfType;
  494. }
  495. DWORD
  496. MapAddressToAdapter(
  497. DWORD Address
  498. )
  499. {
  500. DWORD dwAdapterId;
  501. DWORD dwBCastBit;
  502. DWORD dwReassemblySize;
  503. if (GetAdapterInfo(Address, &dwAdapterId, &dwBCastBit, &dwReassemblySize))
  504. {
  505. return INVALID_IF_INDEX;
  506. }
  507. return dwAdapterId;
  508. }