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.

1070 lines
34 KiB

  1. /*++
  2. Copyright (c) 1999, Microsoft Corporation
  3. Module Name:
  4. routing\netsh\ip\protocols\vrrphlpcfg.c
  5. Abstract:
  6. Virtual Router Redundancy Protocol configuration implementation.
  7. This module contains configuration routines which are relied upon
  8. by vrrphlpopt.c. The routines retrieve, update, and display
  9. the configuration for the VRRP protocol.
  10. This file also contains default configuration settings
  11. for VRRP.
  12. N.B. The display routines require special attention since display
  13. may result in a list of commands sent to a 'dump' file, or in a
  14. textual presentation of the configuration to a console window.
  15. In the latter case, we use non-localizable output routines to generate
  16. a script-like description of the configuration. In the former case,
  17. we use localizable routines to generate a human-readable description.
  18. Author:
  19. Peeyush Ranjan (peeyushr) 3-Mar-1999
  20. Revision History:
  21. --*/
  22. #include "precomp.h"
  23. #pragma hdrstop
  24. #define Malloc(x) HeapAlloc(GetProcessHeap(), 0, (x))
  25. #define Free(x) HeapFree(GetProcessHeap(), 0, (x))
  26. static VRRP_GLOBAL_CONFIG
  27. g_VrrpGlobalDefault =
  28. {
  29. VRRP_LOGGING_ERROR
  30. };
  31. static PUCHAR g_pVrrpGlobalDefault = (PUCHAR)&g_VrrpGlobalDefault;
  32. static VRRP_IF_CONFIG g_VrrpInterfaceDefault =
  33. {
  34. 0
  35. };
  36. static VRRP_VROUTER_CONFIG g_VrrpVrouterDefault =
  37. {
  38. 1,
  39. 100,
  40. 1,
  41. 1,
  42. 0,
  43. 0,
  44. {0,0,0,0,0,0,0,0
  45. },
  46. 0
  47. };
  48. //
  49. // Forward declarations
  50. //
  51. ULONG
  52. ValidateVrrpInterfaceInfo(
  53. PVRRP_IF_CONFIG InterfaceInfo
  54. );
  55. BOOL
  56. FoundIpAddress(
  57. DWORD IPAddress
  58. );
  59. //
  60. // What follows are the arrays used to map values to strings and
  61. // to map values to tokens. These, respectively, are used in the case
  62. // where we are displaying to a 'dump' file and to a console window.
  63. //
  64. VALUE_STRING VrrpGlobalLogginStringArray[] = {
  65. VRRP_LOGGING_NONE, STRING_LOGGING_NONE,
  66. VRRP_LOGGING_ERROR, STRING_LOGGING_ERROR,
  67. VRRP_LOGGING_WARN, STRING_LOGGING_WARN,
  68. VRRP_LOGGING_INFO, STRING_LOGGING_INFO
  69. };
  70. VALUE_TOKEN VrrpGlobalLogginTokenArray[] = {
  71. VRRP_LOGGING_NONE, TOKEN_OPT_VALUE_NONE,
  72. VRRP_LOGGING_ERROR, TOKEN_OPT_VALUE_ERROR,
  73. VRRP_LOGGING_WARN, TOKEN_OPT_VALUE_WARN,
  74. VRRP_LOGGING_INFO, TOKEN_OPT_VALUE_INFO
  75. };
  76. VALUE_STRING VrrpAuthModeStringArray[] = {
  77. VRRP_AUTHTYPE_NONE, STRING_AUTH_NONE,
  78. VRRP_AUTHTYPE_PLAIN, STRING_AUTH_SIMPLEPASSWD,
  79. VRRP_AUTHTYPE_IPHEAD, STRING_AUTH_IPHEADER
  80. };
  81. VALUE_TOKEN VrrpAuthModeTokenArray[] = {
  82. VRRP_AUTHTYPE_NONE, TOKEN_OPT_VALUE_AUTH_NONE,
  83. VRRP_AUTHTYPE_PLAIN, TOKEN_OPT_VALUE_AUTH_SIMPLE_PASSWORD,
  84. VRRP_AUTHTYPE_IPHEAD, TOKEN_OPT_VALUE_AUTH_MD5
  85. };
  86. VALUE_STRING VrrpPreemptModeStringArray[] = {
  87. TRUE, STRING_ENABLED,
  88. FALSE, STRING_DISABLED
  89. };
  90. VALUE_TOKEN VrrpPreemptModeTokenArray[] = {
  91. TRUE, TOKEN_OPT_VALUE_ENABLE,
  92. FALSE,TOKEN_OPT_VALUE_DISABLE
  93. };
  94. typedef enum {
  95. VrrpGlobalLoggingModeIndex,
  96. VrrpAuthModeIndex,
  97. VrrpPreemptModeIndex
  98. } DISPLAY_VALUE_INDEX;
  99. PTCHAR
  100. QueryValueString(
  101. HANDLE FileHandle,
  102. DISPLAY_VALUE_INDEX Index,
  103. ULONG Value
  104. )
  105. {
  106. ULONG Count;
  107. ULONG Error;
  108. PTCHAR String = NULL;
  109. PVALUE_STRING StringArray;
  110. PVALUE_TOKEN TokenArray;
  111. switch (Index) {
  112. case VrrpGlobalLoggingModeIndex:
  113. Count = NUM_VALUES_IN_TABLE(VrrpGlobalLogginStringArray);
  114. StringArray = VrrpGlobalLogginStringArray;
  115. TokenArray = VrrpGlobalLogginTokenArray;
  116. break;
  117. case VrrpAuthModeIndex:
  118. Count = NUM_VALUES_IN_TABLE(VrrpAuthModeStringArray);
  119. StringArray = VrrpAuthModeStringArray;
  120. TokenArray = VrrpAuthModeTokenArray;
  121. break;
  122. case VrrpPreemptModeIndex:
  123. Count = NUM_VALUES_IN_TABLE(VrrpPreemptModeStringArray);
  124. StringArray = VrrpPreemptModeStringArray;
  125. TokenArray = VrrpPreemptModeTokenArray;
  126. break;
  127. default:
  128. return NULL;
  129. }
  130. Error =
  131. GetAltDisplayString(
  132. g_hModule,
  133. FileHandle,
  134. Value,
  135. TokenArray,
  136. StringArray,
  137. Count,
  138. &String
  139. );
  140. return Error ? NULL : String;
  141. }
  142. ULONG
  143. MakeVrrpGlobalInfo(
  144. OUT PUCHAR* GlobalInfo,
  145. OUT PULONG GlobalInfoSize
  146. )
  147. {
  148. *GlobalInfoSize = sizeof(VRRP_GLOBAL_CONFIG);
  149. *GlobalInfo = Malloc(*GlobalInfoSize);
  150. if (!*GlobalInfo) {
  151. DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
  152. return ERROR_NOT_ENOUGH_MEMORY;
  153. }
  154. CopyMemory(*GlobalInfo, g_pVrrpGlobalDefault, *GlobalInfoSize);
  155. return NO_ERROR;
  156. }
  157. ULONG
  158. CreateVrrpGlobalInfo(
  159. OUT PVRRP_GLOBAL_CONFIG* GlobalInfo,
  160. IN DWORD LoggingLevel
  161. )
  162. {
  163. DWORD GlobalInfoSize;
  164. GlobalInfoSize = sizeof(PVRRP_GLOBAL_CONFIG);
  165. *GlobalInfo = Malloc(GlobalInfoSize);
  166. if (!*GlobalInfo) {
  167. DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
  168. return ERROR_NOT_ENOUGH_MEMORY;
  169. }
  170. CopyMemory(*GlobalInfo, g_pVrrpGlobalDefault, GlobalInfoSize);
  171. (*GlobalInfo)->LoggingLevel = LoggingLevel;
  172. return NO_ERROR;
  173. }
  174. ULONG
  175. MakeVrrpInterfaceInfo(
  176. ROUTER_INTERFACE_TYPE InterfaceType,
  177. OUT PUCHAR* InterfaceInfo,
  178. OUT PULONG InterfaceInfoSize
  179. )
  180. {
  181. //
  182. //Why is this check done?
  183. //
  184. if (InterfaceType != ROUTER_IF_TYPE_DEDICATED) {
  185. return ERROR_INVALID_PARAMETER;
  186. }
  187. *InterfaceInfoSize = sizeof(VRRP_IF_CONFIG);
  188. *InterfaceInfo = Malloc(*InterfaceInfoSize);
  189. if (!*InterfaceInfo) {
  190. DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
  191. return ERROR_NOT_ENOUGH_MEMORY;
  192. }
  193. CopyMemory(*InterfaceInfo, &g_VrrpInterfaceDefault, *InterfaceInfoSize);
  194. return NO_ERROR;
  195. }
  196. ULONG
  197. MakeVrrpVRouterInfo(
  198. IN OUT PUCHAR VRouterInfo
  199. )
  200. {
  201. //
  202. // Always assumed that the space has been preassigned
  203. //
  204. if (!VRouterInfo) {
  205. return ERROR_INVALID_PARAMETER;
  206. }
  207. CopyMemory(VRouterInfo,&g_VrrpVrouterDefault,sizeof(g_VrrpVrouterDefault));
  208. return NO_ERROR;
  209. }
  210. ULONG
  211. ShowVrrpGlobalInfo(
  212. HANDLE FileHandle
  213. )
  214. {
  215. ULONG Count = 0;
  216. ULONG Error;
  217. PVRRP_GLOBAL_CONFIG GlobalInfo = NULL;
  218. ULONG i;
  219. PTCHAR LoggingLevel = NULL;
  220. ULONG Size;
  221. do {
  222. //
  223. // Retrieve the global configuration for the VRRP,
  224. // and format its contents to the output file or console.
  225. //
  226. Error =
  227. IpmontrGetInfoBlockFromGlobalInfo(
  228. MS_IP_VRRP,
  229. (PUCHAR*)&GlobalInfo,
  230. &Size,
  231. &Count
  232. );
  233. if (Error) {
  234. break;
  235. } else if (!(Count * Size)) {
  236. Error = ERROR_NOT_FOUND; break;
  237. }
  238. LoggingLevel =
  239. QueryValueString(
  240. FileHandle, VrrpGlobalLoggingModeIndex, GlobalInfo->LoggingLevel
  241. );
  242. if (!LoggingLevel) { break; }
  243. if (FileHandle) {
  244. DisplayMessageT(DMP_VRRP_INSTALL);
  245. DisplayMessageT(
  246. DMP_VRRP_SET_GLOBAL,
  247. TOKEN_OPT_LOGGINGLEVEL, LoggingLevel
  248. );
  249. } else {
  250. DisplayMessage(
  251. g_hModule,
  252. MSG_VRRP_GLOBAL_INFO,
  253. LoggingLevel
  254. );
  255. }
  256. } while(FALSE);
  257. if (LoggingLevel) { Free(LoggingLevel); }
  258. if (GlobalInfo) { Free(GlobalInfo); }
  259. if (!FileHandle && Error) {
  260. if (Error == ERROR_NOT_FOUND) {
  261. DisplayMessage(g_hModule, EMSG_PROTO_NO_GLOBAL_INFO);
  262. } else {
  263. DisplayError(g_hModule, Error);
  264. }
  265. }
  266. return Error;
  267. }
  268. ULONG
  269. ShowVrrpAllInterfaceInfo(
  270. HANDLE FileHandle
  271. )
  272. {
  273. DWORD dwErr, dwCount, dwTotal;
  274. DWORD dwNumParsed, i, dwNumBlocks=1, dwSize, dwIfType;
  275. PBYTE pBuffer;
  276. PMPR_INTERFACE_0 pmi0;
  277. WCHAR wszIfDesc[MAX_INTERFACE_NAME_LEN + 1];
  278. //
  279. // dump vrrp config for all interfaces
  280. //
  281. dwErr = IpmontrInterfaceEnum((PBYTE *) &pmi0,
  282. &dwCount,
  283. &dwTotal);
  284. if(dwErr != NO_ERROR)
  285. {
  286. DisplayError(g_hModule,
  287. dwErr);
  288. return dwErr;
  289. }
  290. for(i = 0; i < dwCount; i++)
  291. {
  292. // make sure that vrrp is configured on that interface
  293. dwErr = IpmontrGetInfoBlockFromInterfaceInfo(pmi0[i].wszInterfaceName,
  294. MS_IP_VRRP,
  295. &pBuffer,
  296. &dwSize,
  297. &dwNumBlocks,
  298. &dwIfType);
  299. if (dwErr != NO_ERROR) {
  300. continue;
  301. }
  302. else {
  303. HEAP_FREE(pBuffer) ;
  304. }
  305. ShowVrrpInterfaceInfo(FileHandle, pmi0[i].wszInterfaceName);
  306. }
  307. return NO_ERROR;
  308. }
  309. ULONG
  310. ShowVrrpInterfaceInfo(
  311. HANDLE FileHandle,
  312. PWCHAR InterfaceName
  313. )
  314. {
  315. ULONG Count = 0;
  316. ULONG Error;
  317. PVRRP_IF_CONFIG InterfaceInfo;
  318. PTCHAR AuthType = NULL;
  319. ULONG Size;
  320. ULONG dwLength;
  321. TCHAR Title[MAX_INTERFACE_NAME_LEN + 1];
  322. ROUTER_INTERFACE_TYPE Type;
  323. ULONG Index;
  324. ULONG IPIndex;
  325. BYTE Password[VRRP_MAX_AUTHKEY_SIZE];
  326. PTCHAR IPAddresses = NULL;
  327. TCHAR Address[VRRP_IPADDR_LENGTH+1];
  328. PVRRP_VROUTER_CONFIG PVrouter;
  329. PTCHAR PreemptMode = NULL;
  330. do {
  331. //
  332. // Retrieve the interface's configuration
  333. // and format it to the output file or console.
  334. //
  335. Error =
  336. IpmontrGetInfoBlockFromInterfaceInfo(
  337. InterfaceName,
  338. MS_IP_VRRP,
  339. (PUCHAR*)&InterfaceInfo,
  340. &Size,
  341. &Count,
  342. &Type
  343. );
  344. if (Error) {
  345. break;
  346. } else if (!(Count * Size)) {
  347. Error = ERROR_NOT_FOUND; break;
  348. }
  349. Size = sizeof(Title);
  350. Error = IpmontrGetFriendlyNameFromIfName(InterfaceName, Title, &Size);
  351. if (Error) {
  352. Error = ERROR_NO_SUCH_INTERFACE;
  353. break;
  354. }
  355. if (FileHandle) {
  356. DisplayMessage(g_hModule, DMP_VRRP_INTERFACE_HEADER, Title);
  357. DisplayMessageT(DMP_VRRP_ADD_INTERFACE,
  358. TOKEN_OPT_NAME, Title);
  359. if (InterfaceInfo->VrouterCount) {
  360. for (Index = 0 , PVrouter = VRRP_FIRST_VROUTER_CONFIG(InterfaceInfo);
  361. Index < InterfaceInfo->VrouterCount;
  362. Index++ , PVrouter = VRRP_NEXT_VROUTER_CONFIG(PVrouter)) {
  363. for (IPIndex = 0; IPIndex < PVrouter->IPCount;
  364. IPIndex++) {
  365. IP_TO_TSTR(Address,
  366. &PVrouter->IPAddress[IPIndex]
  367. );
  368. DisplayMessageT(
  369. DMP_VRRP_ADD_VRID,
  370. TOKEN_OPT_NAME, Title,
  371. TOKEN_OPT_VRID, PVrouter->VRID,
  372. TOKEN_OPT_IPADDRESS, Address
  373. );
  374. }
  375. AuthType =
  376. QueryValueString(
  377. FileHandle, VrrpAuthModeIndex,
  378. PVrouter->AuthenticationType
  379. );
  380. if (!AuthType) {
  381. Error = ERROR_INVALID_PARAMETER;
  382. break;
  383. }
  384. CopyMemory(Password,PVrouter->AuthenticationData,
  385. VRRP_MAX_AUTHKEY_SIZE);
  386. DisplayMessageT(
  387. DMP_VRRP_SET_INTERFACE,
  388. TOKEN_OPT_NAME, Title,
  389. TOKEN_OPT_VRID, PVrouter->VRID,
  390. TOKEN_OPT_AUTH,
  391. (PVrouter->AuthenticationType == VRRP_AUTHTYPE_NONE) ?
  392. TOKEN_OPT_VALUE_AUTH_NONE : ((PVrouter->AuthenticationType
  393. == VRRP_AUTHTYPE_PLAIN) ? TOKEN_OPT_VALUE_AUTH_SIMPLE_PASSWORD :
  394. TOKEN_OPT_VALUE_AUTH_MD5 ) ,
  395. TOKEN_OPT_PASSWD, Password[0], Password[1], Password[2],
  396. Password[3], Password[4], Password[5],Password[6], Password[7],
  397. TOKEN_OPT_ADVTINTERVAL, PVrouter->AdvertisementInterval,
  398. TOKEN_OPT_PRIO,PVrouter->ConfigPriority,
  399. TOKEN_OPT_PREEMPT, PVrouter->PreemptMode? TOKEN_OPT_VALUE_ENABLE :
  400. TOKEN_OPT_VALUE_DISABLE
  401. );
  402. }
  403. }
  404. } else {
  405. DisplayMessage(g_hModule, MSG_VRRP_INTERFACE_INFO,Title,
  406. InterfaceInfo->VrouterCount);
  407. for (Index = 0, PVrouter = VRRP_FIRST_VROUTER_CONFIG(InterfaceInfo);
  408. Index < InterfaceInfo->VrouterCount;
  409. Index++, PVrouter = VRRP_NEXT_VROUTER_CONFIG(PVrouter)) {
  410. AuthType =
  411. QueryValueString(
  412. FileHandle, VrrpAuthModeIndex,
  413. PVrouter->AuthenticationType
  414. );
  415. if (!AuthType) {
  416. Error = ERROR_INVALID_PARAMETER;
  417. break;
  418. }
  419. CopyMemory(Password,PVrouter->AuthenticationData,
  420. VRRP_MAX_AUTHKEY_SIZE);
  421. //
  422. // Allocate space for each IP address, a space+comma each and also a
  423. // null terminator
  424. //
  425. IPAddresses = Malloc(dwLength = (((VRRP_IPADDR_LENGTH+2)*sizeof(TCHAR)*
  426. PVrouter->IPCount)+1));
  427. if (!IPAddresses) {
  428. DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
  429. //
  430. // Set AuthType to 0 which will cause a break from the outer loop
  431. //
  432. AuthType = 0;
  433. Error = ERROR_NOT_ENOUGH_MEMORY;
  434. break;
  435. }
  436. ZeroMemory(IPAddresses,dwLength);
  437. //
  438. // Now build the IP address list from the addresses given
  439. //
  440. for (IPIndex = 0; IPIndex < PVrouter->IPCount; IPIndex++ ) {
  441. IP_TO_TSTR(Address,&PVrouter->IPAddress[IPIndex]);
  442. wcscat(IPAddresses,Address);
  443. if (IPIndex != (ULONG)(PVrouter->IPCount-1)) {
  444. wcscat(IPAddresses,L", ");
  445. }
  446. }
  447. PreemptMode =
  448. QueryValueString(
  449. FileHandle,
  450. VrrpPreemptModeIndex,
  451. PVrouter->PreemptMode
  452. );
  453. if (!PreemptMode) { break; }
  454. DisplayMessage(
  455. g_hModule,
  456. MSG_VRRP_VRID_INFO,
  457. PVrouter->VRID,
  458. IPAddresses,
  459. AuthType,
  460. Password[0], Password[1], Password[2], Password[3],
  461. Password[4], Password[5], Password[6], Password[7],
  462. PVrouter->AdvertisementInterval,
  463. PVrouter->ConfigPriority,
  464. PreemptMode
  465. );
  466. }
  467. }
  468. if (!AuthType) {
  469. break;
  470. }
  471. Error = NO_ERROR;
  472. } while(FALSE);
  473. if (AuthType) { Free(AuthType); }
  474. Free(InterfaceInfo);
  475. if (IPAddresses) Free(IPAddresses);
  476. if (!FileHandle && Error) {
  477. if (Error == ERROR_NOT_FOUND) {
  478. DisplayMessage(g_hModule, EMSG_PROTO_NO_IF_INFO);
  479. } else {
  480. DisplayError(g_hModule, Error);
  481. }
  482. }
  483. return Error;
  484. }
  485. ULONG
  486. UpdateVrrpGlobalInfo(
  487. PVRRP_GLOBAL_CONFIG GlobalInfo
  488. )
  489. {
  490. ULONG Count;
  491. ULONG Error;
  492. PVRRP_GLOBAL_CONFIG NewGlobalInfo = NULL;
  493. PVRRP_GLOBAL_CONFIG OldGlobalInfo = NULL;
  494. ULONG Size;
  495. do {
  496. //
  497. // Retrieve the existing global configuration.
  498. //
  499. Error =
  500. IpmontrGetInfoBlockFromGlobalInfo(
  501. MS_IP_VRRP,
  502. (PUCHAR*)&OldGlobalInfo,
  503. &Size,
  504. &Count
  505. );
  506. if (Error) {
  507. break;
  508. } else if (!(Count * Size)) {
  509. Error = ERROR_NOT_FOUND; break;
  510. }
  511. //
  512. // Allocate a new structure, copy to it the original configuration,
  513. //
  514. NewGlobalInfo = Malloc(Count * Size);
  515. if (!NewGlobalInfo) { Error = ERROR_NOT_ENOUGH_MEMORY; break; }
  516. CopyMemory(NewGlobalInfo, OldGlobalInfo, Count * Size);
  517. //
  518. // Based on the changes requested, change the NewGlobalInfo.
  519. // Since for VRRP there is only the logging level to change, we just set that.
  520. //
  521. NewGlobalInfo->LoggingLevel = GlobalInfo->LoggingLevel;
  522. Error =
  523. IpmontrSetInfoBlockInGlobalInfo(
  524. MS_IP_VRRP,
  525. (PUCHAR)NewGlobalInfo,
  526. FIELD_OFFSET(IP_NAT_GLOBAL_INFO, Header) +
  527. Count * Size,
  528. 1
  529. );
  530. } while(FALSE);
  531. if (NewGlobalInfo) { Free(NewGlobalInfo); }
  532. if (OldGlobalInfo) { Free(OldGlobalInfo); }
  533. if (Error == ERROR_NOT_FOUND) {
  534. DisplayMessage(g_hModule, EMSG_PROTO_NO_GLOBAL_INFO);
  535. } else if (Error) {
  536. DisplayError(g_hModule, Error);
  537. }
  538. return Error;
  539. }
  540. ULONG
  541. UpdateVrrpInterfaceInfo(
  542. PWCHAR InterfaceName,
  543. PVRRP_VROUTER_CONFIG VRouterInfo,
  544. ULONG BitVector,
  545. BOOL AddInterface
  546. )
  547. {
  548. ULONG Count;
  549. ULONG Error;
  550. PVRRP_IF_CONFIG NewInterfaceInfo = NULL;
  551. PVRRP_IF_CONFIG OldInterfaceInfo = NULL;
  552. PVRRP_VROUTER_CONFIG PVrouter = NULL;
  553. ULONG Size;
  554. ROUTER_INTERFACE_TYPE Type;
  555. ULONG i;
  556. if (!AddInterface && !BitVector) { return NO_ERROR; }
  557. do {
  558. //
  559. // Retrieve the existing interface configuration.
  560. // We will update this block below, as well as adding to or removing
  561. // from it depending on the flags specified in 'BitVector'.
  562. //
  563. Error =
  564. IpmontrGetInfoBlockFromInterfaceInfo(
  565. InterfaceName,
  566. MS_IP_VRRP,
  567. (PUCHAR*)&OldInterfaceInfo,
  568. &Size,
  569. &Count,
  570. &Type
  571. );
  572. if (Error) {
  573. //
  574. // No existing configuration is found. This is an error unless
  575. // we are adding the interface anew, in which case we just
  576. // create for ourselves a block containing the default settings.
  577. //
  578. if (!AddInterface) {
  579. break;
  580. } else {
  581. Error = IpmontrGetInterfaceType(InterfaceName, &Type);
  582. if (Error) {
  583. break;
  584. } else {
  585. Count = 1;
  586. Error =
  587. MakeVrrpInterfaceInfo(
  588. Type, (PUCHAR*)&OldInterfaceInfo, &Size
  589. );
  590. if (Error) { break; }
  591. }
  592. }
  593. } else {
  594. //
  595. // There is configuration on the interface. If it is empty this is
  596. // an error. If this is an add interface, and the info exists, it is
  597. // an error.
  598. //
  599. if (!(Count * Size) && !AddInterface) {
  600. Error = ERROR_NOT_FOUND; break;
  601. }
  602. else if (AddInterface) {
  603. //
  604. // We were asked to add an interface which already exists
  605. //
  606. DisplayMessage(g_hModule, EMSG_INTERFACE_EXISTS, InterfaceName);
  607. Error = ERROR_INVALID_PARAMETER;
  608. break;
  609. }
  610. }
  611. if (!BitVector) {
  612. //
  613. // Just add this interface without any additional info.
  614. //
  615. DWORD OldSize;
  616. if (NewInterfaceInfo == NULL){
  617. NewInterfaceInfo = Malloc((OldSize=GetVrrpIfInfoSize(OldInterfaceInfo))+
  618. sizeof(VRRP_VROUTER_CONFIG));
  619. if (!NewInterfaceInfo) {
  620. DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
  621. Error = ERROR_NOT_ENOUGH_MEMORY;
  622. break;
  623. }
  624. }
  625. CopyMemory(NewInterfaceInfo,OldInterfaceInfo,OldSize);
  626. }
  627. else{
  628. if (!AddInterface || (OldInterfaceInfo->VrouterCount != 0)) {
  629. //
  630. // There is a prexisting VRID set. Check for this VRID in the list and then
  631. // update it if required.
  632. //
  633. ASSERT(BitVector & VRRP_INTF_VRID_MASK);
  634. for (i = 0, PVrouter = VRRP_FIRST_VROUTER_CONFIG(OldInterfaceInfo);
  635. i < OldInterfaceInfo->VrouterCount;
  636. i++, PVrouter = VRRP_NEXT_VROUTER_CONFIG(PVrouter)) {
  637. if (PVrouter->VRID == VRouterInfo->VRID) {
  638. break;
  639. }
  640. }
  641. if (i == OldInterfaceInfo->VrouterCount) {
  642. //
  643. // This is a new VRID, Add it.
  644. //
  645. DWORD OldSize;
  646. //
  647. // The IP address should be valid or else this is a set op.
  648. //
  649. if (!(BitVector & VRRP_INTF_IPADDR_MASK)){
  650. DisplayMessage(
  651. g_hModule, EMSG_INVALID_VRID,
  652. VRouterInfo->VRID
  653. );
  654. Error = ERROR_INVALID_PARAMETER;
  655. break;
  656. }
  657. if (NewInterfaceInfo == NULL){
  658. NewInterfaceInfo = Malloc((OldSize=GetVrrpIfInfoSize(
  659. OldInterfaceInfo))+
  660. sizeof(VRRP_VROUTER_CONFIG));
  661. if (!NewInterfaceInfo) {
  662. DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
  663. Error = ERROR_NOT_ENOUGH_MEMORY;
  664. break;
  665. }
  666. }
  667. CopyMemory(NewInterfaceInfo, OldInterfaceInfo, OldSize);
  668. PVrouter = (PVRRP_VROUTER_CONFIG)((PBYTE)NewInterfaceInfo+OldSize);
  669. CopyMemory(PVrouter,VRouterInfo,sizeof(VRRP_VROUTER_CONFIG));
  670. NewInterfaceInfo->VrouterCount++;
  671. //
  672. // Check if we own the IP address given. If yes, set the priority.
  673. //
  674. PVrouter->ConfigPriority =
  675. FoundIpAddress(PVrouter->IPAddress[0]) ? 255 : 100;
  676. }
  677. else{
  678. //
  679. // This is an old VRID. Its priority should not need to be changed.
  680. //
  681. DWORD Offset, OldSize;
  682. if(BitVector & VRRP_INTF_IPADDR_MASK) {
  683. if ( ((PVrouter->ConfigPriority != 255) &&
  684. (FoundIpAddress(VRouterInfo->IPAddress[0]))
  685. )
  686. ||
  687. ((PVrouter->ConfigPriority == 255) &&
  688. (!FoundIpAddress(VRouterInfo->IPAddress[0])))
  689. ) {
  690. DisplayMessage(g_hModule, EMSG_BAD_OPTION_VALUE);
  691. Error = ERROR_INVALID_PARAMETER;
  692. break;
  693. }
  694. //
  695. // Add this IP address to the VRID specified.
  696. //
  697. if (NewInterfaceInfo == NULL){
  698. NewInterfaceInfo = Malloc((OldSize = GetVrrpIfInfoSize(
  699. OldInterfaceInfo))+
  700. sizeof(DWORD));
  701. if (!NewInterfaceInfo) {
  702. DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
  703. Error = ERROR_NOT_ENOUGH_MEMORY;
  704. break;
  705. }
  706. }
  707. //
  708. // Shift all the VROUTER configs after the PVrouter by 1 DWORD.
  709. //
  710. Offset = (PUCHAR) VRRP_NEXT_VROUTER_CONFIG(PVrouter) -
  711. (PUCHAR) OldInterfaceInfo;
  712. CopyMemory(NewInterfaceInfo, OldInterfaceInfo, OldSize);
  713. for (i = 0, PVrouter = VRRP_FIRST_VROUTER_CONFIG(NewInterfaceInfo);
  714. i < NewInterfaceInfo->VrouterCount;
  715. i++, PVrouter = VRRP_NEXT_VROUTER_CONFIG(PVrouter)) {
  716. if (PVrouter->VRID == VRouterInfo->VRID) {
  717. break;
  718. }
  719. }
  720. ASSERT(i < NewInterfaceInfo->VrouterCount);
  721. PVrouter->IPAddress[PVrouter->IPCount++] = VRouterInfo->IPAddress[0];
  722. ASSERT(((PUCHAR)NewInterfaceInfo+Offset+sizeof(DWORD)) ==
  723. (PUCHAR) VRRP_NEXT_VROUTER_CONFIG(PVrouter));
  724. CopyMemory(VRRP_NEXT_VROUTER_CONFIG(PVrouter),
  725. OldInterfaceInfo+Offset, OldSize-Offset);
  726. } else {
  727. //
  728. // Set the new info block as the old info block and point to the
  729. // vrouter block
  730. //
  731. if (NewInterfaceInfo == NULL){
  732. NewInterfaceInfo = Malloc((OldSize = GetVrrpIfInfoSize(
  733. OldInterfaceInfo)));
  734. if (!NewInterfaceInfo) {
  735. DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
  736. Error = ERROR_NOT_ENOUGH_MEMORY;
  737. break;
  738. }
  739. }
  740. CopyMemory(NewInterfaceInfo, OldInterfaceInfo, OldSize);
  741. for (i = 0, PVrouter = VRRP_FIRST_VROUTER_CONFIG(NewInterfaceInfo);
  742. i < NewInterfaceInfo->VrouterCount;
  743. i++, PVrouter = VRRP_NEXT_VROUTER_CONFIG(PVrouter)) {
  744. if (PVrouter->VRID == VRouterInfo->VRID) {
  745. break;
  746. }
  747. }
  748. ASSERT(i < NewInterfaceInfo->VrouterCount);
  749. }
  750. if (BitVector & VRRP_INTF_AUTH_MASK) {
  751. PVrouter->AuthenticationType = VRouterInfo->AuthenticationType;
  752. }
  753. if (BitVector & VRRP_INTF_PASSWD_MASK) {
  754. CopyMemory(PVrouter->AuthenticationData,
  755. VRouterInfo->AuthenticationData,
  756. VRRP_MAX_AUTHKEY_SIZE);
  757. }
  758. if (BitVector & VRRP_INTF_ADVT_MASK) {
  759. PVrouter->AdvertisementInterval = VRouterInfo->AdvertisementInterval;
  760. }
  761. if (BitVector & VRRP_INTF_PRIO_MASK) {
  762. PVrouter->ConfigPriority = VRouterInfo->ConfigPriority;
  763. }
  764. if (BitVector & VRRP_INTF_PREEMPT_MASK) {
  765. PVrouter->PreemptMode = VRouterInfo->PreemptMode;
  766. }
  767. }
  768. }
  769. }
  770. ValidateVrrpInterfaceInfo(NewInterfaceInfo);
  771. Error =
  772. IpmontrSetInfoBlockInInterfaceInfo(
  773. InterfaceName,
  774. MS_IP_VRRP,
  775. (PUCHAR)NewInterfaceInfo,
  776. GetVrrpIfInfoSize(NewInterfaceInfo),
  777. 1
  778. );
  779. } while(FALSE);
  780. if (NewInterfaceInfo) { Free(NewInterfaceInfo); }
  781. if (OldInterfaceInfo) { Free(OldInterfaceInfo); }
  782. if (Error == ERROR_NOT_FOUND) {
  783. DisplayMessage(g_hModule, EMSG_PROTO_NO_IF_INFO);
  784. } else if (Error) {
  785. DisplayError(g_hModule, Error);
  786. }
  787. return Error;
  788. }
  789. ULONG
  790. DeleteVrrpInterfaceInfo(
  791. PWCHAR InterfaceName,
  792. PVRRP_VROUTER_CONFIG VRouterInfo,
  793. ULONG BitVector,
  794. BOOL DeleteInterface
  795. )
  796. {
  797. ULONG Count;
  798. ULONG Error;
  799. PVRRP_IF_CONFIG NewInterfaceInfo = NULL;
  800. PVRRP_IF_CONFIG OldInterfaceInfo = NULL;
  801. PVRRP_VROUTER_CONFIG PVrouter = NULL;
  802. ULONG Size;
  803. ROUTER_INTERFACE_TYPE Type;
  804. ULONG i;
  805. if (!DeleteInterface && !BitVector) { return NO_ERROR; }
  806. do {
  807. //
  808. // Retrieve the existing interface configuration.
  809. // We will update this block below, as well as adding to or removing
  810. // from it depending on the flags specified in 'BitVector'.
  811. //
  812. Error =
  813. IpmontrGetInfoBlockFromInterfaceInfo(
  814. InterfaceName,
  815. MS_IP_VRRP,
  816. (PUCHAR*)&OldInterfaceInfo,
  817. &Size,
  818. &Count,
  819. &Type
  820. );
  821. if (Error) {
  822. //
  823. // No existing configuration is found. This is an error.
  824. //
  825. break;
  826. }
  827. if (DeleteInterface) {
  828. //
  829. // Just delete this interface
  830. //
  831. Error = IpmontrDeleteInfoBlockFromInterfaceInfo(
  832. InterfaceName,
  833. MS_IP_VRRP
  834. );
  835. break;
  836. } else {
  837. DWORD OldSize;
  838. PVRRP_VROUTER_CONFIG PVrouterNew;
  839. //
  840. // Look for the VRID and delete it.
  841. //
  842. for (i = 0, PVrouter = VRRP_FIRST_VROUTER_CONFIG(OldInterfaceInfo);
  843. i < OldInterfaceInfo->VrouterCount;
  844. i++, PVrouter = VRRP_NEXT_VROUTER_CONFIG(PVrouter)) {
  845. if (PVrouter->VRID == VRouterInfo->VRID) {
  846. break;
  847. }
  848. }
  849. if (i >= OldInterfaceInfo->VrouterCount) {
  850. DisplayMessage(g_hModule, EMSG_BAD_OPTION_VALUE);
  851. Error = ERROR_INVALID_PARAMETER;
  852. break;
  853. }
  854. NewInterfaceInfo = Malloc((OldSize=GetVrrpIfInfoSize(OldInterfaceInfo))-
  855. VRRP_VROUTER_CONFIG_SIZE(PVrouter));
  856. if (!NewInterfaceInfo) {
  857. DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
  858. Error = ERROR_NOT_ENOUGH_MEMORY;
  859. break;
  860. }
  861. NewInterfaceInfo->VrouterCount = OldInterfaceInfo->VrouterCount - 1;
  862. PVrouterNew = VRRP_FIRST_VROUTER_CONFIG(NewInterfaceInfo);
  863. for (i = 0, PVrouter = VRRP_FIRST_VROUTER_CONFIG(OldInterfaceInfo);
  864. i < OldInterfaceInfo->VrouterCount;
  865. i++, PVrouter = VRRP_NEXT_VROUTER_CONFIG(PVrouter)) {
  866. if (PVrouter->VRID == VRouterInfo->VRID) {
  867. continue;
  868. }
  869. CopyMemory(PVrouterNew,PVrouter,VRRP_VROUTER_CONFIG_SIZE(PVrouter));
  870. PVrouterNew = VRRP_NEXT_VROUTER_CONFIG(PVrouterNew);
  871. }
  872. ValidateVrrpInterfaceInfo(NewInterfaceInfo);
  873. Error =
  874. IpmontrSetInfoBlockInInterfaceInfo(
  875. InterfaceName,
  876. MS_IP_VRRP,
  877. (PUCHAR)NewInterfaceInfo,
  878. GetVrrpIfInfoSize(NewInterfaceInfo),
  879. 1
  880. );
  881. }
  882. } while(FALSE);
  883. if (NewInterfaceInfo) { Free(NewInterfaceInfo); }
  884. if (OldInterfaceInfo) { Free(OldInterfaceInfo); }
  885. if (Error == ERROR_NOT_FOUND) {
  886. DisplayMessage(g_hModule, EMSG_PROTO_NO_IF_INFO);
  887. } else if (Error) {
  888. DisplayError(g_hModule, Error);
  889. }
  890. return Error;
  891. }
  892. ULONG
  893. ValidateVrrpInterfaceInfo(
  894. PVRRP_IF_CONFIG InterfaceInfo
  895. )
  896. {
  897. return NO_ERROR;
  898. }
  899. DWORD
  900. GetVrrpIfInfoSize(
  901. PVRRP_IF_CONFIG InterfaceInfo
  902. )
  903. {
  904. DWORD Size = 0;
  905. ULONG i;
  906. PVRRP_VROUTER_CONFIG pvr;
  907. Size += sizeof(InterfaceInfo->VrouterCount);
  908. for (i = 0, pvr = VRRP_FIRST_VROUTER_CONFIG(InterfaceInfo);
  909. i < InterfaceInfo->VrouterCount;
  910. i++,pvr = VRRP_NEXT_VROUTER_CONFIG(pvr)) {
  911. Size += VRRP_VROUTER_CONFIG_SIZE(pvr);
  912. }
  913. return Size;
  914. }
  915. BOOL
  916. FoundIpAddress(
  917. DWORD IPAddress
  918. )
  919. {
  920. PMIB_IPADDRTABLE pTable = NULL;
  921. DWORD Size = 0;
  922. ULONG i;
  923. BOOL Result;
  924. GetIpAddrTable( pTable, &Size, TRUE);
  925. pTable = Malloc(Size);
  926. if (!pTable) {
  927. DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
  928. return FALSE;
  929. }
  930. if (GetIpAddrTable(pTable,&Size,TRUE) != NO_ERROR){
  931. return FALSE;
  932. }
  933. for (i = 0; i < pTable->dwNumEntries; i++) {
  934. if (pTable->table[i].dwAddr == IPAddress)
  935. break;
  936. }
  937. Result = (i < pTable->dwNumEntries);
  938. Free(pTable);
  939. return Result;
  940. }
  941. ULONG
  942. SetArpRetryCount(
  943. DWORD Value
  944. )
  945. {
  946. HKEY hKey = NULL;
  947. DWORD dwDisp;
  948. ULONG dwErr = NO_ERROR;
  949. do
  950. {
  951. dwErr = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  952. L"System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
  953. 0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,
  954. &hKey, &dwDisp);
  955. if (dwErr != ERROR_SUCCESS) {
  956. break;
  957. }
  958. dwErr = RegSetValueEx(hKey, L"ArpRetryCount", 0, REG_DWORD, (LPBYTE) &Value,
  959. sizeof(DWORD));
  960. } while (0);
  961. if (hKey) {
  962. RegCloseKey(hKey);
  963. }
  964. if (dwErr == ERROR_SUCCESS) {
  965. dwErr = NO_ERROR;
  966. }
  967. return dwErr;
  968. }