ldd
ldd
驱动牛犊
驱动牛犊
  • 注册日期2001-08-18
  • 最后登录2003-11-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:4681回复:20

我的ptreceive的思路,请指教

楼主#
更多 发布于:2001-08-25 08:12
我参考了passthru和imdrv后对passthru的ptreceive修改如下:
ptreceive()
{
if(LookAheadBufferSize>=PacketSize)
{
// allocate my packet descriptor
NdisDprAllocatePacket();

// copy headerbuffer and lookaheadbuffer into my packet
NdisMoveMemory();

// indicate packet
NdisMIndicateReceivePacket();

// free my packet descriptor
NdisDprFreePacket();
}
else
{
// LookAheadBufferSize < PacketSize
// remaining data for us to receive

// allocate my packet descriptor
NdisDprAllocatePacket();

// copy headerbuffer and lookaheadbuffer into my packet
NdisMoveMemory();

// copy data remained
NdisTransferData();
        if(Status != NDIS_STATUS_PENDING)
{
PtTransferDataComplete();
        }

// free my packet descriptor
// in pttransferdatacomplete
// NdisDprFreePacket();
}

return NDIS_STATUS_SUCCESS;
}

1)思路有什么不对的地方,或是大虾们有更好的,请不吝赐教;
2)这里不单要申请包描述符,还要自己建立MDL,请问大虾这里都要注意什么关键的细节问题?

最新喜欢:

WY.lslrtWY.lsl... riririririri txysptxysp
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2001-08-26 16:21
我没有仔细看,不过你这样处理会损失oob数据。
对于某些情况来说也许是对的,但是某些应用来
说,可能会非常惨。

不再回忆从前,我已经生活在幸福当中。
learner
驱动牛犊
驱动牛犊
  • 注册日期2001-07-27
  • 最后登录2001-12-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2001-08-26 16:56
在PtReceive中,如果LookAheadBufferSize>=PacketSize,按照pcausa的说法,需要调整LookAheadBufferSize = PacketSize.
所以不存在这种情况.根据ddk document,PacketSize >= LookAheadBufferSize, 如果是大于,需要调用ndistransferdata得到后面的数据.而且,PtTransferDataComplete()应该不是这里调用的,而是被ndis在ndistransferdata完成时调用.

至于oob数据,想和hu大侠请教一下:我感觉oob数据是mac用的,存放在ndis_packet里.在ptreceive里,如果NdisGetReceivedPacket 返回0(绝大部分情况如此),也就是下面只提供buffer,没有完整的packet,那么oob数据是不是就已经丢失了?
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
地板#
发布于:2001-08-26 20:46
transferdatacomplete可以在这里调用,此外你说的也对,
让我们来把这个过程理理顺。

ptreceive 接收数据,发现只有头,那么,调用transferdata,
然后,判断pending,然后调用ndistransferdatacomplete。
这是一种做法。我个人推荐这种做法,因为这样节省了一个
pttransferdata,pttransferdatacomplete。

还有一种做法是象passthru一样,调用介质相关函数去
indicatepacket,这样会导致ip.sys调用pttransferdata,
然后是pttransferdatacomplete。这种做法也有好处,
虚拟网卡完全仿真了miniport。

下面关于oob:
oob并不完全是mac用的,协议也用。例如ip/tcpchksum。
ndisgetreceivepacket返回null并不是大多数情况,只有
非常老的网卡是这样。这种情况下没有oob数据,也就是
说不存在丢失的问题。对于不返回null的情况有这么几种:
1、系统内存不够,因此miniport设置packet的status
为resource,然后miniport用介质无关函数indicatepacket,
这种情况会使ndis调用protocol的recevie函数而不是
receivepacket函数。因为receive这个函数所提供的包
是由miniport保留的,protocol只读,而receivepacket
这个函数提供的包对protocol来说是可写的。这里面有些
细节。
2、这个情况是ddk document没有说过的。当网卡被设置
为混杂模式,ndis也调用ptreceive,而不是ptreceivepacket。
这也可以理解,因为混杂模式会收到很多不要的包,如果
用receivpacket,为每个协议driver复制一份,浪费内存。

只要miniport调用介质无关indicatepacket,就会包含
oob data。以上就是ndisgetreceivepacet不返回null
的情况。



