NDIS LWF - FilterRestart 및 FilterPause
-
20-12-2019 - |
문제
저는 NDIS LWF 드라이버를 처음 사용하지만 Win7의 WFP가 내 요구 사항을 충족하지 않는다고 판단한 후 해당 드라이버로 이동해야 했습니다.따라서 이것은 너무 기본적인 질문이 아니기를 바랍니다.
내 요구 사항은 기본적으로 다중 NIC 시스템에서 선택한 NIC를 무차별적으로 수신할 수 있어야 한다는 것입니다.인터페이스를 무차별 모드로 설정하기 위해 LWF 샘플을 수정했지만 이제 지정된 어댑터를 설정하는 방법에 대해 고민하고 있습니다.LWF는 모든 어댑터 위에 위치하므로 NdisOpenAdapterEx를 호출할 수 있는 프로토콜과는 다르지만 특정 어댑터를 무시하려면 필터링 메커니즘이 있어야 한다고 가정합니다.
내가 관심 있는 인터페이스의 선택된 MAC 주소를 드라이버에 IOCTL할 수 있어야 합니다.드라이버를 로드할 수 있지만 특정 인터페이스에서만 필터를 실행하도록 할 수 있습니까? 아니면 FilterReceiveNetBufferLists에서 신경 쓰지 않는 다른 호출을 무시하면 됩니다.특정 인터페이스에 대해 아무것도 하지 않을 경우 FilterReceiveNetBufferLists 콜백을 갖지 않는 것이 더 효율적일 것 같습니다.
나를 당황하게 만드는 것은 DriverEntry 중에 (NdisFRegisterFilterDriver를 통해) FilterRestart가 자동으로 호출되고 NdisFPauseFilter가 없는 것 같습니다(그러나 NdisFRestartFilter는 있음)는 사실입니다.이상적으로는 필터링이 시작되기 전에 필요한 매개변수를 설정할 수 있고 필요에 따라 동적으로 재작업할 수 있는 기능이 여전히 필요하기 때문에 DriverEntry 중에 레지스트리를 사용하지 않고 싶습니다.
마지막으로 NDIS 내부를 더 잘 이해하기 위해 필터 모듈이 일시 중지되면 전체 스택이 일시 중지됩니까, 아니면 NDIS가 일시 중지된 모듈 주위로 라우팅됩니까?
해결책
이것은 좋은 질문입니다.
드라이버를 로드할 수 있지만 필터는 특정 인터페이스에서만 실행될 수 있습니까?
예.여기에는 세 가지 옵션이 있습니다.
- 사용자 모드에서 바인딩을 정적으로 비활성화합니다.또는
- 런타임 시 바인딩을 거부합니다.
- 데이터 경로를 동적으로 우회하고 다시 활성화합니다..(이미 MSDN에 설명되어 있으므로 여기서는 자세히 설명하지 않습니다.)
바인딩을 정적으로 비활성화하려면 다음을 사용합니다. 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
매니저.이는 귀하의 필터가 NIC에 부착될 수 없거나 부착되지 않을 것임을 NDIS에게 확신시키기에 충분합니다.하지만 — 필터가 다음과 같이 표시된 경우 필수적인 (즉, INF의 FilterRunType은 1입니다.) FilterAttach
NIC가 작동하지 않게 됩니다.(결국 그렇죠. 요점 의무적이라는 것.필터가 없으면 데이터 경로가 해서는 안 된다 실행.) 그러나 NIC가 어쨌든 실행을 시작하도록 허용하려면 NDIS_FILTER_ATTACH_FLAGS_IGNORE_MANDATORY
당신의 깃발 NDIS_FILTER_ATTACH_PARAMETERS::Flags
필터가 실패 코드를 반환하기 직전의 필드 FilterAttach
.
특정 인터페이스에 대해 아무것도 하지 않을 경우 FilterReceiveNetBufferLists 콜백을 갖지 않는 것이 더 효율적일 것 같습니다.
당신의 직감이 정확합니다.데이터 경로에 필터를 두는 데에는 오버헤드가 있으며, 필터가 아무 작업도 수행하지 않으면 CPU 주기가 낭비됩니다.하지만 아직 이 옵션을 삭제하지 마세요.어떤 경우에는 이 옵션의 단순성이 (상대적으로 작은) CPU 비용보다 더 큽니다.즉, 목표 시장이 모든 CPU 주기를 계산하지 않는 한 이 간단한 옵션을 사용하는 것으로 충분할 수 있습니다.
필요에 따라 동적으로 작업을 다시 수행하는 기능이 여전히 필요하기 때문에 DriverEntry 중에 레지스트리를 사용하지 않고 싶습니다.
위에서 언급했듯이 당신은 ~할 수 있다 사용자 모드 코드로 다시 작업하십시오.사용자 모드가 INetCfg::Apply를 호출할 때마다 NDIS는 FilterAttach
또는 FilterDetach
올바른 변화를 일으키기 위해 필요합니다.
두 번째 기술을 사용할 때는 실제로 재작업이 불가능합니다.특정 NIC의 작업을 다시 수행해야 하는 경우 첫 번째 또는 세 번째 기술을 사용해야 합니다.
필터 모듈이 일시 중지되면 전체 스택이 일시 중지됩니까, 아니면 NDIS가 일시 중지된 모듈을 중심으로 라우팅됩니까?
전체 스택이 일시 중지되었습니다.NDIS는 필터를 "라우팅"하지 않습니다.(필터가 선택사항인 경우 필터가 실행되지 않을 때 트래픽이 필터를 우회합니다.그러나 필터가 NIC에 연결되어 있는 한 NBL 및 OID는 필터를 통과합니다.)