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.

1299 lines
39 KiB

  1. /*++
  2. Copyright (c) 1999, Microsoft Corporation
  3. Module Name:
  4. net\routing\netsh\ip\protocols\vrrphlpopt.c
  5. Abstract:
  6. VRRP command options implementation.
  7. This module contains handlers for the configuration commands
  8. supported by the VRRP Protocol.
  9. Author:
  10. Peeyush Ranjan (peeyushr) 1-Mar-1999
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #include <ipcmp.h>
  16. #define Malloc(x) HeapAlloc(GetProcessHeap(), 0, (x))
  17. #define Free(x) HeapFree(GetProcessHeap(), 0, (x))
  18. //
  19. // Forward declarations
  20. //
  21. ULONG
  22. QueryTagArray(
  23. PTCHAR ArgumentArray[],
  24. ULONG ArgumentCount,
  25. TAG_TYPE TagTypeArray[],
  26. ULONG TagTypeCount,
  27. OUT PULONG* TagArray
  28. );
  29. ULONG
  30. ValidateTagTypeArray(
  31. TAG_TYPE TagTypeArray[],
  32. ULONG TagTypeCount
  33. );
  34. DWORD
  35. HandleVrrpAddVRID(
  36. PWCHAR MachineName,
  37. PTCHAR* ArgumentArray,
  38. DWORD ArgumentIndex,
  39. DWORD ArgumentCount,
  40. DWORD CmdFlags,
  41. PVOID Data,
  42. BOOL* CommandDone
  43. )
  44. {
  45. ULONG ArgumentsLeft;
  46. ULONG BitVector;
  47. ULONG Error;
  48. ULONG ErrorIndex = 0;
  49. ULONG i;
  50. VRRP_VROUTER_CONFIG VRouterGiven;
  51. PULONG TagArray;
  52. WCHAR InterfaceName[MAX_INTERFACE_NAME_LEN + 1];
  53. ULONG InfoSize;
  54. TAG_TYPE TagTypeArray[] = {
  55. { TOKEN_OPT_INTERFACE_NAME, TRUE, FALSE },
  56. { TOKEN_OPT_VRID, TRUE, FALSE },
  57. { TOKEN_OPT_IPADDRESS, TRUE, FALSE }
  58. };
  59. VERIFY_INSTALLED(MS_IP_VRRP, L"VRRP");
  60. if (ArgumentIndex >= ArgumentCount) { return ERROR_SHOW_USAGE; }
  61. ArgumentsLeft = ArgumentCount - ArgumentIndex;
  62. //
  63. // We convert the optional tags into an array of 'TagTypeArray' indices
  64. // which guide is in our scanning of the argument list.
  65. // Since the tags are optional, this process may result in no tags at all,
  66. // in which case we assume that arguments are specified in exactly the order
  67. // given in 'TagTypeArray' above.
  68. //
  69. Error =
  70. QueryTagArray(
  71. &ArgumentArray[ArgumentIndex],
  72. ArgumentsLeft,
  73. TagTypeArray,
  74. NUM_TAGS_IN_TABLE(TagTypeArray),
  75. &TagArray
  76. );
  77. if (Error) { return Error; }
  78. BitVector = 0;
  79. //
  80. // Make the default info
  81. //
  82. //
  83. MakeVrrpVRouterInfo((PUCHAR) &VRouterGiven);
  84. // We now scan the argument list, converting the arguments
  85. // into information in our 'VrouterGiven' structure.
  86. //
  87. for (i = 0; i < ArgumentsLeft; i++) {
  88. switch(TagArray ? TagArray[i] : i) {
  89. case 0: {
  90. ULONG Length = sizeof(InterfaceName);
  91. Error =
  92. IpmontrGetIfNameFromFriendlyName(
  93. ArgumentArray[i + ArgumentIndex], InterfaceName, &Length
  94. );
  95. if (Error) {
  96. DisplayMessage(
  97. g_hModule, EMSG_NO_INTERFACE,
  98. ArgumentArray[i + ArgumentIndex]
  99. );
  100. Error = ERROR_NO_SUCH_INTERFACE;
  101. i = ArgumentsLeft;
  102. break;
  103. }
  104. TagTypeArray[TagArray ? TagArray[i] : i].bPresent = TRUE;
  105. break;
  106. }
  107. case 1: {
  108. ULONG VRIDGiven;
  109. VRIDGiven = _tcstoul(ArgumentArray[i + ArgumentIndex], NULL, 10);
  110. if (VRIDGiven > 255) {
  111. DisplayMessage(
  112. g_hModule, EMSG_INVALID_VRID,
  113. VRIDGiven
  114. );
  115. Error = ERROR_INVALID_PARAMETER;
  116. i = ArgumentsLeft;
  117. break;
  118. }
  119. VRouterGiven.VRID = (BYTE) VRIDGiven;
  120. BitVector |= VRRP_INTF_VRID_MASK;
  121. TagTypeArray[TagArray ? TagArray[i] : i].bPresent = TRUE;
  122. break;
  123. }
  124. case 2: {
  125. ULONG AddressSpecified;
  126. //
  127. // If the IP address has been specified, the VRID should have been
  128. // specified already
  129. //
  130. if (!(BitVector & VRRP_INTF_VRID_MASK)){
  131. Error = ERROR_INVALID_SYNTAX;
  132. i = ArgumentsLeft;
  133. break;
  134. }
  135. AddressSpecified = GetIpAddress(ArgumentArray[i + ArgumentIndex]);
  136. if (!AddressSpecified || AddressSpecified == INADDR_NONE) {
  137. DisplayMessage(
  138. g_hModule,
  139. MSG_IP_BAD_IP_ADDR,
  140. ArgumentArray[i + ArgumentIndex]
  141. );
  142. Error = ERROR_INVALID_PARAMETER;
  143. ErrorIndex = i;
  144. i = ArgumentsLeft;
  145. break;
  146. }
  147. VRouterGiven.IPCount = 1;
  148. VRouterGiven.IPAddress[0] = AddressSpecified;
  149. BitVector |= VRRP_INTF_IPADDR_MASK;
  150. TagTypeArray[TagArray ? TagArray[i] : i].bPresent = TRUE;
  151. break;
  152. }
  153. default: {
  154. i = ArgumentsLeft;
  155. Error = ERROR_INVALID_SYNTAX;
  156. }
  157. }
  158. }
  159. if (!Error) {
  160. //
  161. // Ensure that all required parameters are present.
  162. //
  163. Error =
  164. ValidateTagTypeArray(TagTypeArray, NUM_TAGS_IN_TABLE(TagTypeArray));
  165. }
  166. if (Error == ERROR_TAG_ALREADY_PRESENT) {
  167. DisplayMessage(g_hModule, EMSG_TAG_ALREADY_PRESENT);
  168. } else if (Error == ERROR_INVALID_PARAMETER && TagArray) {
  169. DispTokenErrMsg(
  170. g_hModule,
  171. EMSG_BAD_OPTION_VALUE,
  172. TagTypeArray[TagArray[ErrorIndex]],
  173. ArgumentArray[ErrorIndex + ArgumentIndex]
  174. );
  175. } else if (!Error && (BitVector)) {
  176. //
  177. // Update the configuration with the new settings.
  178. // Note that the update routine may perform additional validation
  179. // in the process of reconciling the new settings
  180. // with any existing settings.
  181. //
  182. Error =
  183. UpdateVrrpInterfaceInfo(
  184. InterfaceName, &VRouterGiven, BitVector, FALSE
  185. );
  186. }
  187. return Error;
  188. }
  189. DWORD
  190. HandleVrrpAddInterface(
  191. PWCHAR MachineName,
  192. PTCHAR* ArgumentArray,
  193. DWORD ArgumentIndex,
  194. DWORD ArgumentCount,
  195. DWORD CmdFlags,
  196. PVOID Data,
  197. BOOL* CommandDone
  198. )
  199. {
  200. ULONG ArgumentsLeft;
  201. ULONG BitVector;
  202. ULONG Error;
  203. ULONG ErrorIndex = 0;
  204. ULONG i;
  205. VRRP_VROUTER_CONFIG VRouterGiven;
  206. PULONG TagArray;
  207. WCHAR InterfaceName[MAX_INTERFACE_NAME_LEN + 1];
  208. ULONG InfoSize;
  209. TAG_TYPE TagTypeArray[] = {
  210. { TOKEN_OPT_INTERFACE_NAME, TRUE, FALSE },
  211. { TOKEN_OPT_VRID, FALSE, FALSE },
  212. { TOKEN_OPT_IPADDRESS, FALSE, FALSE }
  213. };
  214. VERIFY_INSTALLED(MS_IP_VRRP, L"VRRP");
  215. if (ArgumentIndex >= ArgumentCount) { return ERROR_SHOW_USAGE; }
  216. ArgumentsLeft = ArgumentCount - ArgumentIndex;
  217. //
  218. // We convert the optional tags into an array of 'TagTypeArray' indices
  219. // which guide is in our scanning of the argument list.
  220. // Since the tags are optional, this process may result in no tags at all,
  221. // in which case we assume that arguments are specified in exactly the order
  222. // given in 'TagTypeArray' above.
  223. //
  224. Error =
  225. QueryTagArray(
  226. &ArgumentArray[ArgumentIndex],
  227. ArgumentsLeft,
  228. TagTypeArray,
  229. NUM_TAGS_IN_TABLE(TagTypeArray),
  230. &TagArray
  231. );
  232. if (Error) { return Error; }
  233. BitVector = 0;
  234. //
  235. // We now scan the argument list, converting the arguments
  236. // into information in our 'VrouterGiven' structure.
  237. //
  238. for (i = 0; i < ArgumentsLeft; i++) {
  239. switch(TagArray ? TagArray[i] : i) {
  240. case 0: {
  241. ULONG Length = sizeof(InterfaceName);
  242. Error =
  243. IpmontrGetIfNameFromFriendlyName(
  244. ArgumentArray[i + ArgumentIndex], InterfaceName, &Length
  245. );
  246. if (Error) {
  247. DisplayMessage(
  248. g_hModule, EMSG_NO_INTERFACE,
  249. ArgumentArray[i + ArgumentIndex]
  250. );
  251. Error = ERROR_NO_SUCH_INTERFACE;
  252. i = ArgumentsLeft;
  253. break;
  254. }
  255. TagTypeArray[TagArray ? TagArray[i] : i].bPresent = TRUE;
  256. break;
  257. }
  258. case 1: {
  259. ULONG VRIDGiven;
  260. VRIDGiven = _tcstoul(ArgumentArray[i + ArgumentIndex], NULL, 10);
  261. if (VRIDGiven > 255) {
  262. DisplayMessage(
  263. g_hModule, EMSG_INVALID_VRID,
  264. VRIDGiven
  265. );
  266. Error = ERROR_NO_SUCH_INTERFACE;
  267. i = ArgumentsLeft;
  268. break;
  269. }
  270. VRouterGiven.VRID = (BYTE) VRIDGiven;
  271. BitVector |= VRRP_INTF_VRID_MASK;
  272. TagTypeArray[TagArray ? TagArray[i] : i].bPresent = TRUE;
  273. break;
  274. }
  275. case 2: {
  276. ULONG AddressSpecified;
  277. //
  278. // If the IP address has been specified, the VRID should have been
  279. // specified already
  280. //
  281. if (!(BitVector & VRRP_INTF_VRID_MASK)){
  282. Error = ERROR_INVALID_SYNTAX;
  283. i = ArgumentsLeft;
  284. break;
  285. }
  286. AddressSpecified = GetIpAddress(ArgumentArray[i + ArgumentIndex]);
  287. if (!AddressSpecified || AddressSpecified == INADDR_NONE) {
  288. DisplayMessage(
  289. g_hModule,
  290. MSG_IP_BAD_IP_ADDR,
  291. ArgumentArray[i + ArgumentIndex]
  292. );
  293. Error = ERROR_INVALID_PARAMETER;
  294. ErrorIndex = i;
  295. i = ArgumentsLeft;
  296. break;
  297. }
  298. VRouterGiven.IPCount = 1;
  299. VRouterGiven.IPAddress[0] = AddressSpecified;
  300. BitVector |= VRRP_INTF_IPADDR_MASK;
  301. TagTypeArray[TagArray ? TagArray[i] : i].bPresent = TRUE;
  302. break;
  303. }
  304. default: {
  305. i = ArgumentsLeft;
  306. Error = ERROR_INVALID_SYNTAX;
  307. }
  308. }
  309. }
  310. if ((BitVector) && (!(BitVector & VRRP_INTF_VRID_MASK)
  311. || !(BitVector & VRRP_INTF_IPADDR_MASK))) {
  312. //
  313. // You can either have no VRID, or both VRID and IP address, not only one of them
  314. //
  315. Error = ERROR_INVALID_SYNTAX;
  316. }
  317. if (!Error) {
  318. //
  319. // Ensure that all required parameters are present.
  320. //
  321. Error =
  322. ValidateTagTypeArray(TagTypeArray, NUM_TAGS_IN_TABLE(TagTypeArray));
  323. }
  324. if (Error == ERROR_TAG_ALREADY_PRESENT) {
  325. DisplayMessage(g_hModule, EMSG_TAG_ALREADY_PRESENT);
  326. } else if (Error == ERROR_INVALID_PARAMETER && TagArray) {
  327. DispTokenErrMsg(
  328. g_hModule,
  329. EMSG_BAD_OPTION_VALUE,
  330. TagTypeArray[TagArray[ErrorIndex]],
  331. ArgumentArray[ErrorIndex + ArgumentIndex]
  332. );
  333. } else if (!Error) {
  334. //
  335. // Update the configuration with the new settings.
  336. // Note that the update routine may perform additional validation
  337. // in the process of reconciling the new settings
  338. // with any existing settings.
  339. //
  340. Error =
  341. UpdateVrrpInterfaceInfo(
  342. InterfaceName, &VRouterGiven, BitVector, TRUE
  343. );
  344. }
  345. return Error;
  346. }
  347. DWORD
  348. HandleVrrpDeleteInterface(
  349. PWCHAR MachineName,
  350. PTCHAR* ArgumentArray,
  351. DWORD ArgumentIndex,
  352. DWORD ArgumentCount,
  353. DWORD CmdFlags,
  354. PVOID Data,
  355. BOOL* CommandDone
  356. )
  357. {
  358. ULONG ArgumentsLeft;
  359. ULONG BitVector;
  360. ULONG Error;
  361. ULONG ErrorIndex = 0;
  362. ULONG i;
  363. VRRP_VROUTER_CONFIG VRouterGiven;
  364. PULONG TagArray;
  365. WCHAR InterfaceName[MAX_INTERFACE_NAME_LEN + 1];
  366. ULONG InfoSize;
  367. TAG_TYPE TagTypeArray[] = {
  368. { TOKEN_OPT_INTERFACE_NAME, TRUE, FALSE }
  369. };
  370. VERIFY_INSTALLED(MS_IP_VRRP, L"VRRP");
  371. if (ArgumentIndex >= ArgumentCount) { return ERROR_SHOW_USAGE; }
  372. ArgumentsLeft = ArgumentCount - ArgumentIndex;
  373. //
  374. // We convert the optional tags into an array of 'TagTypeArray' indices
  375. // which guide is in our scanning of the argument list.
  376. // Since the tags are optional, this process may result in no tags at all,
  377. // in which case we assume that arguments are specified in exactly the order
  378. // given in 'TagTypeArray' above.
  379. //
  380. Error =
  381. QueryTagArray(
  382. &ArgumentArray[ArgumentIndex],
  383. ArgumentsLeft,
  384. TagTypeArray,
  385. NUM_TAGS_IN_TABLE(TagTypeArray),
  386. &TagArray
  387. );
  388. if (Error) { return Error; }
  389. BitVector = 0;
  390. //
  391. // We now scan the argument list, converting the arguments
  392. // into information in our 'VrouterGiven' structure.
  393. //
  394. for (i = 0; i < ArgumentsLeft; i++) {
  395. switch(TagArray ? TagArray[i] : i) {
  396. case 0: {
  397. ULONG Length = sizeof(InterfaceName);
  398. Error =
  399. IpmontrGetIfNameFromFriendlyName(
  400. ArgumentArray[i + ArgumentIndex], InterfaceName, &Length
  401. );
  402. if (Error) {
  403. DisplayMessage(
  404. g_hModule, EMSG_NO_INTERFACE,
  405. ArgumentArray[i + ArgumentIndex]
  406. );
  407. Error = ERROR_NO_SUCH_INTERFACE;
  408. i = ArgumentsLeft;
  409. break;
  410. }
  411. TagTypeArray[TagArray ? TagArray[i] : i].bPresent = TRUE;
  412. break;
  413. }
  414. default: {
  415. i = ArgumentsLeft;
  416. Error = ERROR_INVALID_SYNTAX;
  417. }
  418. }
  419. }
  420. if (!Error) {
  421. //
  422. // Ensure that all required parameters are present.
  423. //
  424. Error =
  425. ValidateTagTypeArray(TagTypeArray, NUM_TAGS_IN_TABLE(TagTypeArray));
  426. }
  427. if (Error == ERROR_TAG_ALREADY_PRESENT) {
  428. DisplayMessage(g_hModule, EMSG_TAG_ALREADY_PRESENT);
  429. } else if (Error == ERROR_INVALID_PARAMETER && TagArray) {
  430. DispTokenErrMsg(
  431. g_hModule,
  432. EMSG_BAD_OPTION_VALUE,
  433. TagTypeArray[TagArray[ErrorIndex]],
  434. ArgumentArray[ErrorIndex + ArgumentIndex]
  435. );
  436. } else if (!Error) {
  437. //
  438. // Update the configuration with the new settings.
  439. // Note that the update routine may perform additional validation
  440. // in the process of reconciling the new settings
  441. // with any existing settings.
  442. //
  443. Error =
  444. DeleteVrrpInterfaceInfo(
  445. InterfaceName, &VRouterGiven, BitVector, TRUE
  446. );
  447. }
  448. return Error;
  449. }
  450. DWORD
  451. HandleVrrpDeleteVRID(
  452. PWCHAR MachineName,
  453. PTCHAR* ArgumentArray,
  454. DWORD ArgumentIndex,
  455. DWORD ArgumentCount,
  456. DWORD CmdFlags,
  457. PVOID Data,
  458. BOOL* CommandDone
  459. )
  460. {
  461. ULONG ArgumentsLeft;
  462. ULONG BitVector;
  463. ULONG Error;
  464. ULONG ErrorIndex = 0;
  465. ULONG i;
  466. VRRP_VROUTER_CONFIG VRouterGiven;
  467. PULONG TagArray;
  468. WCHAR InterfaceName[MAX_INTERFACE_NAME_LEN + 1];
  469. ULONG InfoSize;
  470. TAG_TYPE TagTypeArray[] = {
  471. { TOKEN_OPT_INTERFACE_NAME, TRUE, FALSE },
  472. { TOKEN_OPT_VRID, TRUE, FALSE }
  473. };
  474. VERIFY_INSTALLED(MS_IP_VRRP, L"VRRP");
  475. if (ArgumentIndex >= ArgumentCount) { return ERROR_SHOW_USAGE; }
  476. ArgumentsLeft = ArgumentCount - ArgumentIndex;
  477. //
  478. // We convert the optional tags into an array of 'TagTypeArray' indices
  479. // which guide is in our scanning of the argument list.
  480. // Since the tags are optional, this process may result in no tags at all,
  481. // in which case we assume that arguments are specified in exactly the order
  482. // given in 'TagTypeArray' above.
  483. //
  484. Error =
  485. QueryTagArray(
  486. &ArgumentArray[ArgumentIndex],
  487. ArgumentsLeft,
  488. TagTypeArray,
  489. NUM_TAGS_IN_TABLE(TagTypeArray),
  490. &TagArray
  491. );
  492. if (Error) { return Error; }
  493. BitVector = 0;
  494. //
  495. // We now scan the argument list, converting the arguments
  496. // into information in our 'VrouterGiven' structure.
  497. //
  498. for (i = 0; i < ArgumentsLeft; i++) {
  499. switch(TagArray ? TagArray[i] : i) {
  500. case 0: {
  501. ULONG Length = sizeof(InterfaceName);
  502. Error =
  503. IpmontrGetIfNameFromFriendlyName(
  504. ArgumentArray[i + ArgumentIndex], InterfaceName, &Length
  505. );
  506. if (Error) {
  507. DisplayMessage(
  508. g_hModule, EMSG_NO_INTERFACE,
  509. ArgumentArray[i + ArgumentIndex]
  510. );
  511. Error = ERROR_NO_SUCH_INTERFACE;
  512. i = ArgumentsLeft;
  513. break;
  514. }
  515. TagTypeArray[TagArray ? TagArray[i] : i].bPresent = TRUE;
  516. break;
  517. }
  518. case 1: {
  519. ULONG Length = sizeof(InterfaceName);
  520. DWORD VRIDGiven;
  521. VRIDGiven = _tcstoul(ArgumentArray[i + ArgumentIndex], NULL, 10);
  522. if (VRIDGiven > 255) {
  523. DisplayMessage(
  524. g_hModule, EMSG_INVALID_VRID,
  525. VRIDGiven
  526. );
  527. Error = ERROR_NO_SUCH_INTERFACE;
  528. i = ArgumentsLeft;
  529. break;
  530. }
  531. VRouterGiven.VRID = (BYTE) VRIDGiven;
  532. BitVector |= VRRP_INTF_VRID_MASK;
  533. TagTypeArray[TagArray ? TagArray[i] : i].bPresent = TRUE;
  534. break;
  535. }
  536. default: {
  537. i = ArgumentsLeft;
  538. Error = ERROR_INVALID_SYNTAX;
  539. }
  540. }
  541. }
  542. if (!Error) {
  543. //
  544. // Ensure that all required parameters are present.
  545. //
  546. Error =
  547. ValidateTagTypeArray(TagTypeArray, NUM_TAGS_IN_TABLE(TagTypeArray));
  548. }
  549. if (Error == ERROR_TAG_ALREADY_PRESENT) {
  550. DisplayMessage(g_hModule, EMSG_TAG_ALREADY_PRESENT);
  551. } else if (Error == ERROR_INVALID_PARAMETER && TagArray) {
  552. DispTokenErrMsg(
  553. g_hModule,
  554. EMSG_BAD_OPTION_VALUE,
  555. TagTypeArray[TagArray[ErrorIndex]],
  556. ArgumentArray[ErrorIndex + ArgumentIndex]
  557. );
  558. } else if (!Error && (BitVector)) {
  559. //
  560. // Update the configuration with the new settings.
  561. // Note that the update routine may perform additional validation
  562. // in the process of reconciling the new settings
  563. // with any existing settings.
  564. //
  565. Error =
  566. DeleteVrrpInterfaceInfo(
  567. InterfaceName, &VRouterGiven, BitVector, FALSE
  568. );
  569. }
  570. return Error;
  571. }
  572. DWORD
  573. DumpVrrpInformation(VOID)
  574. {
  575. PMPR_INTERFACE_0 Array;
  576. ULONG Count = 0;
  577. ULONG Error;
  578. ULONG i;
  579. PUCHAR Information;
  580. ULONG Length;
  581. ULONG Total;
  582. ULONG Type;
  583. DisplayMessage(g_hModule,DMP_VRRP_HEADER);
  584. DisplayMessageT(DMP_VRRP_PUSHD);
  585. DisplayMessageT(DMP_VRRP_UNINSTALL);
  586. //
  587. // Show the global info commands
  588. //
  589. ShowVrrpGlobalInfo(INVALID_HANDLE_VALUE);
  590. //
  591. // Now show every interface
  592. //
  593. Error = IpmontrInterfaceEnum((PUCHAR*)&Array, &Count, &Total);
  594. if (Error) {
  595. DisplayError(g_hModule, Error);
  596. return NO_ERROR;
  597. }
  598. for (i = 0; i < Count; i++) {
  599. Error =
  600. IpmontrGetInfoBlockFromInterfaceInfo(
  601. Array[i].wszInterfaceName,
  602. MS_IP_VRRP,
  603. &Information,
  604. &Length,
  605. &Total,
  606. &Type
  607. );
  608. if (!Error) {
  609. Free(Information);
  610. ShowVrrpInterfaceInfo(INVALID_HANDLE_VALUE, Array[i].wszInterfaceName);
  611. }
  612. }
  613. DisplayMessageT(DMP_POPD);
  614. DisplayMessage(g_hModule, DMP_VRRP_FOOTER);
  615. Free(Array);
  616. return NO_ERROR;
  617. }
  618. DWORD
  619. HandleVrrpInstall(
  620. PWCHAR MachineName,
  621. PTCHAR* ArgumentArray,
  622. DWORD ArgumentIndex,
  623. DWORD ArgumentCount,
  624. DWORD CmdFlags,
  625. PVOID Data,
  626. BOOL* CommandDone
  627. )
  628. {
  629. ULONG Error;
  630. PUCHAR GlobalInfo;
  631. ULONG Length;
  632. if (ArgumentIndex != ArgumentCount) { return ERROR_SHOW_USAGE; }
  633. //
  634. // To install the VRRP, we construct the default configuration
  635. // and add it to the global configuration for the router.
  636. //
  637. Error = MakeVrrpGlobalInfo(&GlobalInfo, &Length);
  638. if (Error) {
  639. DisplayError(g_hModule, Error);
  640. } else {
  641. Error =
  642. IpmontrSetInfoBlockInGlobalInfo(
  643. MS_IP_VRRP,
  644. GlobalInfo,
  645. Length,
  646. 1
  647. );
  648. Free(GlobalInfo);
  649. if (!Error) {
  650. DEBUG("Added VRRP");
  651. } else {
  652. DisplayError(g_hModule, Error);
  653. }
  654. Error = SetArpRetryCount(0);
  655. }
  656. return Error;
  657. }
  658. DWORD
  659. HandleVrrpSetGlobal(
  660. PWCHAR MachineName,
  661. PTCHAR* ArgumentArray,
  662. DWORD ArgumentIndex,
  663. DWORD ArgumentCount,
  664. DWORD CmdFlags,
  665. PVOID Data,
  666. BOOL* CommandDone
  667. )
  668. {
  669. ULONG ArgumentsLeft;
  670. ULONG Error;
  671. PULONG TagArray;
  672. PVRRP_GLOBAL_CONFIG pVrrpNewGlobalConfig;
  673. DWORD LoggingLevel;
  674. ULONG i;
  675. ULONG ErrorIndex;
  676. TAG_TYPE TagTypeArray[] = {
  677. { TOKEN_OPT_LOGGINGLEVEL, FALSE, FALSE }
  678. };
  679. VERIFY_INSTALLED(MS_IP_VRRP, L"VRRP");
  680. if (ArgumentIndex >= ArgumentCount) {
  681. return ERROR_SHOW_USAGE;
  682. }
  683. ArgumentsLeft = ArgumentCount - ArgumentIndex;
  684. //
  685. // We convert the optional tags into an array of 'TagTypeArray' indices
  686. // which guide is in our scanning of the argument list.
  687. // Since the tags are optional, this process may result in no tags at all,
  688. // in which case we assume that arguments are specified in exactly the order
  689. // given in 'TagTypeArray' above.
  690. //
  691. Error =
  692. QueryTagArray(
  693. &ArgumentArray[ArgumentIndex],
  694. ArgumentsLeft,
  695. TagTypeArray,
  696. NUM_TAGS_IN_TABLE(TagTypeArray),
  697. &TagArray
  698. );
  699. if (Error) { return Error; }
  700. for (i = 0; i < ArgumentsLeft; i++) {
  701. switch(TagArray ? TagArray[i] : i) {
  702. case 0: {
  703. TOKEN_VALUE TokenArray[] = {
  704. { TOKEN_OPT_VALUE_NONE, VRRP_LOGGING_NONE },
  705. { TOKEN_OPT_VALUE_ERROR, VRRP_LOGGING_ERROR },
  706. { TOKEN_OPT_VALUE_WARN, VRRP_LOGGING_WARN },
  707. { TOKEN_OPT_VALUE_INFO, VRRP_LOGGING_INFO }
  708. };
  709. Error =
  710. MatchEnumTag(
  711. g_hModule,
  712. ArgumentArray[i + ArgumentIndex],
  713. NUM_TOKENS_IN_TABLE(TokenArray),
  714. TokenArray,
  715. &LoggingLevel
  716. );
  717. if (Error) {
  718. Error = ERROR_INVALID_PARAMETER;
  719. ErrorIndex = i;
  720. i = ArgumentsLeft;
  721. break;
  722. }
  723. TagTypeArray[TagArray ? TagArray[i] : i].bPresent = TRUE;
  724. break;
  725. }
  726. default: {
  727. i = ArgumentsLeft;
  728. Error = ERROR_INVALID_SYNTAX;
  729. }
  730. }
  731. }
  732. if (!Error) {
  733. //
  734. // Ensure that all required parameters are present.
  735. //
  736. Error =
  737. ValidateTagTypeArray(TagTypeArray, NUM_TAGS_IN_TABLE(TagTypeArray));
  738. }
  739. if (Error == ERROR_TAG_ALREADY_PRESENT) {
  740. DisplayMessage(g_hModule, EMSG_TAG_ALREADY_PRESENT);
  741. } else if (Error == ERROR_INVALID_PARAMETER && TagArray) {
  742. DispTokenErrMsg(
  743. g_hModule,
  744. EMSG_BAD_OPTION_VALUE,
  745. TagTypeArray[TagArray[ErrorIndex]],
  746. ArgumentArray[ErrorIndex + ArgumentIndex]
  747. );
  748. } else if (!Error){
  749. Error = CreateVrrpGlobalInfo(&pVrrpNewGlobalConfig,LoggingLevel);
  750. if (!Error) {
  751. //
  752. // Update the configuration with the new settings.
  753. // Note that the update routine may perform additional validation
  754. // in the process of reconciling the new settings
  755. // with any existing settings.
  756. //
  757. Error = UpdateVrrpGlobalInfo(pVrrpNewGlobalConfig);
  758. Free(pVrrpNewGlobalConfig);
  759. }
  760. }
  761. return NO_ERROR;
  762. }
  763. DWORD
  764. HandleVrrpSetInterface(
  765. PWCHAR MachineName,
  766. PTCHAR* ArgumentArray,
  767. DWORD ArgumentIndex,
  768. DWORD ArgumentCount,
  769. DWORD CmdFlags,
  770. PVOID Data,
  771. BOOL* CommandDone
  772. )
  773. {
  774. ULONG ArgumentsLeft;
  775. ULONG BitVector;
  776. ULONG Error;
  777. ULONG ErrorIndex = 0;
  778. ULONG i;
  779. VRRP_VROUTER_CONFIG VrouterInfo;
  780. PULONG TagArray;
  781. WCHAR InterfaceName[MAX_INTERFACE_NAME_LEN + 1];
  782. TAG_TYPE TagTypeArray[] = {
  783. { TOKEN_OPT_INTERFACE_NAME, TRUE, FALSE },
  784. { TOKEN_OPT_VRID, TRUE, FALSE },
  785. { TOKEN_OPT_AUTH, FALSE, FALSE},
  786. { TOKEN_OPT_PASSWD, FALSE, FALSE},
  787. { TOKEN_OPT_ADVTINTERVAL, FALSE, FALSE},
  788. { TOKEN_OPT_PRIO, FALSE, FALSE},
  789. { TOKEN_OPT_PREEMPT, FALSE, FALSE}
  790. };
  791. VERIFY_INSTALLED(MS_IP_VRRP, L"VRRP");
  792. if (ArgumentIndex >= ArgumentCount) {
  793. return ERROR_SHOW_USAGE;
  794. }
  795. ArgumentsLeft = ArgumentCount - ArgumentIndex;
  796. //
  797. // We convert the optional tags into an array of 'TagTypeArray' indices
  798. // which guide is in our scanning of the argument list.
  799. // Since the tags are optional, this process may result in no tags at all,
  800. // in which case we assume that arguments are specified in exactly the order
  801. // given in 'TagTypeArray' above.
  802. //
  803. Error =
  804. QueryTagArray(
  805. &ArgumentArray[ArgumentIndex],
  806. ArgumentsLeft,
  807. TagTypeArray,
  808. NUM_TAGS_IN_TABLE(TagTypeArray),
  809. &TagArray
  810. );
  811. if (Error) { return Error; }
  812. BitVector = 0;
  813. ZeroMemory(&VrouterInfo, sizeof(VrouterInfo));
  814. //
  815. // We now scan the argument list, converting the arguments
  816. // into information in our 'VrouterInfo' structure.
  817. //
  818. for (i = 0; i < ArgumentsLeft; i++) {
  819. switch(TagArray ? TagArray[i] : i) {
  820. case 0: {
  821. ULONG Length = sizeof(InterfaceName);
  822. Error =
  823. IpmontrGetIfNameFromFriendlyName(
  824. ArgumentArray[i + ArgumentIndex], InterfaceName, &Length
  825. );
  826. if (Error) {
  827. DisplayMessage(
  828. g_hModule, EMSG_NO_INTERFACE,
  829. ArgumentArray[i + ArgumentIndex]
  830. );
  831. Error = ERROR_NO_SUCH_INTERFACE;
  832. i = ArgumentsLeft;
  833. break;
  834. }
  835. TagTypeArray[TagArray ? TagArray[i] : i].bPresent = TRUE;
  836. break;
  837. }
  838. case 1:{
  839. BYTE VRIDGiven;
  840. VRIDGiven =
  841. (UCHAR)_tcstoul(ArgumentArray[i + ArgumentIndex], NULL, 10);
  842. if (VRIDGiven > 255) {
  843. DisplayMessage(
  844. g_hModule, EMSG_INVALID_VRID,
  845. VRIDGiven
  846. );
  847. Error = ERROR_INVALID_PARAMETER;
  848. i = ArgumentsLeft;
  849. break;
  850. }
  851. VrouterInfo.VRID = (BYTE) VRIDGiven;
  852. BitVector |= VRRP_INTF_VRID_MASK;
  853. TagTypeArray[TagArray ? TagArray[i] : i].bPresent = TRUE;
  854. break;
  855. }
  856. case 2:{
  857. TOKEN_VALUE TokenArray[] = {
  858. { TOKEN_OPT_VALUE_AUTH_NONE, VRRP_AUTHTYPE_NONE },
  859. { TOKEN_OPT_VALUE_AUTH_SIMPLE_PASSWORD, VRRP_AUTHTYPE_PLAIN },
  860. { TOKEN_OPT_VALUE_AUTH_MD5, VRRP_AUTHTYPE_IPHEAD }
  861. };
  862. DWORD dwAuthType;
  863. Error =
  864. MatchEnumTag(
  865. g_hModule,
  866. ArgumentArray[i + ArgumentIndex],
  867. NUM_TOKENS_IN_TABLE(TokenArray),
  868. TokenArray,
  869. &dwAuthType
  870. );
  871. VrouterInfo.AuthenticationType = (BYTE) dwAuthType;
  872. if (Error) {
  873. Error = ERROR_INVALID_PARAMETER;
  874. ErrorIndex = i;
  875. i = ArgumentsLeft;
  876. break;
  877. }
  878. BitVector |= VRRP_INTF_AUTH_MASK;
  879. TagTypeArray[TagArray ? TagArray[i] : i].bPresent = TRUE;
  880. break;
  881. }
  882. case 3:{
  883. UINT Index;
  884. UINT PassByte;
  885. PTCHAR Token;
  886. PTCHAR Password;
  887. #if 0
  888. //
  889. // Allocate more space for the tokenizing NULL
  890. //
  891. Password = Malloc((2+_tcslen(ArgumentArray[i + ArgumentIndex])) *
  892. sizeof(TCHAR));
  893. if (!Password) {
  894. Error = ERROR_NOT_ENOUGH_MEMORY;
  895. break;
  896. }
  897. _tcscpy(Password,ArgumentArray[i + ArgumentIndex]);
  898. ZeroMemory(VrouterInfo.AuthenticationData,VRRP_MAX_AUTHKEY_SIZE);
  899. Token = _tcstok(Password,L"-");
  900. for (Index = 0; Index < VRRP_MAX_AUTHKEY_SIZE; Index++) {
  901. PassByte = _tcstoul(Token, NULL, 10);
  902. if (PassByte > 255) {
  903. Error = ERROR_INVALID_PARAMETER;
  904. i = ArgumentsLeft;
  905. break;
  906. }
  907. VrouterInfo.AuthenticationData[Index] = PassByte & 0xff;
  908. Token = _tcstok(NULL,"-");
  909. if (!Token) {
  910. break;
  911. }
  912. }
  913. Free(Password);
  914. if (Error) {
  915. break;
  916. }
  917. #else
  918. Password = ArgumentArray[i + ArgumentIndex];
  919. for (Index = 0; Index < VRRP_MAX_AUTHKEY_SIZE; Index++) {
  920. PassByte = _tcstoul(Password, NULL, 10);
  921. if (PassByte > 255) {
  922. Error = ERROR_INVALID_PARAMETER;
  923. i = ArgumentsLeft;
  924. break;
  925. }
  926. VrouterInfo.AuthenticationData[Index] = PassByte & 0xff;
  927. Password = _tcschr(Password,_T('-'));
  928. if (!Password) {
  929. break;
  930. }
  931. Password ++;
  932. }
  933. #endif
  934. BitVector |= VRRP_INTF_PASSWD_MASK;
  935. TagTypeArray[TagArray ? TagArray[i] : i].bPresent = TRUE;
  936. break;
  937. }
  938. case 4:{
  939. BYTE AdvtIntvl;
  940. AdvtIntvl = (UCHAR)
  941. _tcstoul(ArgumentArray[i + ArgumentIndex], NULL, 10);
  942. if (AdvtIntvl > 255) {
  943. Error = ERROR_INVALID_PARAMETER;
  944. i = ArgumentsLeft;
  945. break;
  946. }
  947. VrouterInfo.AdvertisementInterval = (BYTE) AdvtIntvl;
  948. BitVector |= VRRP_INTF_ADVT_MASK;
  949. TagTypeArray[TagArray ? TagArray[i] : i].bPresent = TRUE;
  950. break;
  951. }
  952. case 5:{
  953. BYTE ConfigPrio;
  954. ConfigPrio = (UCHAR)
  955. _tcstoul(ArgumentArray[i + ArgumentIndex], NULL, 10);
  956. if (ConfigPrio > 255) {
  957. Error = ERROR_INVALID_PARAMETER;
  958. i = ArgumentsLeft;
  959. break;
  960. }
  961. VrouterInfo.ConfigPriority = (BYTE) ConfigPrio;
  962. BitVector |= VRRP_INTF_PRIO_MASK;
  963. TagTypeArray[TagArray ? TagArray[i] : i].bPresent = TRUE;
  964. break;
  965. }
  966. case 6:{
  967. TOKEN_VALUE TokenArray[] = {
  968. { TOKEN_OPT_VALUE_ENABLE, TRUE },
  969. { TOKEN_OPT_VALUE_DISABLE, FALSE }
  970. };
  971. Error =
  972. MatchEnumTag(
  973. g_hModule,
  974. ArgumentArray[i + ArgumentIndex],
  975. NUM_TOKENS_IN_TABLE(TokenArray),
  976. TokenArray,
  977. &VrouterInfo.PreemptMode
  978. );
  979. if (Error) {
  980. Error = ERROR_INVALID_PARAMETER;
  981. ErrorIndex = i;
  982. i = ArgumentsLeft;
  983. break;
  984. }
  985. BitVector |= VRRP_INTF_PREEMPT_MASK;
  986. TagTypeArray[TagArray ? TagArray[i] : i].bPresent = TRUE;
  987. break;
  988. }
  989. }
  990. }
  991. if (!Error) {
  992. //
  993. // Ensure that all required parameters are present.
  994. //
  995. Error =
  996. ValidateTagTypeArray(TagTypeArray, NUM_TAGS_IN_TABLE(TagTypeArray));
  997. }
  998. if (Error == ERROR_TAG_ALREADY_PRESENT) {
  999. DisplayMessage(g_hModule, EMSG_TAG_ALREADY_PRESENT);
  1000. } else if (Error == ERROR_INVALID_PARAMETER && TagArray) {
  1001. DispTokenErrMsg(
  1002. g_hModule,
  1003. EMSG_BAD_OPTION_VALUE,
  1004. TagTypeArray[TagArray[ErrorIndex]],
  1005. ArgumentArray[ErrorIndex + ArgumentIndex]
  1006. );
  1007. } else if (!Error && (BitVector)) {
  1008. //
  1009. // Update the configuration with the new settings.
  1010. // Note that the update routine may perform additional validation
  1011. // in the process of reconciling the new settings
  1012. // with any existing settings.
  1013. //
  1014. Error =
  1015. UpdateVrrpInterfaceInfo(
  1016. InterfaceName, &VrouterInfo, BitVector, FALSE
  1017. );
  1018. }
  1019. if (TagArray) { Free(TagArray); }
  1020. return Error;
  1021. }
  1022. DWORD
  1023. HandleVrrpShowGlobal(
  1024. PWCHAR MachineName,
  1025. PTCHAR* ArgumentArray,
  1026. DWORD ArgumentIndex,
  1027. DWORD ArgumentCount,
  1028. DWORD CmdFlags,
  1029. PVOID Data,
  1030. BOOL* CommandDone
  1031. )
  1032. {
  1033. if (ArgumentIndex != ArgumentCount) { return ERROR_SHOW_USAGE; }
  1034. ShowVrrpGlobalInfo(NULL);
  1035. return NO_ERROR;
  1036. }
  1037. DWORD
  1038. HandleVrrpShowInterface(
  1039. PWCHAR MachineName,
  1040. PTCHAR* ArgumentArray,
  1041. DWORD ArgumentIndex,
  1042. DWORD ArgumentCount,
  1043. DWORD CmdFlags,
  1044. PVOID Data,
  1045. BOOL* CommandDone
  1046. )
  1047. {
  1048. ULONG ArgumentsLeft;
  1049. ULONG Error;
  1050. PULONG TagArray;
  1051. WCHAR InterfaceName[MAX_INTERFACE_NAME_LEN + 1];
  1052. TAG_TYPE TagTypeArray[] = {
  1053. { TOKEN_OPT_INTERFACE_NAME, TRUE, FALSE }
  1054. };
  1055. VERIFY_INSTALLED(MS_IP_VRRP, L"VRRP");
  1056. if (ArgumentIndex >= ArgumentCount) {
  1057. return ERROR_SHOW_USAGE;
  1058. }
  1059. ArgumentsLeft = ArgumentCount - ArgumentIndex;
  1060. //
  1061. // We convert the optional tags into an array of 'TagTypeArray' indices
  1062. // which guide is in our scanning of the argument list.
  1063. // Since the tags are optional, this process may result in no tags at all,
  1064. // in which case we assume that arguments are specified in exactly the order
  1065. // given in 'TagTypeArray' above.
  1066. //
  1067. Error =
  1068. QueryTagArray(
  1069. &ArgumentArray[ArgumentIndex],
  1070. ArgumentsLeft,
  1071. TagTypeArray,
  1072. NUM_TAGS_IN_TABLE(TagTypeArray),
  1073. &TagArray
  1074. );
  1075. if (Error) { return Error; }
  1076. //
  1077. // If any tags were specified, the only one present must refer
  1078. // to the interface name which is index '0' in 'TagTypeArray'.
  1079. // If no tags were specified, we assume the argument is an interface name,
  1080. // and we retrieve its friendly name in order to delete it.
  1081. //
  1082. if (TagArray && TagArray[0] != 0) {
  1083. Free(TagArray);
  1084. return ERROR_SHOW_USAGE;
  1085. } else {
  1086. ULONG Length = sizeof(InterfaceName);
  1087. Error =
  1088. IpmontrGetIfNameFromFriendlyName(
  1089. ArgumentArray[ArgumentIndex], InterfaceName, &Length
  1090. );
  1091. }
  1092. if (!Error) {
  1093. Error = ShowVrrpInterfaceInfo(NULL, InterfaceName);
  1094. }
  1095. if (TagArray) { Free(TagArray); }
  1096. return Error;
  1097. }
  1098. DWORD
  1099. HandleVrrpUninstall(
  1100. PWCHAR MachineName,
  1101. PTCHAR* ArgumentArray,
  1102. DWORD ArgumentIndex,
  1103. DWORD ArgumentCount,
  1104. DWORD CmdFlags,
  1105. PVOID Data,
  1106. BOOL* CommandDone
  1107. )
  1108. {
  1109. ULONG Error;
  1110. if (ArgumentIndex != ArgumentCount) { return ERROR_SHOW_USAGE; }
  1111. Error = IpmontrDeleteProtocol(MS_IP_VRRP);
  1112. if (!Error) { DEBUG("Deleted VRRP"); }
  1113. Error = SetArpRetryCount(3);
  1114. return Error;
  1115. }
  1116. ULONG
  1117. QueryTagArray(
  1118. PTCHAR ArgumentArray[],
  1119. ULONG ArgumentCount,
  1120. TAG_TYPE TagTypeArray[],
  1121. ULONG TagTypeCount,
  1122. OUT PULONG* TagArray
  1123. )
  1124. {
  1125. ULONG Error;
  1126. ULONG i;
  1127. if (!_tcsstr(ArgumentArray[0], ptszDelimiter)) {
  1128. *TagArray = NULL;
  1129. return NO_ERROR;
  1130. }
  1131. *TagArray = Malloc(ArgumentCount * sizeof(ULONG));
  1132. if (!*TagArray) {
  1133. DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
  1134. return ERROR_NOT_ENOUGH_MEMORY;
  1135. }
  1136. Error =
  1137. MatchTagsInCmdLine(
  1138. g_hModule,
  1139. ArgumentArray,
  1140. 0,
  1141. ArgumentCount,
  1142. TagTypeArray,
  1143. TagTypeCount,
  1144. *TagArray
  1145. );
  1146. if (Error) {
  1147. Free(*TagArray);
  1148. *TagArray = NULL;
  1149. if (Error == ERROR_INVALID_OPTION_TAG) {
  1150. return ERROR_INVALID_SYNTAX;
  1151. }
  1152. return ERROR_INVALID_PARAMETER;
  1153. }
  1154. return NO_ERROR;
  1155. }
  1156. ULONG
  1157. ValidateTagTypeArray(
  1158. TAG_TYPE TagTypeArray[],
  1159. ULONG TagTypeCount
  1160. )
  1161. {
  1162. ULONG i;
  1163. //
  1164. // Verify that all required tokens are present.
  1165. //
  1166. for (i = 0; i < TagTypeCount; i++) {
  1167. if ((TagTypeArray[i].dwRequired & NS_REQ_PRESENT)
  1168. && !TagTypeArray[i].bPresent) {
  1169. return ERROR_INVALID_SYNTAX;
  1170. }
  1171. }
  1172. return NO_ERROR;
  1173. }