/*++ Copyright (c) 1995 Microsoft Corporation Module Name: ntos\tdi\isn\fwd\rcvind.c Abstract: Receive indication processing Author: Vadim Eydelman Revision History: --*/ #include "precomp.h" #if DBG VOID DbgFilterReceivedPacket(PUCHAR hdrp); #endif // Doesn't allow accepting packets (for routing) from dial-in clients BOOLEAN ThisMachineOnly = FALSE; /*++ ******************************************************************* F w R e c e i v e Routine Description: Called by the IPX stack to indicate that the IPX packet was received by the NIC dirver. Only external destined packets are indicated by this routine (with the exception of Netbios boradcasts that indicated both for internal and external handlers) Arguments: MacBindingHandle - handle of NIC driver MaxReceiveContext - NIC driver context RemoteAddress - sender's address MacOptions - LookaheadBuffer - packet lookahead buffer that contains complete IPX header LookaheadBufferSize - its size (at least 30 bytes) LookaheadBufferOffset - offset of lookahead buffer in the physical packet Return Value: TRUE if we take the MDL chain to return later with NdisReturnPacket ******************************************************************* --*/ BOOLEAN IpxFwdReceive ( NDIS_HANDLE MacBindingHandle, NDIS_HANDLE MacReceiveContext, ULONG_PTR Context, PIPX_LOCAL_TARGET RemoteAddress, ULONG MacOptions, PUCHAR LookaheadBuffer, UINT LookaheadBufferSize, UINT LookaheadBufferOffset, UINT PacketSize, PMDL pMdl) { PINTERFACE_CB srcIf, dstIf; PPACKET_TAG pktTag; PNDIS_PACKET pktDscr; NDIS_STATUS status; UINT BytesTransferred; LARGE_INTEGER PerfCounter; // check that our configuration process has terminated OK if (!EnterForwarder ()) { return FALSE; } if (!MeasuringPerformance) { PerfCounter.QuadPart = 0; } else { #if DBG static LONGLONG LastCall = 0; KIRQL oldIRQL; #endif PerfCounter = KeQueryPerformanceCounter (NULL); #if DBG KeAcquireSpinLock (&PerfCounterLock, &oldIRQL); ASSERT (PerfCounter.QuadPart-LastCallNicId); // Check if interface is valid if (srcIf!=NULL) { USHORT pktlen; ULONG dstNet; KIRQL oldIRQL; dstNet = GETULONG (LookaheadBuffer + IPXH_DESTNET); pktlen = GETUSHORT(LookaheadBuffer + IPXH_LENGTH); // check if we got the whole IPX header in the lookahead buffer if ((LookaheadBufferSize >= IPXH_HDRSIZE) && (*(LookaheadBuffer + IPXH_XPORTCTL) < 16) && (pktlen<=PacketSize)) { // Lock interface CB to ensure coherency of information in it KeAcquireSpinLock(&srcIf->ICB_Lock, &oldIRQL); // Check if shoud accept packets on this interface if (IS_IF_ENABLED(srcIf) && (srcIf->ICB_Stats.OperationalState!=FWD_OPER_STATE_DOWN) && (!ThisMachineOnly || (srcIf->ICB_InterfaceType !=FWD_IF_REMOTE_WORKSTATION))) { // Check for looped back packets if (IPX_NODE_CMP (RemoteAddress->MacAddress, srcIf->ICB_LocalNode)!=0) { // Separate processing of netbios broadcast packets (20) if (*(LookaheadBuffer + IPXH_PKTTYPE) != IPX_NETBIOS_TYPE) { PFWD_ROUTE dstRoute; INT srcListId, dstListId; // Temp IPX bug fix, they shou;d ensure that // we only get packets that can be routed if ((dstNet==srcIf->ICB_Network) || (dstNet==InternalInterface->ICB_Network)) { InterlockedIncrement (&srcIf->ICB_Stats.InDiscards); KeReleaseSpinLock(&srcIf->ICB_Lock, oldIRQL); ReleaseInterfaceReference (srcIf); LeaveForwarder (); return FALSE; } // ASSERT (dstNet!=srcIf->ICB_Network); // ASSERT ((InternalInterface==NULL) // || (InternalInterface->ICB_Network==0) // || (dstNet!=InternalInterface->ICB_Network)); // Check if needed route is in cash if ((srcIf->ICB_CashedRoute!=NULL) && (dstNet==srcIf->ICB_CashedRoute->FR_Network) // If route was changed or deleted, this will fail && (srcIf->ICB_CashedRoute->FR_InterfaceReference ==srcIf->ICB_CashedInterface)) { dstIf = srcIf->ICB_CashedInterface; dstRoute = srcIf->ICB_CashedRoute; AcquireInterfaceReference (dstIf); AcquireRouteReference (dstRoute); IpxFwdDbgPrint (DBG_RECV, DBG_INFORMATION, ("IpxFwd: Destination in cash.\n")); } else { // Find and cash the route dstIf = FindDestination (dstNet, LookaheadBuffer+IPXH_DESTNODE, &dstRoute ); if (dstIf!=NULL) { // If route is found IpxFwdDbgPrint (DBG_RECV, DBG_INFORMATION, ("IpxFwd: Found destination %0lx.\n", dstIf)); // Don't cash global wan clients and // routes to the same net if ((dstNet!=GlobalNetwork) && (dstIf!=srcIf)) { if (srcIf->ICB_CashedInterface!=NULL) ReleaseInterfaceReference (srcIf->ICB_CashedInterface); if (srcIf->ICB_CashedRoute!=NULL) ReleaseRouteReference (srcIf->ICB_CashedRoute); srcIf->ICB_CashedInterface = dstIf; srcIf->ICB_CashedRoute = dstRoute; AcquireInterfaceReference (dstIf); AcquireRouteReference (dstRoute); } } else { // No route InterlockedIncrement (&srcIf->ICB_Stats.InNoRoutes); KeReleaseSpinLock(&srcIf->ICB_Lock, oldIRQL); IpxFwdDbgPrint (DBG_RECV, DBG_WARNING, ("IpxFwd: No route for packet on interface %ld (icb:%0lx)," " dst-%08lx:%02x%02x%02x%02x%02x%02x, type-%02x.\n", srcIf->ICB_Index, srcIf, dstNet, LookaheadBuffer[IPXH_DESTNODE], LookaheadBuffer[IPXH_DESTNODE+1], LookaheadBuffer[IPXH_DESTNODE+2], LookaheadBuffer[IPXH_DESTNODE+3], LookaheadBuffer[IPXH_DESTNODE+4], LookaheadBuffer[IPXH_DESTNODE+5], LookaheadBuffer[IPXH_PKTTYPE])); ReleaseInterfaceReference (srcIf); LeaveForwarder (); return FALSE; } } srcListId = srcIf->ICB_PacketListId; KeReleaseSpinLock(&srcIf->ICB_Lock, oldIRQL); // Check if destination if can take the packet if (IS_IF_ENABLED (dstIf) // If interface is UP check packet againts actual size limit && (((dstIf->ICB_Stats.OperationalState==FWD_OPER_STATE_UP) && (PacketSize<=dstIf->ICB_Stats.MaxPacketSize)) // if sleeping (WAN), check we can allocate it from WAN list || ((dstIf->ICB_Stats.OperationalState==FWD_OPER_STATE_SLEEPING) && (PacketSize<=WAN_PACKET_SIZE)) // otherwise, interface is down and we can't take the packet ) ){ FILTER_ACTION action; action = FltFilter (LookaheadBuffer, LookaheadBufferSize, srcIf->ICB_FilterInContext, dstIf->ICB_FilterOutContext); if (action==FILTER_PERMIT) { InterlockedIncrement (&srcIf->ICB_Stats.InDelivers); dstListId = dstIf->ICB_PacketListId; // try to get a packet from the rcv pkt pool AllocatePacket (srcListId, dstListId, pktTag); if (pktTag!=NULL) { // Set destination mac in local target if // possible KeAcquireSpinLock (&dstIf->ICB_Lock, &oldIRQL); if (dstIf->ICB_InterfaceType==FWD_IF_PERMANENT) { // Permanent interface: send to the next // hop router if net is not directly connected // or to the dest node otherwise if (dstNet!=dstIf->ICB_Network) { IPX_NODE_CPY (pktTag->PT_Target.MacAddress, dstRoute->FR_NextHopAddress); } else { IPX_NODE_CPY (pktTag->PT_Target.MacAddress, LookaheadBuffer+IPXH_DESTNODE); } } else { // Demand dial interface: assumed to be // point to point connection -> send to // the other party if connection has already // been made, otherwise wait till connected if (dstIf->ICB_Stats.OperationalState == FWD_OPER_STATE_UP) { IPX_NODE_CPY (pktTag->PT_Target.MacAddress, dstIf->ICB_RemoteNode); } // Copy source mac address and nic id in case // we need to spoof this packet else if ((*(LookaheadBuffer+IPXH_PKTTYPE)==0) && (pktlen==IPXH_HDRSIZE+2) && ((LookaheadBufferSizePT_Target.MacAddress, RemoteAddress->MacAddress); pktTag->PT_SourceIf = srcIf; AcquireInterfaceReference (srcIf); pktTag->PT_Flags |= PT_SOURCE_IF; } } KeReleaseSpinLock (&dstIf->ICB_Lock, oldIRQL); ReleaseRouteReference (dstRoute); goto GetPacket; } else { // Allocation failure InterlockedIncrement (&dstIf->ICB_Stats.OutDiscards); } } else {// Filtered out if (action==FILTER_DENY_OUT) InterlockedIncrement (&dstIf->ICB_Stats.OutFiltered); else { ASSERT (action==FILTER_DENY_IN); InterlockedIncrement (&srcIf->ICB_Stats.InFiltered); } IpxFwdDbgPrint (DBG_RECV, DBG_WARNING, ("IpxFwd: Filtered out" " packet on interface %ld (icb:%0lx)," " dst-%ld (icb %08lx) %08lx:%02x%02x%02x%02x%02x%02x, type-%02x.\n", srcIf->ICB_Index, srcIf, dstIf->ICB_Index, dstIf, dstNet, LookaheadBuffer[IPXH_DESTNODE], LookaheadBuffer[IPXH_DESTNODE+1], LookaheadBuffer[IPXH_DESTNODE+2], LookaheadBuffer[IPXH_DESTNODE+3], LookaheadBuffer[IPXH_DESTNODE+4], LookaheadBuffer[IPXH_DESTNODE+5], LookaheadBuffer[IPXH_PKTTYPE])); } } else { // Destination interface is down InterlockedIncrement (&srcIf->ICB_Stats.InDelivers); InterlockedIncrement (&dstIf->ICB_Stats.OutDiscards); IpxFwdDbgPrint (DBG_RECV, DBG_WARNING, ("IpxFwd: Dest interface %ld (icb %08lx) down" " for packet on interface %ld (icb:%0lx)," " dst-%08lx:%02x%02x%02x%02x%02x%02x, type-%02x.\n", dstIf->ICB_Index, dstIf, srcIf->ICB_Index, srcIf, dstNet, LookaheadBuffer[IPXH_DESTNODE], LookaheadBuffer[IPXH_DESTNODE+1], LookaheadBuffer[IPXH_DESTNODE+2], LookaheadBuffer[IPXH_DESTNODE+3], LookaheadBuffer[IPXH_DESTNODE+4], LookaheadBuffer[IPXH_DESTNODE+5], LookaheadBuffer[IPXH_PKTTYPE])); } ReleaseInterfaceReference (dstIf); ReleaseRouteReference (dstRoute); } else { // if netbios // check that this is a netbios bcast packet and // didnt exceed the limit of routers to traverse // and we can accept it on this interface if (srcIf->ICB_NetbiosAccept && (*(LookaheadBuffer + IPXH_XPORTCTL) < 8)) { INT srcListId; srcListId = srcIf->ICB_PacketListId; KeReleaseSpinLock(&srcIf->ICB_Lock, oldIRQL); // Check if packet is valid if (IPX_NODE_CMP (LookaheadBuffer + IPXH_DESTNODE, BROADCAST_NODE)==0) { // Check if we haven't exceeded the quota if (InterlockedDecrement (&NetbiosPacketsQuota)>=0) { // try to get a packet from the rcv pkt pool AllocatePacket (srcListId, srcListId, pktTag); if (pktTag!=NULL) { dstIf = srcIf; AcquireInterfaceReference (dstIf); goto GetPacket; } } else {// Netbios quota exceded IpxFwdDbgPrint (DBG_NETBIOS, DBG_WARNING, ("IpxFwd: Netbios quota exceded" " for packet on interface %ld (icb:%0lx)," " dst-%08lx:%02x%02x%02x%02x%02x%02x, type-%02x.\n", srcIf->ICB_Index, srcIf, dstNet, LookaheadBuffer[IPXH_DESTNODE], LookaheadBuffer[IPXH_DESTNODE+1], LookaheadBuffer[IPXH_DESTNODE+2], LookaheadBuffer[IPXH_DESTNODE+3], LookaheadBuffer[IPXH_DESTNODE+4], LookaheadBuffer[IPXH_DESTNODE+5], LookaheadBuffer[IPXH_PKTTYPE])); InterlockedIncrement (&srcIf->ICB_Stats.InDiscards); } InterlockedIncrement (&NetbiosPacketsQuota); } else { // Bad netbios packet IpxFwdDbgPrint (DBG_NETBIOS, DBG_WARNING, ("IpxFwd: Bad nb packet on interface %ld (icb:%0lx)," " dst-%08lx:%02x%02x%02x%02x%02x%02x, type-%02x.\n", srcIf->ICB_Index, srcIf, dstNet, LookaheadBuffer[IPXH_DESTNODE], LookaheadBuffer[IPXH_DESTNODE+1], LookaheadBuffer[IPXH_DESTNODE+2], LookaheadBuffer[IPXH_DESTNODE+3], LookaheadBuffer[IPXH_DESTNODE+4], LookaheadBuffer[IPXH_DESTNODE+5], LookaheadBuffer[IPXH_PKTTYPE])); InterlockedIncrement (&srcIf->ICB_Stats.InHdrErrors); } } else { // Netbios accept disabled or to many routers crossed KeReleaseSpinLock(&srcIf->ICB_Lock, oldIRQL); InterlockedIncrement (&srcIf->ICB_Stats.InDiscards); IpxFwdDbgPrint (DBG_NETBIOS, DBG_WARNING, ("IpxFwd: NB packet dropped on disabled interface %ld (icb:%0lx)," " dst-%08lx:%02x%02x%02x%02x%02x%02x, type-%02x.\n", srcIf->ICB_Index, srcIf, dstNet, LookaheadBuffer[IPXH_DESTNODE], LookaheadBuffer[IPXH_DESTNODE+1], LookaheadBuffer[IPXH_DESTNODE+2], LookaheadBuffer[IPXH_DESTNODE+3], LookaheadBuffer[IPXH_DESTNODE+4], LookaheadBuffer[IPXH_DESTNODE+5], LookaheadBuffer[IPXH_PKTTYPE])); } } // End netbios specific processing (else if netbios) } else { // Looped back packets discarded without counting // (We shouldn't get them in IPX stack does the right job) KeReleaseSpinLock(&srcIf->ICB_Lock, oldIRQL); } } else { // Interface is down or disabled KeReleaseSpinLock(&srcIf->ICB_Lock, oldIRQL); InterlockedIncrement (&srcIf->ICB_Stats.InDiscards); IpxFwdDbgPrint (DBG_RECV, DBG_WARNING, ("IpxFwd: Packet dropped on disabled interface %ld (icb:%0lx)," " dst-%08lx:%02x%02x%02x%02x%02x%02x, type-%02x.\n", srcIf->ICB_Index, srcIf, dstNet, LookaheadBuffer[IPXH_DESTNODE], LookaheadBuffer[IPXH_DESTNODE+1], LookaheadBuffer[IPXH_DESTNODE+2], LookaheadBuffer[IPXH_DESTNODE+3], LookaheadBuffer[IPXH_DESTNODE+4], LookaheadBuffer[IPXH_DESTNODE+5], LookaheadBuffer[IPXH_PKTTYPE])); } } else { // Obvious header errors (shouldn't IPX do this for us ? InterlockedIncrement (&srcIf->ICB_Stats.InHdrErrors); IpxFwdDbgPrint (DBG_RECV, DBG_ERROR, ("IpxFwd: Header errors in packet on interface %ld (icb:%0lx)," " dst-%08lx:%02x%02x%02x%02x%02x%02x, type-%02x.\n", srcIf->ICB_Index, srcIf, dstNet, LookaheadBuffer[IPXH_DESTNODE], LookaheadBuffer[IPXH_DESTNODE+1], LookaheadBuffer[IPXH_DESTNODE+2], LookaheadBuffer[IPXH_DESTNODE+3], LookaheadBuffer[IPXH_DESTNODE+4], LookaheadBuffer[IPXH_DESTNODE+5], LookaheadBuffer[IPXH_PKTTYPE])); } ReleaseInterfaceReference (srcIf); } // We could not locate the interface from IPX supplied context: there // is just a little time window when interface is deleted // but IPX had already pushed the context on the stack else { IpxFwdDbgPrint (DBG_RECV, DBG_ERROR, ("IpxFwd: Receive, type-%02x" " - src interface context is invalid.\n", LookaheadBuffer[IPXH_PKTTYPE])); } LeaveForwarder (); return FALSE ; GetPacket: InterlockedIncrement (&srcIf->ICB_Stats.InDelivers); ReleaseInterfaceReference (srcIf); pktDscr = CONTAINING_RECORD (pktTag, NDIS_PACKET, ProtocolReserved); pktTag->PT_InterfaceReference = dstIf; pktTag->PT_PerfCounter = PerfCounter.QuadPart; // try to get the packet data IPXTransferData(&status, MacBindingHandle, MacReceiveContext, LookaheadBufferOffset, // start of IPX header PacketSize, // packet size starting at IPX header pktDscr, &BytesTransferred); if (status != NDIS_STATUS_PENDING) { // complete the frame processing (LeaveForwarder will be called there) IpxFwdTransferDataComplete(pktDscr, status, BytesTransferred); } return FALSE; } /*++ ******************************************************************* F w T r a n s f e r D a t a C o m p l e t e Routine Description: Called by the IPX stack when NIC driver completes data transger. Arguments: pktDscr - handle of NIC driver status - result of the transfer bytesTransferred - number of bytest trasferred Return Value: None ******************************************************************* --*/ VOID IpxFwdTransferDataComplete ( PNDIS_PACKET pktDscr, NDIS_STATUS status, UINT bytesTransferred) { PPACKET_TAG pktTag; pktTag = (PPACKET_TAG)(&pktDscr->ProtocolReserved); // If transfer failed, release the packet and interface // if (status==NDIS_STATUS_SUCCESS) { if (*(pktTag->PT_Data + IPXH_PKTTYPE) != IPX_NETBIOS_TYPE) { // pmay: 260480 // // Increment the transport control field so that // the number of routers that this packet has // traversed is increased. IpxFwdReceive will drop // all packets that have traversed more that 15 routers. // // Netbios packets will have their transport control // fields incremented by ProcessNetbiosPacket // *(pktTag->PT_Data + IPXH_XPORTCTL) += 1; SendPacket (pktTag->PT_InterfaceReference, pktTag); } else { ProcessNetbiosPacket (pktTag->PT_InterfaceReference, pktTag); } } else { IpxFwdDbgPrint (DBG_RECV, DBG_ERROR, ("IpxFwd: Trans data failed: packet %08lx on if %08lx!\n", pktTag, pktTag->PT_InterfaceReference)); // Record the fact that we're discarding // if (*(pktTag->PT_Data + IPXH_PKTTYPE) != IPX_NETBIOS_TYPE) { InterlockedIncrement ( &pktTag->PT_InterfaceReference->ICB_Stats.OutDiscards); } // For netbios packets interface reference is // actually a source interface else { InterlockedIncrement (&NetbiosPacketsQuota); InterlockedIncrement ( &pktTag->PT_InterfaceReference->ICB_Stats.InDiscards); } ReleaseInterfaceReference (pktTag->PT_InterfaceReference); FreePacket (pktTag); } LeaveForwarder (); return; } /*++ ******************************************************************* F w R e c e i v e C o m p l e t e Routine Description: This routine receives control from the IPX driver after one or more receive operations have completed and no receive is in progress. It is called under less severe time constraints than IpxFwdReceive. It is used to process netbios queue Arguments: None Return Value: None ******************************************************************* --*/ VOID IpxFwdReceiveComplete ( USHORT NicId ) { // check that our configuration process has terminated OK if(!EnterForwarder ()) { return; } IpxFwdDbgPrint (DBG_RECV, DBG_INFORMATION, ("IpxFwd: FwdReceiveComplete.\n")); ScheduleNetbiosWorker (); LeaveForwarder (); } /*++ ******************************************************************* I p x F w d I n t e r n a l R e c e i v e Routine Description: Called by the IPX stack to indicate that the IPX packet destined to local client was received by the NIC dirver. Arguments: Context - forwarder context associated with the NIC (interface block pointer) RemoteAddress - sender's address LookaheadBuffer - packet lookahead buffer that contains complete IPX header LookaheadBufferSize - its size (at least 30 bytes) Return Value: STATUS_SUCCESS - the packet will be delivered to local destination STATUS_UNSUCCESSFUL - the packet will be dropped ******************************************************************* --*/ NTSTATUS IpxFwdInternalReceive ( IN ULONG_PTR Context, IN PIPX_LOCAL_TARGET RemoteAddress, IN PUCHAR LookAheadBuffer, IN UINT LookAheadBufferSize ) { NTSTATUS status = STATUS_SUCCESS; PINTERFACE_CB srcIf; if (!EnterForwarder ()) { return STATUS_UNSUCCESSFUL; } if (Context!=VIRTUAL_NET_FORWARDER_CONTEXT) { // Check if interface context supplied by IPX driver is valid srcIf = InterfaceContextToReference ((PVOID)Context, RemoteAddress->NicId); } else { srcIf = InternalInterface; AcquireInterfaceReference (srcIf); } if (srcIf!=NULL) { // Check if we can accept on this interface if (IS_IF_ENABLED (srcIf) && (srcIf->ICB_Stats.OperationalState!=FWD_OPER_STATE_DOWN) && ((*(LookAheadBuffer + IPXH_PKTTYPE) != IPX_NETBIOS_TYPE) || srcIf->ICB_NetbiosAccept)) { // Check if we can accept on internal interface if (IS_IF_ENABLED(InternalInterface)) { FILTER_ACTION action; action = FltFilter (LookAheadBuffer, LookAheadBufferSize, srcIf->ICB_FilterInContext, InternalInterface->ICB_FilterOutContext); // Check the filter if (action==FILTER_PERMIT) { // Update source interface statistics InterlockedIncrement (&srcIf->ICB_Stats.InDelivers); // Handle NB packets separatedly if (*(LookAheadBuffer + IPXH_PKTTYPE) != IPX_NETBIOS_TYPE) { InterlockedIncrement ( &InternalInterface->ICB_Stats.OutDelivers); IpxFwdDbgPrint (DBG_INT_RECV, DBG_INFORMATION, ("IpxFwd: FwdInternalReceive," " from %d(%lx)-%.2x%.2x%.2x%.2x:%.2x%.2x%.2x%.2x%.2x%.2x," " type-%02x.\n", srcIf->ICB_Index, srcIf, LookAheadBuffer[IPXH_SRCNET],LookAheadBuffer[IPXH_SRCNET+1], LookAheadBuffer[IPXH_SRCNET+2],LookAheadBuffer[IPXH_SRCNET+3], LookAheadBuffer[IPXH_SRCNODE],LookAheadBuffer[IPXH_SRCNODE+1], LookAheadBuffer[IPXH_SRCNODE+2],LookAheadBuffer[IPXH_SRCNODE+3], LookAheadBuffer[IPXH_SRCNODE+4],LookAheadBuffer[IPXH_SRCNODE+5], LookAheadBuffer[IPXH_PKTTYPE])); } else { // Check if destination netbios name is staticly assigned to // an external interface or netbios delivery options do not // allow us to deliver this packet PINTERFACE_CB dstIf; USHORT dstSock = GETUSHORT (LookAheadBuffer+IPXH_DESTSOCK); InterlockedIncrement (&srcIf->ICB_Stats.NetbiosReceived); // First try to find a static name if we have enough data // in the lookahead buffer if ((dstSock==IPX_NETBIOS_SOCKET) && (LookAheadBufferSize>(NB_NAME+16))) dstIf = FindNBDestination (LookAheadBuffer+(NB_NAME-IPXH_HDRSIZE)); else if ((dstSock==IPX_SMB_NAME_SOCKET) && (LookAheadBufferSize>(SMB_NAME+16))) dstIf = FindNBDestination (LookAheadBuffer+(SMB_NAME-IPXH_HDRSIZE)); else dstIf = NULL; // Now see, if we can deliver the packet if ((((dstIf==NULL) || (dstIf==InternalInterface)) && (InternalInterface->ICB_NetbiosDeliver==FWD_NB_DELIVER_ALL)) || ((dstIf==InternalInterface) && (InternalInterface->ICB_NetbiosDeliver==FWD_NB_DELIVER_STATIC))) { InterlockedIncrement ( &InternalInterface->ICB_Stats.NetbiosSent); InterlockedIncrement ( &InternalInterface->ICB_Stats.OutDelivers); IpxFwdDbgPrint (DBG_INT_RECV, DBG_INFORMATION, ("IpxFwd: FwdInternalReceive, NB" " from %d(%lx)-%.2x%.2x%.2x%.2x:%.2x%.2x%.2x%.2x%.2x%.2x\n", srcIf->ICB_Index, srcIf, LookAheadBuffer[IPXH_SRCNET],LookAheadBuffer[IPXH_SRCNET+1], LookAheadBuffer[IPXH_SRCNET+2],LookAheadBuffer[IPXH_SRCNET+3], LookAheadBuffer[IPXH_SRCNODE],LookAheadBuffer[IPXH_SRCNODE+1], LookAheadBuffer[IPXH_SRCNODE+2],LookAheadBuffer[IPXH_SRCNODE+3], LookAheadBuffer[IPXH_SRCNODE+4],LookAheadBuffer[IPXH_SRCNODE+5])); } else { InterlockedIncrement ( &InternalInterface->ICB_Stats.OutDiscards); IpxFwdDbgPrint (DBG_INT_RECV, DBG_WARNING, ("IpxFwd: FwdInternalReceive, NB dropped because delivery disabled" " from %d(%lx)-%.2x%.2x%.2x%.2x:%.2x%.2x%.2x%.2x%.2x%.2x\n", srcIf->ICB_Index, srcIf, LookAheadBuffer[IPXH_SRCNET],LookAheadBuffer[IPXH_SRCNET+1], LookAheadBuffer[IPXH_SRCNET+2],LookAheadBuffer[IPXH_SRCNET+3], LookAheadBuffer[IPXH_SRCNODE],LookAheadBuffer[IPXH_SRCNODE+1], LookAheadBuffer[IPXH_SRCNODE+2],LookAheadBuffer[IPXH_SRCNODE+3], LookAheadBuffer[IPXH_SRCNODE+4],LookAheadBuffer[IPXH_SRCNODE+5])); status = STATUS_UNSUCCESSFUL; } if (dstIf!=NULL) ReleaseInterfaceReference (dstIf); } } else {// Filtered Out if (action==FILTER_DENY_OUT) { InterlockedIncrement ( &InternalInterface->ICB_Stats.OutFiltered); status=STATUS_UNSUCCESSFUL; } else { ASSERT (action==FILTER_DENY_IN); InterlockedIncrement (&srcIf->ICB_Stats.InFiltered); status=STATUS_UNSUCCESSFUL; } IpxFwdDbgPrint (DBG_INT_RECV, DBG_WARNING, ("IpxFwd: FwdInternalReceive, filtered out" " from %d(%lx)-%.2x%.2x%.2x%.2x:%.2x%.2x%.2x%.2x%.2x%.2x," " type-%02x.\n", srcIf->ICB_Index, srcIf, LookAheadBuffer[IPXH_SRCNET],LookAheadBuffer[IPXH_SRCNET+1], LookAheadBuffer[IPXH_SRCNET+2],LookAheadBuffer[IPXH_SRCNET+3], LookAheadBuffer[IPXH_SRCNODE],LookAheadBuffer[IPXH_SRCNODE+1], LookAheadBuffer[IPXH_SRCNODE+2],LookAheadBuffer[IPXH_SRCNODE+3], LookAheadBuffer[IPXH_SRCNODE+4],LookAheadBuffer[IPXH_SRCNODE+5], LookAheadBuffer[IPXH_PKTTYPE])); } } else {// Internal interface is disabled InterlockedIncrement ( &InternalInterface->ICB_Stats.OutDiscards); status = STATUS_UNSUCCESSFUL; IpxFwdDbgPrint (DBG_INT_RECV, DBG_WARNING, ("IpxFwd: FwdInternalReceive, internal if disabled" " from %d(%lx)-%.2x%.2x%.2x%.2x:%.2x%.2x%.2x%.2x%.2x%.2x," " type-%02x.\n", srcIf->ICB_Index, srcIf, LookAheadBuffer[IPXH_SRCNET],LookAheadBuffer[IPXH_SRCNET+1], LookAheadBuffer[IPXH_SRCNET+2],LookAheadBuffer[IPXH_SRCNET+3], LookAheadBuffer[IPXH_SRCNODE],LookAheadBuffer[IPXH_SRCNODE+1], LookAheadBuffer[IPXH_SRCNODE+2],LookAheadBuffer[IPXH_SRCNODE+3], LookAheadBuffer[IPXH_SRCNODE+4],LookAheadBuffer[IPXH_SRCNODE+5], LookAheadBuffer[IPXH_PKTTYPE])); } } else { // Disabled source interface InterlockedIncrement (&srcIf->ICB_Stats.InDiscards); IpxFwdDbgPrint (DBG_INT_RECV, DBG_ERROR, ("IpxFwd: FwdInternalReceive, source if disabled" " from %d(%lx)-%.2x%.2x%.2x%.2x:%.2x%.2x%.2x%.2x%.2x%.2x," " type-%02x.\n", srcIf->ICB_Index, srcIf, LookAheadBuffer[IPXH_SRCNET],LookAheadBuffer[IPXH_SRCNET+1], LookAheadBuffer[IPXH_SRCNET+2],LookAheadBuffer[IPXH_SRCNET+3], LookAheadBuffer[IPXH_SRCNODE],LookAheadBuffer[IPXH_SRCNODE+1], LookAheadBuffer[IPXH_SRCNODE+2],LookAheadBuffer[IPXH_SRCNODE+3], LookAheadBuffer[IPXH_SRCNODE+4],LookAheadBuffer[IPXH_SRCNODE+5], LookAheadBuffer[IPXH_PKTTYPE])); status = STATUS_UNSUCCESSFUL; } ReleaseInterfaceReference (srcIf); } else { // Invalid source interface context IpxFwdDbgPrint (DBG_INT_RECV, DBG_ERROR, ("IpxFwd: FwdInternalReceive, source if context is invalid" " from (%lx:%d)-%.2x%.2x%.2x%.2x:%.2x%.2x%.2x%.2x%.2x%.2x," " type-%02x.\n", Context, RemoteAddress->NicId, LookAheadBuffer[IPXH_SRCNET],LookAheadBuffer[IPXH_SRCNET+1], LookAheadBuffer[IPXH_SRCNET+2],LookAheadBuffer[IPXH_SRCNET+3], LookAheadBuffer[IPXH_SRCNODE],LookAheadBuffer[IPXH_SRCNODE+1], LookAheadBuffer[IPXH_SRCNODE+2],LookAheadBuffer[IPXH_SRCNODE+3], LookAheadBuffer[IPXH_SRCNODE+4],LookAheadBuffer[IPXH_SRCNODE+5], LookAheadBuffer[IPXH_PKTTYPE])); status = STATUS_UNSUCCESSFUL; } LeaveForwarder (); return status; } /*++ ******************************************************************* D e l e t e R e c v Q u e u e Routine Description: Initializes the netbios bradcast queue Arguments: None Return Value: None ******************************************************************* --*/ VOID DeleteRecvQueue ( void ) { // while (!IsListEmpty (&RecvQueue)) { // PPACKET_TAG pktTag = CONTAINING_RECORD (RecvQueue.Flink, // PACKET_TAG, // PT_QueueLink); // RemoveEntryList (&pktTag->PT_QueueLink); // if (pktTag->PT_InterfaceReference!=NULL) { // ReleaseInterfaceReference (pktTag->PT_InterfaceReference); // } // FreePacket (pktTag); // } } #if DBG ULONG DbgFilterTrap = 0; // 1 - on dst and src (net + node), // 2 - on dst (net + node), // 3 - on src (net + node), // 4 - on dst (net + node + socket) UCHAR DbgFilterDstNet[4]; UCHAR DbgFilterDstNode[6]; UCHAR DbgFilterDstSocket[2]; UCHAR DbgFilterSrcNet[4]; UCHAR DbgFilterSrcNode[6]; UCHAR DbgFilterSrcSocket[2]; PUCHAR DbgFilterFrame; VOID DbgFilterReceivedPacket(PUCHAR hdrp) { switch(DbgFilterTrap) { case 1: if(!memcmp(hdrp + IPXH_DESTNET, DbgFilterDstNet, 4) && !memcmp(hdrp + IPXH_DESTNODE, DbgFilterDstNode, 6) && !memcmp(hdrp + IPXH_SRCNET, DbgFilterSrcNet, 4) && !memcmp(hdrp + IPXH_SRCNODE, DbgFilterSrcNode, 6)) { DbgBreakPoint(); } break; case 2: if(!memcmp(hdrp + IPXH_DESTNET, DbgFilterDstNet, 4) && !memcmp(hdrp + IPXH_DESTNODE, DbgFilterDstNode, 6)) { DbgBreakPoint(); } break; case 3: if(!memcmp(hdrp + IPXH_SRCNET, DbgFilterSrcNet, 4) && !memcmp(hdrp + IPXH_SRCNODE, DbgFilterSrcNode, 6)) { DbgBreakPoint(); } break; case 4: if(!memcmp(hdrp + IPXH_DESTNET, DbgFilterDstNet, 4) && !memcmp(hdrp + IPXH_DESTNODE, DbgFilterDstNode, 6) && !memcmp(hdrp + IPXH_DESTSOCK, DbgFilterDstSocket, 2)) { DbgBreakPoint(); } break; default: break; } DbgFilterFrame = hdrp; } #endif