|
|
//=============================================================================
// 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
|