您的位置:首页 > 理论基础 > 计算机网络

ndis中间层驱动总结---发文于2014.1.21

2016-01-15 23:15 190 查看
1.NDIS_PACKET 包描述符结构

结构中包含3个域,Head,Tail,NdisPacketOobOffset,包描述符和一个或者多个链式数据缓冲区(MDL)关联,这个缓冲区包含真正的网咯数据。Head指向第一个缓冲区地址,Tail指向最后一个为NULL

,可以通过NdisQueryPacket,NdisGetNextBuffer,NdisGetFirstBufferFromPacketSafe等函数获得链式缓冲区信息。带内数据是正常的网络数据,oob带外数据是除正常数据外,需要传达的信息。

NDIS_PACKET_EXTENSION是oob的扩展。

2.DriverEntry 入口函数

初始化小端口包装句柄。使用NdisIMRegisterLayeredMiniport注册小端口特征。它返回NDIS_HANDLE把小端口和协议驱动关联起来。注册

协议驱动特征。通过NdisIMAssociateMiniport关联两个驱动接口。可以认为每个中间层驱动分两层,上层小端口驱动,下层协议驱动。

3.动态绑定NIC设备

由PNP管理器发起,依次调用它们的AddDevice函数。在PtBindAdapter中实现协议和小端口的绑定。ndis驱动不通过设备栈绑定而是直接的函数调用来进行分层传递。

在PtBindAdapter函数内部,使用NdisAllocatePacketPoolEx分配缓冲池,通过函数NdisOpenAdapter实现绑定下层NIC。这个调用是在NDIS的内核对象中,建立起中间层驱动和下层被绑定驱动之间注册

函数的调用关系。建立关系后,中间层和下层驱动就可以互相调用收发包。这是NDIS的绑定实质。因为bind可能异步完成,在bind前调用事件初始化函数,在调用后等待事件,在

PtOpenAdapterComplete中激活事件。调用NdisIMInitializeDeviceInstanceEx初始化驱动的虚拟NIC。

4.小端口miniport初始化MPInitialize 

上面绑定到真实的底层NIC设备后,自己创建一个虚拟的NIC设备,随时过滤从上层过来的请求包。然后NdisMSetAttributesEx设置适配器上下文,不处理超时。

5.发送数据包

当上层驱动将包发到中间层驱动时它能在MpSend回调函数中收到这些包描述符。它可以在这个回调中调用过滤规则函数发送,或者拒绝,或者过滤。发送包的时候调用NdisSend,NdisSendPackets或者

NdisCoSendPackets系列函数。NdisSend函数的第二个参数NdisBindingHandle即包含真实目标NIC或者下层驱动的虚拟NIC的句柄。

6. 包描述符“重利用”和“重申请”

收到的包描述符不修改,传递下去是重利用。根据收到的包描述符,重建新的包描述符,是重申请。重申请只需要申请包描述符后,修改包描述符结构,数据部分把原来的Head和Tail指针复制过来。

7.发送数据包的异步完成

在PtSendComplete中,判断是否重利用则根据包描述符是否是从包池中申请来的。如果是重利用,调用NdisMSendComplete通知上层驱动包发送的完成。如果是重申请,则使用原始包描述符通知上层驱

动,并对正在发送包计数减一。

8. 中间层驱动接收数据包

底层驱动调用NdisMIndicateReceivePacket向中间层驱动通知接收数据包描述符指针。中间层驱动如果提供了PtReceivePacket函数,则该函数被调用。否则,PtReceive函数被调用。如果底层驱动调

用NdisMXxxIndicateReceive函数向中间层驱动通知接收包,则PtReceive函数被调用。协议驱动中PtReceive函数侧重接收包,中间层驱动中侧重于向上通知包。可以在此函数中对收到的数据包进行规

则的处理,比如接收,丢弃,重定向等。

上层驱动收到网络包接收通知后,回调用NdisTransferData要求底层驱动将完整的包数据发送给他。中间层驱动在MPTransferData中收到这个请求。可以在这个函数

中对包数据做规则的处理,比如接收,丢弃,重定向等。如果是异步完成接收包,则在PtTransferDataComplete处理完成。

同步使用PtReceivePacket接收完整的包描述符数据。

9. 对包的过滤

通过NdisQueryPacket获取第一个包的ndisbuffer地址,根据NdisGetNextBuffer获取包的下一个链式数据部分,然后判断是ip,arp包等,如果是ip包,根据ip头判断具体的icmp,udp,tcp等协议,进

行过滤。

10. 中间层驱动的查询和设置。

查询请求:如果NdisRequest异步完成,则返回NDIS_STATUS_PENDING,系统会查询命令完成后调用NDIS函数NdisMQueryInformation,使得中间层驱动的PtRequestComplete被调用。如果是同步,则自

己调用PtRequestComplete.在PtRequestComplete后处理中,将有用信息保存在中间层驱动中,然后调用NdisMQueryInformationComplete完成。设置请求类似。

11.生成普通的控制设备

使用NidsMRegisterDevice生成设备对象,有一个参数可以输入一个分发函数表,这样就不会破坏ndis中间层驱动本身的分发函数。或者先获取原来的分发函数,然后把分发函数指针设置为hook后函数

,在hook函数中调用原来的分发函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息