NDIS6.0 如何拦截数据包

见习学术士 2013-11-18 11:42:10


VOID
FilterReceiveNetBufferLists(
IN NDIS_HANDLE FilterModuleContext,
IN PNET_BUFFER_LIST NetBufferLists,
IN NDIS_PORT_NUMBER PortNumber,
IN ULONG NumberOfNetBufferLists,
IN ULONG ReceiveFlags
)
/*++

Routine Description:

FilerReceiveNetBufferLists is an optional function for filter drivers.
If provided, this function process receive indications made by underlying
NIC or lower level filter drivers. This function can also be called as a
result of loopback. If this handler is NULL, NDIS will skip calling this
filter when processing a receive indication and will call the next upper
filter in the stack with a non-NULL FitlerReceiveNetBufferLists handler
or the procotol driver. A filter that doesn't provide a
FilterReceiveNetBufferLists handler can not provided a
FilterReturnNetBufferLists handler or a initiate a receive indication on
its own.

Arguments:

FilterModuleContext: Pointer to our filter context area.
NetBufferLists: A linked list of NetBufferLists allocated by underlying driver each containing
one NetBuffer.
PortNumber: Port on which the Receive is indicated
ReceiveFlags: Flags associated with the Receive such as whether the filter
can pend the receive


Return Value:

None

--*/
{

PMS_FILTER pFilter = (PMS_FILTER)FilterModuleContext;
BOOLEAN DispatchLevel;
ULONG Ref;
BOOLEAN bFalse = FALSE;
PNET_BUFFER_LIST CurrNbl, NextNbl;
PNET_BUFFER pCurrentNetBuffer;
PVOID pPacketBuffer = NULL;
ULONG ulPacketLength = 0;
IPRESULT result = enumIP_Unknow;

#if DBG
ULONG ReturnFlags;
#endif

DEBUGP(DL_TRACE, ("===>ReceiveNetBufferList: NetBufferLists = %p.\n", NetBufferLists));
do
{

DispatchLevel = NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags);
#if DBG
FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);

if (pFilter->State != FilterRunning)
{
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);

if (NDIS_TEST_RECEIVE_CAN_PEND(ReceiveFlags))
{
ReturnFlags = 0;
if (NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags))
{
NDIS_SET_RETURN_FLAG(ReturnFlags, NDIS_RETURN_FLAGS_DISPATCH_LEVEL);
}

NdisFReturnNetBufferLists(pFilter->FilterHandle, NetBufferLists, ReturnFlags);
}
break;
}
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
#endif

ASSERT(NumberOfNetBufferLists >= 1);

FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);
CurrNbl = NetBufferLists;
while (CurrNbl && result != enumIP_Block)
{
for(pCurrentNetBuffer = NET_BUFFER_LIST_FIRST_NB(CurrNbl);
pCurrentNetBuffer != NULL;
pCurrentNetBuffer = NET_BUFFER_NEXT_NB(pCurrentNetBuffer))
{
pPacketBuffer = NULL;
ReadNetBuffer(pCurrentNetBuffer, &pPacketBuffer, ulPacketLength);

if( pPacketBuffer )
{
if( g_ndisFirewall != NULL )
{
result = g_ndisFirewall->Filter( pPacketBuffer, ulPacketLength, enumPD_Recieve );

if( result == enumIP_Block )
{
break;
}
}

non_paged_pool::__DeallocateSystemMemory( pPacketBuffer );
pPacketBuffer = NULL;
}
}
CurrNbl= NET_BUFFER_LIST_NEXT_NBL(CurrNbl);
}
FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);

if( result == enumIP_Block )
{
NDIS_SET_RECEIVE_FLAG(ReceiveFlags, NDIS_RECEIVE_FLAGS_RESOURCES);
NdisFReturnNetBufferLists(pFilter->FilterHandle, NetBufferLists, ReceiveFlags);
break;
}


//
// If necessary, queue the NetBufferList in a local structure for later processing.
// We may need to travel the list, some of them may not need post processing
//
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);
}

NdisFIndicateReceiveNetBufferLists(
pFilter->FilterHandle,
NetBufferLists,
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));

}


这样整个拦截 NBL 好像有问题,一些正常的SOCKET连接都超时了。
怎么样能对单个NB 拦截呢?
...全文
318 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
paigle 2013-11-21
  • 打赏
  • 举报
