Filtr pakietów na Androida

Filtr pakietów Androida (APF) umożliwia kontrolowanie logiki filtrowania pakietów sprzętowych w czasie działania. Dzięki temu system może oszczędzać energię, odrzucając pakiety na poziomie sprzętu, a jednocześnie umożliwić platformie Android zmianę reguł filtrowania w czasie działania na podstawie warunków sieci.

Omówienie APF

APF składa się z 2 głównych komponentów:

  • Interpreter APF działa na sprzęcie sieciowym (zazwyczaj na układzie Wi-Fi). Interpreter APF wykonuje kod bajtowy APF na pakietach otrzymanych przez sprzęt i decyduje, czy je zaakceptować, odrzucić czy na nie odpowiedzieć.
  • Kod generowania programu APF działa 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 bajtkodu programu APF i odczytywanie bieżących liczników. Moduł głównego modułu sieci może aktualizować bajtowy kod programu APF w dowolnym momencie, gdy APF jest uruchomiony.

Wdrożone jest kilka filtrów APF. Na przykład APF zawiera filtry, które odrzucają niedozwolone typy etheru, filtrują pakiety reklamowe routera IPv6 (RA), filtrują ruch multicast i broadcast, jeśli nie jest zablokowany blokada multicastu, odrzucają pakiety DHCP dla innych hostów oraz odrzucają niechciane pakiety protokołu ARP (adresowania adresów) i pakiety ND (wykrywania sąsiadów). Jeśli oprogramowanie układu scalonego obsługuje APFv6, ApfFilter generuje też reguły, aby odpowiadać na typowe typy pakietów, które w przeciwnym razie wymagałyby przebudzenia procesora, aby odpowiedzieć, takie jak zapytania ARP i NS. Pełna lista filtrów jest zdefiniowana w pliku ApfFilter.

Kod generowania programu APF jest częścią modułu Network Stack, więc możesz używać comiesięcznych [aktualizacji Mainline] do dodawania nowych filtrów i aktualizowania logiki filtrowania.

Wersja APF

Poniżej znajdziesz listę zmian w APF:

  • APFv6: ta wersja została wprowadzona w Androidzie 15. Obsługuje filtrowanie pakietów, zawiera liczniki do debugowania i dane oraz umożliwia przesyłanie pakietów.
  • APFv4: ta wersja została wprowadzona w Androidzie 10 i obsługuje filtrowanie pakietów oraz zawiera liczniki do debugowania i tworzenia danych.
  • APFv2: ta wersja została wprowadzona w Androidzie 7 i obsługuje filtrowanie pakietów.

Integracja z APF

Interfejsy APF między interpreterem APF a sprzętem są zdefiniowane w apf_interpreter.h(APFv4, APFv6). Kod oprogramowania układu Wi-Fi wywołuje funkcję accept_packet() w APFv4 lub apf_run() w APFv6, aby określić, czy pakiet ma zostać odrzucony (wartość zwracana równa 0) czy przekazany procesorowi aplikacji (wartość zwracana różna od 0). Jeśli pakiet musi zostać przesłany, apf_run() zwraca też 0, ponieważ jego pakiet nie musi być przekazywany do procesora aplikacji. Jeśli oprogramowanie sprzętowe obsługuje APFv6, musi wdrażać interfejsy API apf_allocate_buffer()apf_transmit_buffer(). Interpreter APF wywołuje te 2 interfejsy API podczas logiki przesyłania pakietów. Instrukcje APF mają zmienną długość. Każda instrukcja ma co najmniej 1 bajt długości. Kody instrukcji APF są zdefiniowane w apf.h w przypadku APFv4 i wstawiane bezpośrednio w apf_interpreter.c w przypadku APFv6.

APF korzysta z dedykowanej pamięci. Pamięć jest używana zarówno do obsługi programu APF, jak i do przechowywania danych. Nie może być kasowana ani zapisywana przez chipset, z wyjątkiem metod APF HAL. Bytekod APF używa pamięci danych do przechowywania liczników dla akceptowanych i odrzuconych pakietów. Region danych można odczytać z ramy Androida. Instrukcje APF są wydajne pod względem pamięci, ale zmaksymalizowanie ich oszczędności energii i potencjału funkcjonalności wymaga stosowania złożonych, dynamicznych reguł filtrowania. Ta złożoność wymaga dedykowanej części pamięci na procesorze. Minimalne wymagania dotyczące pamięci w przypadku APFv4 to 1024 bajty, a APFv6 – 2048 bajtów. Zalecamy jednak przydzielenie 14 096 bajtów na potrzeby APFv6, aby zapewnić optymalną wydajność. Interpreter APF musi zostać skompilowany do oprogramowania układowego. Interpretatory APFv4 i APFv6 są optymalizowane pod kątem rozmiaru kodu. W architekturze arm32 skompilowany interpreter APFv4 zajmuje około 1,8 KB, a bardziej złożony interpreter APFv6 z dodatkowymi funkcjami (np.obsługą natywnej sumy kontrolnej i natywnym kodem dekompresji DNS) zajmuje około 4 KB.

