/*++ Copyright (c) 1998 Microsoft Corporation Module Name: net\routing\netsh\ip\protocols\msdpmib.c Abstract: Functions to get and display MSDP MIB information. Author: Dave Thaler 11/03/99 Revision History: --*/ #include "precomp.h" #pragma hdrstop #define FREE(x) HeapFree(GetProcessHeap(), 0, (x)) ULONG QueryTagArray( PTCHAR ArgumentArray[], ULONG ArgumentCount, TAG_TYPE TagTypeArray[], ULONG TagTypeCount, OUT PULONG* TagArray ); // // Flag for printing header // BOOL g_bMsdpFirst = TRUE; HANDLE g_hConsole, g_hStdOut; // This can have the other fields pfn etc MIB_OBJECT_PARSER MsdpMIBObjectMap[] = { {TOKEN_MSDP_MIB_OBJECT_GLOBALSTATS,0,0,NULL}, {TOKEN_MSDP_MIB_OBJECT_PEERSTATS, 1,1,GetMsdpMIBIpAddress}, {TOKEN_MSDP_MIB_OBJECT_SA, 0,2,GetMsdpMIBSAIndex}, }; #define MAX_MSDP_MIB_OBJECTS (sizeof(MsdpMIBObjectMap)/sizeof(MIB_OBJECT_PARSER)) MSDP_MAGIC_TABLE MsdpMIBVar[] = { {MIBID_MSDP_GLOBAL, PrintMsdpGlobalStats, 0}, {MIBID_MSDP_IPV4_PEER_ENTRY, PrintMsdpPeerStats, 4}, {MIBID_MSDP_SA_CACHE_ENTRY, PrintMsdpSA, 8}, }; DWORD GetMsdpMIBIpAddress( IN LPCWSTR *ppwcArguments, IN ULONG ulArgumentIndex, IN ULONG ulArgumentCount, OUT PDWORD pdwIndices, OUT PDWORD pdwNumParsed ) /*++ Routine Description: Gets the index IP address for peer Mib variable. Arguments: ppwcArguments - Argument array ulArgumentIndex - Index of the first argument in array pdwIndices - Indices specified in command pdwNumParsed - Number of indices in command Return Value: NO_ERROR --*/ { DWORD dwErr; ULONG i; PULONG pulTagArray; ULONG ulArgumentsLeft = ulArgumentCount - ulArgumentIndex; TAG_TYPE TagTypeArray[] = { { TOKEN_OPT_REMADDR, FALSE, FALSE } }; *pdwNumParsed = 0; if (ulArgumentsLeft < 1) { return NO_ERROR; } dwErr = QueryTagArray( &ppwcArguments[ulArgumentIndex], ulArgumentsLeft, TagTypeArray, NUM_TAGS_IN_TABLE(TagTypeArray), &pulTagArray ); if (dwErr is NO_ERROR) { for (i=0; i 1) && IsHelpToken(ppwcArguments[1])) { DisplayMessage(g_hModule, MsdpMIBObjectMap[i].dwCmdHelpToken, MsdpMIBObjectMap[i].pwszMIBObj); return NO_ERROR; } #endif if (MsdpMIBObjectMap[dwIndex].pfnMIBObjParser) { dwErr = (*MsdpMIBObjectMap[dwIndex].pfnMIBObjParser)(ppwcArguments, 1 + dwInd, dwArgCount, dwIndices, &dwNumParsed); if (dwErr isnot NO_ERROR) { return dwErr; } } // // Convert refresh rate to msec // dwRR *= 1000; dwMIBIndex = dwIndex; pQuery->dwVarId = MsdpMIBVar[dwMIBIndex].dwId; if (!InitializeConsole(&dwRR, &hMib, &g_hConsole)) { return ERROR_INIT_DISPLAY; } for ( ; ; ) { if(dwRR) { DisplayMessageToConsole(g_hModule, g_hConsole, MSG_CTRL_C_TO_QUIT); } // See if we just need to do a GET if (dwNumParsed is MsdpMIBObjectMap[dwIndex].dwNumArgs) { pQuery->rgdwVarIndex[0] = 0; for (i=0; irgdwVarIndex[i] = dwIndices[i]; } dwResult = MprAdminMIBEntryGet(hMibServer, PID_IP, MS_IP_MSDP, (LPVOID) pQuery, sizeof(MIB_OPAQUE_QUERY) + MsdpMIBVar[dwMIBIndex].ulIndexBytes-sizeof(DWORD), (LPVOID *) &pRpcInfo, &dwOutSize ); if (( dwResult isnot NO_ERROR ) and (dwResult isnot ERROR_NOT_FOUND)) { DisplayMessageToConsole( g_hModule, g_hConsole, MSG_IP_DIM_ERROR, dwResult ); break; } if ( pRpcInfo is NULL ) { break; } (*MsdpMIBVar[dwMIBIndex].pfnPrintFunction)(pRpcInfo, FORMAT_VERBOSE); MprAdminMIBBufferFree( (PVOID) pRpcInfo ); } else if (dwNumParsed is 0) { // Display All g_bMsdpFirst = TRUE; dwResult = MprAdminMIBEntryGetFirst(hMibServer, PID_IP, MS_IP_MSDP, (LPVOID) pQuery, sizeof(MIB_OPAQUE_INFO) + MsdpMIBVar[dwMIBIndex].ulIndexBytes-sizeof(DWORD), (LPVOID *) &pRpcInfo, &dwOutSize ); if (( dwResult isnot NO_ERROR ) and (dwResult isnot ERROR_NO_MORE_ITEMS)) { DisplayMessageToConsole( g_hModule, g_hConsole, MSG_IP_DIM_ERROR, dwResult ); break; } if ( pRpcInfo is NULL ) { DisplayMessageToConsole( g_hModule, g_hConsole, MSG_IP_NO_ENTRIES ); break; } (*MsdpMIBVar[dwMIBIndex].pfnPrintFunction)(pRpcInfo, FORMAT_TABLE); g_bMsdpFirst = FALSE; do { // pQuery->rgdwVarIndex[0] = pRpcInfo->IMGOD_IfIndex; // // prepare for next request // CopyMemory(pQuery->rgdwVarIndex, pRpcInfo->rgbyData, MsdpMIBVar[dwMIBIndex].ulIndexBytes ); MprAdminMIBBufferFree( (PVOID) pRpcInfo ); pRpcInfo = NULL; DEBUG2("calling next with index %d", pQuery->rgdwVarIndex[0]); dwResult = MprAdminMIBEntryGetNext(hMibServer, PID_IP, MS_IP_MSDP, (LPVOID) pQuery, sizeof(MIB_OPAQUE_QUERY) + MsdpMIBVar[dwMIBIndex].ulIndexBytes-sizeof(DWORD), (LPVOID *) &pRpcInfo, &dwOutSize ); if (dwResult is ERROR_NO_MORE_ITEMS) { g_bMsdpFirst = TRUE; return dwResult; } if ( dwResult isnot NO_ERROR ) { g_bMsdpFirst = TRUE; break; } if ( pRpcInfo is NULL ) { g_bMsdpFirst = TRUE; break; } if (pQuery->dwVarId isnot pRpcInfo->dwId) { g_bMsdpFirst = TRUE; break; } (*MsdpMIBVar[dwMIBIndex].pfnPrintFunction)(pRpcInfo, FORMAT_TABLE); } while (1); } else { // partially-specified index g_bMsdpFirst = TRUE; pQuery->rgdwVarIndex[0] = 0; for (i=0; irgdwVarIndex[i] = dwIndices[i]; } for (; irgdwVarIndex[i] = 0; } do { dwResult = MprAdminMIBEntryGetNext(hMibServer, PID_IP, MS_IP_MSDP, (LPVOID) pQuery, sizeof(MIB_OPAQUE_QUERY) + MsdpMIBVar[dwMIBIndex].ulIndexBytes-sizeof(DWORD), (LPVOID *) &pRpcInfo, &dwOutSize ); if (dwResult is NO_ERROR) { // See if we've gone too far for (i=0; irgdwVarIndex, pRpcInfo->rgbyData, dwNumParsed * sizeof(DWORD))) { dwResult = ERROR_NO_MORE_ITEMS; break; } } } if (dwResult is ERROR_NO_MORE_ITEMS) { g_bMsdpFirst = TRUE; return dwResult; } if ( dwResult isnot NO_ERROR ) { g_bMsdpFirst = TRUE; break; } if ( pRpcInfo is NULL ) { g_bMsdpFirst = TRUE; break; } if (pQuery->dwVarId isnot pRpcInfo->dwId) { g_bMsdpFirst = TRUE; break; } (*MsdpMIBVar[dwMIBIndex].pfnPrintFunction)(pRpcInfo, FORMAT_TABLE); // // prepare for next request // CopyMemory(pQuery->rgdwVarIndex, pRpcInfo->rgbyData, MsdpMIBVar[dwMIBIndex].ulIndexBytes ); MprAdminMIBBufferFree( (PVOID) pRpcInfo ); pRpcInfo = NULL; g_bMsdpFirst = FALSE; } while (1); } if (!RefreshConsole(hMib, g_hConsole, dwRR)) { break; } } return dwResult; } VOID PrintMsdpGlobalStats( PMIB_OPAQUE_INFO pRpcInfo, DWORD dwFormat ) /*++ Routine Description: Prints msdp global statistics Arguments: Return Value: --*/ { WCHAR wszRouterId[20]; PMSDP_GLOBAL_ENTRY pEntry = (PMSDP_GLOBAL_ENTRY)(pRpcInfo->rgbyData); IP_TO_TSTR(wszRouterId, &pEntry->dwRouterId); DisplayMessageToConsole(g_hModule,g_hConsole,MSG_MSDP_GLOBAL_STATS, pEntry->ulNumSACacheEntries, wszRouterId); } VOID PrintMsdpSA( PMIB_OPAQUE_INFO pRpcInfo, DWORD dwFormat ) { PMSDP_SA_CACHE_ENTRY psa; WCHAR wszGroupAddress[20]; WCHAR wszSourceAddress[20]; WCHAR wszOriginAddress[20]; WCHAR wszLearnedFromAddress[20]; WCHAR wszRPFPeerAddress[20]; DWORD dwId = (dwFormat is FORMAT_TABLE)? MSG_MSDP_SA_INFO : MSG_MSDP_SA_INFO_EX; if (g_bMsdpFirst && (dwFormat is FORMAT_TABLE)) { DisplayMessageToConsole(g_hModule,g_hConsole,MSG_MSDP_SA_INFO_HEADER); } psa = (PMSDP_SA_CACHE_ENTRY)(pRpcInfo->rgbyData); IP_TO_TSTR(wszGroupAddress, &psa->ipGroupAddr); IP_TO_TSTR(wszSourceAddress, &psa->ipSourceAddr); IP_TO_TSTR(wszOriginAddress, &psa->ipOriginRP); IP_TO_TSTR(wszLearnedFromAddress, &psa->ipPeerLearnedFrom); IP_TO_TSTR(wszRPFPeerAddress, &psa->ipRPFPeer); DisplayMessageToConsole(g_hModule, g_hConsole, dwId, wszGroupAddress, wszSourceAddress, wszOriginAddress, wszLearnedFromAddress, wszRPFPeerAddress, psa->ulInSAs, psa->ulUpTime/100, psa->ulExpiryTime/100); } VOID PrintMsdpPeerStats( PMIB_OPAQUE_INFO pRpcInfo, DWORD dwFormat ) /*++ Routine Description: Prints msdp neighbor stats Arguments: Return Value: --*/ { PMSDP_IPV4_PEER_ENTRY pPeer; WCHAR wszAddr[ADDR_LENGTH + 1]; if (g_bMsdpFirst && (dwFormat is FORMAT_TABLE)) { DisplayMessageToConsole(g_hModule,g_hConsole,MSG_MSDP_PEER_STATS_HEADER); } pPeer = (PMSDP_IPV4_PEER_ENTRY)(pRpcInfo->rgbyData); MakeUnicodeIpAddr(wszAddr, inet_ntoa(*((struct in_addr *) (&pPeer->ipRemoteAddress)))); DisplayMessageToConsole(g_hModule, g_hConsole, (dwFormat is FORMAT_TABLE)? MSG_MSDP_PEER_STATS : MSG_MSDP_PEER_STATS_EX, wszAddr, GetTceStateString(pPeer->dwState), pPeer->ulRPFFailures, pPeer->ulInSAs, pPeer->ulOutSAs, pPeer->ulInSARequests, pPeer->ulOutSARequests, pPeer->ulInSAResponses, pPeer->ulOutSAResponses, pPeer->ulInControlMessages, pPeer->ulOutControlMessages, pPeer->ulFsmEstablishedTransitions, pPeer->ulFsmEstablishedTime, pPeer->ulInMessageElapsedTime); }