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.

2514 lines
62 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. #ifdef SN_UNICODE
  4. # define sn_strlen wcslen
  5. # define sn_strcpy wcscpy
  6. # define sn_sprintf wsprintf
  7. # define sn_strcmp wcscmp
  8. # define SN_EMPTYSTRING L""
  9. # define SN_L L
  10. #else
  11. # define sn_strlen strlen
  12. # define sn_strcpy strcpy
  13. # define sn_sprintf sprintf
  14. # define sn_strcmp strcmp
  15. # define SN_EMPTYSTRING ""
  16. # define SN_L
  17. #endif
  18. IPV4_ADDRESS g_ipGrpAddr,
  19. g_ipGrpMask;
  20. SCOPE_NAME g_snScopeName;
  21. enum RouterOps
  22. {
  23. ADD_BOUNDARY = 1,
  24. DELETE_BOUNDARY,
  25. ADD_SCOPE,
  26. DELETE_SCOPE,
  27. SET_SCOPE
  28. };
  29. typedef struct _SCOPE_ENTRY {
  30. IPV4_ADDRESS ipGroupAddress;
  31. IPV4_ADDRESS ipGroupMask;
  32. ULONG ulNumNames;
  33. BOOL bDivisible;
  34. LANGID idLanguage;
  35. SCOPE_NAME_BUFFER snScopeNameBuffer;
  36. DWORD dwNumInterfaces;
  37. } SCOPE_ENTRY, *PSCOPE_ENTRY;
  38. #define MIN_SCOPE_ADDR 0xef000000
  39. #define MAX_SCOPE_ADDR (0xefff0000 - 1)
  40. DWORD
  41. UpdateBoundaryBlock(
  42. IN DWORD dwAction,
  43. IN PBYTE pib,
  44. OUT PBYTE *ppibNew,
  45. IN OUT DWORD *pdwBlkSize,
  46. IN OUT DWORD *pdwCount,
  47. OUT BOOL *bChanged
  48. );
  49. PSCOPE_ENTRY
  50. FindScopeByPrefix(
  51. IN IPV4_ADDRESS ipGroupAddress,
  52. IN IPV4_ADDRESS ipGroupMask,
  53. IN PSCOPE_ENTRY pScopes,
  54. IN ULONG ulNumScopes
  55. )
  56. {
  57. DWORD dwInd;
  58. for (dwInd = 0; dwInd < ulNumScopes; dwInd++)
  59. {
  60. if ( pScopes[dwInd].ipGroupAddress == ipGroupAddress
  61. && pScopes[dwInd].ipGroupMask == ipGroupMask )
  62. {
  63. return &pScopes[dwInd];
  64. }
  65. }
  66. return NULL;
  67. }
  68. DWORD
  69. FindScopeByName(
  70. IN SCOPE_NAME snScopeName,
  71. IN PSCOPE_ENTRY pScopes,
  72. IN ULONG ulNumScopes,
  73. OUT PSCOPE_ENTRY *ppScope
  74. )
  75. {
  76. DWORD dwErr = NO_ERROR;
  77. ULONG i, j, dwCnt = 0;
  78. for (i = 0; i < ulNumScopes; i++)
  79. {
  80. if ( !sn_strcmp(snScopeName, pScopes[i].snScopeNameBuffer))
  81. {
  82. *ppScope = &pScopes[i];
  83. dwCnt++;
  84. }
  85. }
  86. switch (dwCnt)
  87. {
  88. case 0:
  89. *ppScope = NULL;
  90. return ERROR_NOT_FOUND;
  91. case 1:
  92. return NO_ERROR;
  93. default:
  94. return ERROR_MORE_DATA;
  95. }
  96. }
  97. DWORD
  98. MakeInfoFromScopes2(
  99. OUT PBYTE pBuffer,
  100. IN OUT ULONG *pulBufferLen,
  101. IN PSCOPE_ENTRY pScopes,
  102. IN ULONG ulNumScopes
  103. )
  104. /*++
  105. Description:
  106. Compose registry block from array of scopes.
  107. --*/
  108. {
  109. DWORD dwLen, i, dwSize, dwNumNames, j, dwLanguage, dwFlags;
  110. PLIST_ENTRY pleNode;
  111. if (ulNumScopes is 0) {
  112. *pulBufferLen = 0;
  113. return NO_ERROR;
  114. }
  115. // Compute size needed
  116. dwSize = sizeof(DWORD);
  117. for (i=0; i< ulNumScopes; i++)
  118. {
  119. dwSize += 2 * sizeof(IPV4_ADDRESS) + 2 * sizeof(DWORD);
  120. // Currently we only store at most one name.
  121. for (j=0; j<pScopes[i].ulNumNames; j++)
  122. {
  123. dwSize += (DWORD)(2*sizeof(DWORD)
  124. + sn_strlen(pScopes[i].snScopeNameBuffer) * sizeof(SN_CHAR));
  125. }
  126. }
  127. if (dwSize > *pulBufferLen)
  128. {
  129. *pulBufferLen = dwSize;
  130. return ERROR_INSUFFICIENT_BUFFER;
  131. }
  132. //
  133. // Save scope count in first DWORD
  134. //
  135. *((PDWORD) pBuffer) = ulNumScopes;
  136. pBuffer += sizeof(DWORD);
  137. //
  138. // Now step through and add each scope to the buffer
  139. //
  140. for (i=0; i< ulNumScopes; i++)
  141. {
  142. // Copy scope address, and mask
  143. dwLen = 2 * sizeof(IPV4_ADDRESS);
  144. CopyMemory(pBuffer, &pScopes[i], dwLen);
  145. pBuffer += dwLen;
  146. // Copy flags
  147. dwFlags = pScopes[i].bDivisible;
  148. CopyMemory(pBuffer, &dwFlags, sizeof(dwFlags));
  149. pBuffer += sizeof(dwFlags);
  150. // Copy # of names
  151. CopyMemory(pBuffer, &pScopes[i].ulNumNames, sizeof(DWORD));
  152. pBuffer += sizeof(DWORD);
  153. // Currently we only save at most one name
  154. for (j=0; j<pScopes[i].ulNumNames; j++)
  155. {
  156. // Save language
  157. dwLanguage = pScopes[i].idLanguage;
  158. CopyMemory(pBuffer, &dwLanguage, sizeof(dwLanguage));
  159. pBuffer += sizeof(dwLanguage);
  160. // Copy scope name (save length in words)
  161. dwLen = sn_strlen(pScopes[i].snScopeNameBuffer);
  162. CopyMemory(pBuffer, &dwLen, sizeof(DWORD));
  163. pBuffer += sizeof(DWORD);
  164. dwLen *= sizeof(SN_CHAR);
  165. if (dwLen)
  166. {
  167. CopyMemory(pBuffer, pScopes[i].snScopeNameBuffer, dwLen);
  168. pBuffer += dwLen;
  169. }
  170. }
  171. }
  172. return NO_ERROR;
  173. }
  174. DWORD
  175. MakeInfoFromScopes(
  176. OUT PBYTE *ppibNew,
  177. OUT DWORD *pdwSize,
  178. IN PSCOPE_ENTRY pScopes,
  179. IN ULONG ulNumScopes
  180. )
  181. /*++
  182. Description:
  183. Caller is responsible for freeing buffer returned.
  184. --*/
  185. {
  186. *pdwSize = 0;
  187. *ppibNew = NULL;
  188. if (MakeInfoFromScopes2(NULL, pdwSize, pScopes, ulNumScopes)
  189. is ERROR_INSUFFICIENT_BUFFER)
  190. {
  191. *ppibNew = MALLOC( *pdwSize );
  192. if ( *ppibNew == NULL )
  193. {
  194. DisplayMessage( g_hModule, MSG_IP_NOT_ENOUGH_MEMORY );
  195. return ERROR_NOT_ENOUGH_MEMORY;
  196. }
  197. }
  198. return MakeInfoFromScopes2(*ppibNew, pdwSize, pScopes, ulNumScopes);
  199. }
  200. PSCOPE_ENTRY
  201. GetScopesFromInfo(
  202. IN PBYTE pBuffer,
  203. OUT PULONG pulNumScopes
  204. )
  205. /*++
  206. Description:
  207. Convert a registry block into an array of scope information.
  208. Caller is responsible for freeing pointer returned.
  209. --*/
  210. {
  211. PSCOPE_ENTRY pScopes;
  212. DWORD dwLen, i, dwNumNames, j, dwLanguage, dwFlags;
  213. if (pBuffer is NULL)
  214. {
  215. *pulNumScopes = 0;
  216. return NULL;
  217. }
  218. //
  219. // Retrieve scope count from first DWORD
  220. //
  221. *pulNumScopes = *((PDWORD) pBuffer);
  222. pBuffer += sizeof(DWORD);
  223. //
  224. // Malloc enough space for pScopes
  225. //
  226. pScopes = MALLOC( (*pulNumScopes) * sizeof(SCOPE_ENTRY) );
  227. if (pScopes is NULL)
  228. {
  229. *pulNumScopes = 0;
  230. return NULL;
  231. }
  232. //
  233. // Now step through and add each scope to the array
  234. //
  235. for (i=0; i< *pulNumScopes; i++)
  236. {
  237. // Copy scope address, and mask
  238. dwLen = 2 * sizeof(IPV4_ADDRESS);
  239. CopyMemory(&pScopes[i], pBuffer, dwLen);
  240. pBuffer += dwLen;
  241. // Get flags
  242. CopyMemory(&dwFlags, pBuffer, sizeof(dwFlags));
  243. pScopes[i].bDivisible = dwFlags;
  244. pBuffer += sizeof(dwFlags);
  245. // Get # of names
  246. CopyMemory(&dwNumNames, pBuffer, sizeof(DWORD));
  247. pScopes[i].ulNumNames = dwNumNames;
  248. pBuffer += sizeof(DWORD);
  249. // Get names. Currently, we'll only keep the last name (if any)
  250. // and throw out the rest.
  251. for (j=0; j<dwNumNames; j++)
  252. {
  253. // Set language name
  254. CopyMemory(&dwLanguage, pBuffer, sizeof(dwLanguage));
  255. pBuffer += sizeof(dwLanguage);
  256. pScopes[i].idLanguage = (LANGID)dwLanguage;
  257. CopyMemory(&dwLen, pBuffer, sizeof(DWORD));
  258. pBuffer += sizeof(DWORD);
  259. CopyMemory( pScopes[i].snScopeNameBuffer,
  260. pBuffer,
  261. dwLen * sizeof(SN_CHAR) );
  262. pScopes[i].snScopeNameBuffer[ dwLen ] = '\0';
  263. pBuffer += dwLen * sizeof(SN_CHAR);
  264. pScopes[i].ulNumNames = 1;
  265. }
  266. pScopes[i].dwNumInterfaces = 0; // this value is ignored
  267. }
  268. return pScopes;
  269. }
  270. PSCOPE_ENTRY
  271. GetScopes(
  272. OUT PULONG pulNumScopes,
  273. OUT PBYTE *ppBuffer
  274. )
  275. /*++
  276. Description:
  277. Creates a SCOPE_ENTRY array by parsing the info block
  278. Caller is responsible for freeing both the pointer returned
  279. and the buffer passed back.
  280. Called by:
  281. ShowBoundaryInfoForInterface(), UpdateScopeBlock()
  282. --*/
  283. {
  284. DWORD i, dwLen, dwErr, dwBlkSize, dwCount;
  285. DWORD dwInd;
  286. PSCOPE_ENTRY pScopes;
  287. if ( IpmontrGetInfoBlockFromGlobalInfo( IP_MCAST_BOUNDARY_INFO,
  288. ppBuffer,
  289. &dwBlkSize,
  290. &dwCount ) isnot NO_ERROR)
  291. {
  292. *pulNumScopes = 0;
  293. return NULL;
  294. }
  295. pScopes = GetScopesFromInfo(*ppBuffer, pulNumScopes);
  296. return pScopes;
  297. }
  298. DWORD
  299. ScopeNameToPrefix(
  300. IN SCOPE_NAME snScopeName,
  301. OUT IPV4_ADDRESS *pipScopeAddr,
  302. OUT IPV4_ADDRESS *pipScopeMask
  303. )
  304. {
  305. DWORD dwErr = ERROR_NOT_FOUND;
  306. ULONG ulNumScopes;
  307. PBYTE pBuffer = NULL;
  308. PSCOPE_ENTRY pScopes, pScope;
  309. // If first character is a digit, then assume it's
  310. // an address, not a name.
  311. if (iswdigit(snScopeName[0]))
  312. {
  313. dwErr = GetIpAddress(snScopeName, pipScopeAddr);
  314. if (dwErr is NO_ERROR)
  315. {
  316. return NO_ERROR;
  317. }
  318. }
  319. pScopes = GetScopes( &ulNumScopes, &pBuffer );
  320. if (pScopes)
  321. {
  322. dwErr = FindScopeByName(snScopeName, pScopes, ulNumScopes, &pScope);
  323. if (dwErr is NO_ERROR)
  324. {
  325. *pipScopeAddr = pScope->ipGroupAddress;
  326. *pipScopeMask = pScope->ipGroupMask;
  327. dwErr = NO_ERROR;
  328. }
  329. FREE(pScopes);
  330. }
  331. if (pBuffer)
  332. FREE(pBuffer);
  333. return dwErr;
  334. }
  335. DWORD
  336. UpdateScope(
  337. IN PSCOPE_ENTRY pScopeToUpdate,
  338. IN PSCOPE_ENTRY pScopes,
  339. IN ULONG ulNumScopes,
  340. OUT PBYTE *ppibNew,
  341. OUT DWORD *pdwSizeNew
  342. )
  343. /*++
  344. Description:
  345. Caller is responsible for freeing buffer returned.
  346. --*/
  347. {
  348. // Update the scope name
  349. sn_strcpy(pScopeToUpdate->snScopeNameBuffer, g_snScopeName);
  350. pScopeToUpdate->ulNumNames = 1;
  351. pScopeToUpdate->idLanguage = GetUserDefaultLangID();
  352. // Now convert the array to a buffer
  353. return MakeInfoFromScopes( ppibNew, pdwSizeNew, pScopes, ulNumScopes);
  354. }
  355. DWORD
  356. DeleteBoundaryFromInterface(
  357. IN LPCWSTR pwszIfName,
  358. IN PSCOPE_ENTRY pScopeToDelete
  359. )
  360. {
  361. BOOL bChanged;
  362. DWORD dwErr, dwBlkSize, dwCount, dwIfType;
  363. PBYTE pibNew, pib;
  364. dwErr = IpmontrGetInfoBlockFromInterfaceInfo( pwszIfName,
  365. IP_MCAST_BOUNDARY_INFO,
  366. &pib,
  367. &dwBlkSize,
  368. &dwCount,
  369. &dwIfType );
  370. if (dwErr is ERROR_NOT_FOUND)
  371. return NO_ERROR;
  372. if (dwErr isnot NO_ERROR)
  373. return dwErr;
  374. dwErr = UpdateBoundaryBlock( DELETE_BOUNDARY,
  375. pib,
  376. &pibNew,
  377. &dwBlkSize,
  378. &dwCount,
  379. &bChanged );
  380. if (dwErr is NO_ERROR && bChanged)
  381. {
  382. dwErr = IpmontrSetInfoBlockInInterfaceInfo( pwszIfName,
  383. IP_MCAST_BOUNDARY_INFO,
  384. pibNew,
  385. dwBlkSize,
  386. dwCount );
  387. }
  388. if (pib)
  389. FREE(pib);
  390. if (pibNew)
  391. FREE(pibNew);
  392. return dwErr;
  393. }
  394. DWORD
  395. DeleteScopeBoundaries(
  396. IN PSCOPE_ENTRY pScopeToDelete
  397. )
  398. {
  399. DWORD dwErr, dwCount, dwTotal, i;
  400. PMPR_INTERFACE_0 pmi0;
  401. // Enumerate interfaces
  402. dwErr = IpmontrInterfaceEnum((PBYTE *) &pmi0, &dwCount, &dwTotal);
  403. if (dwErr isnot NO_ERROR)
  404. {
  405. DisplayError(g_hModule, dwErr);
  406. return dwErr;
  407. }
  408. // Delete scope boundaries for each interface
  409. for ( i = 0; i < dwCount && dwErr is NO_ERROR; i++)
  410. {
  411. dwErr = DeleteBoundaryFromInterface( pmi0[i].wszInterfaceName,
  412. pScopeToDelete );
  413. // Ignore ERROR_NO_SUCH_INTERFACE since it may be that IP
  414. // is not enabled on the interface, so we expect to get this
  415. // error sometimes.
  416. if (dwErr is ERROR_NO_SUCH_INTERFACE)
  417. {
  418. dwErr = NO_ERROR;
  419. }
  420. }
  421. return dwErr;
  422. }
  423. DWORD
  424. DeleteScope(
  425. IN PSCOPE_ENTRY pScopeToDelete,
  426. IN PSCOPE_ENTRY pScopes,
  427. IN ULONG *pulNumScopes,
  428. OUT PBYTE *ppibNew,
  429. OUT DWORD *pdwSizeNew
  430. )
  431. /*++
  432. Description:
  433. Creates a new info block which does not include the scope given
  434. by pScopeToDelete.
  435. Caller is responsible for freeing buffer returned.
  436. Called by:
  437. UpdateScopeBlock()
  438. --*/
  439. {
  440. DWORD dwErr;
  441. // Delete all boundaries for this scope
  442. dwErr = DeleteScopeBoundaries(pScopeToDelete);
  443. if (dwErr isnot NO_ERROR)
  444. return dwErr;
  445. // Delete the scope from the array
  446. MoveMemory( pScopeToDelete,
  447. pScopeToDelete+1,
  448. ((PBYTE)(pScopes + *pulNumScopes))
  449. - ((PBYTE)(pScopeToDelete + 1) ));
  450. (*pulNumScopes)--;
  451. // Now convert the array to a buffer
  452. return MakeInfoFromScopes( ppibNew, pdwSizeNew, pScopes, *pulNumScopes);
  453. }
  454. DWORD
  455. AddScope(
  456. IN OUT PSCOPE_ENTRY *ppScopes,
  457. IN ULONG *pulNumScopes,
  458. OUT PBYTE *ppibNew,
  459. OUT DWORD *pdwSizeNew
  460. )
  461. /*++
  462. Description:
  463. Creates a new info block which includes the scope given
  464. by g_snScopeName, g_dwDstAddr, and g_dwDstMask.
  465. Caller is responsible for freeing buffer returned.
  466. Called by:
  467. UpdateScopeBlock()
  468. --*/
  469. {
  470. PBYTE *pBuff;
  471. DWORD dwRes = NO_ERROR,
  472. dwInd,
  473. dwSize = 0,
  474. dwSizeReqd = 0;
  475. SCOPE_ENTRY *pScopes = *ppScopes;
  476. do
  477. {
  478. // Make room for the new scope
  479. if (*pulNumScopes > 0)
  480. {
  481. LPVOID Tmp;
  482. Tmp = REALLOC( pScopes,
  483. (*pulNumScopes + 1) * sizeof(SCOPE_ENTRY) );
  484. if (Tmp==NULL && pScopes)
  485. {
  486. FREE( pScopes );
  487. }
  488. pScopes = Tmp;
  489. }
  490. else
  491. pScopes = MALLOC( sizeof(SCOPE_ENTRY) );
  492. if (!pScopes)
  493. return ERROR_NOT_ENOUGH_MEMORY;
  494. dwInd = (*pulNumScopes)++;
  495. // Fill in the new scope
  496. ZeroMemory(&pScopes[dwInd], sizeof(SCOPE_ENTRY));
  497. pScopes[dwInd].ipGroupAddress = g_ipGrpAddr;
  498. pScopes[dwInd].ipGroupMask = g_ipGrpMask;
  499. sn_strcpy(pScopes[dwInd].snScopeNameBuffer, g_snScopeName);
  500. pScopes[dwInd].ulNumNames = 1;
  501. pScopes[dwInd].idLanguage = GetUserDefaultLangID();
  502. // Now convert the array to a buffer
  503. dwRes = MakeInfoFromScopes( ppibNew, &dwSize, pScopes, *pulNumScopes);
  504. } while ( FALSE );
  505. *pdwSizeNew = dwSize;
  506. *ppScopes = pScopes;
  507. return dwRes;
  508. }
  509. BOOL
  510. IsContiguous(
  511. IN IPV4_ADDRESS dwMask
  512. )
  513. {
  514. register int i;
  515. dwMask = ntohl(dwMask);
  516. // Set i to index of lowest 1 bit, or 32 if none
  517. for (i=0; i<32 && !(dwMask & (1<<i)); i++);
  518. // Set i to index of lowest 0 bit greater than the 1 bit found,
  519. // or 32 if none
  520. for (; i<32 && (dwMask & (1<<i)); i++);
  521. // Mask is contiguous if we got up to 32 without finding such
  522. // a 0 bit.
  523. return (i is 32);
  524. }
  525. DWORD
  526. UpdateScopeBlock(
  527. DWORD dwAction,
  528. PBYTE pib,
  529. PBYTE *ppibNew,
  530. DWORD *pdwBlkSize,
  531. DWORD *pdwCount
  532. )
  533. /*++
  534. Description:
  535. Caller is responsible for freeing buffer returned.
  536. Called by:
  537. IpAddSetDelScope()
  538. --*/
  539. {
  540. DWORD dwRes = (DWORD) -1,
  541. dwInd = 0,
  542. dwSize = 0;
  543. ULONG ulNumScopes = 0;
  544. PSCOPE_ENTRY pScopes = NULL,
  545. pFoundScope = NULL;
  546. do
  547. {
  548. *ppibNew = NULL;
  549. *pdwBlkSize = 0;
  550. *pdwCount = 0;
  551. //
  552. // Verify scope info.
  553. //
  554. if ( ( g_ipGrpAddr & g_ipGrpMask ) != g_ipGrpAddr
  555. || ntohl(g_ipGrpAddr) < MIN_SCOPE_ADDR
  556. || ntohl(g_ipGrpAddr) > MAX_SCOPE_ADDR)
  557. {
  558. dwRes = ERROR_INVALID_PARAMETER;
  559. break;
  560. }
  561. // Make sure mask is contiguous
  562. if (!IsContiguous(g_ipGrpMask))
  563. {
  564. char buff[20], *lpstr;
  565. lpstr = inet_ntoa( *((struct in_addr *) &g_ipGrpMask));
  566. if (lpstr != NULL)
  567. {
  568. strcpy( buff, lpstr );
  569. DisplayMessage( g_hModule, MSG_IP_BAD_IP_MASK, buff );
  570. }
  571. break;
  572. }
  573. //
  574. // Find if specified scope is present
  575. //
  576. pScopes = GetScopesFromInfo( pib, &ulNumScopes );
  577. if ( pScopes )
  578. {
  579. pFoundScope = FindScopeByPrefix( g_ipGrpAddr,
  580. g_ipGrpMask,
  581. pScopes,
  582. ulNumScopes
  583. );
  584. }
  585. //
  586. // Update the scope infoblock.
  587. //
  588. switch ( dwAction )
  589. {
  590. case ADD_SCOPE:
  591. //
  592. // If scope is not present, add it. Else return error.
  593. //
  594. if ( !pFoundScope )
  595. {
  596. dwRes = AddScope( &pScopes, &ulNumScopes, ppibNew, &dwSize );
  597. if ( dwRes == NO_ERROR )
  598. {
  599. *pdwBlkSize = dwSize;
  600. *pdwCount = 1;
  601. }
  602. break;
  603. }
  604. // else fall through into SET_SCOPE.
  605. case SET_SCOPE:
  606. //
  607. // if scope present, update it.
  608. //
  609. if ( pFoundScope )
  610. {
  611. dwRes = UpdateScope( pFoundScope,
  612. pScopes,
  613. ulNumScopes,
  614. ppibNew,
  615. &dwSize );
  616. if ( dwRes == NO_ERROR )
  617. {
  618. *pdwBlkSize = dwSize;
  619. *pdwCount = 1;
  620. }
  621. }
  622. else
  623. {
  624. dwRes = ERROR_INVALID_PARAMETER;
  625. }
  626. break;
  627. case DELETE_SCOPE:
  628. //
  629. // Delete scope only if present.
  630. //
  631. if ( pFoundScope )
  632. {
  633. dwRes = DeleteScope( pFoundScope,
  634. pScopes,
  635. &ulNumScopes,
  636. ppibNew,
  637. &dwSize );
  638. if ( dwRes == NO_ERROR )
  639. {
  640. *pdwBlkSize = dwSize;
  641. *pdwCount = (dwSize>0)? 1 : 0;
  642. }
  643. }
  644. else
  645. {
  646. dwRes = ERROR_INVALID_PARAMETER;
  647. }
  648. break;
  649. }
  650. } while ( FALSE );
  651. if (pScopes)
  652. FREE( pScopes );
  653. return dwRes;
  654. }
  655. DWORD
  656. VerifyBoundaryPrefix(
  657. IPV4_ADDRESS ipAddr,
  658. IPV4_ADDRESS ipMask
  659. )
  660. {
  661. WCHAR wstr1[20], wstr2[20];
  662. //
  663. // Verify boundary info.
  664. //
  665. if (ntohl(ipAddr) < MIN_SCOPE_ADDR
  666. || ntohl(ipAddr) > MAX_SCOPE_ADDR)
  667. {
  668. MakeAddressStringW(wstr1, htonl(MIN_SCOPE_ADDR));
  669. MakeAddressStringW(wstr2, htonl(MAX_SCOPE_ADDR));
  670. DisplayMessage( g_hModule,
  671. EMSG_INVALID_ADDR,
  672. wstr1,
  673. wstr2 );
  674. return ERROR_INVALID_PARAMETER;
  675. }
  676. if ( ( ipAddr & ipMask ) != ipAddr )
  677. {
  678. DisplayMessage( g_hModule, EMSG_PREFIX_ERROR );
  679. return ERROR_INVALID_PARAMETER;
  680. }
  681. // Make sure mask is contiguous
  682. if (!IsContiguous(ipMask))
  683. {
  684. char buff[20], *lpstr;
  685. lpstr = inet_ntoa( *((struct in_addr *) &g_ipGrpMask));
  686. if (lpstr != NULL)
  687. {
  688. strcpy( buff, lpstr );
  689. DisplayMessage( g_hModule, MSG_IP_BAD_IP_MASK, buff );
  690. }
  691. return ERROR_INVALID_PARAMETER;
  692. }
  693. return NO_ERROR;
  694. }
  695. DWORD
  696. IpAddSetDelScope(
  697. DWORD dwAction,
  698. PWCHAR *ppwcArguments,
  699. DWORD dwCurrentIndex,
  700. DWORD dwArgCount
  701. )
  702. {
  703. DWORD dwErr;
  704. TAG_TYPE pttTags[] = {{TOKEN_GROUP_ADDRESS,FALSE,FALSE},
  705. {TOKEN_GROUP_MASK, FALSE,FALSE},
  706. {TOKEN_SCOPE_NAME, FALSE,FALSE}};
  707. SCOPE_NAME_BUFFER snScopeName;
  708. DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
  709. IPV4_ADDRESS ipGroup, ipMask;
  710. DWORD dwBlkSize, dwCount, i, dwNumParsed;
  711. PBYTE pib, pibNew = NULL;
  712. DWORD dwArgsReqd = (dwAction is DELETE_SCOPE)? 1 : 3;
  713. PWCHAR p;
  714. // Do generic processing
  715. dwErr = PreHandleCommand( ppwcArguments,
  716. dwCurrentIndex,
  717. dwArgCount,
  718. pttTags,
  719. sizeof(pttTags)/sizeof(TAG_TYPE),
  720. dwArgsReqd,
  721. sizeof(pttTags)/sizeof(TAG_TYPE),
  722. rgdwTagType );
  723. if (dwErr)
  724. {
  725. return dwErr;
  726. }
  727. g_ipGrpAddr = g_ipGrpMask = 0;
  728. for(i = 0; i < dwArgCount - dwCurrentIndex; i ++)
  729. {
  730. switch (rgdwTagType[i])
  731. {
  732. case 1: // GRPMASK
  733. {
  734. dwErr = GetIpMask(ppwcArguments[i + dwCurrentIndex],
  735. &g_ipGrpMask);
  736. if (dwErr is ERROR_INVALID_PARAMETER)
  737. {
  738. DisplayMessage( g_hModule, MSG_IP_BAD_IP_ADDR,
  739. ppwcArguments[i + dwCurrentIndex]);
  740. DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
  741. pttTags[rgdwTagType[i]].pwszTag,
  742. ppwcArguments[i + dwCurrentIndex]);
  743. return NO_ERROR;
  744. }
  745. break;
  746. }
  747. case 0: // GRPADDR
  748. {
  749. dwErr = GetIpPrefix(ppwcArguments[i + dwCurrentIndex],
  750. &g_ipGrpAddr,
  751. &g_ipGrpMask);
  752. if (!((dwErr is ERROR_INVALID_PARAMETER)
  753. && (dwAction is DELETE_SCOPE)))
  754. {
  755. break;
  756. }
  757. // FALLTHROUGH
  758. }
  759. case 2 : // SCOPENAME
  760. {
  761. // Strip leading and trailing whitespace
  762. for (p = ppwcArguments[i + dwCurrentIndex]; iswspace(*p); p++);
  763. while (iswspace( p[wcslen(p) - 1] ))
  764. {
  765. p[ wcslen(p)-1 ] = 0;
  766. }
  767. if (wcslen(p) > MAX_SCOPE_NAME_LEN)
  768. {
  769. DisplayMessage( g_hModule,
  770. EMSG_SCOPE_NAME_TOO_LONG,
  771. MAX_SCOPE_NAME_LEN );
  772. return NO_ERROR;
  773. }
  774. sn_strcpy( snScopeName, p);
  775. g_snScopeName = snScopeName;
  776. if (dwAction is DELETE_SCOPE)
  777. {
  778. dwErr = ScopeNameToPrefix(snScopeName,
  779. &g_ipGrpAddr,
  780. &g_ipGrpMask);
  781. if (dwErr is ERROR_MORE_DATA)
  782. {
  783. DisplayMessage( g_hModule, EMSG_AMBIGUOUS_SCOPE_NAME,
  784. ppwcArguments[i + dwCurrentIndex]);
  785. return NO_ERROR;
  786. }
  787. }
  788. break;
  789. }
  790. }
  791. }
  792. if (dwErr isnot NO_ERROR)
  793. {
  794. return dwErr;
  795. }
  796. if (!g_ipGrpAddr || !g_ipGrpMask)
  797. {
  798. return ERROR_INVALID_SYNTAX;
  799. }
  800. dwErr = VerifyBoundaryPrefix(g_ipGrpAddr, g_ipGrpMask);
  801. if (dwErr)
  802. {
  803. return NO_ERROR;
  804. }
  805. do {
  806. dwErr = IpmontrGetInfoBlockFromGlobalInfo( IP_MCAST_BOUNDARY_INFO,
  807. &pib,
  808. &dwBlkSize,
  809. &dwCount );
  810. if (dwErr is ERROR_NOT_FOUND)
  811. {
  812. //
  813. // No info of this type is currently present
  814. //
  815. dwErr = NO_ERROR;
  816. dwCount = 1;
  817. }
  818. if (dwErr isnot NO_ERROR)
  819. break;
  820. dwErr = UpdateScopeBlock( dwAction,
  821. pib,
  822. &pibNew,
  823. &dwBlkSize,
  824. &dwCount );
  825. if (dwErr isnot NO_ERROR)
  826. break;
  827. dwErr = IpmontrSetInfoBlockInGlobalInfo( IP_MCAST_BOUNDARY_INFO,
  828. pibNew,
  829. dwBlkSize,
  830. dwCount );
  831. } while (FALSE);
  832. if (pib)
  833. HeapFree(GetProcessHeap(), 0 , pib);
  834. if (pibNew)
  835. HeapFree(GetProcessHeap(), 0 , pibNew);
  836. return dwErr;
  837. }
  838. DWORD
  839. HandleIpAddScope(
  840. IN LPCWSTR pwszMachine,
  841. IN OUT LPWSTR *ppwcArguments,
  842. IN DWORD dwCurrentIndex,
  843. IN DWORD dwArgCount,
  844. IN DWORD dwFlags,
  845. IN LPCVOID pvData,
  846. OUT BOOL *pbDone
  847. )
  848. /*++
  849. Routine Description:
  850. Arguments:
  851. ppwcArguments - Argument array
  852. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  853. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  854. Return Value:
  855. NO_ERROR
  856. --*/
  857. {
  858. return IpAddSetDelScope( ADD_SCOPE,
  859. ppwcArguments,
  860. dwCurrentIndex,
  861. dwArgCount );
  862. }
  863. DWORD
  864. HandleIpDelScope(
  865. IN LPCWSTR pwszMachine,
  866. IN OUT LPWSTR *ppwcArguments,
  867. IN DWORD dwCurrentIndex,
  868. IN DWORD dwArgCount,
  869. IN DWORD dwFlags,
  870. IN LPCVOID pvData,
  871. OUT BOOL *pbDone
  872. )
  873. /*++
  874. Routine Description:
  875. Arguments:
  876. ppwcArguments - Argument array
  877. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  878. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  879. Return Value:
  880. NO_ERROR
  881. --*/
  882. {
  883. return IpAddSetDelScope( DELETE_SCOPE,
  884. ppwcArguments,
  885. dwCurrentIndex,
  886. dwArgCount );
  887. }
  888. DWORD
  889. HandleIpSetScope(
  890. IN LPCWSTR pwszMachine,
  891. IN OUT LPWSTR *ppwcArguments,
  892. IN DWORD dwCurrentIndex,
  893. IN DWORD dwArgCount,
  894. IN DWORD dwFlags,
  895. IN LPCVOID pvData,
  896. OUT BOOL *pbDone
  897. )
  898. /*++
  899. Routine Description:
  900. Arguments:
  901. ppwcArguments - Argument array
  902. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  903. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  904. Return Value:
  905. NO_ERROR
  906. --*/
  907. {
  908. return IpAddSetDelScope( SET_SCOPE,
  909. ppwcArguments,
  910. dwCurrentIndex,
  911. dwArgCount );
  912. }
  913. DWORD
  914. ShowScopes(
  915. IN HANDLE hFile
  916. )
  917. {
  918. DWORD dwRes = (DWORD) -1,
  919. dwCnt = 0,
  920. dwInd = 0,
  921. dwGlobalSize = 0;
  922. ULONG ulNumScopes = 0;
  923. CHAR szAddr1[ ADDR_LENGTH ],
  924. szAddr2[ ADDR_LENGTH ];
  925. PSCOPE_ENTRY pScope,
  926. pScopes;
  927. HANDLE hTransport = (HANDLE) NULL;
  928. PBYTE pScopesBuffer;
  929. SCOPE_NAME_BUFFER snScopeNameBuffer;
  930. do
  931. {
  932. pScopes = GetScopes( &ulNumScopes, &pScopesBuffer );
  933. if (hFile is NULL)
  934. {
  935. if (ulNumScopes)
  936. {
  937. DisplayMessage( g_hModule, MSG_RTR_SCOPE_HDR );
  938. }
  939. else
  940. {
  941. DisplayMessage( g_hModule, MSG_IP_NO_ENTRIES );
  942. }
  943. }
  944. //
  945. // Enumerate the scopes
  946. //
  947. for ( dwCnt = 0; dwCnt < ulNumScopes; dwCnt++ )
  948. {
  949. pScope = &pScopes[dwCnt];
  950. strcpy(
  951. szAddr1,
  952. inet_ntoa( *((struct in_addr *) &pScope->ipGroupAddress) )
  953. );
  954. strcpy(
  955. szAddr2,
  956. inet_ntoa( *((struct in_addr *) &pScope->ipGroupMask) )
  957. );
  958. MakePrefixStringW(snScopeNameBuffer,
  959. pScope->ipGroupAddress,
  960. pScope->ipGroupMask);
  961. if (hFile)
  962. {
  963. PWCHAR pwszQuoted = MakeQuotedString( (pScope->ulNumNames)?
  964. pScope->snScopeNameBuffer : snScopeNameBuffer );
  965. DisplayMessageT( DMP_SCOPE_INFO,
  966. szAddr1,
  967. szAddr2,
  968. pwszQuoted );
  969. FreeQuotedString(pwszQuoted);
  970. }
  971. else
  972. {
  973. DisplayMessage( g_hModule,
  974. MSG_RTR_SCOPE_INFO,
  975. szAddr1,
  976. szAddr2,
  977. (pScope->ulNumNames)? pScope->snScopeNameBuffer
  978. : snScopeNameBuffer );
  979. }
  980. }
  981. dwRes = NO_ERROR;
  982. if (pScopes)
  983. FREE(pScopes);
  984. if (pScopesBuffer)
  985. FREE(pScopesBuffer);
  986. } while ( FALSE );
  987. return dwRes;
  988. }
  989. DWORD
  990. HandleIpShowScope(
  991. IN LPCWSTR pwszMachine,
  992. IN OUT LPWSTR *ppwcArguments,
  993. IN DWORD dwCurrentIndex,
  994. IN DWORD dwArgCount,
  995. IN DWORD dwFlags,
  996. IN LPCVOID pvData,
  997. OUT BOOL *pbDone
  998. )
  999. /*++
  1000. Routine Description:
  1001. Arguments:
  1002. ppwcArguments - Argument array
  1003. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  1004. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  1005. Return Value:
  1006. NO_ERROR
  1007. --*/
  1008. {
  1009. return ShowScopes(0);
  1010. }
  1011. DWORD
  1012. DeleteBoundary(
  1013. IN DWORD dwDelInd,
  1014. IN PBYTE pib,
  1015. OUT PBYTE *ppibNew,
  1016. IN OUT DWORD *pdwCount
  1017. )
  1018. /*++
  1019. Description:
  1020. Creates a new info block header which does not include the
  1021. boundary with the specified index.
  1022. Caller is responsible for freeing buffer returned.
  1023. Called by:
  1024. UpdateBoundaryBlock()
  1025. --*/
  1026. {
  1027. DWORD dwInd = 0,
  1028. dwCnt = 0,
  1029. dwCnt0 = 0,
  1030. dwSize = 0,
  1031. dwRes = NO_ERROR;
  1032. LPBYTE pbDst = (LPBYTE) NULL,
  1033. pbSrc = (LPBYTE) NULL;
  1034. PRTR_INFO_BLOCK_HEADER pibh = (PRTR_INFO_BLOCK_HEADER) NULL;
  1035. PMIB_BOUNDARYROW pimbSrc = (PMIB_BOUNDARYROW) NULL;
  1036. PMIB_BOUNDARYROW pimbDst = (PMIB_BOUNDARYROW) NULL;
  1037. //
  1038. // Create new info block with boundary removed.
  1039. //
  1040. dwSize = (*pdwCount - 1) * sizeof( MIB_BOUNDARYROW );
  1041. if (dwSize is 0)
  1042. {
  1043. *ppibNew = NULL;
  1044. *pdwCount = 0;
  1045. return NO_ERROR;
  1046. }
  1047. *ppibNew = MALLOC( dwSize );
  1048. if ( *ppibNew == NULL )
  1049. {
  1050. DisplayMessage( g_hModule, MSG_IP_NOT_ENOUGH_MEMORY );
  1051. return ERROR_NOT_ENOUGH_MEMORY;
  1052. }
  1053. //
  1054. // Copy boundaries, skip boundary to be deleted
  1055. //
  1056. pimbDst = (PMIB_BOUNDARYROW) *ppibNew;
  1057. pimbSrc = (PMIB_BOUNDARYROW) pib;
  1058. for ( dwCnt = 0, dwCnt0 = 0;
  1059. dwCnt < *pdwCount;
  1060. dwCnt++ )
  1061. {
  1062. if ( dwCnt == dwDelInd )
  1063. {
  1064. continue;
  1065. }
  1066. pimbDst[ dwCnt0 ] = pimbSrc[ dwCnt ];
  1067. dwCnt0++;
  1068. }
  1069. (*pdwCount)--;
  1070. return NO_ERROR;
  1071. }
  1072. DWORD
  1073. AddBoundary (
  1074. IN PBYTE pib,
  1075. OUT PBYTE *ppibNew,
  1076. IN OUT DWORD *pdwCount
  1077. )
  1078. /*++
  1079. Description:
  1080. Creates a new info block which includes a boundary for the
  1081. scope identified by g_ipGrpAddr/g_ipGrpMask.
  1082. Caller is responsible for freeing buffer returned.
  1083. Called by:
  1084. UpdateBoundaryBlock()
  1085. --*/
  1086. {
  1087. DWORD dwRes = NO_ERROR,
  1088. dwInd = 0,
  1089. dwSize = 0;
  1090. LPBYTE pbDst = (LPBYTE) NULL,
  1091. pbSrc = (LPBYTE) NULL;
  1092. PMIB_BOUNDARYROW pimb = (PMIB_BOUNDARYROW ) NULL;
  1093. dwRes = VerifyBoundaryPrefix(g_ipGrpAddr, g_ipGrpMask);
  1094. if (dwRes)
  1095. {
  1096. return NO_ERROR;
  1097. }
  1098. do
  1099. {
  1100. *ppibNew = NULL;
  1101. //
  1102. // If this is the first boundary, create info block
  1103. // with an extra TocEntry.
  1104. //
  1105. dwSize = (*pdwCount + 1) * sizeof( MIB_BOUNDARYROW );
  1106. *ppibNew = MALLOC( dwSize );
  1107. if ( *ppibNew == NULL )
  1108. {
  1109. DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY );
  1110. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  1111. break;
  1112. }
  1113. pbDst = *ppibNew;
  1114. CopyMemory( pbDst, pib, (*pdwCount) * sizeof(MIB_BOUNDARYROW) );
  1115. pbDst += (*pdwCount) * sizeof(MIB_BOUNDARYROW);
  1116. (*pdwCount)++;
  1117. pimb = (PMIB_BOUNDARYROW) pbDst;
  1118. pimb-> dwGroupAddress = g_ipGrpAddr;
  1119. pimb-> dwGroupMask = g_ipGrpMask;
  1120. pbDst += sizeof( MIB_BOUNDARYROW );
  1121. } while ( FALSE );
  1122. return dwRes;
  1123. }
  1124. BOOL
  1125. IsBoundaryPresent(
  1126. IN IPV4_ADDRESS ipGroupAddress,
  1127. IN IPV4_ADDRESS ipGroupMask,
  1128. IN PMIB_BOUNDARYROW pimb,
  1129. IN DWORD dwNumBoundaries,
  1130. OUT PDWORD pdwInd
  1131. )
  1132. /*++
  1133. Returns:
  1134. TRUE if present, and sets dwInd to index
  1135. FALSE if not present, and sets dwInd to -1
  1136. Called by:
  1137. UpdateBoundaryBlock()
  1138. --*/
  1139. {
  1140. DWORD dwInd = 0;
  1141. *pdwInd = (DWORD) -1;
  1142. for ( dwInd = 0; dwInd < dwNumBoundaries; dwInd++, pimb++ )
  1143. {
  1144. if ( pimb-> dwGroupAddress != ipGroupAddress
  1145. || pimb-> dwGroupMask != ipGroupMask )
  1146. {
  1147. continue;
  1148. }
  1149. *pdwInd = dwInd;
  1150. return TRUE;
  1151. }
  1152. return FALSE;
  1153. }
  1154. DWORD
  1155. UpdateBoundaryBlock(
  1156. IN DWORD dwAction,
  1157. IN PBYTE pib,
  1158. OUT PBYTE *ppibNew,
  1159. IN OUT DWORD *pdwBlkSize,
  1160. IN OUT DWORD *pdwCount,
  1161. OUT BOOL *pbChanged
  1162. )
  1163. /*++
  1164. Description:
  1165. Caller is responsible for freeing buffer returned.
  1166. Called by:
  1167. IpAddDelBoundary(), DeleteBoundaryFromInterface()
  1168. --*/
  1169. {
  1170. DWORD dwRes = NO_ERROR,
  1171. dwInd = 0,
  1172. dwInd0 = 0;
  1173. BOOL bBoFound = FALSE;
  1174. PMIB_BOUNDARYROW pimb = (PMIB_BOUNDARYROW) NULL;
  1175. *pbChanged = FALSE;
  1176. do
  1177. {
  1178. *ppibNew = NULL;
  1179. //
  1180. // Find if specified boundary is present
  1181. //
  1182. bBoFound = IsBoundaryPresent( g_ipGrpAddr,
  1183. g_ipGrpMask,
  1184. (PMIB_BOUNDARYROW)pib,
  1185. *pdwCount,
  1186. &dwInd0 );
  1187. //
  1188. // Update the boundary infoblock.
  1189. //
  1190. switch ( dwAction )
  1191. {
  1192. case ADD_BOUNDARY:
  1193. //
  1194. // If boundary is not present, add it. Else return error.
  1195. //
  1196. if ( !bBoFound )
  1197. {
  1198. dwRes = AddBoundary( pib, ppibNew, pdwCount );
  1199. *pdwBlkSize = sizeof(MIB_BOUNDARYROW);
  1200. *pbChanged = TRUE;
  1201. }
  1202. else
  1203. {
  1204. dwRes = ERROR_OBJECT_ALREADY_EXISTS;
  1205. }
  1206. break;
  1207. case DELETE_BOUNDARY:
  1208. //
  1209. // Delete boundary only if present.
  1210. //
  1211. if ( bBoFound )
  1212. {
  1213. dwRes = DeleteBoundary( dwInd0, pib, ppibNew, pdwCount );
  1214. *pbChanged = TRUE;
  1215. }
  1216. // If not present, return success but don't set the changed flag.
  1217. break;
  1218. }
  1219. } while ( FALSE );
  1220. return dwRes;
  1221. }
  1222. DWORD
  1223. IpAddDelBoundary(
  1224. DWORD dwAction,
  1225. PWCHAR *ppwcArguments,
  1226. DWORD dwCurrentIndex,
  1227. DWORD dwArgCount
  1228. )
  1229. {
  1230. DWORD dwErr;
  1231. TAG_TYPE pttTags[] = {{TOKEN_NAME, TRUE, FALSE},
  1232. {TOKEN_GROUP_ADDRESS, FALSE,FALSE},
  1233. {TOKEN_GROUP_MASK, FALSE,FALSE},
  1234. {TOKEN_SCOPE_NAME, FALSE,FALSE},
  1235. };
  1236. WCHAR rgwcIfName[MAX_INTERFACE_NAME_LEN + 1];
  1237. DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
  1238. IPV4_ADDRESS ipGroup, ipMask;
  1239. DWORD dwBlkSize, dwCount, dwIfType, i, dwNumParsed;
  1240. PBYTE pib, pibNew = NULL;
  1241. BOOL bChanged;
  1242. // Do generic processing
  1243. dwErr = PreHandleCommand( ppwcArguments,
  1244. dwCurrentIndex,
  1245. dwArgCount,
  1246. pttTags,
  1247. sizeof(pttTags)/sizeof(TAG_TYPE),
  1248. 2,
  1249. 3,
  1250. rgdwTagType );
  1251. if (dwErr)
  1252. {
  1253. return dwErr;
  1254. }
  1255. g_ipGrpAddr = g_ipGrpMask = 0;
  1256. for(i = 0; i < dwArgCount - dwCurrentIndex; i ++)
  1257. {
  1258. switch (rgdwTagType[i])
  1259. {
  1260. case 0 : // NAME
  1261. {
  1262. DWORD BufLen = sizeof(rgwcIfName);
  1263. GetInterfaceName(ppwcArguments[i + dwCurrentIndex],
  1264. rgwcIfName,
  1265. BufLen,
  1266. &dwNumParsed);
  1267. break;
  1268. }
  1269. case 1: // GRPADDR
  1270. {
  1271. dwErr = GetIpPrefix(ppwcArguments[i + dwCurrentIndex],
  1272. &g_ipGrpAddr,
  1273. &g_ipGrpMask);
  1274. if (!((dwErr is ERROR_INVALID_PARAMETER)
  1275. && (dwAction is DELETE_BOUNDARY)))
  1276. {
  1277. break;
  1278. }
  1279. // FALLTHROUGH
  1280. }
  1281. case 3: // SCOPENAME
  1282. {
  1283. dwErr = ScopeNameToPrefix( ppwcArguments[i + dwCurrentIndex],
  1284. &g_ipGrpAddr,
  1285. &g_ipGrpMask );
  1286. if (dwErr is ERROR_MORE_DATA)
  1287. {
  1288. DisplayMessage( g_hModule, EMSG_AMBIGUOUS_SCOPE_NAME,
  1289. ppwcArguments[i + dwCurrentIndex]);
  1290. return NO_ERROR;
  1291. }
  1292. break;
  1293. }
  1294. case 2: // GRPMASK
  1295. {
  1296. dwErr = GetIpMask(ppwcArguments[i + dwCurrentIndex],
  1297. &g_ipGrpMask);
  1298. if (dwErr is ERROR_INVALID_PARAMETER)
  1299. {
  1300. DisplayMessage( g_hModule, MSG_IP_BAD_IP_ADDR,
  1301. ppwcArguments[i + dwCurrentIndex]);
  1302. DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
  1303. pttTags[rgdwTagType[i]].pwszTag,
  1304. ppwcArguments[i + dwCurrentIndex]);
  1305. return NO_ERROR;
  1306. }
  1307. break;
  1308. }
  1309. }
  1310. }
  1311. if (dwErr isnot NO_ERROR)
  1312. {
  1313. return dwErr;
  1314. }
  1315. if (!g_ipGrpAddr || !g_ipGrpMask)
  1316. {
  1317. return ERROR_INVALID_SYNTAX;
  1318. }
  1319. do {
  1320. dwErr = IpmontrGetInfoBlockFromInterfaceInfo( rgwcIfName,
  1321. IP_MCAST_BOUNDARY_INFO,
  1322. &pib,
  1323. &dwBlkSize,
  1324. &dwCount,
  1325. &dwIfType );
  1326. if (dwErr is ERROR_NOT_FOUND)
  1327. {
  1328. //
  1329. // No info of this type is currently present
  1330. //
  1331. dwErr = NO_ERROR;
  1332. dwCount = 0;
  1333. }
  1334. if (dwErr isnot NO_ERROR)
  1335. break;
  1336. dwErr = UpdateBoundaryBlock( dwAction,
  1337. pib,
  1338. &pibNew,
  1339. &dwBlkSize,
  1340. &dwCount,
  1341. &bChanged );
  1342. if (dwErr isnot NO_ERROR)
  1343. break;
  1344. if (bChanged)
  1345. {
  1346. dwErr = IpmontrSetInfoBlockInInterfaceInfo( rgwcIfName,
  1347. IP_MCAST_BOUNDARY_INFO,
  1348. pibNew,
  1349. dwBlkSize,
  1350. dwCount );
  1351. }
  1352. } while (FALSE);
  1353. if (pib)
  1354. FREE(pib);
  1355. if (pibNew)
  1356. FREE(pibNew);
  1357. return dwErr;
  1358. }
  1359. DWORD
  1360. HandleIpAddBoundary(
  1361. IN LPCWSTR pwszMachine,
  1362. IN OUT LPWSTR *ppwcArguments,
  1363. IN DWORD dwCurrentIndex,
  1364. IN DWORD dwArgCount,
  1365. IN DWORD dwFlags,
  1366. IN LPCVOID pvData,
  1367. OUT BOOL *pbDone
  1368. )
  1369. /*++
  1370. Routine Description:
  1371. Arguments:
  1372. ppwcArguments - Argument array
  1373. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  1374. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  1375. Return Value:
  1376. NO_ERROR
  1377. --*/
  1378. {
  1379. return IpAddDelBoundary( ADD_BOUNDARY,
  1380. ppwcArguments,
  1381. dwCurrentIndex,
  1382. dwArgCount );
  1383. }
  1384. DWORD
  1385. HandleIpDelBoundary(
  1386. IN LPCWSTR pwszMachine,
  1387. IN OUT LPWSTR *ppwcArguments,
  1388. IN DWORD dwCurrentIndex,
  1389. IN DWORD dwArgCount,
  1390. IN DWORD dwFlags,
  1391. IN LPCVOID pvData,
  1392. OUT BOOL *pbDone
  1393. )
  1394. /*++
  1395. Routine Description:
  1396. Arguments:
  1397. ppwcArguments - Argument array
  1398. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  1399. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  1400. Return Value:
  1401. NO_ERROR
  1402. --*/
  1403. {
  1404. return IpAddDelBoundary( DELETE_BOUNDARY,
  1405. ppwcArguments,
  1406. dwCurrentIndex,
  1407. dwArgCount );
  1408. }
  1409. DWORD
  1410. ShowBoundaryInfoForInterface(
  1411. IN HANDLE hFile,
  1412. IN LPCWSTR pwszIfName,
  1413. OUT PDWORD pdwNumRows
  1414. )
  1415. /*++
  1416. Called by:
  1417. ShowBoundaryInfo()
  1418. --*/
  1419. {
  1420. DWORD dwErr,
  1421. dwBlkSize,
  1422. dwCount,
  1423. dwIfType,
  1424. dwNumParsed,
  1425. dwInd = 0,
  1426. dwCnt = 0,
  1427. dwSize = 0,
  1428. dwGlobalSize = 0,
  1429. dwIfLen = 0;
  1430. WCHAR wszIfDesc[MAX_INTERFACE_NAME_LEN + 1];
  1431. ULONG ulNumScopes = 0;
  1432. CHAR szAddr1[ ADDR_LENGTH ],
  1433. szAddr2[ ADDR_LENGTH ];
  1434. HANDLE hIfTransport = (HANDLE) NULL,
  1435. hTransport = (HANDLE) NULL;
  1436. PRTR_INFO_BLOCK_HEADER pibhIfInfo = (PRTR_INFO_BLOCK_HEADER) NULL,
  1437. pibhGlobalInfo = (PRTR_INFO_BLOCK_HEADER) NULL;
  1438. PMIB_BOUNDARYROW pimb;
  1439. PSCOPE_ENTRY pScope,
  1440. pScopes;
  1441. PBYTE pScopesBuffer;
  1442. SCOPE_NAME_BUFFER snScopeNameBuffer;
  1443. do
  1444. {
  1445. dwErr = IpmontrGetInfoBlockFromInterfaceInfo( pwszIfName,
  1446. IP_MCAST_BOUNDARY_INFO,
  1447. (PBYTE*)&pimb,
  1448. &dwBlkSize,
  1449. &dwCount,
  1450. &dwIfType );
  1451. if (dwErr is ERROR_NOT_FOUND)
  1452. dwErr = NO_ERROR;
  1453. if (dwErr isnot NO_ERROR)
  1454. return dwErr;
  1455. if ( !dwCount )
  1456. break;
  1457. dwErr = GetInterfaceDescription(pwszIfName,
  1458. wszIfDesc,
  1459. &dwNumParsed);
  1460. if (!dwNumParsed)
  1461. {
  1462. wcscpy(wszIfDesc, pwszIfName);
  1463. }
  1464. dwIfLen = wcslen(wszIfDesc);
  1465. //
  1466. // Retrieve the list of scopes in pScopes[]
  1467. //
  1468. pScopes = GetScopes( &ulNumScopes, &pScopesBuffer );
  1469. //
  1470. // Enumerate the boundaries
  1471. //
  1472. for ( dwCnt = 0; dwCnt < dwCount; dwCnt++ )
  1473. {
  1474. pScope = FindScopeByPrefix( pimb[dwCnt].dwGroupAddress,
  1475. pimb[dwCnt].dwGroupMask,
  1476. pScopes,
  1477. ulNumScopes );
  1478. strcpy( szAddr1,
  1479. inet_ntoa( *((struct in_addr *) &pimb[dwCnt].dwGroupAddress)
  1480. )
  1481. );
  1482. strcpy( szAddr2,
  1483. inet_ntoa( *((struct in_addr *) &pimb[dwCnt].dwGroupMask) )
  1484. );
  1485. // Copy prefix to snScopeNameBuffer
  1486. MakePrefixStringW(snScopeNameBuffer,
  1487. pimb[dwCnt].dwGroupAddress,
  1488. pimb[dwCnt].dwGroupMask);
  1489. if (hFile)
  1490. {
  1491. PWCHAR pwszQuoted = MakeQuotedString(wszIfDesc);
  1492. DisplayMessageT( DMP_BOUNDARY_INFO,
  1493. pwszQuoted,
  1494. szAddr1,
  1495. szAddr2,
  1496. (pScope && pScope->ulNumNames)?
  1497. pScope->snScopeNameBuffer : snScopeNameBuffer );
  1498. FreeQuotedString(pwszQuoted);
  1499. }
  1500. else
  1501. {
  1502. if ( !*pdwNumRows )
  1503. {
  1504. DisplayMessage( g_hModule, MSG_RTR_BOUNDARY_HDR );
  1505. }
  1506. if (dwIfLen <= 15)
  1507. {
  1508. DisplayMessage( g_hModule,
  1509. MSG_RTR_BOUNDARY_INFO_2,
  1510. wszIfDesc,
  1511. szAddr1,
  1512. szAddr2,
  1513. (pScope && pScope->ulNumNames)?
  1514. pScope->snScopeNameBuffer : snScopeNameBuffer );
  1515. }
  1516. else
  1517. {
  1518. DisplayMessage( g_hModule,
  1519. MSG_RTR_BOUNDARY_INFO_0,
  1520. wszIfDesc
  1521. );
  1522. DisplayMessage( g_hModule,
  1523. MSG_RTR_BOUNDARY_INFO_1,
  1524. szAddr1,
  1525. szAddr2,
  1526. (pScope && pScope->ulNumNames)?
  1527. pScope->snScopeNameBuffer : snScopeNameBuffer );
  1528. }
  1529. }
  1530. (*pdwNumRows) ++;
  1531. }
  1532. dwErr = NO_ERROR;
  1533. if (pScopes)
  1534. FREE(pScopes);
  1535. if (pScopesBuffer)
  1536. FREE(pScopesBuffer);
  1537. } while ( FALSE );
  1538. if ( pimb ) { FREE(pimb); }
  1539. return dwErr;
  1540. }
  1541. DWORD
  1542. HandleIpShowBoundary(
  1543. IN LPCWSTR pwszMachine,
  1544. IN OUT LPWSTR *ppwcArguments,
  1545. IN DWORD dwCurrentIndex,
  1546. IN DWORD dwArgCount,
  1547. IN DWORD dwFlags,
  1548. IN LPCVOID pvData,
  1549. OUT BOOL *pbDone
  1550. )
  1551. /*++
  1552. Routine Description:
  1553. Arguments:
  1554. ppwcArguments - Argument array
  1555. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  1556. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  1557. Return Value:
  1558. NO_ERROR
  1559. --*/
  1560. {
  1561. DWORD dwErr, dwTotal;
  1562. TAG_TYPE pttTags[] = {{TOKEN_NAME,FALSE,FALSE}};
  1563. WCHAR rgwcIfName[MAX_INTERFACE_NAME_LEN + 1];
  1564. DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
  1565. DWORD dwBlkSize, dwCount, dwIfType, i, dwNumParsed;
  1566. PBYTE pib, pibNew = NULL;
  1567. PMPR_INTERFACE_0 pmi0;
  1568. DWORD dwNumRows = 0;
  1569. // Do generic processing
  1570. dwErr = PreHandleCommand( ppwcArguments,
  1571. dwCurrentIndex,
  1572. dwArgCount,
  1573. pttTags,
  1574. sizeof(pttTags)/sizeof(TAG_TYPE),
  1575. 0,
  1576. 1,
  1577. rgdwTagType );
  1578. if (dwErr)
  1579. {
  1580. return dwErr;
  1581. }
  1582. // If interface specified, show boundaries for specified interface only.
  1583. if (dwArgCount > dwCurrentIndex)
  1584. {
  1585. DWORD BufLen = sizeof(rgwcIfName);
  1586. GetInterfaceName( ppwcArguments[dwCurrentIndex],
  1587. rgwcIfName,
  1588. BufLen,
  1589. &dwNumParsed );
  1590. dwErr = ShowBoundaryInfoForInterface( 0, rgwcIfName, &dwNumRows );
  1591. if (!dwNumRows)
  1592. {
  1593. DisplayMessage( g_hModule, MSG_IP_NO_ENTRIES );
  1594. }
  1595. return dwErr;
  1596. }
  1597. // No Interface specified. Enumerate interfaces and show
  1598. // boundaries for each interface.
  1599. //
  1600. // No interface name specified. List all interfaces under IP
  1601. //
  1602. dwErr = IpmontrInterfaceEnum((PBYTE *) &pmi0, &dwCount, &dwTotal);
  1603. if (dwErr isnot NO_ERROR)
  1604. {
  1605. DisplayError(g_hModule, dwErr);
  1606. return dwErr;
  1607. }
  1608. for ( i = 0; i < dwCount && dwErr is NO_ERROR; i++)
  1609. {
  1610. dwErr = ShowBoundaryInfoForInterface( 0,
  1611. pmi0[i].wszInterfaceName,
  1612. &dwNumRows );
  1613. if (dwErr is ERROR_NO_SUCH_INTERFACE)
  1614. {
  1615. dwErr = NO_ERROR;
  1616. }
  1617. }
  1618. if (!dwNumRows)
  1619. {
  1620. DisplayMessage( g_hModule, MSG_IP_NO_ENTRIES );
  1621. }
  1622. return dwErr;
  1623. }
  1624. //----------------------------------------------------------------------------
  1625. // PrintScope
  1626. //
  1627. //
  1628. //----------------------------------------------------------------------------
  1629. static VOID
  1630. PrintScope(
  1631. PMIB_OPAQUE_INFO prpcInfo,
  1632. PDWORD pdwLastAddr,
  1633. PDWORD pdwLastMask
  1634. )
  1635. {
  1636. TCHAR ptszAddr[ ADDR_LENGTH + 1 ],
  1637. ptszMask[ ADDR_LENGTH + 1 ],
  1638. ptszBuffer[ MAX_SCOPE_NAME_LEN + 40 ];
  1639. PMIB_IPMCAST_SCOPE pmims;
  1640. //
  1641. // get scope
  1642. //
  1643. pmims = (PMIB_IPMCAST_SCOPE) prpcInfo->rgbyData;
  1644. *pdwLastAddr = pmims-> dwGroupAddress;
  1645. MakeUnicodeIpAddr(ptszAddr,
  1646. inet_ntoa(*((struct in_addr *)(&pmims-> dwGroupAddress))));
  1647. *pdwLastMask = pmims-> dwGroupMask;
  1648. MakeUnicodeIpAddr(ptszMask,
  1649. inet_ntoa(*((struct in_addr *)(&pmims-> dwGroupMask))));
  1650. _stprintf(ptszBuffer, _T("%-15.15s %-15.15s %s"),
  1651. ptszAddr,
  1652. ptszMask,
  1653. pmims-> snNameBuffer
  1654. );
  1655. DisplayMessage( g_hModule,
  1656. MSG_MIB_SCOPE_INFO,
  1657. ptszBuffer
  1658. );
  1659. return;
  1660. }
  1661. //----------------------------------------------------------------------------
  1662. // PrintBoundary
  1663. //
  1664. //
  1665. //----------------------------------------------------------------------------
  1666. static VOID
  1667. PrintBoundary(
  1668. MIB_SERVER_HANDLE hMibServer,
  1669. PMIB_OPAQUE_INFO prpcInfo,
  1670. PDWORD pdwLastIfIndex,
  1671. PDWORD pdwLastAddr,
  1672. PDWORD pdwLastMask
  1673. )
  1674. {
  1675. WCHAR wszBuffer[MAX_INTERFACE_NAME_LEN+1];
  1676. DWORD BufLen = sizeof(wszBuffer);
  1677. TCHAR ptszAddr[ ADDR_LENGTH + 1 ],
  1678. ptszMask[ ADDR_LENGTH + 1 ];
  1679. PMIB_IPMCAST_BOUNDARY pmims;
  1680. //
  1681. // get boundary
  1682. //
  1683. pmims = (PMIB_IPMCAST_BOUNDARY) prpcInfo->rgbyData;
  1684. *pdwLastIfIndex = pmims-> dwIfIndex;
  1685. *pdwLastAddr = pmims-> dwGroupAddress;
  1686. MakeUnicodeIpAddr(ptszAddr,
  1687. inet_ntoa(*((struct in_addr *)(&pmims-> dwGroupAddress))));
  1688. *pdwLastMask = pmims-> dwGroupMask;
  1689. MakeUnicodeIpAddr(ptszMask,
  1690. inet_ntoa(*((struct in_addr *)(&pmims-> dwGroupMask))));
  1691. IpmontrGetFriendlyNameFromIfIndex( hMibServer,
  1692. pmims->dwIfIndex,
  1693. wszBuffer,
  1694. BufLen );
  1695. DisplayMessageToConsole( g_hModule, g_hConsole,
  1696. MSG_MIB_BOUNDARY_INFO,
  1697. ptszAddr,
  1698. ptszMask,
  1699. wszBuffer
  1700. );
  1701. return;
  1702. }
  1703. #if 0
  1704. //----------------------------------------------------------------------------
  1705. // GetPrintScopeInfo
  1706. //
  1707. //----------------------------------------------------------------------------
  1708. DWORD
  1709. GetPrintScopeInfo(
  1710. MIB_SERVER_HANDLE hMIBServer
  1711. )
  1712. {
  1713. DWORD dwErr, dwOutEntrySize = 0, dwQuerySize,
  1714. dwLastAddr = 0,
  1715. dwLastMask = 0, i;
  1716. PMIB_OPAQUE_INFO pRpcInfo = NULL;
  1717. PMIB_IPMCAST_SCOPE pmims = NULL;
  1718. PMIB_OPAQUE_QUERY pQuery;
  1719. do
  1720. {
  1721. //
  1722. // allocate and setup query structure
  1723. //
  1724. dwQuerySize = sizeof( MIB_OPAQUE_QUERY ) + sizeof(DWORD);
  1725. pQuery = (PMIB_OPAQUE_QUERY) HeapAlloc(
  1726. GetProcessHeap(), 0, dwQuerySize
  1727. );
  1728. if ( pQuery == NULL )
  1729. {
  1730. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1731. DisplayMessage( g_hModule, ERROR_CONFIG, dwErr );
  1732. break;
  1733. }
  1734. pQuery->dwVarId = MCAST_SCOPE;
  1735. for( i = 0; i < 2; i++ )
  1736. {
  1737. pQuery->rgdwVarIndex[i] = 0;
  1738. }
  1739. //
  1740. // get first scope
  1741. //
  1742. dwErr = MibGetFirst(
  1743. PID_IP,
  1744. IPRTRMGR_PID,
  1745. (PVOID) pQuery,
  1746. dwQuerySize,
  1747. (PVOID *) &pRpcInfo,
  1748. &dwOutEntrySize
  1749. );
  1750. if ( dwErr != NO_ERROR )
  1751. {
  1752. DisplayError( g_hModule, dwErr );
  1753. break;
  1754. }
  1755. //
  1756. // if no scopes are present print a message to tell the user
  1757. //
  1758. pmims = (PMIB_IPMCAST_SCOPE)( pRpcInfo->rgbyData );
  1759. #if 0
  1760. if ( pTable->dwNumEntries is 0 )
  1761. {
  1762. //
  1763. // no scopes present.
  1764. //
  1765. DisplayMessage( g_hModule, MSG_MIB_NO_SCOPES );
  1766. break;
  1767. }
  1768. #endif
  1769. //
  1770. // print the scope
  1771. //
  1772. DisplayMessage( g_hModule, MSG_MIB_SCOPE_HDR );
  1773. PrintScope( pRpcInfo, &dwLastAddr, &dwLastMask );
  1774. MprAdminMIBBufferFree( pRpcInfo );
  1775. pRpcInfo = NULL;
  1776. dwOutEntrySize = 0;
  1777. //
  1778. // while there are more scopes
  1779. // get next scope
  1780. // print it.
  1781. //
  1782. pQuery->rgdwVarIndex[ 0 ] = dwLastAddr;
  1783. pQuery->rgdwVarIndex[ 1 ] = dwLastMask;
  1784. while ( ( dwErr = MibGetNext(
  1785. PID_IP, IPRTRMGR_PID, (PVOID) pQuery,
  1786. dwQuerySize, (PVOID *) &pRpcInfo, &dwOutEntrySize
  1787. ) ) == NO_ERROR )
  1788. {
  1789. //
  1790. // if no scopes are present quit
  1791. //
  1792. pmims = (PMIB_IPMCAST_SCOPE)( pRpcInfo->rgbyData );
  1793. #if 0
  1794. pTable = (PMIB_IPMCAST_SCOPE)( pRpcInfo->rgbyData );
  1795. if ( pTable->dwNumEntries is 0 )
  1796. {
  1797. break;
  1798. }
  1799. #endif
  1800. //
  1801. // print the scope
  1802. //
  1803. PrintScope( pRpcInfo, &dwLastAddr, &dwLastMask );
  1804. MprAdminMIBBufferFree( pRpcInfo );
  1805. pRpcInfo = NULL;
  1806. dwOutEntrySize = 0;
  1807. //
  1808. // set up the next query
  1809. //
  1810. pQuery->rgdwVarIndex[ 0 ] = dwLastAddr;
  1811. pQuery->rgdwVarIndex[ 1 ] = dwLastMask;
  1812. }
  1813. if ( dwErr != NO_ERROR )
  1814. {
  1815. DisplayMessage( g_hModule, ERROR_ADMIN, dwErr );
  1816. }
  1817. } while ( FALSE );
  1818. return dwErr;
  1819. }
  1820. #endif
  1821. //----------------------------------------------------------------------------
  1822. // GetPrintBoundaryInfo
  1823. //
  1824. //----------------------------------------------------------------------------
  1825. DWORD
  1826. GetPrintBoundaryInfo(
  1827. MIB_SERVER_HANDLE hMIBServer
  1828. )
  1829. {
  1830. DWORD dwErr, dwOutEntrySize = 0, dwQuerySize,
  1831. dwLastIfIndex = 0, dwLastAddr = 0,
  1832. dwLastMask = 0, i;
  1833. PMIB_OPAQUE_INFO pRpcInfo = NULL;
  1834. PMIB_IPMCAST_BOUNDARY pmims = NULL;
  1835. PMIB_OPAQUE_QUERY pQuery;
  1836. do
  1837. {
  1838. //
  1839. // allocate and setup query structure
  1840. //
  1841. dwQuerySize = sizeof( MIB_OPAQUE_QUERY ) + 2 * sizeof(DWORD);
  1842. pQuery = (PMIB_OPAQUE_QUERY) HeapAlloc(
  1843. GetProcessHeap(), 0, dwQuerySize
  1844. );
  1845. if ( pQuery == NULL )
  1846. {
  1847. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1848. DisplayMessage( g_hModule, ERROR_CONFIG, dwErr );
  1849. break;
  1850. }
  1851. pQuery->dwVarId = MCAST_BOUNDARY;
  1852. for( i = 0; i < 2; i++ )
  1853. {
  1854. pQuery->rgdwVarIndex[i] = 0;
  1855. }
  1856. //
  1857. // get first boundary
  1858. //
  1859. dwErr = MibGetFirst(
  1860. PID_IP,
  1861. IPRTRMGR_PID,
  1862. (PVOID) pQuery,
  1863. dwQuerySize,
  1864. (PVOID *) &pRpcInfo,
  1865. &dwOutEntrySize
  1866. );
  1867. if ( dwErr != NO_ERROR )
  1868. {
  1869. DisplayError( g_hModule, dwErr );
  1870. break;
  1871. }
  1872. //
  1873. // if no boundaries are present print a message to tell the user
  1874. //
  1875. pmims = (PMIB_IPMCAST_BOUNDARY)( pRpcInfo->rgbyData );
  1876. #if 0
  1877. if ( pTable->dwNumEntries is 0 )
  1878. {
  1879. //
  1880. // no boundaries present.
  1881. //
  1882. DisplayMessage( g_hModule, MSG_MIB_NO_BOUNDARIES );
  1883. break;
  1884. }
  1885. #endif
  1886. //
  1887. // print the boundary
  1888. //
  1889. DisplayMessageToConsole( g_hModule, g_hConsole, MSG_MIB_BOUNDARY_HDR );
  1890. PrintBoundary( hMIBServer,
  1891. pRpcInfo, &dwLastIfIndex, &dwLastAddr, &dwLastMask );
  1892. MprAdminMIBBufferFree( pRpcInfo );
  1893. pRpcInfo = NULL;
  1894. dwOutEntrySize = 0;
  1895. //
  1896. // while there are more boundaries
  1897. // get next boundary
  1898. // print it.
  1899. //
  1900. pQuery->rgdwVarIndex[ 0 ] = dwLastIfIndex;
  1901. pQuery->rgdwVarIndex[ 1 ] = dwLastAddr;
  1902. pQuery->rgdwVarIndex[ 2 ] = dwLastMask;
  1903. while ( ( dwErr = MibGetNext(
  1904. PID_IP, IPRTRMGR_PID, (PVOID) pQuery,
  1905. dwQuerySize, (PVOID *) &pRpcInfo, &dwOutEntrySize
  1906. ) ) == NO_ERROR )
  1907. {
  1908. //
  1909. // if no boundaries are present quit
  1910. //
  1911. pmims = (PMIB_IPMCAST_BOUNDARY)( pRpcInfo->rgbyData );
  1912. #if 0
  1913. pTable = (PMIB_IPMCAST_BOUNDARY)( pRpcInfo->rgbyData );
  1914. if ( pTable->dwNumEntries is 0 )
  1915. {
  1916. break;
  1917. }
  1918. #endif
  1919. //
  1920. // print the boundary
  1921. //
  1922. PrintBoundary(
  1923. hMIBServer,
  1924. pRpcInfo, &dwLastIfIndex, &dwLastAddr, &dwLastMask
  1925. );
  1926. MprAdminMIBBufferFree( pRpcInfo );
  1927. pRpcInfo = NULL;
  1928. dwOutEntrySize = 0;
  1929. //
  1930. // set up the next query
  1931. //
  1932. pQuery->rgdwVarIndex[ 0 ] = dwLastIfIndex;
  1933. pQuery->rgdwVarIndex[ 1 ] = dwLastAddr;
  1934. pQuery->rgdwVarIndex[ 2 ] = dwLastMask;
  1935. }
  1936. if ( dwErr != NO_ERROR )
  1937. {
  1938. DisplayMessage( g_hModule, ERROR_ADMIN, dwErr );
  1939. }
  1940. } while ( FALSE );
  1941. return dwErr;
  1942. }