不再回忆从前,我已经生活在幸福当中。
Digital
驱动牛犊
驱动牛犊
  • 注册日期2001-08-08
  • 最后登录2008-07-08
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望6点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2001-08-28 16:04
Huyg大侠:
当LookAheadBufferSize < PacketSize 时,如果用你所说的第二种方式,是不是只将HeadERBuffer和LookAheadBuffer都COPY出来以一个自定议的BUFFER,然后系统就会自动调用MPTransferData(对了你上面怎么写的是pttransferdata),然后再在这个函数里加一些操作将其余的数据COPY到自定议BUFFER就能处到整个包啦?

另外,你有QQ或者其它联系方式吗?》

相信自已!
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
5楼#
发布于:2001-08-28 18:21
哦,你说的那个地方是我的笔误。
NDIS当然不会自动调用miniporttransferdata,你
看看passthru怎么做的?它调用了一个介质相关
函数ndiseth/fddi/xxx/indicatepacket。这种情况
你不需要构造packet结构。


我曾经有过一个qq号,但是很久不用,而且我也不
记得号码了。

我一般不用在线聊天工具聊天,多年的战友兄弟们除外。
不再回忆从前,我已经生活在幸福当中。
Digital
驱动牛犊
驱动牛犊
  • 注册日期2001-08-08
  • 最后登录2008-07-08
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望6点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2001-08-28 19:35
老版:
    要不要我给你一个QQ号啊(NND,现在的QQ不能在线申了)。我还有一点问提,我用的是第一种方法,我是想在PTRECEIVE的后的包处理之前,将整个以太包(包括MAC层的)拷贝到一个缓冲,分析整个包并进行过滤(随便改掉IP层的协议),在通常的PC台式机上可能正常运行,可是在笔记本或是HP等专用机上就有问提,不知道哪一步不对,请指教,我的思路是:


