Filtr pakietów Androida

Filtr pakietów systemu Android (APF) umożliwia platformie kontrolowanie logiki sprzętowego filtrowania pakietów w czasie wykonywania. Pozwala to systemowi oszczędzać energię, odrzucając pakiety na sprzęcie, jednocześnie umożliwiając platformie Android zmianę reguł filtrowania w czasie wykonywania w oparciu o warunki sieciowe.

Przegląd APF

APF składa się z dwóch 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 odebranych przez sprzęt i decyduje, czy je zaakceptować, czy odrzucić.
  • 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ą frameworkowi Android zainstalowanie kodu bajtowego programu APF i odczytanie bieżących liczników. Moduł Network Stack Mainline może aktualizować kod bajtowy programu APF w dowolnym momencie, gdy APF jest uruchomiony.

Zaimplementowano kilka filtrów APF. Na przykład APF zawiera filtry usuwające niedozwolone typy eterów, filtrujące pakiety reklam routera IPv6 (RA), filtrujące ruch multiemisji i rozgłoszeniowy, jeśli blokada multiemisji nie jest utrzymywana, usuwające pakiety DHCP dla innych hostów i odrzucające niechciany protokół rozpoznawania adresów (ARP). oraz (odkrycie sąsiada) pakiety ND. Pełna lista filtrów jest zdefiniowana w ApfFilter .

Ponieważ kod generowania programu APF jest częścią modułu Network Stack, można aktualizować logikę filtrowania i dodawać nowe filtry poprzez comiesięczne aktualizacje Mainline.

Integracja APF

Interfejs API APF jest zdefiniowany w apf_interpreter.h . Kod oprogramowania sprzętowego Wi-Fi wywołuje int accept_packet() w celu określenia, czy pakiet powinien zostać odrzucony (wartość zwrócona zerem), czy przekazany (wartość zwrócona różna od zera). Instrukcje APF mają zmienną długość. Każda instrukcja ma długość co najmniej jednego bajtu. Kody instrukcji APF są zdefiniowane w apf.h

APF opiera się na dedykowanej pamięci. Pamięć jest wykorzystywana zarówno przez sam program APF, jak i do przechowywania danych, a pamięć nie może być czyszczona ani zapisywana przez chipset inaczej niż za pomocą metod APF HAL. Kod bajtowy APF wykorzystuje pamięć danych do przechowywania liczników zaakceptowanych i odrzuconych pakietów. Obszar danych można odczytać z platformy Android. Minimalna ilość pamięci dostępna dla APF musi wynosić 1024 bajty.

Debuguj plik APF

Aby sprawdzić, czy na urządzeniu jest włączona funkcja APF, wyświetlić bieżący program i wyświetlić aktualne liczniki, uruchom polecenie adb shell dumpsys network_stack . Poniżej znajduje się 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 chipy Wi-Fi obsługują APF (wersja 4).
  • Last program : Ta sekcja zawiera najnowszy zainstalowany plik binarny programu APF w formacie ciągu szesnastkowego.
  • APF packet counters : ta sekcja pokazuje, ile pakietów zostało przekazanych lub odrzuconych przez APF i konkretne przyczyny.

Aby zdekodować i zdezasemblować kod na czytelny dla człowieka język asemblera, użyj narzędzia apf_disassembler . Aby skompilować plik wykonywalny, uruchom komendę m apf_disassembler . Poniżej znajduje się 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 komendę m apf_run . Poniżej znajduje się przykład sprawdzania pojedynczego pakietu za pomocą komendy apf_run .

Aby zapewnić prezentację surowego pakietu w postaci binarnego ciągu szesnastkowego, użyj opcji --packet . Aby podać szesnastkowy ciąg binarny obszaru danych, który jest używany do przechowywania licznika APF , użyj --data option . Ponieważ każdy licznik ma długość 4 bajtów, obszary danych muszą być wystarczająco długie, aby zapobiec przepełnieniu 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 komendy apf_run w następujący sposób:

out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b989401df06006b947c01d888a27c01d388a47c01ce88b87c01c988cd7c01c488e17c01bf88e384004408066a0e6bdca401a5000600010800060412147a1e016bd884019900021a1c6b907c01960000686bd4a401820006ffffffffffff6a266bc0a4017b0004c0a82b056bf874017084005f08000a17821f1112149c00181fffab0d2a108211446a3239a20506fabe589435936bf47401470a1e52f06bb07c014200e06bb81a1e7e00000135ffffffff6bb47e0000012ac0a82bff6be868a401160006ffffffffffff6bbc7401176bf074010c7c001086dd686bd0a2fb06ffffffffffff6bcc72fd0a147a0b3a6b9c0a267af1ff6be072e70a366bac7ae6858218886a26a2040fff02000000000000000000000000006ba872cbaa0e82be8eaa0f8c00b7025868a2a40ffabe5894359352a9874d08aa86dd606a12a2792600583afffe80000000000000f7d4e8ccd81ddb43fe80000000000000f8be58fffe94359386006a3aa272024108123c94006b02586a3ea25e0800000000000000006a56a25504030440c01a5a94004e02581a5e94004702586a62a23e04000000006a66a229102409891f9a26ae6d00000000000000006a76a22004190300001a7a94001902586a7ea204102409891f9a26ae6dba98e781ca9ef9ba6bc872086be4b03a01b87206b03a01b87201 --pcap apf.pcap --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
37 packets dropped
1733 packets passed
Data: 00000000000000000000000000000000000000000200000005000000000000000000000002000000000000001b000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000689000000000000003c00000000000000000000000000000000000006ea