Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1444 lines
41 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. net\routing\netsh\ip\showmib.c
  5. Abstract:
  6. Fns to parse and show MIB information
  7. Author:
  8. v raman
  9. Revision History:
  10. Anand Mahalingam
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. enum MFETYPES
  15. {
  16. NegativeMfe = 0, PositiveMfe, Both
  17. };
  18. HANDLE g_hConsole, g_hStdOut;
  19. MIB_OBJECT_PARSER MIBObjectMap[] =
  20. {
  21. // {TOKEN_MIB_OBJECT_IPFORWARD,3,GetMIBIpFwdIndex},
  22. {TOKEN_MIB_OBJECT_MFE,0,NULL},
  23. {TOKEN_MIB_OBJECT_MFESTATS,0,NULL},
  24. {TOKEN_MIB_OBJECT_BOUNDARY,0,NULL},
  25. {TOKEN_MIB_OBJECT_SCOPE,0,NULL},
  26. {TOKEN_MIB_OBJECT_RTMDESTINATIONS,0,NULL},
  27. {TOKEN_MIB_OBJECT_RTMROUTES,0,NULL}
  28. };
  29. ULONG g_ulNumMibObjects = sizeof(MIBObjectMap)/sizeof(MIB_OBJECT_PARSER);
  30. MAGIC_TABLE MIBVar[] = {
  31. // {IP_FORWARDROW, PrintIpForwardRow},
  32. // {IP_FORWARDTABLE, PrintIpForwardTable},
  33. {MCAST_MFE, NULL},
  34. {MCAST_MFE, NULL},
  35. {MCAST_MFE_STATS, NULL},
  36. {MCAST_MFE_STATS, NULL},
  37. {MCAST_BOUNDARY, NULL},
  38. {MCAST_BOUNDARY, NULL},
  39. {MCAST_SCOPE, NULL},
  40. {MCAST_SCOPE, NULL},
  41. {0, NULL}, // destinations, unused
  42. {0, NULL}, // destinations, unused
  43. {0, NULL}, // routes, unused
  44. {0, NULL}, // routes, unused
  45. };
  46. #if 0
  47. DWORD
  48. GetMIBIpFwdIndex(
  49. IN PTCHAR *ppwcArguments,
  50. IN DWORD dwCurrentIndex,
  51. OUT PDWORD pdwIndices,
  52. OUT PDWORD pdwNumParsed
  53. )
  54. /*++
  55. Routine Description:
  56. Gets the IP forward index
  57. Arguments:
  58. ppwcArguments - Argument array
  59. dwCurrentIndex - Index of the first argument in array
  60. pdwIndices - Indices specified in command
  61. pdwNumParsed - Number of indices in command
  62. Return Value:
  63. NO_ERROR
  64. --*/
  65. {
  66. DWORD dwErr = GetIpAddress(ppwcArguments[dwCurrentIndex], &pdwIndices[0]);
  67. if (dwErr isnot NO_ERROR)
  68. {
  69. return dwErr;
  70. }
  71. pdwIndices[1] = _tcstoul(ppwcArguments[dwCurrentIndex + 1],NULL,10);
  72. dwErr = GetIpAddress(ppwcArguments[dwCurrentIndex + 2], &pdwIndices[2]);
  73. pdwIndices[3] = 0;
  74. *pdwNumParsed = 4;
  75. return dwErr;
  76. }
  77. #endif
  78. DWORD
  79. HandleIpMibShowObject(
  80. IN LPCWSTR pwszMachine,
  81. IN OUT LPWSTR *ppwcArguments,
  82. IN DWORD dwCurrentIndex,
  83. IN DWORD dwArgCount,
  84. IN DWORD dwFlags,
  85. IN LPCVOID pvData,
  86. OUT BOOL *pbDone
  87. )
  88. /*++
  89. Routine Description:
  90. Parses command to get MIB object and optional parameters
  91. Arguments:
  92. Return Value:
  93. --*/
  94. {
  95. DWORD dwIndices[MAX_NUM_INDICES];
  96. DWORD dwNumParsed = 0;
  97. PMIB_OPAQUE_QUERY pQuery = NULL;
  98. PMIB_OPAQUE_INFO pRpcInfo;
  99. DWORD dwQuerySize;
  100. BOOL bFound = FALSE,bOptPresent = FALSE;
  101. DWORD dwRefreshRate;
  102. DWORD dwOutEntrySize;
  103. DWORD i,dwResult = NO_ERROR,dwErr;
  104. DWORD dwMIBIndex, dwIndex;
  105. BOOL bIndex = FALSE, dwType;
  106. DWORD dwRR = 0, dwInd = 0;
  107. HANDLE hMib;
  108. if ( ! IsRouterRunning() )
  109. {
  110. if (g_pwszRouter)
  111. {
  112. DisplayMessage(g_hModule,
  113. MSG_IP_REMOTE_ROUTER_NOT_RUNNING,
  114. g_pwszRouter);
  115. }
  116. else
  117. {
  118. DisplayMessage(g_hModule,
  119. MSG_IP_LOCAL_ROUTER_NOT_RUNNING);
  120. }
  121. return NO_ERROR;
  122. }
  123. //
  124. // Match MIB object
  125. //
  126. ppwcArguments += (dwCurrentIndex-1);
  127. dwArgCount -= (dwCurrentIndex-1);
  128. dwCurrentIndex = 1;
  129. //DEBUG2("In IP MIB Show : %s\n",ppwcArguments[0]);
  130. for (i = 0; i < sizeof(MIBObjectMap)/sizeof(MIB_OBJECT_PARSER); i++)
  131. {
  132. if (MatchToken(ppwcArguments[0],MIBObjectMap[i].pwszMIBObj))
  133. {
  134. dwIndex = i;
  135. bFound = TRUE;
  136. DEBUG("found");
  137. break;
  138. }
  139. }
  140. if (!bFound)
  141. {
  142. return ERROR_CMD_NOT_FOUND;
  143. }
  144. if (!MatchToken( MIBObjectMap[dwIndex].pwszMIBObj,
  145. TOKEN_MIB_OBJECT_RTMDESTINATIONS)
  146. && !MatchToken( MIBObjectMap[dwIndex].pwszMIBObj,
  147. TOKEN_MIB_OBJECT_RTMROUTES))
  148. {
  149. dwErr = GetMibTagToken(&ppwcArguments[1],
  150. dwArgCount - 1,
  151. MIBObjectMap[dwIndex].dwMinOptArg,
  152. &dwRR,
  153. &bIndex,
  154. &dwInd);
  155. if (dwErr isnot NO_ERROR)
  156. {
  157. return ERROR_INVALID_SYNTAX;
  158. }
  159. }
  160. if (bIndex)
  161. {
  162. dwMIBIndex = dwIndex * 2;
  163. bOptPresent = TRUE;
  164. }
  165. else
  166. {
  167. dwMIBIndex = dwIndex * 2 + 1;
  168. }
  169. //
  170. // Convert refresh rate to msec
  171. //
  172. dwRR *= 1000;
  173. if (!InitializeConsole(&dwRR, &hMib, &g_hConsole))
  174. {
  175. return ERROR_INIT_DISPLAY;
  176. }
  177. //
  178. // Query the MIB
  179. //
  180. pQuery = NULL;
  181. for ( ; ; )
  182. {
  183. if(dwRR)
  184. {
  185. DisplayMessageToConsole(g_hModule,
  186. g_hConsole,
  187. MSG_CTRL_C_TO_QUIT);
  188. }
  189. if (MatchToken(MIBObjectMap[dwIndex].pwszMIBObj,
  190. TOKEN_MIB_OBJECT_BOUNDARY))
  191. {
  192. dwResult = GetPrintBoundaryInfo(g_hMIBServer);
  193. }
  194. else if (MIBVar[ dwMIBIndex ].dwId is MCAST_MFE)
  195. {
  196. //
  197. // Call the special function
  198. //
  199. GetMfe(
  200. g_hMIBServer, bIndex, ppwcArguments + 1, dwArgCount - 1, FALSE
  201. );
  202. }
  203. else if(MIBVar[ dwMIBIndex ].dwId is MCAST_MFE_STATS)
  204. {
  205. //
  206. // Call the special function
  207. //
  208. GetMfe(
  209. g_hMIBServer, bIndex, ppwcArguments + 1, dwArgCount - 1, TRUE
  210. );
  211. }
  212. else
  213. {
  214. //
  215. // For all else, the generic one is just fine
  216. //
  217. if (!(dwMIBIndex % 2))
  218. {
  219. (*MIBObjectMap[dwIndex].pfnMIBObjParser)(ppwcArguments,
  220. 1,
  221. dwIndices,
  222. &dwNumParsed);
  223. }
  224. dwQuerySize = ( sizeof( MIB_OPAQUE_QUERY ) - sizeof( DWORD ) ) +
  225. (dwNumParsed) * sizeof(DWORD);
  226. pQuery = (PMIB_OPAQUE_QUERY)HeapAlloc(GetProcessHeap(),
  227. 0,
  228. dwQuerySize);
  229. if (pQuery is NULL)
  230. {
  231. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  232. DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY);
  233. return dwErr;
  234. }
  235. pQuery->dwVarId = MIBVar[dwMIBIndex].dwId;
  236. for( i = 0; i < dwNumParsed; i++ )
  237. {
  238. pQuery->rgdwVarIndex[i] = dwIndices[i];
  239. }
  240. dwResult = MibGet( PID_IP,
  241. IPRTRMGR_PID,
  242. (PVOID) pQuery,
  243. dwQuerySize,
  244. (PVOID *) &pRpcInfo,
  245. &dwOutEntrySize );
  246. if ( dwResult isnot NO_ERROR )
  247. {
  248. DisplayMessage(g_hModule, MSG_IP_DIM_ERROR, dwResult );
  249. return dwResult;
  250. }
  251. if ( pRpcInfo is NULL )
  252. {
  253. DisplayMessage(g_hModule, MSG_IP_NO_ENTRIES );
  254. return dwResult;
  255. }
  256. (*MIBVar[dwMIBIndex].pfnPrintFunction)(g_hMIBServer, pRpcInfo);
  257. MprAdminMIBBufferFree( (PVOID) pRpcInfo );
  258. }
  259. if(pQuery != NULL )
  260. {
  261. HeapFree(GetProcessHeap(),0,pQuery);
  262. }
  263. if (!RefreshConsole(hMib, g_hConsole, dwRR))
  264. {
  265. break;
  266. }
  267. }
  268. return dwResult;
  269. }
  270. #if 0
  271. VOID
  272. PrintIpForwardTable(
  273. MIB_SERVER_HANDLE hMibServer,
  274. PMIB_OPAQUE_INFO prpcInfo
  275. )
  276. /*++
  277. Routine Description:
  278. Prints IP forward table.
  279. Arguments:
  280. Return Value:
  281. --*/
  282. {
  283. WCHAR wszFriendlyName[MAX_INTERFACE_NAME_LEN + 1];
  284. PMIB_IPFORWARDTABLE lprpcTable = (PMIB_IPFORWARDTABLE)(prpcInfo->rgbyData);
  285. TCHAR tszMask[ADDR_LENGTH + 1],
  286. tszDest[ADDR_LENGTH + 1],
  287. tszNextHop[ADDR_LENGTH + 1];
  288. PTCHAR ptszType, ptszProto;
  289. DWORD i, dwErr = NO_ERROR;
  290. DisplayMessageToConsole(g_hModule, g_hConsole,MSG_MIB_FORWARD_HDR);
  291. if(lprpcTable->dwNumEntries is 0)
  292. {
  293. DisplayMessageToConsole(g_hModule, g_hConsole,MSG_IP_NO_ENTRIES);
  294. return;
  295. }
  296. for(i = 0; i < lprpcTable->dwNumEntries; i++)
  297. {
  298. switch(lprpcTable->table[i].dwForwardProto)
  299. {
  300. case MIB_IPPROTO_LOCAL:
  301. {
  302. ptszProto = MakeString(g_hModule, STRING_LOCAL);
  303. break;
  304. }
  305. case MIB_IPPROTO_NETMGMT:
  306. {
  307. ptszProto = MakeString(g_hModule, STRING_NETMGMT);
  308. break;
  309. }
  310. case MIB_IPPROTO_ICMP:
  311. {
  312. ptszProto = MakeString(g_hModule, STRING_ICMP);
  313. break;
  314. }
  315. case MIB_IPPROTO_EGP:
  316. {
  317. ptszProto = MakeString(g_hModule, STRING_EGP);
  318. break;
  319. }
  320. case MIB_IPPROTO_GGP:
  321. {
  322. ptszProto = MakeString(g_hModule, STRING_GGP);
  323. break;
  324. }
  325. case MIB_IPPROTO_HELLO:
  326. {
  327. ptszProto = MakeString(g_hModule, STRING_HELLO);
  328. break;
  329. }
  330. case MIB_IPPROTO_RIP:
  331. {
  332. ptszProto = MakeString(g_hModule, STRING_RIP);
  333. break;
  334. }
  335. case MIB_IPPROTO_IS_IS:
  336. {
  337. ptszProto = MakeString(g_hModule, STRING_IS_IS);
  338. break;
  339. }
  340. case MIB_IPPROTO_ES_IS:
  341. {
  342. ptszProto = MakeString(g_hModule, STRING_ES_IS);
  343. break;
  344. }
  345. case MIB_IPPROTO_CISCO:
  346. {
  347. ptszProto = MakeString(g_hModule, STRING_CISCO);
  348. break;
  349. }
  350. case MIB_IPPROTO_BBN:
  351. {
  352. ptszProto = MakeString(g_hModule, STRING_BBN);
  353. break;
  354. }
  355. case MIB_IPPROTO_OSPF:
  356. {
  357. ptszProto = MakeString(g_hModule, STRING_OSPF);
  358. break;
  359. }
  360. case MIB_IPPROTO_BGP:
  361. {
  362. ptszProto = MakeString(g_hModule, STRING_BGP);
  363. break;
  364. }
  365. case MIB_IPPROTO_OTHER:
  366. default:
  367. {
  368. ptszProto = MakeString(g_hModule, STRING_OTHER);
  369. break;
  370. }
  371. }
  372. switch(lprpcTable->table[i].dwForwardType)
  373. {
  374. case MIB_IPROUTE_TYPE_INVALID:
  375. {
  376. ptszType = MakeString(g_hModule, STRING_INVALID);
  377. break;
  378. }
  379. case MIB_IPROUTE_TYPE_DIRECT:
  380. {
  381. ptszType = MakeString(g_hModule, STRING_DIRECT);
  382. break;
  383. }
  384. case MIB_IPROUTE_TYPE_INDIRECT:
  385. {
  386. ptszType = MakeString(g_hModule, STRING_INDIRECT);
  387. break;
  388. }
  389. case MIB_IPROUTE_TYPE_OTHER:
  390. default:
  391. {
  392. ptszType = MakeString(g_hModule, STRING_OTHER);
  393. break;
  394. }
  395. }
  396. MakeUnicodeIpAddr(tszDest,
  397. inet_ntoa(*((struct in_addr *)
  398. (&lprpcTable->table[i].dwForwardDest))));
  399. MakeUnicodeIpAddr(tszMask,
  400. inet_ntoa(*((struct in_addr *)
  401. (&lprpcTable->table[i].dwForwardMask))));
  402. MakeUnicodeIpAddr(tszNextHop,
  403. inet_ntoa(*((struct in_addr *)
  404. (&lprpcTable->table[i].dwForwardNextHop))));
  405. dwErr = IpmontrGetFriendlyNameFromIfIndex(
  406. hMibServer,
  407. lprpcTable->table[i].dwForwardIfIndex,
  408. wszFriendlyName,
  409. sizeof(wszFriendlyName) );
  410. DisplayMessageToConsole(g_hModule, g_hConsole,MSG_MIB_FORWARD_ENTRY,
  411. tszDest,
  412. tszMask,
  413. lprpcTable->table[i].dwForwardPolicy,
  414. tszNextHop,
  415. wszFriendlyName,
  416. ptszType,
  417. ptszProto,
  418. lprpcTable->table[i].dwForwardAge,
  419. lprpcTable->table[i].dwForwardNextHopAS,
  420. lprpcTable->table[i].dwForwardMetric1,
  421. lprpcTable->table[i].dwForwardMetric2,
  422. lprpcTable->table[i].dwForwardMetric3,
  423. lprpcTable->table[i].dwForwardMetric4,
  424. lprpcTable->table[i].dwForwardMetric5);
  425. FreeString(ptszType);
  426. FreeString(ptszProto);
  427. }
  428. }
  429. VOID
  430. PrintIpForwardRow(
  431. MIB_SERVER_HANDLE hMibServer,
  432. PMIB_OPAQUE_INFO prpcInfo
  433. )
  434. /*++
  435. Routine Description:
  436. Prints Ip forward table row.
  437. Arguments:
  438. Return Value:
  439. --*/
  440. {
  441. WCHAR wszFriendlyName[MAX_INTERFACE_NAME_LEN + 1];
  442. PMIB_IPFORWARDROW ireRow = (PMIB_IPFORWARDROW)(prpcInfo->rgbyData);
  443. TCHAR tszMask[ADDR_LENGTH + 1],
  444. tszDest[ADDR_LENGTH + 1],
  445. tszNextHop[ADDR_LENGTH + 1];
  446. PTCHAR ptszType, ptszProto;
  447. DWORD dwErr = NO_ERROR;
  448. DisplayMessageToConsole(g_hModule, g_hConsole,MSG_MIB_FORWARD_HDR);
  449. switch(ireRow->dwForwardProto)
  450. {
  451. case MIB_IPPROTO_LOCAL:
  452. {
  453. ptszProto = MakeString(g_hModule, STRING_LOCAL);
  454. break;
  455. }
  456. case MIB_IPPROTO_NETMGMT:
  457. {
  458. ptszProto = MakeString(g_hModule, STRING_NETMGMT);
  459. break;
  460. }
  461. case MIB_IPPROTO_ICMP:
  462. {
  463. ptszProto = MakeString(g_hModule, STRING_ICMP);
  464. break;
  465. }
  466. case MIB_IPPROTO_EGP:
  467. {
  468. ptszProto = MakeString(g_hModule, STRING_EGP);
  469. break;
  470. }
  471. case MIB_IPPROTO_GGP:
  472. {
  473. ptszProto = MakeString(g_hModule, STRING_GGP);
  474. break;
  475. }
  476. case MIB_IPPROTO_HELLO:
  477. {
  478. ptszProto = MakeString(g_hModule, STRING_HELLO);
  479. break;
  480. }
  481. case MIB_IPPROTO_RIP:
  482. {
  483. ptszProto = MakeString(g_hModule, STRING_RIP);
  484. break;
  485. }
  486. case MIB_IPPROTO_IS_IS:
  487. {
  488. ptszProto = MakeString(g_hModule, STRING_IS_IS);
  489. break;
  490. }
  491. case MIB_IPPROTO_ES_IS:
  492. {
  493. ptszProto = MakeString(g_hModule, STRING_ES_IS);
  494. break;
  495. }
  496. case MIB_IPPROTO_CISCO:
  497. {
  498. ptszProto = MakeString(g_hModule, STRING_CISCO);
  499. break;
  500. }
  501. case MIB_IPPROTO_BBN:
  502. {
  503. ptszProto = MakeString(g_hModule, STRING_BBN);
  504. break;
  505. }
  506. case MIB_IPPROTO_OSPF:
  507. {
  508. ptszProto = MakeString(g_hModule, STRING_OSPF);
  509. break;
  510. }
  511. case MIB_IPPROTO_BGP:
  512. {
  513. ptszProto = MakeString(g_hModule, STRING_BGP);
  514. break;
  515. }
  516. case MIB_IPPROTO_OTHER:
  517. default:
  518. {
  519. ptszProto = MakeString(g_hModule, STRING_OTHER);
  520. break;
  521. }
  522. }
  523. switch(ireRow->dwForwardType)
  524. {
  525. case MIB_IPROUTE_TYPE_INVALID:
  526. {
  527. ptszType = MakeString(g_hModule, STRING_INVALID);
  528. break;
  529. }
  530. case MIB_IPROUTE_TYPE_DIRECT:
  531. {
  532. ptszType = MakeString(g_hModule, STRING_DIRECT);
  533. break;
  534. }
  535. case MIB_IPROUTE_TYPE_INDIRECT:
  536. {
  537. ptszType = MakeString(g_hModule, STRING_INDIRECT);
  538. break;
  539. }
  540. case MIB_IPROUTE_TYPE_OTHER:
  541. default:
  542. {
  543. ptszType = MakeString(g_hModule, STRING_OTHER);
  544. break;
  545. }
  546. }
  547. MakeUnicodeIpAddr(tszDest,
  548. inet_ntoa(*((struct in_addr *)
  549. (&ireRow->dwForwardDest))));
  550. MakeUnicodeIpAddr(tszMask,
  551. inet_ntoa(*((struct in_addr *)
  552. (&ireRow->dwForwardMask))));
  553. MakeUnicodeIpAddr(tszNextHop,
  554. inet_ntoa(*((struct in_addr *)
  555. (&ireRow->dwForwardNextHop))));
  556. dwErr = IpmontrGetFriendlyNameFromIfIndex( hMibServer,
  557. ireRow->dwForwardIfIndex,
  558. wszFriendlyName,
  559. sizeof(wszFriendlyName) );
  560. DisplayMessageToConsole(g_hModule, g_hConsole,MSG_MIB_FORWARD_ENTRY,
  561. tszDest,
  562. tszMask,
  563. ireRow->dwForwardPolicy,
  564. tszNextHop,
  565. wszFriendlyName,
  566. ptszType,
  567. ptszProto,
  568. ireRow->dwForwardAge,
  569. ireRow->dwForwardNextHopAS,
  570. ireRow->dwForwardMetric1,
  571. ireRow->dwForwardMetric2,
  572. ireRow->dwForwardMetric3,
  573. ireRow->dwForwardMetric4,
  574. ireRow->dwForwardMetric5);
  575. FreeString(ptszType);
  576. FreeString(ptszProto);
  577. }
  578. #endif
  579. VOID
  580. PrintMfeTable(
  581. MIB_SERVER_HANDLE hMibServer,
  582. PMIB_OPAQUE_INFO prpcInfo,
  583. PDWORD pdwLastGrp,
  584. PDWORD pdwLastSrc,
  585. PDWORD pdwLastSrcMask,
  586. DWORD dwRangeGrp,
  587. DWORD dwRangeGrpMask,
  588. DWORD dwRangeSrc,
  589. DWORD dwRangeSrcMask,
  590. DWORD dwType,
  591. PBOOL pbDone
  592. )
  593. /*++
  594. Routine Description:
  595. Prints MFE table information.
  596. Arguments:
  597. Return Value:
  598. --*/
  599. {
  600. WCHAR wszFriendlyName[MAX_INTERFACE_NAME_LEN + 1];
  601. INT iCmp;
  602. DWORD i, j, dwErr = NO_ERROR;
  603. TCHAR ptszSource[ADDR_LENGTH + 1];
  604. TCHAR ptszGroup[ADDR_LENGTH + 1];
  605. TCHAR ptszUpstrm[ADDR_LENGTH + 1];
  606. TCHAR ptszBuffer[80];
  607. TCHAR ptszIf[18 + 1];
  608. PMIB_MFE_TABLE pTable;
  609. PMIB_IPMCAST_MFE pmimm;
  610. pTable = ( PMIB_MFE_TABLE )( prpcInfo-> rgbyData );
  611. if ( pTable->dwNumEntries is 0 )
  612. {
  613. DisplayMessageToConsole( g_hModule, g_hConsole,MSG_MIB_NO_MFES );
  614. return;
  615. }
  616. pmimm = pTable-> table;
  617. for( i = 0; i < pTable->dwNumEntries; i++ )
  618. {
  619. *pdwLastGrp = pmimm-> dwGroup;
  620. *pdwLastSrc = pmimm-> dwSource ;
  621. *pdwLastSrcMask = pmimm-> dwSrcMask ;
  622. //
  623. // Check if the MFEs are in the range provided
  624. //
  625. if ( dwRangeGrp && dwRangeGrpMask &&
  626. ( ( dwRangeGrp & dwRangeGrpMask ) !=
  627. ( pmimm-> dwGroup & dwRangeGrpMask ) ) )
  628. {
  629. *pbDone = TRUE;
  630. break;
  631. }
  632. if ( dwRangeSrc && dwRangeSrcMask &&
  633. ( ( dwRangeSrc & dwRangeSrcMask ) !=
  634. ( pmimm-> dwSource & dwRangeSrcMask ) ) )
  635. {
  636. continue;
  637. }
  638. if ( ( dwType == Both ) ||
  639. ( ( dwType == PositiveMfe ) && ( pmimm-> ulNumOutIf ) ) ||
  640. ( ( dwType == NegativeMfe ) && ( !pmimm-> ulNumOutIf ) ) )
  641. {
  642. MakePrefixStringW( ptszGroup, pmimm-> dwGroup, 0xFFFFFFFF );
  643. MakePrefixStringW( ptszSource, pmimm-> dwSource, pmimm-> dwSrcMask );
  644. MakeAddressStringW( ptszUpstrm, pmimm-> dwUpStrmNgbr );
  645. IpmontrGetFriendlyNameFromIfIndex(
  646. hMibServer, pmimm-> dwInIfIndex, wszFriendlyName,
  647. sizeof(wszFriendlyName)
  648. );
  649. if ( wcslen(wszFriendlyName) < 18 )
  650. {
  651. wsprintf( ptszIf, L"%-18.18s", wszFriendlyName );
  652. }
  653. else
  654. {
  655. wsprintf(
  656. ptszIf, L"%-12.12s...%-3.3s", wszFriendlyName,
  657. &wszFriendlyName[wcslen(wszFriendlyName) - 3]
  658. );
  659. }
  660. wsprintf(
  661. ptszBuffer, L"\n%18.18s %18.18s %-6.6s %-18.18s %15.15s",
  662. ptszGroup, ptszSource,
  663. GetProtoProtoString(
  664. PROTO_TYPE_MCAST, 0,
  665. pmimm-> dwInIfProtocol
  666. ),
  667. ptszIf, ptszUpstrm
  668. );
  669. DisplayMessageToConsole(
  670. g_hModule, g_hConsole, MSG_MIB_MFE, ptszBuffer
  671. );
  672. for (j = 0; j < pmimm-> ulNumOutIf; j++)
  673. {
  674. IpmontrGetFriendlyNameFromIfIndex(
  675. hMibServer, pmimm-> rgmioOutInfo[j].dwOutIfIndex,
  676. wszFriendlyName,
  677. sizeof(wszFriendlyName)
  678. );
  679. if ( wcslen(wszFriendlyName) < 18 )
  680. {
  681. wsprintf( ptszIf, L"%-18.18s", wszFriendlyName );
  682. }
  683. else
  684. {
  685. wsprintf(
  686. ptszIf, L"%-12.12s...%-3.3s", wszFriendlyName,
  687. &wszFriendlyName[wcslen(wszFriendlyName) - 3]
  688. );
  689. }
  690. MakeAddressStringW( ptszUpstrm, pmimm-> rgmioOutInfo[j].dwNextHopAddr );
  691. wsprintf(
  692. ptszBuffer,
  693. L"\n %-18.18s %15.15s",
  694. ptszIf, ptszUpstrm
  695. );
  696. DisplayMessageToConsole(
  697. g_hModule, g_hConsole, MSG_MIB_MFE, ptszBuffer
  698. );
  699. }
  700. }
  701. pmimm = (PMIB_IPMCAST_MFE)
  702. ((PBYTE) pmimm + SIZEOF_MIB_MFE( pmimm-> ulNumOutIf ));
  703. }
  704. }
  705. //----------------------------------------------------------------------------
  706. // PrintMfeStatsTable
  707. //
  708. //
  709. //----------------------------------------------------------------------------
  710. VOID
  711. PrintMfeStatsTable(
  712. MIB_SERVER_HANDLE hMibServer,
  713. PMIB_OPAQUE_INFO prpcInfo,
  714. PDWORD pdwLastGrp,
  715. PDWORD pdwLastSrc,
  716. PDWORD pdwLastSrcMask,
  717. DWORD dwRangeGrp,
  718. DWORD dwRangeGrpMask,
  719. DWORD dwRangeSrc,
  720. DWORD dwRangeSrcMask,
  721. DWORD dwType,
  722. PBOOL pbDone,
  723. BOOL bStatsAll
  724. )
  725. /*++
  726. Routine Description:
  727. Prints MFE stats table information.
  728. Arguments:
  729. Return Value:
  730. --*/
  731. {
  732. WCHAR wszFriendlyName[MAX_INTERFACE_NAME_LEN + 1];
  733. INT iCmp;
  734. DWORD i, j, dwIndex, dwErr = NO_ERROR,
  735. dwNextMfe;
  736. TCHAR ptszSource[ ADDR_LENGTH + 1 ],
  737. ptszGroup[ ADDR_LENGTH + 1 ],
  738. ptszSrcMask[ ADDR_LENGTH + 1 ],
  739. ptszUpstrm[ ADDR_LENGTH + 1 ],
  740. ptszIf[ 18 + 1 ];
  741. TCHAR ptszBuffer[ 256 ];
  742. ULONG ulCurrLen, ulStringLen;
  743. PTCHAR ptcString;
  744. PMIB_MFE_STATS_TABLE pTable;
  745. PMIB_IPMCAST_MFE_STATS pmims;
  746. PMIB_IPMCAST_OIF_STATS pmimos;
  747. //
  748. // get stats table
  749. //
  750. pTable = (PMIB_MFE_STATS_TABLE)( prpcInfo->rgbyData );
  751. if ( pTable->dwNumEntries is 0 )
  752. {
  753. //
  754. // no MFEs present.
  755. //
  756. return;
  757. }
  758. pmims = pTable-> table;
  759. //
  760. // Display MFE
  761. // - display header and incoming stats
  762. // - display multiple outgoing stats
  763. //
  764. for (i = 0; i < pTable->dwNumEntries; i++)
  765. {
  766. *pdwLastGrp = pmims-> dwGroup;
  767. *pdwLastSrc = pmims-> dwSource;
  768. *pdwLastSrcMask = pmims-> dwSrcMask;
  769. //
  770. // Check if the MFEs are in the range provided
  771. //
  772. if ( dwRangeGrp && dwRangeGrpMask &&
  773. ( ( dwRangeGrp & dwRangeGrpMask ) !=
  774. ( pmims-> dwGroup & dwRangeGrpMask ) ) )
  775. {
  776. *pbDone = TRUE;
  777. break;
  778. }
  779. if ( dwRangeSrc && dwRangeSrcMask &&
  780. ( ( dwRangeSrc & dwRangeSrcMask ) !=
  781. ( pmims-> dwSource & dwRangeSrcMask ) ) )
  782. {
  783. pmims = (PMIB_IPMCAST_MFE_STATS)
  784. ((PBYTE) pmims +
  785. (bStatsAll) ?
  786. SIZEOF_MIB_MFE_STATS_EX( pmims-> ulNumOutIf ) :
  787. SIZEOF_MIB_MFE_STATS( pmims-> ulNumOutIf ));
  788. continue;
  789. }
  790. if ( ( dwType == Both ) ||
  791. ( ( dwType == PositiveMfe ) && ( pmims-> ulNumOutIf ) ) ||
  792. ( ( dwType == NegativeMfe ) && ( !pmims-> ulNumOutIf ) ) )
  793. {
  794. MakePrefixStringW( ptszGroup, pmims-> dwGroup, 0xFFFFFFFF );
  795. MakePrefixStringW( ptszSource, pmims-> dwSource, pmims-> dwSrcMask );
  796. MakeAddressStringW( ptszUpstrm, pmims-> dwUpStrmNgbr );
  797. IpmontrGetFriendlyNameFromIfIndex(
  798. hMibServer, pmims-> dwInIfIndex, wszFriendlyName,
  799. sizeof(wszFriendlyName)
  800. );
  801. if ( wcslen(wszFriendlyName) < 14 )
  802. {
  803. wsprintf( ptszIf, L"%-14.14s", wszFriendlyName );
  804. }
  805. else
  806. {
  807. wsprintf(
  808. ptszIf, L"%-8.8s...%-3.3s", wszFriendlyName,
  809. &wszFriendlyName[wcslen(wszFriendlyName) - 3]
  810. );
  811. }
  812. if (bStatsAll)
  813. {
  814. PMIB_IPMCAST_MFE_STATS_EX pmimsex =
  815. (PMIB_IPMCAST_MFE_STATS_EX) pmims;
  816. wsprintf(
  817. ptszBuffer, L"\n%18.18s %18.18s %-6.6s %-14.14s %15.15s "
  818. L"%10d %10d %10d %10d %10d %10d %10d %10d %10d",
  819. ptszGroup, ptszSource,
  820. GetProtoProtoString(
  821. PROTO_TYPE_MCAST, 0,
  822. pmimsex-> dwInIfProtocol
  823. ),
  824. ptszIf, ptszUpstrm,
  825. pmimsex-> ulInPkts, pmimsex-> ulInOctets,
  826. pmimsex-> ulPktsDifferentIf, pmimsex-> ulQueueOverflow,
  827. pmimsex-> ulUninitMfe, pmimsex-> ulNegativeMfe,
  828. pmimsex-> ulNegativeMfe, pmimsex-> ulInDiscards,
  829. pmimsex-> ulInHdrErrors, pmimsex-> ulTotalOutPackets
  830. );
  831. pmimos = pmimsex-> rgmiosOutStats;
  832. }
  833. else
  834. {
  835. wsprintf(
  836. ptszBuffer, L"\n%18.18s %18.18s %-14.14s %15.15s %10d",
  837. ptszGroup, ptszSource,
  838. ptszIf, ptszUpstrm,
  839. pmims-> ulInPkts
  840. );
  841. pmimos = pmims-> rgmiosOutStats;
  842. }
  843. DisplayMessageToConsole(g_hModule, g_hConsole,
  844. MSG_MIB_MFESTATS,
  845. ptszBuffer);
  846. //
  847. // Display outgoing statistics
  848. //
  849. if ( pmims-> ulNumOutIf )
  850. {
  851. //
  852. // for each outgoing interface show outgoing interface stats
  853. //
  854. for ( j = 0; j < pmims-> ulNumOutIf; j++ )
  855. {
  856. IpmontrGetFriendlyNameFromIfIndex(
  857. hMibServer, pmimos[j].dwOutIfIndex,
  858. wszFriendlyName,
  859. sizeof(wszFriendlyName)
  860. );
  861. if ( wcslen(wszFriendlyName) < 14 )
  862. {
  863. wsprintf( ptszIf, L"%-14.14s", wszFriendlyName );
  864. }
  865. else
  866. {
  867. wsprintf(
  868. ptszIf, L"%-8.8s...%-3.3s", wszFriendlyName,
  869. &wszFriendlyName[wcslen(wszFriendlyName) - 3]
  870. );
  871. }
  872. MakeAddressStringW( ptszUpstrm, pmimos[j].dwNextHopAddr );
  873. if (!bStatsAll)
  874. {
  875. wsprintf(
  876. ptszBuffer,
  877. L"\n %-14.14s %15.15s %10d",
  878. ptszIf, ptszUpstrm,
  879. pmimos[j].ulOutPackets
  880. );
  881. }
  882. else
  883. {
  884. wsprintf(
  885. ptszBuffer,
  886. L"\n %-14.14s %15.15s %10d %10d %10d %10d",
  887. ptszIf, ptszUpstrm,
  888. pmimos[j].ulOutPackets,
  889. pmimos[j].ulOutDiscards,
  890. pmimos[j].ulTtlTooLow,
  891. pmimos[j].ulFragNeeded
  892. );
  893. }
  894. DisplayMessageToConsole(
  895. g_hModule, g_hConsole,
  896. MSG_MIB_MFESTATS,
  897. ptszBuffer);
  898. }
  899. }
  900. }
  901. dwNextMfe = bStatsAll ?
  902. SIZEOF_MIB_MFE_STATS_EX( pmims-> ulNumOutIf ) :
  903. SIZEOF_MIB_MFE_STATS( pmims-> ulNumOutIf );
  904. pmims = (PMIB_IPMCAST_MFE_STATS)
  905. (((PBYTE) pmims) + dwNextMfe);
  906. }
  907. return;
  908. }
  909. //----------------------------------------------------------------------------
  910. // PrintMfeStatsTable
  911. //
  912. //
  913. //----------------------------------------------------------------------------
  914. DWORD
  915. GetMfe(
  916. MIB_SERVER_HANDLE hMprMIB,
  917. BOOL bIndexPresent,
  918. PWCHAR *ppwcArguments,
  919. DWORD dwArgCount,
  920. BOOL bIncludeStats
  921. )
  922. /*++
  923. Routine Description:
  924. Gets MFE stats information.
  925. Arguments:
  926. Return Value:
  927. --*/
  928. {
  929. TAG_TYPE pttTags[] = {{TOKEN_GROUP_ADDRESS, FALSE, FALSE},
  930. {TOKEN_GROUP_MASK, FALSE, FALSE},
  931. {TOKEN_SOURCE_ADDRESS, FALSE, FALSE},
  932. {TOKEN_SOURCE_MASK, FALSE, FALSE},
  933. {TOKEN_TYPE, FALSE, FALSE},
  934. {TOKEN_STATS, FALSE, FALSE}};
  935. DWORD pdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
  936. DWORD dwErr, dwOutEntrySize = 0, dwQuerySize,
  937. dwLastGroup = 0, dwLastSource = 0,
  938. dwLastSrcMask = 0, i,
  939. dwRangeGroup = 0, dwRangeGrpMask = 0,
  940. dwRangeSource = 0, dwRangeSrcMask = 0,
  941. dwNumParsed;
  942. DWORD dwType = Both;
  943. DWORD dwCurrentIndex = 0;
  944. BOOL bDone = FALSE, bStatsAll = FALSE;
  945. PMIB_OPAQUE_INFO pRpcInfo = NULL;
  946. PMIB_MFE_STATS_TABLE pTable = NULL;
  947. PMIB_OPAQUE_QUERY pQuery;
  948. // Do generic processing
  949. dwErr = PreHandleCommand( ppwcArguments,
  950. dwCurrentIndex,
  951. dwArgCount,
  952. pttTags,
  953. sizeof(pttTags)/sizeof(TAG_TYPE),
  954. 0,
  955. sizeof(pttTags)/sizeof(TAG_TYPE),
  956. pdwTagType );
  957. if (dwErr)
  958. {
  959. return dwErr;
  960. }
  961. for (i=0; i<dwArgCount; i++)
  962. {
  963. switch(pdwTagType[i])
  964. {
  965. case 0: // GRPADDR
  966. {
  967. dwErr = GetIpPrefix( ppwcArguments[i+dwCurrentIndex],
  968. &dwRangeGroup,
  969. &dwRangeGrpMask );
  970. if (dwErr is ERROR_INVALID_PARAMETER)
  971. {
  972. DisplayMessage( g_hModule, MSG_IP_BAD_IP_ADDR,
  973. ppwcArguments[i + dwCurrentIndex]);
  974. DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
  975. pttTags[pdwTagType[i]].pwszTag,
  976. ppwcArguments[i + dwCurrentIndex]);
  977. i = dwArgCount;
  978. break;
  979. }
  980. break;
  981. }
  982. case 1: // GRPMASK
  983. {
  984. dwErr = GetIpMask( ppwcArguments[i+dwCurrentIndex],
  985. &dwRangeGrpMask );
  986. if (dwErr is ERROR_INVALID_PARAMETER)
  987. {
  988. DisplayMessage( g_hModule, MSG_IP_BAD_IP_ADDR,
  989. ppwcArguments[i + dwCurrentIndex]);
  990. DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
  991. pttTags[pdwTagType[i]].pwszTag,
  992. ppwcArguments[i + dwCurrentIndex]);
  993. i = dwArgCount;
  994. break;
  995. }
  996. break;
  997. }
  998. case 2: // SRCADDR
  999. {
  1000. dwErr = GetIpPrefix( ppwcArguments[i+dwCurrentIndex],
  1001. &dwRangeSource,
  1002. &dwRangeSrcMask );
  1003. if (dwErr is ERROR_INVALID_PARAMETER)
  1004. {
  1005. DisplayMessage( g_hModule, MSG_IP_BAD_IP_ADDR,
  1006. ppwcArguments[i + dwCurrentIndex]);
  1007. DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
  1008. pttTags[pdwTagType[i]].pwszTag,
  1009. ppwcArguments[i + dwCurrentIndex]);
  1010. i = dwArgCount;
  1011. break;
  1012. }
  1013. break;
  1014. }
  1015. case 3: // SRCMASK
  1016. {
  1017. dwErr = GetIpMask( ppwcArguments[i+dwCurrentIndex],
  1018. &dwRangeSrcMask );
  1019. if (dwErr is ERROR_INVALID_PARAMETER)
  1020. {
  1021. DisplayMessage( g_hModule, MSG_IP_BAD_IP_ADDR,
  1022. ppwcArguments[i + dwCurrentIndex]);
  1023. DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
  1024. pttTags[pdwTagType[i]].pwszTag,
  1025. ppwcArguments[i + dwCurrentIndex]);
  1026. i = dwArgCount;
  1027. break;
  1028. }
  1029. break;
  1030. }
  1031. case 4: // TYPE
  1032. {
  1033. TOKEN_VALUE rgEnums[] =
  1034. {
  1035. { TOKEN_VALUE_POSITIVE, PositiveMfe },
  1036. { TOKEN_VALUE_NEGATIVE, NegativeMfe },
  1037. { TOKEN_VALUE_BOTH, Both }
  1038. };
  1039. dwErr = MatchEnumTag( g_hModule,
  1040. ppwcArguments[i + dwCurrentIndex],
  1041. sizeof(rgEnums)/sizeof(TOKEN_VALUE),
  1042. rgEnums,
  1043. &dwType);
  1044. if (dwErr isnot NO_ERROR)
  1045. {
  1046. DispTokenErrMsg( g_hModule,
  1047. MSG_IP_BAD_OPTION_VALUE,
  1048. pttTags[pdwTagType[i]].pwszTag,
  1049. ppwcArguments[i + dwCurrentIndex] );
  1050. return ERROR_INVALID_PARAMETER;
  1051. }
  1052. break;
  1053. }
  1054. case 5: // STATS
  1055. {
  1056. TOKEN_VALUE rgEnums[] =
  1057. {
  1058. { TOKEN_VALUE_ALL, TRUE },
  1059. };
  1060. dwErr = MatchEnumTag( g_hModule,
  1061. ppwcArguments[i + dwCurrentIndex],
  1062. sizeof(rgEnums)/sizeof(TOKEN_VALUE),
  1063. rgEnums,
  1064. &bStatsAll);
  1065. if (dwErr isnot NO_ERROR)
  1066. {
  1067. DispTokenErrMsg( g_hModule,
  1068. MSG_IP_BAD_OPTION_VALUE,
  1069. pttTags[pdwTagType[i]].pwszTag,
  1070. ppwcArguments[i + dwCurrentIndex] );
  1071. return ERROR_INVALID_PARAMETER;
  1072. }
  1073. break;
  1074. }
  1075. }
  1076. }
  1077. if (dwErr isnot NO_ERROR)
  1078. {
  1079. return dwErr;
  1080. }
  1081. do {
  1082. //
  1083. // allocate and setup query structure
  1084. //
  1085. dwQuerySize = sizeof( MIB_OPAQUE_QUERY ) + 2 * sizeof(DWORD);
  1086. pQuery = (PMIB_OPAQUE_QUERY) HeapAlloc(
  1087. GetProcessHeap(), 0, dwQuerySize
  1088. );
  1089. if ( pQuery == NULL )
  1090. {
  1091. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1092. DisplayMessageToConsole(g_hModule, g_hConsole, ERROR_CONFIG, dwErr );
  1093. break;
  1094. }
  1095. pQuery->dwVarId = ( bIncludeStats ) ?
  1096. ( ( bStatsAll ) ?
  1097. MCAST_MFE_STATS_EX : MCAST_MFE_STATS ) :
  1098. MCAST_MFE;
  1099. pQuery->rgdwVarIndex[ 0 ] = dwRangeGroup & dwRangeGrpMask;
  1100. pQuery->rgdwVarIndex[ 1 ] = dwRangeSource;
  1101. pQuery->rgdwVarIndex[ 2 ] = dwRangeSrcMask;
  1102. if (bIncludeStats)
  1103. {
  1104. DisplayMessageToConsole(
  1105. g_hModule, g_hConsole,
  1106. bStatsAll ? MSG_MIB_MFESTATS_ALL_HDR : MSG_MIB_MFESTATS_HDR
  1107. );
  1108. }
  1109. else
  1110. {
  1111. DisplayMessageToConsole(g_hModule, g_hConsole, MSG_MIB_MFE_HDR );
  1112. }
  1113. while ((dwErr = MibGetNext( PID_IP,
  1114. IPRTRMGR_PID,
  1115. (PVOID) pQuery,
  1116. dwQuerySize,
  1117. (PVOID *) &pRpcInfo,
  1118. &dwOutEntrySize))
  1119. == NO_ERROR )
  1120. {
  1121. //
  1122. // if no MFEs are present quit
  1123. //
  1124. pTable = (PMIB_MFE_STATS_TABLE)( pRpcInfo->rgbyData );
  1125. if ( pTable->dwNumEntries is 0 )
  1126. {
  1127. break;
  1128. }
  1129. //
  1130. // print the MFEs
  1131. //
  1132. if ( bIncludeStats )
  1133. {
  1134. PrintMfeStatsTable( hMprMIB,
  1135. pRpcInfo, &dwLastGroup, &dwLastSource, &dwLastSrcMask,
  1136. dwRangeGroup, dwRangeGrpMask, dwRangeSource,
  1137. dwRangeSrcMask, dwType, &bDone, bStatsAll
  1138. );
  1139. }
  1140. else
  1141. {
  1142. PrintMfeTable( hMprMIB,
  1143. pRpcInfo, &dwLastGroup, &dwLastSource, &dwLastSrcMask,
  1144. dwRangeGroup, dwRangeGrpMask, dwRangeSource,
  1145. dwRangeSrcMask, dwType, &bDone
  1146. );
  1147. }
  1148. MprAdminMIBBufferFree( pRpcInfo );
  1149. pRpcInfo = NULL;
  1150. dwOutEntrySize = 0;
  1151. //
  1152. // Check if we are done
  1153. //
  1154. if ( bDone )
  1155. {
  1156. break;
  1157. }
  1158. //
  1159. // set up the next query
  1160. //
  1161. pQuery->rgdwVarIndex[ 0 ] = dwLastGroup;
  1162. pQuery->rgdwVarIndex[ 1 ] = dwLastSource;
  1163. pQuery->rgdwVarIndex[ 2 ] = dwLastSrcMask;
  1164. }
  1165. if ( dwErr != NO_ERROR && dwErr != ERROR_NO_MORE_ITEMS && dwErr != ERROR_NOT_FOUND )
  1166. {
  1167. DisplayError(NULL, dwErr );
  1168. }
  1169. } while ( FALSE );
  1170. return dwErr;
  1171. }