阅读:3384回复:37
50分,谁解决谁拿走,还是那个mpsend中indicate包以后释放内存的问题,嫌少还可以加......
在passthru代码基础上,拦截本机发出的Arp请求,然后自己构造一个Arp回应,indicate给上层。
处理流程: 1。在MpSend中检查要发出的包,拦截Arp请求发出,构造自己的数据包;easy... 2。用NdisMIndicateReceivePacket通知上层接收这个数据包; 3。传送完毕,释放内存。 NDIS_STATUS MPSend( IN NDIS_HANDLE MiniportAdapterContext, IN PNDIS_PACKET Packet, IN UINT Flags ) { PADAPT pAdapt = (PADAPT)MiniportAdapterContext; NDIS_STATUS Status=NDIS_STATUS_SUCCESS; PNDIS_PACKET MyPacket,MyArpPacket; //MyArpPacket是自己组建的一个Arp Reply,用以递交给上层。 PRSVD Rsvd; PVOID MediaSpecificInfo = NULL; ULONG MediaSpecificInfoSize = 0; UINT PhysicalBufferCount; UINT BufferCount,k; UINT TotalPacketLength; PNDIS_BUFFER CurrentBuffer,NextBuffer,pArpBuffer; UINT CurrentBufferLength; PVOID CurrentBufferVA; NDIS_HANDLE PacketCopyHandle=NULL; NDIS_STATUS ReturnStatus; //PETHHDR DownEthhdr,UpEthhdr; //PARPHDR DownArphdr,UpArphdr; //PIPHDR DownIphdr; PUCHAR pArpContent; UINT PacketLen; DbgPrint(\"===>PassThru MPSend.....\\n\"); .......... //前面已经组建了要发出的MyPacket包,同PassThru的代码 //判断是不是ARP请求,如果是,则走下面的流程 //申请内存 Status=NdisAllocateMemory(&pArpContent,2000,0,HighestAcceptableMax); if(Status==NDIS_STATUS_SUCCESS) { DbgPrint(\"In MPSend:NdisAllocateMemory Successed.\\n\") if(pArpContent!=NULL) { DbgPrint(\"In MPSend:pPacketContent!=NULL\\n\"); NdisZeroMemory(pArpContent,2000); DbgPrint(\"In MPSend:Zero ArpContent Successed.\\n\"); //讲MyPacket的内容拷贝进来,然后修改成一个回应..... CopyPacket2Buffer(MyPacket,pArpContent,&TotalPacketLength); DbgPrint(\"In MPSend...Copy MyPacket to ArpContent Successed.\\n\"); PacketLen=TotalPacketLength; //修改数据,代码省略...... //开始构造组包 NdisAllocatePacketPool(&ReturnStatus,&PacketCopyHandle,1,sizeof(RSVD)); if(ReturnStatus==NDIS_STATUS_SUCCESS) { DbgPrint(\"In MPSend:Ndis Allocate ArpPacket Pool Successed.\\n\"); NdisAllocatePacket(&Status,&MyArpPacket,PacketCopyHandle); if(Status==NDIS_STATUS_SUCCESS) { DbgPrint(\"In MPSend:NdisAllocatePacket successed.\\n\"); NdisAllocateBuffer(&Status,&pArpBuffer,pAdapt->SendBufferPoolHandle,pArpContent,PacketLen); NdisChainBufferAtFront(MyArpPacket,pArpBuffer); //MyArpPacket->Private.Head->Next=NULL; //MyArpPacket->Private.Tail=NULL; NDIS_SET_PACKET_HEADER_SIZE(MyArpPacket,14); DbgPrint(\"In MPSend:Packet build down,begin query new arp packet.\\n\"); NdisQueryPacket(MyArpPacket, &PhysicalBufferCount, &BufferCount, &CurrentBuffer, &TotalPacketLength); DbgPrint(\"BufferCount:%u.\\n\",BufferCount); DbgPrint(\"TotalPacketLength:%u.\\n\",TotalPacketLength); NdisQueryBuffer(CurrentBuffer, &CurrentBufferVA, &CurrentBufferLength); DbgPrint(\"CurrentBufferLength: %u \\n\",CurrentBufferLength); ////组包完毕,用NdisMIndicateReceivePacket通知上层接收这个数据包; //开始通知上层接收这个NEW ARP PACKET。。。 NdisMIndicateReceivePacket(pAdapt->MiniportHandle,&MyArpPacket,1); if(NDIS_GET_PACKET_STATUS(MyPacket)!=NDIS_STATUS_PENDING) { NdisFreeBuffer(pArpBuffer); DbgPrint(\"In MPSend:NdisFree ArpBuffer successed.\\n\"); NdisFreePacket(MyArpPacket); DbgPrint(\"In MPSend:NdisFree MyArpPacket successed.\\n\"); NdisFreeMemory(pArpContent,2000,0); DbgPrint(\"In MPSend: FreeMemory ArpContent Successed.\\n\"); } //返回Pending的时候,在MPReturnPacket中释放内存。。。 } ...... VOID MPReturnPacket( IN NDIS_HANDLE MiniportAdapterContext, IN PNDIS_PACKET Packet ) { PADAPT pAdapt = (PADAPT)MiniportAdapterContext; PNDIS_PACKET MyPacket; PRSVD Resvd; PNDIS_BUFFER pNdisBuffer; PUCHAR pPacketContent; UINT BufferLen; Resvd = (PRSVD)(Packet->MiniportReserved); MyPacket = Resvd->OriginalPkt; if(MyPacket) { NdisFreePacket(Packet); NdisReturnPackets(&MyPacket, 1); DBGPRINT((\"In MPReturnPacket And Free Memory...if\\n\")); } /*================== Add This Code for NdisMIndicateReceivePacket ==================*/ else { NdisUnchainBufferAtFront(Packet,&pNdisBuffer); NdisQueryBuffer(pNdisBuffer,(PVOID *)&pPacketContent,&BufferLen); NdisFreeBuffer(pNdisBuffer); NdisFreePacket(Packet); NdisFreeMemory(pPacketContent,2000,0); DBGPRINT((\"In MPReturnPacket And Free Memory...else\\n\")); } 目前的问题:兰屏,并且中间我做了很多工作,还是不行,受不了啦,哪位大侠能修改一下,让它跑起来,多谢。。。 |
|
沙发#
发布于:2003-05-06 21:32
好像问这个问题的人挺多,我贴一段代码:
KDPC g_DpcObject; DriverEntry: KeInitializeDpc( &g_DpcObject, DpcRoute, NULL ); VOID DpcRoute( IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID Arg1, IN PVOID Arg2 ) { NdisMEthIndicateReceive(...); NdisMEthIndicateReceiveComplete( Arg2 ); Free( Arg1 ); } MPSend: pArpPacket = Allocate( length ); KeInsertQueueDpc( &g_DpcObject, pArpPacket, ( PVOID )MiniportAdapterHandle ); Allocate和Free自行编写。 |
|
板凳#
发布于:2003-05-06 21:39
既然重开了帖子,我也重贴一遍:))
你的问题跟我的问题好像,区别只是我要在接受到数据包时发送,而你是在发送数据包时接收。差不多啦差不多 我觉得你的问题还是在MPReturnPacket里面。也许MPReturnPacket被调用时,实际参数的数据包并不是你自己的驱动构建的,而是来自底层(mimiport)。所以你应该加一个判断 if(NdisGetPoolFromPacket(Packet)==自己的poor) { // 是自己构建的包,想怎么做就怎么做吧 } 先说这么多,即使不是这个原因导致死机,我想用SoftICE也应该能调出来,good luck |
|
地板#
发布于:2003-05-07 08:29
好像问这个问题的人挺多,我贴一段代码: fracker大侠能再详细的说说么? |
|
地下室#
发布于:2003-05-07 08:30
既然重开了帖子,我也重贴一遍:)) NdisGetPoolFromPacket好像没有这个函数吧。。 |
|
5楼#
发布于:2003-05-07 09:10
你是用2000的ddk?那就别的原因了
没用过softice么 |
|
6楼#
发布于:2003-05-07 10:24
怎么在mpsend里面ndisallocatepacketpool??
你这个pool出了mpsend就没有了, 你释放packet的时候往哪里去释放???不兰屏才怪 |
|
|
7楼#
发布于:2003-05-07 10:26
我是用的2000DDK,没有用过softice...见笑了。。。大侠救我阿。。
|
|
8楼#
发布于:2003-05-07 10:34
怎么在mpsend里面ndisallocatepacketpool?? 那应该怎么办?在PtBindAdapter中我已经申请了 收发的PacketPool和BufferPool。是不是应该在这里申请我的新ARP包的PacketPool?那样要修改ADAPT的结构吧。望大侠指教, NdisAllocatePacketPoolEx(Status, &pAdapt->SendPacketPoolHandle, MIN_PACKET_POOL_SIZE, MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE, sizeof(RSVD)); if (*Status != NDIS_STATUS_SUCCESS) {break; } NdisAllocateBufferPool(Status, &pAdapt->SendBufferPoolHandle,sizeof(RSVD)); if (*Status!=NDIS_STATUS_SUCCESS) { break; } // // Allocate a packet pool for receives. We need this to indicate receives. Same consideration // as sends // NdisAllocatePacketPoolEx(Status, &pAdapt->RecvPacketPoolHandle, MIN_PACKET_POOL_SIZE, MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE, sizeof(RSVD)); if (*Status != NDIS_STATUS_SUCCESS) { break; } NdisAllocateBufferPool(Status, &pAdapt->RecvBufferPoolHandle, sizeof(RSVD)); if (*Status != NDIS_STATUS_SUCCESS) { break; } |
|
9楼#
发布于:2003-05-07 10:39
都用那个pool就行了,然后你要注意不是你分配的packet和buffer你不要释放。
|
|
|
10楼#
发布于:2003-05-07 11:27
都用那个pool就行了,然后你要注意不是你分配的packet和buffer你不要释放。 .......... //前面已经组建了要发出的MyPacket包,同PassThru的代码 //判断是不是ARP请求,如果是,则走下面的流程 //申请内存 Status=NdisAllocateMemory(&pArpContent,2000,0,HighestAcceptableMax); if(Status==NDIS_STATUS_SUCCESS) { DbgPrint(\"In MPSend:NdisAllocateMemory Successed.\\n\") if(pArpContent!=NULL) { DbgPrint(\"In MPSend:pPacketContent!=NULL\\n\"); NdisZeroMemory(pArpContent,2000); DbgPrint(\"In MPSend:Zero ArpContent Successed.\\n\"); //讲MyPacket的内容拷贝进来,然后修改成一个回应..... CopyPacket2Buffer(MyPacket,pArpContent,&TotalPacketLength); DbgPrint(\"In MPSend...Copy MyPacket to ArpContent Successed.\\n\"); PacketLen=TotalPacketLength; //修改数据,代码省略...... //开始构造组包 ,××××改动的地方。。×××× NdisAllocatePacket(&Status,&MyArpPacket,pAdapt->SendPacketPoolHandle); if(Status==NDIS_STATUS_SUCCESS) { DbgPrint(\"In MPSend:NdisAllocatePacket successed.\\n\"); NdisAllocateBuffer(&Status,&pArpBuffer,pAdapt->SendBufferPoolHandle,pArpContent,PacketLen); NdisChainBufferAtFront(MyArpPacket,pArpBuffer); NDIS_SET_PACKET_HEADER_SIZE(MyArpPacket,14); DbgPrint(\"In MPSend:Packet build down,begin query new arp packet.\\n\"); NdisQueryPacket(MyArpPacket, &PhysicalBufferCount, &BufferCount, &CurrentBuffer, &TotalPacketLength); DbgPrint(\"BufferCount:%u.\\n\",BufferCount); DbgPrint(\"TotalPacketLength:%u.\\n\",TotalPacketLength); NdisQueryBuffer(CurrentBuffer, &CurrentBufferVA, &CurrentBufferLength); DbgPrint(\"CurrentBufferLength: %u \\n\",CurrentBufferLength); ////组包完毕,用NdisMIndicateReceivePacket通知上层接收这个数据包; //开始通知上层接收这个NEW ARP PACKET。。。 NdisMIndicateReceivePacket(pAdapt->MiniportHandle,&MyArpPacket,1); if(NDIS_GET_PACKET_STATUS(MyPacket)!=NDIS_STATUS_PENDING) { NdisFreeBuffer(pArpBuffer); DbgPrint(\"In MPSend:NdisFree ArpBuffer successed.\\n\"); NdisFreePacket(MyArpPacket); DbgPrint(\"In MPSend:NdisFree MyArpPacket successed.\\n\"); NdisFreeMemory(pArpContent,2000,0); DbgPrint(\"In MPSend: FreeMemory ArpContent Successed.\\n\"); } //返回Pending的时候,在MPReturnPacket中释放内存。。。 ..... 可是编译以后还是兰屏,求大侠指教。 |
|
11楼#
发布于:2003-05-07 11:42
你怎么释放的?
还有你出错的位置究竟是在哪里? |
|
|
12楼#
发布于:2003-05-07 11:52
NdisMIndicateReceivePacket之后,如果返回不是Pending,那么直接释放掉:
if(NDIS_GET_PACKET_STATUS(MyPacket)!=NDIS_STATUS_PENDING) { NdisFreeBuffer(pArpBuffer); DbgPrint(\"In MPSend:NdisFree ArpBuffer successed.\\n\"); NdisFreePacket(MyArpPacket); DbgPrint(\"In MPSend:NdisFree MyArpPacket successed.\\n\"); NdisFreeMemory(pArpContent,2000,0); DbgPrint(\"In MPSend: FreeMemory ArpContent Successed.\\n\"); } //返回Pending的时候,在MPReturnPacket中释放内存。。。 VOID MPReturnPacket( IN NDIS_HANDLE MiniportAdapterContext, IN PNDIS_PACKET Packet ) { PADAPT pAdapt = (PADAPT)MiniportAdapterContext; PNDIS_PACKET MyPacket; PRSVD Resvd; PNDIS_BUFFER pNdisBuffer; PUCHAR pPacketContent; UINT BufferLen; Resvd = (PRSVD)(Packet->MiniportReserved); MyPacket = Resvd->OriginalPkt; if(MyPacket) { NdisFreePacket(Packet); NdisReturnPackets(&MyPacket, 1); DBGPRINT((\"In MPReturnPacket And Free Memory...if\\n\")); } /*================== Add This Code for NdisMIndicateReceivePacket ==================*/ else { NdisUnchainBufferAtFront(Packet,&pNdisBuffer); NdisQueryBuffer(pNdisBuffer,(PVOID *)&pPacketContent,&BufferLen); NdisFreeBuffer(pNdisBuffer); NdisFreePacket(Packet); NdisFreeMemory(pPacketContent,2000,0); DBGPRINT((\"In MPReturnPacket And Free Memory...else\\n\")); } 我认为我的错误就出在这里。。 |
|
13楼#
发布于:2003-05-07 13:03
如果上层发下来的是一个arp包,这时候你怎么处理发下来的那个pacekt??怎么通知协议驱动的?mpsend返回的是什么?
|
|
|
14楼#
发布于:2003-05-07 15:39
我这样释放掉原来的ARP包:
NDIS_SET_PACKET_STATUS(MyPacket,NDIS_STATUS_SUCCESS); DbgPrint(\"In MPSend:set MyPacket Status success.\\n\"); NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket); NdisFreePacket(MyPacket); DbgPrint(\"In MpSend:Free MyPacket.\\n\"); 然后直接返回一个成功值,可以么? |
|
15楼#
发布于:2003-05-08 10:44
说说我的一点想法啊,不一定对,不过互相讨论么 :)偶的工作做的是和你相反的啊,就是截获外部收到的包然后对某些包(自己判断啦)不向上传递同时发送出自定义的包。所以我觉得我们至少思路上完全对称一下就应该问题不大了,呵呵
首先是我理解你的思路,你看看对不对啊: 1。上层发下来的包你先copy到mypacket,用passrhru的源代码。然后做判断,两种情况,有用or无用。 2。无用的包,不用理会他,该怎么样就怎么样。 3。有用的包,先向上层返回一个值说“发送成功”(其实就没发送)。然后构造自己的mypacketreply,并且发送给上层。 4。无论有用无用,干完以后释放mypacket 5。对于有用的包,发送不返回pending,直接释放reply包,返回pending的时候,修改了mpreturnpacket,释放掉mpreturnpacket拿到的包(其实就是你构造的reply包)。 现在说偶觉得的问题,也许有的你已经搞定,偶看得不仔细: a。对于上面的1,passthru的源码中构造mypacket的方式是指针指过去而不是重新拷贝,这样你的4就释放了人家本来上层的包,这是不行的,mypacket的构造要采用重新分配内存然后拷贝的方式才可以。 b。对于5,你修改了mpreturnpacket,导致你在发送包给上层返回pending的情况下,在mpreturnpacket中间释放掉这个发送的包。 那么我想知道对于ptreceive你有没有改动? 因为ptreceive在真正收到网络中的包交给上层的时候也可能出现pending,如果你没有改动,那么这个时候你的mpreturnpacket将会释放掉网络传送给ptreceive的包,这是肯定要当机的。 所以一定要把ptreceive的收包方式也改掉,就是说收包的时候也是分配内存拷贝包,然后用来传送的是你自己分配的包,返回pending则不管,让mpreturnpacket释放去,不返回pending则在发送完毕释放掉自己分配的包。 暂时想到这么多啊,回头慢慢再想^_^ |
|
16楼#
发布于:2003-05-08 15:11
说说我的一点想法啊,不一定对,不过互相讨论么 :)偶的工作做的是和你相反的啊,就是截获外部收到的包然后对某些包(自己判断啦)不向上传递同时发送出自定义的包。所以我觉得我们至少思路上完全对称一下就应该问题不大了,呵呵 汗~,大侠指正的切中要害。能否详细的说说您指出的问题?我想我最有可能出问题的也就是这两个地方,被你一眼看出来。 我以后也要做收包的转发问题,如不吝赐教,我们可以保持联系,多谢! |
|
17楼#
发布于:2003-05-08 23:23
用户被禁言,该主题自动屏蔽! |
|
18楼#
发布于:2003-05-09 08:46
zuozi ,
你说的这些有源码吗?可否给我发一份,我已被这个问题捆了很久了,帮帮我啊! wangsj47@sina.com |
|
|
19楼#
发布于:2003-05-09 09:53
看passthru的例子吧,他的处理方式非常科学,我也是撞头才总结出来的,但我编的程序在实验室的机了呢,无法给你贴出,有时间我去找找。 多谢!一定不要忘记我阿!我这边也在不断努力中,反正有ghost,不怕系统崩,呵呵。 |
|
上一页
下一页