Red de conocimiento informático - Material del sitio web - Cómo utilizar el marco de filtro NDIS en el trabajo de desarrollo de controladores de Windows

Cómo utilizar el marco de filtro NDIS en el trabajo de desarrollo de controladores de Windows

Filtro NDIS NET_BUFFER_LIST NET_BUFFER MDL

1

La estructura de datos de la red es la siguiente:

2

Puede seguir mis métodos de implementación de los siguientes dos códigos de programa para obtener el contenido del paquete de datos. Puede agregar el código directamente al código de su proyecto de filtro NDIS.

3

Entorno de compilación de código: Visual?Studio?2013WDK8.1 Los sistemas Windows que pasaron la prueba son: Windows de 32 bits Windows de 764 bits Windows de 732 bits Windows de 864 bits Windows de 832 bits Windows8.Windows8.1WindowsXP de 164 bits, no es compatible con el marco de filtro NDIS.

4

El primer método:

5

El segundo método:

/** ** ************************************************* * **************?La función de la función GetNetBufferData:?Obtener datos de 1 NET_BUFFER. ¿1 NET_BUFFER contiene uno o más MDL?***************************************** ** **************************/VOID?GetNetBufferData(?PNET_BUFFERNetBuffer,?PUCHAR?OutputBuffer,?ULONG?OutputBufferSize,?PULONG ?OutputBytesCopied ?){?PMDL?Mdl?=?NetBuffer->CurrentMdl;?*OutputBytesCopied?=?0;?if?(NetBuffer->DataLength?>?OutputBufferSize)?{#if?DBGDbgPrint("¿No?¿suficiente? salida? buffer?space,?in:?%d,?out?:?%d\n",NetBuffer->DataLength,OutputBufferSize);#endifreturn;?}?NdisMoveMemory(OutputBuffer,(PUCHAR)MmGetSystemAddressForMdlSafe(Mdl,? LowPagePriority) ?+?NetBuffer->CurrentMdlOffset,Mdl->ByteCount?-?NetBuffer->CurrentMdlOffset);OutputBuffer?+=?Mdl->ByteCount?-?NetBuffer->CurrentMdlOffset;?*OutputBytesCopied?+=?Mdl->ByteCount? -?NetBuffer->CurrentMdlOffset;?//?//Recorra la lista vinculada MDL para obtener los datos de cada nodo. Los datos se guardan en OutputBuffer // El espacio de OutputBuffer continúa expandiéndose.

?//Cuando la lista vinculada no está vacía y la longitud de OutputBuffer Next)!=NULL)?&&?(*OutputBytesCopied ?DataLength)?)?{NdisMoveMemory(OutputBuffer,?MmGetSystemAddressForMdlSafe(Mdl,?LowPagePriority),?Mdl->ByteCount);OutputBuffer?+=?Mdl->ByteCount;?//¿Los datos se guardan en? *OutputBytesCopied?+=?Mdl->ByteCount;//¿El espacio de OutputBuffer continúa expandiéndose?}?if?(Mdl?!=?NULL)?{NdisMoveMemory(OutputBuffer,?MmGetSystemAddressForMdlSafe(Mdl,?LowPagePriority),? NetBuffer ->DataLength);OutputBuffer?+=?Mdl->ByteCount;*OutputBytesCopied?+=?Mdl->ByteCount;?}#if?DBG?DbgPrint("búfer?copiado:?%d?bytes\n", ? *OutputBytesCopied);#endif}

6

Los dos métodos anteriores solo obtienen datos. Los códigos predeterminados originales para estas cuatro funciones proporcionados por el marco de filtro NDIS no realizan ninguna operación y no tienen funciones sustanciales. No necesitamos los códigos predeterminados originales para estas cuatro funciones porque nuestro controlador necesita procesarlos. Estas cuatro funciones son: FilterSendNetBufferListsCompleteFilterSendNetBufferListsFilterReturnNetBufferListsFilterReceiveNetBufferLists

7

En nuestro proyecto NDIS?Filter, necesitamos modificar las funciones de estas cuatro funciones y reemplazarlas con la función que queremos. Por ejemplo, cuando envía o recibe paquetes de datos, debe implementar parte de su propia lógica empresarial en lugar de utilizar las funciones de código originales proporcionadas por Microsoft NDIS Filter.

8

La función FilterSendNetBufferListsComplete: NDIS llama a FilterSendNetBufferListsComplete para devolver la estructura y los datos enviados a FilterDriver. NDIS puede recopilar las estructuras y los datos enviados por NdisFSendNetBufferLists varias veces para formar una lista enlazada individualmente y pasarla a FilterSendNetBufferListsComplete. El estado actual de una solicitud de envío siempre se desconoce a menos que NDIS llame a FilterSendNetBufferListsComplete. Un controlador de filtro no puede verificar NET_BUFFER_LIST y sus datos asociados antes de llamar a FilterSendNetBufferListsComplete en NDIS para devolver la estructura. FilterSendNetBufferListsComplete completa cualquier procesamiento posterior necesario después de que se completa una solicitud de envío.

Cuando NDIS llama a FilterSendNetBufferListsComplete, Filter Driver recupera la propiedad de la estructura y los recursos relacionados con la estructura. Puede liberar recursos relacionados y prepararse para la próxima llamada de NdisFSendNetBufferLists en ?FilterSendNetBufferListsComplete. ?NDIS siempre se pasa al controlador inferior en el orden en que el controlador de filtro llama a NdisFSendNetBufferLists y lo envía, pero el orden en que se devuelve FilterSendNetBufferListsComplete es arbitrario. Filter?Driver puede solicitar una solicitud de envío de bucle invertido, simplemente configure SendFlags de NdisFSendNetBufferLists en NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK. NDIS generará una indicación de recepción de paquete que contiene los datos que se enviarán.

9

Un controlador de filtro debe realizar un seguimiento de las solicitudes de envío que inicia y garantizar que no se llame a la rutina NdisFSendNetBufferComplete al finalizar.

Paso de lectura

10

Función de la función FilterSendNetBufferLists: NDIS llama a una rutina FilterSendNetBufferLists de Filter?Driver para filtrar la solicitud de envío del controlador superior. Filter?Driver no puede cambiar el valor del miembro SourceHandle en la estructura NET_BUFFER_LIST pasada por otros controladores. Puede filtrar datos y enviar los datos filtrados al controlador inferior.

11

Para cada NDIS_BUFFER_LIST enviado a FilterSendNetBufferLists, podemos realizar las siguientes operaciones:

1) ¿El búfer se puede pasar al controlador inferior, NDIS? asegura la validez del espacio de contexto para FilterDriver. El controlador de filtro puede modificar el contenido del búfer antes de enviarlo. Puede manejar este búfer como un búfer que provocó una solicitud de envío usted mismo. ?2) Puede llamar a ?NdisFSendNetBufferListsComplete? para negarse a entregar este paquete. 3) Poner en cola el contenido del búfer en el local para su posterior procesamiento. Por ejemplo, debe procesarse después de un cierto tiempo de espera o después de recibir un paquete específico. Si se admite este método de procesamiento, se debe admitir la operación de cancelar la solicitud. 4) El búfer se puede copiar e iniciar una solicitud de envío. Es similar a activar una solicitud de envío por sí solo, pero primero debe llamar a ?NdisFSendNetBufferComplete para devolver el búfer del controlador superior.

