Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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