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 jednocześnie umożliwia platformie Androida zmianę reguł 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 (zazwyczaj na chipsecie Wi-Fi). Interpreter APF uruchamia kod bajtowy APF na pakietach odbieranych 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 Wi-Fi HAL umożliwiają platformie Androida instalowanie kodu bajtowego programu APF i odczytywanie bieżących liczników. Moduł Network Stack Mainline może w dowolnym momencie zaktualizować kod bajtowy programu APF, gdy APF jest uruchomiony.

Zaimplementowano kilka filtrów APF. APF zawiera na przykład filtry odrzucające niedozwolone typy ethertype, filtrujące pakiety RA (Router Advertisement) IPv6, filtrujące ruch multicastowy i broadcastowy, jeśli nie jest włączona blokada multicastowa, odrzucające pakiety DHCP dla innych hostów oraz odrzucające niechciane pakiety ARP (Address Resolution Protocol) i ND (Neighbor Discovery). Jeśli oprogramowanie układowe obsługuje APFv6, ApfFilter generuje też reguły odpowiadania na typowe typy pakietów, które w przeciwnym razie wymagałyby wybudzenia procesora, np. zapytania ARP i zapytania NS . Pełna lista filtrów jest zdefiniowana w ApfFilter.

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

Wersja APF

Poniższa lista opisuje historię zmian APF:

  • APFv6: wprowadzona w Androidzie 15, ta wersja obsługuje filtrowanie pakietów, zawiera liczniki do debugowania i pomiarów 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, ta wersja obsługuje filtrowanie pakietów.

Integracja APF

Interfejsy API APF między interpreterem APF a sprzętem są zdefiniowane w apf_interpreter.h (APFv4, APFv6). Kod oprogramowania układowego Wi-Fi wywołuje 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 ma zostać przesłany, apf_run() też zwraca zero, ponieważ jego pakiet nie musi być przekazywany do procesora aplikacji. Jeśli oprogramowanie układowe obsługuje APFv6, musi implementować interfejsy API apf_allocate_buffer() i apf_transmit_buffer(). Interpreter APF wywołuje te 2 interfejsy API podczas logiki transmisji 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 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 APF HAL. Kod bajtowy APF używa pamięci do przechowywania liczników zaakceptowanych i odrzuconych pakietów. Region danych możesz odczytać z platformy Androida. Instrukcje APF są wydajne pod względem pamięci, ale maksymalne wykorzystanie ich potencjału w zakresie oszczędzania energii i funkcjonalności wymaga złożonych, dynamicznych reguł filtrowania. Ta złożoność wymaga dedykowanej części pamięci w chipsecie. Minimalne wymagania dotyczące pamięci w przypadku APFv4 to 1024 bajty, a w przypadku APFv6 – 2048 bajtów. Zdecydowanie zalecamy jednak przydzielenie 4096 bajtów na APFv6, aby zapewnić optymalną wydajność. Interpreter APF musi być skompilowany w oprogramowaniu układowym. Interpretery APFv4 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.wbudowaną obsługą sum kontrolnych i wbudowanym kodem dekompresji DNS) ma około 4 KB.

Filtry APF mogą działać razem z innymi filtrami specyficznymi dla dostawcy chipsetu w oprogramowaniu układowym. Możesz zdecydować, czy logika filtrowania ma być uruchamiana przed czy po procesie filtrowania APF. Jeśli pakiet zostanie odrzucony przed dotarciem do filtra APF, filtr APF nie przetworzy pakietu.

Aby sprawdzić prawidłowe działanie filtra APF, gdy APF jest włączony, upewnij się, że oprogramowanie układowe zapewnia filtrowi APF 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 sprawdzić rzeczywisty wygenerowany program, 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 odciążające APFv6. Więcej informacji znajdziesz w dokumentacji w plikach narzędzi Pythona.

Debugowanie APF

Aby sprawdzić, czy APF jest włączony na urządzeniu, wyświetl bieżący program, pokaż bieżące 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ładu polecenia adb shell dumpsys network_stack obejmują:

  • ApfCapabilities{version: 4, maxSize: 4096, format: 1}: oznacza to, że chipsety Wi-Fi obsługują APF (wersja 4).
  • Last program: ta sekcja zawiera najnowszy zainstalowany program APF w formacie ciągu szesnastkowego.
  • APF packet counters: ta sekcja pokazuje, ile pakietów zostało przekazanych lub odrzuconych przez APF oraz konkretne przyczyny.

Aby zdekodować i zdeasemblować 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. 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 w trybie 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 uruchamiane w interpreterze APFv4. Przekazanie argumentu --v6 do apf_run umożliwia uruchomienie go w interpreterze APFv6. Wszystkie inne argumenty mogą być używane zarówno w 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, aby sprawdzić, czy pakiet można odrzucić lub przekazać.

Aby podać szesnastkowy ciąg binarny 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 opcji --data. Ponieważ każdy licznik ma 4 bajty długości, 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 pliku pcap pobranym 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 wyświetla szczegółowe dane wyjściowe każdego kroku wykonywania interpretera, co jest przydatne do debugowania. W tym przykładzie wprowadzasz do programu APF pakiet zapytania ARP. Dane wyjściowe pokazują, że zapytanie ARP zostało odrzucone, ale wygenerowano pakiet odpowiedzi. Szczegóły tego wygenerowanego pakietu są widoczne w sekcji transmitted packet.

Typowe problemy z integracją

