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.

1706 lines
39 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. #ifdef TRACE_ON
  16. #include "interface.tmh"
  17. #endif
  18. DWORD
  19. CreateInterfaceList(
  20. OUT PIPSEC_INTERFACE * ppIfListToCreate
  21. )
  22. {
  23. DWORD dwError = 0;
  24. PIPSEC_INTERFACE pIfList = NULL;
  25. dwError = GetInterfaceListFromStack(
  26. &pIfList
  27. );
  28. ENTER_SPD_SECTION();
  29. *ppIfListToCreate = pIfList;
  30. LEAVE_SPD_SECTION();
  31. return (dwError);
  32. }
  33. VOID
  34. DestroyInterfaceList(
  35. IN PIPSEC_INTERFACE pIfListToDelete
  36. )
  37. {
  38. PIPSEC_INTERFACE pIf = NULL;
  39. PIPSEC_INTERFACE pTempIf = NULL;
  40. pIf = pIfListToDelete;
  41. while (pIf) {
  42. pTempIf = pIf;
  43. pIf = pIf->pNext;
  44. FreeIpsecInterface(pTempIf);
  45. }
  46. }
  47. DWORD
  48. OnInterfaceChangeEvent(
  49. )
  50. {
  51. DWORD dwError = 0;
  52. PIPSEC_INTERFACE pIfList = NULL;
  53. PIPSEC_INTERFACE pObseleteIfList = NULL;
  54. PIPSEC_INTERFACE pNewIfList = NULL;
  55. PIPSEC_INTERFACE pExistingIfList = NULL;
  56. PSPECIAL_ADDR pLatestSpecialAddrsList;
  57. DWORD dwMMError = 0;
  58. DWORD dwTxError = 0;
  59. DWORD dwTnError = 0;
  60. dwError = ResetInterfaceChangeEvent();
  61. (VOID) GetInterfaceListFromStack(
  62. &pIfList
  63. );
  64. (VOID) GetSpecialAddrsList(
  65. &pLatestSpecialAddrsList
  66. );
  67. ENTER_SPD_SECTION();
  68. (VOID) FreeSpecialAddrList(
  69. &gpSpecialAddrsList
  70. );
  71. gpSpecialAddrsList = pLatestSpecialAddrsList;
  72. pExistingIfList = gpInterfaceList;
  73. // Interface List from Stack can be NULL.
  74. FormObseleteAndNewIfLists(
  75. pIfList,
  76. &pExistingIfList,
  77. &pObseleteIfList,
  78. &pNewIfList
  79. );
  80. if (pNewIfList) {
  81. AddToInterfaceList(
  82. pNewIfList,
  83. &pExistingIfList
  84. );
  85. }
  86. if (pObseleteIfList) {
  87. DestroyInterfaceList(
  88. pObseleteIfList
  89. );
  90. }
  91. gpInterfaceList = pExistingIfList;
  92. (VOID) ApplyIfChangeToIniMMFilters(
  93. &dwMMError,
  94. pExistingIfList,
  95. gpSpecialAddrsList
  96. );
  97. (VOID) ApplyIfChangeToIniTxFilters(
  98. &dwTxError,
  99. pExistingIfList,
  100. gpSpecialAddrsList
  101. );
  102. (VOID) ApplyIfChangeToIniTnFilters(
  103. &dwTnError,
  104. pExistingIfList,
  105. gpSpecialAddrsList
  106. );
  107. LEAVE_SPD_SECTION();
  108. if (dwMMError || dwTxError || dwTnError) {
  109. AuditEvent(
  110. SE_CATEGID_POLICY_CHANGE,
  111. SE_AUDITID_IPSEC_POLICY_CHANGED,
  112. IPSECSVC_FAILED_PNP_FILTER_PROCESSING,
  113. NULL,
  114. FALSE,
  115. TRUE
  116. );
  117. }
  118. return (dwError);
  119. }
  120. DWORD
  121. OnSpecialAddrsChange(
  122. )
  123. {
  124. DWORD dwError = 0;
  125. DWORD dwMMError = 0;
  126. DWORD dwTxError = 0;
  127. DWORD dwTnError = 0;
  128. PSPECIAL_ADDR pOldSpecialAddrsList = NULL;
  129. PSPECIAL_ADDR pLatestSpecialAddrsList = NULL;
  130. BOOL bListSame = FALSE;
  131. dwError = GetSpecialAddrsList(
  132. &pLatestSpecialAddrsList
  133. );
  134. BAIL_ON_WIN32_ERROR(dwError);
  135. ENTER_SPD_SECTION();
  136. bListSame = IsSpecialListSame(
  137. pLatestSpecialAddrsList,
  138. gpSpecialAddrsList
  139. );
  140. if (bListSame) {
  141. (VOID) FreeSpecialAddrList(
  142. &pLatestSpecialAddrsList
  143. );
  144. LEAVE_SPD_SECTION();
  145. return ERROR_SUCCESS;
  146. }
  147. pOldSpecialAddrsList = gpSpecialAddrsList;
  148. gpSpecialAddrsList = pLatestSpecialAddrsList;
  149. (VOID) FreeSpecialAddrList(
  150. &pOldSpecialAddrsList
  151. );
  152. (VOID) ApplyIfChangeToIniMMFilters(
  153. &dwMMError,
  154. gpInterfaceList,
  155. gpSpecialAddrsList
  156. );
  157. (VOID) ApplyIfChangeToIniTxFilters(
  158. &dwTxError,
  159. gpInterfaceList,
  160. gpSpecialAddrsList
  161. );
  162. (VOID) ApplyIfChangeToIniTnFilters(
  163. &dwTnError,
  164. gpInterfaceList,
  165. gpSpecialAddrsList
  166. );
  167. LEAVE_SPD_SECTION();
  168. if (dwMMError || dwTxError || dwTnError) {
  169. AuditEvent(
  170. SE_CATEGID_POLICY_CHANGE,
  171. SE_AUDITID_IPSEC_POLICY_CHANGED,
  172. IPSECSVC_FAILED_PNP_FILTER_PROCESSING,
  173. NULL,
  174. FALSE,
  175. TRUE
  176. );
  177. }
  178. error:
  179. return (dwError);
  180. }
  181. VOID
  182. FormObseleteAndNewIfLists(
  183. IN PIPSEC_INTERFACE pIfList,
  184. IN OUT PIPSEC_INTERFACE * ppExistingIfList,
  185. OUT PIPSEC_INTERFACE * ppObseleteIfList,
  186. OUT PIPSEC_INTERFACE * ppNewIfList
  187. )
  188. {
  189. PIPSEC_INTERFACE pObseleteIfList = NULL;
  190. PIPSEC_INTERFACE pNewIfList = NULL;
  191. PIPSEC_INTERFACE pIf = NULL;
  192. PIPSEC_INTERFACE pNewIf = NULL;
  193. PIPSEC_INTERFACE pTempIf = NULL;
  194. BOOL bInterfaceExists = FALSE;
  195. PIPSEC_INTERFACE pExistingIf = NULL;
  196. PIPSEC_INTERFACE pExistingIfList = NULL;
  197. pExistingIfList = *ppExistingIfList;
  198. MarkInterfaceListSuspect(
  199. pExistingIfList
  200. );
  201. pIf = pIfList;
  202. while (pIf) {
  203. bInterfaceExists = InterfaceExistsInList(
  204. pIf,
  205. pExistingIfList,
  206. &pExistingIf
  207. );
  208. if (bInterfaceExists) {
  209. // Interface already exists in the list.
  210. // Delete the interface.
  211. pTempIf = pIf;
  212. pIf = pIf->pNext;
  213. FreeIpsecInterface(pTempIf);
  214. // The corresponding entry in the original interface list
  215. // is not a suspect any more.
  216. pExistingIf->bIsASuspect = FALSE;
  217. }
  218. else {
  219. // This is a new interface.
  220. // Add it to the list of new interfaces.
  221. pNewIf = pIf;
  222. pIf = pIf->pNext;
  223. pTempIf = pNewIfList;
  224. pNewIfList = pNewIf;
  225. pNewIfList->pNext = pTempIf;
  226. }
  227. }
  228. DeleteObseleteInterfaces(
  229. &pExistingIfList,
  230. &pObseleteIfList
  231. );
  232. *ppExistingIfList = pExistingIfList;
  233. *ppObseleteIfList = pObseleteIfList;
  234. *ppNewIfList = pNewIfList;
  235. }
  236. VOID
  237. AddToInterfaceList(
  238. IN PIPSEC_INTERFACE pIfListToAppend,
  239. OUT PIPSEC_INTERFACE * ppOriginalIfList
  240. )
  241. {
  242. PIPSEC_INTERFACE pIf = NULL;
  243. PIPSEC_INTERFACE pIfToAppend = NULL;
  244. PIPSEC_INTERFACE pTempIf = NULL;
  245. pIf = pIfListToAppend;
  246. while (pIf) {
  247. pIfToAppend = pIf;
  248. pIf = pIf->pNext;
  249. pTempIf = *ppOriginalIfList;
  250. *ppOriginalIfList = pIfToAppend;
  251. (*ppOriginalIfList)->pNext = pTempIf;
  252. }
  253. }
  254. VOID
  255. MarkInterfaceListSuspect(
  256. IN PIPSEC_INTERFACE pExistingIfList
  257. )
  258. {
  259. PIPSEC_INTERFACE pIf = NULL;
  260. pIf = pExistingIfList;
  261. while (pIf) {
  262. pIf->bIsASuspect = TRUE;
  263. pIf = pIf->pNext;
  264. }
  265. }
  266. VOID
  267. DeleteObseleteInterfaces(
  268. IN OUT PIPSEC_INTERFACE * ppExistingIfList,
  269. OUT PIPSEC_INTERFACE * ppObseleteIfList
  270. )
  271. {
  272. PIPSEC_INTERFACE pCurIf = NULL;
  273. PIPSEC_INTERFACE pPreIf = NULL;
  274. PIPSEC_INTERFACE pStartIf = NULL;
  275. PIPSEC_INTERFACE pObseleteIfList = NULL;
  276. PIPSEC_INTERFACE pObseleteIf = NULL;
  277. PIPSEC_INTERFACE pTempIf = NULL;
  278. pCurIf = *ppExistingIfList;
  279. pStartIf = pCurIf;
  280. while (pCurIf) {
  281. if (pCurIf->bIsASuspect) {
  282. pObseleteIf = pCurIf;
  283. pCurIf = pCurIf->pNext;
  284. if (pPreIf) {
  285. pPreIf->pNext = pCurIf;
  286. }
  287. else {
  288. pStartIf = pCurIf;
  289. }
  290. pTempIf = pObseleteIfList;
  291. pObseleteIfList = pObseleteIf;
  292. pObseleteIfList->pNext = pTempIf;
  293. }
  294. else {
  295. pPreIf = pCurIf;
  296. pCurIf = pCurIf->pNext;
  297. }
  298. }
  299. *ppObseleteIfList = pObseleteIfList;
  300. *ppExistingIfList = pStartIf;
  301. }
  302. BOOL
  303. InterfaceExistsInList(
  304. IN PIPSEC_INTERFACE pTestIf,
  305. IN PIPSEC_INTERFACE pExistingIfList,
  306. OUT PIPSEC_INTERFACE * ppExistingIf
  307. )
  308. {
  309. PIPSEC_INTERFACE pIf = NULL;
  310. PIPSEC_INTERFACE pExistingIf = NULL;
  311. BOOL bIfExists = FALSE;
  312. pIf = pExistingIfList;
  313. while (pIf) {
  314. if ((pIf->dwIndex == pTestIf->dwIndex) &&
  315. (pIf->IpAddress == pTestIf->IpAddress)) {
  316. bIfExists = TRUE;
  317. pExistingIf = pIf;
  318. break;
  319. }
  320. pIf = pIf->pNext;
  321. }
  322. *ppExistingIf = pExistingIf;
  323. return (bIfExists);
  324. }
  325. DWORD
  326. GetInterfaceListFromStack(
  327. OUT PIPSEC_INTERFACE *ppIfList
  328. )
  329. {
  330. DWORD dwError = 0;
  331. PMIB_IPADDRTABLE pMibIpAddrTable = NULL;
  332. PMIB_IFTABLE pMibIfTable = NULL;
  333. PIPSEC_INTERFACE pIfList = NULL;
  334. dwError = PaPNPGetIpAddrTable(
  335. &pMibIpAddrTable
  336. );
  337. BAIL_ON_WIN32_ERROR(dwError);
  338. dwError = PaPNPGetIfTable(
  339. &pMibIfTable
  340. );
  341. BAIL_ON_WIN32_ERROR(dwError);
  342. dwError = GenerateInterfaces(
  343. pMibIpAddrTable,
  344. pMibIfTable,
  345. &pIfList
  346. );
  347. BAIL_ON_WIN32_ERROR(dwError);
  348. *ppIfList = pIfList;
  349. cleanup:
  350. if (pMibIfTable) {
  351. LocalFree(pMibIfTable);
  352. }
  353. if (pMibIpAddrTable) {
  354. LocalFree(pMibIpAddrTable);
  355. }
  356. return (dwError);
  357. error:
  358. AuditEvent(
  359. SE_CATEGID_POLICY_CHANGE,
  360. SE_AUDITID_IPSEC_POLICY_CHANGED,
  361. IPSECSVC_INTERFACE_LIST_INCOMPLETE,
  362. NULL,
  363. FALSE,
  364. TRUE
  365. );
  366. *ppIfList = NULL;
  367. TRACE(TRC_ERROR, (L"Failed to get interface list from stack: %!winerr!", dwError));
  368. goto cleanup;
  369. }
  370. DWORD
  371. GenerateInterfaces(
  372. IN PMIB_IPADDRTABLE pMibIpAddrTable,
  373. IN PMIB_IFTABLE pMibIfTable,
  374. OUT PIPSEC_INTERFACE * ppIfList
  375. )
  376. {
  377. DWORD dwError = 0;
  378. DWORD dwInterfaceType = 0;
  379. ULONG IpAddress = 0;
  380. DWORD dwIndex = 0;
  381. DWORD dwNumEntries = 0;
  382. DWORD dwCnt = 0;
  383. PMIB_IFROW pMibIfRow = NULL;
  384. PIPSEC_INTERFACE pNewIf = NULL;
  385. PIPSEC_INTERFACE pTempIf = NULL;
  386. PIPSEC_INTERFACE pIfList = NULL;
  387. DWORD dwNewIfsCnt = 0;
  388. dwNumEntries = pMibIpAddrTable->dwNumEntries;
  389. for (dwCnt = 0; dwCnt < dwNumEntries; dwCnt++) {
  390. dwIndex = pMibIpAddrTable->table[dwCnt].dwIndex;
  391. pMibIfRow = GetMibIfRow(
  392. pMibIfTable,
  393. dwIndex
  394. );
  395. if (!pMibIfRow) {
  396. continue;
  397. }
  398. IpAddress = pMibIpAddrTable->table[dwCnt].dwAddr;
  399. dwInterfaceType = pMibIfRow->dwType;
  400. dwError = CreateNewInterface(
  401. dwInterfaceType,
  402. IpAddress,
  403. dwIndex,
  404. pMibIfRow,
  405. &pNewIf
  406. );
  407. if (dwError) {
  408. continue;
  409. }
  410. pTempIf = pIfList;
  411. pIfList = pNewIf;
  412. pIfList->pNext = pTempIf;
  413. dwNewIfsCnt++;
  414. }
  415. if (dwNewIfsCnt) {
  416. *ppIfList = pIfList;
  417. dwError = ERROR_SUCCESS;
  418. }
  419. else {
  420. *ppIfList = NULL;
  421. dwError = ERROR_INVALID_DATA;
  422. }
  423. return (dwError);
  424. }
  425. BOOL
  426. IsInSpecialAddrList(
  427. PSPECIAL_ADDR pSpecialAddrList,
  428. PSPECIAL_ADDR pInSpecialAddr
  429. )
  430. {
  431. PSPECIAL_ADDR pSpecialAddr;
  432. for (pSpecialAddr = pSpecialAddrList;
  433. pSpecialAddr;
  434. pSpecialAddr = pSpecialAddr->pNext) {
  435. if (pSpecialAddr->AddrType == pInSpecialAddr->AddrType
  436. && pSpecialAddr->uIpAddr == pInSpecialAddr->uIpAddr
  437. && pSpecialAddr->InterfaceType
  438. == pInSpecialAddr->InterfaceType) {
  439. return TRUE;
  440. }
  441. }
  442. return FALSE;
  443. }
  444. BOOL
  445. IsSpecialListSame(
  446. PSPECIAL_ADDR pSpecialAddrList1,
  447. PSPECIAL_ADDR pSpecialAddrList2
  448. )
  449. {
  450. PSPECIAL_ADDR pSpecialAddr;
  451. for (pSpecialAddr = pSpecialAddrList1;
  452. pSpecialAddr;
  453. pSpecialAddr = pSpecialAddr->pNext) {
  454. if (!IsInSpecialAddrList(
  455. pSpecialAddrList2,
  456. pSpecialAddr
  457. )) {
  458. return FALSE;
  459. }
  460. }
  461. for (pSpecialAddr = pSpecialAddrList2;
  462. pSpecialAddr;
  463. pSpecialAddr = pSpecialAddr->pNext) {
  464. if (!IsInSpecialAddrList(
  465. pSpecialAddrList1,
  466. pSpecialAddr
  467. )) {
  468. return FALSE;
  469. }
  470. }
  471. return TRUE;
  472. }
  473. DWORD
  474. NoDupAddSpecialAddr(
  475. PSPECIAL_ADDR *ppSpecialAddrList,
  476. ADDR_TYPE AddrType,
  477. IP_ADDRESS_STRING IpAddr,
  478. DWORD dwInterfaceType
  479. )
  480. {
  481. PSPECIAL_ADDR pSpecialAddr;
  482. BOOL Found = FALSE;
  483. BOOL bDupInterface = FALSE;
  484. PSPECIAL_ADDR pSpecialAddrList;
  485. DWORD dwError = ERROR_SUCCESS;
  486. IF_TYPE IfType = 0;
  487. ULONG uIpAddr;
  488. uIpAddr = inet_addr(
  489. IpAddr.String
  490. );
  491. if (uIpAddr == INADDR_NONE || !uIpAddr) {
  492. dwError = ERROR_INVALID_PARAMETER;
  493. BAIL_ON_WIN32_ERROR(dwError);
  494. }
  495. if (IsDialUp(dwInterfaceType)) {
  496. IfType = INTERFACE_TYPE_DIALUP;
  497. }
  498. else if (IsLAN(dwInterfaceType)) {
  499. IfType = INTERFACE_TYPE_LAN;
  500. }
  501. //
  502. // Search if an exact entry already exists or if a similar entry
  503. // with different InterfaceType exists
  504. //
  505. for (pSpecialAddr = *ppSpecialAddrList;
  506. pSpecialAddr;
  507. pSpecialAddr = pSpecialAddr->pNext) {
  508. if (pSpecialAddr->AddrType == AddrType
  509. && pSpecialAddr->uIpAddr == uIpAddr) {
  510. if (pSpecialAddr->InterfaceType == IfType) {
  511. Found = TRUE;
  512. break;
  513. }
  514. else {
  515. bDupInterface = TRUE;
  516. }
  517. }
  518. }
  519. //
  520. // Add new address to list head if it doesn't exist
  521. //
  522. if (!Found) {
  523. dwError = AllocateSPDMemory(
  524. sizeof(SPECIAL_ADDR),
  525. &pSpecialAddr);
  526. BAIL_ON_WIN32_ERROR(dwError);
  527. pSpecialAddr->AddrType = AddrType;
  528. pSpecialAddr->uIpAddr = uIpAddr;
  529. pSpecialAddr->InterfaceType = IfType;
  530. pSpecialAddr->bDupInterface = bDupInterface;
  531. pSpecialAddr->pNext = *ppSpecialAddrList;
  532. *ppSpecialAddrList = pSpecialAddr;
  533. }
  534. error:
  535. return dwError;
  536. }
  537. DWORD
  538. FreeSpecialAddrList(
  539. PSPECIAL_ADDR *ppSpecialAddrList
  540. )
  541. {
  542. PSPECIAL_ADDR pSpecialAddr;
  543. PSPECIAL_ADDR pTemp;
  544. for (pSpecialAddr = *ppSpecialAddrList;
  545. pSpecialAddr;
  546. pSpecialAddr = pTemp) {
  547. pTemp = pSpecialAddr->pNext;
  548. FreeSPDMemory(pSpecialAddr);
  549. }
  550. *ppSpecialAddrList = NULL;
  551. return ERROR_SUCCESS;
  552. }
  553. DWORD
  554. AllocAndGetAdaptersInfo(
  555. PIP_ADAPTER_INFO *ppAdapterInfo,
  556. ULONG *pulOutBufLen
  557. )
  558. {
  559. DWORD dwError = ERROR_SUCCESS;
  560. PIP_ADAPTER_INFO pAdapterInfo = NULL;
  561. ULONG ulOutBufLen = 0;
  562. dwError = GetAdaptersInfo(
  563. pAdapterInfo,
  564. &ulOutBufLen
  565. );
  566. if (dwError == ERROR_BUFFER_OVERFLOW) {
  567. dwError = AllocateSPDMemory(
  568. ulOutBufLen,
  569. &pAdapterInfo
  570. );
  571. BAIL_ON_WIN32_ERROR(dwError);
  572. dwError = GetAdaptersInfo(
  573. pAdapterInfo,
  574. &ulOutBufLen
  575. );
  576. BAIL_ON_WIN32_ERROR(dwError);
  577. }
  578. else {
  579. BAIL_ON_WIN32_ERROR(dwError);
  580. }
  581. *ppAdapterInfo = pAdapterInfo;
  582. *pulOutBufLen = ulOutBufLen;
  583. return dwError;
  584. error:
  585. if (pAdapterInfo) {
  586. FreeSPDMemory(pAdapterInfo);
  587. }
  588. *ppAdapterInfo = NULL;
  589. *pulOutBufLen =0;
  590. return dwError;
  591. }
  592. DWORD
  593. AllocAndGetPerAdapterInfo(
  594. ULONG IfIndex,
  595. PIP_PER_ADAPTER_INFO *ppPerAdapterInfo,
  596. ULONG *pulOutBufLen
  597. )
  598. {
  599. DWORD dwError = ERROR_SUCCESS;
  600. PIP_PER_ADAPTER_INFO pPerAdapterInfo = NULL;
  601. ULONG ulOutBufLen = 0;
  602. dwError = GetPerAdapterInfo(
  603. IfIndex,
  604. pPerAdapterInfo,
  605. &ulOutBufLen
  606. );
  607. if (dwError == ERROR_BUFFER_OVERFLOW) {
  608. dwError = AllocateSPDMemory(
  609. ulOutBufLen,
  610. &pPerAdapterInfo
  611. );
  612. BAIL_ON_WIN32_ERROR(dwError);
  613. dwError = GetPerAdapterInfo(
  614. IfIndex,
  615. pPerAdapterInfo,
  616. &ulOutBufLen
  617. );
  618. BAIL_ON_WIN32_ERROR(dwError);
  619. }
  620. else {
  621. BAIL_ON_WIN32_ERROR(dwError);
  622. }
  623. *ppPerAdapterInfo = pPerAdapterInfo;
  624. *pulOutBufLen = ulOutBufLen;
  625. return dwError;
  626. error:
  627. if (pPerAdapterInfo) {
  628. FreeSPDMemory(pPerAdapterInfo);
  629. }
  630. *ppPerAdapterInfo = NULL;
  631. *pulOutBufLen =0;
  632. return dwError;
  633. }
  634. DWORD
  635. GetSpecialAddrsList(
  636. OUT PSPECIAL_ADDR *ppSpecialAddrsList
  637. )
  638. {
  639. PSPECIAL_ADDR pAddrs = NULL;
  640. DWORD dwAddrCnt = 0;
  641. PIP_ADAPTER_INFO pAdapterInfo = NULL;
  642. PIP_ADAPTER_INFO pAdapterInfoEnum = NULL;
  643. PIP_PER_ADAPTER_INFO pPerAdapterInfo = NULL;
  644. ULONG ulOutBufLen = 0;
  645. PIP_ADDR_STRING pIPAddrStr = NULL;
  646. PSPECIAL_ADDR pSpecialAddrsList = NULL;
  647. DWORD dwError = ERROR_SUCCESS;
  648. DWORD i;
  649. dwError = AllocAndGetAdaptersInfo(
  650. &pAdapterInfo,
  651. &ulOutBufLen
  652. );
  653. BAIL_ON_WIN32_ERROR(dwError);
  654. //
  655. // Fill in special addresses
  656. //
  657. pAdapterInfoEnum = pAdapterInfo;
  658. while (pAdapterInfoEnum) {
  659. if (pAdapterInfoEnum->DhcpEnabled) {
  660. (VOID) NoDupAddSpecialAddr(
  661. &pSpecialAddrsList,
  662. IP_ADDR_DHCP_SERVER,
  663. pAdapterInfoEnum->DhcpServer.IpAddress,
  664. pAdapterInfoEnum->Type
  665. );
  666. }
  667. (VOID) NoDupAddSpecialAddr(
  668. &pSpecialAddrsList,
  669. IP_ADDR_DEFAULT_GATEWAY,
  670. pAdapterInfoEnum->GatewayList.IpAddress,
  671. pAdapterInfoEnum->Type
  672. );
  673. if (pAdapterInfoEnum->HaveWins) {
  674. (VOID) NoDupAddSpecialAddr(
  675. &pSpecialAddrsList,
  676. IP_ADDR_WINS_SERVER,
  677. pAdapterInfoEnum->PrimaryWinsServer.IpAddress,
  678. pAdapterInfoEnum->Type
  679. );
  680. // Get Secondary WINS
  681. pIPAddrStr = &pAdapterInfoEnum->SecondaryWinsServer;
  682. while (pIPAddrStr) {
  683. (VOID) NoDupAddSpecialAddr(
  684. &pSpecialAddrsList,
  685. IP_ADDR_WINS_SERVER,
  686. pIPAddrStr->IpAddress,
  687. pAdapterInfoEnum->Type
  688. );
  689. pIPAddrStr = pIPAddrStr->Next;
  690. }
  691. }
  692. //
  693. // Get DNS servers
  694. //
  695. dwError = AllocAndGetPerAdapterInfo(
  696. pAdapterInfoEnum->Index,
  697. &pPerAdapterInfo,
  698. &ulOutBufLen
  699. );
  700. if (dwError == ERROR_SUCCESS) {
  701. pIPAddrStr = &pPerAdapterInfo->DnsServerList;
  702. while (pIPAddrStr) {
  703. (VOID) NoDupAddSpecialAddr(
  704. &pSpecialAddrsList,
  705. IP_ADDR_DNS_SERVER,
  706. pIPAddrStr->IpAddress,
  707. pAdapterInfoEnum->Type
  708. );
  709. pIPAddrStr = pIPAddrStr->Next;
  710. }
  711. FreeSPDMemory(
  712. pPerAdapterInfo
  713. );
  714. pPerAdapterInfo = NULL;
  715. }
  716. pAdapterInfoEnum = pAdapterInfoEnum->Next;
  717. }
  718. FreeSPDMemory(
  719. pAdapterInfo
  720. );
  721. *ppSpecialAddrsList = pSpecialAddrsList;
  722. return dwError;
  723. error:
  724. FreeSPDMemory(
  725. pAdapterInfo
  726. );
  727. *ppSpecialAddrsList = NULL;
  728. TRACE(TRC_WARNING, (L"Failed to create list of special servers: %!winerr!", dwError));
  729. return dwError;
  730. }
  731. PMIB_IFROW
  732. GetMibIfRow(
  733. IN PMIB_IFTABLE pMibIfTable,
  734. IN DWORD dwIndex
  735. )
  736. {
  737. DWORD i = 0;
  738. PMIB_IFROW pMibIfRow = NULL;
  739. for (i = 0; i < pMibIfTable->dwNumEntries; i++) {
  740. if (pMibIfTable->table[i].dwIndex == dwIndex) {
  741. pMibIfRow = &(pMibIfTable->table[i]);
  742. break;
  743. }
  744. }
  745. return (pMibIfRow);
  746. }
  747. DWORD
  748. CreateNewInterface(
  749. IN DWORD dwInterfaceType,
  750. IN ULONG IpAddress,
  751. IN DWORD dwIndex,
  752. IN PMIB_IFROW pMibIfRow,
  753. OUT PIPSEC_INTERFACE * ppNewInterface
  754. )
  755. {
  756. DWORD dwError = 0;
  757. PIPSEC_INTERFACE pNewInterface = NULL;
  758. LPWSTR pszString = NULL;
  759. LPWSTR pszTemp = NULL;
  760. WCHAR szDeviceName[MAXLEN_IFDESCR*sizeof(WCHAR)];
  761. GUID gInterfaceID;
  762. szDeviceName[0] = L'\0';
  763. if (IpAddress == INADDR_ANY) {
  764. dwError = ERROR_INVALID_DATA;
  765. BAIL_ON_WIN32_ERROR(dwError);
  766. }
  767. else {
  768. if (dwInterfaceType == MIB_IF_TYPE_LOOPBACK) {
  769. dwError = ERROR_INVALID_DATA;
  770. BAIL_ON_WIN32_ERROR(dwError);
  771. }
  772. }
  773. pszString = AllocSPDStr(pMibIfRow->wszName);
  774. if (!pszString) {
  775. dwError = ERROR_OUTOFMEMORY;
  776. BAIL_ON_WIN32_ERROR(dwError);
  777. }
  778. if (wcslen(pszString) <= wcslen(L"\\DEVICE\\TCPIP_")) {
  779. dwError = ERROR_INVALID_DATA;
  780. BAIL_ON_WIN32_ERROR(dwError);
  781. }
  782. pszTemp = pszString + wcslen(L"\\DEVICE\\TCPIP_");
  783. wGUIDFromString(pszTemp, &gInterfaceID);
  784. pNewInterface = (PIPSEC_INTERFACE) AllocSPDMem(
  785. sizeof(IPSEC_INTERFACE)
  786. );
  787. if (!pNewInterface) {
  788. dwError = ERROR_OUTOFMEMORY;
  789. BAIL_ON_WIN32_ERROR(dwError);
  790. }
  791. pNewInterface->dwInterfaceType = dwInterfaceType;
  792. pNewInterface->IpAddress = IpAddress;
  793. pNewInterface->dwIndex = dwIndex;
  794. pNewInterface->bIsASuspect = FALSE;
  795. memcpy(
  796. &pNewInterface->gInterfaceID,
  797. &gInterfaceID,
  798. sizeof(GUID)
  799. );
  800. pNewInterface->pszInterfaceName = NULL;
  801. mbstowcs(
  802. szDeviceName,
  803. pMibIfRow->bDescr,
  804. MAXLEN_IFDESCR
  805. );
  806. pNewInterface->pszDeviceName = AllocSPDStr(
  807. szDeviceName
  808. );
  809. if (!pNewInterface->pszDeviceName) {
  810. dwError = ERROR_OUTOFMEMORY;
  811. BAIL_ON_WIN32_ERROR(dwError);
  812. }
  813. pNewInterface->pNext = NULL;
  814. *ppNewInterface = pNewInterface;
  815. cleanup:
  816. if (pszString) {
  817. FreeSPDStr(pszString);
  818. }
  819. return(dwError);
  820. error:
  821. *ppNewInterface = NULL;
  822. if (pNewInterface) {
  823. FreeIpsecInterface(pNewInterface);
  824. }
  825. goto cleanup;
  826. }
  827. BOOL
  828. MatchInterfaceType(
  829. IN DWORD dwIfListEntryIfType,
  830. IN IF_TYPE FilterIfType
  831. )
  832. {
  833. BOOL bMatchesType = FALSE;
  834. if (FilterIfType == INTERFACE_TYPE_ALL) {
  835. bMatchesType = TRUE;
  836. }
  837. else if (FilterIfType == INTERFACE_TYPE_LAN) {
  838. bMatchesType = IsLAN(dwIfListEntryIfType);
  839. }
  840. else if (FilterIfType == INTERFACE_TYPE_DIALUP) {
  841. bMatchesType = IsDialUp(dwIfListEntryIfType);
  842. }
  843. return (bMatchesType);
  844. }
  845. BOOL
  846. IsLAN(
  847. IN DWORD dwInterfaceType
  848. )
  849. {
  850. BOOL bIsLAN = FALSE;
  851. if ((dwInterfaceType == MIB_IF_TYPE_ETHERNET) ||
  852. (dwInterfaceType == MIB_IF_TYPE_FDDI) ||
  853. (dwInterfaceType == MIB_IF_TYPE_TOKENRING)) {
  854. bIsLAN = TRUE;
  855. }
  856. return (bIsLAN);
  857. }
  858. BOOL
  859. IsDialUp(
  860. IN DWORD dwInterfaceType
  861. )
  862. {
  863. BOOL bIsDialUp = FALSE;
  864. if ((dwInterfaceType == MIB_IF_TYPE_PPP) ||
  865. (dwInterfaceType == MIB_IF_TYPE_SLIP)) {
  866. bIsDialUp = TRUE;
  867. }
  868. return (bIsDialUp);
  869. }
  870. DWORD
  871. InitializeInterfaceChangeEvent(
  872. )
  873. {
  874. DWORD dwError = 0;
  875. WORD wsaVersion = MAKEWORD(2,0);
  876. memset(&gwsaOverlapped, 0, sizeof(WSAOVERLAPPED));
  877. // Start up WinSock.
  878. dwError = WSAStartup(
  879. wsaVersion,
  880. &gwsaData
  881. );
  882. BAIL_ON_WIN32_ERROR(dwError);
  883. gbwsaStarted = TRUE;
  884. if ((LOBYTE(gwsaData.wVersion) != LOBYTE(wsaVersion)) ||
  885. (HIBYTE(gwsaData.wVersion) != HIBYTE(wsaVersion))) {
  886. dwError = WSAVERNOTSUPPORTED;
  887. BAIL_ON_WIN32_ERROR(dwError);
  888. }
  889. // Set up the Socket.
  890. gIfChangeEventSocket = WSASocket(
  891. AF_INET,
  892. SOCK_DGRAM,
  893. 0,
  894. NULL,
  895. 0,
  896. WSA_FLAG_OVERLAPPED
  897. );
  898. if (gIfChangeEventSocket == INVALID_SOCKET) {
  899. dwError = WSAGetLastError();
  900. BAIL_ON_WIN32_ERROR(dwError);
  901. }
  902. ghIfChangeEvent = WSACreateEvent();
  903. if (ghIfChangeEvent == WSA_INVALID_EVENT) {
  904. dwError = WSAGetLastError();
  905. BAIL_ON_WIN32_ERROR(dwError);
  906. }
  907. ghOverlapEvent = WSACreateEvent();
  908. if (ghOverlapEvent == WSA_INVALID_EVENT) {
  909. dwError = WSAGetLastError();
  910. BAIL_ON_WIN32_ERROR(dwError);
  911. }
  912. gwsaOverlapped.hEvent = ghOverlapEvent;
  913. return (dwError);
  914. error:
  915. TRACE(TRC_ERROR, (L"Failed to initialize interface change event: %!winerr!", dwError));
  916. return (dwError);
  917. }
  918. DWORD
  919. ResetInterfaceChangeEvent(
  920. )
  921. {
  922. DWORD dwError = 0;
  923. LONG lNetworkEvents = FD_ADDRESS_LIST_CHANGE;
  924. DWORD dwOutSize = 0;
  925. ResetEvent(ghIfChangeEvent);
  926. gbIsIoctlPended = FALSE;
  927. dwError = WSAIoctl(
  928. gIfChangeEventSocket,
  929. SIO_ADDRESS_LIST_CHANGE,
  930. NULL,
  931. 0,
  932. NULL,
  933. 0,
  934. &dwOutSize,
  935. &gwsaOverlapped,
  936. NULL
  937. );
  938. if (dwError == SOCKET_ERROR) {
  939. dwError = WSAGetLastError();
  940. if (dwError != ERROR_IO_PENDING) {
  941. TRACE(TRC_ERROR, (L"Failed to register for interface change event: %!winerr!", dwError));
  942. return (dwError);
  943. }
  944. else {
  945. gbIsIoctlPended = TRUE;
  946. }
  947. }
  948. dwError = WSAEventSelect(
  949. gIfChangeEventSocket,
  950. ghIfChangeEvent,
  951. lNetworkEvents
  952. );
  953. #ifdef TRACE_ON
  954. if (dwError) {
  955. TRACE(TRC_ERROR, (L"Failed to associate socket with interface change event: %!winerr!", dwError));
  956. }
  957. #endif
  958. return (dwError);
  959. }
  960. VOID
  961. DestroyInterfaceChangeEvent(
  962. )
  963. {
  964. DWORD dwStatus = 0;
  965. BOOL bDoneWaiting = FALSE;
  966. if (gIfChangeEventSocket) {
  967. closesocket(gIfChangeEventSocket);
  968. if (gbIsIoctlPended) {
  969. while (!bDoneWaiting) {
  970. dwStatus = WaitForSingleObject(
  971. ghOverlapEvent,
  972. 1000
  973. );
  974. switch (dwStatus) {
  975. case WAIT_OBJECT_0:
  976. bDoneWaiting = TRUE;
  977. break;
  978. case WAIT_TIMEOUT:
  979. ASSERT(FALSE);
  980. break;
  981. default:
  982. bDoneWaiting = TRUE;
  983. ASSERT(FALSE);
  984. break;
  985. }
  986. }
  987. }
  988. }
  989. if (ghIfChangeEvent) {
  990. CloseHandle(ghIfChangeEvent);
  991. }
  992. if (ghOverlapEvent) {
  993. CloseHandle(ghOverlapEvent);
  994. }
  995. if (gbwsaStarted) {
  996. WSACleanup();
  997. }
  998. }
  999. HANDLE
  1000. GetInterfaceChangeEvent(
  1001. )
  1002. {
  1003. return ghOverlapEvent;
  1004. }
  1005. BOOL
  1006. IsMyAddress(
  1007. IN ULONG IpAddrToCheck,
  1008. IN ULONG IpAddrMask,
  1009. IN PIPSEC_INTERFACE pExistingIfList
  1010. )
  1011. {
  1012. BOOL bIsMyAddress = FALSE;
  1013. PIPSEC_INTERFACE pIf = NULL;
  1014. pIf = pExistingIfList;
  1015. while (pIf) {
  1016. if ((pIf->IpAddress & IpAddrMask) ==
  1017. (IpAddrToCheck & IpAddrMask)) {
  1018. bIsMyAddress = TRUE;
  1019. break;
  1020. }
  1021. pIf = pIf->pNext;
  1022. }
  1023. return (bIsMyAddress);
  1024. }
  1025. VOID
  1026. PrintInterfaceList(
  1027. IN PIPSEC_INTERFACE pInterfaceList
  1028. )
  1029. {
  1030. WCHAR PrintData[256];
  1031. PIPSEC_INTERFACE pInterface = NULL;
  1032. DWORD i = 0;
  1033. pInterface = pInterfaceList;
  1034. while (pInterface) {
  1035. wsprintf(PrintData, L"Interface Entry no. %d\n", i+1);
  1036. OutputDebugString((LPCTSTR) PrintData);
  1037. wsprintf(PrintData, L"\tInterface Type: %d\n", pInterface->dwInterfaceType);
  1038. OutputDebugString((LPCTSTR) PrintData);
  1039. wsprintf(PrintData, L"\tIP Address: %d\n", pInterface->IpAddress);
  1040. OutputDebugString((LPCTSTR) PrintData);
  1041. wsprintf(PrintData, L"\tIndex: %d\n", pInterface->dwIndex);
  1042. OutputDebugString((LPCTSTR) PrintData);
  1043. wsprintf(PrintData, L"\tIs a suspect: %d\n", pInterface->bIsASuspect);
  1044. OutputDebugString((LPCTSTR) PrintData);
  1045. i++;
  1046. pInterface = pInterface->pNext;
  1047. }
  1048. }
  1049. DWORD
  1050. GetMatchingInterfaces(
  1051. IF_TYPE FilterInterfaceType,
  1052. PIPSEC_INTERFACE pExistingIfList,
  1053. MATCHING_ADDR ** ppMatchingAddresses,
  1054. DWORD * pdwAddrCnt
  1055. )
  1056. {
  1057. DWORD dwError = 0;
  1058. MATCHING_ADDR * pMatchingAddresses = NULL;
  1059. PIPSEC_INTERFACE pTempIf = NULL;
  1060. BOOL bMatches = FALSE;
  1061. DWORD dwCnt = 0;
  1062. DWORD i = 0;
  1063. pTempIf = pExistingIfList;
  1064. while (pTempIf) {
  1065. bMatches = MatchInterfaceType(
  1066. pTempIf->dwInterfaceType,
  1067. FilterInterfaceType
  1068. );
  1069. if (bMatches) {
  1070. dwCnt++;
  1071. }
  1072. pTempIf = pTempIf->pNext;
  1073. }
  1074. if (!dwCnt) {
  1075. dwError = ERROR_SUCCESS;
  1076. BAIL_ON_WIN32_SUCCESS(dwError);
  1077. }
  1078. dwError = AllocateSPDMemory(
  1079. sizeof(MATCHING_ADDR) * dwCnt,
  1080. (LPVOID *) &pMatchingAddresses
  1081. );
  1082. BAIL_ON_WIN32_ERROR(dwError);
  1083. pTempIf = pExistingIfList;
  1084. while (pTempIf) {
  1085. bMatches = MatchInterfaceType(
  1086. pTempIf->dwInterfaceType,
  1087. FilterInterfaceType
  1088. );
  1089. if (bMatches) {
  1090. pMatchingAddresses[i].uIpAddr = pTempIf->IpAddress;
  1091. memcpy(
  1092. &pMatchingAddresses[i].gInterfaceID,
  1093. &pTempIf->gInterfaceID,
  1094. sizeof(GUID)
  1095. );
  1096. i++;
  1097. }
  1098. pTempIf = pTempIf->pNext;
  1099. }
  1100. *ppMatchingAddresses = pMatchingAddresses;
  1101. *pdwAddrCnt = i;
  1102. return (dwError);
  1103. success:
  1104. error:
  1105. *ppMatchingAddresses = NULL;
  1106. *pdwAddrCnt = 0;
  1107. return (dwError);
  1108. }
  1109. BOOL
  1110. InterfaceAddrIsLocal(
  1111. ULONG uIpAddr,
  1112. ULONG uIpAddrMask,
  1113. MATCHING_ADDR * pLocalAddresses,
  1114. DWORD dwAddrCnt
  1115. )
  1116. {
  1117. BOOL bIsLocal = FALSE;
  1118. DWORD i = 0;
  1119. for (i = 0; i < dwAddrCnt; i++) {
  1120. if ((pLocalAddresses[i].uIpAddr & uIpAddrMask) ==
  1121. (uIpAddr & uIpAddrMask)) {
  1122. bIsLocal = TRUE;
  1123. break;
  1124. }
  1125. }
  1126. return (bIsLocal);
  1127. }
  1128. VOID
  1129. FreeIpsecInterface(
  1130. PIPSEC_INTERFACE pIpsecInterface
  1131. )
  1132. {
  1133. if (pIpsecInterface) {
  1134. if (pIpsecInterface->pszInterfaceName) {
  1135. FreeSPDStr(pIpsecInterface->pszInterfaceName);
  1136. }
  1137. if (pIpsecInterface->pszDeviceName) {
  1138. FreeSPDStr(pIpsecInterface->pszDeviceName);
  1139. }
  1140. FreeSPDMem(pIpsecInterface);
  1141. }
  1142. }
  1143. DWORD
  1144. EnumIPSecInterfaces(
  1145. LPWSTR pServerName,
  1146. DWORD dwVersion,
  1147. PIPSEC_INTERFACE_INFO pIpsecIfTemplate,
  1148. DWORD dwFlags,
  1149. DWORD dwPreferredNumEntries,
  1150. PIPSEC_INTERFACE_INFO * ppIpsecInterfaces,
  1151. LPDWORD pdwNumInterfaces,
  1152. LPDWORD pdwNumTotalInterfaces,
  1153. LPDWORD pdwResumeHandle,
  1154. LPVOID pvReserved
  1155. )
  1156. {
  1157. DWORD dwError = 0;
  1158. DWORD dwResumeHandle = 0;
  1159. DWORD dwNumToEnum = 0;
  1160. PIPSEC_INTERFACE pIpsecIf = NULL;
  1161. DWORD dwNumTotalInterfaces = 0;
  1162. DWORD i = 0;
  1163. PIPSEC_INTERFACE pTempIf = NULL;
  1164. DWORD dwNumInterfaces = 0;
  1165. PIPSEC_INTERFACE_INFO pIpsecInterfaces = NULL;
  1166. PIPSEC_INTERFACE_INFO pTempInterface = NULL;
  1167. dwResumeHandle = *pdwResumeHandle;
  1168. if (!dwPreferredNumEntries || (dwPreferredNumEntries > MAX_INTERFACE_ENUM_COUNT)) {
  1169. dwNumToEnum = MAX_INTERFACE_ENUM_COUNT;
  1170. }
  1171. else {
  1172. dwNumToEnum = dwPreferredNumEntries;
  1173. }
  1174. ENTER_SPD_SECTION();
  1175. dwError = ValidateSecurity(
  1176. SPD_OBJECT_SERVER,
  1177. SERVER_ACCESS_ADMINISTER,
  1178. NULL,
  1179. NULL
  1180. );
  1181. BAIL_ON_LOCK_ERROR(dwError);
  1182. pIpsecIf = gpInterfaceList;
  1183. for (i = 0; (i < dwResumeHandle) && (pIpsecIf != NULL); i++) {
  1184. dwNumTotalInterfaces++;
  1185. pIpsecIf = pIpsecIf->pNext;
  1186. }
  1187. if (!pIpsecIf) {
  1188. dwError = ERROR_NO_DATA;
  1189. BAIL_ON_LOCK_ERROR(dwError);
  1190. }
  1191. pTempIf = pIpsecIf;
  1192. while (pTempIf && (dwNumInterfaces < dwNumToEnum)) {
  1193. dwNumTotalInterfaces++;
  1194. dwNumInterfaces++;
  1195. pTempIf = pTempIf->pNext;
  1196. }
  1197. while (pTempIf) {
  1198. dwNumTotalInterfaces++;
  1199. pTempIf = pTempIf->pNext;
  1200. }
  1201. dwError = SPDApiBufferAllocate(
  1202. sizeof(IPSEC_INTERFACE_INFO)*dwNumInterfaces,
  1203. &pIpsecInterfaces
  1204. );
  1205. BAIL_ON_LOCK_ERROR(dwError);
  1206. pTempIf = pIpsecIf;
  1207. pTempInterface = pIpsecInterfaces;
  1208. for (i = 0; i < dwNumInterfaces; i++) {
  1209. dwError = CopyIpsecInterface(
  1210. pTempIf,
  1211. pTempInterface
  1212. );
  1213. BAIL_ON_LOCK_ERROR(dwError);
  1214. pTempIf = pTempIf->pNext;
  1215. pTempInterface++;
  1216. }
  1217. *ppIpsecInterfaces = pIpsecInterfaces;
  1218. *pdwNumInterfaces = dwNumInterfaces;
  1219. *pdwNumTotalInterfaces = dwNumTotalInterfaces;
  1220. *pdwResumeHandle = dwResumeHandle + dwNumInterfaces;
  1221. LEAVE_SPD_SECTION();
  1222. return (dwError);
  1223. lock:
  1224. LEAVE_SPD_SECTION();
  1225. if (pIpsecInterfaces) {
  1226. FreeIpsecInterfaceInfos(
  1227. i,
  1228. pIpsecInterfaces
  1229. );
  1230. }
  1231. *ppIpsecInterfaces = NULL;
  1232. *pdwNumInterfaces = 0;
  1233. *pdwNumTotalInterfaces = 0;
  1234. *pdwResumeHandle = dwResumeHandle;
  1235. return (dwError);
  1236. }
  1237. DWORD
  1238. CopyIpsecInterface(
  1239. PIPSEC_INTERFACE pIpsecIf,
  1240. PIPSEC_INTERFACE_INFO pIpsecInterface
  1241. )
  1242. {
  1243. DWORD dwError = 0;
  1244. memcpy(
  1245. &(pIpsecInterface->gInterfaceID),
  1246. &(pIpsecIf->gInterfaceID),
  1247. sizeof(GUID)
  1248. );
  1249. pIpsecInterface->dwIndex = pIpsecIf->dwIndex;
  1250. if (!(pIpsecIf->pszInterfaceName)) {
  1251. (VOID) GetInterfaceName(
  1252. pIpsecIf->gInterfaceID,
  1253. &pIpsecIf->pszInterfaceName
  1254. );
  1255. }
  1256. if (pIpsecIf->pszInterfaceName) {
  1257. dwError = SPDApiBufferAllocate(
  1258. wcslen(pIpsecIf->pszInterfaceName)*sizeof(WCHAR)
  1259. + sizeof(WCHAR),
  1260. &(pIpsecInterface->pszInterfaceName)
  1261. );
  1262. BAIL_ON_WIN32_ERROR(dwError);
  1263. wcscpy(pIpsecInterface->pszInterfaceName, pIpsecIf->pszInterfaceName);
  1264. }
  1265. dwError = SPDApiBufferAllocate(
  1266. wcslen(pIpsecIf->pszDeviceName)*sizeof(WCHAR)
  1267. + sizeof(WCHAR),
  1268. &(pIpsecInterface->pszDeviceName)
  1269. );
  1270. BAIL_ON_WIN32_ERROR(dwError);
  1271. wcscpy(pIpsecInterface->pszDeviceName, pIpsecIf->pszDeviceName);
  1272. pIpsecInterface->dwInterfaceType = pIpsecIf->dwInterfaceType;
  1273. pIpsecInterface->IpVersion = IPSEC_PROTOCOL_V4;
  1274. pIpsecInterface->uIpAddr = pIpsecIf->IpAddress;
  1275. return (dwError);
  1276. error:
  1277. if (pIpsecInterface->pszInterfaceName) {
  1278. SPDApiBufferFree(pIpsecInterface->pszInterfaceName);
  1279. }
  1280. return (dwError);
  1281. }
  1282. VOID
  1283. FreeIpsecInterfaceInfos(
  1284. DWORD dwNumInterfaces,
  1285. PIPSEC_INTERFACE_INFO pIpsecInterfaces
  1286. )
  1287. {
  1288. PIPSEC_INTERFACE_INFO pTempInterface = NULL;
  1289. DWORD i = 0;
  1290. if (!pIpsecInterfaces) {
  1291. return;
  1292. }
  1293. pTempInterface = pIpsecInterfaces;
  1294. for (i = 0; i < dwNumInterfaces; i++) {
  1295. if (pTempInterface->pszInterfaceName) {
  1296. SPDApiBufferFree(pTempInterface->pszInterfaceName);
  1297. }
  1298. if (pTempInterface->pszDeviceName) {
  1299. SPDApiBufferFree(pTempInterface->pszDeviceName);
  1300. }
  1301. pTempInterface++;
  1302. }
  1303. SPDApiBufferFree(pIpsecInterfaces);
  1304. }
  1305. DWORD
  1306. GetInterfaceName(
  1307. GUID gInterfaceID,
  1308. LPWSTR * ppszInterfaceName
  1309. )
  1310. {
  1311. DWORD dwError = 0;
  1312. DWORD dwSize = 0;
  1313. WCHAR szInterfaceName[512];
  1314. *ppszInterfaceName = NULL;
  1315. szInterfaceName[0] = L'\0';
  1316. dwSize = sizeof(szInterfaceName)/sizeof(WCHAR);
  1317. dwError = NhGetInterfaceNameFromGuid(
  1318. &gInterfaceID,
  1319. szInterfaceName,
  1320. &dwSize,
  1321. FALSE,
  1322. FALSE
  1323. );
  1324. BAIL_ON_WIN32_ERROR(dwError);
  1325. *ppszInterfaceName = AllocSPDStr(
  1326. szInterfaceName
  1327. );
  1328. error:
  1329. return (dwError);
  1330. }