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.

2409 lines
61 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. net\sockets\tcpcmd\iphlpapi\internal.c
  5. Abstract:
  6. Contains the private APIs exported by IPHLPAP.DLL These
  7. are exposed because of the MIB-II subagent, and to allow
  8. more flexible use of the dll
  9. Revision History:
  10. Amritansh Raghav
  11. --*/
  12. #include "inc.h"
  13. #pragma hdrstop
  14. HANDLE AddressChangeNotification = NULL;
  15. HANDLE RouteChangeNotification = NULL;
  16. HANDLE ChangeNotificationHandle = INVALID_HANDLE_VALUE;
  17. extern HANDLE g_hIPDriverHandle;
  18. extern HANDLE g_hIPGetDriverHandle;
  19. HANDLE Change6NotificationHandle = INVALID_HANDLE_VALUE;
  20. extern HANDLE g_hIP6DriverHandle;
  21. extern HANDLE g_hIP6GetDriverHandle;
  22. #define ROUTE_CHANGE 0
  23. #define ADDRESS_CHANGE 1
  24. #define TERMINATE_EVENT 2
  25. int ThreadCreated=0;
  26. typedef VOID (*PFNChangeHandler)(PVOID pContext);
  27. typedef VOID (*PFNChangeHandler)(PVOID pContext);
  28. DWORD
  29. NotifyRouteChangeEx(
  30. PHANDLE pHandle,
  31. LPOVERLAPPED pOverLapped,
  32. BOOL bExQueue
  33. );
  34. typedef struct
  35. {
  36. LIST_ENTRY ListEntry;
  37. PVOID context;
  38. PFNChangeHandler Proc;
  39. }NotifyContext;
  40. DWORD
  41. WINAPI
  42. GetNumberOfInterfaces(
  43. PDWORD pdwNumIf
  44. );
  45. LIST_ENTRY AddrNotifyListHead;
  46. LIST_ENTRY RouteNotifyListHead;
  47. int
  48. TCPSendIoctl(
  49. HANDLE hHandle,
  50. ulong Ioctl,
  51. void *InBuf,
  52. ulong *InBufLen,
  53. void *OutBuf,
  54. ulong *OutBufLen
  55. );
  56. BOOL
  57. IsRouterRunning(VOID);
  58. BOOL
  59. IsRouterSettingRoutes(VOID);
  60. extern DWORD IPv4ToMibOperStatus[];
  61. #define NUM_IPV4_OPER_STATUSES (IF_OPER_STATUS_OPERATIONAL+1)
  62. DWORD
  63. InternalGetIfTable(
  64. OUT MIB_IFTABLE **ppIfTable,
  65. IN HANDLE hHeap,
  66. IN DWORD dwAllocFlags
  67. )
  68. {
  69. MIB_OPAQUE_QUERY mqQuery;
  70. PMIB_OPAQUE_INFO pInfo;
  71. PMIB_IFTABLE pTable;
  72. DWORD dwResult, dwOutEntrySize, i;
  73. TraceEnter("InternalGetIfTable");
  74. *ppIfTable = NULL;
  75. #ifndef CHICAGO
  76. if(IsRouterRunning())
  77. {
  78. mqQuery.dwVarId = IF_TABLE;
  79. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  80. PID_IP,
  81. IPRTRMGR_PID,
  82. (PVOID)&mqQuery,
  83. sizeof(MIB_OPAQUE_QUERY),
  84. (PVOID)&pInfo,
  85. &dwOutEntrySize);
  86. if(dwResult isnot NO_ERROR)
  87. {
  88. Trace1(ERR,"InternalGetIfTable: MprAdminMIBEntryGet failed with error %x",
  89. dwResult);
  90. TraceLeave("InternalGetIfTable");
  91. return dwResult;
  92. }
  93. *ppIfTable = HeapAlloc(hHeap,
  94. dwAllocFlags,
  95. dwOutEntrySize);
  96. if(*ppIfTable is NULL)
  97. {
  98. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  99. Trace1(ERR,"InternalGetIfTable: Allocation failed with error %d",
  100. dwResult);
  101. TraceLeave("InternalGetIfTable");
  102. MprAdminMIBBufferFree((PVOID)pInfo);
  103. return dwResult;
  104. }
  105. CAST_MIB_INFO(pInfo, PMIB_IFTABLE, pTable);
  106. Trace3(ERR, "**pTable %x pInfo %x rgdata %x\n",
  107. pTable, pInfo, pInfo->rgbyData);
  108. CopyMemory((PVOID)(*ppIfTable),
  109. (PVOID)pTable,
  110. SIZEOF_IFTABLE(pTable->dwNumEntries));
  111. MprAdminMIBBufferFree((PVOID)pInfo);
  112. }
  113. else
  114. {
  115. #endif
  116. dwResult = AllocateAndGetIfTableFromStack(ppIfTable,
  117. TRUE,
  118. hHeap,
  119. dwAllocFlags,
  120. TRUE);
  121. if(dwResult isnot NO_ERROR)
  122. {
  123. Trace1(ERR,
  124. "InternalGetIfTable: AllocateAndGetIfTableFromStack failed with error %x",
  125. dwResult);
  126. TraceLeave("InternalGetIfTable");
  127. return dwResult;
  128. }
  129. #ifndef CHICAGO
  130. }
  131. #endif
  132. //
  133. // Convert operational status to the numbering space used in the
  134. // MIB RFC's.
  135. //
  136. for (i = 0; i < (*ppIfTable)->dwNumEntries; i++)
  137. {
  138. (*ppIfTable)->table[i].dwOperStatus =
  139. ((*ppIfTable)->table[i].dwOperStatus < NUM_IPV4_OPER_STATUSES)
  140. ? IPv4ToMibOperStatus[(*ppIfTable)->table[i].dwOperStatus]
  141. : IF_STATUS_UNKNOWN;
  142. }
  143. TraceLeave("InternalGetIfTable");
  144. return NO_ERROR;
  145. }
  146. DWORD
  147. InternalGetIpAddrTable(
  148. OUT MIB_IPADDRTABLE **ppIpAddrTable,
  149. IN HANDLE hHeap,
  150. IN DWORD dwAllocFlags
  151. )
  152. {
  153. PMIB_OPAQUE_INFO pInfo;
  154. MIB_OPAQUE_QUERY mqQuery;
  155. DWORD dwResult, dwOutEntrySize;
  156. PMIB_IPADDRTABLE pTable;
  157. TraceEnter("InternalGetIpAddrTable");
  158. *ppIpAddrTable = NULL;
  159. #ifndef CHICAGO
  160. if(IsRouterRunning())
  161. {
  162. mqQuery.dwVarId = IP_ADDRTABLE;
  163. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  164. PID_IP,
  165. IPRTRMGR_PID,
  166. (PVOID)&mqQuery,
  167. sizeof(MIB_OPAQUE_QUERY),
  168. (PVOID)&pInfo,
  169. &dwOutEntrySize);
  170. if(dwResult isnot NO_ERROR)
  171. {
  172. Trace1(ERR,"MprAdminMIBEntryGet failed with error %x",
  173. dwResult);
  174. TraceLeave("InternalGetIpAddrTable");
  175. return dwResult;
  176. }
  177. *ppIpAddrTable = HeapAlloc(hHeap,
  178. dwAllocFlags,
  179. dwOutEntrySize);
  180. if(*ppIpAddrTable is NULL)
  181. {
  182. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  183. Trace1(ERR,"Allocation failed with error %d",
  184. dwResult);
  185. TraceLeave("InternalGetIpAddrTable");
  186. MprAdminMIBBufferFree((PVOID)pInfo);
  187. return dwResult;
  188. }
  189. CAST_MIB_INFO(pInfo, PMIB_IPADDRTABLE, pTable);
  190. CopyMemory((PVOID)(*ppIpAddrTable),
  191. (PVOID)pTable,
  192. SIZEOF_IPADDRTABLE(pTable->dwNumEntries));
  193. MprAdminMIBBufferFree((PVOID)pInfo);
  194. }
  195. else
  196. {
  197. #endif
  198. dwResult = AllocateAndGetIpAddrTableFromStack(ppIpAddrTable,
  199. TRUE,
  200. hHeap,
  201. dwAllocFlags);
  202. if(dwResult isnot NO_ERROR)
  203. {
  204. Trace1(ERR,"InternalGetIpAddrTableFromStack failed with error %x",
  205. dwResult);
  206. TraceLeave("InternalGetIpAddrTable");
  207. return dwResult;
  208. }
  209. #ifndef CHICAGO
  210. }
  211. #endif
  212. TraceLeave("InternalGetIpAddrTable");
  213. return NO_ERROR;
  214. }
  215. DWORD
  216. InternalGetIpNetTable(
  217. OUT MIB_IPNETTABLE **ppIpNetTable,
  218. IN HANDLE hHeap,
  219. IN DWORD dwAllocFlags
  220. )
  221. {
  222. PMIB_OPAQUE_INFO pInfo;
  223. MIB_OPAQUE_QUERY mqQuery;
  224. DWORD dwResult, dwOutEntrySize;
  225. PMIB_IPNETTABLE pTable;
  226. TraceEnter("InternalGetIpNetTable");
  227. *ppIpNetTable = NULL;
  228. #ifndef CHICAGO
  229. if(IsRouterRunning())
  230. {
  231. mqQuery.dwVarId = IP_NETTABLE;
  232. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  233. PID_IP,
  234. IPRTRMGR_PID,
  235. (PVOID)&mqQuery,
  236. sizeof(MIB_OPAQUE_QUERY),
  237. (PVOID)&pInfo,
  238. &dwOutEntrySize);
  239. if(dwResult isnot NO_ERROR)
  240. {
  241. Trace1(ERR,"MprAdminMIBEntryGet failed with error %x",
  242. dwResult);
  243. TraceLeave("InternalGetIpNetTable");
  244. return dwResult;
  245. }
  246. *ppIpNetTable = HeapAlloc(hHeap,
  247. dwAllocFlags,
  248. dwOutEntrySize);
  249. if(*ppIpNetTable is NULL)
  250. {
  251. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  252. Trace1(ERR,"Allocation failed with error %d",
  253. dwResult);
  254. TraceLeave("InternalGetIpNetTable");
  255. MprAdminMIBBufferFree((PVOID)pInfo);
  256. return dwResult;
  257. }
  258. CAST_MIB_INFO(pInfo, PMIB_IPNETTABLE, pTable);
  259. CopyMemory((PVOID)(*ppIpNetTable),
  260. (PVOID)pTable,
  261. SIZEOF_IPNETTABLE(pTable->dwNumEntries));
  262. MprAdminMIBBufferFree((PVOID)pInfo);
  263. }
  264. else
  265. {
  266. #endif
  267. dwResult = AllocateAndGetIpNetTableFromStack(ppIpNetTable,
  268. TRUE,
  269. hHeap,
  270. dwAllocFlags,
  271. FALSE);
  272. if(dwResult isnot NO_ERROR)
  273. {
  274. Trace1(ERR,"AllocateAndGetIpNetTableFromStack failed with error %x",
  275. dwResult);
  276. TraceLeave("InternalGetIpNetTable");
  277. return dwResult;
  278. }
  279. #ifndef CHICAGO
  280. }
  281. #endif
  282. TraceLeave("InternalGetIpNetTable");
  283. return NO_ERROR;
  284. }
  285. DWORD
  286. InternalGetIpForwardTable(
  287. OUT MIB_IPFORWARDTABLE **ppIpForwardTable,
  288. IN HANDLE hHeap,
  289. IN DWORD dwAllocFlags
  290. )
  291. {
  292. PMIB_OPAQUE_INFO pInfo;
  293. MIB_OPAQUE_QUERY mqQuery;
  294. DWORD dwResult, dwOutEntrySize;
  295. PMIB_IPFORWARDTABLE pTable;
  296. TraceEnter("InternalGetIpForwardTable");
  297. *ppIpForwardTable = NULL;
  298. #ifndef CHICAGO
  299. if(IsRouterRunning() &&
  300. IsRouterSettingRoutes())
  301. {
  302. mqQuery.dwVarId = IP_FORWARDTABLE;
  303. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  304. PID_IP,
  305. IPRTRMGR_PID,
  306. (PVOID)&mqQuery,
  307. sizeof(MIB_OPAQUE_QUERY),
  308. (PVOID)&pInfo,
  309. &dwOutEntrySize);
  310. if(dwResult isnot NO_ERROR)
  311. {
  312. Trace1(ERR,"MprAdminMIBEntryGet failed with error %x",
  313. dwResult);
  314. TraceLeave("InternalGetIpForwardTable");
  315. return dwResult;
  316. }
  317. *ppIpForwardTable = HeapAlloc(hHeap,
  318. dwAllocFlags,
  319. dwOutEntrySize);
  320. if(*ppIpForwardTable is NULL)
  321. {
  322. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  323. Trace1(ERR,"Allocation failed with error %d",
  324. dwResult);
  325. TraceLeave("InternalGetIpForwardTable");
  326. MprAdminMIBBufferFree((PVOID)pInfo);
  327. return dwResult;
  328. }
  329. CAST_MIB_INFO(pInfo, PMIB_IPFORWARDTABLE, pTable);
  330. CopyMemory((PVOID)(*ppIpForwardTable),
  331. (PVOID)pTable,
  332. SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries));
  333. MprAdminMIBBufferFree((PVOID)pInfo);
  334. }
  335. else
  336. {
  337. #endif
  338. dwResult = AllocateAndGetIpForwardTableFromStack(ppIpForwardTable,
  339. TRUE,
  340. hHeap,
  341. dwAllocFlags);
  342. if(dwResult isnot NO_ERROR)
  343. {
  344. Trace1(ERR,"InternalGetIpForwardTableFromStack failed with error %x",
  345. dwResult);
  346. TraceLeave("InternalGetIpForwardTable");
  347. return dwResult;
  348. }
  349. #ifndef CHICAGO
  350. }
  351. #endif
  352. TraceLeave("InternalGetIpForwardTable");
  353. return NO_ERROR;
  354. }
  355. DWORD
  356. InternalGetTcpTable(
  357. OUT MIB_TCPTABLE **ppTcpTable,
  358. IN HANDLE hHeap,
  359. IN DWORD dwAllocFlags
  360. )
  361. {
  362. DWORD dwResult;
  363. TraceEnter("InternalGetTcpTable");
  364. *ppTcpTable = NULL;
  365. dwResult = AllocateAndGetTcpTableFromStack(ppTcpTable,
  366. TRUE,
  367. hHeap,
  368. dwAllocFlags);
  369. if(dwResult isnot NO_ERROR)
  370. {
  371. Trace1(ERR,"InternalGetTcpTableFromStack failed with error %x",
  372. dwResult);
  373. TraceLeave("InternalGetTcpTable");
  374. return dwResult;
  375. }
  376. TraceLeave("InternalGetTcpTable");
  377. return NO_ERROR;
  378. }
  379. DWORD
  380. InternalGetUdpTable(
  381. OUT MIB_UDPTABLE **ppUdpTable,
  382. IN HANDLE hHeap,
  383. IN DWORD dwAllocFlags
  384. )
  385. {
  386. DWORD dwResult;
  387. TraceEnter("InternalGetUdpTable");
  388. *ppUdpTable = NULL;
  389. dwResult = AllocateAndGetUdpTableFromStack(ppUdpTable,
  390. TRUE,
  391. hHeap,
  392. dwAllocFlags);
  393. if(dwResult isnot NO_ERROR)
  394. {
  395. Trace1(ERR,"InternalGetUdpTableFromStack failed with error %x",
  396. dwResult);
  397. TraceLeave("InternalGetUdpTable");
  398. return dwResult;
  399. }
  400. TraceLeave("InternalGetUdpTable");
  401. return NO_ERROR;
  402. }
  403. DWORD
  404. InternalSetIfEntry(
  405. IN PMIB_OPAQUE_INFO pInfoRow
  406. )
  407. {
  408. PMIB_IFROW pIfRow = (PMIB_IFROW)(pInfoRow->rgbyData);
  409. DWORD dwResult;
  410. TraceEnter("SetIfEntry");
  411. #ifndef CHICAGO
  412. if(IsRouterRunning())
  413. {
  414. pInfoRow->dwId = IF_ROW;
  415. dwResult = MprAdminMIBEntrySet(g_hMIBServer,
  416. PID_IP,
  417. IPRTRMGR_PID,
  418. (PVOID)pInfoRow,
  419. MIB_INFO_SIZE(MIB_IFROW));
  420. if(dwResult isnot NO_ERROR)
  421. {
  422. Trace1(ERR,"MprAdminMIBEntrySet failed with error %x",
  423. dwResult);
  424. TraceLeave("SetIfEntry");
  425. return dwResult;
  426. }
  427. }
  428. else
  429. {
  430. #endif
  431. dwResult = SetIfEntryToStack(pIfRow,
  432. FALSE);
  433. if(dwResult isnot NO_ERROR)
  434. {
  435. Trace1(ERR,"SetIfEntryToStack failed with error %d",
  436. dwResult);
  437. TraceLeave("SetIfEntry");
  438. return dwResult;
  439. }
  440. #ifndef CHICAGO
  441. }
  442. #endif
  443. TraceLeave("SetIfEntry");
  444. return NO_ERROR;
  445. }
  446. DWORD
  447. InternalCreateIpForwardEntry(
  448. IN PMIB_OPAQUE_INFO pInfoRow
  449. )
  450. {
  451. PMIB_IPFORWARDROW pIpForwardRow = (PMIB_IPFORWARDROW)(pInfoRow->rgbyData);
  452. DWORD dwResult;
  453. TraceEnter("CreateIpForwardEntry");
  454. #ifndef CHICAGO
  455. if(IsRouterRunning() &&
  456. IsRouterSettingRoutes())
  457. {
  458. pInfoRow->dwId = IP_FORWARDROW;
  459. dwResult = MprAdminMIBEntryCreate(g_hMIBServer,
  460. PID_IP,
  461. IPRTRMGR_PID,
  462. (PVOID)pInfoRow,
  463. MIB_INFO_SIZE(MIB_IPFORWARDROW));
  464. if(dwResult isnot NO_ERROR)
  465. {
  466. Trace1(ERR,"MprAdminMIBEntryCreate failed with error %x",
  467. dwResult);
  468. TraceLeave("CreateIpForwardEntry");
  469. return dwResult;
  470. }
  471. }
  472. else
  473. {
  474. #endif
  475. dwResult = SetIpForwardEntryToStack(pIpForwardRow);
  476. if(dwResult isnot NO_ERROR)
  477. {
  478. Trace1(ERR,"SetIpForwarEntryToStack failed with error %d",
  479. dwResult);
  480. TraceLeave("CreateIpForwardEntry");
  481. return dwResult;
  482. }
  483. #ifndef CHICAGO
  484. }
  485. #endif
  486. TraceLeave("CreateIpForwardEntry");
  487. return NO_ERROR;
  488. }
  489. DWORD
  490. InternalSetIpForwardEntry(
  491. IN PMIB_OPAQUE_INFO pInfoRow
  492. )
  493. {
  494. PMIB_IPFORWARDROW pIpForwardRow = (PMIB_IPFORWARDROW)(pInfoRow->rgbyData);
  495. DWORD dwResult;
  496. TraceEnter("SetIpForwardEntry");
  497. #ifndef CHICAGO
  498. if(IsRouterRunning() &&
  499. IsRouterSettingRoutes())
  500. {
  501. pInfoRow->dwId = IP_FORWARDROW;
  502. dwResult = MprAdminMIBEntrySet(g_hMIBServer,
  503. PID_IP,
  504. IPRTRMGR_PID,
  505. (PVOID)pInfoRow,
  506. MIB_INFO_SIZE(MIB_IPFORWARDROW));
  507. if(dwResult isnot NO_ERROR)
  508. {
  509. Trace1(ERR,"MprAdminMIBEntrySet failed with error %x",
  510. dwResult);
  511. TraceLeave("SetIpForwardEntry");
  512. return dwResult;
  513. }
  514. }
  515. else
  516. {
  517. #endif
  518. dwResult = SetIpForwardEntryToStack(pIpForwardRow);
  519. if(dwResult isnot NO_ERROR)
  520. {
  521. Trace1(ERR,"SetIpForwarEntryToStack failed with error %d",
  522. dwResult);
  523. TraceLeave("SetIpForwardEntry");
  524. return dwResult;
  525. }
  526. #ifndef CHICAGO
  527. }
  528. #endif
  529. TraceLeave("SetIpForwardEntry");
  530. return NO_ERROR;
  531. }
  532. DWORD
  533. InternalDeleteIpForwardEntry(
  534. IN PMIB_OPAQUE_INFO pInfoRow
  535. )
  536. {
  537. PMIB_IPFORWARDROW pIpForwardRow = (PMIB_IPFORWARDROW)(pInfoRow->rgbyData);
  538. DWORD dwResult;
  539. TraceEnter("DeleteIpForwardEntry");
  540. pIpForwardRow->dwForwardType = MIB_IPROUTE_TYPE_INVALID;
  541. #ifndef CHICAGO
  542. if(IsRouterRunning() &&
  543. IsRouterSettingRoutes())
  544. {
  545. DWORD rgdwInfo[5];
  546. PMIB_OPAQUE_QUERY pIndex = (PMIB_OPAQUE_QUERY)rgdwInfo;
  547. pIndex->dwVarId = IP_FORWARDROW;
  548. pIndex->rgdwVarIndex[0] = pIpForwardRow->dwForwardDest;
  549. pIndex->rgdwVarIndex[1] = pIpForwardRow->dwForwardProto;
  550. pIndex->rgdwVarIndex[2] = pIpForwardRow->dwForwardPolicy;
  551. pIndex->rgdwVarIndex[3] = pIpForwardRow->dwForwardNextHop;
  552. dwResult = MprAdminMIBEntryDelete(g_hMIBServer,
  553. PID_IP,
  554. IPRTRMGR_PID,
  555. (PVOID)pIndex,
  556. sizeof(rgdwInfo));
  557. if(dwResult isnot NO_ERROR)
  558. {
  559. Trace1(ERR,"MprAdminMIBEntryDelete failed with error %x",
  560. dwResult);
  561. TraceLeave("DeleteIpForwardEntry");
  562. return dwResult;
  563. }
  564. }
  565. else
  566. {
  567. #endif
  568. dwResult = SetIpForwardEntryToStack(pIpForwardRow);
  569. if(dwResult isnot NO_ERROR)
  570. {
  571. Trace1(ERR,"SetIpForwarEntryToStack failed with error %d",
  572. dwResult);
  573. TraceLeave("CreateIpForwardEntry");
  574. return dwResult;
  575. }
  576. #ifndef CHICAGO
  577. }
  578. #endif
  579. TraceLeave("CreateIpForwardEntry");
  580. return NO_ERROR;
  581. }
  582. DWORD
  583. InternalSetIpStats(
  584. IN PMIB_OPAQUE_INFO pInfoRow
  585. )
  586. {
  587. PMIB_IPSTATS pIpStats = (PMIB_IPSTATS)(pInfoRow->rgbyData);
  588. DWORD dwResult;
  589. TraceEnter("SetIpStats");
  590. #ifndef CHICAGO
  591. if(IsRouterRunning())
  592. {
  593. pInfoRow->dwId = IP_STATS;
  594. dwResult = MprAdminMIBEntrySet(g_hMIBServer,
  595. PID_IP,
  596. IPRTRMGR_PID,
  597. (PVOID)pInfoRow,
  598. MIB_INFO_SIZE(MIB_IPSTATS));
  599. if(dwResult isnot NO_ERROR)
  600. {
  601. Trace1(ERR,"MprAdminMIBEntrySet failed with error %x",
  602. dwResult);
  603. TraceLeave("SetIpStats");
  604. return dwResult;
  605. }
  606. }
  607. else
  608. {
  609. #endif
  610. dwResult = SetIpStatsToStack(pIpStats);
  611. if(dwResult isnot NO_ERROR)
  612. {
  613. Trace1(ERR,"SetIpStatsToStack failed with error %d",
  614. dwResult);
  615. TraceLeave("SetIpStats");
  616. return dwResult;
  617. }
  618. #ifndef CHICAGO
  619. }
  620. #endif
  621. TraceLeave("SetIpStats");
  622. return NO_ERROR;
  623. }
  624. DWORD
  625. InternalCreateIpNetEntry(
  626. IN PMIB_OPAQUE_INFO pInfoRow
  627. )
  628. {
  629. PMIB_IPNETROW pIpNetRow = (PMIB_IPNETROW)(pInfoRow->rgbyData);
  630. DWORD dwResult;
  631. TraceEnter("CreateIpNetEntry");
  632. #ifndef CHICAGO
  633. if(IsRouterRunning())
  634. {
  635. pInfoRow->dwId = IP_NETROW;
  636. dwResult = MprAdminMIBEntryCreate(g_hMIBServer,
  637. PID_IP,
  638. IPRTRMGR_PID,
  639. (PVOID)pInfoRow,
  640. MIB_INFO_SIZE(MIB_IPNETROW));
  641. if(dwResult isnot NO_ERROR)
  642. {
  643. Trace1(ERR,"MprAdminMIBEntryCreate failed with error %x",
  644. dwResult);
  645. TraceLeave("CreateIpNetEntry");
  646. return dwResult;
  647. }
  648. }
  649. else
  650. {
  651. #endif
  652. dwResult = SetIpNetEntryToStack(pIpNetRow,
  653. FALSE);
  654. if(dwResult isnot NO_ERROR)
  655. {
  656. Trace1(ERR,"SetIpNetEntryToStack failed with error %d",
  657. dwResult);
  658. TraceLeave("CreateIpNetEntry");
  659. return dwResult;
  660. }
  661. #ifndef CHICAGO
  662. }
  663. #endif
  664. TraceLeave("CreateIpNetEntry");
  665. return NO_ERROR;
  666. }
  667. DWORD
  668. InternalSetIpNetEntry(
  669. PMIB_OPAQUE_INFO pInfoRow
  670. )
  671. {
  672. PMIB_IPNETROW pIpNetRow = (PMIB_IPNETROW)(pInfoRow->rgbyData);
  673. DWORD dwResult;
  674. TraceEnter("SetIpNetEntry");
  675. #ifndef CHICAGO
  676. if(IsRouterRunning())
  677. {
  678. pInfoRow->dwId = IP_NETROW;
  679. dwResult = MprAdminMIBEntrySet(g_hMIBServer,
  680. PID_IP,
  681. IPRTRMGR_PID,
  682. (PVOID)pInfoRow,
  683. MIB_INFO_SIZE(MIB_IPNETROW));
  684. if(dwResult isnot NO_ERROR)
  685. {
  686. Trace1(ERR,"MprAdminMIBEntrySet failed with error %x",
  687. dwResult);
  688. TraceLeave("SetIpNetEntry");
  689. return dwResult;
  690. }
  691. }
  692. else
  693. {
  694. #endif
  695. dwResult = SetIpNetEntryToStack(pIpNetRow,
  696. FALSE);
  697. if(dwResult isnot NO_ERROR)
  698. {
  699. Trace1(ERR,"SetIpNetEntryToStack failed with error %d",
  700. dwResult);
  701. TraceLeave("SetIpNetEntry");
  702. return dwResult;
  703. }
  704. #ifndef CHICAGO
  705. }
  706. #endif
  707. TraceLeave("SetIpNetEntry");
  708. return NO_ERROR;
  709. }
  710. DWORD
  711. InternalDeleteIpNetEntry(
  712. PMIB_OPAQUE_INFO pInfoRow
  713. )
  714. {
  715. PMIB_IPNETROW pIpNetRow = (PMIB_IPNETROW)(pInfoRow->rgbyData);
  716. DWORD dwResult;
  717. TraceEnter("DeleteIpNetEntry");
  718. pIpNetRow->dwType = MIB_IPNET_TYPE_INVALID;
  719. #ifndef CHICAGO
  720. if(IsRouterRunning())
  721. {
  722. DWORD rgdwInfo[3];
  723. PMIB_OPAQUE_QUERY pIndex = (PMIB_OPAQUE_QUERY)rgdwInfo;
  724. pIndex->dwVarId = IP_NETROW;
  725. pIndex->rgdwVarIndex[0] = pIpNetRow->dwIndex;
  726. pIndex->rgdwVarIndex[1] = pIpNetRow->dwAddr;
  727. dwResult = MprAdminMIBEntryDelete(g_hMIBServer,
  728. PID_IP,
  729. IPRTRMGR_PID,
  730. (PVOID)pIndex,
  731. sizeof(rgdwInfo));
  732. if(dwResult isnot NO_ERROR)
  733. {
  734. Trace1(ERR,"MprAdminMIBEntryDelete failed with error %x",
  735. dwResult);
  736. TraceLeave("DeleteIpNetEntry");
  737. return dwResult;
  738. }
  739. }
  740. else
  741. {
  742. #endif
  743. dwResult = SetIpNetEntryToStack(pIpNetRow,
  744. FALSE);
  745. if(dwResult isnot NO_ERROR)
  746. {
  747. Trace1(ERR,"SetIpNetEntryToStack failed with error %d",
  748. dwResult);
  749. TraceLeave("DeleteIpNetEntry");
  750. return dwResult;
  751. }
  752. #ifndef CHICAGO
  753. }
  754. #endif
  755. TraceLeave("DeleteIpNetEntry");
  756. return NO_ERROR;
  757. }
  758. DWORD
  759. InternalSetTcpEntry(
  760. PMIB_OPAQUE_INFO pInfoRow
  761. )
  762. {
  763. PMIB_TCPROW pTcpRow = (PMIB_TCPROW)(pInfoRow->rgbyData);
  764. DWORD dwResult;
  765. TraceEnter("SetTcpEntry");
  766. dwResult = SetTcpEntryToStack(pTcpRow);
  767. if(dwResult isnot NO_ERROR)
  768. {
  769. Trace1(ERR,"SetTcpEntryToStack failed with error %d",
  770. dwResult);
  771. TraceLeave("SetTcpEntry");
  772. return dwResult;
  773. }
  774. TraceLeave("SetTcpEntry");
  775. return NO_ERROR;
  776. }
  777. //#define MAX_ADAPTER_NAME_LENGTH 256
  778. DWORD
  779. OpenAdapterKey(
  780. LPSTR Name,
  781. PHKEY Key
  782. )
  783. {
  784. DWORD dwResult;
  785. CHAR keyName[MAX_ADAPTER_NAME_LENGTH +
  786. sizeof("\\Parameters\\Tcpip") +
  787. sizeof("SYSTEM\\CurrentControlSet\\Services\\")];
  788. //
  789. // open the handle to this adapter's TCPIP parameter key
  790. //
  791. strcpy(keyName, "SYSTEM\\CurrentControlSet\\Services\\");
  792. lstrcpyn(keyName + lstrlen(keyName), Name, MAX_ADAPTER_NAME_LENGTH);
  793. strcat(keyName, "\\Parameters\\Tcpip");
  794. Trace1(ERR,"OpenAdapterKey: %s", keyName);
  795. dwResult = RegOpenKey(HKEY_LOCAL_MACHINE,
  796. keyName,
  797. Key);
  798. return dwResult;
  799. }
  800. DWORD
  801. ReadRegistryDword(HKEY Key, LPSTR ParameterName, PULONG Value)
  802. {
  803. DWORD dwResult, valueLength, valueType;
  804. valueLength = sizeof(*Value);
  805. dwResult = RegQueryValueEx(Key,
  806. ParameterName,
  807. NULL, // reserved
  808. &valueType,
  809. (LPBYTE)Value,
  810. &valueLength);
  811. return dwResult;
  812. }
  813. DWORD
  814. GetAdapterIPInterfaceContext(LPSTR AdapterName, PULONG Context)
  815. {
  816. HKEY key;
  817. DWORD dwResult;
  818. if ((dwResult = OpenAdapterKey(AdapterName, &key)) != NO_ERROR) {
  819. return(dwResult);
  820. }
  821. dwResult = ReadRegistryDword(key, "IPInterfaceContext", Context);
  822. RegCloseKey(key);
  823. return(dwResult);
  824. }
  825. DWORD
  826. GetInterfaceInfo(PIP_INTERFACE_INFO pIPIfInfo, PULONG dwOutBufLen)
  827. {
  828. #if defined(NT4) || defined(_WIN95_)
  829. return ERROR_NOT_SUPPORTED;
  830. #else
  831. DWORD status=0;
  832. DWORD dwNumIf;
  833. DWORD dwResult;
  834. MIB_IPSTATS IpSnmpInfo;
  835. if (IsBadWritePtr(dwOutBufLen, sizeof(ULONG))) {
  836. return ERROR_INVALID_PARAMETER;
  837. }
  838. if (IsBadWritePtr(pIPIfInfo, *dwOutBufLen)) {
  839. return ERROR_INVALID_PARAMETER;
  840. }
  841. dwResult = GetIpStatsFromStack(&IpSnmpInfo);
  842. if(dwResult isnot NO_ERROR) {
  843. Trace1(ERR,"GetInterfaceInfo: GetIpStatsFromStack returned error %d",
  844. dwResult);
  845. return dwResult;
  846. }
  847. dwNumIf = IpSnmpInfo.dwNumIf;
  848. if(dwNumIf is 0) {
  849. Trace0(ERR,"GetInterfaceInfo: No interfaces");
  850. return ERROR_NO_DATA;
  851. }
  852. if (dwOutBufLen == NULL) {
  853. return ERROR_INVALID_PARAMETER;
  854. }
  855. if (!pIPIfInfo ||
  856. (*dwOutBufLen <
  857. (ULONG)sizeof(IP_ADAPTER_INDEX_MAP)*dwNumIf)) {
  858. *dwOutBufLen =
  859. (ULONG)sizeof(IP_ADAPTER_INDEX_MAP)*(dwNumIf + OVERFLOW_COUNT);
  860. return ERROR_INSUFFICIENT_BUFFER;
  861. }
  862. Trace1(ERR, "GetInterfaceInfo: outbuflen %d", *dwOutBufLen);
  863. return TCPSendIoctl(g_hIPGetDriverHandle,
  864. IOCTL_IP_INTERFACE_INFO,
  865. NULL,
  866. &status,
  867. pIPIfInfo,
  868. dwOutBufLen);
  869. #endif
  870. }
  871. DWORD
  872. GetUniDirectionalAdapterInfo(PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS pIPIfInfo,
  873. PULONG dwOutBufLen)
  874. {
  875. DWORD status=0;
  876. if (dwOutBufLen == NULL) {
  877. return ERROR_INVALID_PARAMETER;
  878. }
  879. return TCPSendIoctl(g_hIPGetDriverHandle,
  880. IOCTL_IP_UNIDIRECTIONAL_ADAPTER_ADDRESS,
  881. NULL,
  882. &status,
  883. pIPIfInfo,
  884. dwOutBufLen);
  885. }
  886. DWORD
  887. GetIgmpList(IPAddr NTEAddr, IPAddr *pIgmpList, PULONG pdwOutBufLen)
  888. /*++
  889. Routine Description:
  890. When pIgmpList is NULL, get the amount of space necessary to hold
  891. the group addresses joined on a given interface address.
  892. When pIgmpList is non-NULL and *pdwOutBufLen is more than 4 bytes,
  893. get the actual group addresses.
  894. Arguments:
  895. NTEAddr - Supplies the address of an interface whose multicast
  896. group information is being requested.
  897. pIgmpList - Supplies a buffer in which to put group addresses, or
  898. NULL to just request amount of space desired.
  899. pdwOutBufLen - When pIgmpList is NULL, returns the amount of space
  900. the caller should allocate to get all groups.
  901. When pIgmpList is non-NULL, supplies the size of
  902. the buffer supplied, and returns the amount of
  903. space actually used.
  904. Return Value:
  905. NO_ERROR
  906. ERROR_INVALID_PARAMETER if the arguments don't meet the requirements.
  907. ERROR_INSUFFICIENT_BUFFER if more groups are available than fit.
  908. --*/
  909. {
  910. DWORD inlen = sizeof(IPAddr);
  911. DWORD dwStatus;
  912. if (pdwOutBufLen == NULL) {
  913. return ERROR_INVALID_PARAMETER;
  914. }
  915. if (IsBadWritePtr(pdwOutBufLen, sizeof(ULONG))) {
  916. return ERROR_INVALID_PARAMETER;
  917. }
  918. if (pIgmpList == NULL) {
  919. DWORD dwSize;
  920. //
  921. // When pIgmpList is NULL, the caller is just asking for the
  922. // amount of space needed, so use pdwOutBufLen as the buffer.
  923. //
  924. dwSize = sizeof(*pdwOutBufLen);
  925. dwStatus = TCPSendIoctl(g_hIPGetDriverHandle,
  926. IOCTL_IP_GET_IGMPLIST,
  927. &NTEAddr,
  928. &inlen,
  929. pdwOutBufLen,
  930. &dwSize);
  931. } else {
  932. //
  933. // Otherwise the caller wants the list of groups.
  934. //
  935. if (IsBadWritePtr(pIgmpList, *pdwOutBufLen)) {
  936. return ERROR_INVALID_PARAMETER;
  937. }
  938. if (*pdwOutBufLen <= sizeof(ULONG)) {
  939. //
  940. // Make sure the buffer is bigger than a ULONG or we'll get
  941. // the size back, not group data. The IOCTL insures that
  942. // when the caller requests the size needed, the amount
  943. // returned will be bigger than a ULONG.
  944. //
  945. return ERROR_INVALID_PARAMETER;
  946. }
  947. dwStatus = TCPSendIoctl(g_hIPGetDriverHandle,
  948. IOCTL_IP_GET_IGMPLIST,
  949. &NTEAddr,
  950. &inlen,
  951. pIgmpList,
  952. pdwOutBufLen);
  953. }
  954. if (dwStatus == ERROR_MORE_DATA) {
  955. //
  956. // Callers expect ERROR_INSUFFICIENT_BUFFER when *pdwOutBufLen is
  957. // too small. However, the stack actually generates a warning
  958. // (ERROR_MORE_DATA), rather than an error (ERROR_INSUFFICIENT_BUFFER)
  959. // so that the data gets passed back to the caller.
  960. //
  961. dwStatus = ERROR_INSUFFICIENT_BUFFER;
  962. }
  963. return dwStatus;
  964. }
  965. DWORD
  966. SetBlockRoutes(IPRouteBlock *RouteBlock, PULONG poutbuflen, PULONG statusblock)
  967. {
  968. DWORD inlen;
  969. if (IsRouterRunning()) {
  970. return ERROR_NOT_SUPPORTED;
  971. }
  972. if (poutbuflen == NULL) {
  973. // Null pointers ?
  974. return ERROR_INVALID_PARAMETER;
  975. }
  976. if (IsBadReadPtr(poutbuflen, sizeof(ULONG))) {
  977. return ERROR_INVALID_PARAMETER;
  978. }
  979. if (IsBadReadPtr(RouteBlock, sizeof(IPRouteBlock))) {
  980. return ERROR_INVALID_PARAMETER;
  981. }
  982. inlen = (RouteBlock->numofroutes * sizeof(IPRouteEntry)) + sizeof(ulong);
  983. if (IsBadReadPtr(RouteBlock, inlen)) {
  984. return ERROR_INVALID_PARAMETER;
  985. }
  986. return TCPSendIoctl(g_hIPDriverHandle,
  987. IOCTL_IP_SET_BLOCKOFROUTES,
  988. RouteBlock,
  989. &inlen,
  990. statusblock,
  991. poutbuflen);
  992. }
  993. DWORD
  994. SetRouteWithRef(IN IPRouteEntry *RouteEntry
  995. )
  996. {
  997. DWORD inlen = sizeof(IPRouteEntry);
  998. ULONG outbuflen;
  999. if (IsRouterRunning()) {
  1000. return ERROR_NOT_SUPPORTED;
  1001. }
  1002. if (IsBadReadPtr(RouteEntry, inlen)) {
  1003. return ERROR_INVALID_PARAMETER;
  1004. }
  1005. return TCPSendIoctl(g_hIPDriverHandle,
  1006. IOCTL_IP_SET_ROUTEWITHREF,
  1007. RouteEntry,
  1008. &inlen,
  1009. NULL,
  1010. &outbuflen);
  1011. }
  1012. DWORD
  1013. GetAdapterIndex(
  1014. IN LPWSTR AdapterName,
  1015. OUT PULONG IfIndex
  1016. )
  1017. /*++
  1018. Routine Description:
  1019. Gets the target IP interface given the name of the adapter associated with it.
  1020. Arguments:
  1021. AdapterName - A unicode string identifying the adapter/interface to which
  1022. to add the new NTE.
  1023. ifIndex - Interface index associated with the adapter name.
  1024. Return Value:
  1025. ERROR_SUCCESS or windows error
  1026. --*/
  1027. {
  1028. #ifdef CHICAGO
  1029. return ERROR_NOT_SUPPORTED;
  1030. #else
  1031. int i;
  1032. DWORD dwResult;
  1033. IP_INTERFACE_INFO *pIPIfInfo=NULL;
  1034. DWORD dwNumIf, NumAdapters;
  1035. ULONG dwOutBufLen;
  1036. if (AdapterName == NULL || IfIndex == NULL)
  1037. {
  1038. return(ERROR_INVALID_PARAMETER);
  1039. }
  1040. dwResult = GetNumberOfInterfaces(&dwNumIf);
  1041. if(dwResult isnot NO_ERROR)
  1042. {
  1043. Trace1(ERR,"GetAdapterIndex: GetNumberOfInterfaces returned error %d",
  1044. dwResult);
  1045. return dwResult;
  1046. }
  1047. if(dwNumIf is 0)
  1048. {
  1049. Trace0(ERR,"GetAdapterIndex: No interfaces");
  1050. return ERROR_NO_DATA;
  1051. }
  1052. dwOutBufLen = (ULONG)sizeof(IP_ADAPTER_INDEX_MAP)*(dwNumIf + OVERFLOW_COUNT);
  1053. pIPIfInfo = HeapAlloc(g_hPrivateHeap, FALSE, dwOutBufLen);
  1054. if(pIPIfInfo is NULL)
  1055. {
  1056. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  1057. Trace1(ERR,
  1058. "GetAdapterIndex: Couldnt allocate memory. Error %d",
  1059. dwResult);
  1060. return dwResult;
  1061. }
  1062. dwResult = GetInterfaceInfo(pIPIfInfo, &dwOutBufLen);
  1063. if (dwResult isnot NO_ERROR)
  1064. {
  1065. Trace1(ERR,
  1066. "GetAdapterIndex: Error %d calling GetInterfaceInfo",
  1067. dwResult);
  1068. HeapFree(g_hPrivateHeap, 0, pIPIfInfo);
  1069. return dwResult;
  1070. }
  1071. // search for the adaptername within this info and return the index.
  1072. NumAdapters = pIPIfInfo->NumAdapters;
  1073. for (i = 0; i < (int)pIPIfInfo->NumAdapters; i++) {
  1074. if (lstrcmpiW(AdapterName, pIPIfInfo->Adapter[i].Name) == 0)
  1075. {
  1076. break;
  1077. }
  1078. }
  1079. if (i < (int)pIPIfInfo->NumAdapters)
  1080. {
  1081. *IfIndex = pIPIfInfo->Adapter[i].Index;
  1082. HeapFree(g_hPrivateHeap, 0, pIPIfInfo);
  1083. return(NO_ERROR);
  1084. }
  1085. HeapFree(g_hPrivateHeap, 0, pIPIfInfo);
  1086. return(ERROR_DEV_NOT_EXIST);
  1087. #endif
  1088. }
  1089. DWORD
  1090. AddIPAddress(IPAddr Address, IPMask IpMask, DWORD IfIndex, PULONG NTEContext,
  1091. PULONG NTEInstance)
  1092. {
  1093. #ifdef CHICAGO
  1094. return ERROR_NOT_SUPPORTED;
  1095. #else
  1096. IP_ADD_NTE_REQUEST requestBuffer;
  1097. PIP_ADD_NTE_RESPONSE responseBuffer =
  1098. (PIP_ADD_NTE_RESPONSE) &requestBuffer;
  1099. DWORD requestBufferSize = sizeof(requestBuffer);
  1100. DWORD responseBufferSize = sizeof(requestBuffer);
  1101. DWORD status;
  1102. //
  1103. // Validate the IP address to be added. Check for
  1104. // * broadcast address,
  1105. // * loopback address,
  1106. // * zero address,
  1107. // * Class D address,
  1108. // * zero subnet-broadcast address
  1109. // * all-ones subnet-broadcast address
  1110. // * non-contiguous mask (which we test by negating the host-order mask
  1111. // and verifying that all the bits change when we add 1, i.e. that
  1112. // the negation is of the form 2^n-1).
  1113. //
  1114. if ((Address == INADDR_BROADCAST) ||
  1115. ((ntohl(Address) & IN_CLASSA_NET) ==
  1116. (INADDR_LOOPBACK & IN_CLASSA_NET)) ||
  1117. (Address == 0) ||
  1118. (IN_CLASSD(ntohl(Address))) ||
  1119. ((Address & ~IpMask) == 0) ||
  1120. ((Address & ~IpMask) == ~IpMask) ||
  1121. ((~ntohl(IpMask) + 1) & ~ntohl(IpMask))) {
  1122. return ERROR_INVALID_PARAMETER;
  1123. }
  1124. if ( (NTEContext == NULL) || (NTEInstance == NULL) ) {
  1125. return ERROR_INVALID_PARAMETER;
  1126. }
  1127. if (IsBadWritePtr(NTEContext, sizeof(ULONG))) {
  1128. return ERROR_INVALID_PARAMETER;
  1129. }
  1130. if (IsBadWritePtr(NTEInstance, sizeof(ULONG))) {
  1131. return ERROR_INVALID_PARAMETER;
  1132. }
  1133. requestBuffer.InterfaceContext = (unsigned long) IfIndex;
  1134. requestBuffer.Address = Address;
  1135. requestBuffer.SubnetMask = IpMask;
  1136. status = TCPSendIoctl(g_hIPDriverHandle,
  1137. IOCTL_IP_ADD_NTE,
  1138. &requestBuffer,
  1139. &requestBufferSize,
  1140. responseBuffer,
  1141. &responseBufferSize);
  1142. if (status == NO_ERROR) {
  1143. *NTEContext = (ULONG) responseBuffer->Context;
  1144. *NTEInstance = responseBuffer->Instance;
  1145. } else if (status == STATUS_DUPLICATE_OBJECTID) {
  1146. status = ERROR_DUP_DOMAINNAME;
  1147. }
  1148. return(status);
  1149. #endif
  1150. }
  1151. DWORD
  1152. DeleteIPAddress(ULONG NTEContext)
  1153. {
  1154. #ifdef CHICAGO
  1155. return ERROR_NOT_SUPPORTED;
  1156. #else
  1157. IP_DELETE_NTE_REQUEST requestBuffer;
  1158. DWORD requestBufferSize = sizeof(requestBuffer);
  1159. DWORD responseBufferSize = 0;
  1160. DWORD status;
  1161. requestBuffer.Context = (unsigned short) NTEContext;
  1162. status = TCPSendIoctl(g_hIPDriverHandle,
  1163. IOCTL_IP_DELETE_NTE,
  1164. &requestBuffer,
  1165. &requestBufferSize,
  1166. NULL,
  1167. &responseBufferSize);
  1168. return(status);
  1169. #endif
  1170. }
  1171. #define DEFAULT_TTL 32
  1172. #define DEFAULT_TOS 0
  1173. #define DEFAULT_TIMEOUT 5000L
  1174. #include <icmpapi.h>
  1175. #ifndef CHICAGO
  1176. #include <ntddip.h>
  1177. #endif
  1178. BOOL
  1179. GetRTT(IPAddr DestIpAddress, PULONG Rtt)
  1180. {
  1181. uchar FAR *Opt = (uchar FAR *)0; // Pointer to send options
  1182. uint OptLength = 0;
  1183. uchar Flags = 0;
  1184. ulong Timeout = DEFAULT_TIMEOUT;
  1185. IP_OPTION_INFORMATION SendOpts;
  1186. HANDLE IcmpHandle;
  1187. PICMP_ECHO_REPLY reply;
  1188. char SendBuffer[32], *RcvBuffer;
  1189. uint RcvSize=4096;
  1190. uint SendSize = 32;
  1191. uint i;
  1192. DWORD numberOfReplies;
  1193. if (IsBadWritePtr(Rtt, sizeof(ULONG))) {
  1194. return ERROR_INVALID_PARAMETER;
  1195. }
  1196. IcmpHandle = IcmpCreateFile();
  1197. if (IcmpHandle == INVALID_HANDLE_VALUE) {
  1198. return(FALSE);
  1199. }
  1200. //
  1201. // Allocate space for the response.
  1202. //
  1203. RcvBuffer = HeapAlloc(g_hPrivateHeap, 0, RcvSize);
  1204. if (RcvBuffer == NULL) {
  1205. IcmpCloseHandle(IcmpHandle);
  1206. return(FALSE);
  1207. }
  1208. //
  1209. // Initialize the send buffer pattern.
  1210. //
  1211. for (i = 0; i < SendSize; i++) {
  1212. SendBuffer[i] = (char) ('a' + (i % 23));
  1213. }
  1214. //
  1215. // Initialize the send options
  1216. //
  1217. SendOpts.OptionsData = Opt;
  1218. SendOpts.OptionsSize = (UCHAR) OptLength;
  1219. SendOpts.Ttl = DEFAULT_TTL;
  1220. SendOpts.Tos = DEFAULT_TOS;
  1221. SendOpts.Flags = Flags;
  1222. numberOfReplies = IcmpSendEcho(IcmpHandle,
  1223. DestIpAddress,
  1224. SendBuffer,
  1225. (unsigned short) SendSize,
  1226. &SendOpts,
  1227. RcvBuffer,
  1228. RcvSize,
  1229. DEFAULT_TIMEOUT);
  1230. if (numberOfReplies) {
  1231. numberOfReplies = IcmpSendEcho(IcmpHandle,
  1232. DestIpAddress,
  1233. SendBuffer,
  1234. (unsigned short) SendSize,
  1235. &SendOpts,
  1236. RcvBuffer,
  1237. RcvSize,
  1238. Timeout);
  1239. if (numberOfReplies) {
  1240. reply = (PICMP_ECHO_REPLY) RcvBuffer;
  1241. *Rtt = reply->RoundTripTime;
  1242. HeapFree(g_hPrivateHeap, 0, RcvBuffer);
  1243. IcmpCloseHandle(IcmpHandle);
  1244. return(TRUE);
  1245. }
  1246. }
  1247. HeapFree(g_hPrivateHeap, 0, RcvBuffer);
  1248. IcmpCloseHandle(IcmpHandle);
  1249. return(FALSE);
  1250. }
  1251. BOOL
  1252. GetRTTAndHopCount(IPAddr DestIpAddress, PULONG HopCount, ULONG MaxHops,
  1253. PULONG RTT)
  1254. {
  1255. DWORD numberOfReplies;
  1256. uchar FAR *Opt = (uchar FAR *)0; // Pointer to send options
  1257. uint OptLength = 0;
  1258. uchar Flags = 0;
  1259. ulong Timeout = DEFAULT_TIMEOUT;
  1260. IP_OPTION_INFORMATION SendOpts;
  1261. HANDLE IcmpHandle;
  1262. PICMP_ECHO_REPLY reply;
  1263. char SendBuffer[32], *RcvBuffer;
  1264. uint RcvSize=4096;
  1265. uint SendSize = 32;
  1266. uint i,status;
  1267. ULONG RTT1;
  1268. if (!HopCount || !RTT) {
  1269. return (FALSE);
  1270. }
  1271. if (DestIpAddress == -1L) {
  1272. return(FALSE);
  1273. }
  1274. if (IsBadWritePtr(RTT, sizeof(ULONG))) {
  1275. return (FALSE);
  1276. }
  1277. if (IsBadWritePtr(HopCount, sizeof(ULONG))) {
  1278. return (FALSE);
  1279. }
  1280. IcmpHandle = IcmpCreateFile();
  1281. if (IcmpHandle == INVALID_HANDLE_VALUE) {
  1282. return(FALSE);
  1283. }
  1284. //
  1285. // Allocate space for the response.
  1286. //
  1287. RcvBuffer = HeapAlloc(g_hPrivateHeap, 0, RcvSize);
  1288. if (RcvBuffer == NULL) {
  1289. IcmpCloseHandle(IcmpHandle);
  1290. return(FALSE);
  1291. }
  1292. //
  1293. // Initialize the send buffer pattern.
  1294. //
  1295. for (i = 0; i < SendSize; i++) {
  1296. SendBuffer[i] = (char) ('a' + (i % 23));
  1297. }
  1298. //
  1299. // Initialize the send options
  1300. //
  1301. SendOpts.OptionsData = Opt;
  1302. SendOpts.OptionsSize = (UCHAR) OptLength;
  1303. SendOpts.Ttl = 1;
  1304. SendOpts.Tos = DEFAULT_TOS;
  1305. SendOpts.Flags = Flags;
  1306. while (SendOpts.Ttl <= MaxHops) {
  1307. numberOfReplies = IcmpSendEcho(IcmpHandle,
  1308. DestIpAddress,
  1309. SendBuffer,
  1310. (unsigned short) SendSize,
  1311. &SendOpts,
  1312. RcvBuffer,
  1313. RcvSize,
  1314. Timeout);
  1315. if (numberOfReplies == 0) {
  1316. status = GetLastError();
  1317. reply = NULL;
  1318. } else {
  1319. reply = (PICMP_ECHO_REPLY)RcvBuffer;
  1320. status = reply->Status;
  1321. }
  1322. if (status == IP_SUCCESS) {
  1323. *HopCount = SendOpts.Ttl;
  1324. HeapFree(g_hPrivateHeap, 0, RcvBuffer);
  1325. IcmpCloseHandle(IcmpHandle);
  1326. if (GetRTT(DestIpAddress, &RTT1)) {
  1327. *RTT = RTT1;
  1328. return TRUE;
  1329. } else {
  1330. return FALSE;
  1331. }
  1332. } else if (status == IP_TTL_EXPIRED_TRANSIT ||
  1333. status == IP_REQ_TIMED_OUT) {
  1334. SendOpts.Ttl++;
  1335. } else {
  1336. HeapFree(g_hPrivateHeap, 0, RcvBuffer);
  1337. IcmpCloseHandle(IcmpHandle);
  1338. return FALSE;
  1339. }
  1340. }
  1341. HeapFree(g_hPrivateHeap, 0, RcvBuffer);
  1342. IcmpCloseHandle(IcmpHandle);
  1343. return FALSE;
  1344. }
  1345. #define LOOPBACK_ADDR 0x0100007f
  1346. DWORD
  1347. IsLocalAddress(IPAddr InAddress)
  1348. {
  1349. int i;
  1350. DWORD dwResult;
  1351. int NumEntries;
  1352. PMIB_IPADDRTABLE pIpAddrTable;
  1353. PMIB_IPADDRROW pIpAddrEntry;
  1354. dwResult = AllocateAndGetIpAddrTableFromStack(&pIpAddrTable,
  1355. FALSE,
  1356. g_hPrivateHeap,
  1357. 0);
  1358. if(dwResult isnot NO_ERROR) {
  1359. Trace1(ERR,"GetIpAddrTableFromStack failed with error %x",dwResult);
  1360. TraceLeave("IsLocalAddress");
  1361. return dwResult;
  1362. }
  1363. if (InAddress == LOOPBACK_ADDR) {
  1364. HeapFree(g_hPrivateHeap, 0, pIpAddrTable);
  1365. return(NO_ERROR);
  1366. }
  1367. NumEntries = (*pIpAddrTable).dwNumEntries;
  1368. Trace2(ERR,"IsLocalAddress number of addresses %d chking %x",
  1369. NumEntries,InAddress);
  1370. for (i = 0; i < NumEntries; i++) {
  1371. pIpAddrEntry = &(*pIpAddrTable).table[i];
  1372. Trace1(ERR,"IsLocalAddress cmparing %x",pIpAddrEntry->dwAddr);
  1373. if (pIpAddrEntry->dwAddr == (DWORD)InAddress) {
  1374. HeapFree(g_hPrivateHeap, 0, pIpAddrTable);
  1375. return(NO_ERROR);
  1376. }
  1377. }
  1378. HeapFree(g_hPrivateHeap, 0, pIpAddrTable);
  1379. return(ERROR_INVALID_ADDRESS);
  1380. }
  1381. DWORD
  1382. NotifyAddrChange(HANDLE *pHandle, OVERLAPPED *pOverLapped)
  1383. {
  1384. #if defined(NT4) || defined(CHICAGO)
  1385. return ERROR_NOT_SUPPORTED;
  1386. #else
  1387. BOOL b;
  1388. DWORD dwResult;
  1389. DWORD temp;
  1390. if ((pHandle != NULL) && (pOverLapped != NULL)) {
  1391. Trace0(ERR, "NotifyAddressChange: overlapped request");
  1392. if (IsBadWritePtr(pHandle, sizeof(HANDLE))) {
  1393. return ERROR_INVALID_PARAMETER;
  1394. }
  1395. if (IsBadWritePtr(pOverLapped, sizeof(OVERLAPPED))) {
  1396. return ERROR_INVALID_PARAMETER;
  1397. }
  1398. *pHandle = ChangeNotificationHandle;
  1399. if (*pHandle == INVALID_HANDLE_VALUE){
  1400. Trace1(ERR, "NotifyAddressChange: CreateFile=%d", GetLastError());
  1401. return ERROR_OPEN_FAILED;
  1402. }
  1403. b = DeviceIoControl(*pHandle,
  1404. IOCTL_IP_ADDCHANGE_NOTIFY_REQUEST,
  1405. NULL,
  1406. 0,
  1407. NULL,
  1408. 0,
  1409. &temp,
  1410. pOverLapped);
  1411. if (!b) {
  1412. dwResult = GetLastError();
  1413. Trace1(ERR, "NotifyAddrChange: DeviceIoControl=%d", dwResult);
  1414. return dwResult;
  1415. }
  1416. } else {
  1417. // Synchronous change notification
  1418. // This call will block
  1419. Trace0(ERR, "NotifyAddrChange: synchronous request");
  1420. b = DeviceIoControl(g_hIPGetDriverHandle,
  1421. IOCTL_IP_ADDCHANGE_NOTIFY_REQUEST,
  1422. NULL,
  1423. 0,
  1424. NULL,
  1425. 0,
  1426. &temp,
  1427. NULL);
  1428. if (!b) {
  1429. dwResult = GetLastError();
  1430. Trace1(ERR, "NotifyAddressChange: DeviceIoControl=%d", dwResult);
  1431. return dwResult;
  1432. }
  1433. }
  1434. return NO_ERROR;
  1435. #endif
  1436. }
  1437. DWORD
  1438. NotifyRouteChange(HANDLE *pHandle, OVERLAPPED *pOverLapped)
  1439. {
  1440. return NotifyRouteChangeEx(pHandle, pOverLapped, FALSE);
  1441. }
  1442. DWORD
  1443. NotifyRouteChangeEx(
  1444. PHANDLE pHandle,
  1445. LPOVERLAPPED pOverLapped,
  1446. BOOL bExQueue
  1447. )
  1448. {
  1449. #if defined(NT4) || defined(CHICAGO)
  1450. return ERROR_NOT_SUPPORTED;
  1451. #else
  1452. BOOL b;
  1453. DWORD dwResult;
  1454. DWORD temp;
  1455. DWORD dwIoctl;
  1456. if(bExQueue) {
  1457. dwIoctl = IOCTL_IP_RTCHANGE_NOTIFY_REQUEST_EX;
  1458. } else {
  1459. dwIoctl = IOCTL_IP_RTCHANGE_NOTIFY_REQUEST;
  1460. }
  1461. if ((pHandle != NULL) && (pOverLapped != NULL)) {
  1462. Trace0(ERR, "NotifyRouteChange: overlapped request");
  1463. if (IsBadWritePtr(pHandle, sizeof(HANDLE))) {
  1464. return ERROR_INVALID_PARAMETER;
  1465. }
  1466. if (IsBadWritePtr(pOverLapped, sizeof(OVERLAPPED))) {
  1467. return ERROR_INVALID_PARAMETER;
  1468. }
  1469. *pHandle = ChangeNotificationHandle;
  1470. if(*pHandle == INVALID_HANDLE_VALUE){
  1471. Trace1(ERR, "NotifyRouteChange: CreateFile=%d", GetLastError());
  1472. return ERROR_OPEN_FAILED;
  1473. }
  1474. b = DeviceIoControl(*pHandle,
  1475. dwIoctl,
  1476. NULL,
  1477. 0,
  1478. NULL,
  1479. 0,
  1480. &temp,
  1481. pOverLapped);
  1482. if (!b) {
  1483. dwResult = GetLastError();
  1484. Trace1(ERR, "NotifyRouteChange: DeviceIoControl=%d", dwResult);
  1485. return dwResult;
  1486. }
  1487. } else {
  1488. // Synchronous change notification
  1489. // This call will block
  1490. Trace0(ERR, "NotifyRouteChange: synchronous request");
  1491. b = DeviceIoControl(g_hIPGetDriverHandle,
  1492. dwIoctl,
  1493. NULL,
  1494. 0,
  1495. NULL,
  1496. 0,
  1497. &temp,
  1498. NULL);
  1499. if (!b) {
  1500. dwResult = GetLastError();
  1501. Trace1(ERR, "NotifyRouteChange: DeviceIoControl=%d", dwResult);
  1502. return dwResult;
  1503. }
  1504. }
  1505. return NO_ERROR;
  1506. #endif
  1507. }
  1508. BOOL WINAPI
  1509. CancelIPChangeNotify(LPOVERLAPPED notifyOverlapped)
  1510. {
  1511. BOOL b;
  1512. DWORD temp, dwResult = NO_ERROR;
  1513. b = DeviceIoControl(ChangeNotificationHandle,
  1514. IOCTL_IP_CANCEL_CHANGE_NOTIFY,
  1515. &notifyOverlapped,
  1516. sizeof(notifyOverlapped),
  1517. NULL,
  1518. 0,
  1519. &temp,
  1520. NULL);
  1521. if (!b) {
  1522. dwResult = GetLastError();
  1523. }
  1524. return (BOOL)(dwResult == NO_ERROR);
  1525. }
  1526. DWORD WINAPI
  1527. EnableRouter(HANDLE *pHandle, OVERLAPPED *pOverLapped)
  1528. {
  1529. #if defined(NT4) || defined(CHICAGO)
  1530. return ERROR_NOT_SUPPORTED;
  1531. #else
  1532. BOOL b;
  1533. DWORD dwResult;
  1534. DWORD temp;
  1535. if ((pHandle != NULL) && (pOverLapped != NULL)) {
  1536. Trace0(ERR,"EnableRouter: overlapped request");
  1537. if (IsBadWritePtr(pHandle, sizeof(HANDLE)) ||
  1538. IsBadWritePtr(pOverLapped, sizeof(OVERLAPPED))) {
  1539. return ERROR_INVALID_PARAMETER;
  1540. }
  1541. *pHandle = g_hIPDriverHandle;
  1542. if (*pHandle == INVALID_HANDLE_VALUE) {
  1543. return ERROR_OPEN_FAILED;
  1544. }
  1545. b = DeviceIoControl(
  1546. *pHandle,
  1547. IOCTL_IP_ENABLE_ROUTER_REQUEST,
  1548. NULL,
  1549. 0,
  1550. NULL,
  1551. 0,
  1552. &temp,
  1553. pOverLapped
  1554. );
  1555. if (!b) { return GetLastError(); }
  1556. } else {
  1557. Trace0(ERR,"EnableRouter: synchronous request");
  1558. b = DeviceIoControl(
  1559. g_hIPDriverHandle,
  1560. IOCTL_IP_ENABLE_ROUTER_REQUEST,
  1561. NULL,
  1562. 0,
  1563. NULL,
  1564. 0,
  1565. &temp,
  1566. NULL
  1567. );
  1568. if (!b) {
  1569. dwResult = GetLastError();
  1570. Trace1(ERR,"EnableRouter: DeviceIoControl=%d", dwResult);
  1571. return dwResult;
  1572. }
  1573. }
  1574. return NO_ERROR;
  1575. #endif
  1576. }
  1577. DWORD WINAPI
  1578. UnenableRouter(OVERLAPPED* pOverlapped, LPDWORD lpdwEnableCount OPTIONAL)
  1579. {
  1580. #if defined(NT4) || defined(CHICAGO)
  1581. return ERROR_NOT_SUPPORTED;
  1582. #else
  1583. BOOL b;
  1584. DWORD EnableCount;
  1585. DWORD temp;
  1586. if (lpdwEnableCount && IsBadWritePtr(lpdwEnableCount, sizeof(DWORD))) {
  1587. return ERROR_INVALID_PARAMETER;
  1588. }
  1589. if (g_hIPDriverHandle == INVALID_HANDLE_VALUE) {
  1590. return ERROR_OPEN_FAILED;
  1591. }
  1592. b = DeviceIoControl(
  1593. g_hIPDriverHandle,
  1594. IOCTL_IP_UNENABLE_ROUTER_REQUEST,
  1595. (PVOID)&pOverlapped,
  1596. sizeof(PVOID),
  1597. &EnableCount,
  1598. sizeof(DWORD),
  1599. &temp,
  1600. NULL
  1601. );
  1602. if (!b) { return GetLastError(); }
  1603. if (lpdwEnableCount) { *lpdwEnableCount = EnableCount; }
  1604. return NO_ERROR;
  1605. #endif
  1606. }
  1607. DWORD WINAPI
  1608. DisableMediaSense(HANDLE *pHandle, OVERLAPPED *pOverLapped)
  1609. {
  1610. #if defined(NT4) || defined(CHICAGO)
  1611. return ERROR_NOT_SUPPORTED;
  1612. #else
  1613. BOOL b;
  1614. DWORD dwResult;
  1615. DWORD temp;
  1616. if ((pHandle != NULL) && (pOverLapped != NULL)) {
  1617. Trace0(ERR,"DisableMediaSense: overlapped request");
  1618. if (IsBadWritePtr(pHandle, sizeof(HANDLE)) ||
  1619. IsBadWritePtr(pOverLapped, sizeof(OVERLAPPED))) {
  1620. return ERROR_INVALID_PARAMETER;
  1621. }
  1622. *pHandle = g_hIPDriverHandle;
  1623. if (*pHandle == INVALID_HANDLE_VALUE) {
  1624. return ERROR_OPEN_FAILED;
  1625. }
  1626. b = DeviceIoControl(
  1627. *pHandle,
  1628. IOCTL_IP_DISABLE_MEDIA_SENSE_REQUEST,
  1629. NULL,
  1630. 0,
  1631. NULL,
  1632. 0,
  1633. &temp,
  1634. pOverLapped
  1635. );
  1636. if (!b) { return GetLastError(); }
  1637. } else {
  1638. Trace0(ERR,"DisableMediaSense: synchronous request");
  1639. b = DeviceIoControl(
  1640. g_hIPDriverHandle,
  1641. IOCTL_IP_DISABLE_MEDIA_SENSE_REQUEST,
  1642. NULL,
  1643. 0,
  1644. NULL,
  1645. 0,
  1646. &temp,
  1647. NULL
  1648. );
  1649. if (!b) {
  1650. dwResult = GetLastError();
  1651. Trace1(ERR,"DisableMediaSense: DeviceIoControl=%d", dwResult);
  1652. return dwResult;
  1653. }
  1654. }
  1655. return NO_ERROR;
  1656. #endif
  1657. }
  1658. DWORD WINAPI
  1659. RestoreMediaSense(OVERLAPPED* pOverlapped, LPDWORD lpdwEnableCount OPTIONAL)
  1660. {
  1661. #if defined(NT4) || defined(CHICAGO)
  1662. return ERROR_NOT_SUPPORTED;
  1663. #else
  1664. BOOL b;
  1665. DWORD EnableCount;
  1666. DWORD temp;
  1667. if (lpdwEnableCount && IsBadWritePtr(lpdwEnableCount, sizeof(DWORD))) {
  1668. return ERROR_INVALID_PARAMETER;
  1669. }
  1670. if (g_hIPDriverHandle == INVALID_HANDLE_VALUE) {
  1671. return ERROR_OPEN_FAILED;
  1672. }
  1673. b = DeviceIoControl(
  1674. g_hIPDriverHandle,
  1675. IOCTL_IP_ENABLE_MEDIA_SENSE_REQUEST,
  1676. (PVOID)&pOverlapped,
  1677. sizeof(PVOID),
  1678. &EnableCount,
  1679. sizeof(DWORD),
  1680. &temp,
  1681. NULL
  1682. );
  1683. if (!b) { return GetLastError(); }
  1684. if (lpdwEnableCount) { *lpdwEnableCount = EnableCount; }
  1685. return NO_ERROR;
  1686. #endif
  1687. }
  1688. #if !defined(NT4) && !defined(_WIN95_)
  1689. extern DWORD GetFixedInfoEx(PFIXED_INFO pFixedInfo, PULONG pOutBufLen);
  1690. extern DWORD GetAdapterInfoEx(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen);
  1691. extern DWORD GetAdapterAddressesEx(ULONG Family, DWORD Flags, PIP_ADAPTER_ADDRESSES pAdapterInfo, PULONG pOutBufLen);
  1692. #endif
  1693. #if !defined(NT4) && !defined(CHICAGO)
  1694. extern DWORD GetPerAdapterInfoEx(ULONG IfIndex, PIP_PER_ADAPTER_INFO pPerAdapterInfo, PULONG pOutBufLen);
  1695. #endif
  1696. DWORD
  1697. GetNetworkParams(PFIXED_INFO pFixedInfo, PULONG pOutBufLen)
  1698. {
  1699. #if !defined(NT4) && !defined(_WIN95_)
  1700. CheckTcpipState();
  1701. if (IsBadReadPtr(pOutBufLen, sizeof(ULONG))) {
  1702. return ERROR_INVALID_PARAMETER;
  1703. }
  1704. if (IsBadWritePtr(pOutBufLen, sizeof(ULONG))) {
  1705. return ERROR_INVALID_PARAMETER;
  1706. }
  1707. if (pFixedInfo != NULL &&
  1708. IsBadWritePtr(pFixedInfo, sizeof(FIXED_INFO))) {
  1709. return ERROR_INVALID_PARAMETER;
  1710. }
  1711. return GetFixedInfoEx(pFixedInfo, pOutBufLen);
  1712. #else
  1713. return ERROR_NOT_SUPPORTED;
  1714. #endif
  1715. }
  1716. DWORD
  1717. GetAdaptersAddresses(ULONG Family, DWORD Flags, PVOID Reserved,
  1718. PIP_ADAPTER_ADDRESSES pAdapterAddresses,
  1719. PULONG pOutBufLen)
  1720. {
  1721. #if !defined(NT4) && !defined(_WIN95_)
  1722. CheckTcpipState();
  1723. if (IsBadReadPtr(pOutBufLen, sizeof(ULONG))) {
  1724. return ERROR_INVALID_PARAMETER;
  1725. }
  1726. if (IsBadWritePtr(pOutBufLen, sizeof(ULONG))) {
  1727. return ERROR_INVALID_PARAMETER;
  1728. }
  1729. if (Reserved != NULL) {
  1730. return ERROR_INVALID_PARAMETER;
  1731. }
  1732. if (pAdapterAddresses != NULL &&
  1733. IsBadWritePtr(pAdapterAddresses, sizeof(IP_ADAPTER_ADDRESSES))) {
  1734. return ERROR_INVALID_PARAMETER;
  1735. }
  1736. return GetAdapterAddressesEx(Family, Flags, pAdapterAddresses, pOutBufLen);
  1737. #else
  1738. return ERROR_NOT_SUPPORTED;
  1739. #endif
  1740. }
  1741. DWORD
  1742. GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen)
  1743. {
  1744. #if !defined(NT4) && !defined(_WIN95_)
  1745. // call the init
  1746. CheckTcpipState();
  1747. if (IsBadReadPtr(pOutBufLen, sizeof(ULONG))) {
  1748. return ERROR_INVALID_PARAMETER;
  1749. }
  1750. if (IsBadWritePtr(pOutBufLen, sizeof(ULONG))) {
  1751. return ERROR_INVALID_PARAMETER;
  1752. }
  1753. if (pAdapterInfo != NULL &&
  1754. IsBadWritePtr(pAdapterInfo, sizeof(IP_ADAPTER_INFO))) {
  1755. return ERROR_INVALID_PARAMETER;
  1756. }
  1757. return GetAdapterInfoEx(pAdapterInfo, pOutBufLen);
  1758. #else
  1759. return ERROR_NOT_SUPPORTED;
  1760. #endif
  1761. }
  1762. DWORD
  1763. GetPerAdapterInfo(ULONG IfIndex, PIP_PER_ADAPTER_INFO pPerAdapterInfo,
  1764. PULONG pOutBufLen)
  1765. {
  1766. #if !defined(NT4) && !defined(CHICAGO)
  1767. CheckTcpipState();
  1768. if (IsBadReadPtr(pOutBufLen, sizeof(ULONG))) {
  1769. return ERROR_INVALID_PARAMETER;
  1770. }
  1771. if (IsBadWritePtr(pOutBufLen, sizeof(ULONG))) {
  1772. return ERROR_INVALID_PARAMETER;
  1773. }
  1774. if (pPerAdapterInfo != NULL &&
  1775. IsBadWritePtr(pPerAdapterInfo, sizeof(IP_PER_ADAPTER_INFO))) {
  1776. return ERROR_INVALID_PARAMETER;
  1777. }
  1778. return GetPerAdapterInfoEx(IfIndex, pPerAdapterInfo, pOutBufLen);
  1779. #else
  1780. return ERROR_NOT_SUPPORTED;
  1781. #endif
  1782. }
  1783. extern DWORD
  1784. DhcpReleaseParameters(
  1785. LPWSTR AdapterName
  1786. );
  1787. extern DWORD
  1788. DhcpAcquireParameters(
  1789. LPWSTR AdapterName);
  1790. #define TCP_EXPORT_STRING_PREFIX L"\\DEVICE\\TCPIP_"
  1791. DWORD
  1792. IpReleaseAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
  1793. {
  1794. #if defined(NT4) || defined(_WIN95_)
  1795. return ERROR_NOT_SUPPORTED;
  1796. #else
  1797. DWORD status;
  1798. if (!AdapterInfo) {
  1799. return ERROR_INVALID_PARAMETER;
  1800. }
  1801. if (IsBadReadPtr(AdapterInfo, sizeof(IP_ADAPTER_INDEX_MAP))) {
  1802. return ERROR_INVALID_PARAMETER;
  1803. }
  1804. #ifdef CHICAGO
  1805. {
  1806. // Convert the string to a widechar name
  1807. WCHAR Name[11];
  1808. uint i;
  1809. uint Index = AdapterInfo->Index;
  1810. i = sizeof(Name)/sizeof(Name[0]);
  1811. Name[--i] = L'\0';
  1812. while (i > 0 ) {
  1813. Name[--i] = L'0' + (Index%10);
  1814. Index /= 10;
  1815. }
  1816. status = DhcpReleaseParameters(Name);
  1817. }
  1818. #else
  1819. {
  1820. LPWSTR tmpstr;
  1821. if (wcslen(AdapterInfo->Name) <= wcslen(TCP_EXPORT_STRING_PREFIX)) {
  1822. return ERROR_INVALID_PARAMETER;
  1823. }
  1824. tmpstr = AdapterInfo->Name + wcslen(TCP_EXPORT_STRING_PREFIX);
  1825. __try {
  1826. status = DhcpReleaseParameters(tmpstr);
  1827. } __except(EXCEPTION_EXECUTE_HANDLER) {
  1828. status = ERROR_PROC_NOT_FOUND;
  1829. }
  1830. }
  1831. #endif
  1832. return(status);
  1833. #endif
  1834. }
  1835. DWORD
  1836. IpRenewAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
  1837. {
  1838. #if defined(NT4) || defined(_WIN95_)
  1839. return ERROR_NOT_SUPPORTED;
  1840. #else
  1841. DWORD status;
  1842. if (!AdapterInfo) {
  1843. return ERROR_INVALID_PARAMETER;
  1844. }
  1845. if (IsBadReadPtr(AdapterInfo, sizeof(IP_ADAPTER_INDEX_MAP))) {
  1846. return ERROR_INVALID_PARAMETER;
  1847. }
  1848. #ifdef CHICAGO
  1849. {
  1850. // Convert the string to a widechar name
  1851. WCHAR Name[11];
  1852. uint i;
  1853. uint Index = AdapterInfo->Index;
  1854. i = sizeof(Name)/sizeof(Name[0]);
  1855. Name[--i] = L'\0';
  1856. while (i > 0 ) {
  1857. Name[--i] = L'0' + (Index%10);
  1858. Index /= 10;
  1859. }
  1860. status = DhcpAcquireParameters(Name);
  1861. }
  1862. #else
  1863. {
  1864. LPWSTR tmpstr;
  1865. if (wcslen(AdapterInfo->Name) <= wcslen(TCP_EXPORT_STRING_PREFIX)) {
  1866. return ERROR_INVALID_PARAMETER;
  1867. }
  1868. tmpstr = AdapterInfo->Name + wcslen(TCP_EXPORT_STRING_PREFIX);
  1869. __try {
  1870. status = DhcpAcquireParameters(tmpstr);
  1871. } __except(EXCEPTION_EXECUTE_HANDLER) {
  1872. status = ERROR_PROC_NOT_FOUND;
  1873. }
  1874. }
  1875. #endif
  1876. return(status);
  1877. #endif
  1878. }
  1879. DWORD
  1880. SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAddrLen)
  1881. {
  1882. #if defined(NT4) || defined(_WIN95_)
  1883. return ERROR_NOT_SUPPORTED;
  1884. #else
  1885. ARP_SEND_REPLY requestBuffer;
  1886. DWORD requestBufferSize = sizeof(requestBuffer);
  1887. DWORD status;
  1888. requestBuffer.DestAddress = DestIP;
  1889. requestBuffer.SrcAddress = SrcIP;
  1890. if (IsBadWritePtr(pMacAddr, sizeof(ULONG))) {
  1891. return ERROR_INVALID_PARAMETER;
  1892. }
  1893. if (IsBadWritePtr(PhyAddrLen, sizeof(ULONG))) {
  1894. return ERROR_INVALID_PARAMETER;
  1895. }
  1896. status = TCPSendIoctl(g_hIPGetDriverHandle,
  1897. IOCTL_ARP_SEND_REQUEST,
  1898. &requestBuffer,
  1899. &requestBufferSize,
  1900. pMacAddr,
  1901. PhyAddrLen);
  1902. return(status);
  1903. #endif
  1904. }