Filtro pacchetti Android

Android Packet Filter (APF) consente al framework di controllare la logica di filtraggio dei pacchetti hardware durante il runtime. In questo modo, il sistema risparmia energia eliminando i pacchetti nell'hardware, consentendo al framework Android di modificare le regole di filtraggio in fase di runtime in base alle condizioni di rete.

Panoramica di APF

L'APF è costituito da due componenti principali:

  • L'interprete APF viene eseguito su hardware di rete (in genere, il chipset Wi-Fi). L'interprete APF esegue il bytecode APF sui pacchetti ricevuti dall'hardware e decide se accettarli, eliminarli o rispondere.
  • Il codice di generazione del programma APF viene eseguito sulla CPU principale. Il codice crea e aggiorna i programmi APF in base allo stato della rete e del dispositivo.

I metodi HAL Wi-Fi consentono al framework Android di installare il bytecode del programma APF e di leggere i contatori correnti. Il modulo principale dello stack di rete può aggiornare il bytecode del programma APF in qualsiasi momento durante l'esecuzione di APF.

Sono stati implementati diversi filtri APF. Ad esempio, APF include filtri per eliminare i tipi di Ethernet non consentiti, filtrare i pacchetti di annuncio del router IPv6 (RA), filtrare il traffico multicast e broadcast se il blocco multicast non è attivo, eliminare i pacchetti DHCP per altri host ed eliminare i pacchetti di protocollo di risoluzione degli indirizzi (ARP) e di rilevamento dei vicini (ND) non richiesti. Se il firmware supporta APFv6, ApfFilter genera anche regole per rispondere a tipi di pacchetti comuni che altrimenti richiederebbero l'attivazione della CPU per rispondere, ad esempio query ARP e query NS. L'elenco completo dei filtri è definito in ApfFilter.

Poiché il codice di generazione del programma APF fa parte del modulo Network Stack, puoi utilizzare gli aggiornamenti Mainline mensili per aggiungere nuovi filtri e aggiornare la logica di filtraggio.

Revisione APF

Il seguente elenco descrive la cronologia delle revisioni di APF:

  • APFv6:introdotta in Android 15, questa versione supporta il filtraggio dei pacchetti, include contatori per il debug e le metriche e supporta la trasmissione dei pacchetti.
  • APFv4:introdotta in Android 10, questa versione supporta il filtraggio dei pacchetti e include contatori per il debug e le metriche.
  • APFv2:introdotta in Android 7, questa versione supporta il filtro dei pacchetti.

Integrazione APF

Le API APF tra l'interprete APF e l'hardware sono definite in apf_interpreter.h (APFv4, APFv6). Il codice firmware Wi-Fi chiama accept_packet() in APFv4 o apf_run() in APFv6 per determinare se il pacchetto deve essere eliminato (valore restituito pari a zero) o passato al processore dell'app (valore restituito diverso da zero). Se un pacchetto deve essere trasmesso, apf_run() restituisce anche zero perché il pacchetto non deve essere passato al processore dell'app. Se il firmware supporta APFv6, deve implementare le API apf_allocate_buffer() e apf_transmit_buffer(). L'interprete APF chiama queste due API durante la logica di trasmissione dei pacchetti. Le istruzioni APF hanno una lunghezza variabile. Ogni istruzione è lunga almeno 1 byte. I codici di istruzioni APF sono definiti in apf.h per APFv4 e sono incorporati direttamente in apf_interpreter.c per APFv6.

APF si basa sulla memoria dedicata. La memoria viene utilizzata sia per il programma APF che per l'archiviazione dei dati e non deve essere cancellata o scritta dal chipset, tranne che tramite i metodi APF HAL. Il bytecode APF utilizza l'archiviazione dei dati per memorizzare i contatori dei pacchetti accettati e eliminati. La regione dei dati può essere letta dal framework Android. Le istruzioni APF sono efficienti in termini di memoria, ma per massimizzare il loro potenziale di risparmio energetico e funzionalità sono necessarie regole di filtro complesse e dinamiche. Questa complessità richiede una parte dedicata della memoria sul chipset. Il requisito di memoria minimo per APFv4 è 1024 byte, mentre APFv6 richiede 2048 byte. Tuttavia, consigliamo vivamente di allocare 4096 byte per APFv6 per garantire prestazioni ottimali. L'interprete APF deve essere compilato nel firmware. Gli interpreti APFv4 e APFv6 sono ottimizzati per le dimensioni del codice. Nell'architettura arm32, l'interprete APFv4 compilato è di circa 1,8 KB, mentre l'interprete APFv6 più complesso, con funzionalità aggiuntive (ad esempio, supporto nativo del checksum e codice di decompressione DNS nativo), è di circa 4 KB.