Filtry APF mogą działać razem z innymi filtrami dostawców układów scalonych w oprogramowaniu układu. Dostawcy układów scalonych mogą uruchamiać logikę filtrowania przed lub po procesie filtrowania APF. Jeśli pakiet zostanie odrzucony przed dotarciem do filtra APF, filtr APF nie przetworzy tego pakietu.

Aby zapewnić prawidłowe działanie filtra APF, gdy jest on włączony, oprogramowanie sprzętowe musi zapewnić dostęp do całego pakietu, a nie tylko nagłówka.

Przykłady programu APF

ApfTest i ApfFilterTest zawierają przykładowe programy testowe, które pokazują, jak działa każdy filtr APF. Aby zapoznać się z wygenerowanym programem, zmodyfikuj przypadek testowy, aby wydrukować program jako ciąg szesnastkowy.

Folder testdata zawiera przykładowe programy APFv4 dla filtrów APF RA. Folder samples zawiera narzędzia Pythona, które generują programy przenoszenia APFv6. Więcej informacji znajdziesz w dokumentacji w plikach narzędzia Python.

Debugowanie APF

Aby sprawdzić, czy na urządzeniu jest włączone APF, wyświetl aktualny program, pokaż aktualne liczniki i uruchom polecenie adb shell dumpsys network_stack. Oto 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 układy Wi-Fi obsługują APF (wersja 4).
  • Last program: ta sekcja zawiera najnowszy zainstalowany program binarny APF w formacie ciągu szesnastkowego.
  • APF packet counters: ta sekcja pokazuje, ile pakietów zostało przekazanych lub odrzuconych przez APF oraz konkretne powody.

Aby zdekodować i zdemontować kod na zrozumiały dla człowieka język asemblera, użyj narzędzia apf_disassembler. Aby skompilować plik wykonywalny, uruchom polecenie m apf_disassembler. Oto 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 zarówno interpretery APFv4, jak i APFv6.

Poniżej znajdziesz instrukcję dotyczącą polecenia apf_run. Domyślnie polecenie apf_run jest wykonywane w tłumaczniku APFv4. Przekazanie argumentu --v6 do apf_run pozwala na uruchomienie go w tłumaczu APFv6. Pozostałe argumenty mogą być używane 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ć ciąg bajtów szesnastkowych nieprzetworzonego pakietu, użyj opcji --packet. Aby podać ciąg binarny szesnastkowy regionu danych, który służy do przechowywania licznika APF, użyj elementu --data option. Ponieważ każdy licznik ma długość 4 bajtów, regiony danych muszą być wystarczająco długie, aby nie dopuścić 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 przesyłania 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 zapewnia szczegółowy wynik każdego kroku w wykonywaniu interpretera, co jest przydatne podczas debugowania. W tym przykładzie do programu APF przesyłamy pakiet zapytania ARP. Dane wyjściowe wskazują, że zapytanie ARP zostało odrzucone, ale wygenerowano pakiet odpowiedzi. Szczegóły wygenerowanego pakietu znajdziesz w sekcji transmitted packet.

Typowe problemy z integracją

W tej sekcji omawiamy kilka typowych problemów występujących podczas integracji z APF:

  • Nieoczekiwane wyczyszczanie regionu danych: pamięć APF musi być całkowicie przeznaczona dla APF. Tylko kod interpretera lub kod frameworka (za pomocą interfejsu HAL API) może modyfikować region pamięci APF.
  • Problemy z instalacją programów APF o długości X bajtów (X <= maxLen): Firmware musi obsługiwać odczyt lub zapisywanie dowolnej długości programu do maxLen bez awarii, zawieszania się ani obcinania. Zapisy nie mogą zmieniać żadnych bajtów między XmaxLen.
  • Implementacja APF w kodzie sterownika: APF powinien być implementowany tylko w oprogramowaniu układu, a nie w kodzie sterownika. W przeciwnym razie nie ma żadnych korzyści związanych z oszczędzaniem energii, ponieważ procesor musi się obudzić, aby przetworzyć pakiet.
  • Nieprawidłowe wartości filter_age lub filter_age_16384th: wartości filter_age (APFv4) i filter_age_16384th (APFv6) muszą być prawidłowo przekazywane do funkcji accept_packet()apf_run(). Szczegółowe informacje o obliczaniu wartości filter_age_16384th znajdziesz w dokumentacji w sekcji apf_interpreter.h.
  • APF nie jest włączone, gdy jest wymagane: APF musi być włączone, gdy ekran jest wyłączony, a połączenie Wi-Fi jest nieaktywne lub ruch jest mniejszy niż 10 Mbps.
  • Przesłane do accept_packet() lub apf_run() pakiety zostały obcięte: wszystkie pakiety unicast, broadcast i multicast przesyłane do accept_packet() lub apf_run() muszą być kompletne. Przekazywanie uciętego pakietu do APF jest nieprawidłowe.

Testy APF

