NDIS Filter驱动-简介和说明

Filter驱动经常被翻译为“筛选器”驱动或者“过滤器”驱动,但是由于在DirectX系列编程中,也有将组件称为Filter的,于是觉得还是使用原文比较好,不过在这里使用“过滤器”其实也算合理,DirectX里面的翻译为"连接器"更好一些,不过最终还是使用英文来描述吧。

这可能是最广为人知的驱动程序分类,毕竟很多著名的应用都是在这一层实现,例如许多杀毒软件的包过滤防火墙;工业上使用的千兆网网络相机驱动程序;Wireshark抓包工具等等,这是由于它正在处于一个非常微妙的节点上:

  • Filter驱动在默认情况下位于所有NIC的小端口驱动之上,每个NIC对应的小端口驱动可能都不一样,但是NDIS巧妙的设计使得小端口驱动完全的适配了硬件,故Filter完全不需要考虑硬件相关性,同时Filter驱动不需要考虑无线网卡和有限网卡的区别是什么,它们甚至是一套代码的不同实例;
  • Filter驱动获取数据效率远高于应用层的socket,NI系列的Labview 2010曾经有过使用socket实现网络数据传输的例子,对于80MB/s的带宽,使用socket会导致CPU占用率达到40%,如果使用Filter驱动,那么CPU占用率是5%,差了8倍的效率(本系列的最后,我们会解释这部分原因);
  • Filter驱动的编写非常简单,最开始NDIS 5.1的时候,需要编写中间层驱动,对上模拟自己是一个小端口驱动,对下模拟自己是一个协议驱动,反而同时需要了解两部分的协议,NDIS 6.0之后的Filter驱动则简单了许多;

值得特别指出的是,NDIS 6.0 是网络驱动程序接口规范 (NDIS) 库的下一个主要版本。  NDIS 6.0 包含在 Windows Vista 操作系统中,从现在来看,Vista系统几乎是最难以使用的windows版本,但在内核上,Vista确实比之前的xp有了颠覆性的改变,许多重要的内核变动都是在Vista阶段定型的,甚至于最新的win 11,只是重写了内核,并不是抛弃了之前的设计。

虽然NDIS6.8有许多很不错的特性,但我们还是会重点关注NDIS6.0,原因在于那是一次巨大的变革,理解这个变革能够明白windows在后续6.0~6.8之间改动框架的思路,这比具体的改动要重要许多!

在NDIS6.0 方面,两个主要目标指导了 NDIS 6.0 的设计和开发:

1. 增强驱动程序性能和可伸缩性。 以下重大改进为客户端和服务器提供了显著的性能提升:

  • 网络数据打包
  • 发送和接收路径
  • 运行时重新配置功能
  • 散点/收集 DMA
  • Filter驱动程序
  • 接收数据处理的多处理器缩放
  • 将 TCP 任务卸载到 NIC
  • 简化 NDIS 驱动程序模型

2. 以下改进简化了驱动程序开发:

  • 简化的驱动程序初始化
  • 对 NDIS 接口的版本控制支持
  • 简化的重置处理
  • 用于获取管理信息的标准接口
  • 用于替换Filter中间驱动程序的Filter驱动程序模型

下面大概看一下这些修改把! 

网络数据打包

NDIS 6.0 中重新设计了数据打包。 基于 NDIS_PACKET 结构的发送和接收体系结构已替换为基于 NET_BUFFER 和 NET_BUFFER_LIST 结构的体系结构。 NET_BUFFER结构是NDIS_PACKET结构的功能等效项。 NET_BUFFER结构指定用于网络数据的 MDL 链 (缓冲区) ,以及 NDIS、协议驱动程序和微型端口驱动程序的预留空间。 NET_BUFFER结构可以在由NET_BUFFER_LIST结构描述的列表中链接在一起。 NET_BUFFER_LIST结构还为适用于列表中所有NET_BUFFER结构的带外 (OOB) 数据提供存储。

Microsoft 下一代网络驱动程序堆栈中的所有组件(包括 TCP/IP 传输和 Winsock)都使用NET_BUFFER打包。 整个驱动程序堆栈的统一数据打包无需重新打包数据,简化了数据处理,减少了函数调用的数量。

为了适应使用NDIS_PACKET结构的旧驱动程序,NDIS 6.0 将NDIS_PACKET结构转换为NET_BUFFER结构,反之亦然。 此转换对 NDIS 驱动程序是透明的。

