Я создаю драйвер сетевого фильтра NDIS, но когда я его устанавливаю, я вижу вызов "FilterAttach" 4 раза.
Почему "FilterAttach" вызывается 4 раза в моем драйвере фильтра?
Вызывает FilterAttach в драйвере фильтра
Ответы (1)
Есть 3 причины, по которым вы увидите много вызовов FilterAttach
в своем драйвере:
- несколько сетевых карт,
- мониторинг фильтров и
- Пересчет привязки NDIS
Давайте рассмотрим каждый подробно.
Несколько сетевых карт
Драйверы фильтра привяжут модуль фильтра к каждой сетевой карте, совместимой с драйвером фильтра. Таким образом, если у вас есть 3 совместимых сетевых адаптера, вы получите как минимум три вызова FilterAttach
.
[TCPIP] [TCPIP] [TCPIP]
| | |
[filter1] [filter2] [filter3]
| | |
[NIC1] [NIC2] [NIC3]
Вы можете сказать, что находитесь в этой ситуации, потому что значение NDIS_FILTER_ATTACH_PARAMETERS::BaseMiniportIfIndex
отличается в разных экземплярах FilterAttach
. Это означает, что ваш фильтр привязан к разным сетевым адаптерам.
Фильтры мониторинга
NDIS LWF выполняет либо мониторинг, либо модификацию. Посмотрите в INF-файле, какой тип фильтра у вас есть:
; For a Monitoring filter, use this:
; HKR, Ndi,FilterType,0x00010001, 1 ; Monitoring filter
; For a Modifying filter, use this:
; HKR, Ndi,FilterType,0x00010001, 2 ; Modifying filter
Разница между мониторингом и модификацией заключается в том, как эти фильтры привязываются к сетевой карте. Модифицирующий фильтр самый простой: он просто привязывается один раз к каждой сетевой карте. Напротив, фильтры мониторинга будут привязаны один раз каждый другой фильтр, изменяющий фильтр, и еще один раз для самой сетевой карты. Вот диаграмма того, что происходит, когда у вас есть фильтр мониторинга и 2 изменяющих фильтра:
[TCPIP]
|
[monitoring1] // 3
|
[modifying2]
|
[monitoring1] // 2
|
[modifying1]
|
[monitoring1] // 1
|
[NIC]
Главное, что следует отметить на этой диаграмме, это то, что один и тот же фильтр мониторинга присоединен к стеку 3 раза: один раз над сетевой картой и один раз над каждым из двух модифицирующих фильтров (modifying1
и modifying2
).
Если вы не хотите, чтобы ваш фильтр мониторинга привязывался к каждой высоте таким образом, вы можете возвращать NDIS_STATUS_NOT_SUPPORTED
из обработчика FilterAttach
в любое время, когда NDIS_FILTER_ATTACH_PARAMETERS::LowerIfIndex
отличается от NDIS_FILTER_ATTACH_PARAMETERS::BaseMiniportIfIndex
. Если у вас есть обязательный фильтр, вы также должны установить флаг NDIS_FILTER_ATTACH_FLAGS_IGNORE_MANDATORY
в NDIS_FILTER_ATTACH_PARAMETERS::Flags
, но учтите, что мы не рекомендуем отмечать фильтр мониторинга как обязательный.
Вы можете сказать, что находитесь в этой ситуации, если NDIS_FILTER_ATTACH_PARAMETERS::BaseMiniportIfIndex
одинакова в обоих вызовах FilterAttach
, но NDIS_FILTER_ATTACH_PARAMETERS::FilterModuleGuidNameis different. The
BaseMiniportIfIndextells you which miniport your filter is over, and the
FilterModuleGuidName` точно сообщает, какой экземпляр фильтра подключен.
Пересчет привязки NDIS
Последняя причина, по которой фильтр может видеть несколько вызовов своей подпрограммы FilterAttach
, заключается в том, что NDIS иногда пересчитывает привязки. Возможно, под вашим фильтром устанавливается новый фильтр. NDIS отключит ваш фильтр (FilterDetach
), привяжет новый фильтр, а затем снова привяжет ваш фильтр (FilterAttach
).
Вы можете сказать, что NDIS повторно пытается использовать ваш фильтр из-за пересчета привязки, потому что NDIS_FILTER_ATTACH_PARAMETERS::FilterModuleGuidName
совпадает с предыдущим вызовом FilterAttach
. Это означает, что NDIS прикрепляет ваш фильтр в том же месте, что и раньше.
Советы по отладке
Если у вас подключен отладчик ядра, вы всегда можете использовать !ndiskd.filterdriver
, чтобы увидеть, где подключен ваш фильтр. Вы также можете использовать !ndiskd.netreport
для просмотра графической визуализации сетевого стека.