Songzh
驱动牛犊
驱动牛犊
  • 注册日期2001-12-29
  • 最后登录2011-03-29
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:3031回复:15

修改PtReceive和PtTransferDataComplete,实现过滤ICMP的代码。

楼主#
更多 发布于:2002-04-16 17:50
VOID
PtTransferDataComplete(
IN  NDIS_HANDLE ProtocolBindingContext,
IN  PNDIS_PACKET Packet,
IN  NDIS_STATUS Status,
IN  UINT BytesTransferred
)
/*++

Routine Description:
Same as the Send above, all sends need to be completed on the Primary\'s MiniportHandle

Arguments:

Return Value:

--*/
{
PADAPT  pAdapt =(PADAPT)ProtocolBindingContext;
PRSVD     Resvd;
PNDIS_PACKET     MyPacket, OffsetPacket;
PNDIS_BUFFER     PacketBuffer, OffsetBuffer;
PUCHAR           pPacketContent, pBakContent1, pBakContent2;
UINT             OffsetSize, result, PacketLen, bufLength1, bufLength2;
UINT             bytesTransfered = 0;

NDIS_PHYSICAL_ADDRESS    HighestAcceptableAddress;

NDIS_STATUS status = NDIS_STATUS_SUCCESS;

HighestAcceptableAddress.LowPart  = -1;
HighestAcceptableAddress.HighPart = -1;

DbgPrint(\"==>PtTransferDataComplete(...)\\n\");

Resvd = (PRSVD)(Packet->MiniportReserved);
OffsetPacket = (PNDIS_PACKET)Resvd->OriginalPkt;

// Returning the Send on the Primary, will point to itself if there is no LBFO
pAdapt = pAdapt->pPrimaryAdapt;

if(pAdapt->MiniportHandle)
{
if (OffsetPacket == NULL)
{
NdisMTransferDataComplete(pAdapt->MiniportHandle, Packet, Status, BytesTransferred);
}
else
{
status = NdisAllocateMemory(&pPacketContent, 2000, 0, HighestAcceptableAddress);

// 手动释放offsetpacket
NdisUnchainBufferAtFront(OffsetPacket, &OffsetBuffer);
NdisQueryBufferSafe(OffsetBuffer, &pBakContent1, &bufLength1, 32);

memset(Packet->MiniportReserved, 0, sizeof(Packet->MiniportReserved));

// 手动释放packet
NdisUnchainBufferAtFront(Packet, &PacketBuffer);
NdisQueryBufferSafe(PacketBuffer, &pBakContent2, &bufLength2, 32);

PacketLen = bufLength1 + bufLength2;

RtlZeroMemory(pPacketContent, 2000);
RtlCopyMemory(pPacketContent, pBakContent1, bufLength1);
RtlCopyMemory(pPacketContent + bufLength1, pBakContent2, bufLength2);

if((((char*)pPacketContent)[12] == 8) && (((char*)pPacketContent)[13] == 0) && (((char*)pPacketContent)[23] == 1))
{
DbgPrint(\"拦截到ICMP包!\\n\");
NdisFreeMemory(pPacketContent,2000,0);
NdisDprFreePacket(Packet);
return;
}

NdisAllocateBuffer(&status,&PacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketLen);
NdisChainBufferAtFront(Packet, PacketBuffer);

Packet->Private.Head->Next =NULL;
Packet->Private.Tail=NULL;
NDIS_SET_PACKET_HEADER_SIZE(Packet,14);
NDIS_SET_PACKET_STATUS(Packet, NDIS_STATUS_RESOURCES);

NdisMIndicateReceivePacket(pAdapt->MiniportHandle ,&Packet,1);

ASSERT(NDIS_GET_PACKET_STATUS(MyPacket) == NDIS_STATUS_RESOURCES);
NdisFreeBuffer(PacketBuffer);
NdisFreeMemory(pPacketContent,2000,0);
NdisDprFreePacket(Packet);

}

DbgPrint(\"<==PtTransferDataComplete(...)\\n\");
}
}


NDIS_STATUS
PtReceive(
IN  NDIS_HANDLE ProtocolBindingContext,
IN  NDIS_HANDLE MacReceiveContext,
IN  PVOID HeaderBuffer,
IN  UINT HeaderBufferSize,
IN  PVOID LookAheadBuffer,
IN  UINT LookAheadBufferSize,
IN  UINT PacketSize
)
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
PNDIS_PACKET MyPacket, MyPacket2, Packet;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;

UINT                     PacketLen, OffsetSize, BytesTransferred;
PRSVD                    Resvd;
NDIS_PHYSICAL_ADDRESS    HighestAcceptableAddress;
PUCHAR                   pPacketContent, pBakBuffer;
PNDIS_BUFFER             PacketBuffer, OffsetBuffer;

DbgPrint(\"==>PtReceive()\\n\");

if(!pAdapt->MiniportHandle)
{
Status = NDIS_STATUS_FAILURE;
}
else do
{
if(pAdapt->isSecondary)
{
DBGPRINT(\"PASSTHRU GETTING RECIEVES ON SECONDARY\\n\");
ASSERT(0);
}

        HighestAcceptableAddress.LowPart = -1;
HighestAcceptableAddress.HighPart = -1;

if(PacketSize <= LookAheadBufferSize)
{
DbgPrint(\"PacketSize <= LookAheadBufferSize\\n\");

Status = NdisAllocateMemory(&pPacketContent, 2000, 0, HighestAcceptableAddress);

if (Status != NDIS_STATUS_SUCCESS )
{
DbgPrint(\"ptreceive :ndisallocatememory failed\\n\");
return NDIS_STATUS_NOT_ACCEPTED;
}

if(pPacketContent == NULL)
{
DbgPrint(\"prreceive:pPacketContent == NULL\\n\");
return NDIS_STATUS_NOT_ACCEPTED;
}

RtlZeroMemory(pPacketContent, 2000);
RtlCopyMemory(pPacketContent,HeaderBuffer,HeaderBufferSize);
RtlCopyMemory(pPacketContent+HeaderBufferSize,LookAheadBuffer,LookAheadBufferSize);

if((((char*)pPacketContent)[12] == 8) && (((char*)pPacketContent)[13] == 0) && (((char*)pPacketContent)[23] == 1))
{
DbgPrint(\"拦截到ICMP包!\\n\");
return NDIS_STATUS_NOT_ACCEPTED;
}

PacketLen = PacketSize+HeaderBufferSize;

NdisDprAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle);
if(Status != NDIS_STATUS_SUCCESS)
{
DbgPrint(\"NdisDprAllocatePacket failed!\\n\");
return NDIS_STATUS_NOT_ACCEPTED;
}

if(Status == NDIS_STATUS_SUCCESS)
{
NdisAllocateBuffer(&Status, &PacketBuffer, pAdapt->RecvBufferPoolHandle, pPacketContent,PacketLen);
NdisChainBufferAtFront(MyPacket, PacketBuffer);

MyPacket->Private.Head->Next=NULL;
MyPacket->Private.Tail = NULL;

Resvd =(PRSVD)(MyPacket->MiniportReserved);
Resvd->OriginalPkt = NULL;

NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize);

NDIS_SET_PACKET_STATUS(MyPacket, NDIS_STATUS_RESOURCES);

NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1);

ASSERT(NDIS_GET_PACKET_STATUS(MyPacket) == NDIS_STATUS_RESOURCES);
NdisFreeBuffer(PacketBuffer);
NdisFreeMemory(pPacketContent,2000,0);
NdisDprFreePacket(MyPacket);

return NDIS_STATUS_SUCCESS;
}
}
else
{
DbgPrint(\"PacketSize > LookAheadBufferSize\\n\");

Status = NdisAllocateMemory(&pPacketContent, 2000, 0, HighestAcceptableAddress);
if (Status != NDIS_STATUS_SUCCESS)
{
DbgPrint(\"ptreceive :ndisallocatememory failed\\n\");
return NDIS_STATUS_NOT_ACCEPTED;
}
if(pPacketContent == NULL)
{
DbgPrint(\"prreceive:pPacketContent == NULL\\n\");
return NDIS_STATUS_NOT_ACCEPTED;
}

Status = NdisAllocateMemory(&pBakBuffer, 2000, 0, HighestAcceptableAddress);
if(Status != NDIS_STATUS_SUCCESS)
{
DbgPrint(\"ptreceive:allcate bak buffer failed\\n\");
return NDIS_STATUS_NOT_ACCEPTED;
}

// 将包头和LookAheadBuffer里的数据复制到pBakBuffer
NdisMoveMemory(pBakBuffer,HeaderBuffer,HeaderBufferSize);
NdisMoveMemory(pBakBuffer+HeaderBufferSize,LookAheadBuffer,LookAheadBufferSize);

RtlZeroMemory(pPacketContent, 2000);
NdisDprAllocatePacket(&Status, &MyPacket, pAdapt->RecvPacketPoolHandle);

NdisAllocateBuffer(&Status,&PacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketSize);
NdisChainBufferAtFront(MyPacket, PacketBuffer);

OffsetSize = HeaderBufferSize + LookAheadBufferSize;

// 包描述符MyPacket2影射pBakBuffer的内容(包头 + LookAheadBuffer)
NdisDprAllocatePacket(&Status, &MyPacket2, pAdapt->RecvPacketPoolHandle);
NdisAllocateBuffer(&Status,&OffsetBuffer,pAdapt->RecvBufferPoolHandle ,pBakBuffer,OffsetSize);
NdisChainBufferAtFront(MyPacket2,OffsetBuffer);

Resvd =(PRSVD)(MyPacket->MiniportReserved);
Resvd->OriginalPkt = (PNDIS_PACKET)MyPacket2;

NDIS_SET_PACKET_HEADER_SIZE(MyPacket, HeaderBufferSize);

NdisTransferData(&Status,
pAdapt->BindingHandle,
MacReceiveContext,
LookAheadBufferSize,
PacketSize-LookAheadBufferSize,
MyPacket,
&BytesTransferred);

if ( Status != NDIS_STATUS_PENDING )
{
PtTransferDataComplete((NDIS_HANDLE)pAdapt, MyPacket, Status, BytesTransferred);
}
return NDIS_STATUS_SUCCESS;
}

} while(FALSE);

return Status;
}

安装后在我的win2000上运行正常,可以实现过滤ICMP包的功能。还有哪些需要改进的地方,各位帮忙看看!

最新喜欢:

txysptxysp znsoftznsoft
runsnow
驱动牛犊
驱动牛犊
  • 注册日期2002-03-01
  • 最后登录2002-11-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-04-19 15:57
最好不要用
RtlZeroMemory
RtlCopyMemory
用NdisZeroMemory
NdisCopyMemory

NdisFreeBuffer前unchain buffer
Songzh
驱动牛犊
驱动牛犊
  • 注册日期2001-12-29
  • 最后登录2011-03-29
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-04-19 16:09
终于有人理我了!
多谢指教,愿和你多交流!
overthere
驱动牛犊
驱动牛犊
  • 注册日期2002-03-24
  • 最后登录2002-04-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-04-22 14:28
不知道这个程序运行时间长了会不会有问题。
因为似乎在reReceive中在PacketSize>LookAheadBufferSize时,动态分配的pPacketContent和pBakBuffer没有释放。时间长了,是不是会系统资源不够了?我对此知之不多不知道是不是这样,如能进行交流将非常高兴。
Songzh
驱动牛犊
驱动牛犊
  • 注册日期2001-12-29
  • 最后登录2011-03-29
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-04-22 14:53
我对此也不是很精通,请各位大虾发表一下意见!!
sbni
驱动牛犊
驱动牛犊
  • 注册日期2001-07-06
  • 最后登录2013-05-05
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-04-22 21:49
你分配的内存没有释放,这是很危险的事情,在PtReceive函数中,当PacketSize>LookAheadBufferSize时,分配内存,然后调用PtTransferComplete函数,在该函数中当调用NdisIndicatePacket()函数后,必须根据返回的情况,调用MpReturnPacket,在MpReturnPacket中释放掉你所分配的内存。
Songzh
驱动牛犊
驱动牛犊
  • 注册日期2001-12-29
  • 最后登录2011-03-29
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-04-23 13:05
在MpRetrunPacket中会调用NdisReturnPackets,而NdisReturnPackets不是在miniport用NdisMIndicateReceivePacket向上指示数据包的时候,返还包所有权时用的吗?再我的机器上总是PtReceive被调用,那有可能是miniport用NdisMXxxIndicateReceive向上指示数据包,还用调用MpReturnPacket/NdisReturnpackets吗?
sbni
驱动牛犊
驱动牛犊
  • 注册日期2001-07-06
  • 最后登录2013-05-05
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-04-23 13:37
 请你看看我昨天发的帖子 《高手帮忙看看》。里面有释放所分配的Packet buffer 的例子,即如何在MpReturnPacket中释放这些东西。
Songzh
驱动牛犊
驱动牛犊
  • 注册日期2001-12-29
  • 最后登录2011-03-29
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-04-23 14:50
谢谢!!
另外想请教一个问题:
为什么在passthru中的PtReceivePacket函数中还要再分配一个包描述符MyPacket,并且
Resvd =(PRSVD)(MyPacket->MiniportReserved);
Resvd->OriginalPkt = Packet;
...
然后才NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1)呢?
sbni
驱动牛犊
驱动牛犊
  • 注册日期2001-07-06
  • 最后登录2013-05-05
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望5点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-04-24 12:50
NdisINdicateReceivePacket想上层协议驱动程序指示包之后,如果返回NDIS_STATUS_PENDING,NDIS会自动调用MpReturnPacket。主要用做释放资源。你的程序代码中也有这两条语句呀,难道你不懂吗?仔细看看我的代码。
moqingsong
论坛版主
论坛版主
  • 注册日期2002-04-07
  • 最后登录2011-02-03
  • 粉丝0
  • 关注0
  • 积分74分
  • 威望71点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-05-06 11:35
比较经典,需要学习一下。
按第一贴的“给分”键,给分。
sirroom
驱动大牛
驱动大牛
  • 注册日期2001-07-30
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望11点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-05-06 18:49
很奇怪为什么不做强制类型转换,这样不是马上就可以得到IP头和Mac头,想过滤什么都行啦
111
lyabcd
驱动大牛
驱动大牛
  • 注册日期2001-08-09
  • 最后登录2015-10-01
  • 粉丝0
  • 关注0
  • 积分33分
  • 威望4点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-05-07 20:16
很有收获
datongguandian@sina.com
moqingsong
论坛版主
论坛版主
  • 注册日期2002-04-07
  • 最后登录2011-02-03
  • 粉丝0
  • 关注0
  • 积分74分
  • 威望71点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-05-08 00:04
多看贴子是重要的进步渠道,多灌水是成为专家的捷径。
按第一贴的“给分”键,给分。
.X.T.I.M.
驱动大牛
驱动大牛
  • 注册日期2001-09-22
  • 最后登录2021-08-25
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2002-05-08 21:53
很奇怪为什么不做强制类型转换,这样不是马上就可以得到IP头和Mac头,想过滤什么都行啦

做包过滤也不一定要转换啊!模式匹配是更好的解决方案,我的firewall里面就是这么做的!

另外建议你不要拦截所有的ICMP包!因为有的包是为路由准备的!当网络效率低的时候就有可能丢失数据了!不信?那你试试~~
<IMG src="http://www.microsoft.com/traincert/images/logos/mcp.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcdba.gif" border=0><br> <IMG src="http://www.microsoft.com/traincert/images/logos/mcse.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcsd.gif" border=0>
sirroom
驱动大牛
驱动大牛
  • 注册日期2001-07-30
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望11点
  • 贡献值1点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2002-05-09 18:20
作转换程序看起来更清楚三,至少偶就这样认为,如果只是简单作包过滤。
111
游客

返回顶部