NDIS 将驱动程序的数据回填要求传播到更高级别的驱动程序。 为发送数据分配NET_BUFFER和NET_BUFFER_LIST结构时,较高级别的驱动程序会分配足够的数据空间来容纳堆栈中的所有较低级别的驱动程序。 因此,较低级别的驱动程序不必分配额外的缓冲区空间来容纳特定于层的标头。 相反,它们可以使用预先分配的回填空间来执行此操作。

改进的发送和接收路径

NDIS 6.0 发送和接收路径已得到改进,如下所示以增强性能:

  • 所有 NDIS 6.0 及更高版本的驱动程序发送和接收函数都可以通过单个函数调用传输 NET_BUFFER_LIST 结构及其关联的 NET_BUFFER 结构的链接列表。 这种对真正的多包发送和接收操作的支持大大减少了驱动程序必须进行的函数调用数;
  • 调用发送或接收函数时,在 DISPATCH_LEVEL 运行的驱动程序可以将其 IRQL 指示给 NDIS。 当 NDIS 随后调用堆栈中的其他驱动程序时,这些驱动程序无需测试 IRQL 或将其设置为 DISPATCH_LEVEL。 这可以减少与在关键代码节中测试和设置 IRQL 相关的开销;
  • 驱动程序在驱动程序堆栈中向上和向下传递数据包时,可以请求 NDIS 调整NET_BUFFER数据偏移量以适应标头信息。 发送数据包时,驱动程序可以扩展已用数据空间,以适应驱动程序的标头信息。 指示接收数据包时,驱动程序可以在驱动程序访问完其标头信息后减少已用数据空间。 这种在不分配和释放内存或复制数据的情况下动态调整NET_BUFFER结构中已用数据空间的功能减少了处理网络数据所需的开销;
增强的运行时重新配置功能

NDIS 6.0 引入了暂停和重启驱动程序堆栈的功能,而无需拆毁堆栈并生成新堆栈。 所有 NDIS 6.0 及更高版本的驱动程序都必须支持暂停和重启服务。

暂停堆栈可在重新配置之前将所有驱动程序置于已知状态,从而消除同步问题。 暂停功能还使 NDIS 有机会查询驱动程序特征,并重新配置堆栈的其他特征。

NDIS 可以暂停驱动程序堆栈,例如,在执行即插即用操作(例如添加或删除Filter驱动程序,或绑定或取消绑定协议驱动程序)之前暂时停止数据流。 NDIS 在重新配置后重启堆栈。

微型端口和Filter驱动程序通过函数接口处理暂停和重启服务。 协议驱动程序通过即插即用事件通知来处理暂停和重启服务。

接收端缩放支持

NDIS 6.0 引入了跨多个处理器缩放接收数据包处理的支持。 接收端缩放 (RSS) 接口支持多个级别的 NIC 硬件支持。

根据当前 RSS 配置,微型端口驱动程序或 NIC 确定要与接收的数据关联的目标处理器。 可以调整 RSS 配置,以最有效地使用可用目标处理器。

微型端口驱动程序或 NIC 将接收的数据分配给与目标处理器关联的接收队列。 微型端口驱动程序请求 NDIS 为具有非空接收队列的目标处理器计划延迟的过程调用 (DPC) 。

NDIS 在每个指定的目标处理器上计划 DPC。 每个 DPC 处理指定目标处理器上的特定接收队列。

新的Scatter/Gather DMA 支持

与以前版本的 NDIS 不同,NDIS 6.0 在映射数据包以便进行 DMA 传输之前,将发送数据包传递给微型端口驱动程序。 获取数据包后,微型端口驱动程序可以请求 NDIS 为数据包提供Scatter/Gather列表。

这提供了以下好处:

  • 由于微型端口驱动程序在映射数据包之前有权访问数据包,因此微型端口驱动程序对该数据包所做的任何更改都反映在关联的Scatter/Gather列表数据中;
  • 微型端口驱动程序可以通过将小数据包或高度碎片数据包复制到预分配的缓冲区来优化这些数据包的传输,从而消除映射的需要。 这消除了不必要的处理;
  • NDIS 可以在一个函数调用中安全地将多个 NET_BUFFER 结构传递给微型端口驱动程序。 这可以减少对微型端口驱动程序的调用,从而提高系统性能;
  • 由于微型端口驱动程序可以为Scatter/Gather列表预分配内存,因此 NDIS 不必在运行时为Scatter/Gather列表分配内存;