12

La solicitud de envío continúa completándose en la pila del controlador. Cuando un controlador de minipuerto llama a NdisMSendNetBufferListsComplete para completar una solicitud de envío, NDIS llamará al minipuerto.

>13

Después de completar una operación de envío, Filter?Driver puede hacer lo contrario de todas las modificaciones en FilterSendNetBufferLists. FilterSendNetBufferListsComplete devuelve una lista enlazada individualmente de la estructura NET_BUFFER_LIST y envía el estado final de la solicitud al controlador superior. Cuando se llama al FilterSendNetBufferListsComplete de nivel superior del FilterModule de nivel superior, NDIS llamará al ProtocolSendNetBufferListsComplete del controlador de protocolo que provocó el envío de la solicitud.

Si Filter?Driver no proporciona FilterSendNetBufferLists, aún puede desencadenar una operación de envío, pero debe proporcionar FilterSendNetBufferListsComplete y no puede pasar este evento al controlador superior en esta rutina.

14

Un Filter?Driver puede pasar o filtrar una solicitud de loopback desde un controlador de capa superior. Para pasar una solicitud de loopback, NDIS establecerá el parámetro SendFlags de FilterSendNetBufferLists en NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK. ¿Filtro? El controlador está en Simplemente pase esta etiqueta a NdisFSendNetBufferLists cuando lo llame. En el caso de una solicitud de loopback, NDIS indicará un paquete de recepción que contiene los datos enviados.

15

Si algún comportamiento modificado por un Filter?Driver no es un servicio estándar proporcionado por NDIS, entonces debería proporcionar el servicio correspondiente para el propio NDIS. Por ejemplo, si un controlador de filtro modifica una solicitud de dirección de hardware, debe manejar paquetes de bucle invertido dirigidos a la nueva dirección. En este caso, NDIS no puede proporcionar un servicio de bucle invertido porque el controlador del filtro ha cambiado su dirección.

16

_Use_decl_annotations_VOIDFilterSendNetBufferLists(?NDIS_HANDLE?FilterModuleContext,?PNET_BUFFER_LISTNetBufferLists,?NDIS_PORT_NUMBERPortNumber,?ULONGSendFlags?){?PMS_FILTER?pFilter?=?(PMS_FILTER)FilterModuleCon text;?PNET_ ¿BÚFER? NetBuffer ; ?UCHARTempBuffer[MAX_BUFFER_SIZE];?ULONGBytesCopied;?pEthHdrEthernetHeader;?pIPHdrIpHeader;#if?DBG?DbgPrint(">>>?FilterSendNetBufferLists:?%p\n",?NetBufferLists);#endif?for?(NetBuffer?= ? NetBufferLists->FirstNetBuffer;NetBuffer!=?NULL;NetBuffer?=?NetBuffer->Siguiente)?{GetNetBufferData(NetBuffer,?TempBuffer,?MAX_BUFFER_SIZE,?&BytesCopied);if?(BytesCopied?==?0){#if ? DBG?DbgPrint("Net?buffer?catch?error\n");#endif}else{?EthernetHeader?=?TempBuffer;?if?(EthernetHeader->Type?==?0x0800)//¿Tipo de Ethernet?{ IpHeader?=?EthernetHeader?+?sizeof(EthHdr);?//Elimine el encabezado Ethernet y tome el encabezado IP #if?DBGDbgPrint("Get?ip?packet\n");#endif?}}?}?NdisFSendNetBufferLists (pFilter->FilterHandle,?NetBufferLists,?PortNumber,?SendFlags);}

17

La función de la función FilterReturnNetBufferLists: si Filter?Driver establece el estado de NdisFIndicateReceiveNetBufferLists en NDIS_STATUS_SUCCESS, NDIS devuelve los datos indicados a través de FilterReturnNetBufferLists del controlador. En este caso, FilterDriver pierde la propiedad de NET_BUFFER_LIST hasta que se llama a FilterReturnNetBufferLists. ¿El controlador Filter? llama a NdisFIndicateNetBufferLists? para pasar las instrucciones de recepción al controlador superior en la pila de controladores. Si el controlador superior conserva la propiedad del búfer (NET_BUFFER_LIST), ¿NDIS llamará a la rutina Filter?ReturnNetBufferLists? ?Las operaciones en la ruta de recepción (como algunos procesamientos realizados en ?FilterReciveNetBufferLists) deben deshacerse en FilterReturnNetBufferLists. Cuando el módulo Filter?Module de nivel más bajo completa el procesamiento del búfer (NET_BUFFER_LIST), NDIS devuelve el búfer al controlador de minipuerto.

Si ReceiverFlags de FilterReceiveNetBufferLists no establece la marca NDIS_RECEIVE_FLAGS_RESOURCES, FilterDriver llama a NdisFReturnNetBufferList para devolver los datos del búfer. Si FilterReceiveNetBufferLists está configurado y regresa directamente, el búfer se devuelve al controlador de minipuerto inferior.

Lectura de pasos

18

La función de la función FilterReceiveNetBufferLists: Filter?Driver llama a ?NdisFIndicateReceiveNetBufferLists para indicar el envío de datos. Esta función indica datos al controlador de capa superior a través de la estructura NET_BUFFER_LIST. ¿Filtro? El controlador puede asignar esta estructura desde el grupo. Si Filter Driver establece el estado de NdisFIndicateReceiveNetBufferLists en NDIS_STATUS_SUCCESS, NDIS devuelve datos de indicación a través de FilterReturnNetBufferLists del controlador. En este caso, Filter?Driver pierde la propiedad de NET_BUFFER_LIST hasta que se llama a FilterReturnNetBufferLists. Si Filter?Driver establece ReceiverFlags en NDIS_RECEIVE_FLAGS_RESOURCES al llamar a NdisFIndicateReceiveNetBufferLists, Filter?Driver restaurará inmediatamente la propiedad de NET_BUFFER_LIST después de que la función regrese. En este momento, Filter?Driver debe procesar inmediatamente la devolución de este NET_BUFFER_LIST, porque NDIS no se llamará a FilterReturnNetBufferLists. para devolver la estructura NET_BUFFER_LIST. Nota: Un FilterDriver debe realizar un seguimiento de las instrucciones de recepción que genera para garantizar que no llame a NdisFReturnNetBufferLists en FilterReturnNetBufferLists.

19

_Use_decl_annotations_VOIDFilterReceiveNetBufferLists(?NDIS_HANDLE?FilterModuleContext,?PNET_BUFFER_LISTNetBufferLists,?NDIS_PORT_NUMBERPortNumber,?ULONGNumberOfNetBufferLists,?ULONGReceiveFlags?){?PMS_FILTER?pFilter?=?(PMS_ FILTRO)FilterModuleContext;? PNET_BUFFER ?NetBuffer;?UCHARTempBuffer[MAX_BUFFER_SIZE];?ULONGBytesCopied;?pEthHdrEthernetHeader;?pIPHdrIpHeader;#if?DBG?DbgPrint(">>>?FilterReceiveNetBufferLists:?%p\n",?NetBufferLists,?ReceiveFlags,?NumberOfNetBufferLists ); # endif?do?{for?(NetBuffer?=?NetBufferLists->FirstNetBuffer;?NetBuffer?=?NULL;?NetBuffer?=?NetBuffer->Next){?GetNetBufferData(NetBuffer,?TempBuffer,?MAX_BUFFER_SIZE,?&BytesCopied) ;?if?(BytesCopied?==?0)?{#if?DBGDbgPrint("Net?buffer?catch?error\n");#endif?}?else?{EthernetHeader?=?TempBuffer;if?(EthernetHeader ->Tipo?==?0x0800){?IpHeader?=?EthernetHeader?+?sizeof(EthHdr);#if?DBG?DbgPrint("IP?packet?exist\n");#endif}?}}?} ? while?(FALSE);

20

Llame a ?NdisFIndicateReceiveNetBufferLists para indicar el envío de datos. ?Si Filter?Driver establece el estado de NdisFIndicateReceiveNetBufferLists en NDIS_STATUS_SUCCESS, ?NDIS devuelve los datos de indicación a través de FilterReturnNetBufferLists? del controlador. Si Filter Driver establece el valor de ReceiverFlags de NdisFIndicateReceiveNetBufferLists en NDIS_RECEIVE_FLAGS_RESOURCES, Filter Driver restaurará inmediatamente la propiedad de NET_BUFFER_LIST después de que regrese la función. En este momento, Filter Driver debe procesar inmediatamente la devolución de este NET_BUFFER_LIST. En este caso, no se llamará a FilterReturnNetBufferLists para devolver la estructura NET_BUFFER_LIST.