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.

3415 lines
96 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Abstract:
  4. Functions implementing the 6to4 service, to provide IPv6 connectivity
  5. over an IPv4 network.
  6. --*/
  7. #include "precomp.h"
  8. #pragma hdrstop
  9. extern DWORD
  10. APIENTRY
  11. RasQuerySharedPrivateLan(
  12. OUT GUID* LanGuid );
  13. STATE g_stService = DISABLED;
  14. ULONG g_ulEventCount = 0;
  15. //
  16. // Worst metric for which we can add a route
  17. //
  18. #define UNREACHABLE 0x7fffffff
  19. const IN6_ADDR SixToFourPrefix = { 0x20, 0x02, 0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
  20. #define SIXTOFOUR_METRIC 1000
  21. // Metric of subnet/sitelocal route on a router
  22. #define SUBNET_ROUTE_METRIC 1
  23. #define SITELOCAL_ROUTE_METRIC 1
  24. // Information on a 6to4 subnet that we've generated as a router
  25. typedef struct _SUBNET_CONTEXT {
  26. IN_ADDR V4Addr;
  27. int Publish;
  28. u_int ValidLifetime;
  29. u_int PreferredLifetime;
  30. } SUBNET_CONTEXT, *PSUBNET_CONTEXT;
  31. //
  32. // Variables for settings
  33. //
  34. #define DEFAULT_ENABLE_6TO4 AUTOMATIC
  35. #define DEFAULT_ENABLE_RESOLUTION AUTOMATIC
  36. #define DEFAULT_ENABLE_ROUTING AUTOMATIC
  37. #define DEFAULT_RESOLUTION_INTERVAL (24 * HOURS)
  38. #define DEFAULT_ENABLE_SITELOCALS ENABLED
  39. #define DEFAULT_ENABLE_6OVER4 DISABLED
  40. #define DEFAULT_ENABLE_V4COMPAT DISABLED
  41. #define DEFAULT_RELAY_NAME L"6to4.ipv6.microsoft.com."
  42. #define DEFAULT_UNDO_ON_STOP ENABLED
  43. #define KEY_ENABLE_6TO4 L"Enable6to4"
  44. #define KEY_ENABLE_RESOLUTION L"EnableResolution"
  45. #define KEY_ENABLE_ROUTING L"EnableRouting"
  46. #define KEY_ENABLE_SITELOCALS L"EnableSiteLocals"
  47. #define KEY_ENABLE_6OVER4 L"Enable6over4"
  48. #define KEY_ENABLE_V4COMPAT L"EnableV4Compat"
  49. #define KEY_RESOLUTION_INTERVAL L"ResolutionInterval"
  50. #define KEY_UNDO_ON_STOP L"UndoOnStop"
  51. #define KEY_RELAY_NAME L"RelayName"
  52. typedef enum {
  53. IPV4_SCOPE_NODE,
  54. IPV4_SCOPE_LINK,
  55. IPV4_SCOPE_SM_SITE,
  56. IPV4_SCOPE_MD_SITE,
  57. IPV4_SCOPE_LG_SITE,
  58. IPV4_SCOPE_GLOBAL,
  59. NUM_IPV4_SCOPES
  60. } IPV4_SCOPE;
  61. //
  62. // Global config settings
  63. //
  64. typedef struct {
  65. STATE stEnable6to4;
  66. STATE stEnableRouting;
  67. STATE stEnableResolution;
  68. STATE stEnableSiteLocals;
  69. STATE stEnable6over4;
  70. STATE stEnableV4Compat;
  71. ULONG ulResolutionInterval; // in minutes
  72. WCHAR pwszRelayName[NI_MAXHOST];
  73. STATE stUndoOnStop;
  74. } GLOBAL_SETTINGS;
  75. GLOBAL_SETTINGS g_GlobalSettings;
  76. typedef struct {
  77. STATE st6to4State;
  78. STATE stRoutingState;
  79. STATE stResolutionState;
  80. } GLOBAL_STATE;
  81. GLOBAL_STATE g_GlobalState = { DISABLED, DISABLED, DISABLED };
  82. const ADDR_LIST EmptyAddressList = {0};
  83. // List of public IPv4 addresses used when updating the routing state
  84. ADDR_LIST *g_pIpv4AddressList = NULL;
  85. //
  86. // Variables for interfaces (addresses and routing)
  87. //
  88. typedef struct _IF_SETTINGS {
  89. WCHAR pwszAdapterName[MAX_ADAPTER_NAME];
  90. STATE stEnableRouting; // be a router on this private iface?
  91. } IF_SETTINGS, *PIF_SETTINGS;
  92. typedef struct _IF_SETTINGS_LIST {
  93. ULONG ulNumInterfaces;
  94. IF_SETTINGS arrIf[0];
  95. } IF_SETTINGS_LIST, *PIF_SETTINGS_LIST;
  96. PIF_SETTINGS_LIST g_pInterfaceSettingsList = NULL;
  97. typedef struct _IF_INFO {
  98. WCHAR pwszAdapterName[MAX_ADAPTER_NAME];
  99. ULONG ulIPv6IfIndex;
  100. STATE stRoutingState; // be a router on this private iface?
  101. ULONG ulNumGlobals;
  102. ADDR_LIST *pAddressList;
  103. } IF_INFO, *PIF_INFO;
  104. typedef struct _IF_LIST {
  105. ULONG ulNumInterfaces;
  106. ULONG ulNumScopedAddrs[NUM_IPV4_SCOPES];
  107. IF_INFO arrIf[0];
  108. } IF_LIST, *PIF_LIST;
  109. PIF_LIST g_pInterfaceList = NULL;
  110. HANDLE g_hAddressChangeEvent = NULL;
  111. OVERLAPPED g_hAddressChangeOverlapped;
  112. HANDLE g_hAddressChangeWaitHandle = NULL;
  113. HANDLE g_hRouteChangeEvent = NULL;
  114. OVERLAPPED g_hRouteChangeOverlapped;
  115. HANDLE g_hRouteChangeWaitHandle = NULL;
  116. // This state tracks whether there are any global IPv4 addresses.
  117. STATE g_st6to4State = DISABLED;
  118. BOOL g_b6to4Required = TRUE;
  119. SOCKET g_sIPv4Socket = INVALID_SOCKET;
  120. //////////////////////////
  121. // Routines for 6to4
  122. //////////////////////////
  123. VOID
  124. Update6to4State(
  125. VOID
  126. );
  127. VOID
  128. PreDelete6to4Address(
  129. IN LPSOCKADDR_IN Ipv4Address,
  130. IN PIF_LIST InterfaceList,
  131. IN STATE OldRoutingState
  132. );
  133. VOID
  134. Delete6to4Address(
  135. IN LPSOCKADDR_IN Ipv4Address,
  136. IN PIF_LIST InterfaceList,
  137. IN STATE OldRoutingState
  138. );
  139. VOID
  140. Add6to4Address(
  141. IN LPSOCKADDR_IN Ipv4Address,
  142. IN PIF_LIST InterfaceList,
  143. IN STATE OldRoutingState
  144. );
  145. VOID
  146. PreDelete6to4Routes(
  147. VOID
  148. );
  149. VOID
  150. Update6to4Routes(
  151. VOID
  152. );
  153. ///////////////////////////////////////////////////////////////////////////
  154. // Variables for relays
  155. //
  156. typedef struct _RELAY_INFO {
  157. SOCKADDR_IN sinAddress; // IPv4 address
  158. SOCKADDR_IN6 sin6Address; // IPv6 address
  159. ULONG ulMetric;
  160. } RELAY_INFO, *PRELAY_INFO;
  161. typedef struct _RELAY_LIST {
  162. ULONG ulNumRelays;
  163. RELAY_INFO arrRelay[0];
  164. } RELAY_LIST, *PRELAY_LIST;
  165. PRELAY_LIST g_pRelayList = NULL;
  166. HANDLE g_hTimerQueue = INVALID_HANDLE_VALUE;
  167. HANDLE g_h6to4ResolutionTimer = INVALID_HANDLE_VALUE;
  168. HANDLE g_h6to4TimerCancelledEvent = NULL;
  169. HANDLE g_h6to4TimerCancelledWait = NULL;
  170. VOID
  171. UpdateGlobalResolutionState();
  172. //////////////////////////////////////////////////////////////////////////////
  173. // GetAddrStr - helper routine to get a string literal for an address
  174. LPTSTR
  175. GetAddrStr(
  176. IN LPSOCKADDR pSockaddr,
  177. IN ULONG ulSockaddrLen)
  178. {
  179. static TCHAR tBuffer[INET6_ADDRSTRLEN];
  180. INT iRet;
  181. ULONG ulLen;
  182. ulLen = sizeof(tBuffer);
  183. iRet = WSAAddressToString(pSockaddr, ulSockaddrLen, NULL, tBuffer, &ulLen);
  184. if (iRet) {
  185. swprintf(tBuffer, L"<err %d>", WSAGetLastError());
  186. }
  187. return tBuffer;
  188. }
  189. BOOL
  190. ConvertOemToUnicode(
  191. IN LPSTR OemString,
  192. OUT LPWSTR UnicodeString,
  193. IN int UnicodeLen)
  194. {
  195. return (MultiByteToWideChar(CP_OEMCP, 0, OemString, (int)(strlen(OemString)+1),
  196. UnicodeString, UnicodeLen) != 0);
  197. }
  198. BOOL
  199. ConvertUnicodeToOem(
  200. IN LPWSTR UnicodeString,
  201. OUT LPSTR OemString,
  202. IN int OemLen)
  203. {
  204. return (WideCharToMultiByte(CP_OEMCP, 0, UnicodeString,
  205. (int)(wcslen(UnicodeString)+1), OemString, OemLen, NULL, NULL) != 0);
  206. }
  207. /////////////////////////////////////////////////////////////////////////
  208. // Subroutines for manipulating the list of (usually) public addresses
  209. // being used for both 6to4 addresses and subnet prefixes.
  210. /////////////////////////////////////////////////////////////////////////
  211. DWORD
  212. MakeEmptyAddressList(
  213. OUT PADDR_LIST *ppList)
  214. {
  215. *ppList = MALLOC(FIELD_OFFSET(ADDR_LIST, Address[0]));
  216. if (!*ppList) {
  217. return GetLastError();
  218. }
  219. (*ppList)->iAddressCount = 0;
  220. return NO_ERROR;
  221. }
  222. VOID
  223. FreeAddressList(
  224. IN PADDR_LIST *ppAddressList)
  225. {
  226. ADDR_LIST *pList = *ppAddressList;
  227. int i;
  228. if (pList == NULL) {
  229. return;
  230. }
  231. // Free all addresses
  232. for (i=0; i<pList->iAddressCount; i++) {
  233. FREE(pList->Address[i].lpSockaddr);
  234. }
  235. // Free the list
  236. FREE(pList);
  237. *ppAddressList = NULL;
  238. }
  239. DWORD
  240. AddAddressToList(
  241. IN LPSOCKADDR_IN pAddress,
  242. IN ADDR_LIST **ppAddressList,
  243. IN ULONG ul6over4IfIndex)
  244. {
  245. ADDR_LIST *pOldList = *ppAddressList;
  246. ADDR_LIST *pNewList;
  247. int n = pOldList->iAddressCount;
  248. // Copy existing addresses
  249. pNewList = MALLOC( FIELD_OFFSET(ADDR_LIST, Address[n+1]) );
  250. if (!pNewList) {
  251. return GetLastError();
  252. }
  253. CopyMemory(pNewList, pOldList,
  254. FIELD_OFFSET(ADDR_LIST, Address[n]));
  255. pNewList->iAddressCount = n+1;
  256. // Add new address
  257. pNewList->Address[n].lpSockaddr = MALLOC(sizeof(SOCKADDR_IN));
  258. if (!pNewList->Address[n].lpSockaddr) {
  259. FREE(pNewList);
  260. return ERROR_NOT_ENOUGH_MEMORY;
  261. }
  262. CopyMemory(pNewList->Address[n].lpSockaddr, pAddress, sizeof(SOCKADDR_IN));
  263. pNewList->Address[n].iSockaddrLength = sizeof(SOCKADDR_IN);
  264. pNewList->Address[n].ul6over4IfIndex = ul6over4IfIndex;
  265. // Free the old list without freeing the sockaddrs
  266. FREE(pOldList);
  267. *ppAddressList = pNewList;
  268. return NO_ERROR;
  269. }
  270. DWORD
  271. FindAddressInList(
  272. IN LPSOCKADDR_IN pAddress,
  273. IN ADDR_LIST *pAddressList,
  274. OUT ULONG *pulIndex)
  275. {
  276. int i;
  277. // Find address in list
  278. for (i=0; i<pAddressList->iAddressCount; i++) {
  279. if (!memcmp(pAddress, pAddressList->Address[i].lpSockaddr,
  280. sizeof(SOCKADDR_IN))) {
  281. *pulIndex = i;
  282. return NO_ERROR;
  283. }
  284. }
  285. Trace1(ERR, _T("ERROR: FindAddressInList didn't find %d.%d.%d.%d"),
  286. PRINT_IPADDR(pAddress->sin_addr.s_addr));
  287. return ERROR_NOT_FOUND;
  288. }
  289. DWORD
  290. RemoveAddressFromList(
  291. IN ULONG ulIndex,
  292. IN ADDR_LIST *pAddressList)
  293. {
  294. // Free old address
  295. FREE(pAddressList->Address[ulIndex].lpSockaddr);
  296. // Move the last entry into its place
  297. pAddressList->iAddressCount--;
  298. pAddressList->Address[ulIndex] =
  299. pAddressList->Address[pAddressList->iAddressCount];
  300. return NO_ERROR;
  301. }
  302. ////////////////////////////////////////////////////////////////
  303. // GlobalInfo-related subroutines
  304. ////////////////////////////////////////////////////////////////
  305. int
  306. ConfigureRouteTableUpdate(
  307. IN const IN6_ADDR *Prefix,
  308. IN u_int PrefixLen,
  309. IN u_int Interface,
  310. IN const IN6_ADDR *Neighbor,
  311. IN int Publish,
  312. IN int Immortal,
  313. IN u_int ValidLifetime,
  314. IN u_int PreferredLifetime,
  315. IN u_int SitePrefixLen,
  316. IN u_int Metric)
  317. {
  318. IPV6_INFO_ROUTE_TABLE Route;
  319. SOCKADDR_IN6 saddr;
  320. DWORD dwErr;
  321. ZeroMemory(&saddr, sizeof(saddr));
  322. saddr.sin6_family = AF_INET6;
  323. saddr.sin6_addr = *Prefix;
  324. Trace7(FSM, _T("Updating route %s/%d iface %d metric %d lifetime %d/%d publish %d"),
  325. GetAddrStr((LPSOCKADDR)&saddr, sizeof(saddr)),
  326. PrefixLen,
  327. Interface,
  328. Metric,
  329. PreferredLifetime,
  330. ValidLifetime,
  331. Publish);
  332. memset(&Route, 0, sizeof Route);
  333. Route.This.Prefix = *Prefix;
  334. Route.This.PrefixLength = PrefixLen;
  335. Route.This.Neighbor.IF.Index = Interface;
  336. Route.This.Neighbor.Address = *Neighbor;
  337. Route.ValidLifetime = ValidLifetime;
  338. Route.PreferredLifetime = PreferredLifetime;
  339. Route.Publish = Publish;
  340. Route.Immortal = Immortal;
  341. Route.SitePrefixLength = SitePrefixLen;
  342. Route.Preference = Metric;
  343. Route.Type = RTE_TYPE_MANUAL;
  344. dwErr = UpdateRouteTable(&Route)? NO_ERROR : GetLastError();
  345. if (dwErr != NO_ERROR) {
  346. Trace1(ERR, _T("UpdateRouteTable got error %d"), dwErr);
  347. }
  348. return dwErr;
  349. }
  350. DWORD
  351. InitializeGlobalInfo()
  352. {
  353. DWORD dwErr;
  354. g_GlobalSettings.stEnable6to4 = DEFAULT_ENABLE_6TO4;
  355. g_GlobalSettings.stEnableRouting = DEFAULT_ENABLE_ROUTING;
  356. g_GlobalSettings.stEnableResolution = DEFAULT_ENABLE_RESOLUTION;
  357. g_GlobalSettings.ulResolutionInterval = DEFAULT_RESOLUTION_INTERVAL;
  358. g_GlobalSettings.stEnableSiteLocals = DEFAULT_ENABLE_SITELOCALS;
  359. g_GlobalSettings.stEnable6over4 = DEFAULT_ENABLE_6OVER4;
  360. g_GlobalSettings.stEnableV4Compat = DEFAULT_ENABLE_V4COMPAT;
  361. g_GlobalSettings.stUndoOnStop = DEFAULT_UNDO_ON_STOP;
  362. wcscpy(g_GlobalSettings.pwszRelayName, DEFAULT_RELAY_NAME);
  363. g_GlobalState.st6to4State = DISABLED;
  364. g_GlobalState.stRoutingState = DISABLED;
  365. g_GlobalState.stResolutionState = DISABLED;
  366. g_sIPv4Socket = socket(AF_INET, SOCK_DGRAM, 0);
  367. if (g_sIPv4Socket == INVALID_SOCKET) {
  368. Trace0(ERR, _T("socket failed\n"));
  369. return WSAGetLastError();
  370. }
  371. dwErr = MakeEmptyAddressList(&g_pIpv4AddressList);
  372. return dwErr;
  373. }
  374. // Called by: Stop6to4
  375. VOID
  376. UninitializeGlobalInfo()
  377. {
  378. closesocket(g_sIPv4Socket);
  379. g_sIPv4Socket = INVALID_SOCKET;
  380. FreeAddressList(&g_pIpv4AddressList);
  381. }
  382. ////////////////////////////////////////////////////////////////
  383. // IPv4 and IPv6 Address-related subroutines
  384. ////////////////////////////////////////////////////////////////
  385. typedef struct {
  386. IPV4_SCOPE Scope;
  387. DWORD Address;
  388. DWORD Mask;
  389. ULONG MaskLen;
  390. } IPV4_SCOPE_PREFIX;
  391. IPV4_SCOPE_PREFIX
  392. Ipv4ScopePrefix[] = {
  393. { IPV4_SCOPE_NODE, 0x0100007f, 0xffffffff, 32 }, // 127.0.0.1/32
  394. { IPV4_SCOPE_LINK, 0x0000fea9, 0x0000ffff, 16 }, // 169.254/16
  395. { IPV4_SCOPE_SM_SITE, 0x0000a8c0, 0x0000ffff, 16 }, // 192.168/16
  396. { IPV4_SCOPE_MD_SITE, 0x000010ac, 0x0000f0ff, 12 }, // 172.16/12
  397. { IPV4_SCOPE_LG_SITE, 0x0000000a, 0x000000ff, 8 }, // 10/8
  398. { IPV4_SCOPE_GLOBAL, 0x00000000, 0x00000000, 0 }, // 0/0
  399. };
  400. IPV4_SCOPE
  401. GetIPv4Scope(
  402. IN DWORD Addr)
  403. {
  404. int i;
  405. for (i=0; ; i++) {
  406. if ((Addr & Ipv4ScopePrefix[i].Mask) == Ipv4ScopePrefix[i].Address) {
  407. return Ipv4ScopePrefix[i].Scope;
  408. }
  409. }
  410. }
  411. DWORD
  412. MakeAddressList(
  413. IN PIP_ADDR_STRING pIpAddrList,
  414. OUT ADDR_LIST **ppAddressList,
  415. OUT PULONG pulGlobals,
  416. IN OUT PULONG pulCumulNumScopedAddrs)
  417. {
  418. ULONG ulGlobals = 0, ulAddresses = 0;
  419. INT iLength;
  420. DWORD dwErr = NO_ERROR;
  421. ADDR_LIST *pList = NULL;
  422. PIP_ADDR_STRING pIpAddr;
  423. SOCKADDR_IN *pSin;
  424. IPV4_SCOPE scope;
  425. // Count addresses
  426. for (pIpAddr=pIpAddrList; pIpAddr; pIpAddr=pIpAddr->Next) {
  427. ulAddresses++;
  428. }
  429. *ppAddressList = NULL;
  430. *pulGlobals = 0;
  431. pList = MALLOC( FIELD_OFFSET(ADDR_LIST, Address[ulAddresses] ));
  432. if (pList == NULL) {
  433. return GetLastError();
  434. }
  435. ulAddresses = 0;
  436. for (pIpAddr=pIpAddrList; pIpAddr; pIpAddr=pIpAddr->Next) {
  437. Trace1(FSM, _T("Adding address %hs"), pIpAddr->IpAddress.String);
  438. iLength = sizeof(SOCKADDR_IN);
  439. pSin = MALLOC( iLength );
  440. if (pSin == NULL) {
  441. continue;
  442. }
  443. dwErr = WSAStringToAddressA(pIpAddr->IpAddress.String,
  444. AF_INET,
  445. NULL,
  446. (LPSOCKADDR)pSin,
  447. &iLength);
  448. if (dwErr == SOCKET_ERROR) {
  449. FREE(pSin);
  450. pSin = NULL;
  451. continue;
  452. }
  453. //
  454. // Don't allow 0.0.0.0 as an address. On an interface with no
  455. // addresses, the IPv4 stack will report 1 address of 0.0.0.0.
  456. //
  457. if (pSin->sin_addr.s_addr == INADDR_ANY) {
  458. FREE(pSin);
  459. pSin = NULL;
  460. continue;
  461. }
  462. if ((pSin->sin_addr.s_addr & 0x000000FF) == 0) {
  463. //
  464. // An address in 0/8 isn't a real IP address, it's a fake one that
  465. // the IPv4 stack sticks on a receive-only adapter.
  466. //
  467. FREE(pSin);
  468. pSin = NULL;
  469. continue;
  470. }
  471. scope = GetIPv4Scope(pSin->sin_addr.s_addr);
  472. pulCumulNumScopedAddrs[scope]++;
  473. if (scope == IPV4_SCOPE_GLOBAL) {
  474. ulGlobals++;
  475. }
  476. pList->Address[ulAddresses].iSockaddrLength = iLength;
  477. pList->Address[ulAddresses].lpSockaddr = (LPSOCKADDR)pSin;
  478. ulAddresses++;
  479. }
  480. pList->iAddressCount = ulAddresses;
  481. *ppAddressList = pList;
  482. *pulGlobals = ulGlobals;
  483. return dwErr;
  484. }
  485. //
  486. // Create a 6to4 unicast address for this machine.
  487. //
  488. VOID
  489. Make6to4Address(
  490. OUT LPSOCKADDR_IN6 pIPv6Address,
  491. IN LPSOCKADDR_IN pIPv4Address)
  492. {
  493. IN_ADDR *pIPv4 = &pIPv4Address->sin_addr;
  494. memset(pIPv6Address, 0, sizeof (SOCKADDR_IN6));
  495. pIPv6Address->sin6_family = AF_INET6;
  496. pIPv6Address->sin6_addr.s6_addr[0] = 0x20;
  497. pIPv6Address->sin6_addr.s6_addr[1] = 0x02;
  498. memcpy(&pIPv6Address->sin6_addr.s6_addr[2], pIPv4, sizeof(IN_ADDR));
  499. memcpy(&pIPv6Address->sin6_addr.s6_addr[12], pIPv4, sizeof(IN_ADDR));
  500. }
  501. //
  502. // Create a 6to4 anycast address from a local IPv4 address.
  503. //
  504. VOID
  505. Make6to4AnycastAddress(
  506. OUT LPSOCKADDR_IN6 pIPv6Address,
  507. IN LPSOCKADDR_IN pIPv4Address)
  508. {
  509. IN_ADDR *pIPv4 = &pIPv4Address->sin_addr;
  510. memset(pIPv6Address, 0, sizeof(SOCKADDR_IN6));
  511. pIPv6Address->sin6_family = AF_INET6;
  512. pIPv6Address->sin6_addr.s6_addr[0] = 0x20;
  513. pIPv6Address->sin6_addr.s6_addr[1] = 0x02;
  514. memcpy(&pIPv6Address->sin6_addr.s6_addr[2], pIPv4, sizeof(IN_ADDR));
  515. }
  516. //
  517. // Create a v4-compatible address from an IPv4 address.
  518. //
  519. VOID
  520. MakeV4CompatibleAddress(
  521. OUT LPSOCKADDR_IN6 pIPv6Address,
  522. IN LPSOCKADDR_IN pIPv4Address)
  523. {
  524. IN_ADDR *pIPv4 = &pIPv4Address->sin_addr;
  525. memset(pIPv6Address, 0, sizeof(SOCKADDR_IN6));
  526. pIPv6Address->sin6_family = AF_INET6;
  527. memcpy(&pIPv6Address->sin6_addr.s6_addr[12], pIPv4, sizeof(IN_ADDR));
  528. }
  529. DWORD
  530. ConfigureAddressUpdate(
  531. IN u_int Interface,
  532. IN SOCKADDR_IN6 *Sockaddr,
  533. IN u_int Lifetime,
  534. IN int Type,
  535. IN u_int PrefixConf,
  536. IN u_int SuffixConf)
  537. {
  538. IPV6_UPDATE_ADDRESS Address;
  539. DWORD dwErr = NO_ERROR;
  540. IN6_ADDR *Addr = &Sockaddr->sin6_addr;
  541. Trace6(FSM,
  542. _T("ConfigureAddressUpdate: if %u addr %s life %u type %d conf %u/%u"),
  543. Interface,
  544. GetAddrStr((LPSOCKADDR)Sockaddr, sizeof(SOCKADDR_IN6)),
  545. Lifetime,
  546. Type,
  547. PrefixConf,
  548. SuffixConf);
  549. memset(&Address, 0, sizeof Address);
  550. Address.This.IF.Index = Interface;
  551. Address.This.Address = *Addr;
  552. Address.ValidLifetime = Address.PreferredLifetime = Lifetime;
  553. Address.Type = Type;
  554. Address.PrefixConf = PrefixConf;
  555. Address.InterfaceIdConf = SuffixConf;
  556. if (!UpdateAddress(&Address)) {
  557. dwErr = GetLastError();
  558. Trace1(ERR, _T("ERROR: UpdateAddress got error %d"), dwErr);
  559. }
  560. return dwErr;
  561. }
  562. void
  563. Configure6to4Subnets(
  564. IN ULONG ulIfIndex,
  565. IN PSUBNET_CONTEXT pSubnet);
  566. void
  567. Unconfigure6to4Subnets(
  568. IN ULONG ulIfIndex,
  569. IN PSUBNET_CONTEXT pSubnet);
  570. // Called by: OnChangeInterfaceInfo
  571. DWORD
  572. AddAddress(
  573. IN LPSOCKADDR_IN pIPv4Address, // public address
  574. IN PIF_LIST pInterfaceList, // interface list
  575. IN STATE stOldRoutingState) // routing state
  576. {
  577. SOCKADDR_IN6 OurAddress;
  578. DWORD dwErr;
  579. ULONG ul6over4IfIndex;
  580. Trace2(ENTER, _T("AddAddress %d.%d.%d.%d, isrouter=%d"),
  581. PRINT_IPADDR(pIPv4Address->sin_addr.s_addr),
  582. stOldRoutingState);
  583. // Add 6over4 interface (if enabled)
  584. if (g_GlobalSettings.stEnable6over4 == ENABLED) {
  585. ul6over4IfIndex = Create6over4Interface(pIPv4Address->sin_addr);
  586. } else {
  587. ul6over4IfIndex = 0;
  588. }
  589. Trace1(ERR, _T("6over4 ifindex=%d"), ul6over4IfIndex);
  590. // Put the IPv4 address on our "public" list
  591. dwErr = AddAddressToList(pIPv4Address, &g_pIpv4AddressList,
  592. ul6over4IfIndex);
  593. if (dwErr != NO_ERROR) {
  594. return dwErr;
  595. }
  596. if (GetIPv4Scope(pIPv4Address->sin_addr.s_addr) == IPV4_SCOPE_GLOBAL) {
  597. // Add v4-compatible address (if enabled)
  598. if (g_GlobalSettings.stEnableV4Compat == ENABLED) {
  599. MakeV4CompatibleAddress(&OurAddress, pIPv4Address);
  600. dwErr = ConfigureAddressUpdate(
  601. V4_COMPAT_IFINDEX, &OurAddress, INFINITE_LIFETIME,
  602. ADE_UNICAST, PREFIX_CONF_WELLKNOWN,
  603. IID_CONF_LL_ADDRESS);
  604. if (dwErr != NO_ERROR) {
  605. return dwErr;
  606. }
  607. }
  608. }
  609. IsatapAddressChangeNotification(FALSE, pIPv4Address->sin_addr);
  610. #ifdef TEREDO
  611. TeredoAddressChangeNotification(FALSE, pIPv4Address->sin_addr);
  612. #endif // TEREDO
  613. Add6to4Address(pIPv4Address, pInterfaceList, stOldRoutingState);
  614. TraceLeave("AddAddress");
  615. return NO_ERROR;
  616. }
  617. // Delete the 6to4 address from the global state, and prepare to
  618. // delete it from the stack.
  619. //
  620. // Called by: UninitializeInterfaces
  621. VOID
  622. PreDeleteAddress(
  623. IN LPSOCKADDR_IN pIPv4Address,
  624. IN PIF_LIST pInterfaceList,
  625. IN STATE stOldRoutingState)
  626. {
  627. Trace2(ENTER, _T("PreDeleteAddress %d.%d.%d.%d, wasrouter=%d"),
  628. PRINT_IPADDR(pIPv4Address->sin_addr.s_addr),
  629. stOldRoutingState);
  630. PreDelete6to4Address(pIPv4Address, pInterfaceList, stOldRoutingState);
  631. TraceLeave("PreDeleteAddress");
  632. }
  633. // Delete 6to4 address information from the stack.
  634. //
  635. // Called by: OnChangeInterfaceInfo, UninitializeInterfaces
  636. VOID
  637. DeleteAddress(
  638. IN LPSOCKADDR_IN pIPv4Address,
  639. IN PIF_LIST pInterfaceList,
  640. IN STATE stOldRoutingState)
  641. {
  642. SOCKADDR_IN6 OurAddress;
  643. DWORD dwErr;
  644. ULONG i;
  645. Trace2(ENTER, _T("DeleteAddress %d.%d.%d.%d wasrouter=%d"),
  646. PRINT_IPADDR(pIPv4Address->sin_addr.s_addr),
  647. stOldRoutingState);
  648. if (GetIPv4Scope(pIPv4Address->sin_addr.s_addr) == IPV4_SCOPE_GLOBAL) {
  649. // Delete the v4-compatible address from the stack (if enabled)
  650. if (g_GlobalSettings.stEnableV4Compat == ENABLED) {
  651. MakeV4CompatibleAddress(&OurAddress, pIPv4Address);
  652. ConfigureAddressUpdate(
  653. V4_COMPAT_IFINDEX, &OurAddress, 0, ADE_UNICAST,
  654. PREFIX_CONF_WELLKNOWN, IID_CONF_LL_ADDRESS);
  655. }
  656. }
  657. IsatapAddressChangeNotification(TRUE, pIPv4Address->sin_addr);
  658. #ifdef TEREDO
  659. TeredoAddressChangeNotification(TRUE, pIPv4Address->sin_addr);
  660. #endif // TEREDO
  661. Delete6to4Address(pIPv4Address, pInterfaceList, stOldRoutingState);
  662. //
  663. // We're now completely done with the IPv4 address, so
  664. // remove it from the public address list.
  665. //
  666. dwErr = FindAddressInList(pIPv4Address, g_pIpv4AddressList, &i);
  667. if (dwErr == NO_ERROR) {
  668. // Delete 6over4 interface (if enabled)
  669. if (g_GlobalSettings.stEnable6over4 == ENABLED) {
  670. DeleteInterface(g_pIpv4AddressList->Address[i].ul6over4IfIndex);
  671. }
  672. RemoveAddressFromList(i, g_pIpv4AddressList);
  673. }
  674. TraceLeave("DeleteAddress");
  675. }
  676. ////////////////////////////////////////////////////////////////
  677. // Relay-related subroutines
  678. ////////////////////////////////////////////////////////////////
  679. //
  680. // Given a relay, make sure a default route to it exists with the right metric
  681. //
  682. VOID
  683. AddOrUpdate6to4Relay(
  684. IN PRELAY_INFO pRelay)
  685. {
  686. Trace1(ENTER, _T("AddOrUpdate6to4Relay %d.%d.%d.%d"),
  687. PRINT_IPADDR(pRelay->sinAddress.sin_addr.s_addr));
  688. //
  689. // Create the default route.
  690. //
  691. ConfigureRouteTableUpdate(&in6addr_any, 0,
  692. SIX_TO_FOUR_IFINDEX,
  693. &pRelay->sin6Address.sin6_addr,
  694. TRUE, // Publish.
  695. TRUE, // Immortal.
  696. 2 * HOURS, // Valid lifetime.
  697. 30 * MINUTES, // Preferred lifetime.
  698. 0,
  699. pRelay->ulMetric);
  700. }
  701. VOID
  702. FreeRelayList(
  703. IN PRELAY_LIST *ppList)
  704. {
  705. if (*ppList) {
  706. FREE(*ppList);
  707. *ppList = NULL;
  708. }
  709. }
  710. DWORD
  711. InitializeRelays()
  712. {
  713. g_pRelayList = NULL;
  714. g_hTimerQueue = CreateTimerQueue();
  715. if (g_hTimerQueue == INVALID_HANDLE_VALUE) {
  716. return GetLastError();
  717. }
  718. return NO_ERROR;
  719. }
  720. VOID
  721. IncEventCount(
  722. IN PCHAR pszWhere)
  723. {
  724. ULONG ulCount = InterlockedIncrement(&g_ulEventCount);
  725. Trace2(FSM, _T("++%u event count (%hs)"), ulCount, pszWhere);
  726. }
  727. VOID
  728. DecEventCount(
  729. IN PCHAR pszWhere)
  730. {
  731. ULONG ulCount = InterlockedDecrement(&g_ulEventCount);
  732. Trace2(FSM, _T("--%u event count (%hs)"), ulCount, pszWhere);
  733. if ((ulCount == 0) && (g_stService == DISABLED)) {
  734. SetHelperServiceStatus(SERVICE_STOPPED, NO_ERROR);
  735. }
  736. }
  737. // This routine is invoked when a resolution timer has been cancelled
  738. // and all outstanding timer routines have completed. It is responsible
  739. // for releasing the event count for the periodic timer.
  740. //
  741. VOID CALLBACK
  742. OnResolutionTimerCancelled(
  743. IN PVOID lpParameter,
  744. IN BOOLEAN TimerOrWaitFired)
  745. {
  746. TraceEnter("OnResolutionTimerCancelled");
  747. DecEventCount("RT:CancelResolutionTimer");
  748. TraceLeave("OnResolutionTimerCancelled");
  749. }
  750. DWORD
  751. InitEvents()
  752. {
  753. ASSERT(g_h6to4TimerCancelledEvent == NULL);
  754. g_h6to4TimerCancelledEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  755. if (g_h6to4TimerCancelledEvent == NULL)
  756. return GetLastError();
  757. //
  758. // Schedule OnResolutionTimerCancelled() to be called whenever
  759. // g_h6to4TimerCancelledEvent is signalled.
  760. //
  761. if (! RegisterWaitForSingleObject(&g_h6to4TimerCancelledWait,
  762. g_h6to4TimerCancelledEvent,
  763. OnResolutionTimerCancelled,
  764. NULL,
  765. INFINITE,
  766. WT_EXECUTEDEFAULT)) {
  767. return GetLastError();
  768. }
  769. return NO_ERROR;
  770. }
  771. VOID
  772. CleanupHelperService()
  773. {
  774. if (g_h6to4TimerCancelledWait != NULL) {
  775. UnregisterWait(g_h6to4TimerCancelledWait);
  776. g_h6to4TimerCancelledWait = NULL;
  777. }
  778. if (g_h6to4TimerCancelledEvent != NULL) {
  779. CloseHandle(g_h6to4TimerCancelledEvent);
  780. g_h6to4TimerCancelledEvent = NULL;
  781. }
  782. }
  783. VOID
  784. CancelResolutionTimer(
  785. IN OUT HANDLE *phResolutionTimer,
  786. IN HANDLE hEvent)
  787. {
  788. Trace0(FSM, _T("Cancelling RT"));
  789. // Stop the resolution timer
  790. if (*phResolutionTimer != INVALID_HANDLE_VALUE) {
  791. // Must be done non-blocking since we're holding the lock
  792. // the resolution timeout needs. Ask for notification
  793. // when the cancel completes so we can release the event count.
  794. DeleteTimerQueueTimer(g_hTimerQueue, *phResolutionTimer, hEvent);
  795. *phResolutionTimer = INVALID_HANDLE_VALUE;
  796. }
  797. }
  798. //
  799. // Delete all stack state related to a given relay
  800. //
  801. void
  802. Delete6to4Relay(
  803. IN PRELAY_INFO pRelay)
  804. {
  805. Trace1(ENTER, _T("Delete6to4Relay %d.%d.%d.%d"),
  806. PRINT_IPADDR(pRelay->sinAddress.sin_addr.s_addr));
  807. ConfigureRouteTableUpdate(&in6addr_any, 0,
  808. SIX_TO_FOUR_IFINDEX,
  809. &pRelay->sin6Address.sin6_addr,
  810. FALSE, // Publish.
  811. FALSE, // Immortal.
  812. 0, // Valid lifetime.
  813. 0, // Preferred lifetime.
  814. 0,
  815. pRelay->ulMetric);
  816. }
  817. VOID
  818. UninitializeRelays()
  819. {
  820. ULONG i;
  821. TraceEnter("UninitializeRelays");
  822. CancelResolutionTimer(&g_h6to4ResolutionTimer,
  823. g_h6to4TimerCancelledEvent);
  824. // Delete the timer queue
  825. if (g_hTimerQueue != INVALID_HANDLE_VALUE) {
  826. DeleteTimerQueue(g_hTimerQueue);
  827. g_hTimerQueue = INVALID_HANDLE_VALUE;
  828. }
  829. if (g_GlobalSettings.stUndoOnStop == ENABLED) {
  830. // Delete existing relay tunnels
  831. for (i=0; g_pRelayList && (i<g_pRelayList->ulNumRelays); i++) {
  832. Delete6to4Relay(&g_pRelayList->arrRelay[i]);
  833. }
  834. }
  835. // Free the "old list"
  836. FreeRelayList(&g_pRelayList);
  837. TraceLeave("UninitializeRelays");
  838. }
  839. //
  840. // Start or update the resolution timer to expire in <ulMinutes> minutes
  841. //
  842. DWORD
  843. RestartResolutionTimer(
  844. IN ULONG ulDelayMinutes,
  845. IN ULONG ulPeriodMinutes,
  846. IN HANDLE *phResolutionTimer,
  847. IN WAITORTIMERCALLBACK OnTimeout)
  848. {
  849. ULONG DelayTime = ulDelayMinutes * MINUTES * 1000; // convert mins to ms
  850. ULONG PeriodTime = ulPeriodMinutes * MINUTES * 1000; // convert mins to ms
  851. BOOL bRet;
  852. DWORD dwErr;
  853. if (*phResolutionTimer != INVALID_HANDLE_VALUE) {
  854. bRet = ChangeTimerQueueTimer(g_hTimerQueue, *phResolutionTimer,
  855. DelayTime, PeriodTime);
  856. } else {
  857. bRet = CreateTimerQueueTimer(phResolutionTimer,
  858. g_hTimerQueue,
  859. OnTimeout,
  860. NULL,
  861. DelayTime,
  862. PeriodTime,
  863. 0);
  864. if (bRet) {
  865. IncEventCount("RT:RestartResolutionTimer");
  866. }
  867. }
  868. dwErr = (bRet)? NO_ERROR : GetLastError();
  869. Trace3(TIMER,
  870. _T("RestartResolutionTimer: DueTime %d minutes, Period %d minutes, ReturnCode %d"),
  871. ulDelayMinutes, ulPeriodMinutes, dwErr);
  872. return dwErr;
  873. }
  874. //
  875. // Convert an addrinfo list into a relay list with appropriate metrics
  876. //
  877. DWORD
  878. MakeRelayList(
  879. IN struct addrinfo *addrs)
  880. {
  881. struct addrinfo *ai;
  882. ULONG ulNumRelays = 0;
  883. ULONG ulLatency;
  884. for (ai=addrs; ai; ai=ai->ai_next) {
  885. ulNumRelays++;
  886. }
  887. g_pRelayList = MALLOC( FIELD_OFFSET(RELAY_LIST, arrRelay[ulNumRelays]));
  888. if (g_pRelayList == NULL) {
  889. return GetLastError();
  890. }
  891. g_pRelayList->ulNumRelays = ulNumRelays;
  892. ulNumRelays = 0;
  893. for (ai=addrs; ai; ai=ai->ai_next) {
  894. CopyMemory(&g_pRelayList->arrRelay[ulNumRelays].sinAddress, ai->ai_addr,
  895. ai->ai_addrlen);
  896. //
  897. // Check connectivity using a possible 6to4 address for the relay
  898. // router. However, we'll actually set TTL=1 and accept a
  899. // hop count exceeded message, so we don't have to guess right.
  900. //
  901. Make6to4Address(&g_pRelayList->arrRelay[ulNumRelays].sin6Address,
  902. &g_pRelayList->arrRelay[ulNumRelays].sinAddress);
  903. // ping it to compute a metric
  904. ulLatency = ConfirmIPv6Reachability(&g_pRelayList->arrRelay[ulNumRelays].sin6Address, 1000/*ms*/);
  905. if (ulLatency != 0) {
  906. g_pRelayList->arrRelay[ulNumRelays].ulMetric = 1000 + ulLatency;
  907. } else {
  908. g_pRelayList->arrRelay[ulNumRelays].ulMetric = UNREACHABLE;
  909. }
  910. ulNumRelays++;
  911. }
  912. return NO_ERROR;
  913. }
  914. //
  915. // When the name-resolution timer expires, it's time to re-resolve the
  916. // relay name to a list of relays.
  917. //
  918. DWORD
  919. WINAPI
  920. OnResolutionTimeout(
  921. IN PVOID lpData,
  922. IN BOOLEAN Reason)
  923. {
  924. DWORD dwErr = NO_ERROR;
  925. ADDRINFOW hints;
  926. PADDRINFOW addrs;
  927. PRELAY_LIST pOldRelayList;
  928. ULONG i, j;
  929. ENTER_API();
  930. TraceEnter("OnResolutionTimeout");
  931. if (g_stService == DISABLED) {
  932. TraceLeave("OnResolutionTimeout (disabled)");
  933. LEAVE_API();
  934. return NO_ERROR;
  935. }
  936. pOldRelayList = g_pRelayList;
  937. g_pRelayList = NULL;
  938. // If any 6to4 addresses are configured,
  939. // Resolve the relay name to a set of IPv4 addresses
  940. // Else
  941. // Make the new set empty
  942. if (g_GlobalState.stResolutionState == ENABLED) {
  943. // Resolve the relay name to a set of IPv4 addresses
  944. ZeroMemory(&hints, sizeof(hints));
  945. hints.ai_family = PF_INET;
  946. dwErr = GetAddrInfoW(g_GlobalSettings.pwszRelayName, NULL, &hints, &addrs);
  947. if (dwErr == NO_ERROR) {
  948. dwErr = MakeRelayList((PADDRINFOA)addrs);
  949. FreeAddrInfoW(addrs);
  950. addrs = NULL;
  951. } else {
  952. Trace2(ERR, _T("GetAddrInfoW(%s) returned error %d"),
  953. g_GlobalSettings.pwszRelayName, dwErr);
  954. }
  955. }
  956. // Compare the new set to the old set
  957. // For each address in the new set, ping it to compute a metric
  958. // For each new address, add a route
  959. // For each old address not in the new list, delete the route
  960. // For each address in both, update the route if the metric has changed
  961. //
  962. for (i=0; g_pRelayList && (i<g_pRelayList->ulNumRelays); i++) {
  963. for (j=0; pOldRelayList && (j<pOldRelayList->ulNumRelays); j++) {
  964. if (g_pRelayList->arrRelay[i].sinAddress.sin_addr.s_addr
  965. == pOldRelayList->arrRelay[j].sinAddress.sin_addr.s_addr) {
  966. break;
  967. }
  968. }
  969. if (pOldRelayList && (j<pOldRelayList->ulNumRelays)) {
  970. // update the route if the metric has changed
  971. if (g_pRelayList->arrRelay[i].ulMetric
  972. != pOldRelayList->arrRelay[j].ulMetric) {
  973. AddOrUpdate6to4Relay(&g_pRelayList->arrRelay[i]);
  974. }
  975. g_pRelayList->arrRelay[i].sin6Address = pOldRelayList->arrRelay[j].sin6Address;
  976. } else {
  977. // add a relay
  978. AddOrUpdate6to4Relay(&g_pRelayList->arrRelay[i]);
  979. }
  980. }
  981. for (j=0; pOldRelayList && (j<pOldRelayList->ulNumRelays); j++) {
  982. for (i=0; g_pRelayList && (i<g_pRelayList->ulNumRelays); i++) {
  983. if (g_pRelayList->arrRelay[i].sinAddress.sin_addr.s_addr ==
  984. pOldRelayList->arrRelay[j].sinAddress.sin_addr.s_addr) {
  985. break;
  986. }
  987. }
  988. if (!g_pRelayList || (i == g_pRelayList->ulNumRelays)) {
  989. // delete a relay
  990. Delete6to4Relay(&pOldRelayList->arrRelay[j]);
  991. }
  992. }
  993. FreeRelayList(&pOldRelayList);
  994. TraceLeave("OnResolutionTimeout");
  995. LEAVE_API();
  996. return dwErr;
  997. }
  998. ////////////////////////////////////////////////////////////////
  999. // Routing-related subroutines
  1000. ////////////////////////////////////////////////////////////////
  1001. PIF_SETTINGS
  1002. FindInterfaceSettings(
  1003. IN WCHAR *pwszAdapterName,
  1004. IN IF_SETTINGS_LIST *pList);
  1005. STATE
  1006. Get6to4State(
  1007. VOID
  1008. )
  1009. {
  1010. //
  1011. // Decide whether 6to4 should be enabled or not.
  1012. //
  1013. if (g_GlobalSettings.stEnable6to4 == AUTOMATIC) {
  1014. return (g_b6to4Required ? ENABLED : DISABLED);
  1015. } else {
  1016. return g_GlobalSettings.stEnable6to4;
  1017. }
  1018. }
  1019. //
  1020. // Decide whether routing will be enabled at all
  1021. //
  1022. STATE
  1023. GetGlobalRoutingState(
  1024. VOID
  1025. )
  1026. {
  1027. PIF_LIST pIfList = g_pInterfaceList;
  1028. DWORD dwErr;
  1029. GUID guid;
  1030. if (Get6to4State() == DISABLED) {
  1031. return DISABLED;
  1032. }
  1033. // If routing is explicitly enabled or disabled, use that
  1034. if (g_GlobalSettings.stEnableRouting != AUTOMATIC) {
  1035. return g_GlobalSettings.stEnableRouting;
  1036. }
  1037. // Disable routing if there is no private interface used by ICS
  1038. dwErr = RasQuerySharedPrivateLan(&guid);
  1039. if (dwErr != NO_ERROR) {
  1040. return DISABLED;
  1041. }
  1042. // Disable routing if there are no global IPv4 addresses
  1043. if (!pIfList || !pIfList->ulNumScopedAddrs[IPV4_SCOPE_GLOBAL]) {
  1044. return DISABLED;
  1045. }
  1046. return ENABLED;
  1047. }
  1048. //
  1049. // Decide whether a given interface is one we should treat as
  1050. // a private link to be a router on.
  1051. //
  1052. // Called by: UpdateInterfaceRoutingState, MakeInterfaceList
  1053. STATE
  1054. GetInterfaceRoutingState(
  1055. IN PIF_INFO pIf) // potential private interface
  1056. {
  1057. PIF_SETTINGS pIfSettings;
  1058. STATE stEnableRouting = AUTOMATIC;
  1059. DWORD dwErr;
  1060. GUID guid;
  1061. UNICODE_STRING usGuid;
  1062. WCHAR buffer[MAX_INTERFACE_NAME_LEN];
  1063. if (GetGlobalRoutingState() == DISABLED) {
  1064. return DISABLED;
  1065. }
  1066. pIfSettings = FindInterfaceSettings(pIf->pwszAdapterName,
  1067. g_pInterfaceSettingsList);
  1068. if (pIfSettings) {
  1069. stEnableRouting = pIfSettings->stEnableRouting;
  1070. }
  1071. if (stEnableRouting != AUTOMATIC) {
  1072. return stEnableRouting;
  1073. }
  1074. //
  1075. // Enable routing if this is the private interface used by ICS
  1076. //
  1077. dwErr = RasQuerySharedPrivateLan(&guid);
  1078. if (dwErr != NO_ERROR) {
  1079. // no private interface
  1080. return DISABLED;
  1081. }
  1082. usGuid.Buffer = buffer;
  1083. usGuid.MaximumLength = MAX_INTERFACE_NAME_LEN;
  1084. dwErr = RtlStringFromGUID(&guid, &usGuid);
  1085. if (dwErr != NO_ERROR) {
  1086. // no private interface
  1087. return DISABLED;
  1088. }
  1089. Trace1(ERR, _T("ICS private interface: %ls"), usGuid.Buffer);
  1090. //
  1091. // Compare guid to pIf->pwszAdapterName
  1092. //
  1093. // This must be done using a case-insensitive comparison since
  1094. // GetAdaptersInfo() returns GUID strings with upper-case letters
  1095. // while RtlGetStringFromGUID uses lower-case letters.
  1096. //
  1097. if (!_wcsicmp(pIf->pwszAdapterName, usGuid.Buffer)) {
  1098. return ENABLED;
  1099. }
  1100. return DISABLED;
  1101. }
  1102. // Called by: Configure6to4Subnets, Unconfigure6to4Subnets
  1103. VOID
  1104. Create6to4Prefixes(
  1105. OUT IN6_ADDR *pSubnetPrefix,
  1106. OUT IN6_ADDR *pSiteLocalPrefix,
  1107. IN IN_ADDR *ipOurAddr, // public address
  1108. IN ULONG ulIfIndex) // private interface
  1109. {
  1110. //
  1111. // Create a subnet prefix for the interface,
  1112. // using the interface index as the subnet number.
  1113. //
  1114. memset(pSubnetPrefix, 0, sizeof(IN6_ADDR));
  1115. pSubnetPrefix->s6_addr[0] = 0x20;
  1116. pSubnetPrefix->s6_addr[1] = 0x02;
  1117. memcpy(&pSubnetPrefix->s6_addr[2], ipOurAddr, sizeof(IN_ADDR));
  1118. pSubnetPrefix->s6_addr[6] = HIBYTE(ulIfIndex);
  1119. pSubnetPrefix->s6_addr[7] = LOBYTE(ulIfIndex);
  1120. //
  1121. // Create a site-local prefix for the interface,
  1122. // using the interface index as the subnet number.
  1123. //
  1124. memset(pSiteLocalPrefix, 0, sizeof(IN6_ADDR));
  1125. pSiteLocalPrefix->s6_addr[0] = 0xfe;
  1126. pSiteLocalPrefix->s6_addr[1] = 0xc0;
  1127. pSiteLocalPrefix->s6_addr[6] = HIBYTE(ulIfIndex);
  1128. pSiteLocalPrefix->s6_addr[7] = LOBYTE(ulIfIndex);
  1129. }
  1130. // Called by: EnableInterfaceRouting, AddAddress
  1131. void
  1132. Configure6to4Subnets(
  1133. IN ULONG ulIfIndex, // private interface
  1134. IN PSUBNET_CONTEXT pSubnet) // subnet info, incl. public address
  1135. {
  1136. IN6_ADDR SubnetPrefix;
  1137. IN6_ADDR SiteLocalPrefix;
  1138. if ((GetIPv4Scope(pSubnet->V4Addr.s_addr) != IPV4_SCOPE_GLOBAL)) {
  1139. return;
  1140. }
  1141. Create6to4Prefixes(&SubnetPrefix, &SiteLocalPrefix, &pSubnet->V4Addr,
  1142. ulIfIndex);
  1143. //
  1144. // Configure the subnet route.
  1145. //
  1146. ConfigureRouteTableUpdate(&SubnetPrefix, 64,
  1147. ulIfIndex, &in6addr_any,
  1148. pSubnet->Publish,
  1149. pSubnet->Publish,
  1150. pSubnet->ValidLifetime,
  1151. pSubnet->PreferredLifetime,
  1152. ((g_GlobalSettings.stEnableSiteLocals == ENABLED) ? 48 : 0),
  1153. SUBNET_ROUTE_METRIC);
  1154. if (g_GlobalSettings.stEnableSiteLocals == ENABLED) {
  1155. ConfigureRouteTableUpdate(&SiteLocalPrefix, 64,
  1156. ulIfIndex, &in6addr_any,
  1157. pSubnet->Publish,
  1158. pSubnet->Publish,
  1159. pSubnet->ValidLifetime,
  1160. pSubnet->PreferredLifetime,
  1161. 0,
  1162. SITELOCAL_ROUTE_METRIC);
  1163. }
  1164. }
  1165. // Called by: DisableInterfaceRouting, DeleteAddress
  1166. void
  1167. Unconfigure6to4Subnets(
  1168. IN ULONG ulIfIndex, // private interface
  1169. IN PSUBNET_CONTEXT pSubnet) // subnet info, inc. public address
  1170. {
  1171. IN6_ADDR SubnetPrefix;
  1172. IN6_ADDR SiteLocalPrefix;
  1173. if ((GetIPv4Scope(pSubnet->V4Addr.s_addr) != IPV4_SCOPE_GLOBAL)) {
  1174. return;
  1175. }
  1176. Create6to4Prefixes(&SubnetPrefix, &SiteLocalPrefix, &pSubnet->V4Addr,
  1177. ulIfIndex);
  1178. //
  1179. // Give the 6to4 route a zero lifetime, making it invalid.
  1180. // If we are a router, continue to publish the 6to4 route
  1181. // until we have disabled routing. This will allow
  1182. // the last Router Advertisements to go out with the prefix.
  1183. //
  1184. ConfigureRouteTableUpdate(&SubnetPrefix, 64,
  1185. ulIfIndex, &in6addr_any,
  1186. pSubnet->Publish, // Publish.
  1187. pSubnet->Publish, // Immortal.
  1188. pSubnet->ValidLifetime,
  1189. pSubnet->PreferredLifetime,
  1190. 0, 0);
  1191. if (g_GlobalSettings.stEnableSiteLocals == ENABLED) {
  1192. ConfigureRouteTableUpdate(&SiteLocalPrefix, 64,
  1193. ulIfIndex, &in6addr_any,
  1194. pSubnet->Publish, // Publish.
  1195. pSubnet->Publish, // Immortal.
  1196. pSubnet->ValidLifetime,
  1197. pSubnet->PreferredLifetime,
  1198. 0, 0);
  1199. }
  1200. }
  1201. #define PUBLIC_ZONE_ID 1
  1202. #define PRIVATE_ZONE_ID 2
  1203. // Called by: EnableRouting, DisableRouting, EnableInterfaceRouting,
  1204. // DisableInterfaceRouting
  1205. DWORD
  1206. ConfigureInterfaceUpdate(
  1207. IN u_int Interface,
  1208. IN int Advertises,
  1209. IN int Forwards)
  1210. {
  1211. IPV6_INFO_INTERFACE Update;
  1212. DWORD Result;
  1213. IPV6_INIT_INFO_INTERFACE(&Update);
  1214. Update.This.Index = Interface;
  1215. Update.Advertises = Advertises;
  1216. Update.Forwards = Forwards;
  1217. if (Advertises == TRUE) {
  1218. Update.ZoneIndices[ADE_SITE_LOCAL] = PRIVATE_ZONE_ID;
  1219. Update.ZoneIndices[ADE_ADMIN_LOCAL] = PRIVATE_ZONE_ID;
  1220. Update.ZoneIndices[ADE_SUBNET_LOCAL] = PRIVATE_ZONE_ID;
  1221. } else if (Advertises == FALSE) {
  1222. Update.ZoneIndices[ADE_SITE_LOCAL] = PUBLIC_ZONE_ID;
  1223. Update.ZoneIndices[ADE_ADMIN_LOCAL] = PUBLIC_ZONE_ID;
  1224. Update.ZoneIndices[ADE_SUBNET_LOCAL] = PUBLIC_ZONE_ID;
  1225. }
  1226. Result = UpdateInterface(&Update);
  1227. Trace4(ERR, _T("UpdateInterface if=%d adv=%d fwd=%d result=%d"),
  1228. Interface, Advertises, Forwards, Result);
  1229. return Result;
  1230. }
  1231. // Called by: UpdateGlobalRoutingState
  1232. VOID
  1233. EnableRouting()
  1234. {
  1235. SOCKADDR_IN6 AnycastAddress;
  1236. int i;
  1237. LPSOCKADDR_IN pOurAddr;
  1238. TraceEnter("EnableRouting");
  1239. //
  1240. // Enable forwarding on the tunnel pseudo-interfaces.
  1241. //
  1242. ConfigureInterfaceUpdate(SIX_TO_FOUR_IFINDEX, -1, TRUE);
  1243. ConfigureInterfaceUpdate(V4_COMPAT_IFINDEX, -1, TRUE);
  1244. //
  1245. // Add anycast addresses for all 6to4 addresses
  1246. //
  1247. for (i=0; i<g_pIpv4AddressList->iAddressCount; i++) {
  1248. pOurAddr = (LPSOCKADDR_IN)g_pIpv4AddressList->Address[i].lpSockaddr;
  1249. if ((GetIPv4Scope(pOurAddr->sin_addr.s_addr) != IPV4_SCOPE_GLOBAL)) {
  1250. continue;
  1251. }
  1252. Make6to4AnycastAddress(&AnycastAddress, pOurAddr);
  1253. ConfigureAddressUpdate(
  1254. SIX_TO_FOUR_IFINDEX, &AnycastAddress, INFINITE_LIFETIME,
  1255. ADE_ANYCAST, PREFIX_CONF_WELLKNOWN, IID_CONF_WELLKNOWN);
  1256. }
  1257. g_GlobalState.stRoutingState = ENABLED;
  1258. TraceLeave("EnableRouting");
  1259. }
  1260. // Called by: UpdateGlobalRoutingState
  1261. VOID
  1262. DisableRouting()
  1263. {
  1264. SOCKADDR_IN6 AnycastAddress;
  1265. int i;
  1266. LPSOCKADDR_IN pOurAddr;
  1267. DWORD dwErr;
  1268. TraceEnter("DisableRouting");
  1269. //
  1270. // Disable forwarding on the tunnel pseudo-interfaces.
  1271. //
  1272. ConfigureInterfaceUpdate(SIX_TO_FOUR_IFINDEX, -1, FALSE);
  1273. ConfigureInterfaceUpdate(V4_COMPAT_IFINDEX, -1, FALSE);
  1274. //
  1275. // Remove anycast addresses for all 6to4 addresses
  1276. //
  1277. for (i=0; i<g_pIpv4AddressList->iAddressCount; i++) {
  1278. pOurAddr = (LPSOCKADDR_IN)g_pIpv4AddressList->Address[i].lpSockaddr;
  1279. if ((GetIPv4Scope(pOurAddr->sin_addr.s_addr) != IPV4_SCOPE_GLOBAL)) {
  1280. continue;
  1281. }
  1282. Make6to4AnycastAddress(&AnycastAddress, pOurAddr);
  1283. dwErr = ConfigureAddressUpdate(
  1284. SIX_TO_FOUR_IFINDEX, &AnycastAddress, 0,
  1285. ADE_ANYCAST, PREFIX_CONF_WELLKNOWN, IID_CONF_WELLKNOWN);
  1286. }
  1287. g_GlobalState.stRoutingState = DISABLED;
  1288. TraceLeave("DisableRouting");
  1289. }
  1290. // Called by: UpdateInterfaceRoutingState
  1291. VOID
  1292. EnableInterfaceRouting(
  1293. IN PIF_INFO pIf, // private interface
  1294. IN PADDR_LIST pPublicAddressList) // public address list
  1295. {
  1296. int i;
  1297. LPSOCKADDR_IN pOurAddr;
  1298. SUBNET_CONTEXT Subnet;
  1299. Trace2(ERR, _T("Enabling routing on interface %d: %ls"),
  1300. pIf->ulIPv6IfIndex, pIf->pwszAdapterName);
  1301. ConfigureInterfaceUpdate(pIf->ulIPv6IfIndex, TRUE, TRUE);
  1302. // For each public address
  1303. for (i=0; i<pPublicAddressList->iAddressCount; i++) {
  1304. pOurAddr = (LPSOCKADDR_IN)pPublicAddressList->Address[i].lpSockaddr;
  1305. Subnet.V4Addr = pOurAddr->sin_addr;
  1306. Subnet.Publish = TRUE;
  1307. Subnet.ValidLifetime = 2 * DAYS;
  1308. Subnet.PreferredLifetime = 30 * MINUTES;
  1309. Configure6to4Subnets(pIf->ulIPv6IfIndex, &Subnet);
  1310. }
  1311. pIf->stRoutingState = ENABLED;
  1312. }
  1313. // Called by: PreUpdateInterfaceRoutingState, UninitializeInterfaces
  1314. BOOL
  1315. PreDisableInterfaceRouting(
  1316. IN PIF_INFO pIf, // private interface
  1317. IN PADDR_LIST pPublicAddressList)
  1318. {
  1319. int i;
  1320. LPSOCKADDR_IN pOurAddr;
  1321. SUBNET_CONTEXT Subnet;
  1322. Trace1(ERR, _T("Pre-Disabling routing on interface %d"),
  1323. pIf->ulIPv6IfIndex);
  1324. //
  1325. // For each public address, publish RA saying we're going away
  1326. //
  1327. for (i=0; i<pPublicAddressList->iAddressCount; i++) {
  1328. pOurAddr = (LPSOCKADDR_IN)pPublicAddressList->Address[i].lpSockaddr;
  1329. Subnet.V4Addr = pOurAddr->sin_addr;
  1330. Subnet.Publish = TRUE;
  1331. Subnet.ValidLifetime = Subnet.PreferredLifetime = 0;
  1332. Unconfigure6to4Subnets(pIf->ulIPv6IfIndex, &Subnet);
  1333. }
  1334. return (pPublicAddressList->iAddressCount > 0);
  1335. }
  1336. // Called by: UpdateInterfaceRoutingState, UninitializeInterfaces
  1337. VOID
  1338. DisableInterfaceRouting(
  1339. IN PIF_INFO pIf, // private interface
  1340. IN PADDR_LIST pPublicAddressList)
  1341. {
  1342. int i;
  1343. LPSOCKADDR_IN pOurAddr;
  1344. SUBNET_CONTEXT Subnet;
  1345. Trace1(ERR, _T("Disabling routing on interface %d"), pIf->ulIPv6IfIndex);
  1346. ConfigureInterfaceUpdate(pIf->ulIPv6IfIndex, FALSE, FALSE);
  1347. //
  1348. // For each public address, unconfigure 6to4 subnets
  1349. //
  1350. for (i=0; i<pPublicAddressList->iAddressCount; i++) {
  1351. pOurAddr = (LPSOCKADDR_IN)pPublicAddressList->Address[i].lpSockaddr;
  1352. Subnet.V4Addr = pOurAddr->sin_addr;
  1353. Subnet.Publish = FALSE;
  1354. Subnet.ValidLifetime = Subnet.PreferredLifetime = 0;
  1355. Unconfigure6to4Subnets(pIf->ulIPv6IfIndex, &Subnet);
  1356. }
  1357. pIf->stRoutingState = DISABLED;
  1358. }
  1359. BOOL // TRUE if need to sleep
  1360. PreUpdateInterfaceRoutingState(
  1361. IN PIF_INFO pIf, // private interface
  1362. IN PADDR_LIST pPublicAddressList)
  1363. {
  1364. STATE stIfRoutingState = GetInterfaceRoutingState(pIf);
  1365. if (pIf->stRoutingState == stIfRoutingState) {
  1366. return FALSE;
  1367. }
  1368. if (!(stIfRoutingState == ENABLED)) {
  1369. return PreDisableInterfaceRouting(pIf, pPublicAddressList);
  1370. }
  1371. return FALSE;
  1372. }
  1373. //
  1374. // Update the current state of an interface (i.e. whether or not it's a
  1375. // private interface on which we're serving as a router) according to
  1376. // configuration and whether IPv4 global addresses exist on the interface.
  1377. //
  1378. // Called by: UpdateGlobalRoutingState, OnConfigChange
  1379. VOID
  1380. UpdateInterfaceRoutingState(
  1381. IN PIF_INFO pIf, // private interface
  1382. IN PADDR_LIST pPublicAddressList)
  1383. {
  1384. STATE stIfRoutingState = GetInterfaceRoutingState(pIf);
  1385. if (pIf->stRoutingState == stIfRoutingState) {
  1386. return;
  1387. }
  1388. if (stIfRoutingState == ENABLED) {
  1389. EnableInterfaceRouting(pIf, pPublicAddressList);
  1390. } else {
  1391. DisableInterfaceRouting(pIf, pPublicAddressList);
  1392. }
  1393. }
  1394. BOOL
  1395. PreUpdateGlobalRoutingState()
  1396. {
  1397. ULONG i;
  1398. PIF_LIST pList = g_pInterfaceList;
  1399. BOOL bWait = FALSE;
  1400. if (pList == NULL) {
  1401. return FALSE;
  1402. }
  1403. for (i = 0; i < pList->ulNumInterfaces; i++) {
  1404. bWait |= PreUpdateInterfaceRoutingState(&pList->arrIf[i],
  1405. g_pIpv4AddressList);
  1406. }
  1407. return bWait;
  1408. }
  1409. // Called by: OnConfigChange, OnChangeInterfaceInfo
  1410. VOID
  1411. UpdateGlobalRoutingState()
  1412. {
  1413. ULONG i;
  1414. PIF_LIST pList = g_pInterfaceList;
  1415. STATE stNewRoutingState;
  1416. stNewRoutingState = GetGlobalRoutingState();
  1417. if (g_GlobalState.stRoutingState != stNewRoutingState) {
  1418. if (stNewRoutingState == ENABLED) {
  1419. EnableRouting();
  1420. } else {
  1421. DisableRouting();
  1422. }
  1423. }
  1424. if (pList == NULL) {
  1425. return;
  1426. }
  1427. for (i=0; i<pList->ulNumInterfaces; i++) {
  1428. UpdateInterfaceRoutingState(&pList->arrIf[i], g_pIpv4AddressList);
  1429. }
  1430. }
  1431. ////////////////////////////////////////////////////////////////
  1432. // Interface-related subroutines
  1433. ////////////////////////////////////////////////////////////////
  1434. PIF_SETTINGS
  1435. FindInterfaceSettings(
  1436. IN WCHAR *pwszAdapterName,
  1437. IN IF_SETTINGS_LIST *pList)
  1438. {
  1439. ULONG i;
  1440. PIF_SETTINGS pIf;
  1441. if (pList == NULL) {
  1442. return NULL;
  1443. }
  1444. for (i=0; i<pList->ulNumInterfaces; i++) {
  1445. pIf = &pList->arrIf[i];
  1446. if (wcscmp(pIf->pwszAdapterName, pwszAdapterName)) {
  1447. return pIf;
  1448. }
  1449. }
  1450. return NULL;
  1451. }
  1452. PIF_INFO
  1453. FindInterfaceInfo(
  1454. IN WCHAR *pwszAdapterName,
  1455. IN IF_LIST *pList)
  1456. {
  1457. ULONG i;
  1458. PIF_INFO pIf;
  1459. if (pList == NULL) {
  1460. return NULL;
  1461. }
  1462. for (i=0; i<pList->ulNumInterfaces; i++) {
  1463. pIf = &pList->arrIf[i];
  1464. if (!wcscmp(pIf->pwszAdapterName, pwszAdapterName)) {
  1465. return pIf;
  1466. }
  1467. }
  1468. return NULL;
  1469. }
  1470. DWORD NTAPI
  1471. OnRouteChange(
  1472. IN PVOID Context,
  1473. IN BOOLEAN TimedOut
  1474. );
  1475. VOID
  1476. StopRouteChangeNotification()
  1477. {
  1478. if (g_hRouteChangeWaitHandle) {
  1479. //
  1480. // Block until we're sure that the route change callback isn't
  1481. // still running.
  1482. //
  1483. LEAVE_API();
  1484. UnregisterWaitEx(g_hRouteChangeWaitHandle, INVALID_HANDLE_VALUE);
  1485. ENTER_API();
  1486. //
  1487. // Release the event we counted for RegisterWaitForSingleObject
  1488. //
  1489. DecEventCount("AC:StopIpv4RouteChangeNotification");
  1490. g_hRouteChangeWaitHandle = NULL;
  1491. }
  1492. if (g_hRouteChangeEvent) {
  1493. CloseHandle(g_hRouteChangeEvent);
  1494. g_hRouteChangeEvent = NULL;
  1495. }
  1496. }
  1497. VOID
  1498. StartRouteChangeNotification()
  1499. {
  1500. ULONG Error;
  1501. BOOL bOk;
  1502. HANDLE TcpipHandle;
  1503. TraceEnter("StartRouteChangeNotification");
  1504. //
  1505. // Create an event on which to receive notifications
  1506. // and register a callback routine to be invoked if the event is signalled.
  1507. // Then request notification of route changes on the event.
  1508. //
  1509. if (!g_hRouteChangeEvent) {
  1510. g_hRouteChangeEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  1511. if (g_hRouteChangeEvent == NULL) {
  1512. goto Error;
  1513. }
  1514. //
  1515. // Count the following register as an event.
  1516. //
  1517. IncEventCount("AC:StartIpv4RouteChangeNotification");
  1518. bOk = RegisterWaitForSingleObject(&g_hRouteChangeWaitHandle,
  1519. g_hRouteChangeEvent,
  1520. OnRouteChange,
  1521. NULL,
  1522. INFINITE,
  1523. 0);
  1524. if (!bOk) {
  1525. DecEventCount("AC:StartIpv4RouteChangeNotification");
  1526. goto Error;
  1527. }
  1528. }
  1529. ZeroMemory(&g_hRouteChangeOverlapped, sizeof(OVERLAPPED));
  1530. g_hRouteChangeOverlapped.hEvent = g_hRouteChangeEvent;
  1531. Error = NotifyRouteChange(&TcpipHandle, &g_hRouteChangeOverlapped);
  1532. if (Error != ERROR_IO_PENDING) {
  1533. goto Error;
  1534. }
  1535. return;
  1536. Error:
  1537. //
  1538. // A failure has occurred, so cleanup and quit.
  1539. // We proceed in this case without notification of route changes.
  1540. //
  1541. StopRouteChangeNotification();
  1542. TraceLeave("StartRouteChangeNotification");
  1543. }
  1544. // This routine is invoked when a change to the IPv4 route table is signalled.
  1545. //
  1546. DWORD NTAPI
  1547. OnRouteChange(
  1548. IN PVOID Context,
  1549. IN BOOLEAN TimedOut)
  1550. {
  1551. ENTER_API();
  1552. TraceEnter("OnRouteChange");
  1553. if (g_stService == DISABLED) {
  1554. Trace0(FSM, L"Service disabled");
  1555. goto Done;
  1556. }
  1557. //
  1558. // First register for another route change notification.
  1559. // We must do this *before* processing this route change,
  1560. // to avoid missing an route change.
  1561. //
  1562. StartRouteChangeNotification();
  1563. UpdateGlobalResolutionState();
  1564. IsatapRouteChangeNotification();
  1565. #ifdef TEREDO
  1566. TeredoRouteChangeNotification();
  1567. #endif // TEREDO
  1568. Done:
  1569. TraceLeave("OnRouteChange");
  1570. LEAVE_API();
  1571. return NO_ERROR;
  1572. }
  1573. DWORD NTAPI
  1574. OnChangeInterfaceInfo(
  1575. IN PVOID Context,
  1576. IN BOOLEAN TimedOut
  1577. );
  1578. VOID
  1579. StopAddressChangeNotification()
  1580. {
  1581. if (g_hAddressChangeWaitHandle) {
  1582. //
  1583. // Block until we're sure that the address change callback isn't
  1584. // still running.
  1585. //
  1586. LEAVE_API();
  1587. UnregisterWaitEx(g_hAddressChangeWaitHandle, INVALID_HANDLE_VALUE);
  1588. ENTER_API();
  1589. //
  1590. // Release the event we counted for RegisterWaitForSingleObject
  1591. //
  1592. DecEventCount("AC:StopIpv4AddressChangeNotification");
  1593. g_hAddressChangeWaitHandle = NULL;
  1594. }
  1595. if (g_hAddressChangeEvent) {
  1596. CloseHandle(g_hAddressChangeEvent);
  1597. g_hAddressChangeEvent = NULL;
  1598. }
  1599. }
  1600. VOID
  1601. StartAddressChangeNotification()
  1602. {
  1603. ULONG Error;
  1604. BOOL bOk;
  1605. HANDLE TcpipHandle;
  1606. TraceEnter("StartAddressChangeNotification");
  1607. //
  1608. // Create an event on which to receive notifications
  1609. // and register a callback routine to be invoked if the event is signalled.
  1610. // Then request notification of address changes on the event.
  1611. //
  1612. if (!g_hAddressChangeEvent) {
  1613. g_hAddressChangeEvent = CreateEvent(NULL,
  1614. FALSE,
  1615. FALSE,
  1616. NULL);
  1617. if (g_hAddressChangeEvent == NULL) {
  1618. goto Error;
  1619. }
  1620. //
  1621. // Count the following register as an event.
  1622. //
  1623. IncEventCount("AC:StartIpv4AddressChangeNotification");
  1624. bOk = RegisterWaitForSingleObject(&g_hAddressChangeWaitHandle,
  1625. g_hAddressChangeEvent,
  1626. OnChangeInterfaceInfo,
  1627. NULL,
  1628. INFINITE,
  1629. 0);
  1630. if (!bOk) {
  1631. DecEventCount("AC:StartIpv4AddressChangeNotification");
  1632. goto Error;
  1633. }
  1634. }
  1635. ZeroMemory(&g_hAddressChangeOverlapped, sizeof(OVERLAPPED));
  1636. g_hAddressChangeOverlapped.hEvent = g_hAddressChangeEvent;
  1637. Error = NotifyAddrChange(&TcpipHandle, &g_hAddressChangeOverlapped);
  1638. if (Error != ERROR_IO_PENDING) {
  1639. goto Error;
  1640. }
  1641. return;
  1642. Error:
  1643. //
  1644. // A failure has occurred, so cleanup and quit.
  1645. // We proceed in this case without notification of address changes.
  1646. //
  1647. StopAddressChangeNotification();
  1648. TraceLeave("StartAddressChangeNotification");
  1649. }
  1650. //
  1651. // Convert an "adapter" list to an "interface" list and store the result in
  1652. // the global g_pInterfaceList.
  1653. //
  1654. DWORD
  1655. MakeInterfaceList(
  1656. IN PIP_ADAPTER_INFO pAdapterInfo)
  1657. {
  1658. DWORD dwErr = NO_ERROR;
  1659. ULONG ulNumInterfaces = 0, ulSize;
  1660. PIP_ADAPTER_INFO pAdapter;
  1661. PIF_INFO pIf;
  1662. IPV6_INFO_INTERFACE *pIfStackInfo;
  1663. // count adapters
  1664. for (pAdapter=pAdapterInfo; pAdapter; pAdapter=pAdapter->Next) {
  1665. ulNumInterfaces++;
  1666. }
  1667. // allocate enough space
  1668. ulSize = FIELD_OFFSET(IF_LIST, arrIf[ulNumInterfaces]);
  1669. g_pInterfaceList = MALLOC(ulSize);
  1670. if (g_pInterfaceList == NULL) {
  1671. return GetLastError();
  1672. }
  1673. // fill in list
  1674. g_pInterfaceList->ulNumInterfaces = ulNumInterfaces;
  1675. ZeroMemory(g_pInterfaceList->ulNumScopedAddrs,
  1676. sizeof(ULONG) * NUM_IPV4_SCOPES);
  1677. ulNumInterfaces = 0;
  1678. for (pAdapter=pAdapterInfo; pAdapter; pAdapter=pAdapter->Next) {
  1679. pIf = &g_pInterfaceList->arrIf[ulNumInterfaces];
  1680. ConvertOemToUnicode(pAdapter->AdapterName, pIf->pwszAdapterName,
  1681. MAX_ADAPTER_NAME);
  1682. Trace1(FSM, _T("Adding interface %ls"), pIf->pwszAdapterName);
  1683. dwErr = MakeAddressList(&pAdapter->IpAddressList,
  1684. &pIf->pAddressList, &pIf->ulNumGlobals,
  1685. g_pInterfaceList->ulNumScopedAddrs);
  1686. pIfStackInfo = GetInterfaceStackInfo(pIf->pwszAdapterName);
  1687. if (pIfStackInfo) {
  1688. pIf->ulIPv6IfIndex = pIfStackInfo->This.Index;
  1689. } else {
  1690. pIf->ulIPv6IfIndex = 0;
  1691. }
  1692. FREE(pIfStackInfo);
  1693. pIf->stRoutingState = DISABLED;
  1694. ulNumInterfaces++;
  1695. }
  1696. return dwErr;
  1697. }
  1698. VOID
  1699. FreeInterfaceList(
  1700. IN OUT PIF_LIST *ppList)
  1701. {
  1702. ULONG i;
  1703. if (*ppList == NULL) {
  1704. return;
  1705. }
  1706. for (i=0; i<(*ppList)->ulNumInterfaces; i++) {
  1707. FreeAddressList( &(*ppList)->arrIf[i].pAddressList );
  1708. }
  1709. FREE(*ppList);
  1710. *ppList = NULL;
  1711. }
  1712. DWORD
  1713. InitializeInterfaces()
  1714. {
  1715. g_pInterfaceList = NULL;
  1716. return NO_ERROR;
  1717. }
  1718. VOID
  1719. ProcessInterfaceStateChange(
  1720. IN ADDR_LIST CONST *pAddressList,
  1721. IN ADDR_LIST *pOldAddressList,
  1722. IN PIF_LIST pOldInterfaceList,
  1723. IN GLOBAL_STATE *pOldState,
  1724. IN OUT BOOL *pbNeedDelete)
  1725. {
  1726. INT j,k;
  1727. LPSOCKADDR_IN pAddr;
  1728. // For each new global address not in old list,
  1729. // add a 6to4 address
  1730. for (j=0; j<pAddressList->iAddressCount; j++) {
  1731. pAddr = (LPSOCKADDR_IN)pAddressList->Address[j].lpSockaddr;
  1732. Trace1(FSM, _T("Checking for new address %d.%d.%d.%d"),
  1733. PRINT_IPADDR(pAddr->sin_addr.s_addr));
  1734. // See if address is in old list
  1735. for (k=0; k<pOldAddressList->iAddressCount; k++) {
  1736. if (pAddr->sin_addr.s_addr == ((LPSOCKADDR_IN)pOldAddressList->Address[k].lpSockaddr)->sin_addr.s_addr) {
  1737. break;
  1738. }
  1739. }
  1740. // If so, continue
  1741. if (k<pOldAddressList->iAddressCount) {
  1742. continue;
  1743. }
  1744. // Add an address, and use it for routing if enabled
  1745. AddAddress(pAddr, g_pInterfaceList, g_GlobalState.stRoutingState);
  1746. }
  1747. // For each old global address not in the new list,
  1748. // delete a 6to4 address
  1749. for (k=0; k<pOldAddressList->iAddressCount; k++) {
  1750. pAddr = (LPSOCKADDR_IN)pOldAddressList->Address[k].lpSockaddr;
  1751. Trace1(FSM, _T("Checking for old address %d.%d.%d.%d"),
  1752. PRINT_IPADDR(pAddr->sin_addr.s_addr));
  1753. // See if address is in new list
  1754. for (j=0; j<pAddressList->iAddressCount; j++) {
  1755. if (((LPSOCKADDR_IN)pAddressList->Address[j].lpSockaddr)->sin_addr.s_addr
  1756. == pAddr->sin_addr.s_addr) {
  1757. break;
  1758. }
  1759. }
  1760. // If so, continue
  1761. if (j<pAddressList->iAddressCount) {
  1762. continue;
  1763. }
  1764. // Prepare to delete the 6to4 address
  1765. PreDeleteAddress(pAddr, pOldInterfaceList, pOldState->stRoutingState);
  1766. *pbNeedDelete = TRUE;
  1767. }
  1768. }
  1769. VOID
  1770. FinishInterfaceStateChange(
  1771. IN ADDR_LIST CONST *pAddressList,
  1772. IN ADDR_LIST *pOldAddressList,
  1773. IN PIF_LIST pOldInterfaceList,
  1774. IN GLOBAL_STATE *pOldState)
  1775. {
  1776. INT j,k;
  1777. LPSOCKADDR_IN pAddr;
  1778. // For each old global address not in the new list,
  1779. // delete a 6to4 address
  1780. for (k=0; k<pOldAddressList->iAddressCount; k++) {
  1781. pAddr = (LPSOCKADDR_IN)pOldAddressList->Address[k].lpSockaddr;
  1782. Trace1(FSM, _T("Checking for old address %d.%d.%d.%d"),
  1783. PRINT_IPADDR(pAddr->sin_addr.s_addr));
  1784. // See if address is in new list
  1785. for (j=0; j<pAddressList->iAddressCount; j++) {
  1786. if (((LPSOCKADDR_IN)pAddressList->Address[j].lpSockaddr)->sin_addr.s_addr
  1787. == pAddr->sin_addr.s_addr) {
  1788. break;
  1789. }
  1790. }
  1791. // If so, continue
  1792. if (j<pAddressList->iAddressCount) {
  1793. continue;
  1794. }
  1795. // Prepare to delete the 6to4 address
  1796. DeleteAddress(pAddr, pOldInterfaceList, pOldState->stRoutingState);
  1797. }
  1798. }
  1799. // This routine is invoked when a change to the set of local IPv4 addressed
  1800. // is signalled. It is responsible for updating the bindings of the
  1801. // private and public interfaces, and re-requesting change notification.
  1802. //
  1803. DWORD NTAPI
  1804. OnChangeInterfaceInfo(
  1805. IN PVOID Context,
  1806. IN BOOLEAN TimedOut)
  1807. {
  1808. PIF_INFO pIf, pOldIf;
  1809. ULONG i, ulSize = 0;
  1810. PIP_ADAPTER_INFO pAdapterInfo = NULL;
  1811. PIF_LIST pOldInterfaceList;
  1812. DWORD dwErr = NO_ERROR;
  1813. ADDR_LIST *pAddressList, *pOldAddressList;
  1814. GLOBAL_SETTINGS OldSettings;
  1815. GLOBAL_STATE OldState;
  1816. BOOL bNeedDelete = FALSE, bWait = FALSE;
  1817. ENTER_API();
  1818. TraceEnter("OnChangeInterfaceInfo");
  1819. if (g_stService == DISABLED) {
  1820. Trace0(FSM, L"Service disabled");
  1821. goto Done;
  1822. }
  1823. //
  1824. // First register for another address change notification.
  1825. // We must do this *before* getting the address list,
  1826. // to avoid missing an address change.
  1827. //
  1828. StartAddressChangeNotification();
  1829. OldSettings = g_GlobalSettings; // struct copy
  1830. OldState = g_GlobalState; // struct copy
  1831. //
  1832. // Get the new set of IPv4 addresses on interfaces
  1833. //
  1834. for (;;) {
  1835. dwErr = GetAdaptersInfo(pAdapterInfo, &ulSize);
  1836. if (dwErr == ERROR_SUCCESS) {
  1837. break;
  1838. }
  1839. if (dwErr == ERROR_NO_DATA) {
  1840. dwErr = ERROR_SUCCESS;
  1841. break;
  1842. }
  1843. if (pAdapterInfo) {
  1844. FREE(pAdapterInfo);
  1845. pAdapterInfo = NULL;
  1846. }
  1847. if (dwErr != ERROR_BUFFER_OVERFLOW) {
  1848. dwErr = GetLastError();
  1849. goto Done;
  1850. }
  1851. pAdapterInfo = MALLOC(ulSize);
  1852. if (pAdapterInfo == NULL) {
  1853. dwErr = GetLastError();
  1854. goto Done;
  1855. }
  1856. }
  1857. pOldInterfaceList = g_pInterfaceList;
  1858. g_pInterfaceList = NULL;
  1859. MakeInterfaceList(pAdapterInfo);
  1860. if (pAdapterInfo) {
  1861. FREE(pAdapterInfo);
  1862. pAdapterInfo = NULL;
  1863. }
  1864. //
  1865. // First update global address list
  1866. //
  1867. // For each interface in the new list...
  1868. for (i=0; i<g_pInterfaceList->ulNumInterfaces; i++) {
  1869. pIf = &g_pInterfaceList->arrIf[i];
  1870. pAddressList = pIf->pAddressList;
  1871. pOldIf = FindInterfaceInfo(pIf->pwszAdapterName,
  1872. pOldInterfaceList);
  1873. pOldAddressList = (pOldIf)? pOldIf->pAddressList : &EmptyAddressList;
  1874. if (pOldIf) {
  1875. pIf->stRoutingState = pOldIf->stRoutingState;
  1876. }
  1877. ProcessInterfaceStateChange(pAddressList, pOldAddressList,
  1878. pOldInterfaceList, &OldState, &bNeedDelete);
  1879. }
  1880. // For each old interface not in the new list,
  1881. // delete information.
  1882. for (i=0; pOldInterfaceList && (i<pOldInterfaceList->ulNumInterfaces); i++){
  1883. pOldIf = &pOldInterfaceList->arrIf[i];
  1884. pOldAddressList = pOldIf->pAddressList;
  1885. pIf = FindInterfaceInfo(pOldIf->pwszAdapterName, g_pInterfaceList);
  1886. if (pIf) {
  1887. continue;
  1888. }
  1889. ProcessInterfaceStateChange(&EmptyAddressList, pOldAddressList,
  1890. pOldInterfaceList, &OldState, &bNeedDelete);
  1891. }
  1892. Trace2(FSM, _T("num globals=%d num publics=%d"),
  1893. g_pInterfaceList->ulNumScopedAddrs[IPV4_SCOPE_GLOBAL],
  1894. g_pIpv4AddressList->iAddressCount);
  1895. if (g_pInterfaceList->ulNumScopedAddrs[IPV4_SCOPE_GLOBAL] == 0) {
  1896. PreDelete6to4Routes();
  1897. }
  1898. bWait = PreUpdateGlobalRoutingState();
  1899. //
  1900. // If needed, wait a bit to ensure that Router Advertisements
  1901. // carrying the zero lifetime prefixes get sent.
  1902. //
  1903. if (bWait || (bNeedDelete && (OldState.stRoutingState == ENABLED))) {
  1904. Sleep(2000);
  1905. }
  1906. g_st6to4State = (g_pInterfaceList->ulNumScopedAddrs[IPV4_SCOPE_GLOBAL] > 0)
  1907. ? ENABLED : DISABLED;
  1908. UpdateGlobalResolutionState();
  1909. Update6to4Routes();
  1910. UpdateGlobalRoutingState();
  1911. //
  1912. // Now finish removing the 6to4 addresses.
  1913. //
  1914. if (bNeedDelete) {
  1915. for (i=0; i<g_pInterfaceList->ulNumInterfaces; i++) {
  1916. pIf = &g_pInterfaceList->arrIf[i];
  1917. pAddressList = pIf->pAddressList;
  1918. pOldIf = FindInterfaceInfo(pIf->pwszAdapterName,
  1919. pOldInterfaceList);
  1920. pOldAddressList = (pOldIf)? pOldIf->pAddressList : &EmptyAddressList;
  1921. FinishInterfaceStateChange(pAddressList, pOldAddressList,
  1922. pOldInterfaceList, &OldState);
  1923. }
  1924. for (i=0; pOldInterfaceList && (i<pOldInterfaceList->ulNumInterfaces); i++){
  1925. pOldIf = &pOldInterfaceList->arrIf[i];
  1926. pOldAddressList = pOldIf->pAddressList;
  1927. pIf = FindInterfaceInfo(pOldIf->pwszAdapterName, g_pInterfaceList);
  1928. if (pIf) {
  1929. continue;
  1930. }
  1931. FinishInterfaceStateChange(&EmptyAddressList, pOldAddressList,
  1932. pOldInterfaceList, &OldState);
  1933. }
  1934. }
  1935. FreeInterfaceList(&pOldInterfaceList);
  1936. Done:
  1937. TraceLeave("OnChangeInterfaceInfo");
  1938. LEAVE_API();
  1939. return dwErr;
  1940. }
  1941. // Note that this function can take over 2 seconds to complete if we're a
  1942. // router. (This is by design).
  1943. //
  1944. // Called by: Stop6to4
  1945. VOID
  1946. UninitializeInterfaces()
  1947. {
  1948. PIF_INFO pIf;
  1949. ULONG i;
  1950. int k;
  1951. ADDR_LIST *pAddressList;
  1952. LPSOCKADDR_IN pAddr;
  1953. TraceEnter("UninitializeInterfaces");
  1954. // Cancel the address change notification
  1955. StopIpv6AddressChangeNotification();
  1956. StopAddressChangeNotification();
  1957. StopRouteChangeNotification();
  1958. // Since this is the first function called when stopping,
  1959. // the "old" global state/settings is in g_GlobalState/Settings.
  1960. if (g_GlobalSettings.stUndoOnStop == ENABLED) {
  1961. if (g_GlobalState.stRoutingState == ENABLED) {
  1962. //
  1963. // First announce we're going away
  1964. //
  1965. PreDelete6to4Routes();
  1966. //
  1967. // Now do the same for subnets we're advertising
  1968. //
  1969. for (i=0; i<g_pInterfaceList->ulNumInterfaces; i++) {
  1970. pIf = &g_pInterfaceList->arrIf[i];
  1971. pAddressList = pIf->pAddressList;
  1972. // For each old global address not in the new list,
  1973. // delete a 6to4 address (see below)
  1974. Trace1(FSM, _T("Checking %d old addresses"),
  1975. pAddressList->iAddressCount);
  1976. for (k=0; k<pAddressList->iAddressCount; k++) {
  1977. pAddr = (LPSOCKADDR_IN)pAddressList->Address[k].lpSockaddr;
  1978. Trace1(FSM, _T("Checking for old address %d.%d.%d.%d"),
  1979. PRINT_IPADDR(pAddr->sin_addr.s_addr));
  1980. PreDeleteAddress(pAddr, g_pInterfaceList, ENABLED);
  1981. }
  1982. if (pIf->stRoutingState == ENABLED) {
  1983. PreDisableInterfaceRouting(pIf, g_pIpv4AddressList);
  1984. }
  1985. }
  1986. //
  1987. // Wait a bit to ensure that Router Advertisements
  1988. // carrying the zero lifetime prefixes get sent.
  1989. //
  1990. Sleep(2000);
  1991. }
  1992. g_st6to4State = DISABLED;
  1993. Update6to4Routes();
  1994. //
  1995. // Delete 6to4 addresses
  1996. //
  1997. for (i=0; g_pInterfaceList && i<g_pInterfaceList->ulNumInterfaces; i++) {
  1998. pIf = &g_pInterfaceList->arrIf[i];
  1999. pAddressList = pIf->pAddressList;
  2000. // For each old global address not in the new list,
  2001. // delete a 6to4 address (see below)
  2002. Trace1(FSM, _T("Checking %d old addresses"),
  2003. pAddressList->iAddressCount);
  2004. for (k=0; k<pAddressList->iAddressCount; k++) {
  2005. pAddr = (LPSOCKADDR_IN)pAddressList->Address[k].lpSockaddr;
  2006. Trace1(FSM, _T("Checking for old address %d.%d.%d.%d"),
  2007. PRINT_IPADDR(pAddr->sin_addr.s_addr));
  2008. DeleteAddress(pAddr, g_pInterfaceList,
  2009. g_GlobalState.stRoutingState);
  2010. }
  2011. // update the IPv6 routing state
  2012. if (pIf->stRoutingState == ENABLED) {
  2013. DisableInterfaceRouting(pIf, g_pIpv4AddressList);
  2014. }
  2015. }
  2016. if (g_GlobalState.stRoutingState == ENABLED) {
  2017. DisableRouting();
  2018. }
  2019. }
  2020. // Free the "old list"
  2021. FreeInterfaceList(&g_pInterfaceList);
  2022. TraceLeave("UninitializeInterfaces");
  2023. }
  2024. ////////////////////////////////////////////////////////////////
  2025. // Event-processing functions
  2026. ////////////////////////////////////////////////////////////////
  2027. // Get an integer value from the registry
  2028. ULONG
  2029. GetInteger(
  2030. IN HKEY hKey,
  2031. IN LPCTSTR lpName,
  2032. IN ULONG ulDefault)
  2033. {
  2034. DWORD dwErr, dwType;
  2035. ULONG ulSize, ulValue;
  2036. if (hKey == INVALID_HANDLE_VALUE) {
  2037. return ulDefault;
  2038. }
  2039. ulSize = sizeof(ulValue);
  2040. dwErr = RegQueryValueEx(hKey, lpName, NULL, &dwType, (PBYTE)&ulValue,
  2041. &ulSize);
  2042. if (dwErr != ERROR_SUCCESS) {
  2043. return ulDefault;
  2044. }
  2045. if (dwType != REG_DWORD) {
  2046. return ulDefault;
  2047. }
  2048. if (ulValue == DEFAULT) {
  2049. return ulDefault;
  2050. }
  2051. return ulValue;
  2052. }
  2053. // Get a string value from the registry
  2054. VOID
  2055. GetString(
  2056. IN HKEY hKey,
  2057. IN LPCTSTR lpName,
  2058. IN PWCHAR pBuff,
  2059. IN ULONG ulLength,
  2060. IN PWCHAR pDefault)
  2061. {
  2062. DWORD dwErr, dwType;
  2063. ULONG ulSize;
  2064. if (hKey == INVALID_HANDLE_VALUE) {
  2065. wcsncpy(pBuff, pDefault, ulLength);
  2066. return;
  2067. }
  2068. ulSize = ulLength - sizeof(L'\0');
  2069. dwErr = RegQueryValueEx(hKey, lpName, NULL, &dwType, (PBYTE)pBuff,
  2070. &ulSize);
  2071. if (dwErr != ERROR_SUCCESS) {
  2072. wcsncpy(pBuff, pDefault, ulLength);
  2073. return;
  2074. }
  2075. if (dwType != REG_SZ) {
  2076. wcsncpy(pBuff, pDefault, ulLength);
  2077. return;
  2078. }
  2079. if (pBuff[0] == L'\0') {
  2080. wcsncpy(pBuff, pDefault, ulLength);
  2081. return;
  2082. }
  2083. ASSERT(ulSize < ulLength);
  2084. pBuff[ulSize / sizeof(WCHAR)] = '\0'; // ensure NULL termination.
  2085. }
  2086. // called when # of 6to4 addresses becomes 0 or non-zero
  2087. // and when stEnableResolution setting changes
  2088. //
  2089. // Called by: OnConfigChange, OnChangeInterfaceInfo, OnChangeRouteInfo
  2090. VOID
  2091. UpdateGlobalResolutionState(
  2092. VOID
  2093. )
  2094. {
  2095. DWORD i;
  2096. // Decide whether relay name resolution should be enabled or not
  2097. if (Get6to4State() == DISABLED) {
  2098. g_GlobalState.stResolutionState = DISABLED;
  2099. } else if (g_GlobalSettings.stEnableResolution != AUTOMATIC) {
  2100. g_GlobalState.stResolutionState = g_GlobalSettings.stEnableResolution;
  2101. } else {
  2102. // Enable if we have any 6to4 addresses
  2103. g_GlobalState.stResolutionState = g_st6to4State;
  2104. }
  2105. if (g_GlobalState.stResolutionState == ENABLED) {
  2106. //
  2107. // Restart the resolution timer, even if it's already running
  2108. // and the name and interval haven't changed. We also get
  2109. // called when we first get an IP address, such as when we
  2110. // dial up to the Internet, and we want to immediately retry
  2111. // resolution at this point.
  2112. //
  2113. (VOID) RestartResolutionTimer(
  2114. 0,
  2115. g_GlobalSettings.ulResolutionInterval,
  2116. &g_h6to4ResolutionTimer,
  2117. (WAITORTIMERCALLBACK) OnResolutionTimeout);
  2118. } else {
  2119. if (g_h6to4ResolutionTimer != INVALID_HANDLE_VALUE) {
  2120. //
  2121. // stop it
  2122. //
  2123. CancelResolutionTimer(&g_h6to4ResolutionTimer,
  2124. g_h6to4TimerCancelledEvent);
  2125. }
  2126. // Delete all existing relays
  2127. if (g_pRelayList) {
  2128. for (i=0; i<g_pRelayList->ulNumRelays; i++) {
  2129. Delete6to4Relay(&g_pRelayList->arrRelay[i]);
  2130. }
  2131. FreeRelayList(&g_pRelayList);
  2132. }
  2133. }
  2134. }
  2135. VOID
  2136. Update6over4State(
  2137. IN STATE State
  2138. )
  2139. {
  2140. int i;
  2141. if (g_GlobalSettings.stEnable6over4 == State) {
  2142. return;
  2143. }
  2144. g_GlobalSettings.stEnable6over4 = State;
  2145. if (g_GlobalSettings.stEnable6over4 == ENABLED) {
  2146. // Create 6over4 interfaces
  2147. for (i=0; i<g_pIpv4AddressList->iAddressCount; i++) {
  2148. if (g_pIpv4AddressList->Address[i].ul6over4IfIndex) {
  2149. continue;
  2150. }
  2151. Trace1(ERR, _T("Creating interface for %d.%d.%d.%d"),
  2152. PRINT_IPADDR(((LPSOCKADDR_IN)g_pIpv4AddressList->Address[i].lpSockaddr)->sin_addr.s_addr));
  2153. g_pIpv4AddressList->Address[i].ul6over4IfIndex = Create6over4Interface(((LPSOCKADDR_IN)g_pIpv4AddressList->Address[i].lpSockaddr)->sin_addr);
  2154. }
  2155. } else {
  2156. // Delete all 6over4 interfaces
  2157. for (i=0; i<g_pIpv4AddressList->iAddressCount; i++) {
  2158. if (!g_pIpv4AddressList->Address[i].ul6over4IfIndex) {
  2159. continue;
  2160. }
  2161. Trace1(ERR, _T("Deleting interface for %d.%d.%d.%d"),
  2162. PRINT_IPADDR(((LPSOCKADDR_IN)g_pIpv4AddressList->Address[i].lpSockaddr)->sin_addr.s_addr));
  2163. DeleteInterface(g_pIpv4AddressList->Address[i].ul6over4IfIndex);
  2164. g_pIpv4AddressList->Address[i].ul6over4IfIndex = 0;
  2165. }
  2166. }
  2167. }
  2168. // Process a change to the state of whether v4-compatible addresses
  2169. // are enabled.
  2170. VOID
  2171. UpdateV4CompatState(
  2172. IN STATE State
  2173. )
  2174. {
  2175. int i;
  2176. LPSOCKADDR_IN pIPv4Address;
  2177. SOCKADDR_IN6 OurAddress;
  2178. u_int AddressLifetime;
  2179. if (g_GlobalSettings.stEnableV4Compat == State) {
  2180. return;
  2181. }
  2182. g_GlobalSettings.stEnableV4Compat = State;
  2183. // Create or delete the route, and figure out the address lifetime.
  2184. if (g_GlobalSettings.stEnableV4Compat == ENABLED) {
  2185. ConfigureRouteTableUpdate(&in6addr_any, 96,
  2186. V4_COMPAT_IFINDEX, &in6addr_any,
  2187. TRUE, // Publish.
  2188. TRUE, // Immortal.
  2189. 2 * HOURS, // Valid lifetime.
  2190. 30 * MINUTES, // Preferred lifetime.
  2191. 0,
  2192. SIXTOFOUR_METRIC);
  2193. AddressLifetime = INFINITE_LIFETIME;
  2194. } else {
  2195. ConfigureRouteTableUpdate(&in6addr_any, 96,
  2196. V4_COMPAT_IFINDEX, &in6addr_any,
  2197. FALSE, // Publish.
  2198. FALSE, // Immortal.
  2199. 0, 0, 0, 0);
  2200. AddressLifetime = 0;
  2201. }
  2202. // Now go and update the lifetime of v4-compatible addresses,
  2203. // which will cause them to be added or deleted.
  2204. for (i=0; i<g_pIpv4AddressList->iAddressCount; i++) {
  2205. pIPv4Address = (LPSOCKADDR_IN)g_pIpv4AddressList->
  2206. Address[i].lpSockaddr;
  2207. if (GetIPv4Scope(pIPv4Address->sin_addr.s_addr) != IPV4_SCOPE_GLOBAL) {
  2208. continue;
  2209. }
  2210. MakeV4CompatibleAddress(&OurAddress, pIPv4Address);
  2211. ConfigureAddressUpdate(V4_COMPAT_IFINDEX, &OurAddress,
  2212. AddressLifetime, ADE_UNICAST,
  2213. PREFIX_CONF_WELLKNOWN, IID_CONF_LL_ADDRESS);
  2214. }
  2215. }
  2216. // Process a change to something in the registry
  2217. DWORD
  2218. OnConfigChange()
  2219. {
  2220. HKEY hGlobal, hInterfaces, hIf;
  2221. DWORD dwErr, dwSize;
  2222. STATE State6over4, StateV4Compat;
  2223. DWORD i;
  2224. WCHAR pwszAdapterName[MAX_ADAPTER_NAME];
  2225. IF_SETTINGS *pIfSettings;
  2226. hGlobal = hInterfaces = hIf = INVALID_HANDLE_VALUE;
  2227. ENTER_API();
  2228. TraceEnter("OnConfigChange");
  2229. if (g_stService == DISABLED) {
  2230. TraceLeave("OnConfigChange (disabled)");
  2231. LEAVE_API();
  2232. return NO_ERROR;
  2233. }
  2234. // Read global settings from the registry
  2235. dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_GLOBAL, 0, KEY_QUERY_VALUE,
  2236. &hGlobal);
  2237. g_GlobalSettings.stEnable6to4 = GetInteger(
  2238. hGlobal, KEY_ENABLE_6TO4, DEFAULT_ENABLE_6TO4);
  2239. g_GlobalSettings.stEnableRouting = GetInteger(
  2240. hGlobal, KEY_ENABLE_ROUTING, DEFAULT_ENABLE_ROUTING);
  2241. g_GlobalSettings.stEnableSiteLocals = GetInteger(
  2242. hGlobal, KEY_ENABLE_SITELOCALS, DEFAULT_ENABLE_SITELOCALS);
  2243. g_GlobalSettings.stEnableResolution = GetInteger(
  2244. hGlobal, KEY_ENABLE_RESOLUTION, DEFAULT_ENABLE_RESOLUTION);
  2245. g_GlobalSettings.ulResolutionInterval = GetInteger(
  2246. hGlobal, KEY_RESOLUTION_INTERVAL, DEFAULT_RESOLUTION_INTERVAL);
  2247. GetString(
  2248. hGlobal, KEY_RELAY_NAME,
  2249. g_GlobalSettings.pwszRelayName, NI_MAXHOST, DEFAULT_RELAY_NAME);
  2250. if (g_GlobalSettings.stEnable6to4 == DISABLED) {
  2251. g_GlobalSettings.stEnableRouting
  2252. = g_GlobalSettings.stEnableResolution
  2253. = DISABLED;
  2254. }
  2255. State6over4 = GetInteger(
  2256. hGlobal, KEY_ENABLE_6OVER4, DEFAULT_ENABLE_6OVER4);
  2257. StateV4Compat = GetInteger(
  2258. hGlobal, KEY_ENABLE_V4COMPAT, DEFAULT_ENABLE_V4COMPAT);
  2259. g_GlobalSettings.stUndoOnStop = GetInteger(
  2260. hGlobal, KEY_UNDO_ON_STOP, DEFAULT_UNDO_ON_STOP);
  2261. if (hGlobal != INVALID_HANDLE_VALUE) {
  2262. RegCloseKey(hGlobal);
  2263. }
  2264. // Read interface settings from the registry
  2265. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_INTERFACES, 0, KEY_QUERY_VALUE,
  2266. &hInterfaces) == NO_ERROR) {
  2267. // For each interface in the registry
  2268. for (i=0; ; i++) {
  2269. dwSize = sizeof(pwszAdapterName) / sizeof(WCHAR);
  2270. dwErr = RegEnumKeyEx(hInterfaces, i, pwszAdapterName, &dwSize,
  2271. NULL, NULL, NULL, NULL);
  2272. if (dwErr != NO_ERROR) {
  2273. break;
  2274. }
  2275. // Find settings
  2276. pIfSettings = FindInterfaceSettings(pwszAdapterName,
  2277. g_pInterfaceSettingsList);
  2278. if (pIfSettings) {
  2279. // Read interface settings
  2280. (VOID) RegOpenKeyEx(
  2281. hInterfaces, pwszAdapterName, 0, KEY_QUERY_VALUE, &hIf);
  2282. pIfSettings->stEnableRouting = GetInteger(
  2283. hIf, KEY_ENABLE_ROUTING, DEFAULT_ENABLE_ROUTING);
  2284. if (hIf != INVALID_HANDLE_VALUE) {
  2285. RegCloseKey(hIf);
  2286. }
  2287. }
  2288. }
  2289. RegCloseKey(hInterfaces);
  2290. }
  2291. Update6to4State();
  2292. Update6over4State(State6over4);
  2293. UpdateV4CompatState(StateV4Compat);
  2294. if (!QueueUpdateGlobalPortState(NULL)) {
  2295. Trace0(SOCKET, L"QueueUpdateGlobalPortState failed");
  2296. }
  2297. IsatapConfigurationChangeNotification();
  2298. #ifdef TEREDO
  2299. TeredoConfigurationChangeNotification();
  2300. #endif // TEREDO
  2301. TraceLeave("OnConfigChange");
  2302. LEAVE_API();
  2303. return NO_ERROR;
  2304. }
  2305. ////////////////////////////////////////////////////////////////
  2306. // Startup/Shutdown-related functions
  2307. ////////////////////////////////////////////////////////////////
  2308. // Start the IPv6 helper service.
  2309. //
  2310. // To prevent the SCM from marking the service as hung, we periodically update
  2311. // our status, indicating that we are making progress but need more time.
  2312. //
  2313. // Called by: OnStartup
  2314. DWORD
  2315. StartHelperService()
  2316. {
  2317. DWORD dwErr;
  2318. WSADATA wsaData;
  2319. SetHelperServiceStatus(SERVICE_START_PENDING, NO_ERROR);
  2320. IncEventCount("StartHelperService");
  2321. g_stService = ENABLED;
  2322. //
  2323. // Initialize Winsock.
  2324. //
  2325. if (WSAStartup(MAKEWORD(2, 0), &wsaData)) {
  2326. Trace0(ERR, _T("WSAStartup failed\n"));
  2327. return GetLastError();
  2328. }
  2329. if (!InitIPv6Library()) {
  2330. dwErr = GetLastError();
  2331. Trace1(ERR, _T("InitIPv6Library failed with error %d"), dwErr);
  2332. return dwErr;
  2333. }
  2334. dwErr = InitEvents();
  2335. if (dwErr) {
  2336. return dwErr;
  2337. }
  2338. // Initialize the "old set" of config settings to the defaults
  2339. dwErr = InitializeGlobalInfo();
  2340. if (dwErr) {
  2341. return dwErr;
  2342. }
  2343. // Initialize the "old set" of interfaces (IPv4 addresses) to be empty
  2344. dwErr = InitializeInterfaces();
  2345. if (dwErr) {
  2346. return dwErr;
  2347. }
  2348. // Initialize the "old set" of relays to be empty
  2349. dwErr = InitializeRelays();
  2350. if (dwErr) {
  2351. return dwErr;
  2352. }
  2353. // Initialize the TCP proxy port list
  2354. InitializePorts();
  2355. // Initialize ISATAP
  2356. SetHelperServiceStatus(SERVICE_START_PENDING, NO_ERROR);
  2357. dwErr = IsatapInitialize();
  2358. if (dwErr) {
  2359. return dwErr;
  2360. }
  2361. #ifdef TEREDO
  2362. // Initialize Teredo
  2363. SetHelperServiceStatus(SERVICE_START_PENDING, NO_ERROR);
  2364. dwErr = TeredoInitializeGlobals();
  2365. if (dwErr) {
  2366. return dwErr;
  2367. }
  2368. #endif // TEREDO
  2369. // Process a config change event
  2370. SetHelperServiceStatus(SERVICE_START_PENDING, NO_ERROR);
  2371. dwErr = OnConfigChange();
  2372. if (dwErr) {
  2373. return dwErr;
  2374. }
  2375. // Request IPv4 route change notifications.
  2376. SetHelperServiceStatus(SERVICE_START_PENDING, NO_ERROR);
  2377. StartRouteChangeNotification();
  2378. // Process an IPv4 address change event.
  2379. // This will also schedule a resolution timer expiration if needed.
  2380. SetHelperServiceStatus(SERVICE_START_PENDING, NO_ERROR);
  2381. dwErr = OnChangeInterfaceInfo(NULL, FALSE);
  2382. if (dwErr) {
  2383. return dwErr;
  2384. }
  2385. // Request IPv6 address change notifications.
  2386. SetHelperServiceStatus(SERVICE_START_PENDING, NO_ERROR);
  2387. dwErr = StartIpv6AddressChangeNotification();
  2388. if (dwErr) {
  2389. return dwErr;
  2390. }
  2391. SetHelperServiceStatus(SERVICE_RUNNING, NO_ERROR);
  2392. return NO_ERROR;
  2393. }
  2394. /////////////////////////////////////////////////////////////////////////////
  2395. // Stop the IPv6 helper service. Since this is called with the global lock,
  2396. // we're guaranteed this won't be called while another 6to4 operation
  2397. // is in progress. However, another thread may be blocked waiting for
  2398. // the lock, so we set the state to stopped and check it in all other
  2399. // places after getting the lock.
  2400. //
  2401. // Called by: OnStop
  2402. VOID
  2403. StopHelperService(
  2404. IN DWORD Error
  2405. )
  2406. {
  2407. SetHelperServiceStatus(SERVICE_STOP_PENDING, Error);
  2408. g_stService = DISABLED;
  2409. // We do these in the opposite order from Start6to4
  2410. #ifdef TEREDO
  2411. // Uninitialize Teredo
  2412. TeredoUninitializeGlobals();
  2413. #endif // TEREDO
  2414. // Uninitialize ISATAP
  2415. IsatapUninitialize();
  2416. // Stop proxying
  2417. UninitializePorts();
  2418. // Stop the resolution timer and free resources
  2419. UninitializeRelays();
  2420. // Cancel the IPv4 address change request and free resources
  2421. // Also, stop being a router if we are one.
  2422. UninitializeInterfaces();
  2423. // Free settings resources
  2424. UninitializeGlobalInfo();
  2425. UninitIPv6Library();
  2426. DecEventCount("StopHelperService");
  2427. }
  2428. ////////////////////////////////////////////////////////////
  2429. // 6to4 Specific Code
  2430. ////////////////////////////////////////////////////////////
  2431. DWORD
  2432. __inline
  2433. Configure6to4Address(
  2434. IN BOOL Delete,
  2435. IN PSOCKADDR_IN Ipv4Address
  2436. )
  2437. {
  2438. SOCKADDR_IN6 Ipv6Address;
  2439. if ((GetIPv4Scope(Ipv4Address->sin_addr.s_addr) != IPV4_SCOPE_GLOBAL)) {
  2440. return NO_ERROR;
  2441. }
  2442. Make6to4Address(&Ipv6Address, Ipv4Address);
  2443. return ConfigureAddressUpdate(
  2444. SIX_TO_FOUR_IFINDEX,
  2445. &Ipv6Address,
  2446. Delete ? 0 : INFINITE_LIFETIME,
  2447. ADE_UNICAST, PREFIX_CONF_WELLKNOWN, IID_CONF_LL_ADDRESS);
  2448. }
  2449. VOID
  2450. PreDelete6to4Address(
  2451. IN LPSOCKADDR_IN Ipv4Address,
  2452. IN PIF_LIST InterfaceList,
  2453. IN STATE OldRoutingState
  2454. )
  2455. {
  2456. ULONG i;
  2457. SUBNET_CONTEXT Subnet;
  2458. PIF_INFO Interface;
  2459. if ((g_GlobalState.st6to4State != ENABLED) ||
  2460. (GetIPv4Scope(Ipv4Address->sin_addr.s_addr) != IPV4_SCOPE_GLOBAL)) {
  2461. return;
  2462. }
  2463. if (OldRoutingState != ENABLED) {
  2464. return;
  2465. }
  2466. //
  2467. // Disable the subnet routes on each private interface.
  2468. // This will generate RAs that have a zero lifetime
  2469. // for the subnet prefixes.
  2470. //
  2471. Subnet.V4Addr = Ipv4Address->sin_addr;
  2472. Subnet.Publish = TRUE;
  2473. Subnet.ValidLifetime = Subnet.PreferredLifetime = 0;
  2474. for (i=0; i<InterfaceList->ulNumInterfaces; i++) {
  2475. Interface = &InterfaceList->arrIf[i];
  2476. if (Interface->stRoutingState != ENABLED) {
  2477. continue;
  2478. }
  2479. Unconfigure6to4Subnets(Interface->ulIPv6IfIndex, &Subnet);
  2480. }
  2481. }
  2482. VOID
  2483. Delete6to4Address(
  2484. IN LPSOCKADDR_IN Ipv4Address,
  2485. IN PIF_LIST InterfaceList,
  2486. IN STATE OldRoutingState
  2487. )
  2488. {
  2489. SOCKADDR_IN6 AnycastAddress;
  2490. ULONG i;
  2491. PIF_INFO Interface;
  2492. SUBNET_CONTEXT Subnet;
  2493. if ((g_GlobalState.st6to4State != ENABLED) ||
  2494. (GetIPv4Scope(Ipv4Address->sin_addr.s_addr) != IPV4_SCOPE_GLOBAL)) {
  2495. return;
  2496. }
  2497. // Delete the 6to4 address from the stack
  2498. (VOID) Configure6to4Address(TRUE, (PSOCKADDR_IN) Ipv4Address);
  2499. if (OldRoutingState != ENABLED) {
  2500. return;
  2501. }
  2502. Make6to4AnycastAddress(&AnycastAddress, Ipv4Address);
  2503. (VOID) ConfigureAddressUpdate(
  2504. SIX_TO_FOUR_IFINDEX, &AnycastAddress, 0,
  2505. ADE_ANYCAST, PREFIX_CONF_WELLKNOWN, IID_CONF_WELLKNOWN);
  2506. // Remove subnets from all routing interfaces
  2507. Subnet.V4Addr = Ipv4Address->sin_addr;
  2508. Subnet.Publish = FALSE;
  2509. Subnet.ValidLifetime = Subnet.PreferredLifetime = 0;
  2510. for (i = 0; i < InterfaceList->ulNumInterfaces; i++) {
  2511. Interface = &InterfaceList->arrIf[i];
  2512. if (Interface->stRoutingState != ENABLED) {
  2513. continue;
  2514. }
  2515. Unconfigure6to4Subnets(Interface->ulIPv6IfIndex, &Subnet);
  2516. }
  2517. }
  2518. VOID
  2519. Add6to4Address(
  2520. IN LPSOCKADDR_IN Ipv4Address,
  2521. IN PIF_LIST InterfaceList,
  2522. IN STATE OldRoutingState
  2523. )
  2524. {
  2525. DWORD Error;
  2526. SOCKADDR_IN6 AnycastAddress;
  2527. ULONG i;
  2528. PIF_INFO Interface;
  2529. SUBNET_CONTEXT Subnet;
  2530. if ((g_GlobalState.st6to4State != ENABLED) ||
  2531. (GetIPv4Scope(Ipv4Address->sin_addr.s_addr) != IPV4_SCOPE_GLOBAL)) {
  2532. return;
  2533. }
  2534. // Add a 6to4 address.
  2535. Error = Configure6to4Address(FALSE, (PSOCKADDR_IN) Ipv4Address);
  2536. if (Error != NO_ERROR) {
  2537. return;
  2538. }
  2539. if (OldRoutingState != ENABLED) {
  2540. return;
  2541. }
  2542. Make6to4AnycastAddress(&AnycastAddress, Ipv4Address);
  2543. Error = ConfigureAddressUpdate(
  2544. SIX_TO_FOUR_IFINDEX, &AnycastAddress, INFINITE_LIFETIME,
  2545. ADE_ANYCAST, PREFIX_CONF_WELLKNOWN, IID_CONF_WELLKNOWN);
  2546. if (Error != NO_ERROR) {
  2547. return;
  2548. }
  2549. // Add subnets to all routing interfaces
  2550. for (i = 0; i < InterfaceList->ulNumInterfaces; i++) {
  2551. Interface = &InterfaceList->arrIf[i];
  2552. if (Interface->stRoutingState != ENABLED) {
  2553. continue;
  2554. }
  2555. Subnet.V4Addr = Ipv4Address->sin_addr;
  2556. Subnet.Publish = TRUE;
  2557. Subnet.ValidLifetime = 2 * HOURS;
  2558. Subnet.PreferredLifetime = 30 * MINUTES;
  2559. Configure6to4Subnets(Interface->ulIPv6IfIndex, &Subnet);
  2560. }
  2561. }
  2562. VOID
  2563. PreDelete6to4Routes(
  2564. VOID
  2565. )
  2566. {
  2567. if ((g_GlobalState.st6to4State != ENABLED) ||
  2568. (g_GlobalState.stRoutingState != ENABLED) ||
  2569. (g_st6to4State != ENABLED)) {
  2570. return;
  2571. }
  2572. //
  2573. // We were acting as a router and were publishing the 6to4 route, give the
  2574. // route a zero lifetime and continue to publish it until we have disabled
  2575. // routing. This allows the last RA to go out with the prefix.
  2576. //
  2577. (VOID) ConfigureRouteTableUpdate(
  2578. &SixToFourPrefix, 16, SIX_TO_FOUR_IFINDEX, &in6addr_any,
  2579. TRUE, // Publish
  2580. TRUE, // Immortal
  2581. 0, 0, 0, 0);
  2582. //
  2583. // Do the same for the v4-compatible address route (if enabled).
  2584. //
  2585. if (g_GlobalSettings.stEnableV4Compat == ENABLED) {
  2586. (VOID) ConfigureRouteTableUpdate(
  2587. &in6addr_any, 96, V4_COMPAT_IFINDEX, &in6addr_any,
  2588. TRUE, // Publish
  2589. TRUE, // Immortal
  2590. 0, 0, 0, 0);
  2591. }
  2592. }
  2593. VOID
  2594. Update6to4Routes(
  2595. VOID
  2596. )
  2597. {
  2598. BOOL Delete;
  2599. //
  2600. // CAVEAT: We might still end up trying to add a route that exists,
  2601. // or delete one that doesn't. But this should be harmless.
  2602. //
  2603. //
  2604. // Create/Delete the route for the 6to4 prefix.
  2605. // This route causes packets sent to 6to4 addresses
  2606. // to be encapsulated and sent to the extracted v4 address.
  2607. //
  2608. Delete = (Get6to4State() != ENABLED) || (g_st6to4State != ENABLED);
  2609. (VOID) ConfigureRouteTableUpdate(
  2610. &SixToFourPrefix, 16, SIX_TO_FOUR_IFINDEX, &in6addr_any,
  2611. !Delete, // Publish
  2612. !Delete, // Immortal
  2613. Delete ? 0 : 2 * HOURS, // Valid lifetime.
  2614. Delete ? 0 : 30 * MINUTES, // Preferred lifetime.
  2615. 0, SIXTOFOUR_METRIC);
  2616. //
  2617. // Create/Delete the v4-compatible address route.
  2618. //
  2619. Delete |= (g_GlobalSettings.stEnableV4Compat != ENABLED);
  2620. (VOID) ConfigureRouteTableUpdate(
  2621. &in6addr_any, 96, V4_COMPAT_IFINDEX, &in6addr_any,
  2622. !Delete, // Publish
  2623. !Delete, // Immortal
  2624. Delete ? 0 : 2 * HOURS, // Valid lifetime.
  2625. Delete ? 0 : 30 * MINUTES, // Preferred lifetime.
  2626. 0, SIXTOFOUR_METRIC);
  2627. }
  2628. VOID
  2629. Start6to4(
  2630. VOID
  2631. )
  2632. {
  2633. int i;
  2634. ASSERT(g_GlobalState.st6to4State == DISABLED);
  2635. for (i = 0; i < g_pIpv4AddressList->iAddressCount; i++) {
  2636. (VOID) Configure6to4Address(
  2637. FALSE, (PSOCKADDR_IN) g_pIpv4AddressList->Address[i].lpSockaddr);
  2638. }
  2639. Update6to4Routes();
  2640. UpdateGlobalRoutingState();
  2641. UpdateGlobalResolutionState();
  2642. g_GlobalState.st6to4State = ENABLED;
  2643. }
  2644. VOID
  2645. Stop6to4(
  2646. VOID
  2647. )
  2648. {
  2649. int i;
  2650. ASSERT(g_GlobalState.st6to4State == ENABLED);
  2651. PreDelete6to4Routes();
  2652. if (PreUpdateGlobalRoutingState()) {
  2653. Sleep(2000);
  2654. }
  2655. for (i = 0; i < g_pIpv4AddressList->iAddressCount; i++) {
  2656. (VOID) Configure6to4Address(
  2657. TRUE, (PSOCKADDR_IN) g_pIpv4AddressList->Address[i].lpSockaddr);
  2658. }
  2659. Update6to4Routes();
  2660. UpdateGlobalRoutingState();
  2661. UpdateGlobalResolutionState();
  2662. g_GlobalState.st6to4State = DISABLED;
  2663. }
  2664. VOID
  2665. Refresh6to4(
  2666. VOID
  2667. )
  2668. {
  2669. ASSERT(g_GlobalState.st6to4State == ENABLED);
  2670. if (PreUpdateGlobalRoutingState()) {
  2671. Sleep(2000);
  2672. }
  2673. UpdateGlobalRoutingState();
  2674. UpdateGlobalResolutionState();
  2675. }
  2676. VOID
  2677. Update6to4State(
  2678. VOID
  2679. )
  2680. {
  2681. //
  2682. // Start / Reconfigure / Stop.
  2683. //
  2684. if (Get6to4State() == ENABLED) {
  2685. if (g_GlobalState.st6to4State == ENABLED) {
  2686. Refresh6to4();
  2687. } else {
  2688. Start6to4();
  2689. }
  2690. } else {
  2691. if (g_GlobalState.st6to4State == ENABLED) {
  2692. Stop6to4();
  2693. }
  2694. }
  2695. }
  2696. VOID
  2697. RequirementChangeNotification(
  2698. IN BOOL Required
  2699. )
  2700. /*++
  2701. Routine Description:
  2702. Process a possible requirement change notification.
  2703. Arguments:
  2704. Required - Whether the 6to4 service is required for global connectivity.
  2705. Return Value:
  2706. None.
  2707. Caller LOCK: API.
  2708. --*/
  2709. {
  2710. if (g_b6to4Required != Required) {
  2711. g_b6to4Required = Required;
  2712. Update6to4State();
  2713. }
  2714. }
  2715. VOID
  2716. UpdateServiceRequirements(
  2717. IN PIP_ADAPTER_ADDRESSES Adapters
  2718. )
  2719. {
  2720. BOOL Require6to4 = TRUE, RequireTeredo = TRUE;
  2721. GUID PrivateLan;
  2722. BOOL IcsEnabled = (RasQuerySharedPrivateLan(&PrivateLan) == NO_ERROR);
  2723. PIP_ADAPTER_ADDRESSES Next;
  2724. PIP_ADAPTER_UNICAST_ADDRESS Address;
  2725. WCHAR Guid[MAX_ADAPTER_NAME_LENGTH];
  2726. PSOCKADDR_IN6 Ipv6;
  2727. for (Next = Adapters; Next != NULL; Next = Next->Next) {
  2728. //
  2729. // Disregard disconnected interfaces.
  2730. //
  2731. if (Next->OperStatus != IfOperStatusUp) {
  2732. continue;
  2733. }
  2734. #ifdef TEREDO
  2735. //
  2736. // Disregard the Teredo interface.
  2737. //
  2738. ConvertOemToUnicode(Next->AdapterName, Guid, MAX_ADAPTER_NAME_LENGTH);
  2739. if (TeredoInterface(Guid)) {
  2740. ASSERT(Next->IfType == IF_TYPE_TUNNEL);
  2741. continue;
  2742. }
  2743. #else
  2744. DBG_UNREFERENCED_LOCAL_VARIABLE(Guid);
  2745. #endif // TEREDO
  2746. for (Address = Next->FirstUnicastAddress;
  2747. Address != NULL;
  2748. Address = Address->Next) {
  2749. //
  2750. // Consider only preferred global IPv6 addresses.
  2751. //
  2752. if (Address->Address.lpSockaddr->sa_family != AF_INET6) {
  2753. continue;
  2754. }
  2755. if (Address->DadState != IpDadStatePreferred) {
  2756. continue;
  2757. }
  2758. Ipv6 = (PSOCKADDR_IN6) Address->Address.lpSockaddr;
  2759. if (TeredoIpv6GlobalAddress(&(Ipv6->sin6_addr))) {
  2760. //
  2761. // Since this is not the Teredo interface, and it has a global
  2762. // IPv6 address, Teredo's not required for global connectivity.
  2763. //
  2764. RequireTeredo = FALSE;
  2765. if (Next->Ipv6IfIndex != SIX_TO_FOUR_IFINDEX) {
  2766. //
  2767. // Since this is not the 6to4 interface either, and it has
  2768. // a global IPv6 address, 6to4's not required for global
  2769. // connectivity.
  2770. //
  2771. Require6to4 = FALSE;
  2772. }
  2773. }
  2774. if (!Require6to4) {
  2775. ASSERT(!RequireTeredo);
  2776. goto Done;
  2777. }
  2778. }
  2779. }
  2780. Done:
  2781. //
  2782. // 1. ICS requires 6to4 for advertising a prefix on the private LAN,
  2783. // at least until it implements prefix-delegation or RA proxy.
  2784. //
  2785. // 2. As a result of this advertisement, ICS will configure 6to4 addresses
  2786. // on its private interface as well. If the service should then disable
  2787. // 6to4 because of the presence of these global addresses on the private
  2788. // interface, it would lose these very addresses it was relying upon. The
  2789. // service would notice that it has no global IPv6 addresses and be forced
  2790. // to enable 6to4. Hence it will end up in an infinite loop, cycling 6to4
  2791. // between enabled and disabled states.
  2792. //
  2793. // To circumvent these two issues, we always enable 6to4 on an ICS box.
  2794. //
  2795. RequirementChangeNotification(Require6to4 || IcsEnabled);
  2796. #ifdef TEREDO
  2797. TeredoRequirementChangeNotification(RequireTeredo);
  2798. #endif // TEREDO
  2799. }