O filtro de pacotes do Android (APF, na sigla em inglês) permite que o framework controle a lógica de filtragem de pacotes de hardware no tempo de execução. Isso permite que o sistema economize energia descartando pacotes no hardware, ao mesmo tempo em que permite que o framework Android mude as regras de filtragem no tempo de execução com base nas condições da rede.
Visão geral do APF
O APF consiste em dois componentes principais:
- O interpretador do APF é executado em hardware de rede (normalmente, o chipset Wi-Fi). O interpretador APF executa bytecode APF em pacotes recebidos pelo hardware e decide se os aceita, descarta ou responde.
- O código de geração do programa APF é executado na CPU principal. O código cria e atualiza programas APF de acordo com o estado da rede e do dispositivo.
Os métodos HAL do Wi-Fi permitem que a estrutura do Android instale o bytecode do programa APF e leia os contadores atuais. O módulo principal da pilha de rede pode atualizar o bytecode do programa APF a qualquer momento durante a execução do APF.
Há vários filtros de APF implementados. Por exemplo, o APF inclui filtros para
descartar ethertypes não permitidos, filtrar pacotes de anúncio de roteador (RA) IPv6,
filtrar tráfego multicast e broadcast se o bloqueio multicast não estiver ativo, descartar
pacotes DHCP para outros hosts e descartar pacotes de protocolo de resolução de endereços
(ARP) e descoberta de vizinhos (ND) não solicitados. Se o firmware for compatível com APFv6,
ApfFilter
também vai gerar regras para responder a tipos de pacotes comuns que, de outra forma,
exigiriam que a CPU fosse ativada para responder, como consultas ARP e NS
(em inglês). A lista completa de filtros está definida em
ApfFilter.
Como o código de geração do programa APF faz parte do módulo Network Stack, é possível usar as [atualizações da linha principal mensais para adicionar novos filtros e atualizar a lógica de filtragem.
Revisão do APF
A lista a seguir descreve o histórico de revisões do APF:
- APFv6:introduzida no Android 15, esta versão oferece suporte à filtragem de pacotes, inclui contadores para depuração e métricas e oferece suporte à transmissão de pacotes.
- APFv4:introduzida no Android 10, essa versão oferece suporte à filtragem de pacotes e inclui contadores para depuração e métricas.
- APFv2:introduzida no Android 7, essa versão é compatível com filtragem de pacotes.
Integração com o APF
As APIs APF entre o interpretador APF e o hardware são definidas em
apf_interpreter.h
(APFv4,
APFv6).
O código do firmware Wi-Fi chama
accept_packet()
no APFv4 ou
apf_run()
no APFv6 para determinar se o pacote deve ser descartado (valor de retorno zero) ou
transmitido ao processador de apps (valor de retorno diferente de zero). Se um pacote precisar
ser transmitido,
apf_run()
também vai retornar zero porque o pacote não precisa ser transmitido ao processador
do app. Se o firmware for compatível com APFv6, ele precisará implementar as APIs
apf_allocate_buffer()
e
apf_transmit_buffer(). O intérprete APF chama essas duas APIs durante a lógica de transmissão de pacotes.
As instruções do APF têm tamanho variável. Cada instrução tem pelo menos 1 byte de comprimento. Os códigos de instrução APF são definidos em
apf.h
para APFv4 e são inseridos diretamente em
apf_interpreter.c
para APFv6.
O APF depende de memória dedicada. Ela é usada para o próprio programa APF e para o armazenamento de dados, e não pode ser limpa ou gravada pelo chipset, exceto pelos métodos HAL do APF. O bytecode do APF usa o armazenamento de dados para armazenar contadores de pacotes aceitos e descartados. A região de dados pode ser lida do framework Android. As instruções APF são eficientes em termos de memória, mas para maximizar o potencial de economia de energia e funcionalidade, são necessárias regras de filtragem dinâmicas e complexas. Essa complexidade exige uma parte dedicada da memória no chipset. O requisito mínimo de memória para APFv4 é de 1.024 bytes, enquanto o APFv6 requer 2.048 bytes. No entanto, recomendamos alocar 4.096 bytes para o APFv6 e garantir um desempenho ideal. O intérprete do APF precisa ser compilado no firmware. Os intérpretes APFv4 e APFv6 são otimizados para o tamanho do código. Na arquitetura arm32, o intérprete APFv4 compilado tem cerca de 1,8 KB, enquanto o intérprete APFv6 mais complexo, com recursos adicionados (por exemplo, suporte nativo a checksum e código nativo de descompactação de DNS), tem aproximadamente 4 KB.
Os filtros do APF podem funcionar com outros filtros específicos do fornecedor do chipset no firmware. Os fornecedores de chipset podem executar a lógica de filtragem antes ou depois do processo de filtragem do APF. Se um pacote for descartado antes de chegar ao filtro APF, ele não será processado.
Para garantir a funcionalidade correta do filtro APF, quando o APF está ativado, o firmware precisa fornecer ao filtro APF acesso a todo o pacote, não apenas ao cabeçalho.
Exemplos de programas APF
ApfTest
e
ApfFilterTest
contêm programas de teste de amostra que ilustram como cada filtro da APF funciona. Para estudar o programa gerado, modifique o caso de teste para imprimir o programa como uma string hexadecimal.
A pasta
testdata
contém exemplos de programas APFv4 para filtros de RA do APF. A pasta
samples
contém utilitários Python que geram programas de descarregamento do APFv6. Para mais detalhes, consulte a documentação nos arquivos de utilitários do Python.
Depurar APF
Para verificar se o APF está ativado no dispositivo, mostre o programa atual, os contadores atuais e execute o comando adb shell dumpsys network_stack. Confira
a seguir um exemplo desse 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: 27A saída deste exemplo de comando adb shell dumpsys network_stack inclui
o seguinte:
ApfCapabilities{version: 4, maxSize: 4096, format: 1}: isso significa que os chips Wi-Fi são compatíveis com APF (versão 4).Last program: esta seção é o binário do programa APF instalado mais recente no formato de string hexadecimal.APF packet counters: esta seção mostra quantos pacotes são transmitidos ou descartados pelo APF e os motivos específicos.
Para decodificar e desmontar o código em linguagem de montagem legível por humanos, use a ferramenta
apf_disassembler. Para compilar o binário executável, execute o comando m apf_disassembler.
Confira um exemplo de como usar a ferramenta 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 os resultados do APF off-line, use a ferramenta
apf_run. Para compilar o binário executável, execute o comando m apf_run. A ferramenta
apf_run é compatível com intérpretes APFv4 e APFv6.
Este é o manual do comando apf_run. Por padrão, o comando apf_run
é executado no interpretador APFv4. Ao transmitir o argumento --v6 para apf_run, ele é executado no interpretador APFv6. Todos os outros argumentos podem ser usados para APFv4 e 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.Confira um exemplo para transmitir um pacote ao APF e verificar se ele pode ser descartado ou transmitido.
Para fornecer a apresentação da string binária hexadecimal do pacote bruto, use a opção --packet. Para fornecer a string binária hexadecimal da região de dados, que é
usada para armazenar o
contador de APF,
use --data option. Como cada contador tem 4 bytes, as regiões de dados precisam ser longas o suficiente para evitar estouro de buffer.
out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b9494010c06006b907c010588a27c010088a47c00fb88b87c00f688cd7c00f188e17c00ec88e384003908066a0e6bdca2d40600010800060412147a18016bd882ca021a1c6b8c7ac900686bd4a2b706ffffffffffff6a266bbca2b204c0a814656bf872a8120c84005808000a17821e1112149c00171fffab0d2a108210446a3239a204064651dbcc88ff6bf4727e0a1e52f06bac7a7be06bb41a1e7e0000006effffffff6bb07e00000063c0a814ff6be868a25106ffffffffffff6bb872536bf072497c001086dd686bd0a23806ffffffffffff6bc8723a0a147a0b3a6b980a267a2eff6be072240a366ba87a23858218886a26a2040fff02000000000000000000000000006ba472086be4b03a01b87206b03a01b87201 --packet 5ebcd79a8f0dc244efaab81408060001080006040002c244efaab814c0a8ca1e5ebcd79a8f0d --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Packet passed
Data: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000001Para verificar os resultados do APF em relação ao arquivo pcap coletado pelo tcpdump, use o comando apf_run da seguinte maneira:
out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b989401df06006b947c01d888a27c01d388a47c01ce88b87c01c988cd7c01c488e17c01bf88e384004408066a0e6bdca401a5000600010800060412147a1e016bd884019900021a1c6b907c01960000686bd4a401820006ffffffffffff6a266bc0a4017b0004c0a82b056bf874017084005f08000a17821f1112149c00181fffab0d2a108211446a3239a20506fabe589435936bf47401470a1e52f06bb07c014200e06bb81a1e7e00000135ffffffff6bb47e0000012ac0a82bff6be868a401160006ffffffffffff6bbc7401176bf074010c7c001086dd686bd0a2fb06ffffffffffff6bcc72fd0a147a0b3a6b9c0a267af1ff6be072e70a366bac7ae6858218886a26a2040fff02000000000000000000000000006ba872cbaa0e82be8eaa0f8c00b7025868a2a40ffabe5894359352a9874d08aa86dd606a12a2792600583afffe80000000000000f7d4e8ccd81ddb43fe80000000000000f8be58fffe94359386006a3aa272024108123c94006b02586a3ea25e0800000000000000006a56a25504030440c01a5a94004e02581a5e94004702586a62a23e04000000006a66a229102409891f9a26ae6d00000000000000006a76a22004190300001a7a94001902586a7ea204102409891f9a26ae6dba98e781ca9ef9ba6bc872086be4b03a01b87206b03a01b87201 --pcap apf.pcap --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
37 packets dropped
1733 packets passed
Data: 00000000000000000000000000000000000000000200000005000000000000000000000002000000000000001b000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000689000000000000003c00000000000000000000000000000000000006eaPara testar os recursos de transmissão do APFv6, use o comando apf_run da seguinte maneira:
$ 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
Ao usar o parâmetro --trace, a ferramenta apf_run fornece uma saída detalhada de cada etapa na execução do intérprete, o que é útil para depuração. Neste exemplo, inserimos um pacote de consulta ARP no programa APF.
A saída mostra que a consulta ARP foi descartada, mas um pacote de resposta foi gerado.
Os detalhes desse pacote gerado são mostrados na seção transmitted packet.
Problemas comuns de integração
Esta seção destaca vários problemas comuns encontrados durante a integração do APF:
- Limpeza inesperada da região de dados:a memória do APF precisa ser totalmente dedicada ao APF. Somente o código do interpretador ou do framework (pela API HAL) pode modificar a região de memória do APF.
- Problemas de instalação com programas APF de X bytes (X <=
maxLen): o firmware precisa oferecer suporte à leitura ou gravação de qualquer comprimento de programa atémaxLensem falhas, travamentos ou truncamento. As gravações não podem alterar nenhum byte entreXemaxLen. - Implementação do APF no código do driver:o APF só pode ser implementado no firmware, não no código do driver. Caso contrário, não há benefícios de economia de energia porque a CPU precisa ser ativada para processar o pacote.
- Valores
filter_ageoufilter_age_16384thincorretos:os valoresfilter_age(APFv4) efilter_age_16384th(APFv6) precisam ser transmitidos corretamente para as funçõesaccept_packet()eapf_run(). Para detalhes sobre como calcularfilter_age_16384th, consulte a documentação emapf_interpreter.h. - APF não ativado quando necessário:o APF precisa ser ativado quando a tela está desligada e o link Wi-Fi está inativo ou o tráfego está abaixo de 10 Mbps.
- Pacotes truncados transmitidos para
accept_packet()ouapf_run():todos os pacotes unicast, broadcast e multicast transmitidos paraaccept_packet()ouapf_run()precisam estar completos. Não é válido transmitir pacotes truncados para o APF.
Testes de APF
A partir do Android 15, o Android oferece casos de teste do CTS para um único dispositivo e vários dispositivos para integração do filtro e do interpretador de APF, garantindo a funcionalidade correta do APF. Confira uma descrição da finalidade de cada caso de teste:
- Teste de integração
ApfFiltereapf_interpreter:verifica seApfFiltergera o bytecode correto e seapf_interpreterexecuta o código corretamente para produzir os resultados esperados. - CTS de dispositivo único do APF:usa um único dispositivo para testar a funcionalidade do APF no chipset Wi-Fi.
Confirma que:
- O APF é ativado quando a tela está desligada e o tráfego Wi-Fi está abaixo de 10 Mbps.
- As funcionalidades do APF são declaradas corretamente.
- As operações de leitura e gravação na região de memória do APF são bem-sucedidas, e a região de memória não é modificada inesperadamente.
- Os argumentos são transmitidos corretamente para
accept_packet()ouapf_run(). - O firmware integrado ao APFv4/APFv6 pode descartar pacotes.
- O firmware integrado ao APFv6 pode responder a pacotes.
- CTS de vários dispositivos do APF:usa dois dispositivos (um remetente e um destinatário) para testar o comportamento
de filtragem do APF. Vários tipos de pacotes são gerados no lado do remetente, e o teste confirma se eles são descartados, transmitidos ou respondidos corretamente com base nas regras configuradas em
ApfFilter.
Outras instruções de teste de integração
Além disso, recomendamos que os fornecedores de chipset incorporem testes de APF nos próprios conjuntos de testes de integração de Wi-Fi do firmware.
Integrar testes de APF a conjuntos de testes de integração de Wi-Fi de firmware é crucial para verificar a funcionalidade adequada do APF em cenários complexos de conexão Wi-Fi como make-before-break ou roaming. Confira instruções detalhadas sobre como realizar testes de integração na seção a seguir.
Pré-requisitos
Ao realizar testes de integração, faça o seguinte:
- O APF precisa estar ativado em todos os casos de teste de integração (por exemplo, roaming, make-before-break).
- No início de cada teste, limpe a memória do APF.
- Instale ou reinstale programas APF a cada 5 minutos durante o teste.
Cenários de teste
O APF precisa estar ativo durante os testes de integração. Há dois programas APF fornecidos neste documento que podem ser instalados durante o teste. Os programas estão
no formato de string hexadecimal, e o testador precisa converter a string hexadecimal em binário e
instalá-los no firmware para que possam ser executados pelo
apf_interpreter. Durante o teste de integração, o testador precisa enviar pacotes
que devem acionar a lógica de filtragem no programa 1 e no programa 2.
Programa APF 1
Com a tela do dispositivo ligada, instale o programa 1 do APF. Esse programa pode descartar pacotes inofensivos que não afetam a funcionalidade do dispositivo. Esses pacotes são usados para testar se o APF está filtrando corretamente o tráfego de rede.
A lógica do programa APF 1 é a seguinte:
- Soltar e incrementar contador:
- Valores de EtherType:
0x88A2,0x88A4,0x88B8,0x88CD,0x88E1,0x88E3 - Pacotes de descoberta ou solicitação DHCP IPv4
- Pacotes RS
- Valores de EtherType:
- Aprovar e incrementar o contador: todos os outros pacotes.
Os códigos de 1 byte do programa APF são os seguintes:
6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
Programa APF 2
Com a tela do dispositivo desligada, instale o programa APF 2. Esse programa filtra todos os pacotes que o programa APF 1 filtra, além de pacotes de solicitação de ping. Para verificar se o programa APF 2 está instalado corretamente, envie pacotes de ping para o dispositivo em teste.
A lógica do programa APF 2 é a seguinte:
- Soltar e incrementar contador:
- Valores de EtherType:
0x88A2,0x88A4,0x88B8,0x88CD,0x88E1,0x88E3 - Pacotes de descoberta ou solicitação DHCP IPv4
- Pacotes RS
- Valores de EtherType:
- Descartar e incrementar contador: pacotes de solicitação de ping ICMP
- Passar e incrementar o contador: todos os outros pacotes
Os códigos de 2 bytes do programa APF são os seguintes:
6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C007488A27C006F88A47C006A88B87C006588CD7C006088E17C005B88E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE87234120C84000E86DD0A1482093A0A368204856BE0721F120C84001008000A17820B01AB0D220E8204086BE472086BDCB03A01B87206B03A01B87201
Verificação de dados
Para verificar se o programa APF é executado e os pacotes são transmitidos ou descartados corretamente, faça o seguinte:
- Buscar e verificar a região de dados do APF a cada 5 minutos.
- Não limpe o contador.
- Gere pacotes de teste para acionar cada regra de filtro.
Verifique os incrementos do contador usando os seguintes locais de memória:
Nome do contador Localização da memória 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 o programa 1 e o programa 2 da APF
O pseudocódigo a seguir explica a lógica dos programas 1 e 2 da APF em detalhes:
// 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