1071 lines
34 KiB
C
1071 lines
34 KiB
C
/*++
|
||
|
||
Copyright (c) 1999, Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
routing\netsh\ip\protocols\vrrphlpcfg.c
|
||
|
||
Abstract:
|
||
|
||
Virtual Router Redundancy Protocol configuration implementation.
|
||
This module contains configuration routines which are relied upon
|
||
by vrrphlpopt.c. The routines retrieve, update, and display
|
||
the configuration for the VRRP protocol.
|
||
|
||
This file also contains default configuration settings
|
||
for VRRP.
|
||
|
||
N.B. The display routines require special attention since display
|
||
may result in a list of commands sent to a 'dump' file, or in a
|
||
textual presentation of the configuration to a console window.
|
||
In the latter case, we use non-localizable output routines to generate
|
||
a script-like description of the configuration. In the former case,
|
||
we use localizable routines to generate a human-readable description.
|
||
|
||
Author:
|
||
|
||
Peeyush Ranjan (peeyushr) 3-Mar-1999
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
|
||
#include "precomp.h"
|
||
#pragma hdrstop
|
||
|
||
|
||
#define Malloc(x) HeapAlloc(GetProcessHeap(), 0, (x))
|
||
#define Free(x) HeapFree(GetProcessHeap(), 0, (x))
|
||
|
||
static VRRP_GLOBAL_CONFIG
|
||
g_VrrpGlobalDefault =
|
||
{
|
||
VRRP_LOGGING_ERROR
|
||
};
|
||
|
||
static PUCHAR g_pVrrpGlobalDefault = (PUCHAR)&g_VrrpGlobalDefault;
|
||
|
||
static VRRP_IF_CONFIG g_VrrpInterfaceDefault =
|
||
{
|
||
0
|
||
};
|
||
|
||
static VRRP_VROUTER_CONFIG g_VrrpVrouterDefault =
|
||
{
|
||
1,
|
||
100,
|
||
1,
|
||
1,
|
||
0,
|
||
0,
|
||
{0,0,0,0,0,0,0,0
|
||
},
|
||
0
|
||
};
|
||
|
||
|
||
//
|
||
// Forward declarations
|
||
//
|
||
ULONG
|
||
ValidateVrrpInterfaceInfo(
|
||
PVRRP_IF_CONFIG InterfaceInfo
|
||
);
|
||
|
||
BOOL
|
||
FoundIpAddress(
|
||
DWORD IPAddress
|
||
);
|
||
|
||
//
|
||
// What follows are the arrays used to map values to strings and
|
||
// to map values to tokens. These, respectively, are used in the case
|
||
// where we are displaying to a 'dump' file and to a console window.
|
||
//
|
||
VALUE_STRING VrrpGlobalLogginStringArray[] = {
|
||
VRRP_LOGGING_NONE, STRING_LOGGING_NONE,
|
||
VRRP_LOGGING_ERROR, STRING_LOGGING_ERROR,
|
||
VRRP_LOGGING_WARN, STRING_LOGGING_WARN,
|
||
VRRP_LOGGING_INFO, STRING_LOGGING_INFO
|
||
};
|
||
|
||
VALUE_TOKEN VrrpGlobalLogginTokenArray[] = {
|
||
VRRP_LOGGING_NONE, TOKEN_OPT_VALUE_NONE,
|
||
VRRP_LOGGING_ERROR, TOKEN_OPT_VALUE_ERROR,
|
||
VRRP_LOGGING_WARN, TOKEN_OPT_VALUE_WARN,
|
||
VRRP_LOGGING_INFO, TOKEN_OPT_VALUE_INFO
|
||
};
|
||
|
||
VALUE_STRING VrrpAuthModeStringArray[] = {
|
||
VRRP_AUTHTYPE_NONE, STRING_AUTH_NONE,
|
||
VRRP_AUTHTYPE_PLAIN, STRING_AUTH_SIMPLEPASSWD,
|
||
VRRP_AUTHTYPE_IPHEAD, STRING_AUTH_IPHEADER
|
||
};
|
||
|
||
VALUE_TOKEN VrrpAuthModeTokenArray[] = {
|
||
VRRP_AUTHTYPE_NONE, TOKEN_OPT_VALUE_AUTH_NONE,
|
||
VRRP_AUTHTYPE_PLAIN, TOKEN_OPT_VALUE_AUTH_SIMPLE_PASSWORD,
|
||
VRRP_AUTHTYPE_IPHEAD, TOKEN_OPT_VALUE_AUTH_MD5
|
||
};
|
||
|
||
VALUE_STRING VrrpPreemptModeStringArray[] = {
|
||
TRUE, STRING_ENABLED,
|
||
FALSE, STRING_DISABLED
|
||
};
|
||
|
||
VALUE_TOKEN VrrpPreemptModeTokenArray[] = {
|
||
TRUE, TOKEN_OPT_VALUE_ENABLE,
|
||
FALSE,TOKEN_OPT_VALUE_DISABLE
|
||
};
|
||
|
||
typedef enum {
|
||
VrrpGlobalLoggingModeIndex,
|
||
VrrpAuthModeIndex,
|
||
VrrpPreemptModeIndex
|
||
} DISPLAY_VALUE_INDEX;
|
||
|
||
|
||
|
||
|
||
PTCHAR
|
||
QueryValueString(
|
||
HANDLE FileHandle,
|
||
DISPLAY_VALUE_INDEX Index,
|
||
ULONG Value
|
||
)
|
||
{
|
||
ULONG Count;
|
||
ULONG Error;
|
||
PTCHAR String = NULL;
|
||
PVALUE_STRING StringArray;
|
||
PVALUE_TOKEN TokenArray;
|
||
switch (Index) {
|
||
case VrrpGlobalLoggingModeIndex:
|
||
Count = NUM_VALUES_IN_TABLE(VrrpGlobalLogginStringArray);
|
||
StringArray = VrrpGlobalLogginStringArray;
|
||
TokenArray = VrrpGlobalLogginTokenArray;
|
||
break;
|
||
case VrrpAuthModeIndex:
|
||
Count = NUM_VALUES_IN_TABLE(VrrpAuthModeStringArray);
|
||
StringArray = VrrpAuthModeStringArray;
|
||
TokenArray = VrrpAuthModeTokenArray;
|
||
break;
|
||
case VrrpPreemptModeIndex:
|
||
Count = NUM_VALUES_IN_TABLE(VrrpPreemptModeStringArray);
|
||
StringArray = VrrpPreemptModeStringArray;
|
||
TokenArray = VrrpPreemptModeTokenArray;
|
||
break;
|
||
default:
|
||
return NULL;
|
||
}
|
||
Error =
|
||
GetAltDisplayString(
|
||
g_hModule,
|
||
FileHandle,
|
||
Value,
|
||
TokenArray,
|
||
StringArray,
|
||
Count,
|
||
&String
|
||
);
|
||
return Error ? NULL : String;
|
||
}
|
||
|
||
|
||
|
||
ULONG
|
||
MakeVrrpGlobalInfo(
|
||
OUT PUCHAR* GlobalInfo,
|
||
OUT PULONG GlobalInfoSize
|
||
)
|
||
{
|
||
*GlobalInfoSize = sizeof(VRRP_GLOBAL_CONFIG);
|
||
*GlobalInfo = Malloc(*GlobalInfoSize);
|
||
if (!*GlobalInfo) {
|
||
DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
|
||
return ERROR_NOT_ENOUGH_MEMORY;
|
||
}
|
||
CopyMemory(*GlobalInfo, g_pVrrpGlobalDefault, *GlobalInfoSize);
|
||
return NO_ERROR;
|
||
}
|
||
|
||
ULONG
|
||
CreateVrrpGlobalInfo(
|
||
OUT PVRRP_GLOBAL_CONFIG* GlobalInfo,
|
||
IN DWORD LoggingLevel
|
||
)
|
||
{
|
||
DWORD GlobalInfoSize;
|
||
GlobalInfoSize = sizeof(PVRRP_GLOBAL_CONFIG);
|
||
*GlobalInfo = Malloc(GlobalInfoSize);
|
||
if (!*GlobalInfo) {
|
||
DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
|
||
return ERROR_NOT_ENOUGH_MEMORY;
|
||
}
|
||
CopyMemory(*GlobalInfo, g_pVrrpGlobalDefault, GlobalInfoSize);
|
||
(*GlobalInfo)->LoggingLevel = LoggingLevel;
|
||
|
||
return NO_ERROR;
|
||
}
|
||
|
||
ULONG
|
||
MakeVrrpInterfaceInfo(
|
||
ROUTER_INTERFACE_TYPE InterfaceType,
|
||
OUT PUCHAR* InterfaceInfo,
|
||
OUT PULONG InterfaceInfoSize
|
||
)
|
||
{
|
||
//
|
||
//Why is this check done?
|
||
//
|
||
if (InterfaceType != ROUTER_IF_TYPE_DEDICATED) {
|
||
return ERROR_INVALID_PARAMETER;
|
||
}
|
||
|
||
*InterfaceInfoSize = sizeof(VRRP_IF_CONFIG);
|
||
*InterfaceInfo = Malloc(*InterfaceInfoSize);
|
||
if (!*InterfaceInfo) {
|
||
DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
|
||
return ERROR_NOT_ENOUGH_MEMORY;
|
||
}
|
||
CopyMemory(*InterfaceInfo, &g_VrrpInterfaceDefault, *InterfaceInfoSize);
|
||
return NO_ERROR;
|
||
}
|
||
|
||
ULONG
|
||
MakeVrrpVRouterInfo(
|
||
IN OUT PUCHAR VRouterInfo
|
||
)
|
||
{
|
||
//
|
||
// Always assumed that the space has been preassigned
|
||
//
|
||
if (!VRouterInfo) {
|
||
return ERROR_INVALID_PARAMETER;
|
||
}
|
||
CopyMemory(VRouterInfo,&g_VrrpVrouterDefault,sizeof(g_VrrpVrouterDefault));
|
||
return NO_ERROR;
|
||
}
|
||
|
||
|
||
ULONG
|
||
ShowVrrpGlobalInfo(
|
||
HANDLE FileHandle
|
||
)
|
||
{
|
||
ULONG Count = 0;
|
||
ULONG Error;
|
||
PVRRP_GLOBAL_CONFIG GlobalInfo = NULL;
|
||
ULONG i;
|
||
PTCHAR LoggingLevel = NULL;
|
||
ULONG Size;
|
||
do {
|
||
//
|
||
// Retrieve the global configuration for the VRRP,
|
||
// and format its contents to the output file or console.
|
||
//
|
||
Error =
|
||
IpmontrGetInfoBlockFromGlobalInfo(
|
||
MS_IP_VRRP,
|
||
(PUCHAR*)&GlobalInfo,
|
||
&Size,
|
||
&Count
|
||
);
|
||
if (Error) {
|
||
break;
|
||
} else if (!(Count * Size)) {
|
||
Error = ERROR_NOT_FOUND; break;
|
||
}
|
||
LoggingLevel =
|
||
QueryValueString(
|
||
FileHandle, VrrpGlobalLoggingModeIndex, GlobalInfo->LoggingLevel
|
||
);
|
||
if (!LoggingLevel) { break; }
|
||
if (FileHandle) {
|
||
DisplayMessageT(DMP_VRRP_INSTALL);
|
||
DisplayMessageT(
|
||
DMP_VRRP_SET_GLOBAL,
|
||
TOKEN_OPT_LOGGINGLEVEL, LoggingLevel
|
||
);
|
||
} else {
|
||
DisplayMessage(
|
||
g_hModule,
|
||
MSG_VRRP_GLOBAL_INFO,
|
||
LoggingLevel
|
||
);
|
||
}
|
||
} while(FALSE);
|
||
|
||
if (LoggingLevel) { Free(LoggingLevel); }
|
||
if (GlobalInfo) { Free(GlobalInfo); }
|
||
if (!FileHandle && Error) {
|
||
if (Error == ERROR_NOT_FOUND) {
|
||
DisplayMessage(g_hModule, EMSG_PROTO_NO_GLOBAL_INFO);
|
||
} else {
|
||
DisplayError(g_hModule, Error);
|
||
}
|
||
}
|
||
return Error;
|
||
}
|
||
|
||
ULONG
|
||
ShowVrrpAllInterfaceInfo(
|
||
HANDLE FileHandle
|
||
)
|
||
{
|
||
DWORD dwErr, dwCount, dwTotal;
|
||
DWORD dwNumParsed, i, dwNumBlocks=1, dwSize, dwIfType;
|
||
PBYTE pBuffer;
|
||
PMPR_INTERFACE_0 pmi0;
|
||
WCHAR wszIfDesc[MAX_INTERFACE_NAME_LEN + 1];
|
||
|
||
//
|
||
// dump vrrp config for all interfaces
|
||
//
|
||
|
||
dwErr = IpmontrInterfaceEnum((PBYTE *) &pmi0,
|
||
&dwCount,
|
||
&dwTotal);
|
||
|
||
if(dwErr != NO_ERROR)
|
||
{
|
||
DisplayError(g_hModule,
|
||
dwErr);
|
||
return dwErr;
|
||
}
|
||
|
||
for(i = 0; i < dwCount; i++)
|
||
{
|
||
// make sure that vrrp is configured on that interface
|
||
|
||
dwErr = IpmontrGetInfoBlockFromInterfaceInfo(pmi0[i].wszInterfaceName,
|
||
MS_IP_VRRP,
|
||
&pBuffer,
|
||
&dwSize,
|
||
&dwNumBlocks,
|
||
&dwIfType);
|
||
if (dwErr != NO_ERROR) {
|
||
continue;
|
||
}
|
||
else {
|
||
HEAP_FREE(pBuffer) ;
|
||
}
|
||
|
||
|
||
ShowVrrpInterfaceInfo(FileHandle, pmi0[i].wszInterfaceName);
|
||
}
|
||
return NO_ERROR;
|
||
}
|
||
|
||
ULONG
|
||
ShowVrrpInterfaceInfo(
|
||
HANDLE FileHandle,
|
||
PWCHAR InterfaceName
|
||
)
|
||
{
|
||
ULONG Count = 0;
|
||
ULONG Error;
|
||
PVRRP_IF_CONFIG InterfaceInfo;
|
||
PTCHAR AuthType = NULL;
|
||
ULONG Size;
|
||
ULONG dwLength;
|
||
TCHAR Title[MAX_INTERFACE_NAME_LEN + 1];
|
||
ROUTER_INTERFACE_TYPE Type;
|
||
ULONG Index;
|
||
ULONG IPIndex;
|
||
BYTE Password[VRRP_MAX_AUTHKEY_SIZE];
|
||
PTCHAR IPAddresses = NULL;
|
||
TCHAR Address[VRRP_IPADDR_LENGTH+1];
|
||
PVRRP_VROUTER_CONFIG PVrouter;
|
||
PTCHAR PreemptMode = NULL;
|
||
|
||
do {
|
||
//
|
||
// Retrieve the interface's configuration
|
||
// and format it to the output file or console.
|
||
//
|
||
Error =
|
||
IpmontrGetInfoBlockFromInterfaceInfo(
|
||
InterfaceName,
|
||
MS_IP_VRRP,
|
||
(PUCHAR*)&InterfaceInfo,
|
||
&Size,
|
||
&Count,
|
||
&Type
|
||
);
|
||
if (Error) {
|
||
break;
|
||
} else if (!(Count * Size)) {
|
||
Error = ERROR_NOT_FOUND; break;
|
||
}
|
||
Size = sizeof(Title);
|
||
Error = IpmontrGetFriendlyNameFromIfName(InterfaceName, Title, &Size);
|
||
if (Error) {
|
||
Error = ERROR_NO_SUCH_INTERFACE;
|
||
break;
|
||
}
|
||
if (FileHandle) {
|
||
DisplayMessage(g_hModule, DMP_VRRP_INTERFACE_HEADER, Title);
|
||
DisplayMessageT(DMP_VRRP_ADD_INTERFACE,
|
||
TOKEN_OPT_NAME, Title);
|
||
if (InterfaceInfo->VrouterCount) {
|
||
for (Index = 0 , PVrouter = VRRP_FIRST_VROUTER_CONFIG(InterfaceInfo);
|
||
Index < InterfaceInfo->VrouterCount;
|
||
Index++ , PVrouter = VRRP_NEXT_VROUTER_CONFIG(PVrouter)) {
|
||
for (IPIndex = 0; IPIndex < PVrouter->IPCount;
|
||
IPIndex++) {
|
||
IP_TO_TSTR(Address,
|
||
&PVrouter->IPAddress[IPIndex]
|
||
);
|
||
DisplayMessageT(
|
||
DMP_VRRP_ADD_VRID,
|
||
TOKEN_OPT_NAME, Title,
|
||
TOKEN_OPT_VRID, PVrouter->VRID,
|
||
TOKEN_OPT_IPADDRESS, Address
|
||
);
|
||
}
|
||
|
||
AuthType =
|
||
QueryValueString(
|
||
FileHandle, VrrpAuthModeIndex,
|
||
PVrouter->AuthenticationType
|
||
);
|
||
if (!AuthType) {
|
||
Error = ERROR_INVALID_PARAMETER;
|
||
break;
|
||
}
|
||
CopyMemory(Password,PVrouter->AuthenticationData,
|
||
VRRP_MAX_AUTHKEY_SIZE);
|
||
DisplayMessageT(
|
||
DMP_VRRP_SET_INTERFACE,
|
||
TOKEN_OPT_NAME, Title,
|
||
TOKEN_OPT_VRID, PVrouter->VRID,
|
||
TOKEN_OPT_AUTH,
|
||
(PVrouter->AuthenticationType == VRRP_AUTHTYPE_NONE) ?
|
||
TOKEN_OPT_VALUE_AUTH_NONE : ((PVrouter->AuthenticationType
|
||
== VRRP_AUTHTYPE_PLAIN) ? TOKEN_OPT_VALUE_AUTH_SIMPLE_PASSWORD :
|
||
TOKEN_OPT_VALUE_AUTH_MD5 ) ,
|
||
TOKEN_OPT_PASSWD, Password[0], Password[1], Password[2],
|
||
Password[3], Password[4], Password[5],Password[6], Password[7],
|
||
TOKEN_OPT_ADVTINTERVAL, PVrouter->AdvertisementInterval,
|
||
TOKEN_OPT_PRIO,PVrouter->ConfigPriority,
|
||
TOKEN_OPT_PREEMPT, PVrouter->PreemptMode? TOKEN_OPT_VALUE_ENABLE :
|
||
TOKEN_OPT_VALUE_DISABLE
|
||
);
|
||
}
|
||
}
|
||
} else {
|
||
DisplayMessage(g_hModule, MSG_VRRP_INTERFACE_INFO,Title,
|
||
InterfaceInfo->VrouterCount);
|
||
for (Index = 0, PVrouter = VRRP_FIRST_VROUTER_CONFIG(InterfaceInfo);
|
||
Index < InterfaceInfo->VrouterCount;
|
||
Index++, PVrouter = VRRP_NEXT_VROUTER_CONFIG(PVrouter)) {
|
||
AuthType =
|
||
QueryValueString(
|
||
FileHandle, VrrpAuthModeIndex,
|
||
PVrouter->AuthenticationType
|
||
);
|
||
if (!AuthType) {
|
||
Error = ERROR_INVALID_PARAMETER;
|
||
break;
|
||
}
|
||
CopyMemory(Password,PVrouter->AuthenticationData,
|
||
VRRP_MAX_AUTHKEY_SIZE);
|
||
//
|
||
// Allocate space for each IP address, a space+comma each and also a
|
||
// null terminator
|
||
//
|
||
IPAddresses = Malloc(dwLength = (((VRRP_IPADDR_LENGTH+2)*sizeof(TCHAR)*
|
||
PVrouter->IPCount)+1));
|
||
if (!IPAddresses) {
|
||
DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
|
||
|
||
//
|
||
// Set AuthType to 0 which will cause a break from the outer loop
|
||
//
|
||
|
||
AuthType = 0;
|
||
Error = ERROR_NOT_ENOUGH_MEMORY;
|
||
break;
|
||
}
|
||
ZeroMemory(IPAddresses,dwLength);
|
||
//
|
||
// Now build the IP address list from the addresses given
|
||
//
|
||
for (IPIndex = 0; IPIndex < PVrouter->IPCount; IPIndex++ ) {
|
||
IP_TO_TSTR(Address,&PVrouter->IPAddress[IPIndex]);
|
||
wcscat(IPAddresses,Address);
|
||
if (IPIndex != (ULONG)(PVrouter->IPCount-1)) {
|
||
wcscat(IPAddresses,L", ");
|
||
}
|
||
}
|
||
PreemptMode =
|
||
QueryValueString(
|
||
FileHandle,
|
||
VrrpPreemptModeIndex,
|
||
PVrouter->PreemptMode
|
||
);
|
||
if (!PreemptMode) { break; }
|
||
|
||
DisplayMessage(
|
||
g_hModule,
|
||
MSG_VRRP_VRID_INFO,
|
||
PVrouter->VRID,
|
||
IPAddresses,
|
||
AuthType,
|
||
Password[0], Password[1], Password[2], Password[3],
|
||
Password[4], Password[5], Password[6], Password[7],
|
||
PVrouter->AdvertisementInterval,
|
||
PVrouter->ConfigPriority,
|
||
PreemptMode
|
||
);
|
||
}
|
||
}
|
||
if (!AuthType) {
|
||
break;
|
||
}
|
||
Error = NO_ERROR;
|
||
} while(FALSE);
|
||
if (AuthType) { Free(AuthType); }
|
||
Free(InterfaceInfo);
|
||
if (IPAddresses) Free(IPAddresses);
|
||
if (!FileHandle && Error) {
|
||
if (Error == ERROR_NOT_FOUND) {
|
||
DisplayMessage(g_hModule, EMSG_PROTO_NO_IF_INFO);
|
||
} else {
|
||
DisplayError(g_hModule, Error);
|
||
}
|
||
}
|
||
return Error;
|
||
}
|
||
|
||
ULONG
|
||
UpdateVrrpGlobalInfo(
|
||
PVRRP_GLOBAL_CONFIG GlobalInfo
|
||
)
|
||
{
|
||
ULONG Count;
|
||
ULONG Error;
|
||
PVRRP_GLOBAL_CONFIG NewGlobalInfo = NULL;
|
||
PVRRP_GLOBAL_CONFIG OldGlobalInfo = NULL;
|
||
ULONG Size;
|
||
|
||
do {
|
||
//
|
||
// Retrieve the existing global configuration.
|
||
//
|
||
Error =
|
||
IpmontrGetInfoBlockFromGlobalInfo(
|
||
MS_IP_VRRP,
|
||
(PUCHAR*)&OldGlobalInfo,
|
||
&Size,
|
||
&Count
|
||
);
|
||
if (Error) {
|
||
break;
|
||
} else if (!(Count * Size)) {
|
||
Error = ERROR_NOT_FOUND; break;
|
||
}
|
||
|
||
//
|
||
// Allocate a new structure, copy to it the original configuration,
|
||
//
|
||
|
||
NewGlobalInfo = Malloc(Count * Size);
|
||
if (!NewGlobalInfo) { Error = ERROR_NOT_ENOUGH_MEMORY; break; }
|
||
CopyMemory(NewGlobalInfo, OldGlobalInfo, Count * Size);
|
||
|
||
//
|
||
// Based on the changes requested, change the NewGlobalInfo.
|
||
// Since for VRRP there is only the logging level to change, we just set that.
|
||
//
|
||
|
||
NewGlobalInfo->LoggingLevel = GlobalInfo->LoggingLevel;
|
||
|
||
Error =
|
||
IpmontrSetInfoBlockInGlobalInfo(
|
||
MS_IP_VRRP,
|
||
(PUCHAR)NewGlobalInfo,
|
||
FIELD_OFFSET(IP_NAT_GLOBAL_INFO, Header) +
|
||
Count * Size,
|
||
1
|
||
);
|
||
} while(FALSE);
|
||
if (NewGlobalInfo) { Free(NewGlobalInfo); }
|
||
if (OldGlobalInfo) { Free(OldGlobalInfo); }
|
||
if (Error == ERROR_NOT_FOUND) {
|
||
DisplayMessage(g_hModule, EMSG_PROTO_NO_GLOBAL_INFO);
|
||
} else if (Error) {
|
||
DisplayError(g_hModule, Error);
|
||
}
|
||
return Error;
|
||
}
|
||
|
||
|
||
ULONG
|
||
UpdateVrrpInterfaceInfo(
|
||
PWCHAR InterfaceName,
|
||
PVRRP_VROUTER_CONFIG VRouterInfo,
|
||
ULONG BitVector,
|
||
BOOL AddInterface
|
||
)
|
||
{
|
||
ULONG Count;
|
||
ULONG Error;
|
||
PVRRP_IF_CONFIG NewInterfaceInfo = NULL;
|
||
PVRRP_IF_CONFIG OldInterfaceInfo = NULL;
|
||
PVRRP_VROUTER_CONFIG PVrouter = NULL;
|
||
ULONG Size;
|
||
ROUTER_INTERFACE_TYPE Type;
|
||
ULONG i;
|
||
|
||
if (!AddInterface && !BitVector) { return NO_ERROR; }
|
||
do {
|
||
//
|
||
// Retrieve the existing interface configuration.
|
||
// We will update this block below, as well as adding to or removing
|
||
// from it depending on the flags specified in 'BitVector'.
|
||
//
|
||
Error =
|
||
IpmontrGetInfoBlockFromInterfaceInfo(
|
||
InterfaceName,
|
||
MS_IP_VRRP,
|
||
(PUCHAR*)&OldInterfaceInfo,
|
||
&Size,
|
||
&Count,
|
||
&Type
|
||
);
|
||
if (Error) {
|
||
//
|
||
// No existing configuration is found. This is an error unless
|
||
// we are adding the interface anew, in which case we just
|
||
// create for ourselves a block containing the default settings.
|
||
//
|
||
if (!AddInterface) {
|
||
break;
|
||
} else {
|
||
Error = IpmontrGetInterfaceType(InterfaceName, &Type);
|
||
if (Error) {
|
||
break;
|
||
} else {
|
||
Count = 1;
|
||
Error =
|
||
MakeVrrpInterfaceInfo(
|
||
Type, (PUCHAR*)&OldInterfaceInfo, &Size
|
||
);
|
||
if (Error) { break; }
|
||
}
|
||
}
|
||
} else {
|
||
//
|
||
// There is configuration on the interface. If it is empty this is
|
||
// an error. If this is an add interface, and the info exists, it is
|
||
// an error.
|
||
//
|
||
if (!(Count * Size) && !AddInterface) {
|
||
Error = ERROR_NOT_FOUND; break;
|
||
}
|
||
else if (AddInterface) {
|
||
//
|
||
// We were asked to add an interface which already exists
|
||
//
|
||
DisplayMessage(g_hModule, EMSG_INTERFACE_EXISTS, InterfaceName);
|
||
Error = ERROR_INVALID_PARAMETER;
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
if (!BitVector) {
|
||
//
|
||
// Just add this interface without any additional info.
|
||
//
|
||
DWORD OldSize;
|
||
if (NewInterfaceInfo == NULL){
|
||
NewInterfaceInfo = Malloc((OldSize=GetVrrpIfInfoSize(OldInterfaceInfo))+
|
||
sizeof(VRRP_VROUTER_CONFIG));
|
||
if (!NewInterfaceInfo) {
|
||
DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
|
||
Error = ERROR_NOT_ENOUGH_MEMORY;
|
||
break;
|
||
}
|
||
}
|
||
CopyMemory(NewInterfaceInfo,OldInterfaceInfo,OldSize);
|
||
}
|
||
else{
|
||
if (!AddInterface || (OldInterfaceInfo->VrouterCount != 0)) {
|
||
//
|
||
// There is a prexisting VRID set. Check for this VRID in the list and then
|
||
// update it if required.
|
||
//
|
||
ASSERT(BitVector & VRRP_INTF_VRID_MASK);
|
||
for (i = 0, PVrouter = VRRP_FIRST_VROUTER_CONFIG(OldInterfaceInfo);
|
||
i < OldInterfaceInfo->VrouterCount;
|
||
i++, PVrouter = VRRP_NEXT_VROUTER_CONFIG(PVrouter)) {
|
||
if (PVrouter->VRID == VRouterInfo->VRID) {
|
||
break;
|
||
}
|
||
}
|
||
if (i == OldInterfaceInfo->VrouterCount) {
|
||
//
|
||
// This is a new VRID, Add it.
|
||
//
|
||
DWORD OldSize;
|
||
|
||
//
|
||
// The IP address should be valid or else this is a set op.
|
||
//
|
||
if (!(BitVector & VRRP_INTF_IPADDR_MASK)){
|
||
DisplayMessage(
|
||
g_hModule, EMSG_INVALID_VRID,
|
||
VRouterInfo->VRID
|
||
);
|
||
Error = ERROR_INVALID_PARAMETER;
|
||
break;
|
||
}
|
||
|
||
if (NewInterfaceInfo == NULL){
|
||
NewInterfaceInfo = Malloc((OldSize=GetVrrpIfInfoSize(
|
||
OldInterfaceInfo))+
|
||
sizeof(VRRP_VROUTER_CONFIG));
|
||
if (!NewInterfaceInfo) {
|
||
DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
|
||
Error = ERROR_NOT_ENOUGH_MEMORY;
|
||
break;
|
||
}
|
||
}
|
||
CopyMemory(NewInterfaceInfo, OldInterfaceInfo, OldSize);
|
||
PVrouter = (PVRRP_VROUTER_CONFIG)((PBYTE)NewInterfaceInfo+OldSize);
|
||
CopyMemory(PVrouter,VRouterInfo,sizeof(VRRP_VROUTER_CONFIG));
|
||
NewInterfaceInfo->VrouterCount++;
|
||
|
||
//
|
||
// Check if we own the IP address given. If yes, set the priority.
|
||
//
|
||
PVrouter->ConfigPriority =
|
||
FoundIpAddress(PVrouter->IPAddress[0]) ? 255 : 100;
|
||
}
|
||
else{
|
||
//
|
||
// This is an old VRID. Its priority should not need to be changed.
|
||
//
|
||
DWORD Offset, OldSize;
|
||
|
||
if(BitVector & VRRP_INTF_IPADDR_MASK) {
|
||
if ( ((PVrouter->ConfigPriority != 255) &&
|
||
(FoundIpAddress(VRouterInfo->IPAddress[0]))
|
||
)
|
||
||
|
||
((PVrouter->ConfigPriority == 255) &&
|
||
(!FoundIpAddress(VRouterInfo->IPAddress[0])))
|
||
) {
|
||
DisplayMessage(g_hModule, EMSG_BAD_OPTION_VALUE);
|
||
Error = ERROR_INVALID_PARAMETER;
|
||
break;
|
||
}
|
||
//
|
||
// Add this IP address to the VRID specified.
|
||
//
|
||
if (NewInterfaceInfo == NULL){
|
||
NewInterfaceInfo = Malloc((OldSize = GetVrrpIfInfoSize(
|
||
OldInterfaceInfo))+
|
||
sizeof(DWORD));
|
||
if (!NewInterfaceInfo) {
|
||
DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
|
||
Error = ERROR_NOT_ENOUGH_MEMORY;
|
||
break;
|
||
}
|
||
}
|
||
//
|
||
// Shift all the VROUTER configs after the PVrouter by 1 DWORD.
|
||
//
|
||
Offset = (PUCHAR) VRRP_NEXT_VROUTER_CONFIG(PVrouter) -
|
||
(PUCHAR) OldInterfaceInfo;
|
||
CopyMemory(NewInterfaceInfo, OldInterfaceInfo, OldSize);
|
||
for (i = 0, PVrouter = VRRP_FIRST_VROUTER_CONFIG(NewInterfaceInfo);
|
||
i < NewInterfaceInfo->VrouterCount;
|
||
i++, PVrouter = VRRP_NEXT_VROUTER_CONFIG(PVrouter)) {
|
||
if (PVrouter->VRID == VRouterInfo->VRID) {
|
||
break;
|
||
}
|
||
}
|
||
ASSERT(i < NewInterfaceInfo->VrouterCount);
|
||
PVrouter->IPAddress[PVrouter->IPCount++] = VRouterInfo->IPAddress[0];
|
||
|
||
ASSERT(((PUCHAR)NewInterfaceInfo+Offset+sizeof(DWORD)) ==
|
||
(PUCHAR) VRRP_NEXT_VROUTER_CONFIG(PVrouter));
|
||
|
||
CopyMemory(VRRP_NEXT_VROUTER_CONFIG(PVrouter),
|
||
OldInterfaceInfo+Offset, OldSize-Offset);
|
||
} else {
|
||
//
|
||
// Set the new info block as the old info block and point to the
|
||
// vrouter block
|
||
//
|
||
if (NewInterfaceInfo == NULL){
|
||
NewInterfaceInfo = Malloc((OldSize = GetVrrpIfInfoSize(
|
||
OldInterfaceInfo)));
|
||
if (!NewInterfaceInfo) {
|
||
DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
|
||
Error = ERROR_NOT_ENOUGH_MEMORY;
|
||
break;
|
||
}
|
||
}
|
||
CopyMemory(NewInterfaceInfo, OldInterfaceInfo, OldSize);
|
||
for (i = 0, PVrouter = VRRP_FIRST_VROUTER_CONFIG(NewInterfaceInfo);
|
||
i < NewInterfaceInfo->VrouterCount;
|
||
i++, PVrouter = VRRP_NEXT_VROUTER_CONFIG(PVrouter)) {
|
||
if (PVrouter->VRID == VRouterInfo->VRID) {
|
||
break;
|
||
}
|
||
}
|
||
ASSERT(i < NewInterfaceInfo->VrouterCount);
|
||
}
|
||
|
||
if (BitVector & VRRP_INTF_AUTH_MASK) {
|
||
PVrouter->AuthenticationType = VRouterInfo->AuthenticationType;
|
||
}
|
||
if (BitVector & VRRP_INTF_PASSWD_MASK) {
|
||
CopyMemory(PVrouter->AuthenticationData,
|
||
VRouterInfo->AuthenticationData,
|
||
VRRP_MAX_AUTHKEY_SIZE);
|
||
}
|
||
if (BitVector & VRRP_INTF_ADVT_MASK) {
|
||
PVrouter->AdvertisementInterval = VRouterInfo->AdvertisementInterval;
|
||
}
|
||
if (BitVector & VRRP_INTF_PRIO_MASK) {
|
||
PVrouter->ConfigPriority = VRouterInfo->ConfigPriority;
|
||
}
|
||
if (BitVector & VRRP_INTF_PREEMPT_MASK) {
|
||
PVrouter->PreemptMode = VRouterInfo->PreemptMode;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
ValidateVrrpInterfaceInfo(NewInterfaceInfo);
|
||
|
||
Error =
|
||
IpmontrSetInfoBlockInInterfaceInfo(
|
||
InterfaceName,
|
||
MS_IP_VRRP,
|
||
(PUCHAR)NewInterfaceInfo,
|
||
GetVrrpIfInfoSize(NewInterfaceInfo),
|
||
1
|
||
);
|
||
} while(FALSE);
|
||
if (NewInterfaceInfo) { Free(NewInterfaceInfo); }
|
||
if (OldInterfaceInfo) { Free(OldInterfaceInfo); }
|
||
if (Error == ERROR_NOT_FOUND) {
|
||
DisplayMessage(g_hModule, EMSG_PROTO_NO_IF_INFO);
|
||
} else if (Error) {
|
||
DisplayError(g_hModule, Error);
|
||
}
|
||
return Error;
|
||
}
|
||
|
||
ULONG
|
||
DeleteVrrpInterfaceInfo(
|
||
PWCHAR InterfaceName,
|
||
PVRRP_VROUTER_CONFIG VRouterInfo,
|
||
ULONG BitVector,
|
||
BOOL DeleteInterface
|
||
)
|
||
{
|
||
ULONG Count;
|
||
ULONG Error;
|
||
PVRRP_IF_CONFIG NewInterfaceInfo = NULL;
|
||
PVRRP_IF_CONFIG OldInterfaceInfo = NULL;
|
||
PVRRP_VROUTER_CONFIG PVrouter = NULL;
|
||
ULONG Size;
|
||
ROUTER_INTERFACE_TYPE Type;
|
||
ULONG i;
|
||
|
||
if (!DeleteInterface && !BitVector) { return NO_ERROR; }
|
||
do {
|
||
//
|
||
// Retrieve the existing interface configuration.
|
||
// We will update this block below, as well as adding to or removing
|
||
// from it depending on the flags specified in 'BitVector'.
|
||
//
|
||
Error =
|
||
IpmontrGetInfoBlockFromInterfaceInfo(
|
||
InterfaceName,
|
||
MS_IP_VRRP,
|
||
(PUCHAR*)&OldInterfaceInfo,
|
||
&Size,
|
||
&Count,
|
||
&Type
|
||
);
|
||
if (Error) {
|
||
//
|
||
// No existing configuration is found. This is an error.
|
||
//
|
||
break;
|
||
}
|
||
if (DeleteInterface) {
|
||
//
|
||
// Just delete this interface
|
||
//
|
||
Error = IpmontrDeleteInfoBlockFromInterfaceInfo(
|
||
InterfaceName,
|
||
MS_IP_VRRP
|
||
);
|
||
break;
|
||
} else {
|
||
DWORD OldSize;
|
||
PVRRP_VROUTER_CONFIG PVrouterNew;
|
||
//
|
||
// Look for the VRID and delete it.
|
||
//
|
||
for (i = 0, PVrouter = VRRP_FIRST_VROUTER_CONFIG(OldInterfaceInfo);
|
||
i < OldInterfaceInfo->VrouterCount;
|
||
i++, PVrouter = VRRP_NEXT_VROUTER_CONFIG(PVrouter)) {
|
||
if (PVrouter->VRID == VRouterInfo->VRID) {
|
||
break;
|
||
}
|
||
}
|
||
if (i >= OldInterfaceInfo->VrouterCount) {
|
||
DisplayMessage(g_hModule, EMSG_BAD_OPTION_VALUE);
|
||
Error = ERROR_INVALID_PARAMETER;
|
||
break;
|
||
}
|
||
|
||
NewInterfaceInfo = Malloc((OldSize=GetVrrpIfInfoSize(OldInterfaceInfo))-
|
||
VRRP_VROUTER_CONFIG_SIZE(PVrouter));
|
||
if (!NewInterfaceInfo) {
|
||
DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
|
||
Error = ERROR_NOT_ENOUGH_MEMORY;
|
||
break;
|
||
}
|
||
NewInterfaceInfo->VrouterCount = OldInterfaceInfo->VrouterCount - 1;
|
||
PVrouterNew = VRRP_FIRST_VROUTER_CONFIG(NewInterfaceInfo);
|
||
for (i = 0, PVrouter = VRRP_FIRST_VROUTER_CONFIG(OldInterfaceInfo);
|
||
i < OldInterfaceInfo->VrouterCount;
|
||
i++, PVrouter = VRRP_NEXT_VROUTER_CONFIG(PVrouter)) {
|
||
if (PVrouter->VRID == VRouterInfo->VRID) {
|
||
continue;
|
||
}
|
||
CopyMemory(PVrouterNew,PVrouter,VRRP_VROUTER_CONFIG_SIZE(PVrouter));
|
||
PVrouterNew = VRRP_NEXT_VROUTER_CONFIG(PVrouterNew);
|
||
}
|
||
|
||
ValidateVrrpInterfaceInfo(NewInterfaceInfo);
|
||
|
||
Error =
|
||
IpmontrSetInfoBlockInInterfaceInfo(
|
||
InterfaceName,
|
||
MS_IP_VRRP,
|
||
(PUCHAR)NewInterfaceInfo,
|
||
GetVrrpIfInfoSize(NewInterfaceInfo),
|
||
1
|
||
);
|
||
}
|
||
|
||
} while(FALSE);
|
||
if (NewInterfaceInfo) { Free(NewInterfaceInfo); }
|
||
if (OldInterfaceInfo) { Free(OldInterfaceInfo); }
|
||
if (Error == ERROR_NOT_FOUND) {
|
||
DisplayMessage(g_hModule, EMSG_PROTO_NO_IF_INFO);
|
||
} else if (Error) {
|
||
DisplayError(g_hModule, Error);
|
||
}
|
||
return Error;
|
||
}
|
||
|
||
|
||
ULONG
|
||
ValidateVrrpInterfaceInfo(
|
||
PVRRP_IF_CONFIG InterfaceInfo
|
||
)
|
||
{
|
||
return NO_ERROR;
|
||
}
|
||
|
||
DWORD
|
||
GetVrrpIfInfoSize(
|
||
PVRRP_IF_CONFIG InterfaceInfo
|
||
)
|
||
{
|
||
DWORD Size = 0;
|
||
ULONG i;
|
||
PVRRP_VROUTER_CONFIG pvr;
|
||
|
||
Size += sizeof(InterfaceInfo->VrouterCount);
|
||
|
||
for (i = 0, pvr = VRRP_FIRST_VROUTER_CONFIG(InterfaceInfo);
|
||
i < InterfaceInfo->VrouterCount;
|
||
i++,pvr = VRRP_NEXT_VROUTER_CONFIG(pvr)) {
|
||
Size += VRRP_VROUTER_CONFIG_SIZE(pvr);
|
||
}
|
||
|
||
return Size;
|
||
}
|
||
|
||
BOOL
|
||
FoundIpAddress(
|
||
DWORD IPAddress
|
||
)
|
||
{
|
||
PMIB_IPADDRTABLE pTable = NULL;
|
||
DWORD Size = 0;
|
||
ULONG i;
|
||
BOOL Result;
|
||
|
||
GetIpAddrTable( pTable, &Size, TRUE);
|
||
pTable = Malloc(Size);
|
||
if (!pTable) {
|
||
DisplayMessage(g_hModule, EMSG_NOT_ENOUGH_MEMORY);
|
||
return FALSE;
|
||
}
|
||
if (GetIpAddrTable(pTable,&Size,TRUE) != NO_ERROR){
|
||
return FALSE;
|
||
}
|
||
|
||
for (i = 0; i < pTable->dwNumEntries; i++) {
|
||
if (pTable->table[i].dwAddr == IPAddress)
|
||
break;
|
||
}
|
||
|
||
Result = (i < pTable->dwNumEntries);
|
||
|
||
Free(pTable);
|
||
|
||
return Result;
|
||
|
||
}
|
||
|
||
ULONG
|
||
SetArpRetryCount(
|
||
DWORD Value
|
||
)
|
||
{
|
||
HKEY hKey = NULL;
|
||
DWORD dwDisp;
|
||
ULONG dwErr = NO_ERROR;
|
||
|
||
do
|
||
{
|
||
dwErr = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
||
L"System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
|
||
0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,
|
||
&hKey, &dwDisp);
|
||
if (dwErr != ERROR_SUCCESS) {
|
||
break;
|
||
}
|
||
dwErr = RegSetValueEx(hKey, L"ArpRetryCount", 0, REG_DWORD, (LPBYTE) &Value,
|
||
sizeof(DWORD));
|
||
} while (0);
|
||
|
||
if (hKey) {
|
||
RegCloseKey(hKey);
|
||
}
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
dwErr = NO_ERROR;
|
||
}
|
||
return dwErr;
|
||
}
|
||
|