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.

3522 lines
87 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. #include <ntddip.h>
  11. #ifdef CHICAGO
  12. LPWSCONTROL pWsControl = NULL;
  13. HANDLE hWsock = NULL;
  14. #endif
  15. extern HANDLE g_hIPDriverHandle;
  16. extern HANDLE g_hIPGetDriverHandle;
  17. extern HANDLE ChangeNotificationHandle;
  18. extern HANDLE g_hIP6DriverHandle;
  19. extern HANDLE g_hIP6GetDriverHandle;
  20. extern HANDLE Change6NotificationHandle;
  21. #ifdef DBG
  22. int trace = 1;
  23. #endif
  24. DWORD
  25. OpenTCPDriver(
  26. IN DWORD dwFamily
  27. );
  28. DWORD
  29. OpenIPDriver(
  30. IN DWORD dwFamily
  31. );
  32. DWORD
  33. CloseIPDriver();
  34. DWORD
  35. CloseIP6Driver();
  36. TDIEntityID*
  37. GetTdiEntityCount(
  38. PULONG pulNumEntities
  39. );
  40. DWORD
  41. GetArpEntryCount(
  42. OUT PDWORD pdwNumEntries
  43. );
  44. int
  45. TCPQueryInformationEx(
  46. DWORD Family,
  47. void *InBuf,
  48. ulong *InBufLen,
  49. void *OutBuf,
  50. ulong *OutBufLen
  51. );
  52. int
  53. TCPSetInformationEx(
  54. void *InBuf,
  55. ULONG *InBufLen,
  56. void *OutBuf,
  57. ULONG *OutBufLen
  58. );
  59. DWORD
  60. AccessIfEntryInStack(
  61. IN DWORD dwAction,
  62. IN DWORD dwInstance,
  63. IN OUT PMIB_IFROW pIfEntry
  64. );
  65. int
  66. TCPSendIoctl(
  67. HANDLE hHandle,
  68. ulong Ioctl,
  69. void *InBuf,
  70. ulong *InBufLen,
  71. void *OutBuf,
  72. ulong *OutBufLen
  73. );
  74. // ========================================================================
  75. #ifdef CHICAGO
  76. uint
  77. ConvertTdiErrorToDosError(uint TdiErr)
  78. {
  79. switch (TdiErr) {
  80. case TDI_INVALID_REQUEST:
  81. case TDI_INVALID_QUERY:
  82. return ERROR_INVALID_FUNCTION;
  83. case TDI_BUFFER_TOO_SMALL:
  84. return ERROR_INSUFFICIENT_BUFFER;
  85. case TDI_BUFFER_OVERFLOW:
  86. return ERROR_INSUFFICIENT_BUFFER;
  87. case TDI_PENDING:
  88. return ERROR_SIGNAL_PENDING;
  89. default:
  90. return ERROR_INVALID_PARAMETER;
  91. }
  92. }
  93. #endif
  94. DWORD
  95. AllocateAndGetIfTableFromStack(
  96. OUT MIB_IFTABLE **ppIfTable,
  97. IN BOOL bOrder,
  98. IN HANDLE hHeap,
  99. IN DWORD dwFlags,
  100. IN BOOL bForceUpdate
  101. )
  102. {
  103. DWORD dwResult, dwCount, dwOutBufLen;
  104. MIB_IPSTATS miStats;
  105. *ppIfTable = NULL;
  106. dwResult = GetIpStatsFromStack(&miStats);
  107. if(dwResult isnot NO_ERROR)
  108. {
  109. Trace1(ERR,
  110. "AllocateAndGetIfTableFromStack: Couldnt get Ip Stats From stack. Error %d",
  111. dwResult);
  112. return dwResult;
  113. }
  114. dwCount = miStats.dwNumIf + OVERFLOW_COUNT;
  115. dwOutBufLen = SIZEOF_IFTABLE(dwCount);
  116. *ppIfTable = HeapAlloc(hHeap,
  117. dwFlags,
  118. dwOutBufLen);
  119. if(*ppIfTable is NULL)
  120. {
  121. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  122. Trace1(ERR,
  123. "AllocateAndGetIfTableFromStack: Couldnt allocate memory. Error %d",
  124. dwResult);
  125. return dwResult;
  126. }
  127. if(miStats.dwNumIf is 0)
  128. {
  129. (*ppIfTable)->dwNumEntries = 0;
  130. return NO_ERROR;
  131. }
  132. EnterCriticalSection(&g_ifLock);
  133. if (!bForceUpdate && miStats.dwNumIf != g_dwNumIf)
  134. {
  135. bForceUpdate = TRUE;
  136. }
  137. g_dwNumIf = miStats.dwNumIf;
  138. LeaveCriticalSection(&g_ifLock);
  139. dwResult = GetIfTableFromStack(*ppIfTable,
  140. dwOutBufLen,
  141. bOrder,
  142. bForceUpdate);
  143. if(dwResult isnot NO_ERROR)
  144. {
  145. Trace1(ERR,
  146. "AllocateAndGetIfTableFromStack: Error %d calling GetIfTableFromStack",
  147. dwResult);
  148. HeapFree(hHeap, dwFlags, *ppIfTable);
  149. *ppIfTable = NULL;
  150. }
  151. return dwResult;
  152. }
  153. // ========================================================================
  154. DWORD
  155. GetIfTableFromStack(
  156. OUT PMIB_IFTABLE pIfTable,
  157. IN DWORD dwSize,
  158. IN BOOL bOrder,
  159. IN BOOL bForceUpdate
  160. )
  161. /*++
  162. Routine Description
  163. Locks
  164. None needed on entry. It takes the If lock within the function
  165. Arguments
  166. Return Value
  167. NO_ERROR
  168. --*/
  169. {
  170. DWORD i, dwNumRows, dwCount, dwErr, dwResult;
  171. PLIST_ENTRY pCurrentNode;
  172. LPAIHASH lpAIBlock;
  173. dwNumRows = (dwSize - FIELD_OFFSET(MIB_IFTABLE,table[0]))/sizeof(MIB_IFROW);
  174. dwCount = 0;
  175. dwErr = NO_ERROR;
  176. CheckTcpipState();
  177. if (!g_bIpConfigured)
  178. {
  179. return ERROR_NOT_SUPPORTED;
  180. }
  181. EnterCriticalSection(&g_ifLock);
  182. if(bForceUpdate or
  183. (g_dwLastIfUpdateTime is 0) or
  184. ((GetCurrentTime() - g_dwLastIfUpdateTime) > IF_CACHE_LIFE))
  185. {
  186. dwResult = UpdateAdapterToIFInstanceMapping();
  187. Trace0(ERR, "Update the mapping \n");
  188. if(dwResult isnot NO_ERROR)
  189. {
  190. Trace1(ERR,
  191. "GetIfTableFromStack: Couldnt update map. Error %d",
  192. dwResult);
  193. LeaveCriticalSection(&g_ifLock);
  194. return ERROR_CAN_NOT_COMPLETE;
  195. }
  196. }
  197. for(i = 0; i < MAP_HASH_SIZE; i ++)
  198. {
  199. for(pCurrentNode = g_pAdapterMappingTable[i].Flink;
  200. pCurrentNode isnot &(g_pAdapterMappingTable[i]);
  201. pCurrentNode = pCurrentNode->Flink)
  202. {
  203. lpAIBlock = CONTAINING_RECORD(pCurrentNode,AIHASH,leList);
  204. Trace1(ERR,
  205. "Instance %d \n", lpAIBlock->dwIFInstance);
  206. if(lpAIBlock->dwIFInstance is INVALID_IF_INSTANCE)
  207. {
  208. continue;
  209. }
  210. //
  211. // If there is no more space in the buffer, bail out
  212. //
  213. if(dwCount >= dwNumRows)
  214. {
  215. Trace2(ERR,
  216. "return here dwCount %d dwNumRows %d \n", dwCount, dwNumRows);
  217. dwErr = ERROR_MORE_DATA;
  218. break;
  219. }
  220. dwResult = AccessIfEntryInStack(GET_IF_ENTRY,
  221. lpAIBlock->dwIFInstance,
  222. &(pIfTable->table[dwCount]));
  223. if(dwResult isnot NO_ERROR)
  224. {
  225. Trace2(ERR,
  226. "GetIfTableFromStack: Err %d getting row for inst %d",
  227. dwResult, lpAIBlock->dwIFInstance);
  228. // dwErr = ERROR_MORE_DATA;
  229. // at this point the stack doesn't have the interface
  230. g_dwLastIfUpdateTime = 0;
  231. continue;
  232. }
  233. else
  234. {
  235. dwCount++;
  236. }
  237. }
  238. }
  239. g_dwNumIf = dwCount;
  240. LeaveCriticalSection(&g_ifLock);
  241. pIfTable->dwNumEntries = dwCount;
  242. if(bOrder && (dwCount > 0))
  243. {
  244. qsort(pIfTable->table,
  245. dwCount,
  246. sizeof(MIB_IFROW),
  247. CompareIfRow);
  248. }
  249. return dwErr;
  250. }
  251. // ========================================================================
  252. DWORD
  253. GetIfEntryFromStack(
  254. OUT PMIB_IFROW pIfEntry,
  255. IN DWORD dwAdapterIndex,
  256. IN BOOL bForceUpdate
  257. )
  258. /*++
  259. Routine Description
  260. Locks
  261. Arguments
  262. Return Value
  263. NO_ERROR
  264. --*/
  265. {
  266. DWORD dwResult,dwInBufLen,dwOutBufLen,dwInstance;
  267. TDIObjectID *ID;
  268. BYTE *Context;
  269. TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
  270. if (pIfEntry == NULL) {
  271. return ERROR_INVALID_PARAMETER;
  272. }
  273. CheckTcpipState();
  274. if (!g_bIpConfigured)
  275. {
  276. return ERROR_NOT_SUPPORTED;
  277. }
  278. EnterCriticalSection(&g_ifLock);
  279. if(bForceUpdate)
  280. {
  281. dwResult = UpdateAdapterToIFInstanceMapping();
  282. if(dwResult isnot NO_ERROR)
  283. {
  284. Trace1(ERR,
  285. "GetIfEntryFromStack: Couldnt update map. Error %d",
  286. dwResult);
  287. LeaveCriticalSection(&g_ifLock);
  288. return ERROR_CAN_NOT_COMPLETE;
  289. }
  290. dwInstance = GetIFInstanceFromAdapter(dwAdapterIndex);
  291. }
  292. else
  293. {
  294. dwInstance = GetIFInstanceFromAdapter(dwAdapterIndex);
  295. if(dwInstance is INVALID_IF_INSTANCE)
  296. {
  297. Trace0(ERR,
  298. "GetIfEntryFromStack: Couldnt map to instance - first try");
  299. dwResult = UpdateAdapterToIFInstanceMapping();
  300. if(dwResult isnot NO_ERROR)
  301. {
  302. Trace1(ERR,
  303. "GetIfEntryFromStack: Couldnt update map. Error %d",
  304. dwResult);
  305. LeaveCriticalSection(&g_ifLock);
  306. return ERROR_CAN_NOT_COMPLETE;
  307. }
  308. dwInstance = GetIFInstanceFromAdapter(dwAdapterIndex);
  309. }
  310. }
  311. LeaveCriticalSection(&g_ifLock);
  312. if(dwInstance is INVALID_IF_INSTANCE)
  313. {
  314. Trace0(ERR,
  315. "GetIfEntryFromStack: Couldnt map to instance second try!!!!");
  316. return ERROR_INVALID_DATA;
  317. }
  318. ID = &(trqiInBuf.ID);
  319. ID->toi_entity.tei_entity = IF_ENTITY;
  320. ID->toi_class = INFO_CLASS_PROTOCOL;
  321. ID->toi_type = INFO_TYPE_PROVIDER;
  322. ID->toi_id = IF_MIB_STATS_ID;
  323. ID->toi_entity.tei_instance = dwInstance;
  324. dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
  325. dwOutBufLen = sizeof(IFEntry);
  326. Context = (BYTE *) &(trqiInBuf.Context[0]);
  327. ZeroMemory( Context, CONTEXT_SIZE );
  328. dwResult = AccessIfEntryInStack(GET_IF_ENTRY,
  329. dwInstance,
  330. pIfEntry);
  331. return dwResult;
  332. }
  333. // ========================================================================
  334. DWORD
  335. SetIfEntryToStack(
  336. IN MIB_IFROW *pIfEntry,
  337. IN BOOL bForceUpdate
  338. )
  339. /*++
  340. Routine Description
  341. Locks
  342. Arguments
  343. Return Value
  344. NO_ERROR
  345. --*/
  346. {
  347. DWORD dwResult,dwInstance;
  348. CheckTcpipState();
  349. if (!g_bIpConfigured)
  350. {
  351. return ERROR_NOT_SUPPORTED;
  352. }
  353. EnterCriticalSection(&g_ifLock);
  354. if(bForceUpdate)
  355. {
  356. dwResult = UpdateAdapterToIFInstanceMapping();
  357. if(dwResult isnot NO_ERROR)
  358. {
  359. LeaveCriticalSection(&g_ifLock);
  360. Trace1(ERR,
  361. "SetIfEntryToStack: Couldnt update map. Error %d",
  362. dwResult);
  363. return ERROR_CAN_NOT_COMPLETE;
  364. }
  365. dwInstance = GetIFInstanceFromAdapter(pIfEntry->dwIndex);
  366. }
  367. else
  368. {
  369. dwInstance = GetIFInstanceFromAdapter(pIfEntry->dwIndex);
  370. if(dwInstance is INVALID_IF_INSTANCE)
  371. {
  372. Trace0(ERR,
  373. "SetIfEntryToStack: Couldnt map to instance - first try");
  374. dwResult = UpdateAdapterToIFInstanceMapping();
  375. if(dwResult isnot NO_ERROR)
  376. {
  377. LeaveCriticalSection(&g_ifLock);
  378. Trace1(ERR,
  379. "SetIfEntryToStack: Couldnt update map. Error %d",
  380. dwResult);
  381. return ERROR_CAN_NOT_COMPLETE;
  382. }
  383. dwInstance = GetIFInstanceFromAdapter(pIfEntry->dwIndex);
  384. }
  385. }
  386. if(dwInstance is INVALID_IF_INSTANCE)
  387. {
  388. LeaveCriticalSection(&g_ifLock);
  389. Trace0(ERR,
  390. "SetIfEntryToStack: Couldnt map to instance");
  391. return ERROR_INVALID_DATA;
  392. }
  393. dwResult = AccessIfEntryInStack(SET_IF_ENTRY,
  394. dwInstance,
  395. pIfEntry);
  396. LeaveCriticalSection(&g_ifLock);
  397. return dwResult;
  398. }
  399. // ========================================================================
  400. /*++
  401. Routine Description
  402. Arguments
  403. dwAction Can be SET_IF or GET_IF
  404. picb the Interface Control Block
  405. lpOutBuf
  406. Return Value
  407. DWORD: NO_ERROR or some error code
  408. --*/
  409. DWORD
  410. AccessIfEntryInStack(
  411. IN DWORD dwAction,
  412. IN DWORD dwInstance,
  413. IN OUT PMIB_IFROW pIfEntry
  414. )
  415. {
  416. DWORD dwResult;
  417. DWORD dwInBufLen,dwOutBufLen;
  418. TDIObjectID *ID;
  419. BYTE *Context;
  420. switch(dwAction)
  421. {
  422. case GET_IF_ENTRY:
  423. {
  424. TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
  425. dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
  426. ID = &(trqiInBuf.ID);
  427. Context = (BYTE *) &(trqiInBuf.Context[0]);
  428. ID->toi_entity.tei_entity = IF_ENTITY;
  429. ID->toi_class = INFO_CLASS_PROTOCOL;
  430. ID->toi_type = INFO_TYPE_PROVIDER;
  431. ID->toi_id = IF_MIB_STATS_ID;
  432. dwOutBufLen = sizeof(MIB_IFROW) - FIELD_OFFSET(MIB_IFROW, dwIndex);
  433. ID->toi_entity.tei_instance = dwInstance;
  434. ZeroMemory( Context, CONTEXT_SIZE );
  435. dwResult = TCPQueryInformationEx(AF_INET,
  436. &trqiInBuf,
  437. &dwInBufLen,
  438. &(pIfEntry->dwIndex),
  439. &dwOutBufLen);
  440. break;
  441. }
  442. case SET_IF_ENTRY:
  443. {
  444. TCP_REQUEST_SET_INFORMATION_EX *lptrsiInBuf;
  445. IFEntry *pifeSetInfo;
  446. dwInBufLen = sizeof(TCP_REQUEST_SET_INFORMATION_EX) + sizeof(IFEntry) - 1;
  447. lptrsiInBuf = HeapAlloc(g_hPrivateHeap,0,dwInBufLen);
  448. if(lptrsiInBuf is NULL)
  449. {
  450. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  451. Trace1(ERR,
  452. "AccessIfEntryInStack: Error %d allocating memory",
  453. dwResult);
  454. return dwResult;
  455. }
  456. ID = &lptrsiInBuf->ID;
  457. ID->toi_class = INFO_CLASS_PROTOCOL;
  458. ID->toi_type = INFO_TYPE_PROVIDER;
  459. ID->toi_entity.tei_entity = IF_ENTITY;
  460. ID->toi_id = IF_MIB_STATS_ID;
  461. ID->toi_entity.tei_instance = dwInstance;
  462. lptrsiInBuf->BufferSize = sizeof(IFEntry);
  463. dwOutBufLen = 0;
  464. pifeSetInfo = (IFEntry*)lptrsiInBuf->Buffer;
  465. *pifeSetInfo = *(IFEntry*)(&(pIfEntry->dwIndex));
  466. dwResult = TCPSetInformationEx((PVOID) lptrsiInBuf,
  467. &dwInBufLen,
  468. NULL,
  469. &dwOutBufLen);
  470. HeapFree(g_hPrivateHeap,0,lptrsiInBuf);
  471. break;
  472. }
  473. default:
  474. dwResult = ERROR_INVALID_PARAMETER;
  475. break;
  476. }
  477. return dwResult;
  478. }
  479. DWORD
  480. NhpGetInterfaceIndexFromStack(
  481. IN PWCHAR pwszIfName,
  482. OUT PDWORD pdwIfIndex
  483. )
  484. /*++
  485. Routine Description
  486. Gets the interface index from IP
  487. Locks
  488. None
  489. Arguments
  490. pwszIfName NULL terminated unique name for interface
  491. dwIfIndex [OUT] Interface Index
  492. Return Value
  493. NO_ERROR
  494. ERROR_INVALID_PARAMETER
  495. --*/
  496. {
  497. DWORD rgdwBuffer[255], dwStatus, dwInSize, dwOutSize;
  498. PIP_GET_IF_INDEX_INFO pInfo;
  499. #ifdef _WIN95_
  500. return ERROR_NOT_SUPPORTED;
  501. #else
  502. CheckTcpipState();
  503. if (!g_bIpConfigured)
  504. {
  505. return ERROR_NOT_SUPPORTED;
  506. }
  507. //
  508. // The if name should be NULL terminated and should fit in the buffer
  509. // above
  510. //
  511. if((FIELD_OFFSET(IP_GET_IF_INDEX_INFO, Name[0]) +
  512. ((wcslen(pwszIfName) + 1) * sizeof(WCHAR))) > sizeof(rgdwBuffer))
  513. {
  514. return ERROR_INVALID_PARAMETER;
  515. }
  516. pInfo = (PIP_GET_IF_INDEX_INFO)rgdwBuffer;
  517. ZeroMemory(rgdwBuffer,
  518. sizeof(rgdwBuffer));
  519. wcscpy(pInfo->Name,
  520. pwszIfName);
  521. dwInSize = FIELD_OFFSET(IP_GET_IF_INDEX_INFO, Name[0]) +
  522. (DWORD)((wcslen(pwszIfName) + 1) * sizeof(WCHAR));
  523. dwOutSize = dwInSize;
  524. dwStatus = TCPSendIoctl(g_hIPGetDriverHandle,
  525. IOCTL_IP_GET_IF_INDEX,
  526. pInfo,
  527. &dwInSize,
  528. pInfo,
  529. &dwOutSize);
  530. *pdwIfIndex = pInfo->Index;
  531. return dwStatus;
  532. #endif
  533. }
  534. DWORD
  535. NhpAllocateAndGetInterfaceInfoFromStack(
  536. OUT IP_INTERFACE_NAME_INFO **ppTable,
  537. OUT PDWORD pdwCount,
  538. IN BOOL bOrder,
  539. IN HANDLE hHeap,
  540. IN DWORD dwFlags
  541. )
  542. /*++
  543. Routine Description
  544. Internal no fuss routine for getting the interface info.
  545. This is not an optimal routine when there are many interfaces in the
  546. stack, since the allocations become huge
  547. Locks
  548. None
  549. Arguments
  550. ppTable Allocated table
  551. pdwCount Number of entries in the allocated table
  552. bOrder If TRUE, the table is ordered
  553. hHeap Handle of heap to allocate from
  554. dwFlags Flags to use for allocation
  555. Return Value
  556. NO_ERROR
  557. --*/
  558. {
  559. MIB_IPSTATS miStats;
  560. PIP_GET_IF_NAME_INFO pInfo;
  561. DWORD i, dwResult, dwOutSize, dwInSize, dwCount;
  562. *ppTable = NULL;
  563. *pdwCount = 0;
  564. dwResult = GetIpStatsFromStack(&miStats);
  565. if(dwResult isnot NO_ERROR)
  566. {
  567. return dwResult;
  568. }
  569. dwCount = miStats.dwNumIf + OVERFLOW_COUNT;
  570. dwOutSize = FIELD_OFFSET(IP_GET_IF_NAME_INFO, Info) +
  571. (dwCount * sizeof(IP_INTERFACE_NAME_INFO));
  572. dwInSize = FIELD_OFFSET(IP_GET_IF_NAME_INFO, Info);
  573. pInfo = HeapAlloc(g_hPrivateHeap,
  574. 0,
  575. dwOutSize);
  576. if(pInfo is NULL)
  577. {
  578. return ERROR_NOT_ENOUGH_MEMORY;
  579. }
  580. pInfo->Context = 0;
  581. dwResult = TCPSendIoctl(g_hIPGetDriverHandle,
  582. IOCTL_IP_GET_IF_NAME,
  583. pInfo,
  584. &dwInSize,
  585. pInfo,
  586. &dwOutSize);
  587. if(dwResult isnot NO_ERROR)
  588. {
  589. HeapFree(g_hPrivateHeap,
  590. 0,
  591. pInfo);
  592. return dwResult;
  593. }
  594. #if DBG
  595. dwCount = (dwOutSize - FIELD_OFFSET(IP_GET_IF_NAME_INFO, Info))/sizeof(IP_INTERFACE_NAME_INFO);
  596. ASSERT(dwCount is pInfo->Count);
  597. #endif
  598. if(pInfo->Count is 0)
  599. {
  600. HeapFree(g_hPrivateHeap,
  601. 0,
  602. pInfo);
  603. return ERROR_NO_DATA;
  604. }
  605. //
  606. // Allocate for the user and copy out the info
  607. //
  608. dwOutSize = pInfo->Count * sizeof(IP_INTERFACE_NAME_INFO);
  609. *ppTable = HeapAlloc(hHeap,
  610. dwFlags,
  611. dwOutSize);
  612. if(*ppTable is NULL)
  613. {
  614. HeapFree(g_hPrivateHeap,
  615. 0,
  616. pInfo);
  617. return ERROR_NOT_ENOUGH_MEMORY;
  618. }
  619. //
  620. // Copy out the info
  621. //
  622. for(i = 0; i < pInfo->Count; i++)
  623. {
  624. //
  625. // Structure copy
  626. //
  627. (*ppTable)[i] = pInfo->Info[i];
  628. }
  629. if(pInfo->Count and bOrder)
  630. {
  631. qsort(*ppTable,
  632. pInfo->Count,
  633. sizeof(IP_INTERFACE_NAME_INFO),
  634. NhiCompareIfInfoRow);
  635. }
  636. *pdwCount = pInfo->Count;
  637. HeapFree(g_hPrivateHeap,
  638. 0,
  639. pInfo);
  640. return NO_ERROR;
  641. }
  642. // ========================================================================
  643. DWORD
  644. AllocateAndGetIpAddrTableFromStack(
  645. OUT MIB_IPADDRTABLE **ppIpAddrTable,
  646. IN BOOL bOrder,
  647. IN HANDLE hHeap,
  648. IN DWORD dwFlags
  649. )
  650. {
  651. DWORD dwResult,dwCount;
  652. DWORD dwOutBufLen;
  653. MIB_IPSTATS IpSnmpInfo;
  654. *ppIpAddrTable = NULL;
  655. //
  656. // Find out the number of entries the stack has. It returns this as part of
  657. // the IP Stats
  658. //
  659. dwResult = GetIpStatsFromStack(&IpSnmpInfo);
  660. if(dwResult isnot NO_ERROR)
  661. {
  662. Trace1(ERR,
  663. "AllocateAndGetIpAddrTableFromStack: Couldnt get Ip Stats From stack. Error %d",
  664. dwResult);
  665. return dwResult;
  666. }
  667. //
  668. // Add extra to take care of increase between the two calls
  669. //
  670. dwCount = IpSnmpInfo.dwNumAddr + OVERFLOW_COUNT;
  671. dwOutBufLen = SIZEOF_IPADDRTABLE(dwCount);
  672. *ppIpAddrTable = HeapAlloc(hHeap,
  673. dwFlags,
  674. dwOutBufLen);
  675. if(*ppIpAddrTable is NULL)
  676. {
  677. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  678. Trace1(ERR,
  679. "AllocateAndGetIpAddrTableFromStack: Couldnt allocate memory. Error %d",
  680. dwResult);
  681. return dwResult;
  682. }
  683. if(IpSnmpInfo.dwNumAddr is 0)
  684. {
  685. //
  686. // Just return an empty table.
  687. // We do this because there is some code in MIB-II agent that
  688. // expects to get a table back, even if there are not entries in
  689. // it.
  690. //
  691. (*ppIpAddrTable)->dwNumEntries = 0;
  692. return NO_ERROR;
  693. }
  694. dwResult = GetIpAddrTableFromStack(*ppIpAddrTable,
  695. dwOutBufLen,
  696. bOrder);
  697. if(dwResult isnot NO_ERROR)
  698. {
  699. Trace1(ERR,
  700. "AllocateAndGetIpAddrTableFromStack: Error %d GetIpAddrTableFromStack",
  701. dwResult);
  702. HeapFree(hHeap, dwFlags, *ppIpAddrTable);
  703. *ppIpAddrTable = NULL;
  704. }
  705. return dwResult;
  706. }
  707. // ========================================================================
  708. DWORD
  709. GetIpAddrTableFromStack(
  710. OUT PMIB_IPADDRTABLE pIpAddrTable,
  711. IN DWORD dwSize,
  712. IN BOOL bOrder
  713. )
  714. {
  715. DWORD dwOutBufLen, dwInBufLen, dwResult;
  716. BYTE *Context;
  717. TDIObjectID *ID;
  718. TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
  719. CheckTcpipState();
  720. if (!g_bIpConfigured)
  721. {
  722. return ERROR_NOT_SUPPORTED;
  723. }
  724. ID = &(trqiInBuf.ID);
  725. ID->toi_entity.tei_entity = CL_NL_ENTITY;
  726. ID->toi_entity.tei_instance = 0;
  727. ID->toi_class = INFO_CLASS_PROTOCOL;
  728. ID->toi_type = INFO_TYPE_PROVIDER;
  729. ID->toi_id = IP_MIB_ADDRTABLE_ENTRY_ID;
  730. Context = (BYTE *) &(trqiInBuf.Context[0]);
  731. ZeroMemory(Context,CONTEXT_SIZE);
  732. dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
  733. dwOutBufLen = dwSize - FIELD_OFFSET(MIB_IPADDRTABLE, table[0]);
  734. dwResult = TCPQueryInformationEx(AF_INET,
  735. &trqiInBuf,
  736. &dwInBufLen,
  737. (PVOID)(pIpAddrTable->table),
  738. &dwOutBufLen);
  739. if(dwResult isnot NO_ERROR)
  740. {
  741. Trace1(ERR,
  742. "GetIpAddrTableFromStack: Couldnt Query information from stack. Error %x",
  743. dwResult);
  744. return (dwResult);
  745. }
  746. pIpAddrTable->dwNumEntries = (dwOutBufLen / sizeof(MIB_IPADDRROW));
  747. //
  748. // Now sort the address table. Key is IP address.
  749. //
  750. if((pIpAddrTable->dwNumEntries > 0) and bOrder)
  751. {
  752. qsort(pIpAddrTable->table,
  753. pIpAddrTable->dwNumEntries,
  754. sizeof(MIB_IPADDRROW),
  755. CompareIpAddrRow);
  756. }
  757. return NO_ERROR;
  758. }
  759. // ========================================================================
  760. DWORD
  761. AllocateAndGetTcpTableFromStack(
  762. OUT MIB_TCPTABLE **ppTcpTable,
  763. IN BOOL bOrder,
  764. IN HANDLE hHeap,
  765. IN DWORD dwFlags
  766. )
  767. {
  768. DWORD dwResult,dwCount;
  769. DWORD dwOutBufLen;
  770. MIB_TCPSTATS TcpInfo;
  771. *ppTcpTable = NULL;
  772. //
  773. // Find out the number of entries the stack has. It returns this as part of
  774. // the Tcp Stats
  775. //
  776. dwResult = GetTcpStatsFromStack(&TcpInfo);
  777. if(dwResult isnot NO_ERROR)
  778. {
  779. Trace1(ERR,
  780. "AllocateAndGetTcpTableFromStack: Couldnt get Tcp Stats From stack. Error %d",
  781. dwResult);
  782. return dwResult;
  783. }
  784. dwCount = TcpInfo.dwNumConns + OVERFLOW_COUNT;
  785. dwOutBufLen = SIZEOF_TCPTABLE(dwCount);
  786. *ppTcpTable = HeapAlloc(hHeap,
  787. dwFlags,
  788. dwOutBufLen);
  789. if(*ppTcpTable is NULL)
  790. {
  791. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  792. Trace1(ERR,
  793. "AllocateAndGetTcpTableFromStack: Couldnt allocate memory. Error %d",
  794. dwResult);
  795. return dwResult;
  796. }
  797. if(TcpInfo.dwNumConns is 0)
  798. {
  799. (*ppTcpTable)->dwNumEntries = 0;
  800. return NO_ERROR;
  801. }
  802. dwResult = GetTcpTableFromStack(*ppTcpTable,
  803. dwOutBufLen,
  804. bOrder);
  805. if(dwResult isnot NO_ERROR)
  806. {
  807. Trace1(ERR,
  808. "AllocateAndGetTcpTableFromStack: Error %d GetTcpTableFromStack",
  809. dwResult);
  810. HeapFree(hHeap, dwFlags, *ppTcpTable);
  811. *ppTcpTable = NULL;
  812. }
  813. return dwResult;
  814. }
  815. // ========================================================================
  816. DWORD
  817. GetTcpTableFromStack(
  818. OUT PMIB_TCPTABLE pTcpTable,
  819. IN DWORD dwSize,
  820. IN BOOL bOrder
  821. )
  822. {
  823. DWORD dwInBufLen, dwOutBufLen, dwResult;
  824. TDIObjectID *ID;
  825. BYTE *Context;
  826. TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
  827. CheckTcpipState();
  828. if (!g_bIpConfigured)
  829. {
  830. return ERROR_NOT_SUPPORTED;
  831. }
  832. ID = &(trqiInBuf.ID);
  833. ID->toi_entity.tei_entity = CO_TL_ENTITY;
  834. ID->toi_entity.tei_instance = 0;
  835. ID->toi_class = INFO_CLASS_PROTOCOL;
  836. ID->toi_type = INFO_TYPE_PROVIDER;
  837. ID->toi_id = TCP_MIB_TABLE_ID;
  838. Context = (BYTE *) &(trqiInBuf.Context[0]);
  839. ZeroMemory( Context, CONTEXT_SIZE );
  840. dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
  841. dwOutBufLen = dwSize - FIELD_OFFSET(MIB_TCPTABLE, table[0]);
  842. dwResult = TCPQueryInformationEx(AF_INET,
  843. &trqiInBuf,
  844. &dwInBufLen,
  845. (PVOID)(pTcpTable->table),
  846. &dwOutBufLen);
  847. if(dwResult isnot NO_ERROR)
  848. {
  849. Trace1(ERR,
  850. "GetTcpTableFromStack: Couldnt query stack. Error %x",
  851. dwResult);
  852. return dwResult;
  853. }
  854. pTcpTable->dwNumEntries = (dwOutBufLen/sizeof(MIB_TCPROW));
  855. if((pTcpTable->dwNumEntries > 0) and bOrder)
  856. {
  857. qsort(pTcpTable->table,
  858. pTcpTable->dwNumEntries,
  859. sizeof(MIB_TCPROW),
  860. CompareTcpRow);
  861. }
  862. return NO_ERROR;
  863. }
  864. // ========================================================================
  865. DWORD
  866. SetTcpEntryToStack(
  867. IN PMIB_TCPROW pTcpRow
  868. )
  869. {
  870. TCP_REQUEST_SET_INFORMATION_EX *ptrsiInBuf;
  871. TDIObjectID *ID;
  872. MIB_TCPROW *copyInfo;
  873. DWORD dwInBufLen,dwOutBufLen,dwResult;
  874. #define REQ_SIZE sizeof(TCP_REQUEST_SET_INFORMATION_EX) + \
  875. sizeof(MIB_TCPROW) - 1
  876. BYTE rgbyBuffer[REQ_SIZE + 4]; // +4 to avoid any alignment problems
  877. ptrsiInBuf = (TCP_REQUEST_SET_INFORMATION_EX *)rgbyBuffer;
  878. dwInBufLen = REQ_SIZE;
  879. #undef REQ_SIZE
  880. CheckTcpipState();
  881. if (!g_bIpConfigured)
  882. {
  883. return ERROR_NOT_SUPPORTED;
  884. }
  885. ID = &ptrsiInBuf->ID;
  886. ID->toi_class = INFO_CLASS_PROTOCOL;
  887. ID->toi_type = INFO_TYPE_PROVIDER;
  888. ID->toi_entity.tei_entity = CO_TL_ENTITY;
  889. ID->toi_id = TCP_MIB_TABLE_ID;
  890. ID->toi_entity.tei_instance = 0;
  891. copyInfo = (MIB_TCPROW*)ptrsiInBuf->Buffer;
  892. *copyInfo = *pTcpRow;
  893. ptrsiInBuf->BufferSize = sizeof(TCPConnTableEntry);
  894. dwResult = TCPSetInformationEx((PVOID)ptrsiInBuf,
  895. &dwInBufLen,
  896. NULL,
  897. &dwOutBufLen);
  898. return dwResult;
  899. }
  900. // ========================================================================
  901. DWORD
  902. AllocateAndGetUdpTableFromStack(
  903. OUT MIB_UDPTABLE **ppUdpTable,
  904. IN BOOL bOrder,
  905. IN HANDLE hHeap,
  906. IN DWORD dwFlags
  907. )
  908. {
  909. DWORD dwResult, dwCount, dwOutBufLen;
  910. MIB_UDPSTATS UdpInfo;
  911. *ppUdpTable = NULL;
  912. //
  913. // Find out the number of entries the stack has. It returns this as part of
  914. // the Tcp Stats
  915. //
  916. dwResult = GetUdpStatsFromStack(&UdpInfo);
  917. if(dwResult isnot NO_ERROR)
  918. {
  919. Trace1(ERR,
  920. "AllocateAndGetUdpTableFromStack: Couldnt get Udp Stats From stack. Error %d",
  921. dwResult);
  922. return dwResult;
  923. }
  924. dwCount = UdpInfo.dwNumAddrs + OVERFLOW_COUNT;
  925. dwOutBufLen = SIZEOF_UDPTABLE(dwCount);
  926. *ppUdpTable = HeapAlloc(hHeap,
  927. dwFlags,
  928. dwOutBufLen);
  929. if(*ppUdpTable is NULL)
  930. {
  931. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  932. Trace1(ERR,
  933. "AllocateAndGetUdpTableFromStack: Couldnt allocate memory. Error %d",
  934. dwResult);
  935. return dwResult;
  936. }
  937. if(UdpInfo.dwNumAddrs is 0)
  938. {
  939. (*ppUdpTable)->dwNumEntries = 0;
  940. return NO_ERROR;
  941. }
  942. dwResult = GetUdpTableFromStack(*ppUdpTable,
  943. dwOutBufLen,
  944. bOrder);
  945. if(dwResult isnot NO_ERROR)
  946. {
  947. Trace1(ERR,
  948. "AllocateAndGetUdpTableFromStack: Error %d GetUdpTableFromStack",
  949. dwResult);
  950. HeapFree(hHeap, dwFlags, *ppUdpTable);
  951. *ppUdpTable = NULL;
  952. }
  953. return dwResult;
  954. }
  955. // ========================================================================
  956. DWORD
  957. GetUdpTableFromStack(
  958. OUT PMIB_UDPTABLE pUdpTable,
  959. IN DWORD dwSize,
  960. IN BOOL bOrder
  961. )
  962. {
  963. DWORD dwInBufLen, dwOutBufLen, dwResult;
  964. BYTE *Context;
  965. TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
  966. TDIObjectID *ID;
  967. CheckTcpipState();
  968. if (!g_bIpConfigured)
  969. {
  970. return ERROR_NOT_SUPPORTED;
  971. }
  972. ID = &(trqiInBuf.ID);
  973. ID->toi_entity.tei_entity = CL_TL_ENTITY;
  974. ID->toi_entity.tei_instance = 0;
  975. ID->toi_class = INFO_CLASS_PROTOCOL;
  976. ID->toi_type = INFO_TYPE_PROVIDER;
  977. ID->toi_id = UDP_MIB_TABLE_ID;
  978. Context = (BYTE *) &(trqiInBuf.Context[0]);
  979. ZeroMemory( Context, CONTEXT_SIZE );
  980. dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
  981. dwOutBufLen = dwSize - FIELD_OFFSET(MIB_UDPTABLE, table[0]);
  982. dwResult = TCPQueryInformationEx(AF_INET,
  983. &trqiInBuf,
  984. &dwInBufLen,
  985. (PVOID)(pUdpTable->table),
  986. &dwOutBufLen);
  987. if(dwResult isnot NO_ERROR)
  988. {
  989. Trace1(ERR,
  990. "GetUdpTableFromStack: Couldnt query TCP information. Error %d",
  991. dwResult);
  992. return dwResult;
  993. }
  994. pUdpTable->dwNumEntries = (dwOutBufLen / sizeof(MIB_UDPROW));
  995. //
  996. // Now sort the UDP connection table. Keys are: local address, and local
  997. // port.
  998. //
  999. if((pUdpTable->dwNumEntries > 0) and bOrder)
  1000. {
  1001. qsort(pUdpTable->table,
  1002. pUdpTable->dwNumEntries,
  1003. sizeof(MIB_UDPROW),
  1004. CompareUdpRow);
  1005. }
  1006. TraceLeave("GetUdpTableFromStack");
  1007. return NO_ERROR;
  1008. }
  1009. // ========================================================================
  1010. DWORD
  1011. AllocateAndGetIpForwardTableFromStack(
  1012. OUT MIB_IPFORWARDTABLE **ppForwardTable,
  1013. IN BOOL bOrder,
  1014. IN HANDLE hHeap,
  1015. IN DWORD dwFlags
  1016. )
  1017. {
  1018. DWORD dwResult = NO_ERROR,dwCount,dwOutBufLen;
  1019. MIB_IPSTATS IpInfo;
  1020. DWORD dwLoops;
  1021. TraceEnter("AllocateAndGetIpForwardTableFromStack");
  1022. *ppForwardTable = NULL;
  1023. dwLoops = 0;
  1024. while(dwLoops <= 1)
  1025. {
  1026. //
  1027. // Find out the number of entries the stack has. It returns this as
  1028. // part of the IP Stats
  1029. //
  1030. dwResult = GetIpStatsFromStack(&IpInfo);
  1031. if(dwResult isnot NO_ERROR)
  1032. {
  1033. Trace1(ERR,"Couldnt get Ip Stats From stack. Error %d",
  1034. dwResult);
  1035. return dwResult;
  1036. }
  1037. dwCount = IpInfo.dwNumRoutes + ROUTE_OVERFLOW_COUNT + (dwLoops * 50);
  1038. dwOutBufLen = SIZEOF_IPFORWARDTABLE(dwCount);
  1039. *ppForwardTable = HeapAlloc(hHeap,
  1040. dwFlags,
  1041. dwOutBufLen);
  1042. if(*ppForwardTable is NULL)
  1043. {
  1044. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  1045. Trace1(ERR,
  1046. "AllocateAndGetIpForwardTableFromStack: Couldnt allocate memory. Error %d",
  1047. dwResult);
  1048. return dwResult;
  1049. }
  1050. if(IpInfo.dwNumRoutes is 0)
  1051. {
  1052. (*ppForwardTable)->dwNumEntries = 0;
  1053. TraceLeave("AllocateAndGetIPForwardTableFromStack");
  1054. return NO_ERROR;
  1055. }
  1056. dwResult = GetIpForwardTableFromStack(*ppForwardTable,
  1057. dwOutBufLen,
  1058. bOrder);
  1059. if(dwResult isnot NO_ERROR)
  1060. {
  1061. Trace1(ERR,
  1062. "AllocateAndGetIpForwardTableFromStack: Error %d GetIpForwardTableFromStack",
  1063. dwResult);
  1064. HeapFree(hHeap,
  1065. dwFlags,
  1066. *ppForwardTable);
  1067. *ppForwardTable = NULL;
  1068. }
  1069. if(dwResult is ERROR_MORE_DATA)
  1070. {
  1071. dwLoops++;
  1072. }
  1073. else
  1074. {
  1075. break;
  1076. }
  1077. }
  1078. return dwResult;
  1079. }
  1080. // ========================================================================
  1081. DWORD
  1082. GetIpForwardTableFromStack(
  1083. OUT PMIB_IPFORWARDTABLE pForwardTable,
  1084. IN DWORD dwSize,
  1085. IN BOOL bOrder
  1086. )
  1087. {
  1088. DWORD dwInBufLen, dwOutBufLen, dwNumRoutes;
  1089. DWORD i, dwCount, dwResult;
  1090. UCHAR *Context;
  1091. TDIObjectID *ID;
  1092. MIB_IPSTATS IpInfo;
  1093. IPRouteEntry *pTempTable;
  1094. TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
  1095. //
  1096. // How many routes can the input buffer hold?
  1097. //
  1098. dwNumRoutes = (dwSize - FIELD_OFFSET(MIB_IPFORWARDTABLE,table[0]))/sizeof(MIB_IPFORWARDROW);
  1099. //
  1100. // Find out the number of entries the stack has. It returns this as part of
  1101. // the IP Stats
  1102. //
  1103. dwResult = GetIpStatsFromStack(&IpInfo);
  1104. if(dwResult isnot NO_ERROR)
  1105. {
  1106. Trace1(ERR,"Couldnt get Ip Stats From stack. Error %d",
  1107. dwResult);
  1108. return dwResult;
  1109. }
  1110. dwCount = IpInfo.dwNumRoutes + ROUTE_OVERFLOW_COUNT;
  1111. dwOutBufLen = dwCount * sizeof(IPRouteEntry);
  1112. pTempTable = HeapAlloc(g_hPrivateHeap,
  1113. 0,
  1114. dwOutBufLen);
  1115. if(pTempTable is NULL)
  1116. {
  1117. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  1118. Trace1(ERR,
  1119. "Couldnt allocate memory for temporary table. Error %d",
  1120. dwResult);
  1121. return dwResult;
  1122. }
  1123. ID = &(trqiInBuf.ID);
  1124. ID->toi_entity.tei_entity = CL_NL_ENTITY;
  1125. ID->toi_entity.tei_instance = 0;
  1126. ID->toi_class = INFO_CLASS_PROTOCOL;
  1127. ID->toi_type = INFO_TYPE_PROVIDER;
  1128. ID->toi_id = IP_MIB_RTTABLE_ENTRY_ID;
  1129. Context = (BYTE *) &(trqiInBuf.Context[0]);
  1130. ZeroMemory(Context,
  1131. CONTEXT_SIZE );
  1132. dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
  1133. dwResult = TCPQueryInformationEx(AF_INET,
  1134. &trqiInBuf,
  1135. &dwInBufLen,
  1136. (PVOID)pTempTable,
  1137. &dwOutBufLen );
  1138. if(dwResult isnot NO_ERROR)
  1139. {
  1140. HeapFree(g_hPrivateHeap,
  1141. 0,
  1142. pTempTable);
  1143. Trace1(ERR,"Couldnt query stack. Error %x",
  1144. dwResult);
  1145. TraceLeave("GetIpForwardTableFromStack");
  1146. return dwResult;
  1147. }
  1148. dwCount = (dwOutBufLen / sizeof(IPRouteEntry));
  1149. if(dwNumRoutes >= dwCount)
  1150. {
  1151. //
  1152. // There is space for all the entries returned by the stack
  1153. //
  1154. pForwardTable->dwNumEntries = dwCount;
  1155. }
  1156. else
  1157. {
  1158. //
  1159. // Take the first dwNumRoute entries
  1160. //
  1161. pForwardTable->dwNumEntries = dwNumRoutes;
  1162. dwResult = ERROR_MORE_DATA;
  1163. }
  1164. for (i = 0; i < pForwardTable->dwNumEntries; i++ )
  1165. {
  1166. ConvertRouteToForward(&(pTempTable[i]),
  1167. &(pForwardTable->table[i]));
  1168. }
  1169. HeapFree(g_hPrivateHeap,
  1170. 0,
  1171. pTempTable);
  1172. if((pForwardTable->dwNumEntries > 0) and bOrder)
  1173. {
  1174. qsort(pForwardTable->table,
  1175. pForwardTable->dwNumEntries,
  1176. sizeof(MIB_IPFORWARDROW),
  1177. CompareIpForwardRow);
  1178. }
  1179. TraceLeave("GetIPForwardTableFromStack");
  1180. return dwResult;
  1181. }
  1182. // ========================================================================
  1183. DWORD
  1184. AllocateAndGetIpNetTableFromStack(
  1185. OUT MIB_IPNETTABLE **ppNetTable,
  1186. IN BOOL bOrder,
  1187. IN HANDLE hHeap,
  1188. IN DWORD dwFlags,
  1189. IN BOOL bForceUpdate
  1190. )
  1191. {
  1192. DWORD dwResult, dwOutBufLen, dwNetEntryCount;
  1193. DWORD dwCount;
  1194. TraceEnter("AllocateAndGetIpNetTableFromStack");
  1195. CheckTcpipState();
  1196. if (!g_bIpConfigured)
  1197. {
  1198. return ERROR_NOT_SUPPORTED;
  1199. }
  1200. *ppNetTable = NULL;
  1201. EnterCriticalSection(&g_ipNetLock);
  1202. dwResult = GetArpEntryCount(&dwNetEntryCount);
  1203. LeaveCriticalSection(&g_ipNetLock);
  1204. if(dwResult isnot NO_ERROR)
  1205. {
  1206. Trace1(ERR,
  1207. "AllocateAndGetIpNetTableFromStack: Couldnt query Information from stack. Error %x",
  1208. dwResult);
  1209. TraceLeave("AllocateAndGetIpNetTableFromStack");
  1210. return dwResult;
  1211. }
  1212. //
  1213. // This is generally a memory hog
  1214. //
  1215. dwCount = dwNetEntryCount + (g_dwNumArpEntEntries) * OVERFLOW_COUNT;
  1216. dwOutBufLen = SIZEOF_IPNETTABLE(dwCount);
  1217. *ppNetTable = HeapAlloc(hHeap,
  1218. dwFlags,
  1219. dwOutBufLen);
  1220. if(*ppNetTable is NULL)
  1221. {
  1222. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  1223. Trace1(ERR,
  1224. "AllocateAndGetIpNetTableFromStack: Couldnt allocate memory. Error %d",
  1225. dwResult);
  1226. TraceLeave("AllocateAndGetIpNetTableFromStack");
  1227. return dwResult;
  1228. }
  1229. if(dwNetEntryCount is 0)
  1230. {
  1231. (*ppNetTable)->dwNumEntries = 0;
  1232. TraceLeave("AllocateAndGetIpNetTableFromStack");
  1233. return NO_ERROR;
  1234. }
  1235. dwResult = GetIpNetTableFromStack(*ppNetTable,
  1236. dwOutBufLen,
  1237. bOrder,
  1238. bForceUpdate);
  1239. if(dwResult isnot NO_ERROR)
  1240. {
  1241. Trace1(ERR,
  1242. "AllocateAndGetIpNetTableFromStack: Error %d GetIpNetTableFromStack",
  1243. dwResult);
  1244. HeapFree(hHeap, dwFlags, *ppNetTable);
  1245. *ppNetTable = NULL;
  1246. }
  1247. TraceLeave("AllocateAndGetIpNetTableFromStack");
  1248. return dwResult;
  1249. }
  1250. // ========================================================================
  1251. DWORD
  1252. GetIpNetTableFromStack(
  1253. OUT PMIB_IPNETTABLE pNetTable,
  1254. IN DWORD dwSize,
  1255. IN BOOL bOrder,
  1256. IN BOOL bForceUpdate
  1257. )
  1258. {
  1259. TDIObjectID *ID;
  1260. PBYTE pbyEnd, pbyStart, Context;
  1261. DWORD dwNumAdded,dwValidNetEntries;
  1262. DWORD dwInBufLen,dwOutBufLen;
  1263. DWORD dwResult, dwErr, i;
  1264. TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
  1265. CheckTcpipState();
  1266. if (!g_bIpConfigured)
  1267. {
  1268. return ERROR_NOT_SUPPORTED;
  1269. }
  1270. dwValidNetEntries = 0;
  1271. dwErr = NO_ERROR;
  1272. //
  1273. // Now query the stack for the IpNet tables of each of the arp entities
  1274. //
  1275. Context = (BYTE *) &(trqiInBuf.Context[0]);
  1276. ZeroMemory( Context, CONTEXT_SIZE );
  1277. ID = &(trqiInBuf.ID);
  1278. ID->toi_entity.tei_entity = AT_ENTITY;
  1279. ID->toi_type = INFO_TYPE_PROVIDER;
  1280. ID->toi_class = INFO_CLASS_PROTOCOL;
  1281. ID->toi_id = AT_MIB_ADDRXLAT_ENTRY_ID;
  1282. dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
  1283. pbyStart = (PBYTE)(pNetTable->table);
  1284. pbyEnd = (PBYTE)((PBYTE)pNetTable + dwSize);
  1285. EnterCriticalSection(&g_ipNetLock);
  1286. if(bForceUpdate or
  1287. (g_dwLastArpUpdateTime is 0) or
  1288. ((GetCurrentTime() - g_dwLastArpUpdateTime) > ARP_CACHE_LIFE))
  1289. {
  1290. dwResult = UpdateAdapterToATInstanceMapping();
  1291. if(dwResult isnot NO_ERROR)
  1292. {
  1293. LeaveCriticalSection(&g_ipNetLock);
  1294. Trace1(ERR,
  1295. "GetIpNetTableFromStack: Couldnt update AT Map. Error %d",
  1296. dwResult);
  1297. TraceLeave("GetIpNetTableFromStack");
  1298. return ERROR_CAN_NOT_COMPLETE;
  1299. }
  1300. }
  1301. for(i = 0; i < g_dwNumArpEntEntries; i++ )
  1302. {
  1303. //
  1304. // If the current buffer wont hold even one row, stop
  1305. //
  1306. dwOutBufLen = (DWORD)(pbyEnd - pbyStart);
  1307. if(dwOutBufLen < sizeof(MIB_IPNETROW))
  1308. {
  1309. dwErr = ERROR_MORE_DATA;
  1310. break;
  1311. }
  1312. ID->toi_entity.tei_instance = g_pdwArpEntTable[i];
  1313. ZeroMemory(Context, CONTEXT_SIZE);
  1314. dwResult = TCPQueryInformationEx(AF_INET,
  1315. &trqiInBuf,
  1316. &dwInBufLen,
  1317. (PVOID)pbyStart,
  1318. &dwOutBufLen);
  1319. if (dwResult isnot NO_ERROR)
  1320. {
  1321. Trace1(ERR,"Query to Arp Entity id %d for ARP Table failed. Error %d",
  1322. dwResult);
  1323. dwErr = ERROR_MORE_DATA;
  1324. continue;
  1325. }
  1326. dwNumAdded = dwOutBufLen/(sizeof(MIB_IPNETROW));
  1327. pbyStart += dwOutBufLen;
  1328. dwValidNetEntries += dwNumAdded;
  1329. }
  1330. pNetTable->dwNumEntries = dwValidNetEntries;
  1331. //
  1332. // Now sort the net table. Keys are IF index and address
  1333. //
  1334. if((dwValidNetEntries > 0) and bOrder)
  1335. {
  1336. qsort(pNetTable->table,
  1337. dwValidNetEntries,
  1338. sizeof(MIB_IPNETROW),
  1339. CompareIpNetRow);
  1340. }
  1341. LeaveCriticalSection(&g_ipNetLock);
  1342. TraceLeave("GetIpNetTableFromStack");
  1343. return dwErr;
  1344. }
  1345. // ========================================================================
  1346. DWORD
  1347. GetIpStatsFromStackEx(
  1348. OUT PMIB_IPSTATS pIpStats,
  1349. IN DWORD dwFamily
  1350. )
  1351. {
  1352. DWORD dwResult, dwInBufLen, dwOutBufLen;
  1353. TDIObjectID *ID;
  1354. BYTE *Context;
  1355. TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
  1356. TraceEnter("GetIpStatsFromStackEx");
  1357. if ((dwFamily != AF_INET) && (dwFamily != AF_INET6))
  1358. {
  1359. return ERROR_INVALID_PARAMETER;
  1360. }
  1361. CheckTcpipState();
  1362. if (((dwFamily == AF_INET) && !g_bIpConfigured) ||
  1363. ((dwFamily == AF_INET6) && !g_bIp6Configured))
  1364. {
  1365. return ERROR_NOT_SUPPORTED;
  1366. }
  1367. dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
  1368. dwOutBufLen = sizeof(MIB_IPSTATS);
  1369. ID = &(trqiInBuf.ID);
  1370. ID->toi_entity.tei_entity = CL_NL_ENTITY;
  1371. ID->toi_entity.tei_instance = 0;
  1372. ID->toi_class = INFO_CLASS_PROTOCOL;
  1373. ID->toi_type = INFO_TYPE_PROVIDER;
  1374. ID->toi_id = IP_MIB_STATS_ID;
  1375. Context = (BYTE *) &(trqiInBuf.Context[0]);
  1376. ZeroMemory(Context, CONTEXT_SIZE);
  1377. dwResult = TCPQueryInformationEx(dwFamily,
  1378. &trqiInBuf,
  1379. &dwInBufLen,
  1380. (PVOID)pIpStats,
  1381. &dwOutBufLen);
  1382. if (dwResult isnot NO_ERROR)
  1383. {
  1384. Trace1(ERR,"Couldnt query stack. Error %d",
  1385. dwResult);
  1386. TraceLeave("GetIpStatsFromStackEx");
  1387. return dwResult;
  1388. }
  1389. TraceLeave("GetIpStatsFromStackEx");
  1390. return NO_ERROR;
  1391. }
  1392. // ========================================================================
  1393. DWORD
  1394. GetIpStatsFromStack(
  1395. OUT PMIB_IPSTATS pIpStats
  1396. )
  1397. {
  1398. return GetIpStatsFromStackEx(pIpStats, AF_INET);
  1399. }
  1400. // ========================================================================
  1401. DWORD
  1402. SetIpStatsToStack(
  1403. IN PMIB_IPSTATS pIpStats
  1404. )
  1405. {
  1406. TCP_REQUEST_SET_INFORMATION_EX *ptrsiInBuf;
  1407. TDIObjectID *ID;
  1408. MIB_IPSTATS *copyInfo;
  1409. DWORD dwInBufLen,dwOutBufLen,dwResult;
  1410. #define REQ_SIZE sizeof(TCP_REQUEST_SET_INFORMATION_EX) + \
  1411. sizeof(MIB_IPSTATS) - 1
  1412. BYTE rgbyBuffer[REQ_SIZE + 4]; // +4 to avoid any alignment problems
  1413. ptrsiInBuf = (TCP_REQUEST_SET_INFORMATION_EX *)rgbyBuffer;
  1414. dwInBufLen = REQ_SIZE;
  1415. #undef REQ_SIZE
  1416. TraceEnter("SetIpStatsToStack");
  1417. CheckTcpipState();
  1418. if (!g_bIpConfigured)
  1419. {
  1420. return ERROR_NOT_SUPPORTED;
  1421. }
  1422. ID = &ptrsiInBuf->ID;
  1423. ID->toi_class = INFO_CLASS_PROTOCOL;
  1424. ID->toi_type = INFO_TYPE_PROVIDER;
  1425. ID->toi_entity.tei_entity = CL_NL_ENTITY;
  1426. ID->toi_id = IP_MIB_STATS_ID;
  1427. ID->toi_entity.tei_instance = 0;
  1428. copyInfo = (MIB_IPSTATS*)ptrsiInBuf->Buffer;
  1429. *copyInfo = *pIpStats;
  1430. ptrsiInBuf->BufferSize = sizeof(IPSNMPInfo);
  1431. dwResult = TCPSetInformationEx((PVOID)ptrsiInBuf,
  1432. &dwInBufLen,
  1433. NULL,
  1434. &dwOutBufLen);
  1435. TraceLeave("SetIpStatsToStack");
  1436. return dwResult;
  1437. }
  1438. // ========================================================================
  1439. DWORD
  1440. GetIcmpStatsFromStackEx(
  1441. OUT PVOID pIcmpStats,
  1442. IN DWORD dwFamily
  1443. )
  1444. {
  1445. DWORD dwResult;
  1446. DWORD dwInBufLen;
  1447. DWORD dwOutBufLen;
  1448. TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
  1449. TDIObjectID *ID;
  1450. BYTE *Context;
  1451. TraceEnter("GetIcmpStatsFromStackEx");
  1452. if ((dwFamily != AF_INET) && (dwFamily != AF_INET6))
  1453. {
  1454. return ERROR_INVALID_PARAMETER;
  1455. }
  1456. CheckTcpipState();
  1457. if (((dwFamily == AF_INET) && !g_bIpConfigured) ||
  1458. ((dwFamily == AF_INET6) && !g_bIp6Configured))
  1459. {
  1460. return ERROR_NOT_SUPPORTED;
  1461. }
  1462. dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
  1463. ID = &(trqiInBuf.ID);
  1464. ID->toi_entity.tei_instance = 0;
  1465. ID->toi_class = INFO_CLASS_PROTOCOL;
  1466. ID->toi_type = INFO_TYPE_PROVIDER;
  1467. if (dwFamily == AF_INET)
  1468. {
  1469. ID->toi_entity.tei_entity = ER_ENTITY;
  1470. ID->toi_id = ICMP_MIB_STATS_ID;
  1471. dwOutBufLen = sizeof(MIB_ICMP);
  1472. }
  1473. else
  1474. {
  1475. ID->toi_entity.tei_entity = CL_NL_ENTITY;
  1476. ID->toi_id = ICMP6_MIB_STATS_ID;
  1477. dwOutBufLen = sizeof(ICMPv6SNMPInfo);
  1478. }
  1479. Context = (BYTE *) &(trqiInBuf.Context[0]);
  1480. ZeroMemory(Context,CONTEXT_SIZE);
  1481. dwResult = TCPQueryInformationEx(dwFamily,
  1482. &trqiInBuf,
  1483. &dwInBufLen,
  1484. (PVOID)pIcmpStats,
  1485. &dwOutBufLen);
  1486. if (dwResult isnot NO_ERROR)
  1487. {
  1488. Trace1(ERR,"Couldnt query stack. Error %x",
  1489. dwResult);
  1490. TraceLeave("GetIcmpStatsFromStackEx");
  1491. return dwResult;
  1492. }
  1493. TraceLeave("GetIcmpStatsFromStackEx");
  1494. return NO_ERROR;
  1495. }
  1496. // ========================================================================
  1497. DWORD
  1498. GetIcmpStatsFromStack(
  1499. OUT PMIB_ICMP pIcmpStats
  1500. )
  1501. {
  1502. return GetIcmpStatsFromStackEx(pIcmpStats, AF_INET);
  1503. }
  1504. // ========================================================================
  1505. DWORD
  1506. GetUdpStatsFromStackEx(
  1507. OUT PMIB_UDPSTATS pUdpStats,
  1508. IN DWORD dwFamily
  1509. )
  1510. {
  1511. DWORD dwResult;
  1512. DWORD dwInBufLen;
  1513. DWORD dwOutBufLen;
  1514. TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
  1515. TDIObjectID *ID;
  1516. BYTE *Context;
  1517. TraceEnter("GetUdpStatsFromStack");
  1518. if ((dwFamily != AF_INET) && (dwFamily != AF_INET6))
  1519. {
  1520. return ERROR_INVALID_PARAMETER;
  1521. }
  1522. CheckTcpipState();
  1523. if (((dwFamily == AF_INET) && !g_bIpConfigured) ||
  1524. ((dwFamily == AF_INET6) && !g_bIp6Configured))
  1525. {
  1526. return ERROR_NOT_SUPPORTED;
  1527. }
  1528. dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
  1529. dwOutBufLen = sizeof(MIB_UDPSTATS);
  1530. ID = &(trqiInBuf.ID);
  1531. ID->toi_entity.tei_entity = CL_TL_ENTITY;
  1532. ID->toi_entity.tei_instance = 0;
  1533. ID->toi_class = INFO_CLASS_PROTOCOL;
  1534. ID->toi_type = INFO_TYPE_PROVIDER;
  1535. ID->toi_id = UDP_MIB_STAT_ID;
  1536. Context = (BYTE *) &(trqiInBuf.Context[0]);
  1537. ZeroMemory( Context, CONTEXT_SIZE );
  1538. dwResult = TCPQueryInformationEx(dwFamily,
  1539. &trqiInBuf,
  1540. &dwInBufLen,
  1541. (PVOID)pUdpStats,
  1542. &dwOutBufLen );
  1543. if(dwResult isnot NO_ERROR)
  1544. {
  1545. Trace1(ERR,"Couldnt query stack. Error %x",
  1546. dwResult);
  1547. TraceLeave("GetUdpStatsFromStack");
  1548. return dwResult;
  1549. }
  1550. TraceLeave("GetUdpStatsFromStack");
  1551. return NO_ERROR;
  1552. }
  1553. // ========================================================================
  1554. DWORD
  1555. GetUdpStatsFromStack(
  1556. OUT PMIB_UDPSTATS pUdpStats
  1557. )
  1558. {
  1559. return GetUdpStatsFromStackEx(pUdpStats, AF_INET);
  1560. }
  1561. // ========================================================================
  1562. DWORD
  1563. GetTcpStatsFromStackEx(
  1564. OUT PMIB_TCPSTATS pTcpStats,
  1565. IN DWORD dwFamily
  1566. )
  1567. {
  1568. DWORD dwResult;
  1569. DWORD dwInBufLen;
  1570. DWORD dwOutBufLen;
  1571. TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
  1572. TDIObjectID *ID;
  1573. BYTE *Context;
  1574. TraceEnter("GetTcpStatsFromStack");
  1575. if ((dwFamily != AF_INET) && (dwFamily != AF_INET6))
  1576. {
  1577. return ERROR_INVALID_PARAMETER;
  1578. }
  1579. CheckTcpipState();
  1580. if (((dwFamily == AF_INET) && !g_bIpConfigured) ||
  1581. ((dwFamily == AF_INET6) && !g_bIp6Configured))
  1582. {
  1583. return ERROR_NOT_SUPPORTED;
  1584. }
  1585. dwInBufLen = sizeof( TCP_REQUEST_QUERY_INFORMATION_EX );
  1586. dwOutBufLen = sizeof( MIB_TCPSTATS );
  1587. ID = &(trqiInBuf.ID);
  1588. ID->toi_entity.tei_entity = CO_TL_ENTITY;
  1589. ID->toi_entity.tei_instance = 0;
  1590. ID->toi_class = INFO_CLASS_PROTOCOL;
  1591. ID->toi_type = INFO_TYPE_PROVIDER;
  1592. ID->toi_id = TCP_MIB_STAT_ID;
  1593. Context = (BYTE *) &(trqiInBuf.Context[0]);
  1594. ZeroMemory(Context,CONTEXT_SIZE);
  1595. dwResult = TCPQueryInformationEx(dwFamily,
  1596. &trqiInBuf,
  1597. &dwInBufLen,
  1598. (PVOID)pTcpStats,
  1599. &dwOutBufLen );
  1600. if(dwResult isnot NO_ERROR)
  1601. {
  1602. Trace1(ERR,"Couldnt query stack. Error %x",
  1603. dwResult);
  1604. TraceLeave("GetTcpStatsFromStack");
  1605. return dwResult;
  1606. }
  1607. TraceLeave("GetTcpStatsFromStack");
  1608. return NO_ERROR;
  1609. }
  1610. // ========================================================================
  1611. DWORD
  1612. GetTcpStatsFromStack(
  1613. OUT PMIB_TCPSTATS pTcpStats
  1614. )
  1615. {
  1616. return GetTcpStatsFromStackEx(pTcpStats, AF_INET);
  1617. }
  1618. // ========================================================================
  1619. DWORD
  1620. SetIpNetEntryToStack(
  1621. IN MIB_IPNETROW *pNetRow,
  1622. IN BOOL bForceUpdate
  1623. )
  1624. {
  1625. TCP_REQUEST_SET_INFORMATION_EX *ptrsiInBuf;
  1626. TDIObjectID *ID;
  1627. MIB_IPNETROW *copyInfo;
  1628. DWORD dwInBufLen,dwOutBufLen,dwResult;
  1629. DWORD dwInstance;
  1630. #define REQ_SIZE sizeof(TCP_REQUEST_SET_INFORMATION_EX) + \
  1631. sizeof(MIB_IPNETROW) - 1
  1632. BYTE rgbyBuffer[REQ_SIZE + 4]; // +4 to avoid any alignment problems
  1633. ptrsiInBuf = (TCP_REQUEST_SET_INFORMATION_EX *)rgbyBuffer;
  1634. dwInBufLen = REQ_SIZE;
  1635. #undef REQ_SIZE
  1636. TraceEnter("SetIpNetEntryToStack");
  1637. CheckTcpipState();
  1638. if (!g_bIpConfigured)
  1639. {
  1640. return ERROR_NOT_SUPPORTED;
  1641. }
  1642. EnterCriticalSection(&g_ipNetLock);
  1643. if(bForceUpdate or
  1644. (g_dwLastArpUpdateTime is 0) or
  1645. ((GetCurrentTime() - g_dwLastArpUpdateTime) < ARP_CACHE_LIFE))
  1646. {
  1647. dwResult = UpdateAdapterToATInstanceMapping();
  1648. if(dwResult isnot NO_ERROR)
  1649. {
  1650. LeaveCriticalSection(&g_ipNetLock);
  1651. Trace1(ERR,"Couldnt update AT Map. Error %d",dwResult);
  1652. TraceLeave("SetIpNetEntryToStack");
  1653. return ERROR_CAN_NOT_COMPLETE;
  1654. }
  1655. }
  1656. dwInstance = GetATInstanceFromAdapter(pNetRow->dwIndex);
  1657. if(dwInstance is INVALID_AT_INSTANCE)
  1658. {
  1659. dwResult = UpdateAdapterToATInstanceMapping();
  1660. if(dwResult isnot NO_ERROR)
  1661. {
  1662. LeaveCriticalSection(&g_ipNetLock);
  1663. Trace1(ERR,"Couldnt update AT Map. Error %d",dwResult);
  1664. return ERROR_CAN_NOT_COMPLETE;
  1665. }
  1666. }
  1667. LeaveCriticalSection(&g_ipNetLock);
  1668. ID = &ptrsiInBuf->ID;
  1669. ID->toi_class = INFO_CLASS_PROTOCOL;
  1670. ID->toi_entity.tei_entity = AT_ENTITY;
  1671. ID->toi_type = INFO_TYPE_PROVIDER;
  1672. ID->toi_id = AT_MIB_ADDRXLAT_ENTRY_ID;
  1673. ID->toi_entity.tei_instance = dwInstance;
  1674. //
  1675. // Since MIB_IPNETROW is a fixed size structure
  1676. //
  1677. copyInfo = (MIB_IPNETROW*)ptrsiInBuf->Buffer;
  1678. *copyInfo = *pNetRow;
  1679. dwOutBufLen = 0;
  1680. ptrsiInBuf->BufferSize = sizeof(IPNetToMediaEntry);
  1681. dwResult = TCPSetInformationEx((PVOID)ptrsiInBuf,
  1682. &dwInBufLen,
  1683. NULL,
  1684. &dwOutBufLen);
  1685. TraceLeave("SetIpNetEntryToStack");
  1686. return dwResult;
  1687. }
  1688. DWORD
  1689. FlushIpNetTableFromStack(
  1690. IN DWORD dwIfIndex
  1691. )
  1692. {
  1693. #ifdef _WIN95_
  1694. return ERROR_NOT_SUPPORTED;
  1695. #else
  1696. DWORD status;
  1697. DWORD requestBufferSize = sizeof(DWORD);
  1698. DWORD OutBufLen= 0;
  1699. CheckTcpipState();
  1700. if (!g_bIpConfigured)
  1701. {
  1702. return ERROR_NOT_SUPPORTED;
  1703. }
  1704. status = TCPSendIoctl(g_hIPDriverHandle,
  1705. IOCTL_IP_FLUSH_ARP_TABLE,
  1706. &dwIfIndex,
  1707. &requestBufferSize,
  1708. NULL,
  1709. &OutBufLen);
  1710. #endif
  1711. return(status);
  1712. }
  1713. DWORD
  1714. SetProxyArpEntryToStack(
  1715. DWORD dwAddress,
  1716. DWORD dwMask,
  1717. DWORD dwAdapterIndex,
  1718. BOOL bAddEntry,
  1719. BOOL bForceUpdate
  1720. )
  1721. {
  1722. DWORD dwResult, dwATInstance, dwInBufLen, dwOutBufLen;
  1723. ProxyArpEntry *pEntry;
  1724. TDIObjectID *pID;
  1725. PTCP_REQUEST_SET_INFORMATION_EX ptrsiInBuf;
  1726. #define REQ_SIZE sizeof(TCP_REQUEST_SET_INFORMATION_EX) + \
  1727. sizeof(ProxyArpEntry) - 1
  1728. BYTE rgbyBuffer[REQ_SIZE + 4]; // +4 to avoid any alignment problems
  1729. ptrsiInBuf = (TCP_REQUEST_SET_INFORMATION_EX *)rgbyBuffer;
  1730. dwInBufLen = REQ_SIZE;
  1731. #undef REQ_SIZE
  1732. TraceEnter("SetProxyArpEntryToStack");
  1733. CheckTcpipState();
  1734. if (!g_bIpConfigured)
  1735. {
  1736. return ERROR_NOT_SUPPORTED;
  1737. }
  1738. EnterCriticalSection(&g_ipNetLock);
  1739. if(bForceUpdate or
  1740. (g_dwLastArpUpdateTime is 0) or
  1741. ((GetCurrentTime() - g_dwLastArpUpdateTime) < ARP_CACHE_LIFE))
  1742. {
  1743. dwResult = UpdateAdapterToATInstanceMapping();
  1744. if(dwResult isnot NO_ERROR)
  1745. {
  1746. LeaveCriticalSection(&g_ipNetLock);
  1747. Trace1(ERR,"Couldnt update AT Map. Error %d",dwResult);
  1748. TraceLeave("SetProxyArpEntryToStack");
  1749. return ERROR_CAN_NOT_COMPLETE;
  1750. }
  1751. }
  1752. dwATInstance = GetATInstanceFromAdapter(dwAdapterIndex);
  1753. if(dwATInstance is INVALID_IF_INSTANCE)
  1754. {
  1755. LeaveCriticalSection(&g_ipNetLock);
  1756. Trace1(ERR,
  1757. "SetProxyArpEntryToStacki: Couldnt get AT instance for %d",
  1758. dwAdapterIndex);
  1759. TraceLeave("SetProxyArpEntryToStack");
  1760. return ERROR_INVALID_PARAMETER;
  1761. }
  1762. LeaveCriticalSection(&g_ipNetLock);
  1763. pID = &ptrsiInBuf->ID;
  1764. pID->toi_entity.tei_entity = AT_ENTITY;
  1765. pID->toi_entity.tei_instance = dwATInstance;
  1766. pID->toi_type = INFO_TYPE_PROVIDER;
  1767. pID->toi_class = INFO_CLASS_IMPLEMENTATION;
  1768. pID->toi_id = AT_ARP_PARP_ENTRY_ID;
  1769. //
  1770. // Fill in the set entry, and pass it down.
  1771. //
  1772. pEntry = (ProxyArpEntry *)ptrsiInBuf->Buffer;
  1773. pEntry->pae_status = (bAddEntry ? PAE_STATUS_VALID : PAE_STATUS_INVALID);
  1774. pEntry->pae_addr = dwAddress;
  1775. pEntry->pae_mask = dwMask;
  1776. ptrsiInBuf->BufferSize = sizeof(ProxyArpEntry);
  1777. dwOutBufLen = 0;
  1778. dwResult = TCPSetInformationEx((PVOID)ptrsiInBuf,
  1779. &dwInBufLen,
  1780. NULL,
  1781. &dwOutBufLen);
  1782. TraceLeave("SetProxyArpEntryToStack");
  1783. return dwResult;
  1784. }
  1785. // ========================================================================
  1786. DWORD
  1787. GetArpEntryCount(
  1788. OUT PDWORD pdwNumEntries
  1789. )
  1790. {
  1791. DWORD dwResult, i;
  1792. DWORD dwInBufLen, dwOutBufLen;
  1793. TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
  1794. TDIObjectID *ID;
  1795. UCHAR *Context;
  1796. AddrXlatInfo AXI;
  1797. *pdwNumEntries = 0;
  1798. Context = (BYTE *) &(trqiInBuf.Context[0]);
  1799. ZeroMemory( Context, CONTEXT_SIZE );
  1800. ID = &(trqiInBuf.ID);
  1801. ID->toi_entity.tei_entity = AT_ENTITY;
  1802. ID->toi_type = INFO_TYPE_PROVIDER;
  1803. dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
  1804. for (i = 0; i < g_dwNumArpEntEntries; i++ )
  1805. {
  1806. //
  1807. // First add up the AXI counts
  1808. //
  1809. ID->toi_class = INFO_CLASS_PROTOCOL;
  1810. ID->toi_id = AT_MIB_ADDRXLAT_INFO_ID;
  1811. ID->toi_entity.tei_instance = g_pdwArpEntTable[i];
  1812. dwOutBufLen = sizeof(AXI);
  1813. ZeroMemory(Context, CONTEXT_SIZE);
  1814. dwResult = TCPQueryInformationEx(AF_INET,
  1815. &trqiInBuf,
  1816. &dwInBufLen,
  1817. &AXI,
  1818. &dwOutBufLen);
  1819. if (dwResult == ERROR_INVALID_FUNCTION)
  1820. {
  1821. Trace0(ERR, "GetArpEntryCount: ERROR_INVALID_FUNCTION, axi_count = 0");
  1822. AXI.axi_count = 0;
  1823. }
  1824. else if(dwResult isnot NO_ERROR)
  1825. {
  1826. Trace1(ERR,"GetArpEntryCount: Couldnt query Information from stack. Error %x",
  1827. dwResult);
  1828. return dwResult;
  1829. }
  1830. //
  1831. // Increment the total number of entries
  1832. //
  1833. *pdwNumEntries += AXI.axi_count;
  1834. }
  1835. return NO_ERROR;
  1836. }
  1837. // ========================================================================
  1838. DWORD
  1839. AllocateAndGetArpEntTableFromStack(
  1840. OUT PDWORD *ppdwArpEntTable,
  1841. OUT PDWORD pdwNumEntries,
  1842. IN HANDLE hHeap,
  1843. IN DWORD dwAllocFlags,
  1844. IN DWORD dwReAllocFlags
  1845. )
  1846. {
  1847. DWORD dwResult;
  1848. DWORD dwInBufLen;
  1849. DWORD dwOutBufLen;
  1850. TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
  1851. DWORD dwATType;
  1852. UCHAR *Context;
  1853. TDIObjectID *ID;
  1854. TDIEntityID *pEntTable;
  1855. DWORD dwNumEntities,dwCurrEntries;
  1856. DWORD i,dwCount ;
  1857. TraceEnter("GetArpEntTableFromStack");
  1858. *ppdwArpEntTable = NULL;
  1859. *pdwNumEntries = 0;
  1860. pEntTable = GetTdiEntityCount(&dwNumEntities);
  1861. if (!pEntTable)
  1862. {
  1863. return ERROR_NOT_ENOUGH_MEMORY;
  1864. }
  1865. //
  1866. // Create a table that will hold 16 entries
  1867. //
  1868. dwCurrEntries = 16;
  1869. *ppdwArpEntTable = HeapAlloc(hHeap,
  1870. dwAllocFlags,
  1871. dwCurrEntries*sizeof(DWORD));
  1872. if(*ppdwArpEntTable is NULL)
  1873. {
  1874. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  1875. Trace1(ERR,"GetArpEntTableFromStack: Couldnt allocate memory. Error %d",
  1876. dwResult);
  1877. HeapFree(g_hPrivateHeap,0,pEntTable);
  1878. return dwResult;
  1879. }
  1880. dwCount = 0;
  1881. Trace1(ERR, "Numberofentities %d \n", dwNumEntities);
  1882. for(i = 0; i < dwNumEntities; i++)
  1883. {
  1884. //
  1885. // See which ones are AT
  1886. //
  1887. if(pEntTable[i].tei_entity is AT_ENTITY)
  1888. {
  1889. //
  1890. // Query the entity to see if it supports ARP
  1891. //
  1892. ID = &(trqiInBuf.ID);
  1893. ID->toi_entity.tei_entity = AT_ENTITY;
  1894. ID->toi_class = INFO_CLASS_GENERIC;
  1895. ID->toi_type = INFO_TYPE_PROVIDER;
  1896. ID->toi_id = ENTITY_TYPE_ID;
  1897. ID->toi_entity.tei_instance = pEntTable[i].tei_instance;
  1898. Trace1(ERR,
  1899. "Querying for instance %d \n", pEntTable[i].tei_instance);
  1900. dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
  1901. dwOutBufLen = sizeof(dwATType);
  1902. Context = (BYTE *) &(trqiInBuf.Context[0]);
  1903. ZeroMemory(Context,CONTEXT_SIZE);
  1904. dwResult = TCPQueryInformationEx(AF_INET,
  1905. &trqiInBuf,
  1906. &dwInBufLen,
  1907. (PVOID)&dwATType,
  1908. &dwOutBufLen );
  1909. if(dwResult is ERROR_INVALID_FUNCTION)
  1910. {
  1911. //
  1912. // Doesnt support ARP
  1913. //
  1914. continue;
  1915. }
  1916. if(dwResult isnot NO_ERROR)
  1917. {
  1918. Trace1(ERR,"GetArpEntTableFromStack: Couldnt query information. Error %x",
  1919. dwResult);
  1920. HeapFree(hHeap,0,*ppdwArpEntTable);
  1921. HeapFree(g_hPrivateHeap,0,pEntTable);
  1922. return dwResult;
  1923. }
  1924. if(dwATType is AT_ARP)
  1925. {
  1926. //
  1927. // The entity is an AT_ENTITY that supports ARP. Add the instance
  1928. // to the arp entity table. If the current count >= current size of
  1929. // table, means we have run out of space, so reallocate and get double
  1930. // the space
  1931. //
  1932. if(dwCount is dwCurrEntries)
  1933. {
  1934. PDWORD pdwNewTable;
  1935. pdwNewTable = HeapReAlloc(hHeap,
  1936. dwReAllocFlags,
  1937. (PVOID)*ppdwArpEntTable,
  1938. ((dwCurrEntries)<<1)*sizeof(DWORD));
  1939. if(pdwNewTable is NULL)
  1940. {
  1941. dwResult = GetLastError();
  1942. Trace1(ERR,"GetArpEntTableFromStack: Couldnt reallocate memory. Error %d",
  1943. dwResult);
  1944. HeapFree(hHeap,0,*ppdwArpEntTable);
  1945. HeapFree(g_hPrivateHeap,0,pEntTable);
  1946. return dwResult;
  1947. }
  1948. *ppdwArpEntTable = pdwNewTable;
  1949. dwCurrEntries = dwCurrEntries<<1;
  1950. }
  1951. (*ppdwArpEntTable)[dwCount] = pEntTable[i].tei_instance;
  1952. dwCount++;
  1953. }
  1954. }
  1955. }
  1956. HeapFree(g_hPrivateHeap,0,pEntTable);
  1957. *pdwNumEntries = dwCount;
  1958. return NO_ERROR;
  1959. }
  1960. // ========================================================================
  1961. DWORD
  1962. SetIpForwardEntryToStack(
  1963. IN PMIB_IPFORWARDROW pForwardRow
  1964. )
  1965. {
  1966. IPRouteEntry route;
  1967. CheckTcpipState();
  1968. if (!g_bIpConfigured)
  1969. {
  1970. return ERROR_NOT_SUPPORTED;
  1971. }
  1972. ConvertForwardToRoute((&route),pForwardRow);
  1973. return SetIpRouteEntryToStack(&route);
  1974. }
  1975. // ========================================================================
  1976. DWORD
  1977. SetIpRouteEntryToStack(
  1978. IN IPRouteEntry *pRoute
  1979. )
  1980. {
  1981. TDIObjectID *pObject;
  1982. DWORD dwOutBufLen, dwInBufLen, dwResult;
  1983. TCP_REQUEST_SET_INFORMATION_EX *ptrsiBuffer;
  1984. IPRouteEntry *copyInfo;
  1985. #define REQ_SIZE sizeof(TCP_REQUEST_SET_INFORMATION_EX) + sizeof(IPRouteEntry) - 1
  1986. BYTE rgbyBuffer[REQ_SIZE + 4]; // +4 to avoid any alignment problems
  1987. ptrsiBuffer = (TCP_REQUEST_SET_INFORMATION_EX *)rgbyBuffer;
  1988. dwInBufLen = REQ_SIZE;
  1989. #undef REQ_SIZE
  1990. CheckTcpipState();
  1991. if (!g_bIpConfigured)
  1992. {
  1993. return ERROR_NOT_SUPPORTED;
  1994. }
  1995. ptrsiBuffer->BufferSize = sizeof(IPRouteEntry);
  1996. pObject = &ptrsiBuffer->ID;
  1997. pObject->toi_id = IP_MIB_RTTABLE_ENTRY_ID;
  1998. pObject->toi_type = INFO_TYPE_PROVIDER;
  1999. pObject->toi_class = INFO_CLASS_PROTOCOL;
  2000. pObject->toi_entity.tei_entity = CL_NL_ENTITY;
  2001. pObject->toi_entity.tei_instance = 0;
  2002. dwOutBufLen = 0;
  2003. copyInfo = (IPRouteEntry *)ptrsiBuffer->Buffer;
  2004. *copyInfo = *pRoute;
  2005. dwResult = TCPSetInformationEx((PVOID)ptrsiBuffer,
  2006. &dwInBufLen,
  2007. NULL,
  2008. &dwOutBufLen);
  2009. return dwResult;
  2010. }
  2011. DWORD
  2012. SetIpMultihopRouteEntryToStack(
  2013. IN IPMultihopRouteEntry *RouteEntry
  2014. )
  2015. {
  2016. ULONG inpbuflen;
  2017. ULONG outbuflen;
  2018. CheckTcpipState();
  2019. if (!g_bIpConfigured)
  2020. {
  2021. return ERROR_NOT_SUPPORTED;
  2022. }
  2023. inpbuflen = sizeof(IPMultihopRouteEntry);
  2024. if (RouteEntry->imre_numnexthops > 2)
  2025. {
  2026. inpbuflen += (RouteEntry->imre_numnexthops - 2) *
  2027. sizeof(IPRouteNextHopEntry);
  2028. }
  2029. if (IsBadReadPtr(RouteEntry, inpbuflen)) {
  2030. return ERROR_INVALID_PARAMETER;
  2031. }
  2032. return (TCPSendIoctl(
  2033. g_hIPDriverHandle,
  2034. IOCTL_IP_SET_MULTIHOPROUTE,
  2035. RouteEntry,
  2036. &inpbuflen,
  2037. NULL,
  2038. &outbuflen
  2039. ));
  2040. }
  2041. DWORD
  2042. GetBestInterfaceFromStack(
  2043. DWORD dwDestAddress,
  2044. PDWORD pdwBestIfIndex
  2045. )
  2046. {
  2047. #ifdef _WIN95_
  2048. return ERROR_NOT_SUPPORTED;
  2049. #else
  2050. DWORD status;
  2051. DWORD requestBufferSize = sizeof(DWORD);
  2052. DWORD OutBufLen= sizeof(DWORD);
  2053. CheckTcpipState();
  2054. if (!g_bIpConfigured)
  2055. {
  2056. return ERROR_NOT_SUPPORTED;
  2057. }
  2058. status = TCPSendIoctl(g_hIPGetDriverHandle,
  2059. IOCTL_IP_GET_BEST_INTERFACE,
  2060. &dwDestAddress,
  2061. &requestBufferSize,
  2062. pdwBestIfIndex,
  2063. &OutBufLen);
  2064. return(status);
  2065. #endif
  2066. }
  2067. // ========================================================================
  2068. //* TCPQueryInformationEx
  2069. //
  2070. // Description: Get information from the stack.
  2071. //
  2072. // Parameters: HANDLE hHandle: handle to the stack.
  2073. // TDIObjectID *ID: pointer to TDIObjectID info.
  2074. // void *Buffer: buffer to receive data from the stack.
  2075. // ulong *Bufferlen: IN: tells stack size of available buffer,
  2076. // OUT: tells us how much data is available.
  2077. // CONTEXT *Context: allows queries spanning more than one call.
  2078. //
  2079. // Returns: int:
  2080. //
  2081. //*
  2082. int
  2083. TCPQueryInformationEx(
  2084. DWORD Family,
  2085. void *InBuf,
  2086. ulong *InBufLen,
  2087. void *OutBuf,
  2088. ulong *OutBufLen
  2089. )
  2090. {
  2091. #ifdef CHICAGO
  2092. //
  2093. // This section is obsolete code
  2094. //
  2095. DWORD result;
  2096. if( ! pWsControl ) {
  2097. OpenTCPDriver(AF_INET);
  2098. }
  2099. if( ! pWsControl || (Family != AF_INET)) {
  2100. DEBUG_PRINT(("TCPQueryInformationEx: !pWsControl.\n"));
  2101. return ERROR_NOT_SUPPORTED;
  2102. }
  2103. assert( pWsControl );
  2104. result = (
  2105. (*pWsControl)(
  2106. IPPROTO_TCP,
  2107. WSCNTL_TCPIP_QUERY_INFO,
  2108. InBuf,
  2109. InBufLen ,
  2110. OutBuf,
  2111. OutBufLen
  2112. ) );
  2113. if( result ){
  2114. return ConvertTdiErrorToDosError(result);
  2115. }
  2116. return NO_ERROR;
  2117. #else
  2118. NTSTATUS Status;
  2119. IO_STATUS_BLOCK IoStatusBlock;
  2120. HANDLE hEvent;
  2121. HANDLE hDriver = (Family == AF_INET)? g_hTCPDriverGetHandle :
  2122. g_hTCP6DriverGetHandle;
  2123. hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
  2124. if( NULL == hEvent ) return GetLastError();
  2125. Status = NtDeviceIoControlFile(hDriver,
  2126. hEvent,
  2127. NULL,
  2128. NULL,
  2129. &IoStatusBlock,
  2130. IOCTL_TCP_QUERY_INFORMATION_EX,
  2131. InBuf,
  2132. *InBufLen,
  2133. OutBuf,
  2134. *OutBufLen );
  2135. if ( Status == STATUS_PENDING )
  2136. {
  2137. Status = NtWaitForSingleObject(hEvent, FALSE, NULL );
  2138. Status = IoStatusBlock.Status;
  2139. }
  2140. CloseHandle(hEvent);
  2141. if ( !NT_SUCCESS( Status ) )
  2142. {
  2143. Trace1(ERR,"Device IOCTL failed in TCPQuery %x",Status);
  2144. *OutBufLen = 0;
  2145. return ( RtlNtStatusToDosError(Status) );
  2146. }
  2147. //
  2148. // Tell caller how much was written
  2149. //
  2150. *OutBufLen = (ULONG)IoStatusBlock.Information;
  2151. return ( NO_ERROR );
  2152. #endif
  2153. }
  2154. // ========================================================================
  2155. //* TCPSendIoctl
  2156. //
  2157. // Description: Get information from the stack.
  2158. //
  2159. // Parameters: HANDLE hHandle: handle to the stack.
  2160. // TDIObjectID *ID: pointer to TDIObjectID info.
  2161. // void *Buffer: buffer to receive data from the stack.
  2162. // ulong *Bufferlen: IN: tells stack size of available buffer,
  2163. // OUT: tells us how much data is available.
  2164. // CONTEXT *Context: allows queries spanning more than one call.
  2165. //
  2166. // Returns: int:
  2167. //
  2168. //*
  2169. int
  2170. TCPSendIoctl( HANDLE hHandle,
  2171. ulong Ioctl,
  2172. void *InBuf,
  2173. ulong *InBufLen,
  2174. void *OutBuf,
  2175. ulong *OutBufLen)
  2176. {
  2177. #ifdef CHICAGO
  2178. // OVERLAPPED overlap;
  2179. uint ok;
  2180. ok = DeviceIoControl( hHandle, Ioctl,
  2181. InBuf, *InBufLen,
  2182. OutBuf, *OutBufLen, OutBufLen,
  2183. NULL // &overlap
  2184. );
  2185. if( !ok ){
  2186. int err = GetLastError();
  2187. DEBUG_PRINT(("TCPSendIoctl: DeviceIoControl err %d\n", err ));
  2188. return err;
  2189. }
  2190. return NO_ERROR;
  2191. #else
  2192. NTSTATUS Status;
  2193. IO_STATUS_BLOCK IoStatusBlock;
  2194. HANDLE hEvent;
  2195. hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
  2196. if( NULL == hEvent ) return GetLastError();
  2197. ZeroMemory(&IoStatusBlock, sizeof(IoStatusBlock));
  2198. Status = NtDeviceIoControlFile(hHandle,
  2199. hEvent,
  2200. NULL,
  2201. NULL,
  2202. &IoStatusBlock,
  2203. Ioctl,
  2204. InBuf,
  2205. *InBufLen,
  2206. OutBuf,
  2207. *OutBufLen );
  2208. if ( Status == STATUS_PENDING )
  2209. {
  2210. Status = NtWaitForSingleObject( hEvent, FALSE, NULL );
  2211. Status = IoStatusBlock.Status;
  2212. }
  2213. CloseHandle(hEvent);
  2214. if ( !NT_SUCCESS( Status ) )
  2215. {
  2216. Trace1(ERR,"Device IOCTL failed in TCPSendIoctl %x",Status);
  2217. if (OutBufLen)
  2218. *OutBufLen = (ULONG)IoStatusBlock.Information;
  2219. return ( RtlNtStatusToDosError(Status) );
  2220. }
  2221. //
  2222. // Tell caller how much was written
  2223. //
  2224. if (OutBufLen)
  2225. *OutBufLen = (ULONG)IoStatusBlock.Information;
  2226. return ( NO_ERROR );
  2227. #endif
  2228. }
  2229. // ========================================================================
  2230. //* TCPSetInformationEx()
  2231. //
  2232. // Description: Send information to the stack
  2233. //
  2234. // Parameters: HANDLE hHandle: handle to the stack.
  2235. // TDIObjectID *ID: pointer to TDIObjectID info.
  2236. // void *Buffer: buffer to receive data from the stack.
  2237. // ulong Bufferlen: tells stack size of available buffer,
  2238. //
  2239. // Returns: int:
  2240. //
  2241. //*
  2242. int
  2243. TCPSetInformationEx(
  2244. void *InBuf,
  2245. ULONG *InBufLen,
  2246. void *OutBuf,
  2247. ULONG *OutBufLen
  2248. )
  2249. {
  2250. #ifdef CHICAGO
  2251. DWORD result;
  2252. if( ! pWsControl )
  2253. OpenTCPDriver(AF_INET);
  2254. if( ! pWsControl ){
  2255. DEBUG_PRINT(("TCPQueryInformationEx: !pWsControl.\n"));
  2256. return 0;
  2257. }
  2258. assert( pWsControl );
  2259. result = (
  2260. (*pWsControl)(
  2261. IPPROTO_TCP,
  2262. WSCNTL_TCPIP_SET_INFO,
  2263. InBuf,
  2264. InBufLen,
  2265. OutBuf,
  2266. OutBufLen
  2267. ) );
  2268. if( result ){
  2269. return ConvertTdiErrorToDosError(result);
  2270. }
  2271. return NO_ERROR;
  2272. #else
  2273. NTSTATUS Status;
  2274. IO_STATUS_BLOCK IoStatusBlock;
  2275. if(g_hTCPDriverSetHandle is NULL)
  2276. {
  2277. return ERROR_NETWORK_ACCESS_DENIED;
  2278. }
  2279. Status = NtDeviceIoControlFile(g_hTCPDriverSetHandle,
  2280. NULL,
  2281. NULL,
  2282. NULL,
  2283. &IoStatusBlock,
  2284. IOCTL_TCP_SET_INFORMATION_EX,
  2285. InBuf,
  2286. *InBufLen,
  2287. OutBuf,
  2288. *OutBufLen );
  2289. if ( Status == STATUS_PENDING )
  2290. {
  2291. Status = NtWaitForSingleObject(g_hTCPDriverSetHandle, FALSE, NULL );
  2292. Status = IoStatusBlock.Status;
  2293. }
  2294. if ( !NT_SUCCESS( Status ) )
  2295. {
  2296. return ( RtlNtStatusToDosError(Status) );
  2297. }
  2298. return ( NO_ERROR );
  2299. #endif
  2300. }
  2301. // ========================================================================
  2302. // SYNOPSIS: opens handles to tcpip driver.
  2303. //
  2304. // returns
  2305. // 0 == NO_ERROR == STATUS_SUCCESS on success.
  2306. // err or 1 on failure.
  2307. //
  2308. // - MohsinA, 02-Jul-97.
  2309. //
  2310. DWORD
  2311. OpenTCPDriver(
  2312. IN DWORD dwFamily
  2313. )
  2314. {
  2315. #ifdef CHICAGO
  2316. int err = 0;
  2317. if (dwFamily != AF_INET) {
  2318. return ERROR_INVALID_PARAMETER;
  2319. }
  2320. hWsock = LoadLibrary(TEXT("wsock32.dll"));
  2321. if(! hWsock ){
  2322. err = GetLastError();
  2323. DEBUG_PRINT(("RTStartup: can't load wsock32.dll, %d\n", err ));
  2324. DEBUG_PRINT(("OpenTcp: !hWsock\n"));
  2325. return err? err: 1;
  2326. }
  2327. pWsControl = (LPWSCONTROL) GetProcAddress(hWsock, "WsControl");
  2328. if (! pWsControl ){
  2329. err = GetLastError();
  2330. DEBUG_PRINT((
  2331. "RTStartup: GetProcAddress(wsock32,WsControl) failed %d\n",
  2332. GetLastError()));
  2333. return err? err: 1;
  2334. }
  2335. // open the handle to VIP
  2336. g_hIPDriverHandle = NULL;
  2337. g_hIPGetDriverHandle = NULL;
  2338. #ifndef _WIN95_
  2339. g_hIPDriverHandle = OsOpenVxdHandle( "VIP", VIP_Device_ID );
  2340. if( ! g_hIPDriverHandle ){
  2341. err = GetLastError();
  2342. DEBUG_PRINT(("no ip handle, err %d\n", err ));
  2343. return err? err : 1;
  2344. }
  2345. g_hIPGetDriverHandle = g_hIPDriverHandle;
  2346. #endif
  2347. return NO_ERROR;
  2348. #else
  2349. NTSTATUS status;
  2350. UNICODE_STRING nameString;
  2351. IO_STATUS_BLOCK ioStatusBlock;
  2352. OBJECT_ATTRIBUTES objectAttributes;
  2353. PWCHAR pwszDdDeviceName;
  2354. HANDLE *pDriverGetHandle, *pDriverSetHandle;
  2355. switch (dwFamily) {
  2356. case AF_INET:
  2357. pwszDdDeviceName = DD_TCP_DEVICE_NAME;
  2358. pDriverGetHandle = &g_hTCPDriverGetHandle;
  2359. pDriverSetHandle = &g_hTCPDriverSetHandle;
  2360. break;
  2361. case AF_INET6:
  2362. pwszDdDeviceName = DD_TCPV6_DEVICE_NAME;
  2363. pDriverGetHandle = &g_hTCP6DriverGetHandle;
  2364. pDriverSetHandle = &g_hTCP6DriverSetHandle;
  2365. break;
  2366. default:
  2367. return ERROR_INVALID_PARAMETER;
  2368. }
  2369. RtlInitUnicodeString(&nameString, pwszDdDeviceName);
  2370. InitializeObjectAttributes(&objectAttributes, &nameString,
  2371. OBJ_CASE_INSENSITIVE, NULL, NULL);
  2372. status = NtCreateFile(pDriverGetHandle,
  2373. GENERIC_EXECUTE,
  2374. &objectAttributes,
  2375. &ioStatusBlock,
  2376. NULL,
  2377. FILE_ATTRIBUTE_NORMAL,
  2378. FILE_SHARE_READ | FILE_SHARE_WRITE,
  2379. FILE_OPEN_IF,
  2380. 0,
  2381. NULL,
  2382. 0);
  2383. if(status isnot STATUS_SUCCESS)
  2384. {
  2385. return ERROR_OPEN_FAILED;
  2386. }
  2387. RtlInitUnicodeString(&nameString, pwszDdDeviceName);
  2388. InitializeObjectAttributes(&objectAttributes, &nameString,
  2389. OBJ_CASE_INSENSITIVE, NULL, NULL);
  2390. NtCreateFile(pDriverSetHandle,
  2391. GENERIC_WRITE,
  2392. &objectAttributes,
  2393. &ioStatusBlock,
  2394. NULL,
  2395. FILE_ATTRIBUTE_NORMAL,
  2396. FILE_SHARE_READ | FILE_SHARE_WRITE,
  2397. FILE_OPEN_IF,
  2398. 0,
  2399. NULL,
  2400. 0);
  2401. OpenIPDriver(dwFamily);
  2402. return NO_ERROR;
  2403. #endif
  2404. }
  2405. // ========================================================================
  2406. DWORD
  2407. CloseTCPDriver()
  2408. {
  2409. #ifdef CHICAGO
  2410. if( hWsock )
  2411. FreeLibrary( hWsock );
  2412. hWsock = NULL;
  2413. pWsControl = NULL;
  2414. if (g_hIPDriverHandle)
  2415. OsCloseVxdHandle( g_hIPDriverHandle );
  2416. g_hIPDriverHandle = NULL;
  2417. g_hIPGetDriverHandle = NULL;
  2418. #else
  2419. if(g_hTCPDriverGetHandle isnot NULL)
  2420. {
  2421. CloseHandle (g_hTCPDriverGetHandle) ;
  2422. }
  2423. if(g_hTCPDriverSetHandle isnot NULL)
  2424. {
  2425. CloseHandle (g_hTCPDriverSetHandle) ;
  2426. }
  2427. CloseIPDriver();
  2428. #endif
  2429. return NO_ERROR ;
  2430. }
  2431. DWORD
  2432. CloseTCP6Driver()
  2433. {
  2434. if(g_hTCP6DriverGetHandle isnot NULL)
  2435. {
  2436. CloseHandle (g_hTCP6DriverGetHandle) ;
  2437. }
  2438. if(g_hTCP6DriverSetHandle isnot NULL)
  2439. {
  2440. CloseHandle (g_hTCP6DriverSetHandle) ;
  2441. }
  2442. CloseIP6Driver();
  2443. return NO_ERROR ;
  2444. }
  2445. #ifndef CHICAGO
  2446. DWORD
  2447. OpenIPDriver(
  2448. IN DWORD dwFamily
  2449. )
  2450. {
  2451. NTSTATUS status;
  2452. UNICODE_STRING nameString;
  2453. IO_STATUS_BLOCK ioStatusBlock;
  2454. OBJECT_ATTRIBUTES objectAttributes;
  2455. PWCHAR pwszDdDeviceName;
  2456. LPCTSTR ptszWinDeviceName;
  2457. HANDLE *pDriverHandle, *pGetDriverHandle, *pChangeHandle;
  2458. switch (dwFamily) {
  2459. case AF_INET:
  2460. pwszDdDeviceName = DD_IP_DEVICE_NAME;
  2461. ptszWinDeviceName = TEXT ("\\\\.\\Ip");
  2462. pDriverHandle = &g_hIPDriverHandle;
  2463. pGetDriverHandle = &g_hIPGetDriverHandle;
  2464. pChangeHandle = &ChangeNotificationHandle;
  2465. break;
  2466. case AF_INET6:
  2467. pwszDdDeviceName = DD_IPV6_DEVICE_NAME;
  2468. ptszWinDeviceName = TEXT ("\\\\.\\Ip6");;
  2469. pDriverHandle = &g_hIP6DriverHandle;
  2470. pGetDriverHandle = &g_hIP6GetDriverHandle;
  2471. pChangeHandle = &Change6NotificationHandle;
  2472. break;
  2473. default:
  2474. return ERROR_INVALID_PARAMETER;
  2475. }
  2476. RtlInitUnicodeString(&nameString, pwszDdDeviceName);
  2477. InitializeObjectAttributes(&objectAttributes, &nameString,
  2478. OBJ_CASE_INSENSITIVE, NULL, NULL);
  2479. status = NtCreateFile(pGetDriverHandle,
  2480. GENERIC_EXECUTE,
  2481. &objectAttributes, &ioStatusBlock, NULL,
  2482. FILE_ATTRIBUTE_NORMAL,
  2483. FILE_SHARE_READ | FILE_SHARE_WRITE,
  2484. FILE_OPEN_IF, 0, NULL, 0);
  2485. if (status == STATUS_SUCCESS) {
  2486. RtlInitUnicodeString(&nameString, pwszDdDeviceName);
  2487. InitializeObjectAttributes(&objectAttributes, &nameString,
  2488. OBJ_CASE_INSENSITIVE, NULL, NULL);
  2489. NtCreateFile(pDriverHandle,
  2490. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  2491. &objectAttributes, &ioStatusBlock, NULL,
  2492. FILE_ATTRIBUTE_NORMAL,
  2493. FILE_SHARE_READ | FILE_SHARE_WRITE,
  2494. FILE_OPEN_IF, 0, NULL, 0);
  2495. *pChangeHandle = CreateFile(ptszWinDeviceName,
  2496. GENERIC_EXECUTE,
  2497. FILE_SHARE_READ | FILE_SHARE_WRITE,
  2498. NULL,
  2499. OPEN_EXISTING,
  2500. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
  2501. NULL);
  2502. }
  2503. return (NO_ERROR);
  2504. }
  2505. DWORD
  2506. CloseIPDriver()
  2507. {
  2508. if(g_hIPDriverHandle isnot NULL)
  2509. {
  2510. CloseHandle (g_hIPDriverHandle) ;
  2511. }
  2512. if(g_hIPGetDriverHandle isnot NULL)
  2513. {
  2514. CloseHandle (g_hIPGetDriverHandle) ;
  2515. }
  2516. if (ChangeNotificationHandle isnot NULL)
  2517. {
  2518. CloseHandle (ChangeNotificationHandle);
  2519. }
  2520. return NO_ERROR ;
  2521. }
  2522. DWORD
  2523. CloseIP6Driver()
  2524. {
  2525. if(g_hIP6DriverHandle isnot NULL)
  2526. {
  2527. CloseHandle (g_hIP6DriverHandle) ;
  2528. }
  2529. if(g_hIP6GetDriverHandle isnot NULL)
  2530. {
  2531. CloseHandle (g_hIP6GetDriverHandle) ;
  2532. }
  2533. if (Change6NotificationHandle isnot NULL)
  2534. {
  2535. CloseHandle (Change6NotificationHandle);
  2536. }
  2537. return NO_ERROR ;
  2538. }
  2539. #endif
  2540. DWORD
  2541. GetBestRouteFromStack(
  2542. IN DWORD dwDestAddr,
  2543. IN DWORD dwSrcAddr, OPTIONAL
  2544. OUT PMIB_IPFORWARDROW pBestRoute
  2545. )
  2546. {
  2547. DWORD dwResult;
  2548. DWORD dwInBufLen, dwOutBufLen;
  2549. TDIObjectID *ID;
  2550. IPRouteEntry Route;
  2551. PIPRouteLookupData pLookup;
  2552. PTCP_REQUEST_QUERY_INFORMATION_EX ptrqiInBuf;
  2553. #define REQ_SIZE sizeof(TCP_REQUEST_QUERY_INFORMATION_EX) + \
  2554. sizeof(IPRouteLookupData) - 1
  2555. BYTE rgbyBuffer[REQ_SIZE + 4]; // +4 to avoid any alignment problems
  2556. ptrqiInBuf = (PTCP_REQUEST_QUERY_INFORMATION_EX)rgbyBuffer;
  2557. dwInBufLen = REQ_SIZE;
  2558. #undef REQ_SIZE
  2559. CheckTcpipState();
  2560. if (!g_bIpConfigured)
  2561. {
  2562. return ERROR_NOT_SUPPORTED;
  2563. }
  2564. ID = &(ptrqiInBuf->ID);
  2565. pLookup = (PIPRouteLookupData)(ptrqiInBuf->Context);
  2566. pLookup->Version = 1;
  2567. pLookup->DestAdd = dwDestAddr;
  2568. pLookup->SrcAdd = dwSrcAddr;
  2569. ID->toi_entity.tei_entity = CL_NL_ENTITY;
  2570. ID->toi_entity.tei_instance = 0;
  2571. ID->toi_class = INFO_CLASS_PROTOCOL;
  2572. ID->toi_type = INFO_TYPE_PROVIDER;
  2573. ID->toi_id = IP_MIB_SINGLE_RT_ENTRY_ID;
  2574. dwOutBufLen = sizeof(IPRouteEntry);
  2575. dwResult = TCPQueryInformationEx(AF_INET,
  2576. ptrqiInBuf,
  2577. &dwInBufLen,
  2578. &Route,
  2579. &dwOutBufLen);
  2580. ConvertRouteToForward(&Route, pBestRoute);
  2581. return dwResult;
  2582. }
  2583. TDIEntityID*
  2584. GetTdiEntityCount(
  2585. PULONG pulNumEntities
  2586. )
  2587. {
  2588. DWORD dwResult;
  2589. DWORD dwInBufLen;
  2590. DWORD dwOutBufLen;
  2591. TCP_REQUEST_QUERY_INFORMATION_EX trqiInBuf;
  2592. UCHAR *Context;
  2593. TDIObjectID *ID;
  2594. TDIEntityID *pEntTable = NULL;
  2595. TraceEnter("GetTdiEntityCount");
  2596. *pulNumEntities = 0;
  2597. dwInBufLen = sizeof(TCP_REQUEST_QUERY_INFORMATION_EX);
  2598. dwOutBufLen = sizeof(TDIEntityID) * MAX_TDI_ENTITIES;
  2599. pEntTable = (TDIEntityID*)HeapAlloc(g_hPrivateHeap,0,dwOutBufLen);
  2600. if (!pEntTable) {
  2601. Trace1(ERR,"GetTdiEntityCount: Couldnt allocate memory of size %d",
  2602. dwOutBufLen);
  2603. return NULL;
  2604. }
  2605. ID = &(trqiInBuf.ID);
  2606. ID->toi_entity.tei_entity = GENERIC_ENTITY;
  2607. ID->toi_entity.tei_instance = 0;
  2608. ID->toi_class = INFO_CLASS_GENERIC;
  2609. ID->toi_type = INFO_TYPE_PROVIDER;
  2610. ID->toi_id = ENTITY_LIST_ID;
  2611. Context = (BYTE *) &(trqiInBuf.Context[0]);
  2612. ZeroMemory(Context, CONTEXT_SIZE);
  2613. dwResult = TCPQueryInformationEx(AF_INET,
  2614. &trqiInBuf,
  2615. &dwInBufLen,
  2616. (PVOID)pEntTable,
  2617. &dwOutBufLen);
  2618. if(dwResult isnot NO_ERROR)
  2619. {
  2620. Trace1(ERR,"GetTdiEntityCount: Couldnt query information. Error %x",
  2621. dwResult);
  2622. HeapFree(g_hPrivateHeap,0,pEntTable);
  2623. return NULL;
  2624. }
  2625. //
  2626. // Now we have all the TDI entities
  2627. //
  2628. *pulNumEntities = dwOutBufLen / sizeof(TDIEntityID);
  2629. return pEntTable;
  2630. }