El filtro de paquetes de Android (APF) permite que el framework controle la lógica de filtrado de paquetes de hardware en el tiempo de ejecución. Esto permite que el sistema ahorre energía descartando paquetes en el hardware, a la vez que permite que el framework de Android cambie las reglas de filtrado en el tiempo de ejecución según las condiciones de la red.
Descripción general de APF
El APF consta de dos componentes principales:
- El intérprete de APF se ejecuta en el hardware de redes (por lo general, el chipset de Wi-Fi). El intérprete de APF ejecuta el bytecode de APF en los paquetes que recibe el hardware y decide si aceptarlos, descartarlos o responderlos.
- El código de generación del programa de APF se ejecuta en la CPU principal. El código crea y actualiza programas de APF según el estado de la red y del dispositivo.
Los métodos de HAL de Wi-Fi permiten que el framework de Android instale el bytecode del programa APF y lea los contadores actuales. El módulo de la línea principal de la pila de red puede actualizar el bytecode del programa APF en cualquier momento mientras se ejecuta APF.
Se implementaron varios filtros de APF. Por ejemplo, APF incluye filtros para descartar tipos de Ethernet no permitidos, filtrar paquetes de anuncio de router (RA) de IPv6, filtrar tráfico de multidifusión y difusión si no se mantiene el bloqueo de multidifusión, descartar paquetes de DHCP para otros hosts y descartar paquetes no solicitados del protocolo de resolución de direcciones (ARP) y del protocolo de detección de vecinos (ND). Si el firmware admite APFv6, ApfFilter
también genera reglas para responder a tipos de paquetes comunes que, de lo contrario, requerirían que la CPU se activara para responder, como las consultas ARP y las consultas NS. La lista completa de filtros se define en ApfFilter
.
Dado que el código de generación del programa de APF forma parte del módulo de la pila de red, puedes usar las actualizaciones de Mainline mensuales para agregar filtros nuevos y actualizar la lógica de filtrado.
Revisión del APF
En la siguiente lista, se describe el historial de revisiones de APF:
- APFv6: Esta versión, que se introdujo en Android 15, admite el filtrado de paquetes, incluye contadores para la depuración y las métricas, y admite la transmisión de paquetes.
- APFv4: Esta versión, que se introdujo en Android 10, admite el filtrado de paquetes y contiene contadores para la depuración y las métricas.
- APFv2: Esta versión, que se introdujo en Android 7, admite el filtrado de paquetes.
Integración de APF
Las APIs de APF entre el intérprete de APF y el hardware se definen en apf_interpreter.h
(APFv4, APFv6).
El código de firmware de Wi-Fi llama a accept_packet()
en APFv4 o a apf_run()
en APFv6 para determinar si se debe descartar el paquete (valor de retorno cero) o pasarlo al procesador de la app (valor de retorno distinto de cero). Si se debe transmitir un paquete, apf_run()
también devuelve cero porque su paquete no necesita pasar al procesador de la app. Si el firmware admite APFv6, debe implementar las APIs de apf_allocate_buffer()
y apf_transmit_buffer()
. El intérprete de APF llama a estas dos APIs durante la lógica de transmisión de paquetes.
Las instrucciones de APF tienen una longitud variable. Cada instrucción tiene una longitud de al menos 1 byte. Los códigos de instrucciones de APF se definen en apf.h
para APFv4 y se insertan directamente en apf_interpreter.c
para APFv6.
El APF depende de la memoria dedicada. La memoria se usa tanto para el programa de APF como para el almacenamiento de datos, y el chipset no debe borrarla ni escribir en ella, excepto a través de los métodos de HAL de APF. El bytecode del APF usa el almacenamiento de datos para almacenar contadores de paquetes aceptados y descartados. La región de datos se puede leer desde el framework de Android. Las instrucciones de APF son eficientes en cuanto a la memoria, pero maximizar su potencial de ahorro de energía y funcionalidad requiere reglas de filtrado dinámicas y complejas. Esta complejidad requiere una parte dedicada de la memoria del chipset. El requisito mínimo de memoria para APFv4 es de 1,024 bytes, mientras que APFv6 requiere 2,048 bytes. Sin embargo, te recomendamos que asignes 4,096 bytes para APFv6 para garantizar un rendimiento óptimo. El intérprete de APF debe compilarse en el firmware. Ambos intérpretes de APFv4 y APFv6 están optimizados para el tamaño del código. En la arquitectura arm32, el intérprete de APFv4 compilado ocupa alrededor de 1.8 KB, mientras que el intérprete de APFv6, más complejo y con funciones adicionales (por ejemplo, compatibilidad nativa con sumas de verificación y código nativo de descompresión de DNS), ocupa aproximadamente 4 KB.
Los filtros de APF pueden funcionar junto con otros filtros específicos del proveedor del chipset dentro del firmware. Los proveedores de chipsets pueden optar por ejecutar su lógica de filtrado antes o después del proceso de filtrado del APF. Si se descarta un paquete antes de llegar al filtro de APF, este no lo procesa.
Para garantizar el correcto funcionamiento del filtro de APF, cuando se activa el APF, el firmware debe proporcionar al filtro de APF acceso a todo el paquete, no solo al encabezado.
Ejemplos de programas de APF
ApfTest
y ApfFilterTest
contienen programas de prueba de muestra que ilustran cómo funciona cada filtro de APF. Para estudiar el programa generado real, modifica el caso de prueba para imprimir el programa como una cadena hexadecimal.
La carpeta testdata
contiene programas de APFv4 de ejemplo para los filtros de RA de APF. La carpeta samples
contiene utilidades de Python que generan programas de descarga de APFv6. Para obtener más detalles, consulta la documentación en los archivos de utilidad de Python.
Depura el APF
Para verificar si el APF está habilitado en el dispositivo, muestra el programa actual, los contadores actuales y ejecuta el comando adb shell dumpsys network_stack
. El siguiente es un ejemplo de este comando:
adb shell dumpsys network_stack
......
IpClient.wlan0 APF dump:
Capabilities: ApfCapabilities{version: 4, maxSize: 4096, format: 1}
......
Last program:
6bfcb03a01b8120c6b9494026506006b907c025e88a27c025988a47c025488b87c024f88cd7c024a88e17c024588e384004408066a0e6bdca4022b000600010800060412147a1e016bd884021f00021a1c6b8c7c021c0000686bd4a402080006ffffffffffff6a266bbca402010004c0a801eb6bf87401f6120c84005f08000a17821f1112149c00181fffab0d2a108211446a3239a20506c2fc393057dd6bf47401cb0a1e52f06bac7c01c600e06bb41a1e7e000001b9ffffffff6bb07e000001aec0a801ff6be868a4019a0006ffffffffffff6bb874019b6bf07401907c001386dd686bd0a4017d0006ffffffffffff6bc874017e0a147a0e3a6b980a267c017000ff6be07401650a366ba87c016200858219886a26a2050fff02000000000000000000000000006ba4740146aa0e84013700e6aa0f8c0130006068a4011b000f33330000000184c9b26aed4c86dd606a12a2f02600b03afffe8000000000000086c9b2fffe6aed4cff02000000000000000000000000000186006a3aa2e9024000123c92e4606a3ea2d70800000000000000006a56a2ce04030440c01a5a92c9601a5e92c4606a62a2bb04000000006a66a2a6102401fa00049c048400000000000000006a76a29d04030440c01a7a9298601a7e9293606c0082a28904000000006c0086a27310fdfd9ed67950000400000000000000006c0096a2690418033c001a9a9264606c009ea24e102401fa00049c048000000000000000006c00aea24404180330001ab2923f606c00b6a22910fdfd9ed67950000000000000000000006c00c6a21f04190300001aca921a606c00cea20410fdfd9ed67950000400000000000000016bc472086be4b03a01b87206b03a01b87201
APF packet counters:
TOTAL_PACKETS: 469
PASSED_DHCP: 4
PASSED_IPV4: 65
PASSED_IPV6_NON_ICMP: 64
PASSED_IPV4_UNICAST: 64
PASSED_IPV6_ICMP: 223
PASSED_IPV6_UNICAST_NON_ICMP: 6
PASSED_ARP_UNICAST_REPLY: 4
PASSED_NON_IP_UNICAST: 1
DROPPED_RA: 4
DROPPED_IPV4_BROADCAST_ADDR: 7
DROPPED_IPV4_BROADCAST_NET: 27
El resultado de este comando adb shell dumpsys network_stack
de ejemplo incluye lo siguiente:
ApfCapabilities{version: 4, maxSize: 4096, format: 1}
: Esto significa que los chips Wi-Fi admiten APF (versión 4).Last program
: Esta sección es el último programa binario de APF instalado en formato de cadena hexadecimal.APF packet counters
: En esta sección, se muestra cuántos paquetes se pasan o descartan con APF y los motivos específicos.
Para decodificar y desensamblar el código en un lenguaje ensamblador legible, usa la herramienta apf_disassembler
. Para compilar el objeto binario ejecutable, ejecuta el comando m apf_disassembler
.
A continuación, se muestra un ejemplo de cómo usar la herramienta apf_disassembler
:
echo "6bfcb03a01b8120c6b949401e906006b907c01e288a27c01dd88a47c01d888b87c01d388cd7c01ce88e17c01c988e384004008066a0e6bdca401af000600010800060412147a1e016bd88401a300021a1c6b8c7c01a00000686bd4a4018c0006ffffffffffff1a266bc07c018900006bf874017e120c84005408000a17821f1112149c00181fffab0d2a108211446a3239a205065a56483ac3146bf47401530a1e52f06bac7c014e00e06bb41a1e7e00000141ffffffff6be868a4012d0006ffffffffffff6bb874012e6bf07401237c001386dd686bd0a401100006ffffffffffff6bc87401110a147a0d3a6b980a267c010300ff6be072f90a366ba87af8858218886a26a2040fff02000000000000000000000000006ba472ddaa0e82d0aeaa0f8c00c9025868a2b60f5a56483ac3140c8126f3895186dd606a12a28b2600783afffe8000000000000002005efffe00026fff02000000000000000000000000000186006a3aa284024000123c94007d02586a3ea2700800000000000000006a56a26704190500001a5a94006002586a5ea23b2020014860486000000000000000006464200148604860000000000000000000646a7ea23204030440c01a8294002b02581a8694002402586c008aa21a04000000006c008ea204102a0079e10abcf60500000000000000006bc472086be4b03a01b87206b03a01b87201" | out/host/linux-x86/bin/apf_disassembler
0: li r1, -4
2: lddw r0, [r1+0]
3: add r0, 1
5: stdw r0, [r1+0]
6: ldh r0, [12]
8: li r1, -108
10: jlt r0, 0x600, 504
15: li r1, -112
17: jeq r0, 0x88a2, 504
22: jeq r0, 0x88a4, 504
27: jeq r0, 0x88b8, 504
32: jeq r0, 0x88cd, 504
37: jeq r0, 0x88e1, 504
42: jeq r0, 0x88e3, 504
47: jne r0, 0x806, 116
......
Para verificar los resultados de APF sin conexión, usa la herramienta apf_run
. Para compilar el objeto binario ejecutable, ejecuta el comando m apf_run
. La herramienta apf_run
admite los intérpretes de APFv4 y APFv6.
A continuación, se incluye el manual del comando apf_run
. De forma predeterminada, el comando apf_run
se ejecuta en el intérprete de APFv4. Si pasas el argumento --v6
a apf_run
, se ejecutará en el intérprete de APFv6. Todos los demás argumentos se pueden usar tanto para APFv4 como para APFv6.
apf_run --help
Usage: apf_run --program <program> --pcap <file>|--packet <packet> [--data <content>] [--age <number>] [--trace]
--program APF program, in hex.
--pcap Pcap file to run through program.
--packet Packet to run through program.
--data Data memory contents, in hex.
--age Age of program in seconds (default: 0).
--trace Enable APF interpreter debug tracing
--v6 Use APF v6
-c, --cnt Print the APF counters
-h, --help Show this message.
A continuación, se muestra un ejemplo para pasar un paquete al APF y verificar si se puede descartar o pasar.
Para proporcionar la presentación de la cadena binaria hexadecimal del paquete sin procesar, usa la opción --packet
. Para proporcionar la cadena binaria hexadecimal de la región de datos, que se usa para almacenar el contador de APF, usa --data option
. Dado que cada contador tiene 4 bytes de longitud, las regiones de datos deben ser lo suficientemente largas para garantizar que no se produzca un desbordamiento del búfer.
out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b9494010c06006b907c010588a27c010088a47c00fb88b87c00f688cd7c00f188e17c00ec88e384003908066a0e6bdca2d40600010800060412147a18016bd882ca021a1c6b8c7ac900686bd4a2b706ffffffffffff6a266bbca2b204c0a814656bf872a8120c84005808000a17821e1112149c00171fffab0d2a108210446a3239a204064651dbcc88ff6bf4727e0a1e52f06bac7a7be06bb41a1e7e0000006effffffff6bb07e00000063c0a814ff6be868a25106ffffffffffff6bb872536bf072497c001086dd686bd0a23806ffffffffffff6bc8723a0a147a0b3a6b980a267a2eff6be072240a366ba87a23858218886a26a2040fff02000000000000000000000000006ba472086be4b03a01b87206b03a01b87201 --packet 5ebcd79a8f0dc244efaab81408060001080006040002c244efaab814c0a8ca1e5ebcd79a8f0d --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Packet passed
Data: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000001
Para verificar los resultados de APF en comparación con el archivo pcap que tomó tcpdump, usa el comando apf_run
de la siguiente manera:
out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b989401df06006b947c01d888a27c01d388a47c01ce88b87c01c988cd7c01c488e17c01bf88e384004408066a0e6bdca401a5000600010800060412147a1e016bd884019900021a1c6b907c01960000686bd4a401820006ffffffffffff6a266bc0a4017b0004c0a82b056bf874017084005f08000a17821f1112149c00181fffab0d2a108211446a3239a20506fabe589435936bf47401470a1e52f06bb07c014200e06bb81a1e7e00000135ffffffff6bb47e0000012ac0a82bff6be868a401160006ffffffffffff6bbc7401176bf074010c7c001086dd686bd0a2fb06ffffffffffff6bcc72fd0a147a0b3a6b9c0a267af1ff6be072e70a366bac7ae6858218886a26a2040fff02000000000000000000000000006ba872cbaa0e82be8eaa0f8c00b7025868a2a40ffabe5894359352a9874d08aa86dd606a12a2792600583afffe80000000000000f7d4e8ccd81ddb43fe80000000000000f8be58fffe94359386006a3aa272024108123c94006b02586a3ea25e0800000000000000006a56a25504030440c01a5a94004e02581a5e94004702586a62a23e04000000006a66a229102409891f9a26ae6d00000000000000006a76a22004190300001a7a94001902586a7ea204102409891f9a26ae6dba98e781ca9ef9ba6bc872086be4b03a01b87206b03a01b87201 --pcap apf.pcap --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
37 packets dropped
1733 packets passed
Data: 00000000000000000000000000000000000000000200000005000000000000000000000002000000000000001b000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000689000000000000003c00000000000000000000000000000000000006ea
Para probar las capacidades de transmisión de APFv6, usa el comando apf_run
de la siguiente manera:
$ apf_run --program 75001001020304050608060001080006040002AA300E3CAA0FBA06AA09BA07AA08BA086A01BA09120C84006F08066A0EA30206000108000604032B12147A27017A020203301A1C820200032D68A30206FFFFFFFFFFFF020E1A267E000000020A000001032C020B1A267E000000020A000001032CAB24003CCA0606CB0306CB090ACB0306C60A000001CA0606CA1C04AA 0A3A12AA1AAA25FFFF032F020D120C84001708000A1782100612149C00091FFFAB0D2A10820207032A02117C000E86DD68A30206FFFFFFFFFFFF021603190A1482020002187A023A02120A36820285031F8216886A26A2020FFF020000000000000000000000000003200214 --packet FFFFFFFFFFFF112233445566080600010800060400011122334455660A0000020000000000000A0000 01 --data 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 --age 0 --v6 --trace R0 R1 PC Instruction
------------------------------------------------- 0 0 0: data 16, 01020304050608060001080006040002 0 0 19: debugbuf size=3644 0 0 23: ldm r0, m[15] 0 0 25: stdw counter=6, r0 0 0 27: ldm r0, m[9] 0 0 29: stdw counter=7, r0 0 0 31: ldm r0, m[8] 134d811 0 33: stdw counter=8, r0 134d811 0 35: li r0, 1 1 0 37: stdw counter=9, r0 1 0 39: ldh r0, [12] 806 0 41: jne r0, 0x806, 157 806 0 46: li r0, 14 e 0 48: jbseq r0, 0x6, 59, 000108000604 e 0 59: ldh r0, [20] 1 0 61: jeq r0, 0x1, 103 1 0 103: ldw r0, [38] a000001 0 105: jeq r0, 0xa000001, 116 a000001 0 116: allocate 60 a000001 0 120: pktcopy src=6, len=6 a000001 0 123: datacopy src=3, len=6 a000001 0 126: datacopy src=9, len=10 a000001 0 129: datacopy src=3, len=6 a000001 0 132: write 0x0a000001 a000001 0 137: pktcopy src=6, len=6 a000001 0 140: pktcopy src=28, len=4 a000001 0 143: ldm r0, m[10] 2a 0 145: add r0, 18 3c 0 147: stm r0, m[10] 3c 0 149: transmit ip_ofs=255 3c 0 153: drop counter=47 Packet dropped Data: 00000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000100000011d8340100000000000000000000000000000000000000000100000078563412 transmitted packet: 112233445566010203040506080600010800060400020102030405060a0000011122334455660a000002000000000000000000000000000000000000
Cuando usas el parámetro --trace
, la herramienta apf_run
proporciona un resultado detallado de cada paso en la ejecución del intérprete, lo que resulta útil para la depuración. En este ejemplo, ingresamos un paquete de consulta ARP en el programa APF.
El resultado muestra que se descarta la consulta ARP, pero se genera un paquete de respuesta.
Los detalles de este paquete generado se muestran en la sección transmitted packet
.
Problemas comunes de integración
En esta sección, se destacan varios problemas comunes que se encuentran durante la integración de la APF:
- Borrado inesperado de la región de datos: La memoria de APF debe dedicarse por completo a APF; solo se permite que el código del intérprete o el código del framework (a través de la API de HAL) modifiquen la región de memoria de APF.
- Problemas de instalación con programas de APF de X bytes (X <=
maxLen
): El firmware debe admitir la lectura o escritura de cualquier longitud de programa hastamaxLen
sin fallas, bloqueos ni truncamientos. Las escrituras no deben alterar ningún byte entreX
ymaxLen
. - Implementación de APF en el código del controlador: El APF solo debe implementarse dentro del firmware, no en el código del controlador. De lo contrario, no habrá beneficios de ahorro de energía, ya que la CPU deberá activarse para procesar el paquete.
- Valores de
filter_age
ofilter_age_16384th
incorrectos: Los valores defilter_age
(APFv4) yfilter_age_16384th
(APFv6) deben pasarse correctamente a las funcionesaccept_packet()
yapf_run()
. Para obtener detalles sobre cómo calcularfilter_age_16384th
, consulta la documentación enapf_interpreter.h
. - El APF no está habilitado cuando es necesario: El APF debe estar habilitado cuando la pantalla está apagada y el vínculo de Wi-Fi está inactivo o el tráfico es inferior a 10 Mbps.
- Paquetes truncados que se pasan a
accept_packet()
oapf_run()
: Todos los paquetes de unidifusión, transmisión y multidifusión que se pasan aaccept_packet()
oapf_run()
deben estar completos. No es válido pasar paquetes truncados al APF.
Pruebas de APF
A partir de Android 15, Android proporciona casos de prueba del CTS para uno y varios dispositivos para la integración del filtro y el intérprete de APF, lo que garantiza la correcta funcionalidad del APF. A continuación, se incluye un desglose del propósito de cada caso de prueba:
ApfFilter
yapf_interpreter
prueba de integración: Verifica queApfFilter
genere bytecode correcto y queapf_interpreter
ejecute el código correctamente para producir los resultados esperados.- CTS de APF para un solo dispositivo: Usa un solo dispositivo para probar la funcionalidad de APF en el chipset de Wi-Fi.
Confirma lo siguiente:
- El APF se activa cuando la pantalla está apagada y el tráfico de Wi-Fi es inferior a 10 Mbps.
- Las capacidades de APF se declaran correctamente.
- Las operaciones de lectura y escritura en la región de memoria de APF se realizan correctamente, y la región de memoria no se modifica de forma inesperada.
- Los argumentos se pasan correctamente a
accept_packet()
oapf_run()
. - El firmware integrado con APFv4/APFv6 puede descartar paquetes.
- El firmware integrado con APFv6 puede responder a los paquetes.
- CTS de APF para varios dispositivos: Emplea dos dispositivos (uno emisor y otro receptor) para probar el comportamiento de filtrado del APF. En el lado del remitente, se generan varios tipos de paquetes, y la prueba confirma si se descartan, pasan o responden correctamente según las reglas configuradas en
ApfFilter
.
Instrucciones adicionales para la prueba de integración
Además, recomendamos que los proveedores de chipsets incorporen pruebas de APF en sus propios conjuntos de pruebas de integración de Wi-Fi de firmware.
Integrar las pruebas de APF en los conjuntos de pruebas de integración de Wi-Fi del firmware es fundamental para verificar la funcionalidad adecuada de APF en situaciones complejas de conexión Wi-Fi, como situaciones de conexión Wi-Fi de roaming o de make-before-break. En la siguiente sección, encontrarás instrucciones detalladas para realizar pruebas de integración.
Requisitos previos
Cuando realices pruebas de integración, haz lo siguiente:
- El APF debe estar habilitado en todos los casos de prueba de integración (por ejemplo, roaming, make-before-break).
- Al inicio de cada prueba, borra la memoria del APF.
- Instala o vuelve a instalar los programas de APF cada 5 minutos durante la prueba.
Situaciones de prueba
El APF debe estar activo durante las pruebas de integración. En este documento, se proporcionan dos programas de APF que se pueden instalar durante las pruebas. Los programas están en formato de cadena hexadecimal, y el verificador debe convertir la cadena hexadecimal en binaria e instalarla en el firmware para que apf_interpreter
pueda ejecutar los programas. Durante la prueba de integración, el verificador debe enviar paquetes que se espera que activen la lógica de filtrado en el programa 1 y el programa 2.
Programa de APF 1
Cuando la pantalla del dispositivo esté encendida, instala el programa 1 del APF. Este programa puede descartar paquetes inofensivos que no afectan la funcionalidad del dispositivo. Estos paquetes se usan para probar si el APF filtra correctamente el tráfico de red.
La lógica del programa 1 del APF es la siguiente:
- Soltar y aumentar el contador:
- Valores de EtherType:
0x88A2
,0x88A4
,0x88B8
,0x88CD
,0x88E1
,0x88E3
- Paquetes de detección o solicitud de DHCP IPv4
- Paquetes de RS
- Valores de EtherType:
- Pasa y aumenta el contador: Todos los demás paquetes.
Los códigos de 1 byte del programa de APF son los siguientes:
6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
Programa de APF 2
Cuando la pantalla del dispositivo esté apagada, instala el programa 2 de APF. Este programa filtra todos los paquetes que filtra el programa 1 del APF, así como los paquetes de solicitudes de ping. Para verificar que el programa 2 de APF esté instalado correctamente, envía paquetes de ping al dispositivo que se está probando.
La lógica del programa 2 del APF es la siguiente:
- Soltar y aumentar el contador:
- Valores de EtherType:
0x88A2
,0x88A4
,0x88B8
,0x88CD
,0x88E1
,0x88E3
- Paquetes de detección o solicitud de DHCP IPv4
- Paquetes de RS
- Valores de EtherType:
- Paquetes de solicitud de ping ICMP: Descartar y aumentar el contador
- Pasa y aumenta el contador: Todos los demás paquetes
Los códigos de 2 bytes del programa de APF son los siguientes:
6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C007488A27C006F88A47C006A88B87C006588CD7C006088E17C005B88E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE87234120C84000E86DD0A1482093A0A368204856BE0721F120C84001008000A17820B01AB0D220E8204086BE472086BDCB03A01B87206B03A01B87201
Verificación de datos
Para verificar que el programa de APF se ejecute y que los paquetes se pasen o descarten correctamente, haz lo siguiente:
- Recupera y verifica la región de datos de APF cada 5 minutos.
- No borres el contador.
- Genera paquetes de prueba para activar cada regla de filtro.
Verifica los incrementos del contador con las siguientes ubicaciones de memoria:
Nombre del contador Ubicación de la memoria DROPPED_ETHERTYPE_DENYLISTED
[ApfRamSize - 20, ApfRamSize - 16] DROPPED_DHCP_REQUEST_DISCOVERY
[ApfRamSize - 24, ApfRamSize - 20] DROPPED_ICMP4_ECHO_REQUEST
[ApfRamSize - 28, ApfRamSize - 24] DROPPED_RS
[ApfRamSize - 32, ApfRamSize - 28] PASSED_PACKET
[ApfRamSize - 36, ApfRamSize - 32]
Pseudocódigo para el programa 1 del APF y el programa 2 del APF
El siguiente pseudocódigo explica la lógica del programa 1 y el programa 2 del APF en detalle:
// ethertype filter
If the ethertype in [0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3]:
drop packet and increase counter: DROPPED_ETHERTYPE_DENYLISTED
// dhcp discover/request filter
if ethertype != ETH_P_IP:
skip the filter
if ipv4_src_addr != 0.0.0.0:
skip the filter
if ipv4_dst_addr != 255.255.255.255
skip the filter
if not UDP packet:
skip the filter
if UDP src port is not dhcp request port:
skip the filter
else:
drop the packet and increase the counter: DROPPED_DHCP_REQUEST_DISCOVERY
// Router Solicitation filter:
if ethertype != ETH_P_IPV6:
skip the filter
if not ICMP6 packet:
skip the filter
if ICMP6 type is not a Router Solicitation:
skip the filter
else:
drop the packet and increase the counter: DROPPED_RS
// IPv4 ping filter (only included in Program 2)
if ethertype != ETH_P_IP:
skip the filter
if it ipv4 protocol is not ICMP:
skip the filter
if port is not a ping request port
skip the filter
else:
drop the packet and increase the counter: DROPPED_ICMP4_ECHO_REQUEST
pass the packet and increase: PASSED_PACKET