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.

900 lines
30 KiB

  1. /*++
  2. Copyright (c) 1999, Microsoft Corporation
  3. Module Name:
  4. net\routing\netsh\ip\protocols\msdpopt.c
  5. Abstract:
  6. MSDP command options implementation.
  7. This module contains handlers for the configuration commands
  8. supported by the MSDP Protocol.
  9. Author:
  10. Dave Thaler (dthaler) 21-May-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. IN PTCHAR ppwszArgumentArray[],
  24. IN ULONG ululArgumentCount,
  25. IN TAG_TYPE pttTagTypeArray[],
  26. IN ULONG ulTagTypeCount,
  27. OUT PULONG* ppulTagArray
  28. );
  29. ULONG
  30. ValidateTagTypeArray(
  31. IN TAG_TYPE pttTagTypeArray[],
  32. IN ULONG ulTagTypeCount
  33. );
  34. DWORD
  35. HandleMsdpAddPeer(
  36. PWCHAR pwszMachineName,
  37. PTCHAR* ArgumentArray,
  38. DWORD ulArgumentIndex,
  39. DWORD ulArgumentCount,
  40. DWORD dwFlags,
  41. PVOID pvData,
  42. BOOL* CommandDone
  43. )
  44. {
  45. ULONG ulArgumentsLeft;
  46. ULONG BitVector;
  47. DWORD dwErr;
  48. ULONG ulErrorIndex = 0;
  49. ULONG i;
  50. PULONG pulTagArray;
  51. ULONG InfoSize;
  52. DWORD dwBufferSize = MAX_INTERFACE_NAME_LEN + 1;
  53. WCHAR wszInterfaceName[MAX_INTERFACE_NAME_LEN + 1];
  54. TAG_TYPE TagTypeArray[] = { { TOKEN_OPT_NAME, NS_REQ_PRESENT, FALSE },
  55. { TOKEN_OPT_REMADDR, NS_REQ_PRESENT, FALSE },
  56. { TOKEN_OPT_LOCALADDR, NS_REQ_PRESENT, FALSE },
  57. { TOKEN_OPT_KEEPALIVE, NS_REQ_ZERO, FALSE },
  58. { TOKEN_OPT_CONNECTRETRY, NS_REQ_ZERO, FALSE },
  59. { TOKEN_OPT_CACHING, NS_REQ_ZERO, FALSE },
  60. { TOKEN_OPT_DEFAULTPEER, NS_REQ_ZERO, FALSE },
  61. { TOKEN_OPT_ENCAPSMETHOD, NS_REQ_ZERO, FALSE },
  62. };
  63. PMSDP_IPV4_PEER_CONFIG pPeer = NULL;
  64. VERIFY_INSTALLED(MS_IP_MSDP, L"MSDP");
  65. if (ulArgumentIndex >= ulArgumentCount) {
  66. return ERROR_SHOW_USAGE;
  67. }
  68. ulArgumentsLeft = ulArgumentCount - ulArgumentIndex;
  69. //
  70. // We convert the optional tags into an array of 'TagTypeArray' indices
  71. // which guide is in our scanning of the argument list.
  72. // Since the tags are optional, this process may result in no tags at all,
  73. // in which case we assume that arguments are specified in exactly the order
  74. // given in 'TagTypeArray' above.
  75. //
  76. dwErr = QueryTagArray( &ArgumentArray[ulArgumentIndex],
  77. ulArgumentsLeft,
  78. TagTypeArray,
  79. NUM_TAGS_IN_TABLE(TagTypeArray),
  80. &pulTagArray );
  81. if (dwErr) { return dwErr; }
  82. BitVector = 0;
  83. do {
  84. dwErr = MakeMsdpIPv4PeerConfig(&pPeer);
  85. if (dwErr isnot NO_ERROR)
  86. {
  87. break;
  88. }
  89. //
  90. // We now scan the argument list, converting the arguments
  91. // into information in our 'VrouterGiven' structure.
  92. //
  93. for (i = 0; i < ulArgumentsLeft; i++) {
  94. switch(pulTagArray ? pulTagArray[i] : i) {
  95. case 0: { // name
  96. wcscpy(wszInterfaceName, ArgumentArray[i+ulArgumentIndex]);
  97. break;
  98. }
  99. case 1: { // remaddr
  100. pPeer->ipRemoteAddress = GetIpAddress(
  101. ArgumentArray[i + ulArgumentIndex]);
  102. break;
  103. }
  104. case 2: { // localaddr
  105. pPeer->ipLocalAddress = GetIpAddress(
  106. ArgumentArray[i + ulArgumentIndex]);
  107. break;
  108. }
  109. case 3: { // keepalive
  110. if (!MatchToken(ArgumentArray[i+ulArgumentIndex],
  111. TOKEN_OPT_VALUE_DEFAULT))
  112. {
  113. pPeer->ulKeepAlive = _tcstoul(
  114. ArgumentArray[i + ulArgumentIndex],
  115. NULL, 10);
  116. pPeer->dwConfigFlags |= MSDP_PEER_CONFIG_KEEPALIVE;
  117. }
  118. break;
  119. }
  120. case 4: { // connectretry
  121. if (!MatchToken(ArgumentArray[i+ulArgumentIndex],
  122. TOKEN_OPT_VALUE_DEFAULT))
  123. {
  124. pPeer->ulConnectRetry = _tcstoul(
  125. ArgumentArray[i + ulArgumentIndex],
  126. NULL, 10);
  127. pPeer->dwConfigFlags |= MSDP_PEER_CONFIG_CONNECTRETRY;
  128. }
  129. break;
  130. }
  131. case 5: { // caching
  132. DWORD dwValue;
  133. TOKEN_VALUE TokenArray[] = {
  134. { TOKEN_OPT_VALUE_NO, FALSE },
  135. { TOKEN_OPT_VALUE_YES, TRUE }
  136. };
  137. pPeer->dwConfigFlags &= ~MSDP_PEER_CONFIG_CACHING;
  138. dwErr = MatchEnumTag( g_hModule,
  139. ArgumentArray[i + ulArgumentIndex],
  140. NUM_TOKENS_IN_TABLE(TokenArray),
  141. TokenArray,
  142. &dwValue );
  143. if (dwErr isnot NO_ERROR)
  144. {
  145. dwErr = ERROR_INVALID_PARAMETER;
  146. break;
  147. }
  148. if (dwValue is TRUE)
  149. {
  150. pPeer->dwConfigFlags |= MSDP_PEER_CONFIG_CACHING;
  151. }
  152. break;
  153. }
  154. case 6: { // defaultpeer
  155. DWORD dwValue;
  156. TOKEN_VALUE TokenArray[] = {
  157. { TOKEN_OPT_VALUE_NO, FALSE },
  158. { TOKEN_OPT_VALUE_YES, TRUE }
  159. };
  160. pPeer->dwConfigFlags &= ~MSDP_PEER_CONFIG_DEFAULTPEER;
  161. dwErr = MatchEnumTag( g_hModule,
  162. ArgumentArray[i + ulArgumentIndex],
  163. NUM_TOKENS_IN_TABLE(TokenArray),
  164. TokenArray,
  165. &dwValue );
  166. if (dwErr isnot NO_ERROR)
  167. {
  168. dwErr = ERROR_INVALID_PARAMETER;
  169. break;
  170. }
  171. if (dwValue is TRUE)
  172. {
  173. pPeer->dwConfigFlags |= MSDP_PEER_CONFIG_DEFAULTPEER;
  174. }
  175. break;
  176. }
  177. case 7: { // encapsulation
  178. DWORD dwValue;
  179. dwErr = MatchEnumTag( g_hModule,
  180. ArgumentArray[i + ulArgumentIndex],
  181. MSDP_ENCAPS_SIZE,
  182. (PTOKEN_VALUE)MsdpEncapsTokenArray,
  183. &dwValue );
  184. if (dwErr isnot NO_ERROR)
  185. {
  186. dwErr = ERROR_INVALID_PARAMETER;
  187. break;
  188. }
  189. pPeer->dwEncapsMethod = dwValue;
  190. break;
  191. }
  192. }
  193. }
  194. if (dwErr isnot NO_ERROR)
  195. {
  196. break;
  197. }
  198. // higher IP is passive. Setting this bit has no effect
  199. // except on the "show peer" report when the router isn't running.
  200. if (ntohl(pPeer->ipLocalAddress) > ntohl(pPeer->ipRemoteAddress))
  201. {
  202. pPeer->dwConfigFlags |= MSDP_PEER_CONFIG_PASSIVE;
  203. }
  204. //
  205. // Update the configuration with the new settings.
  206. // Note that the update routine may perform additional validation
  207. // in the process of reconciling the new settings
  208. // with any existing settings.
  209. //
  210. dwErr = MsdpAddIPv4PeerInterface(pwszMachineName,
  211. wszInterfaceName, pPeer );
  212. } while (FALSE);
  213. if (pPeer)
  214. {
  215. FREE(pPeer);
  216. }
  217. if (pulTagArray)
  218. {
  219. FREE(pulTagArray);
  220. }
  221. if (dwErr is NO_ERROR)
  222. {
  223. dwErr = ERROR_OKAY;
  224. }
  225. return dwErr;
  226. }
  227. DWORD
  228. HandleMsdpDeletePeer(
  229. PWCHAR pwszMachineName,
  230. PTCHAR* ArgumentArray,
  231. DWORD ulArgumentIndex,
  232. DWORD ulArgumentCount,
  233. DWORD dwFlags,
  234. PVOID pvData,
  235. BOOL* CommandDone
  236. )
  237. {
  238. ULONG ulArgumentsLeft;
  239. ULONG BitVector;
  240. DWORD dwErr;
  241. ULONG ulErrorIndex = 0;
  242. ULONG i;
  243. PULONG pulTagArray;
  244. ULONG InfoSize;
  245. WCHAR wszInterfaceName[MAX_INTERFACE_NAME_LEN + 1];
  246. DWORD dwBufferSize = sizeof(wszInterfaceName);
  247. TAG_TYPE TagTypeArray[] = { { TOKEN_OPT_NAME, NS_REQ_PRESENT, FALSE }
  248. };
  249. VERIFY_INSTALLED(MS_IP_MSDP, L"MSDP");
  250. if (ulArgumentIndex >= ulArgumentCount) {
  251. return ERROR_SHOW_USAGE;
  252. }
  253. ulArgumentsLeft = ulArgumentCount - ulArgumentIndex;
  254. //
  255. // We convert the optional tags into an array of 'TagTypeArray' indices
  256. // which guide is in our scanning of the argument list.
  257. // Since the tags are optional, this process may result in no tags at all,
  258. // in which case we assume that arguments are specified in exactly the order
  259. // given in 'TagTypeArray' above.
  260. //
  261. dwErr = QueryTagArray( &ArgumentArray[ulArgumentIndex],
  262. ulArgumentsLeft,
  263. TagTypeArray,
  264. NUM_TAGS_IN_TABLE(TagTypeArray),
  265. &pulTagArray );
  266. if (dwErr) { return dwErr; }
  267. BitVector = 0;
  268. for (i = 0; i < ulArgumentsLeft; i++) {
  269. switch(pulTagArray ? pulTagArray[i] : i) {
  270. case 0: { // name
  271. IpmontrGetIfNameFromFriendlyName(
  272. ArgumentArray[i + ulArgumentIndex],
  273. wszInterfaceName,
  274. &dwBufferSize);
  275. break;
  276. }
  277. }
  278. }
  279. dwErr = IpmontrDeleteInterface( pwszMachineName, wszInterfaceName );
  280. if (dwErr is NO_ERROR)
  281. {
  282. dwErr = ERROR_OKAY;
  283. }
  284. return dwErr;
  285. }
  286. DWORD
  287. HandleMsdpInstall(
  288. PWCHAR pwszMachineName,
  289. PTCHAR* ArgumentArray,
  290. DWORD ulArgumentIndex,
  291. DWORD ulArgumentCount,
  292. DWORD dwFlags,
  293. PVOID pvData,
  294. BOOL* CommandDone
  295. )
  296. {
  297. DWORD dwErr = ERROR_OKAY;
  298. PUCHAR pGlobalInfo;
  299. ULONG ulLength;
  300. if (ulArgumentIndex != ulArgumentCount) {
  301. return ERROR_SHOW_USAGE;
  302. }
  303. //
  304. // To install MSDP, we construct the default configuration
  305. // and add it to the global configuration for the router.
  306. //
  307. dwErr = MakeMsdpGlobalConfig(&pGlobalInfo, &ulLength);
  308. if (dwErr isnot NO_ERROR) {
  309. DisplayError(g_hModule, dwErr);
  310. } else {
  311. dwErr = IpmontrSetInfoBlockInGlobalInfo( MS_IP_MSDP,
  312. pGlobalInfo,
  313. ulLength,
  314. 1 );
  315. FREE(pGlobalInfo);
  316. if (dwErr is NO_ERROR) {
  317. dwErr = ERROR_OKAY;
  318. } else {
  319. DisplayError(g_hModule, dwErr);
  320. }
  321. }
  322. return dwErr;
  323. }
  324. DWORD
  325. HandleMsdpSetGlobal(
  326. PWCHAR pwszMachineName,
  327. PTCHAR* ArgumentArray,
  328. ULONG ulArgumentIndex,
  329. ULONG ulArgumentCount,
  330. DWORD dwFlags,
  331. PVOID pvData,
  332. BOOL* CommandDone
  333. )
  334. {
  335. ULONG ulArgumentsLeft;
  336. DWORD dwErr;
  337. PULONG pulTagArray = NULL;
  338. DWORD dwLoggingLevel, dwAcceptAll;
  339. ULONG i, ulTemp;
  340. ULONG ulErrorIndex;
  341. PMSDP_GLOBAL_CONFIG pGlobalInfo = NULL;
  342. TAG_TYPE TagTypeArray[] = { { TOKEN_OPT_LOGGINGLEVEL, FALSE, FALSE },
  343. { TOKEN_OPT_KEEPALIVE, FALSE, FALSE },
  344. { TOKEN_OPT_SAHOLDDOWN, FALSE, FALSE },
  345. { TOKEN_OPT_CONNECTRETRY, FALSE, FALSE },
  346. { TOKEN_OPT_ACCEPTALL, FALSE, FALSE },
  347. { TOKEN_OPT_CACHELIFETIME,FALSE, FALSE },
  348. };
  349. VERIFY_INSTALLED(MS_IP_MSDP, L"MSDP");
  350. if (ulArgumentIndex >= ulArgumentCount) {
  351. return ERROR_SHOW_USAGE;
  352. }
  353. ulArgumentsLeft = ulArgumentCount - ulArgumentIndex;
  354. //
  355. // We convert the optional tags into an array of 'TagTypeArray' indices
  356. // which guide us in our scanning of the argument list.
  357. // Since the tags are optional, this process may result in no tags at all,
  358. // in which case we assume that arguments are specified in exactly the order
  359. // given in 'TagTypeArray' above.
  360. //
  361. dwErr = QueryTagArray( &ArgumentArray[ulArgumentIndex],
  362. ulArgumentsLeft,
  363. TagTypeArray,
  364. NUM_TAGS_IN_TABLE(TagTypeArray),
  365. &pulTagArray );
  366. if (dwErr) { return dwErr; }
  367. do {
  368. dwErr = GetMsdpGlobalConfig( &pGlobalInfo );
  369. if (dwErr isnot NO_ERROR)
  370. {
  371. break;
  372. }
  373. for (i = 0; i < ulArgumentsLeft; i++) {
  374. switch(pulTagArray ? pulTagArray[i] : i) {
  375. case 0: { // loglevel
  376. TOKEN_VALUE TokenArray[] = {
  377. { TOKEN_OPT_VALUE_NONE, MSDP_LOGGING_NONE },
  378. { TOKEN_OPT_VALUE_ERROR, MSDP_LOGGING_ERROR },
  379. { TOKEN_OPT_VALUE_WARN, MSDP_LOGGING_WARN },
  380. { TOKEN_OPT_VALUE_INFO, MSDP_LOGGING_INFO }
  381. };
  382. dwErr = MatchEnumTag( g_hModule,
  383. ArgumentArray[i + ulArgumentIndex],
  384. NUM_TOKENS_IN_TABLE(TokenArray),
  385. TokenArray,
  386. &pGlobalInfo->dwLoggingLevel );
  387. if (dwErr) {
  388. dwErr = ERROR_INVALID_PARAMETER;
  389. ulErrorIndex = i;
  390. i = ulArgumentsLeft;
  391. break;
  392. }
  393. TagTypeArray[pulTagArray ? pulTagArray[i] : i].bPresent = TRUE;
  394. break;
  395. }
  396. case 1: { // keepalive
  397. pGlobalInfo->ulDefKeepAlive = _tcstoul(
  398. ArgumentArray[i + ulArgumentIndex],
  399. NULL, 10);
  400. break;
  401. }
  402. case 2: { // SA holddown
  403. pGlobalInfo->ulSAHolddown = _tcstoul(
  404. ArgumentArray[i + ulArgumentIndex],
  405. NULL, 10);
  406. break;
  407. }
  408. case 3: { // connectretry
  409. pGlobalInfo->ulDefConnectRetry = _tcstoul(
  410. ArgumentArray[i + ulArgumentIndex],
  411. NULL, 10);
  412. break;
  413. }
  414. case 4: { // acceptall
  415. TOKEN_VALUE TokenArray[] = {
  416. { TOKEN_OPT_VALUE_DISABLE, FALSE },
  417. { TOKEN_OPT_VALUE_ENABLE, TRUE }
  418. };
  419. pGlobalInfo->dwFlags &= ~MSDP_GLOBAL_FLAG_ACCEPT_ALL;
  420. dwErr = MatchEnumTag( g_hModule,
  421. ArgumentArray[i + ulArgumentIndex],
  422. NUM_TOKENS_IN_TABLE(TokenArray),
  423. TokenArray,
  424. &dwAcceptAll );
  425. if (dwErr isnot NO_ERROR)
  426. {
  427. dwErr = ERROR_INVALID_PARAMETER;
  428. break;
  429. }
  430. if (dwAcceptAll is TRUE)
  431. {
  432. pGlobalInfo->dwFlags |= MSDP_GLOBAL_FLAG_ACCEPT_ALL;
  433. }
  434. break;
  435. }
  436. case 5: { // cachelifetime
  437. ulTemp = _tcstoul( ArgumentArray[i + ulArgumentIndex],
  438. NULL, 10);
  439. if ((ulTemp>0) and (ulTemp<MSDP_MIN_CACHE_LIFETIME))
  440. {
  441. DisplayMessage(g_hModule, EMSG_BAD_OPTION_VALUE,
  442. ArgumentArray[i + ulArgumentIndex],
  443. TOKEN_OPT_CACHELIFETIME);
  444. dwErr = ERROR_SUPPRESS_OUTPUT;
  445. break;
  446. }
  447. pGlobalInfo->ulCacheLifetime = ulTemp;
  448. break;
  449. }
  450. }
  451. }
  452. if (dwErr isnot NO_ERROR)
  453. {
  454. break;
  455. }
  456. dwErr = SetMsdpGlobalConfig(pGlobalInfo);
  457. } while (FALSE);
  458. if (pulTagArray)
  459. {
  460. FREE(pulTagArray);
  461. }
  462. if (pGlobalInfo)
  463. {
  464. FREE(pGlobalInfo);
  465. }
  466. if (dwErr is NO_ERROR)
  467. {
  468. dwErr = ERROR_OKAY;
  469. }
  470. return dwErr;
  471. }
  472. DWORD
  473. HandleMsdpSetPeer(
  474. PWCHAR pwszMachineName,
  475. PTCHAR* ArgumentArray,
  476. DWORD ulArgumentIndex,
  477. DWORD ulArgumentCount,
  478. DWORD dwCmdFlags,
  479. PVOID pvData,
  480. BOOL* CommandDone
  481. )
  482. {
  483. IPV4_ADDRESS ipLocalAddress, ipRemoteAddress;
  484. ULONG ulKeepAlive=0, ulSAPeriod=0, ulConnectRetry=0;
  485. DWORD dwEncapsMethod=0;
  486. DWORD dwErr = NO_ERROR;
  487. DWORD dwFlags = 0, dwFlagsMask = 0;
  488. ULONG ulArgumentsLeft;
  489. ULONG i;
  490. PMSDP_IPV4_PEER_CONFIG pPeer = NULL;
  491. PULONG pulTagArray;
  492. WCHAR wszInterfaceName[MAX_INTERFACE_NAME_LEN + 1];
  493. DWORD dwBufferSize = sizeof(wszInterfaceName);
  494. TAG_TYPE TagTypeArray[] = { { TOKEN_OPT_NAME, NS_REQ_PRESENT, FALSE },
  495. { TOKEN_OPT_REMADDR, NS_REQ_ZERO, FALSE },
  496. { TOKEN_OPT_LOCALADDR, NS_REQ_ZERO, FALSE },
  497. { TOKEN_OPT_KEEPALIVE, NS_REQ_ZERO, FALSE },
  498. { TOKEN_OPT_CONNECTRETRY, NS_REQ_ZERO, FALSE },
  499. { TOKEN_OPT_CACHING, NS_REQ_ZERO, FALSE },
  500. { TOKEN_OPT_DEFAULTPEER, NS_REQ_ZERO, FALSE },
  501. { TOKEN_OPT_ENCAPSMETHOD, NS_REQ_ZERO, FALSE },
  502. };
  503. VERIFY_INSTALLED(MS_IP_MSDP, L"MSDP");
  504. if (ulArgumentIndex >= ulArgumentCount) {
  505. return ERROR_SHOW_USAGE;
  506. }
  507. ulArgumentsLeft = ulArgumentCount - ulArgumentIndex;
  508. //
  509. // We convert the optional tags into an array of 'TagTypeArray' indices
  510. // which guide is in our scanning of the argument list.
  511. // Since the tags are optional, this process may result in no tags at all,
  512. // in which case we assume that arguments are specified in exactly the order
  513. // given in 'TagTypeArray' above.
  514. //
  515. dwErr = QueryTagArray( &ArgumentArray[ulArgumentIndex],
  516. ulArgumentsLeft,
  517. TagTypeArray,
  518. NUM_TAGS_IN_TABLE(TagTypeArray),
  519. &pulTagArray );
  520. if (dwErr) { return dwErr; }
  521. do {
  522. for (i = 0; i < ulArgumentsLeft; i++) {
  523. switch(pulTagArray ? pulTagArray[i] : i) {
  524. case 0: { // name
  525. IpmontrGetIfNameFromFriendlyName(
  526. ArgumentArray[i + ulArgumentIndex],
  527. wszInterfaceName,
  528. &dwBufferSize);
  529. break;
  530. }
  531. case 1: { // remaddr
  532. ipRemoteAddress = GetIpAddress(
  533. ArgumentArray[i + ulArgumentIndex]);
  534. break;
  535. }
  536. case 2: { // localaddr
  537. ipLocalAddress = GetIpAddress(
  538. ArgumentArray[i + ulArgumentIndex]);
  539. break;
  540. }
  541. case 3: { // keepalive
  542. dwFlagsMask |= MSDP_PEER_CONFIG_KEEPALIVE;
  543. if (!MatchToken(ArgumentArray[i+ulArgumentIndex],
  544. TOKEN_OPT_VALUE_DEFAULT))
  545. {
  546. ulKeepAlive = _tcstoul(
  547. ArgumentArray[i + ulArgumentIndex],
  548. NULL, 10);
  549. dwFlags |= MSDP_PEER_CONFIG_KEEPALIVE;
  550. }
  551. break;
  552. }
  553. case 4: { // connectretry
  554. dwFlagsMask |= MSDP_PEER_CONFIG_CONNECTRETRY;
  555. if (!MatchToken(ArgumentArray[i+ulArgumentIndex],
  556. TOKEN_OPT_VALUE_DEFAULT))
  557. {
  558. ulConnectRetry = _tcstoul(
  559. ArgumentArray[i + ulArgumentIndex],
  560. NULL, 10);
  561. dwFlags |= MSDP_PEER_CONFIG_CONNECTRETRY;
  562. }
  563. break;
  564. }
  565. case 5: { // caching
  566. DWORD dwValue;
  567. TOKEN_VALUE TokenArray[] = {
  568. { TOKEN_OPT_VALUE_NO, FALSE },
  569. { TOKEN_OPT_VALUE_YES, TRUE }
  570. };
  571. dwFlagsMask |= MSDP_PEER_CONFIG_CONNECTRETRY;
  572. dwErr = MatchEnumTag( g_hModule,
  573. ArgumentArray[i + ulArgumentIndex],
  574. NUM_TOKENS_IN_TABLE(TokenArray),
  575. TokenArray,
  576. &dwValue );
  577. if (dwErr isnot NO_ERROR)
  578. {
  579. dwErr = ERROR_INVALID_PARAMETER;
  580. break;
  581. }
  582. if (dwValue is TRUE)
  583. {
  584. dwFlags |= MSDP_PEER_CONFIG_CACHING;
  585. }
  586. break;
  587. }
  588. case 6: { // defaultpeer
  589. DWORD dwValue;
  590. TOKEN_VALUE TokenArray[] = {
  591. { TOKEN_OPT_VALUE_NO, FALSE },
  592. { TOKEN_OPT_VALUE_YES, TRUE }
  593. };
  594. dwFlagsMask |= MSDP_PEER_CONFIG_DEFAULTPEER;
  595. dwErr = MatchEnumTag( g_hModule,
  596. ArgumentArray[i + ulArgumentIndex],
  597. NUM_TOKENS_IN_TABLE(TokenArray),
  598. TokenArray,
  599. &dwValue );
  600. if (dwErr isnot NO_ERROR)
  601. {
  602. dwErr = ERROR_INVALID_PARAMETER;
  603. break;
  604. }
  605. if (dwValue is TRUE)
  606. {
  607. dwFlags |= MSDP_PEER_CONFIG_DEFAULTPEER;
  608. }
  609. break;
  610. }
  611. case 7: { // encapsulation
  612. DWORD dwValue;
  613. TOKEN_VALUE TokenArray[] = {
  614. { TOKEN_OPT_VALUE_NONE, MSDP_ENCAPS_NONE },
  615. };
  616. dwErr = MatchEnumTag( g_hModule,
  617. ArgumentArray[i + ulArgumentIndex],
  618. NUM_TOKENS_IN_TABLE(TokenArray),
  619. TokenArray,
  620. &dwValue );
  621. if (dwErr isnot NO_ERROR)
  622. {
  623. dwErr = ERROR_INVALID_PARAMETER;
  624. break;
  625. }
  626. dwEncapsMethod = dwValue;
  627. break;
  628. }
  629. }
  630. }
  631. if (dwErr isnot NO_ERROR)
  632. {
  633. break;
  634. }
  635. // Locate peer
  636. dwErr = GetMsdpInterfaceConfig(wszInterfaceName, &pPeer);
  637. if (dwErr isnot NO_ERROR)
  638. {
  639. break;
  640. }
  641. // Update fields
  642. if (TagTypeArray[1].bPresent)
  643. {
  644. pPeer->ipRemoteAddress = ipRemoteAddress;
  645. }
  646. if (TagTypeArray[2].bPresent)
  647. {
  648. pPeer->ipLocalAddress = ipLocalAddress;
  649. }
  650. if (TagTypeArray[3].bPresent)
  651. {
  652. pPeer->ulKeepAlive = ulKeepAlive;
  653. }
  654. if (TagTypeArray[4].bPresent)
  655. {
  656. pPeer->ulConnectRetry = ulConnectRetry;
  657. }
  658. if (TagTypeArray[5].bPresent)
  659. {
  660. pPeer->dwEncapsMethod = dwEncapsMethod;
  661. }
  662. pPeer->dwConfigFlags = (pPeer->dwConfigFlags & ~dwFlagsMask) | dwFlags;
  663. // higher IP is passive. Setting bit has no effect except on
  664. // the "show peer" output when the router isn't running.
  665. if (ntohl(pPeer->ipLocalAddress) > ntohl(pPeer->ipRemoteAddress))
  666. {
  667. pPeer->dwConfigFlags |= MSDP_PEER_CONFIG_PASSIVE;
  668. }
  669. else
  670. {
  671. pPeer->dwConfigFlags &= ~MSDP_PEER_CONFIG_PASSIVE;
  672. }
  673. // Update the configuration with the new settings.
  674. dwErr = SetMsdpInterfaceConfig(wszInterfaceName, pPeer);
  675. } while (FALSE);
  676. if (pPeer)
  677. {
  678. FREE(pPeer);
  679. }
  680. if (pulTagArray)
  681. {
  682. FREE(pulTagArray);
  683. }
  684. if (dwErr is NO_ERROR)
  685. {
  686. dwErr = ERROR_OKAY;
  687. }
  688. return dwErr;
  689. }
  690. DWORD
  691. HandleMsdpShowGlobal(
  692. PWCHAR pwszMachineName,
  693. PTCHAR* ArgumentArray,
  694. DWORD ulArgumentIndex,
  695. DWORD ulArgumentCount,
  696. DWORD dwFlags,
  697. PVOID pvData,
  698. BOOL* CommandDone
  699. )
  700. {
  701. VERIFY_INSTALLED(MS_IP_MSDP, L"MSDP");
  702. if (ulArgumentIndex != ulArgumentCount) {
  703. return ERROR_SHOW_USAGE;
  704. }
  705. ShowMsdpGlobalInfo(FORMAT_VERBOSE);
  706. return NO_ERROR;
  707. }
  708. DWORD
  709. HandleMsdpShowPeer(
  710. PWCHAR pwszMachineName,
  711. PTCHAR* ArgumentArray,
  712. DWORD ulArgumentIndex,
  713. DWORD ulArgumentCount,
  714. DWORD dwFlags,
  715. PVOID pvData,
  716. BOOL* CommandDone
  717. )
  718. {
  719. ULONG ulArgumentsLeft;
  720. DWORD dwErr = NO_ERROR;
  721. PULONG pulTagArray = NULL;
  722. TAG_TYPE TagTypeArray[] = { { TOKEN_OPT_REMADDR, NS_REQ_ZERO, FALSE },
  723. { TOKEN_OPT_NAME, NS_REQ_ZERO, FALSE },
  724. };
  725. VERIFY_INSTALLED(MS_IP_MSDP, L"MSDP");
  726. if (ulArgumentIndex is ulArgumentCount)
  727. {
  728. return ShowMsdpPeerInfo(FORMAT_TABLE, NULL, NULL);
  729. }
  730. if (ulArgumentIndex > ulArgumentCount) {
  731. return ERROR_SHOW_USAGE;
  732. }
  733. ulArgumentsLeft = ulArgumentCount - ulArgumentIndex;
  734. //
  735. // We convert the optional tags into an array of 'TagTypeArray' indices
  736. // which guide is in our scanning of the argument list.
  737. // Since the tags are optional, this process may result in no tags
  738. // at all, in which case we assume that arguments are specified in
  739. // exactly the order given in 'TagTypeArray' above.
  740. //
  741. dwErr = QueryTagArray( &ArgumentArray[ulArgumentIndex],
  742. ulArgumentsLeft,
  743. TagTypeArray,
  744. NUM_TAGS_IN_TABLE(TagTypeArray),
  745. &pulTagArray );
  746. if (dwErr) { return dwErr; }
  747. if (!pulTagArray) {
  748. dwErr = ShowMsdpPeerInfo(FORMAT_VERBOSE,NULL,NULL);
  749. } else if (pulTagArray[0] is 0) { // address
  750. dwErr = ShowMsdpPeerInfo(FORMAT_VERBOSE,
  751. ArgumentArray[ulArgumentIndex],
  752. NULL);
  753. } else if (pulTagArray[0] is 1) { // name
  754. dwErr = ShowMsdpPeerInfo(FORMAT_VERBOSE,
  755. NULL,
  756. ArgumentArray[ulArgumentIndex]);
  757. } else {
  758. dwErr = ERROR_SHOW_USAGE;
  759. }
  760. if (pulTagArray) { FREE(pulTagArray); }
  761. return dwErr;
  762. }
  763. DWORD
  764. HandleMsdpUninstall(
  765. PWCHAR pwszMachineName,
  766. PTCHAR* ArgumentArray,
  767. DWORD ulArgumentIndex,
  768. DWORD ulArgumentCount,
  769. DWORD dwFlags,
  770. PVOID pvData,
  771. BOOL* CommandDone
  772. )
  773. {
  774. DWORD dwErr, dwTotal;
  775. ULONG ulNumInterfaces, i;
  776. PMPR_INTERFACE_0 pmi0 = NULL;
  777. if (ulArgumentIndex isnot ulArgumentCount)
  778. {
  779. return ERROR_SHOW_USAGE;
  780. }
  781. // First delete all peers. We need to do this ourselves since
  782. // IpmontrDeleteProtocol won't delete the peer interfaces.
  783. dwErr = IpmontrInterfaceEnum((PBYTE *) &pmi0,
  784. &ulNumInterfaces,
  785. &dwTotal);
  786. if (dwErr isnot NO_ERROR)
  787. {
  788. return dwErr;
  789. }
  790. for (i=0; i<ulNumInterfaces; i++)
  791. {
  792. dwErr = IpmontrDeleteInterface( pwszMachineName,
  793. pmi0[i].wszInterfaceName );
  794. }
  795. if (pmi0)
  796. {
  797. FREE(pmi0);
  798. }
  799. dwErr = IpmontrDeleteProtocol(MS_IP_MSDP);
  800. if (dwErr is NO_ERROR)
  801. {
  802. dwErr = ERROR_OKAY;
  803. }
  804. return dwErr;
  805. }