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 momento da execução. Isso permite que o sistema economize energia descartando pacotes na hardware, permitindo que o framework do Android mude as regras de filtragem no momento da execução com base nas condições da rede.
Visão geral do APF
O APF consiste em dois componentes principais:
- O interpretador APF é executado em hardware de rede (normalmente, o chipset Wi-Fi). O interpretador do APF executa o bytecode do APF em pacotes recebidos pelo hardware e decide se vai aceitar, descartar ou responder a eles.
- O código de geração de programas APF é executado na CPU principal. O código cria e atualiza programas APF de acordo com a rede e o estado do dispositivo.
Os métodos do HAL do Wi-Fi permitem que o framework do Android instale o bytecode do programa do APF e leia os contadores atuais. O módulo de linha 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 APF implementados. Por exemplo, o APF inclui filtros para
descartar ethertypes não permitidos, filtrar pacotes de anúncio de roteador IPv6 (RA),
filtrar o 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ço
(ARP) e de descoberta de vizinho (ND) não solicitados. Se o firmware oferecer suporte ao APFv6,
o 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 consultas
NS. A lista completa de filtros é definida em
ApfFilter
.
Como o código de geração de programa APF faz parte do módulo de pilha de rede, é possível usar mensalmente as [Mainline updates (em inglês) para adicionar novos filtros e atualizar a lógica de filtragem.
Revisão de APF
A lista a seguir descreve o histórico de revisões do APF:
- APFv6:introduzida no Android 15, essa 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 oferece suporte à filtragem de pacotes.
Integração com o APF
As APIs APF entre o intérprete APF e o hardware são definidas em
apf_interpreter.h
(APFv4,
APFv6).
O código do firmware do 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
transferido para o processador do app (valor de retorno diferente de zero). Se um pacote precisar
ser transmitido,
apf_run()
também retornará zero, porque o pacote não precisa ser transmitido ao processador
do app. Se o firmware oferecer suporte ao APFv6, ele precisará implementar as APIs
apf_allocate_buffer()
e
apf_transmit_buffer()
. O interpretador APF chama essas duas APIs durante a lógica de transmissão de pacotes.
As instruções APF têm comprimento variável. Cada instrução tem pelo menos 1 byte de
comprimento. Os códigos de instrução do APF são definidos em
apf.h
para APFv4 e são inline diretamente em
apf_interpreter.c
para APFv6.
A APF depende de memória dedicada. A memória é usada para o programa APF e para o armazenamento de dados. Ela 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 do Android. As instruções APF são eficientes em termos de memória, mas maximizar o potencial de economia de energia e funcionalidade exige regras de filtragem complexas e dinâmicas. Essa complexidade exige uma parte dedicada de 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 4096 bytes para o APFv6 para garantir o 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 interpretador APFv4 compilado tem cerca de 1,8 KB, enquanto o interpretador APFv6 mais complexo, com recursos adicionais (por exemplo, suporte nativo a checksum e código de descompressão DNS nativo), é aproximadamente 4 KB.
Os filtros 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 da 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, quando o APF está ativado.
Exemplos de programas de APF
ApfTest
e
ApfFilterTest
contêm programas de teste de exemplo que ilustram como cada filtro 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 programas APFv4 de exemplo para filtros RA do APF. A pasta
samples
contém utilitários Python que geram programas de transferência de 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, mostre 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: 27
A saída do comando adb shell dumpsys network_stack
deste exemplo inclui
o seguinte:
ApfCapabilities{version: 4, maxSize: 4096, format: 1}
: significa que os chips Wi-Fi oferecem suporte a 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 uma linguagem assembly legível por humanos, use
a ferramenta
apf_disassembler
. Para compilar o binário executável, execute o comando m apf_disassembler
.
Confira a seguir 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 da 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
oferece suporte a intérpretes APFv4 e APFv6.
Confira a seguir o manual do comando apf_run
. Por padrão, o comando apf_run
é executado no interpretador APFv4. A transmissão do argumento --v6
para apf_run
permite que ele seja 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 de como transmitir um pacote para o APF para verificar se ele pode ser excluído ou transmitido.
Para fornecer a apresentação de 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 APF,
use o --data option
. Como cada contador tem 4 bytes, as regiões de dados
precisam ser longas o suficiente para garantir que não ocorra um buffer overflow.
out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b9494010c06006b907c010588a27c010088a47c00fb88b87c00f688cd7c00f188e17c00ec88e384003908066a0e6bdca2d40600010800060412147a18016bd882ca021a1c6b8c7ac900686bd4a2b706ffffffffffff6a266bbca2b204c0a814656bf872a8120c84005808000a17821e1112149c00171fffab0d2a108210446a3239a204064651dbcc88ff6bf4727e0a1e52f06bac7a7be06bb41a1e7e0000006effffffff6bb07e00000063c0a814ff6be868a25106ffffffffffff6bb872536bf072497c001086dd686bd0a23806ffffffffffff6bc8723a0a147a0b3a6b980a267a2eff6be072240a366ba87a23858218886a26a2040fff02000000000000000000000000006ba472086be4b03a01b87206b03a01b87201 --packet 5ebcd79a8f0dc244efaab81408060001080006040002c244efaab814c0a8ca1e5ebcd79a8f0d --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Packet passed
Data: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000001
Para verificar os resultados do APF em relação ao arquivo pcap capturado 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: 00000000000000000000000000000000000000000200000005000000000000000000000002000000000000001b000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000689000000000000003c00000000000000000000000000000000000006ea
Para 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
Quando você usa o parâmetro --trace
, a ferramenta apf_run
fornece uma saída detalhada
de cada etapa na execução do interpretador, o que é útil para
depurar. 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 da APF:
- Limpeza inesperada da região de dados:a memória do APF precisa ser totalmente dedicada ao APF. Somente o código do intérprete 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émaxLen
sem falhas, travamentos ou truncamentos. As gravações não podem alterar bytes entreX
emaxLen
. - Implementação de APF no código do driver:o APF precisa ser implementado apenas 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_age
oufilter_age_16384th
incorretos:os valoresfilter_age
(APFv4) efilter_age_16384th
(APFv6) precisam ser transmitidos corretamente para as funçõesaccept_packet()
eapf_run()
. Para mais detalhes sobre o cálculo defilter_age_16384th
, consulte a documentação emapf_interpreter.h
. - APF não ativado quando necessário:o APF precisa estar ativado quando a tela estiver desligada e o link Wi-Fi estiver inativo ou o tráfego estiver 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. A transmissão de pacotes truncados para o APF não é válida.
Testes de APF
A partir do Android 15, o Android oferece casos de teste do CTS para um dispositivo e vários dispositivos para o filtro APF e a integração do interpretador APF para garantir a funcionalidade correta do APF. Confira o objetivo de cada caso de teste:
- Teste de integração
de
ApfFilter
eapf_interpreter
:verifica seApfFilter
gera o bytecode correto e seapf_interpreter
executa o código corretamente para produzir os resultados esperados. - CTS de APF para um único dispositivo:usa um único dispositivo para testar a funcionalidade de APF no chipset Wi-Fi.
Confirma que:
- O APF é ativado quando a tela está desligada e o tráfego de Wi-Fi está abaixo de 10 Mbps.
- Os recursos do APF são declarados 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 de forma inesperada.
- 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 emissor e um receptor) 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
.
Instruções adicionais para testes de integração
Além disso, recomendamos que os fornecedores de chipset incorporem os testes de APF nas próprias suítes de teste de integração do firmware Wi-Fi.
A integração de testes de APF em pacotes 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 cenários de conexão Wi-Fi de 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 ser 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 os 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 de 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á-la no firmware para que os programas possam ser executados por
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
Quando a tela do dispositivo estiver ligada, instale o programa APF 1. 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 1 do APF é a seguinte:
- Contador de queda e incremento:
- Valores de EtherType:
0x88A2
,0x88A4
,0x88B8
,0x88CD
,0x88E1
,0x88E3
- Pacotes de descoberta ou solicitação DHCP IPv4
- Pacotes RS
- Valores de EtherType:
- Contador de passagem e incremento: todos os outros pacotes.
Os códigos de 1 byte do programa APF são os seguintes:
6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
Programa APF 2
Quando a tela do dispositivo estiver desligada, instale o programa 2 do APF. Esse programa filtra todos os pacotes que o programa 1 do APF filtra, bem como pacotes de solicitação de ping. Para verificar se o programa 2 do APF está instalado corretamente, envie pacotes de ping para o dispositivo em teste.
A lógica do programa 2 do APF é a seguinte:
- Contador de queda e incremento:
- Valores de EtherType:
0x88A2
,0x88A4
,0x88B8
,0x88CD
,0x88E1
,0x88E3
- Pacotes de descoberta ou solicitação DHCP IPv4
- Pacotes RS
- Valores de EtherType:
- Contador de descarte e incremento: pacotes de solicitação de ping ICMP
- Contador de passagem e incremento: 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:
- Extraia e verifique a região de dados do APF a cada cinco minutos.
- Não limpe o contador.
- Gerar pacotes de teste para acionar cada regra de filtro.
Verifique os incrementos do contador usando os seguintes locais de memória:
Nome do contador Local de 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 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