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.

2699 lines
60 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. TraceLeave("GetIfTable");
  196. return ERROR_INSUFFICIENT_BUFFER;
  197. }
  198. *pdwSize = SIZEOF_IFTABLE(pTable->dwNumEntries);
  199. CopyMemory((PVOID)(pIfTable),
  200. (PVOID)pTable,
  201. SIZEOF_IFTABLE(pTable->dwNumEntries));
  202. MprAdminMIBBufferFree((PVOID)pInfo);
  203. }
  204. else
  205. {
  206. #endif
  207. EnterCriticalSection(&g_ifLock);
  208. if (dwNumIf != g_dwNumIf)
  209. {
  210. bForceUpdate = TRUE;
  211. }
  212. g_dwNumIf = dwNumIf;
  213. LeaveCriticalSection(&g_ifLock);
  214. dwResult = GetIfTableFromStack(pIfTable,
  215. *pdwSize,
  216. bOrder,
  217. bForceUpdate);
  218. if(dwResult isnot NO_ERROR)
  219. {
  220. Trace1(ERR,"GetIfTable: GetIfTableFromStack failed with error %d",
  221. dwResult);
  222. }
  223. #ifndef CHICAGO
  224. }
  225. #endif
  226. // if bOrder is 0 sort on adapter order
  227. if( (bOrder == 0) && (dwResult == NO_ERROR) && (pIfTable) ) {
  228. EnterCriticalSection(&g_ifLock);
  229. if (g_adapterOrderMap = GetAdapterOrderMap()) {
  230. qsort(pIfTable->table,
  231. pIfTable->dwNumEntries,
  232. sizeof(MIB_IFROW),
  233. CompareIfRow2);
  234. LocalFree(g_adapterOrderMap);
  235. }
  236. LeaveCriticalSection(&g_ifLock);
  237. }
  238. TraceLeave("GetIfTable");
  239. return dwResult;
  240. }
  241. DWORD
  242. WINAPI
  243. GetIpAddrTable(
  244. OUT PMIB_IPADDRTABLE pIpAddrTable,
  245. IN OUT PULONG pdwSize,
  246. IN BOOL bOrder
  247. )
  248. {
  249. DWORD dwResult, dwOutEntrySize;
  250. MIB_IPSTATS miStats;
  251. PMIB_IPADDRTABLE pTable;
  252. MIB_OPAQUE_QUERY mqQuery;
  253. PMIB_OPAQUE_INFO pInfo;
  254. TraceEnter("GetIpAddrTable");
  255. CheckTcpipState();
  256. if(!g_bIpConfigured)
  257. {
  258. Trace0(ERR, "GetIpAddrTable: No IP Stack on machine\n");
  259. TraceLeave("GetIpAddrTable");
  260. return ERROR_NOT_SUPPORTED;
  261. }
  262. if(pdwSize is NULL)
  263. {
  264. Trace0(ERR,"GetIpAddrTable: pdwSize is NULL");
  265. TraceLeave("GetIpAddrTable");
  266. return ERROR_INVALID_PARAMETER;
  267. }
  268. if (IsBadWritePtr(pdwSize, sizeof(ULONG))) {
  269. return ERROR_INVALID_PARAMETER;
  270. }
  271. if (IsBadWritePtr(pIpAddrTable, *pdwSize)) {
  272. return ERROR_INVALID_PARAMETER;
  273. }
  274. dwResult = GetIpStatsFromStack(&miStats);
  275. if(dwResult isnot NO_ERROR)
  276. {
  277. Trace1(ERR,"GetIpAddrTable: GetIpStatistics returned error %d",
  278. dwResult);
  279. TraceLeave("GetIpAddrTable");
  280. return dwResult;
  281. }
  282. if(miStats.dwNumAddr is 0)
  283. {
  284. Trace0(ERR,"GetIpAddrTable: No entries");
  285. TraceLeave("GetIpAddrTable");
  286. return ERROR_NO_DATA;
  287. }
  288. if( (*pdwSize < SIZEOF_IPADDRTABLE(miStats.dwNumAddr)) || (pIpAddrTable is NULL) )
  289. {
  290. Trace3(TRACE,"GetIpAddrTable: In size %d. Required %d. With overflow %d",
  291. *pdwSize,
  292. SIZEOF_IPADDRTABLE(miStats.dwNumAddr),
  293. SIZEOF_IPADDRTABLE(miStats.dwNumAddr + OVERFLOW_COUNT));
  294. *pdwSize = SIZEOF_IPADDRTABLE(miStats.dwNumAddr + OVERFLOW_COUNT);
  295. TraceLeave("GetIpAddrTable");
  296. return ERROR_INSUFFICIENT_BUFFER;
  297. }
  298. //
  299. // Retrieve the IP address table directly from TCP/IP. Note that we do not
  300. // determine first whether RRAS is running, since the IP address table
  301. // held by TCP/IP is always complete, and always contains interface indices
  302. // consistent with those held by RRAS.
  303. //
  304. dwResult = GetIpAddrTableFromStack(pIpAddrTable,
  305. *pdwSize,
  306. bOrder);
  307. if(dwResult isnot NO_ERROR)
  308. {
  309. Trace1(ERR,"GetIpAddrTable: GetIpAddrTableFromStack failed with error %d",
  310. dwResult);
  311. }
  312. // if bOrder is 0 sort on adapter order
  313. if( (bOrder == 0) && (dwResult == NO_ERROR) && (pIpAddrTable) ) {
  314. EnterCriticalSection(&g_ifLock);
  315. if (g_adapterOrderMap = GetAdapterOrderMap()) {
  316. qsort(pIpAddrTable->table,
  317. pIpAddrTable->dwNumEntries,
  318. sizeof(MIB_IPADDRROW),
  319. CompareIpAddrRow2);
  320. LocalFree(g_adapterOrderMap);
  321. }
  322. LeaveCriticalSection(&g_ifLock);
  323. }
  324. TraceLeave("GetIpAddrTable");
  325. return dwResult;
  326. }
  327. DWORD
  328. WINAPI
  329. GetIpNetTable(
  330. OUT PMIB_IPNETTABLE pIpNetTable,
  331. IN OUT PULONG pdwSize,
  332. IN BOOL bOrder
  333. )
  334. {
  335. DWORD dwResult, dwOutEntrySize, dwArpCount;
  336. PMIB_IPNETTABLE pTable;
  337. MIB_OPAQUE_QUERY mqQuery;
  338. PMIB_OPAQUE_INFO pInfo;
  339. TraceEnter("GetIpNetTable");
  340. CheckTcpipState();
  341. if(!g_bIpConfigured)
  342. {
  343. Trace0(ERR, "GetIpNetTable: No IP Stack on machine\n");
  344. TraceLeave("GetIpNetTable");
  345. return ERROR_NOT_SUPPORTED;
  346. }
  347. if(pdwSize is NULL)
  348. {
  349. Trace0(ERR,"GetIpNetTable: pdwSize is NULL");
  350. TraceLeave("GetIpNetTable");
  351. return ERROR_INVALID_PARAMETER;
  352. }
  353. if (IsBadWritePtr(pdwSize, sizeof(ULONG))) {
  354. return ERROR_INVALID_PARAMETER;
  355. }
  356. if (IsBadWritePtr(pIpNetTable, *pdwSize)) {
  357. return ERROR_INVALID_PARAMETER;
  358. }
  359. dwArpCount = 0;
  360. EnterCriticalSection(&g_ipNetLock);
  361. dwResult = GetArpEntryCount(&dwArpCount);
  362. LeaveCriticalSection(&g_ipNetLock);
  363. if(dwResult isnot NO_ERROR)
  364. {
  365. Trace1(ERR,"GetIpNetTable: GetIpStatistics returned error %d",
  366. dwResult);
  367. TraceLeave("GetIpNetTable");
  368. return dwResult;
  369. }
  370. if(dwArpCount is 0)
  371. {
  372. Trace0(ERR,"GetIpNetTable: No entries");
  373. TraceLeave("GetIpNetTable");
  374. return ERROR_NO_DATA;
  375. }
  376. if( (*pdwSize < SIZEOF_IPNETTABLE(dwArpCount)) || (pIpNetTable is NULL) )
  377. {
  378. Trace3(TRACE,"GetIpNetTable: In size %d. Required %d. With overflow %d",
  379. *pdwSize,
  380. SIZEOF_IPNETTABLE(dwArpCount),
  381. SIZEOF_IPNETTABLE(dwArpCount + OVERFLOW_COUNT));
  382. *pdwSize = SIZEOF_IPNETTABLE(dwArpCount + OVERFLOW_COUNT);
  383. TraceLeave("GetIpNetTable");
  384. return ERROR_INSUFFICIENT_BUFFER;
  385. }
  386. #ifndef CHICAGO
  387. if(IsRouterRunning())
  388. {
  389. mqQuery.dwVarId = IP_NETTABLE;
  390. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  391. PID_IP,
  392. IPRTRMGR_PID,
  393. (PVOID)&mqQuery,
  394. sizeof(MIB_OPAQUE_QUERY),
  395. (PVOID)&pInfo,
  396. &dwOutEntrySize);
  397. if(dwResult isnot NO_ERROR)
  398. {
  399. Trace1(ERR,"GetIpNetTable: MprAdminMIBEntryGet failed with error %x",
  400. dwResult);
  401. TraceLeave("GetIpNetTable");
  402. return dwResult;
  403. }
  404. CAST_MIB_INFO(pInfo, PMIB_IPNETTABLE, pTable);
  405. if(pTable->dwNumEntries is 0)
  406. {
  407. Trace0(ERR,"GetIpNetTable: MprAdminMIBEntryGet returned 0 interfaces");
  408. MprAdminMIBBufferFree((PVOID)pInfo);
  409. TraceLeave("GetIpNetTable");
  410. return ERROR_NO_DATA;
  411. }
  412. if(*pdwSize < SIZEOF_IPNETTABLE(pTable->dwNumEntries))
  413. {
  414. Trace3(ERR,"GetIpNetTable: After MIBQuery. In size %d. Required %d. With overflow %d",
  415. *pdwSize,
  416. SIZEOF_IPNETTABLE(pTable->dwNumEntries),
  417. SIZEOF_IPNETTABLE(pTable->dwNumEntries + OVERFLOW_COUNT));
  418. *pdwSize = SIZEOF_IPNETTABLE(pTable->dwNumEntries + OVERFLOW_COUNT);
  419. TraceLeave("GetIpNetTable");
  420. return ERROR_INSUFFICIENT_BUFFER;
  421. }
  422. *pdwSize = SIZEOF_IPNETTABLE(pTable->dwNumEntries);
  423. CopyMemory((PVOID)(pIpNetTable),
  424. (PVOID)pTable,
  425. SIZEOF_IPNETTABLE(pTable->dwNumEntries));
  426. MprAdminMIBBufferFree((PVOID)pInfo);
  427. }
  428. else
  429. {
  430. #endif
  431. dwResult = GetIpNetTableFromStack(pIpNetTable,
  432. *pdwSize,
  433. bOrder,
  434. FALSE);
  435. if(dwResult isnot NO_ERROR)
  436. {
  437. Trace1(ERR,"GetIpNetTable: GetIpNetTableFromStack failed with error %d",
  438. dwResult);
  439. }
  440. #ifndef CHICAGO
  441. }
  442. #endif
  443. TraceLeave("GetIpNetTable");
  444. return dwResult;
  445. }
  446. DWORD
  447. WINAPI
  448. GetIpForwardTable(
  449. OUT PMIB_IPFORWARDTABLE pIpForwardTable,
  450. IN OUT PULONG pdwSize,
  451. IN BOOL bOrder
  452. )
  453. {
  454. DWORD dwResult, dwOutEntrySize;
  455. MIB_IPSTATS miStats;
  456. PMIB_IPFORWARDTABLE pTable;
  457. MIB_OPAQUE_QUERY mqQuery;
  458. PMIB_OPAQUE_INFO pInfo;
  459. TraceEnter("GetIpForwardTable");
  460. CheckTcpipState();
  461. if(!g_bIpConfigured)
  462. {
  463. Trace0(ERR, "GetIpForwardTable: No IP Stack on machine\n");
  464. TraceLeave("GetIpForwardTable");
  465. return ERROR_NOT_SUPPORTED;
  466. }
  467. if(pdwSize is NULL)
  468. {
  469. Trace0(ERR,"GetIpForwardTable: pdwSize is NULL");
  470. TraceLeave("GetIpForwardTable");
  471. return ERROR_INVALID_PARAMETER;
  472. }
  473. if (IsBadWritePtr(pdwSize, sizeof(ULONG))) {
  474. return ERROR_INVALID_PARAMETER;
  475. }
  476. if (IsBadWritePtr(pIpForwardTable, *pdwSize)) {
  477. return ERROR_INVALID_PARAMETER;
  478. }
  479. dwResult = GetIpStatistics(&miStats);
  480. if(dwResult isnot NO_ERROR)
  481. {
  482. Trace1(ERR,"GetIpForwardTable: GetIpStatistics returned error %d",
  483. dwResult);
  484. TraceLeave("GetIpForwardTable");
  485. return dwResult;
  486. }
  487. if(miStats.dwNumRoutes is 0)
  488. {
  489. Trace0(ERR,"GetIpForwardTable: No entries");
  490. TraceLeave("GetIpForwardTable");
  491. return ERROR_NO_DATA;
  492. }
  493. if( (*pdwSize < SIZEOF_IPFORWARDTABLE(miStats.dwNumRoutes)) || (pIpForwardTable is NULL) )
  494. {
  495. Trace3(TRACE,"GetIpForwardTable: In size %d. Required %d. With overflow %d",
  496. *pdwSize,
  497. SIZEOF_IPFORWARDTABLE(miStats.dwNumRoutes),
  498. SIZEOF_IPFORWARDTABLE(miStats.dwNumRoutes + ROUTE_OVERFLOW_COUNT));
  499. *pdwSize = SIZEOF_IPFORWARDTABLE(miStats.dwNumRoutes + ROUTE_OVERFLOW_COUNT);
  500. TraceLeave("GetIpForwardTable");
  501. return ERROR_INSUFFICIENT_BUFFER;
  502. }
  503. #ifndef CHICAGO
  504. if(IsRouterRunning())
  505. {
  506. mqQuery.dwVarId = IP_FORWARDTABLE;
  507. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  508. PID_IP,
  509. IPRTRMGR_PID,
  510. (PVOID)&mqQuery,
  511. sizeof(MIB_OPAQUE_QUERY),
  512. (PVOID)&pInfo,
  513. &dwOutEntrySize);
  514. if(dwResult isnot NO_ERROR)
  515. {
  516. Trace1(ERR,"GetIpForwardTable: MprAdminMIBEntryGet failed with error %x",
  517. dwResult);
  518. TraceLeave("GetIpForwardTable");
  519. return dwResult;
  520. }
  521. CAST_MIB_INFO(pInfo, PMIB_IPFORWARDTABLE, pTable);
  522. if(pTable->dwNumEntries is 0)
  523. {
  524. Trace0(ERR,"GetIpForwardTable: MprAdminMIBEntryGet returned 0 interfaces");
  525. MprAdminMIBBufferFree((PVOID)pInfo);
  526. TraceLeave("GetIpForwardTable");
  527. return ERROR_NO_DATA;
  528. }
  529. if(*pdwSize < SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries))
  530. {
  531. Trace3(ERR,"GetIpForwardTable: After MIBQuery. In size %d. Required %d. With overflow %d",
  532. *pdwSize,
  533. SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries),
  534. SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries + ROUTE_OVERFLOW_COUNT));
  535. *pdwSize = SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries + ROUTE_OVERFLOW_COUNT);
  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, dwOutEntrySize;
  571. PMIB_TCPTABLE pTable;
  572. MIB_TCPSTATS mtStats;
  573. MIB_OPAQUE_QUERY mqQuery;
  574. PMIB_OPAQUE_INFO pInfo;
  575. TraceEnter("GetTcpTable");
  576. CheckTcpipState();
  577. if(!g_bIpConfigured)
  578. {
  579. Trace0(ERR, "GetTcpTable: No IP Stack on machine\n");
  580. TraceLeave("GetTcpTable");
  581. return ERROR_NOT_SUPPORTED;
  582. }
  583. if(pdwSize is NULL)
  584. {
  585. Trace0(ERR,"GetTcpTable: pdwSize is NULL");
  586. TraceLeave("GetTcpTable");
  587. return ERROR_INVALID_PARAMETER;
  588. }
  589. if (IsBadWritePtr(pdwSize, sizeof(ULONG))) {
  590. return ERROR_INVALID_PARAMETER;
  591. }
  592. if (IsBadWritePtr(pTcpTable, *pdwSize)) {
  593. return ERROR_INVALID_PARAMETER;
  594. }
  595. dwResult = GetTcpStatistics(&mtStats);
  596. if(dwResult isnot NO_ERROR)
  597. {
  598. Trace1(ERR,"GetTcpTable: GetTcpStatistics returned error %d",
  599. dwResult);
  600. TraceLeave("GetTcpTable");
  601. return dwResult;
  602. }
  603. if(mtStats.dwNumConns is 0)
  604. {
  605. Trace0(ERR,"GetTcpTable: No entries");
  606. TraceLeave("GetTcpTable");
  607. return ERROR_NO_DATA;
  608. }
  609. if( (*pdwSize < SIZEOF_TCPTABLE(mtStats.dwNumConns)) || (pTcpTable is NULL) )
  610. {
  611. Trace3(TRACE,"GetTcpTable: In size %d. Required %d. With overflow %d",
  612. *pdwSize,
  613. SIZEOF_TCPTABLE(mtStats.dwNumConns),
  614. SIZEOF_TCPTABLE(mtStats.dwNumConns + OVERFLOW_COUNT));
  615. *pdwSize = SIZEOF_TCPTABLE(mtStats.dwNumConns + OVERFLOW_COUNT);
  616. TraceLeave("GetTcpTable");
  617. return ERROR_INSUFFICIENT_BUFFER;
  618. }
  619. #ifndef CHICAGO
  620. if(IsRouterRunning())
  621. {
  622. mqQuery.dwVarId = TCP_TABLE;
  623. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  624. PID_IP,
  625. IPRTRMGR_PID,
  626. (PVOID)&mqQuery,
  627. sizeof(MIB_OPAQUE_QUERY),
  628. (PVOID)&pInfo,
  629. &dwOutEntrySize);
  630. if(dwResult isnot NO_ERROR)
  631. {
  632. Trace1(ERR,"GetTcpTable: MprAdminMIBEntryGet failed with error %x",
  633. dwResult);
  634. TraceLeave("GetTcpTable");
  635. return dwResult;
  636. }
  637. CAST_MIB_INFO(pInfo, PMIB_TCPTABLE, pTable);
  638. if(pTable->dwNumEntries is 0)
  639. {
  640. Trace0(ERR,"GetTcpTable: MprAdminMIBEntryGet returned 0 interfaces");
  641. MprAdminMIBBufferFree((PVOID)pInfo);
  642. TraceLeave("GetTcpTable");
  643. return ERROR_NO_DATA;
  644. }
  645. if(*pdwSize < SIZEOF_TCPTABLE(pTable->dwNumEntries))
  646. {
  647. Trace3(ERR,"GetTcpTable: After MIBQuery. In size %d. Required %d. With overflow %d",
  648. *pdwSize,
  649. SIZEOF_TCPTABLE(pTable->dwNumEntries),
  650. SIZEOF_TCPTABLE(pTable->dwNumEntries + OVERFLOW_COUNT));
  651. *pdwSize = SIZEOF_TCPTABLE(pTable->dwNumEntries + OVERFLOW_COUNT);
  652. TraceLeave("GetTcpTable");
  653. return ERROR_INSUFFICIENT_BUFFER;
  654. }
  655. *pdwSize = SIZEOF_TCPTABLE(pTable->dwNumEntries);
  656. CopyMemory((PVOID)(pTcpTable),
  657. (PVOID)pTable,
  658. SIZEOF_TCPTABLE(pTable->dwNumEntries));
  659. MprAdminMIBBufferFree((PVOID)pInfo);
  660. }
  661. else
  662. {
  663. #endif
  664. dwResult = GetTcpTableFromStack(pTcpTable,
  665. *pdwSize,
  666. bOrder);
  667. if(dwResult isnot NO_ERROR)
  668. {
  669. Trace1(ERR,"GetTcpTable: GetTcpTableFromStack failed with error %d",
  670. dwResult);
  671. }
  672. #ifndef CHICAGO
  673. }
  674. #endif
  675. TraceLeave("GetTcpTable");
  676. return dwResult;
  677. }
  678. DWORD
  679. WINAPI
  680. GetUdpTable(
  681. OUT PMIB_UDPTABLE pUdpTable,
  682. IN OUT PDWORD pdwSize,
  683. IN BOOL bOrder
  684. )
  685. {
  686. DWORD dwResult, dwOutEntrySize;
  687. PMIB_UDPTABLE pTable;
  688. MIB_UDPSTATS muStats;
  689. MIB_OPAQUE_QUERY mqQuery;
  690. PMIB_OPAQUE_INFO pInfo;
  691. TraceEnter("GetUdpTable");
  692. CheckTcpipState();
  693. if(!g_bIpConfigured)
  694. {
  695. Trace0(ERR, "GetUdpTable: No IP Stack on machine\n");
  696. TraceLeave("GetUdpTable");
  697. return ERROR_NOT_SUPPORTED;
  698. }
  699. if(pdwSize is NULL)
  700. {
  701. Trace0(ERR,"GetUdpTable: pdwSize is NULL");
  702. TraceLeave("GetUdpTable");
  703. return ERROR_INVALID_PARAMETER;
  704. }
  705. if (IsBadWritePtr(pdwSize, sizeof(ULONG))) {
  706. return ERROR_INVALID_PARAMETER;
  707. }
  708. if (IsBadWritePtr(pUdpTable, *pdwSize)) {
  709. return ERROR_INVALID_PARAMETER;
  710. }
  711. dwResult = GetUdpStatistics(&muStats);
  712. if(dwResult isnot NO_ERROR)
  713. {
  714. Trace1(ERR,"GetUdpTable: GetUdpStatistics returned error %d",
  715. dwResult);
  716. TraceLeave("GetUdpTable");
  717. return dwResult;
  718. }
  719. if(muStats.dwNumAddrs is 0)
  720. {
  721. Trace0(ERR,"GetUdpTable: No entries");
  722. TraceLeave("GetUdpTable");
  723. return ERROR_NO_DATA;
  724. }
  725. if( (*pdwSize < SIZEOF_UDPTABLE(muStats.dwNumAddrs)) || (pUdpTable is NULL) )
  726. {
  727. Trace3(TRACE,"GetUdpTable: In size %d. Required %d. With overflow %d",
  728. *pdwSize,
  729. SIZEOF_UDPTABLE(muStats.dwNumAddrs),
  730. SIZEOF_UDPTABLE(muStats.dwNumAddrs + OVERFLOW_COUNT));
  731. *pdwSize = SIZEOF_UDPTABLE(muStats.dwNumAddrs + OVERFLOW_COUNT);
  732. TraceLeave("GetUdpTable");
  733. return ERROR_INSUFFICIENT_BUFFER;
  734. }
  735. #ifndef CHICAGO
  736. if(IsRouterRunning())
  737. {
  738. mqQuery.dwVarId = UDP_TABLE;
  739. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  740. PID_IP,
  741. IPRTRMGR_PID,
  742. (PVOID)&mqQuery,
  743. sizeof(MIB_OPAQUE_QUERY),
  744. (PVOID)&pInfo,
  745. &dwOutEntrySize);
  746. if(dwResult isnot NO_ERROR)
  747. {
  748. Trace1(ERR,"GetUdpTable: MprAdminMIBEntryGet failed with error %x",
  749. dwResult);
  750. TraceLeave("GetUdpTable");
  751. return dwResult;
  752. }
  753. CAST_MIB_INFO(pInfo, PMIB_UDPTABLE, pTable);
  754. if(pTable->dwNumEntries is 0)
  755. {
  756. Trace0(ERR,"GetUdpTable: MprAdminMIBEntryGet returned 0 interfaces");
  757. MprAdminMIBBufferFree((PVOID)pInfo);
  758. TraceLeave("GetUdpTable");
  759. return ERROR_NO_DATA;
  760. }
  761. if(*pdwSize < SIZEOF_UDPTABLE(pTable->dwNumEntries))
  762. {
  763. Trace3(ERR,"GetUdpTable: After MIBQuery. In size %d. Required %d. With overflow %d",
  764. *pdwSize,
  765. SIZEOF_UDPTABLE(pTable->dwNumEntries),
  766. SIZEOF_UDPTABLE(pTable->dwNumEntries + OVERFLOW_COUNT));
  767. *pdwSize = SIZEOF_UDPTABLE(pTable->dwNumEntries + OVERFLOW_COUNT);
  768. TraceLeave("GetUdpTable");
  769. return ERROR_INSUFFICIENT_BUFFER;
  770. }
  771. *pdwSize = SIZEOF_UDPTABLE(pTable->dwNumEntries);
  772. CopyMemory((PVOID)(pUdpTable),
  773. (PVOID)pTable,
  774. SIZEOF_UDPTABLE(pTable->dwNumEntries));
  775. MprAdminMIBBufferFree((PVOID)pInfo);
  776. }
  777. else
  778. {
  779. #endif
  780. dwResult = GetUdpTableFromStack(pUdpTable,
  781. *pdwSize,
  782. bOrder);
  783. if(dwResult isnot NO_ERROR)
  784. {
  785. Trace1(ERR,"GetUdpTable: GetUdpTableFromStack failed with error %d",
  786. dwResult);
  787. }
  788. #ifndef CHICAGO
  789. }
  790. #endif
  791. TraceLeave("GetUdpTable");
  792. return dwResult;
  793. }
  794. DWORD
  795. WINAPI
  796. GetIpStatisticsEx(
  797. OUT PMIB_IPSTATS pStats,
  798. IN DWORD dwFamily
  799. )
  800. {
  801. DWORD dwResult, dwOutEntrySize;
  802. MIB_OPAQUE_QUERY mqQuery;
  803. PMIB_OPAQUE_INFO pInfo;
  804. PMIB_IPSTATS pIpStats;
  805. TraceEnter("GetIpStatisticsEx");
  806. if (pStats == NULL)
  807. {
  808. return ERROR_INVALID_PARAMETER;
  809. }
  810. if ((dwFamily != AF_INET) && (dwFamily != AF_INET6))
  811. {
  812. return ERROR_INVALID_PARAMETER;
  813. }
  814. if (IsBadWritePtr(pStats, sizeof(MIB_IPSTATS))) {
  815. return ERROR_INVALID_PARAMETER;
  816. }
  817. CheckTcpipState();
  818. if (((dwFamily == AF_INET) && !g_bIpConfigured) ||
  819. ((dwFamily == AF_INET6) && !g_bIp6Configured))
  820. {
  821. Trace0(ERR, "GetIpStatistics: No IP Stack on machine\n");
  822. TraceLeave("GetIpStatistics");
  823. return ERROR_NOT_SUPPORTED;
  824. }
  825. #ifndef CHICAGO
  826. if((dwFamily == AF_INET) && IsRouterRunning())
  827. {
  828. mqQuery.dwVarId = IP_STATS;
  829. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  830. PID_IP,
  831. IPRTRMGR_PID,
  832. (PVOID)&mqQuery,
  833. sizeof(MIB_OPAQUE_QUERY),
  834. (PVOID)&pInfo,
  835. &dwOutEntrySize);
  836. if(dwResult isnot NO_ERROR)
  837. {
  838. Trace1(ERR,"MprAdminMIBEntryGet failed with error %x",
  839. dwResult);
  840. TraceLeave("GetIpStats");
  841. return dwResult;
  842. }
  843. CAST_MIB_INFO(pInfo, PMIB_IPSTATS, pIpStats);
  844. *pStats = *pIpStats;
  845. MprAdminMIBBufferFree((PVOID)pInfo);
  846. }
  847. else
  848. {
  849. #endif
  850. dwResult = GetIpStatsFromStackEx(pStats, dwFamily);
  851. if(dwResult isnot NO_ERROR)
  852. {
  853. Trace1(ERR,"GetIpStatsFromStackEx failed with error %x",
  854. dwResult);
  855. }
  856. #ifndef CHICAGO
  857. }
  858. #endif
  859. TraceLeave("GetIpStatisticsEx");
  860. return dwResult;
  861. }
  862. DWORD
  863. WINAPI
  864. GetIpStatistics(
  865. OUT PMIB_IPSTATS pStats
  866. )
  867. {
  868. return GetIpStatisticsEx(pStats, AF_INET);
  869. }
  870. DWORD
  871. WINAPI
  872. GetIcmpStatistics(
  873. OUT PMIB_ICMP pStats
  874. )
  875. {
  876. DWORD dwResult, dwOutEntrySize;
  877. MIB_OPAQUE_QUERY mqQuery;
  878. PMIB_OPAQUE_INFO pInfo;
  879. PMIB_ICMP pIcmp;
  880. CheckTcpipState();
  881. if(!g_bIpConfigured)
  882. {
  883. Trace0(ERR, "GetIcmpStatistics: No IP Stack on machine\n");
  884. TraceLeave("GetIcmpStatistics");
  885. return ERROR_NOT_SUPPORTED;
  886. }
  887. if (pStats == NULL)
  888. {
  889. return ERROR_INVALID_PARAMETER;
  890. }
  891. if (IsBadWritePtr(pStats, sizeof(MIB_ICMP))) {
  892. return ERROR_INVALID_PARAMETER;
  893. }
  894. #ifndef CHICAGO
  895. if(IsRouterRunning())
  896. {
  897. mqQuery.dwVarId = ICMP_STATS;
  898. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  899. PID_IP,
  900. IPRTRMGR_PID,
  901. (PVOID)&mqQuery,
  902. sizeof(MIB_OPAQUE_QUERY),
  903. (PVOID)&pInfo,
  904. &dwOutEntrySize);
  905. if(dwResult isnot NO_ERROR)
  906. {
  907. Trace1(ERR,"MprAdminMIBEntryGet failed with error %x",
  908. dwResult);
  909. TraceLeave("GetIcmpStats");
  910. return dwResult;
  911. }
  912. CAST_MIB_INFO(pInfo, PMIB_ICMP, pIcmp);
  913. *pStats = *pIcmp;
  914. MprAdminMIBBufferFree((PVOID)pInfo);
  915. }
  916. else
  917. {
  918. #endif
  919. dwResult = GetIcmpStatsFromStack(pStats);
  920. if(dwResult isnot NO_ERROR)
  921. {
  922. Trace1(ERR,"GetIpStatsFromStack failed with error %x",
  923. dwResult);
  924. }
  925. #ifndef CHICAGO
  926. }
  927. #endif
  928. TraceLeave("GetIcmpStats");
  929. return NO_ERROR;
  930. }
  931. VOID
  932. MakeIcmpStatsEx(
  933. OUT PMIBICMPSTATS_EX pNewStats,
  934. IN PMIBICMPSTATS pOldStats
  935. )
  936. {
  937. pNewStats->dwMsgs = pOldStats->dwMsgs;
  938. pNewStats->dwErrors = pOldStats->dwErrors;
  939. ZeroMemory(pNewStats->rgdwTypeCount, sizeof(pNewStats->rgdwTypeCount));
  940. pNewStats->rgdwTypeCount[ICMP4_DST_UNREACH] = pOldStats->dwDestUnreachs;
  941. pNewStats->rgdwTypeCount[ICMP4_TIME_EXCEEDED] = pOldStats->dwTimeExcds;
  942. pNewStats->rgdwTypeCount[ICMP4_PARAM_PROB] = pOldStats->dwParmProbs;
  943. pNewStats->rgdwTypeCount[ICMP4_SOURCE_QUENCH] = pOldStats->dwSrcQuenchs;
  944. pNewStats->rgdwTypeCount[ICMP4_REDIRECT] = pOldStats->dwRedirects;
  945. pNewStats->rgdwTypeCount[ICMP4_ECHO_REQUEST] = pOldStats->dwEchos;
  946. pNewStats->rgdwTypeCount[ICMP4_ECHO_REPLY] = pOldStats->dwEchoReps;
  947. pNewStats->rgdwTypeCount[ICMP4_TIMESTAMP_REQUEST] = pOldStats->dwTimestamps;
  948. pNewStats->rgdwTypeCount[ICMP4_TIMESTAMP_REPLY] = pOldStats->dwTimestampReps;
  949. pNewStats->rgdwTypeCount[ICMP4_MASK_REQUEST] = pOldStats->dwAddrMasks;
  950. pNewStats->rgdwTypeCount[ICMP4_MASK_REPLY] = pOldStats->dwAddrMaskReps;
  951. }
  952. DWORD
  953. WINAPI
  954. GetIcmpStatisticsEx(
  955. OUT PMIB_ICMP_EX pStats,
  956. IN DWORD dwFamily
  957. )
  958. {
  959. DWORD dwResult, dwOutEntrySize;
  960. MIB_OPAQUE_QUERY mqQuery;
  961. PMIB_OPAQUE_INFO pInfo;
  962. PVOID pIcmp;
  963. TraceEnter("GetIcmpStatisticsEx");
  964. if (pStats == NULL)
  965. {
  966. return ERROR_INVALID_PARAMETER;
  967. }
  968. if ((dwFamily != AF_INET) && (dwFamily != AF_INET6))
  969. {
  970. return ERROR_INVALID_PARAMETER;
  971. }
  972. if (IsBadWritePtr(pStats, sizeof(MIB_ICMP_EX))) {
  973. return ERROR_INVALID_PARAMETER;
  974. }
  975. CheckTcpipState();
  976. if (((dwFamily == AF_INET) && !g_bIpConfigured) ||
  977. ((dwFamily == AF_INET6) && !g_bIp6Configured))
  978. {
  979. Trace0(ERR, "GetIcmpStatisticsEx: No IP Stack on machine\n");
  980. TraceLeave("GetIcmpStatisticsEx");
  981. return ERROR_NOT_SUPPORTED;
  982. }
  983. if (dwFamily == AF_INET)
  984. {
  985. //
  986. // The IPv4 stack doesn't yet support MIB_ICMP_EX, so we'll
  987. // get the MIB_ICMP structure and convert it.
  988. //
  989. MIB_ICMP OldStats;
  990. dwResult = GetIcmpStatistics(&OldStats);
  991. if(dwResult == NO_ERROR)
  992. {
  993. MakeIcmpStatsEx(&pStats->icmpInStats,
  994. &OldStats.stats.icmpInStats);
  995. MakeIcmpStatsEx(&pStats->icmpOutStats,
  996. &OldStats.stats.icmpOutStats);
  997. }
  998. }
  999. else
  1000. {
  1001. dwResult = GetIcmpStatsFromStackEx(pStats, dwFamily);
  1002. if(dwResult isnot NO_ERROR)
  1003. {
  1004. Trace1(ERR,"GetIpStatsFromStackEx failed with error %x",
  1005. dwResult);
  1006. }
  1007. }
  1008. TraceLeave("GetIcmpStatisticsEx");
  1009. return dwResult;
  1010. }
  1011. DWORD
  1012. WINAPI
  1013. GetTcpStatisticsEx(
  1014. OUT PMIB_TCPSTATS pStats,
  1015. IN DWORD dwFamily
  1016. )
  1017. {
  1018. DWORD dwResult, dwOutEntrySize;
  1019. MIB_OPAQUE_QUERY mqQuery;
  1020. PMIB_OPAQUE_INFO pInfo;
  1021. PMIB_TCPSTATS pTcpStats;
  1022. if ((dwFamily != AF_INET) && (dwFamily != AF_INET6))
  1023. {
  1024. return ERROR_INVALID_PARAMETER;
  1025. }
  1026. CheckTcpipState();
  1027. if (((dwFamily == AF_INET) && !g_bIpConfigured) ||
  1028. ((dwFamily == AF_INET6) && !g_bIp6Configured))
  1029. {
  1030. Trace0(ERR, "GetTcpStatistics: No IP Stack on machine\n");
  1031. TraceLeave("GetTcpStatistics");
  1032. return ERROR_NOT_SUPPORTED;
  1033. }
  1034. if(pStats == NULL)
  1035. {
  1036. return ERROR_INVALID_PARAMETER;
  1037. }
  1038. if (IsBadWritePtr(pStats, sizeof(MIB_TCPSTATS))) {
  1039. return ERROR_INVALID_PARAMETER;
  1040. }
  1041. #ifndef CHICAGO
  1042. if((dwFamily == AF_INET) && IsRouterRunning())
  1043. {
  1044. mqQuery.dwVarId = TCP_STATS;
  1045. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  1046. PID_IP,
  1047. IPRTRMGR_PID,
  1048. (PVOID)&mqQuery,
  1049. sizeof(MIB_OPAQUE_QUERY),
  1050. (PVOID)&pInfo,
  1051. &dwOutEntrySize);
  1052. if(dwResult isnot NO_ERROR)
  1053. {
  1054. Trace1(ERR,"MprAdminMIBEntryGet failed with error %x",
  1055. dwResult);
  1056. TraceLeave("GetTcpStats");
  1057. return dwResult;
  1058. }
  1059. CAST_MIB_INFO(pInfo, PMIB_TCPSTATS, pTcpStats);
  1060. *pStats = *pTcpStats;
  1061. MprAdminMIBBufferFree((PVOID)pInfo);
  1062. }
  1063. else
  1064. {
  1065. #endif
  1066. dwResult = GetTcpStatsFromStackEx(pStats, dwFamily);
  1067. if(dwResult isnot NO_ERROR)
  1068. {
  1069. Trace1(ERR,"GetTcpStatsFromStackEx failed with error %x",
  1070. dwResult);
  1071. }
  1072. #ifndef CHICAGO
  1073. }
  1074. #endif
  1075. TraceLeave("GetTcpStats");
  1076. return dwResult;
  1077. }
  1078. DWORD
  1079. WINAPI
  1080. GetTcpStatistics(
  1081. OUT PMIB_TCPSTATS pStats
  1082. )
  1083. {
  1084. return GetTcpStatisticsEx(pStats, AF_INET);
  1085. }
  1086. DWORD
  1087. WINAPI
  1088. GetUdpStatisticsEx(
  1089. OUT PMIB_UDPSTATS pStats,
  1090. IN DWORD dwFamily
  1091. )
  1092. {
  1093. DWORD dwResult,dwOutEntrySize;
  1094. PMIB_OPAQUE_INFO pInfo;
  1095. PMIB_UDPSTATS pUdpStats;
  1096. MIB_OPAQUE_QUERY mqQuery;
  1097. if ((dwFamily != AF_INET) && (dwFamily != AF_INET6))
  1098. {
  1099. return ERROR_INVALID_PARAMETER;
  1100. }
  1101. CheckTcpipState();
  1102. if (((dwFamily == AF_INET) && !g_bIpConfigured) ||
  1103. ((dwFamily == AF_INET6) && !g_bIp6Configured))
  1104. {
  1105. Trace0(ERR, "GetUdpStatistics: No IP Stack on machine\n");
  1106. TraceLeave("GetUdpStatistics");
  1107. return ERROR_NOT_SUPPORTED;
  1108. }
  1109. if(pStats == NULL)
  1110. {
  1111. return ERROR_INVALID_PARAMETER;
  1112. }
  1113. if (IsBadWritePtr(pStats, sizeof(MIB_UDPSTATS))) {
  1114. return ERROR_INVALID_PARAMETER;
  1115. }
  1116. #ifndef CHICAGO
  1117. if((dwFamily == AF_INET) && IsRouterRunning())
  1118. {
  1119. mqQuery.dwVarId = UDP_STATS;
  1120. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  1121. PID_IP,
  1122. IPRTRMGR_PID,
  1123. (PVOID)&mqQuery,
  1124. sizeof(MIB_OPAQUE_QUERY),
  1125. (PVOID)&pInfo,
  1126. &dwOutEntrySize);
  1127. if(dwResult isnot NO_ERROR)
  1128. {
  1129. Trace1(ERR,"MprAdminMIBEntryGet failed with error %x",
  1130. dwResult);
  1131. TraceLeave("GetUdpStats");
  1132. return dwResult;
  1133. }
  1134. CAST_MIB_INFO(pInfo, PMIB_UDPSTATS, pUdpStats);
  1135. *pStats = *pUdpStats;
  1136. MprAdminMIBBufferFree((PVOID)pInfo);
  1137. }
  1138. else
  1139. {
  1140. #endif
  1141. dwResult = GetUdpStatsFromStackEx(pStats, dwFamily);
  1142. if(dwResult isnot NO_ERROR)
  1143. {
  1144. Trace1(ERR,"GetUdpStatsFromStack failed with error %x",
  1145. dwResult);
  1146. }
  1147. #ifndef CHICAGO
  1148. }
  1149. #endif
  1150. TraceLeave("GetUdpStats");
  1151. return dwResult;
  1152. }
  1153. DWORD
  1154. WINAPI
  1155. GetUdpStatistics(
  1156. OUT PMIB_UDPSTATS pStats
  1157. )
  1158. {
  1159. return GetUdpStatisticsEx(pStats, AF_INET);
  1160. }
  1161. DWORD
  1162. GetIfEntry(
  1163. IN OUT PMIB_IFROW pIfEntry
  1164. )
  1165. {
  1166. if (!pIfEntry ||
  1167. IsBadWritePtr(pIfEntry, sizeof(MIB_IFROW)))
  1168. {
  1169. return ERROR_INVALID_PARAMETER;
  1170. }
  1171. CheckTcpipState();
  1172. if(!g_bIpConfigured)
  1173. {
  1174. return ERROR_NOT_SUPPORTED;
  1175. }
  1176. return GetIfEntryFromStack(pIfEntry,
  1177. pIfEntry->dwIndex,
  1178. TRUE);
  1179. }
  1180. DWORD
  1181. WINAPI
  1182. SetIfEntry(
  1183. IN PMIB_IFROW pIfRow
  1184. )
  1185. {
  1186. DWORD dwResult;
  1187. DEFINE_MIB_BUFFER(pInfo,MIB_IFROW, pSetRow);
  1188. TraceEnter("SetIfEntry");
  1189. if(pIfRow == NULL)
  1190. {
  1191. return ERROR_INVALID_PARAMETER;
  1192. }
  1193. if (IsBadReadPtr(pIfRow, sizeof(MIB_IFROW))) {
  1194. return ERROR_INVALID_PARAMETER;
  1195. }
  1196. CheckTcpipState();
  1197. if(!g_bIpConfigured)
  1198. {
  1199. Trace0(ERR, "SetIfEntry: No IP Stack on machine\n");
  1200. TraceLeave("SetIfEntry");
  1201. return ERROR_NOT_SUPPORTED;
  1202. }
  1203. if (!pInfo) {
  1204. Trace0(ERR, "SetIfEntry: If Entry NULL\n");
  1205. TraceLeave("SetIfEntry");
  1206. return ERROR_INVALID_DATA;
  1207. }
  1208. pInfo->dwId = IF_ROW;
  1209. *pSetRow = *pIfRow;
  1210. dwResult = InternalSetIfEntry(pInfo);
  1211. if(dwResult isnot NO_ERROR)
  1212. {
  1213. Trace1(ERR,
  1214. "SetIfEntry: InternalSetIfEntry returned %d",
  1215. dwResult);
  1216. }
  1217. TraceLeave("SetIfEntry");
  1218. return dwResult;
  1219. }
  1220. DWORD
  1221. WINAPI
  1222. CreateIpForwardEntry(
  1223. IN PMIB_IPFORWARDROW pRoute
  1224. )
  1225. {
  1226. DWORD dwResult;
  1227. DEFINE_MIB_BUFFER(pCreateInfo,MIB_IPFORWARDROW,pCreateRow);
  1228. TraceEnter("CreateIpForwardEntry");
  1229. CheckTcpipState();
  1230. if(!g_bIpConfigured)
  1231. {
  1232. Trace0(ERR, "CreateIpForwardEntry: No IP Stack on machine\n");
  1233. TraceLeave("CreateIpForwardEntry");
  1234. return ERROR_NOT_SUPPORTED;
  1235. }
  1236. if(pRoute == NULL)
  1237. {
  1238. return(ERROR_INVALID_PARAMETER);
  1239. }
  1240. if (IsBadReadPtr(pRoute, sizeof(MIB_IPFORWARDROW))) {
  1241. return ERROR_INVALID_PARAMETER;
  1242. }
  1243. pCreateInfo->dwId = IP_FORWARDROW;
  1244. *pCreateRow = *pRoute;
  1245. dwResult = InternalCreateIpForwardEntry(pCreateInfo);
  1246. if(dwResult isnot NO_ERROR)
  1247. {
  1248. Trace1(ERR,
  1249. "CreateIpForwardEntry: InternalCreateIpForwardEntry returned %d",
  1250. dwResult);
  1251. }
  1252. if (dwResult == STATUS_INVALID_PARAMETER) {
  1253. return(ERROR_INVALID_PARAMETER);
  1254. }
  1255. TraceLeave("CreateIpForwardEntry");
  1256. return dwResult;
  1257. }
  1258. DWORD
  1259. WINAPI
  1260. SetIpForwardEntry(
  1261. IN PMIB_IPFORWARDROW pRoute
  1262. )
  1263. {
  1264. DWORD dwResult;
  1265. DEFINE_MIB_BUFFER(pSetInfo,MIB_IPFORWARDROW,pSetRow);
  1266. TraceEnter("SetIpForwardEntry");
  1267. CheckTcpipState();
  1268. if(!g_bIpConfigured)
  1269. {
  1270. Trace0(ERR, "SetIpForwardEntry: No IP Stack on machine\n");
  1271. TraceLeave("SetIpForwardEntry");
  1272. return ERROR_NOT_SUPPORTED;
  1273. }
  1274. if(pRoute == NULL)
  1275. {
  1276. return(ERROR_INVALID_PARAMETER);
  1277. }
  1278. if (IsBadReadPtr(pRoute, sizeof(MIB_IPFORWARDROW))) {
  1279. return ERROR_INVALID_PARAMETER;
  1280. }
  1281. pSetInfo->dwId = IP_FORWARDROW;
  1282. *pSetRow = *pRoute;
  1283. dwResult = InternalSetIpForwardEntry(pSetInfo);
  1284. if(dwResult isnot NO_ERROR)
  1285. {
  1286. Trace1(ERR,
  1287. "SetIpForwardEntry: InternalSetIpForwardEntry returned %d",
  1288. dwResult);
  1289. }
  1290. if (dwResult == STATUS_INVALID_PARAMETER) {
  1291. return(ERROR_INVALID_PARAMETER);
  1292. }
  1293. TraceLeave("SetIpForwardEntry");
  1294. return dwResult;
  1295. }
  1296. DWORD
  1297. WINAPI
  1298. DeleteIpForwardEntry(
  1299. IN PMIB_IPFORWARDROW pRoute
  1300. )
  1301. {
  1302. DWORD dwResult;
  1303. DEFINE_MIB_BUFFER(pDeleteInfo,MIB_IPFORWARDROW,pDeleteRow);
  1304. TraceEnter("DeleteIpForwardEntry");
  1305. CheckTcpipState();
  1306. if(!g_bIpConfigured)
  1307. {
  1308. Trace0(ERR, "DeleteIpForwardEntry: No IP Stack on machine\n");
  1309. TraceLeave("DeleteIpForwardEntry");
  1310. return ERROR_NOT_SUPPORTED;
  1311. }
  1312. if(pRoute == NULL)
  1313. {
  1314. return(ERROR_INVALID_PARAMETER);
  1315. }
  1316. if (IsBadReadPtr(pRoute, sizeof(MIB_IPFORWARDROW))) {
  1317. return ERROR_INVALID_PARAMETER;
  1318. }
  1319. pDeleteInfo->dwId = IP_FORWARDROW;
  1320. *pDeleteRow = *pRoute;
  1321. dwResult = InternalDeleteIpForwardEntry(pDeleteInfo);
  1322. if(dwResult isnot NO_ERROR)
  1323. {
  1324. Trace1(ERR,
  1325. "DeleteIpForwardEntry: InternalDeleteIpForwardEntry returned %d",
  1326. dwResult);
  1327. }
  1328. if (dwResult == STATUS_INVALID_PARAMETER) {
  1329. return(ERROR_NOT_FOUND);
  1330. }
  1331. TraceLeave("DeleteIpForwardEntry");
  1332. return dwResult;
  1333. }
  1334. DWORD
  1335. WINAPI
  1336. SetIpTTL(
  1337. UINT nTTL
  1338. )
  1339. {
  1340. MIB_IPSTATS Stats;
  1341. DWORD dwResult;
  1342. TraceEnter("SetIpTTL");
  1343. CheckTcpipState();
  1344. if(!g_bIpConfigured)
  1345. {
  1346. Trace0(ERR, "SetIpTTL: No IP Stack on machine\n");
  1347. TraceLeave("SetIpTTL");
  1348. return ERROR_NOT_SUPPORTED;
  1349. }
  1350. dwResult = GetIpStatistics( &Stats );
  1351. if(dwResult isnot NO_ERROR)
  1352. {
  1353. Trace1(ERR,"SetIpTll: GetIpStatistics failed with error %x",
  1354. dwResult);
  1355. TraceLeave("SetIpTTL");
  1356. return dwResult;
  1357. }
  1358. Stats.dwForwarding = MIB_USE_CURRENT_FORWARDING;
  1359. Stats.dwDefaultTTL = nTTL;
  1360. dwResult = SetIpStatistics( &Stats );
  1361. if(dwResult isnot NO_ERROR)
  1362. {
  1363. Trace1(ERR,"SetIpTll: GetIpStatistics failed with error %x",
  1364. dwResult);
  1365. }
  1366. TraceLeave("SetIpTTL");
  1367. return dwResult;
  1368. }
  1369. DWORD
  1370. WINAPI
  1371. SetIpStatistics(
  1372. IN PMIB_IPSTATS pIpStats
  1373. )
  1374. {
  1375. DWORD dwResult;
  1376. DEFINE_MIB_BUFFER(pSetInfo,MIB_IPSTATS,pSetStats);
  1377. TraceEnter("SetIpStatistics");
  1378. CheckTcpipState();
  1379. if(!g_bIpConfigured)
  1380. {
  1381. Trace0(ERR, "SetIpStatistics: No IP Stack on machine\n");
  1382. TraceLeave("SetIpStatistics");
  1383. return ERROR_NOT_SUPPORTED;
  1384. }
  1385. if(pIpStats == NULL)
  1386. {
  1387. return(ERROR_INVALID_PARAMETER);
  1388. }
  1389. if (IsBadReadPtr(pIpStats, sizeof(MIB_IPSTATS))) {
  1390. return ERROR_INVALID_PARAMETER;
  1391. }
  1392. pSetInfo->dwId = IP_STATS;
  1393. *pSetStats = *pIpStats;
  1394. dwResult = InternalSetIpStats(pSetInfo);
  1395. if(dwResult isnot NO_ERROR)
  1396. {
  1397. Trace1(ERR,
  1398. "SetIpStatistics: InternalSetIpStats returned %d",
  1399. dwResult);
  1400. }
  1401. TraceLeave("SetIpStatistics");
  1402. return dwResult;
  1403. }
  1404. DWORD
  1405. WINAPI
  1406. CreateIpNetEntry(
  1407. IN PMIB_IPNETROW pArpEntry
  1408. )
  1409. {
  1410. DWORD dwResult;
  1411. DEFINE_MIB_BUFFER(pCreateInfo,MIB_IPNETROW,pCreateRow);
  1412. TraceEnter("CreateIpNetEntry");
  1413. CheckTcpipState();
  1414. if(!g_bIpConfigured)
  1415. {
  1416. Trace0(ERR, "CreateIpNetEntry: No IP Stack on machine\n");
  1417. TraceLeave("CreateIpNetEntry");
  1418. return ERROR_NOT_SUPPORTED;
  1419. }
  1420. if(!pArpEntry)
  1421. {
  1422. return ERROR_INVALID_PARAMETER;
  1423. }
  1424. pCreateInfo->dwId = IP_NETROW;
  1425. *pCreateRow = *pArpEntry;
  1426. if((pArpEntry->dwPhysAddrLen is 0) or
  1427. (pArpEntry->dwPhysAddrLen > MAXLEN_PHYSADDR))
  1428. {
  1429. return ERROR_INVALID_PARAMETER;
  1430. }
  1431. if(((pArpEntry->dwAddr & 0x000000FF) is 0x0000007F) or
  1432. ((DWORD)(pArpEntry->dwAddr & 0x000000FF) >= (DWORD) 0x000000E0))
  1433. {
  1434. return ERROR_INVALID_PARAMETER;
  1435. }
  1436. dwResult = InternalCreateIpNetEntry(pCreateInfo);
  1437. if(dwResult isnot NO_ERROR)
  1438. {
  1439. Trace1(ERR,
  1440. "CreateIpNetEntry: InternalCreateIpNetEntry returned %d",
  1441. dwResult);
  1442. }
  1443. TraceLeave("CreateIpNetEntry");
  1444. return dwResult;
  1445. }
  1446. DWORD
  1447. WINAPI
  1448. SetIpNetEntry(
  1449. IN PMIB_IPNETROW pArpEntry
  1450. )
  1451. {
  1452. DWORD dwResult;
  1453. DEFINE_MIB_BUFFER(pSetInfo,MIB_IPNETROW,pSetRow);
  1454. TraceEnter("SetIpNetEntry");
  1455. CheckTcpipState();
  1456. if(!g_bIpConfigured)
  1457. {
  1458. Trace0(ERR, "SetIpNetEntry: No IP Stack on machine\n");
  1459. TraceLeave("SetIpNetEntry");
  1460. return ERROR_NOT_SUPPORTED;
  1461. }
  1462. if (!pArpEntry)
  1463. {
  1464. return ERROR_INVALID_PARAMETER;
  1465. }
  1466. if (IsBadReadPtr(pArpEntry, sizeof(MIB_IPNETROW))) {
  1467. return ERROR_INVALID_PARAMETER;
  1468. }
  1469. pSetInfo->dwId = IP_NETROW;
  1470. *pSetRow = *pArpEntry;
  1471. dwResult = InternalSetIpNetEntry(pSetInfo);
  1472. if(dwResult isnot NO_ERROR)
  1473. {
  1474. Trace1(ERR,
  1475. "SetIpNetEntry: InternalSetIpNetEntry returned %d",
  1476. dwResult);
  1477. }
  1478. TraceLeave("SetIpNetEntry");
  1479. return dwResult;
  1480. }
  1481. DWORD
  1482. WINAPI
  1483. DeleteIpNetEntry(
  1484. IN PMIB_IPNETROW pArpEntry
  1485. )
  1486. {
  1487. DWORD dwResult;
  1488. DEFINE_MIB_BUFFER(pDeleteInfo,MIB_IPNETROW,pDeleteRow);
  1489. TraceEnter("DeleteIpNetEntry");
  1490. CheckTcpipState();
  1491. if(!g_bIpConfigured)
  1492. {
  1493. Trace0(ERR, "DeleteIpNetEntry: No IP Stack on machine\n");
  1494. TraceLeave("DeleteIpNetEntry");
  1495. return ERROR_NOT_SUPPORTED;
  1496. }
  1497. if(pArpEntry == NULL)
  1498. {
  1499. return(ERROR_INVALID_PARAMETER);
  1500. }
  1501. if (IsBadReadPtr(pArpEntry, sizeof(MIB_IPNETROW))) {
  1502. return ERROR_INVALID_PARAMETER;
  1503. }
  1504. pDeleteInfo->dwId = IP_NETROW;
  1505. *pDeleteRow = *pArpEntry;
  1506. dwResult = InternalDeleteIpNetEntry(pDeleteInfo);
  1507. if(dwResult isnot NO_ERROR)
  1508. {
  1509. Trace1(ERR,
  1510. "DeleteIpNetEntry: InternalDeleteIpNetEntry returned %d",
  1511. dwResult);
  1512. }
  1513. TraceLeave("DeleteIpNetEntry");
  1514. return dwResult;
  1515. }
  1516. DWORD
  1517. WINAPI
  1518. FlushIpNetTable(
  1519. IN DWORD dwIfIndex
  1520. )
  1521. {
  1522. DWORD dwResult;
  1523. DEFINE_MIB_BUFFER(pDeleteInfo,MIB_IPNETROW,pDeleteRow);
  1524. TraceEnter("FlushIpNetTable");
  1525. CheckTcpipState();
  1526. if(!g_bIpConfigured)
  1527. {
  1528. Trace0(ERR, "FlushIpNetTable: No IP Stack on machine\n");
  1529. TraceLeave("FlushIpNetTable");
  1530. return ERROR_NOT_SUPPORTED;
  1531. }
  1532. if(dwIfIndex == 0)
  1533. {
  1534. return(ERROR_INVALID_PARAMETER);
  1535. }
  1536. #ifndef CHICAGO
  1537. if(IsRouterRunning())
  1538. {
  1539. MIB_OPAQUE_QUERY Query;
  1540. Query.dwVarId = IP_NETTABLE;
  1541. Query.rgdwVarIndex[0] = dwIfIndex;
  1542. dwResult = MprAdminMIBEntryDelete(g_hMIBServer,
  1543. PID_IP,
  1544. IPRTRMGR_PID,
  1545. &Query,
  1546. sizeof(Query));
  1547. if(dwResult isnot NO_ERROR)
  1548. {
  1549. Trace1(ERR,"MprAdminMIBEntryDelete failed with error %x",
  1550. dwResult);
  1551. TraceLeave("FlushIpNetTable");
  1552. return dwResult;
  1553. }
  1554. }
  1555. else
  1556. {
  1557. #endif
  1558. dwResult = FlushIpNetTableFromStack(dwIfIndex);
  1559. if(dwResult isnot NO_ERROR)
  1560. {
  1561. Trace1(ERR,"FlushIpNetTableFromStack failed with error %d",
  1562. dwResult);
  1563. TraceLeave("FlushIpNetTable");
  1564. return dwResult;
  1565. }
  1566. #ifndef CHICAGO
  1567. }
  1568. #endif
  1569. TraceLeave("FlushIpNetTable");
  1570. return dwResult;
  1571. }
  1572. DWORD
  1573. WINAPI
  1574. SetTcpEntry(
  1575. IN PMIB_TCPROW pTcpRow
  1576. )
  1577. {
  1578. DWORD dwResult;
  1579. DEFINE_MIB_BUFFER(pSetInfo,MIB_TCPROW,pSetRow);
  1580. TraceEnter("SetTcpEntry");
  1581. if(!pTcpRow)
  1582. {
  1583. return ERROR_INVALID_PARAMETER;
  1584. }
  1585. CheckTcpipState();
  1586. if(!g_bIpConfigured)
  1587. {
  1588. Trace0(ERR, "SetTcpEntry: No IP Stack on machine\n");
  1589. TraceLeave("SetTcpEntry");
  1590. return ERROR_NOT_SUPPORTED;
  1591. }
  1592. if (IsBadReadPtr(pTcpRow, sizeof(MIB_TCPROW))) {
  1593. return ERROR_INVALID_PARAMETER;
  1594. }
  1595. pSetInfo->dwId = TCP_ROW;
  1596. *pSetRow = *pTcpRow;
  1597. dwResult = InternalSetTcpEntry(pSetInfo);
  1598. if(dwResult isnot NO_ERROR)
  1599. {
  1600. Trace1(ERR,
  1601. "SetTcpEntry: InternalSetTcpEntry returned %d",
  1602. dwResult);
  1603. }
  1604. TraceLeave("SetTcpEntry");
  1605. return dwResult;
  1606. }
  1607. DWORD
  1608. WINAPI
  1609. GetBestInterface(
  1610. IN IPAddr dwDestAddr,
  1611. OUT PDWORD pdwBestIfIndex
  1612. )
  1613. {
  1614. DWORD dwResult, dwOutEntrySize;
  1615. MIB_OPAQUE_QUERY mqQuery;
  1616. PMIB_OPAQUE_INFO pInfo;
  1617. PMIB_BEST_IF pBestIf;
  1618. TraceEnter("GetBestInterface");
  1619. if(pdwBestIfIndex is NULL)
  1620. {
  1621. return ERROR_INVALID_PARAMETER;
  1622. }
  1623. if (IsBadWritePtr(pdwBestIfIndex, sizeof(DWORD))) {
  1624. return ERROR_INVALID_PARAMETER;
  1625. }
  1626. CheckTcpipState();
  1627. if(!g_bIpConfigured)
  1628. {
  1629. Trace0(ERR, "GetBestInterface: No IP Stack on machine\n");
  1630. TraceLeave("GetBestInterface");
  1631. return ERROR_NOT_SUPPORTED;
  1632. }
  1633. #ifndef CHICAGO
  1634. if(IsRouterRunning())
  1635. {
  1636. mqQuery.dwVarId = BEST_IF;
  1637. mqQuery.rgdwVarIndex[0] = dwDestAddr;
  1638. dwResult = MprAdminMIBEntryGet(g_hMIBServer,
  1639. PID_IP,
  1640. IPRTRMGR_PID,
  1641. (PVOID)&mqQuery,
  1642. sizeof(MIB_OPAQUE_QUERY),
  1643. (PVOID)&pInfo,
  1644. &dwOutEntrySize);
  1645. if(dwResult isnot NO_ERROR)
  1646. {
  1647. Trace1(ERR,"GetIfTable: MprAdminMIBEntryGet failed with error %x",
  1648. dwResult);
  1649. TraceLeave("GetIfTable");
  1650. return dwResult;
  1651. }
  1652. CAST_MIB_INFO(pInfo, PMIB_BEST_IF, pBestIf);
  1653. if(dwDestAddr is pBestIf->dwDestAddr)
  1654. {
  1655. *pdwBestIfIndex = pBestIf->dwIfIndex;
  1656. }
  1657. else
  1658. {
  1659. dwResult = ERROR_CAN_NOT_COMPLETE;
  1660. }
  1661. MprAdminMIBBufferFree((PVOID)pInfo);
  1662. }
  1663. else
  1664. {
  1665. #endif
  1666. dwResult = GetBestInterfaceFromStack(dwDestAddr,
  1667. pdwBestIfIndex);
  1668. if(dwResult is STATUS_SUCCESS)
  1669. {
  1670. dwResult = NO_ERROR;
  1671. }
  1672. else
  1673. {
  1674. dwResult = ERROR_CAN_NOT_COMPLETE;
  1675. }
  1676. #ifndef CHICAGO
  1677. }
  1678. #endif
  1679. return dwResult;
  1680. }
  1681. DWORD
  1682. WINAPI
  1683. GetBestInterfaceEx(
  1684. IN LPSOCKADDR pSockAddr,
  1685. OUT PDWORD pdwBestIfIndex
  1686. )
  1687. {
  1688. DWORD dwResult;
  1689. LPSOCKADDR_IN6 pSin6;
  1690. IPAddr dwDestAddr;
  1691. if (IsBadReadPtr(pSockAddr, sizeof(SOCKADDR))) {
  1692. return ERROR_INVALID_PARAMETER;
  1693. }
  1694. if (pSockAddr->sa_family == AF_INET) {
  1695. return GetBestInterface(((LPSOCKADDR_IN)pSockAddr)->sin_addr.s_addr, pdwBestIfIndex);
  1696. }
  1697. if (pSockAddr->sa_family != AF_INET6) {
  1698. return ERROR_INVALID_PARAMETER;
  1699. }
  1700. if (IsBadReadPtr(pSockAddr, sizeof(SOCKADDR_IN6))) {
  1701. return ERROR_INVALID_PARAMETER;
  1702. }
  1703. pSin6 = (LPSOCKADDR_IN6)pSockAddr;
  1704. if (IN6_IS_ADDR_V4MAPPED(&pSin6->sin6_addr)) {
  1705. CopyMemory(&dwDestAddr,
  1706. &pSin6->sin6_addr.s6_words[6],
  1707. sizeof(dwDestAddr));
  1708. return GetBestInterface(dwDestAddr, pdwBestIfIndex);
  1709. }
  1710. if (pdwBestIfIndex is NULL) {
  1711. return ERROR_INVALID_PARAMETER;
  1712. }
  1713. if (IsBadWritePtr(pdwBestIfIndex, sizeof(DWORD))) {
  1714. return ERROR_INVALID_PARAMETER;
  1715. }
  1716. CheckTcpipState();
  1717. if (!g_bIp6Configured) {
  1718. Trace0(ERR, "GetBestInterface: No IPv6 Stack on machine\n");
  1719. return ERROR_NOT_SUPPORTED;
  1720. }
  1721. dwResult = GetBestInterfaceFromIpv6Stack(pSin6, pdwBestIfIndex);
  1722. return dwResult;
  1723. }
  1724. DWORD
  1725. WINAPI
  1726. GetBestRoute(
  1727. IN DWORD dwDestAddr,
  1728. IN DWORD dwSourceAddr, OPTIONAL
  1729. OUT PMIB_IPFORWARDROW pBestRoute
  1730. )
  1731. {
  1732. DWORD dwResult, dwOutEntrySize, dwQuerySize;
  1733. TraceEnter("GetBestRoute");
  1734. CheckTcpipState();
  1735. if(!g_bIpConfigured)
  1736. {
  1737. Trace0(ERR, "GetBestInterface: No IP Stack on machine\n");
  1738. TraceLeave("GetBestInterface");
  1739. return ERROR_NOT_SUPPORTED;
  1740. }
  1741. if(pBestRoute is NULL)
  1742. {
  1743. return ERROR_INVALID_PARAMETER;
  1744. }
  1745. if (IsBadWritePtr(pBestRoute, sizeof(MIB_IPFORWARDROW))) {
  1746. return ERROR_INVALID_PARAMETER;
  1747. }
  1748. dwResult = GetBestRouteFromStack(dwDestAddr,
  1749. dwSourceAddr,
  1750. pBestRoute);
  1751. if(dwResult is STATUS_SUCCESS)
  1752. {
  1753. dwResult = NO_ERROR;
  1754. }
  1755. else
  1756. {
  1757. dwResult = ERROR_CAN_NOT_COMPLETE;
  1758. }
  1759. return dwResult;
  1760. }
  1761. DWORD
  1762. WINAPI
  1763. CreateProxyArpEntry(
  1764. IN DWORD dwAddress,
  1765. IN DWORD dwMask,
  1766. IN DWORD dwIfIndex
  1767. )
  1768. {
  1769. DWORD dwResult, dwClassMask;
  1770. DEFINE_MIB_BUFFER(pSetInfo,MIB_PROXYARP,pParpRow);
  1771. TraceEnter("CreateProxyArpEntry");
  1772. #ifdef CHICAGO
  1773. TraceLeave("CreateProxyArpEntry");
  1774. return ERROR_NOT_SUPPORTED;
  1775. #else
  1776. CheckTcpipState();
  1777. if(!g_bIpConfigured)
  1778. {
  1779. Trace0(ERR, "CreateProxyArpEntry: No IP Stack on machine\n");
  1780. TraceLeave("CreateProxyArpEntry");
  1781. return ERROR_NOT_SUPPORTED;
  1782. }
  1783. dwClassMask = GetClassMask(dwAddress);
  1784. //
  1785. // Address & Mask should == Address
  1786. // Address should not be in the loopback range
  1787. // Address should not be all 0's
  1788. // Address should not be < ClassD
  1789. // Address should not be the all subnets broadcast
  1790. //
  1791. if(((dwAddress & 0x000000FF) is 0x0000007F) or
  1792. (dwAddress is 0x00000000) or
  1793. ((DWORD)(dwAddress & 0x000000FF) >= (DWORD) 0x000000E0) or
  1794. ((dwAddress & dwMask) isnot dwAddress) or
  1795. (dwAddress is (dwAddress | ~dwClassMask)))
  1796. {
  1797. TraceLeave("CreateProxyArpEntry");
  1798. return ERROR_INVALID_PARAMETER;
  1799. }
  1800. if(IsRouterRunning())
  1801. {
  1802. pSetInfo->dwId = PROXY_ARP;
  1803. pParpRow->dwAddress = dwAddress;
  1804. pParpRow->dwMask = dwMask;
  1805. pParpRow->dwIfIndex = dwIfIndex;
  1806. dwResult = MprAdminMIBEntrySet(g_hMIBServer,
  1807. PID_IP,
  1808. IPRTRMGR_PID,
  1809. (PVOID)pSetInfo,
  1810. MIB_INFO_SIZE(MIB_PROXYARP));
  1811. if(dwResult isnot NO_ERROR)
  1812. {
  1813. Trace1(ERR,
  1814. "MprAdminMIBEntrySet failed with error %x",
  1815. dwResult);
  1816. TraceLeave("CreateProxyArpEntry");
  1817. return dwResult;
  1818. }
  1819. }
  1820. else
  1821. {
  1822. dwResult = SetProxyArpEntryToStack(dwAddress,
  1823. dwMask,
  1824. dwIfIndex,
  1825. TRUE,
  1826. FALSE);
  1827. if(dwResult isnot NO_ERROR)
  1828. {
  1829. Trace1(ERR,
  1830. "SetProxyArpEntryToStack failed with error %d",
  1831. dwResult);
  1832. TraceLeave("CreateProxyArpEntry");
  1833. return dwResult;
  1834. }
  1835. }
  1836. TraceLeave("CreateProxyArpEntry");
  1837. return NO_ERROR;
  1838. #endif
  1839. }
  1840. DWORD
  1841. WINAPI
  1842. DeleteProxyArpEntry(
  1843. IN DWORD dwAddress,
  1844. IN DWORD dwMask,
  1845. IN DWORD dwIfIndex
  1846. )
  1847. {
  1848. DWORD dwResult, dwClassMask;
  1849. PMIB_OPAQUE_QUERY pmqQuery;
  1850. #define QUERY_SIZE sizeof(MIB_OPAQUE_QUERY) + 2 * sizeof(DWORD)
  1851. BYTE rgbyBuffer[QUERY_SIZE];
  1852. #undef QUERY_SIZE
  1853. TraceEnter("DeleteProxyArpEntry");
  1854. #ifdef CHICAGO
  1855. TraceLeave("DeleteProxyArpEntry");
  1856. return ERROR_NOT_SUPPORTED;
  1857. #else
  1858. CheckTcpipState();
  1859. if(!g_bIpConfigured)
  1860. {
  1861. Trace0(ERR,
  1862. "DeleteProxyArpEntry: No IP Stack on machine\n");
  1863. TraceLeave("DeleteProxyArpEntry");
  1864. return ERROR_NOT_SUPPORTED;
  1865. }
  1866. dwClassMask = GetClassMask(dwAddress);
  1867. if(((dwAddress & 0x000000FF) is 0x0000007F) or
  1868. (dwAddress is 0x00000000) or
  1869. ((DWORD)(dwAddress & 0x000000FF) >= (DWORD) 0x000000E0) or
  1870. ((dwAddress & dwMask) isnot dwAddress) or
  1871. (dwAddress is (dwAddress | ~dwClassMask)))
  1872. {
  1873. TraceLeave("DeleteProxyArpEntry");
  1874. return ERROR_INVALID_PARAMETER;
  1875. }
  1876. if(IsRouterRunning())
  1877. {
  1878. pmqQuery = (PMIB_OPAQUE_QUERY)rgbyBuffer;
  1879. pmqQuery->dwVarId = PROXY_ARP;
  1880. pmqQuery->rgdwVarIndex[0] = dwAddress;
  1881. pmqQuery->rgdwVarIndex[1] = dwMask;
  1882. pmqQuery->rgdwVarIndex[2] = dwIfIndex;
  1883. dwResult = MprAdminMIBEntryDelete(g_hMIBServer,
  1884. PID_IP,
  1885. IPRTRMGR_PID,
  1886. (PVOID)pmqQuery,
  1887. sizeof(rgbyBuffer));
  1888. if(dwResult isnot NO_ERROR)
  1889. {
  1890. Trace1(ERR,
  1891. "MprAdminMIBEntryDelete failed with error %x",
  1892. dwResult);
  1893. TraceLeave("DeleteProxyArpEntry");
  1894. return dwResult;
  1895. }
  1896. }
  1897. else
  1898. {
  1899. dwResult = SetProxyArpEntryToStack(dwAddress,
  1900. dwMask,
  1901. dwIfIndex,
  1902. FALSE,
  1903. FALSE);
  1904. if(dwResult isnot NO_ERROR)
  1905. {
  1906. Trace1(ERR,
  1907. "SetProxyArpEntryToStack failed with error %x",
  1908. dwResult);
  1909. TraceLeave("DeleteProxyArpEntry");
  1910. return dwResult;
  1911. }
  1912. }
  1913. TraceLeave("DeleteProxyArpEntry");
  1914. return NO_ERROR;
  1915. #endif
  1916. }
  1917. DWORD
  1918. WINAPI
  1919. GetFriendlyIfIndex(
  1920. DWORD IfIndex
  1921. )
  1922. {
  1923. return (0x00FFFFFF & IfIndex);
  1924. }
  1925. PWCHAR
  1926. NhGetInterfaceTypeString(
  1927. IN DWORD dwIfType
  1928. )
  1929. {
  1930. PWCHAR pwszOut;
  1931. if((dwIfType < MIN_IF_TYPE) or
  1932. (dwIfType > MAX_IF_TYPE))
  1933. {
  1934. return NULL;
  1935. }
  1936. pwszOut = HeapAlloc(g_hPrivateHeap,
  1937. 0,
  1938. MAX_IF_TYPE_LENGTH * sizeof(WCHAR));
  1939. if(pwszOut is NULL)
  1940. {
  1941. return NULL;
  1942. }
  1943. if(!LoadStringW(g_hModule,
  1944. dwIfType,
  1945. pwszOut,
  1946. MAX_IF_TYPE_LENGTH))
  1947. {
  1948. HeapFree(g_hPrivateHeap,
  1949. 0,
  1950. pwszOut);
  1951. return NULL;
  1952. }
  1953. return pwszOut;
  1954. }
  1955. VOID
  1956. NhFreeString(
  1957. IN PWCHAR pwszString
  1958. )
  1959. {
  1960. HeapFree(g_hPrivateHeap,
  1961. 0,
  1962. pwszString);
  1963. }
  1964. VOID
  1965. CheckTcpipState()
  1966. {
  1967. // Check whether tcpip was configured
  1968. // if not, check whether tcpip is configured now
  1969. EnterCriticalSection(&g_stateLock);
  1970. if (!g_bIpConfigured) {
  1971. if(OpenTCPDriver(AF_INET) == NO_ERROR) {
  1972. g_bIpConfigured = TRUE;
  1973. if(UpdateAdapterToIFInstanceMapping() != NO_ERROR) {
  1974. g_bIpConfigured = FALSE;
  1975. CloseTCPDriver();
  1976. } else {
  1977. if(UpdateAdapterToATInstanceMapping() != NO_ERROR) {
  1978. g_bIpConfigured = FALSE;
  1979. CloseTCPDriver();
  1980. } else {
  1981. g_bIpConfigured = TRUE;
  1982. }
  1983. }
  1984. } else {
  1985. g_bIpConfigured = FALSE;
  1986. }
  1987. if (g_bIpConfigured) {
  1988. if (IpcfgdllInit(NULL, DLL_PROCESS_ATTACH, NULL) == FALSE) {
  1989. g_bIpConfigured = FALSE;
  1990. CloseTCPDriver();
  1991. }
  1992. }
  1993. }
  1994. if (!g_bIp6Configured) {
  1995. if(OpenTCPDriver(AF_INET6) == NO_ERROR) {
  1996. g_bIp6Configured = TRUE;
  1997. } else {
  1998. g_bIp6Configured = FALSE;
  1999. }
  2000. }
  2001. LeaveCriticalSection(&g_stateLock);
  2002. }