Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

1377 lines
31 KiB

//=============================================================================
// Copyright (c) 1997 Microsoft Corporation
// File Name: if.c
// Abstract:
//
// Author: K.S.Lokesh (lokeshs@) 1-1-98
//=============================================================================
#include "pchdvmrp.h"
#pragma hdrstop
//----------------------------------------------------------------------------
// _AddInterface
//----------------------------------------------------------------------------
DWORD
WINAPI
AddInterface(
IN PWCHAR pInterfaceName,//not used
IN ULONG IfIndex,
IN NET_INTERFACE_TYPE IfType,
IN DWORD MediaType,
IN WORD AccessType,
IN WORD ConnectionType,
IN PVOID pConfig,
IN ULONG StructureVersion,
IN ULONG StructureSize,
IN ULONG StructureCount
)
{
DWORD Error = NO_ERROR;
Trace1(ENTER, "entering AddInterface(): IfIndex:%d", IfIndex);
ACQUIRE_IF_LIST_LOCK("_AddInterface");
ACQUIRE_IF_LOCK_EXCLUSIVE(IfIndex, "_AddInterface");
Error = AddIfEntry(IfIndex, pConfig, StructureSize);
RELEASE_IF_LIST_LOCK("_AddInterface");
RELEASE_IF_LOCK_EXCLUSIVE(IfIndex, "_AddInterface");
Trace2(LEAVE, "leaving AddInterface(%d): %d\n", IfIndex, Error);
return Error;
}
//----------------------------------------------------------------------------
// _AddIfEntry
//----------------------------------------------------------------------------
DWORD
AddIfEntry(
ULONG IfIndex,
PVOID pConfig,
ULONG StructureSize
)
{
DWORD Error = NO_ERROR;
PIF_CONFIG pIfConfig = (PIF_CONFIG) pConfig;
PIF_TABLE_ENTRY pite = NULL;
//
// validate interface config
//
Error = ValidateIfConfig(IfIndex, pIfConfig, StructureSize);
if (Error != NO_ERROR) {
Trace1(ERR,
"AddInterface(%d) failed due to invalid configuration",
IfIndex);
return Error;
}
BEGIN_BREAKOUT_BLOCK1 {
//
// fail if the interface exists.
//
pite = GetIfEntry(IfIndex);
if (pite != NULL) {
Trace1(ERR, "interface %d already exists", IfIndex);
Error = ERROR_INVALID_PARAMETER;
GOTO_END_BLOCK1;
}
//
// allocate memory for the new interface and its different fields
//
// allocate memory for IfTable
pite = DVMRP_ALLOC_AND_ZERO(sizeof(IF_TABLE_ENTRY));
PROCESS_ALLOC_FAILURE3(pite, "interface %d", Error,
sizeof(IF_TABLE_ENTRY), IfIndex, GOTO_END_BLOCK1);
InitializeListHead(&pite->Link);
InitializeListHead(&pite->HTLink);
pite->IfIndex = IfIndex;
// set interface status (neither bound, enabled or activated)
pite->Status = IF_CREATED_FLAG;
// set base refcount to 1
pite->RefCount = 1;
//
// allocate memory for IfConfig and copy it.
//
pite->pConfig = DVMRP_ALLOC_AND_ZERO(DVMRP_IF_CONFIG_SIZE(pIfConfig));
PROCESS_ALLOC_FAILURE3(pite, "interface %d", Error,
DVMRP_IF_CONFIG_SIZE(pIfConfig), IfIndex, GOTO_END_BLOCK1);
memcpy(pite->pConfig, pIfConfig, DVMRP_IF_CONFIG_SIZE(pIfConfig));
// allocate memory for IfInfo
pite->pInfo = DVMRP_ALLOC_AND_ZERO(sizeof(IF_INFO));
PROCESS_ALLOC_FAILURE3(pite, "interface %d", Error,
sizeof(IF_INFO), IfIndex, GOTO_END_BLOCK1);
//
// allocate memory for Socket data
//
pite->pSocketData = DVMRP_ALLOC_AND_ZERO(sizeof(ASYNC_SOCKET_DATA));
PROCESS_ALLOC_FAILURE3(pite, "interface %d", Error,
sizeof(ASYNC_SOCKET_DATA), IfIndex, GOTO_END_BLOCK1);
pite->pSocketData->WsaBuf.buf = DVMRP_ALLOC(PACKET_BUFFER_SIZE);
PROCESS_ALLOC_FAILURE3(pite, "interface %d", Error,
PACKET_BUFFER_SIZE, IfIndex, GOTO_END_BLOCK1);
pite->pSocketData->WsaBuf.len = PACKET_BUFFER_SIZE;
pite->pSocketData->pite = pite;
} END_BREAKOUT_BLOCK1;
// initialize the sockets to invalid_socket
pite->Socket = INVALID_SOCKET;
// insert the interface in the hash table at the end.
InsertTailList(&G_pIfTable->IfHashTable[IF_HASH_VALUE(IfIndex)],
&pite->HTLink);
//
// insert the entry into the interface list
//
{
PIF_TABLE_ENTRY piteTmp;
PLIST_ENTRY pHead, ple;
pHead = &G_pIfTable->IfList;
for (ple=pHead->Flink; ple!=pHead; ple=ple->Flink) {
piteTmp = CONTAINING_RECORD(ple, IF_TABLE_ENTRY, Link);
if (pite->IfIndex < piteTmp->IfIndex)
break;
}
InsertTailList(ple, &pite->Link);
}
if ( (Error!=NO_ERROR)&&(pite!=NULL) ) {
DeleteIfEntry(pite);
}
return Error;
}//end AddIfEntry
//-----------------------------------------------------------------------------
// _DeleteIfEntry
//-----------------------------------------------------------------------------
VOID
DeleteIfEntry(
PIF_TABLE_ENTRY pite
)
{
if (!pite)
return;
//
// delete peers
//
//
// remove the entry from the interface list, and hashTable
//
RemoveEntryList(&pite->Link);
RemoveEntryList(&pite->HTLink);
if (pite->Socket != INVALID_SOCKET) {
closesocket(pite->Socket);
}
DVMRP_FREE(pite->pInfo);
DVMRP_FREE(pite->pBinding);
DVMRP_FREE(pite->pConfig);
return;
}//end _DeleteIfEntry
//----------------------------------------------------------------------------
// _DeleteInterface
//----------------------------------------------------------------------------
DWORD
DeleteInterface(
IN DWORD IfIndex
)
{
DWORD Error = NO_ERROR;
return Error;
}//end _DeleteInterface
//----------------------------------------------------------------------------
// _InterfaceStatus
//----------------------------------------------------------------------------
DWORD
WINAPI
InterfaceStatus(
ULONG IfIndex,
BOOL IsIfActive,
DWORD StatusType,
PVOID pStatusInfo
)
{
DWORD Error = NO_ERROR;
switch(StatusType)
{
case RIS_INTERFACE_ADDRESS_CHANGE:
{
PIP_ADAPTER_BINDING_INFO pBindInfo
= (PIP_ADAPTER_BINDING_INFO)pStatusInfo;
if(pBindInfo->AddressCount)
{
Error = BindInterface(IfIndex, pBindInfo);
}
else
{
Error = UnBindInterface(IfIndex);
}
break;
}
case RIS_INTERFACE_ENABLED:
{
Error = EnableInterface(IfIndex);
break;
}
case RIS_INTERFACE_DISABLED:
{
Error = DisableInterface(IfIndex);
break;
}
}
return Error;
}
//----------------------------------------------------------------------------
// _BindInterface
//----------------------------------------------------------------------------
DWORD
BindInterface(
ULONG IfIndex,
PIP_ADAPTER_BINDING_INFO pBinding
)
{
DWORD Error = NO_ERROR;
PIF_TABLE_ENTRY pite = NULL;
DWORD i, Size, AddrCount;
IPADDR MinAddr;
PDVMRP_ADDR_MASK pAddrBinding;
INT cmp;
IPADDR ConfigAddr = 0;
Trace1(ENTER1, "entering BindInterface: %d", IfIndex);
Trace1(IF, "binding interface %d", IfIndex);
// pBinding should not be NULL
if (pBinding == NULL) {
Trace0(IF, "error: binding struct pointer is NULL");
Trace1(LEAVE, "leaving BindInterface: %d", ERROR_INVALID_PARAMETER);
return ERROR_INVALID_PARAMETER;
}
//
// take exclusive interface lock
//
ACQUIRE_IF_LOCK_EXCLUSIVE(IfIndex, "_BindInterface");
BEGIN_BREAKOUT_BLOCK1 {
AddrCount = pBinding->AddressCount;
//
// retrieve the interface entry
//
pite = GetIfByIndex(IfIndex);
if (pite == NULL) {
Error = ERROR_INVALID_PARAMETER;
GOTO_END_BLOCK1;
}
//
// If the interface is already bound then return error.
// todo: do I need to check if the bindings are same
//
if (IS_IF_BOUND(pite)) {
Trace1(IF, "interface %d is already bound", IfIndex);
GOTO_END_BLOCK1;
}
//
// make sure there is at least one address.
//
if (AddrCount==0) {
Error = ERROR_CAN_NOT_COMPLETE;
GOTO_END_BLOCK1;
}
//
// if an effective address is already configured, make sure it
// is present in the list of address bindings
//
ConfigAddr = pite->pConfig->ConfigIpAddr;
if (ConfigAddr) {
BOOL Found = FALSE;
for (i=0; i<AddrCount; i++) {
if (ConfigAddr == pBinding->Address[i].Address) {
Found = TRUE;
break;
}
}
if (!Found) {
Trace2(ERR,
"Configured effective IP Address:%d.%d.%d.%d on interface"
":%d not part of address bindings",
PRINT_IPADDR(ConfigAddr), IfIndex);
Error = ERROR_CAN_NOT_COMPLETE;
GOTO_END_BLOCK1;
}
}
//
// allocate memory to store the binding
//
Size = AddrCount * sizeof(DVMRP_ADDR_MASK);
pAddrBinding = DVMRP_ALLOC(Size);
PROCESS_ALLOC_FAILURE3(pAddrBinding, "binding on interface %d",
Error, Size, IfIndex, GOTO_END_BLOCK1);
//
// copy the bindings
//
MinAddr = ~0;
for (i=0; i<AddrCount; i++,pAddrBinding++) {
pAddrBinding->IpAddr = pBinding->Address[i].Address;
pAddrBinding->Mask = pBinding->Address[i].Mask;
if (!ConfigAddr && (INET_CMP(MinAddr, pAddrBinding->IpAddr, cmp)>0))
MinAddr = pAddrBinding->IpAddr;
}
//
// set the Interface effective address to the smallest bound address
//
pite->IpAddr = ConfigAddr ? ConfigAddr : MinAddr;
//
// save the binding in the interface entry
//
pite->pBinding = pAddrBinding;
pite->NumAddrBound = pBinding->AddressCount;
//
// mark the interface as being bound
//
pite->Status |= IF_BOUND_FLAG;
//
// if interface is also enabled, it is now active
// so activate it
//
if (IS_IF_ENABLED_BOUND(pite)) {
//
// Activate the Interface
//
Error = ActivateInterface(pite);
//
// if could not activate the interface then undo the binding
//
if (Error != NO_ERROR) {
Trace1(ERR,
"Unbinding interface(%d) as it could not be activated",
IfIndex);
Error = ERROR_CAN_NOT_COMPLETE;
GOTO_END_BLOCK1;
}
}
} END_BREAKOUT_BLOCK1;
//
// if there was any error, then set the status to unbound (pite is null
// if interface was not found)
//
if ((Error!=NO_ERROR)&&(pite!=NULL)) {
pite->Status &= ~IF_BOUND_FLAG;
if (pite->pBinding)
DVMRP_FREE_AND_NULL(pite->pBinding);
pite->NumAddrBound = 0;
pite->IpAddr = 0;
}
RELEASE_IF_LOCK_EXCLUSIVE(IfIndex, "_BindInterface");
Trace2(LEAVE1, "leaving _BindInterface(%d): %d\n", IfIndex, Error);
return Error;
}
//-----------------------------------------------------------------------------
// _EnableInterface
//
// sets the status to enabled. If interface is also bound and enabled in
// config, then activate the interface.
//
// Locks: Exclusive IfLock
//-----------------------------------------------------------------------------
DWORD
EnableInterface(
IN DWORD IfIndex
)
{
DWORD Error = NO_ERROR;
Trace1(ENTER1, "entering _EnableInterface(%d):", IfIndex);
Trace1(IF, "enabling interface %d", IfIndex);
//
// enable the interface
//
ACQUIRE_IF_LOCK_EXCLUSIVE(IfIndex, "_EnableInterface");
Error = EnableIfEntry(IfIndex, TRUE); //enabled by RtrMgr
RELEASE_IF_LOCK_EXCLUSIVE(IfIndex, "_EnableInterface");
Trace2(LEAVE1, "leaving _EnableInterface(%d): %d\n", IfIndex, Error);
return Error;
}
//-----------------------------------------------------------------------------
// _EnableIfEntry
//-----------------------------------------------------------------------------
DWORD
EnableIfEntry(
DWORD IfIndex,
BOOL bChangedByRtrmgr // changed by rtrmg or SetInterfaceConfigInfo
)
{
DWORD Error = NO_ERROR;
PLIST_ENTRY ple, phead;
PIF_TABLE_ENTRY pite = NULL;
BEGIN_BREAKOUT_BLOCK1 {
//
// retrieve the interface
//
pite = GetIfByIndex(IfIndex);
if (pite == NULL) {
Trace1(IF, "could not find interface %d",IfIndex);
Error = ERROR_INVALID_PARAMETER;
GOTO_END_BLOCK1;
}
if (bChangedByRtrmgr) {
//
// quit if the interface is already enabled by the router manager
//
if (IS_IF_ENABLED_BY_RTRMGR(pite)) {
Trace1(IF, "interface %d is already enabled by RtrMgr",
IfIndex);
Error = NO_ERROR;
GOTO_END_BLOCK1;
}
// set the flag to enabled by router manager
pite->Status |= IF_ENABLED_FLAG;
// print trace if enabled flag not set in the Config.
if (!IS_IF_ENABLED_IN_CONFIG(pite)) {
Trace1(IF,
"Interface(%d) enabled by router manager but not enabled"
"in the Config", pite->IfIndex);
}
}
else {
//
// quit if the interface is already enabled in config
//
if (IS_IF_ENABLED_IN_CONFIG(pite)) {
Trace1(IF, "interface %d is already enabled in Config",
IfIndex);
Error = NO_ERROR;
GOTO_END_BLOCK1;
}
// set the config flag to enabled
pite->pConfig->Flags |= DVMRP_IF_ENABLED_IN_CONFIG;
// print trace if interface not enabled by router manager
if (!IS_IF_ENABLED_BY_RTRMGR(pite)) {
Trace1(IF,
"Interface(%d) enabled in config but not by RtrMgr",
IfIndex);
Error = NO_ERROR;
GOTO_END_BLOCK1;
}
}
//
// if interface is already bound, it should be activated
// if the bInterfaceEnabled flag is also set in config (by the UI)
//
if (IS_IF_ENABLED_BOUND(pite)) {
//
// Activate the Interface
//
Error = ActivateInterface(pite);
//
// if could not activate the interface then disable it again
//
if (Error != NO_ERROR) {
Trace1(ERR,
"Disabling interface(%d) as it could not be activated",
IfIndex);
Error = ERROR_CAN_NOT_COMPLETE;
GOTO_END_BLOCK1;
}
}
} END_BREAKOUT_BLOCK1;
//
// if an error occured somewhere, set the interface back to the previous
// disabled state.(pite may be null if interface was not found).
//
if ((Error!=NO_ERROR)&&(pite!=NULL)) {
if (bChangedByRtrmgr)
pite->Status &= ~IF_ENABLED_FLAG;
else
pite->pConfig->Flags &= DVMRP_IF_ENABLED_IN_CONFIG;
}
return Error;
}//end _EnableIfEntry
//-----------------------------------------------------------------------------
// _DisableInterface
//
// If interface is activated, then deactivates it.
// Locks: Runs completely in exclusive interface lock.
// Calls: _DisableIfEntry()
//-----------------------------------------------------------------------------
DWORD
DisableInterface(
IN DWORD IfIndex
)
{
DWORD Error;
Trace1(ENTER, "entering DisableInterface(%d):", IfIndex);
//
// disable the interface
//
ACQUIRE_IF_LOCK_EXCLUSIVE(IfIndex, "_DisableInterface");
Error = DisableIfEntry(IfIndex, TRUE); //disabled by RtrMgr
RELEASE_IF_LOCK_EXCLUSIVE(IfIndex, "_DisableInterface");
Trace2(LEAVE, "leaving DisableInterface(%d): %d\n", IfIndex, Error);
return Error;
}
//-----------------------------------------------------------------------------
// _DisableIfEntry
//
// Called by: _DisableInterface()
//-----------------------------------------------------------------------------
DWORD
DisableIfEntry(
DWORD IfIndex,
BOOL bChangedByRtrmgr
)
{
DWORD Error = NO_ERROR;
PIF_TABLE_ENTRY pite, piteNew;
BOOL bProxy;
BEGIN_BREAKOUT_BLOCK1 {
//
// retrieve the interface to be disabled
//
pite = GetIfByIndex(IfIndex);
if (pite == NULL) {
Trace1(IF, "could not find interface %d", IfIndex);
Error = ERROR_INVALID_PARAMETER;
GOTO_END_BLOCK1;
}
if (bChangedByRtrmgr) {
//
// quit if already disabled by router manager
//
if (!IS_IF_ENABLED_BY_RTRMGR(pite)) {
Trace1(IF, "interface %d already disabled by router manager",
IfIndex);
Error = ERROR_INVALID_PARAMETER;
GOTO_END_BLOCK1;
}
}
else {
//
// quit if already disabled in Config
//
if (!IS_IF_ENABLED_IN_CONFIG(pite)) {
Trace1(IF, "interface %d already disabled in config",
IfIndex);
Error = ERROR_INVALID_PARAMETER;
GOTO_END_BLOCK1;
}
}
//
// if IF activated (ie also enabled), deactivate it
// note: check for activated flag, and not for enabled flag
//
if (IS_IF_ACTIVATED(pite)) {
DeactivateInterface(pite);
}
//
// clear the enabled flag
//
if (bChangedByRtrmgr)
pite->Status &= ~IF_ENABLED_FLAG;
else
pite->pConfig->Flags &= ~DVMRP_IF_ENABLED_IN_CONFIG;
} END_BREAKOUT_BLOCK1;
return Error;
} //end _DisableIfEntry
//-----------------------------------------------------------------------------
// _CreateIfSockets
//-----------------------------------------------------------------------------
DWORD
CreateIfSockets(
PIF_TABLE_ENTRY pite
)
{
DWORD Error = NO_ERROR;
DWORD Retval, SockType;
DWORD IpAddr = pite->IpAddr;
DWORD IfIndex = pite->IfIndex;
SOCKADDR_IN saLocalIf;
BEGIN_BREAKOUT_BLOCK1 {
//
// create input socket
//
pite->Socket = WSASocket(AF_INET, SOCK_RAW, IPPROTO_IGMP, NULL, 0, 0);
if (pite->Socket == INVALID_SOCKET) {
LPSTR lpszAddr;
Error = WSAGetLastError();
lpszAddr = INET_NTOA(IpAddr);
Trace3(IF,
"error %d creating socket for interface %d (%d.%d.%d.%d)",
Error, IfIndex, PRINT_IPADDR(IpAddr));
Logerr1(CREATE_SOCKET_FAILED_2, "%S", lpszAddr, Error);
GOTO_END_BLOCK1;
}
//
// bind socket to local interface. If I dont bind multicast may
// not work.
//
ZeroMemory(&saLocalIf, sizeof(saLocalIf));
saLocalIf.sin_family = PF_INET;
saLocalIf.sin_addr.s_addr = IpAddr;
saLocalIf.sin_port = 0; //port shouldnt matter
// bind the input socket
Error = bind(pite->Socket, (SOCKADDR FAR *)&saLocalIf,
sizeof(SOCKADDR));
if (Error == SOCKET_ERROR) {
LPSTR lpszAddr;
Error = WSAGetLastError();
lpszAddr = INET_NTOA(IpAddr);
Trace3(IF, "error %d binding on socket for interface %d (%d.%d.%d.%d)",
Error, IfIndex, PRINT_IPADDR(IpAddr));
Logerr1(BIND_FAILED, "S", lpszAddr, Error);
GOTO_END_BLOCK1;
}
// set ttl to 1: not required as it is set to 1 by default.
McastSetTtl(pite->Socket, 1);
//
// disable multicast packets from being loopedback.
//
{
BOOL bLoopBack = FALSE;
DWORD Retval;
Retval = setsockopt(pite->Socket, IPPROTO_IP, IP_MULTICAST_LOOP,
(char *)&bLoopBack, sizeof(BOOL));
if (Retval==SOCKET_ERROR) {
Trace2(ERR, "error %d disabling multicast loopBack on IfIndex %d",
WSAGetLastError(), IfIndex);
}
}
//
// set the interface on which multicasts must be sent
//
Retval = setsockopt(pite->Socket, IPPROTO_IP, IP_MULTICAST_IF,
(PBYTE)&saLocalIf.sin_addr, sizeof(IN_ADDR));
if (Retval == SOCKET_ERROR) {
LPSTR lpszAddr;
Error = WSAGetLastError();
lpszAddr = INET_NTOA(pite->IpAddr);
Trace3(IF, "error %d setting interface %d (%s) to send multicast",
Error, IfIndex, lpszAddr);
Logerr1(SET_MCAST_IF_FAILED, "%S", lpszAddr, Error);
Error = Retval;
GOTO_END_BLOCK1;
}
//
// join dvmrp multicast group
//
JoinMulticastGroup(pite->Socket, ALL_DVMRP_ROUTERS_MCAST_GROUP,
pite->IfIndex, pite->IpAddr);
// bind socket to io completion port
BindIoCompletionCallback((HANDLE)pite->Socket,
ProcessAsyncReceivePacket, 0);
// increment refcount corresponding to the pending IO requests
pite->RefCount++;
// post async Read request
#if 0
// kslksl
PostAsyncRead(pite);
#endif
} END_BREAKOUT_BLOCK1;
if (Error!=NO_ERROR)
DeleteIfSockets(pite);
return Error;
} //end _CreateIfSockets
VOID
DeleteIfSockets(
PIF_TABLE_ENTRY pite
)
{
return;
}
//-----------------------------------------------------------------------------
// _ActivateInterface
//
// an interface is activated: when it is bound, enabled by RtrMgr & in config
// When activated,
// (1) call is made to MGM to take interface ownership,
// (2) timers set and input socket is activated.
//
// Called by: _BindIfEntry, _EnableIfEntry,
//-----------------------------------------------------------------------------
DWORD
ActivateInterface(
PIF_TABLE_ENTRY pite
)
{
DWORD Error = NO_ERROR, IfIndex = pite->IfIndex;
LONGLONG CurTime = GetCurrentDvmrpTime();
Trace2(ENTER, "entering ActivateInterface(%d:%d.%d.%d.%d)",
IfIndex, PRINT_IPADDR(pite->IpAddr));
BEGIN_BREAKOUT_BLOCK1 {
//
// set time when it is activated
//
pite->pInfo->TimeWhenActivated = CurTime;
//
// create sockets for interface
//
Error = CreateIfSockets(pite);
if (Error != NO_ERROR) {
Trace2(IF, "error %d initializing sockets for interface %d",
Error, pite->IfIndex);
GOTO_END_BLOCK1;
}
pite->CreationFlags |= IF_FLAGS_SOCKETS_CREATED;
//
// register the protocol with mgm if it is the first active IF
//
if (!G_pIfTable->NumActiveIfs++) {
Error = RegisterDvmrpWithMgm();
if (Error!=NO_ERROR) {
G_pIfTable->NumActiveIfs--;
GOTO_END_BLOCK1;
}
}
pite->CreationFlags |= IF_FLAGS_PROTO_REGISTERED_WITH_MGM;
//
// take interface ownership with MGM
//
Error = MgmTakeInterfaceOwnership(Globals.MgmDvmrpHandle, IfIndex, 0);
if (Error!=NO_ERROR) {
Trace1(MGM, "MgmTakeInterfaceOwnership rejected for interface %d",
IfIndex);
Logerr0(MGM_TAKE_IF_OWNERSHIP_FAILED, Error);
GOTO_END_BLOCK1;
}
else {
Trace1(MGM,
"MgmTakeInterfaceOwnership successful for interface %d",
IfIndex);
}
pite->CreationFlags |= IF_FLAGS_IF_REGISTERED_WITH_MGM;
//
// dvmrp does a (*,*) join
//
Error = MgmAddGroupMembershipEntry(Globals.MgmDvmrpHandle, 0, 0, 0, 0,
IfIndex, 0);
if (Error!=NO_ERROR) {
Trace1(ERR,
"Dvmrp failed to add *,* entry to MGM on interface %d",
IfIndex);
GOTO_END_BLOCK1;
}
Trace0(MGM, "Dvmrp added *,* entry to MGM");
//
// create required timers
//
} END_BREAKOUT_BLOCK1;
//
// if error, deactivate interface
//
if (Error!=NO_ERROR) {
DeactivateInterface(pite);
pite->Status &= ~IF_ACTIVATED_FLAG;
}
else {
//
// set interface status to activated
//
pite->Status |= IF_ACTIVATED_FLAG;
}
Trace1(LEAVE, "leaving ActivateInterface():%d\n", Error);
return Error;
} //end _ActivateInterface
DWORD
DeactivateInterface(
PIF_TABLE_ENTRY pite
)
{
DWORD Error;
// zero info
Error = NO_ERROR;
return Error;
}
//-----------------------------------------------------------------------------
// UnBindInterface
//-----------------------------------------------------------------------------
DWORD
UnBindInterface(
IN DWORD IfIndex
)
{
DWORD Error;
PIF_TABLE_ENTRY pite, piteNew;
Trace1(ENTER, "entering UnBindInterface(%d):", IfIndex);
//
// unbind the interface
//
//
// acquire exclusive interface lock
//
ACQUIRE_IF_LOCK_EXCLUSIVE(IfIndex, "_UnBindInterface");
BEGIN_BREAKOUT_BLOCK1 {
//
// retrieve the interface specified
//
pite = GetIfByIndex(IfIndex);
if (pite == NULL) {
Trace1(ERR, "UnbindInterface called for non existing If(%d)",
IfIndex);
Error = ERROR_INVALID_PARAMETER;
GOTO_END_BLOCK1;
}
//
// quit if the interface is already unbound
//
if (!IS_IF_BOUND(pite)) {
Error = ERROR_INVALID_PARAMETER;
Trace1(ERR, "interface %d is already unbound", IfIndex);
GOTO_END_BLOCK1;
}
//
// clear the "bound" flag
//
pite->Status &= ~IF_BOUND_FLAG;
//
// if IF activated (ie also enabled), deactivate it
// note: check for activated flag, and not for enabled flag
//
if (IS_IF_ACTIVATED(pite)) {
DeactivateInterface(pite);
}
//
// unbind IF
//
DVMRP_FREE_AND_NULL(pite->pBinding);
pite->NumAddrBound = 0;
pite->IpAddr = 0;
} END_BREAKOUT_BLOCK1;
RELEASE_IF_LOCK_EXCLUSIVE(IfIndex, "_UnBindInterface");
Trace2(LEAVE, "leaving UnBindInterface(%d): %d\n", IfIndex, Error);
return Error;
}
//----------------------------------------------------------------------------
// _SetInterfaceConfigInfo
//----------------------------------------------------------------------------
DWORD
WINAPI
SetInterfaceConfigInfo(
IN DWORD IfIndex,
IN PVOID pvConfig,
IN ULONG ulStructureVersion,
IN ULONG ulStructureSize,
IN ULONG ulStructureCount
)
{
DWORD Error = NO_ERROR;
return Error;
}
//----------------------------------------------------------------------------
// _GetInterfaceConfigInfo
//----------------------------------------------------------------------------
DWORD
WINAPI
GetInterfaceConfigInfo(
IN DWORD IfIndex,
IN OUT PVOID pvConfig,
IN OUT PDWORD pdwSize,
IN OUT PULONG pulStructureVersion,
IN OUT PULONG pulStructureSize,
IN OUT PULONG pulStructureCount
)
{
DWORD Error = NO_ERROR;
return Error;
}
//----------------------------------------------------------------------------
// _ValidateIfConfig
//----------------------------------------------------------------------------
DWORD
ValidateIfConfig(
ULONG IfIndex,
PDVMRP_IF_CONFIG pIfConfig,
ULONG StructureSize
)
{
//
// check IfConfig size
//
if (StructureSize < sizeof(DVMRP_IF_CONFIG)
|| (StructureSize != DVMRP_IF_CONFIG_SIZE(pIfConfig))
){
Trace1(ERR, "Dvmrp config structure for interface:%d too small.\n",
IfIndex);
return ERROR_INVALID_DATA;
}
DebugPrintIfConfig(IfIndex, pIfConfig);
//
// check Probe Interval
//
if (pIfConfig->ProbeInterval != DVMRP_PROBE_INTERVAL) {
Trace2(CONFIG,
"ProbeInterval being set to %d. Suggested value:%d",
pIfConfig->ProbeInterval, DVMRP_PROBE_INTERVAL);
}
if (pIfConfig->ProbeInterval < 1000) {
Trace2(ERR,
"ProbeInterval has very low value:%d, suggested:%d",
pIfConfig->ProbeInterval, DVMRP_PROBE_INTERVAL);
return ERROR_INVALID_DATA;
}
//
// check Peer timeout interval
//
if (pIfConfig->PeerTimeoutInterval != PEER_TIMEOUT_INTERVAL) {
Trace2(CONFIG,
"PeerTimeoutInterval being set to %d. Suggested value:%d",
pIfConfig->PeerTimeoutInterval, PEER_TIMEOUT_INTERVAL);
}
if (pIfConfig->PeerTimeoutInterval < 1000) {
Trace2(ERR,
"PeerTimeoutInterval has very low value:%d, suggested:%d",
pIfConfig->PeerTimeoutInterval, PEER_TIMEOUT_INTERVAL);
return ERROR_INVALID_DATA;
}
//
// check MinTriggeredUpdateInterval
//
if (pIfConfig->MinTriggeredUpdateInterval
!= MIN_TRIGGERED_UPDATE_INTERVAL
) {
Trace2(CONFIG,
"MinTriggeredUpdateInterval being set to %d. Suggested value:%d",
pIfConfig->MinTriggeredUpdateInterval,
MIN_TRIGGERED_UPDATE_INTERVAL);
}
//
// check PeerFilterMode
//
switch(pIfConfig->PeerFilterMode) {
case DVMRP_FILTER_DISABLED:
case DVMRP_FILTER_INCLUDE:
case DVMRP_FILTER_EXCLUDE:
{
break;
}
default:
{
Trace2(ERR, "Invalid value:%d for PeerFilterMode on Interface:%d",
pIfConfig->PeerFilterMode, IfIndex);
return ERROR_INVALID_DATA;
}
}
} //end _ValidateIfConfig