Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

620 lines
19 KiB

  1. /*
  2. File: Rip.c
  3. Performs an upgrade of ip rip to nt5 router by munging registry values.
  4. Paul Mayfield, 9/3/97
  5. The following steps are neccessary to upgrade rip:
  6. Params = HKLM/SYS/CCS/Services/IpRip/Parameters
  7. 1. Get the global info block for IP w/ MprConfigTransportGetInfo
  8. - Add a IPRIP_GLOBAL_CONFIG (ipriprm.h) block
  9. initialized as in routemon (rip.c, protocol.c)
  10. - Type is MS_IP_RIP as in sdk/inc/ipinfoid.h
  11. - Mappings
  12. Params.LoggingLevel to this global config blob
  13. 2. Get Interface info for each ras or lan ip interface
  14. - Add an IPRIP_IF_CONFIG (ipriprm.h) block (type MS_IP_RIP)
  15. - Initialize as per routemon
  16. - Mappings
  17. Params.AcceptHostRoutes - IC_ProtocolFlags (0=disable,1=enable)
  18. Params.UpdateFreq...=FullUpdateInterval
  19. Params.*Timeouts=
  20. 3. "SilentRip" param rules
  21. - If wks->srv, ignore this and set announce to disabled. accept=rip1
  22. - If srv->srv, map announce to this value. accept=rip1
  23. IP Rip Parameter Mapping
  24. ========================
  25. Rip Listener IpRip in Router
  26. RIP_PARAMETERS IPRIP_IF_CONFIG
  27. ============== ===============
  28. "SilentRIP" IC_AcceptMode,IC_AnnounceMode
  29. "AcceptHostRoutes" IC_ProtocolFlags
  30. "AnnounceHostRoutes" IC_ProtocolFlags
  31. "AcceptDefaultRoutes" IC_ProtocolFlags
  32. "AnnounceDefaultRoutes" IC_ProtocolFlags
  33. "EnableSplitHorizon" IC_ProtocolFlags
  34. "EnablePoisonedReverse" IC_ProtocolFlags
  35. "RouteTimeout" IC_RouteExpirationInterval
  36. "GarbageTimeout" IC_RouteRemovalInterval
  37. "UpdateFrequency" IC_FullUpdateInterval
  38. "EnableTriggeredUpdates" IC_ProtocolFlags
  39. "MaxTriggeredUpdateFrequency" NOT MIGRATED
  40. "OverwriteStaticRoutes" IC_ProtocolFlags
  41. IpRip in Router
  42. IPRIP_GLOBAL_CONFIG
  43. ===============
  44. "LoggingLevel" GC_LoggingLevel
  45. REGVAL_ACCEPT_HOST "AcceptHostRoutes"
  46. REGVAL_ANNOUNCE_HOST "AnnounceHostRoutes"
  47. REGVAL_ACCEPT_DEFAULT "AcceptDefaultRoutes"
  48. REGVAL_ANNOUNCE_DEFAULT "AnnounceDefaultRoutes"
  49. REGVAL_SPLITHORIZON "EnableSplitHorizon"
  50. REGVAL_POISONREVERSE "EnablePoisonedReverse"
  51. REGVAL_LOGGINGLEVEL "LoggingLevel"
  52. REGVAL_ROUTETIMEOUT "RouteTimeout"
  53. REGVAL_GARBAGETIMEOUT "GarbageTimeout"
  54. REGVAL_UPDATEFREQUENCY "UpdateFrequency"
  55. REGVAL_TRIGGEREDUPDATES "EnableTriggeredUpdates"
  56. REGVAL_TRIGGERFREQUENCY "MaxTriggeredUpdateFrequency"
  57. REGVAL_OVERWRITESTATIC "OverwriteStaticRoutes"
  58. */
  59. #include "upgrade.h"
  60. #include <ipriprm.h>
  61. #include <routprot.h>
  62. #include <mprapi.h>
  63. // Definition of table that migrates rip parameters
  64. typedef struct _PARAM_TO_FLAG {
  65. PWCHAR pszParam;
  66. DWORD dwFlag;
  67. } PARAM_TO_FLAG;
  68. // Definition of user data passed to interface enumeration
  69. // callback
  70. typedef struct _RIP_IF_DATA {
  71. IPRIP_IF_CONFIG * pLanConfig;
  72. IPRIP_IF_CONFIG * pWanConfig;
  73. } RIP_IF_DATA;
  74. // Types of upgrade
  75. #define SRV_TO_SRV 0
  76. #define WKS_TO_SRV 1
  77. // Globals
  78. static const WCHAR szTempKey[] = L"DeleteMe";
  79. static HKEY hkRouter = NULL;
  80. static HKEY hkTemp = NULL;
  81. PARAM_TO_FLAG ParamFlagTable[] =
  82. {
  83. {L"AcceptHostRoutes", IPRIP_FLAG_ACCEPT_HOST_ROUTES},
  84. {L"AnnounceHostRoutes", IPRIP_FLAG_ANNOUNCE_HOST_ROUTES},
  85. {L"AcceptDefaultRoutes", IPRIP_FLAG_ACCEPT_DEFAULT_ROUTES},
  86. {L"AnnounceDefaultRoutes", IPRIP_FLAG_ANNOUNCE_DEFAULT_ROUTES},
  87. {L"EnableSplitHorizon", IPRIP_FLAG_SPLIT_HORIZON},
  88. {L"EnablePoisonedReverse", IPRIP_FLAG_POISON_REVERSE},
  89. {L"EnableTriggeredUpdates", IPRIP_FLAG_TRIGGERED_UPDATES},
  90. {L"OverwriteStaticRoutes", IPRIP_FLAG_OVERWRITE_STATIC_ROUTES},
  91. {NULL, 0}
  92. };
  93. // Restore the registry from from
  94. // backup and make sure all global handles are opened
  95. DWORD IpRipPrepareRegistry(
  96. IN PWCHAR BackupFileName)
  97. {
  98. DWORD dwErr,dwDisposition;
  99. // Get access to the router registry key
  100. dwErr = UtlAccessRouterKey(&hkRouter);
  101. if (dwErr != ERROR_SUCCESS) {
  102. PrintMessage(L"Unable to access router key.\n");
  103. return dwErr;
  104. }
  105. // Restore the rip parameters from backup
  106. __try {
  107. // Open up the temporary key
  108. dwErr = RegCreateKeyEx(
  109. hkRouter,
  110. szTempKey,
  111. 0,
  112. NULL,
  113. 0,
  114. KEY_ALL_ACCESS,
  115. NULL,
  116. &hkTemp,
  117. &dwDisposition);
  118. if (dwErr!=ERROR_SUCCESS)
  119. return dwErr;
  120. // Restore the saved registry information to
  121. // the temp key
  122. UtlSetupRestorePrivilege(TRUE);
  123. dwErr = RegRestoreKeyW(
  124. hkTemp,
  125. BackupFileName,
  126. 0);
  127. if (dwErr != ERROR_SUCCESS)
  128. return dwErr;
  129. }
  130. __finally {
  131. UtlSetupRestorePrivilege(FALSE);
  132. }
  133. return NO_ERROR;
  134. }
  135. // Function initializes the rip global information based
  136. // on the parameters saved from the iprip service.
  137. //
  138. // 1. Get the global info block for IP w/ MprConfigTransportGetInfo
  139. // - Add a IPRIP_GLOBAL_CONFIG (ipriprm.h)
  140. // block initialized as in routemon (rip.c, protocol.c)
  141. // - Type is MS_IP_RIP as in sdk/inc/ipinfoid.h
  142. // - Mappings
  143. // Params.LoggingLevel to this global config blob
  144. DWORD IpRipUpgradeGlobalInfo(
  145. IN dwt * RipParams)
  146. {
  147. DWORD dwErr, dwTransSize, dwVal, dwNewSize = 0;
  148. LPBYTE lpTransInfo=NULL, lpNewTransInfo=NULL;
  149. HANDLE hSvrConfig=NULL, hTransport=NULL;
  150. // Create/initialize an IPRIP_GLOBAL_CONFIG block
  151. IPRIP_GLOBAL_CONFIG RipGlobalConfig = {
  152. IPRIP_LOGGING_ERROR, // Logging level
  153. 1024 * 1024, // Max recv-queue size
  154. 1024 * 1024, // Max send-queue size
  155. 5, // Minimum triggered-update interval
  156. IPRIP_FILTER_DISABLED, // Peer-filter mode
  157. 0 // Peer-filter count
  158. };
  159. // Reset any values read from the previous iprip configuration
  160. dwErr = dwtGetValue(
  161. RipParams,
  162. L"LoggingLevel",
  163. &dwVal);
  164. if (dwErr == NO_ERROR)
  165. RipGlobalConfig.GC_LoggingLevel=dwVal;
  166. __try {
  167. // Add the rip global config to ip's global config
  168. dwErr = MprConfigServerConnect(
  169. NULL,
  170. &hSvrConfig);
  171. if (dwErr != NO_ERROR)
  172. return dwErr;
  173. dwErr = MprConfigTransportGetHandle(
  174. hSvrConfig,
  175. PID_IP,
  176. &hTransport);
  177. if (dwErr != NO_ERROR)
  178. return dwErr;
  179. dwErr = MprConfigTransportGetInfo(
  180. hSvrConfig,
  181. hTransport,
  182. &lpTransInfo,
  183. &dwTransSize,
  184. NULL,
  185. NULL,
  186. NULL);
  187. if (dwErr != NO_ERROR)
  188. return dwErr;
  189. dwErr = UtlUpdateInfoBlock(
  190. TRUE,
  191. lpTransInfo,
  192. MS_IP_RIP,
  193. sizeof(IPRIP_GLOBAL_CONFIG),
  194. 1,
  195. (LPBYTE)&RipGlobalConfig,
  196. &lpNewTransInfo,
  197. &dwNewSize);
  198. if (dwErr != NO_ERROR)
  199. return dwErr;
  200. // Commit the information
  201. dwErr = MprConfigTransportSetInfo(
  202. hSvrConfig,
  203. hTransport,
  204. lpNewTransInfo,
  205. dwNewSize,
  206. NULL,
  207. 0,
  208. NULL);
  209. if (dwErr != NO_ERROR)
  210. return NO_ERROR;
  211. }
  212. __finally {
  213. if (lpTransInfo)
  214. MprConfigBufferFree(lpTransInfo);
  215. if (lpNewTransInfo)
  216. MprConfigBufferFree(lpNewTransInfo);
  217. if (hSvrConfig)
  218. MprConfigServerDisconnect(hSvrConfig);
  219. }
  220. return NO_ERROR;
  221. }
  222. // Returns whether this is a wks->srv or srv->srv upgrade
  223. DWORD IpRipGetUpgradeType() {
  224. return SRV_TO_SRV;
  225. }
  226. // Migrates the silent rip parameter.
  227. // 3. "SilentRip" param rules
  228. // - If wks->srv, announce=disabled, accept=rip1
  229. // - If srv->srv, announce=SilentRip, accept=rip1
  230. DWORD IpRipMigrateRipSilence(
  231. IN OUT IPRIP_IF_CONFIG * RipIfConfig,
  232. IN DWORD dwSilence,
  233. IN BOOL IsWan)
  234. {
  235. DWORD UpgradeType = IpRipGetUpgradeType();
  236. if (IsWan) {
  237. if (UpgradeType == WKS_TO_SRV) {
  238. RipIfConfig->IC_AcceptMode = IPRIP_ACCEPT_RIP1_COMPAT;
  239. RipIfConfig->IC_AnnounceMode = IPRIP_ACCEPT_DISABLED;
  240. }
  241. else if (UpgradeType == SRV_TO_SRV) {
  242. RipIfConfig->IC_AcceptMode = IPRIP_ACCEPT_RIP1_COMPAT;
  243. RipIfConfig->IC_AnnounceMode = dwSilence;
  244. }
  245. }
  246. else {
  247. if (UpgradeType == WKS_TO_SRV) {
  248. RipIfConfig->IC_AcceptMode = IPRIP_ACCEPT_RIP1;
  249. RipIfConfig->IC_AnnounceMode = IPRIP_ACCEPT_DISABLED;
  250. }
  251. else if (UpgradeType == SRV_TO_SRV) {
  252. RipIfConfig->IC_AcceptMode = IPRIP_ACCEPT_RIP1;
  253. RipIfConfig->IC_AnnounceMode = dwSilence;
  254. }
  255. }
  256. return NO_ERROR;
  257. }
  258. DWORD IpRipSetParamFlag(
  259. IN dwt * RipParams,
  260. IN PWCHAR ValName,
  261. IN DWORD dwFlag,
  262. OUT DWORD * dwParam)
  263. {
  264. DWORD dwVal, dwErr;
  265. dwErr = dwtGetValue(RipParams, ValName, &dwVal);
  266. if (dwErr == NO_ERROR) {
  267. if (dwVal)
  268. *dwParam |= dwFlag;
  269. else
  270. *dwParam &= ~dwFlag;
  271. }
  272. return NO_ERROR;
  273. }
  274. // Update the lan interface parameters from previous config
  275. DWORD IpRipUpdateIfConfig(
  276. IN dwt * RipParams,
  277. OUT IPRIP_IF_CONFIG * RipIfConfig,
  278. IN BOOL IsWan)
  279. {
  280. DWORD dwErr, dwVal;
  281. PARAM_TO_FLAG * pCurFlag;
  282. // Loop through all the parameter mappings,
  283. // setting the appripriate flag in the rip config
  284. pCurFlag = &(ParamFlagTable[0]);
  285. while (pCurFlag->pszParam) {
  286. // Set the flag as appropriate
  287. IpRipSetParamFlag(
  288. RipParams,
  289. pCurFlag->pszParam,
  290. pCurFlag->dwFlag,
  291. &(RipIfConfig->IC_ProtocolFlags));
  292. // Increment the enumeration
  293. pCurFlag++;
  294. }
  295. // Set the parameters migrated as parameters
  296. dwErr = dwtGetValue(RipParams, L"UpdateFrequency", &dwVal);
  297. if (dwErr == NO_ERROR)
  298. RipIfConfig->IC_FullUpdateInterval = dwVal;
  299. dwErr = dwtGetValue(RipParams, L"RouteTimeout", &dwVal);
  300. if (dwErr == NO_ERROR)
  301. RipIfConfig->IC_RouteExpirationInterval = dwVal;
  302. dwErr = dwtGetValue(RipParams, L"GarbageTimeout", &dwVal);
  303. if (dwErr == NO_ERROR)
  304. RipIfConfig->IC_RouteRemovalInterval = dwVal;
  305. // Upgrade the silence parameter
  306. dwErr = dwtGetValue(RipParams, L"SilentRIP", &dwVal);
  307. if (dwErr == NO_ERROR)
  308. IpRipMigrateRipSilence(RipIfConfig, dwVal, IsWan);
  309. return NO_ERROR;
  310. }
  311. //
  312. // Callback function takes an interface and updates
  313. // its rip configuration.
  314. //
  315. // Returns TRUE to continue the enumerate, FALSE to
  316. // stop it
  317. //
  318. DWORD IpRipUpgradeInterface(
  319. IN HANDLE hConfig,
  320. IN MPR_INTERFACE_0 * pIf,
  321. IN HANDLE hUserData)
  322. {
  323. RIP_IF_DATA * pData = (RIP_IF_DATA*)hUserData;
  324. IPRIP_IF_CONFIG * pConfig;
  325. HANDLE hTransport = NULL;
  326. LPBYTE pTransInfo=NULL, pNewTransInfo=NULL;
  327. DWORD dwErr, dwIfSize, dwNewTransSize = 0;
  328. // Validate lan and wan interfaces
  329. if ((hConfig == NULL) ||
  330. (pIf == NULL) ||
  331. (pData == NULL))
  332. {
  333. return FALSE;
  334. }
  335. // Is this a LAN or a WAN interface
  336. if (pIf->dwIfType == ROUTER_IF_TYPE_DEDICATED)
  337. pConfig = pData->pLanConfig;
  338. else if (pIf->dwIfType == ROUTER_IF_TYPE_HOME_ROUTER ||
  339. pIf->dwIfType == ROUTER_IF_TYPE_FULL_ROUTER)
  340. pConfig = pData->pWanConfig;
  341. else
  342. return TRUE;
  343. do {
  344. // Get the handle to ip info associated with this if
  345. dwErr = MprConfigInterfaceTransportGetHandle(
  346. hConfig,
  347. pIf->hInterface,
  348. PID_IP,
  349. &hTransport);
  350. if (dwErr != NO_ERROR)
  351. break;
  352. // Get the ip info associated with this if
  353. dwErr = MprConfigInterfaceTransportGetInfo(
  354. hConfig,
  355. pIf->hInterface,
  356. hTransport,
  357. &pTransInfo,
  358. &dwIfSize);
  359. if (dwErr != NO_ERROR)
  360. break;
  361. // Update the info block with the rip data
  362. dwErr = UtlUpdateInfoBlock (
  363. TRUE,
  364. pTransInfo,
  365. MS_IP_RIP,
  366. sizeof(IPRIP_IF_CONFIG),
  367. 1,
  368. (LPBYTE)pConfig,
  369. &pNewTransInfo,
  370. &dwNewTransSize);
  371. if (dwErr != NO_ERROR)
  372. break;
  373. // Commit the change
  374. dwErr = MprConfigInterfaceTransportSetInfo(
  375. hConfig,
  376. pIf->hInterface,
  377. hTransport,
  378. pNewTransInfo,
  379. dwNewTransSize);
  380. if (dwErr != NO_ERROR)
  381. break;
  382. } while (FALSE);
  383. // Cleanup
  384. {
  385. if (pNewTransInfo)
  386. MprConfigBufferFree(pNewTransInfo);
  387. if (pTransInfo)
  388. MprConfigBufferFree(pTransInfo);
  389. }
  390. return TRUE;
  391. }
  392. // Initializes the rip per-interface information based on the
  393. // parameters saved from the iprip service.
  394. //
  395. // 2. Get Interface info for each ras or lan ip interface
  396. // - Add an IPRIP_IF_CONFIG (ipriprm.h) block (type MS_IP_RIP)
  397. // - Initialize as per routemon
  398. // - Mappings
  399. // Params.AcceptHostRoutes - IC_ProtocolFlags (0=disable,1=enable)
  400. // Params.UpdateFreq...=FullUpdateInterval
  401. // Params.*Timeouts=
  402. DWORD IpRipUpgradeInterfaces(
  403. IN dwt * RipParams)
  404. {
  405. DWORD dwErr;
  406. // Create/initialize an rip info blocks
  407. IPRIP_IF_CONFIG RipLanConfig = {
  408. 0, // State (read-only)
  409. 1, // Metric
  410. IPRIP_UPDATE_PERIODIC, // Update mode
  411. IPRIP_ACCEPT_RIP1, // Accept mode
  412. IPRIP_ANNOUNCE_RIP1, // Announce mode
  413. IPRIP_FLAG_SPLIT_HORIZON |
  414. IPRIP_FLAG_POISON_REVERSE |
  415. IPRIP_FLAG_GRACEFUL_SHUTDOWN |
  416. IPRIP_FLAG_TRIGGERED_UPDATES, // Protocol flags
  417. 180, // Route-expiration interval
  418. 120, // Route-removal interval
  419. 30, // Full-update interval
  420. IPRIP_AUTHTYPE_NONE, // Authentication type
  421. {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Authentication key
  422. 0, // Route tag
  423. IPRIP_PEER_DISABLED, // Unicast-peer mode
  424. IPRIP_FILTER_DISABLED, // Accept-filter mode
  425. IPRIP_FILTER_DISABLED, // Announce-filter mode
  426. 0, // Unicast-peer count
  427. 0, // Accept-filter count
  428. 0 // Announce-filter count
  429. };
  430. IPRIP_IF_CONFIG RipWanConfig = {
  431. 0,
  432. 1,
  433. IPRIP_UPDATE_DEMAND, // Update mode for WAN
  434. IPRIP_ACCEPT_RIP1,
  435. IPRIP_ANNOUNCE_RIP1,
  436. IPRIP_FLAG_SPLIT_HORIZON |
  437. IPRIP_FLAG_POISON_REVERSE |
  438. IPRIP_FLAG_GRACEFUL_SHUTDOWN,
  439. 180,
  440. 120,
  441. 30,
  442. IPRIP_AUTHTYPE_NONE,
  443. {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
  444. 0,
  445. IPRIP_PEER_DISABLED,
  446. IPRIP_FILTER_DISABLED,
  447. IPRIP_FILTER_DISABLED,
  448. 0,
  449. 0,
  450. 0
  451. };
  452. RIP_IF_DATA RipBlobs =
  453. {
  454. &RipLanConfig,
  455. &RipWanConfig
  456. };
  457. // Update the lan config blob with values from previous
  458. // installation of rip service.
  459. dwErr = IpRipUpdateIfConfig(RipParams, RipBlobs.pLanConfig, FALSE);
  460. if (dwErr != NO_ERROR)
  461. return dwErr;
  462. // Update the wan config blob with values from previous
  463. // installation of rip service.
  464. dwErr = IpRipUpdateIfConfig(RipParams, RipBlobs.pWanConfig, TRUE);
  465. if (dwErr != NO_ERROR)
  466. return dwErr;
  467. // Enumerate the interfaces, updating each one with
  468. // rip config as you go.
  469. dwErr = UtlEnumerateInterfaces(
  470. IpRipUpgradeInterface,
  471. &RipBlobs);
  472. if (dwErr != NO_ERROR)
  473. return dwErr;
  474. return NO_ERROR;
  475. }
  476. // Restores the Rip parameters that were saved before upgrade.
  477. // This function assumes that those parameters are being stored
  478. // temporarily in hkTemp
  479. DWORD IpRipMigrateParams() {
  480. DWORD dwErr, dwVal;
  481. dwt RipParams;
  482. __try {
  483. // Load in the parameters that were set for Rip
  484. dwErr = dwtLoadRegistyTable(&RipParams, hkTemp);
  485. if (dwErr != NO_ERROR)
  486. return dwErr;
  487. // Migrate the various types of paramters
  488. dwErr = IpRipUpgradeGlobalInfo(&RipParams);
  489. if (dwErr != NO_ERROR)
  490. return dwErr;
  491. // Migrate the per-interface parameters
  492. dwErr = IpRipUpgradeInterfaces(&RipParams);
  493. if (dwErr != NO_ERROR)
  494. return dwErr;
  495. }
  496. __finally {
  497. dwtCleanup(&RipParams);
  498. }
  499. return NO_ERROR;
  500. }
  501. // Cleanup the work done in the registry
  502. DWORD IpRipCleanupRegistry() {
  503. if (hkTemp)
  504. RegCloseKey(hkTemp);
  505. if (hkRouter) {
  506. RegDeleteKey(hkRouter, szTempKey);
  507. RegCloseKey(hkRouter);
  508. }
  509. hkTemp = NULL;
  510. hkRouter = NULL;
  511. return NO_ERROR;
  512. }
  513. // Upgrades iprip to nt 5.0 router
  514. DWORD IpRipToRouterUpgrade(
  515. IN PWCHAR FileName)
  516. {
  517. DWORD dwErr;
  518. __try {
  519. // Restore the registry from the backup file
  520. dwErr = IpRipPrepareRegistry(FileName);
  521. if (dwErr != NO_ERROR)
  522. return dwErr;
  523. // Migrate rip's parameters to the appropriate
  524. // new locations
  525. dwErr = IpRipMigrateParams();
  526. if (dwErr != NO_ERROR)
  527. return dwErr;
  528. // Mark the computer as having been configured
  529. //
  530. dwErr = UtlMarkRouterConfigured();
  531. if (dwErr != NO_ERROR)
  532. {
  533. PrintMessage(L"Unable to mark router as configured.\n");
  534. return dwErr;
  535. }
  536. }
  537. __finally {
  538. IpRipCleanupRegistry();
  539. }
  540. return NO_ERROR;
  541. }