Android Packet Filter

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: 27

A 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: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000001

Para 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: 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

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é maxLen sem falhas, travamentos ou truncamento. As gravações não podem alterar nenhum byte entre X e maxLen.
  • 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_age ou filter_age_16384th incorretos:os valores filter_age (APFv4) e filter_age_16384th (APFv6) precisam ser transmitidos corretamente para as funções accept_packet() e apf_run(). Para detalhes sobre como calcular filter_age_16384th, consulte a documentação em apf_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() ou apf_run():todos os pacotes unicast, broadcast e multicast transmitidos para accept_packet() ou apf_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 ApfFilter e apf_interpreter:verifica se ApfFilter gera o bytecode correto e se apf_interpreter executa 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() ou apf_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:

  1. Soltar e incrementar contador:
    1. Valores de EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. Pacotes de descoberta ou solicitação DHCP IPv4
    3. Pacotes RS
  2. 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:

  1. Soltar e incrementar contador:
    1. Valores de EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. Pacotes de descoberta ou solicitação DHCP IPv4
    3. Pacotes RS
  2. Descartar e incrementar contador: pacotes de solicitação de ping ICMP
  3. 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