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

2501 lines
59 KiB
C

#include "precomp.h"
#pragma hdrstop
#ifdef SN_UNICODE
# define sn_strlen wcslen
# define sn_strcpy wcscpy
# define sn_sprintf wsprintf
# define sn_strcmp wcscmp
# define SN_EMPTYSTRING L""
# define SN_L L
#else
# define sn_strlen strlen
# define sn_strcpy strcpy
# define sn_sprintf sprintf
# define sn_strcmp strcmp
# define SN_EMPTYSTRING ""
# define SN_L
#endif
IPV4_ADDRESS g_ipGrpAddr,
g_ipGrpMask;
SCOPE_NAME g_snScopeName;
enum RouterOps
{
ADD_BOUNDARY = 1,
DELETE_BOUNDARY,
ADD_SCOPE,
DELETE_SCOPE,
SET_SCOPE
};
typedef struct _SCOPE_ENTRY {
IPV4_ADDRESS ipGroupAddress;
IPV4_ADDRESS ipGroupMask;
ULONG ulNumNames;
BOOL bDivisible;
LANGID idLanguage;
SCOPE_NAME_BUFFER snScopeNameBuffer;
DWORD dwNumInterfaces;
} SCOPE_ENTRY, *PSCOPE_ENTRY;
#define MIN_SCOPE_ADDR 0xef000000
#define MAX_SCOPE_ADDR (0xefff0000 - 1)
DWORD
UpdateBoundaryBlock(
IN DWORD dwAction,
IN PBYTE pib,
OUT PBYTE *ppibNew,
IN OUT DWORD *pdwBlkSize,
IN OUT DWORD *pdwCount,
OUT BOOL *bChanged
);
PSCOPE_ENTRY
FindScopeByPrefix(
IN IPV4_ADDRESS ipGroupAddress,
IN IPV4_ADDRESS ipGroupMask,
IN PSCOPE_ENTRY pScopes,
IN ULONG ulNumScopes
)
{
DWORD dwInd;
for (dwInd = 0; dwInd < ulNumScopes; dwInd++)
{
if ( pScopes[dwInd].ipGroupAddress == ipGroupAddress
&& pScopes[dwInd].ipGroupMask == ipGroupMask )
{
return &pScopes[dwInd];
}
}
return NULL;
}
DWORD
FindScopeByName(
IN SCOPE_NAME snScopeName,
IN PSCOPE_ENTRY pScopes,
IN ULONG ulNumScopes,
OUT PSCOPE_ENTRY *ppScope
)
{
DWORD dwErr = NO_ERROR;
ULONG i, j, dwCnt = 0;
for (i = 0; i < ulNumScopes; i++)
{
if ( !sn_strcmp(snScopeName, pScopes[i].snScopeNameBuffer))
{
*ppScope = &pScopes[i];
dwCnt++;
}
}
switch (dwCnt)
{
case 0:
*ppScope = NULL;
return ERROR_NOT_FOUND;
case 1:
return NO_ERROR;
default:
return ERROR_MORE_DATA;
}
}
DWORD
MakeInfoFromScopes2(
OUT PBYTE pBuffer,
IN OUT ULONG *pulBufferLen,
IN PSCOPE_ENTRY pScopes,
IN ULONG ulNumScopes
)
/*++
Description:
Compose registry block from array of scopes.
--*/
{
DWORD dwLen, i, dwSize, dwNumNames, j, dwLanguage, dwFlags;
PLIST_ENTRY pleNode;
if (ulNumScopes is 0) {
*pulBufferLen = 0;
return NO_ERROR;
}
// Compute size needed
dwSize = sizeof(DWORD);
for (i=0; i< ulNumScopes; i++)
{
dwSize += 2 * sizeof(IPV4_ADDRESS) + 2 * sizeof(DWORD);
// Currently we only store at most one name.
for (j=0; j<pScopes[i].ulNumNames; j++)
{
dwSize += (DWORD)(2*sizeof(DWORD)
+ sn_strlen(pScopes[i].snScopeNameBuffer) * sizeof(SN_CHAR));
}
}
if (dwSize > *pulBufferLen)
{
*pulBufferLen = dwSize;
return ERROR_INSUFFICIENT_BUFFER;
}
//
// Save scope count in first DWORD
//
*((PDWORD) pBuffer) = ulNumScopes;
pBuffer += sizeof(DWORD);
//
// Now step through and add each scope to the buffer
//
for (i=0; i< ulNumScopes; i++)
{
// Copy scope address, and mask
dwLen = 2 * sizeof(IPV4_ADDRESS);
CopyMemory(pBuffer, &pScopes[i], dwLen);
pBuffer += dwLen;
// Copy flags
dwFlags = pScopes[i].bDivisible;
CopyMemory(pBuffer, &dwFlags, sizeof(dwFlags));
pBuffer += sizeof(dwFlags);
// Copy # of names
CopyMemory(pBuffer, &pScopes[i].ulNumNames, sizeof(DWORD));
pBuffer += sizeof(DWORD);
// Currently we only save at most one name
for (j=0; j<pScopes[i].ulNumNames; j++)
{
// Save language
dwLanguage = pScopes[i].idLanguage;
CopyMemory(pBuffer, &dwLanguage, sizeof(dwLanguage));
pBuffer += sizeof(dwLanguage);
// Copy scope name (save length in words)
dwLen = sn_strlen(pScopes[i].snScopeNameBuffer);
CopyMemory(pBuffer, &dwLen, sizeof(DWORD));
pBuffer += sizeof(DWORD);
dwLen *= sizeof(SN_CHAR);
if (dwLen)
{
CopyMemory(pBuffer, pScopes[i].snScopeNameBuffer, dwLen);
pBuffer += dwLen;
}
}
}
return NO_ERROR;
}
DWORD
MakeInfoFromScopes(
OUT PBYTE *ppibNew,
OUT DWORD *pdwSize,
IN PSCOPE_ENTRY pScopes,
IN ULONG ulNumScopes
)
/*++
Description:
Caller is responsible for freeing buffer returned.
--*/
{
*pdwSize = 0;
*ppibNew = NULL;
if (MakeInfoFromScopes2(NULL, pdwSize, pScopes, ulNumScopes)
is ERROR_INSUFFICIENT_BUFFER)
{
*ppibNew = MALLOC( *pdwSize );
if ( *ppibNew == NULL )
{
DisplayMessage( g_hModule, MSG_IP_NOT_ENOUGH_MEMORY );
return ERROR_NOT_ENOUGH_MEMORY;
}
}
return MakeInfoFromScopes2(*ppibNew, pdwSize, pScopes, ulNumScopes);
}
PSCOPE_ENTRY
GetScopesFromInfo(
IN PBYTE pBuffer,
OUT PULONG pulNumScopes
)
/*++
Description:
Convert a registry block into an array of scope information.
Caller is responsible for freeing pointer returned.
--*/
{
PSCOPE_ENTRY pScopes;
DWORD dwLen, i, dwNumNames, j, dwLanguage, dwFlags;
if (pBuffer is NULL)
{
*pulNumScopes = 0;
return NULL;
}
//
// Retrieve scope count from first DWORD
//
*pulNumScopes = *((PDWORD) pBuffer);
pBuffer += sizeof(DWORD);
//
// Malloc enough space for pScopes
//
pScopes = MALLOC( (*pulNumScopes) * sizeof(SCOPE_ENTRY) );
if (pScopes is NULL)
{
*pulNumScopes = 0;
return NULL;
}
//
// Now step through and add each scope to the array
//
for (i=0; i< *pulNumScopes; i++)
{
// Copy scope address, and mask
dwLen = 2 * sizeof(IPV4_ADDRESS);
CopyMemory(&pScopes[i], pBuffer, dwLen);
pBuffer += dwLen;
// Get flags
CopyMemory(&dwFlags, pBuffer, sizeof(dwFlags));
pScopes[i].bDivisible = dwFlags;
pBuffer += sizeof(dwFlags);
// Get # of names
CopyMemory(&dwNumNames, pBuffer, sizeof(DWORD));
pScopes[i].ulNumNames = dwNumNames;
pBuffer += sizeof(DWORD);
// Get names. Currently, we'll only keep the last name (if any)
// and throw out the rest.
for (j=0; j<dwNumNames; j++)
{
// Set language name
CopyMemory(&dwLanguage, pBuffer, sizeof(dwLanguage));
pBuffer += sizeof(dwLanguage);
pScopes[i].idLanguage = (LANGID)dwLanguage;
CopyMemory(&dwLen, pBuffer, sizeof(DWORD));
pBuffer += sizeof(DWORD);
CopyMemory( pScopes[i].snScopeNameBuffer,
pBuffer,
dwLen * sizeof(SN_CHAR) );
pScopes[i].snScopeNameBuffer[ dwLen ] = '\0';
pBuffer += dwLen * sizeof(SN_CHAR);
pScopes[i].ulNumNames = 1;
}
pScopes[i].dwNumInterfaces = 0; // this value is ignored
}
return pScopes;
}
PSCOPE_ENTRY
GetScopes(
OUT PULONG pulNumScopes,
OUT PBYTE *ppBuffer
)
/*++
Description:
Creates a SCOPE_ENTRY array by parsing the info block
Caller is responsible for freeing both the pointer returned
and the buffer passed back.
Called by:
ShowBoundaryInfoForInterface(), UpdateScopeBlock()
--*/
{
DWORD i, dwLen, dwErr, dwBlkSize, dwCount;
DWORD dwInd;
PSCOPE_ENTRY pScopes;
if ( IpmontrGetInfoBlockFromGlobalInfo( IP_MCAST_BOUNDARY_INFO,
ppBuffer,
&dwBlkSize,
&dwCount ) isnot NO_ERROR)
{
*pulNumScopes = 0;
return NULL;
}
pScopes = GetScopesFromInfo(*ppBuffer, pulNumScopes);
return pScopes;
}
DWORD
ScopeNameToPrefix(
IN SCOPE_NAME snScopeName,
OUT IPV4_ADDRESS *pipScopeAddr,
OUT IPV4_ADDRESS *pipScopeMask
)
{
DWORD dwErr = ERROR_NOT_FOUND;
ULONG ulNumScopes;
PBYTE pBuffer = NULL;
PSCOPE_ENTRY pScopes, pScope;
// If first character is a digit, then assume it's
// an address, not a name.
if (iswdigit(snScopeName[0]))
{
dwErr = GetIpAddress(snScopeName, pipScopeAddr);
if (dwErr is NO_ERROR)
{
return NO_ERROR;
}
}
pScopes = GetScopes( &ulNumScopes, &pBuffer );
if (pScopes)
{
dwErr = FindScopeByName(snScopeName, pScopes, ulNumScopes, &pScope);
if (dwErr is NO_ERROR)
{
*pipScopeAddr = pScope->ipGroupAddress;
*pipScopeMask = pScope->ipGroupMask;
dwErr = NO_ERROR;
}
FREE(pScopes);
}
if (pBuffer)
FREE(pBuffer);
return dwErr;
}
DWORD
UpdateScope(
IN PSCOPE_ENTRY pScopeToUpdate,
IN PSCOPE_ENTRY pScopes,
IN ULONG ulNumScopes,
OUT PBYTE *ppibNew,
OUT DWORD *pdwSizeNew
)
/*++
Description:
Caller is responsible for freeing buffer returned.
--*/
{
// Update the scope name
sn_strcpy(pScopeToUpdate->snScopeNameBuffer, g_snScopeName);
pScopeToUpdate->ulNumNames = 1;
pScopeToUpdate->idLanguage = GetUserDefaultLangID();
// Now convert the array to a buffer
return MakeInfoFromScopes( ppibNew, pdwSizeNew, pScopes, ulNumScopes);
}
DWORD
DeleteBoundaryFromInterface(
IN LPCWSTR pwszIfName,
IN PSCOPE_ENTRY pScopeToDelete
)
{
BOOL bChanged;
DWORD dwErr, dwBlkSize, dwCount, dwIfType;
PBYTE pibNew, pib;
dwErr = IpmontrGetInfoBlockFromInterfaceInfo( pwszIfName,
IP_MCAST_BOUNDARY_INFO,
&pib,
&dwBlkSize,
&dwCount,
&dwIfType );
if (dwErr is ERROR_NOT_FOUND)
return NO_ERROR;
if (dwErr isnot NO_ERROR)
return dwErr;
dwErr = UpdateBoundaryBlock( DELETE_BOUNDARY,
pib,
&pibNew,
&dwBlkSize,
&dwCount,
&bChanged );
if (dwErr is NO_ERROR && bChanged)
{
dwErr = IpmontrSetInfoBlockInInterfaceInfo( pwszIfName,
IP_MCAST_BOUNDARY_INFO,
pibNew,
dwBlkSize,
dwCount );
}
if (pib)
FREE(pib);
if (pibNew)
FREE(pibNew);
return dwErr;
}
DWORD
DeleteScopeBoundaries(
IN PSCOPE_ENTRY pScopeToDelete
)
{
DWORD dwErr, dwCount, dwTotal, i;
PMPR_INTERFACE_0 pmi0;
// Enumerate interfaces
dwErr = IpmontrInterfaceEnum((PBYTE *) &pmi0, &dwCount, &dwTotal);
if (dwErr isnot NO_ERROR)
{
DisplayError(g_hModule, dwErr);
return dwErr;
}
// Delete scope boundaries for each interface
for ( i = 0; i < dwCount && dwErr is NO_ERROR; i++)
{
dwErr = DeleteBoundaryFromInterface( pmi0[i].wszInterfaceName,
pScopeToDelete );
// Ignore ERROR_NO_SUCH_INTERFACE since it may be that IP
// is not enabled on the interface, so we expect to get this
// error sometimes.
if (dwErr is ERROR_NO_SUCH_INTERFACE)
{
dwErr = NO_ERROR;
}
}
return dwErr;
}
DWORD
DeleteScope(
IN PSCOPE_ENTRY pScopeToDelete,
IN PSCOPE_ENTRY pScopes,
IN ULONG *pulNumScopes,
OUT PBYTE *ppibNew,
OUT DWORD *pdwSizeNew
)
/*++
Description:
Creates a new info block which does not include the scope given
by pScopeToDelete.
Caller is responsible for freeing buffer returned.
Called by:
UpdateScopeBlock()
--*/
{
DWORD dwErr;
// Delete all boundaries for this scope
dwErr = DeleteScopeBoundaries(pScopeToDelete);
if (dwErr isnot NO_ERROR)
return dwErr;
// Delete the scope from the array
MoveMemory( pScopeToDelete,
pScopeToDelete+1,
((PBYTE)(pScopes + *pulNumScopes))
- ((PBYTE)(pScopeToDelete + 1) ));
(*pulNumScopes)--;
// Now convert the array to a buffer
return MakeInfoFromScopes( ppibNew, pdwSizeNew, pScopes, *pulNumScopes);
}
DWORD
AddScope(
IN OUT PSCOPE_ENTRY *ppScopes,
IN ULONG *pulNumScopes,
OUT PBYTE *ppibNew,
OUT DWORD *pdwSizeNew
)
/*++
Description:
Creates a new info block which includes the scope given
by g_snScopeName, g_dwDstAddr, and g_dwDstMask.
Caller is responsible for freeing buffer returned.
Called by:
UpdateScopeBlock()
--*/
{
PBYTE *pBuff;
DWORD dwRes = NO_ERROR,
dwInd,
dwSize = 0,
dwSizeReqd = 0;
SCOPE_ENTRY *pScopes = *ppScopes;
do
{
// Make room for the new scope
if (*pulNumScopes > 0)
pScopes = REALLOC( pScopes,
(*pulNumScopes + 1) * sizeof(SCOPE_ENTRY) );
else
pScopes = MALLOC( sizeof(SCOPE_ENTRY) );
if (!pScopes)
return ERROR_NOT_ENOUGH_MEMORY;
dwInd = (*pulNumScopes)++;
// Fill in the new scope
ZeroMemory(&pScopes[dwInd], sizeof(SCOPE_ENTRY));
pScopes[dwInd].ipGroupAddress = g_ipGrpAddr;
pScopes[dwInd].ipGroupMask = g_ipGrpMask;
sn_strcpy(pScopes[dwInd].snScopeNameBuffer, g_snScopeName);
pScopes[dwInd].ulNumNames = 1;
pScopes[dwInd].idLanguage = GetUserDefaultLangID();
// Now convert the array to a buffer
dwRes = MakeInfoFromScopes( ppibNew, &dwSize, pScopes, *pulNumScopes);
} while ( FALSE );
*pdwSizeNew = dwSize;
*ppScopes = pScopes;
return dwRes;
}
BOOL
IsContiguous(
IN IPV4_ADDRESS dwMask
)
{
register int i;
dwMask = ntohl(dwMask);
// Set i to index of lowest 1 bit, or 32 if none
for (i=0; i<32 && !(dwMask & (1<<i)); i++);
// Set i to index of lowest 0 bit greater than the 1 bit found,
// or 32 if none
for (; i<32 && (dwMask & (1<<i)); i++);
// Mask is contiguous if we got up to 32 without finding such
// a 0 bit.
return (i is 32);
}
DWORD
UpdateScopeBlock(
DWORD dwAction,
PBYTE pib,
PBYTE *ppibNew,
DWORD *pdwBlkSize,
DWORD *pdwCount
)
/*++
Description:
Caller is responsible for freeing buffer returned.
Called by:
IpAddSetDelScope()
--*/
{
DWORD dwRes = (DWORD) -1,
dwInd = 0,
dwSize = 0;
ULONG ulNumScopes = 0;
PSCOPE_ENTRY pScopes = NULL,
pFoundScope = NULL;
do
{
*ppibNew = NULL;
*pdwBlkSize = 0;
*pdwCount = 0;
//
// Verify scope info.
//
if ( ( g_ipGrpAddr & g_ipGrpMask ) != g_ipGrpAddr
|| ntohl(g_ipGrpAddr) < MIN_SCOPE_ADDR
|| ntohl(g_ipGrpAddr) > MAX_SCOPE_ADDR)
{
dwRes = ERROR_INVALID_PARAMETER;
break;
}
// Make sure mask is contiguous
if (!IsContiguous(g_ipGrpMask))
{
char buff[20], *lpstr;
lpstr = inet_ntoa( *((struct in_addr *) &g_ipGrpMask));
if (lpstr != NULL)
{
strcpy( buff, lpstr );
DisplayMessage( g_hModule, MSG_IP_BAD_IP_MASK, buff );
}
break;
}
//
// Find if specified scope is present
//
pScopes = GetScopesFromInfo( pib, &ulNumScopes );
if ( pScopes )
{
pFoundScope = FindScopeByPrefix( g_ipGrpAddr,
g_ipGrpMask,
pScopes,
ulNumScopes
);
}
//
// Update the scope infoblock.
//
switch ( dwAction )
{
case ADD_SCOPE:
//
// If scope is not present, add it. Else return error.
//
if ( !pFoundScope )
{
dwRes = AddScope( &pScopes, &ulNumScopes, ppibNew, &dwSize );
if ( dwRes == NO_ERROR )
{
*pdwBlkSize = dwSize;
*pdwCount = 1;
}
break;
}
// else fall through into SET_SCOPE.
case SET_SCOPE:
//
// if scope present, update it.
//
if ( pFoundScope )
{
dwRes = UpdateScope( pFoundScope,
pScopes,
ulNumScopes,
ppibNew,
&dwSize );
if ( dwRes == NO_ERROR )
{
*pdwBlkSize = dwSize;
*pdwCount = 1;
}
}
else
{
dwRes = ERROR_INVALID_PARAMETER;
}
break;
case DELETE_SCOPE:
//
// Delete scope only if present.
//
if ( pFoundScope )
{
dwRes = DeleteScope( pFoundScope,
pScopes,
&ulNumScopes,
ppibNew,
&dwSize );
if ( dwRes == NO_ERROR )
{
*pdwBlkSize = dwSize;
*pdwCount = (dwSize>0)? 1 : 0;
}
}
else
{
dwRes = ERROR_INVALID_PARAMETER;
}
break;
}
} while ( FALSE );
if (pScopes)
FREE( pScopes );
return dwRes;
}
DWORD
VerifyBoundaryPrefix(
IPV4_ADDRESS ipAddr,
IPV4_ADDRESS ipMask
)
{
WCHAR wstr1[20], wstr2[20];
//
// Verify boundary info.
//
if (ntohl(ipAddr) < MIN_SCOPE_ADDR
|| ntohl(ipAddr) > MAX_SCOPE_ADDR)
{
MakeAddressStringW(wstr1, htonl(MIN_SCOPE_ADDR));
MakeAddressStringW(wstr2, htonl(MAX_SCOPE_ADDR));
DisplayMessage( g_hModule,
EMSG_INVALID_ADDR,
wstr1,
wstr2 );
return ERROR_INVALID_PARAMETER;
}
if ( ( ipAddr & ipMask ) != ipAddr )
{
DisplayMessage( g_hModule, EMSG_PREFIX_ERROR );
return ERROR_INVALID_PARAMETER;
}
// Make sure mask is contiguous
if (!IsContiguous(ipMask))
{
char buff[20], *lpstr;
lpstr = inet_ntoa( *((struct in_addr *) &g_ipGrpMask));
if (lpstr != NULL)
{
strcpy( buff, lpstr );
DisplayMessage( g_hModule, MSG_IP_BAD_IP_MASK, buff );
}
return ERROR_INVALID_PARAMETER;
}
return NO_ERROR;
}
DWORD
IpAddSetDelScope(
DWORD dwAction,
PWCHAR *ppwcArguments,
DWORD dwCurrentIndex,
DWORD dwArgCount
)
{
DWORD dwErr;
TAG_TYPE pttTags[] = {{TOKEN_GROUP_ADDRESS,FALSE,FALSE},
{TOKEN_GROUP_MASK, FALSE,FALSE},
{TOKEN_SCOPE_NAME, FALSE,FALSE}};
SCOPE_NAME_BUFFER snScopeName;
DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
IPV4_ADDRESS ipGroup, ipMask;
DWORD dwBlkSize, dwCount, i, dwNumParsed;
PBYTE pib, pibNew = NULL;
DWORD dwArgsReqd = (dwAction is DELETE_SCOPE)? 1 : 3;
PWCHAR p;
// Do generic processing
dwErr = PreHandleCommand( ppwcArguments,
dwCurrentIndex,
dwArgCount,
pttTags,
sizeof(pttTags)/sizeof(TAG_TYPE),
dwArgsReqd,
sizeof(pttTags)/sizeof(TAG_TYPE),
rgdwTagType );
if (dwErr)
{
return dwErr;
}
g_ipGrpAddr = g_ipGrpMask = 0;
for(i = 0; i < dwArgCount - dwCurrentIndex; i ++)
{
switch (rgdwTagType[i])
{
case 1: // GRPMASK
{
dwErr = GetIpMask(ppwcArguments[i + dwCurrentIndex],
&g_ipGrpMask);
if (dwErr is ERROR_INVALID_PARAMETER)
{
DisplayMessage( g_hModule, MSG_IP_BAD_IP_ADDR,
ppwcArguments[i + dwCurrentIndex]);
DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
pttTags[rgdwTagType[i]].pwszTag,
ppwcArguments[i + dwCurrentIndex]);
return NO_ERROR;
}
break;
}
case 0: // GRPADDR
{
dwErr = GetIpPrefix(ppwcArguments[i + dwCurrentIndex],
&g_ipGrpAddr,
&g_ipGrpMask);
if (!((dwErr is ERROR_INVALID_PARAMETER)
&& (dwAction is DELETE_SCOPE)))
{
break;
}
// FALLTHROUGH
}
case 2 : // SCOPENAME
{
// Strip leading and trailing whitespace
for (p = ppwcArguments[i + dwCurrentIndex]; iswspace(*p); p++);
while (iswspace( p[wcslen(p) - 1] ))
{
p[ wcslen(p)-1 ] = 0;
}
if (wcslen(p) > MAX_SCOPE_NAME_LEN)
{
DisplayMessage( g_hModule,
EMSG_SCOPE_NAME_TOO_LONG,
MAX_SCOPE_NAME_LEN );
return NO_ERROR;
}
sn_strcpy( snScopeName, p);
g_snScopeName = snScopeName;
if (dwAction is DELETE_SCOPE)
{
dwErr = ScopeNameToPrefix(snScopeName,
&g_ipGrpAddr,
&g_ipGrpMask);
if (dwErr is ERROR_MORE_DATA)
{
DisplayMessage( g_hModule, EMSG_AMBIGUOUS_SCOPE_NAME,
ppwcArguments[i + dwCurrentIndex]);
return NO_ERROR;
}
}
break;
}
}
}
if (dwErr isnot NO_ERROR)
{
return dwErr;
}
if (!g_ipGrpAddr || !g_ipGrpMask)
{
return ERROR_INVALID_SYNTAX;
}
dwErr = VerifyBoundaryPrefix(g_ipGrpAddr, g_ipGrpMask);
if (dwErr)
{
return NO_ERROR;
}
do {
dwErr = IpmontrGetInfoBlockFromGlobalInfo( IP_MCAST_BOUNDARY_INFO,
&pib,
&dwBlkSize,
&dwCount );
if (dwErr is ERROR_NOT_FOUND)
{
//
// No info of this type is currently present
//
dwErr = NO_ERROR;
dwCount = 1;
}
if (dwErr isnot NO_ERROR)
break;
dwErr = UpdateScopeBlock( dwAction,
pib,
&pibNew,
&dwBlkSize,
&dwCount );
if (dwErr isnot NO_ERROR)
break;
dwErr = IpmontrSetInfoBlockInGlobalInfo( IP_MCAST_BOUNDARY_INFO,
pibNew,
dwBlkSize,
dwCount );
} while (FALSE);
if (pib)
HeapFree(GetProcessHeap(), 0 , pib);
if (pibNew)
HeapFree(GetProcessHeap(), 0 , pibNew);
return dwErr;
}
DWORD
HandleIpAddScope(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
/*++
Routine Description:
Arguments:
ppwcArguments - Argument array
dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR
--*/
{
return IpAddSetDelScope( ADD_SCOPE,
ppwcArguments,
dwCurrentIndex,
dwArgCount );
}
DWORD
HandleIpDelScope(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
/*++
Routine Description:
Arguments:
ppwcArguments - Argument array
dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR
--*/
{
return IpAddSetDelScope( DELETE_SCOPE,
ppwcArguments,
dwCurrentIndex,
dwArgCount );
}
DWORD
HandleIpSetScope(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
/*++
Routine Description:
Arguments:
ppwcArguments - Argument array
dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR
--*/
{
return IpAddSetDelScope( SET_SCOPE,
ppwcArguments,
dwCurrentIndex,
dwArgCount );
}
DWORD
ShowScopes(
IN HANDLE hFile
)
{
DWORD dwRes = (DWORD) -1,
dwCnt = 0,
dwInd = 0,
dwGlobalSize = 0;
ULONG ulNumScopes = 0;
CHAR szAddr1[ ADDR_LENGTH ],
szAddr2[ ADDR_LENGTH ];
PSCOPE_ENTRY pScope,
pScopes;
HANDLE hTransport = (HANDLE) NULL;
PBYTE pScopesBuffer;
SCOPE_NAME_BUFFER snScopeNameBuffer;
do
{
pScopes = GetScopes( &ulNumScopes, &pScopesBuffer );
if (hFile is NULL)
{
if (ulNumScopes)
{
DisplayMessage( g_hModule, MSG_RTR_SCOPE_HDR );
}
else
{
DisplayMessage( g_hModule, MSG_IP_NO_ENTRIES );
}
}
//
// Enumerate the scopes
//
for ( dwCnt = 0; dwCnt < ulNumScopes; dwCnt++ )
{
pScope = &pScopes[dwCnt];
strcpy(
szAddr1,
inet_ntoa( *((struct in_addr *) &pScope->ipGroupAddress) )
);
strcpy(
szAddr2,
inet_ntoa( *((struct in_addr *) &pScope->ipGroupMask) )
);
MakePrefixStringW(snScopeNameBuffer,
pScope->ipGroupAddress,
pScope->ipGroupMask);
if (hFile)
{
PWCHAR pwszQuoted = MakeQuotedString( (pScope->ulNumNames)?
pScope->snScopeNameBuffer : snScopeNameBuffer );
DisplayMessageT( DMP_SCOPE_INFO,
szAddr1,
szAddr2,
pwszQuoted );
FreeQuotedString(pwszQuoted);
}
else
{
DisplayMessage( g_hModule,
MSG_RTR_SCOPE_INFO,
szAddr1,
szAddr2,
(pScope->ulNumNames)? pScope->snScopeNameBuffer
: snScopeNameBuffer );
}
}
dwRes = NO_ERROR;
if (pScopes)
FREE(pScopes);
if (pScopesBuffer)
FREE(pScopesBuffer);
} while ( FALSE );
return dwRes;
}
DWORD
HandleIpShowScope(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
/*++
Routine Description:
Arguments:
ppwcArguments - Argument array
dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR
--*/
{
return ShowScopes(0);
}
DWORD
DeleteBoundary(
IN DWORD dwDelInd,
IN PBYTE pib,
OUT PBYTE *ppibNew,
IN OUT DWORD *pdwCount
)
/*++
Description:
Creates a new info block header which does not include the
boundary with the specified index.
Caller is responsible for freeing buffer returned.
Called by:
UpdateBoundaryBlock()
--*/
{
DWORD dwInd = 0,
dwCnt = 0,
dwCnt0 = 0,
dwSize = 0,
dwRes = NO_ERROR;
LPBYTE pbDst = (LPBYTE) NULL,
pbSrc = (LPBYTE) NULL;
PRTR_INFO_BLOCK_HEADER pibh = (PRTR_INFO_BLOCK_HEADER) NULL;
PMIB_BOUNDARYROW pimbSrc = (PMIB_BOUNDARYROW) NULL;
PMIB_BOUNDARYROW pimbDst = (PMIB_BOUNDARYROW) NULL;
//
// Create new info block with boundary removed.
//
dwSize = (*pdwCount - 1) * sizeof( MIB_BOUNDARYROW );
if (dwSize is 0)
{
*ppibNew = NULL;
*pdwCount = 0;
return NO_ERROR;
}
*ppibNew = MALLOC( dwSize );
if ( *ppibNew == NULL )
{
DisplayMessage( g_hModule, MSG_IP_NOT_ENOUGH_MEMORY );
return ERROR_NOT_ENOUGH_MEMORY;
}
//
// Copy boundaries, skip boundary to be deleted
//
pimbDst = (PMIB_BOUNDARYROW) *ppibNew;
pimbSrc = (PMIB_BOUNDARYROW) pib;
for ( dwCnt = 0, dwCnt0 = 0;
dwCnt < *pdwCount;
dwCnt++ )
{
if ( dwCnt == dwDelInd )
{
continue;
}
pimbDst[ dwCnt0 ] = pimbSrc[ dwCnt ];
dwCnt0++;
}
(*pdwCount)--;
return NO_ERROR;
}
DWORD
AddBoundary (
IN PBYTE pib,
OUT PBYTE *ppibNew,
IN OUT DWORD *pdwCount
)
/*++
Description:
Creates a new info block which includes a boundary for the
scope identified by g_ipGrpAddr/g_ipGrpMask.
Caller is responsible for freeing buffer returned.
Called by:
UpdateBoundaryBlock()
--*/
{
DWORD dwRes = NO_ERROR,
dwInd = 0,
dwSize = 0;
LPBYTE pbDst = (LPBYTE) NULL,
pbSrc = (LPBYTE) NULL;
PMIB_BOUNDARYROW pimb = (PMIB_BOUNDARYROW ) NULL;
dwRes = VerifyBoundaryPrefix(g_ipGrpAddr, g_ipGrpMask);
if (dwRes)
{
return NO_ERROR;
}
do
{
*ppibNew = NULL;
//
// If this is the first boundary, create info block
// with an extra TocEntry.
//
dwSize = (*pdwCount + 1) * sizeof( MIB_BOUNDARYROW );
*ppibNew = MALLOC( dwSize );
if ( *ppibNew == NULL )
{
DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY );
dwRes = ERROR_NOT_ENOUGH_MEMORY;
break;
}
pbDst = *ppibNew;
CopyMemory( pbDst, pib, (*pdwCount) * sizeof(MIB_BOUNDARYROW) );
pbDst += (*pdwCount) * sizeof(MIB_BOUNDARYROW);
(*pdwCount)++;
pimb = (PMIB_BOUNDARYROW) pbDst;
pimb-> dwGroupAddress = g_ipGrpAddr;
pimb-> dwGroupMask = g_ipGrpMask;
pbDst += sizeof( MIB_BOUNDARYROW );
} while ( FALSE );
return dwRes;
}
BOOL
IsBoundaryPresent(
IN IPV4_ADDRESS ipGroupAddress,
IN IPV4_ADDRESS ipGroupMask,
IN PMIB_BOUNDARYROW pimb,
IN DWORD dwNumBoundaries,
OUT PDWORD pdwInd
)
/*++
Returns:
TRUE if present, and sets dwInd to index
FALSE if not present, and sets dwInd to -1
Called by:
UpdateBoundaryBlock()
--*/
{
DWORD dwInd = 0;
*pdwInd = (DWORD) -1;
for ( dwInd = 0; dwInd < dwNumBoundaries; dwInd++, pimb++ )
{
if ( pimb-> dwGroupAddress != ipGroupAddress
|| pimb-> dwGroupMask != ipGroupMask )
{
continue;
}
*pdwInd = dwInd;
return TRUE;
}
return FALSE;
}
DWORD
UpdateBoundaryBlock(
IN DWORD dwAction,
IN PBYTE pib,
OUT PBYTE *ppibNew,
IN OUT DWORD *pdwBlkSize,
IN OUT DWORD *pdwCount,
OUT BOOL *pbChanged
)
/*++
Description:
Caller is responsible for freeing buffer returned.
Called by:
IpAddDelBoundary(), DeleteBoundaryFromInterface()
--*/
{
DWORD dwRes = NO_ERROR,
dwInd = 0,
dwInd0 = 0;
BOOL bBoFound = FALSE;
PMIB_BOUNDARYROW pimb = (PMIB_BOUNDARYROW) NULL;
*pbChanged = FALSE;
do
{
*ppibNew = NULL;
//
// Find if specified boundary is present
//
bBoFound = IsBoundaryPresent( g_ipGrpAddr,
g_ipGrpMask,
(PMIB_BOUNDARYROW)pib,
*pdwCount,
&dwInd0 );
//
// Update the boundary infoblock.
//
switch ( dwAction )
{
case ADD_BOUNDARY:
//
// If boundary is not present, add it. Else return error.
//
if ( !bBoFound )
{
dwRes = AddBoundary( pib, ppibNew, pdwCount );
*pdwBlkSize = sizeof(MIB_BOUNDARYROW);
*pbChanged = TRUE;
}
else
{
dwRes = ERROR_OBJECT_ALREADY_EXISTS;
}
break;
case DELETE_BOUNDARY:
//
// Delete boundary only if present.
//
if ( bBoFound )
{
dwRes = DeleteBoundary( dwInd0, pib, ppibNew, pdwCount );
*pbChanged = TRUE;
}
// If not present, return success but don't set the changed flag.
break;
}
} while ( FALSE );
return dwRes;
}
DWORD
IpAddDelBoundary(
DWORD dwAction,
PWCHAR *ppwcArguments,
DWORD dwCurrentIndex,
DWORD dwArgCount
)
{
DWORD dwErr;
TAG_TYPE pttTags[] = {{TOKEN_NAME, TRUE, FALSE},
{TOKEN_GROUP_ADDRESS, FALSE,FALSE},
{TOKEN_GROUP_MASK, FALSE,FALSE},
{TOKEN_SCOPE_NAME, FALSE,FALSE},
};
WCHAR rgwcIfName[MAX_INTERFACE_NAME_LEN + 1];
DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
IPV4_ADDRESS ipGroup, ipMask;
DWORD dwBlkSize, dwCount, dwIfType, i, dwNumParsed;
PBYTE pib, pibNew = NULL;
BOOL bChanged;
// Do generic processing
dwErr = PreHandleCommand( ppwcArguments,
dwCurrentIndex,
dwArgCount,
pttTags,
sizeof(pttTags)/sizeof(TAG_TYPE),
2,
3,
rgdwTagType );
if (dwErr)
{
return dwErr;
}
g_ipGrpAddr = g_ipGrpMask = 0;
for(i = 0; i < dwArgCount - dwCurrentIndex; i ++)
{
switch (rgdwTagType[i])
{
case 0 : // NAME
{
GetInterfaceName(ppwcArguments[i + dwCurrentIndex],
rgwcIfName,
sizeof(rgwcIfName),
&dwNumParsed);
break;
}
case 1: // GRPADDR
{
dwErr = GetIpPrefix(ppwcArguments[i + dwCurrentIndex],
&g_ipGrpAddr,
&g_ipGrpMask);
if (!((dwErr is ERROR_INVALID_PARAMETER)
&& (dwAction is DELETE_BOUNDARY)))
{
break;
}
// FALLTHROUGH
}
case 3: // SCOPENAME
{
dwErr = ScopeNameToPrefix( ppwcArguments[i + dwCurrentIndex],
&g_ipGrpAddr,
&g_ipGrpMask );
if (dwErr is ERROR_MORE_DATA)
{
DisplayMessage( g_hModule, EMSG_AMBIGUOUS_SCOPE_NAME,
ppwcArguments[i + dwCurrentIndex]);
return NO_ERROR;
}
break;
}
case 2: // GRPMASK
{
dwErr = GetIpMask(ppwcArguments[i + dwCurrentIndex],
&g_ipGrpMask);
if (dwErr is ERROR_INVALID_PARAMETER)
{
DisplayMessage( g_hModule, MSG_IP_BAD_IP_ADDR,
ppwcArguments[i + dwCurrentIndex]);
DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
pttTags[rgdwTagType[i]].pwszTag,
ppwcArguments[i + dwCurrentIndex]);
return NO_ERROR;
}
break;
}
}
}
if (dwErr isnot NO_ERROR)
{
return dwErr;
}
if (!g_ipGrpAddr || !g_ipGrpMask)
{
return ERROR_INVALID_SYNTAX;
}
do {
dwErr = IpmontrGetInfoBlockFromInterfaceInfo( rgwcIfName,
IP_MCAST_BOUNDARY_INFO,
&pib,
&dwBlkSize,
&dwCount,
&dwIfType );
if (dwErr is ERROR_NOT_FOUND)
{
//
// No info of this type is currently present
//
dwErr = NO_ERROR;
dwCount = 0;
}
if (dwErr isnot NO_ERROR)
break;
dwErr = UpdateBoundaryBlock( dwAction,
pib,
&pibNew,
&dwBlkSize,
&dwCount,
&bChanged );
if (dwErr isnot NO_ERROR)
break;
if (bChanged)
{
dwErr = IpmontrSetInfoBlockInInterfaceInfo( rgwcIfName,
IP_MCAST_BOUNDARY_INFO,
pibNew,
dwBlkSize,
dwCount );
}
} while (FALSE);
if (pib)
FREE(pib);
if (pibNew)
FREE(pibNew);
return dwErr;
}
DWORD
HandleIpAddBoundary(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
/*++
Routine Description:
Arguments:
ppwcArguments - Argument array
dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR
--*/
{
return IpAddDelBoundary( ADD_BOUNDARY,
ppwcArguments,
dwCurrentIndex,
dwArgCount );
}
DWORD
HandleIpDelBoundary(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
/*++
Routine Description:
Arguments:
ppwcArguments - Argument array
dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR
--*/
{
return IpAddDelBoundary( DELETE_BOUNDARY,
ppwcArguments,
dwCurrentIndex,
dwArgCount );
}
DWORD
ShowBoundaryInfoForInterface(
IN HANDLE hFile,
IN LPCWSTR pwszIfName,
OUT PDWORD pdwNumRows
)
/*++
Called by:
ShowBoundaryInfo()
--*/
{
DWORD dwErr,
dwBlkSize,
dwCount,
dwIfType,
dwNumParsed,
dwInd = 0,
dwCnt = 0,
dwSize = 0,
dwGlobalSize = 0,
dwIfLen = 0;
WCHAR wszIfDesc[MAX_INTERFACE_NAME_LEN + 1];
ULONG ulNumScopes = 0;
CHAR szAddr1[ ADDR_LENGTH ],
szAddr2[ ADDR_LENGTH ];
HANDLE hIfTransport = (HANDLE) NULL,
hTransport = (HANDLE) NULL;
PRTR_INFO_BLOCK_HEADER pibhIfInfo = (PRTR_INFO_BLOCK_HEADER) NULL,
pibhGlobalInfo = (PRTR_INFO_BLOCK_HEADER) NULL;
PMIB_BOUNDARYROW pimb;
PSCOPE_ENTRY pScope,
pScopes;
PBYTE pScopesBuffer;
SCOPE_NAME_BUFFER snScopeNameBuffer;
do
{
dwErr = IpmontrGetInfoBlockFromInterfaceInfo( pwszIfName,
IP_MCAST_BOUNDARY_INFO,
(PBYTE*)&pimb,
&dwBlkSize,
&dwCount,
&dwIfType );
if (dwErr is ERROR_NOT_FOUND)
dwErr = NO_ERROR;
if (dwErr isnot NO_ERROR)
return dwErr;
if ( !dwCount )
break;
dwErr = GetInterfaceDescription(pwszIfName,
wszIfDesc,
&dwNumParsed);
if (!dwNumParsed)
{
wcscpy(wszIfDesc, pwszIfName);
}
dwIfLen = wcslen(wszIfDesc);
//
// Retrieve the list of scopes in pScopes[]
//
pScopes = GetScopes( &ulNumScopes, &pScopesBuffer );
//
// Enumerate the boundaries
//
for ( dwCnt = 0; dwCnt < dwCount; dwCnt++ )
{
pScope = FindScopeByPrefix( pimb[dwCnt].dwGroupAddress,
pimb[dwCnt].dwGroupMask,
pScopes,
ulNumScopes );
strcpy( szAddr1,
inet_ntoa( *((struct in_addr *) &pimb[dwCnt].dwGroupAddress)
)
);
strcpy( szAddr2,
inet_ntoa( *((struct in_addr *) &pimb[dwCnt].dwGroupMask) )
);
// Copy prefix to snScopeNameBuffer
MakePrefixStringW(snScopeNameBuffer,
pimb[dwCnt].dwGroupAddress,
pimb[dwCnt].dwGroupMask);
if (hFile)
{
PWCHAR pwszQuoted = MakeQuotedString(wszIfDesc);
DisplayMessageT( DMP_BOUNDARY_INFO,
pwszQuoted,
szAddr1,
szAddr2,
(pScope && pScope->ulNumNames)?
pScope->snScopeNameBuffer : snScopeNameBuffer );
FreeQuotedString(pwszQuoted);
}
else
{
if ( !*pdwNumRows )
{
DisplayMessage( g_hModule, MSG_RTR_BOUNDARY_HDR );
}
if (dwIfLen <= 15)
{
DisplayMessage( g_hModule,
MSG_RTR_BOUNDARY_INFO_2,
wszIfDesc,
szAddr1,
szAddr2,
(pScope && pScope->ulNumNames)?
pScope->snScopeNameBuffer : snScopeNameBuffer );
}
else
{
DisplayMessage( g_hModule,
MSG_RTR_BOUNDARY_INFO_0,
wszIfDesc
);
DisplayMessage( g_hModule,
MSG_RTR_BOUNDARY_INFO_1,
szAddr1,
szAddr2,
(pScope && pScope->ulNumNames)?
pScope->snScopeNameBuffer : snScopeNameBuffer );
}
}
(*pdwNumRows) ++;
}
dwErr = NO_ERROR;
if (pScopes)
FREE(pScopes);
if (pScopesBuffer)
FREE(pScopesBuffer);
} while ( FALSE );
if ( pimb ) { FREE(pimb); }
return dwErr;
}
DWORD
HandleIpShowBoundary(
IN LPCWSTR pwszMachine,
IN OUT LPWSTR *ppwcArguments,
IN DWORD dwCurrentIndex,
IN DWORD dwArgCount,
IN DWORD dwFlags,
IN LPCVOID pvData,
OUT BOOL *pbDone
)
/*++
Routine Description:
Arguments:
ppwcArguments - Argument array
dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
Return Value:
NO_ERROR
--*/
{
DWORD dwErr, dwTotal;
TAG_TYPE pttTags[] = {{TOKEN_NAME,FALSE,FALSE}};
WCHAR rgwcIfName[MAX_INTERFACE_NAME_LEN + 1];
DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
DWORD dwBlkSize, dwCount, dwIfType, i, dwNumParsed;
PBYTE pib, pibNew = NULL;
PMPR_INTERFACE_0 pmi0;
DWORD dwNumRows = 0;
// Do generic processing
dwErr = PreHandleCommand( ppwcArguments,
dwCurrentIndex,
dwArgCount,
pttTags,
sizeof(pttTags)/sizeof(TAG_TYPE),
0,
1,
rgdwTagType );
if (dwErr)
{
return dwErr;
}
// If interface specified, show boundaries for specified interface only.
if (dwArgCount > dwCurrentIndex) {
GetInterfaceName( ppwcArguments[dwCurrentIndex],
rgwcIfName,
sizeof(rgwcIfName),
&dwNumParsed );
dwErr = ShowBoundaryInfoForInterface( 0, rgwcIfName, &dwNumRows );
if (!dwNumRows)
{
DisplayMessage( g_hModule, MSG_IP_NO_ENTRIES );
}
return dwErr;
}
// No Interface specified. Enumerate interfaces and show
// boundaries for each interface.
//
// No interface name specified. List all interfaces under IP
//
dwErr = IpmontrInterfaceEnum((PBYTE *) &pmi0, &dwCount, &dwTotal);
if (dwErr isnot NO_ERROR)
{
DisplayError(g_hModule, dwErr);
return dwErr;
}
for ( i = 0; i < dwCount && dwErr is NO_ERROR; i++)
{
dwErr = ShowBoundaryInfoForInterface( 0,
pmi0[i].wszInterfaceName,
&dwNumRows );
if (dwErr is ERROR_NO_SUCH_INTERFACE)
{
dwErr = NO_ERROR;
}
}
if (!dwNumRows)
{
DisplayMessage( g_hModule, MSG_IP_NO_ENTRIES );
}
return dwErr;
}
//----------------------------------------------------------------------------
// PrintScope
//
//
//----------------------------------------------------------------------------
static VOID
PrintScope(
PMIB_OPAQUE_INFO prpcInfo,
PDWORD pdwLastAddr,
PDWORD pdwLastMask
)
{
TCHAR ptszAddr[ ADDR_LENGTH + 1 ],
ptszMask[ ADDR_LENGTH + 1 ],
ptszBuffer[ MAX_SCOPE_NAME_LEN + 40 ];
PMIB_IPMCAST_SCOPE pmims;
//
// get scope
//
pmims = (PMIB_IPMCAST_SCOPE) prpcInfo->rgbyData;
*pdwLastAddr = pmims-> dwGroupAddress;
MakeUnicodeIpAddr(ptszAddr,
inet_ntoa(*((struct in_addr *)(&pmims-> dwGroupAddress))));
*pdwLastMask = pmims-> dwGroupMask;
MakeUnicodeIpAddr(ptszMask,
inet_ntoa(*((struct in_addr *)(&pmims-> dwGroupMask))));
_stprintf(ptszBuffer, _T("%-15.15s %-15.15s %s"),
ptszAddr,
ptszMask,
pmims-> snNameBuffer
);
DisplayMessage( g_hModule,
MSG_MIB_SCOPE_INFO,
ptszBuffer
);
return;
}
//----------------------------------------------------------------------------
// PrintBoundary
//
//
//----------------------------------------------------------------------------
static VOID
PrintBoundary(
MIB_SERVER_HANDLE hMibServer,
PMIB_OPAQUE_INFO prpcInfo,
PDWORD pdwLastIfIndex,
PDWORD pdwLastAddr,
PDWORD pdwLastMask
)
{
WCHAR wszBuffer[MAX_INTERFACE_NAME_LEN+1];
TCHAR ptszAddr[ ADDR_LENGTH + 1 ],
ptszMask[ ADDR_LENGTH + 1 ];
PMIB_IPMCAST_BOUNDARY pmims;
//
// get boundary
//
pmims = (PMIB_IPMCAST_BOUNDARY) prpcInfo->rgbyData;
*pdwLastIfIndex = pmims-> dwIfIndex;
*pdwLastAddr = pmims-> dwGroupAddress;
MakeUnicodeIpAddr(ptszAddr,
inet_ntoa(*((struct in_addr *)(&pmims-> dwGroupAddress))));
*pdwLastMask = pmims-> dwGroupMask;
MakeUnicodeIpAddr(ptszMask,
inet_ntoa(*((struct in_addr *)(&pmims-> dwGroupMask))));
IpmontrGetFriendlyNameFromIfIndex( hMibServer,
pmims->dwIfIndex,
wszBuffer,
sizeof(wszBuffer) );
DisplayMessageToConsole( g_hModule, g_hConsole,
MSG_MIB_BOUNDARY_INFO,
ptszAddr,
ptszMask,
wszBuffer
);
return;
}
#if 0
//----------------------------------------------------------------------------
// GetPrintScopeInfo
//
//----------------------------------------------------------------------------
DWORD
GetPrintScopeInfo(
MIB_SERVER_HANDLE hMIBServer
)
{
DWORD dwErr, dwOutEntrySize = 0, dwQuerySize,
dwLastAddr = 0,
dwLastMask = 0, i;
PMIB_OPAQUE_INFO pRpcInfo = NULL;
PMIB_IPMCAST_SCOPE pmims = NULL;
PMIB_OPAQUE_QUERY pQuery;
do
{
//
// allocate and setup query structure
//
dwQuerySize = sizeof( MIB_OPAQUE_QUERY ) + sizeof(DWORD);
pQuery = (PMIB_OPAQUE_QUERY) HeapAlloc(
GetProcessHeap(), 0, dwQuerySize
);
if ( pQuery == NULL )
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
DisplayMessage( g_hModule, ERROR_CONFIG, dwErr );
break;
}
pQuery->dwVarId = MCAST_SCOPE;
for( i = 0; i < 2; i++ )
{
pQuery->rgdwVarIndex[i] = 0;
}
//
// get first scope
//
dwErr = MibGetFirst(
PID_IP,
IPRTRMGR_PID,
(PVOID) pQuery,
dwQuerySize,
(PVOID *) &pRpcInfo,
&dwOutEntrySize
);
if ( dwErr != NO_ERROR )
{
DisplayError( g_hModule, dwErr );
break;
}
//
// if no scopes are present print a message to tell the user
//
pmims = (PMIB_IPMCAST_SCOPE)( pRpcInfo->rgbyData );
#if 0
if ( pTable->dwNumEntries is 0 )
{
//
// no scopes present.
//
DisplayMessage( g_hModule, MSG_MIB_NO_SCOPES );
break;
}
#endif
//
// print the scope
//
DisplayMessage( g_hModule, MSG_MIB_SCOPE_HDR );
PrintScope( pRpcInfo, &dwLastAddr, &dwLastMask );
MprAdminMIBBufferFree( pRpcInfo );
pRpcInfo = NULL;
dwOutEntrySize = 0;
//
// while there are more scopes
// get next scope
// print it.
//
pQuery->rgdwVarIndex[ 0 ] = dwLastAddr;
pQuery->rgdwVarIndex[ 1 ] = dwLastMask;
while ( ( dwErr = MibGetNext(
PID_IP, IPRTRMGR_PID, (PVOID) pQuery,
dwQuerySize, (PVOID *) &pRpcInfo, &dwOutEntrySize
) ) == NO_ERROR )
{
//
// if no scopes are present quit
//
pmims = (PMIB_IPMCAST_SCOPE)( pRpcInfo->rgbyData );
#if 0
pTable = (PMIB_IPMCAST_SCOPE)( pRpcInfo->rgbyData );
if ( pTable->dwNumEntries is 0 )
{
break;
}
#endif
//
// print the scope
//
PrintScope( pRpcInfo, &dwLastAddr, &dwLastMask );
MprAdminMIBBufferFree( pRpcInfo );
pRpcInfo = NULL;
dwOutEntrySize = 0;
//
// set up the next query
//
pQuery->rgdwVarIndex[ 0 ] = dwLastAddr;
pQuery->rgdwVarIndex[ 1 ] = dwLastMask;
}
if ( dwErr != NO_ERROR )
{
DisplayMessage( g_hModule, ERROR_ADMIN, dwErr );
}
} while ( FALSE );
return dwErr;
}
#endif
//----------------------------------------------------------------------------
// GetPrintBoundaryInfo
//
//----------------------------------------------------------------------------
DWORD
GetPrintBoundaryInfo(
MIB_SERVER_HANDLE hMIBServer
)
{
DWORD dwErr, dwOutEntrySize = 0, dwQuerySize,
dwLastIfIndex = 0, dwLastAddr = 0,
dwLastMask = 0, i;
PMIB_OPAQUE_INFO pRpcInfo = NULL;
PMIB_IPMCAST_BOUNDARY pmims = NULL;
PMIB_OPAQUE_QUERY pQuery;
do
{
//
// allocate and setup query structure
//
dwQuerySize = sizeof( MIB_OPAQUE_QUERY ) + 2 * sizeof(DWORD);
pQuery = (PMIB_OPAQUE_QUERY) HeapAlloc(
GetProcessHeap(), 0, dwQuerySize
);
if ( pQuery == NULL )
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
DisplayMessage( g_hModule, ERROR_CONFIG, dwErr );
break;
}
pQuery->dwVarId = MCAST_BOUNDARY;
for( i = 0; i < 2; i++ )
{
pQuery->rgdwVarIndex[i] = 0;
}
//
// get first boundary
//
dwErr = MibGetFirst(
PID_IP,
IPRTRMGR_PID,
(PVOID) pQuery,
dwQuerySize,
(PVOID *) &pRpcInfo,
&dwOutEntrySize
);
if ( dwErr != NO_ERROR )
{
DisplayError( g_hModule, dwErr );
break;
}
//
// if no boundaries are present print a message to tell the user
//
pmims = (PMIB_IPMCAST_BOUNDARY)( pRpcInfo->rgbyData );
#if 0
if ( pTable->dwNumEntries is 0 )
{
//
// no boundaries present.
//
DisplayMessage( g_hModule, MSG_MIB_NO_BOUNDARIES );
break;
}
#endif
//
// print the boundary
//
DisplayMessageToConsole( g_hModule, g_hConsole, MSG_MIB_BOUNDARY_HDR );
PrintBoundary( hMIBServer,
pRpcInfo, &dwLastIfIndex, &dwLastAddr, &dwLastMask );
MprAdminMIBBufferFree( pRpcInfo );
pRpcInfo = NULL;
dwOutEntrySize = 0;
//
// while there are more boundaries
// get next boundary
// print it.
//
pQuery->rgdwVarIndex[ 0 ] = dwLastIfIndex;
pQuery->rgdwVarIndex[ 1 ] = dwLastAddr;
pQuery->rgdwVarIndex[ 2 ] = dwLastMask;
while ( ( dwErr = MibGetNext(
PID_IP, IPRTRMGR_PID, (PVOID) pQuery,
dwQuerySize, (PVOID *) &pRpcInfo, &dwOutEntrySize
) ) == NO_ERROR )
{
//
// if no boundaries are present quit
//
pmims = (PMIB_IPMCAST_BOUNDARY)( pRpcInfo->rgbyData );
#if 0
pTable = (PMIB_IPMCAST_BOUNDARY)( pRpcInfo->rgbyData );
if ( pTable->dwNumEntries is 0 )
{
break;
}
#endif
//
// print the boundary
//
PrintBoundary(
hMIBServer,
pRpcInfo, &dwLastIfIndex, &dwLastAddr, &dwLastMask
);
MprAdminMIBBufferFree( pRpcInfo );
pRpcInfo = NULL;
dwOutEntrySize = 0;
//
// set up the next query
//
pQuery->rgdwVarIndex[ 0 ] = dwLastIfIndex;
pQuery->rgdwVarIndex[ 1 ] = dwLastAddr;
pQuery->rgdwVarIndex[ 2 ] = dwLastMask;
}
if ( dwErr != NO_ERROR )
{
DisplayMessage( g_hModule, ERROR_ADMIN, dwErr );
}
} while ( FALSE );
return dwErr;
}