⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 packet.cpp

📁 pppoe client
💻 CPP
📖 第 1 页 / 共 2 页
字号:

//********************************************************************
//	日期:	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 + -