Android Packet Filter (APF) consente al framework di controllare la logica di filtrado delle schede hardware durante il runtime. In questo modo, il sistema risparmia energia eliminando i pacchetti in hardware, consentendo al framework Android di modificare le regole di filtrazione in fase di esecuzione in base alle condizioni della rete.
Panoramica dell'AFP
L'AFP è costituito da due componenti principali:
- L'interprete APF viene eseguito sull'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, ignorarli 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 Mainline 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 gli ethertype non consentiti, i pacchetti di annunci router IPv6 (RA), il traffico multicast e broadcast se il blocco multicast non è attivo, i pacchetti DHCP per altri host e i pacchetti ARP (Address Resolution Protocol) e ND (Neighbor Discovery) indesiderati. Se il firmware supporta APFv6, ApfFilter
genera anche regole per rispondere a tipi di pacchetti comuni che altrimenti richiederebbero la riattivazione della CPU per rispondere, ad esempio query ARP e 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 mensile [Aggiornamenti principali per aggiungere nuovi filtri e aggiornare la logica di filtro.
Revisione APF
Il seguente elenco descrive la cronologia delle revisioni dell'AFP:
- APFv6: introdotta in Android 15, questa versione supporta il filtro 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 filtering dei pacchetti.
Integrazione di APF
Le API APF tra l'interprete APF e l'hardware sono definite in
apf_interpreter.h
(APFv4,
APFv6).
Il codice del 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
tramesso all'app processor (valore restituito diverso da zero). Se un pacchetto deve essere trasmesso, anche apf_run()
restituisce zero perché il pacchetto non deve essere passato all'app processor. 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 sono di lunghezza variabile. Ogni istruzione deve avere una lunghezza minima di 1 byte. I codici delle istruzioni APF sono definiti in apf.h
per APFv4 e sono incorporati direttamente in apf_interpreter.c
per APFv6.
L'APF si basa su una memoria dedicata. La memoria viene utilizzata sia per il programma APF stesso sia per l'archiviazione dei dati e non deve essere cancellata o scritta dal chipset, se non tramite i metodi APF HAL. Il bytecode APF utilizza lo spazio di archiviazione dei dati per memorizzare i contatori per i pacchetti accettati e persi. La regione di 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 minima per APFv4 è di 1024 byte, mentre APFv6 richiede 2048 byte. Tuttavia, consigliamo vivamente di allocare 4096 byte per APFv6 per garantire un rendimento ottimale. L'interprete APF deve essere compilato nel firmware. Entrambi 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 il supporto del checksum nativo e il codice di decompressione DNS nativo), è di circa 4 KB.
I filtri APF possono funzionare insieme ad altri filtri specifici del fornitore di chipset all'interno del firmware. I fornitori di chipset possono scegliere di eseguire la logica di filtro prima o dopo la procedura di filtro APF. Se un pacchetto viene eliminato prima di raggiungere il filtro APF, il pacchetto non lo elabora.
Per garantire il corretto funzionamento del filtro APF, quando questo è attivo, il firmware deve fornire al filtro APF l'accesso all'intero pacchetto, non solo all'intestazione.
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 il caso di test in modo da stampare il programma come stringa
esadecimale.
La
testdata
cartella contiene programmi APFv4 di esempio per i filtri RA APF. La
samples
cartella contiene utilità Python che generano programmi di offload APFv6. Per maggiori dettagli, consulta la documentazione nei file di utilità Python.
Eseguire il debug dell'API APF
Per verificare se l'AFP è abilitata 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 è il programma APF binario più recente installato in formato di stringa esadecimale.APF packet counters
: questa sezione mostra quanti pacchetti vengono passati o eliminati dall'APF e i motivi specifici.
Per decodificare e disassemblare il codice in un linguaggio assembler leggibile, utilizza lo strumento
apf_disassembler
. Per compilare il file eseguibile binario, 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 dell'AFP offline, utilizza lo strumento
apf_run
. Per compilare il file eseguibile binario, esegui il comando m apf_run
. Lo
strumento apf_run
supporta gli interpreti APFv4 e APFv6.
Di seguito è riportato il manuale del comando apf_run
. Per impostazione predefinita, il comando apf_run
viene eseguito nell'interprete APFv4. Se passi l'argomento --v6
a apf_run
,
puoi eseguirlo con l'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 abbandonato o trasmesso.
Per fornire la presentazione in 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 memorizzare il contatore APF, utilizza --data option
. Poiché ogni contatore è lungo 4 byte, le regioni di dati devono essere sufficientemente lunghe da evitare un overflow del buffer.
out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b9494010c06006b907c010588a27c010088a47c00fb88b87c00f688cd7c00f188e17c00ec88e384003908066a0e6bdca2d40600010800060412147a18016bd882ca021a1c6b8c7ac900686bd4a2b706ffffffffffff6a266bbca2b204c0a814656bf872a8120c84005808000a17821e1112149c00171fffab0d2a108210446a3239a204064651dbcc88ff6bf4727e0a1e52f06bac7a7be06bb41a1e7e0000006effffffff6bb07e00000063c0a814ff6be868a25106ffffffffffff6bb872536bf072497c001086dd686bd0a23806ffffffffffff6bc8723a0a147a0b3a6b980a267a2eff6be072240a366ba87a23858218886a26a2040fff02000000000000000000000000006ba472086be4b03a01b87206b03a01b87201 --packet 5ebcd79a8f0dc244efaab81408060001080006040002c244efaab814c0a8ca1e5ebcd79a8f0d --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Packet passed
Data: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000001
Per verificare i risultati dell'AFP rispetto al 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 debugging. 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 riportati nella transmitted packet
sezione.
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 framework (tramite l'API HAL) può 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 amaxLen
senza errori, arresti anomali o troncamenti. Le scritture non devono alterare i byte traX
emaxLen
. - Implementazione della funzionalità APF nel codice del driver: la funzionalità APF deve essere implementata 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
ofilter_age_16384th
errati: i valorifilter_age
(APFv4) efilter_age_16384th
(APFv6) devono essere passati correttamente alle funzioniaccept_packet()
eapf_run()
. Per i dettagli sul calcolo difilter_age_16384th
, consulta la documentazione inapf_interpreter.h
. - APF non attivato quando richiesto: la funzionalità APF deve essere attivata quando lo schermo è spento e il link Wi-Fi è inattivo o il traffico è inferiore a 10 Mbps.
- Pacchetti troncati passati a
accept_packet()
oapf_run()
: tutti i pacchetti unicast, broadcast e multicast passati aaccept_packet()
oapf_run()
devono essere completi. Il passaggio di pacchetti troncati in APF non è valido.
Test APF
A partire da Android 15, Android fornisce sia i casi di test CTS su singolo dispositivo sia su più dispositivi per l'integrazione del filtro APF e dell'interprete APF per garantire il corretto funzionamento dell'APF. Ecco una suddivisione dello scopo di ogni scenario di test:
- Test di integrazione di
ApfFilter
eapf_interpreter
: verifica cheApfFilter
generi bytecode corretto e cheapf_interpreter
esegua il codice correttamente per produrre i risultati previsti. - CTS con un solo dispositivo APF:
utilizza un singolo dispositivo per testare la funzionalità APF sul chipset Wi-Fi.
Conferma che:
- L'AFP si attiva quando lo schermo è acceso 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 vanno a buon fine e la regione di memoria non viene modificata in modo imprevisto.
- Argomenti vengono passati correttamente a
accept_packet()
oapf_run()
. - Il firmware integrato con APFv4/APFv6 può perdere pacchetti.
- Il firmware integrato con APFv6 può rispondere ai pacchetti.
- CTS multi-dispositivo APF: impiega due dispositivi (un mittente e un destinatario) per testare il comportamento di filtraggio dell'APF. Sul lato del mittente vengono generati vari tipi di pacchetti e il test conferma se vengono eliminati, trasmessi o a cui viene data risposta correttamente in base alle regole configurate in
ApfFilter
.
Istruzioni aggiuntive per i 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 contatto iniziale o roaming. Istruzioni dettagliate su come eseguire i test di integrazione sono disponibili nella sezione seguente.
Prerequisiti
Quando esegui i test di integrazione:
- L'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
L'APF deve essere attivo durante tutti i test di integrazione. Questo documento include due programmi APF
che possono essere installati durante il test. I programmi sono in formato di stringa esadecimale e il tester deve convertire la stringa esadecimale in binario e installarla nel firmware in modo che i programmi possano essere eseguiti da apf_interpreter
. Durante il test di integrazione, il tester deve inviare pacchetti
che dovrebbero attivare la logica di filtro nel programma 1 e nel programma 2.
Programma APF 1
Quando lo schermo del dispositivo è acceso, installa il programma APF 1. Questo programma può rilasciare pacchetti innocui che non incidono sulla funzionalità del dispositivo. Questi pacchetti vengono utilizzati per verificare se l'APF filtra correttamente il traffico di rete.
La logica del programma APF 1 è la seguente:
- Rilascia e incrementa il contatore:
- Valori EtherType:
0x88A2
,0x88A4
,0x88B8
,0x88CD
,0x88E1
,0x88E3
- Pacchetti di richiesta o discovery DHCP IPv4
- Pacchetti RS
- Valori EtherType:
- Contatore di passaggio e incremento: tutti gli altri pacchetti.
I codici di byte del programma APF 1 sono i seguenti:
6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
Programma APF 2
Quando lo schermo del dispositivo è spento, installa il programma APF 2. Questo programma esclude tutti i pacchetti filtrati dal programma APF 1, nonché i pacchetti di richiesta di ping. Per verificare che il programma APF 2 sia installato correttamente, invia i pacchetti di ping al dispositivo sottoposto a test.
La logica del programma APF 2 è la seguente:
- Rilascia e incrementa il contatore:
- Valori EtherType:
0x88A2
,0x88A4
,0x88B8
,0x88CD
,0x88E1
,0x88E3
- Pacchetti di richiesta o discovery DHCP IPv4
- Pacchetti RS
- Valori EtherType:
- Contatore di incremento e abbandono: pacchetti di richiesta di ping ICMP
- Contatore di passaggio e incremento: tutti gli altri pacchetti
I codici da 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 trasmessi o eliminati correttamente:
- Recupera e verifica la regione di dati APF ogni 5 minuti.
- Non cancellare 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
[Dimensione ApfRam - 20, Dimensione ApfRam - 16] DROPPED_DHCP_REQUEST_DISCOVERY
[Dimensione ApfRam - 24, Dimensione ApfRam - 20] DROPPED_ICMP4_ECHO_REQUEST
[Dimensione ApfRam - 28, Dimensione ApfRam - 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