更快的Filter驱动程序

NDIS 6.x Filter驱动程序模型取代了 NDIS 5.x Filter中间驱动程序模型。 新的Filter驱动程序模型通过多种方式增强系统性能:

  • 与 NDIS Filter中间驱动程序不同,NDIS 6.0 或更高版本的Filter驱动程序不是作为微型端口驱动程序和协议驱动程序的组合实现的。 它具有类似于微型端口和协议驱动程序的唯一接口,但针对筛选在驱动程序堆栈上传递的信息进行了优化。
  • NDIS 6.0 及更高版本的Filter驱动程序支持绕过功能,以便在不需要此类处理时,驱动程序不会处理数据。
  • NDIS 6.0 及更高版本的Filter驱动程序可以在运行时动态插入驱动程序堆栈或从驱动程序堆栈中删除,而无需拆解绑定。 在发生此类动态操作之前,NDIS 6.0 会暂停堆栈中的所有 NDIS 驱动程序。 重新配置完成后,NDIS 会重启堆栈。
完全 TCP 卸载

NDIS 6.0 引入了用于完全 TCP 卸载的体系结构。 此体系结构称为“chimney offload”体系结构,因为它在应用程序和支持卸载的 NIC 之间提供称为“chimney”的直接连接。 chimney使 NIC 能够对卸载的连接执行 TCP 处理,包括维护协议状态。

chimney offload体系结构减少了网络密集型应用程序的主机网络处理。 这允许网络应用程序更有效地缩放,同时减少端到端延迟。 托管应用程序所需的服务器更少,并且服务器能够使用完整的以太网带宽。

TCP chimney offload一个或多个 TCP 连接的所有 TCP 处理。 主要的性能提升是通过卸载分段和重新组装 (SAR) 、卸载处理(确保可靠连接 ,例如,ACK 处理和 TCP 重新传输计时器))以及减少中断加载中获得的。

注意 Windows Vista 操作系统继续支持早期版本的操作系统中可用的单个 TCP 任务卸载。 这些任务可以在尚未通过chimney offload的连接上卸载。 支持卸载的 NIC 应支持chimney offload和任务卸载。 此类 NIC 提供最高程度的卸载优化

Filter驱动程序的特征

Filter驱动程序为微型端口驱动程序提供数据包的过滤服务。 NDIS 驱动程序堆栈必须包含微型端口驱动程序和协议驱动程序,并选择性地包含Filter驱动程序。 以下应用程序可能需要Filter驱动程序: 

  • 出于安全或其他目的的数据筛选应用程序;
  • 监视和收集网络数据统计信息的应用程序;

Filter驱动程序具有以下特征:

  • Filter驱动程序的实例称为 Filter模块。 Filter模块附加到基础微型端口适配器。 同一Filter驱动程序或不同Filter驱动程序中的多个Filter模块可以堆叠在适配器上。
  • 在此类驱动程序和基础微型端口驱动程序之间安装Filter模块时,无需提供替代功能, 除非另有规定,Filter模块对过度使用协议驱动程序是透明的。
  • 由于Filter驱动程序不实现虚拟微型端口(如中间驱动程序),因此Filter驱动程序不与设备对象相关联。 具有过度筛选模块的微型端口适配器充当微型端口适配器的修改版本。 
  • NDIS 使用配置信息按正确的驱动程序堆栈顺序将Filter模块附加到适配器。 
  • NDIS 可以在驱动程序堆栈中动态插入或删除Filter模块,或者重新配置Filter模块,而无需拆毁整个堆栈。
  • 当 NDIS 重启驱动程序堆栈时,协议驱动程序可以获取驱动程序堆栈中的Filter模块列表。
  • Filter驱动程序可以筛选与基础微型端口适配器之间的大多数通信。 Filter模块不与过度协议驱动程序和微型端口适配器之间的任何特定绑定相关联。
  • Filter驱动程序可以选择已筛选的服务,对于未筛选的服务,可以绕过这些服务。 可以动态重新配置被绕过的服务以及筛选的服务的选择。 
  • NDIS 保证上下文空间的可用性, 查看Filter驱动程序 NET_BUFFER_LIST_CONTEXT结构 。 因此,Filter驱动程序不需要包含代码来复制缓冲区以获取上下文空间。 
Filter驱动程序服务

