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