📄 packet.cpp
字号:
//********************************************************************
// 日期: 2004/08/24 - 24:8:2004 20:37
// 名前: tiamo
// 描述: packet
//*********************************************************************
#include "Stdafx.h"
// for debug memory allocate
#define __ulFILE__ MAKE_SIG('P','A','K','T')
// pool
PACKET_POOL g_poolPacket;
BUFFER_POOL g_poolBuffer;
// ndis buffer pool
NDIS_HANDLE g_hNdisBufferPool;
// packet lookaside
NPAGED_LOOKASIDE_LIST g_lookasidePacket;
// init pool
NDIS_STATUS InitializePoolSystem()
{
// packet pool
g_poolPacket.m_ulSig = PACKET_POOL_SIG;
g_poolPacket.m_ulFreePackets = 0;
g_poolPacket.m_ulMaxFreeGuard = 100;
g_poolPacket.m_ulPacketsPerBlock = 16;
g_poolPacket.m_ulProtocolReservedLen = sizeof(PROTOCOL_RESERVED);
g_poolPacket.m_ulTotalPackets = 0;
NdisInitializeListHead(&g_poolPacket.m_ltPacketBlocksHead);
NdisInitializeListHead(&g_poolPacket.m_ltFreePacketsHead);
NdisAllocateSpinLock(&g_poolPacket.m_lockSelf);
g_poolBuffer.m_ulSig = BUFFER_POOL_SIG;
g_poolBuffer.m_ulBufferSize = PPPOE_MAX_ETH_FRAME_SIZE;
g_poolBuffer.m_ulBuffersPerBlock = 10;
g_poolBuffer.m_ulFreeBuffers = 0;
g_poolBuffer.m_ulMaxFreeGuard = 100;
g_poolBuffer.m_ulTotalBuffers = 0;
NdisAllocateSpinLock(&g_poolBuffer.m_lockSelf);
NdisInitializeListHead(&g_poolBuffer.m_ltBufferBlocksHead);
NdisInitializeListHead(&g_poolBuffer.m_ltFreeBuffersHead);
NdisInitializeNPagedLookasideList(&g_lookasidePacket,0,0,0,sizeof(PACKET),PACKET_SIG,0);
NDIS_STATUS status = NDIS_STATUS_SUCCESS;
// for ndis buffer pool
NdisAllocateBufferPool(&status,&g_hNdisBufferPool,30);
if(status != NDIS_STATUS_SUCCESS)
{
DebugError(("can't allocate ndis buffer pool status = 0x%x.\n",status));
}
return status;
}
// shut down
VOID ShutdownPoolSystem()
{
ASSERT(g_poolBuffer.m_ulSig == BUFFER_POOL_SIG);
ASSERT(g_poolPacket.m_ulSig == PACKET_POOL_SIG);
// free buffer pool
NdisAcquireSpinLock(&g_poolBuffer.m_lockSelf);
FreeUnusedBufferBlock(&g_poolBuffer);
NdisReleaseSpinLock(&g_poolBuffer.m_lockSelf);
// free packet pool
NdisAcquireSpinLock(&g_poolPacket.m_lockSelf);
FreeUnusedPacketBlock(&g_poolPacket);
NdisReleaseSpinLock(&g_poolPacket.m_lockSelf);
// free npaged list
NdisDeleteNPagedLookasideList(&g_lookasidePacket);
// free ndis buffer pool
if(g_hNdisBufferPool)
{
NdisFreeBufferPool(g_hNdisBufferPool);
}
// dump packet leak
DumpPoolLeak();
NdisFreeSpinLock(&g_poolPacket.m_lockSelf);
NdisFreeSpinLock(&g_poolBuffer.m_lockSelf);
}
// reference packet
VOID ReferencePacket(PPACKET pPacket)
{
ASSERT(pPacket && pPacket->m_ulSig == PACKET_SIG);
InterlockedIncrement(&pPacket->m_lRefCount);
}
// dereference packet
VOID DereferencePacket(PPACKET pPacket)
{
ASSERT(pPacket && pPacket->m_lRefCount > 0 && pPacket->m_ulSig == PACKET_SIG);
LONG lCount = InterlockedDecrement(&pPacket->m_lRefCount);
// ref == 0
if(!lCount)
{
// header buffer chained
if(pPacket->m_ulFlags & PPPOE_PACKET_HEADER_BUFFER_CHAINED)
{
ASSERT(pPacket->m_pNdisPacket);
NdisUnchainBufferAtFront(pPacket->m_pNdisPacket,&pPacket->m_pNdisHeaderBuffer);
}
// data chained
if(pPacket->m_ulFlags & PPPOE_PACKET_DATA_BUFFER_CHAINED)
{
ASSERT(pPacket->m_pNdisPacket);
NdisUnchainBufferAtFront(pPacket->m_pNdisPacket,&pPacket->m_pNdisDataBuffer);
}
// allocated from our pool
if(pPacket->m_ulFlags & PPPOE_PACKET_BUFFER_FROM_POOL)
{
ASSERT(pPacket->m_pNdisDataBuffer && pPacket->m_pNdisHeaderBuffer && pPacket->m_pRealBuffer);
NdisAdjustBufferLength(pPacket->m_pNdisDataBuffer,g_poolBuffer.m_ulBufferSize - PPPOE_HEADER_LEN);
FreeNdisBufferToPool(&g_poolBuffer,pPacket->m_pRealBuffer);
}
// allocated from ndis pool
if(pPacket->m_ulFlags & PPPOE_PACKET_HEADER_BUFFER_FROM_NDIS)
{
ASSERT(pPacket->m_pNdisHeaderBuffer);
NdisFreeBuffer(pPacket->m_pNdisHeaderBuffer);
}
if(pPacket->m_ulFlags & PPPOE_PACKET_DATA_BUFFER_FROM_NDIS)
{
ASSERT(pPacket->m_pNdisDataBuffer);
NdisFreeBuffer(pPacket->m_pNdisDataBuffer);
}
// call send complete
if(pPacket->m_ulFlags & PPPOE_PACKET_NEED_CALL_SEND_COMPLETE)
{
ASSERT(pPacket->m_pNdisPacket && pPacket->m_pNdisDataBuffer);
PPROTOCOL_RESERVED pResv = reinterpret_cast<PPROTOCOL_RESERVED>(pPacket->m_pNdisPacket->ProtocolReserved);
ASSERT(pResv && pResv->m_pOrginalPacket && pResv->m_pOrginalPacket);
NdisChainBufferAtFront(pResv->m_pOrginalPacket,pPacket->m_pNdisDataBuffer);
ASSERT(pResv->m_pChannel && pResv->m_pChannel->m_hNdisVcHandle);
NdisMCoSendComplete(pPacket->m_status,pResv->m_pChannel->m_hNdisVcHandle,pResv->m_pOrginalPacket);
NdisInterlockedDecrement(&pResv->m_pChannel->m_lSendingPackets);
}
// free to pool
if(pPacket->m_ulFlags & PPPOE_PACKET_FROM_POOL)
{
ASSERT(pPacket->m_pNdisPacket);
FreeNdisPacketToPool(&g_poolPacket,pPacket->m_pPacketItem);
}
// return the packet
if(pPacket->m_ulFlags & PPPOE_PACKET_NEED_RETURN_PACKET)
{
ASSERT(pPacket->m_pNdisPacket && pPacket->m_pNdisReturnBuffer);
NdisChainBufferAtFront(pPacket->m_pNdisPacket,pPacket->m_pNdisReturnBuffer);
NdisReturnPackets(&pPacket->m_pNdisPacket,1);
ASSERT(pPacket->m_pBindContext);
NdisInterlockedDecrement(&pPacket->m_pBindContext->m_lPacketNeedReturn);
}
FreePacket(pPacket);
}
}
// get simple packet
PPACKET GetSimplePacket()
{
PPACKET pRetPacket = NULL;
__try
{
// allocate packet storage
pRetPacket = AllocPacket();
// get ndis packet
pRetPacket->m_pNdisPacket = GetNdisPacketFromPool(&g_poolPacket,&pRetPacket->m_pPacketItem);
// set pointer
reinterpret_cast<PPROTOCOL_RESERVED>(pRetPacket->m_pNdisPacket->ProtocolReserved)->m_pPacket = pRetPacket;
// got here packet pointer is not null,set flags
pRetPacket->m_ulFlags |= PPPOE_PACKET_FROM_POOL;
// get frame buffer and ndis buffers
pRetPacket->m_pFrame = GetNdisBufferFromPool(&g_poolBuffer,&pRetPacket->m_pNdisHeaderBuffer,&pRetPacket->m_pNdisDataBuffer);
// chain
NdisChainBufferAtFront(pRetPacket->m_pNdisPacket,pRetPacket->m_pNdisDataBuffer);
// set flags
pRetPacket->m_ulFlags |= PPPOE_PACKET_BUFFER_FROM_POOL;
pRetPacket->m_ulFlags |= PPPOE_PACKET_DATA_BUFFER_CHAINED;
NdisChainBufferAtFront(pRetPacket->m_pNdisPacket,pRetPacket->m_pNdisHeaderBuffer);
pRetPacket->m_ulFlags |= PPPOE_PACKET_HEADER_BUFFER_CHAINED;
// set pointer
pRetPacket->m_pucDataBuffer = pRetPacket->m_pucFrame + PPPOE_HEADER_LEN;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
if(pRetPacket)
{
DereferencePacket(pRetPacket);
pRetPacket = NULL;
}
}
return pRetPacket;
}
// clone packet
PPACKET ClonePacket(PPACKET pPacket)
{
PPACKET pRet = GetSimplePacket();
if(pRet)
{
NdisMoveMemory(pRet->m_pFrame,pPacket->m_pFrame,PPPOE_HEADER_LEN);
NdisMoveMemory(pRet->m_pucDataBuffer,pPacket->m_pucDataBuffer,PPPOE_MAX_DATA_SIZE);
NdisAdjustBufferLength(pRet->m_pNdisDataBuffer,ntohs(pPacket->m_pFrame->m_pppFrame.m_usLen));
}
return pRet;
}
// get packet from pool
PNDIS_PACKET GetNdisPacketFromPool(PPACKET_POOL pPacketPool,PPACKET_ITEM *ppItem)
{
PNDIS_PACKET pRet = NULL;
ASSERT(ppItem && pPacketPool && pPacketPool->m_ulSig == PACKET_POOL_SIG);
*ppItem = NULL;
NdisAcquireSpinLock(&pPacketPool->m_lockSelf);
// no free packets
if(IsListEmpty(&pPacketPool->m_ltFreePacketsHead))
{
// allocate a block
pRet = AddPacketBlockToPool(pPacketPool,ppItem);
}
else
{
PLIST_ENTRY pEntry = RemoveHeadList(&pPacketPool->m_ltFreePacketsHead);
PPACKET_ITEM pItem = CONTAINING_RECORD(pEntry,PACKET_ITEM,m_ltPacketItemAnchor);
pRet = pItem->m_pNdisPacket;
*ppItem = pItem;
pPacketPool->m_ulFreePackets --;
pItem->m_pPacketBlock->m_ulFreePacketItems --;
}
NdisReleaseSpinLock(&pPacketPool->m_lockSelf);
return pRet;
}
// get ndis buffer from pool
PPPPOE_FRAME GetNdisBufferFromPool(PBUFFER_POOL pBufferPool,PNDIS_BUFFER *ppHeaderBuffer,PNDIS_BUFFER *ppDataBuffer)
{
PPPPOE_FRAME pRet = NULL;
ASSERT(ppHeaderBuffer && ppDataBuffer && pBufferPool && pBufferPool->m_ulSig == BUFFER_POOL_SIG);
*ppHeaderBuffer = NULL;
*ppDataBuffer = NULL;
NdisAcquireSpinLock(&pBufferPool->m_lockSelf);
// no free packets
if(IsListEmpty(&pBufferPool->m_ltFreeBuffersHead))
{
// allocate a block
pRet = AddBufferBlockToPool(pBufferPool,ppHeaderBuffer,ppDataBuffer);
}
else
{
// get a free buffer
PLIST_ENTRY pEntry = RemoveHeadList(&pBufferPool->m_ltFreeBuffersHead);
PBUFFER_ITEM pItem = CONTAINING_RECORD(pEntry,BUFFER_ITEM,m_ltBufferItemAnchor);
pRet = reinterpret_cast<PPPPOE_FRAME>(pItem->m_pStorage);
*ppHeaderBuffer = pItem->m_pNdisHeadBuffer;
*ppDataBuffer = pItem->m_pNdisDataBuffer;
pBufferPool->m_ulFreeBuffers --;
pItem->m_pBufferBlock->m_ulFreeBufferItems --;
}
NdisReleaseSpinLock(&pBufferPool->m_lockSelf);
return pRet;
}
// allocate packet
PPACKET AllocPacket()
{
PPACKET pRet = static_cast<PPACKET>(NdisAllocateFromNPagedLookasideList(&g_lookasidePacket));
NdisZeroMemory(pRet,sizeof(PACKET));
pRet->m_lRefCount = 1;
pRet->m_ulSig = PACKET_SIG;
NdisInitializeListHead(&pRet->m_ltPacketAnchor);
return pRet;
}
// free buffers to pool
VOID FreeNdisBufferToPool(PBUFFER_POOL pPool,PVOID pRealBuffer)
{
ASSERT(pPool && pRealBuffer && pPool->m_ulSig == BUFFER_POOL_SIG);
NdisAcquireSpinLock(&pPool->m_lockSelf);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -