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.

1463 lines
43 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. {
  406. DWORD BufLen = sizeof(wszFriendlyName);
  407. dwErr = IpmontrGetFriendlyNameFromIfIndex(
  408. hMibServer,
  409. lprpcTable->table[i].dwForwardIfIndex,
  410. wszFriendlyName,
  411. BufLen );
  412. }
  413. DisplayMessageToConsole(g_hModule, g_hConsole,MSG_MIB_FORWARD_ENTRY,
  414. tszDest,
  415. tszMask,
  416. lprpcTable->table[i].dwForwardPolicy,
  417. tszNextHop,
  418. wszFriendlyName,
  419. ptszType,
  420. ptszProto,
  421. lprpcTable->table[i].dwForwardAge,
  422. lprpcTable->table[i].dwForwardNextHopAS,
  423. lprpcTable->table[i].dwForwardMetric1,
  424. lprpcTable->table[i].dwForwardMetric2,
  425. lprpcTable->table[i].dwForwardMetric3,
  426. lprpcTable->table[i].dwForwardMetric4,
  427. lprpcTable->table[i].dwForwardMetric5);
  428. FreeString(ptszType);
  429. FreeString(ptszProto);
  430. }
  431. }
  432. VOID
  433. PrintIpForwardRow(
  434. MIB_SERVER_HANDLE hMibServer,
  435. PMIB_OPAQUE_INFO prpcInfo
  436. )
  437. /*++
  438. Routine Description:
  439. Prints Ip forward table row.
  440. Arguments:
  441. Return Value:
  442. --*/
  443. {
  444. WCHAR wszFriendlyName[MAX_INTERFACE_NAME_LEN + 1];
  445. PMIB_IPFORWARDROW ireRow = (PMIB_IPFORWARDROW)(prpcInfo->rgbyData);
  446. TCHAR tszMask[ADDR_LENGTH + 1],
  447. tszDest[ADDR_LENGTH + 1],
  448. tszNextHop[ADDR_LENGTH + 1];
  449. PTCHAR ptszType, ptszProto;
  450. DWORD dwErr = NO_ERROR;
  451. DisplayMessageToConsole(g_hModule, g_hConsole,MSG_MIB_FORWARD_HDR);
  452. switch(ireRow->dwForwardProto)
  453. {
  454. case MIB_IPPROTO_LOCAL:
  455. {
  456. ptszProto = MakeString(g_hModule, STRING_LOCAL);
  457. break;
  458. }
  459. case MIB_IPPROTO_NETMGMT:
  460. {
  461. ptszProto = MakeString(g_hModule, STRING_NETMGMT);
  462. break;
  463. }
  464. case MIB_IPPROTO_ICMP:
  465. {
  466. ptszProto = MakeString(g_hModule, STRING_ICMP);
  467. break;
  468. }
  469. case MIB_IPPROTO_EGP:
  470. {
  471. ptszProto = MakeString(g_hModule, STRING_EGP);
  472. break;
  473. }
  474. case MIB_IPPROTO_GGP:
  475. {
  476. ptszProto = MakeString(g_hModule, STRING_GGP);
  477. break;
  478. }
  479. case MIB_IPPROTO_HELLO:
  480. {
  481. ptszProto = MakeString(g_hModule, STRING_HELLO);
  482. break;
  483. }
  484. case MIB_IPPROTO_RIP:
  485. {
  486. ptszProto = MakeString(g_hModule, STRING_RIP);
  487. break;
  488. }
  489. case MIB_IPPROTO_IS_IS:
  490. {
  491. ptszProto = MakeString(g_hModule, STRING_IS_IS);
  492. break;
  493. }
  494. case MIB_IPPROTO_ES_IS:
  495. {
  496. ptszProto = MakeString(g_hModule, STRING_ES_IS);
  497. break;
  498. }
  499. case MIB_IPPROTO_CISCO:
  500. {
  501. ptszProto = MakeString(g_hModule, STRING_CISCO);
  502. break;
  503. }
  504. case MIB_IPPROTO_BBN:
  505. {
  506. ptszProto = MakeString(g_hModule, STRING_BBN);
  507. break;
  508. }
  509. case MIB_IPPROTO_OSPF:
  510. {
  511. ptszProto = MakeString(g_hModule, STRING_OSPF);
  512. break;
  513. }
  514. case MIB_IPPROTO_BGP:
  515. {
  516. ptszProto = MakeString(g_hModule, STRING_BGP);
  517. break;
  518. }
  519. case MIB_IPPROTO_OTHER:
  520. default:
  521. {
  522. ptszProto = MakeString(g_hModule, STRING_OTHER);
  523. break;
  524. }
  525. }
  526. switch(ireRow->dwForwardType)
  527. {
  528. case MIB_IPROUTE_TYPE_INVALID:
  529. {
  530. ptszType = MakeString(g_hModule, STRING_INVALID);
  531. break;
  532. }
  533. case MIB_IPROUTE_TYPE_DIRECT:
  534. {
  535. ptszType = MakeString(g_hModule, STRING_DIRECT);
  536. break;
  537. }
  538. case MIB_IPROUTE_TYPE_INDIRECT:
  539. {
  540. ptszType = MakeString(g_hModule, STRING_INDIRECT);
  541. break;
  542. }
  543. case MIB_IPROUTE_TYPE_OTHER:
  544. default:
  545. {
  546. ptszType = MakeString(g_hModule, STRING_OTHER);
  547. break;
  548. }
  549. }
  550. MakeUnicodeIpAddr(tszDest,
  551. inet_ntoa(*((struct in_addr *)
  552. (&ireRow->dwForwardDest))));
  553. MakeUnicodeIpAddr(tszMask,
  554. inet_ntoa(*((struct in_addr *)
  555. (&ireRow->dwForwardMask))));
  556. MakeUnicodeIpAddr(tszNextHop,
  557. inet_ntoa(*((struct in_addr *)
  558. (&ireRow->dwForwardNextHop))));
  559. {
  560. DWORD BufLen = sizeof(wszFriendlyName);
  561. dwErr = IpmontrGetFriendlyNameFromIfIndex( hMibServer,
  562. ireRow->dwForwardIfIndex,
  563. wszFriendlyName,
  564. BufLen );
  565. }
  566. DisplayMessageToConsole(g_hModule, g_hConsole,MSG_MIB_FORWARD_ENTRY,
  567. tszDest,
  568. tszMask,
  569. ireRow->dwForwardPolicy,
  570. tszNextHop,
  571. wszFriendlyName,
  572. ptszType,
  573. ptszProto,
  574. ireRow->dwForwardAge,
  575. ireRow->dwForwardNextHopAS,
  576. ireRow->dwForwardMetric1,
  577. ireRow->dwForwardMetric2,
  578. ireRow->dwForwardMetric3,
  579. ireRow->dwForwardMetric4,
  580. ireRow->dwForwardMetric5);
  581. FreeString(ptszType);
  582. FreeString(ptszProto);
  583. }
  584. #endif
  585. VOID
  586. PrintMfeTable(
  587. MIB_SERVER_HANDLE hMibServer,
  588. PMIB_OPAQUE_INFO prpcInfo,
  589. PDWORD pdwLastGrp,
  590. PDWORD pdwLastSrc,
  591. PDWORD pdwLastSrcMask,
  592. DWORD dwRangeGrp,
  593. DWORD dwRangeGrpMask,
  594. DWORD dwRangeSrc,
  595. DWORD dwRangeSrcMask,
  596. DWORD dwType,
  597. PBOOL pbDone
  598. )
  599. /*++
  600. Routine Description:
  601. Prints MFE table information.
  602. Arguments:
  603. Return Value:
  604. --*/
  605. {
  606. WCHAR wszFriendlyName[MAX_INTERFACE_NAME_LEN + 1];
  607. INT iCmp;
  608. DWORD i, j, dwErr = NO_ERROR;
  609. TCHAR ptszSource[ADDR_LENGTH + 1];
  610. TCHAR ptszGroup[ADDR_LENGTH + 1];
  611. TCHAR ptszUpstrm[ADDR_LENGTH + 1];
  612. TCHAR ptszBuffer[80];
  613. TCHAR ptszIf[18 + 1];
  614. PMIB_MFE_TABLE pTable;
  615. PMIB_IPMCAST_MFE pmimm;
  616. pTable = ( PMIB_MFE_TABLE )( prpcInfo-> rgbyData );
  617. if ( pTable->dwNumEntries is 0 )
  618. {
  619. DisplayMessageToConsole( g_hModule, g_hConsole,MSG_MIB_NO_MFES );
  620. return;
  621. }
  622. pmimm = pTable-> table;
  623. for( i = 0; i < pTable->dwNumEntries; i++ )
  624. {
  625. *pdwLastGrp = pmimm-> dwGroup;
  626. *pdwLastSrc = pmimm-> dwSource ;
  627. *pdwLastSrcMask = pmimm-> dwSrcMask ;
  628. //
  629. // Check if the MFEs are in the range provided
  630. //
  631. if ( dwRangeGrp && dwRangeGrpMask &&
  632. ( ( dwRangeGrp & dwRangeGrpMask ) !=
  633. ( pmimm-> dwGroup & dwRangeGrpMask ) ) )
  634. {
  635. *pbDone = TRUE;
  636. break;
  637. }
  638. if ( dwRangeSrc && dwRangeSrcMask &&
  639. ( ( dwRangeSrc & dwRangeSrcMask ) !=
  640. ( pmimm-> dwSource & dwRangeSrcMask ) ) )
  641. {
  642. continue;
  643. }
  644. if ( ( dwType == Both ) ||
  645. ( ( dwType == PositiveMfe ) && ( pmimm-> ulNumOutIf ) ) ||
  646. ( ( dwType == NegativeMfe ) && ( !pmimm-> ulNumOutIf ) ) )
  647. {
  648. MakePrefixStringW( ptszGroup, pmimm-> dwGroup, 0xFFFFFFFF );
  649. MakePrefixStringW( ptszSource, pmimm-> dwSource, pmimm-> dwSrcMask );
  650. MakeAddressStringW( ptszUpstrm, pmimm-> dwUpStrmNgbr );
  651. {
  652. DWORD BufLen = sizeof(wszFriendlyName);
  653. IpmontrGetFriendlyNameFromIfIndex(
  654. hMibServer, pmimm-> dwInIfIndex, wszFriendlyName,
  655. BufLen
  656. );
  657. }
  658. if ( wcslen(wszFriendlyName) < 18 )
  659. {
  660. #pragma prefast(suppress:69, "Inefficient use of wsprintf: dont need")
  661. wsprintf( ptszIf, L"%-18.18s", wszFriendlyName );
  662. }
  663. else
  664. {
  665. wsprintf(
  666. ptszIf, L"%-12.12s...%-3.3s", wszFriendlyName,
  667. &wszFriendlyName[wcslen(wszFriendlyName) - 3]
  668. );
  669. }
  670. wsprintf(
  671. ptszBuffer, L"\n%18.18s %18.18s %-6.6s %-18.18s %15.15s",
  672. ptszGroup, ptszSource,
  673. GetProtoProtoString(
  674. PROTO_TYPE_MCAST, 0,
  675. pmimm-> dwInIfProtocol
  676. ),
  677. ptszIf, ptszUpstrm
  678. );
  679. DisplayMessageToConsole(
  680. g_hModule, g_hConsole, MSG_MIB_MFE, ptszBuffer
  681. );
  682. for (j = 0; j < pmimm-> ulNumOutIf; j++)
  683. {
  684. DWORD BufLen = sizeof(wszFriendlyName);
  685. IpmontrGetFriendlyNameFromIfIndex(
  686. hMibServer, pmimm-> rgmioOutInfo[j].dwOutIfIndex,
  687. wszFriendlyName,
  688. BufLen
  689. );
  690. if ( wcslen(wszFriendlyName) < 18 )
  691. {
  692. #pragma prefast(suppress:69, "Inefficient use of wsprintf: dont need")
  693. wsprintf( ptszIf, L"%-18.18s", wszFriendlyName );
  694. }
  695. else
  696. {
  697. wsprintf(
  698. ptszIf, L"%-12.12s...%-3.3s", wszFriendlyName,
  699. &wszFriendlyName[wcslen(wszFriendlyName) - 3]
  700. );
  701. }
  702. MakeAddressStringW( ptszUpstrm, pmimm-> rgmioOutInfo[j].dwNextHopAddr );
  703. wsprintf(
  704. ptszBuffer,
  705. L"\n %-18.18s %15.15s",
  706. ptszIf, ptszUpstrm
  707. );
  708. DisplayMessageToConsole(
  709. g_hModule, g_hConsole, MSG_MIB_MFE, ptszBuffer
  710. );
  711. }
  712. }
  713. pmimm = (PMIB_IPMCAST_MFE)
  714. ((PBYTE) pmimm + SIZEOF_MIB_MFE( pmimm-> ulNumOutIf ));
  715. }
  716. }
  717. //----------------------------------------------------------------------------
  718. // PrintMfeStatsTable
  719. //
  720. //
  721. //----------------------------------------------------------------------------
  722. VOID
  723. PrintMfeStatsTable(
  724. MIB_SERVER_HANDLE hMibServer,
  725. PMIB_OPAQUE_INFO prpcInfo,
  726. PDWORD pdwLastGrp,
  727. PDWORD pdwLastSrc,
  728. PDWORD pdwLastSrcMask,
  729. DWORD dwRangeGrp,
  730. DWORD dwRangeGrpMask,
  731. DWORD dwRangeSrc,
  732. DWORD dwRangeSrcMask,
  733. DWORD dwType,
  734. PBOOL pbDone,
  735. BOOL bStatsAll
  736. )
  737. /*++
  738. Routine Description:
  739. Prints MFE stats table information.
  740. Arguments:
  741. Return Value:
  742. --*/
  743. {
  744. WCHAR wszFriendlyName[MAX_INTERFACE_NAME_LEN + 1];
  745. INT iCmp;
  746. DWORD i, j, dwIndex, dwErr = NO_ERROR,
  747. dwNextMfe;
  748. TCHAR ptszSource[ ADDR_LENGTH + 1 ],
  749. ptszGroup[ ADDR_LENGTH + 1 ],
  750. ptszSrcMask[ ADDR_LENGTH + 1 ],
  751. ptszUpstrm[ ADDR_LENGTH + 1 ],
  752. ptszIf[ 18 + 1 ];
  753. TCHAR ptszBuffer[ 256 ];
  754. ULONG ulCurrLen, ulStringLen;
  755. PTCHAR ptcString;
  756. PMIB_MFE_STATS_TABLE pTable;
  757. PMIB_IPMCAST_MFE_STATS pmims;
  758. PMIB_IPMCAST_OIF_STATS pmimos;
  759. //
  760. // get stats table
  761. //
  762. pTable = (PMIB_MFE_STATS_TABLE)( prpcInfo->rgbyData );
  763. if ( pTable->dwNumEntries is 0 )
  764. {
  765. //
  766. // no MFEs present.
  767. //
  768. return;
  769. }
  770. pmims = pTable-> table;
  771. //
  772. // Display MFE
  773. // - display header and incoming stats
  774. // - display multiple outgoing stats
  775. //
  776. for (i = 0; i < pTable->dwNumEntries; i++)
  777. {
  778. *pdwLastGrp = pmims-> dwGroup;
  779. *pdwLastSrc = pmims-> dwSource;
  780. *pdwLastSrcMask = pmims-> dwSrcMask;
  781. //
  782. // Check if the MFEs are in the range provided
  783. //
  784. if ( dwRangeGrp && dwRangeGrpMask &&
  785. ( ( dwRangeGrp & dwRangeGrpMask ) !=
  786. ( pmims-> dwGroup & dwRangeGrpMask ) ) )
  787. {
  788. *pbDone = TRUE;
  789. break;
  790. }
  791. if ( dwRangeSrc && dwRangeSrcMask &&
  792. ( ( dwRangeSrc & dwRangeSrcMask ) !=
  793. ( pmims-> dwSource & dwRangeSrcMask ) ) )
  794. {
  795. pmims = (PMIB_IPMCAST_MFE_STATS)
  796. ((PBYTE) pmims +
  797. (bStatsAll) ?
  798. SIZEOF_MIB_MFE_STATS_EX( pmims-> ulNumOutIf ) :
  799. SIZEOF_MIB_MFE_STATS( pmims-> ulNumOutIf ));
  800. continue;
  801. }
  802. if ( ( dwType == Both ) ||
  803. ( ( dwType == PositiveMfe ) && ( pmims-> ulNumOutIf ) ) ||
  804. ( ( dwType == NegativeMfe ) && ( !pmims-> ulNumOutIf ) ) )
  805. {
  806. DWORD BufLen;
  807. MakePrefixStringW( ptszGroup, pmims-> dwGroup, 0xFFFFFFFF );
  808. MakePrefixStringW( ptszSource, pmims-> dwSource, pmims-> dwSrcMask );
  809. MakeAddressStringW( ptszUpstrm, pmims-> dwUpStrmNgbr );
  810. BufLen = sizeof(wszFriendlyName);
  811. IpmontrGetFriendlyNameFromIfIndex(
  812. hMibServer, pmims-> dwInIfIndex, wszFriendlyName,
  813. BufLen
  814. );
  815. if ( wcslen(wszFriendlyName) < 14 )
  816. {
  817. #pragma prefast(suppress:69, "Inefficient use of wsprintf: dont need")
  818. wsprintf( ptszIf, L"%-14.14s", wszFriendlyName );
  819. }
  820. else
  821. {
  822. wsprintf(
  823. ptszIf, L"%-8.8s...%-3.3s", wszFriendlyName,
  824. &wszFriendlyName[wcslen(wszFriendlyName) - 3]
  825. );
  826. }
  827. if (bStatsAll)
  828. {
  829. PMIB_IPMCAST_MFE_STATS_EX pmimsex =
  830. (PMIB_IPMCAST_MFE_STATS_EX) pmims;
  831. wsprintf(
  832. ptszBuffer, L"\n%18.18s %18.18s %-6.6s %-14.14s %15.15s "
  833. L"%10d %10d %10d %10d %10d %10d %10d %10d %10d %10d",
  834. ptszGroup, ptszSource,
  835. GetProtoProtoString(
  836. PROTO_TYPE_MCAST, 0,
  837. pmimsex-> dwInIfProtocol
  838. ),
  839. ptszIf, ptszUpstrm,
  840. pmimsex-> ulInPkts, pmimsex-> ulInOctets,
  841. pmimsex-> ulPktsDifferentIf, pmimsex-> ulQueueOverflow,
  842. pmimsex-> ulUninitMfe, pmimsex-> ulNegativeMfe,
  843. pmimsex-> ulNegativeMfe, pmimsex-> ulInDiscards,
  844. pmimsex-> ulInHdrErrors, pmimsex-> ulTotalOutPackets
  845. );
  846. pmimos = pmimsex-> rgmiosOutStats;
  847. }
  848. else
  849. {
  850. wsprintf(
  851. ptszBuffer, L"\n%18.18s %18.18s %-14.14s %15.15s %10d",
  852. ptszGroup, ptszSource,
  853. ptszIf, ptszUpstrm,
  854. pmims-> ulInPkts
  855. );
  856. pmimos = pmims-> rgmiosOutStats;
  857. }
  858. DisplayMessageToConsole(g_hModule, g_hConsole,
  859. MSG_MIB_MFESTATS,
  860. ptszBuffer);
  861. //
  862. // Display outgoing statistics
  863. //
  864. if ( pmims-> ulNumOutIf )
  865. {
  866. //
  867. // for each outgoing interface show outgoing interface stats
  868. //
  869. for ( j = 0; j < pmims-> ulNumOutIf; j++ )
  870. {
  871. BufLen = sizeof(wszFriendlyName);
  872. IpmontrGetFriendlyNameFromIfIndex(
  873. hMibServer, pmimos[j].dwOutIfIndex,
  874. wszFriendlyName,
  875. BufLen
  876. );
  877. if ( wcslen(wszFriendlyName) < 14 )
  878. {
  879. #pragma prefast(suppress:69, "Inefficient use of wsprintf: dont need")
  880. wsprintf( ptszIf, L"%-14.14s", wszFriendlyName );
  881. }
  882. else
  883. {
  884. wsprintf(
  885. ptszIf, L"%-8.8s...%-3.3s", wszFriendlyName,
  886. &wszFriendlyName[wcslen(wszFriendlyName) - 3]
  887. );
  888. }
  889. MakeAddressStringW( ptszUpstrm, pmimos[j].dwNextHopAddr );
  890. if (!bStatsAll)
  891. {
  892. wsprintf(
  893. ptszBuffer,
  894. L"\n %-14.14s %15.15s %10d",
  895. ptszIf, ptszUpstrm,
  896. pmimos[j].ulOutPackets
  897. );
  898. }
  899. else
  900. {
  901. wsprintf(
  902. ptszBuffer,
  903. L"\n %-14.14s %15.15s %10d %10d %10d %10d",
  904. ptszIf, ptszUpstrm,
  905. pmimos[j].ulOutPackets,
  906. pmimos[j].ulOutDiscards,
  907. pmimos[j].ulTtlTooLow,
  908. pmimos[j].ulFragNeeded
  909. );
  910. }
  911. DisplayMessageToConsole(
  912. g_hModule, g_hConsole,
  913. MSG_MIB_MFESTATS,
  914. ptszBuffer);
  915. }
  916. }
  917. }
  918. dwNextMfe = bStatsAll ?
  919. SIZEOF_MIB_MFE_STATS_EX( pmims-> ulNumOutIf ) :
  920. SIZEOF_MIB_MFE_STATS( pmims-> ulNumOutIf );
  921. pmims = (PMIB_IPMCAST_MFE_STATS)
  922. (((PBYTE) pmims) + dwNextMfe);
  923. }
  924. return;
  925. }
  926. //----------------------------------------------------------------------------
  927. // PrintMfeStatsTable
  928. //
  929. //
  930. //----------------------------------------------------------------------------
  931. DWORD
  932. GetMfe(
  933. MIB_SERVER_HANDLE hMprMIB,
  934. BOOL bIndexPresent,
  935. PWCHAR *ppwcArguments,
  936. DWORD dwArgCount,
  937. BOOL bIncludeStats
  938. )
  939. /*++
  940. Routine Description:
  941. Gets MFE stats information.
  942. Arguments:
  943. Return Value:
  944. --*/
  945. {
  946. TAG_TYPE pttTags[] = {{TOKEN_GROUP_ADDRESS, FALSE, FALSE},
  947. {TOKEN_GROUP_MASK, FALSE, FALSE},
  948. {TOKEN_SOURCE_ADDRESS, FALSE, FALSE},
  949. {TOKEN_SOURCE_MASK, FALSE, FALSE},
  950. {TOKEN_TYPE, FALSE, FALSE},
  951. {TOKEN_STATS, FALSE, FALSE}};
  952. DWORD pdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
  953. DWORD dwErr, dwOutEntrySize = 0, dwQuerySize,
  954. dwLastGroup = 0, dwLastSource = 0,
  955. dwLastSrcMask = 0, i,
  956. dwRangeGroup = 0, dwRangeGrpMask = 0,
  957. dwRangeSource = 0, dwRangeSrcMask = 0,
  958. dwNumParsed;
  959. DWORD dwType = Both;
  960. DWORD dwCurrentIndex = 0;
  961. BOOL bDone = FALSE, bStatsAll = FALSE;
  962. PMIB_OPAQUE_INFO pRpcInfo = NULL;
  963. PMIB_MFE_STATS_TABLE pTable = NULL;
  964. PMIB_OPAQUE_QUERY pQuery;
  965. // Do generic processing
  966. dwErr = PreHandleCommand( ppwcArguments,
  967. dwCurrentIndex,
  968. dwArgCount,
  969. pttTags,
  970. sizeof(pttTags)/sizeof(TAG_TYPE),
  971. 0,
  972. sizeof(pttTags)/sizeof(TAG_TYPE),
  973. pdwTagType );
  974. if (dwErr)
  975. {
  976. return dwErr;
  977. }
  978. for (i=0; i<dwArgCount; i++)
  979. {
  980. switch(pdwTagType[i])
  981. {
  982. case 0: // GRPADDR
  983. {
  984. dwErr = GetIpPrefix( ppwcArguments[i+dwCurrentIndex],
  985. &dwRangeGroup,
  986. &dwRangeGrpMask );
  987. if (dwErr is ERROR_INVALID_PARAMETER)
  988. {
  989. DisplayMessage( g_hModule, MSG_IP_BAD_IP_ADDR,
  990. ppwcArguments[i + dwCurrentIndex]);
  991. DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
  992. pttTags[pdwTagType[i]].pwszTag,
  993. ppwcArguments[i + dwCurrentIndex]);
  994. i = dwArgCount;
  995. break;
  996. }
  997. break;
  998. }
  999. case 1: // GRPMASK
  1000. {
  1001. dwErr = GetIpMask( ppwcArguments[i+dwCurrentIndex],
  1002. &dwRangeGrpMask );
  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 2: // SRCADDR
  1016. {
  1017. dwErr = GetIpPrefix( ppwcArguments[i+dwCurrentIndex],
  1018. &dwRangeSource,
  1019. &dwRangeSrcMask );
  1020. if (dwErr is ERROR_INVALID_PARAMETER)
  1021. {
  1022. DisplayMessage( g_hModule, MSG_IP_BAD_IP_ADDR,
  1023. ppwcArguments[i + dwCurrentIndex]);
  1024. DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
  1025. pttTags[pdwTagType[i]].pwszTag,
  1026. ppwcArguments[i + dwCurrentIndex]);
  1027. i = dwArgCount;
  1028. break;
  1029. }
  1030. break;
  1031. }
  1032. case 3: // SRCMASK
  1033. {
  1034. dwErr = GetIpMask( ppwcArguments[i+dwCurrentIndex],
  1035. &dwRangeSrcMask );
  1036. if (dwErr is ERROR_INVALID_PARAMETER)
  1037. {
  1038. DisplayMessage( g_hModule, MSG_IP_BAD_IP_ADDR,
  1039. ppwcArguments[i + dwCurrentIndex]);
  1040. DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
  1041. pttTags[pdwTagType[i]].pwszTag,
  1042. ppwcArguments[i + dwCurrentIndex]);
  1043. i = dwArgCount;
  1044. break;
  1045. }
  1046. break;
  1047. }
  1048. case 4: // TYPE
  1049. {
  1050. TOKEN_VALUE rgEnums[] =
  1051. {
  1052. { TOKEN_VALUE_POSITIVE, PositiveMfe },
  1053. { TOKEN_VALUE_NEGATIVE, NegativeMfe },
  1054. { TOKEN_VALUE_BOTH, Both }
  1055. };
  1056. dwErr = MatchEnumTag( g_hModule,
  1057. ppwcArguments[i + dwCurrentIndex],
  1058. sizeof(rgEnums)/sizeof(TOKEN_VALUE),
  1059. rgEnums,
  1060. &dwType);
  1061. if (dwErr isnot NO_ERROR)
  1062. {
  1063. DispTokenErrMsg( g_hModule,
  1064. MSG_IP_BAD_OPTION_VALUE,
  1065. pttTags[pdwTagType[i]].pwszTag,
  1066. ppwcArguments[i + dwCurrentIndex] );
  1067. return ERROR_INVALID_PARAMETER;
  1068. }
  1069. break;
  1070. }
  1071. case 5: // STATS
  1072. {
  1073. TOKEN_VALUE rgEnums[] =
  1074. {
  1075. { TOKEN_VALUE_ALL, TRUE },
  1076. };
  1077. dwErr = MatchEnumTag( g_hModule,
  1078. ppwcArguments[i + dwCurrentIndex],
  1079. sizeof(rgEnums)/sizeof(TOKEN_VALUE),
  1080. rgEnums,
  1081. &bStatsAll);
  1082. if (dwErr isnot NO_ERROR)
  1083. {
  1084. DispTokenErrMsg( g_hModule,
  1085. MSG_IP_BAD_OPTION_VALUE,
  1086. pttTags[pdwTagType[i]].pwszTag,
  1087. ppwcArguments[i + dwCurrentIndex] );
  1088. return ERROR_INVALID_PARAMETER;
  1089. }
  1090. break;
  1091. }
  1092. }
  1093. }
  1094. if (dwErr isnot NO_ERROR)
  1095. {
  1096. return dwErr;
  1097. }
  1098. do {
  1099. //
  1100. // allocate and setup query structure
  1101. //
  1102. dwQuerySize = sizeof( MIB_OPAQUE_QUERY ) + 2 * sizeof(DWORD);
  1103. pQuery = (PMIB_OPAQUE_QUERY) HeapAlloc(
  1104. GetProcessHeap(), 0, dwQuerySize
  1105. );
  1106. if ( pQuery == NULL )
  1107. {
  1108. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1109. DisplayMessageToConsole(g_hModule, g_hConsole, ERROR_CONFIG, dwErr );
  1110. break;
  1111. }
  1112. pQuery->dwVarId = ( bIncludeStats ) ?
  1113. ( ( bStatsAll ) ?
  1114. MCAST_MFE_STATS_EX : MCAST_MFE_STATS ) :
  1115. MCAST_MFE;
  1116. pQuery->rgdwVarIndex[ 0 ] = dwRangeGroup & dwRangeGrpMask;
  1117. pQuery->rgdwVarIndex[ 1 ] = dwRangeSource;
  1118. pQuery->rgdwVarIndex[ 2 ] = dwRangeSrcMask;
  1119. if (bIncludeStats)
  1120. {
  1121. DisplayMessageToConsole(
  1122. g_hModule, g_hConsole,
  1123. bStatsAll ? MSG_MIB_MFESTATS_ALL_HDR : MSG_MIB_MFESTATS_HDR
  1124. );
  1125. }
  1126. else
  1127. {
  1128. DisplayMessageToConsole(g_hModule, g_hConsole, MSG_MIB_MFE_HDR );
  1129. }
  1130. while ((dwErr = MibGetNext( PID_IP,
  1131. IPRTRMGR_PID,
  1132. (PVOID) pQuery,
  1133. dwQuerySize,
  1134. (PVOID *) &pRpcInfo,
  1135. &dwOutEntrySize))
  1136. == NO_ERROR )
  1137. {
  1138. //
  1139. // if no MFEs are present quit
  1140. //
  1141. pTable = (PMIB_MFE_STATS_TABLE)( pRpcInfo->rgbyData );
  1142. if ( pTable->dwNumEntries is 0 )
  1143. {
  1144. break;
  1145. }
  1146. //
  1147. // print the MFEs
  1148. //
  1149. if ( bIncludeStats )
  1150. {
  1151. PrintMfeStatsTable( hMprMIB,
  1152. pRpcInfo, &dwLastGroup, &dwLastSource, &dwLastSrcMask,
  1153. dwRangeGroup, dwRangeGrpMask, dwRangeSource,
  1154. dwRangeSrcMask, dwType, &bDone, bStatsAll
  1155. );
  1156. }
  1157. else
  1158. {
  1159. PrintMfeTable( hMprMIB,
  1160. pRpcInfo, &dwLastGroup, &dwLastSource, &dwLastSrcMask,
  1161. dwRangeGroup, dwRangeGrpMask, dwRangeSource,
  1162. dwRangeSrcMask, dwType, &bDone
  1163. );
  1164. }
  1165. MprAdminMIBBufferFree( pRpcInfo );
  1166. pRpcInfo = NULL;
  1167. dwOutEntrySize = 0;
  1168. //
  1169. // Check if we are done
  1170. //
  1171. if ( bDone )
  1172. {
  1173. break;
  1174. }
  1175. //
  1176. // set up the next query
  1177. //
  1178. pQuery->rgdwVarIndex[ 0 ] = dwLastGroup;
  1179. pQuery->rgdwVarIndex[ 1 ] = dwLastSource;
  1180. pQuery->rgdwVarIndex[ 2 ] = dwLastSrcMask;
  1181. }
  1182. if ( dwErr != NO_ERROR && dwErr != ERROR_NO_MORE_ITEMS && dwErr != ERROR_NOT_FOUND )
  1183. {
  1184. DisplayError(NULL, dwErr );
  1185. }
  1186. } while ( FALSE );
  1187. return dwErr;
  1188. }