jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1904回复:7

胡大侠,asmsys,youngyt各位版主,大侠帮帮忙了

楼主#
更多 发布于:2004-06-07 10:24
在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很乱,不知为何。还请各位大侠帮帮我了!
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-06-07 16:25
谢谢asmsys大佬,待会一起放分
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-06-07 15:20
后根据分析pPacketContent前14个字节就是MAC头,也就是说MAC头在HeadBuffer中,接着在分析第15个字节就属于IP头了?也就是说LookAheadBuffer就是以IP头开始的,不知对否?
==================================================
是的。
54包含14,是我说错了,时间长了记不清了,SORRY。
HUYUGUANG的代码不是你那个样子的。下面的有个帖子叫“给初学。。。的建议”的贴子里贴的第一个就是由huyuguang的框架改的,他处理>的情况是完全正确的。请参考。注意ptreceive和PtTransferDataComplete都有要处理的地方。
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于: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.
好像这里说不包括什么的

好了,在此不讨论这个问题了,帮我解决一下我自己的问题了:(

canoe982
驱动牛犊
驱动牛犊
  • 注册日期2003-04-11
  • 最后登录2005-12-14
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-06-07 14:39
我还发现发给本机的ARP帧仅有42个字长,但从本机发出的数据,或者是与梧桐不相关的ARP数据,则是60个字长的。我怀疑在数据包被截获之前,就已经过滤掉了那些填充数据。
独怜幽草涧边生, 上有黄鹂深树鸣。 春潮带雨晚来急, 野渡无人舟自横。
canoe982
驱动牛犊
驱动牛犊
  • 注册日期2003-04-11
  • 最后登录2005-12-14
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
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,可能是捕获到的数据已经把填充的数据过滤掉了吧。
独怜幽草涧边生, 上有黄鹂深树鸣。 春潮带雨晚来急, 野渡无人舟自横。
jackieky
驱动牛犊
驱动牛犊
  • 注册日期2004-02-10
  • 最后登录2004-08-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
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了。
asmsys
驱动老牛
驱动老牛
  • 注册日期2002-03-29
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望17点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-06-07 10:26
54包含14,这个够明白的了把。
关于那个问题,已经说的很明白了,人家都贴出代码来了。
但照搬是不好的主意,你要理解了他的实现流程,然后自己重新写代码。
游客

返回顶部