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.

2374 lines
54 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. net\routing\iphlpapi.c
  5. Abstract:
  6. This files contains the public APIs are that exported by IPHLPAPI.DLL
  7. Revision History:
  8. Amritansh Raghav
  9. --*/
  10. #include "inc.h"
  11. #pragma hdrstop
  12. #define CLASSA_ADDR(a) (( (*((uchar *)&(a))) & 0x80) == 0)
  13. #define CLASSB_ADDR(a) (( (*((uchar *)&(a))) & 0xc0) == 0x80)
  14. #define CLASSC_ADDR(a) (( (*((uchar *)&(a))) & 0xe0) == 0xc0)
  15. #define CLASSD_ADDR(a) (( (*((uchar *)&(a))) & 0xf0) == 0xe0)
  16. #define CLASSE_ADDR(a) ((( (*((uchar *)&(a))) & 0xf0) == 0xf0) && \
  17. ((a) != 0xffffffff))
  18. #define CLASSA_MASK 0x000000FF
  19. #define CLASSB_MASK 0x0000FFFF
  20. #define CLASSC_MASK 0x00FFFFFF
  21. #define CLASSD_MASK 0x000000E0
  22. #define CLASSE_MASK 0xFFFFFFFF
  23. #define GetClassMask(a) \
  24. (CLASSA_ADDR(a) ? CLASSA_MASK : \
  25. (CLASSB_ADDR(a) ? CLASSB_MASK : \
  26. (CLASSC_ADDR(a) ? CLASSC_MASK : \
  27. (CLASSD_ADDR(a) ? CLASSD_MASK : CLASSE_MASK))))
  28. PIP_ADAPTER_ORDER_MAP g_adapterOrderMap = NULL;
  29. extern PIP_ADAPTER_ORDER_MAP APIENTRY GetAdapterOrderMap();
  30. DWORD
  31. GetArpEntryCount(
  32. OUT PDWORD pdwNumEntries
  33. );
  34. BOOL
  35. IsRouterRunning(VOID);
  36. DWORD
  37. GetBestInterfaceFromIpv6Stack(
  38. IN LPSOCKADDR_IN6 pSockAddr,
  39. OUT PDWORD pdwBestIfIndex
  40. );
  41. DWORD
  42. WINAPI
  43. GetNumberOfInterfaces(
  44. OUT PDWORD pdwNumIf
  45. )
  46. {
  47. PMIB_OPAQUE_INFO pInfo;
  48. PMIB_IFNUMBER pIfNum;
  49. MIB_OPAQUE_QUERY mqQuery;
  50. DWORD dwResult, dwOutEntrySize;
  51. MIB_IPSTATS IpSnmpInfo;
  52. TraceEnter("GetIfNumber");
  53. CheckTcpipState();
  54. if(!g_bIpConfigured)
  55. {
  56. Trace0(ERR, "GetIfNumber: No IP Stack on machine\n");
  57. TraceLeave("GetIfNumber");
  58. return ERROR_NOT_SUPPORTED;
  59. }
  60. if (!pdwNumIf)
  61. {
  62. return ERROR_INVALID_PARAMETER;
  63. }
  64. *pdwNumIf = 0;
  65. #ifndef CHICAGO
  66. if(IsRouterRunning())
  67. {
  68. mqQuery.dwVarId = IF_NUMBER;
  69. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  70. PID_IP,
  71. IPRTRMGR_PID,
  72. (PVOID)&mqQuery,
  73. sizeof(MIB_OPAQUE_QUERY),
  74. (PVOID)&pInfo,
  75. &dwOutEntrySize);
  76. if(dwResult isnot NO_ERROR)
  77. {
  78. Trace1(ERR,"GetIfNumber: MprAdminMIBEntryGet failed with error %x",
  79. dwResult);
  80. TraceLeave("GetIfNumber");
  81. return dwResult;
  82. }
  83. CAST_MIB_INFO(pInfo, PMIB_IFNUMBER, pIfNum);
  84. *pdwNumIf = pIfNum->dwValue;
  85. MprAdminMIBBufferFree((PVOID)pInfo);
  86. }
  87. else
  88. {
  89. #endif
  90. dwResult = GetIpStatsFromStack(&IpSnmpInfo);
  91. if(dwResult isnot NO_ERROR)
  92. {
  93. Trace1(ERR,"GetIfNumber: GetIpStatsFromStack failed with error %x",
  94. dwResult);
  95. TraceLeave("GetIfNumber");
  96. return dwResult;
  97. }
  98. *pdwNumIf = IpSnmpInfo.dwNumIf;
  99. #ifndef CHICAGO
  100. }
  101. #endif
  102. TraceLeave("GetIfNumber");
  103. return NO_ERROR;
  104. }
  105. DWORD
  106. WINAPI
  107. GetIfTable(
  108. OUT PMIB_IFTABLE pIfTable,
  109. IN OUT PULONG pdwSize,
  110. IN BOOL bOrder
  111. )
  112. {
  113. DWORD dwNumIf, dwResult, dwOutEntrySize;
  114. PMIB_IFTABLE pTable;
  115. MIB_OPAQUE_QUERY mqQuery;
  116. PMIB_OPAQUE_INFO pInfo;
  117. BOOL bForceUpdate = FALSE;
  118. TraceEnter("GetIfTable");
  119. CheckTcpipState();
  120. if(!g_bIpConfigured)
  121. {
  122. Trace0(ERR, "GetIfTable: No IP Stack on machine\n");
  123. TraceLeave("GetIfTable");
  124. return ERROR_NOT_SUPPORTED;
  125. }
  126. if(pdwSize is NULL)
  127. {
  128. Trace0(ERR,"GetIfTable: pdwSize is NULL");
  129. TraceLeave("GetIfTable");
  130. return ERROR_INVALID_PARAMETER;
  131. }
  132. if (IsBadWritePtr(pdwSize, sizeof(ULONG))) {
  133. return ERROR_INVALID_PARAMETER;
  134. }
  135. if (IsBadWritePtr(pIfTable, *pdwSize)) {
  136. return ERROR_INVALID_PARAMETER;
  137. }
  138. dwResult = GetNumberOfInterfaces(&dwNumIf);
  139. if(dwResult isnot NO_ERROR)
  140. {
  141. Trace1(ERR,"GetIfTable: GetIfNumber returned error %d",
  142. dwResult);
  143. TraceLeave("GetIfTable");
  144. return dwResult;
  145. }
  146. if(dwNumIf is 0)
  147. {
  148. Trace0(ERR,"GetIfTable: No interfaces");
  149. TraceLeave("GetIfTable");
  150. return ERROR_NO_DATA;
  151. }
  152. if( (*pdwSize < SIZEOF_IFTABLE(dwNumIf)) || (pIfTable is NULL) )
  153. {
  154. Trace3(TRACE,"GetIfTable: In size %d. Required %d. With overflow %d",
  155. *pdwSize,
  156. SIZEOF_IFTABLE(dwNumIf),
  157. SIZEOF_IFTABLE(dwNumIf + OVERFLOW_COUNT));
  158. *pdwSize = SIZEOF_IFTABLE(dwNumIf + OVERFLOW_COUNT);
  159. TraceLeave("GetIfTable");
  160. return ERROR_INSUFFICIENT_BUFFER;
  161. }
  162. #ifndef CHICAGO
  163. if(IsRouterRunning())
  164. {
  165. mqQuery.dwVarId = IF_TABLE;
  166. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  167. PID_IP,
  168. IPRTRMGR_PID,
  169. (PVOID)&mqQuery,
  170. sizeof(MIB_OPAQUE_QUERY),
  171. (PVOID)&pInfo,
  172. &dwOutEntrySize);
  173. if(dwResult isnot NO_ERROR)
  174. {
  175. Trace1(ERR,"GetIfTable: MprAdminMIBEntryGet failed with error %x",
  176. dwResult);
  177. TraceLeave("GetIfTable");
  178. return dwResult;
  179. }
  180. CAST_MIB_INFO(pInfo, PMIB_IFTABLE, pTable);
  181. if(pTable->dwNumEntries is 0)
  182. {
  183. Trace0(ERR,"GetIfTable: MprAdminMIBEntryGet returned 0 interfaces");
  184. MprAdminMIBBufferFree((PVOID)pInfo);
  185. TraceLeave("GetIfTable");
  186. return ERROR_NO_DATA;
  187. }
  188. if(*pdwSize < SIZEOF_IFTABLE(pTable->dwNumEntries))
  189. {
  190. Trace3(ERR,"GetIfTable: After MIBQuery. In size %d. Required %d. With overflow %d",
  191. *pdwSize,
  192. SIZEOF_IFTABLE(pTable->dwNumEntries),
  193. SIZEOF_IFTABLE(pTable->dwNumEntries + OVERFLOW_COUNT));
  194. *pdwSize = SIZEOF_IFTABLE(pTable->dwNumEntries + OVERFLOW_COUNT);
  195. MprAdminMIBBufferFree((PVOID)pInfo);
  196. TraceLeave("GetIfTable");
  197. return ERROR_INSUFFICIENT_BUFFER;
  198. }
  199. *pdwSize = SIZEOF_IFTABLE(pTable->dwNumEntries);
  200. CopyMemory((PVOID)(pIfTable),
  201. (PVOID)pTable,
  202. SIZEOF_IFTABLE(pTable->dwNumEntries));
  203. MprAdminMIBBufferFree((PVOID)pInfo);
  204. }
  205. else
  206. {
  207. #endif
  208. EnterCriticalSection(&g_ifLock);
  209. if (dwNumIf != g_dwNumIf)
  210. {
  211. bForceUpdate = TRUE;
  212. }
  213. g_dwNumIf = dwNumIf;
  214. LeaveCriticalSection(&g_ifLock);
  215. dwResult = GetIfTableFromStack(pIfTable,
  216. *pdwSize,
  217. bOrder,
  218. bForceUpdate);
  219. if(dwResult isnot NO_ERROR)
  220. {
  221. Trace1(ERR,"GetIfTable: GetIfTableFromStack failed with error %d",
  222. dwResult);
  223. }
  224. #ifndef CHICAGO
  225. }
  226. #endif
  227. // if bOrder is 0 sort on adapter order
  228. if( (bOrder == 0) && (dwResult == NO_ERROR) && (pIfTable) ) {
  229. EnterCriticalSection(&g_ifLock);
  230. if ((g_adapterOrderMap = GetAdapterOrderMap()) != NULL) {
  231. qsort(pIfTable->table,
  232. pIfTable->dwNumEntries,
  233. sizeof(MIB_IFROW),
  234. CompareIfRow2);
  235. LocalFree(g_adapterOrderMap);
  236. }
  237. LeaveCriticalSection(&g_ifLock);
  238. }
  239. TraceLeave("GetIfTable");
  240. return dwResult;
  241. }
  242. DWORD
  243. WINAPI
  244. GetIpAddrTable(
  245. OUT PMIB_IPADDRTABLE pIpAddrTable,
  246. IN OUT PULONG pdwSize,
  247. IN BOOL bOrder
  248. )
  249. {
  250. DWORD dwResult;
  251. MIB_IPSTATS miStats;
  252. TraceEnter("GetIpAddrTable");
  253. CheckTcpipState();
  254. if(!g_bIpConfigured)
  255. {
  256. Trace0(ERR, "GetIpAddrTable: No IP Stack on machine\n");
  257. TraceLeave("GetIpAddrTable");
  258. return ERROR_NOT_SUPPORTED;
  259. }
  260. if(pdwSize is NULL)
  261. {
  262. Trace0(ERR,"GetIpAddrTable: pdwSize is NULL");
  263. TraceLeave("GetIpAddrTable");
  264. return ERROR_INVALID_PARAMETER;
  265. }
  266. if (IsBadWritePtr(pdwSize, sizeof(ULONG))) {
  267. return ERROR_INVALID_PARAMETER;
  268. }
  269. if (IsBadWritePtr(pIpAddrTable, *pdwSize)) {
  270. return ERROR_INVALID_PARAMETER;
  271. }
  272. dwResult = GetIpStatsFromStack(&miStats);
  273. if(dwResult isnot NO_ERROR)
  274. {
  275. Trace1(ERR,"GetIpAddrTable: GetIpStatistics returned error %d",
  276. dwResult);
  277. TraceLeave("GetIpAddrTable");
  278. return dwResult;
  279. }
  280. if(miStats.dwNumAddr is 0)
  281. {
  282. Trace0(ERR,"GetIpAddrTable: No entries");
  283. TraceLeave("GetIpAddrTable");
  284. return ERROR_NO_DATA;
  285. }
  286. if( (*pdwSize < SIZEOF_IPADDRTABLE(miStats.dwNumAddr)) || (pIpAddrTable is NULL) )
  287. {
  288. Trace3(TRACE,"GetIpAddrTable: In size %d. Required %d. With overflow %d",
  289. *pdwSize,
  290. SIZEOF_IPADDRTABLE(miStats.dwNumAddr),
  291. SIZEOF_IPADDRTABLE(miStats.dwNumAddr + OVERFLOW_COUNT));
  292. *pdwSize = SIZEOF_IPADDRTABLE(miStats.dwNumAddr + OVERFLOW_COUNT);
  293. TraceLeave("GetIpAddrTable");
  294. return ERROR_INSUFFICIENT_BUFFER;
  295. }
  296. //
  297. // Retrieve the IP address table directly from TCP/IP. Note that we do not
  298. // determine first whether RRAS is running, since the IP address table
  299. // held by TCP/IP is always complete, and always contains interface indices
  300. // consistent with those held by RRAS.
  301. //
  302. dwResult = GetIpAddrTableFromStack(pIpAddrTable,
  303. *pdwSize,
  304. bOrder);
  305. if(dwResult isnot NO_ERROR)
  306. {
  307. Trace1(ERR,"GetIpAddrTable: GetIpAddrTableFromStack failed with error %d",
  308. dwResult);
  309. }
  310. // if bOrder is 0 sort on adapter order
  311. if( (bOrder == 0) && (dwResult == NO_ERROR) && (pIpAddrTable) ) {
  312. EnterCriticalSection(&g_ifLock);
  313. if ((g_adapterOrderMap = GetAdapterOrderMap()) != NULL) {
  314. qsort(pIpAddrTable->table,
  315. pIpAddrTable->dwNumEntries,
  316. sizeof(MIB_IPADDRROW),
  317. CompareIpAddrRow2);
  318. LocalFree(g_adapterOrderMap);
  319. }
  320. LeaveCriticalSection(&g_ifLock);
  321. }
  322. TraceLeave("GetIpAddrTable");
  323. return dwResult;
  324. }
  325. DWORD
  326. WINAPI
  327. GetIpNetTable(
  328. OUT PMIB_IPNETTABLE pIpNetTable,
  329. IN OUT PULONG pdwSize,
  330. IN BOOL bOrder
  331. )
  332. {
  333. DWORD dwResult, dwOutEntrySize, dwArpCount;
  334. PMIB_IPNETTABLE pTable;
  335. MIB_OPAQUE_QUERY mqQuery;
  336. PMIB_OPAQUE_INFO pInfo;
  337. TraceEnter("GetIpNetTable");
  338. CheckTcpipState();
  339. if(!g_bIpConfigured)
  340. {
  341. Trace0(ERR, "GetIpNetTable: No IP Stack on machine\n");
  342. TraceLeave("GetIpNetTable");
  343. return ERROR_NOT_SUPPORTED;
  344. }
  345. if(pdwSize is NULL)
  346. {
  347. Trace0(ERR,"GetIpNetTable: pdwSize is NULL");
  348. TraceLeave("GetIpNetTable");
  349. return ERROR_INVALID_PARAMETER;
  350. }
  351. if (IsBadWritePtr(pdwSize, sizeof(ULONG))) {
  352. return ERROR_INVALID_PARAMETER;
  353. }
  354. if (IsBadWritePtr(pIpNetTable, *pdwSize)) {
  355. return ERROR_INVALID_PARAMETER;
  356. }
  357. dwArpCount = 0;
  358. EnterCriticalSection(&g_ipNetLock);
  359. dwResult = GetArpEntryCount(&dwArpCount);
  360. LeaveCriticalSection(&g_ipNetLock);
  361. if(dwResult isnot NO_ERROR)
  362. {
  363. Trace1(ERR,"GetIpNetTable: GetIpStatistics returned error %d",
  364. dwResult);
  365. TraceLeave("GetIpNetTable");
  366. return dwResult;
  367. }
  368. if(dwArpCount is 0)
  369. {
  370. Trace0(ERR,"GetIpNetTable: No entries");
  371. TraceLeave("GetIpNetTable");
  372. return ERROR_NO_DATA;
  373. }
  374. if( (*pdwSize < SIZEOF_IPNETTABLE(dwArpCount)) || (pIpNetTable is NULL) )
  375. {
  376. Trace3(TRACE,"GetIpNetTable: In size %d. Required %d. With overflow %d",
  377. *pdwSize,
  378. SIZEOF_IPNETTABLE(dwArpCount),
  379. SIZEOF_IPNETTABLE(dwArpCount + OVERFLOW_COUNT));
  380. *pdwSize = SIZEOF_IPNETTABLE(dwArpCount + OVERFLOW_COUNT);
  381. TraceLeave("GetIpNetTable");
  382. return ERROR_INSUFFICIENT_BUFFER;
  383. }
  384. #ifndef CHICAGO
  385. if(IsRouterRunning())
  386. {
  387. mqQuery.dwVarId = IP_NETTABLE;
  388. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  389. PID_IP,
  390. IPRTRMGR_PID,
  391. (PVOID)&mqQuery,
  392. sizeof(MIB_OPAQUE_QUERY),
  393. (PVOID)&pInfo,
  394. &dwOutEntrySize);
  395. if(dwResult isnot NO_ERROR)
  396. {
  397. Trace1(ERR,"GetIpNetTable: MprAdminMIBEntryGet failed with error %x",
  398. dwResult);
  399. TraceLeave("GetIpNetTable");
  400. return dwResult;
  401. }
  402. CAST_MIB_INFO(pInfo, PMIB_IPNETTABLE, pTable);
  403. if(pTable->dwNumEntries is 0)
  404. {
  405. Trace0(ERR,"GetIpNetTable: MprAdminMIBEntryGet returned 0 interfaces");
  406. MprAdminMIBBufferFree((PVOID)pInfo);
  407. TraceLeave("GetIpNetTable");
  408. return ERROR_NO_DATA;
  409. }
  410. if(*pdwSize < SIZEOF_IPNETTABLE(pTable->dwNumEntries))
  411. {
  412. Trace3(ERR,"GetIpNetTable: After MIBQuery. In size %d. Required %d. With overflow %d",
  413. *pdwSize,
  414. SIZEOF_IPNETTABLE(pTable->dwNumEntries),
  415. SIZEOF_IPNETTABLE(pTable->dwNumEntries + OVERFLOW_COUNT));
  416. *pdwSize = SIZEOF_IPNETTABLE(pTable->dwNumEntries + OVERFLOW_COUNT);
  417. MprAdminMIBBufferFree((PVOID)pInfo);
  418. TraceLeave("GetIpNetTable");
  419. return ERROR_INSUFFICIENT_BUFFER;
  420. }
  421. *pdwSize = SIZEOF_IPNETTABLE(pTable->dwNumEntries);
  422. CopyMemory((PVOID)(pIpNetTable),
  423. (PVOID)pTable,
  424. SIZEOF_IPNETTABLE(pTable->dwNumEntries));
  425. MprAdminMIBBufferFree((PVOID)pInfo);
  426. }
  427. else
  428. {
  429. #endif
  430. dwResult = GetIpNetTableFromStack(pIpNetTable,
  431. *pdwSize,
  432. bOrder,
  433. FALSE);
  434. if(dwResult isnot NO_ERROR)
  435. {
  436. Trace1(ERR,"GetIpNetTable: GetIpNetTableFromStack failed with error %d",
  437. dwResult);
  438. }
  439. #ifndef CHICAGO
  440. }
  441. #endif
  442. TraceLeave("GetIpNetTable");
  443. return dwResult;
  444. }
  445. DWORD
  446. WINAPI
  447. GetIpForwardTable(
  448. OUT PMIB_IPFORWARDTABLE pIpForwardTable,
  449. IN OUT PULONG pdwSize,
  450. IN BOOL bOrder
  451. )
  452. {
  453. DWORD dwResult, dwOutEntrySize;
  454. MIB_IPSTATS miStats;
  455. PMIB_IPFORWARDTABLE pTable;
  456. MIB_OPAQUE_QUERY mqQuery;
  457. PMIB_OPAQUE_INFO pInfo;
  458. TraceEnter("GetIpForwardTable");
  459. CheckTcpipState();
  460. if(!g_bIpConfigured)
  461. {
  462. Trace0(ERR, "GetIpForwardTable: No IP Stack on machine\n");
  463. TraceLeave("GetIpForwardTable");
  464. return ERROR_NOT_SUPPORTED;
  465. }
  466. if(pdwSize is NULL)
  467. {
  468. Trace0(ERR,"GetIpForwardTable: pdwSize is NULL");
  469. TraceLeave("GetIpForwardTable");
  470. return ERROR_INVALID_PARAMETER;
  471. }
  472. if (IsBadWritePtr(pdwSize, sizeof(ULONG))) {
  473. return ERROR_INVALID_PARAMETER;
  474. }
  475. if (IsBadWritePtr(pIpForwardTable, *pdwSize)) {
  476. return ERROR_INVALID_PARAMETER;
  477. }
  478. dwResult = GetIpStatistics(&miStats);
  479. if(dwResult isnot NO_ERROR)
  480. {
  481. Trace1(ERR,"GetIpForwardTable: GetIpStatistics returned error %d",
  482. dwResult);
  483. TraceLeave("GetIpForwardTable");
  484. return dwResult;
  485. }
  486. if(miStats.dwNumRoutes is 0)
  487. {
  488. Trace0(ERR,"GetIpForwardTable: No entries");
  489. TraceLeave("GetIpForwardTable");
  490. return ERROR_NO_DATA;
  491. }
  492. if( (*pdwSize < SIZEOF_IPFORWARDTABLE(miStats.dwNumRoutes)) || (pIpForwardTable is NULL) )
  493. {
  494. Trace3(TRACE,"GetIpForwardTable: In size %d. Required %d. With overflow %d",
  495. *pdwSize,
  496. SIZEOF_IPFORWARDTABLE(miStats.dwNumRoutes),
  497. SIZEOF_IPFORWARDTABLE(miStats.dwNumRoutes + ROUTE_OVERFLOW_COUNT));
  498. *pdwSize = SIZEOF_IPFORWARDTABLE(miStats.dwNumRoutes + ROUTE_OVERFLOW_COUNT);
  499. TraceLeave("GetIpForwardTable");
  500. return ERROR_INSUFFICIENT_BUFFER;
  501. }
  502. #ifndef CHICAGO
  503. if(IsRouterRunning())
  504. {
  505. mqQuery.dwVarId = IP_FORWARDTABLE;
  506. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  507. PID_IP,
  508. IPRTRMGR_PID,
  509. (PVOID)&mqQuery,
  510. sizeof(MIB_OPAQUE_QUERY),
  511. (PVOID)&pInfo,
  512. &dwOutEntrySize);
  513. if(dwResult isnot NO_ERROR)
  514. {
  515. Trace1(ERR,"GetIpForwardTable: MprAdminMIBEntryGet failed with error %x",
  516. dwResult);
  517. TraceLeave("GetIpForwardTable");
  518. return dwResult;
  519. }
  520. CAST_MIB_INFO(pInfo, PMIB_IPFORWARDTABLE, pTable);
  521. if(pTable->dwNumEntries is 0)
  522. {
  523. Trace0(ERR,"GetIpForwardTable: MprAdminMIBEntryGet returned 0 interfaces");
  524. MprAdminMIBBufferFree((PVOID)pInfo);
  525. TraceLeave("GetIpForwardTable");
  526. return ERROR_NO_DATA;
  527. }
  528. if(*pdwSize < SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries))
  529. {
  530. Trace3(ERR,"GetIpForwardTable: After MIBQuery. In size %d. Required %d. With overflow %d",
  531. *pdwSize,
  532. SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries),
  533. SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries + ROUTE_OVERFLOW_COUNT));
  534. *pdwSize = SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries + ROUTE_OVERFLOW_COUNT);
  535. MprAdminMIBBufferFree((PVOID)pInfo);
  536. TraceLeave("GetIpForwardTable");
  537. return ERROR_INSUFFICIENT_BUFFER;
  538. }
  539. *pdwSize = SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries);
  540. CopyMemory((PVOID)(pIpForwardTable),
  541. (PVOID)pTable,
  542. SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries));
  543. MprAdminMIBBufferFree((PVOID)pInfo);
  544. }
  545. else
  546. {
  547. #endif
  548. dwResult = GetIpForwardTableFromStack(pIpForwardTable,
  549. *pdwSize,
  550. bOrder);
  551. if(dwResult isnot NO_ERROR)
  552. {
  553. Trace1(ERR,"GetIpForwardTable: GetIpForwardTableFromStack failed with error %d",
  554. dwResult);
  555. }
  556. #ifndef CHICAGO
  557. }
  558. #endif
  559. TraceLeave("GetIpForwardTable");
  560. return dwResult;
  561. }
  562. DWORD
  563. WINAPI
  564. GetTcpTable(
  565. OUT PMIB_TCPTABLE pTcpTable,
  566. IN OUT PDWORD pdwSize,
  567. IN BOOL bOrder
  568. )
  569. {
  570. DWORD dwResult;
  571. MIB_TCPSTATS mtStats;
  572. TraceEnter("GetTcpTable");
  573. CheckTcpipState();
  574. if(!g_bIpConfigured)
  575. {
  576. Trace0(ERR, "GetTcpTable: No IP Stack on machine\n");
  577. TraceLeave("GetTcpTable");
  578. return ERROR_NOT_SUPPORTED;
  579. }
  580. if(pdwSize is NULL)
  581. {
  582. Trace0(ERR,"GetTcpTable: pdwSize is NULL");
  583. TraceLeave("GetTcpTable");
  584. return ERROR_INVALID_PARAMETER;
  585. }
  586. if (IsBadWritePtr(pdwSize, sizeof(ULONG))) {
  587. return ERROR_INVALID_PARAMETER;
  588. }
  589. if (IsBadWritePtr(pTcpTable, *pdwSize)) {
  590. return ERROR_INVALID_PARAMETER;
  591. }
  592. dwResult = GetTcpStatistics(&mtStats);
  593. if(dwResult isnot NO_ERROR)
  594. {
  595. Trace1(ERR,"GetTcpTable: GetTcpStatistics returned error %d",
  596. dwResult);
  597. TraceLeave("GetTcpTable");
  598. return dwResult;
  599. }
  600. if(mtStats.dwNumConns is 0)
  601. {
  602. Trace0(ERR,"GetTcpTable: No entries");
  603. TraceLeave("GetTcpTable");
  604. return ERROR_NO_DATA;
  605. }
  606. if( (*pdwSize < SIZEOF_TCPTABLE(mtStats.dwNumConns)) || (pTcpTable is NULL) )
  607. {
  608. Trace3(TRACE,"GetTcpTable: In size %d. Required %d. With overflow %d",
  609. *pdwSize,
  610. SIZEOF_TCPTABLE(mtStats.dwNumConns),
  611. SIZEOF_TCPTABLE(mtStats.dwNumConns + OVERFLOW_COUNT));
  612. *pdwSize = SIZEOF_TCPTABLE(mtStats.dwNumConns + OVERFLOW_COUNT);
  613. TraceLeave("GetTcpTable");
  614. return ERROR_INSUFFICIENT_BUFFER;
  615. }
  616. dwResult = GetTcpTableFromStack(pTcpTable,
  617. *pdwSize,
  618. bOrder);
  619. if(dwResult isnot NO_ERROR)
  620. {
  621. Trace1(ERR,"GetTcpTable: GetTcpTableFromStack failed with error %d",
  622. dwResult);
  623. }
  624. TraceLeave("GetTcpTable");
  625. return dwResult;
  626. }
  627. DWORD
  628. WINAPI
  629. GetUdpTable(
  630. OUT PMIB_UDPTABLE pUdpTable,
  631. IN OUT PDWORD pdwSize,
  632. IN BOOL bOrder
  633. )
  634. {
  635. DWORD dwResult;
  636. MIB_UDPSTATS muStats;
  637. TraceEnter("GetUdpTable");
  638. CheckTcpipState();
  639. if(!g_bIpConfigured)
  640. {
  641. Trace0(ERR, "GetUdpTable: No IP Stack on machine\n");
  642. TraceLeave("GetUdpTable");
  643. return ERROR_NOT_SUPPORTED;
  644. }
  645. if(pdwSize is NULL)
  646. {
  647. Trace0(ERR,"GetUdpTable: pdwSize is NULL");
  648. TraceLeave("GetUdpTable");
  649. return ERROR_INVALID_PARAMETER;
  650. }
  651. if (IsBadWritePtr(pdwSize, sizeof(ULONG))) {
  652. return ERROR_INVALID_PARAMETER;
  653. }
  654. if (IsBadWritePtr(pUdpTable, *pdwSize)) {
  655. return ERROR_INVALID_PARAMETER;
  656. }
  657. dwResult = GetUdpStatistics(&muStats);
  658. if(dwResult isnot NO_ERROR)
  659. {
  660. Trace1(ERR,"GetUdpTable: GetUdpStatistics returned error %d",
  661. dwResult);
  662. TraceLeave("GetUdpTable");
  663. return dwResult;
  664. }
  665. if(muStats.dwNumAddrs is 0)
  666. {
  667. Trace0(ERR,"GetUdpTable: No entries");
  668. TraceLeave("GetUdpTable");
  669. return ERROR_NO_DATA;
  670. }
  671. if( (*pdwSize < SIZEOF_UDPTABLE(muStats.dwNumAddrs)) || (pUdpTable is NULL) )
  672. {
  673. Trace3(TRACE,"GetUdpTable: In size %d. Required %d. With overflow %d",
  674. *pdwSize,
  675. SIZEOF_UDPTABLE(muStats.dwNumAddrs),
  676. SIZEOF_UDPTABLE(muStats.dwNumAddrs + OVERFLOW_COUNT));
  677. *pdwSize = SIZEOF_UDPTABLE(muStats.dwNumAddrs + OVERFLOW_COUNT);
  678. TraceLeave("GetUdpTable");
  679. return ERROR_INSUFFICIENT_BUFFER;
  680. }
  681. dwResult = GetUdpTableFromStack(pUdpTable,
  682. *pdwSize,
  683. bOrder);
  684. if(dwResult isnot NO_ERROR)
  685. {
  686. Trace1(ERR,"GetUdpTable: GetUdpTableFromStack failed with error %d",
  687. dwResult);
  688. }
  689. TraceLeave("GetUdpTable");
  690. return dwResult;
  691. }
  692. DWORD
  693. WINAPI
  694. GetIpStatisticsEx(
  695. OUT PMIB_IPSTATS pStats,
  696. IN DWORD dwFamily
  697. )
  698. {
  699. DWORD dwResult, dwOutEntrySize;
  700. MIB_OPAQUE_QUERY mqQuery;
  701. PMIB_OPAQUE_INFO pInfo;
  702. PMIB_IPSTATS pIpStats;
  703. TraceEnter("GetIpStatisticsEx");
  704. if (pStats == NULL)
  705. {
  706. return ERROR_INVALID_PARAMETER;
  707. }
  708. if ((dwFamily != AF_INET) && (dwFamily != AF_INET6))
  709. {
  710. return ERROR_INVALID_PARAMETER;
  711. }
  712. if (IsBadWritePtr(pStats, sizeof(MIB_IPSTATS))) {
  713. return ERROR_INVALID_PARAMETER;
  714. }
  715. CheckTcpipState();
  716. if (((dwFamily == AF_INET) && !g_bIpConfigured) ||
  717. ((dwFamily == AF_INET6) && !g_bIp6Configured))
  718. {
  719. Trace0(ERR, "GetIpStatistics: No IP Stack on machine\n");
  720. TraceLeave("GetIpStatistics");
  721. return ERROR_NOT_SUPPORTED;
  722. }
  723. #ifndef CHICAGO
  724. if((dwFamily == AF_INET) && IsRouterRunning())
  725. {
  726. mqQuery.dwVarId = IP_STATS;
  727. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  728. PID_IP,
  729. IPRTRMGR_PID,
  730. (PVOID)&mqQuery,
  731. sizeof(MIB_OPAQUE_QUERY),
  732. (PVOID)&pInfo,
  733. &dwOutEntrySize);
  734. if(dwResult isnot NO_ERROR)
  735. {
  736. Trace1(ERR,"MprAdminMIBEntryGet failed with error %x",
  737. dwResult);
  738. TraceLeave("GetIpStats");
  739. return dwResult;
  740. }
  741. CAST_MIB_INFO(pInfo, PMIB_IPSTATS, pIpStats);
  742. *pStats = *pIpStats;
  743. MprAdminMIBBufferFree((PVOID)pInfo);
  744. }
  745. else
  746. {
  747. #endif
  748. dwResult = GetIpStatsFromStackEx(pStats, dwFamily);
  749. if(dwResult isnot NO_ERROR)
  750. {
  751. Trace1(ERR,"GetIpStatsFromStackEx failed with error %x",
  752. dwResult);
  753. }
  754. #ifndef CHICAGO
  755. }
  756. #endif
  757. TraceLeave("GetIpStatisticsEx");
  758. return dwResult;
  759. }
  760. DWORD
  761. WINAPI
  762. GetIpStatistics(
  763. OUT PMIB_IPSTATS pStats
  764. )
  765. {
  766. return GetIpStatisticsEx(pStats, AF_INET);
  767. }
  768. DWORD
  769. WINAPI
  770. GetIcmpStatistics(
  771. OUT PMIB_ICMP pStats
  772. )
  773. {
  774. DWORD dwResult;
  775. CheckTcpipState();
  776. if(!g_bIpConfigured)
  777. {
  778. Trace0(ERR, "GetIcmpStatistics: No IP Stack on machine\n");
  779. TraceLeave("GetIcmpStatistics");
  780. return ERROR_NOT_SUPPORTED;
  781. }
  782. if (pStats == NULL)
  783. {
  784. return ERROR_INVALID_PARAMETER;
  785. }
  786. if (IsBadWritePtr(pStats, sizeof(MIB_ICMP))) {
  787. return ERROR_INVALID_PARAMETER;
  788. }
  789. dwResult = GetIcmpStatsFromStack(pStats);
  790. if(dwResult isnot NO_ERROR)
  791. {
  792. Trace1(ERR,"GetIpStatsFromStack failed with error %x",
  793. dwResult);
  794. }
  795. TraceLeave("GetIcmpStats");
  796. return NO_ERROR;
  797. }
  798. VOID
  799. MakeIcmpStatsEx(
  800. OUT PMIBICMPSTATS_EX pNewStats,
  801. IN PMIBICMPSTATS pOldStats
  802. )
  803. {
  804. pNewStats->dwMsgs = pOldStats->dwMsgs;
  805. pNewStats->dwErrors = pOldStats->dwErrors;
  806. ZeroMemory(pNewStats->rgdwTypeCount, sizeof(pNewStats->rgdwTypeCount));
  807. pNewStats->rgdwTypeCount[ICMP4_DST_UNREACH] = pOldStats->dwDestUnreachs;
  808. pNewStats->rgdwTypeCount[ICMP4_TIME_EXCEEDED] = pOldStats->dwTimeExcds;
  809. pNewStats->rgdwTypeCount[ICMP4_PARAM_PROB] = pOldStats->dwParmProbs;
  810. pNewStats->rgdwTypeCount[ICMP4_SOURCE_QUENCH] = pOldStats->dwSrcQuenchs;
  811. pNewStats->rgdwTypeCount[ICMP4_REDIRECT] = pOldStats->dwRedirects;
  812. pNewStats->rgdwTypeCount[ICMP4_ECHO_REQUEST] = pOldStats->dwEchos;
  813. pNewStats->rgdwTypeCount[ICMP4_ECHO_REPLY] = pOldStats->dwEchoReps;
  814. pNewStats->rgdwTypeCount[ICMP4_TIMESTAMP_REQUEST] = pOldStats->dwTimestamps;
  815. pNewStats->rgdwTypeCount[ICMP4_TIMESTAMP_REPLY] = pOldStats->dwTimestampReps;
  816. pNewStats->rgdwTypeCount[ICMP4_MASK_REQUEST] = pOldStats->dwAddrMasks;
  817. pNewStats->rgdwTypeCount[ICMP4_MASK_REPLY] = pOldStats->dwAddrMaskReps;
  818. }
  819. DWORD
  820. WINAPI
  821. GetIcmpStatisticsEx(
  822. OUT PMIB_ICMP_EX pStats,
  823. IN DWORD dwFamily
  824. )
  825. {
  826. DWORD dwResult;
  827. TraceEnter("GetIcmpStatisticsEx");
  828. if (pStats == NULL)
  829. {
  830. return ERROR_INVALID_PARAMETER;
  831. }
  832. if ((dwFamily != AF_INET) && (dwFamily != AF_INET6))
  833. {
  834. return ERROR_INVALID_PARAMETER;
  835. }
  836. if (IsBadWritePtr(pStats, sizeof(MIB_ICMP_EX))) {
  837. return ERROR_INVALID_PARAMETER;
  838. }
  839. CheckTcpipState();
  840. if (((dwFamily == AF_INET) && !g_bIpConfigured) ||
  841. ((dwFamily == AF_INET6) && !g_bIp6Configured))
  842. {
  843. Trace0(ERR, "GetIcmpStatisticsEx: No IP Stack on machine\n");
  844. TraceLeave("GetIcmpStatisticsEx");
  845. return ERROR_NOT_SUPPORTED;
  846. }
  847. if (dwFamily == AF_INET)
  848. {
  849. //
  850. // The IPv4 stack doesn't yet support MIB_ICMP_EX, so we'll
  851. // get the MIB_ICMP structure and convert it.
  852. //
  853. MIB_ICMP OldStats;
  854. dwResult = GetIcmpStatistics(&OldStats);
  855. if(dwResult == NO_ERROR)
  856. {
  857. MakeIcmpStatsEx(&pStats->icmpInStats,
  858. &OldStats.stats.icmpInStats);
  859. MakeIcmpStatsEx(&pStats->icmpOutStats,
  860. &OldStats.stats.icmpOutStats);
  861. }
  862. }
  863. else
  864. {
  865. dwResult = GetIcmpStatsFromStackEx(pStats, dwFamily);
  866. if(dwResult isnot NO_ERROR)
  867. {
  868. Trace1(ERR,"GetIpStatsFromStackEx failed with error %x",
  869. dwResult);
  870. }
  871. }
  872. TraceLeave("GetIcmpStatisticsEx");
  873. return dwResult;
  874. }
  875. DWORD
  876. WINAPI
  877. GetTcpStatisticsEx(
  878. OUT PMIB_TCPSTATS pStats,
  879. IN DWORD dwFamily
  880. )
  881. {
  882. DWORD dwResult;
  883. if ((dwFamily != AF_INET) && (dwFamily != AF_INET6))
  884. {
  885. return ERROR_INVALID_PARAMETER;
  886. }
  887. CheckTcpipState();
  888. if (((dwFamily == AF_INET) && !g_bIpConfigured) ||
  889. ((dwFamily == AF_INET6) && !g_bIp6Configured))
  890. {
  891. Trace0(ERR, "GetTcpStatistics: No IP Stack on machine\n");
  892. TraceLeave("GetTcpStatistics");
  893. return ERROR_NOT_SUPPORTED;
  894. }
  895. if(pStats == NULL)
  896. {
  897. return ERROR_INVALID_PARAMETER;
  898. }
  899. if (IsBadWritePtr(pStats, sizeof(MIB_TCPSTATS))) {
  900. return ERROR_INVALID_PARAMETER;
  901. }
  902. dwResult = GetTcpStatsFromStackEx(pStats, dwFamily);
  903. if(dwResult isnot NO_ERROR)
  904. {
  905. Trace1(ERR,"GetTcpStatsFromStackEx failed with error %x",
  906. dwResult);
  907. }
  908. TraceLeave("GetTcpStats");
  909. return dwResult;
  910. }
  911. DWORD
  912. WINAPI
  913. GetTcpStatistics(
  914. OUT PMIB_TCPSTATS pStats
  915. )
  916. {
  917. return GetTcpStatisticsEx(pStats, AF_INET);
  918. }
  919. DWORD
  920. WINAPI
  921. GetUdpStatisticsEx(
  922. OUT PMIB_UDPSTATS pStats,
  923. IN DWORD dwFamily
  924. )
  925. {
  926. DWORD dwResult;
  927. if ((dwFamily != AF_INET) && (dwFamily != AF_INET6))
  928. {
  929. return ERROR_INVALID_PARAMETER;
  930. }
  931. CheckTcpipState();
  932. if (((dwFamily == AF_INET) && !g_bIpConfigured) ||
  933. ((dwFamily == AF_INET6) && !g_bIp6Configured))
  934. {
  935. Trace0(ERR, "GetUdpStatistics: No IP Stack on machine\n");
  936. TraceLeave("GetUdpStatistics");
  937. return ERROR_NOT_SUPPORTED;
  938. }
  939. if(pStats == NULL)
  940. {
  941. return ERROR_INVALID_PARAMETER;
  942. }
  943. if (IsBadWritePtr(pStats, sizeof(MIB_UDPSTATS))) {
  944. return ERROR_INVALID_PARAMETER;
  945. }
  946. dwResult = GetUdpStatsFromStackEx(pStats, dwFamily);
  947. if(dwResult isnot NO_ERROR)
  948. {
  949. Trace1(ERR,"GetUdpStatsFromStack failed with error %x",
  950. dwResult);
  951. }
  952. TraceLeave("GetUdpStats");
  953. return dwResult;
  954. }
  955. DWORD
  956. WINAPI
  957. GetUdpStatistics(
  958. OUT PMIB_UDPSTATS pStats
  959. )
  960. {
  961. return GetUdpStatisticsEx(pStats, AF_INET);
  962. }
  963. DWORD
  964. GetIfEntry(
  965. IN OUT PMIB_IFROW pIfEntry
  966. )
  967. {
  968. if (!pIfEntry ||
  969. IsBadWritePtr(pIfEntry, sizeof(MIB_IFROW)))
  970. {
  971. return ERROR_INVALID_PARAMETER;
  972. }
  973. CheckTcpipState();
  974. if(!g_bIpConfigured)
  975. {
  976. return ERROR_NOT_SUPPORTED;
  977. }
  978. return GetIfEntryFromStack(pIfEntry,
  979. pIfEntry->dwIndex,
  980. TRUE);
  981. }
  982. DWORD
  983. WINAPI
  984. SetIfEntry(
  985. IN PMIB_IFROW pIfRow
  986. )
  987. {
  988. DWORD dwResult;
  989. DEFINE_MIB_BUFFER(pInfo,MIB_IFROW, pSetRow);
  990. TraceEnter("SetIfEntry");
  991. if(pIfRow == NULL)
  992. {
  993. return ERROR_INVALID_PARAMETER;
  994. }
  995. if (IsBadReadPtr(pIfRow, sizeof(MIB_IFROW))) {
  996. return ERROR_INVALID_PARAMETER;
  997. }
  998. CheckTcpipState();
  999. if(!g_bIpConfigured)
  1000. {
  1001. Trace0(ERR, "SetIfEntry: No IP Stack on machine\n");
  1002. TraceLeave("SetIfEntry");
  1003. return ERROR_NOT_SUPPORTED;
  1004. }
  1005. pInfo->dwId = IF_ROW;
  1006. *pSetRow = *pIfRow;
  1007. dwResult = InternalSetIfEntry(pInfo);
  1008. if(dwResult isnot NO_ERROR)
  1009. {
  1010. Trace1(ERR,
  1011. "SetIfEntry: InternalSetIfEntry returned %d",
  1012. dwResult);
  1013. }
  1014. TraceLeave("SetIfEntry");
  1015. return dwResult;
  1016. }
  1017. DWORD
  1018. WINAPI
  1019. CreateIpForwardEntry(
  1020. IN PMIB_IPFORWARDROW pRoute
  1021. )
  1022. {
  1023. DWORD dwResult;
  1024. DEFINE_MIB_BUFFER(pCreateInfo,MIB_IPFORWARDROW,pCreateRow);
  1025. TraceEnter("CreateIpForwardEntry");
  1026. CheckTcpipState();
  1027. if(!g_bIpConfigured)
  1028. {
  1029. Trace0(ERR, "CreateIpForwardEntry: No IP Stack on machine\n");
  1030. TraceLeave("CreateIpForwardEntry");
  1031. return ERROR_NOT_SUPPORTED;
  1032. }
  1033. if(pRoute == NULL)
  1034. {
  1035. return(ERROR_INVALID_PARAMETER);
  1036. }
  1037. if (IsBadReadPtr(pRoute, sizeof(MIB_IPFORWARDROW))) {
  1038. return ERROR_INVALID_PARAMETER;
  1039. }
  1040. pCreateInfo->dwId = IP_FORWARDROW;
  1041. *pCreateRow = *pRoute;
  1042. dwResult = InternalCreateIpForwardEntry(pCreateInfo);
  1043. if(dwResult isnot NO_ERROR)
  1044. {
  1045. Trace1(ERR,
  1046. "CreateIpForwardEntry: InternalCreateIpForwardEntry returned %d",
  1047. dwResult);
  1048. }
  1049. if (dwResult == STATUS_INVALID_PARAMETER) {
  1050. return(ERROR_INVALID_PARAMETER);
  1051. }
  1052. TraceLeave("CreateIpForwardEntry");
  1053. return dwResult;
  1054. }
  1055. DWORD
  1056. WINAPI
  1057. SetIpForwardEntry(
  1058. IN PMIB_IPFORWARDROW pRoute
  1059. )
  1060. {
  1061. DWORD dwResult;
  1062. DEFINE_MIB_BUFFER(pSetInfo,MIB_IPFORWARDROW,pSetRow);
  1063. TraceEnter("SetIpForwardEntry");
  1064. CheckTcpipState();
  1065. if(!g_bIpConfigured)
  1066. {
  1067. Trace0(ERR, "SetIpForwardEntry: No IP Stack on machine\n");
  1068. TraceLeave("SetIpForwardEntry");
  1069. return ERROR_NOT_SUPPORTED;
  1070. }
  1071. if(pRoute == NULL)
  1072. {
  1073. return(ERROR_INVALID_PARAMETER);
  1074. }
  1075. if (IsBadReadPtr(pRoute, sizeof(MIB_IPFORWARDROW))) {
  1076. return ERROR_INVALID_PARAMETER;
  1077. }
  1078. pSetInfo->dwId = IP_FORWARDROW;
  1079. *pSetRow = *pRoute;
  1080. dwResult = InternalSetIpForwardEntry(pSetInfo);
  1081. if(dwResult isnot NO_ERROR)
  1082. {
  1083. Trace1(ERR,
  1084. "SetIpForwardEntry: InternalSetIpForwardEntry returned %d",
  1085. dwResult);
  1086. }
  1087. if (dwResult == STATUS_INVALID_PARAMETER) {
  1088. return(ERROR_INVALID_PARAMETER);
  1089. }
  1090. TraceLeave("SetIpForwardEntry");
  1091. return dwResult;
  1092. }
  1093. DWORD
  1094. WINAPI
  1095. DeleteIpForwardEntry(
  1096. IN PMIB_IPFORWARDROW pRoute
  1097. )
  1098. {
  1099. DWORD dwResult;
  1100. DEFINE_MIB_BUFFER(pDeleteInfo,MIB_IPFORWARDROW,pDeleteRow);
  1101. TraceEnter("DeleteIpForwardEntry");
  1102. CheckTcpipState();
  1103. if(!g_bIpConfigured)
  1104. {
  1105. Trace0(ERR, "DeleteIpForwardEntry: No IP Stack on machine\n");
  1106. TraceLeave("DeleteIpForwardEntry");
  1107. return ERROR_NOT_SUPPORTED;
  1108. }
  1109. if(pRoute == NULL)
  1110. {
  1111. return(ERROR_INVALID_PARAMETER);
  1112. }
  1113. if (IsBadReadPtr(pRoute, sizeof(MIB_IPFORWARDROW))) {
  1114. return ERROR_INVALID_PARAMETER;
  1115. }
  1116. pDeleteInfo->dwId = IP_FORWARDROW;
  1117. *pDeleteRow = *pRoute;
  1118. dwResult = InternalDeleteIpForwardEntry(pDeleteInfo);
  1119. if(dwResult isnot NO_ERROR)
  1120. {
  1121. Trace1(ERR,
  1122. "DeleteIpForwardEntry: InternalDeleteIpForwardEntry returned %d",
  1123. dwResult);
  1124. }
  1125. if (dwResult == STATUS_INVALID_PARAMETER) {
  1126. return(ERROR_NOT_FOUND);
  1127. }
  1128. TraceLeave("DeleteIpForwardEntry");
  1129. return dwResult;
  1130. }
  1131. DWORD
  1132. WINAPI
  1133. SetIpTTL(
  1134. UINT nTTL
  1135. )
  1136. {
  1137. MIB_IPSTATS Stats;
  1138. DWORD dwResult;
  1139. TraceEnter("SetIpTTL");
  1140. CheckTcpipState();
  1141. if(!g_bIpConfigured)
  1142. {
  1143. Trace0(ERR, "SetIpTTL: No IP Stack on machine\n");
  1144. TraceLeave("SetIpTTL");
  1145. return ERROR_NOT_SUPPORTED;
  1146. }
  1147. dwResult = GetIpStatistics( &Stats );
  1148. if(dwResult isnot NO_ERROR)
  1149. {
  1150. Trace1(ERR,"SetIpTll: GetIpStatistics failed with error %x",
  1151. dwResult);
  1152. TraceLeave("SetIpTTL");
  1153. return dwResult;
  1154. }
  1155. Stats.dwForwarding = MIB_USE_CURRENT_FORWARDING;
  1156. Stats.dwDefaultTTL = nTTL;
  1157. dwResult = SetIpStatistics( &Stats );
  1158. if(dwResult isnot NO_ERROR)
  1159. {
  1160. Trace1(ERR,"SetIpTll: GetIpStatistics failed with error %x",
  1161. dwResult);
  1162. }
  1163. TraceLeave("SetIpTTL");
  1164. return dwResult;
  1165. }
  1166. DWORD
  1167. WINAPI
  1168. SetIpStatistics(
  1169. IN PMIB_IPSTATS pIpStats
  1170. )
  1171. {
  1172. DWORD dwResult;
  1173. DEFINE_MIB_BUFFER(pSetInfo,MIB_IPSTATS,pSetStats);
  1174. TraceEnter("SetIpStatistics");
  1175. CheckTcpipState();
  1176. if(!g_bIpConfigured)
  1177. {
  1178. Trace0(ERR, "SetIpStatistics: No IP Stack on machine\n");
  1179. TraceLeave("SetIpStatistics");
  1180. return ERROR_NOT_SUPPORTED;
  1181. }
  1182. if(pIpStats == NULL)
  1183. {
  1184. return(ERROR_INVALID_PARAMETER);
  1185. }
  1186. if (IsBadReadPtr(pIpStats, sizeof(MIB_IPSTATS))) {
  1187. return ERROR_INVALID_PARAMETER;
  1188. }
  1189. pSetInfo->dwId = IP_STATS;
  1190. *pSetStats = *pIpStats;
  1191. dwResult = InternalSetIpStats(pSetInfo);
  1192. if(dwResult isnot NO_ERROR)
  1193. {
  1194. Trace1(ERR,
  1195. "SetIpStatistics: InternalSetIpStats returned %d",
  1196. dwResult);
  1197. }
  1198. TraceLeave("SetIpStatistics");
  1199. return dwResult;
  1200. }
  1201. DWORD
  1202. WINAPI
  1203. CreateIpNetEntry(
  1204. IN PMIB_IPNETROW pArpEntry
  1205. )
  1206. {
  1207. DWORD dwResult;
  1208. DEFINE_MIB_BUFFER(pCreateInfo,MIB_IPNETROW,pCreateRow);
  1209. TraceEnter("CreateIpNetEntry");
  1210. CheckTcpipState();
  1211. if(!g_bIpConfigured)
  1212. {
  1213. Trace0(ERR, "CreateIpNetEntry: No IP Stack on machine\n");
  1214. TraceLeave("CreateIpNetEntry");
  1215. return ERROR_NOT_SUPPORTED;
  1216. }
  1217. if(!pArpEntry)
  1218. {
  1219. return ERROR_INVALID_PARAMETER;
  1220. }
  1221. pCreateInfo->dwId = IP_NETROW;
  1222. *pCreateRow = *pArpEntry;
  1223. if((pArpEntry->dwPhysAddrLen is 0) or
  1224. (pArpEntry->dwPhysAddrLen > MAXLEN_PHYSADDR))
  1225. {
  1226. return ERROR_INVALID_PARAMETER;
  1227. }
  1228. if(((pArpEntry->dwAddr & 0x000000FF) is 0x0000007F) or
  1229. ((DWORD)(pArpEntry->dwAddr & 0x000000FF) >= (DWORD) 0x000000E0))
  1230. {
  1231. return ERROR_INVALID_PARAMETER;
  1232. }
  1233. dwResult = InternalCreateIpNetEntry(pCreateInfo);
  1234. if(dwResult isnot NO_ERROR)
  1235. {
  1236. Trace1(ERR,
  1237. "CreateIpNetEntry: InternalCreateIpNetEntry returned %d",
  1238. dwResult);
  1239. }
  1240. TraceLeave("CreateIpNetEntry");
  1241. return dwResult;
  1242. }
  1243. DWORD
  1244. WINAPI
  1245. SetIpNetEntry(
  1246. IN PMIB_IPNETROW pArpEntry
  1247. )
  1248. {
  1249. DWORD dwResult;
  1250. DEFINE_MIB_BUFFER(pSetInfo,MIB_IPNETROW,pSetRow);
  1251. TraceEnter("SetIpNetEntry");
  1252. CheckTcpipState();
  1253. if(!g_bIpConfigured)
  1254. {
  1255. Trace0(ERR, "SetIpNetEntry: No IP Stack on machine\n");
  1256. TraceLeave("SetIpNetEntry");
  1257. return ERROR_NOT_SUPPORTED;
  1258. }
  1259. if (!pArpEntry)
  1260. {
  1261. return ERROR_INVALID_PARAMETER;
  1262. }
  1263. if (IsBadReadPtr(pArpEntry, sizeof(MIB_IPNETROW))) {
  1264. return ERROR_INVALID_PARAMETER;
  1265. }
  1266. pSetInfo->dwId = IP_NETROW;
  1267. *pSetRow = *pArpEntry;
  1268. dwResult = InternalSetIpNetEntry(pSetInfo);
  1269. if(dwResult isnot NO_ERROR)
  1270. {
  1271. Trace1(ERR,
  1272. "SetIpNetEntry: InternalSetIpNetEntry returned %d",
  1273. dwResult);
  1274. }
  1275. TraceLeave("SetIpNetEntry");
  1276. return dwResult;
  1277. }
  1278. DWORD
  1279. WINAPI
  1280. DeleteIpNetEntry(
  1281. IN PMIB_IPNETROW pArpEntry
  1282. )
  1283. {
  1284. DWORD dwResult;
  1285. DEFINE_MIB_BUFFER(pDeleteInfo,MIB_IPNETROW,pDeleteRow);
  1286. TraceEnter("DeleteIpNetEntry");
  1287. CheckTcpipState();
  1288. if(!g_bIpConfigured)
  1289. {
  1290. Trace0(ERR, "DeleteIpNetEntry: No IP Stack on machine\n");
  1291. TraceLeave("DeleteIpNetEntry");
  1292. return ERROR_NOT_SUPPORTED;
  1293. }
  1294. if(pArpEntry == NULL)
  1295. {
  1296. return(ERROR_INVALID_PARAMETER);
  1297. }
  1298. if (IsBadReadPtr(pArpEntry, sizeof(MIB_IPNETROW))) {
  1299. return ERROR_INVALID_PARAMETER;
  1300. }
  1301. pDeleteInfo->dwId = IP_NETROW;
  1302. *pDeleteRow = *pArpEntry;
  1303. dwResult = InternalDeleteIpNetEntry(pDeleteInfo);
  1304. if(dwResult isnot NO_ERROR)
  1305. {
  1306. Trace1(ERR,
  1307. "DeleteIpNetEntry: InternalDeleteIpNetEntry returned %d",
  1308. dwResult);
  1309. }
  1310. TraceLeave("DeleteIpNetEntry");
  1311. return dwResult;
  1312. }
  1313. DWORD
  1314. WINAPI
  1315. FlushIpNetTable(
  1316. IN DWORD dwIfIndex
  1317. )
  1318. {
  1319. DWORD dwResult;
  1320. TraceEnter("FlushIpNetTable");
  1321. CheckTcpipState();
  1322. if(!g_bIpConfigured)
  1323. {
  1324. Trace0(ERR, "FlushIpNetTable: No IP Stack on machine\n");
  1325. TraceLeave("FlushIpNetTable");
  1326. return ERROR_NOT_SUPPORTED;
  1327. }
  1328. if(dwIfIndex == 0)
  1329. {
  1330. return(ERROR_INVALID_PARAMETER);
  1331. }
  1332. #ifndef CHICAGO
  1333. if(IsRouterRunning())
  1334. {
  1335. MIB_OPAQUE_QUERY Query;
  1336. Query.dwVarId = IP_NETTABLE;
  1337. Query.rgdwVarIndex[0] = dwIfIndex;
  1338. dwResult = MprAdminMIBEntryDelete(g_hMIBServer,
  1339. PID_IP,
  1340. IPRTRMGR_PID,
  1341. &Query,
  1342. sizeof(Query));
  1343. if(dwResult isnot NO_ERROR)
  1344. {
  1345. Trace1(ERR,"MprAdminMIBEntryDelete failed with error %x",
  1346. dwResult);
  1347. TraceLeave("FlushIpNetTable");
  1348. return dwResult;
  1349. }
  1350. }
  1351. else
  1352. {
  1353. #endif
  1354. dwResult = FlushIpNetTableFromStack(dwIfIndex);
  1355. if(dwResult isnot NO_ERROR)
  1356. {
  1357. Trace1(ERR,"FlushIpNetTableFromStack failed with error %d",
  1358. dwResult);
  1359. TraceLeave("FlushIpNetTable");
  1360. return dwResult;
  1361. }
  1362. #ifndef CHICAGO
  1363. }
  1364. #endif
  1365. TraceLeave("FlushIpNetTable");
  1366. return dwResult;
  1367. }
  1368. DWORD
  1369. WINAPI
  1370. SetTcpEntry(
  1371. IN PMIB_TCPROW pTcpRow
  1372. )
  1373. {
  1374. DWORD dwResult;
  1375. DEFINE_MIB_BUFFER(pSetInfo,MIB_TCPROW,pSetRow);
  1376. TraceEnter("SetTcpEntry");
  1377. if(!pTcpRow)
  1378. {
  1379. return ERROR_INVALID_PARAMETER;
  1380. }
  1381. CheckTcpipState();
  1382. if(!g_bIpConfigured)
  1383. {
  1384. Trace0(ERR, "SetTcpEntry: No IP Stack on machine\n");
  1385. TraceLeave("SetTcpEntry");
  1386. return ERROR_NOT_SUPPORTED;
  1387. }
  1388. if (IsBadReadPtr(pTcpRow, sizeof(MIB_TCPROW))) {
  1389. return ERROR_INVALID_PARAMETER;
  1390. }
  1391. pSetInfo->dwId = TCP_ROW;
  1392. *pSetRow = *pTcpRow;
  1393. dwResult = InternalSetTcpEntry(pSetInfo);
  1394. if(dwResult isnot NO_ERROR)
  1395. {
  1396. Trace1(ERR,
  1397. "SetTcpEntry: InternalSetTcpEntry returned %d",
  1398. dwResult);
  1399. }
  1400. TraceLeave("SetTcpEntry");
  1401. return dwResult;
  1402. }
  1403. DWORD
  1404. WINAPI
  1405. GetBestInterface(
  1406. IN IPAddr dwDestAddr,
  1407. OUT PDWORD pdwBestIfIndex
  1408. )
  1409. {
  1410. DWORD dwResult, dwOutEntrySize;
  1411. MIB_OPAQUE_QUERY mqQuery;
  1412. PMIB_OPAQUE_INFO pInfo;
  1413. PMIB_BEST_IF pBestIf;
  1414. TraceEnter("GetBestInterface");
  1415. if(pdwBestIfIndex is NULL)
  1416. {
  1417. return ERROR_INVALID_PARAMETER;
  1418. }
  1419. if (IsBadWritePtr(pdwBestIfIndex, sizeof(DWORD))) {
  1420. return ERROR_INVALID_PARAMETER;
  1421. }
  1422. CheckTcpipState();
  1423. if(!g_bIpConfigured)
  1424. {
  1425. Trace0(ERR, "GetBestInterface: No IP Stack on machine\n");
  1426. TraceLeave("GetBestInterface");
  1427. return ERROR_NOT_SUPPORTED;
  1428. }
  1429. #ifndef CHICAGO
  1430. if(IsRouterRunning())
  1431. {
  1432. mqQuery.dwVarId = BEST_IF;
  1433. mqQuery.rgdwVarIndex[0] = dwDestAddr;
  1434. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  1435. PID_IP,
  1436. IPRTRMGR_PID,
  1437. (PVOID)&mqQuery,
  1438. sizeof(MIB_OPAQUE_QUERY),
  1439. (PVOID)&pInfo,
  1440. &dwOutEntrySize);
  1441. if(dwResult isnot NO_ERROR)
  1442. {
  1443. Trace1(ERR,"GetIfTable: MprAdminMIBEntryGet failed with error %x",
  1444. dwResult);
  1445. TraceLeave("GetIfTable");
  1446. return dwResult;
  1447. }
  1448. CAST_MIB_INFO(pInfo, PMIB_BEST_IF, pBestIf);
  1449. if(dwDestAddr is pBestIf->dwDestAddr)
  1450. {
  1451. *pdwBestIfIndex = pBestIf->dwIfIndex;
  1452. }
  1453. else
  1454. {
  1455. dwResult = ERROR_CAN_NOT_COMPLETE;
  1456. }
  1457. MprAdminMIBBufferFree((PVOID)pInfo);
  1458. }
  1459. else
  1460. {
  1461. #endif
  1462. dwResult = GetBestInterfaceFromStack(dwDestAddr,
  1463. pdwBestIfIndex);
  1464. if(dwResult is STATUS_SUCCESS)
  1465. {
  1466. dwResult = NO_ERROR;
  1467. }
  1468. else
  1469. {
  1470. dwResult = ERROR_CAN_NOT_COMPLETE;
  1471. }
  1472. #ifndef CHICAGO
  1473. }
  1474. #endif
  1475. return dwResult;
  1476. }
  1477. DWORD
  1478. WINAPI
  1479. GetBestInterfaceEx(
  1480. IN LPSOCKADDR pSockAddr,
  1481. OUT PDWORD pdwBestIfIndex
  1482. )
  1483. {
  1484. DWORD dwResult;
  1485. LPSOCKADDR_IN6 pSin6;
  1486. IPAddr dwDestAddr;
  1487. if (IsBadReadPtr(pSockAddr, sizeof(SOCKADDR))) {
  1488. return ERROR_INVALID_PARAMETER;
  1489. }
  1490. if (pSockAddr->sa_family == AF_INET) {
  1491. return GetBestInterface(((LPSOCKADDR_IN)pSockAddr)->sin_addr.s_addr, pdwBestIfIndex);
  1492. }
  1493. if (pSockAddr->sa_family != AF_INET6) {
  1494. return ERROR_INVALID_PARAMETER;
  1495. }
  1496. if (IsBadReadPtr(pSockAddr, sizeof(SOCKADDR_IN6))) {
  1497. return ERROR_INVALID_PARAMETER;
  1498. }
  1499. pSin6 = (LPSOCKADDR_IN6)pSockAddr;
  1500. if (IN6_IS_ADDR_V4MAPPED(&pSin6->sin6_addr)) {
  1501. CopyMemory(&dwDestAddr,
  1502. &pSin6->sin6_addr.s6_words[6],
  1503. sizeof(dwDestAddr));
  1504. return GetBestInterface(dwDestAddr, pdwBestIfIndex);
  1505. }
  1506. if (pdwBestIfIndex is NULL) {
  1507. return ERROR_INVALID_PARAMETER;
  1508. }
  1509. if (IsBadWritePtr(pdwBestIfIndex, sizeof(DWORD))) {
  1510. return ERROR_INVALID_PARAMETER;
  1511. }
  1512. CheckTcpipState();
  1513. if (!g_bIp6Configured) {
  1514. Trace0(ERR, "GetBestInterface: No IPv6 Stack on machine\n");
  1515. return ERROR_NOT_SUPPORTED;
  1516. }
  1517. dwResult = GetBestInterfaceFromIpv6Stack(pSin6, pdwBestIfIndex);
  1518. return dwResult;
  1519. }
  1520. DWORD
  1521. WINAPI
  1522. GetBestRoute(
  1523. IN DWORD dwDestAddr,
  1524. IN DWORD dwSourceAddr, OPTIONAL
  1525. OUT PMIB_IPFORWARDROW pBestRoute
  1526. )
  1527. {
  1528. DWORD dwResult;
  1529. TraceEnter("GetBestRoute");
  1530. CheckTcpipState();
  1531. if(!g_bIpConfigured)
  1532. {
  1533. Trace0(ERR, "GetBestInterface: No IP Stack on machine\n");
  1534. TraceLeave("GetBestInterface");
  1535. return ERROR_NOT_SUPPORTED;
  1536. }
  1537. if(pBestRoute is NULL)
  1538. {
  1539. return ERROR_INVALID_PARAMETER;
  1540. }
  1541. if (IsBadWritePtr(pBestRoute, sizeof(MIB_IPFORWARDROW))) {
  1542. return ERROR_INVALID_PARAMETER;
  1543. }
  1544. dwResult = GetBestRouteFromStack(dwDestAddr,
  1545. dwSourceAddr,
  1546. pBestRoute);
  1547. if(dwResult is STATUS_SUCCESS)
  1548. {
  1549. dwResult = NO_ERROR;
  1550. }
  1551. else
  1552. {
  1553. dwResult = ERROR_CAN_NOT_COMPLETE;
  1554. }
  1555. return dwResult;
  1556. }
  1557. DWORD
  1558. WINAPI
  1559. CreateProxyArpEntry(
  1560. IN DWORD dwAddress,
  1561. IN DWORD dwMask,
  1562. IN DWORD dwIfIndex
  1563. )
  1564. {
  1565. DWORD dwResult, dwClassMask;
  1566. DEFINE_MIB_BUFFER(pSetInfo,MIB_PROXYARP,pParpRow);
  1567. TraceEnter("CreateProxyArpEntry");
  1568. #ifdef CHICAGO
  1569. TraceLeave("CreateProxyArpEntry");
  1570. return ERROR_NOT_SUPPORTED;
  1571. #else
  1572. CheckTcpipState();
  1573. if(!g_bIpConfigured)
  1574. {
  1575. Trace0(ERR, "CreateProxyArpEntry: No IP Stack on machine\n");
  1576. TraceLeave("CreateProxyArpEntry");
  1577. return ERROR_NOT_SUPPORTED;
  1578. }
  1579. dwClassMask = GetClassMask(dwAddress);
  1580. //
  1581. // Address & Mask should == Address
  1582. // Address should not be in the loopback range
  1583. // Address should not be all 0's
  1584. // Address should not be < ClassD
  1585. // Address should not be the all subnets broadcast
  1586. //
  1587. if(((dwAddress & 0x000000FF) is 0x0000007F) or
  1588. (dwAddress is 0x00000000) or
  1589. ((DWORD)(dwAddress & 0x000000FF) >= (DWORD) 0x000000E0) or
  1590. ((dwAddress & dwMask) isnot dwAddress) or
  1591. (dwAddress is (dwAddress | ~dwClassMask)))
  1592. {
  1593. TraceLeave("CreateProxyArpEntry");
  1594. return ERROR_INVALID_PARAMETER;
  1595. }
  1596. if(IsRouterRunning())
  1597. {
  1598. pSetInfo->dwId = PROXY_ARP;
  1599. pParpRow->dwAddress = dwAddress;
  1600. pParpRow->dwMask = dwMask;
  1601. pParpRow->dwIfIndex = dwIfIndex;
  1602. dwResult = MprAdminMIBEntrySet(g_hMIBServer,
  1603. PID_IP,
  1604. IPRTRMGR_PID,
  1605. (PVOID)pSetInfo,
  1606. MIB_INFO_SIZE(MIB_PROXYARP));
  1607. if(dwResult isnot NO_ERROR)
  1608. {
  1609. Trace1(ERR,
  1610. "MprAdminMIBEntrySet failed with error %x",
  1611. dwResult);
  1612. TraceLeave("CreateProxyArpEntry");
  1613. return dwResult;
  1614. }
  1615. }
  1616. else
  1617. {
  1618. dwResult = SetProxyArpEntryToStack(dwAddress,
  1619. dwMask,
  1620. dwIfIndex,
  1621. TRUE,
  1622. FALSE);
  1623. if(dwResult isnot NO_ERROR)
  1624. {
  1625. Trace1(ERR,
  1626. "SetProxyArpEntryToStack failed with error %d",
  1627. dwResult);
  1628. TraceLeave("CreateProxyArpEntry");
  1629. return dwResult;
  1630. }
  1631. }
  1632. TraceLeave("CreateProxyArpEntry");
  1633. return NO_ERROR;
  1634. #endif
  1635. }
  1636. DWORD
  1637. WINAPI
  1638. DeleteProxyArpEntry(
  1639. IN DWORD dwAddress,
  1640. IN DWORD dwMask,
  1641. IN DWORD dwIfIndex
  1642. )
  1643. {
  1644. DWORD dwResult, dwClassMask;
  1645. PMIB_OPAQUE_QUERY pmqQuery;
  1646. #define QUERY_SIZE sizeof(MIB_OPAQUE_QUERY) + 2 * sizeof(DWORD)
  1647. BYTE rgbyBuffer[QUERY_SIZE];
  1648. #undef QUERY_SIZE
  1649. TraceEnter("DeleteProxyArpEntry");
  1650. #ifdef CHICAGO
  1651. TraceLeave("DeleteProxyArpEntry");
  1652. return ERROR_NOT_SUPPORTED;
  1653. #else
  1654. CheckTcpipState();
  1655. if(!g_bIpConfigured)
  1656. {
  1657. Trace0(ERR,
  1658. "DeleteProxyArpEntry: No IP Stack on machine\n");
  1659. TraceLeave("DeleteProxyArpEntry");
  1660. return ERROR_NOT_SUPPORTED;
  1661. }
  1662. dwClassMask = GetClassMask(dwAddress);
  1663. if(((dwAddress & 0x000000FF) is 0x0000007F) or
  1664. (dwAddress is 0x00000000) or
  1665. ((DWORD)(dwAddress & 0x000000FF) >= (DWORD) 0x000000E0) or
  1666. ((dwAddress & dwMask) isnot dwAddress) or
  1667. (dwAddress is (dwAddress | ~dwClassMask)))
  1668. {
  1669. TraceLeave("DeleteProxyArpEntry");
  1670. return ERROR_INVALID_PARAMETER;
  1671. }
  1672. if(IsRouterRunning())
  1673. {
  1674. pmqQuery = (PMIB_OPAQUE_QUERY)rgbyBuffer;
  1675. pmqQuery->dwVarId = PROXY_ARP;
  1676. pmqQuery->rgdwVarIndex[0] = dwAddress;
  1677. pmqQuery->rgdwVarIndex[1] = dwMask;
  1678. pmqQuery->rgdwVarIndex[2] = dwIfIndex;
  1679. dwResult = MprAdminMIBEntryDelete(g_hMIBServer,
  1680. PID_IP,
  1681. IPRTRMGR_PID,
  1682. (PVOID)pmqQuery,
  1683. sizeof(rgbyBuffer));
  1684. if(dwResult isnot NO_ERROR)
  1685. {
  1686. Trace1(ERR,
  1687. "MprAdminMIBEntryDelete failed with error %x",
  1688. dwResult);
  1689. TraceLeave("DeleteProxyArpEntry");
  1690. return dwResult;
  1691. }
  1692. }
  1693. else
  1694. {
  1695. dwResult = SetProxyArpEntryToStack(dwAddress,
  1696. dwMask,
  1697. dwIfIndex,
  1698. FALSE,
  1699. FALSE);
  1700. if(dwResult isnot NO_ERROR)
  1701. {
  1702. Trace1(ERR,
  1703. "SetProxyArpEntryToStack failed with error %x",
  1704. dwResult);
  1705. TraceLeave("DeleteProxyArpEntry");
  1706. return dwResult;
  1707. }
  1708. }
  1709. TraceLeave("DeleteProxyArpEntry");
  1710. return NO_ERROR;
  1711. #endif
  1712. }
  1713. DWORD
  1714. WINAPI
  1715. GetFriendlyIfIndex(
  1716. DWORD IfIndex
  1717. )
  1718. {
  1719. return (0x00FFFFFF & IfIndex);
  1720. }
  1721. VOID
  1722. CheckTcpipState()
  1723. {
  1724. // Check whether tcpip was configured
  1725. // if not, check whether tcpip is configured now
  1726. EnterCriticalSection(&g_stateLock);
  1727. if (!g_bIpConfigured) {
  1728. if (OpenTCPDriver(AF_INET) == NO_ERROR) {
  1729. if (UpdateAdapterToIFInstanceMapping() != NO_ERROR) {
  1730. CloseTCPDriver();
  1731. } else if (UpdateAdapterToATInstanceMapping() != NO_ERROR) {
  1732. CloseTCPDriver();
  1733. } else if (IpcfgdllInit(NULL, DLL_PROCESS_ATTACH, NULL) == FALSE) {
  1734. CloseTCPDriver();
  1735. } else {
  1736. g_bIpConfigured = TRUE;
  1737. }
  1738. }
  1739. }
  1740. if (!g_bIp6Configured) {
  1741. if (OpenTCPDriver(AF_INET6) == NO_ERROR) {
  1742. g_bIp6Configured = TRUE;
  1743. }
  1744. }
  1745. LeaveCriticalSection(&g_stateLock);
  1746. }