/*++ Copyright (c) 1990 Microsoft Corporation Module Name: tpstress.c Abstract: This module implements the Test Protocol Stress routines and the basic controls for stressing the MAC. Author: Tom Adams (tomad) 15-Dec-1990 Environment: Kernel mode Revision History: --*/ #include #include #include "tpdefs.h" #include "media.h" #include "tpprocs.h" NDIS_STATUS TpStressReceive( IN NDIS_HANDLE ProtocolBindingContext, IN NDIS_HANDLE MacReceiveContext, IN PVOID HeaderBuffer, IN UINT HeaderBufferSize, IN PVOID LookaheadBuffer, IN UINT LookaheadBufferSize, IN UINT PacketSize ) /*++ Routine Description: Arguments: Return Value: --*/ { POPEN_BLOCK OpenP = ((POPEN_BLOCK)ProtocolBindingContext); NDIS_STATUS Status = NDIS_STATUS_SUCCESS; PNDIS_PACKET Packet; PCLIENT_STORAGE Client; PSERVER_STORAGE Server; PSTRESS_ARGUMENTS Args; PPACKET_INFO pi; PSTRESS_CONTROL sc; UCHAR NextClient; UCHAR NextServer; INT NewPacketSize; INT NumResponses; BOOLEAN NewClient; BOOLEAN NewServer; PUCHAR DestAddr; PUCHAR SrcAddr; DestAddr = (PUCHAR)HeaderBuffer + (ULONG)OpenP->Media->DestAddrOffset; SrcAddr = (PUCHAR)HeaderBuffer + (ULONG)OpenP->Media->SrcAddrOffset; // // pi is the packet information section of the test prot packet header, // sc is the stress control section of the testprot packet header. We // will us pi and sc to quickly reference info in the header. // pi = (PPACKET_INFO)LookaheadBuffer; sc = (PSTRESS_CONTROL)((PUCHAR)LookaheadBuffer + (ULONG)sizeof( PACKET_INFO )); if ( !TpCheckSum( (PUCHAR)pi, sizeof( STRESS_PACKET ) - ( sizeof( ULONG ) + OpenP->Media->HeaderSize ), (PULONG)&sc->CheckSum )) { NdisAcquireSpinLock( &OpenP->SpinLock ); ++OpenP->GlobalCounters->CorruptRecs; NdisReleaseSpinLock( &OpenP->SpinLock ); Status = NDIS_STATUS_NOT_RECOGNIZED; } Client = OpenP->Stress->Client; Server = OpenP->Stress->Server; Args = OpenP->Stress->Arguments; switch( pi->u.PacketProtocol ) { // // A REGISTER_REQ(2) packet is a request from a TP_CLIENT to // participate in a stress test. If this packet is from a new // client then a response packet will be set back to the client, // the client will be added to the Clients array, and its counters // and control structures for the test will be reset. If this is // an old client, then we will just reset the counters and control // structures. // case REGISTER_REQ: case REGISTER_REQ2: // // Is this packet really destined for us, check that the // destination address matches the stress address. // if ( RtlCompareMemory( DestAddr, OpenP->Environment->StressAddress, OpenP->Media->AddressLen ) != OpenP->Media->AddressLen ) { // // the destination address does not match the stress // address, we should never have received this packet! // NdisAcquireSpinLock( &OpenP->SpinLock ); ++OpenP->GlobalCounters->InvalidPacketRecs; NdisReleaseSpinLock( &OpenP->SpinLock ); // // This packet is a request from a Client to register. // Are we a Server? // } else if ( Args->MemberType == TP_CLIENT ) { // // No! We are not a Server, ignore this packet. // Status = NDIS_STATUS_NOT_RECOGNIZED; } else { // // If there is room, see if this is a new client and if so // register it, and send a REGISTER_RESP packet. // if ( Server->NumClients < MAX_CLIENTS ) { NextClient = 0; NewClient = TRUE; // // See if we have already registered this client. // while ( NextClient < Server->NumClients ) { // // If the Src Address matches a previously registered // Client, and the Open Instance of that Client matches // the Src Instance then we have already registered // this Client, reset the counters, send a response, // but ignore it. Otherwise this is a new Client so // register it properly. // if (( RtlCompareMemory( SrcAddr, Server->Clients[NextClient].Address, OpenP->Media->AddressLen ) == (ULONG)OpenP->Media->AddressLen ) && ( pi->SrcInstance == Server->Clients[NextClient].ClientInstance )) { // // We have already registered with this client. // NewClient = FALSE; break; } else { // // This is not a match , try the next one. // NextClient++; } } } // // This REGISTER_REQ(2) packet is from a New Client, and we // have room for it, so register it. // if ( NewClient == TRUE ) { IF_TPDBG ( TP_DEBUG_DPC ) { TpPrint0("TpStressReceive: REGISTER_REQ(2) - Registering Client\n"); } // // set up the CLIENT_INFO data structure and initialize it. // NextClient = Server->NumClients++; ++Server->ActiveClients; Server->Clients[NextClient].ClientReference = NextClient; Server->Clients[NextClient].ClientInstance = pi->SrcInstance; Server->Clients[NextClient].ServerResponseType = sc->ResponseType; Server->Clients[NextClient].DataChecking = sc->DataChecking; Server->Clients[NextClient].LastSequenceNumber = 0; RtlMoveMemory( Server->Clients[NextClient].Address, SrcAddr, OpenP->Media->AddressLen ); // // Now allocate and initialize the instances counter // Status = NdisAllocateMemory( (PVOID *)&Server->Clients[NextClient].Counters, sizeof( INSTANCE_COUNTERS ), 0, HighestAddress ); if ( Status != NDIS_STATUS_SUCCESS ) { IF_TPDBG (TP_DEBUG_RESOURCES) { TpPrint0("TpStressReceive: failed to allocate counters.\n"); } Status = NDIS_STATUS_RESOURCES; break; } else { NdisZeroMemory( (PVOID)Server->Clients[NextClient].Counters, sizeof( INSTANCE_COUNTERS ) ); } } else if ( pi->u.PacketProtocol == REGISTER_REQ ) { NdisZeroMemory( (PVOID)Server->Clients[NextClient].Counters, sizeof( INSTANCE_COUNTERS ) ); Server->Clients[NextClient].ServerResponseType = sc->ResponseType; Server->Clients[NextClient].DataChecking = sc->DataChecking; Server->Clients[NextClient].LastSequenceNumber = 0; } if (( pi->u.PacketProtocol == REGISTER_REQ ) || ( NewClient == TRUE )) { // // Then build a REGISTER_RESP packet to register with, and // send it to the Client. // do { Packet = TpStressCreatePacket( OpenP, Server->PacketHandle, Args->PacketMakeUp, pi->SrcInstance, OpenP->OpenInstance, REGISTER_RESP, Args->ResponseType, SrcAddr, sizeof( STRESS_PACKET ), sizeof( STRESS_PACKET ), sc->SequenceNumber, sc->SequenceNumber + OpenP->Environment->WindowSize, NextClient, 0, Args->DataChecking ); if ( Packet == NULL ) { IF_TPDBG ( TP_DEBUG_RESOURCES ) { TpPrint0("TpStressReceive: failed to create REGISTER_RESP Packet\n"); } } } while ( Packet == NULL ); // // And send it. // TpStressSend( OpenP,Packet,NULL ); } } break; // // A REGISTER_RESP packet is a response from a TP_SERVER to a // previously sent REGISTER_REQ(2) that the server will be // participating in the next stress test. If this packet is from // a new server then the server will be added to the Server array, // and its counters and control structures for the test will be // reset. If the response packet is from an old client, then we // will just reset the counters. // case REGISTER_RESP: // // Is this packet really destined for us, check that the // destination address matches the local card address we // queried and stored in the OPEN_BLOCK. // if ( RtlCompareMemory( DestAddr, OpenP->StationAddress, OpenP->Media->AddressLen ) != OpenP->Media->AddressLen ) { // // the destination address does not match the local card // address, we should never have received this packet! // NdisAcquireSpinLock( &OpenP->SpinLock ); ++OpenP->GlobalCounters->InvalidPacketRecs; NdisReleaseSpinLock( &OpenP->SpinLock ); // // This packet is a response from a Server to register. Are we a Client? // } else if ( Args->MemberType == TP_SERVER ) { // // No! We are not a Client, ignore this packet. // Status = NDIS_STATUS_NOT_RECOGNIZED; } else { if ( Client->NumServers < MAX_SERVERS ) { NextServer = 0; NewServer = TRUE; // // See if this is a new server. // while ( NextServer < Client->NumServers ) { if (( RtlCompareMemory( SrcAddr, Client->Servers[NextServer].Address, OpenP->Media->AddressLen) == (ULONG)OpenP->Media->AddressLen ) && ( pi->SrcInstance == Client->Servers[NextServer].ServerInstance )) { // // This server has already registered, ignore it. // NewServer = FALSE; break; } else { // // Not this server, try the next one. // NextServer++; } } } if ( NewServer == TRUE ) { IF_TPDBG ( TP_DEBUG_DPC ) { TpPrint0("TpStressReceive: REGISTER_RESP - Registering Server\n"); } // // set up the SERVER_INFO data structure and initialize it. // NextServer = Client->NumServers++; NextServer = Client->ActiveServers++; Client->Servers[NextServer].ServerReference = NextServer; Client->Servers[NextServer].ClientReference = sc->ClientReference; Client->Servers[NextServer].ServerInstance = pi->SrcInstance; Client->Servers[NextServer].ServerActive = TRUE; Client->Servers[NextServer].LastSequenceNumber = 0; RtlMoveMemory( Client->Servers[NextServer].Address, SrcAddr, OpenP->Media->AddressLen ); // // Now allocate and initialize the instances counter // Status = NdisAllocateMemory( (PVOID *)&Client->Servers[NextServer].Counters, sizeof( INSTANCE_COUNTERS ), 0, HighestAddress ); if ( Status != NDIS_STATUS_SUCCESS ) { IF_TPDBG (TP_DEBUG_RESOURCES) { TpPrint0("TpStressReceive: failed to allocate counters.\n"); } Status = NDIS_STATUS_RESOURCES; break; } else { NdisZeroMemory( (PVOID)Client->Servers[NextServer].Counters, sizeof( INSTANCE_COUNTERS ) ); } } else { // // Old Server, reset the statistics counters. // NdisZeroMemory( (PVOID)Client->Servers[NextServer].Counters, sizeof( INSTANCE_COUNTERS ) ); Client->Servers[NextServer].LastSequenceNumber = 0; } } break; // // A TEST_REQ packet is the standard test packet sent from a the // client to each of the servers participating in the test. This // packet is evaluated for data integrity, counted, and the required // response packet is returned to the client. // case TEST_REQ: // // Is this packet really destined for us, check that the // destination address matches the local card address we // queried and stored in the OPEN_BLOCK. // if ( RtlCompareMemory( DestAddr, OpenP->StationAddress, OpenP->Media->AddressLen ) != OpenP->Media->AddressLen ) { // // the destination address does not match the local card // address, we should never have received this packet! // NdisAcquireSpinLock( &OpenP->SpinLock ); ++OpenP->GlobalCounters->InvalidPacketRecs; NdisReleaseSpinLock( &OpenP->SpinLock ); // // This packet is a test request from a Client. Are we a Server?, // } else if ( Args->MemberType == TP_CLIENT ) { // // No! We are not a Server, ignore this packet. // Status = NDIS_STATUS_NOT_RECOGNIZED; // // Is this a client we have previously registered with? // } else if (( RtlCompareMemory( SrcAddr, Server->Clients[sc->ClientReference].Address, OpenP->Media->AddressLen) != (ULONG)OpenP->Media->AddressLen ) || ( pi->SrcInstance != Server->Clients[sc->ClientReference].ClientInstance )) { // // No! We should ignore this packet. // Status = NDIS_STATUS_NOT_RECOGNIZED; // // Is this packet destined for our open instance or another // open instance of the same card? // } else if (( RtlCompareMemory( SrcAddr, Server->Clients[sc->ClientReference].Address, OpenP->Media->AddressLen) == (ULONG)OpenP->Media->AddressLen) && ( pi->DestInstance != OpenP->OpenInstance )) { // // No, this packet is for some other open instance. // Status = NDIS_STATUS_NOT_RECOGNIZED; } else { if ( Args->BeginReceives == FALSE ) { IF_TPDBG ( TP_DEBUG_DPC ) { TpPrint0("TpStressReceive: received TEST_REQ packet, not initialized\n"); } // Increment receive counter for accounting purposes. break; } // // Has this packet arrived out of order? // if ( sc->SequenceNumber <= Server->Clients[sc->ClientReference].LastSequenceNumber ) { IF_TPDBG ( TP_DEBUG_NDIS_ERROR ) { TpPrint0("\nTpStressReceive: PACKET ARRIVED OUT OF ORDER, OR ARRIVED TWICE !!!\n"); TpPrint3("TEST_REQ Packet: Sequence Number %d @ 0x%lX, expected greater than %d.\n\n", sc->SequenceNumber, HeaderBuffer, Server->Clients[sc->ClientReference].LastSequenceNumber); TpBreakPoint(); } } else { Server->Clients[sc->ClientReference].LastSequenceNumber = sc->SequenceNumber; } if ( Server->Clients[sc->ClientReference].DataChecking == TRUE ) { if (( pi->PacketSize - sizeof( STRESS_PACKET )) > 0 ) { TpStressCheckPacketData( OpenP, MacReceiveContext, sc->DataBufOffset, pi->PacketSize, Server->Clients[sc->ClientReference].Counters ); } } NdisAcquireSpinLock( &OpenP->SpinLock ); ++Server->Clients[sc->ClientReference].Counters->Receives; NdisReleaseSpinLock( &OpenP->SpinLock ); switch( Server->Clients[sc->ClientReference].ServerResponseType ) { case NO_RESPONSE: NumResponses = 0; break; case FULL_RESPONSE: NumResponses = 1; NewPacketSize = pi->PacketSize; break; case ACK_EVERY: NumResponses = 1; NewPacketSize = sizeof( STRESS_PACKET ); break; case ACK_10_TIMES: NumResponses = 10; NewPacketSize = sizeof( STRESS_PACKET ); break; default: IF_TPDBG ( TP_DEBUG_DPC ) { TpPrint0("TpStressReceive: Unknown Response Type\n"); } NdisAcquireSpinLock( &OpenP->SpinLock ); ++OpenP->GlobalCounters->CorruptRecs; NdisReleaseSpinLock( &OpenP->SpinLock ); Status = NDIS_STATUS_NOT_RECOGNIZED; break; } while ( NumResponses-- > 0 ) { // // if send now, build and send a TEST_RESP packet // TpStressServerSend( OpenP, Server->TransmitPool, SrcAddr, pi->SrcInstance, OpenP->OpenInstance, sc->SequenceNumber, sc->SequenceNumber + OpenP->Environment->WindowSize, sc->ClientReference, sc->ServerReference, NewPacketSize, sc->DataBufOffset ); } // // else queue send for TpStressReceiveComplete send // } break; // // A TEST_RESP packet is the response from a server to a client's // TEST_REQ packet. This packet is checked for data integrity, // counted, and discarded. // case TEST_RESP: // // Is this packet really destined for us, check that the // destination address matches the local card address we // queried and stored in the OPEN_BLOCK. // if ( RtlCompareMemory( DestAddr, OpenP->StationAddress, OpenP->Media->AddressLen ) != OpenP->Media->AddressLen ) { // // the destination address does not match the local card // address, we should never have received this packet! // NdisAcquireSpinLock( &OpenP->SpinLock ); ++OpenP->GlobalCounters->InvalidPacketRecs; NdisReleaseSpinLock( &OpenP->SpinLock ); // // This packet is a test response from a Server. Are we a Client? // } else if ( Args->MemberType == TP_SERVER ) { // // No! We are not a Client, ignore this packet. // Status = NDIS_STATUS_NOT_RECOGNIZED; // // Is this a Server that has previously registered with us? // } else if (( RtlCompareMemory( SrcAddr, Client->Servers[sc->ServerReference].Address, OpenP->Media->AddressLen) != (ULONG)OpenP->Media->AddressLen ) || ( pi->SrcInstance != Client->Servers[sc->ServerReference].ServerInstance )) { // // No! We should ignore this packet. // Status = NDIS_STATUS_NOT_RECOGNIZED; // // Is this packet destined for this open instance or another // open instance of the same card? // } else if (( RtlCompareMemory( SrcAddr, Client->Servers[sc->ServerReference].Address, OpenP->Media->AddressLen) == (ULONG)OpenP->Media->AddressLen) && ( pi->DestInstance != OpenP->OpenInstance )) { // // This packet is for some other open instance, ignore it. // Status = NDIS_STATUS_NOT_RECOGNIZED; } else { // // Has this packet arrived out of order? // if ( sc->SequenceNumber <= Client->Servers[sc->ServerReference].LastSequenceNumber ) { if (( Args->ResponseType == ACK_10_TIMES ) && ( sc->SequenceNumber == Client->Servers[sc->ServerReference].LastSequenceNumber )) { ; // This is okay, we expect 10 packets with same // number ignore packet. } else { // // A Packet has arrived out or order, PANIC! // IF_TPDBG ( TP_DEBUG_DPC ) { TpPrint0("\nTpStressReceive: PACKET ARRIVED OUT OF ORDER, OR ARRIVED TWICE !!!\n"); TpPrint3("TEST_RESP Packet: Sequence Number %d @ 0x%lX, expected greater than %d.\n\n", sc->SequenceNumber, HeaderBuffer, Client->Servers[sc->ServerReference].LastSequenceNumber); TpBreakPoint(); } } } else { Client->Servers[sc->ServerReference].LastSequenceNumber = sc->SequenceNumber; } if ( Args->WindowEnabled == TRUE ) { Client->Servers[sc->ServerReference].MaxSequenceNumber = sc->MaxSequenceNumber; } else { Client->Servers[sc->ServerReference].MaxSequenceNumber = 0xFFFFFFFF; } // // We have received a packet from this server so zero its // window resetting counter in case it has any strikes // against it. // Client->Servers[sc->ServerReference].WindowReset = 0; // // Update the instance receive counters for the Server // NdisAcquireSpinLock( &OpenP->SpinLock ); ++Client->Servers[sc->ServerReference].Counters->Receives; NdisReleaseSpinLock( &OpenP->SpinLock ); if ( Args->DataChecking == TRUE ) { if (( pi->PacketSize - sizeof( STRESS_PACKET )) > 0 ) { TpStressCheckPacketData( OpenP, MacReceiveContext, sc->DataBufOffset, pi->PacketSize, Client->Servers[sc->ServerReference].Counters ); } } } break; // // A STATS_REQ packet is a request by the client at the end of // a stress test for the server to return the statistics. // case STATS_REQ: // // Is this packet really destined for us, check that the // destination address matches the local card address we // queried and stored in the OPEN_BLOCK. // if ( RtlCompareMemory( DestAddr, OpenP->StationAddress, OpenP->Media->AddressLen ) != OpenP->Media->AddressLen ) { // // the destination address does not match the local card // address, we should never have received this packet! // NdisAcquireSpinLock( &OpenP->SpinLock ); ++OpenP->GlobalCounters->InvalidPacketRecs; NdisReleaseSpinLock( &OpenP->SpinLock ); // // This packet is a Statistics request from a Client. // Are we a Server?, // } else if ( Args->MemberType == TP_CLIENT ) { // // No! We are not a Server, ignore this packet. // Status = NDIS_STATUS_NOT_RECOGNIZED; // // Is this a client we have previously registered with? // } else if (( RtlCompareMemory( SrcAddr, Server->Clients[sc->ClientReference].Address, OpenP->Media->AddressLen ) != (ULONG)OpenP->Media->AddressLen ) || ( pi->SrcInstance != Server->Clients[sc->ClientReference].ClientInstance )) { // // No! We should ignore this packet. // Status = NDIS_STATUS_NOT_RECOGNIZED; // // Is this packet destined for our open instance or another // open instance on the same card? // } else if (( pi->DestInstance != OpenP->OpenInstance ) && ( RtlCompareMemory( SrcAddr, Server->Clients[sc->ClientReference].Address, OpenP->Media->AddressLen ) == (ULONG)OpenP->Media->AddressLen )) { // // This packet is for some other open instance, ignore it. // Status = NDIS_STATUS_NOT_RECOGNIZED; } else { // // We need to respond to the client's request for the // test statistics, so create a STATS_RESP packet, // Packet = TpStressCreatePacket( OpenP, Server->PacketHandle, KNOWN, pi->SrcInstance, OpenP->OpenInstance, STATS_RESP, Args->ResponseType, SrcAddr, sizeof( STRESS_PACKET ) + sizeof( INSTANCE_COUNTERS ) + sizeof( GLOBAL_COUNTERS ), // PacketSize sizeof( STRESS_PACKET ) + sizeof( INSTANCE_COUNTERS ) + sizeof( GLOBAL_COUNTERS ), // BufferSize sc->SequenceNumber, sc->SequenceNumber, sc->ClientReference, sc->ServerReference, FALSE ); if ( Packet == NULL ) { IF_TPDBG(TP_DEBUG_RESOURCES) { TpPrint0("TpStressReceive: failed to create STATS_RESP Packet\n"); } } else { // // Write the statistics into the packet, // TpWriteServerStatistics( OpenP, Packet, &Server->Clients[sc->ClientReference] ); if ( sc->SequenceNumber == 0 ) { // // Maybe instead of checking the SequenceNumber is // zero, the first packet, we should have a flag in // the server for this in case we miss the first // STATS_REQ packet. // TpPrintServerStatistics( OpenP, &Server->Clients[sc->ClientReference] ); } // // And send it back to the Client. // TpStressSend( OpenP,Packet,NULL ); } } break; // // A STATS_RESP packet is the server responding to a clients // request for stress statistics. The stats a bundled in the // data field of the packet. The client will read them into // the local buffer and discard the packet. // case STATS_RESP: // // Is this packet really destined for us, check that the // destination address matches the local card address we // queried and stored in the OPEN_BLOCK. // if ( RtlCompareMemory( DestAddr, OpenP->StationAddress, OpenP->Media->AddressLen ) != OpenP->Media->AddressLen ) { // // the destination address does not match the local card // address, we should never have received this packet! // NdisAcquireSpinLock( &OpenP->SpinLock ); ++OpenP->GlobalCounters->InvalidPacketRecs; NdisReleaseSpinLock( &OpenP->SpinLock ); // // This packet is a Statistics response from a Server. // Are we a Client? // } else if ( Args->MemberType == TP_SERVER ) { // // No! We are not a Client, ignore this packet. // Status = NDIS_STATUS_NOT_RECOGNIZED; // // Is this a Server that has previously registered with us? // } else if (( RtlCompareMemory( SrcAddr, Client->Servers[sc->ServerReference].Address, OpenP->Media->AddressLen) != (ULONG)OpenP->Media->AddressLen ) || ( pi->SrcInstance != Client->Servers[sc->ServerReference].ServerInstance )) { // // No! We should ignore this packet. // Status = NDIS_STATUS_NOT_RECOGNIZED; // // Is this packet destined for our open instance or another // open instance on the same card? // } else if (( pi->DestInstance != OpenP->OpenInstance ) && ( RtlCompareMemory( SrcAddr, Client->Servers[sc->ServerReference].Address, OpenP->Media->AddressLen) == (ULONG)OpenP->Media->AddressLen )) { // // This packet is for some other open instance, ignore it. // Status = NDIS_STATUS_NOT_RECOGNIZED; } else { // // Copy the server's stats to the Stress Results buffer. // TpCopyServerStatistics( OpenP, LookaheadBuffer, sc->ServerReference ); } break; // // AN END_REQ packet is a notification by a client that the stress // test has completed. The server decrements the number of clients, // and discards the packet. // case END_REQ: { UINT i; // // Is this packet really destined for us, check that the // destination address matches the local card address we // queried and stored in the OPEN_BLOCK. // if ( RtlCompareMemory( DestAddr, OpenP->StationAddress, OpenP->Media->AddressLen ) != OpenP->Media->AddressLen ) { // // the destination address does not match the local card // address, we should never have received this packet! // NdisAcquireSpinLock( &OpenP->SpinLock ); ++OpenP->GlobalCounters->InvalidPacketRecs; NdisReleaseSpinLock( &OpenP->SpinLock ); // // This packet is an end request from a Client. Are we a Server?, // } else if ( Args->MemberType == TP_CLIENT ) { // // No! We are not a Server, ignote this packet. // Status = NDIS_STATUS_NOT_RECOGNIZED; // // Is this a client we have previously registered with? // } else if (( RtlCompareMemory( SrcAddr, Server->Clients[sc->ClientReference].Address, OpenP->Media->AddressLen) != (ULONG)OpenP->Media->AddressLen ) || ( pi->SrcInstance != Server->Clients[sc->ClientReference].ClientInstance )) { // // No! We should ignore this packet. // Status = NDIS_STATUS_NOT_RECOGNIZED; // // Is this packet destined for our open instance or another // open instance on the same card? // } else if (( pi->DestInstance != OpenP->OpenInstance ) && ( RtlCompareMemory( SrcAddr, Server->Clients[sc->ClientReference].Address, OpenP->Media->AddressLen) == (ULONG)OpenP->Media->AddressLen)) { // // This packet is for some other open instance, ignore it. // Status = NDIS_STATUS_NOT_RECOGNIZED; } else { if ( Server->Clients[sc->ClientReference].TestEnding == FALSE ) { Server->Clients[sc->ClientReference].TestEnding = TRUE; --Server->ActiveClients; } // // If we are running as only a server, and there are packets // remaining in the Pend Queue, display them to the debug // screen. // if (( Args->MemberType == TP_SERVER ) && ( OpenP->Stress->Pend->PendingPackets != 0 )) { // // There are packets in the pend queue, so print out // the packet addresses and break. // IF_TPDBG( TP_DEBUG_DPC ) { TpPrint1("TpStressEndDpc: The following %d packets are still in the\n", OpenP->Stress->Pend->PendingPackets); TpPrint1(" Server's Pend Queue for Open Instance %d.\n", OpenP->OpenInstance); TpPrint1(" Pend Queue = %lX\n\n", OpenP->Stress->Pend); for ( i=0 ; iStress->Pend->Packets[i] != NULL ) && ( OpenP->Stress->Pend->Packets[i] != (PNDIS_PACKET)-1 )) { TpPrint1("\t\t%lX\n", OpenP->Stress->Pend->Packets[i]); } } TpBreakPoint(); // // And set the PendingPackets counter to zero, so // we will not print this message on the remainder // of the END_REQ packets that we receive. // OpenP->Stress->Pend->PendingPackets = 0; } TpInitializePending( OpenP->Stress->Pend ); } } break; } default: IF_TPDBG ( TP_DEBUG_DPC ) { TpPrint0("TpStressReceive: Unknown Packet Protocol\n"); } NdisAcquireSpinLock( &OpenP->SpinLock ); ++OpenP->GlobalCounters->CorruptRecs; NdisReleaseSpinLock( &OpenP->SpinLock ); Status = NDIS_STATUS_NOT_RECOGNIZED; } return Status; } VOID TpStressReceiveComplete( IN NDIS_HANDLE ProtocolBindingContext ) /*++ Routine Description: Arguments: Return Value: --*/ { POPEN_BLOCK OpenP = ((POPEN_BLOCK)ProtocolBindingContext); ULONG i; if (( OpenP->Stress != NULL ) && ( OpenP->Stress->Client != NULL )) { for ( i=0;iStress->Client->Servers[i].Counters != NULL ) { NdisAcquireSpinLock( &OpenP->SpinLock ); ++OpenP->Stress->Client->Servers[i].Counters->ReceiveComps; NdisReleaseSpinLock( &OpenP->SpinLock ); } } } if (( OpenP->Stress != NULL ) && ( OpenP->Stress->Server != NULL )) { for ( i=0;iStress->Server->Clients[i].Counters != NULL ) { NdisAcquireSpinLock( &OpenP->SpinLock ); ++OpenP->Stress->Server->Clients[i].Counters->ReceiveComps; NdisReleaseSpinLock( &OpenP->SpinLock ); } } } return; }