I filtri APF possono funzionare insieme ad altri filtri specifici del fornitore del chipset all'interno del firmware. I fornitori di chipset possono scegliere di eseguire la logica di filtraggio prima o dopo la procedura di filtraggio APF. Se un pacchetto viene eliminato prima di raggiungere il filtro APF, quest'ultimo non lo elabora.

Per garantire il corretto funzionamento del filtro APF, quando APF è attivo, il firmware deve fornire al filtro APF l'accesso all'intero pacchetto, non solo all'intestazione, quando APF è abilitato.

Esempi di programmi APF

ApfTest e ApfFilterTest contengono programmi di test di esempio che illustrano il funzionamento di ciascun filtro APF. Per studiare il programma generato effettivo, modifica lo scenario di test per stampare il programma come stringa esadecimale.

La cartella testdata contiene programmi APFv4 di esempio per i filtri APF RA. La cartella samples contiene utilità Python che generano programmi di offload APFv6. Per maggiori dettagli, consulta la documentazione nei file di utilità Python.

Esegui il debug di APF

Per verificare se APF è abilitato sul dispositivo, visualizza il programma corrente, mostra i contatori correnti ed esegui il comando adb shell dumpsys network_stack. Di seguito è riportato un esempio di questo 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

L'output di questo comando adb shell dumpsys network_stack di esempio include quanto segue:

  • ApfCapabilities{version: 4, maxSize: 4096, format: 1}: significa che i chip Wi-Fi supportano APF (versione 4).
  • Last program: questa sezione contiene l'ultimo binario del programma APF installato in formato stringa esadecimale.
  • APF packet counters: questa sezione mostra quanti pacchetti vengono passati o eliminati da APF e i motivi specifici.

Per decodificare e disassemblare il codice in linguaggio assembler leggibile, utilizza lo strumento apf_disassembler. Per compilare il binario eseguibile, esegui il comando m apf_disassembler. Di seguito è riportato un esempio di come utilizzare lo strumento 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
......

Per controllare i risultati APF offline, utilizza lo strumento apf_run. Per compilare il binario eseguibile, esegui il comando m apf_run. Lo strumento apf_run supporta gli interpreti APFv4 e APFv6.

Di seguito è riportato il manuale per il comando apf_run. Per impostazione predefinita, il comando apf_run viene eseguito nell'interprete APFv4. Il passaggio dell'argomento --v6 a apf_run consente di eseguirlo rispetto all'interprete APFv6. Tutti gli altri argomenti possono essere utilizzati sia per APFv4 che per 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.

Ecco un esempio per passare un pacchetto ad APF per verificare se può essere eliminato o passato.

Per fornire la rappresentazione della stringa binaria esadecimale del pacchetto non elaborato, utilizza l'opzione --packet. Per fornire la stringa binaria esadecimale della regione di dati, che viene utilizzata per archiviare il contatore APF, utilizza --data option. Poiché ogni contatore è lungo 4 byte, le regioni di dati devono essere sufficientemente lunghe per garantire che non si verifichi alcun overflow del buffer.

out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b9494010c06006b907c010588a27c010088a47c00fb88b87c00f688cd7c00f188e17c00ec88e384003908066a0e6bdca2d40600010800060412147a18016bd882ca021a1c6b8c7ac900686bd4a2b706ffffffffffff6a266bbca2b204c0a814656bf872a8120c84005808000a17821e1112149c00171fffab0d2a108210446a3239a204064651dbcc88ff6bf4727e0a1e52f06bac7a7be06bb41a1e7e0000006effffffff6bb07e00000063c0a814ff6be868a25106ffffffffffff6bb872536bf072497c001086dd686bd0a23806ffffffffffff6bc8723a0a147a0b3a6b980a267a2eff6be072240a366ba87a23858218886a26a2040fff02000000000000000000000000006ba472086be4b03a01b87206b03a01b87201 --packet 5ebcd79a8f0dc244efaab81408060001080006040002c244efaab814c0a8ca1e5ebcd79a8f0d --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Packet passed
Data: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000001

Per confrontare i risultati di APF con il file pcap acquisito da tcpdump, utilizza il comando apf_run come segue:

