📄 read.c
字号:
#include "packet.h"
#include "filter.h"
BOOL bNowGetBufType=FALSE;
//extern BOOL PKTWrite (POPEN_INSTANCE, PVOID, DWORD, PDWORD);
/*
* This function does nothing. There is no concept of seek in
* packet io. Function simply returns -1
*
*/
DWORD PKT_Seek(DWORD Handle, LONG lDistance, WORD dwMoveMethod)
{
return 0xFFFFFFFF;
}
/*
* This function does nothing
* all the read calls are handled by IO Control function
*
*/
DWORD PKT_Read(DWORD dwContext, LPVOID pBuffer, DWORD Count)
{
return 0;
}
UINT GetBuffOccupancy(POPEN_INSTANCE pOpen)
{
if (pOpen->Btail - pOpen->Bhead >= 0) {
return pOpen->Btail - pOpen->Bhead;
}
return pOpen->BLastByte - pOpen->Bhead + pOpen->Btail;
}
void PacketMoveMem(PVOID Destination, PVOID Source, ULONG Length, UINT *Bhead)
{
ULONG WordLength;
UINT n,i,NBlocks;
WordLength = Length >> 2;
NBlocks = WordLength >> 8;
for (n = 0; n < NBlocks; n++) {
for (i = 0; i < 256; i++) {
*((PULONG)Destination)++ = *((PULONG)Source)++;
}
*Bhead += 1024;
}
n = WordLength - (NBlocks << 8);
for (i = 0; i < n; i++) {
*((PULONG)Destination)++ = *((PULONG)Source)++;
}
*Bhead += n << 2;
n = Length - (WordLength << 2);
for (i = 0; i < n; i++) {
*((PUCHAR)Destination)++ = *((PUCHAR)Source)++;
}
*Bhead += n;
}
/*
* Reads into user buffer
*
*/
BOOL PKTRead (POPEN_INSTANCE pOI, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut)
{
UINT Thead;
UINT Ttail;
UINT TLastByte;
ULONG Input_Buffer_Length;
UINT nCount;
PBYTE pCurrBuff;
UINT cplen;
UINT CpStart;
PUCHAR packp; //buffer that maps the application memory
UINT TheadAddLen;
if (dwLenOut < ETHERNET_HEADER_LENGTH) {
// the application's buffer if too small to contain the packet
SAFE_SET(pdwActualOut, 0);
return FALSE;
}
//See if the buffer is full enough to be copied
if (GetBuffOccupancy (pOI) <= pOI->MinToCopy) {
//there are not enough buffered packets: the application must wait
//wait until some packets arrive or the timeout expires
ResetEvent (pOI->ReadEvent);
if (pOI->TimeOut != -1) {
WaitForSingleObject (pOI->ReadEvent, pOI->TimeOut);
}
// reset the event
ResetEvent (pOI->ReadEvent);
if (pOI->Bhead == pOI->Btail)
{
//the timeout has expired, but the buffer is still empty.
//we must awake the application returning an empty buffer.
SetEvent (pOI->ReadEvent);
SAFE_SET (pdwActualOut, 0);
return TRUE;
}
}
// see if there are packets in the buffer
Thead = pOI->Bhead;
Ttail = pOI->Btail;
TLastByte = pOI->BLastByte;
// there is at least a buffered packet: the read call can be completed
Input_Buffer_Length = dwLenOut;
packp = (PUCHAR)pBufOut;
nCount = 0;
// get the address of the buffer
pCurrBuff = pOI->Buffer;
// fill the application buffer
// first of all see if it we can copy all the buffer in one go
if (Ttail > Thead) {
if ((Ttail - Thead) < Input_Buffer_Length) {
PacketMoveMem (packp, pCurrBuff + Thead, Ttail - Thead, &(pOI->Bhead));
SAFE_SET (pdwActualOut, Ttail - Thead);
// The buffer is empty: reset the read event
ResetEvent (pOI->ReadEvent);
return TRUE;
}
}
else if ((TLastByte - Thead) < Input_Buffer_Length) {
PacketMoveMem (packp, pCurrBuff + Thead, TLastByte - Thead, &(pOI->Bhead));
TheadAddLen=TLastByte - Thead;
pOI->BLastByte = Ttail;
pOI->Bhead = 0;
Thead =0;
PacketMoveMem (packp+TheadAddLen, pCurrBuff, Ttail, &(pOI->Bhead));
SAFE_SET(pdwActualOut, TheadAddLen + Ttail);
// The buffer is empty: reset the read event
ResetEvent (pOI->ReadEvent);
return TRUE;
}
// scan the buffer
CpStart = Thead;
while (TRUE) {
if (Thead == Ttail) {
break;
}
if (Thead == TLastByte) {
PacketMoveMem (packp, pCurrBuff + CpStart, Thead - CpStart, &(pOI->Bhead));
packp += (Thead - CpStart);
pOI->Bhead = 0;
Thead = 0;
CpStart = 0;
}
cplen = ((struct bpf_hdr*) (pCurrBuff + Thead))->bh_caplen +
sizeof(struct bpf_hdr);
if ((nCount + cplen > Input_Buffer_Length)) {
PacketMoveMem (packp, pCurrBuff + CpStart, Thead - CpStart, &(pOI->Bhead));
SAFE_SET (pdwActualOut, nCount);
ResetEvent (pOI->ReadEvent);
return TRUE;
}
cplen = PACKET_WORDALIGN(cplen);
nCount += cplen;
Thead += cplen;
}
ResetEvent (pOI->ReadEvent);
PacketMoveMem (packp, pCurrBuff + CpStart, Thead - CpStart, &(pOI->Bhead));
pOI->Bhead = Thead;
SAFE_SET (pdwActualOut, nCount);
return TRUE;
}
BOOL PKTWriteSend(POPEN_INSTANCE pOI, PVOID pBufIn, DWORD dwLenIn, PDWORD pdwActualOut)
{
NDIS_STATUS Status;
PNDIS_PACKET pPacket;
PNDIS_BUFFER pNdisBuffer;
// check if the length of the packet is zero
if (dwLenIn == 0) {
return TRUE;
}
do
{
// mark io pending
pOI->Status = NDIS_STATUS_PENDING;
// allocate packet
NdisAllocatePacket (&Status, &pPacket, pOI->PacketPool);
if (Status != NDIS_STATUS_SUCCESS) {
SAFE_SET (pdwActualOut, 0);
return FALSE;
}
// allocate the buffer
NdisAllocateBuffer (&Status, &pNdisBuffer, pOI->BufferPool, pBufIn, dwLenIn);
if (Status != NDIS_STATUS_SUCCESS) {
NdisReinitializePacket(pPacket);
NdisFreePacket(pPacket);
SAFE_SET (pdwActualOut, 0);
return FALSE;
}
// add the buffer to the buffer chain
NdisChainBufferAtFront (pPacket, pNdisBuffer);
// send the packet on the network
NdisSend (&Status, pOI->AdapterHandle, pPacket);
if (Status != NDIS_STATUS_PENDING) {
PacketWriteComplete (pOI, pPacket, Status);
}
} while(FALSE);
return TRUE;
}
NDIS_STATUS PacketReceive(IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE MacReceiveContext,
IN PVOID HeaderBuffer,
IN UINT HeaderBufferSize,
IN PVOID LookAheadBuffer,
IN UINT LookaheadBufferSize,
IN UINT PacketSize)
{
POPEN_INSTANCE pOI;
UINT fres; //filter result
UINT Thead;
UINT Ttail;
UINT TLastByte;
UINT maxbufspace;
PUCHAR CurrBuff;
NDIS_STATUS Status;
PNDIS_BUFFER pNdisBuffer;
PNDIS_PACKET pPacket;
ULONG BufferLength;
ULONG SizeToTransfer;
UINT BytesTransfered;
// LARGE_INTEGER CapTime;
// LARGE_INTEGER TimeFreq;
struct bpf_hdr *header;
DWORD dGetSendInfo=0;
PUCHAR pSendLsBuf,pSendLsHeadbuf;
PUCHAR ChectBuf;
pOI = (POPEN_INSTANCE) ProtocolBindingContext;
/*
Check if the lookahead buffer follows the mac header.
If the data follow the header (i.e. there is only a buffer) a normal bpf_filter() is
executed on the packet.
Otherwise if there are 2 separate buffers (this could be the case of LAN emulation or
stuff like this) bpf_filter_with_2_buffers() is executed.
*/
if ((UINT)LookAheadBuffer - (UINT)HeaderBuffer != HeaderBufferSize) {
fres = bpf_filter_with_2_buffers ((struct bpf_insn*)(pOI->bpfprogram),
HeaderBuffer, LookAheadBuffer, HeaderBufferSize,
PacketSize + HeaderBufferSize, LookaheadBufferSize + HeaderBufferSize);
} else {
fres = bpf_filter ((struct bpf_insn*)(pOI->bpfprogram),
HeaderBuffer, PacketSize + HeaderBufferSize,
LookaheadBufferSize + HeaderBufferSize);
}
// if filter returns 0 the packet is rejected
if (fres == 0) {
return NDIS_STATUS_NOT_ACCEPTED;
}
//if the filter returns -1 the whole packet must be accepted
if (fres == -1) {
fres = PacketSize + HeaderBufferSize;
}
//
if (pOI->BufSize == 0) {
return NDIS_STATUS_NOT_ACCEPTED;
}
Thead = pOI->Bhead;
Ttail = pOI->Btail;
TLastByte = pOI->BLastByte;
maxbufspace =fres + sizeof(struct bpf_hdr);
//////////////////////////////////
//*******王树 2006-03-29 **************
ChectBuf=(PUCHAR)HeaderBuffer;
if(ChectBuf[0]==0x80 && ChectBuf[1]==0x81){
if(PacketSize + HeaderBufferSize==128){
return NDIS_STATUS_NOT_ACCEPTED;
}
}
////////////////////////////////////
if(PacketSize+HeaderBufferSize==128 && ChectBuf[0]==0xAA && ChectBuf[1]==0x55)
{ /// 128 字节 发送数据包
if(bDriverSendFlag && pOI != NULL)
{
ResetEvent(pOI->SendFlagEvent);
pSendLsBuf=(PUCHAR)pSendBufIn+lPacketIndex*129;
if(lStartPacket==TRUE)
{ //如果是第一次发包
if(pSendLsBuf[129*48]==0x01)
{
PKTWriteSend(pOI,(PVOID)(pSendLsBuf+1),128, &dGetSendInfo);
pSendLsBuf[0]=0x00;
lStartPacket=FALSE;
// memset(pSendLsBuf+17,0,64);
}
} else {
pSendLsHeadbuf=pSendLsBuf;
lPacketIndex=(lPacketIndex+1)%lPacketCount;
pSendLsBuf=(PUCHAR)pSendBufIn+lPacketIndex*129;
if(pSendLsBuf[0]==0x01)
{
PKTWriteSend (pOI,(PVOID)(pSendLsBuf+1),128, &dGetSendInfo);
pSendLsBuf[0]=0x00;
// memset(pSendLsBuf+17,0,64);
} else {
memset(pSendLsHeadbuf+17,0,64);
if(lPacketIndex==0)
{
lPacketIndex=lPacketCount-1;
} else {
lPacketIndex=lPacketIndex-1;
}
PKTWriteSend (pOI,(PVOID)(pSendLsHeadbuf+1),128, &dGetSendInfo);
pSendLsHeadbuf[0]=0x02;
} //if(pSendLsBuf[0]==0x01)
} //if(lStartPacket==TRUE)
SetEvent(pOI->SendFlagEvent);
}
}
///////////////////////////////////
///////////////////////////////////
if (Ttail + maxbufspace >= pOI->BufSize) {
if(Thead <= maxbufspace) {
//the buffer is full: the packet is lost
return NDIS_STATUS_NOT_ACCEPTED;
} else {
Ttail = 0;
}
}
if((Ttail < Thead) && (Ttail + maxbufspace >= Thead)) {
//the buffer is full: the incoming packet is lost
return NDIS_STATUS_NOT_ACCEPTED;
}
CurrBuff = pOI->Buffer+Ttail;
// allocate the ndis buffer
NdisAllocateBuffer (&Status, &pNdisBuffer, pOI->BufferPool,
CurrBuff + sizeof(struct bpf_hdr) + HeaderBufferSize, fres);
if (Status != NDIS_STATUS_SUCCESS) {
return NDIS_STATUS_NOT_ACCEPTED;
}
// allocate the packet from NDIS
NdisAllocatePacket (&Status, &pPacket, pOI->PacketPool);
if (Status != NDIS_STATUS_SUCCESS) {
NdisFreeBuffer( pNdisBuffer );
return NDIS_STATUS_NOT_ACCEPTED;
}
// link the buffer to the packet
NdisChainBufferAtFront(pPacket, pNdisBuffer);
BufferLength = fres - HeaderBufferSize;
//Find out how much to transfer
SizeToTransfer = (PacketSize < BufferLength) ? PacketSize : BufferLength;
//copy the ethernet header into buffer
NdisMoveMemory ((CurrBuff) + sizeof(struct bpf_hdr),
HeaderBuffer, HeaderBufferSize);
// call the Mac to transfer the packet
NdisTransferData (&Status, pOI->AdapterHandle,
MacReceiveContext, 0, SizeToTransfer, pPacket,
&BytesTransfered);
if (Status != NDIS_STATUS_FAILURE) {
//store the capture time
if (fres > BytesTransfered + HeaderBufferSize) {
fres = BytesTransfered + HeaderBufferSize;
}
//fill the bpf header for this packet
// CapTime.QuadPart += pOI->StartTime.QuadPart;
header = (struct bpf_hdr*)CurrBuff;
header->bh_tstamp.tv_usec =0;// (long)((CapTime.QuadPart % TimeFreq.QuadPart * 1000000) / TimeFreq.QuadPart);
header->bh_tstamp.tv_sec =0;// (long)(CapTime.QuadPart / TimeFreq.QuadPart);
header->bh_caplen = fres;
header->bh_datalen = PacketSize + HeaderBufferSize;
header->bh_hdrlen = sizeof(struct bpf_hdr);
//update the buffer
Ttail += PACKET_WORDALIGN(fres + sizeof (struct bpf_hdr));
if (Ttail > Thead) {
TLastByte = Ttail;
}
pOI->Btail = Ttail;
pOI->BLastByte = TLastByte;
}
// free the allocated buffer
NdisFreeBuffer (pNdisBuffer);
// recylcle the packet
NdisReinitializePacket(pPacket);
// put the packet on the free queue
NdisFreePacket (pPacket);
// unfreeze PacketRead
if (GetBuffOccupancy (pOI) > pOI->MinToCopy) {
SetEvent(pOI->ReadEvent);
}
return NDIS_STATUS_SUCCESS;
}
/*
* The Receive Complete handler. This function is not required
*
*/
VOID PacketReceiveComplete(IN NDIS_HANDLE ProtocolBindingContext)
{
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -