【问题标题】:NDIS LWF - FilterRestart and FilterPauseNDIS LWF - FilterRestart 和 FilterPause
【发布时间】:2014-05-25 03:27:39
【问题描述】:

我是 NDIS LWF 驱动程序的新手,但在确定 Win7 上的 WFP 无法满足我的要求后,我不得不转向它们。所以希望这不是一个太基本的问题。

我的要求基本上是能够在多 NIC 系统上的选定 NIC 上混杂地监听。我已经修改了 LWF 示例以将接口置于混杂模式,但我现在陷入了如何设置指定适配器的问题。我意识到 LWF 位于所有适配器之上,因此它不像我可以调用 NdisOpenAdapterEx 的协议,但我认为必须有一些过滤机制来忽略某些适配器。

我需要能够将我关心的接口的选定 MAC 地址 IOCTL 到驱动程序。是否可以加载驱动程序但仅在特定接口上运行过滤器,或者我只需要忽略来自其他人在 FilterReceiveNetBufferLists 中不关心的调用。如果我不对特定接口执行任何操作,似乎不必使用 FilterReceiveNetBufferLists 回调会更有效。

让我感到困惑的是,FilterRestart 在 DriverEntry 期间被自动调用(通过 NdisFRegisterFilterDriver),并且似乎没有 NdisFPauseFilter(但有一个 NdisFRestartFilter)。理想情况下,我希望能够在任何过滤开始之前设置必要的参数,并且我希望在 DriverEntry 期间不要使用注册表,因为我仍然需要能够根据需要动态重新分配任务。

最后,为了更好地理解 NDIS 内部结构,当过滤器模块暂停时,整个堆栈是否会暂停,或者 NDIS 是否围绕暂停的模块路由?

【问题讨论】:

    标签: windows networking kernel driver ndis


    【解决方案1】:

    这些都是好问题。

    是否可以加载驱动程序但只在特定接口上运行过滤器

    是的。这里有三个选项。

    1. 在用户模式下静态禁用绑定;或
    2. 在运行时拒绝绑定。
    3. Dynamically bypass and re-enable the datapath。 (此处不再详述,因为在 MSDN 上已有概述。)

    要静态禁用绑定,您可以使用the INetCfg API 查找过滤器驱动程序和 NIC 之间的绑定,然后禁用它。这可能看起来像:

    INetCfg::Initialize
    myFilter = INetCfg::FindComponent
    myFilter->QueryInterface(INetCfgComponentBindings)
    for each binding in bindings
        if binding is to undesirable NIC
            INetCfgBindingPath::Enable(FALSE)
    

    安装驱动程序后,您可以随时执行此操作。例如,您的用户模式应用可能决定仅在其 GUI 运行时启用与某些 NIC 的绑定。

    但是运行用户模式代码并不总是很方便,如果您的驱动程序还没有用户模式存在,那么创建一个只是为了禁用一些绑定可能有点过头了。这是第二种技术派上用场的地方。您可以在用户模式下静态启用绑定,但在运行时拒绝绑定。

    如何拒绝在运行时绑定?在许多情况下,您所要做的就是从您的FilterAttach 处理程序返回一个失败状态。这足以让 NDIS 相信您的过滤器不能(或不会)连接到 NIC。但是 — 如果您的过滤器被标记为 Mandatory(即 INF 的 FilterRunType 为 1),那么您的 FilterAttach 失败将导致 NIC 无法运行。 (毕竟,这是强制的全部意义。如果您的过滤器不存在,那么数据路径不得运行。)但是如果您想允许 NIC无论如何开始运行,在您的过滤器从其FilterAttach 返回失败代码之前,在您的NDIS_FILTER_ATTACH_PARAMETERS::Flags 字段中设置NDIS_FILTER_ATTACH_FLAGS_IGNORE_MANDATORY 标志。

    如果我不对特定接口执行任何操作,似乎不必使用 FilterReceiveNetBufferLists 回调会更有效。

    你的直觉是正确的。在数据路径中有一个过滤器是有开销的,如果过滤器什么都不做,那就是浪费了 CPU 周期。但是暂时不要取消这个选项。在某些情况下,此选项的简单性超过了其(相对较小的)CPU 成本。也就是说,除非您的目标市场正在计算每个 CPU 周期,否则使用这个简单的选项可能就足够了。

    我不想在 DriverEntry 期间使用注册表,因为我仍然需要能够根据需要动态重新分配任务。

    如上所述,您可以使用用户模式代码重新分配任务。每次用户模式调用 INetCfg::Apply 时,NDIS 都会调用任何需要进行正确更改的FilterAttachFilterDetach

    当您使用第二种技术时,实际上不可能重新分配任务。如果您确实需要重新分配特定 NIC 的任务,那么您应该使用第一种或第三种技术。

    当过滤器模块暂停时,整个堆栈是否会暂停,或者 NDIS 是否围绕暂停的模块进行路由?

    整个堆栈暂停。 NDIS 不会“绕过”过滤器。 (如果您的过滤器是可选的,那么当您的过滤器未运行时,流量将绕过您的过滤器。但只要您的过滤器连接到 NIC,NBL 和 OID 就会通过您的过滤器。)

    【讨论】:

    • 非常感谢杰弗里。我希望你能回答。我最终通过忽略回调中某些接口的简单方法让它工作,但我想我将使用你提到的数据绕过方法。并不是说我在计算 CPU 周期,但它似乎是一个更优雅的解决方案。再次感谢。
    猜你喜欢
    • 2022-11-27
    • 2022-06-11
    • 2013-08-07
    • 2014-10-27
    • 2015-09-30
    • 2021-12-01
    • 2019-11-24
    • 2020-02-11
    • 2014-11-29
    相关资源
    最近更新 更多