Filtr pakietów Androida (APF) umożliwia platformie sterowanie logiką filtrowania pakietów sprzętowych w czasie działania. Dzięki temu system może oszczędzać energię, odrzucając pakiety w sprzęcie, a platforma Androida może zmieniać reguły filtrowania w czasie działania na podstawie warunków sieciowych.
Omówienie APF
APF składa się z 2 głównych komponentów:
- Interpreter APF działa na sprzęcie sieciowym (zwykle na chipsecie Wi-Fi). Interpreter APF uruchamia kod bajtowy APF na pakietach otrzymanych przez sprzęt i decyduje, czy je zaakceptować, odrzucić czy na nie odpowiedzieć.
- Kod generowania programu APF jest uruchamiany na głównym procesorze. Kod tworzy i aktualizuje programy APF zgodnie ze stanem sieci i urządzenia.
Metody HAL Wi-Fi umożliwiają platformie Android instalowanie kodu bajtowego programu APF i odczytywanie bieżących liczników. Moduł główny stosu sieciowego może w dowolnym momencie aktualizować kod bajtowy programu APF podczas jego działania.
Wdrożono kilka filtrów APF. Na przykład APF zawiera filtry, które
odrzucają niedozwolone typy Ethernetu, filtrują pakiety reklam routera IPv6 (RA),
filtrują ruch multicast i broadcast, jeśli blokada multicast nie jest utrzymywana, odrzucają
pakiety DHCP dla innych hostów oraz odrzucają niechciane pakiety protokołu ARP
i protokołu ND. Jeśli oprogramowanie sprzętowe obsługuje APFv6,
ApfFilter
generuje też reguły odpowiadania na typowe typy pakietów, które w przeciwnym razie
wymagałyby wybudzenia procesora w celu udzielenia odpowiedzi, np. zapytania ARP i zapytania NS. Pełna lista filtrów jest zdefiniowana w ApfFilter
.
Kod generowania programu APF jest częścią modułu Network Stack, dlatego możesz używać comiesięcznych aktualizacji Mainline, aby dodawać nowe filtry i aktualizować logikę filtrowania.
Wersja APF
Poniżej znajdziesz historię zmian w APF:
- APFv6: wprowadzona w Androidzie 15, ta wersja obsługuje filtrowanie pakietów, zawiera liczniki do debugowania i zbierania danych oraz obsługuje transmisję pakietów.
- APFv4: wprowadzona w Androidzie 10, ta wersja obsługuje filtrowanie pakietów i zawiera liczniki do debugowania i pomiarów.
- APFv2: wprowadzona w Androidzie 7, obsługuje filtrowanie pakietów.
Integracja z platformą APF
Interfejsy API APF między interpreterem APF a sprzętem są zdefiniowane w apf_interpreter.h
(APFv4, APFv6).
Kod oprogramowania sprzętowego Wi-Fi wywołuje funkcję
accept_packet()
w APFv4 lub
apf_run()
w APFv6, aby określić, czy pakiet powinien zostać odrzucony (wartość zwracana to zero), czy
przekazany do procesora aplikacji (wartość zwracana jest różna od zera). Jeśli pakiet musi zostać przesłany, funkcja
apf_run()
zwraca też zero, ponieważ pakiet nie musi być przekazywany do procesora aplikacji. Jeśli oprogramowanie sprzętowe obsługuje APFv6, musi implementować interfejsy API apf_allocate_buffer()
i apf_transmit_buffer()
. Interpreter APF wywołuje te 2 interfejsy API w logice transmisji pakietów.
Instrukcje APF mają zmienną długość. Każda instrukcja ma długość co najmniej 1 bajt. Kody instrukcji APF są zdefiniowane w apf.h
w przypadku APFv4 i są wstawiane bezpośrednio w apf_interpreter.c
w przypadku APFv6.
APF korzysta z dedykowanej pamięci. Pamięć jest używana zarówno na potrzeby samego programu APF, jak i do przechowywania danych. Nie może być czyszczona ani zapisywana przez chipset, z wyjątkiem metod HAL APF. Kod bajtowy APF wykorzystuje pamięć masową do przechowywania liczników zaakceptowanych i odrzuconych pakietów. Region danych można odczytać z platformy Androida. Instrukcje APF są oszczędne pod względem pamięci, ale maksymalizacja ich potencjału w zakresie oszczędzania energii i funkcjonalności wymaga złożonych, dynamicznych reguł filtrowania. Ta złożoność wymaga wydzielenia części pamięci na chipsecie. Minimalne wymagania dotyczące pamięci w przypadku APFv4 to 1024 bajty, a w przypadku APFv6 – 2048 bajty. Zalecamy jednak przydzielenie 4096 bajtów na APFv6, aby zapewnić optymalną wydajność. Interpreter APF musi być skompilowany w oprogramowaniu układowym. Zarówno interpreter APFv4, jak i APFv6 są zoptymalizowane pod kątem rozmiaru kodu. W architekturze arm32 skompilowany interpreter APFv4 ma około 1,8 KB, a bardziej złożony interpreter APFv6 z dodatkowymi funkcjami (np.natywną obsługą sumy kontrolnej i natywnym kodem dekompresji DNS) ma około 4 KB.
Filtry APF mogą działać w oprogramowaniu sprzętowym razem z innymi filtrami specyficznymi dla dostawcy chipsetu. Dostawcy chipsetów mogą uruchamiać logikę filtrowania przed procesem filtrowania APF lub po nim. Jeśli pakiet zostanie odrzucony przed dotarciem do filtra APF, filtr APF go nie przetworzy.
Aby zapewnić prawidłowe działanie filtra APF, gdy jest on włączony, oprogramowanie sprzętowe musi zapewnić mu dostęp do całego pakietu, a nie tylko do nagłówka.
Przykłady programów APF
ApfTest
i
ApfFilterTest
zawierają przykładowe programy testowe, które pokazują, jak działa każdy filtr APF. Aby zbadać wygenerowany program, zmodyfikuj przypadek testowy, aby wyświetlać program jako ciąg szesnastkowy.
Folder testdata
zawiera przykładowe programy APFv4 dla filtrów APF RA. Folder
samples
zawiera narzędzia w języku Python, które generują programy odciążania APFv6. Więcej informacji znajdziesz w dokumentacji w plikach narzędzia w Pythonie.
Debugowanie APF
Aby sprawdzić, czy na urządzeniu jest włączona funkcja APF, wyświetl bieżący program, pokaż bieżące liczniki i uruchom polecenie adb shell dumpsys network_stack
. Poniżej znajdziesz przykład tego polecenia:
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
Dane wyjściowe tego przykładowego polecenia adb shell dumpsys network_stack
obejmują:
ApfCapabilities{version: 4, maxSize: 4096, format: 1}
: oznacza to, że moduły Wi-Fi obsługują APF (wersja 4).Last program
: ta sekcja zawiera najnowszy zainstalowany plik binarny programu APF w formacie ciągu szesnastkowym.APF packet counters
: ta sekcja pokazuje, ile pakietów zostało przekazanych lub odrzuconych przez APF, oraz podaje konkretne przyczyny.
Aby zdekodować i zdezasemblować kod do postaci zrozumiałego dla człowieka języka asemblera, użyj narzędzia apf_disassembler
. Aby skompilować plik wykonywalny, uruchom polecenie m apf_disassembler
.
Poniżej znajdziesz przykład użycia narzędzia 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
......
Aby sprawdzić wyniki APF offline, użyj narzędzia
apf_run
. Aby skompilować plik wykonywalny, uruchom polecenie m apf_run
. Narzędzie apf_run
obsługuje interpretery APFv4 i APFv6.
Poniżej znajdziesz instrukcję obsługi polecenia apf_run
. Domyślnie polecenie apf_run
jest wykonywane w interpreterze APFv4. Przekazanie argumentu --v6
do apf_run
umożliwia uruchomienie go w interpreterze APFv6. Wszystkie pozostałe argumenty można stosować zarówno w przypadku APFv4, jak i 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.
Oto przykład przekazania jednego pakietu do APF w celu sprawdzenia, czy można go odrzucić lub przekazać.
Aby podać szesnastkową postać binarną surowego pakietu, użyj opcji --packet
. Aby podać szesnastkowy ciąg binarny regionu danych, który jest używany do przechowywania licznika APF, użyj --data option
. Każdy licznik ma długość 4 bajtów, więc regiony danych muszą być wystarczająco długie, aby nie doszło do przepełnienia bufora.
out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b9494010c06006b907c010588a27c010088a47c00fb88b87c00f688cd7c00f188e17c00ec88e384003908066a0e6bdca2d40600010800060412147a18016bd882ca021a1c6b8c7ac900686bd4a2b706ffffffffffff6a266bbca2b204c0a814656bf872a8120c84005808000a17821e1112149c00171fffab0d2a108210446a3239a204064651dbcc88ff6bf4727e0a1e52f06bac7a7be06bb41a1e7e0000006effffffff6bb07e00000063c0a814ff6be868a25106ffffffffffff6bb872536bf072497c001086dd686bd0a23806ffffffffffff6bc8723a0a147a0b3a6b980a267a2eff6be072240a366ba87a23858218886a26a2040fff02000000000000000000000000006ba472086be4b03a01b87206b03a01b87201 --packet 5ebcd79a8f0dc244efaab81408060001080006040002c244efaab814c0a8ca1e5ebcd79a8f0d --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Packet passed
Data: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000001
Aby sprawdzić wyniki APF w porównaniu z plikiem pcap utworzonym przez tcpdump, użyj polecenia apf_run
w ten sposób:
out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b989401df06006b947c01d888a27c01d388a47c01ce88b87c01c988cd7c01c488e17c01bf88e384004408066a0e6bdca401a5000600010800060412147a1e016bd884019900021a1c6b907c01960000686bd4a401820006ffffffffffff6a266bc0a4017b0004c0a82b056bf874017084005f08000a17821f1112149c00181fffab0d2a108211446a3239a20506fabe589435936bf47401470a1e52f06bb07c014200e06bb81a1e7e00000135ffffffff6bb47e0000012ac0a82bff6be868a401160006ffffffffffff6bbc7401176bf074010c7c001086dd686bd0a2fb06ffffffffffff6bcc72fd0a147a0b3a6b9c0a267af1ff6be072e70a366bac7ae6858218886a26a2040fff02000000000000000000000000006ba872cbaa0e82be8eaa0f8c00b7025868a2a40ffabe5894359352a9874d08aa86dd606a12a2792600583afffe80000000000000f7d4e8ccd81ddb43fe80000000000000f8be58fffe94359386006a3aa272024108123c94006b02586a3ea25e0800000000000000006a56a25504030440c01a5a94004e02581a5e94004702586a62a23e04000000006a66a229102409891f9a26ae6d00000000000000006a76a22004190300001a7a94001902586a7ea204102409891f9a26ae6dba98e781ca9ef9ba6bc872086be4b03a01b87206b03a01b87201 --pcap apf.pcap --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
37 packets dropped
1733 packets passed
Data: 00000000000000000000000000000000000000000200000005000000000000000000000002000000000000001b000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000689000000000000003c00000000000000000000000000000000000006ea
Aby przetestować możliwości transmisji APFv6, użyj polecenia apf_run
w ten sposób:
$ 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
Gdy używasz parametru --trace
, narzędzie apf_run
podaje szczegółowe dane wyjściowe każdego kroku wykonania interpretera, co jest przydatne podczas debugowania. W tym przykładzie wprowadzamy do programu APF pakiet zapytania ARP.
Dane wyjściowe pokazują, że zapytanie ARP zostało odrzucone, ale wygenerowano pakiet odpowiedzi.
Szczegóły wygenerowanego pakietu są widoczne w sekcji transmitted packet
.
Typowe problemy z integracją
W tej sekcji znajdziesz kilka typowych problemów, które mogą wystąpić podczas integracji APF:
- Nieoczekiwane czyszczenie regionu danych: pamięć APF musi być w całości przeznaczona na APF. Tylko kod interpretera lub kod platformy (za pomocą interfejsu HAL API) mogą modyfikować region pamięci APF.
- Problemy z instalacją programów APF o rozmiarze X bajtów (X <=
maxLen
): oprogramowanie musi obsługiwać odczyt lub zapis dowolnej długości programu domaxLen
bez awarii, zawieszeń lub obcinania. Operacje zapisu nie mogą zmieniać żadnych bajtów międzyX
amaxLen
. - Implementacja APF w kodzie sterownika: APF należy implementować tylko w oprogramowaniu sprzętowym, a nie w kodzie sterownika. W przeciwnym razie nie ma korzyści związanych z oszczędzaniem energii, ponieważ procesor musi się włączyć, aby przetworzyć pakiet.
- Nieprawidłowe wartości
filter_age
lubfilter_age_16384th
: wartościfilter_age
(APFv4) ifilter_age_16384th
(APFv6) muszą być prawidłowo przekazywane do funkcjiaccept_packet()
iapf_run()
. Szczegółowe informacje o obliczaniu wartościfilter_age_16384th
znajdziesz w dokumentacji wapf_interpreter.h
. - APF nie jest włączony, gdy jest to wymagane: APF musi być włączony, gdy ekran jest wyłączony, a połączenie Wi-Fi jest nieaktywne lub ruch jest mniejszy niż 10 Mb/s.
- Obcięte pakiety przekazywane do
accept_packet()
lubapf_run()
: wszystkie pakiety unicast, broadcast i multicast przekazywane doaccept_packet()
lubapf_run()
muszą być kompletne. Przekazywanie do APF obciętych pakietów jest nieprawidłowe.
Testy APF
Od Androida 15 Android udostępnia testy CTS dla jednego i wielu urządzeń w przypadku integracji filtra APF i interpretera APF, aby zapewnić prawidłowe działanie APF. Oto opis celu każdego przypadku testowego:
ApfFilter
iapf_interpreter
test integracji: sprawdza, czyApfFilter
generuje prawidłowy kod bajtowy, aapf_interpreter
wykonuje kod prawidłowo, aby uzyskać oczekiwane wyniki.- CTS na 1 urządzenie APF:
używa 1 urządzenia do testowania funkcji APF na chipsecie Wi-Fi.
Potwierdza, że:
- APF włącza się, gdy ekran jest wyłączony, a ruch w sieci Wi-Fi jest mniejszy niż 10 Mb/s.
- Możliwości APF są prawidłowo zadeklarowane.
- Operacje odczytu i zapisu w obszarze pamięci APF są wykonywane prawidłowo, a obszar pamięci nie jest modyfikowany w nieoczekiwany sposób.
- Argumenty są prawidłowo przekazywane do
accept_packet()
lubapf_run()
. - Oprogramowanie sprzętowe zintegrowane z APFv4/APFv6 może odrzucać pakiety.
- Oprogramowanie sprzętowe zintegrowane z APFv6 może odpowiadać na pakiety.
- CTS na wiele urządzeń APF:
wykorzystuje 2 urządzenia (nadawcę i odbiorcę) do testowania zachowania filtrowania APF. Po stronie nadawcy generowane są różne typy pakietów, a test sprawdza, czy są one prawidłowo odrzucane, przekazywane lub odpowiadane na podstawie reguł skonfigurowanych w
ApfFilter
.
Dodatkowe instrukcje dotyczące testów integracji
Dodatkowo zdecydowanie zalecamy, aby dostawcy chipsetów uwzględnili testy APF w swoich zestawach testów integracji Wi-Fi z oprogramowaniem sprzętowym.
Zintegrowanie testów APF z zestawami testów integracji Wi-Fi w oprogramowaniu sprzętowym jest kluczowe dla weryfikacji prawidłowego działania APF w złożonych scenariuszach połączeń Wi-Fi, takich jak scenariusze połączeń Wi-Fi typu „make-before-break” lub roaming. Szczegółowe instrukcje dotyczące przeprowadzania testów integracyjnych znajdziesz w następnej sekcji.
Wymagania wstępne
Podczas przeprowadzania testów integracji wykonaj te czynności:
- Funkcja APF musi być włączona we wszystkich przypadkach testowych integracji (np. roaming, make-before-break).
- Na początku każdego testu wyczyść pamięć APF.
- Instaluj lub ponownie instaluj programy APF co 5 minut podczas testu.
Scenariusze testów
APF musi być aktywny podczas testów integracji. W tym dokumencie znajdziesz 2 programy APF, które można zainstalować podczas testowania. Programy są w formacie ciągu szesnastkowym, a tester musi przekonwertować ciąg szesnastkowy na binarny i zainstalować go w oprogramowaniu układowym, aby programy mogły być wykonywane przez apf_interpreter
. Podczas testu integracji tester powinien wysyłać pakiety, które powinny wywoływać logikę filtrowania w programie 1 i programie 2.
Program APF 1
Gdy ekran urządzenia jest włączony, zainstaluj program APF 1. Ten program może odrzucać nieszkodliwe pakiety, które nie mają wpływu na działanie urządzenia. Te pakiety służą do sprawdzania, czy filtr APF prawidłowo filtruje ruch w sieci.
Logika programu APF 1 jest następująca:
- Upuść i zwiększ licznik:
- Wartości EtherType:
0x88A2
,0x88A4
,0x88B8
,0x88CD
,0x88E1
,0x88E3
- Pakiety wykrywania lub żądania DHCP IPv4
- Pakiety RS
- Wartości EtherType:
- Przekazywanie i zwiększanie licznika: wszystkie pozostałe pakiety.
Kody 1-bajtowe programu APF są następujące:
6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
Program APF 2
Gdy ekran urządzenia jest wyłączony, zainstaluj program APF 2. Ten program odfiltrowuje wszystkie pakiety, które odfiltrowuje program APF 1, a także pakiety z żądaniami ping. Aby sprawdzić, czy program APF 2 jest prawidłowo zainstalowany, wyślij pakiety ping do testowanego urządzenia.
Logika programu APF 2 jest następująca:
- Upuść i zwiększ licznik:
- Wartości EtherType:
0x88A2
,0x88A4
,0x88B8
,0x88CD
,0x88E1
,0x88E3
- Pakiety wykrywania lub żądania DHCP IPv4
- Pakiety RS
- Wartości EtherType:
- Odrzucanie i zwiększanie licznika: pakiety żądań ping ICMP
- Przekazywanie i zwiększanie licznika: wszystkie inne pakiety
Kody programów APF składają się z 2 bajtów:
6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C007488A27C006F88A47C006A88B87C006588CD7C006088E17C005B88E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE87234120C84000E86DD0A1482093A0A368204856BE0721F120C84001008000A17820B01AB0D220E8204086BE472086BDCB03A01B87206B03A01B87201
Weryfikacja danych
Aby sprawdzić, czy program APF jest wykonywany, a pakiety są przekazywane lub odrzucane prawidłowo, wykonaj te czynności:
- Pobieranie i weryfikowanie regionu danych APF co 5 minut.
- Nie czyść licznika.
- Generuj pakiety testowe, aby wywołać każdą regułę filtrowania.
Sprawdź, czy liczniki zwiększają się w odpowiednich miejscach w pamięci:
Nazwa licznika Lokalizacja pamięci 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]
Pseudokod programów APF 1 i APF 2
Poniższy pseudokod szczegółowo wyjaśnia logikę programu APF 1 i programu 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