out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b989401df06006b947c01d888a27c01d388a47c01ce88b87c01c988cd7c01c488e17c01bf88e384004408066a0e6bdca401a5000600010800060412147a1e016bd884019900021a1c6b907c01960000686bd4a401820006ffffffffffff6a266bc0a4017b0004c0a82b056bf874017084005f08000a17821f1112149c00181fffab0d2a108211446a3239a20506fabe589435936bf47401470a1e52f06bb07c014200e06bb81a1e7e00000135ffffffff6bb47e0000012ac0a82bff6be868a401160006ffffffffffff6bbc7401176bf074010c7c001086dd686bd0a2fb06ffffffffffff6bcc72fd0a147a0b3a6b9c0a267af1ff6be072e70a366bac7ae6858218886a26a2040fff02000000000000000000000000006ba872cbaa0e82be8eaa0f8c00b7025868a2a40ffabe5894359352a9874d08aa86dd606a12a2792600583afffe80000000000000f7d4e8ccd81ddb43fe80000000000000f8be58fffe94359386006a3aa272024108123c94006b02586a3ea25e0800000000000000006a56a25504030440c01a5a94004e02581a5e94004702586a62a23e04000000006a66a229102409891f9a26ae6d00000000000000006a76a22004190300001a7a94001902586a7ea204102409891f9a26ae6dba98e781ca9ef9ba6bc872086be4b03a01b87206b03a01b87201 --pcap apf.pcap --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
37 packets dropped
1733 packets passed
Data: 00000000000000000000000000000000000000000200000005000000000000000000000002000000000000001b000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000689000000000000003c00000000000000000000000000000000000006ea

Per testare le funzionalità di trasmissione APFv6, utilizza il comando apf_run come segue:

$ 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 utilizzi il parametro --trace, lo strumento apf_run fornisce un output dettagliato di ogni passaggio dell'esecuzione dell'interprete, utile per il debug. In questo esempio, inseriamo un pacchetto di query ARP nel programma APF. L'output mostra che la query ARP viene eliminata, ma viene generato un pacchetto di risposta. I dettagli di questo pacchetto generato sono mostrati nella sezione transmitted packet.

Problemi di integrazione comuni

Questa sezione evidenzia diversi problemi comuni riscontrati durante l'integrazione di APF:

  • Cancellazione imprevista della regione di dati:la memoria APF deve essere interamente dedicata ad APF; solo il codice dell'interprete o il codice del framework (tramite l'API HAL) possono modificare la regione di memoria APF.
  • Problemi di installazione con programmi APF di X byte (X <= maxLen): Il firmware deve supportare la lettura o la scrittura di qualsiasi lunghezza del programma fino a maxLen senza errori, arresti anomali o troncamento. Le scritture non devono alterare alcun byte tra X e maxLen.
  • Implementazione di APF nel codice del driver: APF deve essere implementato solo all'interno del firmware, non nel codice del driver. In caso contrario, non ci sono vantaggi in termini di risparmio energetico perché la CPU deve riattivarsi per elaborare il pacchetto.
  • Valori filter_age o filter_age_16384th errati: i valori filter_age (APFv4) e filter_age_16384th (APFv6) devono essere passati correttamente alle funzioni accept_packet() e apf_run(). Per dettagli sul calcolo di filter_age_16384th, consulta la documentazione in apf_interpreter.h.
  • APF non abilitato quando richiesto: APF deve essere abilitato quando lo schermo è spento e il collegamento Wi-Fi è inattivo o il traffico è inferiore a 10 Mbps.
  • Pacchetti troncati passati a accept_packet() o apf_run(): tutti i pacchetti unicast, broadcast e multicast passati a accept_packet() o apf_run() devono essere completi. Il passaggio di pacchetti troncati in APF non è valido.

Test APF

