mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2164 lines
59 KiB
2164 lines
59 KiB
/*++
|
|
|
|
Copyright (c) 1990 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
packet.c
|
|
|
|
Abstract:
|
|
|
|
simple protocol to test the NDIS wrapper.
|
|
|
|
Author:
|
|
|
|
Tom Adams (tomad) 14-Jul-1990
|
|
|
|
Environment:
|
|
|
|
Kernel mode, FSD
|
|
|
|
Revision History:
|
|
|
|
Sanjeev Katariya (sanjeevk) 3-24-1993
|
|
1. Corrected TpStressCreatePacket() to allocate the first buffer in a packet of correct
|
|
size. Added functionality to work with discontiguous physical data(Buffer chains)
|
|
2. Changed functions to reflect the data structure change in
|
|
STRESS_BLOCK
|
|
a. TpStressCreateTruncatedPacket()
|
|
b. TpStressSetTruncatedPacketInfo()
|
|
|
|
--*/
|
|
|
|
#include <ndis.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "tpdefs.h"
|
|
#include "media.h"
|
|
#include "tpprocs.h"
|
|
|
|
|
|
|
|
VOID
|
|
TpSetRandom(
|
|
VOID
|
|
)
|
|
{
|
|
LARGE_INTEGER TmpTime;
|
|
|
|
//
|
|
// Uses the system clock to return a random number.
|
|
// The randomness of the number is subject to some debate.
|
|
// The time increments in exact intervals; for example on
|
|
// a 386 it is 300000. We want to shift over enough that
|
|
// the LSB changes rapidly, but not too much so that we
|
|
// can only handle a small Range.
|
|
//
|
|
|
|
KeQuerySystemTime( &TmpTime );
|
|
srand( TmpTime.LowTime >> 10 );
|
|
}
|
|
|
|
|
|
UINT
|
|
TpGetRandom(
|
|
IN UINT Low,
|
|
IN UINT High
|
|
)
|
|
{
|
|
UINT Range = High - Low + 1;
|
|
|
|
return (UINT)(( rand() % Range ) + Low );
|
|
}
|
|
|
|
|
|
PTP_PACKET
|
|
TpStressInitPacketHeader(
|
|
IN POPEN_BLOCK OpenP,
|
|
IN INT TmpBufSize,
|
|
IN INT PacketSize,
|
|
IN PUCHAR DestAddr,
|
|
IN PUCHAR SrcAddr,
|
|
IN UCHAR DestInstance,
|
|
IN UCHAR SrcInstance,
|
|
IN UCHAR PacketProtocol,
|
|
IN UCHAR ResponseType,
|
|
IN ULONG DataBufOffset,
|
|
IN ULONG SequenceNumber,
|
|
IN ULONG MaxSequenceNumber,
|
|
IN UCHAR ClientReference,
|
|
IN UCHAR ServerReference,
|
|
IN BOOLEAN DataChecking
|
|
)
|
|
{
|
|
NDIS_STATUS Status;
|
|
PTP_PACKET TmpBuffer;
|
|
|
|
//
|
|
// Allocate a buffer to hold the packet header information.
|
|
//
|
|
|
|
Status = NdisAllocateMemory(
|
|
(PVOID *)&TmpBuffer,
|
|
TmpBufSize,
|
|
0,
|
|
HighestAddress
|
|
);
|
|
|
|
if ( Status != NDIS_STATUS_SUCCESS ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressInitPacketHeader: failed to allocate TmpBuffer\n");
|
|
}
|
|
return NULL;
|
|
} else {
|
|
NdisZeroMemory( (PVOID)TmpBuffer,TmpBufSize );
|
|
}
|
|
|
|
//
|
|
// and stuff the packet header info into it.
|
|
//
|
|
|
|
if ( !TpInitMediaHeader(
|
|
&TmpBuffer->u.S.hdr,
|
|
OpenP->Media,
|
|
DestAddr,
|
|
SrcAddr,
|
|
PacketSize
|
|
)) {
|
|
NdisFreeMemory( TmpBuffer,0,0 );
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// initialize the Stress header information.
|
|
//
|
|
|
|
TmpBuffer->u.S.hdr.info.Signature = STRESS_PACKET_SIGNATURE;
|
|
TmpBuffer->u.S.hdr.info.PacketSize = PacketSize;
|
|
TmpBuffer->u.S.hdr.info.DestInstance = DestInstance;
|
|
TmpBuffer->u.S.hdr.info.SrcInstance = SrcInstance;
|
|
TmpBuffer->u.S.hdr.info.PacketType = STRESS_PACKET_TYPE;
|
|
TmpBuffer->u.S.hdr.info.u.PacketProtocol = PacketProtocol;
|
|
TmpBuffer->u.S.hdr.info.CheckSum = 0xFFFFFFFF;
|
|
|
|
TmpBuffer->u.S.sc.DataBufOffset = DataBufOffset;
|
|
TmpBuffer->u.S.sc.SequenceNumber = SequenceNumber;
|
|
TmpBuffer->u.S.sc.MaxSequenceNumber = MaxSequenceNumber;
|
|
TmpBuffer->u.S.sc.ResponseType = ResponseType;
|
|
TmpBuffer->u.S.sc.ClientReference = ClientReference;
|
|
TmpBuffer->u.S.sc.ServerReference = ServerReference;
|
|
TmpBuffer->u.S.sc.DataChecking = DataChecking;
|
|
|
|
return TmpBuffer;
|
|
}
|
|
|
|
|
|
PNDIS_PACKET
|
|
TpStressCreatePacket(
|
|
IN POPEN_BLOCK OpenP,
|
|
IN NDIS_HANDLE PacketHandle,
|
|
IN PACKET_MAKEUP PacketMakeUp,
|
|
IN UCHAR DestInstance,
|
|
IN UCHAR SrcInstance,
|
|
IN UCHAR PacketProtocol,
|
|
IN UCHAR ResponseType,
|
|
IN PUCHAR DestAddr,
|
|
IN INT PacketSize,
|
|
IN INT BufferSize,
|
|
IN ULONG SequenceNumber,
|
|
IN ULONG MaxSequenceNumber,
|
|
IN UCHAR ClientReference,
|
|
IN UCHAR ServerReference,
|
|
IN BOOLEAN DataChecking
|
|
)
|
|
|
|
{
|
|
NDIS_STATUS Status ;
|
|
PNDIS_PACKET Packet ;
|
|
PNDIS_BUFFER Buffer ;
|
|
PPROTOCOL_RESERVED ProtRes ;
|
|
PUCHAR DataBufOffset1 ;
|
|
PUCHAR DataBufOffset2 ;
|
|
PUCHAR TmpBuf ;
|
|
PUCHAR TmpBufDataOffset ;
|
|
ULONG RandomOffset ;
|
|
INT TmpBufSize ;
|
|
INT TmpBufDataSize ;
|
|
INT MdlSize ;
|
|
INT NumBuffers ;
|
|
INT i ;
|
|
INT RemainingHdr ;
|
|
INT RemainingPkt ;
|
|
BOOLEAN FirstBuffer = TRUE ;
|
|
BOOLEAN Pulse = TRUE ;
|
|
|
|
//
|
|
// Using a DISCONTIGUOUS allocation scheme in the CLIENT pool case
|
|
//
|
|
|
|
//
|
|
// Comments : SanjeevK
|
|
//
|
|
// BRIEF WORKING
|
|
//
|
|
// This function simply allocates a packet from the packet pool and
|
|
// is reponsible for putting the packet together. The data portion of the
|
|
// packet is directly used from the the DataBuffers associated with the
|
|
// stress block. The packet creation is given the option of using
|
|
// a known buffer size mapping(which generates a definite number of buffers
|
|
// since the packet size is known) or can simply randomly choose how big
|
|
// or small it would like to make the buffer sizes. This option is characterized
|
|
// by the parameter KNOWN.
|
|
// The packet is created by created an initial header, setting the appropriate fields
|
|
// and then linking in the data buffers. The total length of the created packet is
|
|
// controlled by the PacketSize
|
|
//
|
|
// The variables and their boundary sizes are given below:
|
|
//
|
|
// <-------------------- PacketSize ------------------->[STRESS_PACKET,MAX_PACKET_LENGTH]
|
|
//
|
|
// <------ TmpBufSize ---->[STRESS_PACKET,max(2*STRESS_PACKET,PacketSize)]
|
|
// for PacketMakeUp != KNOWN
|
|
//
|
|
// MEDIA_FRAME,PacketSize]
|
|
//
|
|
// ----------------------------------------------------
|
|
// | STRESS_PACKET+ | Additional DATA |
|
|
// | Random Data Size | |
|
|
// ----------------------- ----------------------------
|
|
//
|
|
// ---.....-----....----....---
|
|
// | |
|
|
// |
|
|
// ---.....-----....----....---
|
|
//
|
|
// <-------- BufferSize -------->[MediaHeaderSize, max(STRESS_PACKET,PacketSize)]
|
|
//
|
|
//
|
|
|
|
|
|
|
|
//
|
|
// Make sure that this is a legal packetsize, and buffersize if
|
|
// PacketMakeUp = KNOWN, if not use a default smallest or largest
|
|
// size allowable.
|
|
//
|
|
if ( PacketSize < sizeof( STRESS_PACKET )) {
|
|
PacketSize = sizeof( STRESS_PACKET );
|
|
} else if ( PacketSize > (INT)OpenP->Media->MaxPacketLen ) {
|
|
PacketSize = OpenP->Media->MaxPacketLen;
|
|
}
|
|
|
|
|
|
//
|
|
// Check the condition for KNOWN packet type.
|
|
// If TRUE ensure that the BufferSize is between
|
|
// MediaHeaderSize and max(STRESS_PACKET,PacketSize).
|
|
//
|
|
if ( PacketMakeUp == KNOWN ) {
|
|
if ( BufferSize < OpenP->Media->HeaderSize ) {
|
|
BufferSize = OpenP->Media->HeaderSize ;
|
|
} else if ( BufferSize > PacketSize ) {
|
|
BufferSize = PacketSize;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
// Allocate a PACKET out of the packet pool
|
|
//
|
|
NdisAllocatePacket( &Status,&Packet,PacketHandle );
|
|
|
|
if ( Status != NDIS_STATUS_SUCCESS ) {
|
|
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
|
|
if( OpenP->Stress->Arguments != NULL ) {
|
|
|
|
//
|
|
// This is the special case where we realize that we will run out
|
|
// of packets very quickly since the packet pool is 200 only. ONLY
|
|
// in this case will we not issue a debug message to the screen
|
|
//
|
|
if ( (OpenP->Stress->Arguments->WindowEnabled == FALSE ) &&
|
|
(OpenP->Stress->Arguments->ResponseType == ACK_10_TIMES )
|
|
) return NULL;
|
|
|
|
}
|
|
|
|
TpPrint1("TpStressCreatePacket: NdisAllocatePacket failed %s\n",
|
|
TpGetStatus( Status ));
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
//
|
|
// Mark the Packet's protocol reserved section to NULL to indicate
|
|
// that this packet was not allocated from a TP_TRANSMIT_POOL, and set
|
|
// the InstanceCounters to NULL. TpStressCreateTransmitPool and the
|
|
// Packet Set Info routines will set them if applicable.
|
|
//
|
|
|
|
ProtRes = PROT_RES( Packet );
|
|
ProtRes->Pool.TransmitPool = NULL;
|
|
ProtRes->InstanceCounters = NULL;
|
|
|
|
//
|
|
// Now select the random size of the header buffer which will be used to
|
|
// hold the Frame Header, the Test Protocol Packet Header, and a random
|
|
// chunk of the actual frame data.
|
|
//
|
|
// TmpBufSize = The random size of the header buffer
|
|
// where
|
|
// Header buffer = Frame Header +
|
|
// Test Protocol Packet Header +
|
|
// A random chunk of the actual frame data.
|
|
//
|
|
//
|
|
if ( PacketMakeUp != KNOWN ) { // ( PacketMakeUp == RAND|ONES|ZEROS|SMALL )
|
|
|
|
//
|
|
// Sanjeevk : Comment
|
|
//
|
|
// The TmpBufSize being within the bounds, STRESS_PACKET and 2*STRESS_PACKET
|
|
// will quite comfortably accomodate the MEDIA_HEADER. This restriction must
|
|
// be followed closely since this is the first buffer in the packet chain
|
|
//
|
|
|
|
TmpBufSize = TpGetRandom(
|
|
sizeof( STRESS_PACKET ),
|
|
( 2 * sizeof( STRESS_PACKET ))
|
|
);
|
|
|
|
if ( TmpBufSize > PacketSize ) {
|
|
TmpBufSize = PacketSize;
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
//
|
|
// Packet_MakeUp is KNOWN, i.e. we can calculate the number of buffers
|
|
// from the size of the packet and the given buffersize
|
|
// We must however determine the number of buffers that
|
|
// will fit in the TP_PACKET_HEADER section of the packet, and how
|
|
// large that header will actually be.
|
|
//
|
|
// At this point BufferSize is between MediaHeaderSize
|
|
// and max(PacketSize,STRESS_PACKET)
|
|
//
|
|
if ( BufferSize >= sizeof( STRESS_PACKET ) ) {
|
|
|
|
//
|
|
// If the BufferSize is greater than the size needed to fit the
|
|
// packet header then we will just allocate one chunk of memory
|
|
// of that size, and tack on some additional data at the the end.
|
|
//
|
|
|
|
TmpBufSize = BufferSize;
|
|
RemainingPkt = PacketSize % BufferSize;
|
|
RemainingHdr = 0;
|
|
NumBuffers = 1;
|
|
|
|
} else {
|
|
|
|
//
|
|
// The BufferSize is smaller that then packet header, so we must
|
|
// determine the number of buffers that will fit in the header,
|
|
// and, if there is any remainder, how big it is.
|
|
//
|
|
|
|
NumBuffers = sizeof( STRESS_PACKET ) / BufferSize;
|
|
RemainingHdr = sizeof( STRESS_PACKET ) % BufferSize;
|
|
RemainingPkt = PacketSize % BufferSize;
|
|
|
|
//
|
|
// There are three possible cases here that must be handled.
|
|
//
|
|
// 1) only X buffers are needed to create the packet header
|
|
//
|
|
// 2) X buffers, and a remainder buffer are needed to create the
|
|
// packet header.
|
|
// a) the remainder is the rest of the actual packet.
|
|
//
|
|
// b) the remainder is the rest of the header. (and the
|
|
// packet)
|
|
//
|
|
// [-------------------------------------]
|
|
// packet header
|
|
//
|
|
// 1) [---------][---------][- -][---------]
|
|
// buf_1 buf_2 ... buf_X
|
|
//
|
|
// 2a) [-------][-------][- -][-------][--------------]
|
|
// buf_1 buf_2 ... buf_X remaining packet
|
|
//
|
|
// 2b) [-------][-------][- -][-------][---]
|
|
// buf_1 buf_2 ... buf_X remaining header
|
|
//
|
|
|
|
if (((NumBuffers+1) * BufferSize) <= PacketSize ) {
|
|
|
|
//
|
|
// The packet header can fit in NumBuffers+1 buffers.
|
|
//
|
|
|
|
TmpBufSize = (( NumBuffers + 1 ) * BufferSize );
|
|
NumBuffers++;
|
|
RemainingHdr = 0;
|
|
|
|
} else if ((( NumBuffers * BufferSize ) + RemainingPkt ) == PacketSize ) {
|
|
|
|
//
|
|
// The packet header can fit in a NumBuffers buffers plus the
|
|
// remainder of the packet. This is the entire packet.
|
|
//
|
|
|
|
TmpBufSize = ( NumBuffers * BufferSize ) + RemainingPkt ;
|
|
RemainingHdr = RemainingPkt;
|
|
RemainingPkt = 0;
|
|
|
|
} else {
|
|
|
|
//
|
|
// The packet header can fit in a NumBuffers buffers plus the
|
|
// remainder of the header. This is the entire packet.
|
|
//
|
|
|
|
TmpBufSize = (( NumBuffers * BufferSize ) + RemainingHdr );
|
|
TP_ASSERT( RemainingHdr != RemainingPkt );
|
|
RemainingPkt = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
RandomOffset = TpGetRandom( 0,OpenP->Media->MaxPacketLen );
|
|
|
|
TmpBuf = (PUCHAR)TpStressInitPacketHeader(
|
|
OpenP,
|
|
TmpBufSize,
|
|
PacketSize,
|
|
DestAddr,
|
|
OpenP->StationAddress,
|
|
DestInstance,
|
|
SrcInstance,
|
|
PacketProtocol,
|
|
ResponseType,
|
|
RandomOffset,
|
|
SequenceNumber,
|
|
MaxSequenceNumber,
|
|
ClientReference,
|
|
ServerReference,
|
|
DataChecking
|
|
);
|
|
|
|
if ( TmpBuf == NULL ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreatePacket: failed to initialize Packet Header\n");
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
((PTP_PACKET)TmpBuf)->u.S.sc.CheckSum =
|
|
|
|
TpSetCheckSum(
|
|
(PUCHAR)&((PTP_PACKET)TmpBuf)->u.S.hdr.info,
|
|
sizeof( STRESS_PACKET ) -
|
|
// ( sizeof( ULONG ) + OpenP->Media->HeaderSize )
|
|
( sizeof(ULONG) + sizeof(MEDIA_HEADER))
|
|
);
|
|
|
|
//
|
|
// Now setup the remainder of TmpBuf with a random amount of data
|
|
// from the data buffer.
|
|
//
|
|
// DataBufOffset1,2 is the random offset into the data buffer that will be
|
|
// used to fill the packet.
|
|
//
|
|
|
|
DataBufOffset1 = OpenP->Stress->DataBuffer[0] + RandomOffset;
|
|
DataBufOffset2 = OpenP->Stress->DataBuffer[1] + RandomOffset;
|
|
|
|
//
|
|
// TmpBufDataSize is the remainder of the TmpBuf that will be filled with
|
|
// data from the DataBuf
|
|
//
|
|
|
|
TmpBufDataSize = TmpBufSize - sizeof( STRESS_PACKET );
|
|
|
|
if ( TmpBufDataSize > 0 ) {
|
|
|
|
TmpBufDataOffset = TmpBuf + sizeof( STRESS_PACKET );
|
|
|
|
RtlMoveMemory(
|
|
TmpBufDataOffset,
|
|
DataBufOffset1,
|
|
TmpBufDataSize
|
|
);
|
|
|
|
DataBufOffset1 += TmpBufDataSize;
|
|
DataBufOffset2 += TmpBufDataSize;
|
|
|
|
} else {
|
|
TP_ASSERT( TmpBufDataSize >= 0 );
|
|
}
|
|
|
|
|
|
//
|
|
// Sanjeevk : Comment
|
|
//
|
|
// We now simply proceed to create the packet. We start of by using the TmpBuf we created
|
|
// and forming the header and then tack on the data buffer we allocated. MDL's are allocated
|
|
// as we go thru the data portions
|
|
//
|
|
// NOTE: To make the data discontiguous, we are using the following sheme
|
|
//
|
|
// We have allocated two data buffers and filled them in with identical contents
|
|
//
|
|
// LOC.A
|
|
// --------------------------------
|
|
// BUFFER 1 | 00 01 02 03 .....FF 00 01 ..... |
|
|
// --------------------------------
|
|
// LOC.B
|
|
// ---------------------------------
|
|
// BUFFER 2 | 00 01 02 03 .....FF 00 01 ..... |
|
|
// ---------------------------------
|
|
// ^
|
|
// |
|
|
// COMMON OFFSET
|
|
// We now maintain a common offset into both buffers and simply switch between the two
|
|
// locations.
|
|
//
|
|
// LOGIC
|
|
// 1. Get location A at COMMON OFFSET from buffer 1. Take length Y. Obtain a MDL
|
|
// and chain than buffer onto the packet
|
|
// 2. Increment the COMMON OFFSET by length Y
|
|
// 3. Get location B at COMMON OFFSET from buffer 2. Take length X. Obtain a MDL
|
|
// and chain than buffer onto the packet
|
|
// 4. Increment the COMMON OFFSET by length X
|
|
// 5. Repeat steps 1,2,3 and 4 till you have reached the end of the total packet
|
|
// length to be mapped(ie. incremental length = 0 )
|
|
//
|
|
// This makes the data verification an easy process since the sequence of data bytes
|
|
// stays the same although now the data areas are no longer contiguous.
|
|
//
|
|
switch( PacketMakeUp ) {
|
|
|
|
case RAND:
|
|
|
|
//
|
|
// Slice up the TmpBuf containing the Frame Header and the
|
|
// TP_PACKET_HEADER, and create the beginning of the PACKET.
|
|
//
|
|
|
|
while ( TmpBufSize > 0 ) {
|
|
|
|
MdlSize = TpGetRandom(
|
|
0,
|
|
OpenP->Media->MaxPacketLen /
|
|
( 2 * OpenP->Environment->RandomBufferNumber )
|
|
);
|
|
|
|
if ( MdlSize > TmpBufSize ) {
|
|
MdlSize = TmpBufSize;
|
|
}
|
|
|
|
|
|
//
|
|
// STARTCHANGE
|
|
//
|
|
//
|
|
// Ensure that the first buffer in the packet has length >= size
|
|
// of the media header. This is an NDIS 3.0 requirement for
|
|
// the sake of maintaining performance
|
|
//
|
|
if ( FirstBuffer ) {
|
|
if ( MdlSize < OpenP->Media->HeaderSize ) {
|
|
MdlSize = OpenP->Media->HeaderSize;
|
|
}
|
|
FirstBuffer = FALSE;
|
|
}
|
|
//
|
|
// STOPCHANGE
|
|
//
|
|
|
|
Buffer = TpAllocateBuffer( TmpBuf,MdlSize );
|
|
|
|
if ( Buffer == NULL ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreatePacket: failed to create the MDL\n");
|
|
}
|
|
TpStressFreePacket( Packet );
|
|
return NULL;
|
|
}
|
|
|
|
NdisChainBufferAtBack( Packet,Buffer );
|
|
|
|
TmpBuf += MdlSize;
|
|
TmpBufSize -= MdlSize;
|
|
PacketSize -= MdlSize;
|
|
}
|
|
|
|
//
|
|
// Now convert the data section of the into NDIS_BUFFERs and add to the
|
|
// end of the PACKET.
|
|
//
|
|
|
|
while ( PacketSize > 0 ) {
|
|
|
|
MdlSize = TpGetRandom(
|
|
0,
|
|
OpenP->Media->MaxPacketLen /
|
|
( 2 * OpenP->Environment->RandomBufferNumber )
|
|
);
|
|
|
|
if ( MdlSize > PacketSize ) {
|
|
MdlSize = PacketSize;
|
|
}
|
|
|
|
//
|
|
// Using DISCONTIGUITY
|
|
//
|
|
if ( Pulse ) {
|
|
Buffer = TpAllocateBuffer( DataBufOffset1,MdlSize );
|
|
Pulse = FALSE;
|
|
} else {
|
|
Buffer = TpAllocateBuffer( DataBufOffset2,MdlSize );
|
|
Pulse = TRUE;
|
|
}
|
|
|
|
|
|
if ( Buffer == NULL ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreatePacket: failed to create the MDL\n");
|
|
}
|
|
TpStressFreePacket( Packet );
|
|
return NULL;
|
|
}
|
|
|
|
NdisChainBufferAtBack( Packet,Buffer );
|
|
|
|
PacketSize -= MdlSize;
|
|
DataBufOffset1 += (ULONG)MdlSize;
|
|
DataBufOffset2 += (ULONG)MdlSize;
|
|
}
|
|
break;
|
|
|
|
case ZEROS:
|
|
|
|
//
|
|
// Slice up the TmpBuf containing the Frame Header and the
|
|
// TP_PACKET_HEADER, and create the beginning of the PACKET.
|
|
//
|
|
|
|
while (TmpBufSize > 0) {
|
|
|
|
if ( ( MdlSize = TpGetRandom( 0,3 ) ) != 0 ) {
|
|
MdlSize = TpGetRandom(
|
|
0,
|
|
OpenP->Media->MaxPacketLen /
|
|
( 2 * OpenP->Environment->RandomBufferNumber )
|
|
);
|
|
}
|
|
if ( MdlSize > TmpBufSize ) {
|
|
MdlSize = TmpBufSize;
|
|
}
|
|
//
|
|
// STARTCHANGE
|
|
//
|
|
//
|
|
// Ensure that the first buffer in the pakcet has length >= size
|
|
// of the media header. This is an NDIS 3.0 requirement for
|
|
// the sake of maintaining performance
|
|
//
|
|
if ( FirstBuffer ) {
|
|
if ( MdlSize < OpenP->Media->HeaderSize ) {
|
|
MdlSize = OpenP->Media->HeaderSize;
|
|
}
|
|
FirstBuffer = FALSE;
|
|
}
|
|
//
|
|
// STOPCHANGE
|
|
//
|
|
Buffer = TpAllocateBuffer( TmpBuf,MdlSize );
|
|
|
|
if ( Buffer == NULL ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreatePacket: failed to create the MDL\n");
|
|
}
|
|
TpStressFreePacket( Packet );
|
|
return NULL;
|
|
}
|
|
|
|
NdisChainBufferAtBack( Packet,Buffer );
|
|
|
|
TmpBuf += MdlSize;
|
|
TmpBufSize -= MdlSize;
|
|
PacketSize -= MdlSize;
|
|
}
|
|
|
|
//
|
|
// Now convert the data section of the into NDIS_BUFFERs and add to the
|
|
// end of the PACKET.
|
|
//
|
|
|
|
while ( PacketSize > 0 ) {
|
|
|
|
if ( ( MdlSize = TpGetRandom( 0,3 ) ) != 0 ) {
|
|
MdlSize = TpGetRandom(
|
|
0,
|
|
OpenP->Media->MaxPacketLen /
|
|
( 2 * OpenP->Environment->RandomBufferNumber )
|
|
);
|
|
}
|
|
|
|
if ( MdlSize > PacketSize ) {
|
|
MdlSize = PacketSize;
|
|
}
|
|
|
|
|
|
//
|
|
// Using DISCONTIGUITY
|
|
//
|
|
if ( Pulse ) {
|
|
Buffer = TpAllocateBuffer( DataBufOffset1,MdlSize );
|
|
Pulse = FALSE;
|
|
} else {
|
|
Buffer = TpAllocateBuffer( DataBufOffset2,MdlSize );
|
|
Pulse = TRUE;
|
|
}
|
|
|
|
|
|
if ( Buffer == NULL ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreatePacket: failed to create the MDL\n");
|
|
}
|
|
TpStressFreePacket( Packet );
|
|
return NULL;
|
|
}
|
|
|
|
NdisChainBufferAtBack( Packet,Buffer );
|
|
|
|
PacketSize -= MdlSize;
|
|
DataBufOffset1 += (ULONG)MdlSize;
|
|
DataBufOffset2 += (ULONG)MdlSize;
|
|
}
|
|
break;
|
|
|
|
case ONES:
|
|
|
|
//
|
|
// Slice up the TmpBuf containing the Frame Header and the
|
|
// TP_PACKET_HEADER, and create the beginning of the PACKET.
|
|
//
|
|
|
|
while ( TmpBufSize > 0 ) {
|
|
|
|
if ( ( MdlSize = TpGetRandom( 0,3 ) ) != 1 ) {
|
|
MdlSize = TpGetRandom(
|
|
0,
|
|
OpenP->Media->MaxPacketLen /
|
|
( 2 * OpenP->Environment->RandomBufferNumber )
|
|
);
|
|
}
|
|
if ( MdlSize > TmpBufSize ) {
|
|
MdlSize = TmpBufSize;
|
|
}
|
|
|
|
//
|
|
// STARTCHANGE
|
|
//
|
|
//
|
|
// Ensure that the first buffer in the pakcet has length >= size
|
|
// of the media header. This is an NDIS 3.0 requirement for
|
|
// the sake of maintaining performance
|
|
//
|
|
if ( FirstBuffer ) {
|
|
if ( MdlSize < OpenP->Media->HeaderSize ) {
|
|
MdlSize = OpenP->Media->HeaderSize;
|
|
}
|
|
FirstBuffer = FALSE;
|
|
}
|
|
//
|
|
// STOPCHANGE
|
|
//
|
|
|
|
Buffer = TpAllocateBuffer( TmpBuf,MdlSize );
|
|
|
|
if ( Buffer == NULL ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreatePacket: failed to create the MDL\n");
|
|
}
|
|
TpStressFreePacket( Packet );
|
|
return NULL;
|
|
}
|
|
|
|
NdisChainBufferAtBack( Packet,Buffer );
|
|
|
|
TmpBuf += MdlSize;
|
|
TmpBufSize -= MdlSize;
|
|
PacketSize -= MdlSize;
|
|
}
|
|
|
|
//
|
|
// Now convert the data section of the into NDIS_BUFFERs and add to the
|
|
// end of the PACKET.
|
|
//
|
|
|
|
while ( PacketSize > 0 ) {
|
|
|
|
if ( ( MdlSize = TpGetRandom( 0,3 ) ) != 1 ) {
|
|
MdlSize = TpGetRandom(
|
|
0,
|
|
OpenP->Media->MaxPacketLen /
|
|
( 2 * OpenP->Environment->RandomBufferNumber )
|
|
);
|
|
}
|
|
|
|
if ( MdlSize > PacketSize ) {
|
|
MdlSize = PacketSize;
|
|
}
|
|
|
|
//
|
|
// Using DISCONTIGUITY
|
|
//
|
|
if ( Pulse ) {
|
|
Buffer = TpAllocateBuffer( DataBufOffset1,MdlSize );
|
|
Pulse = FALSE;
|
|
} else {
|
|
Buffer = TpAllocateBuffer( DataBufOffset2,MdlSize );
|
|
Pulse = TRUE;
|
|
}
|
|
|
|
if ( Buffer == NULL ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreatePacket: failed to create the MDL\n");
|
|
}
|
|
TpStressFreePacket( Packet );
|
|
return NULL;
|
|
}
|
|
|
|
NdisChainBufferAtBack( Packet,Buffer );
|
|
|
|
PacketSize -= MdlSize;
|
|
DataBufOffset1 += (ULONG)MdlSize;
|
|
DataBufOffset2 += (ULONG)MdlSize;
|
|
|
|
}
|
|
break;
|
|
|
|
case SMALL:
|
|
|
|
//
|
|
// Slice up the TmpBuf containing the Frame Header and the
|
|
// TP_PACKET_HEADER, and create the beginning of the PACKET.
|
|
//
|
|
|
|
while ( TmpBufSize > 0 ) {
|
|
|
|
MdlSize = TpGetRandom( 0,OpenP->Media->MaxPacketLen/50 );
|
|
|
|
if ( MdlSize > TmpBufSize ) {
|
|
MdlSize = TmpBufSize;
|
|
}
|
|
|
|
//
|
|
// STARTCHANGE
|
|
//
|
|
//
|
|
// Ensure that the first buffer in the pakcet has length >= size
|
|
// of the media header. This is an NDIS 3.0 requirement for
|
|
// the sake of maintaining performance
|
|
//
|
|
if ( FirstBuffer ) {
|
|
if ( MdlSize < OpenP->Media->HeaderSize ) {
|
|
MdlSize = OpenP->Media->HeaderSize;
|
|
}
|
|
FirstBuffer = FALSE;
|
|
}
|
|
//
|
|
// STOPCHANGE
|
|
//
|
|
|
|
Buffer = TpAllocateBuffer( TmpBuf,MdlSize );
|
|
|
|
if ( Buffer == NULL ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES) {
|
|
TpPrint0("TpStressCreatePacket: failed to create the MDL\n");
|
|
}
|
|
TpStressFreePacket( Packet );
|
|
return NULL;
|
|
}
|
|
|
|
NdisChainBufferAtBack( Packet,Buffer );
|
|
|
|
TmpBuf += MdlSize;
|
|
TmpBufSize -= MdlSize;
|
|
PacketSize -= MdlSize;
|
|
}
|
|
|
|
//
|
|
// Now convert the data section of the into NDIS_BUFFERs and add to the
|
|
// end of the PACKET.
|
|
//
|
|
|
|
while ( PacketSize > 0 ) {
|
|
|
|
MdlSize = TpGetRandom( 0,OpenP->Media->MaxPacketLen/50 );
|
|
|
|
if ( MdlSize > PacketSize ) {
|
|
MdlSize = PacketSize;
|
|
}
|
|
|
|
//
|
|
// Using DISCONTIGUITY
|
|
//
|
|
if ( Pulse ) {
|
|
Buffer = TpAllocateBuffer( DataBufOffset1,MdlSize );
|
|
Pulse = FALSE;
|
|
} else {
|
|
Buffer = TpAllocateBuffer( DataBufOffset2,MdlSize );
|
|
Pulse = TRUE;
|
|
}
|
|
|
|
if ( Buffer == NULL ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreatePacket: failed to create the MDL\n");
|
|
}
|
|
TpStressFreePacket( Packet );
|
|
return NULL;
|
|
}
|
|
|
|
NdisChainBufferAtBack( Packet,Buffer );
|
|
|
|
PacketSize -= MdlSize;
|
|
DataBufOffset1 += (ULONG)MdlSize;
|
|
DataBufOffset2 += (ULONG)MdlSize;
|
|
}
|
|
break;
|
|
|
|
case KNOWN:
|
|
|
|
|
|
for ( i=0;i<NumBuffers;i++ ) {
|
|
|
|
Buffer = TpAllocateBuffer( TmpBuf,BufferSize );
|
|
|
|
if ( Buffer == NULL ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreatePacket: failed to create the MDL\n");
|
|
}
|
|
TpStressFreePacket( Packet );
|
|
return NULL;
|
|
}
|
|
|
|
NdisChainBufferAtBack( Packet,Buffer );
|
|
|
|
TmpBuf += BufferSize;
|
|
PacketSize -= BufferSize;
|
|
}
|
|
|
|
if ( RemainingHdr > 0 ) {
|
|
|
|
Buffer = TpAllocateBuffer( TmpBuf,RemainingHdr );
|
|
|
|
if ( Buffer == NULL ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreatePacket: failed to create the MDL\n");
|
|
}
|
|
TpStressFreePacket( Packet );
|
|
return NULL;
|
|
}
|
|
|
|
NdisChainBufferAtBack( Packet,Buffer );
|
|
|
|
PacketSize -= RemainingHdr;
|
|
}
|
|
|
|
if ( PacketSize > 0 ) {
|
|
|
|
//
|
|
// Determine the number of remaining buffers, and if it exists,
|
|
// the size of the last buffer.
|
|
//
|
|
|
|
NumBuffers = PacketSize / BufferSize;
|
|
|
|
for (i=0;i<NumBuffers;i++ ) {
|
|
|
|
//
|
|
// Using DISCONTIGUITY
|
|
//
|
|
if ( Pulse ) {
|
|
Buffer = TpAllocateBuffer( DataBufOffset1,BufferSize );
|
|
Pulse = FALSE;
|
|
} else {
|
|
Buffer = TpAllocateBuffer( DataBufOffset2,BufferSize );
|
|
Pulse = TRUE;
|
|
}
|
|
|
|
if ( Buffer == NULL ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreatePacket: failed to create the MDL\n");
|
|
}
|
|
TpStressFreePacket( Packet );
|
|
return NULL;
|
|
}
|
|
|
|
NdisChainBufferAtBack( Packet,Buffer );
|
|
|
|
DataBufOffset1 += (ULONG)BufferSize;
|
|
DataBufOffset2 += (ULONG)BufferSize;
|
|
}
|
|
|
|
if ( RemainingPkt > 0 ) {
|
|
|
|
//
|
|
// Using DISCONTIGUITY
|
|
//
|
|
if ( Pulse ) {
|
|
Buffer = TpAllocateBuffer( DataBufOffset1,RemainingPkt );
|
|
Pulse = FALSE;
|
|
} else {
|
|
Buffer = TpAllocateBuffer( DataBufOffset2,RemainingPkt );
|
|
Pulse = TRUE;
|
|
}
|
|
|
|
if ( Buffer == NULL ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreatePacket: failed to create the MDL\n");
|
|
}
|
|
TpStressFreePacket( Packet );
|
|
return NULL;
|
|
}
|
|
|
|
NdisChainBufferAtBack( Packet,Buffer );
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreatePacket: unknown packet makeup\n");
|
|
}
|
|
return NULL;
|
|
}
|
|
return Packet;
|
|
}
|
|
|
|
|
|
PNDIS_PACKET
|
|
TpStressCreateTruncatedPacket(
|
|
IN POPEN_BLOCK OpenP,
|
|
IN NDIS_HANDLE PacketHandle,
|
|
IN UCHAR PacketProtocol,
|
|
IN UCHAR ResponseType
|
|
)
|
|
{
|
|
NDIS_STATUS Status;
|
|
PNDIS_PACKET Packet;
|
|
PNDIS_BUFFER Buffer;
|
|
PUCHAR TmpBuf;
|
|
PPROTOCOL_RESERVED ProtRes;
|
|
|
|
//
|
|
// Using a CONTIGUOUS allocation scheme in the SERVER pool
|
|
//
|
|
NdisAllocatePacket( &Status,&Packet,PacketHandle );
|
|
|
|
if ( Status != NDIS_STATUS_SUCCESS ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint1("TpStressCreatePacket: NdisAllocatePacket failed %s\n",
|
|
TpGetStatus( Status ));
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Mark the Protocol's reserved section to NULL to indicate that
|
|
// this packet was not allocated from a TP_TRANSMIT_POOL, and set
|
|
// the InstanceCounters to NULL. TpStressCreateTransmitPool and the
|
|
// Packet Set Info routines will set them if applicable.
|
|
//
|
|
|
|
ProtRes = PROT_RES( Packet );
|
|
ProtRes->Pool.TransmitPool = NULL;
|
|
ProtRes->InstanceCounters = NULL;
|
|
|
|
TmpBuf = (PUCHAR)TpStressInitPacketHeader(
|
|
OpenP,
|
|
( 2 * sizeof( STRESS_PACKET ) ),
|
|
sizeof( STRESS_PACKET ),
|
|
NULL_ADDRESS,
|
|
OpenP->StationAddress,
|
|
0, //DestInstance
|
|
0, //SrcInstance
|
|
PacketProtocol,
|
|
ResponseType,
|
|
0, //RandomOffset
|
|
0L, //SequenceNumber
|
|
0L, //MaxSequenceNumber
|
|
0, //ClientReference
|
|
0, //ServerReference
|
|
FALSE // DataChecking
|
|
);
|
|
|
|
if ( TmpBuf == NULL ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreateTruncatedPacket: failed to initialize Packet Header\n");
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
Buffer = TpAllocateBuffer( TmpBuf,sizeof( STRESS_PACKET ) );
|
|
|
|
if ( Buffer == NULL ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreatePacket: failed to create the MDL\n");
|
|
}
|
|
TpStressFreePacket( Packet );
|
|
return NULL;
|
|
}
|
|
|
|
NdisChainBufferAtBack( Packet,Buffer );
|
|
|
|
Buffer = TpAllocateBuffer(
|
|
OpenP->Stress->DataBuffer[0],
|
|
OpenP->Media->MaxPacketLen*2
|
|
);
|
|
|
|
if ( Buffer == NULL ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreatePacket: failed to create the MDL\n");
|
|
}
|
|
TpStressFreePacket( Packet );
|
|
return NULL;
|
|
}
|
|
|
|
NdisChainBufferAtBack( Packet,Buffer );
|
|
|
|
//
|
|
// STOPCHANGE
|
|
//
|
|
|
|
return Packet;
|
|
}
|
|
|
|
|
|
ULONG
|
|
TpGetPacketSignature(
|
|
IN PNDIS_PACKET Packet
|
|
)
|
|
|
|
{
|
|
NDIS_STATUS Status;
|
|
PUCHAR TmpBuf;
|
|
PUCHAR TmpBuf1;
|
|
UINT TmpBufSize = sizeof( STRESS_PACKET );
|
|
PNDIS_BUFFER Buffer;
|
|
PUCHAR Memory;
|
|
UINT MemoryLength;
|
|
ULONG Signature;
|
|
BOOLEAN GotWholeTpPacket;
|
|
|
|
if ( Packet == NULL ) {
|
|
return 0xffffffff;
|
|
}
|
|
|
|
Status = NdisAllocateMemory(
|
|
(PVOID *)&TmpBuf,
|
|
TmpBufSize,
|
|
0,
|
|
HighestAddress
|
|
);
|
|
|
|
if ( Status != NDIS_STATUS_SUCCESS ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpGetPacketSignature: unable to allocate tmp buffer\n");
|
|
}
|
|
return 0xffffffff;
|
|
} else {
|
|
NdisZeroMemory( TmpBuf,TmpBufSize );
|
|
}
|
|
|
|
TmpBuf1 = TmpBuf;
|
|
|
|
NdisQueryPacket( Packet,NULL,NULL,&Buffer,NULL );
|
|
|
|
GotWholeTpPacket = FALSE;
|
|
|
|
while ( Buffer != NULL ) {
|
|
|
|
NdisQueryBuffer(
|
|
Buffer,
|
|
(PVOID *)&Memory,
|
|
&MemoryLength
|
|
);
|
|
|
|
if ( MemoryLength > TmpBufSize ) {
|
|
MemoryLength = TmpBufSize;
|
|
}
|
|
|
|
RtlMoveMemory( TmpBuf1,Memory,MemoryLength );
|
|
|
|
TmpBufSize -= MemoryLength;
|
|
TmpBuf1 += MemoryLength;
|
|
|
|
if (TmpBufSize == 0 ) {
|
|
GotWholeTpPacket = TRUE;
|
|
break;
|
|
}
|
|
|
|
NdisGetNextBuffer( Buffer,&Buffer );
|
|
}
|
|
|
|
if ( GotWholeTpPacket == TRUE ) {
|
|
Signature = ((PSTRESS_PACKET)TmpBuf)->hdr.info.Signature;
|
|
} else {
|
|
Signature = 0xffffffff;
|
|
}
|
|
|
|
NdisFreeMemory( TmpBuf,0,0 );
|
|
|
|
return Signature;
|
|
}
|
|
|
|
|
|
VOID
|
|
TpStressFreePacket(
|
|
IN PNDIS_PACKET Packet
|
|
)
|
|
{
|
|
PNDIS_BUFFER HeadBuffer;
|
|
PNDIS_BUFFER Buffer;
|
|
PPROTOCOL_RESERVED ProtRes;
|
|
|
|
|
|
if ( Packet == NULL ) {
|
|
return;
|
|
}
|
|
|
|
NdisUnchainBufferAtFront( Packet,&HeadBuffer );
|
|
|
|
if ( HeadBuffer != NULL ) {
|
|
|
|
NdisUnchainBufferAtFront( Packet,&Buffer );
|
|
|
|
while ( Buffer != NULL ) {
|
|
TpFreeBuffer( Buffer );
|
|
NdisUnchainBufferAtFront( Packet,&Buffer );
|
|
}
|
|
|
|
//
|
|
// Due to the method used to create the header buffer this
|
|
// size is now invalid, but will work.
|
|
//
|
|
|
|
HeadBuffer->ByteCount = ( sizeof( STRESS_PACKET ) * 2 );
|
|
|
|
NdisFreeMemory( MmGetMdlVirtualAddress( HeadBuffer ),0,0 );
|
|
|
|
TpFreeBuffer( HeadBuffer );
|
|
}
|
|
|
|
ProtRes = PROT_RES( Packet );
|
|
|
|
ProtRes->Pool.TransmitPool = NULL;
|
|
ProtRes->InstanceCounters = NULL;
|
|
|
|
NdisFreePacket( Packet );
|
|
|
|
Packet = NULL;
|
|
}
|
|
|
|
|
|
PTP_TRANSMIT_POOL
|
|
TpStressCreateTransmitPool(
|
|
IN POPEN_BLOCK OpenP,
|
|
IN NDIS_HANDLE PacketHandle,
|
|
IN PACKET_MAKEUP PacketMakeUp,
|
|
IN UCHAR PacketProtocol,
|
|
IN UCHAR ResponseType,
|
|
IN INT PacketSize,
|
|
IN INT NumPackets,
|
|
IN BOOLEAN ServerPool
|
|
)
|
|
{
|
|
NDIS_STATUS Status;
|
|
PTP_TRANSMIT_POOL TmpPool;
|
|
PNDIS_PACKET Packet;
|
|
PPROTOCOL_RESERVED ProtRes;
|
|
ULONG SequenceNumber = 0;
|
|
ULONG MaxSequenceNumber = 0;
|
|
INT NextPacketSize;
|
|
INT i;
|
|
UCHAR DestInstance = 0;
|
|
UCHAR SrcInstance = 0;
|
|
UCHAR ClientReference = 0;
|
|
UCHAR ServerReference = 0;
|
|
|
|
//
|
|
// Allocate the Packet Pool Structure
|
|
//
|
|
|
|
Status = NdisAllocateMemory(
|
|
(PVOID *)&TmpPool,
|
|
sizeof( TP_TRANSMIT_POOL ),
|
|
0,
|
|
HighestAddress
|
|
);
|
|
|
|
if ( Status != NDIS_STATUS_SUCCESS ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreateTransmitPool: failed to allocate TmpPool\n");
|
|
}
|
|
return NULL;
|
|
} else {
|
|
NdisZeroMemory( TmpPool,sizeof( TP_TRANSMIT_POOL ));
|
|
}
|
|
|
|
//
|
|
// and allocate it's SpinLock
|
|
//
|
|
|
|
TmpPool->SpinLockAllocated = FALSE;
|
|
|
|
NdisAllocateSpinLock( &TmpPool->SpinLock );
|
|
|
|
TmpPool->SpinLockAllocated = TRUE;
|
|
|
|
//
|
|
// Set the Packet Pool Chain to empty
|
|
//
|
|
|
|
TmpPool->Head = NULL;
|
|
TmpPool->Tail = NULL;
|
|
|
|
for ( i=0;i<NumPackets-1;i++ ) {
|
|
|
|
if ( ServerPool == TRUE ) {
|
|
|
|
Packet = TpStressCreateTruncatedPacket(
|
|
OpenP,
|
|
PacketHandle,
|
|
PacketProtocol,
|
|
ResponseType
|
|
);
|
|
} else {
|
|
|
|
if ( OpenP->Stress->Arguments->PacketType == RANDOMSIZE ) {
|
|
|
|
NextPacketSize = TpGetRandom(
|
|
sizeof( STRESS_PACKET ),
|
|
PacketSize
|
|
);
|
|
|
|
} else { // ( OpenP->Arguments->Packet_Size == FIXEDSIZE )
|
|
|
|
NextPacketSize = PacketSize;
|
|
}
|
|
|
|
Packet = TpStressCreatePacket(
|
|
OpenP,
|
|
PacketHandle,
|
|
PacketMakeUp,
|
|
DestInstance,
|
|
SrcInstance,
|
|
PacketProtocol,
|
|
ResponseType,
|
|
NULL_ADDRESS,
|
|
NextPacketSize,
|
|
0, // BufferSize
|
|
SequenceNumber,
|
|
MaxSequenceNumber,
|
|
ClientReference,
|
|
ServerReference,
|
|
FALSE
|
|
);
|
|
}
|
|
|
|
if ( Packet == NULL ) {
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES ) {
|
|
TpPrint0("TpStressCreateTransmitPool: could not allocate packet for pool.\n");
|
|
}
|
|
TpStressFreeTransmitPool( TmpPool );
|
|
return NULL;
|
|
}
|
|
|
|
ProtRes = PROT_RES( Packet );
|
|
ProtRes->Pool.NextPacket = TmpPool->Head;
|
|
TmpPool->Head = Packet;
|
|
|
|
if ( i == 0 ) {
|
|
TmpPool->Tail = Packet;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Initialize the NumPackets var and the allocation counters
|
|
//
|
|
|
|
TmpPool->Allocated = 0;
|
|
TmpPool->Deallocated = 0;
|
|
|
|
return TmpPool;
|
|
}
|
|
|
|
|
|
VOID
|
|
TpStressFreeTransmitPool(
|
|
IN PTP_TRANSMIT_POOL TpTransmitPool
|
|
)
|
|
{
|
|
PNDIS_PACKET Packet;
|
|
PPROTOCOL_RESERVED ProtRes;
|
|
|
|
if ( TpTransmitPool == NULL ) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// If the spin lock was allocated free it.
|
|
//
|
|
|
|
if ( TpTransmitPool->SpinLockAllocated == TRUE ) {
|
|
NdisFreeSpinLock( &TpTransmitPool->SpinLock );
|
|
}
|
|
|
|
//
|
|
// Unchain and destroy the packets chained in the Packet Pool.
|
|
//
|
|
|
|
while ( TpTransmitPool->Head != NULL ) {
|
|
Packet = TpTransmitPool->Head;
|
|
|
|
ProtRes = PROT_RES( TpTransmitPool->Head );
|
|
TpTransmitPool->Head = ProtRes->Pool.NextPacket;
|
|
|
|
TpStressFreePacket( Packet );
|
|
}
|
|
|
|
//
|
|
// And free the Packet Pool Structure.
|
|
//
|
|
|
|
NdisFreeMemory( TpTransmitPool,0,0 );
|
|
}
|
|
|
|
|
|
PNDIS_PACKET
|
|
TpStressAllocatePoolPacket(
|
|
IN PTP_TRANSMIT_POOL TpTransmitPool,
|
|
IN PINSTANCE_COUNTERS Counters
|
|
)
|
|
{
|
|
PPROTOCOL_RESERVED ProtRes;
|
|
PNDIS_PACKET Packet;
|
|
|
|
NdisAcquireSpinLock( &TpTransmitPool->SpinLock );
|
|
|
|
if ( TpTransmitPool->Head == NULL ) {
|
|
NdisReleaseSpinLock( &TpTransmitPool->SpinLock );
|
|
return NULL;
|
|
}
|
|
|
|
Packet = TpTransmitPool->Head;
|
|
|
|
ProtRes = PROT_RES( Packet );
|
|
TpTransmitPool->Head = ProtRes->Pool.NextPacket;
|
|
|
|
if ( TpTransmitPool->Head == NULL ) {
|
|
TpTransmitPool->Tail = NULL;
|
|
}
|
|
|
|
TpTransmitPool->Allocated++;
|
|
|
|
NdisReleaseSpinLock( &TpTransmitPool->SpinLock );
|
|
|
|
ProtRes->Pool.TransmitPool = TpTransmitPool;
|
|
ProtRes->InstanceCounters = Counters;
|
|
|
|
return Packet;
|
|
}
|
|
|
|
|
|
VOID
|
|
TpStressSetPoolPacketInfo(
|
|
IN POPEN_BLOCK OpenP,
|
|
IN OUT PNDIS_PACKET Packet,
|
|
IN PUCHAR DestAddr,
|
|
IN UCHAR DestInstance,
|
|
IN UCHAR SrcInstance,
|
|
IN ULONG SequenceNumber,
|
|
IN ULONG MaxSequenceNumber,
|
|
IN UCHAR ClientReference,
|
|
IN UCHAR ServerReference
|
|
)
|
|
{
|
|
PNDIS_BUFFER Buffer;
|
|
PUCHAR Memory;
|
|
UINT Length;
|
|
PSTRESS_PACKET StrPacket;
|
|
|
|
NdisQueryPacket( Packet,NULL,NULL,&Buffer,NULL );
|
|
|
|
NdisQueryBuffer( Buffer,(PVOID *)&Memory,&Length );
|
|
|
|
StrPacket = (PSTRESS_PACKET)Memory;
|
|
|
|
StrPacket->hdr.info.DestInstance = DestInstance;
|
|
StrPacket->hdr.info.SrcInstance = SrcInstance;
|
|
StrPacket->hdr.info.CheckSum = 0xFFFFFFFF;
|
|
|
|
StrPacket->sc.SequenceNumber = SequenceNumber;
|
|
StrPacket->sc.MaxSequenceNumber = MaxSequenceNumber;
|
|
StrPacket->sc.ClientReference = ClientReference;
|
|
StrPacket->sc.ServerReference = ServerReference;
|
|
|
|
TpInitPoolMediaHeader( &StrPacket->hdr,OpenP->Media,DestAddr );
|
|
|
|
|
|
StrPacket->sc.CheckSum = TpSetCheckSum(
|
|
(PUCHAR)&StrPacket->hdr.info,
|
|
sizeof( STRESS_PACKET ) -
|
|
( sizeof( ULONG ) +
|
|
OpenP->Media->HeaderSize )
|
|
);
|
|
|
|
}
|
|
|
|
|
|
VOID
|
|
TpStressSetTruncatedPacketInfo(
|
|
IN POPEN_BLOCK OpenP,
|
|
IN OUT PNDIS_PACKET Packet,
|
|
IN PUCHAR DestAddr,
|
|
IN INT PacketSize,
|
|
IN UCHAR DestInstance,
|
|
IN UCHAR SrcInstance,
|
|
IN ULONG SequenceNumber,
|
|
IN ULONG MaxSequenceNumber,
|
|
IN UCHAR ClientReference,
|
|
IN UCHAR ServerReference,
|
|
IN ULONG DataBufferOffset
|
|
)
|
|
{
|
|
PNDIS_BUFFER Buffer;
|
|
PNDIS_BUFFER NextBuffer;
|
|
PUCHAR Memory;
|
|
UINT Length;
|
|
LONG DataBufferSize;
|
|
PSTRESS_PACKET TpPacket;
|
|
BOOLEAN Reset;
|
|
static BOOLEAN IntroduceFalsePageInfo;
|
|
register UINT PageCount1;
|
|
register UINT PageCount2;
|
|
|
|
Reset = FALSE;
|
|
|
|
NdisQueryPacket( Packet,NULL,NULL,&Buffer,NULL );
|
|
|
|
NdisQueryBuffer(
|
|
Buffer,
|
|
(PVOID *)&Memory,
|
|
&Length
|
|
);
|
|
|
|
TpPacket = (PSTRESS_PACKET)Memory;
|
|
|
|
TpPacket->hdr.info.PacketSize = PacketSize;
|
|
TpPacket->hdr.info.DestInstance = DestInstance;
|
|
TpPacket->hdr.info.SrcInstance = SrcInstance;
|
|
TpPacket->hdr.info.CheckSum = 0xFFFFFFFF;
|
|
|
|
TpPacket->sc.SequenceNumber = SequenceNumber;
|
|
TpPacket->sc.MaxSequenceNumber = MaxSequenceNumber;
|
|
TpPacket->sc.ClientReference = ClientReference;
|
|
TpPacket->sc.ServerReference = ServerReference;
|
|
TpPacket->sc.DataBufOffset = DataBufferOffset;
|
|
|
|
TpInitTruncatedMediaHeader(
|
|
&TpPacket->hdr,
|
|
OpenP->Media,
|
|
DestAddr,
|
|
PacketSize
|
|
);
|
|
|
|
TpPacket->sc.CheckSum = TpSetCheckSum(
|
|
(PUCHAR)&TpPacket->hdr.info,
|
|
sizeof( STRESS_PACKET ) -
|
|
( sizeof( ULONG ) +
|
|
OpenP->Media->HeaderSize )
|
|
);
|
|
|
|
NdisGetNextBuffer( Buffer,&NextBuffer );
|
|
|
|
DataBufferSize = PacketSize - sizeof( STRESS_PACKET );
|
|
|
|
TP_ASSERT( DataBufferSize >= 0 );
|
|
|
|
if ( DataBufferSize == 0 ) {
|
|
DataBufferSize = 1;
|
|
Reset = TRUE;
|
|
}
|
|
|
|
// test
|
|
{
|
|
PMDL TmpMdl;
|
|
ULONG TmpSize;
|
|
PVOID VirtualAddress;
|
|
|
|
TmpMdl = (PMDL)NextBuffer;
|
|
VirtualAddress = OpenP->Stress->DataBuffer[0]+DataBufferOffset;
|
|
|
|
TmpSize = COMPUTE_PAGES_SPANNED(VirtualAddress, DataBufferSize);
|
|
if (((TmpMdl->Size - sizeof(MDL)) >> 2L) < TmpSize)
|
|
{
|
|
TpPrint0("TpStressSetTruncatePacketInfo: bad mdl size\n");
|
|
TpPrint1("New Mdl size = %d\n", TmpMdl->Size);
|
|
TpPrint1("DataBufferSize = %d\n", DataBufferSize);
|
|
TpPrint1("PagesSpanned = %d\n", TmpSize);
|
|
TpPrint1("MdlPages = %d\n", (TmpMdl->Size - sizeof(MDL)) >> 2L);
|
|
TpBreakPoint();
|
|
}
|
|
}
|
|
|
|
IoBuildPartialMdl(
|
|
OpenP->Stress->DataBufferMdl[0],
|
|
(PMDL)NextBuffer,
|
|
(PVOID)(OpenP->Stress->DataBuffer[0]+DataBufferOffset),
|
|
DataBufferSize
|
|
);
|
|
|
|
if ( Reset == TRUE ) {
|
|
NextBuffer->ByteCount = 0;
|
|
}
|
|
|
|
Packet->Private.TotalLength = PacketSize;
|
|
|
|
|
|
|
|
|
|
PageCount1 = ADDRESS_AND_SIZE_TO_SPAN_PAGES( MmGetMdlVirtualAddress( NextBuffer ), MmGetMdlByteCount( NextBuffer ) );
|
|
PageCount2 = ADDRESS_AND_SIZE_TO_SPAN_PAGES( MmGetMdlVirtualAddress( Buffer ), MmGetMdlByteCount( Buffer ) );
|
|
|
|
|
|
if ( IntroduceFalsePageInfo ) {
|
|
IntroduceFalsePageInfo = FALSE;
|
|
Packet->Private.PhysicalCount = (PageCount1 + PageCount2) | 0x08000000 ;
|
|
} else {
|
|
IntroduceFalsePageInfo = TRUE;
|
|
Packet->Private.PhysicalCount = PageCount1 + PageCount2;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
TpStressFreePoolPacket(
|
|
IN OUT PNDIS_PACKET Packet
|
|
)
|
|
{
|
|
PPROTOCOL_RESERVED ProtRes;
|
|
PTP_TRANSMIT_POOL TpTransmitPool;
|
|
|
|
//
|
|
// Determine the location of the Test Protocol Packet Pool to return
|
|
// this packet to.
|
|
//
|
|
|
|
ProtRes = PROT_RES( Packet );
|
|
TpTransmitPool = ProtRes->Pool.TransmitPool;
|
|
|
|
//
|
|
// Null out the Packets NextPacket pointer. It will be placed the
|
|
// end of the Packet Pool chain.
|
|
//
|
|
|
|
ProtRes->Pool.TransmitPool = NULL;
|
|
ProtRes->InstanceCounters = NULL;
|
|
|
|
//
|
|
// Take the SpinLock which guards the Packet Pool
|
|
//
|
|
|
|
NdisAcquireSpinLock( &TpTransmitPool->SpinLock );
|
|
|
|
//
|
|
// If the Packet Pool's Head pointer is NULL the poll is
|
|
// empty, and this packet is at the Head and the Tail.
|
|
//
|
|
|
|
if ( TpTransmitPool->Head == NULL ) {
|
|
|
|
//
|
|
// Chain the packet to the head of the Packet Pool Chain.
|
|
//
|
|
|
|
TpTransmitPool->Head = Packet;
|
|
|
|
} else {
|
|
|
|
//
|
|
// Else chain the packet to the end of the Packet Pool Chain.
|
|
//
|
|
|
|
ProtRes = PROT_RES( TpTransmitPool->Tail );
|
|
ProtRes->Pool.NextPacket = Packet;
|
|
}
|
|
|
|
//
|
|
// Finally point the Packet Pool Struct Tail pointer at this packet,
|
|
// and incremented the Deallocated Packets counter.
|
|
//
|
|
|
|
TpTransmitPool->Tail = Packet;
|
|
TpTransmitPool->Deallocated++;
|
|
|
|
//
|
|
// And release the Packet Pool SpinLock.
|
|
//
|
|
|
|
NdisReleaseSpinLock( &TpTransmitPool->SpinLock );
|
|
}
|
|
|
|
//
|
|
// Functional Packet Routines
|
|
//
|
|
|
|
|
|
PTP_PACKET
|
|
TpFuncInitPacketHeader(
|
|
IN POPEN_BLOCK OpenP,
|
|
IN INT PacketSize
|
|
)
|
|
|
|
// ---------------
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Return Value:
|
|
//
|
|
// ----------------
|
|
|
|
{
|
|
NDIS_STATUS Status;
|
|
PTP_PACKET TmpBuffer;
|
|
PUCHAR DataField;
|
|
INT DataFieldSize;
|
|
USHORT i;
|
|
|
|
Status = NdisAllocateMemory((PVOID *)&TmpBuffer,
|
|
PacketSize,
|
|
0,
|
|
HighestAddress );
|
|
|
|
if ( Status != NDIS_STATUS_SUCCESS )
|
|
{
|
|
IF_TPDBG ( TP_DEBUG_RESOURCES )
|
|
{
|
|
TpPrint0("TpFuncInitPacketHeader: failed to allocate TmpBuffer\n");
|
|
}
|
|
return NULL;
|
|
|
|
}
|
|
else
|
|
{
|
|
NdisZeroMemory( (PVOID)TmpBuffer,PacketSize );
|
|
}
|
|
|
|
if ( !TpInitMediaHeader(&TmpBuffer->u.F2.hdr1,
|
|
OpenP->Media,
|
|
OpenP->Send->DestAddress,
|
|
OpenP->StationAddress,
|
|
PacketSize))
|
|
{
|
|
NdisFreeMemory( TmpBuffer,0,0 );
|
|
return NULL;
|
|
}
|
|
|
|
|
|
//
|
|
// initialize the packet information header
|
|
//
|
|
|
|
TmpBuffer->u.F2.hdr1.info.Signature = FUNC1_PACKET_SIGNATURE;
|
|
TmpBuffer->u.F2.hdr1.info.DestInstance = OpenP->OpenInstance;
|
|
TmpBuffer->u.F2.hdr1.info.SrcInstance = 0;
|
|
TmpBuffer->u.F2.hdr1.info.PacketSize = PacketSize;
|
|
TmpBuffer->u.F2.hdr1.info.PacketType = FUNC1_PACKET_TYPE;
|
|
TmpBuffer->u.F2.hdr1.info.u.PacketNumber = (UCHAR)OpenP->Send->PacketsSent;
|
|
|
|
//
|
|
// and set the checksum in the header.
|
|
//
|
|
|
|
TmpBuffer->u.F2.hdr1.info.CheckSum =TpSetCheckSum((PUCHAR)&TmpBuffer->u.F2.hdr1.info,
|
|
sizeof( PACKET_INFO ) - sizeof( ULONG ));
|
|
|
|
|
|
if ( OpenP->Send->ResendPackets == TRUE )
|
|
{
|
|
//
|
|
// We are building a resend packet, fill in the FUNC_PACKET info
|
|
// for the internal packet, and determine the start of the test
|
|
// data field.
|
|
//
|
|
|
|
if ( !TpInitMediaHeader(&TmpBuffer->u.F2.hdr2,
|
|
OpenP->Media,
|
|
OpenP->Send->ResendAddress,
|
|
OpenP->Send->DestAddress,
|
|
( PacketSize - sizeof( FUNC1_PACKET))))
|
|
{
|
|
NdisFreeMemory( TmpBuffer,0,0 );
|
|
return NULL;
|
|
}
|
|
|
|
|
|
TmpBuffer->u.F2.hdr2.info.Signature = FUNC2_PACKET_SIGNATURE;
|
|
TmpBuffer->u.F2.hdr2.info.DestInstance = OpenP->OpenInstance;
|
|
TmpBuffer->u.F2.hdr2.info.SrcInstance = 0;
|
|
TmpBuffer->u.F2.hdr2.info.PacketSize = PacketSize - sizeof( FUNC1_PACKET );
|
|
TmpBuffer->u.F2.hdr2.info.PacketType = FUNC2_PACKET_TYPE;
|
|
TmpBuffer->u.F2.hdr2.info.u.PacketNumber = (UCHAR)OpenP->Send->PacketsSent;
|
|
|
|
DataField = (PUCHAR)((PUCHAR)TmpBuffer + (ULONG)sizeof( FUNC2_PACKET ));
|
|
|
|
//
|
|
// Now set the checksum value for the header.
|
|
//
|
|
|
|
TmpBuffer->u.F2.hdr2.info.CheckSum = TpSetCheckSum((PUCHAR)&TmpBuffer->u.F2.hdr2.info,
|
|
sizeof( PACKET_INFO ) - sizeof( ULONG ));
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Otherwise this is just a standard packet with no resend
|
|
// packet contained within. Mark it as such, a set the data field
|
|
// pointer to the beginning of the data field.
|
|
//
|
|
|
|
DataField = (PUCHAR)((PUCHAR)TmpBuffer + (ULONG)sizeof( FUNC1_PACKET ) );
|
|
|
|
}
|
|
|
|
DataFieldSize = PacketSize - (ULONG)( DataField - (PUCHAR)TmpBuffer );
|
|
|
|
for ( i = 0 ; i < (USHORT)DataFieldSize ; i++ )
|
|
{
|
|
DataField[i] = (UCHAR)( i % 256 );
|
|
}
|
|
|
|
return TmpBuffer;
|
|
}
|
|
|
|
|
|
ULONG
|
|
TpSetCheckSum(
|
|
IN PUCHAR Buffer,
|
|
IN ULONG BufLen
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
PUCHAR TmpBuffer = Buffer;
|
|
ULONG TmpCheckSum = 0;
|
|
ULONG i;
|
|
|
|
for ( i = 0 ; i < BufLen ; i++ ) {
|
|
TmpCheckSum += (ULONG)*TmpBuffer++;
|
|
}
|
|
|
|
return ~TmpCheckSum;
|
|
}
|
|
/*
|
|
|
|
VOID
|
|
TpSetCheckSum(
|
|
IN PUCHAR Buffer,
|
|
IN ULONG BufLen,
|
|
IN PULONG CheckSum
|
|
)
|
|
|
|
/ *++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--* /
|
|
|
|
{
|
|
PUCHAR TmpBuffer = Buffer;
|
|
ULONG TmpCheckSum = 0;
|
|
ULONG i;
|
|
|
|
return;
|
|
|
|
for ( i = 0 ; i < BufLen ; i++ ) {
|
|
TmpCheckSum += (ULONG)*TmpBuffer++;
|
|
}
|
|
|
|
*CheckSum = ~TmpCheckSum;
|
|
}
|
|
*/
|
|
|
|
|
|
BOOLEAN
|
|
TpCheckSum(
|
|
IN PUCHAR Buffer,
|
|
IN ULONG BufLen,
|
|
IN PULONG CheckSum
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
PUCHAR TmpBuffer = Buffer;
|
|
ULONG TmpCheckSum = 0;
|
|
ULONG i;
|
|
|
|
return TRUE;
|
|
|
|
for ( i = 0 ; i < BufLen ; i++ ) {
|
|
TmpCheckSum += (ULONG)*TmpBuffer++;
|
|
}
|
|
|
|
if (( *CheckSum + TmpCheckSum ) != -1 ) {
|
|
TP_ASSERT( FALSE );
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
PNDIS_PACKET
|
|
TpFuncAllocateSendPacket(
|
|
IN POPEN_BLOCK OpenP
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
|
|
{
|
|
NDIS_STATUS Status;
|
|
PPROTOCOL_RESERVED ProtRes;
|
|
PNDIS_PACKET Packet;
|
|
PNDIS_BUFFER Buffer;
|
|
PUCHAR TmpBuf;
|
|
INT TmpBufSize;
|
|
INT MdlSize;
|
|
INT i;
|
|
|
|
//
|
|
// Make sure that this is a legal packetsize, and if it isn't,
|
|
// then set it to the nearest valid size.
|
|
//
|
|
|
|
if (( OpenP->Send->ResendPackets == FALSE ) &&
|
|
( OpenP->Send->PacketSize < sizeof( FUNC1_PACKET ))) {
|
|
|
|
OpenP->Send->PacketSize = sizeof( FUNC1_PACKET );
|
|
|
|
TpPrint0("TpFuncAllocateSendPacket: PacketSize to small for packet type.\n");
|
|
TpPrint1("TpFuncAllocateSendPacket: Using %d\n",OpenP->Send->PacketSize);
|
|
|
|
|
|
} else if (( OpenP->Send->ResendPackets == TRUE ) &&
|
|
( OpenP->Send->PacketSize < sizeof( FUNC2_PACKET ))) {
|
|
|
|
OpenP->Send->PacketSize = sizeof( FUNC2_PACKET );
|
|
|
|
TpPrint0("TpFuncAllocateSendPacket: Invalid PacketSize for packet type.\n");
|
|
TpPrint1("TpFuncAllocateSendPacket: Using %d\n",OpenP->Send->PacketSize);
|
|
|
|
} else if ( OpenP->Send->PacketSize >
|
|
(ULONG)OpenP->Media->MaxPacketLen ) {
|
|
|
|
OpenP->Send->PacketSize = (ULONG)OpenP->Media->MaxPacketLen;
|
|
|
|
TpPrint0("TpFuncAllocateSendPacket: PacketSize to large for media.\n");
|
|
TpPrint1("TpFuncAllocateSendPacket: Using %d\n",OpenP->Send->PacketSize);
|
|
}
|
|
|
|
NdisAllocatePacket(
|
|
&Status,
|
|
&Packet,
|
|
OpenP->Send->PacketHandle
|
|
);
|
|
|
|
if ( Status != NDIS_STATUS_SUCCESS ) {
|
|
|
|
TpPrint1("TpFuncAllocateSendPacket: NdisAllocatePacket failed %s\n",
|
|
TpGetStatus( Status ));
|
|
return NULL;
|
|
}
|
|
|
|
ProtRes = PROT_RES( Packet );
|
|
ProtRes->Pool.PacketHandle = &OpenP->Send->PacketHandle;
|
|
ProtRes->InstanceCounters = OpenP->Send->Counters;
|
|
|
|
TmpBufSize = OpenP->Send->PacketSize;
|
|
|
|
TmpBuf = (PUCHAR)TpFuncInitPacketHeader( OpenP,TmpBufSize );
|
|
|
|
if ( TmpBuf == NULL ) {
|
|
TpPrint0("TpFuncAllocateSendPacket: failed to initialize Packet Header\n");
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Functional packets are made up of two small buffers at the beginning
|
|
// of the MDL chain followed by one large buffer at the end of the chain.
|
|
// If there is not enough room in the packet the buffer chain will be
|
|
// affected accordingly.
|
|
//
|
|
|
|
for ( i=0;i<2;i++ ) {
|
|
|
|
//
|
|
// Select the size of the first and second buffer.
|
|
//
|
|
|
|
MdlSize = TpGetRandom( OpenP->Media->HeaderSize,0x64 );
|
|
|
|
if ( MdlSize > TmpBufSize ) {
|
|
|
|
//
|
|
// If it is larger than the remaining packet size, then
|
|
// we will use only the remaining packet.
|
|
//
|
|
|
|
MdlSize = TmpBufSize;
|
|
}
|
|
|
|
//
|
|
// Create a buffer (MDL) using this portion of the packet.
|
|
//
|
|
|
|
Buffer = TpAllocateBuffer( TmpBuf,MdlSize );
|
|
|
|
if ( Buffer == NULL ) {
|
|
TpPrint0("TpFuncAllocateSendPacket: failed to create the MDL\n");
|
|
TpFuncFreePacket( Packet,OpenP->Send->PacketSize );
|
|
return (PNDIS_PACKET)NULL;
|
|
}
|
|
|
|
//
|
|
// And chain it to the back of the packet.
|
|
//
|
|
|
|
NdisChainBufferAtBack( Packet,Buffer );
|
|
|
|
//
|
|
// reset the packet size counters and see if we are out of packet.
|
|
//
|
|
|
|
TmpBuf += MdlSize;
|
|
TmpBufSize -= MdlSize;
|
|
|
|
if ( TmpBufSize == 0 ) {
|
|
|
|
//
|
|
// if so, then return the packet we have made.
|
|
//
|
|
|
|
return Packet;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Otherwise tack on the remainder of the buffer as the last mdl
|
|
// in the chain.
|
|
//
|
|
|
|
Buffer = TpAllocateBuffer( TmpBuf,TmpBufSize );
|
|
|
|
NdisChainBufferAtBack( Packet,Buffer );
|
|
|
|
if ( Buffer == NULL ) {
|
|
TpPrint0("TpFuncAllocateSendPacket: failed to create the MDL\n");
|
|
TpFuncFreePacket( Packet,OpenP->Send->PacketSize );
|
|
return NULL;
|
|
}
|
|
|
|
return Packet;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
TpFuncFreePacket(
|
|
PNDIS_PACKET Packet,
|
|
ULONG PacketSize
|
|
)
|
|
|
|
{
|
|
PNDIS_BUFFER HeadBuffer;
|
|
PNDIS_BUFFER Buffer;
|
|
|
|
if ( Packet == NULL ) {
|
|
return;
|
|
}
|
|
|
|
NdisUnchainBufferAtFront( Packet,&HeadBuffer );
|
|
|
|
if ( HeadBuffer != NULL ) {
|
|
|
|
NdisUnchainBufferAtFront( Packet,&Buffer );
|
|
|
|
while ( Buffer != NULL ) {
|
|
TpFreeBuffer( Buffer );
|
|
NdisUnchainBufferAtFront( Packet,&Buffer );
|
|
}
|
|
|
|
HeadBuffer->ByteCount = PacketSize;
|
|
|
|
NdisFreeMemory( MmGetMdlVirtualAddress( HeadBuffer ),0,0 );
|
|
|
|
TpFreeBuffer( HeadBuffer );
|
|
}
|
|
|
|
NdisFreePacket( Packet );
|
|
}
|