Android Packet Filter

Android Packet Filter (APF) memungkinkan framework mengontrol logika pemfilteran paket hardware saat runtime. Hal ini memungkinkan sistem menghemat daya dengan menghapus paket di hardware, sekaligus memungkinkan framework Android mengubah aturan pemfilteran saat runtime berdasarkan kondisi jaringan.

Ringkasan APF

APF terdiri dari dua komponen utama:

  • Penafsir APF berjalan di hardware jaringan (biasanya, chipset Wi-Fi). Penafsir APF menjalankan bytecode APF pada paket yang diterima oleh hardware dan memutuskan apakah akan menerima, menghapus, atau membalasnya.
  • Kode pembuatan program APF berjalan di CPU utama. Kode ini membuat dan mengupdate program APF sesuai dengan status jaringan dan perangkat.

Metode HAL Wi-Fi memungkinkan framework Android menginstal bytecode program APF dan membaca penghitung saat ini. Modul Mainline Stack Jaringan dapat mengupdate bytecode program APF kapan saja saat APF berjalan.

Ada beberapa filter APF yang diterapkan. Misalnya, APF menyertakan filter untuk menghapus ethertype yang tidak diizinkan, memfilter paket iklan router IPv6 (RA), memfilter traffic multicast dan broadcast jika kunci multicast tidak ditahan, menghapus paket DHCP untuk host lain, dan menghapus paket address resolution protocol (ARP) dan neighbor discovery (ND) yang tidak diminta. Jika firmware mendukung APFv6, ApfFilter juga menghasilkan aturan untuk membalas jenis paket umum yang memerlukan CPU untuk aktif agar dapat merespons, seperti kueri ARP dan kueri NS. Daftar lengkap filter ditentukan di ApfFilter.

