Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1070 lines
35 KiB

/*++
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;
}