W tej sekcji opisujemy kilka typowych problemów występujących 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 API HAL) może modyfikować region pamięci APF.
  • Problemy z instalacją programów APF o rozmiarze X bajtów (X <= maxLen): oprogramowanie układowe musi obsługiwać odczytywanie i zapisywanie programów o dowolnej długości do maxLen bez awarii, zawieszeń ani obcinania. Operacje zapisu nie mogą zmieniać żadnych bajtów między X a maxLen.
  • Implementacja APF w kodzie sterownika: APF należy implementować tylko w oprogramowaniu układowym, a nie w kodzie sterownika. W przeciwnym razie nie ma korzyści z oszczędzania energii, ponieważ procesor musi się wybudzić, 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() i apf_run(). Szczegółowe informacje o obliczaniu filter_age_16384th znajdziesz w dokumentacji w apf_interpreter.h.
  • APF nie jest włączony, gdy jest wymagany: 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 unicastowe, broadcastowe i multicastowe przekazywane do accept_packet() lub apf_run() muszą być kompletne. Przekazywanie obciętych pakietów do APF jest niedozwolone.

Testy APF

Od Androida 15 Android udostępnia przypadki testowe Compatibility Test Suite (CTS) na jedno i wiele urządzeń do integracji filtra APF i interpretera APF, aby sprawdzić prawidłowe działanie APF. Oto zestawienie celu każdego przypadku testowego:

  • Test integracji ApfFilter i apf_interpreter: sprawdza, czy ApfFilter generuje prawidłowy kod bajtowy, a apf_interpreter prawidłowo wykonuje kod, aby uzyskać oczekiwane wyniki.
  • **CTS APF na jedno urządzenie**: używa jednego urządzenia do testowania działania APF na chipsecie Wi-Fi. Potwierdza, że:
    • APF włącza się, gdy ekran jest wyłączony, a ruch Wi-Fi jest mniejszy niż 10 Mb/s.
    • Możliwości APF są prawidłowo zadeklarowane.
    • Operacje odczytu i zapisu w regionie pamięci APF są wykonywane prawidłowo, a region pamięci nie jest nieoczekiwanie modyfikowany.
    • Argumenty są prawidłowo przekazywane do accept_packet() lub apf_run().
    • Oprogramowanie układowe zintegrowane z APFv4/APFv6 może odrzucać pakiety.
    • Oprogramowanie układowe zintegrowane z APFv6 może odpowiadać na pakiety.
  • CTS APF na wiele urządzeń: używa 2 urządzeń (nadawcy i odbiorcy) do testowania zachowania filtrowania APF. Po stronie nadawcy generowane są różne typy pakietów, a test potwierdza, czy są one prawidłowo odrzucane, przekazywane lub na nie odpowiadane na podstawie reguł skonfigurowanych w ApfFilter, aby sprawdzić prawidłowe działanie APF.

Dodatkowe instrukcje dotyczące testów integracji

Zdecydowanie zalecamy też uwzględnienie testowania APF w pakietach testów integracji Wi-Fi oprogramowania układowego.

Zintegrowanie testowania APF z pakietami testów integracji Wi-Fi oprogramowania układowego jest niezbędne do sprawdzenia 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 integracji znajdziesz w następnej sekcji.

Wymagania wstępne

Podczas przeprowadzania 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.
  • Instaluj lub ponownie instaluj programy APF co 5 minut podczas testu.

Scenariusze testowe

APF musi być aktywny podczas testów integracji. Ten dokument zawiera 2 programy APF, które możesz zainstalować podczas testowania. Programy są w formacie ciągu szesnastkowego. Musisz przekonwertować ciąg szesnastkowy na binarny i zainstalować programy w oprogramowaniu układowym, aby apf_interpreter mógł je wykonać. Podczas testu integracji należy wysyłać pakiety, które powinny 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 mają wpływu na działanie urządzenia. Te pakiety służą do testowania, czy APF prawidłowo filtruje ruch w sieci.

Logika programu APF 1 jest następująca:

  1. Odrzuć i zwiększ licznik:
    1. Wartości EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. Pakiety IPv4 DHCP discover lub request
    3. Pakiety RS
  2. Przekaż i zwiększ licznik: wszystkie inne pakiety.

Kody bajtowe programu APF 1 są następujące:

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
Program APF 2

Gdy ekran urządzenia jest wyłączony, zainstaluj program APF 2. Ten program filtruje wszystkie pakiety, które filtruje 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.

Logika programu APF 2 jest następująca:

  1. Odrzuć i zwiększ licznik:
    1. Wartości EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. Pakiety IPv4 DHCP discover lub request
    3. Pakiety RS
  2. Odrzuć i zwiększ licznik: pakiety żądań ping ICMP.
  3. Przekaż i zwiększ licznik: wszystkie inne pakiety.

Kody bajtowe programu APF 2 są następujące:

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C007488A27C006F88A47C006A88B87C006588CD7C006088E17C005B88E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE87234120C84000E86DD0A1482093A0A368204856BE0721F120C84001008000A17820B01AB0D220E8204086BE472086BDCB03A01B87206B03A01B87201
Weryfikacja danych

Aby sprawdzić, czy program APF wykonuje się prawidłowo i przekazuje lub odrzuca pakiety, wykonaj te czynności:

  • Pobieraj i weryfikuj region danych APF co 5 minut.
  • Nie czyść licznika.
  • Generuj pakiety testowe, aby wywołać każdą regułę filtra.
  • Sprawdź przyrosty 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 programu APF 1 i programu 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