📄 tx.cpp
字号:
// Tx.cpp: implementation of the CTx class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "Tx.h"
#include "ZDWlanAdapter.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CTx::CTx()
:m_UserDefinedPattern(0)
{
}
CTx::~CTx()
{
m_CompleteRoutine = NULL;
if (m_UserDefinedPattern) free(m_UserDefinedPattern);
}
DWORD CTx::HandleSendComplete(
PSendPackage pTxPackage
)
{
pTxPackage->pAdapter->m_nSendPacketCount++;
pTxPackage->pAdapter->m_BytesSent += pTxPackage->nFrameSize;
HP_DestroySendPackage( pTxPackage );
return( 0 );
}
void CALLBACK CTx::SendCompleteApcNT(
DWORD dwErrorCode,
DWORD dwNumberOfBytesTransfered,
LPOVERLAPPED lpOverlapped
)
{
PSendPackage pTxPackage = NULL;
// ATTENTION!!! Consider using try/except here...
pTxPackage = (PSendPackage )lpOverlapped->OffsetHigh;
CTx::HandleSendComplete( pTxPackage );
}
DWORD CALLBACK CTx::SendCompleteApc95(LPOVERLAPPED lpOverlapped)
{
PSendPackage pTxPackage = NULL;
pTxPackage = (PSendPackage )lpOverlapped->OffsetHigh;
CTx::HandleSendComplete( pTxPackage );
return 0;
}
void CTx::HP_DestroySendPackage( PSendPackage pTxPackage )
{
if( pTxPackage->nSignature != TX_PACKAGE_SIGN )
{
return;
}
//
// Zap The Signature For Sanity Checks
//
pTxPackage->nSignature = 0;
if( pTxPackage->OverLapped.hEvent )
{
CloseHandle( pTxPackage->OverLapped.hEvent );
pTxPackage->OverLapped.hEvent = NULL;
}
free( pTxPackage );
}
PSendPackage CTx::HP_CreateSendPackage( CTx *pTx,
DWORD nDataSize,
BOOL bInitOverlappedEvent
)
{
PSendPackage pTxPackage = NULL;
int infoHeaderSize = sizeof(FRAME_INFO_HEADER);
//
// Make Sure Driver Has Been Opened
//
if( pTx->m_HookAdapter.m_hDevice == INVALID_HANDLE_VALUE )
{
return NULL;
}
if (nDataSize == 0){
// if pattern size = 0, we randomly determine the size
// 36 <= nDataSize <= 1400
//srand( (unsigned)time( NULL ) );
nDataSize = rand() % (MAX_ETHER_SIZE - MIN_ETHER_SIZE + 1) + MIN_ETHER_SIZE - MHdrSize - infoHeaderSize;
}
if( MHdrSize + nDataSize + infoHeaderSize < MIN_ETHER_SIZE )
{
return NULL;
}
if( MHdrSize + nDataSize + infoHeaderSize > PACKET_BUFFER_SIZE )
{
return NULL;
}
//
// Allocate The Send Package
//
pTxPackage = (PSendPackage )malloc( sizeof( SendPackage ) );
if( !pTxPackage )
{
return NULL;
}
// clear buffer space
ZeroMemory(pTxPackage, sizeof( SendPackage ));
//
// Save The Frame Size
//
pTxPackage->nFrameSize = MHdrSize + nDataSize + infoHeaderSize;
//
// Set The Destination Link Address
//
memcpy(
&pTxPackage->PacketBufferSpace[ MDstAddr ],
m_DestAddr,
ETHER_ADDR_LENGTH
);
memcpy(
&pTxPackage->PacketBufferSpace[ MSrcAddr ],
pTx->m_HookAdapter.m_CurrentAddress,
ETHER_ADDR_LENGTH
);
//
// Set The EtherType To DEC Experimental Type
//
pTxPackage->PacketBufferSpace[ MLength ] = 0x60;
pTxPackage->PacketBufferSpace[ MLength + 1 ] = 0x00;
// Set ZyDas Header
PFRAME_INFO_HEADER pInfoHeader = (PFRAME_INFO_HEADER)(pTxPackage->PacketBufferSpace + MHdrSize);
pInfoHeader->CheckCode[0] = '$';
pInfoHeader->CheckCode[1] = 'Z';
pInfoHeader->CheckCode[2] = (char)0xED;
//-----------------------------------------------------------
DWORD i;
int random = pTx->m_Pattern;
FILL_SEND_PATTERN:
switch (random)
{
case TX_PATTERN_0:
memset(&pTxPackage->PacketBufferSpace[ MHdrSize + infoHeaderSize ], 0, nDataSize);
break;
case TX_PATTERN_FF:
memset(&pTxPackage->PacketBufferSpace[ MHdrSize + infoHeaderSize ], 0xFF, nDataSize);
break;
case TX_PATTERN_1234:
for(i=0; i<nDataSize; i++)
pTxPackage->PacketBufferSpace[ i+MHdrSize + infoHeaderSize ] = (char)(i + pTx->m_SequenceNmber);
break;
case TX_PATTERN_SEQUENCE:
memset(&pTxPackage->PacketBufferSpace[ MHdrSize + infoHeaderSize ], m_SequencePattern, nDataSize);
m_SequencePattern++;
break;
case TX_PATTERN_RANDOM:
//srand( (unsigned)time( NULL ) );
//for( i=0; i<nDataSize; i++ )
// pTxPackage->PacketBufferSpace[ i+MHdrSize + infoHeaderSize ] = (char) rand();
random = rand() % TX_PATTERN_RANDOM;
goto FILL_SEND_PATTERN;
break;
case TX_PATTERN_USER_DEFINED:
if (!m_UserDefinedPattern) return NULL;
memcpy( &pTxPackage->PacketBufferSpace[ MHdrSize + infoHeaderSize ],
m_UserDefinedPattern,
this->m_UserDefinedPattern_Len
);
break;
}
pInfoHeader->PatternType = random;
// use this field as sequence number and CRC
if (pTx->m_bCheckLost){
USHORT *pnum = (USHORT *)pInfoHeader->CheckLostNumber;
*pnum = pTx->m_SequenceNmber;
pTx->m_SequenceNmber++;
}
if (pTx->m_bCRC){
char checksum = 0;
pInfoHeader->IfSetCheckSum = 1;
for(i=0; i<nDataSize; i++)
checksum += pTxPackage->PacketBufferSpace[ i + MHdrSize + infoHeaderSize ];
for(i=0; i<(UINT)(MHdrSize + infoHeaderSize - 1); i++) //check sum of MAC header and infoheader, but not include pInfoHeader->CheckSum
checksum += pTxPackage->PacketBufferSpace[ i ];
pInfoHeader->CheckSum = checksum;
}
// now send packet is ready
if (pTx->m_CheckHeader)
{
// swap the header
char *tmpBuffer = (char *)malloc(MHdrSize + infoHeaderSize);
memcpy(tmpBuffer, (char *)pTxPackage->PacketBufferSpace, MHdrSize + infoHeaderSize);
memcpy((char *)pTxPackage->PacketBufferSpace, (char *)pTxPackage->PacketBufferSpace + MHdrSize + infoHeaderSize, MHdrSize + infoHeaderSize);
memcpy((char *)pTxPackage->PacketBufferSpace + MHdrSize + infoHeaderSize, tmpBuffer, MHdrSize + infoHeaderSize);
free(tmpBuffer);
}
//
// Common Initialization
//
if( pTxPackage )
{
pTxPackage->nSignature = TX_PACKAGE_SIGN; // Signature
pTxPackage->pAdapter = &pTx->m_HookAdapter; // Adapter Pointer
pTxPackage->OverLapped.OffsetHigh = (DWORD )pTxPackage;
if( bInitOverlappedEvent )
{
pTxPackage->OverLapped.hEvent = CreateEvent(
NULL, // Security Attributes
TRUE, // Manual-Reset
FALSE, // Initial State Not Signaled
NULL // Event-object Name
);
if( !pTxPackage->OverLapped.hEvent )
{
free( pTxPackage );
return( (PSendPackage )NULL );
}
}
else
{
pTxPackage->OverLapped.hEvent = NULL;
}
}
return pTxPackage;
}
DWORD CTx::GetPacketsSent()
{
return this->m_HookAdapter.m_nSendPacketCount;
}
DWORD CTx::GetSentDuration()
{
if (m_ThreadRunning)
return (GetTickCount() - m_StartTimeMs);
else
return (m_EndTimeMs - m_StartTimeMs);
}
bool CTx::DoContinueSend(int pattern,
const char* RemoteMAC,
int PacketLen,
DWORD PacketNum,
int Interval,
bool EnableChecklost,
bool EnableCRC,
bool EnableCheckHeader,
UCHAR sequence,
AFX_THREADPROC CompletionRoutine,
LPVOID pParam
)
{
this->m_Pattern = pattern;
if (RemoteMAC)
memcpy(this->m_DestAddr, RemoteMAC, 6);
else
memset(m_DestAddr, 0xFF, 6);
this->m_CheckHeader = EnableCheckHeader;
this->m_PacketLen = PacketLen;
this->m_PacketNum = PacketNum;
this->m_Interval = Interval;
this->m_CompleteRoutine = CompletionRoutine;
this->m_HookAdapter.m_nSendPacketCount = 0;
this->m_HookAdapter.m_BytesSent = 0;
this->m_pParam = pParam;
this->m_bCheckLost = EnableChecklost;
this->m_SequenceNmber = 0;
this->m_bCRC = EnableCRC;
this->m_SequencePattern = sequence;
if (AfxBeginThread(SendThread, this))
return TRUE;
else
return FALSE;
}
UINT CTx::SendThread( LPVOID pParam )
{
CTx* pTx = (CTx *) pParam;
if (!pTx) return 0;
pTx->m_ThreadRunning = 1;
HANDLE hSendEvent;
DWORD nResult;
srand( (unsigned)time( NULL ) );
hSendEvent = CreateEvent(
NULL, // Security Attributes
FALSE, // Auto-Reset
TRUE, // Initial State Signaled
NULL // Event-object Name
);
if( pTx->m_HookAdapter.m_hDevice == INVALID_HANDLE_VALUE )
{
pTx->m_ThreadRunning = 0;
AfxEndThread(0);
return 0;
}
PSendPackage pTxPackage = NULL;
BOOL bSendResult;
DWORD nSendResult;
pTx->m_StartTimeMs = GetTickCount();
while(1){
nResult = WaitForSingleObjectEx( hSendEvent, 1000, TRUE );
if (pTx->m_Interval)
Sleep(pTx->m_Interval);
if(pTx->m_PacketNum)
if (pTx->m_HookAdapter.m_nSendPacketCount >= pTx->m_PacketNum)
pTx->m_ThreadRunning = 0;
if (!pTx->m_ThreadRunning)
{
// wait the completion routine end
//
// Free Resources
//
pTx->m_EndTimeMs = GetTickCount();
if (pTx->m_CompleteRoutine)
AfxBeginThread(pTx->m_CompleteRoutine, pTx->m_pParam);
CloseHandle( hSendEvent );
pTx->m_ThreadRunning = 0;
AfxEndThread(0);
}
pTxPackage = pTx->HP_CreateSendPackage(
pTx,
pTx->m_PacketLen,
W32N_IsWindows95()
);
if( pTxPackage )
{
//
// Call The Driver To Send The Packet
//
if( W32N_IsWindows95() )
{
bSendResult = W32N_PacketSendEx(
pTx->m_HookAdapter.m_hDevice,
pTxPackage->PacketBufferSpace,
pTxPackage->nFrameSize, // Input Data (i.e., To Driver)
&pTxPackage->nBytesReturned,
&pTxPackage->OverLapped, // REQUIRED For FILE_FLAG_OVERLAPPED
(PVOID)CTx::SendCompleteApc95
);
}
else if( W32N_IsWindowsNT() )
{
bSendResult = W32N_PacketSendEx(
pTx->m_HookAdapter.m_hDevice,
pTxPackage->PacketBufferSpace,
pTxPackage->nFrameSize, // Input Data (i.e., To Driver)
&pTxPackage->nBytesReturned,
&pTxPackage->OverLapped, // REQUIRED For FILE_FLAG_OVERLAPPED
(PVOID)CTx::SendCompleteApcNT
);
}
else
{
// ATTENTION!!! Deal with this case!!!
}
if( !bSendResult )
{
nSendResult = W32N_GetLastError();
if( nSendResult == ERROR_SUCCESS )
{
//
// Immediate Completion
// --------------------
// But SendCompleteApc() should still be called. Don't free
// any resources here!
//
return TRUE;
}
if( nSendResult != ERROR_IO_PENDING )
{
//
// Send Failed
// -----------
// SendCompleteApc() won't be called. Free resources here.
//
HP_DestroySendPackage( pTxPackage );
return TRUE;
}
}
}
}
// wait the completion routine end
nResult = WaitForSingleObjectEx( hSendEvent, 10, TRUE );
//
// Free Resources
//
CloseHandle( hSendEvent );
return 0;
}
bool CTx::DoStopContinueSend()
{
this->m_ThreadRunning = 0;
return 1;
}
bool CTx::SetUserDefinedPattern(const char *ptr, int size)
{
if( (MHdrSize + size + sizeof(FRAME_INFO_HEADER)) > PACKET_BUFFER_SIZE )
{
return FALSE;
}
if (m_UserDefinedPattern) free(m_UserDefinedPattern);
m_UserDefinedPattern = (char *)malloc(size);
if (!m_UserDefinedPattern) return FALSE;
memcpy(this->m_UserDefinedPattern, ptr, size);
m_UserDefinedPattern_Len = size;
return TRUE;
}
bool CTx::IsSending()
{
return this->m_ThreadRunning;
}
DWORD64 CTx::GetTotalBytes()
{
return this->m_HookAdapter.m_BytesSent;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -