407 lines
9.3 KiB
C
407 lines
9.3 KiB
C
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
init.c
|
|
|
|
Abstract:
|
|
|
|
Some router initialization functions
|
|
|
|
Author:
|
|
|
|
Stefan Solomon 05/10/1995
|
|
|
|
Revision History:
|
|
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
//*******************************************************************
|
|
//* *
|
|
//* IPXCP Interface Functions *
|
|
//* *
|
|
//*******************************************************************
|
|
|
|
|
|
#define IPXCP_INITIALIZE_ENTRY_POINT "IpxCpInit"
|
|
#define IPXCP_CLEANUP_ENTRY_POINT IPXCP_INITIALIZE_ENTRY_POINT
|
|
|
|
typedef DWORD (* IpxcpInitFunPtr)(BOOL);
|
|
typedef DWORD (* IpxcpCleanupFunPtr)(BOOL);
|
|
|
|
|
|
// Initializes IpxCp so that it can be used. Assumes the IpxCp
|
|
DWORD InitializeIpxCp (HINSTANCE hInstDll) {
|
|
IpxcpInitFunPtr pfnInit;
|
|
DWORD dwErr;
|
|
|
|
pfnInit = (IpxcpInitFunPtr)GetProcAddress(hInstDll, IPXCP_INITIALIZE_ENTRY_POINT);
|
|
if (!pfnInit)
|
|
return ERROR_CAN_NOT_COMPLETE;
|
|
|
|
if ((dwErr = (*pfnInit)(TRUE)) != NO_ERROR)
|
|
return dwErr;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
// Cleansup the initialization of ipxcp that occurred when the
|
|
// program loaded.
|
|
DWORD CleanupIpxCp (HINSTANCE hInstDll) {
|
|
IpxcpCleanupFunPtr pfnCleanup;
|
|
DWORD dwErr;
|
|
|
|
pfnCleanup = (IpxcpCleanupFunPtr)GetProcAddress(hInstDll, IPXCP_CLEANUP_ENTRY_POINT);
|
|
if (!pfnCleanup)
|
|
return ERROR_CAN_NOT_COMPLETE;
|
|
|
|
if ((dwErr = (*pfnCleanup)(FALSE)) != NO_ERROR)
|
|
return dwErr;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/*++
|
|
|
|
Function: RmCreateGlobalRoute
|
|
|
|
Descr: called by ipxcp to create the global wan net if so configured
|
|
|
|
--*/
|
|
|
|
DWORD
|
|
RmCreateGlobalRoute(PUCHAR Network)
|
|
{
|
|
DWORD rc;
|
|
|
|
Trace(IPXCPIF_TRACE, "RmCreateGlobalRoute: Entered for 0x%x%x%x%x%x%x (%x)",
|
|
Network[0], Network[1], Network[2], Network[3], Network[4], Network[5],
|
|
WanNetDatabaseInitialized);
|
|
|
|
ACQUIRE_DATABASE_LOCK;
|
|
|
|
if((RouterOperState != OPER_STATE_UP) || LanOnlyMode) {
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
return ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
|
|
// In NT5 we allow changing the global route on the
|
|
// fly although it will only happen when there are
|
|
// no WAN connections active.
|
|
//
|
|
// SS_ASSERT(WanNetDatabaseInitialized == FALSE);
|
|
//
|
|
if (WanNetDatabaseInitialized == TRUE) {
|
|
DeleteGlobalRoute(GlobalWanNet);
|
|
}
|
|
|
|
WanNetDatabaseInitialized = TRUE;
|
|
|
|
if((rc = CreateGlobalRoute(Network)) != NO_ERROR) {
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
return rc;
|
|
}
|
|
|
|
EnableGlobalWanNet = TRUE;
|
|
memcpy(GlobalWanNet, Network, 4);
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Function: AllLocalWkstaDialoutInterface
|
|
|
|
Descr: called by ipxcp to add an interface for the case when the
|
|
host dials out. This interface type is not handled by DIM
|
|
|
|
--*/
|
|
|
|
|
|
DWORD
|
|
RmAddLocalWkstaDialoutInterface(
|
|
IN LPWSTR InterfaceNamep,
|
|
IN LPVOID InterfaceInfop,
|
|
IN OUT PULONG InterfaceIndexp)
|
|
{
|
|
PICB icbp;
|
|
ULONG InterfaceNameLen; // if name length in bytes including wchar NULL
|
|
PIPX_IF_INFO IpxIfInfop;
|
|
PIPXWAN_IF_INFO IpxwanIfInfop;
|
|
PIPX_INFO_BLOCK_HEADER IfInfop = (PIPX_INFO_BLOCK_HEADER)InterfaceInfop;
|
|
PACB acbp;
|
|
PIPX_TOC_ENTRY tocep;
|
|
UINT i;
|
|
ULONG tmp;
|
|
FW_IF_INFO FwIfInfo;
|
|
|
|
Trace(IPXCPIF_TRACE, "AddLocalWkstaDialoutInterface: Entered for interface %S\n", InterfaceNamep);
|
|
|
|
// interface name length including the unicode null
|
|
InterfaceNameLen = (wcslen(InterfaceNamep) + 1) * sizeof(WCHAR);
|
|
|
|
ACQUIRE_DATABASE_LOCK;
|
|
|
|
if((RouterOperState != OPER_STATE_UP) || LanOnlyMode) {
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
return ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
|
|
// Allocate a new ICB and initialize it
|
|
// we allocate the interface and adapter name buffers at the end of the
|
|
// ICB struct.
|
|
if((icbp = (PICB)GlobalAlloc(GPTR,
|
|
sizeof(ICB) +
|
|
InterfaceNameLen)) == NULL) {
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
|
|
// can't alloc memory
|
|
SS_ASSERT(FALSE);
|
|
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
// signature
|
|
memcpy(&icbp->Signature, InterfaceSignature, 4);
|
|
|
|
icbp->InterfaceIndex = GetNextInterfaceIndex();
|
|
|
|
// copy the interface name
|
|
icbp->InterfaceNamep = (PWSTR)((PUCHAR)icbp + sizeof(ICB));
|
|
memcpy(icbp->InterfaceNamep, InterfaceNamep, InterfaceNameLen);
|
|
|
|
icbp->AdapterNamep = NULL;
|
|
icbp->PacketType = 0;
|
|
|
|
// set the DIM interface type of this ICB
|
|
icbp->DIMInterfaceType = 0xFFFFFFFF;
|
|
|
|
// set the MIB interface type of this ICB
|
|
icbp->MIBInterfaceType = IF_TYPE_ROUTER_WORKSTATION_DIALOUT;
|
|
|
|
// mark the interface as unbound to an adapter (default)
|
|
icbp->acbp = NULL;
|
|
|
|
// get the if handle used when calling DIM entry points
|
|
icbp->hDIMInterface = INVALID_HANDLE_VALUE;
|
|
|
|
// reset the update status fields
|
|
ResetUpdateRequest(icbp);
|
|
|
|
// mark connection not requested yet
|
|
icbp->ConnectionRequestPending = FALSE;
|
|
|
|
// get to the interface entries in the interface info block
|
|
if(((IpxIfInfop = (PIPX_IF_INFO)GetInfoEntry(InterfaceInfop, IPX_INTERFACE_INFO_TYPE)) == NULL) ||
|
|
((IpxwanIfInfop = (PIPXWAN_IF_INFO)GetInfoEntry(InterfaceInfop, IPXWAN_INTERFACE_INFO_TYPE)) == NULL)) {
|
|
|
|
GlobalFree(icbp);
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
|
|
IF_LOG (EVENTLOG_ERROR_TYPE) {
|
|
RouterLogErrorDataW (RMEventLogHdl,
|
|
ROUTERLOG_IPX_BAD_CLIENT_INTERFACE_CONFIG,
|
|
0, NULL, 0, NULL);
|
|
}
|
|
// don't have all ipx or ipxwan interfaces info
|
|
Trace(IPXCPIF_TRACE, "AddInterface: missing ipx or ipxwan interface info\n");
|
|
|
|
SS_ASSERT(FALSE);
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
// set the IPXWAN interface info
|
|
icbp->EnableIpxWanNegotiation = IpxwanIfInfop->AdminState;
|
|
|
|
// Initialize the Oper State of this interface.
|
|
icbp->OperState = OPER_STATE_DOWN;
|
|
|
|
// this is a WAN interface. As long as it isn't connected, and enabled the
|
|
// oper state will be sleeping on this interface
|
|
if(IpxIfInfop->AdminState == ADMIN_STATE_ENABLED)
|
|
icbp->OperState = OPER_STATE_SLEEPING;
|
|
|
|
// create the routing protocols (rip/sap or nlsp) interface info
|
|
// insert the if in the index hash table
|
|
AddIfToDB(icbp);
|
|
|
|
// If the routing protocols interface info is missing this will fail
|
|
if(CreateRoutingProtocolsInterfaces(InterfaceInfop, icbp) != NO_ERROR) {
|
|
|
|
RemoveIfFromDB(icbp);
|
|
GlobalFree(icbp);
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
|
|
IF_LOG (EVENTLOG_ERROR_TYPE) {
|
|
RouterLogErrorDataW (RMEventLogHdl,
|
|
ROUTERLOG_IPX_BAD_CLIENT_INTERFACE_CONFIG,
|
|
0, NULL, 0, NULL);
|
|
}
|
|
// don't have all rip and sap interfaces info
|
|
Trace(IPXCPIF_TRACE, "AddInterface: missing routing protocols interface info\n");
|
|
|
|
SS_ASSERT(FALSE);
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
// create the Forwarder interface
|
|
FwIfInfo.NetbiosAccept = IpxIfInfop->NetbiosAccept;
|
|
FwIfInfo.NetbiosDeliver = IpxIfInfop->NetbiosDeliver;
|
|
FwCreateInterface(icbp->InterfaceIndex,
|
|
LOCAL_WORKSTATION_DIAL,
|
|
&FwIfInfo);
|
|
|
|
// mark the interface reachable
|
|
icbp->InterfaceReachable = TRUE;
|
|
|
|
// set the admin state
|
|
if(IpxIfInfop->AdminState == ADMIN_STATE_ENABLED) {
|
|
|
|
AdminEnable(icbp);
|
|
}
|
|
else
|
|
{
|
|
AdminDisable(icbp);
|
|
}
|
|
|
|
// increment the interface counter
|
|
InterfaceCount++;
|
|
|
|
*InterfaceIndexp = icbp->InterfaceIndex;
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
DWORD
|
|
RmDeleteLocalWkstaDialoutInterface(ULONG InterfaceIndex)
|
|
{
|
|
return(DeleteInterface((HANDLE)UlongToPtr(InterfaceIndex)));
|
|
}
|
|
|
|
DWORD
|
|
RmGetIpxwanInterfaceConfig(ULONG InterfaceIndex,
|
|
PULONG IpxwanConfigRequired)
|
|
{
|
|
PICB icbp;
|
|
|
|
ACQUIRE_DATABASE_LOCK;
|
|
|
|
if((RouterOperState != OPER_STATE_UP) || LanOnlyMode) {
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
return ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
|
|
if((icbp = GetInterfaceByIndex(InterfaceIndex)) == NULL) {
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
return ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
|
|
if(icbp->EnableIpxWanNegotiation == ADMIN_STATE_ENABLED) {
|
|
|
|
*IpxwanConfigRequired = 1;
|
|
}
|
|
else
|
|
{
|
|
*IpxwanConfigRequired = 0;
|
|
}
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
BOOL
|
|
RmIsRoute(PUCHAR Network)
|
|
{
|
|
BOOL rc;
|
|
|
|
ACQUIRE_DATABASE_LOCK;
|
|
|
|
if((RouterOperState != OPER_STATE_UP) || LanOnlyMode) {
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
return FALSE;
|
|
}
|
|
|
|
rc = IsRoute(Network);
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
|
|
return rc;
|
|
}
|
|
|
|
DWORD
|
|
RmGetInternalNetNumber(PUCHAR Network)
|
|
{
|
|
PACB acbp;
|
|
|
|
ACQUIRE_DATABASE_LOCK;
|
|
|
|
if((RouterOperState != OPER_STATE_UP) || LanOnlyMode) {
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
return ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
|
|
if(InternalInterfacep) {
|
|
|
|
if(acbp = InternalInterfacep->acbp) {
|
|
|
|
memcpy(Network, acbp->AdapterInfo.Network, 4);
|
|
RELEASE_DATABASE_LOCK;
|
|
return NO_ERROR;
|
|
}
|
|
}
|
|
|
|
RELEASE_DATABASE_LOCK;
|
|
|
|
return ERROR_CAN_NOT_COMPLETE;
|
|
}
|
|
|
|
//
|
|
// This is a function added for pnp reasons so that the
|
|
// ipx-related ras server settings could be updated.
|
|
//
|
|
DWORD RmUpdateIpxcpConfig (PIPXCP_ROUTER_CONFIG_PARAMS pParams) {
|
|
DWORD dwErr;
|
|
|
|
// Validate parameters
|
|
if (! pParams)
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
// Trace out the new settings
|
|
Trace(IPXCPIF_TRACE, "RmUpdateIpxcpConfig: entered: %x %x %x %x",
|
|
pParams->ThisMachineOnly, pParams->WanNetDatabaseInitialized,
|
|
pParams->EnableGlobalWanNet, *((DWORD*)pParams->GlobalWanNet));
|
|
|
|
// Update the forwarder's ThisMachineOnly setting
|
|
if ((dwErr = FwUpdateConfig(pParams->ThisMachineOnly)) != NO_ERROR)
|
|
return dwErr;
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
|