Filtr pakietów na Androida

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()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 do maxLen bez awarii, zawieszeń lub obcinania. Operacje zapisu nie mogą zmieniać żadnych bajtów między XmaxLen.
  • 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 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 apf_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() lub apf_run(): wszystkie pakiety unicast, broadcast i multicast przekazywane do accept_packet() lub apf_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:

  • ApfFilterapf_interpreter test integracji: sprawdza, czy ApfFilter generuje prawidłowy kod bajtowy, a apf_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() lub apf_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:

  1. Upuść i zwiększ licznik:
    1. Wartości EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. Pakiety wykrywania lub żądania DHCP IPv4
    3. Pakiety RS
  2. 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:

  1. Upuść i zwiększ licznik:
    1. Wartości EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. Pakiety wykrywania lub żądania DHCP IPv4
    3. Pakiety RS
  2. Odrzucanie i zwiększanie licznika: pakiety żądań ping ICMP
  3. 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