Karena kode pembuatan program APF adalah bagian dari modul Stack Jaringan, Anda dapat menggunakan [Update utama bulanan untuk menambahkan filter baru dan memperbarui logika pemfilteran.

Revisi APF

Daftar berikut menjelaskan histori revisi APF:

  • APFv6: Diperkenalkan di Android 15, versi ini mendukung pemfilteran paket, menyertakan penghitung untuk proses debug dan metrik, serta mendukung transmisi paket.
  • APFv4: Diperkenalkan di Android 10, versi ini mendukung pemfilteran paket dan menyertakan penghitung untuk proses debug dan metrik.
  • APFv2: Diperkenalkan di Android 7, versi ini mendukung pemfilteran paket.

Integrasi APF

API APF antara penafsir APF dan hardware ditentukan di apf_interpreter.h (APFv4, APFv6). Kode firmware Wi-Fi memanggil accept_packet() di APFv4 atau apf_run() di APFv6 untuk menentukan apakah paket harus dihapus (nilai yang ditampilkan nol) atau diteruskan ke pemroses aplikasi (nilai yang ditampilkan bukan nol). Jika paket perlu ditransmisikan, apf_run() juga menampilkan nol karena paketnya tidak perlu diteruskan ke pemroses aplikasi. Jika firmware mendukung APFv6, firmware tersebut harus mengimplementasikan API apf_allocate_buffer() dan apf_transmit_buffer(). Penafsir APF memanggil kedua API ini selama logika transmisi paket. Petunjuk APF memiliki panjang variabel. Setiap instruksi memiliki panjang minimal 1 byte. Kode petunjuk APF ditentukan dalam apf.h untuk APFv4 dan disisipkan langsung dalam apf_interpreter.c untuk APFv6.

APF mengandalkan memori khusus. Memori digunakan untuk program APF itu sendiri dan untuk penyimpanan data, dan memori tidak boleh dihapus atau ditulis oleh chipset kecuali melalui metode HAL APF. Bytecode APF menggunakan penyimpanan data untuk menyimpan penghitung untuk paket yang diterima dan dihapus. Wilayah data dapat dibaca dari framework Android. Petunjuk APF hemat memori, tetapi memaksimalkan potensi penghematan daya dan fungsinya memerlukan aturan pemfilteran dinamis yang kompleks. Kompleksitas ini memerlukan bagian khusus memori di chipset. Persyaratan memori minimum untuk APFv4 adalah 1.024 byte, sedangkan APFv6 memerlukan 2.048 byte. Namun, sebaiknya alokasikan 4096 byte untuk APFv6 guna memastikan performa optimal. Penafsir APF harus dikompilasi ke dalam firmware. Penafsir APFv4 dan APFv6 dioptimalkan untuk ukuran kode. Pada arsitektur arm32, penafsir APFv4 yang dikompilasi berukuran sekitar 1,8 KB, sedangkan penafsir APFv6 yang lebih kompleks, dengan fitur tambahan (misalnya, dukungan checksum native dan kode dekompresi DNS native), berukuran sekitar 4 KB.

Filter APF dapat berfungsi bersama filter khusus vendor chipset lainnya dalam firmware. Vendor chipset dapat memilih untuk menjalankan logika pemfilteran sebelum atau setelah proses pemfilteran APF. Jika paket dihapus sebelum mencapai filter APF, filter APF tidak akan memproses paket.

Untuk memastikan fungsi filter APF yang benar, saat APF diaktifkan, firmware harus memberikan filter APF dengan akses ke seluruh paket, bukan hanya header, saat APF diaktifkan.

Contoh program APF

ApfTest dan ApfFilterTest berisi contoh program pengujian yang menggambarkan cara kerja setiap filter APF. Untuk mempelajari program yang sebenarnya dihasilkan, ubah kasus pengujian untuk mencetak program sebagai string hex.

Folder testdata berisi contoh program APFv4 untuk filter RA APF. Folder samples berisi utilitas Python yang menghasilkan program offload APFv6. Untuk mengetahui detail selengkapnya, lihat dokumentasi dalam file utilitas Python.

Men-debug APF

Untuk memeriksa apakah APF diaktifkan di perangkat, tampilkan program saat ini, tampilkan penghitung saat ini, dan jalankan perintah adb shell dumpsys network_stack. Berikut adalah contoh perintah ini:

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

Output untuk contoh perintah adb shell dumpsys network_stack ini mencakup hal berikut:

  • ApfCapabilities{version: 4, maxSize: 4096, format: 1}: Artinya, chip Wi-Fi mendukung APF (versi 4).
  • Last program: Bagian ini adalah biner program APF terbaru yang diinstal dalam format string hex.
  • APF packet counters: Bagian ini menunjukkan jumlah paket yang diteruskan atau dihapus oleh APF dan alasannya.

Untuk mendekode dan menyambungkan kode ke dalam bahasa assembler yang dapat dibaca manusia, gunakan alat apf_disassembler. Untuk mengompilasi biner yang dapat dieksekusi, jalankan perintah m apf_disassembler. Berikut adalah contoh cara menggunakan alat 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
......

Untuk memeriksa hasil APF secara offline, gunakan alat apf_run. Untuk mengompilasi biner yang dapat dieksekusi, jalankan perintah m apf_run. Alat apf_run mendukung penafsir APFv4 dan APFv6.

Berikut adalah manual untuk perintah apf_run. Secara default, perintah apf_run berjalan di penafsir APFv4. Meneruskan argumen --v6 ke apf_run memungkinkan argumen tersebut berjalan pada penafsir APFv6. Semua argumen lainnya dapat digunakan untuk APFv4 dan 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.

Berikut adalah contoh untuk meneruskan satu paket ke APF guna memeriksa apakah paket dapat dihapus atau diteruskan.

Untuk memberikan presentasi string biner hex dari paket mentah, gunakan opsi --packet. Untuk memberikan string biner hex dari region data, yang digunakan untuk menyimpan penghitung APF, gunakan --data option. Karena setiap penghitung memiliki panjang 4 byte, region data harus cukup panjang untuk memastikan tidak terjadi overflow buffering.

out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b9494010c06006b907c010588a27c010088a47c00fb88b87c00f688cd7c00f188e17c00ec88e384003908066a0e6bdca2d40600010800060412147a18016bd882ca021a1c6b8c7ac900686bd4a2b706ffffffffffff6a266bbca2b204c0a814656bf872a8120c84005808000a17821e1112149c00171fffab0d2a108210446a3239a204064651dbcc88ff6bf4727e0a1e52f06bac7a7be06bb41a1e7e0000006effffffff6bb07e00000063c0a814ff6be868a25106ffffffffffff6bb872536bf072497c001086dd686bd0a23806ffffffffffff6bc8723a0a147a0b3a6b980a267a2eff6be072240a366ba87a23858218886a26a2040fff02000000000000000000000000006ba472086be4b03a01b87206b03a01b87201 --packet 5ebcd79a8f0dc244efaab81408060001080006040002c244efaab814c0a8ca1e5ebcd79a8f0d --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Packet passed
Data: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000001

Untuk memeriksa hasil APF terhadap file pcap yang diambil oleh tcpdump, gunakan perintah apf_run sebagai berikut:

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

Untuk menguji kemampuan transmisi APFv6, gunakan perintah apf_run sebagai berikut:

$ 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

Saat Anda menggunakan parameter --trace, alat apf_run akan memberikan output mendetail dari setiap langkah dalam eksekusi penafsir, yang berguna untuk proses debug. Dalam contoh ini, kita memasukkan paket kueri ARP ke dalam program APF. Output menunjukkan bahwa kueri ARP dihapus, tetapi paket balasan dibuat. Detail paket yang dihasilkan ini ditampilkan di bagian transmitted packet.

Masalah integrasi umum

Bagian ini menyoroti beberapa masalah umum yang dialami selama integrasi APF:

  • Pembersihan wilayah data yang tidak terduga: Memori APF harus sepenuhnya didedikasikan untuk APF; hanya kode penafsir atau kode framework (melalui HAL API) yang diizinkan untuk mengubah wilayah memori APF.
  • Masalah penginstalan dengan program APF berukuran X byte (X <= maxLen): Firmware harus mendukung pembacaan atau penulisan panjang program apa pun hingga maxLen tanpa kegagalan, error, atau pemotongan. Operasi tulis tidak boleh mengubah byte apa pun antara X dan maxLen.
  • Implementasi APF dalam kode driver: APF hanya boleh diterapkan dalam firmware, bukan kode driver. Jika tidak, tidak ada manfaat penghematan daya karena CPU perlu aktif untuk memproses paket.
  • Nilai filter_age atau filter_age_16384th salah: Nilai filter_age (APFv4) dan filter_age_16384th (APFv6) harus diteruskan dengan benar ke fungsi accept_packet() dan apf_run(). Untuk mengetahui detail penghitungan filter_age_16384th, lihat dokumentasi di apf_interpreter.h.
  • APF tidak diaktifkan saat diperlukan: APF harus diaktifkan saat layar nonaktif dan link Wi-Fi tidak ada aktivitas atau traffic di bawah 10 Mbps.
  • Paket yang terpotong yang diteruskan ke accept_packet() atau apf_run(): Semua paket unicast, broadcast, dan multicast yang diteruskan ke accept_packet() atau apf_run() harus lengkap. Meneruskan paket yang terpotong ke APF tidak valid.

Pengujian APF

Mulai Android 15, Android menyediakan kasus pengujian CTS perangkat tunggal dan multi-perangkat untuk integrasi filter APF dan penafsir APF untuk memastikan fungsi APF yang benar. Berikut adalah perincian tujuan setiap kasus pengujian:

  • Pengujian integrasi ApfFilter dan apf_interpreter: Memverifikasi bahwa ApfFilter menghasilkan bytecode yang benar, dan apf_interpreter menjalankan kode dengan benar untuk menghasilkan hasil yang diharapkan.
  • CTS perangkat tunggal APF: Menggunakan satu perangkat untuk menguji fungsi APF pada chipset Wi-Fi. Mengonfirmasi bahwa:
    • APF akan aktif saat layar nonaktif dan traffic Wi-Fi di bawah 10 Mbps.
    • Kemampuan APF dideklarasikan dengan benar.
    • Operasi baca dan tulis pada region memori APF berhasil, dan region memori tidak diubah secara tidak terduga.
    • Argumen diteruskan dengan benar ke accept_packet() atau apf_run().
    • Firmware yang terintegrasi dengan APFv4/APFv6 dapat menghapus paket.
    • Firmware yang terintegrasi dengan APFv6 dapat membalas paket.
  • CTS multi-perangkat APF: Menggunakan dua perangkat (satu pengirim, satu penerima) untuk menguji perilaku pemfilteran APF. Berbagai jenis paket dihasilkan di sisi pengirim, dan pengujian mengonfirmasi apakah paket tersebut dihapus, diteruskan, atau dibalas dengan benar berdasarkan aturan yang dikonfigurasi di ApfFilter.

Petunjuk pengujian integrasi tambahan

Selain itu, sebaiknya vendor chipset menggabungkan pengujian APF ke dalam rangkaian pengujian integrasi Wi-Fi firmware mereka sendiri.

Mengintegrasikan pengujian APF ke dalam rangkaian pengujian integrasi Wi-Fi firmware sangat penting untuk memverifikasi fungsi APF yang tepat dalam skenario koneksi Wi-Fi yang kompleks seperti skenario koneksi Wi-Fi roaming atau make-before-break. Petunjuk mendetail tentang cara melakukan pengujian integrasi dapat ditemukan di bagian berikut.

Prasyarat

Saat melakukan pengujian integrasi, lakukan hal berikut:

  • APF harus diaktifkan di semua kasus pengujian integrasi (misalnya, roaming, make-before-break).
  • Di awal setiap pengujian, hapus memori APF.
  • Instal atau instal ulang program APF setiap 5 menit selama pengujian.

Skenario pengujian

APF harus aktif selama pengujian integrasi. Ada dua program APF yang disediakan dalam dokumen ini yang dapat diinstal selama pengujian. Program tersebut berformat string hex, dan penguji harus mengonversi string hex menjadi biner dan menginstalnya ke firmware agar program dapat dieksekusi oleh apf_interpreter. Selama pengujian integrasi, penguji harus mengirim paket yang diharapkan akan memicu logika pemfilteran di program 1 dan program 2.

Program APF 1

Saat layar perangkat aktif, instal program APF 1. Program ini dapat menghapus paket yang tidak berbahaya dan tidak memengaruhi fungsi perangkat. Paket ini digunakan untuk menguji apakah APF memfilter traffic jaringan dengan benar.

Logika program 1 APF adalah sebagai berikut:

  1. Menurunkan dan menambahkan penghitung:
    1. Nilai EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. Paket penemuan atau permintaan DHCP IPv4
    3. Paket RS
  2. Melewatkan dan menambahkan penghitung: Semua paket lainnya.

Kode byte 1 program APF adalah sebagai berikut:

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
Program APF 2

Saat layar perangkat nonaktif, instal program APF 2. Program ini memfilter semua paket yang difilter program APF 1, serta paket permintaan ping. Untuk memverifikasi bahwa program APF 2 diinstal dengan benar, kirim paket ping ke perangkat yang sedang diuji.

Logika program 2 APF adalah sebagai berikut:

  1. Menurunkan dan menambahkan penghitung:
    1. Nilai EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. Paket penemuan atau permintaan DHCP IPv4
    3. Paket RS
  2. Menurunkan dan menambahkan penghitung: Paket permintaan ping ICMP
  3. Melewatkan dan menambahkan penghitung: Semua paket lainnya

Kode 2 byte program APF adalah sebagai berikut:

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C007488A27C006F88A47C006A88B87C006588CD7C006088E17C005B88E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE87234120C84000E86DD0A1482093A0A368204856BE0721F120C84001008000A17820B01AB0D220E8204086BE472086BDCB03A01B87206B03A01B87201
Verifikasi data

Untuk memverifikasi bahwa program APF dijalankan dan paket diteruskan atau dihapus dengan benar, lakukan hal berikut:

  • Ambil dan verifikasi region data APF setiap 5 menit.
  • Jangan menghapus penghitung.
  • Buat paket pengujian untuk memicu setiap aturan filter.
  • Verifikasi penambahan penghitung menggunakan lokasi memori berikut:

    Nama penghitung Lokasi memori
    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]

Pseudocode untuk program APF 1 dan program APF 2

Pseudocode berikut menjelaskan logika program APF 1 dan program APF 2 secara mendetail:

// 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