tanm2000
驱动牛犊
驱动牛犊
  • 注册日期2005-05-12
  • 最后登录2008-07-04
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望12点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
阅读:1700回复:8

复制ndispacket的两个方法比较

楼主#
更多 发布于:2005-06-11 17:51
1、passthru中mpsend中的方法
2、用ndisCopyFacketFromPacket

请问这两种方法有什么区别

最新喜欢:

xiaojian521xiaoji...
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2005-06-11 22:45
1、passthru中mpsend中的方法
2、用ndisCopyFacketFromPacket

请问这两种方法有什么区别

 

1.passthru中mpsend仅仅是新建立了一个NDIS_PACKET,并没有真正复制数据,数据是通过NDIS_BUFFER(就是MDL)来描述的,。
2.NdisCopyPacketFromPacket,不仅建立了一个NDIS_PACKET,还要建立NDIS_BUFFER,还要真正的分配内存,会真正的拷贝数据,调用memcpy。
理解这个差别需要你透彻理解NDIS_PACKET,NDIS_BUFFER的结构,和关系
显然1比2快的多
tanm2000
驱动牛犊
驱动牛犊
  • 注册日期2005-05-12
  • 最后登录2008-07-04
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望12点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-06-12 10:07
版主每次都这么耐心的解答,真是感谢!

我看passthru最后发的是MyPacket,也就是新建的ndis packet
如果没copy数据的话那不是发了个空的packet了吗?

如果我想在IP包头前加上自己的IP包头,在server端解析,那应该有什么步骤!谢谢
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2005-06-12 10:46
版主每次都这么耐心的解答,真是感谢!

我看passthru最后发的是MyPacket,也就是新建的ndis packet
如果没copy数据的话那不是发了个空的packet了吗?

如果我想在IP包头前加上自己的IP包头,在server端解析,那应该有什么步骤!谢谢
 

1。MyPacket,和协议传过来的Packet,都指向同一块真正的数据,
NDIS_PACKET仅仅是一个管理真正的数据的单独结构,和真正的数据是分开存放的(中间还有一个NDIS_BUFFER,所以相当于二重索引,),具体你可以看一下ddk中NDIS_PACKET结构的定义。类似于
建立一个文件的快捷,当然就不要真正复制文件了。
2。那你就不仅要分配NDIS_PACKET,还要分配NDIS_BUFFER,分配内存,真正的做数据的复制了,
frank_ding1015
驱动牛犊
驱动牛犊
  • 注册日期2005-06-11
  • 最后登录2005-06-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2005-06-13 17:55

1。MyPacket,和协议传过来的Packet,都指向同一块真正的数据,
NDIS_PACKET仅仅是一个管理真正的数据的单独结构,和真正的数据是分开存放的(中间还有一个NDIS_BUFFER,所以相当于二重索引,),具体你可以看一下ddk中NDIS_PACKET结构的定义。类似于
建立一个文件的快捷,当然就不要真正复制文件了。
2。那你就不仅要分配NDIS_PACKET,还要分配NDIS_BUFFER,分配内存,真正的做数据的复制了,


虽然说比较有效率的方式应该是直接去修改该数据真正位置的内容,不过好像是因为virtual address关系,不允许这样做。如此每次在NDIS IM层要修改数据包的内容都必须做一次 组包 的动作.. 真的是很没有效率...
有谁有更好的方式可以建议的吗?我只是想做UDP Port的映对转换
tanm2000
驱动牛犊
驱动牛犊
  • 注册日期2005-05-12
  • 最后登录2008-07-04
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望12点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-06-14 10:41
版主,我写了以下代码,组包,发包

