阅读:1904回复:7
胡大侠,asmsys,youngyt各位版主,大侠帮帮忙了
在ptreceive中数据的转发还没有解决,我现在ptTransferDataComplete采用的是胡大侠的一段代码
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; PUCHAR pPacketContent; PRSVD Rsvd; UINT OffsetSize,Result,PacketLen; PNDIS_BUFFER pPacketBuffer; PNDIS_PACKET pBakPacket; PNDIS_BUFFER pBakBuffer; PUCHAR pBakContent; UINT BufferLen; DBGPRINT(("In PtTransferDataComplete\n")); // // Returning the Send on the Primary, will point to itself if there is no LBFO // pAdapt = pAdapt->pPrimaryAdapt; Rsvd =(PRSVD)(Packet->MiniportReserved); pBakPacket=(PNDIS_PACKET)(Rsvd->OriginalPkt); if(pAdapt->MiniportHandle) { if(pBakPacket==NULL) NdisMTransferDataComplete(pAdapt->MiniportHandle,Packet,Status,BytesTransferred); else { Status=NdisAllocateMemory(&pPacketContent,BUFFER_SIZE,0,HighestAcceptableMax); CopyPacket2Buffer(pBakPacket,pPacketContent,&OffsetSize); CopyPacket2Buffer(Packet,pPacketContent+OffsetSize,&PacketLen); PacketLen+=OffsetSize; NdisUnchainBufferAtFront(pBakPacket,&pBakBuffer); NdisQueryBufferSafe(pBakBuffer,&pBakContent,&BufferLen,32); NdisFreeBuffer(pBakBuffer); NdisFreeMemory(pBakContent,BUFFER_SIZE,0); NdisFreePacket(pBakPacket); memset(Packet->MiniportReserved,0,sizeof(Packet->MiniportReserved)); NdisUnchainBufferAtFront(Packet,&pPacketBuffer); NdisQueryBufferSafe(pPacketBuffer,&pBakContent,&BufferLen,32); NdisFreeBuffer(pPacketBuffer); NdisFreeMemory(pBakContent,BUFFER_SIZE,0); NdisAllocateBuffer(&Status,&pPacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,PacketLen); NdisChainBufferAtFront(Packet,pPacketBuffer); Packet->Private.Head->Next=NULL; Packet->Private.Tail=NULL; NDIS_SET_PACKET_HEADER_SIZE(Packet,14); NdisMIndicateReceivePacket(pAdapt->MiniportHandle,&Packet,1); if(NDIS_GET_PACKET_STATUS(Packet)!=NDIS_STATUS_PENDING) { MPReturnPacket((NDIS_HANDLE)pAdapt,Packet); } } } return; } 在ptreceive里我是这么处理的(当PacketSize<=LookAheadBufferSize,对这种情况的处理是正确的,在此就不写了,关键是在与PacketSize>LookAheadBufferSize的时候的处理,现面就是对于这种情况的处理:其中pPacketContent在前面就已经处理过: ntStatus = NdisAllocateMemory(&pPacketContent,2000,0,HighestAcceptableMax); if(ntStatus != NDIS_STATUS_SUCCESS) { return ntStatus; } NdisZeroMemory(pPacketContent,2000); NdisMoveMemory( pPacketContent, HeaderBuffer, HeaderBufferSize ); NdisMoveMemory( pPacketContent+HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize ); 下面是PacketSize>LookAheadBufferSize的处理: else if(PacketSize>LookAheadBufferSize) { DbgPrint("packetsize>lookaheadsize"); NdisDprAllocatePacket(&Status,&MyPacket,pAdapt->RecvPacketPoolHandle); Status=NdisAllocateMemory(&pBakContent,BUFFER_SIZE,0,HighestAcceptableMax); if(Status!=NDIS_STATUS_SUCCESS) { DbgPrint("PtReceive:NdisAllocateMemory Failed.\n"); return(NDIS_STATUS_NOT_ACCEPTED); } NdisZeroMemory(pBakContent,BUFFER_SIZE); if(pBakContent==NULL) { DbgPrint("PTReceive:pPacketContent==NULL\n"); return(NDIS_STATUS_NOT_ACCEPTED); } PacketLen=HeaderBufferSize+PacketSize; NdisAllocateBuffer(&Status,&pBakBuffer,pAdapt->RecvBufferPoolHandle,pBakContent,PacketSize-LookAheadBufferSize); NdisChainBufferAtFront(MyPacket,pBakBuffer); MyPacket->Private.Head->Next=NULL; MyPacket->Private.Tail=NULL; OffsetSize=HeaderBufferSize+LookAheadBufferSize; NdisDprAllocatePacket(&Status,&MyPacket1,pAdapt->RecvPacketPoolHandle); NdisAllocateBuffer(&Status,&pPacketBuffer,pAdapt->RecvBufferPoolHandle,pPacketContent,OffsetSize); NdisChainBufferAtFront(MyPacket1,pPacketBuffer); Rsvd=(PRSVD)(MyPacket->MiniportReserved); Rsvd->OriginalPkt=(PNDIS_PACKET)MyPacket1; NDIS_SET_PACKET_HEADER_SIZE(MyPacket,HeaderBufferSize); NdisTransferData(&Status,pAdapt->BindingHandle,MacReceiveContext,LookAheadBufferSize,PacketSize-LookAheadBufferSize,MyPacket,&BytesTransferred); if(Status!=NDIS_STATUS_PENDING) { DbgPrint("status==Ndis_status_pending"); DbgPrint("High layer call PtTransferDataCompleten"); //传输完毕,直接调用PtTransferDataComplete PtTransferDataComplete( (NDIS_HANDLE)pAdapt, MyPacket, Status, BytesTransferred ); pAnalyze(MyPacket1);//包的分析 pAnalyze(MyPacket);//包的分析 NdisSend(&Status, pAdapt->BindingHandle, MyPacket1);//发送,这个包发出去了,是 NdisSend(&Status, pAdapt->BindingHandle, MyPacket);//这个包的内容很乱,连包头部分都不正确,连MAC包头都不正确,不知道为什么 if (Status != NDIS_STATUS_PENDING) { // NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket); NdisUnchainBufferAtFront(MyPacket ,&pPacketBuffer); NdisQueryBufferSafe(pPacketBuffer,(PVOID *)&pPacketContent,&PacketBufferLen,32); NdisFreeBuffer(pPacketBuffer); NdisFreeMemory(pPacketContent,2000,0); NdisDprFreePacket(MyPacket); NdisUnchainBufferAtFront(MyPacket1 ,&pBakBuffer); NdisQueryBufferSafe(pBakBuffer,(PVOID *)&pBakContent,&PacketBufferLen,32); NdisFreeBuffer(pBakBuffer); NdisFreeMemory(pBakContent,2000,0); NdisDprFreePacket(MyPacket1); } return(Status); //PtTransferDataComplete((NDIS_HANDLE)pAdapt,MyPacket,Status,BytesTransferred); } return(Status); } 程序在运行的时候,如果修改了PtTransferDataComplete然后在ptreceive中调用了这个函数,当内网机器连上来的时候,网关就立刻重新启动,不知道问什么。没有用这个函数的时候,我分析和打印了mypacket和mypacket1(包前面部分),发现mypacket1是正确的,但是mypacket很乱,不知为何。还请各位大侠帮帮我了! |
|
沙发#
发布于:2004-06-07 16:25
谢谢asmsys大佬,待会一起放分
|
|
板凳#
发布于:2004-06-07 15:20
后根据分析pPacketContent前14个字节就是MAC头,也就是说MAC头在HeadBuffer中,接着在分析第15个字节就属于IP头了?也就是说LookAheadBuffer就是以IP头开始的,不知对否?
================================================== 是的。 54包含14,是我说错了,时间长了记不清了,SORRY。 HUYUGUANG的代码不是你那个样子的。下面的有个帖子叫“给初学。。。的建议”的贴子里贴的第一个就是由huyuguang的框架改的,他处理>的情况是完全正确的。请参考。注意ptreceive和PtTransferDataComplete都有要处理的地方。 |
|
地板#
发布于:2004-06-07 15:09
这是DDK help文档对VOID
NdisMEthIndicateReceive( IN NDIS_HANDLE MiniportAdapterHandle, IN NDIS_HANDLE MiniportReceiveContext, IN PVOID HeaderBuffer, IN UINT HeaderBufferSize, IN PVOID LookaheadBuffer, IN UINT LookaheadBufferSize, IN UINT PacketSize ); 的参数的解释: PacketSize Specifies the size in bytes of the received packet data. This value does not include the HeaderBufferSize. 好像这里说不包括什么的 好了,在此不讨论这个问题了,帮我解决一下我自己的问题了:( |
|
地下室#
发布于:2004-06-07 14:39
我还发现发给本机的ARP帧仅有42个字长,但从本机发出的数据,或者是与梧桐不相关的ARP数据,则是60个字长的。我怀疑在数据包被截获之前,就已经过滤掉了那些填充数据。
|
|
|
5楼#
发布于:2004-06-07 12:01
Packet length: 54
00000000 : 00 e0 0f 20 1a d8 00 e0 4c 60 32 01 08 00 45 00 00000010 : 00 28 4a 85 40 00 80 06 27 6e c0 a8 05 01 3d 87 00000020 : 85 ac 04 94 00 50 cc 12 e3 2c 55 3e 3f fd 50 10 00000030 : fa f0 e2 a7 00 00 这就是捕获到的54个数据的包长,是HTTP应答内容,应用层的内容为空。从格式分析确实包含了14字长的MAC内容。不过,很多书上也确实说过MAC帧长最小应为60,可能是捕获到的数据已经把填充的数据过滤掉了吧。 |
|
|
6楼#
发布于:2004-06-07 10:57
但是 NdisMoveMemory(
pPacketContent, HeaderBuffer, HeaderBufferSize ); NdisMoveMemory( pPacketContent+HeaderBufferSize, LookAheadBuffer, LookAheadBufferSize ); 后根据分析pPacketContent前14个字节就是MAC头,也就是说MAC头在HeadBuffer中,接着在分析第15个字节就属于IP头了?也就是说LookAheadBuffer就是以IP头开始的,不知对否?还有根据MAC帧的结构,几乎所有的网络书中都会在802.3中(我的就是这个环境)说数据部分长度46~1500,再加上14个包头,也就是说MAC帧的长度最少为60。我很难相信这个54就是整个包的长度。另外我也用sniffer截过多次,发现都是这种情况,当包的长度不够时,系统会补足的。但至少有一点可以肯定,包的总长度绝对不会小于60!那也就是说不会是54了。 |
|
7楼#
发布于:2004-06-07 10:26
54包含14,这个够明白的了把。
关于那个问题,已经说的很明白了,人家都贴出代码来了。 但照搬是不好的主意,你要理解了他的实现流程,然后自己重新写代码。 |
|