A partire da Android 15, Android fornisce test CTS per singolo dispositivo e per più dispositivi per l'integrazione del filtro APF e dell'interprete APF per garantire la corretta funzionalità APF. Ecco una suddivisione dello scopo di ogni scenario di test:

  • Test di integrazione di ApfFilter e apf_interpreter: verifica che ApfFilter generi il bytecode corretto e che apf_interpreter esegua il codice correttamente per produrre i risultati previsti.
  • CTS per un singolo dispositivo APF: utilizza un singolo dispositivo per testare la funzionalità APF sul chipset Wi-Fi. Conferma che:
    • La funzionalità APF si attiva quando lo schermo è spento e il traffico Wi-Fi è inferiore a 10 Mbps.
    • Le funzionalità APF sono dichiarate correttamente.
    • Le operazioni di lettura e scrittura nella regione di memoria APF hanno esito positivo e la regione di memoria non viene modificata in modo imprevisto.
    • Gli argomenti vengono passati correttamente a accept_packet() o apf_run().
    • Il firmware integrato con APFv4/APFv6 può eliminare i pacchetti.
    • Il firmware integrato con APFv6 può rispondere ai pacchetti.
  • CTS multi-dispositivo APF: Utilizza due dispositivi (un mittente e un destinatario) per testare il comportamento di filtraggio di APF. Sul lato mittente vengono generati vari tipi di pacchetti e il test conferma se vengono eliminati, superati o a cui viene risposto correttamente in base alle regole configurate in ApfFilter.

Istruzioni aggiuntive per il test di integrazione

Inoltre, consigliamo vivamente ai fornitori di chipset di incorporare i test APF nelle proprie suite di test di integrazione Wi-Fi del firmware.

L'integrazione dei test APF nelle suite di test di integrazione Wi-Fi del firmware è fondamentale per verificare la corretta funzionalità APF in scenari di connessione Wi-Fi complessi come scenari di connessione Wi-Fi make-before-break o roaming. Istruzioni dettagliate su come eseguire i test di integrazione sono disponibili nella sezione seguente.

Prerequisiti

Quando esegui i test di integrazione:

  • APF deve essere abilitato in tutti gli scenari di test di integrazione (ad esempio, roaming, make-before-break).
  • All'inizio di ogni test, cancella la memoria APF.
  • Installa o reinstalla i programmi APF ogni 5 minuti durante il test.

Scenari di test

APF deve essere attivo durante i test di integrazione. In questo documento sono disponibili due programmi APF che possono essere installati durante il test. I programmi sono in formato stringa esadecimale e il tester deve convertire la stringa esadecimale in binario e installarli nel firmware in modo che possano essere eseguiti da apf_interpreter. Durante il test di integrazione, il tester deve inviare pacchetti che dovrebbero attivare la logica di filtraggio nel programma 1 e nel programma 2.

APF program 1

Quando lo schermo del dispositivo è acceso, installa APF program 1. Questo programma può eliminare pacchetti innocui che non influiscono sulla funzionalità del dispositivo. Questi pacchetti vengono utilizzati per verificare se APF filtra correttamente il traffico di rete.

La logica del programma APF 1 è la seguente:

  1. Contatore di gocce e incrementi:
    1. Valori EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. Pacchetti di richiesta o rilevamento DHCP IPv4
    3. Pacchetti RS
  2. Passa e incrementa il contatore: tutti gli altri pacchetti.

I codici di 1 byte del programma APF sono i seguenti:

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
Programma APF 2

Quando lo schermo del dispositivo è spento, installa APF program 2. Questo programma filtra tutti i pacchetti che APF program 1 filtra, nonché i pacchetti di richiesta ping. Per verificare che il programma APF 2 sia installato correttamente, invia pacchetti ping al dispositivo in fase di test.

La logica del programma APF 2 è la seguente:

  1. Contatore di gocce e incrementi:
    1. Valori EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. Pacchetti di richiesta o rilevamento DHCP IPv4
    3. Pacchetti RS
  2. Decremento e incremento del contatore: pacchetti di richiesta ping ICMP
  3. Pass and increment counter: tutti gli altri pacchetti

I codici di 2 byte del programma APF sono i seguenti:

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C007488A27C006F88A47C006A88B87C006588CD7C006088E17C005B88E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE87234120C84000E86DD0A1482093A0A368204856BE0721F120C84001008000A17820B01AB0D220E8204086BE472086BDCB03A01B87206B03A01B87201
Verifica dei dati

Per verificare che il programma APF venga eseguito e che i pacchetti vengano passati o eliminati correttamente, procedi nel seguente modo:

  • Recupera e verifica la regione dei dati APF ogni 5 minuti.
  • Non azzerare il contatore.
  • Genera pacchetti di test per attivare ogni regola di filtro.
  • Verifica gli incrementi del contatore utilizzando le seguenti posizioni di memoria:

    Nome contatore Posizione della 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]

Pseudocodice per il programma APF 1 e il programma APF 2

Il seguente pseudocodice spiega in dettaglio la logica del programma APF 1 e del programma APF 2:

// 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