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;
|
||
}
|