NDIS_STATUS NDIS_API
XF_SendPacket(
IN NDIS_HANDLE MacBindingHandle,
IN PNDIS_PACKET Packet
)
{

PNDIS_PACKET OurPacket = NULL;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PNDIS_BUFFER pNdisBuffer,pOurBuffer;
ULONG PacketLength = 0;
ULONG bytescopied = 0;
PVOID virtualaddr = NULL;
NDIS_HANDLE MyPacketPool;
NDIS_HANDLE MyBufferPool;

NdisAllocatePacketPoolEx(&Status,
                                   &MyPacketPool,
                                   MIN_PACKET_POOL_SIZE,
                                   MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
                                   PROTOCOL_RESERVED_SIZE_IN_PACKET);
NdisAllocateBufferPool(&Status,&MyBufferPool,0xff);
NdisDprAllocatePacket(&Status, &OurPacket, MyPacketPool);
NdisQueryPacket(Packet,NULL,NULL,&pNdisBuffer,&PacketLength );

NdisAllocateMemoryWithTag(&virtualaddr,PacketLength,\'DMSA\');

NdisAllocateBuffer(&Status,&pOurBuffer,MyBufferPool,virtualaddr,PacketLength);

NdisChainBufferAtFront(OurPacket,pOurBuffer);
NdisCopyFromPacketToPacket(OurPacket,0,PacketLength,Packet,0,&bytescopied);

Status=m_pSendHandler(MacBindingHandle, OurPacket);
if(Status != NDIS_STATUS_PENDING)
{
NdisFreePacket(OurPacket);
}
return Status;

}

但系统没登陆就重启了,如果把Status=m_pSendHandler(MacBindingHandle, OurPacket);改成Status=m_pSendHandler(MacBindingHandle, Packet);也就是发原来的包,系统就不重启
请问我的程序哪错了?我是个新手,不好意思,又麻烦你了
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
6楼#
发布于:2005-06-14 13:04
版主,我写了以下代码,组包,发包

NDIS_STATUS NDIS_API
XF_SendPacket(
IN NDIS_HANDLE MacBindingHandle,
IN PNDIS_PACKET Packet
)
{

PNDIS_PACKET OurPacket = NULL;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PNDIS_BUFFER pNdisBuffer,pOurBuffer;
ULONG PacketLength = 0;
ULONG bytescopied = 0;
PVOID virtualaddr = NULL;
NDIS_HANDLE MyPacketPool;
NDIS_HANDLE MyBufferPool;

NdisAllocatePacketPoolEx(&Status,
                                   &MyPacketPool,
                                   MIN_PACKET_POOL_SIZE,
                                   MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE,
                                   PROTOCOL_RESERVED_SIZE_IN_PACKET);
NdisAllocateBufferPool(&Status,&MyBufferPool,0xff);
NdisDprAllocatePacket(&Status, &OurPacket, MyPacketPool);
NdisQueryPacket(Packet,NULL,NULL,&pNdisBuffer,&PacketLength );

NdisAllocateMemoryWithTag(&virtualaddr,PacketLength,\'DMSA\');

NdisAllocateBuffer(&Status,&pOurBuffer,MyBufferPool,virtualaddr,PacketLength);

NdisChainBufferAtFront(OurPacket,pOurBuffer);
NdisCopyFromPacketToPacket(OurPacket,0,PacketLength,Packet,0,&bytescopied);

Status=m_pSendHandler(MacBindingHandle, OurPacket);
if(Status != NDIS_STATUS_PENDING)
{
NdisFreePacket(OurPacket);
}
return Status;

}

但系统没登陆就重启了,如果把Status=m_pSendHandler(MacBindingHandle, OurPacket);改成Status=m_pSendHandler(MacBindingHandle, Packet);也就是发原来的包,系统就不重启
请问我的程序哪错了?我是个新手,不好意思,又麻烦你了
 

1.NdisAllocatePacketPoolEx不要在这里分配
2.如果你自己复制了一份packet,就要注意你的packet,buffer等的释放,以及要通知上层协议发送完
成,上层协议好释放它分配的packet,以及相关的资源
3.对于重起,装上ice,看看崩溃现场,还可以用windbg分析转储文件
tanm2000
驱动牛犊
驱动牛犊
  • 注册日期2005-05-12
  • 最后登录2008-07-04
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望12点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2005-06-14 14:28
我把NdisAllocatePacketPool改在openAdapter前里分配,但问题还是出现!softice的远程串口调试我试过,但没配成功。请指教。
zhaock
驱动太牛
驱动太牛
  • 注册日期2002-01-26
  • 最后登录2018-06-02
  • 粉丝3
  • 关注2
  • 积分73328分
  • 威望362317点
  • 贡献值1点
  • 好评度226点
  • 原创分0分
  • 专家分0分
  • 社区居民
8楼#
发布于:2005-06-14 15:00
softice最大的优点就是单机调试,何必还要双机呢?
游客

返回顶部