阅读:3031回复:15
修改PtReceive和PtTransferDataComplete,实现过滤ICMP的代码。
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包的功能。还有哪些需要改进的地方,各位帮忙看看! |
|
沙发#
发布于:2002-04-19 15:57
最好不要用
RtlZeroMemory RtlCopyMemory 用NdisZeroMemory NdisCopyMemory NdisFreeBuffer前unchain buffer |
|
板凳#
发布于:2002-04-19 16:09
终于有人理我了!
多谢指教,愿和你多交流! |
|
地板#
发布于:2002-04-22 14:28
不知道这个程序运行时间长了会不会有问题。
因为似乎在reReceive中在PacketSize>LookAheadBufferSize时,动态分配的pPacketContent和pBakBuffer没有释放。时间长了,是不是会系统资源不够了?我对此知之不多不知道是不是这样,如能进行交流将非常高兴。 |
|
地下室#
发布于:2002-04-22 14:53
我对此也不是很精通,请各位大虾发表一下意见!!
|
|
5楼#
发布于:2002-04-22 21:49
你分配的内存没有释放,这是很危险的事情,在PtReceive函数中,当PacketSize>LookAheadBufferSize时,分配内存,然后调用PtTransferComplete函数,在该函数中当调用NdisIndicatePacket()函数后,必须根据返回的情况,调用MpReturnPacket,在MpReturnPacket中释放掉你所分配的内存。
|
|
6楼#
发布于:2002-04-23 13:05
在MpRetrunPacket中会调用NdisReturnPackets,而NdisReturnPackets不是在miniport用NdisMIndicateReceivePacket向上指示数据包的时候,返还包所有权时用的吗?再我的机器上总是PtReceive被调用,那有可能是miniport用NdisMXxxIndicateReceive向上指示数据包,还用调用MpReturnPacket/NdisReturnpackets吗?
|
|
7楼#
发布于:2002-04-23 13:37
请你看看我昨天发的帖子 《高手帮忙看看》。里面有释放所分配的Packet buffer 的例子,即如何在MpReturnPacket中释放这些东西。
|
|
8楼#
发布于:2002-04-23 14:50
谢谢!!
另外想请教一个问题: 为什么在passthru中的PtReceivePacket函数中还要再分配一个包描述符MyPacket,并且 Resvd =(PRSVD)(MyPacket->MiniportReserved); Resvd->OriginalPkt = Packet; ... 然后才NdisMIndicateReceivePacket(pAdapt->MiniportHandle, &MyPacket, 1)呢? |
|
9楼#
发布于:2002-04-24 12:50
NdisINdicateReceivePacket想上层协议驱动程序指示包之后,如果返回NDIS_STATUS_PENDING,NDIS会自动调用MpReturnPacket。主要用做释放资源。你的程序代码中也有这两条语句呀,难道你不懂吗?仔细看看我的代码。
|
|
10楼#
发布于:2002-05-06 11:35
比较经典,需要学习一下。
|
|
|
11楼#
发布于:2002-05-06 18:49
很奇怪为什么不做强制类型转换,这样不是马上就可以得到IP头和Mac头,想过滤什么都行啦
|
|
|
12楼#
发布于:2002-05-07 20:16
很有收获
|
|
|
13楼#
发布于:2002-05-08 00:04
多看贴子是重要的进步渠道,多灌水是成为专家的捷径。
|
|
|
14楼#
发布于:2002-05-08 21:53
很奇怪为什么不做强制类型转换,这样不是马上就可以得到IP头和Mac头,想过滤什么都行啦 做包过滤也不一定要转换啊!模式匹配是更好的解决方案,我的firewall里面就是这么做的! 另外建议你不要拦截所有的ICMP包!因为有的包是为路由准备的!当网络效率低的时候就有可能丢失数据了!不信?那你试试~~ |
|
|
15楼#
发布于:2002-05-09 18:20
作转换程序看起来更清楚三,至少偶就这样认为,如果只是简单作包过滤。
|
|
|