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.

1889 lines
61 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. rtrwiz.cpp
  7. Router & Remote access configuration wizard
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "rtrwiz.h"
  12. #include "rtrutilp.h"
  13. #include "rtrcomn.h" // CoCreateRouterConfig
  14. #include "rrasutil.h"
  15. #include "rtutils.h" // Tracing functions
  16. #include "helper.h" // HrIsStandaloneServer
  17. #include "infoi.h" // SRtrMgrProtocolCBList
  18. #include "routprot.h" // MS_IP_XXXX
  19. #include "snaputil.h"
  20. #include "globals.h"
  21. #include "rraswiz.h"
  22. #include "iprtrmib.h" // MIB_IPFORWARDROW
  23. // Include headers for IP-specific stuff
  24. extern "C"
  25. {
  26. #include <ipnat.h>
  27. #include <ipnathlp.h>
  28. #include <sainfo.h>
  29. };
  30. #include "igmprm.h"
  31. #include "ipbootp.h"
  32. #ifdef _DEBUG
  33. #define new DEBUG_NEW
  34. #undef THIS_FILE
  35. static char THIS_FILE[] = __FILE__;
  36. #endif
  37. HRESULT AddIGMPToInterface(IInterfaceInfo *pIf, BOOL fRouter);
  38. HRESULT AddIPBOOTPToInterface(IInterfaceInfo *pIf);
  39. HRESULT AddNATSimpleServers(NewRtrWizData *pNewRtrWizData,
  40. RtrConfigData *pRtrConfigData);
  41. HRESULT AddNATToInterfaces(NewRtrWizData *pNewRtrWizData,
  42. RtrConfigData *pRtrConfigData,
  43. IRouterInfo *pRouter,
  44. BOOL fCreateDD);
  45. HRESULT AddNATToInterface(MPR_SERVER_HANDLE hMprServer,
  46. HANDLE hMprConfig,
  47. NewRtrWizData *pNewRtrWizData,
  48. RtrConfigData *pRtrConfigData,
  49. LPCTSTR pszInterface,
  50. BOOL fDemandDial,
  51. BOOL fPublic);
  52. HRESULT AddDhcpServerToBOOTPGlobalInfo(LPCTSTR pszServerName,
  53. DWORD netDhcpServer);
  54. /*---------------------------------------------------------------------------
  55. Defaults
  56. ---------------------------------------------------------------------------*/
  57. //
  58. // Default values for LAN-interface IGMP configuration
  59. //
  60. // NOTE: Any changes made here should also be made to ipsnap\globals.cpp
  61. //
  62. IGMP_MIB_IF_CONFIG g_IGMPLanDefault = {
  63. IGMP_VERSION_3, //Version
  64. 0, //IfIndex (readOnly)
  65. 0, //IpAddr (readOnly)
  66. IGMP_IF_NOT_RAS, //IfType;
  67. IGMP_INTERFACE_ENABLED_IN_CONFIG, //Flags
  68. IGMP_ROUTER_V3, //IgmpProtocolType;
  69. 2, //RobustnessVariable;
  70. 31, //StartupQueryInterval;
  71. 2, //StartupQueryCount;
  72. 125, //GenQueryInterval;
  73. 10, //GenQueryMaxResponseTime;
  74. 1000, //LastMemQueryInterval; (msec)
  75. 2, //LastMemQueryCount;
  76. 255, //OtherQuerierPresentInterval;
  77. 260, //GroupMembershipTimeout;
  78. 0 //NumStaticGroups
  79. };
  80. //----------------------------------------------------------------------------
  81. // DHCP Relay-agent default configuration
  82. //
  83. //----------------------------------------------------------------------------
  84. //
  85. // Default values for LAN-interface DHCP Relay-agent configuration
  86. //
  87. IPBOOTP_IF_CONFIG
  88. g_relayLanDefault = {
  89. 0, // State (read-only)
  90. IPBOOTP_RELAY_ENABLED, // Relay-mode
  91. 4, // Max hop-count
  92. 4 // Min seconds-since-boot
  93. };
  94. /*!--------------------------------------------------------------------------
  95. RtrWizFinish
  96. -
  97. Author: KennT
  98. ---------------------------------------------------------------------------*/
  99. DWORD RtrWizFinish(RtrConfigData* pRtrConfigData, IRouterInfo *pRouter)
  100. {
  101. HRESULT hr = hrOK;
  102. LPCTSTR pszServerFlagsKey = NULL;
  103. LPCTSTR pszRouterTypeKey = NULL;
  104. RegKey rkey;
  105. RouterVersionInfo routerVersion;
  106. HKEY hkeyMachine = NULL;
  107. CString stMachine, stPhonebookPath;
  108. // Connect to the remote machine's registry
  109. // ----------------------------------------------------------------
  110. CWRg( ConnectRegistry(pRtrConfigData->m_stServerName, &hkeyMachine) );
  111. QueryRouterVersionInfo(hkeyMachine, &routerVersion);
  112. if (routerVersion.dwOsBuildNo < RASMAN_PPP_KEY_LAST_VERSION)
  113. pszRouterTypeKey = c_szRegKeyRasProtocols;
  114. else
  115. pszRouterTypeKey = c_szRegKeyRemoteAccessParameters;
  116. // enable routing & RAS page
  117. // ----------------------------------------------------------------
  118. if ( ERROR_SUCCESS == rkey.Open(hkeyMachine, pszRouterTypeKey) )
  119. {
  120. rkey.SetValue( c_szRouterType,pRtrConfigData->m_dwRouterType);
  121. }
  122. // protocols page
  123. // ----------------------------------------------------------------
  124. // RAS routing
  125. // ----------------------------------------------------------------
  126. if ((pRtrConfigData->m_fUseIp) &&
  127. (pRtrConfigData->m_dwRouterType & (ROUTER_TYPE_RAS | ROUTER_TYPE_WAN)))
  128. pRtrConfigData->m_ipData.SaveToReg(pRouter, routerVersion);
  129. if ( pRtrConfigData->m_dwRouterType & ROUTER_TYPE_RAS )
  130. {
  131. if (pRtrConfigData->m_fUseIpx)
  132. {
  133. pRtrConfigData->m_ipxData.SaveToReg(pRouter);
  134. }
  135. if (pRtrConfigData->m_fUseNbf)
  136. pRtrConfigData->m_nbfData.SaveToReg();
  137. if (pRtrConfigData->m_fUseArap)
  138. pRtrConfigData->m_arapData.SaveToReg();
  139. }
  140. // Save the err log data
  141. pRtrConfigData->m_errlogData.SaveToReg();
  142. // Save the auth data
  143. pRtrConfigData->m_authData.SaveToReg(NULL);
  144. // Set some global registry settings (that need to get set,
  145. // independent of the router type).
  146. // ----------------------------------------------------------------
  147. InstallGlobalSettings(pRtrConfigData->m_stServerName, pRouter);
  148. // router only will start service and return
  149. // ----------------------------------------------------------------
  150. if ( !(pRtrConfigData->m_dwRouterType & (ROUTER_TYPE_RAS | ROUTER_TYPE_WAN)) )
  151. {
  152. // implies LAN routing; so start router & return
  153. // ------------------------------------------------------------
  154. goto EndConfig;
  155. }
  156. // security page
  157. // ----------------------------------------------------------------
  158. // Depending on the version depends on where we look for the
  159. // key.
  160. // ----------------------------------------------------------------
  161. if (routerVersion.dwOsBuildNo < RASMAN_PPP_KEY_LAST_VERSION)
  162. pszServerFlagsKey = c_szRasmanPPPKey;
  163. else
  164. pszServerFlagsKey = c_szRegKeyRemoteAccessParameters;
  165. if ( ERROR_SUCCESS == rkey.Open(HKEY_LOCAL_MACHINE,
  166. pszServerFlagsKey,
  167. KEY_ALL_ACCESS, pRtrConfigData->m_stServerName) )
  168. {
  169. DWORD dwServerFlags = 0;
  170. // Windows NT Bug : 299456
  171. // Query for the server flags before overwriting it. This way
  172. // we don't overwrite the old values.
  173. // ------------------------------------------------------------
  174. rkey.QueryValue( c_szServerFlags, dwServerFlags );
  175. // Add in the defaults (minus MSCHAP) for the PPP Settings.
  176. // ------------------------------------------------------------
  177. dwServerFlags |= (PPPCFG_UseSwCompression |
  178. PPPCFG_UseLcpExtensions |
  179. PPPCFG_NegotiateMultilink |
  180. PPPCFG_NegotiateBacp);
  181. // Set the value
  182. // ------------------------------------------------------------
  183. rkey.SetValue( c_szServerFlags, dwServerFlags );
  184. }
  185. // Delete the router.pbk
  186. // ----------------------------------------------------------------
  187. DeleteRouterPhonebook( pRtrConfigData->m_stServerName );
  188. EndConfig:
  189. WriteRouterConfiguredReg(pRtrConfigData->m_stServerName, TRUE);
  190. WriteRRASExtendsComputerManagementKey(pRtrConfigData->m_stServerName, TRUE);
  191. WriteErasePSKReg ( pRtrConfigData->m_stServerName, TRUE );
  192. Error:
  193. if (hkeyMachine)
  194. DisconnectRegistry(hkeyMachine);
  195. return hr;
  196. }
  197. extern "C"
  198. HRESULT APIENTRY MprConfigServerInstallPrivate( VOID )
  199. {
  200. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  201. DWORD dwErr = ERROR_SUCCESS;
  202. RtrConfigData wizData;
  203. //
  204. // We removed this smart pointer definition as it was causing
  205. // a warning during build on alpha 32 bit. Looks like the extern "C"
  206. // of the function definition is conflicting with the smart pointer.
  207. //
  208. // SPIRemoteNetworkConfig spNetwork;
  209. IRemoteNetworkConfig * pNetwork = NULL;
  210. IUnknown * punk = NULL;
  211. CWaitCursor wait;
  212. HRESULT hr = hrOK;
  213. // Create the remote config object
  214. // ----------------------------------------------------------------
  215. CORg( CoCreateRouterConfig(NULL,
  216. NULL,
  217. NULL,
  218. IID_IRemoteNetworkConfig,
  219. &punk) );
  220. pNetwork = (IRemoteNetworkConfig *) punk;
  221. punk = NULL;
  222. // Upgrade the configuration (ensure that the registry keys
  223. // are populated correctly).
  224. // ------------------------------------------------------------
  225. CORg( pNetwork->UpgradeRouterConfig() );
  226. wizData.m_stServerName.Empty();
  227. wizData.m_dwRouterType = (ROUTER_TYPE_RAS|ROUTER_TYPE_LAN|ROUTER_TYPE_WAN);
  228. // Need to get version information and initialize
  229. // the RAS structures (IP only)
  230. // Assume that this is on NT5
  231. wizData.m_fUseIp = TRUE;
  232. wizData.m_ipData.UseDefaults(_T(""), FALSE);
  233. wizData.m_ipData.m_dwAllowNetworkAccess = TRUE;
  234. wizData.m_authData.UseDefaults(NULL, FALSE);
  235. wizData.m_errlogData.UseDefaults(NULL, FALSE);
  236. dwErr = RtrWizFinish(&wizData, NULL);
  237. hr = HResultFromWin32(dwErr);
  238. SetDeviceType(NULL, wizData.m_dwRouterType, 10);
  239. RegisterRouterInDomain(NULL, TRUE);
  240. Error:
  241. if (pNetwork)
  242. pNetwork->Release();
  243. return hr;
  244. }
  245. /*!--------------------------------------------------------------------------
  246. MprConfigServerUnattendedInstall
  247. Call this function to setup the registry entries for the server.
  248. This works only with the local machine for now.
  249. pswzServer - name of the server
  250. fInstall - TRUE if we are installing, FALSE if we are removing
  251. Author: KennT
  252. ---------------------------------------------------------------------------*/
  253. extern "C"
  254. HRESULT APIENTRY MprConfigServerUnattendedInstall(LPCWSTR pswzServer, BOOL fInstall)
  255. {
  256. HRESULT hr = hrOK;
  257. #if 0 // remove this restriciton and see what happens
  258. // We only the local machine (for now).
  259. // ----------------------------------------------------------------
  260. if (pswzServer)
  261. {
  262. return HResultFromWin32( ERROR_INVALID_PARAMETER );
  263. }
  264. #endif
  265. // Write out the various registry settings
  266. // ----------------------------------------------------------------
  267. // CORg( SetRouterInstallRegistrySettings(pswzServer, fInstall, TRUE) );
  268. // Write the "router is configured" flag
  269. // ----------------------------------------------------------------
  270. CORg( WriteRouterConfiguredReg(pswzServer, fInstall) );
  271. // Write out the RRAS extend Computer Management key
  272. CORg( WriteRRASExtendsComputerManagementKey(pswzServer, fInstall) );
  273. if (fInstall)
  274. {
  275. // Set the state of the router to Autostart
  276. // ------------------------------------------------------------
  277. SetRouterServiceStartType(pswzServer,
  278. SERVICE_AUTO_START);
  279. }
  280. Error:
  281. return hr;
  282. }
  283. /*!--------------------------------------------------------------------------
  284. AddIGMPToRasServer
  285. -
  286. Author: KennT
  287. ---------------------------------------------------------------------------*/
  288. HRESULT AddIGMPToRasServer(RtrConfigData *pRtrConfigData,
  289. IRouterInfo *pRouter)
  290. {
  291. HRESULT hr = hrOK;
  292. SPIRouterProtocolConfig spRouterConfig;
  293. SRtrMgrProtocolCBList SRmProtCBList;
  294. POSITION pos;
  295. SRtrMgrProtocolCB * pSRmProtCB;
  296. BOOL fFoundDedicatedInterface;
  297. GUID guidConfig = GUID_RouterNull;
  298. SPIInterfaceInfo spIf;
  299. SPIRtrMgrInterfaceInfo spRmIf;
  300. DWORD dwIfType;
  301. SPIEnumInterfaceInfo spEnumInterface;
  302. // Check to see if IP is enabled
  303. // ------------------------------------------------------------
  304. if (pRtrConfigData->m_ipData.m_dwEnableIn &&
  305. pRtrConfigData->m_fIpSetup)
  306. {
  307. // If so, then we can add IGMP.
  308. // --------------------------------------------------------
  309. // Find the GUID for the IGMP Configuration.
  310. // We get the list directly (rather than from the pRouter)
  311. // because the data for the RtrMgrProtocols has not been
  312. // loaded yet. The IRouterInfo only has information on the
  313. // interfaces and not for the protocols (since the router
  314. // is not yet configured).
  315. // --------------------------------------------------------
  316. RouterInfo::LoadInstalledRtrMgrProtocolList(pRtrConfigData->m_stServerName,
  317. PID_IP, &SRmProtCBList, pRouter);
  318. // Now iterate through this list looking for the igmp entry.
  319. // ------------------------------------------------------------
  320. pos = SRmProtCBList.GetHeadPosition();
  321. while (pos)
  322. {
  323. pSRmProtCB = SRmProtCBList.GetNext(pos);
  324. if ((pSRmProtCB->dwTransportId == PID_IP) &&
  325. (pSRmProtCB->dwProtocolId == MS_IP_IGMP))
  326. {
  327. guidConfig = pSRmProtCB->guidConfig;
  328. break;
  329. }
  330. }
  331. if (guidConfig == GUID_RouterNull)
  332. goto Error;
  333. // Now add IGMP.
  334. // --------------------------------------------------------
  335. CORg( CoCreateProtocolConfig(guidConfig,
  336. pRouter,
  337. PID_IP,
  338. MS_IP_IGMP,
  339. &spRouterConfig) );
  340. if (spRouterConfig)
  341. hr = spRouterConfig->AddProtocol(pRtrConfigData->m_stServerName,
  342. PID_IP,
  343. MS_IP_IGMP,
  344. NULL,
  345. 0,
  346. pRouter,
  347. 0);
  348. CORg( hr );
  349. // In addition, we will also need to add IGMP router to the
  350. // internal interface and IGMP proxy to one of the LAN
  351. // interfaces.
  352. // ------------------------------------------------------------
  353. // Do we have the router managers for the interfaces?
  354. // ------------------------------------------------------------
  355. pRouter->EnumInterface(&spEnumInterface);
  356. fFoundDedicatedInterface = FALSE;
  357. for (spEnumInterface->Reset();
  358. spEnumInterface->Next(1, &spIf, NULL) == hrOK;
  359. spIf.Release())
  360. {
  361. dwIfType = spIf->GetInterfaceType();
  362. // Add IGMP if this is an internal interface or
  363. // if this is the first dedicated interface.
  364. // --------------------------------------------------------
  365. if ((dwIfType == ROUTER_IF_TYPE_INTERNAL) ||
  366. (!fFoundDedicatedInterface &&
  367. (dwIfType == ROUTER_IF_TYPE_DEDICATED)))
  368. {
  369. // Ok, add IGMP to this interface
  370. // ----------------------------------------------------
  371. // If this is a dedicated interface and a private network
  372. // is specified, use that.
  373. // ----------------------------------------------------
  374. if ((dwIfType == ROUTER_IF_TYPE_DEDICATED) &&
  375. !pRtrConfigData->m_ipData.m_stNetworkAdapterGUID.IsEmpty() &&
  376. (pRtrConfigData->m_ipData.m_stNetworkAdapterGUID != spIf->GetId()))
  377. continue;
  378. // Get the IP Router Manager
  379. // ----------------------------------------------------
  380. spRmIf.Release();
  381. CORg( spIf->FindRtrMgrInterface(PID_IP, &spRmIf) );
  382. if (!spRmIf)
  383. break;
  384. if (dwIfType == ROUTER_IF_TYPE_DEDICATED)
  385. fFoundDedicatedInterface = TRUE;
  386. if (dwIfType == ROUTER_IF_TYPE_INTERNAL)
  387. AddIGMPToInterface(spIf, TRUE /* fRouter */);
  388. else
  389. AddIGMPToInterface(spIf, FALSE /* fRouter */);
  390. }
  391. }
  392. }
  393. Error:
  394. while (!SRmProtCBList.IsEmpty())
  395. delete SRmProtCBList.RemoveHead();
  396. return hr;
  397. }
  398. /*!--------------------------------------------------------------------------
  399. AddIGMPToNATServer
  400. -
  401. Author: KennT
  402. ---------------------------------------------------------------------------*/
  403. HRESULT AddIGMPToNATServer(RtrConfigData *pRtrConfigData,
  404. IRouterInfo *pRouter)
  405. {
  406. HRESULT hr = hrOK;
  407. SPIRouterProtocolConfig spRouterConfig;
  408. SRtrMgrProtocolCBList SRmProtCBList;
  409. POSITION pos;
  410. SRtrMgrProtocolCB * pSRmProtCB;
  411. GUID guidConfig = GUID_RouterNull;
  412. SPIInterfaceInfo spIf;
  413. SPIEnumInterfaceInfo spEnumInterface;
  414. // Check to see if IP is enabled
  415. // ------------------------------------------------------------
  416. if (pRtrConfigData->m_ipData.m_dwEnableIn &&
  417. pRtrConfigData->m_fIpSetup)
  418. {
  419. // If so, then we can add IGMP.
  420. // --------------------------------------------------------
  421. // Find the GUID for the IGMP Configuration.
  422. // We get the list directly (rather than from the pRouter)
  423. // because the data for the RtrMgrProtocols has not been
  424. // loaded yet. The IRouterInfo only has information on the
  425. // interfaces and not for the protocols (since the router
  426. // is not yet configured).
  427. // --------------------------------------------------------
  428. RouterInfo::LoadInstalledRtrMgrProtocolList(pRtrConfigData->m_stServerName,
  429. PID_IP, &SRmProtCBList, pRouter);
  430. // Now iterate through this list looking for the igmp entry.
  431. // ------------------------------------------------------------
  432. pos = SRmProtCBList.GetHeadPosition();
  433. while (pos)
  434. {
  435. pSRmProtCB = SRmProtCBList.GetNext(pos);
  436. if ((pSRmProtCB->dwTransportId == PID_IP) &&
  437. (pSRmProtCB->dwProtocolId == MS_IP_IGMP))
  438. {
  439. guidConfig = pSRmProtCB->guidConfig;
  440. break;
  441. }
  442. }
  443. if (guidConfig == GUID_RouterNull)
  444. goto Error;
  445. // Now add IGMP.
  446. // --------------------------------------------------------
  447. CORg( CoCreateProtocolConfig(guidConfig,
  448. pRouter,
  449. PID_IP,
  450. MS_IP_IGMP,
  451. &spRouterConfig) );
  452. if (spRouterConfig)
  453. hr = spRouterConfig->AddProtocol(pRtrConfigData->m_stServerName,
  454. PID_IP,
  455. MS_IP_IGMP,
  456. NULL,
  457. 0,
  458. pRouter,
  459. 0);
  460. CORg( hr );
  461. pRouter->EnumInterface(&spEnumInterface);
  462. for (spEnumInterface->Reset();
  463. spEnumInterface->Next(1, &spIf, NULL) == hrOK;
  464. spIf.Release())
  465. {
  466. if (pRtrConfigData->m_ipData.m_stPublicAdapterGUID.CompareNoCase(spIf->GetId()) == 0)
  467. {
  468. // Ok, add the public interface as the proxy
  469. AddIGMPToInterface(spIf, FALSE /* fRouter */);
  470. }
  471. if (pRtrConfigData->m_ipData.m_stPrivateAdapterGUID.CompareNoCase(spIf->GetId()) == 0)
  472. {
  473. // Ok, add the private interface as the router
  474. AddIGMPToInterface(spIf, TRUE /* fRouter */);
  475. }
  476. }
  477. }
  478. Error:
  479. while (!SRmProtCBList.IsEmpty())
  480. delete SRmProtCBList.RemoveHead();
  481. return hr;
  482. }
  483. HRESULT AddIGMPToInterface(IInterfaceInfo *pIf, BOOL fRouter)
  484. {
  485. HRESULT hr = hrOK;
  486. SPIRtrMgrInterfaceInfo spRmIf;
  487. SPIInfoBase spInfoBase;
  488. IGMP_MIB_IF_CONFIG igmpConfig;
  489. BOOL bVersion2=TRUE;
  490. // Get the IP Router Manager
  491. // ----------------------------------------------------
  492. CORg( pIf->FindRtrMgrInterface(PID_IP, &spRmIf) );
  493. if (spRmIf == NULL)
  494. CORg( E_FAIL );
  495. CORg( spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase) );
  496. igmpConfig = g_IGMPLanDefault;
  497. {
  498. if(pIf)
  499. {
  500. CString szMachineName;
  501. LPWSTR lpcwMachine = NULL;
  502. WKSTA_INFO_100* pWkstaInfo100 = NULL;
  503. szMachineName = pIf->GetMachineName();
  504. if(!szMachineName.IsEmpty() && szMachineName[0] != L'\\')
  505. // append \\ prefix the machine name before call NetWks
  506. {
  507. CString str = L"\\\\";
  508. str += szMachineName;
  509. lpcwMachine = (LPWSTR)(LPCWSTR)str;
  510. }
  511. if( NERR_Success == NetWkstaGetInfo(lpcwMachine, 100, (LPBYTE*)&pWkstaInfo100))
  512. {
  513. Assert(pWkstaInfo100);
  514. if(pWkstaInfo100->wki100_ver_major > 5 || ( pWkstaInfo100->wki100_ver_major == 5 && pWkstaInfo100->wki100_ver_minor > 0))
  515. // dont support IGMPv3
  516. bVersion2 = FALSE;
  517. NetApiBufferFree(pWkstaInfo100);
  518. }
  519. }
  520. }
  521. if (fRouter)
  522. {
  523. igmpConfig.IgmpProtocolType = bVersion2? IGMP_ROUTER_V2: IGMP_ROUTER_V3;
  524. }
  525. else
  526. igmpConfig.IgmpProtocolType = IGMP_PROXY;
  527. if (bVersion2)
  528. igmpConfig.Version = IGMP_VERSION_1_2;
  529. CORg( spInfoBase->AddBlock(MS_IP_IGMP,
  530. sizeof(IGMP_MIB_IF_CONFIG),
  531. (LPBYTE) &igmpConfig,
  532. 1,
  533. TRUE) );
  534. CORg( spRmIf->Save(pIf->GetMachineName(),
  535. NULL, NULL, NULL, spInfoBase, 0) );
  536. Error:
  537. return hr;
  538. }
  539. /*!--------------------------------------------------------------------------
  540. RtrConfigData::Init
  541. -
  542. Author: KennT
  543. ---------------------------------------------------------------------------*/
  544. HRESULT RtrConfigData::Init(LPCTSTR pszServerName, IRouterInfo *pRouter)
  545. {
  546. RouterVersionInfo routerVersion;
  547. BOOL fNt4 = FALSE;
  548. BOOL fRemote;
  549. pRouter->GetRouterVersionInfo(&routerVersion);
  550. fNt4 = (routerVersion.dwRouterVersion == 4);
  551. m_fRemote = !IsLocalMachine(pszServerName);
  552. m_stServerName = pszServerName;
  553. // Load data from the registry
  554. m_ipData.UseDefaults(pszServerName, fNt4);
  555. m_ipxData.UseDefaults(pszServerName, fNt4);
  556. m_nbfData.UseDefaults(pszServerName, fNt4);
  557. m_arapData.UseDefaults(pszServerName, fNt4);
  558. m_errlogData.UseDefaults(pszServerName, fNt4);
  559. m_authData.UseDefaults(pszServerName, fNt4);
  560. // Determine what protocols are installed
  561. // ----------------------------------------------------------------
  562. m_fUseIp = (HrIsProtocolSupported(pszServerName,
  563. c_szRegKeyTcpip,
  564. c_szRegKeyRasIp,
  565. c_szRegKeyRasIpRtrMgr) == hrOK);
  566. m_fUseIpx = (HrIsProtocolSupported(pszServerName,
  567. c_szRegKeyNwlnkIpx,
  568. c_szRegKeyRasIpx,
  569. NULL) == hrOK);
  570. m_fUseNbf = (HrIsProtocolSupported(pszServerName,
  571. c_szRegKeyNbf,
  572. c_szRegKeyRasNbf,
  573. NULL) == hrOK);
  574. m_fUseArap = (HrIsProtocolSupported(pszServerName,
  575. c_szRegKeyAppletalk,
  576. c_szRegKeyRasAppletalk,
  577. NULL) == hrOK);
  578. return hrOK;
  579. }
  580. /*!--------------------------------------------------------------------------
  581. CleanupTunnelFriendlyNames
  582. Removes the list of Ip-in-Ip tunnel friendly names. This should
  583. be used ONLY if we have already removed the interfaces.
  584. Author: KennT
  585. ---------------------------------------------------------------------------*/
  586. DWORD CleanupTunnelFriendlyNames(IRouterInfo *pRouter)
  587. {
  588. LPBYTE pBuffer = NULL;
  589. DWORD dwErr = ERROR_SUCCESS;
  590. DWORD dwEntriesRead = 0;
  591. MPR_IPINIP_INTERFACE_0 *pTunnel0 = NULL;
  592. // Get the list of Ip-in-Ip tunnels
  593. // ----------------------------------------------------------------
  594. dwErr = MprSetupIpInIpInterfaceFriendlyNameEnum((LPWSTR) pRouter->GetMachineName(),
  595. &pBuffer,
  596. &dwEntriesRead);
  597. pTunnel0 = (MPR_IPINIP_INTERFACE_0 *) pBuffer;
  598. if (dwErr == ERROR_SUCCESS)
  599. {
  600. // Now go through the tunnels and delete all of them
  601. // ------------------------------------------------------------
  602. for (DWORD i=0; i<dwEntriesRead; i++, pTunnel0++)
  603. {
  604. MprSetupIpInIpInterfaceFriendlyNameDelete(
  605. (LPWSTR) pRouter->GetMachineName(),
  606. &(pTunnel0->Guid));
  607. }
  608. }
  609. // Free up the buffer returned from the enum
  610. // ----------------------------------------------------------------
  611. if (pBuffer)
  612. MprSetupIpInIpInterfaceFriendlyNameFree(pBuffer);
  613. return dwErr;
  614. }
  615. /*!--------------------------------------------------------------------------
  616. AddNATToServer
  617. -
  618. Author: KennT
  619. ---------------------------------------------------------------------------*/
  620. HRESULT AddNATToServer(NewRtrWizData *pNewRtrWizData,
  621. RtrConfigData *pRtrConfigData,
  622. IRouterInfo *pRouter,
  623. BOOL fCreateDD,
  624. BOOL fAddProtocolOnly //Do not add interfaces. Just add the protocol and nothing else
  625. )
  626. {
  627. HRESULT hr = hrOK;
  628. SPIRouterProtocolConfig spRouterConfig;
  629. SRtrMgrProtocolCBList SRmProtCBList;
  630. POSITION pos;
  631. SRtrMgrProtocolCB * pSRmProtCB;
  632. GUID guidConfig = GUID_RouterNull;
  633. SPIInfoBase spInfoBase;
  634. BOOL fSave = FALSE;
  635. Assert(pNewRtrWizData);
  636. Assert(pRtrConfigData);
  637. Assert(pRtrConfigData->m_dwConfigFlags & RTRCONFIG_SETUP_NAT);
  638. // Check to see if IP is enabled
  639. // ------------------------------------------------------------
  640. if (!pRtrConfigData->m_ipData.m_dwEnableIn ||
  641. !pRtrConfigData->m_fIpSetup)
  642. return hrOK;
  643. // If so, then we can add NAT.
  644. // --------------------------------------------------------
  645. // Find the GUID for the NAT Configuration.
  646. // Manually load this since the IRouterInfo has not yet
  647. // loaded the RtrMgrProtocol info since the router is
  648. // still in an unconfigured state.
  649. // --------------------------------------------------------
  650. RouterInfo::LoadInstalledRtrMgrProtocolList(pRtrConfigData->m_stServerName,
  651. PID_IP, &SRmProtCBList, pRouter);
  652. // Now iterate through this list looking for the nat entry.
  653. // ------------------------------------------------------------
  654. pos = SRmProtCBList.GetHeadPosition();
  655. while (pos)
  656. {
  657. pSRmProtCB = SRmProtCBList.GetNext(pos);
  658. if ((pSRmProtCB->dwTransportId == PID_IP) &&
  659. (pSRmProtCB->dwProtocolId == MS_IP_NAT))
  660. {
  661. guidConfig = pSRmProtCB->guidConfig;
  662. break;
  663. }
  664. }
  665. if (guidConfig == GUID_RouterNull)
  666. goto Error;
  667. // Now add NAT.
  668. // --------------------------------------------------------
  669. CORg( CoCreateProtocolConfig(guidConfig,
  670. pRouter,
  671. PID_IP,
  672. MS_IP_NAT,
  673. &spRouterConfig) );
  674. if (spRouterConfig)
  675. hr = spRouterConfig->AddProtocol(pRtrConfigData->m_stServerName,
  676. PID_IP,
  677. MS_IP_NAT,
  678. NULL,
  679. 0,
  680. pRouter,
  681. 0);
  682. CORg( hr );
  683. if ( !fAddProtocolOnly )
  684. {
  685. // Check the flags to see if we have to add the DNS proxy
  686. // and the DHCP allocator.
  687. // ------------------------------------------------------------
  688. // Get the router manager for IP
  689. // We have to do this manually since the IRouterInfo will not
  690. // have RtrMgr or RtrMgrProtocol information since the router
  691. // is still in the unconfigured state.
  692. // ------------------------------------------------------------
  693. if (FHrSucceeded(hr))
  694. CORg( AddNATSimpleServers(pNewRtrWizData, pRtrConfigData) );
  695. // Now that we've added the DNS proxy/DHCP allocator, add
  696. // NAT to the specific interfaces involved.
  697. // ----------------------------------------------------------------
  698. if (FHrSucceeded(hr))
  699. CORg( AddNATToInterfaces(pNewRtrWizData, pRtrConfigData, pRouter, fCreateDD) );
  700. }
  701. Error:
  702. while (!SRmProtCBList.IsEmpty())
  703. delete SRmProtCBList.RemoveHead();
  704. return hr;
  705. }
  706. /*!--------------------------------------------------------------------------
  707. AddNATSimpleServers
  708. -
  709. Author: KennT
  710. ---------------------------------------------------------------------------*/
  711. HRESULT AddNATSimpleServers(NewRtrWizData *pNewRtrWizData,
  712. RtrConfigData *pRtrConfigData)
  713. {
  714. HRESULT hr = hrOK;
  715. DWORD dwErr = ERROR_SUCCESS;
  716. DWORD dwErrT = ERROR_SUCCESS;
  717. MPR_SERVER_HANDLE hMprServer = NULL;
  718. MPR_CONFIG_HANDLE hMprConfig = NULL;
  719. LPBYTE pByte = NULL;
  720. DWORD dwSize = 0;
  721. SPIInfoBase spInfoBase;
  722. HANDLE hTransport = NULL;
  723. BOOL fSave = FALSE;
  724. CORg( CreateInfoBase(&spInfoBase) );
  725. // Connect to the server
  726. // ----------------------------------------------------------------
  727. dwErr = MprAdminServerConnect((LPWSTR) (LPCTSTR) pRtrConfigData->m_stServerName, &hMprServer);
  728. if (dwErr == ERROR_SUCCESS)
  729. {
  730. // Ok, get the infobase from the server
  731. dwErr = MprAdminTransportGetInfo(hMprServer,
  732. PID_IP,
  733. &pByte,
  734. &dwSize,
  735. NULL,
  736. NULL);
  737. if (dwErr == ERROR_SUCCESS)
  738. {
  739. spInfoBase->LoadFrom(dwSize, pByte);
  740. MprAdminBufferFree(pByte);
  741. pByte = NULL;
  742. dwSize = 0;
  743. }
  744. }
  745. // We also have to open the hMprConfig, but we can ignore the error
  746. dwErrT = MprConfigServerConnect((LPWSTR) (LPCTSTR) pRtrConfigData->m_stServerName, &hMprConfig);
  747. if (dwErrT == ERROR_SUCCESS)
  748. {
  749. dwErrT = MprConfigTransportGetHandle(hMprConfig, PID_IP, &hTransport);
  750. }
  751. if (dwErr != ERROR_SUCCESS)
  752. {
  753. // Ok, try to use the MprConfig calls.
  754. CWRg( MprConfigTransportGetInfo(hMprConfig,
  755. hTransport,
  756. &pByte,
  757. &dwSize,
  758. NULL,
  759. NULL,
  760. NULL) );
  761. spInfoBase->LoadFrom(dwSize, pByte);
  762. MprConfigBufferFree(pByte);
  763. pByte = NULL;
  764. dwSize = 0;
  765. }
  766. Assert(spInfoBase);
  767. // deonb - add H323 & Directplay support
  768. if (pRtrConfigData->m_dwConfigFlags & RTRCONFIG_SETUP_H323)
  769. {
  770. IP_H323_GLOBAL_INFO globalInfo;
  771. globalInfo = *( (IP_H323_GLOBAL_INFO *)g_pH323GlobalDefault);
  772. CORg( spInfoBase->AddBlock(MS_IP_H323,
  773. sizeof(IP_H323_GLOBAL_INFO),
  774. (LPBYTE) &globalInfo, 1, TRUE));
  775. fSave = TRUE;
  776. }
  777. // deonb - add H323 & Directplay support <end>
  778. if (pRtrConfigData->m_dwConfigFlags & RTRCONFIG_SETUP_FTP)
  779. {
  780. IP_FTP_GLOBAL_INFO globalInfo;
  781. globalInfo = *( (IP_FTP_GLOBAL_INFO *)g_pFtpGlobalDefault);
  782. CORg( spInfoBase->AddBlock(MS_IP_FTP,
  783. sizeof(IP_FTP_GLOBAL_INFO),
  784. (LPBYTE) &globalInfo, 1, TRUE));
  785. fSave = TRUE;
  786. }
  787. if (pRtrConfigData->m_dwConfigFlags & RTRCONFIG_SETUP_DNS_PROXY)
  788. {
  789. IP_DNS_PROXY_GLOBAL_INFO globalInfo;
  790. globalInfo = *( (IP_DNS_PROXY_GLOBAL_INFO *)g_pDnsProxyGlobalDefault);
  791. // Windows NT Bug : 393749
  792. // Remove the WINS flag
  793. globalInfo.Flags &= ~IP_DNS_PROXY_FLAG_ENABLE_WINS;
  794. CORg( spInfoBase->AddBlock(MS_IP_DNS_PROXY,
  795. sizeof(IP_DNS_PROXY_GLOBAL_INFO),
  796. (LPBYTE) &globalInfo, 1, TRUE));
  797. fSave = TRUE;
  798. }
  799. if (pRtrConfigData->m_dwConfigFlags & RTRCONFIG_SETUP_DHCP_ALLOCATOR)
  800. {
  801. IP_AUTO_DHCP_GLOBAL_INFO dhcpGlobalInfo;
  802. RtrWizInterface * pRtrWizIf = NULL;
  803. dhcpGlobalInfo = * ( (IP_AUTO_DHCP_GLOBAL_INFO *) g_pAutoDhcpGlobalDefault);
  804. // Windows NT Bug : 385112
  805. // Due to the problems with changing the IP Address of the
  806. // adapter, let's just set the DHCP scope to be the scope of the
  807. // underlying subnet.
  808. // Need to get the IP address of the private interface
  809. pNewRtrWizData->m_ifMap.Lookup(pNewRtrWizData->m_stPrivateInterfaceId,
  810. pRtrWizIf);
  811. // If we cannot find this interface, go with the default values
  812. // for the subnet/mask. Otherwise use the IP address of the private
  813. // interface.
  814. if (pRtrWizIf && !pRtrWizIf->m_stIpAddress.IsEmpty())
  815. {
  816. CString stFirstIp;
  817. CString stFirstMask;
  818. int iPos;
  819. // Just take the first IP Address
  820. stFirstIp = pRtrWizIf->m_stIpAddress;
  821. iPos = pRtrWizIf->m_stIpAddress.Find(_T(','));
  822. if (iPos >= 0)
  823. stFirstIp = pRtrWizIf->m_stIpAddress.Left(iPos);
  824. else
  825. stFirstIp = pRtrWizIf->m_stIpAddress;
  826. stFirstMask = pRtrWizIf->m_stMask;
  827. iPos = pRtrWizIf->m_stMask.Find(_T(','));
  828. if (iPos >= 0)
  829. stFirstMask = pRtrWizIf->m_stMask.Left(iPos);
  830. else
  831. stFirstMask = pRtrWizIf->m_stMask;
  832. // Now convert this into a net address
  833. dhcpGlobalInfo.ScopeMask = INET_ADDR(stFirstMask);
  834. dhcpGlobalInfo.ScopeNetwork = INET_ADDR(stFirstIp) & dhcpGlobalInfo.ScopeMask;
  835. }
  836. CORg( spInfoBase->AddBlock(MS_IP_DHCP_ALLOCATOR,
  837. sizeof(dhcpGlobalInfo),
  838. (PBYTE) &dhcpGlobalInfo, 1, TRUE) );
  839. fSave = TRUE;
  840. }
  841. if (fSave)
  842. {
  843. spInfoBase->WriteTo(&pByte, &dwSize);
  844. if (hMprServer)
  845. {
  846. MprAdminTransportSetInfo(hMprServer,
  847. PID_IP,
  848. pByte,
  849. dwSize,
  850. NULL,
  851. 0);
  852. }
  853. if (hMprConfig && hTransport)
  854. {
  855. MprConfigTransportSetInfo(hMprConfig,
  856. hTransport,
  857. pByte,
  858. dwSize,
  859. NULL,
  860. NULL,
  861. NULL);
  862. }
  863. if (pByte)
  864. CoTaskMemFree(pByte);
  865. }
  866. Error:
  867. if (hMprConfig)
  868. MprConfigServerDisconnect(hMprConfig);
  869. if (hMprServer)
  870. MprAdminServerDisconnect(hMprServer);
  871. return hr;
  872. }
  873. /*!--------------------------------------------------------------------------
  874. AddNATToInterfaces
  875. -
  876. Author: KennT
  877. ---------------------------------------------------------------------------*/
  878. HRESULT AddNATToInterfaces(NewRtrWizData *pNewRtrWizData,
  879. RtrConfigData *pRtrConfigData,
  880. IRouterInfo *pRouter,
  881. BOOL fCreateDD)
  882. {
  883. HRESULT hr = hrOK;
  884. DWORD dwErr = ERROR_SUCCESS;
  885. DWORD dwErrT = ERROR_SUCCESS;
  886. MPR_SERVER_HANDLE hMprServer = NULL;
  887. MPR_CONFIG_HANDLE hMprConfig = NULL;
  888. LPBYTE pByte = NULL;
  889. DWORD dwSize = 0;
  890. SPIInfoBase spInfoBase;
  891. HANDLE hTransport = NULL;
  892. CString stIfName;
  893. CORg( CreateInfoBase(&spInfoBase) );
  894. // Connect to the server
  895. // ----------------------------------------------------------------
  896. MprAdminServerConnect((LPWSTR) (LPCTSTR) pRtrConfigData->m_stServerName, &hMprServer);
  897. MprConfigServerConnect((LPWSTR) (LPCTSTR) pRtrConfigData->m_stServerName, &hMprConfig);
  898. // Install public NAT on public interface
  899. AddNATToInterface(hMprServer,
  900. hMprConfig,
  901. pNewRtrWizData,
  902. pRtrConfigData,
  903. pRtrConfigData->m_ipData.m_stPublicAdapterGUID,
  904. fCreateDD,
  905. TRUE);
  906. if (!(pNewRtrWizData->m_fSetVPNFilter))
  907. {
  908. // Install private NAT on private interface
  909. AddNATToInterface(hMprServer,
  910. hMprConfig,
  911. pNewRtrWizData,
  912. pRtrConfigData,
  913. pRtrConfigData->m_ipData.m_stPrivateAdapterGUID,
  914. FALSE,
  915. FALSE);
  916. }
  917. Error:
  918. if (hMprConfig)
  919. MprConfigServerDisconnect(hMprConfig);
  920. if (hMprServer)
  921. MprAdminServerDisconnect(hMprServer);
  922. return hr;
  923. }
  924. //
  925. // Default values for LAN-interface NAT configuration
  926. //
  927. IP_NAT_INTERFACE_INFO
  928. g_ipnatLanDefault = {
  929. 0, // Index (unused)
  930. 0, // Flags
  931. { IP_NAT_VERSION, sizeof(RTR_INFO_BLOCK_HEADER), 0,
  932. { 0, 0, 0, 0}} // Header
  933. };
  934. BYTE* g_pIpnatLanDefault = (BYTE*)&g_ipnatLanDefault;
  935. //
  936. // Default values for WAN-interface NAT configuration
  937. //
  938. IP_NAT_INTERFACE_INFO
  939. g_ipnatWanDefault = {
  940. 0, // Index (unused)
  941. IP_NAT_INTERFACE_FLAGS_BOUNDARY|
  942. IP_NAT_INTERFACE_FLAGS_NAPT, // Flags
  943. { IP_NAT_VERSION, sizeof(RTR_INFO_BLOCK_HEADER), 0,
  944. { 0, 0, 0, 0}} // Header
  945. };
  946. BYTE* g_pIpnatWanDefault = (BYTE*)&g_ipnatWanDefault;
  947. DWORD CreatePortMappingsForVPNFilters(
  948. NewRtrWizData *pNewRtrWizData,
  949. IP_NAT_PORT_MAPPING **ppPortMappingsForVPNFilters,
  950. DWORD *dwNumPortMappings)
  951. {
  952. DWORD i, j, dwSize, dwNumMappingsPerAddress;
  953. DWORD dwIpAddress = 0;
  954. CString singleAddr;
  955. CString tempAddrList;
  956. CDWordArray arrIpAddr;
  957. RtrWizInterface *pIf = NULL;
  958. IP_NAT_PORT_MAPPING *pMappings = NULL;
  959. USES_CONVERSION;
  960. //
  961. // The set of generic Port Mappings corresponding to
  962. // VPN server specific filters
  963. //
  964. IP_NAT_PORT_MAPPING
  965. GenericPortMappingsArray[] =
  966. {
  967. {
  968. NAT_PROTOCOL_TCP,
  969. ntohs(1723),
  970. IP_NAT_ADDRESS_UNSPECIFIED,
  971. ntohs(1723),
  972. ntohl(INADDR_LOOPBACK)
  973. },
  974. {
  975. NAT_PROTOCOL_UDP,
  976. ntohs(500),
  977. IP_NAT_ADDRESS_UNSPECIFIED,
  978. ntohs(500),
  979. ntohl(INADDR_LOOPBACK)
  980. },
  981. {
  982. NAT_PROTOCOL_UDP,
  983. ntohs(1701),
  984. IP_NAT_ADDRESS_UNSPECIFIED,
  985. ntohs(1701),
  986. ntohl(INADDR_LOOPBACK)
  987. }
  988. };
  989. pNewRtrWizData->m_ifMap.Lookup(pNewRtrWizData->m_stPublicInterfaceId, pIf);
  990. tempAddrList = pIf->m_stIpAddress;
  991. while (!tempAddrList.IsEmpty())
  992. {
  993. i = tempAddrList.Find(_T(','));
  994. if ( i != -1 )
  995. {
  996. singleAddr = tempAddrList.Left(i);
  997. tempAddrList = tempAddrList.Mid(i + 1);
  998. }
  999. else
  1000. {
  1001. singleAddr = tempAddrList;
  1002. tempAddrList.Empty();
  1003. }
  1004. dwIpAddress = inet_addr(T2A((LPCTSTR)singleAddr));
  1005. if (INADDR_NONE != dwIpAddress) // successful
  1006. arrIpAddr.Add(dwIpAddress);
  1007. }
  1008. dwSize = sizeof(GenericPortMappingsArray) * arrIpAddr.GetSize();
  1009. pMappings = (PIP_NAT_PORT_MAPPING) new BYTE[dwSize];
  1010. if ( pMappings == NULL )
  1011. {
  1012. *ppPortMappingsForVPNFilters = NULL;
  1013. *dwNumPortMappings = 0;
  1014. return ERROR_NOT_ENOUGH_MEMORY;
  1015. }
  1016. ::ZeroMemory(pMappings, dwSize);
  1017. dwNumMappingsPerAddress =
  1018. sizeof(GenericPortMappingsArray)/sizeof(IP_NAT_PORT_MAPPING);
  1019. for ( i = 0; i < arrIpAddr.GetSize(); i++ )
  1020. {
  1021. // Copy the generic port mappings array. We will then set the correct
  1022. // ip address in each of the mappings struct
  1023. memcpy(
  1024. (LPVOID) &(pMappings[i * dwNumMappingsPerAddress]),
  1025. (LPVOID) &(GenericPortMappingsArray[0]),
  1026. sizeof(GenericPortMappingsArray));
  1027. dwIpAddress = arrIpAddr.GetAt(i);
  1028. for ( j = 0; j < dwNumMappingsPerAddress; j++ )
  1029. {
  1030. pMappings[(i*dwNumMappingsPerAddress) + j].PrivateAddress =
  1031. dwIpAddress;
  1032. }
  1033. }
  1034. *ppPortMappingsForVPNFilters = pMappings;
  1035. *dwNumPortMappings = dwNumMappingsPerAddress * arrIpAddr.GetSize();
  1036. return ERROR_SUCCESS;
  1037. }
  1038. /*!--------------------------------------------------------------------------
  1039. AddNATToInterface
  1040. -
  1041. Author: KennT
  1042. ---------------------------------------------------------------------------*/
  1043. HRESULT AddNATToInterface(MPR_SERVER_HANDLE hMprServer,
  1044. HANDLE hMprConfig,
  1045. NewRtrWizData *pNewRtrWizData,
  1046. RtrConfigData *pRtrConfigData,
  1047. LPCTSTR pszInterface,
  1048. BOOL fDemandDial,
  1049. BOOL fPublic)
  1050. {
  1051. HRESULT hr = hrOK;
  1052. HANDLE hInterface = NULL;
  1053. HANDLE hIfTransport = NULL;
  1054. LPBYTE pByte = NULL;
  1055. DWORD dwSize = 0, dwIfBlkSize = 0;
  1056. LPBYTE pDefault = NULL;
  1057. IP_NAT_INTERFACE_INFO ipnat;
  1058. PIP_NAT_INTERFACE_INFO pipnat = NULL;
  1059. DWORD dwErr = ERROR_SUCCESS;
  1060. DWORD dwNumPortMappings = 0;
  1061. PIP_NAT_PORT_MAPPING pPortMappingsForVPNFilters = NULL;
  1062. SPIInfoBase spInfoBase;
  1063. IP_DNS_PROXY_INTERFACE_INFO dnsIfInfo;
  1064. MIB_IPFORWARDROW row;
  1065. if ((pszInterface == NULL) || (*pszInterface == 0))
  1066. return hrOK;
  1067. // Setup the data structures
  1068. // ----------------------------------------------------------------
  1069. if (pNewRtrWizData->m_fSetVPNFilter)
  1070. {
  1071. SPIInfoBase spIB;
  1072. CORg( CreateInfoBase( &spIB ) );
  1073. dwErr = CreatePortMappingsForVPNFilters(
  1074. pNewRtrWizData,
  1075. &pPortMappingsForVPNFilters,
  1076. &dwNumPortMappings
  1077. );
  1078. if ( dwErr == ERROR_SUCCESS && pPortMappingsForVPNFilters)
  1079. {
  1080. spIB->AddBlock(
  1081. IP_NAT_PORT_MAPPING_TYPE,
  1082. sizeof( IP_NAT_PORT_MAPPING ),
  1083. (PBYTE)pPortMappingsForVPNFilters,
  1084. dwNumPortMappings,
  1085. TRUE
  1086. );
  1087. spIB->WriteTo(&pByte, &dwIfBlkSize);
  1088. pipnat = (PIP_NAT_INTERFACE_INFO)
  1089. new BYTE[
  1090. FIELD_OFFSET(IP_NAT_INTERFACE_INFO, Header) +
  1091. dwIfBlkSize ];
  1092. memcpy(&(pipnat->Header), pByte, dwIfBlkSize);
  1093. pipnat->Flags = IP_NAT_INTERFACE_FLAGS_FW;
  1094. /*
  1095. pipnat->Flags = IP_NAT_INTERFACE_FLAGS_BOUNDARY |
  1096. IP_NAT_INTERFACE_FLAGS_FW;
  1097. */
  1098. pipnat->Index = 0;
  1099. pDefault = (LPBYTE) pipnat;
  1100. dwIfBlkSize += FIELD_OFFSET(IP_NAT_INTERFACE_INFO, Header);
  1101. CoTaskMemFree( pByte );
  1102. spIB.Release();
  1103. pByte = NULL;
  1104. }
  1105. else
  1106. {
  1107. ipnat = g_ipnatLanDefault;
  1108. pDefault = (LPBYTE) &ipnat;
  1109. dwIfBlkSize = sizeof(IP_NAT_INTERFACE_INFO);
  1110. }
  1111. }
  1112. else
  1113. {
  1114. if (fDemandDial)
  1115. ipnat = g_ipnatWanDefault;
  1116. else
  1117. ipnat = g_ipnatLanDefault;
  1118. ::ZeroMemory(&dnsIfInfo, sizeof(dnsIfInfo));
  1119. if (fPublic)
  1120. {
  1121. ipnat.Flags |= IP_NAT_INTERFACE_FLAGS_BOUNDARY;
  1122. // Windows NT Bug : 393731
  1123. // This will enable the "Translate TCP/UDP headers in the UI"
  1124. // ------------------------------------------------------------
  1125. ipnat.Flags |= IP_NAT_INTERFACE_FLAGS_NAPT;
  1126. // Windows NT Bug : 393809
  1127. // Enable the DNS resolution
  1128. // ------------------------------------------------------------
  1129. if (fDemandDial)
  1130. dnsIfInfo.Flags |= IP_DNS_PROXY_INTERFACE_FLAG_DEFAULT;
  1131. }
  1132. pDefault = (LPBYTE) &ipnat;
  1133. dwIfBlkSize = sizeof(IP_NAT_INTERFACE_INFO);
  1134. }
  1135. ::ZeroMemory(&row, sizeof(row));
  1136. // Windows Nt Bug : 389441
  1137. // If this is a demand-dial interface, we will have to add
  1138. // a static route to the interface
  1139. // ----------------------------------------------------------------
  1140. if (fDemandDial && fPublic)
  1141. {
  1142. // Note: this is a new interface so there should not be
  1143. // any blocks.
  1144. // ------------------------------------------------------------
  1145. // What is the index of the demand-dial interface?
  1146. row.dwForwardMetric1 = 1;
  1147. row.dwForwardProto = PROTO_IP_NT_STATIC;
  1148. }
  1149. CORg( CreateInfoBase( &spInfoBase ) );
  1150. // ok, we need to get the RmIf
  1151. if (hMprServer)
  1152. {
  1153. dwErr = MprAdminInterfaceGetHandle(hMprServer,
  1154. (LPWSTR) pszInterface,
  1155. &hInterface,
  1156. FALSE);
  1157. if (dwErr == ERROR_SUCCESS)
  1158. dwErr = MprAdminInterfaceTransportGetInfo(hMprServer,
  1159. hInterface,
  1160. PID_IP,
  1161. &pByte,
  1162. &dwSize);
  1163. if (dwErr == ERROR_SUCCESS)
  1164. {
  1165. spInfoBase->LoadFrom(dwSize, pByte);
  1166. MprAdminBufferFree(pByte);
  1167. }
  1168. pByte = NULL;
  1169. dwSize = 0;
  1170. if (dwErr == ERROR_SUCCESS)
  1171. {
  1172. // Manipulate the infobase
  1173. spInfoBase->AddBlock(MS_IP_NAT,
  1174. dwIfBlkSize,
  1175. pDefault,
  1176. 1,
  1177. TRUE);
  1178. if (pRtrConfigData->m_dwConfigFlags & RTRCONFIG_SETUP_DNS_PROXY)
  1179. {
  1180. spInfoBase->AddBlock(MS_IP_DNS_PROXY,
  1181. sizeof(dnsIfInfo),
  1182. (LPBYTE) &dnsIfInfo,
  1183. 1,
  1184. TRUE);
  1185. }
  1186. // Windows NT Bug : 389441
  1187. // Add the default route to the internet.
  1188. // --------------------------------------------------------
  1189. if (fDemandDial && fPublic)
  1190. {
  1191. // Note: this assumes that there are no routes
  1192. // already defined for this interface
  1193. // ----------------------------------------------------
  1194. Assert(spInfoBase->BlockExists(IP_ROUTE_INFO) == S_FALSE);
  1195. spInfoBase->AddBlock(IP_ROUTE_INFO,
  1196. sizeof(row),
  1197. (PBYTE) &row,
  1198. 1, TRUE);
  1199. }
  1200. spInfoBase->WriteTo(&pByte, &dwSize);
  1201. }
  1202. if (dwErr == ERROR_SUCCESS)
  1203. {
  1204. MprAdminInterfaceTransportSetInfo(hMprServer,
  1205. hInterface,
  1206. PID_IP,
  1207. pByte,
  1208. dwSize);
  1209. }
  1210. if (pByte)
  1211. CoTaskMemFree(pByte);
  1212. pByte = NULL;
  1213. dwSize = 0;
  1214. }
  1215. hInterface = NULL;
  1216. if (hMprConfig)
  1217. {
  1218. dwErr = MprConfigInterfaceGetHandle(hMprConfig,
  1219. (LPWSTR) pszInterface,
  1220. &hInterface);
  1221. if (dwErr == ERROR_SUCCESS)
  1222. dwErr = MprConfigInterfaceTransportGetHandle(hMprConfig,
  1223. hInterface,
  1224. PID_IP,
  1225. &hIfTransport);
  1226. if (dwErr == ERROR_SUCCESS)
  1227. dwErr = MprConfigInterfaceTransportGetInfo(hMprConfig,
  1228. hInterface,
  1229. hIfTransport,
  1230. &pByte,
  1231. &dwSize);
  1232. if (dwErr == ERROR_SUCCESS)
  1233. {
  1234. spInfoBase->LoadFrom(dwSize, pByte);
  1235. MprConfigBufferFree(pByte);
  1236. }
  1237. pByte = NULL;
  1238. dwSize = 0;
  1239. if (dwErr == ERROR_SUCCESS)
  1240. {
  1241. // Manipulate the infobase
  1242. spInfoBase->AddBlock(MS_IP_NAT,
  1243. dwIfBlkSize,
  1244. pDefault,
  1245. 1,
  1246. TRUE);
  1247. if (pRtrConfigData->m_dwConfigFlags & RTRCONFIG_SETUP_DNS_PROXY)
  1248. {
  1249. spInfoBase->AddBlock(MS_IP_DNS_PROXY,
  1250. sizeof(dnsIfInfo),
  1251. (LPBYTE) &dnsIfInfo,
  1252. 1,
  1253. TRUE);
  1254. }
  1255. // Windows NT Bug : 389441
  1256. // Add the default route to the internet.
  1257. // --------------------------------------------------------
  1258. if (fDemandDial && fPublic)
  1259. {
  1260. // Note: this assumes that there are no routes
  1261. // already defined for this interface
  1262. // ----------------------------------------------------
  1263. Assert(spInfoBase->BlockExists(IP_ROUTE_INFO) == S_FALSE);
  1264. spInfoBase->AddBlock(IP_ROUTE_INFO,
  1265. sizeof(row),
  1266. (PBYTE) &row,
  1267. 1, TRUE);
  1268. }
  1269. spInfoBase->WriteTo(&pByte, &dwSize);
  1270. }
  1271. if (dwErr == ERROR_SUCCESS)
  1272. {
  1273. MprConfigInterfaceTransportSetInfo(hMprConfig,
  1274. hInterface,
  1275. hIfTransport,
  1276. pByte,
  1277. dwSize);
  1278. }
  1279. if (pByte)
  1280. CoTaskMemFree(pByte);
  1281. pByte = NULL;
  1282. dwSize = 0;
  1283. spInfoBase.Release();
  1284. }
  1285. Error:
  1286. if (pipnat != NULL) { delete [] pipnat; }
  1287. return HResultFromWin32(dwErr);
  1288. }
  1289. /*!--------------------------------------------------------------------------
  1290. AddIPBOOTPToServer
  1291. If dwDhcpServer is 0, then we do not set it in the global list.
  1292. dwDhcpServer is the IP address of the DHCP Server in network order.
  1293. Author: KennT
  1294. ---------------------------------------------------------------------------*/
  1295. HRESULT AddIPBOOTPToServer(RtrConfigData *pRtrConfigData,
  1296. IRouterInfo *pRouter,
  1297. DWORD dwDhcpServer)
  1298. {
  1299. HRESULT hr = hrOK;
  1300. SPIRouterProtocolConfig spRouterConfig;
  1301. SRtrMgrProtocolCBList SRmProtCBList;
  1302. POSITION pos;
  1303. SRtrMgrProtocolCB * pSRmProtCB;
  1304. GUID guidConfig = GUID_RouterNull;
  1305. SPIInterfaceInfo spIf;
  1306. SPIEnumInterfaceInfo spEnumInterface;
  1307. // Check to see if IP is enabled
  1308. // ------------------------------------------------------------
  1309. if (pRtrConfigData->m_ipData.m_dwEnableIn &&
  1310. pRtrConfigData->m_fIpSetup)
  1311. {
  1312. // If so, then we can add IPBOOTP.
  1313. // --------------------------------------------------------
  1314. // Find the GUID for the IPBOOTP Configuration.
  1315. // We get the list directly (rather than from the pRouter)
  1316. // because the data for the RtrMgrProtocols has not been
  1317. // loaded yet. The IRouterInfo only has information on the
  1318. // interfaces and not for the protocols (since the router
  1319. // is not yet configured).
  1320. // --------------------------------------------------------
  1321. RouterInfo::LoadInstalledRtrMgrProtocolList(pRtrConfigData->m_stServerName,
  1322. PID_IP, &SRmProtCBList, pRouter);
  1323. // Now iterate through this list looking for the igmp entry.
  1324. // ------------------------------------------------------------
  1325. pos = SRmProtCBList.GetHeadPosition();
  1326. while (pos)
  1327. {
  1328. pSRmProtCB = SRmProtCBList.GetNext(pos);
  1329. if ((pSRmProtCB->dwTransportId == PID_IP) &&
  1330. (pSRmProtCB->dwProtocolId == MS_IP_BOOTP))
  1331. {
  1332. guidConfig = pSRmProtCB->guidConfig;
  1333. break;
  1334. }
  1335. }
  1336. if (guidConfig == GUID_RouterNull)
  1337. goto Error;
  1338. // Now add IGMP.
  1339. // --------------------------------------------------------
  1340. CORg( CoCreateProtocolConfig(guidConfig,
  1341. pRouter,
  1342. PID_IP,
  1343. MS_IP_BOOTP,
  1344. &spRouterConfig) );
  1345. if (spRouterConfig)
  1346. hr = spRouterConfig->AddProtocol(pRtrConfigData->m_stServerName,
  1347. PID_IP,
  1348. MS_IP_BOOTP,
  1349. NULL,
  1350. 0,
  1351. pRouter,
  1352. 0);
  1353. CORg( hr );
  1354. // In order to do this, we'll have to get the IPBOOTP global
  1355. // info and add the server to the list.
  1356. // ------------------------------------------------------------
  1357. if ((dwDhcpServer != 0) &&
  1358. (dwDhcpServer != MAKEIPADDRESS(255,255,255,255)))
  1359. {
  1360. AddDhcpServerToBOOTPGlobalInfo(pRtrConfigData->m_stServerName,
  1361. dwDhcpServer);
  1362. }
  1363. pRouter->EnumInterface(&spEnumInterface);
  1364. for (spEnumInterface->Reset();
  1365. spEnumInterface->Next(1, &spIf, NULL) == hrOK;
  1366. spIf.Release())
  1367. {
  1368. // Look for the internal interface
  1369. if (spIf->GetInterfaceType() == ROUTER_IF_TYPE_INTERNAL)
  1370. {
  1371. AddIPBOOTPToInterface(spIf);
  1372. break;
  1373. }
  1374. }
  1375. }
  1376. Error:
  1377. while (!SRmProtCBList.IsEmpty())
  1378. delete SRmProtCBList.RemoveHead();
  1379. return hr;
  1380. }
  1381. /*!--------------------------------------------------------------------------
  1382. AddIPBOOTPToInterface
  1383. -
  1384. Author: KennT
  1385. ---------------------------------------------------------------------------*/
  1386. HRESULT AddIPBOOTPToInterface(IInterfaceInfo *pIf)
  1387. {
  1388. HRESULT hr = hrOK;
  1389. SPIRtrMgrInterfaceInfo spRmIf;
  1390. SPIInfoBase spInfoBase;
  1391. // Get the IP Router Manager
  1392. // ----------------------------------------------------
  1393. CORg( pIf->FindRtrMgrInterface(PID_IP, &spRmIf) );
  1394. if (spRmIf == NULL)
  1395. CORg( E_FAIL );
  1396. CORg( spRmIf->GetInfoBase(NULL, NULL, NULL, &spInfoBase) );
  1397. CORg( spInfoBase->AddBlock(MS_IP_BOOTP,
  1398. sizeof(IPBOOTP_IF_CONFIG),
  1399. (LPBYTE) &g_relayLanDefault,
  1400. 1,
  1401. TRUE) );
  1402. CORg( spRmIf->Save(pIf->GetMachineName(),
  1403. NULL, NULL, NULL, spInfoBase, 0) );
  1404. Error:
  1405. return hr;
  1406. }
  1407. HRESULT AddDhcpServerToBOOTPGlobalInfo(LPCTSTR pszServerName,
  1408. DWORD netDhcpServer)
  1409. {
  1410. HRESULT hr = hrOK;
  1411. DWORD dwErr = ERROR_SUCCESS;
  1412. DWORD dwErrT = ERROR_SUCCESS;
  1413. MPR_SERVER_HANDLE hMprServer = NULL;
  1414. MPR_CONFIG_HANDLE hMprConfig = NULL;
  1415. LPBYTE pByte = NULL;
  1416. DWORD dwSize = 0;
  1417. SPIInfoBase spInfoBase;
  1418. HANDLE hTransport = NULL;
  1419. BOOL fSave = FALSE;
  1420. IPBOOTP_GLOBAL_CONFIG * pgc = NULL;
  1421. IPBOOTP_GLOBAL_CONFIG * pgcNew = NULL;
  1422. CORg( CreateInfoBase(&spInfoBase) );
  1423. // Connect to the server
  1424. // ----------------------------------------------------------------
  1425. dwErr = MprAdminServerConnect((LPWSTR) pszServerName, &hMprServer);
  1426. if (dwErr == ERROR_SUCCESS)
  1427. {
  1428. // Ok, get the infobase from the server
  1429. dwErr = MprAdminTransportGetInfo(hMprServer,
  1430. PID_IP,
  1431. &pByte,
  1432. &dwSize,
  1433. NULL,
  1434. NULL);
  1435. if (dwErr == ERROR_SUCCESS)
  1436. {
  1437. spInfoBase->LoadFrom(dwSize, pByte);
  1438. MprAdminBufferFree(pByte);
  1439. pByte = NULL;
  1440. dwSize = 0;
  1441. }
  1442. }
  1443. // We also have to open the hMprConfig, but we can ignore the error
  1444. // ----------------------------------------------------------------
  1445. dwErrT = MprConfigServerConnect((LPWSTR) pszServerName, &hMprConfig);
  1446. if (dwErrT == ERROR_SUCCESS)
  1447. {
  1448. dwErrT = MprConfigTransportGetHandle(hMprConfig, PID_IP, &hTransport);
  1449. }
  1450. if (dwErr != ERROR_SUCCESS)
  1451. {
  1452. // No errors from the MprConfig calls
  1453. // ------------------------------------------------------------
  1454. CWRg( dwErrT );
  1455. // Ok, try to use the MprConfig calls.
  1456. // ------------------------------------------------------------
  1457. CWRg( MprConfigTransportGetInfo(hMprConfig,
  1458. hTransport,
  1459. &pByte,
  1460. &dwSize,
  1461. NULL,
  1462. NULL,
  1463. NULL) );
  1464. spInfoBase->LoadFrom(dwSize, pByte);
  1465. MprConfigBufferFree(pByte);
  1466. pByte = NULL;
  1467. dwSize = 0;
  1468. }
  1469. Assert(spInfoBase);
  1470. // Ok, get the current global config and add on this particular
  1471. // DHCP server
  1472. // ----------------------------------------------------------------
  1473. spInfoBase->GetData(MS_IP_BOOTP, 0, (PBYTE *) &pgc);
  1474. // Resize the struct for the increased address
  1475. // ----------------------------------------------------------------
  1476. dwSize = sizeof(IPBOOTP_GLOBAL_CONFIG) +
  1477. ((pgc->GC_ServerCount + 1) * sizeof(DWORD));
  1478. pgcNew = (IPBOOTP_GLOBAL_CONFIG *) new BYTE[dwSize];
  1479. // Copy over the original information
  1480. // ----------------------------------------------------------------
  1481. CopyMemory(pgcNew, pgc, IPBOOTP_GLOBAL_CONFIG_SIZE(pgc));
  1482. // Add in the new DHCP server
  1483. // ----------------------------------------------------------------
  1484. IPBOOTP_GLOBAL_SERVER_TABLE(pgcNew)[pgc->GC_ServerCount] = netDhcpServer;
  1485. pgcNew->GC_ServerCount++;
  1486. spInfoBase->AddBlock(MS_IP_BOOTP,
  1487. dwSize,
  1488. (LPBYTE) pgcNew,
  1489. 1,
  1490. TRUE);
  1491. spInfoBase->WriteTo(&pByte, &dwSize);
  1492. if (hMprServer)
  1493. {
  1494. MprAdminTransportSetInfo(hMprServer,
  1495. PID_IP,
  1496. pByte,
  1497. dwSize,
  1498. NULL,
  1499. 0);
  1500. }
  1501. if (hMprConfig && hTransport)
  1502. {
  1503. MprConfigTransportSetInfo(hMprConfig,
  1504. hTransport,
  1505. pByte,
  1506. dwSize,
  1507. NULL,
  1508. NULL,
  1509. NULL);
  1510. }
  1511. if (pByte)
  1512. CoTaskMemFree(pByte);
  1513. Error:
  1514. delete [] pgcNew;
  1515. if (hMprConfig)
  1516. MprConfigServerDisconnect(hMprConfig);
  1517. if (hMprServer)
  1518. MprAdminServerDisconnect(hMprServer);
  1519. return hr;
  1520. }