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.

1426 lines
32 KiB

  1. /*
  2. Copyright (c) 1998, Microsoft Corporation, all rights reserved
  3. Description:
  4. History:
  5. */
  6. #include "rassrvr_.h"
  7. // This flag indicates if netbios options are to be preserved for
  8. // the ras server adapter or not.
  9. BOOL g_fDisableNetbiosOverTcpip = FALSE;
  10. extern BOOL HelperInitialized;
  11. BOOL WINAPI ShutdownHandlerRoutine ( DWORD dwCtrlType )
  12. {
  13. if ( CTRL_SHUTDOWN_EVENT == dwCtrlType )
  14. {
  15. TraceHlp("ShutdownHandlerRoutine. Got Shutdown Event. Releasing DhcpAddresses");
  16. //uninitialize Dhcp addresses here.
  17. RasDhcpUninitialize();
  18. return TRUE;
  19. }
  20. return FALSE;
  21. }
  22. /*
  23. Returns:
  24. Notes:
  25. */
  26. DWORD
  27. RasSrvrInitialize(
  28. IN MPRADMINGETIPADDRESSFORUSER* pfnMprGetAddress,
  29. IN MPRADMINRELEASEIPADDRESS* pfnMprReleaseAddress
  30. )
  31. {
  32. DNS_STATUS DnsStatus;
  33. HINSTANCE hInstance;
  34. DWORD dwErr = NO_ERROR;
  35. TraceHlp("RasSrvrInitialize");
  36. g_fDisableNetbiosOverTcpip = FALSE;
  37. //
  38. // Read the key that tells whether to disable netbios over ip
  39. //
  40. {
  41. HKEY hkeyRASIp;
  42. dwErr = RegOpenKeyExA(
  43. HKEY_LOCAL_MACHINE, REGKEY_RAS_IP_PARAM_A, 0,
  44. KEY_READ, &hkeyRASIp);
  45. if(NO_ERROR == dwErr)
  46. {
  47. DWORD dwSize = sizeof(DWORD) , dwData = 0, dwType;
  48. dwErr = RegQueryValueExA(
  49. hkeyRASIp,
  50. "DisableNetbiosOverTcpip",
  51. NULL, &dwType, (BYTE *) &dwData,
  52. &dwSize);
  53. if( (NO_ERROR == dwErr)
  54. && (dwType == REG_DWORD))
  55. {
  56. g_fDisableNetbiosOverTcpip = !!(dwData);
  57. }
  58. RegCloseKey(hkeyRASIp);
  59. dwErr = NO_ERROR;
  60. }
  61. }
  62. TraceHlp("DisableNetbt = %d", g_fDisableNetbiosOverTcpip);
  63. // Keep a ref count in HelperUninitialize, and call HelperUninitialize
  64. // once for each time you call HelperInitialize.
  65. dwErr = HelperInitialize(&hInstance);
  66. if (NO_ERROR != dwErr)
  67. {
  68. // goto LDone; Don't do this. The CriticalSections are not available.
  69. return(dwErr);
  70. }
  71. EnterCriticalSection(&RasSrvrCriticalSection);
  72. if (RasSrvrRunning)
  73. {
  74. goto LDone;
  75. }
  76. //Set the control handler for the process here
  77. if ( !SetProcessShutdownParameters( 510 , SHUTDOWN_NORETRY ) )
  78. {
  79. TraceHlp("SetProcessShutdownParameters failed and returned 0x%x. This is not a fatal error so continuing on with server start", GetLastError());
  80. }
  81. else
  82. {
  83. if ( !SetConsoleCtrlHandler( ShutdownHandlerRoutine, TRUE ) )
  84. {
  85. TraceHlp("SetConsoleCtrlHandler failed and returned 0x%x. This is not a fatal error so continuing on with server start", GetLastError());
  86. }
  87. }
  88. dwErr = rasSrvrInitAdapterName();
  89. if (NO_ERROR != dwErr)
  90. {
  91. goto LDone;
  92. }
  93. dwErr = MprAdminMIBServerConnect(NULL, &RasSrvrHMIBServer);
  94. if (NO_ERROR != dwErr)
  95. {
  96. TraceHlp("MprAdminMIBServerConnect failed and returned 0x%x", dwErr);
  97. goto LDone;
  98. }
  99. pfnMprAdminGetIpAddressForUser = pfnMprGetAddress;
  100. pfnMprAdminReleaseIpAddress = pfnMprReleaseAddress;
  101. DnsStatus = DnsDhcpSrvRegisterInit();
  102. if (DNSDHCP_SUCCESS != DnsStatus)
  103. {
  104. dwErr = DnsStatus;
  105. TraceHlp("DnsDhcpSrvRegisterInit failed and returned 0x%x", dwErr);
  106. goto LDone;
  107. }
  108. // HelperChangeNotification();
  109. dwErr = RasSrvrStart();
  110. if (NO_ERROR != dwErr)
  111. {
  112. TraceHlp("RasSrvrStart failed and returned 0x%x", dwErr);
  113. goto LDone;
  114. }
  115. RasSrvrRunning = TRUE;
  116. LDone:
  117. if (NO_ERROR != dwErr)
  118. {
  119. RasSrvrUninitialize();
  120. }
  121. LeaveCriticalSection(&RasSrvrCriticalSection);
  122. return(dwErr);
  123. }
  124. /*
  125. Returns:
  126. VOID
  127. Notes:
  128. */
  129. VOID
  130. RasSrvrUninitialize(
  131. VOID
  132. )
  133. {
  134. AINODE* pAiNode;
  135. DNS_STATUS DnsStatus;
  136. DWORD dwErr;
  137. TraceHlp("RasSrvrUninitialize");
  138. RasSrvrRunning = FALSE;
  139. /*
  140. Don't call RasSrvrStop when you have RasSrvrCriticalSection. It will call
  141. RasDhcpUninitialize, which will call RasDhcpTimerUninitialize, which will
  142. wait till all the timer work itemss are done. The timer work item could be
  143. rasDhcpAllocateAddress or rasDhcpRenewLease, both of which can call
  144. RasSrvrDhcpCallback, which tries to acquire RasSrvrCriticalSection.
  145. */
  146. SetConsoleCtrlHandler(ShutdownHandlerRoutine, FALSE);
  147. RasSrvrStop(FALSE /* fParametersChanged */);
  148. EnterCriticalSection(&RasSrvrCriticalSection);
  149. if (NULL != RasSrvrHMIBServer)
  150. {
  151. MprAdminMIBServerDisconnect(RasSrvrHMIBServer);
  152. RasSrvrHMIBServer = NULL;
  153. }
  154. pfnMprAdminGetIpAddressForUser = NULL;
  155. pfnMprAdminReleaseIpAddress = NULL;
  156. DnsStatus = DnsDhcpSrvRegisterTerm();
  157. if (DNSDHCP_SUCCESS != DnsStatus)
  158. {
  159. TraceHlp("DnsDhcpSrvRegisterTerm failed and returned 0x%x",
  160. DnsStatus);
  161. }
  162. if (NULL != PDisableDhcpInformServer)
  163. {
  164. PDisableDhcpInformServer();
  165. }
  166. g_fDisableNetbiosOverTcpip = FALSE;
  167. LeaveCriticalSection(&RasSrvrCriticalSection);
  168. }
  169. /*
  170. Returns:
  171. Notes:
  172. */
  173. DWORD
  174. RasSrvrStart(
  175. VOID
  176. )
  177. {
  178. DWORD dwErr;
  179. TraceHlp("RasSrvrStart");
  180. EnterCriticalSection(&RasSrvrCriticalSection);
  181. if (HelperRegVal.fUseDhcpAddressing)
  182. {
  183. dwErr = RasDhcpInitialize();
  184. }
  185. else
  186. {
  187. dwErr = RasStatInitialize();
  188. }
  189. LeaveCriticalSection(&RasSrvrCriticalSection);
  190. return(dwErr);
  191. }
  192. /*
  193. Returns:
  194. VOID
  195. Notes:
  196. */
  197. VOID
  198. RasSrvrStop(
  199. IN BOOL fParametersChanged
  200. )
  201. {
  202. AINODE* pAiNode;
  203. CHAR szIpAddress[MAXIPSTRLEN + 1];
  204. CHAR* sz;
  205. DWORD dwNumBytes;
  206. DWORD dwErr;
  207. WANARP_MAP_SERVER_ADAPTER_INFO info;
  208. TraceHlp("RasSrvrStop");
  209. RasDhcpUninitialize();
  210. EnterCriticalSection(&RasSrvrCriticalSection);
  211. if ( fParametersChanged
  212. && (0 != RasSrvrNboServerIpAddress))
  213. {
  214. AbcdSzFromIpAddress(RasSrvrNboServerIpAddress, szIpAddress);
  215. sz = szIpAddress;
  216. LogEvent(EVENTLOG_WARNING_TYPE, ROUTERLOG_SRV_ADDR_CHANGED, 1,
  217. (CHAR**)&sz);
  218. }
  219. if (!fParametersChanged)
  220. {
  221. while (NULL != RasSrvrAcquiredIpAddresses)
  222. {
  223. RasSrvrReleaseAddress(
  224. RasSrvrAcquiredIpAddresses->nboIpAddr,
  225. RasSrvrAcquiredIpAddresses->wszUserName,
  226. RasSrvrAcquiredIpAddresses->wszPortName,
  227. TRUE);
  228. // Assert: the list decreases by one node in each iteration.
  229. }
  230. }
  231. RasStatUninitialize();
  232. RasStatSetRoutes(RasSrvrNboServerIpAddress, FALSE);
  233. RasTcpSetProxyArp(RasSrvrNboServerIpAddress, FALSE);
  234. rasSrvrSetIpAddressInRegistry(0, 0);
  235. dwErr = PDhcpNotifyConfigChange(NULL, g_rgwcAdapterName, TRUE,
  236. 0, 0, 0, IgnoreFlag);
  237. if (NO_ERROR != dwErr)
  238. {
  239. TraceHlp("DhcpNotifyConfigChange failed and returned %d", dwErr);
  240. }
  241. if (RasSrvrAdapterMapped)
  242. {
  243. // Ask wanarp to unmap the adapter
  244. info.fMap = 0;
  245. if(!DeviceIoControl(HelperWanArpHandle,
  246. IOCTL_WANARP_MAP_SERVER_ADAPTER,
  247. &info,
  248. sizeof(WANARP_MAP_SERVER_ADAPTER_INFO),
  249. &info,
  250. sizeof(WANARP_MAP_SERVER_ADAPTER_INFO),
  251. &dwNumBytes,
  252. NULL))
  253. {
  254. dwErr = GetLastError();
  255. TraceHlp("Error %d unmapping server adapter", dwErr);
  256. }
  257. TraceHlp("RasSrvrAdapterUnMapped");
  258. RasSrvrAdapterMapped = FALSE;
  259. }
  260. RasSrvrNboServerIpAddress = 0;
  261. RasSrvrNboServerSubnetMask = 0;
  262. LeaveCriticalSection(&RasSrvrCriticalSection);
  263. /*
  264. Don't call RasDhcpUninitialize when you have RasSrvrCriticalSection. It
  265. will call RasDhcpTimerUninitialize, which will wait till all the timer work
  266. itemss are done. The timer work item could be rasDhcpAllocateAddress or
  267. rasDhcpRenewLease, both of which can call RasSrvrDhcpCallback, which tries
  268. to acquire RasSrvrCriticalSection.
  269. */
  270. //RasDhcpUninitialize();
  271. }
  272. /*
  273. Returns:
  274. Description:
  275. */
  276. DWORD
  277. RasSrvrAcquireAddress(
  278. IN HPORT hPort,
  279. IN IPADDR nboIpAddressRequested,
  280. OUT IPADDR* pnboIpAddressAllocated,
  281. IN WCHAR* wszUserName,
  282. IN WCHAR* wszPortName
  283. )
  284. {
  285. IPADDR nboIpAddr;
  286. IPADDR nboIpMask;
  287. IPADDR nboIpAddrObtained = 0;
  288. IPADDR nboIpAddrFromDll = 0;
  289. BOOL fNotifyDll = FALSE;
  290. BOOL fEasyNet = FALSE;
  291. WCHAR* wszUserNameTemp = NULL;
  292. WCHAR* wszPortNameTemp = NULL;
  293. AINODE* pAiNode = NULL;
  294. DWORD dwErr = NO_ERROR;
  295. TraceHlp("RasSrvrAcquireAddress(hPort: 0x%x, IP address: 0x%x, "
  296. "UserName: %ws, PortName: %ws)",
  297. hPort, nboIpAddressRequested, wszUserName, wszPortName);
  298. EnterCriticalSection(&RasSrvrCriticalSection);
  299. dwErr = rasSrvrGetAddressForServerAdapter();
  300. if (NO_ERROR != dwErr)
  301. {
  302. goto LDone;
  303. }
  304. if (nboIpAddressRequested == RasSrvrNboServerIpAddress)
  305. {
  306. // The server's address is being requested. Forget the request.
  307. nboIpAddressRequested = 0;
  308. }
  309. nboIpAddr = nboIpAddressRequested;
  310. dwErr = rasSrvrAcquireAddressEx(hPort, &nboIpAddr, &nboIpMask, &fEasyNet);
  311. if ( (NO_ERROR != dwErr)
  312. && (0 != nboIpAddr))
  313. {
  314. // We couldn't get the address we wanted. Let us get any other
  315. // address.
  316. nboIpAddr = 0;
  317. dwErr = rasSrvrAcquireAddressEx(hPort, &nboIpAddr, &nboIpMask,
  318. &fEasyNet);
  319. }
  320. if (NO_ERROR == dwErr)
  321. {
  322. RTASSERT(0 != nboIpAddr);
  323. nboIpAddrObtained = nboIpAddr;
  324. }
  325. else
  326. {
  327. RTASSERT(0 == nboIpAddr);
  328. goto LDone;
  329. }
  330. if (NULL != pfnMprAdminGetIpAddressForUser)
  331. {
  332. nboIpAddrFromDll = nboIpAddrObtained;
  333. dwErr = pfnMprAdminGetIpAddressForUser(wszUserName, wszPortName,
  334. &nboIpAddrFromDll, &fNotifyDll);
  335. if (NO_ERROR != dwErr)
  336. {
  337. TraceHlp("MprAdminGetIpAddressForUser(%ws, %ws, 0x%x) failed "
  338. "and returned %d",
  339. wszUserName, wszPortName, nboIpAddrFromDll, dwErr);
  340. goto LDone;
  341. }
  342. if ( (0 == nboIpAddrFromDll)
  343. || (RasSrvrNboServerIpAddress == nboIpAddrFromDll))
  344. {
  345. // We can't give the server's address.
  346. TraceHlp("3rd party DLL wants to hand out bad address 0x%x",
  347. nboIpAddrFromDll);
  348. dwErr = ERROR_NOT_FOUND;
  349. goto LDone;
  350. }
  351. if (nboIpAddrObtained != nboIpAddrFromDll)
  352. {
  353. TraceHlp("3rd party DLL wants to hand out address 0x%x",
  354. nboIpAddrFromDll);
  355. // We have to make sure that nboIpAddrFromDll is available.
  356. // The DLL changed what we had got from Dhcp or Static. Release the
  357. // old address.
  358. if (HelperRegVal.fUseDhcpAddressing)
  359. {
  360. RasDhcpReleaseAddress(nboIpAddrObtained);
  361. }
  362. else
  363. {
  364. RasStatReleaseAddress(nboIpAddrObtained);
  365. }
  366. nboIpAddrObtained = 0;
  367. fEasyNet = FALSE;
  368. nboIpAddr = nboIpAddrFromDll;
  369. dwErr = rasSrvrAcquireAddressEx(hPort, &nboIpAddr, &nboIpMask,
  370. &fEasyNet);
  371. if (NO_ERROR != dwErr)
  372. {
  373. goto LDone;
  374. }
  375. nboIpAddrObtained = nboIpAddr;
  376. }
  377. }
  378. wszUserNameTemp = _wcsdup(wszUserName);
  379. if (NULL == wszUserNameTemp)
  380. {
  381. dwErr = ERROR_OUTOFMEMORY;
  382. TraceHlp("_strdup failed and returned %d", dwErr);
  383. goto LDone;
  384. }
  385. wszPortNameTemp = _wcsdup(wszPortName);
  386. if (NULL == wszPortNameTemp)
  387. {
  388. dwErr = ERROR_OUTOFMEMORY;
  389. TraceHlp("_strdup failed and returned %d", dwErr);
  390. goto LDone;
  391. }
  392. pAiNode = LocalAlloc(LPTR, sizeof(AINODE));
  393. if (NULL == pAiNode)
  394. {
  395. dwErr = GetLastError();
  396. TraceHlp("LocalAlloc failed and returned %d", dwErr);
  397. goto LDone;
  398. }
  399. pAiNode->hPort = hPort;
  400. pAiNode->fFlags = fNotifyDll ? AINODE_FLAG_NOTIFY_DLL : 0;
  401. pAiNode->fFlags |= fEasyNet ? AINODE_FLAG_EASYNET : 0;
  402. pAiNode->wszUserName = wszUserNameTemp;
  403. pAiNode->wszPortName = wszPortNameTemp;
  404. pAiNode->pNext = RasSrvrAcquiredIpAddresses;
  405. RasSrvrAcquiredIpAddresses = pAiNode;
  406. pAiNode->nboIpAddr = *pnboIpAddressAllocated = nboIpAddrObtained;
  407. LDone:
  408. if (NO_ERROR != dwErr)
  409. {
  410. if (fNotifyDll)
  411. {
  412. pfnMprAdminReleaseIpAddress(wszUserName, wszPortName,
  413. &nboIpAddrFromDll);
  414. }
  415. if (0 != nboIpAddrObtained)
  416. {
  417. if (HelperRegVal.fUseDhcpAddressing)
  418. {
  419. RasDhcpReleaseAddress(nboIpAddrObtained);
  420. }
  421. else
  422. {
  423. RasStatReleaseAddress(nboIpAddrObtained);
  424. }
  425. }
  426. free(wszUserNameTemp);
  427. free(wszPortNameTemp);
  428. }
  429. LeaveCriticalSection(&RasSrvrCriticalSection);
  430. return(dwErr);
  431. }
  432. /*
  433. Returns:
  434. Description:
  435. */
  436. VOID
  437. RasSrvrReleaseAddress(
  438. IN IPADDR nboIpAddress,
  439. IN WCHAR* wszUserName,
  440. IN WCHAR* wszPortName,
  441. IN BOOL fDeregister
  442. )
  443. {
  444. DNS_STATUS DnsStatus;
  445. REGISTER_HOST_ENTRY HostAddr;
  446. AINODE* pAiNode = NULL;
  447. DWORD dwErr;
  448. TraceHlp("RasSrvrReleaseAddress(IP address: 0x%x, "
  449. "UserName: %ws, PortName: %ws)",
  450. nboIpAddress, wszUserName, wszPortName);
  451. EnterCriticalSection(&RasSrvrCriticalSection);
  452. if (fDeregister)
  453. {
  454. HostAddr.dwOptions = REGISTER_HOST_PTR;
  455. HostAddr.Addr.ipAddr = nboIpAddress;
  456. DnsStatus = DnsDhcpSrvRegisterHostName_W(
  457. HostAddr, NULL, 600,
  458. DYNDNS_DELETE_ENTRY | DYNDNS_REG_FORWARD,
  459. NULL, NULL, NULL, 0);
  460. if (DNSDHCP_SUCCESS != DnsStatus)
  461. {
  462. TraceHlp("DnsDhcpSrvRegisterHostName_A(0x%x) failed: 0x%x",
  463. nboIpAddress, DnsStatus);
  464. }
  465. }
  466. pAiNode = rasSrvrFindAiNode(nboIpAddress, TRUE /* fRemoveFromList */);
  467. if (NULL == pAiNode)
  468. {
  469. TraceHlp("Couldn't find address 0x%x in Acquired Ip Addresses list",
  470. nboIpAddress);
  471. goto LDone;
  472. }
  473. if (HelperRegVal.fUseDhcpAddressing)
  474. {
  475. RasDhcpReleaseAddress(nboIpAddress);
  476. }
  477. else
  478. {
  479. RasStatReleaseAddress(nboIpAddress);
  480. }
  481. if (pAiNode->fFlags & AINODE_FLAG_NOTIFY_DLL)
  482. {
  483. pfnMprAdminReleaseIpAddress(wszUserName, wszPortName, &nboIpAddress);
  484. }
  485. if (pAiNode->fFlags & AINODE_FLAG_ACTIVATED)
  486. {
  487. if (!(pAiNode->fFlags & AINODE_FLAG_EASYNET))
  488. {
  489. RasTcpSetProxyArp(nboIpAddress, FALSE);
  490. }
  491. dwErr = rasSrvrGetAddressForServerAdapter();
  492. if (NO_ERROR != dwErr)
  493. {
  494. TraceHlp("Couldn't get address for server adapter");
  495. goto LDone;
  496. }
  497. RasTcpSetRoute(nboIpAddress,
  498. nboIpAddress,
  499. HOST_MASK,
  500. RasSrvrNboServerIpAddress,
  501. FALSE,
  502. 1,
  503. TRUE);
  504. }
  505. LDone:
  506. LeaveCriticalSection(&RasSrvrCriticalSection);
  507. rasSrvrFreeAiNode(pAiNode);
  508. }
  509. /*
  510. Returns:
  511. Description:
  512. Look up the DNS server, WINS server, and "this server" addresses.
  513. */
  514. DWORD
  515. RasSrvrQueryServerAddresses(
  516. IN OUT IPINFO* pIpInfo
  517. )
  518. {
  519. DWORD dwNumBytes;
  520. IPADDR nboWins1 = 0;
  521. IPADDR nboWins2 = 0;
  522. IPADDR nboDns1 = 0;
  523. IPADDR nboDns2 = 0;
  524. DWORD dwErr = NO_ERROR;
  525. TraceHlp("RasSrvrQueryServerAddresses");
  526. EnterCriticalSection(&RasSrvrCriticalSection);
  527. dwErr = rasSrvrGetAddressForServerAdapter();
  528. if (NO_ERROR != dwErr)
  529. {
  530. goto LDone;
  531. }
  532. // Ignore errors; its OK not to be able to give DNS or WINS server
  533. // addresses
  534. GetPreferredAdapterInfo(NULL, &nboDns1, &nboDns2, &nboWins1,
  535. &nboWins2, NULL);
  536. if (TRUE == HelperRegVal.fSuppressWINSNameServers)
  537. {
  538. nboWins1 = 0;
  539. nboWins2 = 0;
  540. }
  541. else if (0 != HelperRegVal.nboWINSNameServer1)
  542. {
  543. nboWins1 = HelperRegVal.nboWINSNameServer1;
  544. nboWins2 = HelperRegVal.nboWINSNameServer2;
  545. }
  546. if (TRUE == HelperRegVal.fSuppressDNSNameServers)
  547. {
  548. nboDns1 = 0;
  549. nboDns2 = 0;
  550. }
  551. else if (0 != HelperRegVal.nboDNSNameServer1)
  552. {
  553. nboDns1 = HelperRegVal.nboDNSNameServer1;
  554. nboDns2 = HelperRegVal.nboDNSNameServer2;
  555. }
  556. pIpInfo->nboDNSAddress = nboDns1;
  557. pIpInfo->nboDNSAddressBackup = nboDns2;
  558. pIpInfo->nboWINSAddress = nboWins1;
  559. pIpInfo->nboWINSAddressBackup = nboWins2;
  560. pIpInfo->nboServerIpAddress = RasSrvrNboServerIpAddress;
  561. pIpInfo->nboServerSubnetMask = RasSrvrNboServerSubnetMask;
  562. LDone:
  563. LeaveCriticalSection(&RasSrvrCriticalSection);
  564. return(dwErr);
  565. }
  566. /*
  567. Returns:
  568. Description:
  569. Does two things - RasTcpSetRoute and RasTcpSetProxyArp.
  570. */
  571. DWORD
  572. RasSrvrActivateIp(
  573. IN IPADDR nboIpAddress,
  574. IN DWORD dwUsage
  575. )
  576. {
  577. AINODE* pAiNode;
  578. DWORD dwErr = NO_ERROR;
  579. TraceHlp("RasSrvrActivateIp(IpAddr = 0x%x, dwUsage = %d)",
  580. nboIpAddress, dwUsage);
  581. EnterCriticalSection(&RasSrvrCriticalSection);
  582. pAiNode = rasSrvrFindAiNode(nboIpAddress, FALSE /* fRemoveFromList */);
  583. if (NULL == pAiNode)
  584. {
  585. TraceHlp("Couldn't find address 0x%x in Acquired Ip Addresses list",
  586. nboIpAddress);
  587. dwErr = ERROR_IP_CONFIGURATION;
  588. goto LDone;
  589. }
  590. pAiNode->fFlags |= AINODE_FLAG_ACTIVATED;
  591. RasTcpSetProxyArp(nboIpAddress, TRUE);
  592. if (dwUsage != DU_ROUTER)
  593. {
  594. // Add a route to the route table. Router connections get
  595. // added by router manager
  596. dwErr = rasSrvrGetAddressForServerAdapter();
  597. if (NO_ERROR != dwErr)
  598. {
  599. // Don't return an error, because we have done RasTcpSetProxyArp.
  600. dwErr = NO_ERROR;
  601. TraceHlp("Couldn't get address for server adapter");
  602. goto LDone;
  603. }
  604. RasTcpSetRoute(nboIpAddress,
  605. nboIpAddress,
  606. HOST_MASK,
  607. RasSrvrNboServerIpAddress,
  608. TRUE,
  609. 1,
  610. TRUE);
  611. }
  612. LDone:
  613. LeaveCriticalSection(&RasSrvrCriticalSection);
  614. return(dwErr);
  615. }
  616. /*
  617. Returns:
  618. VOID
  619. Description:
  620. Called by dhcp address code when the lease for a given address expires.
  621. nboIpAddr = 0 indicates the server's IP address.
  622. */
  623. VOID
  624. RasSrvrDhcpCallback(
  625. IN IPADDR nboIpAddr
  626. )
  627. {
  628. AINODE* pAiNode = NULL;
  629. CHAR szIpAddress[MAXIPSTRLEN + 1];
  630. CHAR* sz;
  631. DWORD dwErr = NO_ERROR;
  632. TraceHlp("RasSrvrDhcpCallback(0x%x)", nboIpAddr);
  633. EnterCriticalSection(&RasSrvrCriticalSection);
  634. if ( (0 == nboIpAddr)
  635. && (0 == RasSrvrNboServerIpAddress))
  636. {
  637. // The server hasn't got an IP address yet. Its lease hasn't really
  638. // expired. We are just simulating it.
  639. goto LDone;
  640. }
  641. if ( (0 == nboIpAddr)
  642. || (nboIpAddr == RasSrvrNboServerIpAddress))
  643. {
  644. TraceHlp("******** SERVER ADDRESS (0x%x) LEASE EXPIRED ********",
  645. RasSrvrNboServerIpAddress);
  646. AbcdSzFromIpAddress(RasSrvrNboServerIpAddress, szIpAddress);
  647. sz = szIpAddress;
  648. // Log that the server adapter address lease was lost
  649. LogEvent(EVENTLOG_WARNING_TYPE, ROUTERLOG_SRV_ADDR_CHANGED, 1,
  650. (CHAR**)&sz);
  651. // Unroute all the connected clients
  652. while (NULL != RasSrvrAcquiredIpAddresses)
  653. {
  654. RasSrvrReleaseAddress(
  655. RasSrvrAcquiredIpAddresses->nboIpAddr,
  656. RasSrvrAcquiredIpAddresses->wszUserName,
  657. RasSrvrAcquiredIpAddresses->wszPortName,
  658. TRUE);
  659. // Assert: the list decreases by one node in each iteration.
  660. }
  661. RasTcpSetProxyArp(RasSrvrNboServerIpAddress, FALSE);
  662. rasSrvrSetIpAddressInRegistry(0, 0);
  663. dwErr = PDhcpNotifyConfigChange(NULL, g_rgwcAdapterName, TRUE,
  664. 0, 0, 0, IgnoreFlag);
  665. if (NO_ERROR != dwErr)
  666. {
  667. TraceHlp("DhcpNotifyConfigChange failed and returned %d", dwErr);
  668. }
  669. RasSrvrNboServerIpAddress = 0;
  670. RasSrvrNboServerSubnetMask = 0;
  671. }
  672. else
  673. {
  674. pAiNode = rasSrvrFindAiNode(nboIpAddr, TRUE /* fRemoveFromList */);
  675. if (NULL != pAiNode)
  676. {
  677. TraceHlp("******** CLIENT ADDRESS (0x%x) LEASE EXPIRED ********",
  678. nboIpAddr);
  679. AbcdSzFromIpAddress(nboIpAddr, szIpAddress);
  680. sz = szIpAddress;
  681. // Log that the client's address lease could not be renewed
  682. LogEvent(EVENTLOG_WARNING_TYPE, ROUTERLOG_CLIENT_ADDR_LEASE_LOST, 1,
  683. (CHAR**)&sz);
  684. RasSrvrReleaseAddress(nboIpAddr, pAiNode->wszUserName,
  685. pAiNode->wszPortName, TRUE);
  686. }
  687. }
  688. LDone:
  689. LeaveCriticalSection(&RasSrvrCriticalSection);
  690. rasSrvrFreeAiNode(pAiNode);
  691. }
  692. /*
  693. Returns:
  694. VOID
  695. Description:
  696. */
  697. VOID
  698. RasSrvrEnableRouter(
  699. BOOL fEnable
  700. )
  701. {
  702. DWORD dwErr;
  703. DEFINE_MIB_BUFFER(pSetInfo, MIB_IPSTATS, pSetStats);
  704. TraceHlp("RasSrvrEnableRouter(%d)", fEnable);
  705. EnterCriticalSection(&RasSrvrCriticalSection);
  706. pSetInfo->dwId = IP_STATS;
  707. pSetStats->dwForwarding = fEnable? MIB_IP_FORWARDING: MIB_IP_NOT_FORWARDING;
  708. pSetStats->dwDefaultTTL = MIB_USE_CURRENT_TTL;
  709. dwErr = MprAdminMIBEntrySet(
  710. RasSrvrHMIBServer,
  711. PID_IP,
  712. IPRTRMGR_PID,
  713. (VOID*)pSetInfo,
  714. MIB_INFO_SIZE(MIB_IPSTATS));
  715. if (NO_ERROR != dwErr)
  716. {
  717. TraceHlp("MprAdminMIBEntrySet failed with error %x", dwErr);
  718. }
  719. LeaveCriticalSection(&RasSrvrCriticalSection);
  720. }
  721. /*
  722. Returns:
  723. VOID
  724. Description:
  725. */
  726. VOID
  727. RasSrvrAdapterUnmapped(
  728. VOID
  729. )
  730. {
  731. if (HelperInitialized)
  732. {
  733. EnterCriticalSection(&RasSrvrCriticalSection);
  734. RasSrvrAdapterMapped = FALSE;
  735. TraceHlp("RasSrvrAdapterUnMapped");
  736. LeaveCriticalSection(&RasSrvrCriticalSection);
  737. }
  738. }
  739. /*
  740. Returns:
  741. VOID
  742. Description:
  743. */
  744. DWORD
  745. rasSrvrInitAdapterName(
  746. VOID
  747. )
  748. {
  749. DWORD dwNumBytes;
  750. WANARP_ADD_INTERFACE_INFO info;
  751. DWORD dwErr = NO_ERROR;
  752. info.dwUserIfIndex = WANARP_INVALID_IFINDEX;
  753. info.bCallinInterface = TRUE;
  754. if (!DeviceIoControl(HelperWanArpHandle,
  755. IOCTL_WANARP_ADD_INTERFACE,
  756. &info,
  757. sizeof(WANARP_ADD_INTERFACE_INFO),
  758. &info,
  759. sizeof(WANARP_ADD_INTERFACE_INFO),
  760. &dwNumBytes,
  761. NULL))
  762. {
  763. dwErr = GetLastError();
  764. TraceHlp("rasSrvrInitAdapterName: Error %d getting server name",
  765. dwErr);
  766. goto LDone;
  767. }
  768. wcsncpy(g_rgwcAdapterName, info.rgwcDeviceName, WANARP_MAX_DEVICE_NAME_LEN);
  769. // The RAS server adapter must not be registered with DNS. (These API's are
  770. // called in IpcpProjectionNotification also.)
  771. DnsDisableAdapterDomainNameRegistration(g_rgwcAdapterName);
  772. DnsDisableDynamicRegistration(g_rgwcAdapterName);
  773. LDone:
  774. return(dwErr);
  775. }
  776. /*
  777. Returns:
  778. Description:
  779. */
  780. AINODE*
  781. rasSrvrFindAiNode(
  782. IN IPADDR nboIpAddr,
  783. IN BOOL fRemoveFromList
  784. )
  785. {
  786. AINODE* pNode;
  787. AINODE* pNodePrev;
  788. EnterCriticalSection(&RasSrvrCriticalSection);
  789. for (pNode = RasSrvrAcquiredIpAddresses, pNodePrev = pNode;
  790. NULL != pNode;
  791. pNodePrev = pNode, pNode = pNode->pNext)
  792. {
  793. if (pNode->nboIpAddr == nboIpAddr)
  794. {
  795. break;
  796. }
  797. }
  798. if (!fRemoveFromList)
  799. {
  800. goto LDone;
  801. }
  802. if (NULL == pNode)
  803. {
  804. goto LDone;
  805. }
  806. if (pNode == pNodePrev)
  807. {
  808. RTASSERT(pNode == RasSrvrAcquiredIpAddresses);
  809. RasSrvrAcquiredIpAddresses = pNode->pNext;
  810. goto LDone;
  811. }
  812. pNodePrev->pNext = pNode->pNext;
  813. LDone:
  814. LeaveCriticalSection(&RasSrvrCriticalSection);
  815. return(pNode);
  816. }
  817. /*
  818. Returns:
  819. Description:
  820. */
  821. VOID
  822. rasSrvrFreeAiNode(
  823. IN AINODE* pNode
  824. )
  825. {
  826. if (NULL != pNode)
  827. {
  828. free(pNode->wszUserName);
  829. free(pNode->wszPortName);
  830. LocalFree(pNode);
  831. }
  832. }
  833. /*
  834. Returns:
  835. Description:
  836. */
  837. DWORD
  838. rasSrvrSetIpAddressInRegistry(
  839. IN IPADDR nboIpAddr,
  840. IN IPADDR nboIpMask
  841. )
  842. {
  843. TCPIP_INFO* pTcpipInfo = NULL;
  844. DWORD dwErr = NO_ERROR;
  845. dwErr = LoadTcpipInfo(&pTcpipInfo, g_rgwcAdapterName,
  846. TRUE /* fAdapterOnly */);
  847. if (NO_ERROR != dwErr)
  848. {
  849. TraceHlp("LoadTcpipInfo(%ws) failed and returned %d",
  850. g_rgwcAdapterName, dwErr);
  851. goto LDone;
  852. }
  853. AbcdWszFromIpAddress(nboIpAddr, pTcpipInfo->wszIPAddress);
  854. AbcdWszFromIpAddress(nboIpMask, pTcpipInfo->wszSubnetMask);
  855. if(g_fDisableNetbiosOverTcpip)
  856. {
  857. TraceHlp("rasSrvrSetIpAddressInRegistry: Netbios disabled");
  858. pTcpipInfo->fDisableNetBIOSoverTcpip = TRUE;
  859. }
  860. pTcpipInfo->fChanged = TRUE;
  861. dwErr = SaveTcpipInfo(pTcpipInfo);
  862. if (dwErr != NO_ERROR)
  863. {
  864. TraceHlp("SaveTcpipInfo(%ws) failed and returned %d",
  865. g_rgwcAdapterName, dwErr);
  866. goto LDone;
  867. }
  868. LDone:
  869. FreeTcpipInfo(&pTcpipInfo);
  870. return(dwErr);
  871. }
  872. /*
  873. Returns:
  874. Notes:
  875. */
  876. DWORD
  877. rasSrvrAcquireAddressEx(
  878. IN HPORT hPort,
  879. IN OUT IPADDR* pnboIpAddr,
  880. IN OUT IPADDR* pnboIpMask,
  881. OUT BOOL* pfEasyNet
  882. )
  883. {
  884. BOOL fExitWhile;
  885. BOOL fAnyAddress;
  886. AINODE* pAiNode;
  887. DWORD dwErr = NO_ERROR;
  888. EnterCriticalSection(&RasSrvrCriticalSection);
  889. if (NULL != pfEasyNet)
  890. {
  891. *pfEasyNet = FALSE;
  892. }
  893. fAnyAddress = (0 == *pnboIpAddr);
  894. fExitWhile = FALSE;
  895. while (!fExitWhile)
  896. {
  897. dwErr = NO_ERROR;
  898. if (fAnyAddress)
  899. {
  900. if (HelperRegVal.fUseDhcpAddressing)
  901. {
  902. dwErr = RasDhcpAcquireAddress(hPort, pnboIpAddr, pnboIpMask,
  903. pfEasyNet);
  904. }
  905. else
  906. {
  907. dwErr = RasStatAcquireAddress(hPort, pnboIpAddr, pnboIpMask);
  908. }
  909. }
  910. if (NO_ERROR != dwErr)
  911. {
  912. goto LDone;
  913. }
  914. for (pAiNode = RasSrvrAcquiredIpAddresses; NULL != pAiNode;
  915. pAiNode = pAiNode->pNext)
  916. {
  917. if (pAiNode->nboIpAddr == *pnboIpAddr)
  918. {
  919. // This address is in use
  920. if (fAnyAddress)
  921. {
  922. // Ask for another address
  923. goto LWhileEnd;
  924. }
  925. else
  926. {
  927. TraceHlp("Address 0x%x is already in use", *pnboIpAddr);
  928. dwErr = ERROR_PPP_REQUIRED_ADDRESS_REJECTED;
  929. goto LDone;
  930. }
  931. }
  932. }
  933. dwErr = NO_ERROR;
  934. fExitWhile = TRUE;
  935. LWhileEnd:
  936. ;
  937. }
  938. LDone:
  939. LeaveCriticalSection(&RasSrvrCriticalSection);
  940. if ( fAnyAddress
  941. && (NO_ERROR != dwErr))
  942. {
  943. LogEvent(EVENTLOG_WARNING_TYPE, ROUTERLOG_NO_IP_ADDRESS, 0, NULL);
  944. }
  945. return(dwErr);
  946. }
  947. /*
  948. Returns:
  949. Description:
  950. */
  951. DWORD
  952. rasSrvrGetAddressForServerAdapter(
  953. VOID
  954. )
  955. {
  956. IPADDR nboIpAddr = 0;
  957. IPADDR nboIpMask;
  958. CHAR szIpAddress[MAXIPSTRLEN + 1];
  959. CHAR* sz;
  960. BOOL fAddrAcquired = FALSE;
  961. BOOL fAdapterMapped = FALSE;
  962. DWORD dwNumBytes;
  963. DWORD dwErrTemp;
  964. DWORD dwErr = NO_ERROR;
  965. WANARP_MAP_SERVER_ADAPTER_INFO info;
  966. TraceHlp("rasSrvrGetAddressForServerAdapter");
  967. EnterCriticalSection(&RasSrvrCriticalSection);
  968. if (!RasSrvrAdapterMapped)
  969. {
  970. // First time - ask wanarp to map the adapter
  971. info.fMap = 1;
  972. info.dwAdapterIndex = (DWORD)-1;
  973. if(!DeviceIoControl(HelperWanArpHandle,
  974. IOCTL_WANARP_MAP_SERVER_ADAPTER,
  975. &info,
  976. sizeof(WANARP_MAP_SERVER_ADAPTER_INFO),
  977. &info,
  978. sizeof(WANARP_MAP_SERVER_ADAPTER_INFO),
  979. &dwNumBytes,
  980. NULL))
  981. {
  982. dwErr = GetLastError();
  983. TraceHlp("Error %d mapping server adapter", dwErr);
  984. goto LDone;
  985. }
  986. TraceHlp("RasSrvrAdapterMapped");
  987. RasSrvrAdapterMapped = TRUE;
  988. fAdapterMapped = TRUE;
  989. }
  990. if (0 != RasSrvrNboServerIpAddress)
  991. {
  992. if (!fAdapterMapped)
  993. {
  994. goto LDone;
  995. }
  996. }
  997. else
  998. {
  999. dwErr = rasSrvrAcquireAddressEx((HPORT) ULongToPtr(((ULONG) SERVER_HPORT)),
  1000. &nboIpAddr, &nboIpMask, NULL);
  1001. if (NO_ERROR != dwErr)
  1002. {
  1003. goto LDone;
  1004. }
  1005. fAddrAcquired = TRUE;
  1006. RasSrvrNboServerIpAddress = nboIpAddr;
  1007. RasSrvrNboServerSubnetMask = HOST_MASK;
  1008. }
  1009. dwErr = rasSrvrSetIpAddressInRegistry(
  1010. RasSrvrNboServerIpAddress, RasSrvrNboServerSubnetMask);
  1011. if (NO_ERROR != dwErr)
  1012. {
  1013. goto LDone;
  1014. }
  1015. dwErr = PDhcpNotifyConfigChange(NULL, g_rgwcAdapterName, TRUE, 0,
  1016. RasSrvrNboServerIpAddress,
  1017. RasSrvrNboServerSubnetMask,
  1018. IgnoreFlag);
  1019. if (NO_ERROR != dwErr)
  1020. {
  1021. TraceHlp("DhcpNotifyConfigChange(%ws) failed and returned %d",
  1022. g_rgwcAdapterName, dwErr);
  1023. goto LDone;
  1024. }
  1025. /*
  1026. It looks like the default subnet route no longer gets added.
  1027. // Now delete the default subnet route added as a result of setting the
  1028. // adapter's IP address and subnet mask
  1029. RasTcpSetRoute(RasSrvrNboServerIpAddress & RasSrvrNboServerSubnetMask,
  1030. RasSrvrNboServerIpAddress,
  1031. RasSrvrNboServerSubnetMask,
  1032. RasSrvrNboServerIpAddress,
  1033. FALSE,
  1034. 1,
  1035. TRUE);
  1036. */
  1037. RasTcpSetProxyArp(RasSrvrNboServerIpAddress, TRUE);
  1038. if (!HelperRegVal.fUseDhcpAddressing)
  1039. {
  1040. RasStatSetRoutes(RasSrvrNboServerIpAddress, TRUE);
  1041. }
  1042. AbcdSzFromIpAddress(RasSrvrNboServerIpAddress, szIpAddress);
  1043. sz = szIpAddress;
  1044. LogEvent(EVENTLOG_INFORMATION_TYPE, ROUTERLOG_SRV_ADDR_ACQUIRED, 1,
  1045. (CHAR**)&sz);
  1046. TraceHlp("Acquired IP address 0x%x(%s) and subnet mask 0x%x for the server",
  1047. RasSrvrNboServerIpAddress, szIpAddress, RasSrvrNboServerSubnetMask);
  1048. LDone:
  1049. if (NO_ERROR != dwErr)
  1050. {
  1051. // Some cleanup is required here. We must release the
  1052. // address if RasSrvrNboServerIpAddress != 0 and get rid of the
  1053. // variable fAddrAcquired.
  1054. if (fAddrAcquired)
  1055. {
  1056. if (HelperRegVal.fUseDhcpAddressing)
  1057. {
  1058. RasDhcpReleaseAddress(nboIpAddr);
  1059. }
  1060. else
  1061. {
  1062. RasStatReleaseAddress(nboIpAddr);
  1063. }
  1064. RasTcpSetProxyArp(RasSrvrNboServerIpAddress, FALSE);
  1065. }
  1066. RasSrvrNboServerIpAddress = RasSrvrNboServerSubnetMask = 0;
  1067. rasSrvrSetIpAddressInRegistry(0, 0);
  1068. dwErrTemp = PDhcpNotifyConfigChange(NULL, g_rgwcAdapterName, TRUE,
  1069. 0, 0, 0, IgnoreFlag);
  1070. if (NO_ERROR != dwErrTemp)
  1071. {
  1072. TraceHlp("DhcpNotifyConfigChange failed and returned %d",
  1073. dwErrTemp);
  1074. }
  1075. }
  1076. LeaveCriticalSection(&RasSrvrCriticalSection);
  1077. return(dwErr);
  1078. }