901 lines
30 KiB
C
901 lines
30 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1999, Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
net\routing\netsh\ip\protocols\msdpopt.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
MSDP command options implementation.
|
|||
|
This module contains handlers for the configuration commands
|
|||
|
supported by the MSDP Protocol.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Dave Thaler (dthaler) 21-May-1999
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "precomp.h"
|
|||
|
#pragma hdrstop
|
|||
|
#include <ipcmp.h>
|
|||
|
|
|||
|
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
|
|||
|
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
|
|||
|
|
|||
|
//
|
|||
|
// Forward declarations
|
|||
|
//
|
|||
|
|
|||
|
ULONG
|
|||
|
QueryTagArray(
|
|||
|
IN PTCHAR ppwszArgumentArray[],
|
|||
|
IN ULONG ululArgumentCount,
|
|||
|
IN TAG_TYPE pttTagTypeArray[],
|
|||
|
IN ULONG ulTagTypeCount,
|
|||
|
OUT PULONG* ppulTagArray
|
|||
|
);
|
|||
|
|
|||
|
ULONG
|
|||
|
ValidateTagTypeArray(
|
|||
|
IN TAG_TYPE pttTagTypeArray[],
|
|||
|
IN ULONG ulTagTypeCount
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
HandleMsdpAddPeer(
|
|||
|
PWCHAR pwszMachineName,
|
|||
|
PTCHAR* ArgumentArray,
|
|||
|
DWORD ulArgumentIndex,
|
|||
|
DWORD ulArgumentCount,
|
|||
|
DWORD dwFlags,
|
|||
|
PVOID pvData,
|
|||
|
BOOL* CommandDone
|
|||
|
)
|
|||
|
{
|
|||
|
ULONG ulArgumentsLeft;
|
|||
|
ULONG BitVector;
|
|||
|
DWORD dwErr;
|
|||
|
ULONG ulErrorIndex = 0;
|
|||
|
ULONG i;
|
|||
|
PULONG pulTagArray;
|
|||
|
ULONG InfoSize;
|
|||
|
DWORD dwBufferSize = MAX_INTERFACE_NAME_LEN + 1;
|
|||
|
WCHAR wszInterfaceName[MAX_INTERFACE_NAME_LEN + 1];
|
|||
|
TAG_TYPE TagTypeArray[] = { { TOKEN_OPT_NAME, NS_REQ_PRESENT, FALSE },
|
|||
|
{ TOKEN_OPT_REMADDR, NS_REQ_PRESENT, FALSE },
|
|||
|
{ TOKEN_OPT_LOCALADDR, NS_REQ_PRESENT, FALSE },
|
|||
|
{ TOKEN_OPT_KEEPALIVE, NS_REQ_ZERO, FALSE },
|
|||
|
{ TOKEN_OPT_CONNECTRETRY, NS_REQ_ZERO, FALSE },
|
|||
|
{ TOKEN_OPT_CACHING, NS_REQ_ZERO, FALSE },
|
|||
|
{ TOKEN_OPT_DEFAULTPEER, NS_REQ_ZERO, FALSE },
|
|||
|
{ TOKEN_OPT_ENCAPSMETHOD, NS_REQ_ZERO, FALSE },
|
|||
|
};
|
|||
|
PMSDP_IPV4_PEER_CONFIG pPeer = NULL;
|
|||
|
|
|||
|
VERIFY_INSTALLED(MS_IP_MSDP, L"MSDP");
|
|||
|
|
|||
|
if (ulArgumentIndex >= ulArgumentCount) {
|
|||
|
return ERROR_SHOW_USAGE;
|
|||
|
}
|
|||
|
ulArgumentsLeft = ulArgumentCount - ulArgumentIndex;
|
|||
|
|
|||
|
//
|
|||
|
// We convert the optional tags into an array of 'TagTypeArray' indices
|
|||
|
// which guide is in our scanning of the argument list.
|
|||
|
// Since the tags are optional, this process may result in no tags at all,
|
|||
|
// in which case we assume that arguments are specified in exactly the order
|
|||
|
// given in 'TagTypeArray' above.
|
|||
|
//
|
|||
|
|
|||
|
dwErr = QueryTagArray( &ArgumentArray[ulArgumentIndex],
|
|||
|
ulArgumentsLeft,
|
|||
|
TagTypeArray,
|
|||
|
NUM_TAGS_IN_TABLE(TagTypeArray),
|
|||
|
&pulTagArray );
|
|||
|
if (dwErr) { return dwErr; }
|
|||
|
|
|||
|
BitVector = 0;
|
|||
|
|
|||
|
do {
|
|||
|
dwErr = MakeMsdpIPv4PeerConfig(&pPeer);
|
|||
|
if (dwErr isnot NO_ERROR)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// We now scan the argument list, converting the arguments
|
|||
|
// into information in our 'VrouterGiven' structure.
|
|||
|
//
|
|||
|
|
|||
|
for (i = 0; i < ulArgumentsLeft; i++) {
|
|||
|
switch(pulTagArray ? pulTagArray[i] : i) {
|
|||
|
case 0: { // name
|
|||
|
wcscpy(wszInterfaceName, ArgumentArray[i+ulArgumentIndex]);
|
|||
|
break;
|
|||
|
}
|
|||
|
case 1: { // remaddr
|
|||
|
pPeer->ipRemoteAddress = GetIpAddress(
|
|||
|
ArgumentArray[i + ulArgumentIndex]);
|
|||
|
break;
|
|||
|
}
|
|||
|
case 2: { // localaddr
|
|||
|
pPeer->ipLocalAddress = GetIpAddress(
|
|||
|
ArgumentArray[i + ulArgumentIndex]);
|
|||
|
break;
|
|||
|
}
|
|||
|
case 3: { // keepalive
|
|||
|
if (!MatchToken(ArgumentArray[i+ulArgumentIndex],
|
|||
|
TOKEN_OPT_VALUE_DEFAULT))
|
|||
|
{
|
|||
|
pPeer->ulKeepAlive = _tcstoul(
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
NULL, 10);
|
|||
|
pPeer->dwConfigFlags |= MSDP_PEER_CONFIG_KEEPALIVE;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
case 4: { // connectretry
|
|||
|
if (!MatchToken(ArgumentArray[i+ulArgumentIndex],
|
|||
|
TOKEN_OPT_VALUE_DEFAULT))
|
|||
|
{
|
|||
|
pPeer->ulConnectRetry = _tcstoul(
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
NULL, 10);
|
|||
|
pPeer->dwConfigFlags |= MSDP_PEER_CONFIG_CONNECTRETRY;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
case 5: { // caching
|
|||
|
DWORD dwValue;
|
|||
|
TOKEN_VALUE TokenArray[] = {
|
|||
|
{ TOKEN_OPT_VALUE_NO, FALSE },
|
|||
|
{ TOKEN_OPT_VALUE_YES, TRUE }
|
|||
|
};
|
|||
|
pPeer->dwConfigFlags &= ~MSDP_PEER_CONFIG_CACHING;
|
|||
|
dwErr = MatchEnumTag( g_hModule,
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
NUM_TOKENS_IN_TABLE(TokenArray),
|
|||
|
TokenArray,
|
|||
|
&dwValue );
|
|||
|
if (dwErr isnot NO_ERROR)
|
|||
|
{
|
|||
|
dwErr = ERROR_INVALID_PARAMETER;
|
|||
|
break;
|
|||
|
}
|
|||
|
if (dwValue is TRUE)
|
|||
|
{
|
|||
|
pPeer->dwConfigFlags |= MSDP_PEER_CONFIG_CACHING;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
case 6: { // defaultpeer
|
|||
|
DWORD dwValue;
|
|||
|
TOKEN_VALUE TokenArray[] = {
|
|||
|
{ TOKEN_OPT_VALUE_NO, FALSE },
|
|||
|
{ TOKEN_OPT_VALUE_YES, TRUE }
|
|||
|
};
|
|||
|
pPeer->dwConfigFlags &= ~MSDP_PEER_CONFIG_DEFAULTPEER;
|
|||
|
dwErr = MatchEnumTag( g_hModule,
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
NUM_TOKENS_IN_TABLE(TokenArray),
|
|||
|
TokenArray,
|
|||
|
&dwValue );
|
|||
|
if (dwErr isnot NO_ERROR)
|
|||
|
{
|
|||
|
dwErr = ERROR_INVALID_PARAMETER;
|
|||
|
break;
|
|||
|
}
|
|||
|
if (dwValue is TRUE)
|
|||
|
{
|
|||
|
pPeer->dwConfigFlags |= MSDP_PEER_CONFIG_DEFAULTPEER;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
case 7: { // encapsulation
|
|||
|
DWORD dwValue;
|
|||
|
dwErr = MatchEnumTag( g_hModule,
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
MSDP_ENCAPS_SIZE,
|
|||
|
(PTOKEN_VALUE)MsdpEncapsTokenArray,
|
|||
|
&dwValue );
|
|||
|
if (dwErr isnot NO_ERROR)
|
|||
|
{
|
|||
|
dwErr = ERROR_INVALID_PARAMETER;
|
|||
|
break;
|
|||
|
}
|
|||
|
pPeer->dwEncapsMethod = dwValue;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (dwErr isnot NO_ERROR)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
// higher IP is passive. Setting this bit has no effect
|
|||
|
// except on the "show peer" report when the router isn't running.
|
|||
|
if (ntohl(pPeer->ipLocalAddress) > ntohl(pPeer->ipRemoteAddress))
|
|||
|
{
|
|||
|
pPeer->dwConfigFlags |= MSDP_PEER_CONFIG_PASSIVE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Update the configuration with the new settings.
|
|||
|
// Note that the update routine may perform additional validation
|
|||
|
// in the process of reconciling the new settings
|
|||
|
// with any existing settings.
|
|||
|
//
|
|||
|
dwErr = MsdpAddIPv4PeerInterface(pwszMachineName,
|
|||
|
wszInterfaceName, pPeer );
|
|||
|
} while (FALSE);
|
|||
|
|
|||
|
if (pPeer)
|
|||
|
{
|
|||
|
FREE(pPeer);
|
|||
|
}
|
|||
|
|
|||
|
if (pulTagArray)
|
|||
|
{
|
|||
|
FREE(pulTagArray);
|
|||
|
}
|
|||
|
if (dwErr is NO_ERROR)
|
|||
|
{
|
|||
|
dwErr = ERROR_OKAY;
|
|||
|
}
|
|||
|
|
|||
|
return dwErr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
HandleMsdpDeletePeer(
|
|||
|
PWCHAR pwszMachineName,
|
|||
|
PTCHAR* ArgumentArray,
|
|||
|
DWORD ulArgumentIndex,
|
|||
|
DWORD ulArgumentCount,
|
|||
|
DWORD dwFlags,
|
|||
|
PVOID pvData,
|
|||
|
BOOL* CommandDone
|
|||
|
)
|
|||
|
{
|
|||
|
ULONG ulArgumentsLeft;
|
|||
|
ULONG BitVector;
|
|||
|
DWORD dwErr;
|
|||
|
ULONG ulErrorIndex = 0;
|
|||
|
ULONG i;
|
|||
|
PULONG pulTagArray;
|
|||
|
ULONG InfoSize;
|
|||
|
WCHAR wszInterfaceName[MAX_INTERFACE_NAME_LEN + 1];
|
|||
|
DWORD dwBufferSize = sizeof(wszInterfaceName);
|
|||
|
|
|||
|
TAG_TYPE TagTypeArray[] = { { TOKEN_OPT_NAME, NS_REQ_PRESENT, FALSE }
|
|||
|
};
|
|||
|
|
|||
|
VERIFY_INSTALLED(MS_IP_MSDP, L"MSDP");
|
|||
|
|
|||
|
if (ulArgumentIndex >= ulArgumentCount) {
|
|||
|
return ERROR_SHOW_USAGE;
|
|||
|
}
|
|||
|
ulArgumentsLeft = ulArgumentCount - ulArgumentIndex;
|
|||
|
|
|||
|
//
|
|||
|
// We convert the optional tags into an array of 'TagTypeArray' indices
|
|||
|
// which guide is in our scanning of the argument list.
|
|||
|
// Since the tags are optional, this process may result in no tags at all,
|
|||
|
// in which case we assume that arguments are specified in exactly the order
|
|||
|
// given in 'TagTypeArray' above.
|
|||
|
//
|
|||
|
|
|||
|
dwErr = QueryTagArray( &ArgumentArray[ulArgumentIndex],
|
|||
|
ulArgumentsLeft,
|
|||
|
TagTypeArray,
|
|||
|
NUM_TAGS_IN_TABLE(TagTypeArray),
|
|||
|
&pulTagArray );
|
|||
|
if (dwErr) { return dwErr; }
|
|||
|
|
|||
|
BitVector = 0;
|
|||
|
|
|||
|
for (i = 0; i < ulArgumentsLeft; i++) {
|
|||
|
switch(pulTagArray ? pulTagArray[i] : i) {
|
|||
|
case 0: { // name
|
|||
|
IpmontrGetIfNameFromFriendlyName(
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
wszInterfaceName,
|
|||
|
&dwBufferSize);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
dwErr = IpmontrDeleteInterface( pwszMachineName, wszInterfaceName );
|
|||
|
if (dwErr is NO_ERROR)
|
|||
|
{
|
|||
|
dwErr = ERROR_OKAY;
|
|||
|
}
|
|||
|
|
|||
|
return dwErr;
|
|||
|
}
|
|||
|
|
|||
|
DWORD
|
|||
|
HandleMsdpInstall(
|
|||
|
PWCHAR pwszMachineName,
|
|||
|
PTCHAR* ArgumentArray,
|
|||
|
DWORD ulArgumentIndex,
|
|||
|
DWORD ulArgumentCount,
|
|||
|
DWORD dwFlags,
|
|||
|
PVOID pvData,
|
|||
|
BOOL* CommandDone
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwErr = ERROR_OKAY;
|
|||
|
PUCHAR pGlobalInfo;
|
|||
|
ULONG ulLength;
|
|||
|
|
|||
|
if (ulArgumentIndex != ulArgumentCount) {
|
|||
|
return ERROR_SHOW_USAGE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// To install MSDP, we construct the default configuration
|
|||
|
// and add it to the global configuration for the router.
|
|||
|
//
|
|||
|
dwErr = MakeMsdpGlobalConfig(&pGlobalInfo, &ulLength);
|
|||
|
if (dwErr isnot NO_ERROR) {
|
|||
|
DisplayError(g_hModule, dwErr);
|
|||
|
} else {
|
|||
|
dwErr = IpmontrSetInfoBlockInGlobalInfo( MS_IP_MSDP,
|
|||
|
pGlobalInfo,
|
|||
|
ulLength,
|
|||
|
1 );
|
|||
|
FREE(pGlobalInfo);
|
|||
|
if (dwErr is NO_ERROR) {
|
|||
|
dwErr = ERROR_OKAY;
|
|||
|
} else {
|
|||
|
DisplayError(g_hModule, dwErr);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return dwErr;
|
|||
|
}
|
|||
|
|
|||
|
DWORD
|
|||
|
HandleMsdpSetGlobal(
|
|||
|
PWCHAR pwszMachineName,
|
|||
|
PTCHAR* ArgumentArray,
|
|||
|
ULONG ulArgumentIndex,
|
|||
|
ULONG ulArgumentCount,
|
|||
|
DWORD dwFlags,
|
|||
|
PVOID pvData,
|
|||
|
BOOL* CommandDone
|
|||
|
)
|
|||
|
{
|
|||
|
ULONG ulArgumentsLeft;
|
|||
|
DWORD dwErr;
|
|||
|
PULONG pulTagArray = NULL;
|
|||
|
DWORD dwLoggingLevel, dwAcceptAll;
|
|||
|
ULONG i, ulTemp;
|
|||
|
ULONG ulErrorIndex;
|
|||
|
PMSDP_GLOBAL_CONFIG pGlobalInfo = NULL;
|
|||
|
|
|||
|
TAG_TYPE TagTypeArray[] = { { TOKEN_OPT_LOGGINGLEVEL, FALSE, FALSE },
|
|||
|
{ TOKEN_OPT_KEEPALIVE, FALSE, FALSE },
|
|||
|
{ TOKEN_OPT_SAHOLDDOWN, FALSE, FALSE },
|
|||
|
{ TOKEN_OPT_CONNECTRETRY, FALSE, FALSE },
|
|||
|
{ TOKEN_OPT_ACCEPTALL, FALSE, FALSE },
|
|||
|
{ TOKEN_OPT_CACHELIFETIME,FALSE, FALSE },
|
|||
|
};
|
|||
|
|
|||
|
VERIFY_INSTALLED(MS_IP_MSDP, L"MSDP");
|
|||
|
|
|||
|
if (ulArgumentIndex >= ulArgumentCount) {
|
|||
|
return ERROR_SHOW_USAGE;
|
|||
|
}
|
|||
|
|
|||
|
ulArgumentsLeft = ulArgumentCount - ulArgumentIndex;
|
|||
|
|
|||
|
//
|
|||
|
// We convert the optional tags into an array of 'TagTypeArray' indices
|
|||
|
// which guide us in our scanning of the argument list.
|
|||
|
// Since the tags are optional, this process may result in no tags at all,
|
|||
|
// in which case we assume that arguments are specified in exactly the order
|
|||
|
// given in 'TagTypeArray' above.
|
|||
|
//
|
|||
|
|
|||
|
dwErr = QueryTagArray( &ArgumentArray[ulArgumentIndex],
|
|||
|
ulArgumentsLeft,
|
|||
|
TagTypeArray,
|
|||
|
NUM_TAGS_IN_TABLE(TagTypeArray),
|
|||
|
&pulTagArray );
|
|||
|
if (dwErr) { return dwErr; }
|
|||
|
|
|||
|
do {
|
|||
|
dwErr = GetMsdpGlobalConfig( &pGlobalInfo );
|
|||
|
if (dwErr isnot NO_ERROR)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
for (i = 0; i < ulArgumentsLeft; i++) {
|
|||
|
switch(pulTagArray ? pulTagArray[i] : i) {
|
|||
|
case 0: { // loglevel
|
|||
|
TOKEN_VALUE TokenArray[] = {
|
|||
|
{ TOKEN_OPT_VALUE_NONE, MSDP_LOGGING_NONE },
|
|||
|
{ TOKEN_OPT_VALUE_ERROR, MSDP_LOGGING_ERROR },
|
|||
|
{ TOKEN_OPT_VALUE_WARN, MSDP_LOGGING_WARN },
|
|||
|
{ TOKEN_OPT_VALUE_INFO, MSDP_LOGGING_INFO }
|
|||
|
};
|
|||
|
dwErr = MatchEnumTag( g_hModule,
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
NUM_TOKENS_IN_TABLE(TokenArray),
|
|||
|
TokenArray,
|
|||
|
&pGlobalInfo->dwLoggingLevel );
|
|||
|
if (dwErr) {
|
|||
|
dwErr = ERROR_INVALID_PARAMETER;
|
|||
|
ulErrorIndex = i;
|
|||
|
i = ulArgumentsLeft;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
TagTypeArray[pulTagArray ? pulTagArray[i] : i].bPresent = TRUE;
|
|||
|
break;
|
|||
|
}
|
|||
|
case 1: { // keepalive
|
|||
|
pGlobalInfo->ulDefKeepAlive = _tcstoul(
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
NULL, 10);
|
|||
|
break;
|
|||
|
}
|
|||
|
case 2: { // SA holddown
|
|||
|
pGlobalInfo->ulSAHolddown = _tcstoul(
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
NULL, 10);
|
|||
|
break;
|
|||
|
}
|
|||
|
case 3: { // connectretry
|
|||
|
pGlobalInfo->ulDefConnectRetry = _tcstoul(
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
NULL, 10);
|
|||
|
break;
|
|||
|
}
|
|||
|
case 4: { // acceptall
|
|||
|
TOKEN_VALUE TokenArray[] = {
|
|||
|
{ TOKEN_OPT_VALUE_DISABLE, FALSE },
|
|||
|
{ TOKEN_OPT_VALUE_ENABLE, TRUE }
|
|||
|
};
|
|||
|
pGlobalInfo->dwFlags &= ~MSDP_GLOBAL_FLAG_ACCEPT_ALL;
|
|||
|
dwErr = MatchEnumTag( g_hModule,
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
NUM_TOKENS_IN_TABLE(TokenArray),
|
|||
|
TokenArray,
|
|||
|
&dwAcceptAll );
|
|||
|
if (dwErr isnot NO_ERROR)
|
|||
|
{
|
|||
|
dwErr = ERROR_INVALID_PARAMETER;
|
|||
|
break;
|
|||
|
}
|
|||
|
if (dwAcceptAll is TRUE)
|
|||
|
{
|
|||
|
pGlobalInfo->dwFlags |= MSDP_GLOBAL_FLAG_ACCEPT_ALL;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
case 5: { // cachelifetime
|
|||
|
ulTemp = _tcstoul( ArgumentArray[i + ulArgumentIndex],
|
|||
|
NULL, 10);
|
|||
|
|
|||
|
if ((ulTemp>0) and (ulTemp<MSDP_MIN_CACHE_LIFETIME))
|
|||
|
{
|
|||
|
DisplayMessage(g_hModule, EMSG_BAD_OPTION_VALUE,
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
TOKEN_OPT_CACHELIFETIME);
|
|||
|
dwErr = ERROR_SUPPRESS_OUTPUT;
|
|||
|
break;
|
|||
|
}
|
|||
|
pGlobalInfo->ulCacheLifetime = ulTemp;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (dwErr isnot NO_ERROR)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
dwErr = SetMsdpGlobalConfig(pGlobalInfo);
|
|||
|
|
|||
|
} while (FALSE);
|
|||
|
|
|||
|
if (pulTagArray)
|
|||
|
{
|
|||
|
FREE(pulTagArray);
|
|||
|
}
|
|||
|
if (pGlobalInfo)
|
|||
|
{
|
|||
|
FREE(pGlobalInfo);
|
|||
|
}
|
|||
|
|
|||
|
if (dwErr is NO_ERROR)
|
|||
|
{
|
|||
|
dwErr = ERROR_OKAY;
|
|||
|
}
|
|||
|
return dwErr;
|
|||
|
}
|
|||
|
|
|||
|
DWORD
|
|||
|
HandleMsdpSetPeer(
|
|||
|
PWCHAR pwszMachineName,
|
|||
|
PTCHAR* ArgumentArray,
|
|||
|
DWORD ulArgumentIndex,
|
|||
|
DWORD ulArgumentCount,
|
|||
|
DWORD dwCmdFlags,
|
|||
|
PVOID pvData,
|
|||
|
BOOL* CommandDone
|
|||
|
)
|
|||
|
{
|
|||
|
IPV4_ADDRESS ipLocalAddress, ipRemoteAddress;
|
|||
|
ULONG ulKeepAlive=0, ulSAPeriod=0, ulConnectRetry=0;
|
|||
|
DWORD dwEncapsMethod=0;
|
|||
|
DWORD dwErr = NO_ERROR;
|
|||
|
DWORD dwFlags = 0, dwFlagsMask = 0;
|
|||
|
ULONG ulArgumentsLeft;
|
|||
|
ULONG i;
|
|||
|
PMSDP_IPV4_PEER_CONFIG pPeer = NULL;
|
|||
|
PULONG pulTagArray;
|
|||
|
WCHAR wszInterfaceName[MAX_INTERFACE_NAME_LEN + 1];
|
|||
|
DWORD dwBufferSize = sizeof(wszInterfaceName);
|
|||
|
TAG_TYPE TagTypeArray[] = { { TOKEN_OPT_NAME, NS_REQ_PRESENT, FALSE },
|
|||
|
{ TOKEN_OPT_REMADDR, NS_REQ_ZERO, FALSE },
|
|||
|
{ TOKEN_OPT_LOCALADDR, NS_REQ_ZERO, FALSE },
|
|||
|
{ TOKEN_OPT_KEEPALIVE, NS_REQ_ZERO, FALSE },
|
|||
|
{ TOKEN_OPT_CONNECTRETRY, NS_REQ_ZERO, FALSE },
|
|||
|
{ TOKEN_OPT_CACHING, NS_REQ_ZERO, FALSE },
|
|||
|
{ TOKEN_OPT_DEFAULTPEER, NS_REQ_ZERO, FALSE },
|
|||
|
{ TOKEN_OPT_ENCAPSMETHOD, NS_REQ_ZERO, FALSE },
|
|||
|
};
|
|||
|
|
|||
|
VERIFY_INSTALLED(MS_IP_MSDP, L"MSDP");
|
|||
|
|
|||
|
if (ulArgumentIndex >= ulArgumentCount) {
|
|||
|
return ERROR_SHOW_USAGE;
|
|||
|
}
|
|||
|
ulArgumentsLeft = ulArgumentCount - ulArgumentIndex;
|
|||
|
|
|||
|
//
|
|||
|
// We convert the optional tags into an array of 'TagTypeArray' indices
|
|||
|
// which guide is in our scanning of the argument list.
|
|||
|
// Since the tags are optional, this process may result in no tags at all,
|
|||
|
// in which case we assume that arguments are specified in exactly the order
|
|||
|
// given in 'TagTypeArray' above.
|
|||
|
//
|
|||
|
|
|||
|
dwErr = QueryTagArray( &ArgumentArray[ulArgumentIndex],
|
|||
|
ulArgumentsLeft,
|
|||
|
TagTypeArray,
|
|||
|
NUM_TAGS_IN_TABLE(TagTypeArray),
|
|||
|
&pulTagArray );
|
|||
|
if (dwErr) { return dwErr; }
|
|||
|
|
|||
|
do {
|
|||
|
for (i = 0; i < ulArgumentsLeft; i++) {
|
|||
|
switch(pulTagArray ? pulTagArray[i] : i) {
|
|||
|
case 0: { // name
|
|||
|
IpmontrGetIfNameFromFriendlyName(
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
wszInterfaceName,
|
|||
|
&dwBufferSize);
|
|||
|
break;
|
|||
|
}
|
|||
|
case 1: { // remaddr
|
|||
|
ipRemoteAddress = GetIpAddress(
|
|||
|
ArgumentArray[i + ulArgumentIndex]);
|
|||
|
break;
|
|||
|
}
|
|||
|
case 2: { // localaddr
|
|||
|
ipLocalAddress = GetIpAddress(
|
|||
|
ArgumentArray[i + ulArgumentIndex]);
|
|||
|
break;
|
|||
|
}
|
|||
|
case 3: { // keepalive
|
|||
|
dwFlagsMask |= MSDP_PEER_CONFIG_KEEPALIVE;
|
|||
|
if (!MatchToken(ArgumentArray[i+ulArgumentIndex],
|
|||
|
TOKEN_OPT_VALUE_DEFAULT))
|
|||
|
{
|
|||
|
ulKeepAlive = _tcstoul(
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
NULL, 10);
|
|||
|
dwFlags |= MSDP_PEER_CONFIG_KEEPALIVE;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
case 4: { // connectretry
|
|||
|
dwFlagsMask |= MSDP_PEER_CONFIG_CONNECTRETRY;
|
|||
|
if (!MatchToken(ArgumentArray[i+ulArgumentIndex],
|
|||
|
TOKEN_OPT_VALUE_DEFAULT))
|
|||
|
{
|
|||
|
ulConnectRetry = _tcstoul(
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
NULL, 10);
|
|||
|
dwFlags |= MSDP_PEER_CONFIG_CONNECTRETRY;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
case 5: { // caching
|
|||
|
DWORD dwValue;
|
|||
|
TOKEN_VALUE TokenArray[] = {
|
|||
|
{ TOKEN_OPT_VALUE_NO, FALSE },
|
|||
|
{ TOKEN_OPT_VALUE_YES, TRUE }
|
|||
|
};
|
|||
|
dwFlagsMask |= MSDP_PEER_CONFIG_CONNECTRETRY;
|
|||
|
dwErr = MatchEnumTag( g_hModule,
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
NUM_TOKENS_IN_TABLE(TokenArray),
|
|||
|
TokenArray,
|
|||
|
&dwValue );
|
|||
|
if (dwErr isnot NO_ERROR)
|
|||
|
{
|
|||
|
dwErr = ERROR_INVALID_PARAMETER;
|
|||
|
break;
|
|||
|
}
|
|||
|
if (dwValue is TRUE)
|
|||
|
{
|
|||
|
dwFlags |= MSDP_PEER_CONFIG_CACHING;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
case 6: { // defaultpeer
|
|||
|
DWORD dwValue;
|
|||
|
TOKEN_VALUE TokenArray[] = {
|
|||
|
{ TOKEN_OPT_VALUE_NO, FALSE },
|
|||
|
{ TOKEN_OPT_VALUE_YES, TRUE }
|
|||
|
};
|
|||
|
dwFlagsMask |= MSDP_PEER_CONFIG_DEFAULTPEER;
|
|||
|
dwErr = MatchEnumTag( g_hModule,
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
NUM_TOKENS_IN_TABLE(TokenArray),
|
|||
|
TokenArray,
|
|||
|
&dwValue );
|
|||
|
if (dwErr isnot NO_ERROR)
|
|||
|
{
|
|||
|
dwErr = ERROR_INVALID_PARAMETER;
|
|||
|
break;
|
|||
|
}
|
|||
|
if (dwValue is TRUE)
|
|||
|
{
|
|||
|
dwFlags |= MSDP_PEER_CONFIG_DEFAULTPEER;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
case 7: { // encapsulation
|
|||
|
DWORD dwValue;
|
|||
|
TOKEN_VALUE TokenArray[] = {
|
|||
|
{ TOKEN_OPT_VALUE_NONE, MSDP_ENCAPS_NONE },
|
|||
|
};
|
|||
|
dwErr = MatchEnumTag( g_hModule,
|
|||
|
ArgumentArray[i + ulArgumentIndex],
|
|||
|
NUM_TOKENS_IN_TABLE(TokenArray),
|
|||
|
TokenArray,
|
|||
|
&dwValue );
|
|||
|
if (dwErr isnot NO_ERROR)
|
|||
|
{
|
|||
|
dwErr = ERROR_INVALID_PARAMETER;
|
|||
|
break;
|
|||
|
}
|
|||
|
dwEncapsMethod = dwValue;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (dwErr isnot NO_ERROR)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
// Locate peer
|
|||
|
dwErr = GetMsdpInterfaceConfig(wszInterfaceName, &pPeer);
|
|||
|
if (dwErr isnot NO_ERROR)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
// Update fields
|
|||
|
if (TagTypeArray[1].bPresent)
|
|||
|
{
|
|||
|
pPeer->ipRemoteAddress = ipRemoteAddress;
|
|||
|
}
|
|||
|
if (TagTypeArray[2].bPresent)
|
|||
|
{
|
|||
|
pPeer->ipLocalAddress = ipLocalAddress;
|
|||
|
}
|
|||
|
if (TagTypeArray[3].bPresent)
|
|||
|
{
|
|||
|
pPeer->ulKeepAlive = ulKeepAlive;
|
|||
|
}
|
|||
|
if (TagTypeArray[4].bPresent)
|
|||
|
{
|
|||
|
pPeer->ulConnectRetry = ulConnectRetry;
|
|||
|
}
|
|||
|
if (TagTypeArray[5].bPresent)
|
|||
|
{
|
|||
|
pPeer->dwEncapsMethod = dwEncapsMethod;
|
|||
|
}
|
|||
|
pPeer->dwConfigFlags = (pPeer->dwConfigFlags & ~dwFlagsMask) | dwFlags;
|
|||
|
|
|||
|
// higher IP is passive. Setting bit has no effect except on
|
|||
|
// the "show peer" output when the router isn't running.
|
|||
|
if (ntohl(pPeer->ipLocalAddress) > ntohl(pPeer->ipRemoteAddress))
|
|||
|
{
|
|||
|
pPeer->dwConfigFlags |= MSDP_PEER_CONFIG_PASSIVE;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pPeer->dwConfigFlags &= ~MSDP_PEER_CONFIG_PASSIVE;
|
|||
|
}
|
|||
|
|
|||
|
// Update the configuration with the new settings.
|
|||
|
dwErr = SetMsdpInterfaceConfig(wszInterfaceName, pPeer);
|
|||
|
} while (FALSE);
|
|||
|
|
|||
|
if (pPeer)
|
|||
|
{
|
|||
|
FREE(pPeer);
|
|||
|
}
|
|||
|
|
|||
|
if (pulTagArray)
|
|||
|
{
|
|||
|
FREE(pulTagArray);
|
|||
|
}
|
|||
|
|
|||
|
if (dwErr is NO_ERROR)
|
|||
|
{
|
|||
|
dwErr = ERROR_OKAY;
|
|||
|
}
|
|||
|
|
|||
|
return dwErr;
|
|||
|
}
|
|||
|
|
|||
|
DWORD
|
|||
|
HandleMsdpShowGlobal(
|
|||
|
PWCHAR pwszMachineName,
|
|||
|
PTCHAR* ArgumentArray,
|
|||
|
DWORD ulArgumentIndex,
|
|||
|
DWORD ulArgumentCount,
|
|||
|
DWORD dwFlags,
|
|||
|
PVOID pvData,
|
|||
|
BOOL* CommandDone
|
|||
|
)
|
|||
|
{
|
|||
|
VERIFY_INSTALLED(MS_IP_MSDP, L"MSDP");
|
|||
|
|
|||
|
if (ulArgumentIndex != ulArgumentCount) {
|
|||
|
return ERROR_SHOW_USAGE;
|
|||
|
}
|
|||
|
|
|||
|
ShowMsdpGlobalInfo(FORMAT_VERBOSE);
|
|||
|
|
|||
|
return NO_ERROR;
|
|||
|
}
|
|||
|
|
|||
|
DWORD
|
|||
|
HandleMsdpShowPeer(
|
|||
|
PWCHAR pwszMachineName,
|
|||
|
PTCHAR* ArgumentArray,
|
|||
|
DWORD ulArgumentIndex,
|
|||
|
DWORD ulArgumentCount,
|
|||
|
DWORD dwFlags,
|
|||
|
PVOID pvData,
|
|||
|
BOOL* CommandDone
|
|||
|
)
|
|||
|
{
|
|||
|
ULONG ulArgumentsLeft;
|
|||
|
DWORD dwErr = NO_ERROR;
|
|||
|
PULONG pulTagArray = NULL;
|
|||
|
TAG_TYPE TagTypeArray[] = { { TOKEN_OPT_REMADDR, NS_REQ_ZERO, FALSE },
|
|||
|
{ TOKEN_OPT_NAME, NS_REQ_ZERO, FALSE },
|
|||
|
};
|
|||
|
|
|||
|
VERIFY_INSTALLED(MS_IP_MSDP, L"MSDP");
|
|||
|
|
|||
|
if (ulArgumentIndex is ulArgumentCount)
|
|||
|
{
|
|||
|
return ShowMsdpPeerInfo(FORMAT_TABLE, NULL, NULL);
|
|||
|
}
|
|||
|
|
|||
|
if (ulArgumentIndex > ulArgumentCount) {
|
|||
|
return ERROR_SHOW_USAGE;
|
|||
|
}
|
|||
|
ulArgumentsLeft = ulArgumentCount - ulArgumentIndex;
|
|||
|
|
|||
|
//
|
|||
|
// We convert the optional tags into an array of 'TagTypeArray' indices
|
|||
|
// which guide is in our scanning of the argument list.
|
|||
|
// Since the tags are optional, this process may result in no tags
|
|||
|
// at all, in which case we assume that arguments are specified in
|
|||
|
// exactly the order given in 'TagTypeArray' above.
|
|||
|
//
|
|||
|
|
|||
|
dwErr = QueryTagArray( &ArgumentArray[ulArgumentIndex],
|
|||
|
ulArgumentsLeft,
|
|||
|
TagTypeArray,
|
|||
|
NUM_TAGS_IN_TABLE(TagTypeArray),
|
|||
|
&pulTagArray );
|
|||
|
if (dwErr) { return dwErr; }
|
|||
|
|
|||
|
if (!pulTagArray) {
|
|||
|
dwErr = ShowMsdpPeerInfo(FORMAT_VERBOSE,NULL,NULL);
|
|||
|
} else if (pulTagArray[0] is 0) { // address
|
|||
|
dwErr = ShowMsdpPeerInfo(FORMAT_VERBOSE,
|
|||
|
ArgumentArray[ulArgumentIndex],
|
|||
|
NULL);
|
|||
|
} else if (pulTagArray[0] is 1) { // name
|
|||
|
dwErr = ShowMsdpPeerInfo(FORMAT_VERBOSE,
|
|||
|
NULL,
|
|||
|
ArgumentArray[ulArgumentIndex]);
|
|||
|
} else {
|
|||
|
dwErr = ERROR_SHOW_USAGE;
|
|||
|
}
|
|||
|
|
|||
|
if (pulTagArray) { FREE(pulTagArray); }
|
|||
|
return dwErr;
|
|||
|
}
|
|||
|
|
|||
|
DWORD
|
|||
|
HandleMsdpUninstall(
|
|||
|
PWCHAR pwszMachineName,
|
|||
|
PTCHAR* ArgumentArray,
|
|||
|
DWORD ulArgumentIndex,
|
|||
|
DWORD ulArgumentCount,
|
|||
|
DWORD dwFlags,
|
|||
|
PVOID pvData,
|
|||
|
BOOL* CommandDone
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD dwErr, dwTotal;
|
|||
|
ULONG ulNumInterfaces, i;
|
|||
|
PMPR_INTERFACE_0 pmi0 = NULL;
|
|||
|
|
|||
|
if (ulArgumentIndex isnot ulArgumentCount)
|
|||
|
{
|
|||
|
return ERROR_SHOW_USAGE;
|
|||
|
}
|
|||
|
|
|||
|
// First delete all peers. We need to do this ourselves since
|
|||
|
// IpmontrDeleteProtocol won't delete the peer interfaces.
|
|||
|
|
|||
|
dwErr = IpmontrInterfaceEnum((PBYTE *) &pmi0,
|
|||
|
&ulNumInterfaces,
|
|||
|
&dwTotal);
|
|||
|
if (dwErr isnot NO_ERROR)
|
|||
|
{
|
|||
|
return dwErr;
|
|||
|
}
|
|||
|
|
|||
|
for (i=0; i<ulNumInterfaces; i++)
|
|||
|
{
|
|||
|
dwErr = IpmontrDeleteInterface( pwszMachineName,
|
|||
|
pmi0[i].wszInterfaceName );
|
|||
|
}
|
|||
|
|
|||
|
if (pmi0)
|
|||
|
{
|
|||
|
FREE(pmi0);
|
|||
|
}
|
|||
|
|
|||
|
dwErr = IpmontrDeleteProtocol(MS_IP_MSDP);
|
|||
|
if (dwErr is NO_ERROR)
|
|||
|
{
|
|||
|
dwErr = ERROR_OKAY;
|
|||
|
}
|
|||
|
return dwErr;
|
|||
|
}
|