Od Androida 15 platforma udostępnia przypadki testowe CTS dotyczące zarówno filtra APF, jak i jego interpretacji na jednym urządzeniu i na wielu urządzeniach, aby zapewnić prawidłową funkcjonalność APF. Oto szczegółowy opis celu każdego przypadku testowego:

  • ApfFilterapf_interpreter test integracji: sprawdza, czy ApfFilter generuje prawidłowy kod bajtowy, a apf_interpreter prawidłowo wykonuje kod, aby uzyskać oczekiwane wyniki.
  • CTS APF na jednym urządzeniu: Testowanie funkcji APF na jednym urządzeniu z użyciem chipsetu Wi-Fi. Potwierdza, że:
    • APF włącza się, gdy ekran jest wyłączony, a ruch Wi-Fi jest mniejszy niż 10 Mbps.
    • funkcje APF są prawidłowo zadeklarowane;
    • Operacje odczytu i zapisu w regionie pamięci APF są wykonywane pomyślnie, a region pamięci nie jest nieoczekiwanie modyfikowany.
    • Argumenty są poprawnie przekazywane do accept_packet() lub apf_run().
    • Oprogramowanie sprzętowe zintegrowane z APFv4/APFv6 może gubić pakiety.
    • Oprogramowanie sprzętowe zintegrowane z APFv6 może odpowiadać na pakiety.
  • CTS dla wielu urządzeń w ramach APF: wykorzystuje 2 urządzenia (jedno nadające, drugie odbierające) do testowania działania filtrowania APF. Po stronie nadawcy generowane są różne typy pakietów, a test potwierdza, czy są one prawidłowo odrzucane, przekazywane dalej lub odbierane na podstawie reguł skonfigurowanych w ApfFilter.

Dodatkowe instrukcje dotyczące testów integracji

Ponadto zdecydowanie zalecamy, aby dostawcy chipsetów uwzględnili testowanie APF w swoich własnych pakietach testów integracji z firmwarem Wi-Fi.

Ważne jest, aby zintegrować testy APF z kompletnymi pakietami testów integracji z Wi-Fi. Pozwoli to na sprawdzenie prawidłowej funkcjonalności APF w skomplikowanych scenariuszach połączenia Wi-Fi, takich jak scenariusze połączenia Wi-Fi typu „make-before-break” lub roamingu Wi-Fi. Szczegółowe instrukcje dotyczące wykonywania testów integracyjnych znajdziesz w następnym rozdziale.

Wymagania wstępne

Podczas wykonywania testów integracji:

  • APF musi być włączony we wszystkich przypadkach testów integracji (np. roaming, make-before-break).
  • Na początku każdego testu wyczyść pamięć APF.
  • instalować lub ponownie instalować programy APF co 5 minut podczas testu.

Scenariusze testowe

APF musi być aktywny podczas testów integracji. W tym dokumencie opisano 2 programy APF, które można zainstalować podczas testowania. Programy są w formacie ciągu szesnastkowego, 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 mają wywołać 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 wpływają na działanie urządzenia. Te pakiety są używane do testowania, czy APF poprawnie filtruje ruch w sieci.

Zasada programu APF 1:

  1. Upuszczanie i zwiększanie licznika:
    1. Wartości EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. Pakiety IPv4 DHCP wykrywania lub żądania
    3. Pakiety RS
  2. Przekazywanie i zwiększanie wartości licznika: wszystkie pozostałe pakiety.

Kody 1-bajtowe programu APF:

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
Program APF 2

Gdy ekran urządzenia jest wyłączony, zainstaluj program APF 2. Ten program odfiltrowuje wszystkie pakiety, które są odfiltrowywane przez program APF 1, a także pakiety żądań ping. Aby sprawdzić, czy program APF 2 jest prawidłowo zainstalowany, wyślij pakiety ping do testowanego urządzenia.

Zasada programu APF 2:

  1. Upuszczanie i zwiększanie licznika:
    1. Wartości EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. Pakiety IPv4 DHCP wykrywania lub żądania
    3. Pakiety RS
  2. Upuszczanie i zwiększanie licznika: pakiety żądań ICMP ping
  3. Przekazywanie i zwiększanie wartości licznika: wszystkie inne pakiety

Kody 2-bajtowe programu APF:

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C007488A27C006F88A47C006A88B87C006588CD7C006088E17C005B88E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE87234120C84000E86DD0A1482093A0A368204856BE0721F120C84001008000A17820B01AB0D220E8204086BE472086BDCB03A01B87206B03A01B87201
Weryfikacja danych

Aby sprawdzić, czy program APF jest wykonywany, a pakiety są przekazywane lub odrzucane prawidłowo, wykonaj te czynności:

  • Co 5 minut pobieraj i sprawdzaj region danych APF.
  • Nie czyść licznika.
  • generować pakiety testowe, aby aktywować poszczególne reguły filtra.
  • Sprawdzanie przyrostów licznika za pomocą tych lokalizacji 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 dla programu APF 1 i APF 2

Poniższy pseudokod szczegółowo opisuje logikę programów APF 1 i 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