Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2591 lines
63 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. PMIB_OPAQUE_INFO pInfo;
  363. MIB_OPAQUE_QUERY mqQuery;
  364. DWORD dwResult, dwOutEntrySize;
  365. PMIB_TCPTABLE pTable;
  366. TraceEnter("InternalGetTcpTable");
  367. *ppTcpTable = NULL;
  368. #ifndef CHICAGO
  369. if(IsRouterRunning())
  370. {
  371. mqQuery.dwVarId = TCP_TABLE;
  372. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  373. PID_IP,
  374. IPRTRMGR_PID,
  375. (PVOID)&mqQuery,
  376. sizeof(MIB_OPAQUE_QUERY),
  377. (PVOID)&pInfo,
  378. &dwOutEntrySize);
  379. if(dwResult isnot NO_ERROR)
  380. {
  381. Trace1(ERR,"MprAdminMIBEntryGet failed with error %x",
  382. dwResult);
  383. TraceLeave("InternalGetTcpTable");
  384. return dwResult;
  385. }
  386. *ppTcpTable = HeapAlloc(hHeap,
  387. dwAllocFlags,
  388. dwOutEntrySize);
  389. if(*ppTcpTable is NULL)
  390. {
  391. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  392. Trace1(ERR,"Allocation failed with error %d",
  393. dwResult);
  394. TraceLeave("InternalGetTcpTable");
  395. MprAdminMIBBufferFree((PVOID)pInfo);
  396. return dwResult;
  397. }
  398. CAST_MIB_INFO(pInfo, PMIB_TCPTABLE, pTable);
  399. CopyMemory((PVOID)(*ppTcpTable),
  400. (PVOID)pTable,
  401. SIZEOF_TCPTABLE(pTable->dwNumEntries));
  402. MprAdminMIBBufferFree((PVOID)pInfo);
  403. }
  404. else
  405. {
  406. #endif
  407. dwResult = AllocateAndGetTcpTableFromStack(ppTcpTable,
  408. TRUE,
  409. hHeap,
  410. dwAllocFlags);
  411. if(dwResult isnot NO_ERROR)
  412. {
  413. Trace1(ERR,"InternalGetTcpTableFromStack failed with error %x",
  414. dwResult);
  415. TraceLeave("InternalGetTcpTable");
  416. return dwResult;
  417. }
  418. #ifndef CHICAGO
  419. }
  420. #endif
  421. TraceLeave("InternalGetTcpTable");
  422. return NO_ERROR;
  423. }
  424. DWORD
  425. InternalGetUdpTable(
  426. OUT MIB_UDPTABLE **ppUdpTable,
  427. IN HANDLE hHeap,
  428. IN DWORD dwAllocFlags
  429. )
  430. {
  431. PMIB_OPAQUE_INFO pInfo;
  432. MIB_OPAQUE_QUERY mqQuery;
  433. DWORD dwResult, dwOutEntrySize;
  434. PMIB_UDPTABLE pTable;
  435. TraceEnter("InternalGetUdpTable");
  436. *ppUdpTable = NULL;
  437. #ifndef CHICAGO
  438. if(IsRouterRunning())
  439. {
  440. mqQuery.dwVarId = UDP_TABLE;
  441. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  442. PID_IP,
  443. IPRTRMGR_PID,
  444. (PVOID)&mqQuery,
  445. sizeof(MIB_OPAQUE_QUERY),
  446. (PVOID)&pInfo,
  447. &dwOutEntrySize);
  448. if(dwResult isnot NO_ERROR)
  449. {
  450. Trace1(ERR,"MprAdminMIBEntryGet failed with error %x",
  451. dwResult);
  452. TraceLeave("InternalGetUdpTable");
  453. return dwResult;
  454. }
  455. *ppUdpTable = HeapAlloc(hHeap,
  456. dwAllocFlags,
  457. dwOutEntrySize);
  458. if(*ppUdpTable is NULL)
  459. {
  460. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  461. Trace1(ERR,"Allocation failed with error %d",
  462. dwResult);
  463. MprAdminMIBBufferFree((PVOID)pInfo);
  464. return dwResult;
  465. }
  466. CAST_MIB_INFO(pInfo, PMIB_UDPTABLE, pTable);
  467. CopyMemory((PVOID)(*ppUdpTable),
  468. (PVOID)pTable,
  469. SIZEOF_UDPTABLE(pTable->dwNumEntries));
  470. MprAdminMIBBufferFree((PVOID)pInfo);
  471. }
  472. else
  473. {
  474. #endif
  475. dwResult = AllocateAndGetUdpTableFromStack(ppUdpTable,
  476. TRUE,
  477. hHeap,
  478. dwAllocFlags);
  479. if(dwResult isnot NO_ERROR)
  480. {
  481. Trace1(ERR,"InternalGetUdpTableFromStack failed with error %x",
  482. dwResult);
  483. TraceLeave("InternalGetUdpTable");
  484. return dwResult;
  485. }
  486. #ifndef CHICAGO
  487. }
  488. #endif
  489. TraceLeave("InternalGetUdpTable");
  490. return NO_ERROR;
  491. }
  492. DWORD
  493. InternalSetIfEntry(
  494. IN PMIB_OPAQUE_INFO pInfoRow
  495. )
  496. {
  497. PMIB_IFROW pIfRow = (PMIB_IFROW)(pInfoRow->rgbyData);
  498. DWORD dwResult;
  499. TraceEnter("SetIfEntry");
  500. #ifndef CHICAGO
  501. if(IsRouterRunning())
  502. {
  503. pInfoRow->dwId = IF_ROW;
  504. dwResult = MprAdminMIBEntrySet(g_hMIBServer,
  505. PID_IP,
  506. IPRTRMGR_PID,
  507. (PVOID)pInfoRow,
  508. MIB_INFO_SIZE(MIB_IFROW));
  509. if(dwResult isnot NO_ERROR)
  510. {
  511. Trace1(ERR,"MprAdminMIBEntrySet failed with error %x",
  512. dwResult);
  513. TraceLeave("SetIfEntry");
  514. return dwResult;
  515. }
  516. }
  517. else
  518. {
  519. #endif
  520. dwResult = SetIfEntryToStack(pIfRow,
  521. FALSE);
  522. if(dwResult isnot NO_ERROR)
  523. {
  524. Trace1(ERR,"SetIfEntryToStack failed with error %d",
  525. dwResult);
  526. TraceLeave("SetIfEntry");
  527. return dwResult;
  528. }
  529. #ifndef CHICAGO
  530. }
  531. #endif
  532. TraceLeave("SetIfEntry");
  533. return NO_ERROR;
  534. }
  535. DWORD
  536. InternalCreateIpForwardEntry(
  537. IN PMIB_OPAQUE_INFO pInfoRow
  538. )
  539. {
  540. PMIB_IPFORWARDROW pIpForwardRow = (PMIB_IPFORWARDROW)(pInfoRow->rgbyData);
  541. DWORD dwResult;
  542. TraceEnter("CreateIpForwardEntry");
  543. #ifndef CHICAGO
  544. if(IsRouterRunning() &&
  545. IsRouterSettingRoutes())
  546. {
  547. pInfoRow->dwId = IP_FORWARDROW;
  548. dwResult = MprAdminMIBEntryCreate(g_hMIBServer,
  549. PID_IP,
  550. IPRTRMGR_PID,
  551. (PVOID)pInfoRow,
  552. MIB_INFO_SIZE(MIB_IPFORWARDROW));
  553. if(dwResult isnot NO_ERROR)
  554. {
  555. Trace1(ERR,"MprAdminMIBEntryCreate failed with error %x",
  556. dwResult);
  557. TraceLeave("CreateIpForwardEntry");
  558. return dwResult;
  559. }
  560. }
  561. else
  562. {
  563. #endif
  564. dwResult = SetIpForwardEntryToStack(pIpForwardRow);
  565. if(dwResult isnot NO_ERROR)
  566. {
  567. Trace1(ERR,"SetIpForwarEntryToStack failed with error %d",
  568. dwResult);
  569. TraceLeave("CreateIpForwardEntry");
  570. return dwResult;
  571. }
  572. #ifndef CHICAGO
  573. }
  574. #endif
  575. TraceLeave("CreateIpForwardEntry");
  576. return NO_ERROR;
  577. }
  578. DWORD
  579. InternalSetIpForwardEntry(
  580. IN PMIB_OPAQUE_INFO pInfoRow
  581. )
  582. {
  583. PMIB_IPFORWARDROW pIpForwardRow = (PMIB_IPFORWARDROW)(pInfoRow->rgbyData);
  584. DWORD dwResult;
  585. TraceEnter("SetIpForwardEntry");
  586. #ifndef CHICAGO
  587. if(IsRouterRunning() &&
  588. IsRouterSettingRoutes())
  589. {
  590. pInfoRow->dwId = IP_FORWARDROW;
  591. dwResult = MprAdminMIBEntrySet(g_hMIBServer,
  592. PID_IP,
  593. IPRTRMGR_PID,
  594. (PVOID)pInfoRow,
  595. MIB_INFO_SIZE(MIB_IPFORWARDROW));
  596. if(dwResult isnot NO_ERROR)
  597. {
  598. Trace1(ERR,"MprAdminMIBEntrySet failed with error %x",
  599. dwResult);
  600. TraceLeave("SetIpForwardEntry");
  601. return dwResult;
  602. }
  603. }
  604. else
  605. {
  606. #endif
  607. dwResult = SetIpForwardEntryToStack(pIpForwardRow);
  608. if(dwResult isnot NO_ERROR)
  609. {
  610. Trace1(ERR,"SetIpForwarEntryToStack failed with error %d",
  611. dwResult);
  612. TraceLeave("SetIpForwardEntry");
  613. return dwResult;
  614. }
  615. #ifndef CHICAGO
  616. }
  617. #endif
  618. TraceLeave("SetIpForwardEntry");
  619. return NO_ERROR;
  620. }
  621. DWORD
  622. InternalDeleteIpForwardEntry(
  623. IN PMIB_OPAQUE_INFO pInfoRow
  624. )
  625. {
  626. PMIB_IPFORWARDROW pIpForwardRow = (PMIB_IPFORWARDROW)(pInfoRow->rgbyData);
  627. DWORD dwResult;
  628. TraceEnter("DeleteIpForwardEntry");
  629. pIpForwardRow->dwForwardType = MIB_IPROUTE_TYPE_INVALID;
  630. #ifndef CHICAGO
  631. if(IsRouterRunning() &&
  632. IsRouterSettingRoutes())
  633. {
  634. DWORD rgdwInfo[5];
  635. PMIB_OPAQUE_QUERY pIndex = (PMIB_OPAQUE_QUERY)rgdwInfo;
  636. pIndex->dwVarId = IP_FORWARDROW;
  637. pIndex->rgdwVarIndex[0] = pIpForwardRow->dwForwardDest;
  638. pIndex->rgdwVarIndex[1] = pIpForwardRow->dwForwardProto;
  639. pIndex->rgdwVarIndex[2] = pIpForwardRow->dwForwardPolicy;
  640. pIndex->rgdwVarIndex[3] = pIpForwardRow->dwForwardNextHop;
  641. dwResult = MprAdminMIBEntryDelete(g_hMIBServer,
  642. PID_IP,
  643. IPRTRMGR_PID,
  644. (PVOID)pIndex,
  645. sizeof(rgdwInfo));
  646. if(dwResult isnot NO_ERROR)
  647. {
  648. Trace1(ERR,"MprAdminMIBEntryDelete failed with error %x",
  649. dwResult);
  650. TraceLeave("DeleteIpForwardEntry");
  651. return dwResult;
  652. }
  653. }
  654. else
  655. {
  656. #endif
  657. dwResult = SetIpForwardEntryToStack(pIpForwardRow);
  658. if(dwResult isnot NO_ERROR)
  659. {
  660. Trace1(ERR,"SetIpForwarEntryToStack failed with error %d",
  661. dwResult);
  662. TraceLeave("CreateIpForwardEntry");
  663. return dwResult;
  664. }
  665. #ifndef CHICAGO
  666. }
  667. #endif
  668. TraceLeave("CreateIpForwardEntry");
  669. return NO_ERROR;
  670. }
  671. DWORD
  672. InternalSetIpStats(
  673. IN PMIB_OPAQUE_INFO pInfoRow
  674. )
  675. {
  676. PMIB_IPSTATS pIpStats = (PMIB_IPSTATS)(pInfoRow->rgbyData);
  677. DWORD dwResult;
  678. TraceEnter("SetIpStats");
  679. #ifndef CHICAGO
  680. if(IsRouterRunning())
  681. {
  682. pInfoRow->dwId = IP_STATS;
  683. dwResult = MprAdminMIBEntrySet(g_hMIBServer,
  684. PID_IP,
  685. IPRTRMGR_PID,
  686. (PVOID)pInfoRow,
  687. MIB_INFO_SIZE(MIB_IPSTATS));
  688. if(dwResult isnot NO_ERROR)
  689. {
  690. Trace1(ERR,"MprAdminMIBEntrySet failed with error %x",
  691. dwResult);
  692. TraceLeave("SetIpStats");
  693. return dwResult;
  694. }
  695. }
  696. else
  697. {
  698. #endif
  699. dwResult = SetIpStatsToStack(pIpStats);
  700. if(dwResult isnot NO_ERROR)
  701. {
  702. Trace1(ERR,"SetIpStatsToStack failed with error %d",
  703. dwResult);
  704. TraceLeave("SetIpStats");
  705. return dwResult;
  706. }
  707. #ifndef CHICAGO
  708. }
  709. #endif
  710. TraceLeave("SetIpStats");
  711. return NO_ERROR;
  712. }
  713. DWORD
  714. InternalCreateIpNetEntry(
  715. IN PMIB_OPAQUE_INFO pInfoRow
  716. )
  717. {
  718. PMIB_IPNETROW pIpNetRow = (PMIB_IPNETROW)(pInfoRow->rgbyData);
  719. DWORD dwResult;
  720. TraceEnter("CreateIpNetEntry");
  721. #ifndef CHICAGO
  722. if(IsRouterRunning())
  723. {
  724. pInfoRow->dwId = IP_NETROW;
  725. dwResult = MprAdminMIBEntryCreate(g_hMIBServer,
  726. PID_IP,
  727. IPRTRMGR_PID,
  728. (PVOID)pInfoRow,
  729. MIB_INFO_SIZE(MIB_IPNETROW));
  730. if(dwResult isnot NO_ERROR)
  731. {
  732. Trace1(ERR,"MprAdminMIBEntryCreate failed with error %x",
  733. dwResult);
  734. TraceLeave("CreateIpNetEntry");
  735. return dwResult;
  736. }
  737. }
  738. else
  739. {
  740. #endif
  741. dwResult = SetIpNetEntryToStack(pIpNetRow,
  742. FALSE);
  743. if(dwResult isnot NO_ERROR)
  744. {
  745. Trace1(ERR,"SetIpNetEntryToStack failed with error %d",
  746. dwResult);
  747. TraceLeave("CreateIpNetEntry");
  748. return dwResult;
  749. }
  750. #ifndef CHICAGO
  751. }
  752. #endif
  753. TraceLeave("CreateIpNetEntry");
  754. return NO_ERROR;
  755. }
  756. DWORD
  757. InternalSetIpNetEntry(
  758. PMIB_OPAQUE_INFO pInfoRow
  759. )
  760. {
  761. PMIB_IPNETROW pIpNetRow = (PMIB_IPNETROW)(pInfoRow->rgbyData);
  762. DWORD dwResult;
  763. TraceEnter("SetIpNetEntry");
  764. #ifndef CHICAGO
  765. if(IsRouterRunning())
  766. {
  767. pInfoRow->dwId = IP_NETROW;
  768. dwResult = MprAdminMIBEntrySet(g_hMIBServer,
  769. PID_IP,
  770. IPRTRMGR_PID,
  771. (PVOID)pInfoRow,
  772. MIB_INFO_SIZE(MIB_IPNETROW));
  773. if(dwResult isnot NO_ERROR)
  774. {
  775. Trace1(ERR,"MprAdminMIBEntrySet failed with error %x",
  776. dwResult);
  777. TraceLeave("SetIpNetEntry");
  778. return dwResult;
  779. }
  780. }
  781. else
  782. {
  783. #endif
  784. dwResult = SetIpNetEntryToStack(pIpNetRow,
  785. FALSE);
  786. if(dwResult isnot NO_ERROR)
  787. {
  788. Trace1(ERR,"SetIpNetEntryToStack failed with error %d",
  789. dwResult);
  790. TraceLeave("SetIpNetEntry");
  791. return dwResult;
  792. }
  793. #ifndef CHICAGO
  794. }
  795. #endif
  796. TraceLeave("SetIpNetEntry");
  797. return NO_ERROR;
  798. }
  799. DWORD
  800. InternalDeleteIpNetEntry(
  801. PMIB_OPAQUE_INFO pInfoRow
  802. )
  803. {
  804. PMIB_IPNETROW pIpNetRow = (PMIB_IPNETROW)(pInfoRow->rgbyData);
  805. DWORD dwResult;
  806. TraceEnter("DeleteIpNetEntry");
  807. pIpNetRow->dwType = MIB_IPNET_TYPE_INVALID;
  808. #ifndef CHICAGO
  809. if(IsRouterRunning())
  810. {
  811. DWORD rgdwInfo[3];
  812. PMIB_OPAQUE_QUERY pIndex = (PMIB_OPAQUE_QUERY)rgdwInfo;
  813. pIndex->dwVarId = IP_NETROW;
  814. pIndex->rgdwVarIndex[0] = pIpNetRow->dwIndex;
  815. pIndex->rgdwVarIndex[1] = pIpNetRow->dwAddr;
  816. dwResult = MprAdminMIBEntryDelete(g_hMIBServer,
  817. PID_IP,
  818. IPRTRMGR_PID,
  819. (PVOID)pIndex,
  820. sizeof(rgdwInfo));
  821. if(dwResult isnot NO_ERROR)
  822. {
  823. Trace1(ERR,"MprAdminMIBEntryDelete failed with error %x",
  824. dwResult);
  825. TraceLeave("DeleteIpNetEntry");
  826. return dwResult;
  827. }
  828. }
  829. else
  830. {
  831. #endif
  832. dwResult = SetIpNetEntryToStack(pIpNetRow,
  833. FALSE);
  834. if(dwResult isnot NO_ERROR)
  835. {
  836. Trace1(ERR,"SetIpNetEntryToStack failed with error %d",
  837. dwResult);
  838. TraceLeave("DeleteIpNetEntry");
  839. return dwResult;
  840. }
  841. #ifndef CHICAGO
  842. }
  843. #endif
  844. TraceLeave("DeleteIpNetEntry");
  845. return NO_ERROR;
  846. }
  847. DWORD
  848. InternalSetTcpEntry(
  849. PMIB_OPAQUE_INFO pInfoRow
  850. )
  851. {
  852. PMIB_TCPROW pTcpRow = (PMIB_TCPROW)(pInfoRow->rgbyData);
  853. DWORD dwResult;
  854. TraceEnter("SetTcpEntry");
  855. #ifndef CHICAGO
  856. if(IsRouterRunning())
  857. {
  858. pInfoRow->dwId = TCP_ROW;
  859. dwResult = MprAdminMIBEntrySet(g_hMIBServer,
  860. PID_IP,
  861. IPRTRMGR_PID,
  862. (PVOID)pInfoRow,
  863. MIB_INFO_SIZE(MIB_TCPROW));
  864. if(dwResult isnot NO_ERROR)
  865. {
  866. Trace1(ERR,"MprAdminMIBEntrySet failed with error %x",
  867. dwResult);
  868. TraceLeave("SetTcpEntry");
  869. return dwResult;
  870. }
  871. }
  872. else
  873. {
  874. #endif
  875. dwResult = SetTcpEntryToStack(pTcpRow);
  876. if(dwResult isnot NO_ERROR)
  877. {
  878. Trace1(ERR,"SetTcpEntryToStack failed with error %d",
  879. dwResult);
  880. TraceLeave("SetTcpEntry");
  881. return dwResult;
  882. }
  883. #ifndef CHICAGO
  884. }
  885. #endif
  886. TraceLeave("SetTcpEntry");
  887. return NO_ERROR;
  888. }
  889. //#define MAX_ADAPTER_NAME_LENGTH 256
  890. DWORD
  891. OpenAdapterKey(
  892. LPSTR Name,
  893. PHKEY Key
  894. )
  895. {
  896. DWORD dwResult;
  897. CHAR keyName[MAX_ADAPTER_NAME_LENGTH +
  898. sizeof("\\Parameters\\Tcpip") +
  899. sizeof("SYSTEM\\CurrentControlSet\\Services\\")];
  900. //
  901. // open the handle to this adapter's TCPIP parameter key
  902. //
  903. strcpy(keyName, "SYSTEM\\CurrentControlSet\\Services\\");
  904. strcat(keyName, Name);
  905. strcat(keyName, "\\Parameters\\Tcpip");
  906. Trace1(ERR,"OpenAdapterKey: %s", keyName);
  907. dwResult = RegOpenKey(HKEY_LOCAL_MACHINE,
  908. keyName,
  909. Key);
  910. return dwResult;
  911. }
  912. DWORD
  913. ReadRegistryDword(HKEY Key, LPSTR ParameterName, PULONG Value)
  914. {
  915. DWORD dwResult, valueLength, valueType;
  916. valueLength = sizeof(*Value);
  917. dwResult = RegQueryValueEx(Key,
  918. ParameterName,
  919. NULL, // reserved
  920. &valueType,
  921. (LPBYTE)Value,
  922. &valueLength);
  923. return dwResult;
  924. }
  925. DWORD
  926. GetAdapterIPInterfaceContext(LPSTR AdapterName, PULONG Context)
  927. {
  928. HKEY key;
  929. DWORD dwResult;
  930. if ((dwResult = OpenAdapterKey(AdapterName, &key)) != NO_ERROR) {
  931. return(dwResult);
  932. }
  933. if ((dwResult = ReadRegistryDword(key, "IPInterfaceContext", Context))
  934. != NO_ERROR) {
  935. return(dwResult);
  936. }
  937. RegCloseKey(key);
  938. return(NO_ERROR);
  939. }
  940. DWORD
  941. GetInterfaceInfo(PIP_INTERFACE_INFO pIPIfInfo, PULONG dwOutBufLen)
  942. {
  943. #if defined(NT4) || defined(_WIN95_)
  944. return ERROR_NOT_SUPPORTED;
  945. #else
  946. DWORD status=0;
  947. DWORD dwNumIf, NumAdapters;
  948. int i;
  949. DWORD dwResult;
  950. MIB_IPSTATS IpSnmpInfo;
  951. if (IsBadWritePtr(dwOutBufLen, sizeof(ULONG))) {
  952. return ERROR_INVALID_PARAMETER;
  953. }
  954. if (IsBadWritePtr(pIPIfInfo, *dwOutBufLen)) {
  955. return ERROR_INVALID_PARAMETER;
  956. }
  957. dwResult = GetIpStatsFromStack(&IpSnmpInfo);
  958. if(dwResult isnot NO_ERROR) {
  959. Trace1(ERR,"GetInterfaceInfo: GetIpStatsFromStack returned error %d",
  960. dwResult);
  961. return dwResult;
  962. }
  963. dwNumIf = IpSnmpInfo.dwNumIf;
  964. if(dwNumIf is 0) {
  965. Trace0(ERR,"GetInterfaceInfo: No interfaces");
  966. return ERROR_NO_DATA;
  967. }
  968. if (dwOutBufLen == NULL) {
  969. return ERROR_INVALID_PARAMETER;
  970. }
  971. if (!pIPIfInfo ||
  972. (*dwOutBufLen <
  973. (ULONG)sizeof(IP_ADAPTER_INDEX_MAP)*(dwNumIf + OVERFLOW_COUNT))) {
  974. *dwOutBufLen =
  975. (ULONG)sizeof(IP_ADAPTER_INDEX_MAP)*(dwNumIf + OVERFLOW_COUNT);
  976. return ERROR_INSUFFICIENT_BUFFER;
  977. }
  978. Trace1(ERR, "GetInterfaceInfo: outbuflen %d", *dwOutBufLen);
  979. return TCPSendIoctl(g_hIPGetDriverHandle,
  980. IOCTL_IP_INTERFACE_INFO,
  981. NULL,
  982. &status,
  983. pIPIfInfo,
  984. dwOutBufLen);
  985. #endif
  986. }
  987. DWORD
  988. GetUniDirectionalAdapterInfo(PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS pIPIfInfo,
  989. PULONG dwOutBufLen)
  990. {
  991. DWORD status=0;
  992. if (dwOutBufLen == NULL) {
  993. return ERROR_INVALID_PARAMETER;
  994. }
  995. return TCPSendIoctl(g_hIPGetDriverHandle,
  996. IOCTL_IP_UNIDIRECTIONAL_ADAPTER_ADDRESS,
  997. NULL,
  998. &status,
  999. pIPIfInfo,
  1000. dwOutBufLen);
  1001. }
  1002. DWORD
  1003. GetIgmpList(IPAddr NTEAddr, IPAddr *pIgmpList, PULONG pdwOutBufLen)
  1004. /*++
  1005. Routine Description:
  1006. When pIgmpList is NULL, get the amount of space necessary to hold
  1007. the group addresses joined on a given interface address.
  1008. When pIgmpList is non-NULL and *pdwOutBufLen is more than 4 bytes,
  1009. get the actual group addresses.
  1010. Arguments:
  1011. NTEAddr - Supplies the address of an interface whose multicast
  1012. group information is being requested.
  1013. pIgmpList - Supplies a buffer in which to put group addresses, or
  1014. NULL to just request amount of space desired.
  1015. pdwOutBufLen - When pIgmpList is NULL, returns the amount of space
  1016. the caller should allocate to get all groups.
  1017. When pIgmpList is non-NULL, supplies the size of
  1018. the buffer supplied, and returns the amount of
  1019. space actually used.
  1020. Return Value:
  1021. NO_ERROR
  1022. ERROR_INVALID_PARAMETER if the arguments don't meet the requirements.
  1023. ERROR_INSUFFICIENT_BUFFER if more groups are available than fit.
  1024. --*/
  1025. {
  1026. DWORD inlen = sizeof(IPAddr);
  1027. DWORD dwStatus;
  1028. if (pdwOutBufLen == NULL) {
  1029. return ERROR_INVALID_PARAMETER;
  1030. }
  1031. if (IsBadWritePtr(pdwOutBufLen, sizeof(ULONG))) {
  1032. return ERROR_INVALID_PARAMETER;
  1033. }
  1034. if (pIgmpList == NULL) {
  1035. DWORD dwSize;
  1036. //
  1037. // When pIgmpList is NULL, the caller is just asking for the
  1038. // amount of space needed, so use pdwOutBufLen as the buffer.
  1039. //
  1040. dwSize = sizeof(*pdwOutBufLen);
  1041. dwStatus = TCPSendIoctl(g_hIPGetDriverHandle,
  1042. IOCTL_IP_GET_IGMPLIST,
  1043. &NTEAddr,
  1044. &inlen,
  1045. pdwOutBufLen,
  1046. &dwSize);
  1047. } else {
  1048. //
  1049. // Otherwise the caller wants the list of groups.
  1050. //
  1051. if (IsBadWritePtr(pIgmpList, *pdwOutBufLen)) {
  1052. return ERROR_INVALID_PARAMETER;
  1053. }
  1054. if (*pdwOutBufLen <= sizeof(ULONG)) {
  1055. //
  1056. // Make sure the buffer is bigger than a ULONG or we'll get
  1057. // the size back, not group data. The IOCTL insures that
  1058. // when the caller requests the size needed, the amount
  1059. // returned will be bigger than a ULONG.
  1060. //
  1061. return ERROR_INVALID_PARAMETER;
  1062. }
  1063. dwStatus = TCPSendIoctl(g_hIPGetDriverHandle,
  1064. IOCTL_IP_GET_IGMPLIST,
  1065. &NTEAddr,
  1066. &inlen,
  1067. pIgmpList,
  1068. pdwOutBufLen);
  1069. }
  1070. if (dwStatus == ERROR_MORE_DATA) {
  1071. //
  1072. // Callers expect ERROR_INSUFFICIENT_BUFFER when *pdwOutBufLen is
  1073. // too small. However, the stack actually generates a warning
  1074. // (ERROR_MORE_DATA), rather than an error (ERROR_INSUFFICIENT_BUFFER)
  1075. // so that the data gets passed back to the caller.
  1076. //
  1077. dwStatus = ERROR_INSUFFICIENT_BUFFER;
  1078. }
  1079. return dwStatus;
  1080. }
  1081. DWORD
  1082. SetBlockRoutes(IPRouteBlock *RouteBlock, PULONG poutbuflen, PULONG statusblock)
  1083. {
  1084. DWORD inlen;
  1085. if (IsRouterRunning()) {
  1086. return ERROR_NOT_SUPPORTED;
  1087. }
  1088. if (poutbuflen == NULL) {
  1089. // Null pointers ?
  1090. return ERROR_INVALID_PARAMETER;
  1091. }
  1092. if (IsBadReadPtr(poutbuflen, sizeof(ULONG))) {
  1093. return ERROR_INVALID_PARAMETER;
  1094. }
  1095. if (IsBadReadPtr(RouteBlock, sizeof(IPRouteBlock))) {
  1096. return ERROR_INVALID_PARAMETER;
  1097. }
  1098. inlen = (RouteBlock->numofroutes * sizeof(IPRouteEntry)) + sizeof(ulong);
  1099. if (IsBadReadPtr(RouteBlock, inlen)) {
  1100. return ERROR_INVALID_PARAMETER;
  1101. }
  1102. return TCPSendIoctl(g_hIPDriverHandle,
  1103. IOCTL_IP_SET_BLOCKOFROUTES,
  1104. RouteBlock,
  1105. &inlen,
  1106. statusblock,
  1107. poutbuflen);
  1108. }
  1109. DWORD
  1110. SetRouteWithRef(IN IPRouteEntry *RouteEntry
  1111. )
  1112. {
  1113. DWORD inlen = sizeof(IPRouteEntry);
  1114. ULONG outbuflen;
  1115. if (IsRouterRunning()) {
  1116. return ERROR_NOT_SUPPORTED;
  1117. }
  1118. if (IsBadReadPtr(RouteEntry, inlen)) {
  1119. return ERROR_INVALID_PARAMETER;
  1120. }
  1121. return TCPSendIoctl(g_hIPDriverHandle,
  1122. IOCTL_IP_SET_ROUTEWITHREF,
  1123. RouteEntry,
  1124. &inlen,
  1125. NULL,
  1126. &outbuflen);
  1127. }
  1128. DWORD
  1129. GetAdapterIndex(
  1130. IN LPWSTR AdapterName,
  1131. OUT PULONG IfIndex
  1132. )
  1133. /*++
  1134. Routine Description:
  1135. Gets the target IP interface given the name of the adapter associated with it.
  1136. Arguments:
  1137. AdapterName - A unicode string identifying the adapter/interface to which
  1138. to add the new NTE.
  1139. ifIndex - Interface index associated with the adapter name.
  1140. Return Value:
  1141. ERROR_SUCCESS or windows error
  1142. --*/
  1143. {
  1144. #ifdef CHICAGO
  1145. return ERROR_NOT_SUPPORTED;
  1146. #else
  1147. int i;
  1148. DWORD dwResult;
  1149. MIB_IPADDRTABLE *pIpAddrTable;
  1150. MIB_IPADDRROW *pIpAddrEntry;
  1151. ULONG Context;
  1152. int NumEntries;
  1153. IP_INTERFACE_INFO *pIPIfInfo=NULL;
  1154. DWORD dwNumIf, NumAdapters;
  1155. ULONG dwOutBufLen;
  1156. if (AdapterName == NULL || IfIndex == NULL)
  1157. {
  1158. return(ERROR_INVALID_PARAMETER);
  1159. }
  1160. dwResult = GetNumberOfInterfaces(&dwNumIf);
  1161. if(dwResult isnot NO_ERROR)
  1162. {
  1163. Trace1(ERR,"GetAdapterIndex: GetNumberOfInterfaces returned error %d",
  1164. dwResult);
  1165. return dwResult;
  1166. }
  1167. if(dwNumIf is 0)
  1168. {
  1169. Trace0(ERR,"GetAdapterIndex: No interfaces");
  1170. return ERROR_NO_DATA;
  1171. }
  1172. dwOutBufLen = (ULONG)sizeof(IP_ADAPTER_INDEX_MAP)*(dwNumIf + OVERFLOW_COUNT);
  1173. pIPIfInfo = HeapAlloc(g_hPrivateHeap, FALSE, dwOutBufLen);
  1174. if(pIPIfInfo is NULL)
  1175. {
  1176. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  1177. Trace1(ERR,
  1178. "GetAdapterIndex: Couldnt allocate memory. Error %d",
  1179. dwResult);
  1180. return dwResult;
  1181. }
  1182. dwResult = GetInterfaceInfo(pIPIfInfo, &dwOutBufLen);
  1183. if (dwResult isnot NO_ERROR)
  1184. {
  1185. Trace1(ERR,
  1186. "GetAdapterIndex: Error %d calling GetInterfaceInfo",
  1187. dwResult);
  1188. HeapFree(g_hPrivateHeap, 0, pIPIfInfo);
  1189. return dwResult;
  1190. }
  1191. // search for the adaptername within this info and return the index.
  1192. NumAdapters = pIPIfInfo->NumAdapters;
  1193. for (i = 0; i < (int)pIPIfInfo->NumAdapters; i++) {
  1194. if (lstrcmpiW(AdapterName, pIPIfInfo->Adapter[i].Name) == 0)
  1195. {
  1196. break;
  1197. }
  1198. }
  1199. if (i < (int)pIPIfInfo->NumAdapters)
  1200. {
  1201. *IfIndex = pIPIfInfo->Adapter[i].Index;
  1202. HeapFree(g_hPrivateHeap, 0, pIPIfInfo);
  1203. return(NO_ERROR);
  1204. }
  1205. HeapFree(g_hPrivateHeap, 0, pIPIfInfo);
  1206. return(ERROR_DEV_NOT_EXIST);
  1207. #endif
  1208. }
  1209. DWORD
  1210. AddIPAddress(IPAddr Address, IPMask IpMask, DWORD IfIndex, PULONG NTEContext,
  1211. PULONG NTEInstance)
  1212. {
  1213. #ifdef CHICAGO
  1214. return ERROR_NOT_SUPPORTED;
  1215. #else
  1216. IP_ADD_NTE_REQUEST requestBuffer;
  1217. PIP_ADD_NTE_RESPONSE responseBuffer =
  1218. (PIP_ADD_NTE_RESPONSE) &requestBuffer;
  1219. DWORD requestBufferSize = sizeof(requestBuffer);
  1220. DWORD responseBufferSize = sizeof(requestBuffer);
  1221. DWORD status;
  1222. //
  1223. // Validate the IP address to be added. Check for
  1224. // * broadcast address,
  1225. // * loopback address,
  1226. // * zero address,
  1227. // * Class D address,
  1228. // * zero subnet-broadcast address
  1229. // * all-ones subnet-broadcast address
  1230. // * non-contiguous mask (which we test by negating the host-order mask
  1231. // and verifying that all the bits change when we add 1, i.e. that
  1232. // the negation is of the form 2^n-1).
  1233. //
  1234. if ((Address == INADDR_BROADCAST) ||
  1235. ((ntohl(Address) & IN_CLASSA_NET) ==
  1236. (INADDR_LOOPBACK & IN_CLASSA_NET)) ||
  1237. (Address == 0) ||
  1238. (IN_CLASSD(ntohl(Address))) ||
  1239. ((Address & ~IpMask) == 0) ||
  1240. ((Address & ~IpMask) == ~IpMask) ||
  1241. ((~ntohl(IpMask) + 1) & ~ntohl(IpMask))) {
  1242. return ERROR_INVALID_PARAMETER;
  1243. }
  1244. if ( (NTEContext == NULL) || (NTEInstance == NULL) ) {
  1245. return ERROR_INVALID_PARAMETER;
  1246. }
  1247. if (IsBadWritePtr(NTEContext, sizeof(ULONG))) {
  1248. return ERROR_INVALID_PARAMETER;
  1249. }
  1250. if (IsBadWritePtr(NTEInstance, sizeof(ULONG))) {
  1251. return ERROR_INVALID_PARAMETER;
  1252. }
  1253. requestBuffer.InterfaceContext = (unsigned long) IfIndex;
  1254. requestBuffer.Address = Address;
  1255. requestBuffer.SubnetMask = IpMask;
  1256. status = TCPSendIoctl(g_hIPDriverHandle,
  1257. IOCTL_IP_ADD_NTE,
  1258. &requestBuffer,
  1259. &requestBufferSize,
  1260. responseBuffer,
  1261. &responseBufferSize);
  1262. if (status == NO_ERROR) {
  1263. *NTEContext = (ULONG) responseBuffer->Context;
  1264. *NTEInstance = responseBuffer->Instance;
  1265. } else if (status == STATUS_DUPLICATE_OBJECTID) {
  1266. status = ERROR_DUP_DOMAINNAME;
  1267. }
  1268. return(status);
  1269. #endif
  1270. }
  1271. DWORD
  1272. DeleteIPAddress(ULONG NTEContext)
  1273. {
  1274. #ifdef CHICAGO
  1275. return ERROR_NOT_SUPPORTED;
  1276. #else
  1277. IP_DELETE_NTE_REQUEST requestBuffer;
  1278. DWORD requestBufferSize = sizeof(requestBuffer);
  1279. DWORD responseBufferSize = 0;
  1280. DWORD status;
  1281. requestBuffer.Context = (unsigned short) NTEContext;
  1282. status = TCPSendIoctl(g_hIPDriverHandle,
  1283. IOCTL_IP_DELETE_NTE,
  1284. &requestBuffer,
  1285. &requestBufferSize,
  1286. NULL,
  1287. &responseBufferSize);
  1288. return(status);
  1289. #endif
  1290. }
  1291. #define DEFAULT_TTL 32
  1292. #define DEFAULT_TOS 0
  1293. #define DEFAULT_TIMEOUT 5000L
  1294. #include <icmpapi.h>
  1295. #ifndef CHICAGO
  1296. #include <ntddip.h>
  1297. #endif
  1298. BOOL
  1299. GetRTT(IPAddr DestIpAddress, PULONG Rtt)
  1300. {
  1301. uchar FAR *Opt = (uchar FAR *)0; // Pointer to send options
  1302. uint OptLength = 0;
  1303. int OptIndex = 0; // Current index into SendOptions
  1304. uchar Flags = 0;
  1305. ulong Timeout = DEFAULT_TIMEOUT;
  1306. IP_OPTION_INFORMATION SendOpts;
  1307. HANDLE IcmpHandle;
  1308. PICMP_ECHO_REPLY reply;
  1309. char SendBuffer[32], RcvBuffer[4096];
  1310. uint RcvSize=4096;
  1311. uint SendSize = 32;
  1312. uint i;
  1313. DWORD numberOfReplies;
  1314. IcmpHandle = IcmpCreateFile();
  1315. if (IcmpHandle == INVALID_HANDLE_VALUE) {
  1316. return(FALSE);
  1317. }
  1318. if (IsBadWritePtr(Rtt, sizeof(ULONG))) {
  1319. return ERROR_INVALID_PARAMETER;
  1320. }
  1321. //
  1322. // Initialize the send buffer pattern.
  1323. //
  1324. for (i = 0; i < SendSize; i++) {
  1325. SendBuffer[i] = (char) ('a' + (i % 23));
  1326. }
  1327. //
  1328. // Initialize the send options
  1329. //
  1330. SendOpts.OptionsData = Opt;
  1331. SendOpts.OptionsSize = (UCHAR) OptLength;
  1332. SendOpts.Ttl = DEFAULT_TTL;
  1333. SendOpts.Tos = DEFAULT_TOS;
  1334. SendOpts.Flags = Flags;
  1335. numberOfReplies = IcmpSendEcho(IcmpHandle,
  1336. DestIpAddress,
  1337. SendBuffer,
  1338. (unsigned short) SendSize,
  1339. &SendOpts,
  1340. RcvBuffer,
  1341. RcvSize,
  1342. DEFAULT_TIMEOUT);
  1343. if (numberOfReplies) {
  1344. numberOfReplies = IcmpSendEcho(IcmpHandle,
  1345. DestIpAddress,
  1346. SendBuffer,
  1347. (unsigned short) SendSize,
  1348. &SendOpts,
  1349. RcvBuffer,
  1350. RcvSize,
  1351. Timeout);
  1352. if (numberOfReplies) {
  1353. reply = (PICMP_ECHO_REPLY) RcvBuffer;
  1354. *Rtt = reply->RoundTripTime;
  1355. IcmpCloseHandle(IcmpHandle);
  1356. return(TRUE);
  1357. }
  1358. }
  1359. IcmpCloseHandle(IcmpHandle);
  1360. return(FALSE);
  1361. }
  1362. BOOL
  1363. GetRTTAndHopCount(IPAddr DestIpAddress, PULONG HopCount, ULONG MaxHops,
  1364. PULONG RTT)
  1365. {
  1366. DWORD numberOfReplies;
  1367. uchar FAR *Opt = (uchar FAR *)0; // Pointer to send options
  1368. uint OptLength = 0;
  1369. int OptIndex = 0; // Current index into SendOptions
  1370. uchar Flags = 0;
  1371. ulong Timeout = DEFAULT_TIMEOUT;
  1372. IP_OPTION_INFORMATION SendOpts;
  1373. HANDLE IcmpHandle;
  1374. PICMP_ECHO_REPLY reply;
  1375. char SendBuffer[32], RcvBuffer[4096];
  1376. uint RcvSize=4096;
  1377. uint SendSize = 32;
  1378. uint i,status;
  1379. ULONG RTT1;
  1380. IcmpHandle = IcmpCreateFile();
  1381. if (IcmpHandle == INVALID_HANDLE_VALUE) {
  1382. return(FALSE);
  1383. }
  1384. if (!HopCount || !RTT) {
  1385. return (FALSE);
  1386. }
  1387. if (DestIpAddress == -1L) {
  1388. return(FALSE);
  1389. }
  1390. if (IsBadWritePtr(RTT, sizeof(ULONG))) {
  1391. return (FALSE);
  1392. }
  1393. if (IsBadWritePtr(HopCount, sizeof(ULONG))) {
  1394. return (FALSE);
  1395. }
  1396. //
  1397. // Initialize the send buffer pattern.
  1398. //
  1399. for (i = 0; i < SendSize; i++) {
  1400. SendBuffer[i] = (char) ('a' + (i % 23));
  1401. }
  1402. //
  1403. // Initialize the send options
  1404. //
  1405. SendOpts.OptionsData = Opt;
  1406. SendOpts.OptionsSize = (UCHAR) OptLength;
  1407. SendOpts.Ttl = 1;
  1408. SendOpts.Tos = DEFAULT_TOS;
  1409. SendOpts.Flags = Flags;
  1410. while (SendOpts.Ttl <= MaxHops) {
  1411. numberOfReplies = IcmpSendEcho(IcmpHandle,
  1412. DestIpAddress,
  1413. SendBuffer,
  1414. (unsigned short) SendSize,
  1415. &SendOpts,
  1416. RcvBuffer,
  1417. RcvSize,
  1418. Timeout);
  1419. if (numberOfReplies == 0) {
  1420. status = GetLastError();
  1421. reply = NULL;
  1422. } else {
  1423. reply = (PICMP_ECHO_REPLY)RcvBuffer;
  1424. status = reply->Status;
  1425. }
  1426. if (status == IP_SUCCESS) {
  1427. *HopCount = SendOpts.Ttl;
  1428. IcmpCloseHandle(IcmpHandle);
  1429. if (GetRTT(DestIpAddress, &RTT1)) {
  1430. *RTT = RTT1;
  1431. return TRUE;
  1432. } else {
  1433. return FALSE;
  1434. }
  1435. } else if (status == IP_TTL_EXPIRED_TRANSIT) {
  1436. SendOpts.Ttl++;
  1437. } else {
  1438. IcmpCloseHandle(IcmpHandle);
  1439. return FALSE;
  1440. }
  1441. }
  1442. IcmpCloseHandle(IcmpHandle);
  1443. return FALSE;
  1444. }
  1445. #define LOOPBACK_ADDR 0x0100007f
  1446. DWORD
  1447. IsLocalAddress(IPAddr InAddress)
  1448. {
  1449. int i;
  1450. DWORD dwResult;
  1451. int NumEntries;
  1452. PMIB_IPADDRTABLE pIpAddrTable;
  1453. PMIB_IPADDRROW pIpAddrEntry;
  1454. dwResult = AllocateAndGetIpAddrTableFromStack(&pIpAddrTable,
  1455. FALSE,
  1456. g_hPrivateHeap,
  1457. 0);
  1458. if(dwResult isnot NO_ERROR) {
  1459. Trace1(ERR,"GetIpAddrTableFromStack failed with error %x",dwResult);
  1460. TraceLeave("IsLocalAddress");
  1461. return dwResult;
  1462. }
  1463. if (InAddress == LOOPBACK_ADDR) {
  1464. HeapFree(g_hPrivateHeap, 0, pIpAddrTable);
  1465. return(NO_ERROR);
  1466. }
  1467. NumEntries = (*pIpAddrTable).dwNumEntries;
  1468. Trace2(ERR,"IsLocalAddress number of addresses %d chking %x",
  1469. NumEntries,InAddress);
  1470. for (i = 0; i < NumEntries; i++) {
  1471. pIpAddrEntry = &(*pIpAddrTable).table[i];
  1472. Trace1(ERR,"IsLocalAddress cmparing %x",pIpAddrEntry->dwAddr);
  1473. if (pIpAddrEntry->dwAddr == (DWORD)InAddress) {
  1474. HeapFree(g_hPrivateHeap, 0, pIpAddrTable);
  1475. return(NO_ERROR);
  1476. }
  1477. }
  1478. HeapFree(g_hPrivateHeap, 0, pIpAddrTable);
  1479. return(ERROR_INVALID_ADDRESS);
  1480. }
  1481. DWORD
  1482. GetArpTable(PMIB_IPNETTABLE pIpNetTable, PDWORD pdwSize)
  1483. {
  1484. return(GetIpNetTable(pIpNetTable,pdwSize,TRUE));
  1485. }
  1486. DWORD
  1487. AddArpEntry(IPAddr IPAddress, PUCHAR pPhyAddress, ULONG PhyAddrLen,
  1488. ULONG IfIndex, BOOLEAN Dynamic)
  1489. {
  1490. MIB_IPNETROW NetRow;
  1491. uint i;
  1492. DWORD dwResult;
  1493. NetRow.dwIndex = IfIndex;
  1494. NetRow.dwPhysAddrLen = PhyAddrLen;
  1495. if (pPhyAddress == NULL) {
  1496. return(ERROR_INVALID_PARAMETER);
  1497. }
  1498. if (PhyAddrLen > MAXLEN_PHYSADDR) {
  1499. return(ERROR_INVALID_PARAMETER);
  1500. }
  1501. // Check for bcast, loopback and class D address
  1502. if ((IPAddress == 0xffffffff) ||
  1503. (ntohl(IPAddress) == 0x7f000001) ||
  1504. ((ntohl(IPAddress) >= 0xe0000000) &&
  1505. (ntohl(IPAddress) <= 0xefffffff))) {
  1506. return ERROR_INVALID_PARAMETER;
  1507. }
  1508. for (i=0; i < PhyAddrLen; i++) {
  1509. NetRow.bPhysAddr[i] = pPhyAddress[i];
  1510. }
  1511. NetRow.dwAddr = IPAddress;
  1512. NetRow.dwType = MIB_IPNET_TYPE_DYNAMIC;
  1513. if (!Dynamic) {
  1514. NetRow.dwType = MIB_IPNET_TYPE_STATIC;
  1515. }
  1516. dwResult = SetIpNetEntryToStack(&NetRow, FALSE);
  1517. if (dwResult == STATUS_INVALID_PARAMETER) {
  1518. return(ERROR_INVALID_PARAMETER);
  1519. } else if (dwResult == STATUS_INVALID_DEVICE_REQUEST) {
  1520. return(ERROR_INVALID_PARAMETER);
  1521. }
  1522. if (dwResult == STATUS_SUCCESS) {
  1523. return(NO_ERROR);
  1524. } else {
  1525. return(dwResult);
  1526. }
  1527. }
  1528. DWORD
  1529. DeleteArpEntry(IPAddr IPAddress, ULONG IfIndex)
  1530. {
  1531. MIB_IPNETROW NetRow;
  1532. DWORD dwResult;
  1533. NetRow.dwIndex = IfIndex;
  1534. NetRow.dwAddr = IPAddress;
  1535. NetRow.dwType = MIB_IPNET_TYPE_INVALID;
  1536. dwResult = SetIpNetEntryToStack(&NetRow, FALSE);
  1537. if (dwResult == STATUS_INVALID_PARAMETER) {
  1538. return(ERROR_INVALID_PARAMETER);
  1539. }
  1540. return(dwResult);
  1541. }
  1542. DWORD
  1543. NotifyAddrChange(HANDLE *pHandle, OVERLAPPED *pOverLapped)
  1544. {
  1545. #if defined(NT4) || defined(CHICAGO)
  1546. return ERROR_NOT_SUPPORTED;
  1547. #else
  1548. BOOL b;
  1549. DWORD dwResult;
  1550. DWORD temp;
  1551. if ((pHandle != NULL) && (pOverLapped != NULL)) {
  1552. Trace0(ERR, "NotifyAddressChange: overlapped request");
  1553. if (IsBadWritePtr(pHandle, sizeof(HANDLE))) {
  1554. return ERROR_INVALID_PARAMETER;
  1555. }
  1556. if (IsBadWritePtr(pOverLapped, sizeof(OVERLAPPED))) {
  1557. return ERROR_INVALID_PARAMETER;
  1558. }
  1559. *pHandle = ChangeNotificationHandle;
  1560. if (*pHandle == INVALID_HANDLE_VALUE){
  1561. Trace1(ERR, "NotifyAddressChange: CreateFile=%d", GetLastError());
  1562. return ERROR_OPEN_FAILED;
  1563. }
  1564. b = DeviceIoControl(*pHandle,
  1565. IOCTL_IP_ADDCHANGE_NOTIFY_REQUEST,
  1566. NULL,
  1567. 0,
  1568. NULL,
  1569. 0,
  1570. &temp,
  1571. pOverLapped);
  1572. if (!b) {
  1573. dwResult = GetLastError();
  1574. Trace1(ERR, "NotifyAddrChange: DeviceIoControl=%d", dwResult);
  1575. return dwResult;
  1576. }
  1577. } else {
  1578. // Synchronous change notification
  1579. // This call will block
  1580. Trace0(ERR, "NotifyAddrChange: synchronous request");
  1581. b = DeviceIoControl(g_hIPGetDriverHandle,
  1582. IOCTL_IP_ADDCHANGE_NOTIFY_REQUEST,
  1583. NULL,
  1584. 0,
  1585. NULL,
  1586. 0,
  1587. &temp,
  1588. NULL);
  1589. if (!b) {
  1590. dwResult = GetLastError();
  1591. Trace1(ERR, "NotifyAddressChange: DeviceIoControl=%d", dwResult);
  1592. return dwResult;
  1593. }
  1594. }
  1595. return NO_ERROR;
  1596. #endif
  1597. }
  1598. DWORD
  1599. NotifyRouteChange(HANDLE *pHandle, OVERLAPPED *pOverLapped)
  1600. {
  1601. return NotifyRouteChangeEx(pHandle, pOverLapped, FALSE);
  1602. }
  1603. DWORD
  1604. NotifyRouteChangeEx(
  1605. PHANDLE pHandle,
  1606. LPOVERLAPPED pOverLapped,
  1607. BOOL bExQueue
  1608. )
  1609. {
  1610. #if defined(NT4) || defined(CHICAGO)
  1611. return ERROR_NOT_SUPPORTED;
  1612. #else
  1613. BOOL b;
  1614. DWORD dwResult;
  1615. DWORD temp;
  1616. DWORD dwIoctl;
  1617. if(bExQueue) {
  1618. dwIoctl = IOCTL_IP_RTCHANGE_NOTIFY_REQUEST_EX;
  1619. } else {
  1620. dwIoctl = IOCTL_IP_RTCHANGE_NOTIFY_REQUEST;
  1621. }
  1622. if ((pHandle != NULL) && (pOverLapped != NULL)) {
  1623. Trace0(ERR, "NotifyRouteChange: overlapped request");
  1624. if (IsBadWritePtr(pHandle, sizeof(HANDLE))) {
  1625. return ERROR_INVALID_PARAMETER;
  1626. }
  1627. if (IsBadWritePtr(pOverLapped, sizeof(OVERLAPPED))) {
  1628. return ERROR_INVALID_PARAMETER;
  1629. }
  1630. *pHandle = ChangeNotificationHandle;
  1631. if(*pHandle == INVALID_HANDLE_VALUE){
  1632. Trace1(ERR, "NotifyRouteChange: CreateFile=%d", GetLastError());
  1633. return ERROR_OPEN_FAILED;
  1634. }
  1635. b = DeviceIoControl(*pHandle,
  1636. dwIoctl,
  1637. NULL,
  1638. 0,
  1639. NULL,
  1640. 0,
  1641. &temp,
  1642. pOverLapped);
  1643. if (!b) {
  1644. dwResult = GetLastError();
  1645. Trace1(ERR, "NotifyRouteChange: DeviceIoControl=%d", dwResult);
  1646. return dwResult;
  1647. }
  1648. } else {
  1649. // Synchronous change notification
  1650. // This call will block
  1651. Trace0(ERR, "NotifyRouteChange: synchronous request");
  1652. b = DeviceIoControl(g_hIPGetDriverHandle,
  1653. dwIoctl,
  1654. NULL,
  1655. 0,
  1656. NULL,
  1657. 0,
  1658. &temp,
  1659. NULL);
  1660. if (!b) {
  1661. dwResult = GetLastError();
  1662. Trace1(ERR, "NotifyRouteChange: DeviceIoControl=%d", dwResult);
  1663. return dwResult;
  1664. }
  1665. }
  1666. return NO_ERROR;
  1667. #endif
  1668. }
  1669. DWORD WINAPI
  1670. EnableRouter(HANDLE *pHandle, OVERLAPPED *pOverLapped)
  1671. {
  1672. #if defined(NT4) || defined(CHICAGO)
  1673. return ERROR_NOT_SUPPORTED;
  1674. #else
  1675. BOOL b;
  1676. DWORD dwResult;
  1677. DWORD temp;
  1678. if ((pHandle != NULL) && (pOverLapped != NULL)) {
  1679. Trace0(ERR,"EnableRouter: overlapped request");
  1680. if (IsBadWritePtr(pHandle, sizeof(HANDLE)) ||
  1681. IsBadWritePtr(pOverLapped, sizeof(OVERLAPPED))) {
  1682. return ERROR_INVALID_PARAMETER;
  1683. }
  1684. *pHandle = g_hIPDriverHandle;
  1685. if (*pHandle == INVALID_HANDLE_VALUE) {
  1686. return ERROR_OPEN_FAILED;
  1687. }
  1688. b = DeviceIoControl(
  1689. *pHandle,
  1690. IOCTL_IP_ENABLE_ROUTER_REQUEST,
  1691. NULL,
  1692. 0,
  1693. NULL,
  1694. 0,
  1695. &temp,
  1696. pOverLapped
  1697. );
  1698. if (!b) { return GetLastError(); }
  1699. } else {
  1700. Trace0(ERR,"EnableRouter: synchronous request");
  1701. b = DeviceIoControl(
  1702. g_hIPDriverHandle,
  1703. IOCTL_IP_ENABLE_ROUTER_REQUEST,
  1704. NULL,
  1705. 0,
  1706. NULL,
  1707. 0,
  1708. &temp,
  1709. NULL
  1710. );
  1711. if (!b) {
  1712. dwResult = GetLastError();
  1713. Trace1(ERR,"EnableRouter: DeviceIoControl=%d", dwResult);
  1714. return dwResult;
  1715. }
  1716. }
  1717. return NO_ERROR;
  1718. #endif
  1719. }
  1720. DWORD WINAPI
  1721. UnenableRouter(OVERLAPPED* pOverlapped, LPDWORD lpdwEnableCount OPTIONAL)
  1722. {
  1723. #if defined(NT4) || defined(CHICAGO)
  1724. return ERROR_NOT_SUPPORTED;
  1725. #else
  1726. BOOL b;
  1727. DWORD EnableCount;
  1728. DWORD temp;
  1729. if (lpdwEnableCount && IsBadWritePtr(lpdwEnableCount, sizeof(DWORD))) {
  1730. return ERROR_INVALID_PARAMETER;
  1731. }
  1732. if (g_hIPDriverHandle == INVALID_HANDLE_VALUE) {
  1733. return ERROR_OPEN_FAILED;
  1734. }
  1735. b = DeviceIoControl(
  1736. g_hIPDriverHandle,
  1737. IOCTL_IP_UNENABLE_ROUTER_REQUEST,
  1738. (PVOID)&pOverlapped,
  1739. sizeof(PVOID),
  1740. &EnableCount,
  1741. sizeof(DWORD),
  1742. &temp,
  1743. NULL
  1744. );
  1745. if (!b) { return GetLastError(); }
  1746. if (lpdwEnableCount) { *lpdwEnableCount = EnableCount; }
  1747. return NO_ERROR;
  1748. #endif
  1749. }
  1750. DWORD WINAPI
  1751. DisableMediaSense(HANDLE *pHandle, OVERLAPPED *pOverLapped)
  1752. {
  1753. #if defined(NT4) || defined(CHICAGO)
  1754. return ERROR_NOT_SUPPORTED;
  1755. #else
  1756. BOOL b;
  1757. DWORD dwResult;
  1758. DWORD temp;
  1759. if ((pHandle != NULL) && (pOverLapped != NULL)) {
  1760. Trace0(ERR,"DisableMediaSense: overlapped request");
  1761. if (IsBadWritePtr(pHandle, sizeof(HANDLE)) ||
  1762. IsBadWritePtr(pOverLapped, sizeof(OVERLAPPED))) {
  1763. return ERROR_INVALID_PARAMETER;
  1764. }
  1765. *pHandle = g_hIPDriverHandle;
  1766. if (*pHandle == INVALID_HANDLE_VALUE) {
  1767. return ERROR_OPEN_FAILED;
  1768. }
  1769. b = DeviceIoControl(
  1770. *pHandle,
  1771. IOCTL_IP_DISABLE_MEDIA_SENSE_REQUEST,
  1772. NULL,
  1773. 0,
  1774. NULL,
  1775. 0,
  1776. &temp,
  1777. pOverLapped
  1778. );
  1779. if (!b) { return GetLastError(); }
  1780. } else {
  1781. Trace0(ERR,"DisableMediaSense: synchronous request");
  1782. b = DeviceIoControl(
  1783. g_hIPDriverHandle,
  1784. IOCTL_IP_DISABLE_MEDIA_SENSE_REQUEST,
  1785. NULL,
  1786. 0,
  1787. NULL,
  1788. 0,
  1789. &temp,
  1790. NULL
  1791. );
  1792. if (!b) {
  1793. dwResult = GetLastError();
  1794. Trace1(ERR,"DisableMediaSense: DeviceIoControl=%d", dwResult);
  1795. return dwResult;
  1796. }
  1797. }
  1798. return NO_ERROR;
  1799. #endif
  1800. }
  1801. DWORD WINAPI
  1802. RestoreMediaSense(OVERLAPPED* pOverlapped, LPDWORD lpdwEnableCount OPTIONAL)
  1803. {
  1804. #if defined(NT4) || defined(CHICAGO)
  1805. return ERROR_NOT_SUPPORTED;
  1806. #else
  1807. BOOL b;
  1808. DWORD EnableCount;
  1809. DWORD temp;
  1810. if (lpdwEnableCount && IsBadWritePtr(lpdwEnableCount, sizeof(DWORD))) {
  1811. return ERROR_INVALID_PARAMETER;
  1812. }
  1813. if (g_hIPDriverHandle == INVALID_HANDLE_VALUE) {
  1814. return ERROR_OPEN_FAILED;
  1815. }
  1816. b = DeviceIoControl(
  1817. g_hIPDriverHandle,
  1818. IOCTL_IP_ENABLE_MEDIA_SENSE_REQUEST,
  1819. (PVOID)&pOverlapped,
  1820. sizeof(PVOID),
  1821. &EnableCount,
  1822. sizeof(DWORD),
  1823. &temp,
  1824. NULL
  1825. );
  1826. if (!b) { return GetLastError(); }
  1827. if (lpdwEnableCount) { *lpdwEnableCount = EnableCount; }
  1828. return NO_ERROR;
  1829. #endif
  1830. }
  1831. #if !defined(NT4) && !defined(_WIN95_)
  1832. extern DWORD GetFixedInfoEx(PFIXED_INFO pFixedInfo, PULONG pOutBufLen);
  1833. extern DWORD GetAdapterInfoEx(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen);
  1834. extern DWORD GetAdapterAddressesEx(ULONG Family, DWORD Flags, PIP_ADAPTER_ADDRESSES pAdapterInfo, PULONG pOutBufLen);
  1835. #endif
  1836. #if !defined(NT4) && !defined(CHICAGO)
  1837. extern DWORD GetPerAdapterInfoEx(ULONG IfIndex, PIP_PER_ADAPTER_INFO pPerAdapterInfo, PULONG pOutBufLen);
  1838. #endif
  1839. DWORD
  1840. GetNetworkParams(PFIXED_INFO pFixedInfo, PULONG pOutBufLen)
  1841. {
  1842. #if !defined(NT4) && !defined(_WIN95_)
  1843. CheckTcpipState();
  1844. if (IsBadReadPtr(pOutBufLen, sizeof(ULONG))) {
  1845. return ERROR_INVALID_PARAMETER;
  1846. }
  1847. if (IsBadWritePtr(pOutBufLen, sizeof(ULONG))) {
  1848. return ERROR_INVALID_PARAMETER;
  1849. }
  1850. if (pFixedInfo != NULL &&
  1851. IsBadWritePtr(pFixedInfo, sizeof(FIXED_INFO))) {
  1852. return ERROR_INVALID_PARAMETER;
  1853. }
  1854. return GetFixedInfoEx(pFixedInfo, pOutBufLen);
  1855. #else
  1856. return ERROR_NOT_SUPPORTED;
  1857. #endif
  1858. }
  1859. DWORD
  1860. GetAdaptersAddresses(ULONG Family, DWORD Flags, PVOID Reserved,
  1861. PIP_ADAPTER_ADDRESSES pAdapterAddresses,
  1862. PULONG pOutBufLen)
  1863. {
  1864. #if !defined(NT4) && !defined(_WIN95_)
  1865. CheckTcpipState();
  1866. if (IsBadReadPtr(pOutBufLen, sizeof(ULONG))) {
  1867. return ERROR_INVALID_PARAMETER;
  1868. }
  1869. if (IsBadWritePtr(pOutBufLen, sizeof(ULONG))) {
  1870. return ERROR_INVALID_PARAMETER;
  1871. }
  1872. if (Reserved != NULL) {
  1873. return ERROR_INVALID_PARAMETER;
  1874. }
  1875. if (pAdapterAddresses != NULL &&
  1876. IsBadWritePtr(pAdapterAddresses, sizeof(IP_ADAPTER_ADDRESSES))) {
  1877. return ERROR_INVALID_PARAMETER;
  1878. }
  1879. return GetAdapterAddressesEx(Family, Flags, pAdapterAddresses, pOutBufLen);
  1880. #else
  1881. return ERROR_NOT_SUPPORTED;
  1882. #endif
  1883. }
  1884. DWORD
  1885. GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen)
  1886. {
  1887. #if !defined(NT4) && !defined(_WIN95_)
  1888. // call the init
  1889. CheckTcpipState();
  1890. if (IsBadReadPtr(pOutBufLen, sizeof(ULONG))) {
  1891. return ERROR_INVALID_PARAMETER;
  1892. }
  1893. if (IsBadWritePtr(pOutBufLen, sizeof(ULONG))) {
  1894. return ERROR_INVALID_PARAMETER;
  1895. }
  1896. if (pAdapterInfo != NULL &&
  1897. IsBadWritePtr(pAdapterInfo, sizeof(IP_ADAPTER_INFO))) {
  1898. return ERROR_INVALID_PARAMETER;
  1899. }
  1900. return GetAdapterInfoEx(pAdapterInfo, pOutBufLen);
  1901. #else
  1902. return ERROR_NOT_SUPPORTED;
  1903. #endif
  1904. }
  1905. DWORD
  1906. GetPerAdapterInfo(ULONG IfIndex, PIP_PER_ADAPTER_INFO pPerAdapterInfo,
  1907. PULONG pOutBufLen)
  1908. {
  1909. #if !defined(NT4) && !defined(CHICAGO)
  1910. CheckTcpipState();
  1911. if (IsBadReadPtr(pOutBufLen, sizeof(ULONG))) {
  1912. return ERROR_INVALID_PARAMETER;
  1913. }
  1914. if (IsBadWritePtr(pOutBufLen, sizeof(ULONG))) {
  1915. return ERROR_INVALID_PARAMETER;
  1916. }
  1917. if (pPerAdapterInfo != NULL &&
  1918. IsBadWritePtr(pPerAdapterInfo, sizeof(IP_PER_ADAPTER_INFO))) {
  1919. return ERROR_INVALID_PARAMETER;
  1920. }
  1921. return GetPerAdapterInfoEx(IfIndex, pPerAdapterInfo, pOutBufLen);
  1922. #else
  1923. return ERROR_NOT_SUPPORTED;
  1924. #endif
  1925. }
  1926. extern DWORD
  1927. DhcpReleaseParameters(
  1928. LPWSTR AdapterName
  1929. );
  1930. extern DWORD
  1931. DhcpAcquireParameters(
  1932. LPWSTR AdapterName);
  1933. #define TCP_EXPORT_STRING_PREFIX L"\\DEVICE\\TCPIP_"
  1934. DWORD
  1935. IpReleaseAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
  1936. {
  1937. #if defined(NT4) || defined(_WIN95_)
  1938. return ERROR_NOT_SUPPORTED;
  1939. #else
  1940. DWORD status;
  1941. if (!AdapterInfo) {
  1942. return ERROR_INVALID_PARAMETER;
  1943. }
  1944. if (IsBadReadPtr(AdapterInfo, sizeof(IP_ADAPTER_INDEX_MAP))) {
  1945. return ERROR_INVALID_PARAMETER;
  1946. }
  1947. #ifdef CHICAGO
  1948. {
  1949. // Convert the string to a widechar name
  1950. WCHAR Name[11];
  1951. uint i;
  1952. uint Index = AdapterInfo->Index;
  1953. i = sizeof(Name)/sizeof(Name[0]);
  1954. Name[--i] = L'\0';
  1955. while (i > 0 ) {
  1956. Name[--i] = L'0' + (Index%10);
  1957. Index /= 10;
  1958. }
  1959. status = DhcpReleaseParameters(Name);
  1960. }
  1961. #else
  1962. {
  1963. LPWSTR tmpstr;
  1964. if (wcslen(AdapterInfo->Name) <= wcslen(TCP_EXPORT_STRING_PREFIX)) {
  1965. return ERROR_INVALID_PARAMETER;
  1966. }
  1967. tmpstr = AdapterInfo->Name + wcslen(TCP_EXPORT_STRING_PREFIX);
  1968. __try {
  1969. status = DhcpReleaseParameters(tmpstr);
  1970. } __except(EXCEPTION_EXECUTE_HANDLER) {
  1971. status = ERROR_PROC_NOT_FOUND;
  1972. }
  1973. }
  1974. #endif
  1975. return(status);
  1976. #endif
  1977. }
  1978. DWORD
  1979. IpRenewAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo)
  1980. {
  1981. #if defined(NT4) || defined(_WIN95_)
  1982. return ERROR_NOT_SUPPORTED;
  1983. #else
  1984. DWORD status;
  1985. if (!AdapterInfo) {
  1986. return ERROR_INVALID_PARAMETER;
  1987. }
  1988. if (IsBadReadPtr(AdapterInfo, sizeof(IP_ADAPTER_INDEX_MAP))) {
  1989. return ERROR_INVALID_PARAMETER;
  1990. }
  1991. #ifdef CHICAGO
  1992. {
  1993. // Convert the string to a widechar name
  1994. WCHAR Name[11];
  1995. uint i;
  1996. uint Index = AdapterInfo->Index;
  1997. i = sizeof(Name)/sizeof(Name[0]);
  1998. Name[--i] = L'\0';
  1999. while (i > 0 ) {
  2000. Name[--i] = L'0' + (Index%10);
  2001. Index /= 10;
  2002. }
  2003. status = DhcpAcquireParameters(Name);
  2004. }
  2005. #else
  2006. {
  2007. LPWSTR tmpstr;
  2008. if (wcslen(AdapterInfo->Name) <= wcslen(TCP_EXPORT_STRING_PREFIX)) {
  2009. return ERROR_INVALID_PARAMETER;
  2010. }
  2011. tmpstr = AdapterInfo->Name + wcslen(TCP_EXPORT_STRING_PREFIX);
  2012. __try {
  2013. status = DhcpAcquireParameters(tmpstr);
  2014. } __except(EXCEPTION_EXECUTE_HANDLER) {
  2015. status = ERROR_PROC_NOT_FOUND;
  2016. }
  2017. }
  2018. #endif
  2019. return(status);
  2020. #endif
  2021. }
  2022. DWORD
  2023. SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAddrLen)
  2024. {
  2025. #if defined(NT4) || defined(_WIN95_)
  2026. return ERROR_NOT_SUPPORTED;
  2027. #else
  2028. ARP_SEND_REPLY requestBuffer;
  2029. DWORD requestBufferSize = sizeof(requestBuffer);
  2030. DWORD status;
  2031. requestBuffer.DestAddress = DestIP;
  2032. requestBuffer.SrcAddress = SrcIP;
  2033. if (IsBadWritePtr(pMacAddr, sizeof(ULONG))) {
  2034. return ERROR_INVALID_PARAMETER;
  2035. }
  2036. if (IsBadWritePtr(PhyAddrLen, sizeof(ULONG))) {
  2037. return ERROR_INVALID_PARAMETER;
  2038. }
  2039. status = TCPSendIoctl(g_hIPGetDriverHandle,
  2040. IOCTL_ARP_SEND_REQUEST,
  2041. &requestBuffer,
  2042. &requestBufferSize,
  2043. pMacAddr,
  2044. PhyAddrLen);
  2045. return(status);
  2046. #endif
  2047. }