如题,在玩传说中的ndis6,把接收到的数据拷贝一份然后转发到自己定义的地方,主要实现在FilterReceiveNetBufferLists这个处理接收数据的回调里。但是问题来了,数据都木有问题,但是转发的时候,对方却没有capture到包。。。
看代码:
VOID
FilterReceiveNetBufferLists(
IN NDIS_HANDLE FilterModuleContext,
IN PNET_BUFFER_LIST NetBufferLists,
IN NDIS_PORT_NUMBER PortNumber,
IN ULONG NumberOfNetBufferLists,
IN ULONG ReceiveFlags
)
{
PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
BOOLEAN DispatchLevel;
ULONG Ref;
BOOLEAN bFalse = FALSE;
PNET_BUFFER_LIST CurrNbl,NextNbl,RedirectNbl,NomalNbl ;
PNET_BUFFER pCurrentNetBuffer;
PUCHAR pPacketBuffer = NULL ;
ULONG ulPacketLength;
IPRESULT result = enumIP_Unknow;
NBL_QUEUE_HEADER NblReceiveQueue; // NBLs to passthrough to lower-level miniport
NBL_QUEUE_HEADER NblRedirectQueue; // NBLs to redirect by send completion
NBL_QUEUE_HEADER NblBlockQueue; // NBLs to return to higher-level protocol by send completion
#if DBG
ULONG ReturnFlags;
#endif
DEBUGP(DL_TRACE, ("===>ReceiveNetBufferList: NetBufferLists = %p.\n", NetBufferLists));
do
{
DispatchLevel = NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags);
ASSERT(NumberOfNetBufferLists >= 1);
/************************************************************************/
/* NDIS6 Filter Frame pause */
/************************************************************************/////////////////////////////////////////////////////////////////
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);
//
INIT_NBL_QUEUE_HEADER( &NblReceiveQueue );
INIT_NBL_QUEUE_HEADER( &NblRedirectQueue );
INIT_NBL_QUEUE_HEADER( &NblBlockQueue );
CurrNbl = NetBufferLists;
while (CurrNbl)
{
for(pCurrentNetBuffer = NET_BUFFER_LIST_FIRST_NB(CurrNbl);
pCurrentNetBuffer != NULL;
pCurrentNetBuffer = NET_BUFFER_NEXT_NB(pCurrentNetBuffer))
{
RedirectNbl = NULL;
ReadNetBuffer(pCurrentNetBuffer, &pPacketBuffer, &ulPacketLength);
if (pPacketBuffer)
{
result = AuditNetBuf(pPacketBuffer, TRUE, &ulPacketLength);
}
if ( result == enumIP_Redirect )
{
struct iphdr* pIpHdr = NULL;
RedirectNbl = BuildNetBufferLists(pPacketBuffer, ulPacketLength, pFilter);
pIpHdr = (struct iphdr*)(pPacketBuffer + sizeof(struct ethhdr));
pFilter->uiChkTag = pIpHdr->check;
INSERT_TAIL_NBL_QUEUE( &NblRedirectQueue, RedirectNbl );
//INSERT_TAIL_NBL_QUEUE( &NblBlockQueue, RedirectNbl );
}
else
{
//NomalNbl = BuildNetBufferLists(pPacketBuffer, ulPacketLength, pFilter);
pFilter->uiChkTag = 0;
//INSERT_TAIL_NBL_QUEUE( &NblReceiveQueue, NomalNbl );
}
ExFreePoolWithTag(pPacketBuffer, 'Fbtn');
pPacketBuffer = NULL;
}
if ( result == enumIP_Unknow )
{
INSERT_TAIL_NBL_QUEUE( &NblReceiveQueue, CurrNbl );
}
else if ( result == enumIP_Redirect )
{
INSERT_TAIL_NBL_QUEUE( &NblBlockQueue, CurrNbl );
}
result = enumIP_Unknow;
CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
}
if( GET_NBL_QUEUE_HEAD( &NblRedirectQueue ))
{
NdisFSendNetBufferLists(
pFilter->FilterHandle,
GET_NBL_QUEUE_HEAD( &NblRedirectQueue ),
PortNumber,
NDIS_SEND_FLAGS_DISPATCH_LEVEL
);
}
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
/************************************************************************/
/* NDIS6 Filter Frame continue */
/************************************************************************/////////////////////////////////////////////////////////////////
//
if (pFilter->TrackReceives)
{
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);
pFilter->OutstandingRcvs += NumberOfNetBufferLists;
Ref = pFilter->OutstandingRcvs;
FILTER_LOG_RCV_REF(1, pFilter, NetBufferLists, Ref);
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
}
// Complete Blocked NetBufferLists
if( GET_NBL_QUEUE_HEAD( &NblBlockQueue ) )
{
ReturnFlags = 0;
if (NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags))
{
NDIS_SET_RETURN_FLAG(ReturnFlags, NDIS_RETURN_FLAGS_DISPATCH_LEVEL);
}
NdisFReturnNetBufferLists( pFilter->FilterHandle, GET_NBL_QUEUE_HEAD( &NblBlockQueue ), ReturnFlags );
}
// Complete Received NetBufferLists
if( GET_NBL_QUEUE_HEAD( &NblReceiveQueue ) )
{
NdisFIndicateReceiveNetBufferLists(
pFilter->FilterHandle,
GET_NBL_QUEUE_HEAD( &NblReceiveQueue ),
PortNumber,
NumberOfNetBufferLists,
ReceiveFlags
);
}
if (NDIS_TEST_RECEIVE_CANNOT_PEND(ReceiveFlags) &&
pFilter->TrackReceives)
{
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);
pFilter->OutstandingRcvs -= NumberOfNetBufferLists;
Ref = pFilter->OutstandingRcvs;
FILTER_LOG_RCV_REF(2, pFilter, NetBufferLists, Ref);
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
}
} while (bFalse);
DEBUGP(DL_TRACE, ("<===ReceiveNetBufferList: Flags = %8x.\n", ReceiveFlags));
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!