Filter驱动程序可以提供以下服务:

  • 源自发送请求和接收指示;
  • 修改发送和接收数据路径中的数据缓冲区排序或计时;
  • 在驱动程序堆栈的发送和接收数据路径中添加、修改、删除网络数据缓冲区;
  • 发起查询并将 OID 请求设置为基础驱动程序;
  • 筛选查询并将 OID 请求设置为基础驱动程序;
  • 筛选来自基础驱动程序的 OID 请求的响应;
  • 向过度覆盖的驱动程序发出状态指示;
  • 从基础驱动程序筛选状态指示;
  • 管理注册表中与其接口的每个微型端口适配器的配置参数;
Filter驱动程序的类型

有两种主要类型的Filter驱动程序:

  • 监视:这些Filter驱动程序监视驱动程序堆栈中的行为。 但是,它们仅传递信息,不修改驱动程序堆栈的行为,监视Filter驱动程序无法修改或源自数据;
  • 修改:这些Filter驱动程序修改驱动程序堆栈的行为。 修改类型特定于驱动程序;

INF 文件中的 FilterType 条目0x00000001用于监视Filter驱动程序,0x00000002用于修改Filter驱动程序。

可以指定Filter驱动程序是必需的。 此功能通常用于修改Filter驱动程序。 如果未加载强制Filter驱动程序,则关联的驱动程序堆栈将被拆除。

必需的Filter驱动程序

必需Filter驱动程序是必须存在的Filter驱动程序,驱动程序堆栈才能正常运行。 如果未附加必需的Filter模块,驱动程序堆栈的其余部分将被拆掉。 修改或监视Filter驱动程序 可能是必需的。 所有Filter中间驱动程序都是可选的。

若要将必需Filter模块附加到驱动程序堆栈,NDIS 会取消绑定所有协议绑定,附加Filter模块,然后重新建立所有协议绑定。 如果驱动程序未附加,NDIS 会拆掉基础驱动程序堆栈。

若要从驱动程序堆栈中分离必需的Filter模块,NDIS 取消绑定所有协议绑定,分离Filter模块,然后重新建立协议绑定。 为了分离可选的Filter模块,NDIS 会暂停堆栈并重启它,而不解除协议驱动程序的绑定。

当计算机重启时,如果与该适配器关联的任何必需Filter模块未附加到微型端口适配器,则 NDIS 不会将任何协议驱动程序绑定到微型端口适配器。

若要安装必需的Filter驱动程序,必须在 INF 文件中为 FilterRunType 指定值 0x00000001。 若要安装可选的Filter驱动程序,必须在 INF 文件中为 FilterRunType 指定值 0x00000002。

  • 18
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Filter Drivers主要包括以下特性:   1) 一个Filter Drivers实例叫Filter Module。Filter Module附加在一个适配器的微端口驱动上, 来自相同或不同Filter Drivers的多个Filter Module都可以被堆叠在一个网络适配器上   2) 在Filter Module被安装到驱动栈时,之上的协议驱动和之下的微端口驱动都不需要提供额外的支持功能   3) 因为Filter Module不像中间层驱动(intermediate driver)那样提供一个虚拟的微口,也不与某个设备对象联结,所以在微端口适配器(miniport adapter)之上的Filter Module 功能相当于一个修过过版本的微端口适配器(miniport adapter)。(原文:Because filter drivers do not implement virtual miniports like an intermediate driver, filter drivers are not associated with a device object. A miniport adapter with overlying filter modules functions as a modified version of the miniport adapter.)   4) NDIS使用配置信息来到决定一个Filter Module附加到一个网络适配器栈上的顺序   5) 在不用拆除整驱动栈的情况下,NDIS可以动态的插入、删除Filter Module或进行重新配置   6) 当NDIS重起驱动栈的时候协议驱动可以获得在栈上的Filter Module列表   7) Filter Drivers可以过滤下层网络适配器上绝大部分的通信。Filter Module不联结某特定的绑定(Filter modules are not associated with any particular binding between overlying protocol drivers and the miniport adapter.)   8) Filter Drivers 可以选择为过滤服务也可以选择为分流的不过滤服务,选择为哪一种是可以动态配置的(Filter drivers can select the services that are filtered and can be bypassed for the services that are not filtered. The selection of the services that are bypassed and the services that are filtered can be reconfigured dynamically.)   9) NDIS 保证有效的上下文空间,也不就是说Filter Drivers不要需要通代码COPY缓冲区来获得上下文空间  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值