windows-nt/Source/XPSP1/NT/net/rras/netsh/ip/preview/msdpmib.c
2020-09-26 16:20:57 +08:00

658 lines
18 KiB
C

/*++
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<ulArgumentsLeft; i++) {
switch(pulTagArray ? pulTagArray[i] : i) {
case 0: { // remaddr
pdwIndices[0] = GetIpAddress(ppwcArguments[i+
ulArgumentIndex]);
(*pdwNumParsed)++;
break;
}
}
}
} else {
dwErr = ERROR_SHOW_USAGE;
}
if (pulTagArray) { FREE(pulTagArray); }
return dwErr;
}
DWORD
GetMsdpMIBSAIndex(
IN LPCWSTR *ppwcArguments,
IN ULONG ulArgumentIndex,
IN ULONG ulArgumentCount,
OUT PDWORD pdwIndices,
OUT PDWORD pdwNumParsed
)
{
DWORD dwErr;
ULONG i;
ULONG ulArgumentsLeft = ulArgumentCount - ulArgumentIndex;
PULONG pulTagArray;
TAG_TYPE TagTypeArray[] = { { TOKEN_OPT_GROUPADDR, FALSE, FALSE },
{ TOKEN_OPT_SOURCEADDR, 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<ulArgumentsLeft; i++) {
switch(pulTagArray ? pulTagArray[i] : i) {
case 0: { // grpaddr
pdwIndices[0] = GetIpAddress(ppwcArguments[i+
ulArgumentIndex]);
(*pdwNumParsed)++;
break;
}
case 1: { // srcaddr
pdwIndices[1] = GetIpAddress(ppwcArguments[i+
ulArgumentIndex]);
(*pdwNumParsed)++;
break;
}
}
}
}
if (pulTagArray) { FREE(pulTagArray); }
return dwErr;
}
PWCHAR
GetTceStateString(
DWORD dwState
)
{
PWCHAR pwszStr;
static WCHAR buff[80];
VALUE_STRING ppsList[] = {{MSDP_STATE_IDLE, STRING_IDLE},
{MSDP_STATE_CONNECT, STRING_CONNECT},
{MSDP_STATE_ACTIVE, STRING_ACTIVE},
{MSDP_STATE_OPENSENT, STRING_OPENSENT},
{MSDP_STATE_OPENCONFIRM, STRING_OPENCONFIRM},
{MSDP_STATE_ESTABLISHED, STRING_ESTABLISHED},
};
DWORD dwNum = sizeof(ppsList)/sizeof(VALUE_STRING), i;
DWORD dwMsgId = 0;
for (i=0; i<dwNum; i++)
{
if (dwState is ppsList[i].dwValue)
{
dwMsgId = ppsList[i].dwStringId;
break;
}
}
if (dwMsgId)
{
pwszStr = MakeString( g_hModule, dwMsgId);
wcscpy(buff, pwszStr);
FreeString(pwszStr);
}
else
{
wsprintf(buff, L"%d", dwState);
}
return buff;
}
DWORD
HandleMsdpMibShowObject(
PWCHAR pwszMachine,
PWCHAR *ppwcArguments,
DWORD dwCurrentIndex,
DWORD dwArgCount,
DWORD dwFlags,
MIB_SERVER_HANDLE hMibServer,
BOOL *pbDone
)
/*++
Routine Description:
Parses command to get MIB object and optional parameters
Arguments:
Return Value:
--*/
{
DWORD dwIndices[MAX_NUM_INDICES];
DWORD dwNumParsed = 0;
MIB_OPAQUE_QUERY rgQueryBuff[2];
PMIB_OPAQUE_QUERY pQuery = rgQueryBuff;
PMIB_OPAQUE_INFO pRpcInfo;
DWORD dwQuerySize;
BOOL bFound = FALSE,bOptPresent = FALSE;
DWORD dwRefreshRate;
DWORD dwOutEntrySize;
DWORD i,dwResult,dwErr;
DWORD dwMIBIndex, dwIndex;
BOOL bIndex = FALSE, dwType;
DWORD dwRR = 0, dwInd = 0;
HANDLE hMib;
DWORD dwDisplayInfoId, dwDisplayInfoType, dwOptVar;
DWORD dwOutSize;
VERIFY_INSTALLED(MS_IP_MSDP, L"MSDP");
//
// Match MIB object
//
g_hMibServer = hMibServer;
ppwcArguments += (dwCurrentIndex-1);
dwArgCount -= (dwCurrentIndex-1);
dwCurrentIndex = 1;
DEBUG1("In MSDP MIB Show : %s\n",ppwcArguments[0]);
for (i = 0; i < MAX_MSDP_MIB_OBJECTS; i++)
{
if (MatchToken(ppwcArguments[0],MsdpMIBObjectMap[i].pwszMIBObj))
{
dwIndex = i;
bFound = TRUE;
DEBUG("found");
break;
}
}
if (!bFound)
{
return ERROR_CMD_NOT_FOUND;
}
#if 0
if ((dwArgCount > 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; i<MsdpMIBObjectMap[dwIndex].dwNumArgs; i++)
{
pQuery->rgdwVarIndex[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; i<dwNumParsed; i++)
{
pQuery->rgdwVarIndex[i] = dwIndices[i];
}
for (; i<MsdpMIBObjectMap[dwIndex].dwNumArgs; i++)
{
pQuery->rgdwVarIndex[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; i<dwNumParsed; i++)
{
// All index fields are DWORDs
if (memcmp(pQuery->rgdwVarIndex, 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);
}