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.

1248 lines
26 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. interface.c
  5. Abstract:
  6. This module contains all of the code to drive
  7. the interface list management of IPSecSPD Service.
  8. Author:
  9. abhisheV 30-September-1999
  10. Environment
  11. User Level: Win32
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. DWORD
  16. CreateInterfaceList(
  17. OUT PIPSEC_INTERFACE * ppIfListToCreate
  18. )
  19. {
  20. DWORD dwError = 0;
  21. PIPSEC_INTERFACE pIfList = NULL;
  22. dwError = GetInterfaceListFromStack(
  23. &pIfList
  24. );
  25. ENTER_SPD_SECTION();
  26. *ppIfListToCreate = pIfList;
  27. LEAVE_SPD_SECTION();
  28. return (dwError);
  29. }
  30. VOID
  31. DestroyInterfaceList(
  32. IN PIPSEC_INTERFACE pIfListToDelete
  33. )
  34. {
  35. PIPSEC_INTERFACE pIf = NULL;
  36. PIPSEC_INTERFACE pTempIf = NULL;
  37. pIf = pIfListToDelete;
  38. while (pIf) {
  39. pTempIf = pIf;
  40. pIf = pIf->pNext;
  41. FreeIpsecInterface(pTempIf);
  42. }
  43. }
  44. DWORD
  45. OnInterfaceChangeEvent(
  46. )
  47. {
  48. DWORD dwError = 0;
  49. PIPSEC_INTERFACE pIfList = NULL;
  50. PIPSEC_INTERFACE pObseleteIfList = NULL;
  51. PIPSEC_INTERFACE pNewIfList = NULL;
  52. PIPSEC_INTERFACE pExistingIfList = NULL;
  53. DWORD dwMMError = 0;
  54. DWORD dwTxError = 0;
  55. DWORD dwTnError = 0;
  56. dwError = ResetInterfaceChangeEvent();
  57. (VOID) GetInterfaceListFromStack(
  58. &pIfList
  59. );
  60. ENTER_SPD_SECTION();
  61. pExistingIfList = gpInterfaceList;
  62. // Interface List from Stack can be NULL.
  63. FormObseleteAndNewIfLists(
  64. pIfList,
  65. &pExistingIfList,
  66. &pObseleteIfList,
  67. &pNewIfList
  68. );
  69. if (pNewIfList) {
  70. AddToInterfaceList(
  71. pNewIfList,
  72. &pExistingIfList
  73. );
  74. }
  75. if (pObseleteIfList) {
  76. DestroyInterfaceList(
  77. pObseleteIfList
  78. );
  79. }
  80. gpInterfaceList = pExistingIfList;
  81. (VOID) ApplyIfChangeToIniMMFilters(
  82. &dwMMError,
  83. pExistingIfList
  84. );
  85. (VOID) ApplyIfChangeToIniTxFilters(
  86. &dwTxError,
  87. pExistingIfList
  88. );
  89. (VOID) ApplyIfChangeToIniTnFilters(
  90. &dwTnError,
  91. pExistingIfList
  92. );
  93. LEAVE_SPD_SECTION();
  94. if (dwMMError || dwTxError || dwTnError) {
  95. AuditEvent(
  96. SE_CATEGID_POLICY_CHANGE,
  97. SE_AUDITID_IPSEC_POLICY_CHANGED,
  98. IPSECSVC_FAILED_PNP_FILTER_PROCESSING,
  99. NULL,
  100. FALSE,
  101. TRUE
  102. );
  103. }
  104. return (dwError);
  105. }
  106. VOID
  107. FormObseleteAndNewIfLists(
  108. IN PIPSEC_INTERFACE pIfList,
  109. IN OUT PIPSEC_INTERFACE * ppExistingIfList,
  110. OUT PIPSEC_INTERFACE * ppObseleteIfList,
  111. OUT PIPSEC_INTERFACE * ppNewIfList
  112. )
  113. {
  114. PIPSEC_INTERFACE pObseleteIfList = NULL;
  115. PIPSEC_INTERFACE pNewIfList = NULL;
  116. PIPSEC_INTERFACE pIf = NULL;
  117. PIPSEC_INTERFACE pNewIf = NULL;
  118. PIPSEC_INTERFACE pTempIf = NULL;
  119. BOOL bInterfaceExists = FALSE;
  120. PIPSEC_INTERFACE pExistingIf = NULL;
  121. PIPSEC_INTERFACE pExistingIfList = NULL;
  122. pExistingIfList = *ppExistingIfList;
  123. MarkInterfaceListSuspect(
  124. pExistingIfList
  125. );
  126. pIf = pIfList;
  127. while (pIf) {
  128. bInterfaceExists = InterfaceExistsInList(
  129. pIf,
  130. pExistingIfList,
  131. &pExistingIf
  132. );
  133. if (bInterfaceExists) {
  134. // Interface already exists in the list.
  135. // Delete the interface.
  136. pTempIf = pIf;
  137. pIf = pIf->pNext;
  138. FreeIpsecInterface(pTempIf);
  139. // The corresponding entry in the original interface list
  140. // is not a suspect any more.
  141. pExistingIf->bIsASuspect = FALSE;
  142. }
  143. else {
  144. // This is a new interface.
  145. // Add it to the list of new interfaces.
  146. pNewIf = pIf;
  147. pIf = pIf->pNext;
  148. pTempIf = pNewIfList;
  149. pNewIfList = pNewIf;
  150. pNewIfList->pNext = pTempIf;
  151. }
  152. }
  153. DeleteObseleteInterfaces(
  154. &pExistingIfList,
  155. &pObseleteIfList
  156. );
  157. *ppExistingIfList = pExistingIfList;
  158. *ppObseleteIfList = pObseleteIfList;
  159. *ppNewIfList = pNewIfList;
  160. }
  161. VOID
  162. AddToInterfaceList(
  163. IN PIPSEC_INTERFACE pIfListToAppend,
  164. OUT PIPSEC_INTERFACE * ppOriginalIfList
  165. )
  166. {
  167. PIPSEC_INTERFACE pIf = NULL;
  168. PIPSEC_INTERFACE pIfToAppend = NULL;
  169. PIPSEC_INTERFACE pTempIf = NULL;
  170. pIf = pIfListToAppend;
  171. while (pIf) {
  172. pIfToAppend = pIf;
  173. pIf = pIf->pNext;
  174. pTempIf = *ppOriginalIfList;
  175. *ppOriginalIfList = pIfToAppend;
  176. (*ppOriginalIfList)->pNext = pTempIf;
  177. }
  178. }
  179. VOID
  180. MarkInterfaceListSuspect(
  181. IN PIPSEC_INTERFACE pExistingIfList
  182. )
  183. {
  184. PIPSEC_INTERFACE pIf = NULL;
  185. pIf = pExistingIfList;
  186. while (pIf) {
  187. pIf->bIsASuspect = TRUE;
  188. pIf = pIf->pNext;
  189. }
  190. }
  191. VOID
  192. DeleteObseleteInterfaces(
  193. IN OUT PIPSEC_INTERFACE * ppExistingIfList,
  194. OUT PIPSEC_INTERFACE * ppObseleteIfList
  195. )
  196. {
  197. PIPSEC_INTERFACE pCurIf = NULL;
  198. PIPSEC_INTERFACE pPreIf = NULL;
  199. PIPSEC_INTERFACE pStartIf = NULL;
  200. PIPSEC_INTERFACE pObseleteIfList = NULL;
  201. PIPSEC_INTERFACE pObseleteIf = NULL;
  202. PIPSEC_INTERFACE pTempIf = NULL;
  203. pCurIf = *ppExistingIfList;
  204. pStartIf = pCurIf;
  205. while (pCurIf) {
  206. if (pCurIf->bIsASuspect) {
  207. pObseleteIf = pCurIf;
  208. pCurIf = pCurIf->pNext;
  209. if (pPreIf) {
  210. pPreIf->pNext = pCurIf;
  211. }
  212. else {
  213. pStartIf = pCurIf;
  214. }
  215. pTempIf = pObseleteIfList;
  216. pObseleteIfList = pObseleteIf;
  217. pObseleteIfList->pNext = pTempIf;
  218. }
  219. else {
  220. pPreIf = pCurIf;
  221. pCurIf = pCurIf->pNext;
  222. }
  223. }
  224. *ppObseleteIfList = pObseleteIfList;
  225. *ppExistingIfList = pStartIf;
  226. }
  227. BOOL
  228. InterfaceExistsInList(
  229. IN PIPSEC_INTERFACE pTestIf,
  230. IN PIPSEC_INTERFACE pExistingIfList,
  231. OUT PIPSEC_INTERFACE * ppExistingIf
  232. )
  233. {
  234. PIPSEC_INTERFACE pIf = NULL;
  235. PIPSEC_INTERFACE pExistingIf = NULL;
  236. BOOL bIfExists = FALSE;
  237. pIf = pExistingIfList;
  238. while (pIf) {
  239. if ((pIf->dwIndex == pTestIf->dwIndex) &&
  240. (pIf->IpAddress == pTestIf->IpAddress)) {
  241. bIfExists = TRUE;
  242. pExistingIf = pIf;
  243. break;
  244. }
  245. pIf = pIf->pNext;
  246. }
  247. *ppExistingIf = pExistingIf;
  248. return (bIfExists);
  249. }
  250. DWORD
  251. GetInterfaceListFromStack(
  252. OUT PIPSEC_INTERFACE *ppIfList
  253. )
  254. {
  255. DWORD dwError = 0;
  256. PMIB_IPADDRTABLE pMibIpAddrTable = NULL;
  257. PMIB_IFTABLE pMibIfTable = NULL;
  258. PIPSEC_INTERFACE pIfList = NULL;
  259. dwError = PaPNPGetIpAddrTable(
  260. &pMibIpAddrTable
  261. );
  262. BAIL_ON_WIN32_ERROR(dwError);
  263. dwError = PaPNPGetIfTable(
  264. &pMibIfTable
  265. );
  266. BAIL_ON_WIN32_ERROR(dwError);
  267. dwError = GenerateInterfaces(
  268. pMibIpAddrTable,
  269. pMibIfTable,
  270. &pIfList
  271. );
  272. BAIL_ON_WIN32_ERROR(dwError);
  273. *ppIfList = pIfList;
  274. cleanup:
  275. if (pMibIfTable) {
  276. LocalFree(pMibIfTable);
  277. }
  278. if (pMibIpAddrTable) {
  279. LocalFree(pMibIpAddrTable);
  280. }
  281. return (dwError);
  282. error:
  283. AuditEvent(
  284. SE_CATEGID_POLICY_CHANGE,
  285. SE_AUDITID_IPSEC_POLICY_CHANGED,
  286. IPSECSVC_INTERFACE_LIST_INCOMPLETE,
  287. NULL,
  288. FALSE,
  289. TRUE
  290. );
  291. *ppIfList = NULL;
  292. goto cleanup;
  293. }
  294. DWORD
  295. GenerateInterfaces(
  296. IN PMIB_IPADDRTABLE pMibIpAddrTable,
  297. IN PMIB_IFTABLE pMibIfTable,
  298. OUT PIPSEC_INTERFACE * ppIfList
  299. )
  300. {
  301. DWORD dwError = 0;
  302. DWORD dwInterfaceType = 0;
  303. ULONG IpAddress = 0;
  304. DWORD dwIndex = 0;
  305. DWORD dwNumEntries = 0;
  306. DWORD dwCnt = 0;
  307. PMIB_IFROW pMibIfRow = NULL;
  308. PIPSEC_INTERFACE pNewIf = NULL;
  309. PIPSEC_INTERFACE pTempIf = NULL;
  310. PIPSEC_INTERFACE pIfList = NULL;
  311. DWORD dwNewIfsCnt = 0;
  312. dwNumEntries = pMibIpAddrTable->dwNumEntries;
  313. for (dwCnt = 0; dwCnt < dwNumEntries; dwCnt++) {
  314. dwIndex = pMibIpAddrTable->table[dwCnt].dwIndex;
  315. pMibIfRow = GetMibIfRow(
  316. pMibIfTable,
  317. dwIndex
  318. );
  319. if (!pMibIfRow) {
  320. continue;
  321. }
  322. IpAddress = pMibIpAddrTable->table[dwCnt].dwAddr;
  323. dwInterfaceType = pMibIfRow->dwType;
  324. dwError = CreateNewInterface(
  325. dwInterfaceType,
  326. IpAddress,
  327. dwIndex,
  328. pMibIfRow,
  329. &pNewIf
  330. );
  331. if (dwError) {
  332. continue;
  333. }
  334. pTempIf = pIfList;
  335. pIfList = pNewIf;
  336. pIfList->pNext = pTempIf;
  337. dwNewIfsCnt++;
  338. }
  339. if (dwNewIfsCnt) {
  340. *ppIfList = pIfList;
  341. dwError = ERROR_SUCCESS;
  342. }
  343. else {
  344. *ppIfList = NULL;
  345. dwError = ERROR_INVALID_DATA;
  346. }
  347. return (dwError);
  348. }
  349. PMIB_IFROW
  350. GetMibIfRow(
  351. IN PMIB_IFTABLE pMibIfTable,
  352. IN DWORD dwIndex
  353. )
  354. {
  355. DWORD i = 0;
  356. PMIB_IFROW pMibIfRow = NULL;
  357. for (i = 0; i < pMibIfTable->dwNumEntries; i++) {
  358. if (pMibIfTable->table[i].dwIndex == dwIndex) {
  359. pMibIfRow = &(pMibIfTable->table[i]);
  360. break;
  361. }
  362. }
  363. return (pMibIfRow);
  364. }
  365. DWORD
  366. CreateNewInterface(
  367. IN DWORD dwInterfaceType,
  368. IN ULONG IpAddress,
  369. IN DWORD dwIndex,
  370. IN PMIB_IFROW pMibIfRow,
  371. OUT PIPSEC_INTERFACE * ppNewInterface
  372. )
  373. {
  374. DWORD dwError = 0;
  375. PIPSEC_INTERFACE pNewInterface = NULL;
  376. LPWSTR pszString = NULL;
  377. LPWSTR pszTemp = NULL;
  378. WCHAR szDeviceName[MAXLEN_IFDESCR*sizeof(WCHAR)];
  379. GUID gInterfaceID;
  380. szDeviceName[0] = L'\0';
  381. if (IpAddress == INADDR_ANY) {
  382. dwError = ERROR_INVALID_DATA;
  383. BAIL_ON_WIN32_ERROR(dwError);
  384. }
  385. else {
  386. if (dwInterfaceType == MIB_IF_TYPE_LOOPBACK) {
  387. dwError = ERROR_INVALID_DATA;
  388. BAIL_ON_WIN32_ERROR(dwError);
  389. }
  390. }
  391. pszString = AllocSPDStr(pMibIfRow->wszName);
  392. if (!pszString) {
  393. dwError = ERROR_OUTOFMEMORY;
  394. BAIL_ON_WIN32_ERROR(dwError);
  395. }
  396. if (wcslen(pszString) <= wcslen(L"\\DEVICE\\TCPIP_")) {
  397. dwError = ERROR_INVALID_DATA;
  398. BAIL_ON_WIN32_ERROR(dwError);
  399. }
  400. pszTemp = pszString + wcslen(L"\\DEVICE\\TCPIP_");
  401. wGUIDFromString(pszTemp, &gInterfaceID);
  402. pNewInterface = (PIPSEC_INTERFACE) AllocSPDMem(
  403. sizeof(IPSEC_INTERFACE)
  404. );
  405. if (!pNewInterface) {
  406. dwError = ERROR_OUTOFMEMORY;
  407. BAIL_ON_WIN32_ERROR(dwError);
  408. }
  409. pNewInterface->dwInterfaceType = dwInterfaceType;
  410. pNewInterface->IpAddress = IpAddress;
  411. pNewInterface->dwIndex = dwIndex;
  412. pNewInterface->bIsASuspect = FALSE;
  413. memcpy(
  414. &pNewInterface->gInterfaceID,
  415. &gInterfaceID,
  416. sizeof(GUID)
  417. );
  418. pNewInterface->pszInterfaceName = NULL;
  419. mbstowcs(
  420. szDeviceName,
  421. pMibIfRow->bDescr,
  422. MAXLEN_IFDESCR
  423. );
  424. pNewInterface->pszDeviceName = AllocSPDStr(
  425. szDeviceName
  426. );
  427. if (!pNewInterface->pszDeviceName) {
  428. dwError = ERROR_OUTOFMEMORY;
  429. BAIL_ON_WIN32_ERROR(dwError);
  430. }
  431. pNewInterface->pNext = NULL;
  432. *ppNewInterface = pNewInterface;
  433. cleanup:
  434. if (pszString) {
  435. FreeSPDStr(pszString);
  436. }
  437. return(dwError);
  438. error:
  439. *ppNewInterface = NULL;
  440. if (pNewInterface) {
  441. FreeIpsecInterface(pNewInterface);
  442. }
  443. goto cleanup;
  444. }
  445. BOOL
  446. MatchInterfaceType(
  447. IN DWORD dwIfListEntryIfType,
  448. IN IF_TYPE FilterIfType
  449. )
  450. {
  451. BOOL bMatchesType = FALSE;
  452. if (FilterIfType == INTERFACE_TYPE_ALL) {
  453. bMatchesType = TRUE;
  454. }
  455. else if (FilterIfType == INTERFACE_TYPE_LAN) {
  456. bMatchesType = IsLAN(dwIfListEntryIfType);
  457. }
  458. else if (FilterIfType == INTERFACE_TYPE_DIALUP) {
  459. bMatchesType = IsDialUp(dwIfListEntryIfType);
  460. }
  461. return (bMatchesType);
  462. }
  463. BOOL
  464. IsLAN(
  465. IN DWORD dwInterfaceType
  466. )
  467. {
  468. BOOL bIsLAN = FALSE;
  469. if ((dwInterfaceType == MIB_IF_TYPE_ETHERNET) ||
  470. (dwInterfaceType == MIB_IF_TYPE_FDDI) ||
  471. (dwInterfaceType == MIB_IF_TYPE_TOKENRING)) {
  472. bIsLAN = TRUE;
  473. }
  474. return (bIsLAN);
  475. }
  476. BOOL
  477. IsDialUp(
  478. IN DWORD dwInterfaceType
  479. )
  480. {
  481. BOOL bIsDialUp = FALSE;
  482. if ((dwInterfaceType == MIB_IF_TYPE_PPP) ||
  483. (dwInterfaceType == MIB_IF_TYPE_SLIP)) {
  484. bIsDialUp = TRUE;
  485. }
  486. return (bIsDialUp);
  487. }
  488. DWORD
  489. InitializeInterfaceChangeEvent(
  490. )
  491. {
  492. DWORD dwError = 0;
  493. WORD wsaVersion = MAKEWORD(2,0);
  494. memset(&gwsaOverlapped, 0, sizeof(WSAOVERLAPPED));
  495. // Start up WinSock.
  496. dwError = WSAStartup(
  497. wsaVersion,
  498. &gwsaData
  499. );
  500. BAIL_ON_WIN32_ERROR(dwError);
  501. gbwsaStarted = TRUE;
  502. if ((LOBYTE(gwsaData.wVersion) != LOBYTE(wsaVersion)) ||
  503. (HIBYTE(gwsaData.wVersion) != HIBYTE(wsaVersion))) {
  504. dwError = WSAVERNOTSUPPORTED;
  505. BAIL_ON_WIN32_ERROR(dwError);
  506. }
  507. // Set up the Socket.
  508. gIfChangeEventSocket = WSASocket(
  509. AF_INET,
  510. SOCK_DGRAM,
  511. 0,
  512. NULL,
  513. 0,
  514. WSA_FLAG_OVERLAPPED
  515. );
  516. if (gIfChangeEventSocket == INVALID_SOCKET) {
  517. dwError = WSAGetLastError();
  518. BAIL_ON_WIN32_ERROR(dwError);
  519. }
  520. ghIfChangeEvent = WSACreateEvent();
  521. if (ghIfChangeEvent == WSA_INVALID_EVENT) {
  522. dwError = WSAGetLastError();
  523. BAIL_ON_WIN32_ERROR(dwError);
  524. }
  525. ghOverlapEvent = WSACreateEvent();
  526. if (ghOverlapEvent == WSA_INVALID_EVENT) {
  527. dwError = WSAGetLastError();
  528. BAIL_ON_WIN32_ERROR(dwError);
  529. }
  530. gwsaOverlapped.hEvent = ghOverlapEvent;
  531. error:
  532. return (dwError);
  533. }
  534. DWORD
  535. ResetInterfaceChangeEvent(
  536. )
  537. {
  538. DWORD dwError = 0;
  539. LONG lNetworkEvents = FD_ADDRESS_LIST_CHANGE;
  540. DWORD dwOutSize = 0;
  541. ResetEvent(ghIfChangeEvent);
  542. gbIsIoctlPended = FALSE;
  543. dwError = WSAIoctl(
  544. gIfChangeEventSocket,
  545. SIO_ADDRESS_LIST_CHANGE,
  546. NULL,
  547. 0,
  548. NULL,
  549. 0,
  550. &dwOutSize,
  551. &gwsaOverlapped,
  552. NULL
  553. );
  554. if (dwError == SOCKET_ERROR) {
  555. dwError = WSAGetLastError();
  556. if (dwError != ERROR_IO_PENDING) {
  557. return (dwError);
  558. }
  559. else {
  560. gbIsIoctlPended = TRUE;
  561. }
  562. }
  563. dwError = WSAEventSelect(
  564. gIfChangeEventSocket,
  565. ghIfChangeEvent,
  566. lNetworkEvents
  567. );
  568. return (dwError);
  569. }
  570. VOID
  571. DestroyInterfaceChangeEvent(
  572. )
  573. {
  574. DWORD dwStatus = 0;
  575. BOOL bDoneWaiting = FALSE;
  576. if (gIfChangeEventSocket) {
  577. if (gbIsIoctlPended) {
  578. CancelIo((HANDLE) gIfChangeEventSocket);
  579. while (!bDoneWaiting) {
  580. dwStatus = WaitForSingleObject(
  581. ghOverlapEvent,
  582. 1000
  583. );
  584. switch (dwStatus) {
  585. case WAIT_OBJECT_0:
  586. bDoneWaiting = TRUE;
  587. break;
  588. case WAIT_TIMEOUT:
  589. ASSERT(FALSE);
  590. break;
  591. default:
  592. bDoneWaiting = TRUE;
  593. ASSERT(FALSE);
  594. break;
  595. }
  596. }
  597. }
  598. closesocket(gIfChangeEventSocket);
  599. }
  600. if (ghIfChangeEvent) {
  601. CloseHandle(ghIfChangeEvent);
  602. }
  603. if (ghOverlapEvent) {
  604. CloseHandle(ghOverlapEvent);
  605. }
  606. if (gbwsaStarted) {
  607. WSACleanup();
  608. }
  609. }
  610. HANDLE
  611. GetInterfaceChangeEvent(
  612. )
  613. {
  614. return ghOverlapEvent;
  615. }
  616. BOOL
  617. IsMyAddress(
  618. IN ULONG IpAddrToCheck,
  619. IN ULONG IpAddrMask,
  620. IN PIPSEC_INTERFACE pExistingIfList
  621. )
  622. {
  623. BOOL bIsMyAddress = FALSE;
  624. PIPSEC_INTERFACE pIf = NULL;
  625. pIf = pExistingIfList;
  626. while (pIf) {
  627. if ((pIf->IpAddress & IpAddrMask) ==
  628. (IpAddrToCheck & IpAddrMask)) {
  629. bIsMyAddress = TRUE;
  630. break;
  631. }
  632. pIf = pIf->pNext;
  633. }
  634. return (bIsMyAddress);
  635. }
  636. VOID
  637. PrintInterfaceList(
  638. IN PIPSEC_INTERFACE pInterfaceList
  639. )
  640. {
  641. WCHAR PrintData[256];
  642. PIPSEC_INTERFACE pInterface = NULL;
  643. DWORD i = 0;
  644. pInterface = pInterfaceList;
  645. while (pInterface) {
  646. wsprintf(PrintData, L"Interface Entry no. %d\n", i+1);
  647. OutputDebugString((LPCTSTR) PrintData);
  648. wsprintf(PrintData, L"\tInterface Type: %d\n", pInterface->dwInterfaceType);
  649. OutputDebugString((LPCTSTR) PrintData);
  650. wsprintf(PrintData, L"\tIP Address: %s\n", pInterface->IpAddress);
  651. OutputDebugString((LPCTSTR) PrintData);
  652. wsprintf(PrintData, L"\tIndex: %d\n", pInterface->dwIndex);
  653. OutputDebugString((LPCTSTR) PrintData);
  654. wsprintf(PrintData, L"\tIs a suspect: %d\n", pInterface->bIsASuspect);
  655. OutputDebugString((LPCTSTR) PrintData);
  656. i++;
  657. pInterface = pInterface->pNext;
  658. }
  659. }
  660. DWORD
  661. GetMatchingInterfaces(
  662. IF_TYPE FilterInterfaceType,
  663. PIPSEC_INTERFACE pExistingIfList,
  664. MATCHING_ADDR ** ppMatchingAddresses,
  665. DWORD * pdwAddrCnt
  666. )
  667. {
  668. DWORD dwError = 0;
  669. MATCHING_ADDR * pMatchingAddresses = NULL;
  670. PIPSEC_INTERFACE pTempIf = NULL;
  671. BOOL bMatches = FALSE;
  672. DWORD dwCnt = 0;
  673. DWORD i = 0;
  674. pTempIf = pExistingIfList;
  675. while (pTempIf) {
  676. bMatches = MatchInterfaceType(
  677. pTempIf->dwInterfaceType,
  678. FilterInterfaceType
  679. );
  680. if (bMatches) {
  681. dwCnt++;
  682. }
  683. pTempIf = pTempIf->pNext;
  684. }
  685. if (!dwCnt) {
  686. dwError = ERROR_SUCCESS;
  687. BAIL_ON_WIN32_SUCCESS(dwError);
  688. }
  689. dwError = AllocateSPDMemory(
  690. sizeof(MATCHING_ADDR) * dwCnt,
  691. (LPVOID *) &pMatchingAddresses
  692. );
  693. BAIL_ON_WIN32_ERROR(dwError);
  694. pTempIf = pExistingIfList;
  695. while (pTempIf) {
  696. bMatches = MatchInterfaceType(
  697. pTempIf->dwInterfaceType,
  698. FilterInterfaceType
  699. );
  700. if (bMatches) {
  701. pMatchingAddresses[i].uIpAddr = pTempIf->IpAddress;
  702. memcpy(
  703. &pMatchingAddresses[i].gInterfaceID,
  704. &pTempIf->gInterfaceID,
  705. sizeof(GUID)
  706. );
  707. i++;
  708. }
  709. pTempIf = pTempIf->pNext;
  710. }
  711. *ppMatchingAddresses = pMatchingAddresses;
  712. *pdwAddrCnt = i;
  713. return (dwError);
  714. success:
  715. error:
  716. *ppMatchingAddresses = NULL;
  717. *pdwAddrCnt = 0;
  718. return (dwError);
  719. }
  720. BOOL
  721. InterfaceAddrIsLocal(
  722. ULONG uIpAddr,
  723. ULONG uIpAddrMask,
  724. MATCHING_ADDR * pLocalAddresses,
  725. DWORD dwAddrCnt
  726. )
  727. {
  728. BOOL bIsLocal = FALSE;
  729. DWORD i = 0;
  730. for (i = 0; i < dwAddrCnt; i++) {
  731. if ((pLocalAddresses[i].uIpAddr & uIpAddrMask) ==
  732. (uIpAddr & uIpAddrMask)) {
  733. bIsLocal = TRUE;
  734. break;
  735. }
  736. }
  737. return (bIsLocal);
  738. }
  739. VOID
  740. FreeIpsecInterface(
  741. PIPSEC_INTERFACE pIpsecInterface
  742. )
  743. {
  744. if (pIpsecInterface) {
  745. if (pIpsecInterface->pszInterfaceName) {
  746. FreeSPDStr(pIpsecInterface->pszInterfaceName);
  747. }
  748. if (pIpsecInterface->pszDeviceName) {
  749. FreeSPDStr(pIpsecInterface->pszDeviceName);
  750. }
  751. FreeSPDMem(pIpsecInterface);
  752. }
  753. }
  754. DWORD
  755. EnumIPSecInterfaces(
  756. LPWSTR pServerName,
  757. PIPSEC_INTERFACE_INFO pIpsecIfTemplate,
  758. PIPSEC_INTERFACE_INFO * ppIpsecInterfaces,
  759. DWORD dwPreferredNumEntries,
  760. LPDWORD pdwNumInterfaces,
  761. LPDWORD pdwNumTotalInterfaces,
  762. LPDWORD pdwResumeHandle,
  763. DWORD dwFlags
  764. )
  765. {
  766. DWORD dwError = 0;
  767. DWORD dwResumeHandle = 0;
  768. DWORD dwNumToEnum = 0;
  769. PIPSEC_INTERFACE pIpsecIf = NULL;
  770. DWORD dwNumTotalInterfaces = 0;
  771. DWORD i = 0;
  772. PIPSEC_INTERFACE pTempIf = NULL;
  773. DWORD dwNumInterfaces = 0;
  774. PIPSEC_INTERFACE_INFO pIpsecInterfaces = NULL;
  775. PIPSEC_INTERFACE_INFO pTempInterface = NULL;
  776. dwResumeHandle = *pdwResumeHandle;
  777. if (!dwPreferredNumEntries || (dwPreferredNumEntries > MAX_INTERFACE_ENUM_COUNT)) {
  778. dwNumToEnum = MAX_INTERFACE_ENUM_COUNT;
  779. }
  780. else {
  781. dwNumToEnum = dwPreferredNumEntries;
  782. }
  783. ENTER_SPD_SECTION();
  784. dwError = ValidateSecurity(
  785. SPD_OBJECT_SERVER,
  786. SERVER_ACCESS_ADMINISTER,
  787. NULL,
  788. NULL
  789. );
  790. BAIL_ON_LOCK_ERROR(dwError);
  791. pIpsecIf = gpInterfaceList;
  792. for (i = 0; (i < dwResumeHandle) && (pIpsecIf != NULL); i++) {
  793. dwNumTotalInterfaces++;
  794. pIpsecIf = pIpsecIf->pNext;
  795. }
  796. if (!pIpsecIf) {
  797. dwError = ERROR_NO_DATA;
  798. BAIL_ON_LOCK_ERROR(dwError);
  799. }
  800. pTempIf = pIpsecIf;
  801. while (pTempIf && (dwNumInterfaces < dwNumToEnum)) {
  802. dwNumTotalInterfaces++;
  803. dwNumInterfaces++;
  804. pTempIf = pTempIf->pNext;
  805. }
  806. while (pTempIf) {
  807. dwNumTotalInterfaces++;
  808. pTempIf = pTempIf->pNext;
  809. }
  810. dwError = SPDApiBufferAllocate(
  811. sizeof(IPSEC_INTERFACE_INFO)*dwNumInterfaces,
  812. &pIpsecInterfaces
  813. );
  814. BAIL_ON_LOCK_ERROR(dwError);
  815. pTempIf = pIpsecIf;
  816. pTempInterface = pIpsecInterfaces;
  817. for (i = 0; i < dwNumInterfaces; i++) {
  818. dwError = CopyIpsecInterface(
  819. pTempIf,
  820. pTempInterface
  821. );
  822. BAIL_ON_LOCK_ERROR(dwError);
  823. pTempIf = pTempIf->pNext;
  824. pTempInterface++;
  825. }
  826. *ppIpsecInterfaces = pIpsecInterfaces;
  827. *pdwNumInterfaces = dwNumInterfaces;
  828. *pdwNumTotalInterfaces = dwNumTotalInterfaces;
  829. *pdwResumeHandle = dwResumeHandle + dwNumInterfaces;
  830. LEAVE_SPD_SECTION();
  831. return (dwError);
  832. lock:
  833. LEAVE_SPD_SECTION();
  834. if (pIpsecInterfaces) {
  835. FreeIpsecInterfaceInfos(
  836. i,
  837. pIpsecInterfaces
  838. );
  839. }
  840. *ppIpsecInterfaces = NULL;
  841. *pdwNumInterfaces = 0;
  842. *pdwNumTotalInterfaces = 0;
  843. *pdwResumeHandle = dwResumeHandle;
  844. return (dwError);
  845. }
  846. DWORD
  847. CopyIpsecInterface(
  848. PIPSEC_INTERFACE pIpsecIf,
  849. PIPSEC_INTERFACE_INFO pIpsecInterface
  850. )
  851. {
  852. DWORD dwError = 0;
  853. memcpy(
  854. &(pIpsecInterface->gInterfaceID),
  855. &(pIpsecIf->gInterfaceID),
  856. sizeof(GUID)
  857. );
  858. pIpsecInterface->dwIndex = pIpsecIf->dwIndex;
  859. if (!(pIpsecIf->pszInterfaceName)) {
  860. (VOID) GetInterfaceName(
  861. pIpsecIf->gInterfaceID,
  862. &pIpsecIf->pszInterfaceName
  863. );
  864. }
  865. if (pIpsecIf->pszInterfaceName) {
  866. dwError = SPDApiBufferAllocate(
  867. wcslen(pIpsecIf->pszInterfaceName)*sizeof(WCHAR)
  868. + sizeof(WCHAR),
  869. &(pIpsecInterface->pszInterfaceName)
  870. );
  871. BAIL_ON_WIN32_ERROR(dwError);
  872. wcscpy(pIpsecInterface->pszInterfaceName, pIpsecIf->pszInterfaceName);
  873. }
  874. dwError = SPDApiBufferAllocate(
  875. wcslen(pIpsecIf->pszDeviceName)*sizeof(WCHAR)
  876. + sizeof(WCHAR),
  877. &(pIpsecInterface->pszDeviceName)
  878. );
  879. BAIL_ON_WIN32_ERROR(dwError);
  880. wcscpy(pIpsecInterface->pszDeviceName, pIpsecIf->pszDeviceName);
  881. pIpsecInterface->dwInterfaceType = pIpsecIf->dwInterfaceType;
  882. pIpsecInterface->uIpAddr = pIpsecIf->IpAddress;
  883. return (dwError);
  884. error:
  885. if (pIpsecInterface->pszInterfaceName) {
  886. SPDApiBufferFree(pIpsecInterface->pszInterfaceName);
  887. }
  888. return (dwError);
  889. }
  890. VOID
  891. FreeIpsecInterfaceInfos(
  892. DWORD dwNumInterfaces,
  893. PIPSEC_INTERFACE_INFO pIpsecInterfaces
  894. )
  895. {
  896. PIPSEC_INTERFACE_INFO pTempInterface = NULL;
  897. DWORD i = 0;
  898. if (!pIpsecInterfaces) {
  899. return;
  900. }
  901. pTempInterface = pIpsecInterfaces;
  902. for (i = 0; i < dwNumInterfaces; i++) {
  903. if (pTempInterface->pszInterfaceName) {
  904. SPDApiBufferFree(pTempInterface->pszInterfaceName);
  905. }
  906. if (pTempInterface->pszDeviceName) {
  907. SPDApiBufferFree(pTempInterface->pszDeviceName);
  908. }
  909. pTempInterface++;
  910. }
  911. SPDApiBufferFree(pIpsecInterfaces);
  912. }
  913. DWORD
  914. GetInterfaceName(
  915. GUID gInterfaceID,
  916. LPWSTR * ppszInterfaceName
  917. )
  918. {
  919. DWORD dwError = 0;
  920. DWORD dwSize = 0;
  921. WCHAR szInterfaceName[512];
  922. *ppszInterfaceName = NULL;
  923. szInterfaceName[0] = L'\0';
  924. dwSize = sizeof(szInterfaceName)/sizeof(WCHAR);
  925. dwError = NhGetInterfaceNameFromGuid(
  926. &gInterfaceID,
  927. szInterfaceName,
  928. &dwSize,
  929. FALSE,
  930. FALSE
  931. );
  932. BAIL_ON_WIN32_ERROR(dwError);
  933. *ppszInterfaceName = AllocSPDStr(
  934. szInterfaceName
  935. );
  936. error:
  937. return (dwError);
  938. }