回复
引用 2 楼 xiaoc1026 的回复:
[quote=引用 1 楼 paigle 的回复:] MSDN上是这样说的: Discard the buffer. If NDIS cleared the NDIS_RECEIVE_FLAGS_RESOURCES flag, call the NdisFReturnNetBufferLists function to discard the buffer. If NDIS set the NDIS_RECEIVE_FLAGS_RESOURCES flag, take no action and return from FilterReceiveNetBufferLists to discard the buffer. ------- 即,要丢弃数据包 如果 ReceiveFlags 无 NDIS_RECEIVE_FLAGS_RESOURCES 标记,调用 NdisFReturnNetBufferLists 丢弃 如果 ReceiveFlags 有 NDIS_RECEIVE_FLAGS_RESOURCES 标记,直接从 FilterReceiveNetBufferLists return 即可 ------- 实际上,这个sample已经有示例了: FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel); if (pFilter->State != FilterRunning) { FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel); // 需要丢弃数据包 if (NDIS_TEST_RECEIVE_CAN_PEND(ReceiveFlags)) { // ReceiveFlags 无 NDIS_RECEIVE_FLAGS_RESOURCES 标记,调用NdisFReturnNetBufferLists() ReturnFlags = 0; if (NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags)) { NDIS_SET_RETURN_FLAG(ReturnFlags, NDIS_RETURN_FLAGS_DISPATCH_LEVEL); } NdisFReturnNetBufferLists(pFilter->FilterHandle, NetBufferLists, ReturnFlags); } else { // ReceiveFlags 有 NDIS_RECEIVE_FLAGS_RESOURCES 标记,不做任何事,直接后面 break后return即可 } break; } FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
解决办法是:分别为需要拦截和放行的NB 创建NBL,然后对应处理NBL[/quote] 给帮我给个示例么?
见习学术士 2013-11-21
  • 打赏
  • 举报
回复
引用 1 楼 paigle 的回复:
MSDN上是这样说的: Discard the buffer. If NDIS cleared the NDIS_RECEIVE_FLAGS_RESOURCES flag, call the NdisFReturnNetBufferLists function to discard the buffer. If NDIS set the NDIS_RECEIVE_FLAGS_RESOURCES flag, take no action and return from FilterReceiveNetBufferLists to discard the buffer. ------- 即,要丢弃数据包 如果 ReceiveFlags 无 NDIS_RECEIVE_FLAGS_RESOURCES 标记,调用 NdisFReturnNetBufferLists 丢弃 如果 ReceiveFlags 有 NDIS_RECEIVE_FLAGS_RESOURCES 标记,直接从 FilterReceiveNetBufferLists return 即可 ------- 实际上,这个sample已经有示例了: FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel); if (pFilter->State != FilterRunning) { FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel); // 需要丢弃数据包 if (NDIS_TEST_RECEIVE_CAN_PEND(ReceiveFlags)) { // ReceiveFlags 无 NDIS_RECEIVE_FLAGS_RESOURCES 标记,调用NdisFReturnNetBufferLists() ReturnFlags = 0; if (NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags)) { NDIS_SET_RETURN_FLAG(ReturnFlags, NDIS_RETURN_FLAGS_DISPATCH_LEVEL); } NdisFReturnNetBufferLists(pFilter->FilterHandle, NetBufferLists, ReturnFlags); } else { // ReceiveFlags 有 NDIS_RECEIVE_FLAGS_RESOURCES 标记,不做任何事,直接后面 break后return即可 } break; } FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);
解决办法是:分别为需要拦截和放行的NB 创建NBL,然后对应处理NBL
paigle 2013-11-21
  • 打赏
  • 举报
回复
MSDN上是这样说的: Discard the buffer. If NDIS cleared the NDIS_RECEIVE_FLAGS_RESOURCES flag, call the NdisFReturnNetBufferLists function to discard the buffer. If NDIS set the NDIS_RECEIVE_FLAGS_RESOURCES flag, take no action and return from FilterReceiveNetBufferLists to discard the buffer. ------- 即,要丢弃数据包 如果 ReceiveFlags 无 NDIS_RECEIVE_FLAGS_RESOURCES 标记,调用 NdisFReturnNetBufferLists 丢弃 如果 ReceiveFlags 有 NDIS_RECEIVE_FLAGS_RESOURCES 标记,直接从 FilterReceiveNetBufferLists return 即可 ------- 实际上,这个sample已经有示例了: FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel); if (pFilter->State != FilterRunning) { FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel); // 需要丢弃数据包 if (NDIS_TEST_RECEIVE_CAN_PEND(ReceiveFlags)) { // ReceiveFlags 无 NDIS_RECEIVE_FLAGS_RESOURCES 标记,调用NdisFReturnNetBufferLists() ReturnFlags = 0; if (NDIS_TEST_RECEIVE_AT_DISPATCH_LEVEL(ReceiveFlags)) { NDIS_SET_RETURN_FLAG(ReturnFlags, NDIS_RETURN_FLAGS_DISPATCH_LEVEL); } NdisFReturnNetBufferLists(pFilter->FilterHandle, NetBufferLists, ReturnFlags); } else { // ReceiveFlags 有 NDIS_RECEIVE_FLAGS_RESOURCES 标记,不做任何事,直接后面 break后return即可 } break; } FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);

18,363

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