ptreceive()
{
////////////////////////////////////add
  UCHAR pBuffer[2000];
...
if(LookAheadBufferSize==PacketSize)
{
   将HeaderBuffer和LookAheadBuffer copy到pBuffer
}
else if (LookAheadBufferSize<PacketSize)
{
   将HeaderBuffer和LookAheadBuffer的前20byte copy到pBuffer
   我以为,在这种情况下,系统会自动调用miniport.c的MPTransferData(),所以我就在这种函数可添加了一段代码,完成将其余的数据COPY到pBuffer的相应位置来完成对数据的获取,不知道对不对?
}
//分析判断是否要过滤,如果过滤就将第三层协议随便改一个值!
/////////////////////////////////////////
..
//其后不变
if(!pAdapt->MiniportHandle)
{
Status = NDIS_STATUS_FAILURE;
}
.......
   pAdapt->IndicateRcvComplete = TRUE;
  switch(pAdapt->Medium)
  {
    case NdisMedium802_3:

。。。。
}
相信自已!
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
7楼#
发布于:2001-08-28 21:28
关于为什么代码在有些机器上能跑,在另外一些机器上不能跑,
我曾经在whnet bbs上发过多篇贴子讨论这个问题。因为我自己
也曾经为此和17熬了几乎有一个星期的通宵。

所有的问题都来自网卡,和网卡状态,以及网卡驱动程序。

但是好的代码应该能够适应所有的环境。

你必须自己调用ndistransferdata,不要用mptransferdata,
你用第一种做法,可以不要mptransferdata这个函数(注释掉
它吧)。而且也注释掉后面的
switch case xxx
{}
都用不着



我不要QQ号,因为我上qq几乎都是用来和小妹妹聊天。

不再回忆从前,我已经生活在幸福当中。
Digital
驱动牛犊
驱动牛犊
  • 注册日期2001-08-08
  • 最后登录2008-07-08
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望6点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2001-08-29 09:31
Huyg大侠,能 不能给个筐架啊?

我试了一下,如果不调用
pAdapt->IndicateRcvComplete = TRUE;
switch(pAdapt->Medium)
{
case NdisMedium802_3:
。。的话,什么包都不能上传了。。》?
相信自已!
Digital
驱动牛犊
驱动牛犊
  • 注册日期2001-08-08
  • 最后登录2008-07-08
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望6点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2001-08-29 09:35
另外较正一下,我用的是第二种方式(我纺造PASSTHRU改的),在数据上传之前,怎么获取整个包的数据,进行处理。
相信自已!
Digital
驱动牛犊
驱动牛犊
  • 注册日期2001-08-08
  • 最后登录2008-07-08
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望6点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2001-08-29 10:17
这是我的监视记录,我是用的PASSTHRU的方式处理LookAheadBufferSize < PacketSize 的,可是为何多次出现这种情况后Ndis才调用MPTransferData(内含NdisTransferData)?
请指教!


101.399837 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 1496
101.520389 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=52  PacketSize = 52
101.557171 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 1496
101.900381 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 1496
102.057922 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 1496
102.142583 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 296
102.142662 Default *** E:\FW\2000\port\miniport.c (1152) *** NdisTransferData have been called (LookAheadBufferSize < PacketSize)

102.144032 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 852
102.144095 Default *** E:\FW\2000\port\miniport.c (1152) *** NdisTransferData have been called (LookAheadBufferSize < PacketSize)

102.144134 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=140  PacketSize = 140
102.400964 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 1496
102.558654 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 1496
102.901504 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 1496
103.059389 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 1496
103.402575 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 1496
103.560120 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 1496
103.902609 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 1496
103.935210 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=194  PacketSize = 194
104.060866 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 1496
104.403163 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 1496
104.561605 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 1496
104.585576 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 296
104.585646 Default *** E:\FW\2000\port\miniport.c (1152) *** NdisTransferData have been called (LookAheadBufferSize < PacketSize)

104.586266 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=140  PacketSize = 140
104.903724 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 1496
105.062374 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 1496
105.198491 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 852
105.198572 Default *** E:\FW\2000\port\miniport.c (1152) *** NdisTransferData have been called (LookAheadBufferSize < PacketSize)

105.404288 Default Recv Packet HeadBufferSize = 14  LookAheeadBufferSize=200  PacketSize = 1496
相信自已!
ldd
ldd
驱动牛犊
驱动牛犊
  • 注册日期2001-08-18
  • 最后登录2003-11-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2001-08-29 10:46
不只是Digital,这种情况我也遇到过,就是因为
搞不懂,所以决定采用第一种方法的(仿照imdrv,
也是版主推荐的)

斑竹,继续出手吧! :)
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
12楼#
发布于:2001-08-29 10:51
哦,关于这两种方法,不同时期我曾经推荐过不同的方法。
原因是第一种省事,也许效率高些,第二种更兼容。
不同时期我看重不同的东西。

第2种方法并不适合你的项目,我想你是要修改包内容的吧?
ndisethindicatepacket已经把包交给了ip,你还怎么改?
不再回忆从前,我已经生活在幸福当中。
ldd
ldd
驱动牛犊
驱动牛犊
  • 注册日期2001-08-18
  • 最后登录2003-11-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2001-08-29 11:12
我也是想在passthru的基础上,加入对指定的包类型
进行过滤,这样的话就必须首先得到整个包,看来
我还是用地一种方法吧 :( 这样的话,就得全面改写
ptreceive,还要注意版主提到的oob数据



HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
14楼#
发布于:2001-08-29 11:26
实验室的东西往往很简单,但是实用化就比较困难。
97年的时候我就开始学习ndis,但是直到现在还是
一知半解。新东西和老东西简直无法兼容,ipsec
和nat,ipip的兼容都很难解决。


学习ndis,对注册表的了解是非常重要的,我推荐一个
东西,2k/nt 的resource kit。这个东西没有盗版,
但是总是会有人买msdn,然后放到网上。resource kit
里面详细的描述了所有注册表信息的含义。开发
driver资料很重要,没有chk build有的时候也
很难受。
不再回忆从前,我已经生活在幸福当中。
Digital
驱动牛犊
驱动牛犊
  • 注册日期2001-08-08
  • 最后登录2008-07-08
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望6点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2001-08-29 11:30
我对第一种的流程还是不大清楚,我享细说一下,不对了请指教:
ptreceive()
{
if(LookAheadBufferSize>=PacketSize)
{
//这种情直接将将HEADERBUFFER和LookAheadBUffer组合就是了
//致于以下几步是不是指示上层,已接收到数据包,如果是,哪么、上层(如IP层)又以何种方式取得数据包呢?
// allocate my packet descriptor
NdisDprAllocatePacket();
// copy headerbuffer and lookaheadbuffer into my packet
NdisMoveMemory();
// indicate packet
NdisMIndicateReceivePacket();
// free my packet descriptor
NdisDprFreePacket();
}
else
{
//这种情况下,调用了NDISTRANSFERDATA是不是将数据传到了上层,为何又没有调用 NdisMIndicateReceivePacket(),还有就是在这种情况下,是不是我还要写一个函数将数据从PACKET描述符中取出,并与前面的组合,
// LookAheadBufferSize < PacketSize
// remaining data for us to receive
// allocate my packet descriptor
NdisDprAllocatePacket();
// copy headerbuffer and lookaheadbuffer into my packet
NdisMoveMemory();
// copy data remained
NdisTransferData();
if(Status != NDIS_STATUS_PENDING)
{
PtTransferDataComplete();
}
// free my packet descriptor
// in pttransferdatacomplete
// NdisDprFreePacket();
}

return NDIS_STATUS_SUCCESS;
}

谢谢指捣,  请教两位的联系方式,
我的QQ:15614487
email:digitalbrain@163.com
个人主页:www.ishacker.com
相信自已!
Dino
驱动牛犊
驱动牛犊
  • 注册日期2001-08-07
  • 最后登录2007-01-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2001-08-29 14:29
if(LookAheadBufferSize>=PacketSize) 的时候你需要将HEADERBUFFER和LookAheadBUffer的数据考到自己的缓冲区中,然后检查,再自己分配PNDIS_BUFFER和PNDIS_PACKET,然后将你自己的Packet指示给Ip。
else的时候,你也要将HEADERBUFFER和LookAheadBUffer的数据考到自己的缓冲区中,然后调用NdisTransferData,在ProtocolTransferDataComplete里面你就能得到后续的数据,然后再自己构造一个Packet,指示给IP。
Death is only the beginning
baijbup
驱动牛犊
驱动牛犊
  • 注册日期2001-08-03
  • 最后登录2003-05-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2001-10-23 10:22
版主:
   请问为什么在PASSTHRUY基础上网卡工作在混杂模式的时候,本机收到的LOOKAHEADBUFFERSIZE<PACKETSIZE是都会调用MPTRANSFERDATA
但是如果是其他及其的包,就不一定了,有时候会调用,有时候不会调用。我个人认为是因为PROTOCOL接到NdisMEthIndicateReceive
通知,发现接收的包衣本机无关,那么就放弃,自然就不会调用
MPTRANSFERDATA了,如果是这样,请问怎么让PROTOCOL一定调用
MPTRANSFERDATA呢????清多指点,谢谢!
至于直接调用NDISTRANSFERDATA,我是过了,实在PTRECEIVE中
直接调用的,我只是NdisDprAllocatePacket,没有定义什么MDL
各种包的标志设置什么的(因为不知道这个包是什么样的)。后
果是一进入NDISTRANSFERDATA系统就崩溃了。我应该怎么做呢!
????
************************ 寻找快乐的人 ************************
moqingsong
论坛版主
论坛版主
  • 注册日期2002-04-07
  • 最后登录2011-02-03
  • 粉丝0
  • 关注0
  • 积分74分
  • 威望71点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2002-06-02 23:51
需要好好学习,看了很多遍,还是有不理解的。
按第一贴的“给分”键,给分。
cyran
驱动中牛
驱动中牛
  • 注册日期2001-09-28
  • 最后登录2009-02-24
  • 粉丝0
  • 关注0
  • 积分101分
  • 威望20点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2002-06-03 09:29

学习ndis,对注册表的了解是非常重要的,我推荐一个
东西,2k/nt 的resource kit。这个东西没有盗版,
但是总是会有人买msdn,然后放到网上。resource kit
里面详细的描述了所有注册表信息的含义。开发
driver资料很重要,没有chk build有的时候也
很难受。


请问版主有没有网址给一个,下载2k/nt 的resource kit!

多谢!!!
上一页
游客

返回顶部