diff options
Diffstat (limited to '')
-rw-r--r-- | private/ntos/tdi/isn/fwd/lineind.c | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/private/ntos/tdi/isn/fwd/lineind.c b/private/ntos/tdi/isn/fwd/lineind.c new file mode 100644 index 000000000..e00518d6a --- /dev/null +++ b/private/ntos/tdi/isn/fwd/lineind.c @@ -0,0 +1,323 @@ +/*++ + +Copyright (c) 1995 Microsoft Corporation + +Module Name: + + ntos\tdi\isn\fwd\lineind.c + +Abstract: + Processing line indication (bind/unbind) + + +Author: + + Vadim Eydelman + +Revision History: + +--*/ + +#include "precomp.h" + + +/*++ +******************************************************************* + B i n d I n t e r f a c e + +Routine Description: + Binds interface to physical adapter and exchanges contexts + with IPX stack +Arguments: + ifCB - interface to bind + NicId - id of an adapter + MaxPacketSize - max size of packet allowed + Network - adapter network address + LocalNode - adapter local node address + RemoteNode - peer node address (for clients on global + net) +Return Value: + STATUS_SUCCESS - interface was bound OK + error status returned by IPX stack driver + +******************************************************************* +--*/ +NTSTATUS +BindInterface ( + IN PINTERFACE_CB ifCB, + IN USHORT NicId, + IN ULONG MaxPacketSize, + IN ULONG Network, + IN PUCHAR LocalNode, + IN PUCHAR RemoteNode + ) { + KIRQL oldIRQL; + NTSTATUS status; + NIC_HANDLE NicHandle={0}; + + KeAcquireSpinLock (&ifCB->ICB_Lock, &oldIRQL); + if (ifCB->ICB_Stats.OperationalState!=FWD_OPER_STATE_UP) { + switch (ifCB->ICB_InterfaceType) { + case FWD_IF_PERMANENT: + if (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX) + status = RegisterPacketConsumer (MaxPacketSize, + &ifCB->ICB_PacketListId); + else + status = STATUS_SUCCESS; + break; + case FWD_IF_DEMAND_DIAL: + case FWD_IF_LOCAL_WORKSTATION: + case FWD_IF_REMOTE_WORKSTATION: + if (IS_IF_CONNECTING (ifCB)) { + SET_IF_NOT_CONNECTING (ifCB); + DequeueConnectionRequest (ifCB); + } + status = STATUS_SUCCESS; + break; + default: + ASSERTMSG ("Invalid interface type ", FALSE); + break; + } + if (NT_SUCCESS (status)) { + if (Network==GlobalNetwork) { + ASSERT (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX); + IPX_NODE_CPY (ifCB->ICB_RemoteNode, RemoteNode); + status = AddGlobalNetClient (ifCB); + ASSERT (status==STATUS_SUCCESS); + } + KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL); + + if (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX) { + NIC_HANDLE_FROM_NIC(NicHandle, NicId); + status = IPXOpenAdapterProc (NicHandle, (ULONG)ifCB, + &ifCB->ICB_AdapterContext); + } + + if (NT_SUCCESS (status)) { + ifCB->ICB_Network = Network; + IPX_NODE_CPY (ifCB->ICB_RemoteNode, RemoteNode); + IPX_NODE_CPY (ifCB->ICB_LocalNode, LocalNode); + if (ifCB->ICB_InterfaceType==FWD_IF_PERMANENT) + ifCB->ICB_Stats.MaxPacketSize = MaxPacketSize; + else + ifCB->ICB_Stats.MaxPacketSize = WAN_PACKET_SIZE; + ifCB->ICB_NicId = NicId; + ifCB->ICB_Stats.OperationalState = FWD_OPER_STATE_UP; + + AcquireInterfaceReference (ifCB); + IpxFwdDbgPrint (DBG_LINEIND, DBG_INFORMATION, + ("IpxFwd: Bound interface %ld (icb: %08lx):" + " Nic-%d, Net-%08lx," + " LocalNode-%02x%02x%02x%02x%02x%02x," + " RemoteNode-%02x%02x%02x%02x%02x%02x.\n", + ifCB->ICB_Index, ifCB, NicId, Network, + LocalNode[0], LocalNode[1], LocalNode[2], + LocalNode[3], LocalNode[4], LocalNode[5], + RemoteNode[0], RemoteNode[1], RemoteNode[2], + RemoteNode[3], RemoteNode[4], RemoteNode[5])); + + if (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX) { + ProcessInternalQueue (ifCB); + ProcessExternalQueue (ifCB); + } + return STATUS_SUCCESS; + } + + IpxFwdDbgPrint (DBG_LINEIND, DBG_ERROR, + ("IpxFwd: Could not open adapter %d to bind" + " interface %ld (icb: %08lx)!\n", + NicId, ifCB->ICB_Index, ifCB)); + + KeAcquireSpinLock (&ifCB->ICB_Lock, &oldIRQL); + if (Network==GlobalNetwork) { + DeleteGlobalNetClient (ifCB); + } + + switch (ifCB->ICB_InterfaceType) { + case FWD_IF_PERMANENT: + DeregisterPacketConsumer (ifCB->ICB_PacketListId); + break; + case FWD_IF_DEMAND_DIAL: + case FWD_IF_LOCAL_WORKSTATION: + case FWD_IF_REMOTE_WORKSTATION: + break; + } + } + ifCB->ICB_Stats.OperationalState = FWD_OPER_STATE_DOWN; + KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL); + + ProcessInternalQueue (ifCB); + ProcessExternalQueue (ifCB); + } + else { + ASSERT (Network==ifCB->ICB_Network); + ASSERT (NicId==(USHORT)ifCB->ICB_AdapterContext.NicId); + KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL); + status = STATUS_SUCCESS; // Report success if already + // connected + IpxFwdDbgPrint (DBG_LINEIND, DBG_WARNING, + ("IpxFwd: Interface %ld (icb: %08lx) is already bound to Nic %d.\n", + ifCB->ICB_Index, ifCB, NicId)); + } + return status; +} + + +/*++ +******************************************************************* + U n b i n d I n t e r f a c e + +Routine Description: + Unbinds interface from physical adapter and breaks connection + with IPX stack +Arguments: + ifCB - interface to unbind +Return Value: + None +******************************************************************* +--*/ +VOID +UnbindInterface ( + PINTERFACE_CB ifCB + ) { + KIRQL oldIRQL; + KeAcquireSpinLock (&ifCB->ICB_Lock, &oldIRQL); + if (ifCB->ICB_Stats.OperationalState==FWD_OPER_STATE_UP) { + switch (ifCB->ICB_InterfaceType) { + case FWD_IF_PERMANENT: + ifCB->ICB_Stats.OperationalState = FWD_OPER_STATE_DOWN; + if (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX) + DeregisterPacketConsumer (ifCB->ICB_PacketListId); + break; + case FWD_IF_DEMAND_DIAL: + case FWD_IF_LOCAL_WORKSTATION: + case FWD_IF_REMOTE_WORKSTATION: + ifCB->ICB_Stats.OperationalState = FWD_OPER_STATE_SLEEPING; + KeQuerySystemTime ((PLARGE_INTEGER)&ifCB->ICB_DisconnectTime); + break; + default: + ASSERTMSG ("Invalid interface type ", FALSE); + break; + } + if (ifCB->ICB_CashedInterface!=NULL) + ReleaseInterfaceReference (ifCB->ICB_CashedInterface); + ifCB->ICB_CashedInterface = NULL; + if (ifCB->ICB_CashedRoute!=NULL) + ReleaseRouteReference (ifCB->ICB_CashedRoute); + ifCB->ICB_CashedRoute = NULL; + if (ifCB->ICB_Network==GlobalNetwork) + DeleteGlobalNetClient (ifCB); + KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL); + + IpxFwdDbgPrint (DBG_LINEIND, DBG_INFORMATION, + ("IpxFwd: Unbinding interface %ld (icb: %08lx) from Nic %ld.\n", + ifCB->ICB_Index, ifCB, ifCB->ICB_AdapterContext)); + if (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX) { + IPXCloseAdapterProc (ifCB->ICB_AdapterContext); + ProcessInternalQueue (ifCB); + ProcessExternalQueue (ifCB); + } + ReleaseInterfaceReference (ifCB); + } + else { + KeReleaseSpinLock (&ifCB->ICB_Lock, oldIRQL); + IpxFwdDbgPrint (DBG_LINEIND, DBG_WARNING, + ("IpxFwd: Interface %ld (icb: %08lx) is already unbound.\n", + ifCB->ICB_Index, ifCB)); + } +} + + + +/*++ +******************************************************************* + F w L i n e U p + +Routine Description: + Process line up indication delivered by IPX stack +Arguments: + NicId - adapter ID on which connection was established + LineInfo - NDIS/IPX line information + DeviceType - medium specs + ConfigurationData - IPX CP configuration data +Return Value: + None + +******************************************************************* +--*/ +VOID +IpxFwdLineUp ( + IN USHORT NicId, + IN PIPX_LINE_INFO LineInfo, + IN NDIS_MEDIUM DeviceType, + IN PVOID ConfigurationData + ) { + PINTERFACE_CB ifCB; + if (ConfigurationData==NULL) // This is just an update for multilink + // connections + return; + + if (!EnterForwarder()) { + return; + } + IpxFwdDbgPrint (DBG_LINEIND, DBG_INFORMATION, ("IpxFwd: FwdLineUp.\n")); + + ifCB = GetInterfaceReference ( + ((PIPXCP_CONFIGURATION)ConfigurationData)->InterfaceIndex); + if (ifCB!=NULL) { + LONG Net = GETULONG (((PIPXCP_CONFIGURATION)ConfigurationData)->Network); + + ASSERT (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX); + ASSERT (ifCB->ICB_InterfaceType!=FWD_IF_PERMANENT); + + BindInterface (ifCB, + NicId, + LineInfo->MaximumPacketSize, + Net, + ((PIPXCP_CONFIGURATION)ConfigurationData)->LocalNode, + ((PIPXCP_CONFIGURATION)ConfigurationData)->RemoteNode + ); + ReleaseInterfaceReference (ifCB); + } + LeaveForwarder (); +} + + + + +/*++ +******************************************************************* + F w L i n e D o w n + +Routine Description: + Process line down indication delivered by IPX stack +Arguments: + NicId - disconnected adapter ID +Return Value: + None + +******************************************************************* +--*/ +VOID +IpxFwdLineDown ( + IN USHORT NicId, + IN ULONG Context + ) { + PINTERFACE_CB ifCB; + + if (!EnterForwarder()) { + return; + } + IpxFwdDbgPrint (DBG_LINEIND, DBG_INFORMATION, ("IpxFwd: FwdLineDown.\n")); + + + ifCB = InterfaceContextToReference ((PVOID)Context, NicId); + if (ifCB!=NULL) { + ASSERT (ifCB->ICB_Index!=FWD_INTERNAL_INTERFACE_INDEX); + ASSERT (ifCB->ICB_InterfaceType!=FWD_IF_PERMANENT); + UnbindInterface (ifCB); + ReleaseInterfaceReference (ifCB); + } + LeaveForwarder (); +} + |